9#include <fei_sstream.hpp>
10#include <fei_fstream.hpp>
12#include <test_utils/fei_test_utils.hpp>
14#include <test_utils/FEI_tester.hpp>
16#include <fei_LinearSystemCore.hpp>
17#include <fei_LibraryWrapper.hpp>
18#include <snl_fei_Utils.hpp>
20#include <fei_FEI_Impl.hpp>
22#include <test_utils/LibraryFactory.hpp>
25#include <FETI_DP_FiniteElementData.h>
28#include <test_utils/DataReader.hpp>
29#include <test_utils/SolnCheck.hpp>
32#define fei_file "FEI_tester.cpp"
34#include <fei_ErrMacros.hpp>
38 MPI_Comm comm,
int localProc,
int numProcs,
bool useNewFEI)
54FEI_tester::~FEI_tester()
61int FEI_tester::testInitialization()
63 if (data_.
get() == NULL) {
67 CHK_ERR( createFEIinstance(data_->solverLibraryName_.c_str()) );
69 const char* feiVersionString;
70 CHK_ERR( fei_->
version(feiVersionString) );
72 FEI_COUT <<
"FEI version: " << feiVersionString << FEI_ENDL;
74 fei_->
parameters(data_->numParams_, data_->paramStrings_);
82 if (data_->solveType_ == FEI_AGGREGATE_SUM) {
83 CHK_ERR( setIDlists());
86 CHK_ERR( initializationPhase() );
89 for(
int i=0; i<data_->numElemBlocks_; ++i) {
90 ElemBlock& eblk = data_->elemBlocks_[i];
91 int elemBlockID = eblk.blockID_;
101int FEI_tester::testLoading()
112 if (data_->solveType_ == FEI_SINGLE_SYSTEM) {
113 CHK_ERR( normalLoadPhase());
115 if (data_->solveType_ == FEI_AGGREGATE_SUM) {
116 CHK_ERR( aggregateLoadPhase());
121 CHK_ERR( exerciseResidualNorm() );
124 CHK_ERR( exercisePutFunctions() );
130int FEI_tester::testSolve()
134 std::string sname(data_->solverLibraryName_);
135 if (sname ==
"TEST_LSC") {
140 int err = fei_->
solve(status);
144 if (err != 0 || status != 0) {
145 FEI_COUT <<
"!!!! solve returned: err: "<<err<<
", status: "<<status<<FEI_ENDL;
149 if (localProc_ == 0) {
155 CHK_ERR( exerciseResidualNorm() );
161void FEI_tester::dumpMatrixFiles()
166void FEI_tester::setParameter(
const char*)
171int FEI_tester::testCheckResult()
175 std::string sname(data_->solverLibraryName_);
176 if (sname ==
"TEST_LSC") {
177 return( lsc_matrix_check() );
180 CHK_ERR( save_block_node_soln(*data_, *fei_, data_->solnFileName_.c_str(),
181 numProcs_, localProc_, 1));
183 CHK_ERR( save_block_elem_soln(*data_, *fei_, data_->solnFileName_.c_str(),
184 numProcs_, localProc_, 1));
186 CHK_ERR( save_multiplier_soln(*data_, *fei_, data_->solnFileName_.c_str(),
187 numProcs_, localProc_, 1));
189 int err = SolnCheck::checkSolution(localProc_, numProcs_, data_->solnFileName_.c_str(),
190 data_->checkFileName_.c_str(),
"node", 1);
192 err += SolnCheck::checkSolution(localProc_, numProcs_, data_->solnFileName_.c_str(),
193 data_->checkFileName_.c_str(),
"elem", 1);
195 err += SolnCheck::checkSolution(localProc_, numProcs_, data_->solnFileName_.c_str(),
196 data_->checkFileName_.c_str(),
"mult", 1);
199 if (MPI_SUCCESS != MPI_Allreduce(&err, &globalErr, 1, MPI_INT, MPI_SUM,
202 if (globalErr != 0) {
210int FEI_tester::createFEIinstance(
const char* solverName)
215 catch(std::runtime_error& exc) {
220 if (wrapper_.
get() == NULL) ERReturn(-1);
229 if (fei_.
get() == NULL) ERReturn(-1);
235int FEI_tester::setIDlists()
237 snl_fei::getIntParamValue(
"numMatrices",
239 data_->paramStrings_,
242 matrixIDs =
new int[numMatrices];
247 for(
int i=0; i<numMatrices; i++) {
251 CHK_ERR(fei_->
setIDLists(numMatrices, matrixIDs, numRHSs, rhsIDs));
256int FEI_tester::initializationPhase()
258 if (data_->solveType_ != FEI_SINGLE_SYSTEM &&
259 data_->solveType_ != FEI_AGGREGATE_SUM) {
260 FEI_COUT <<
"FEI_tester: bad solveType: " << data_->solveType_ << FEI_ENDL;
266 CHK_ERR(fei_->
initFields(data_->numFields_, data_->fieldSizes_, data_->fieldIDs_));
269 for(i=0; i<data_->numElemBlocks_; i++) {
270 ElemBlock& block = data_->elemBlocks_[i];
274 block.numNodesPerElement_,
275 block.numFieldsPerNode_,
276 block.nodalFieldIDs_,
278 block.elemDOFFieldIDs_,
279 block.interleaveStrategy_) );
281 for(
int el=0; el<block.numElements_; el++) {
282 CHK_ERR(fei_->
initElem(block.blockID_,
284 block.elemConn_[el]));
288 for(i=0; i<data_->numSharedNodeSets_; i++) {
289 CommNodeSet& shNodeSet = data_->sharedNodeSets_[i];
292 shNodeSet.procsPerNode_, shNodeSet.procs_));
297 for(i=0; i<data_->numSlaveVars_; i++) {
298 CRSet& crSet = data_->slaveVars_[i];
312 for(i=0; i<data_->numCRMultSets_; i++) {
313 CRSet& crSet = data_->crMultSets_[i];
315 for(
int j=0; j<1; j++) {
323 for(i=0; i<data_->numCRPenSets_; i++) {
324 CRSet& crSet = data_->crPenSets_[i];
326 for(
int j=0; j<1; j++) {
339int FEI_tester::normalLoadPhase()
345 for(i=0; i<data_->numBCNodeSets_; i++) {
346 BCNodeSet& bcSet = data_->bcNodeSets_[i];
351 bcSet.offsetsIntoField_,
352 bcSet.prescribed_values_));
355 for(i=0; i<data_->numElemBlocks_; i++) {
356 ElemBlock& block = data_->elemBlocks_[i];
358 for(
int el=0; el<block.numElements_; el++) {
363 block.elemStiff_[el],
368 for(i=0; i<data_->numElemBlocks_; i++) {
369 ElemBlock& block = data_->elemBlocks_[i];
371 for(
int el=0; el<block.numElements_; el++) {
376 block.elemLoad_[el]));
382 for(i=0; i<data_->numCRMultSets_; i++) {
383 CRSet& crSet = data_->crMultSets_[i];
385 for(
int j=0; j<1; j++) {
395 for(i=0; i<data_->numCRPenSets_; i++) {
396 CRSet& crSet = data_->crPenSets_[i];
398 for(
int j=0; j<1; j++) {
405 crSet.penValues_[j]))
412int FEI_tester::aggregateLoadPhase()
416 for(i=0; i<numMatrices; i++) {
419 for(
int j=0; j<data_->numElemBlocks_; j++) {
420 ElemBlock& block = data_->elemBlocks_[j];
422 for(
int el=0; el<block.numElements_; el++) {
427 block.elemStiff_[el],
433 for(i=0; i<numRHSs; i++) {
436 for(
int j=0; j<data_->numElemBlocks_; j++) {
437 ElemBlock& block = data_->elemBlocks_[j];
439 for(
int el=0; el<block.numElements_; el++) {
443 block.elemLoad_[el]))
450 for(i=0; i<data_->numBCNodeSets_; i++) {
451 BCNodeSet& bcSet = data_->bcNodeSets_[i];
456 bcSet.offsetsIntoField_,
457 bcSet.prescribed_values_))
460 double* matScalars =
new double[numMatrices];
461 for(i=0; i<numMatrices; i++) {
465 int rhsScaleID = rhsIDs[0];
466 double rhsScalar = 1.0;
468 CHK_ERR(fei_->
setMatScalars(numMatrices, matrixIDs, matScalars))
471 delete [] matScalars;
476int FEI_tester::exerciseResidualNorm()
478 std::string sname(data_->solverLibraryName_);
479 if (sname ==
"TEST_LSC") {
483 double* norms =
new double[data_->numFields_];
484 int *fields =
new int[data_->numFields_];
485 for(
int i=0; i<data_->numFields_; ++i) {
486 fields[i] = data_->fieldIDs_[i];
489 CHK_ERR( fei_->
residualNorm(1, data_->numFields_, fields, norms) );
502int FEI_tester::exercisePutFunctions()
508 std::vector<int> nodeIDs(numNodes);
509 int* nodeIDsPtr = &nodeIDs[0];
513 for(
int i=0; i<data_->numFields_; ++i) {
514 int fieldID = data_->fieldIDs_[i];
515 int fieldSize = data_->fieldSizes_[i];
516 std::vector<double> data(numNodes*fieldSize, 0.0001);
526int FEI_tester::save_block_node_soln(DataReader& data,
FEI&
fei,
527 const char* solnFileName,
int numProcs,
528 int localProc,
int solveCounter)
533 int maxNumEqnsPerNode = 0;
534 for(i=0; i<data.numFields_; ++i) {
535 maxNumEqnsPerNode += data.fieldSizes_[i];
538 std::vector<double> soln(maxNumEqnsPerNode);
541 CHK_ERR(
fei.getNumLocalNodes(numNodes) );
543 std::vector<GlobalID> nodes(numNodes);
544 int* nodesPtr = &nodes[0];
547 CHK_ERR(
fei.getLocalNodeIDList( checkNumNodes, nodesPtr, numNodes) );
549 if (checkNumNodes != numNodes) {
553 FEI_OSTRINGSTREAM fileName;
555 FEI_OFSTREAM outfile(fileName.str().c_str());
557 if (!outfile || outfile.bad()) {
558 FEI_COUT <<
"ERROR opening solution output file " << fileName.str() << FEI_ENDL;
562 outfile.setf(IOS_SCIENTIFIC, IOS_FLOATFIELD);
564 std::vector<int> offsets(2);
566 for(i=0; i<numNodes; ++i) {
567 CHK_ERR(
fei.getNodalSolution(1, &(nodesPtr[i]),
568 &offsets[0], &soln[0]) );
570 int numDOF = offsets[1];
572 outfile << nodesPtr[i] <<
" " << numDOF << FEI_ENDL;
573 for(
int j=0; j<numDOF; j++) {
574 outfile << soln[j] <<
" ";
583int FEI_tester::save_block_elem_soln(DataReader& data,
FEI&
fei,
584 const char* solnFileName,
585 int numProcs,
int localProc,
589 FEI_OSTRINGSTREAM fileName;
591 FEI_OFSTREAM outfile(fileName.str().c_str());
593 if (!outfile || outfile.bad()) {
594 FEI_COUT <<
"ERROR opening elem-solution output file " << fileName.str() << FEI_ENDL;
598 for(
int i=0; i<data.numElemBlocks_; i++) {
599 if (returnValue != 0)
break;
601 ElemBlock& eb = data.elemBlocks_[i];
603 GlobalID blockID = eb.blockID_;
605 CHK_ERR(
fei.getNumBlockElements(blockID, numElems))
608 CHK_ERR(
fei.getNumBlockElemDOF(blockID, dofPerElem))
609 int totalNumElemDOF = numElems*dofPerElem;
611 if (totalNumElemDOF < 1) {
615 GlobalID* elemIDs =
new GlobalID[numElems];
616 if (elemIDs==NULL)
return(-1);
618 int err =
fei.getBlockElemIDList(blockID, numElems, elemIDs);
619 if (err) returnValue = 1;
621 int* offsets =
new int[numElems+1];
622 if (offsets == NULL)
return(-1);
624 if (totalNumElemDOF > 0) {
625 double* solnValues =
new double[totalNumElemDOF];
626 if (solnValues == NULL)
return(-1);
628 err =
fei.getBlockElemSolution(blockID, numElems, elemIDs,
629 dofPerElem, solnValues);
630 if (err) returnValue = 1;
633 for(
int j=0; j<numElems; j++) {
635 outfile << (int)elemIDs[j] <<
" " << dofPerElem << FEI_ENDL <<
" ";
636 for(
int k=0; k<dofPerElem; k++) {
637 outfile << solnValues[j*dofPerElem + k] <<
" ";
643 delete [] solnValues;
654int FEI_tester::save_multiplier_soln(DataReader& data,
FEI&
fei,
655 const char* solnFileName,
656 int numProcs,
int localProc,
int solveCounter)
660 CHK_ERR(
fei.getNumCRMultipliers(numCRs) );
662 int* globalNumCRs =
new int[
numProcs];
664 if (MPI_Allgather(&numCRs, 1, MPI_INT, globalNumCRs, 1, MPI_INT,
665 comm_) != MPI_SUCCESS) {
670 int localCRStart = 0;
671 for(
int p=0; p<
localProc; p++) localCRStart += globalNumCRs[p];
673 delete [] globalNumCRs;
675 FEI_OSTRINGSTREAM fileName;
677 FEI_OFSTREAM outfile(fileName.str().c_str());
679 if (!outfile || outfile.bad()) {
680 FEI_COUT <<
"ERROR opening mult-solution output file " << fileName.str() << FEI_ENDL;
684 int* CRIDs = numCRs > 0 ?
new int[numCRs] : NULL;
685 double* results = numCRs > 0 ?
new double[numCRs] : NULL;
687 if (numCRs > 0 && (CRIDs==NULL || results==NULL)) {
695 CHK_ERR(
fei.getCRMultIDList(numCRs, CRIDs) );
697 std::string sname(data_->solverLibraryName_);
698 if (sname ==
"FETI") {
699 for(
int ii=0; ii<numCRs; ++ii) results[ii] = -999.99;
702 CHK_ERR(
fei.getCRMultipliers(numCRs, CRIDs, results));
705 for(
int i=0; i<numCRs; i++) {
706 outfile << localCRStart++ <<
" " << 1 << FEI_ENDL;
708 outfile <<
" " << results[i] << FEI_ENDL;
718int FEI_tester::lsc_matrix_check()
720 if (localProc_ == 0) {
721 char* current_dir = NULL;
722 CHK_ERR( fei_test_utils::dirname(data_->solnFileName_.c_str(), current_dir));
724 FEI_OSTRINGSTREAM solnMtxName;
725 solnMtxName<< current_dir<<
"/A_TLSC.mtx";
726 fei::FillableMat solnMtx, checkMtx;
727 CHK_ERR( SolnCheck::readMatrix(solnMtxName.str().c_str(), numProcs_, solnMtx) );
728 CHK_ERR( SolnCheck::readMatrix(data_->checkFileName_.c_str(), numProcs_, checkMtx) );
729 int err = SolnCheck::compareMatrices(solnMtx, checkMtx);
730 delete [] current_dir;
732 FEI_COUT <<
"Utst_fei_lsc: TEST PASSED" << FEI_ENDL;
735 FEI_COUT <<
"Utst_fei_lsc: TEST FAILED" << FEI_ENDL;
virtual int initComplete()=0
virtual int getLocalNodeIDList(int &numNodes, GlobalID *nodeIDs, int lenNodeIDs)=0
virtual int residualNorm(int whichNorm, int numFields, int *fieldIDs, double *norms)=0
virtual int setCurrentMatrix(int matrixID)=0
virtual int initElemBlock(GlobalID elemBlockID, int numElements, int numNodesPerElement, const int *numFieldsPerNode, const int *const *nodalFieldIDs, int numElemDofFieldsPerElement, const int *elemDOFFieldIDs, int interleaveStrategy)=0
virtual int sumInElemMatrix(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn, const double *const *elemStiffness, int elemFormat)=0
virtual int iterations(int &itersTaken) const =0
virtual int loadCRPen(int CRPenID, int numCRNodes, const GlobalID *CRNodeIDs, const int *CRFieldIDs, const double *CRWeights, double CRValue, double penValue)=0
virtual int initCRPen(int numCRNodes, const GlobalID *CRNodeIDs, const int *CRFieldIDs, int &CRID)=0
virtual int putNodalFieldData(int fieldID, int numNodes, const GlobalID *nodeIDs, const double *data)=0
virtual int setMatScalars(int numScalars, const int *IDs, const double *scalars)=0
virtual int initCRMult(int numCRNodes, const GlobalID *CRNodeIDs, const int *CRFieldIDs, int &CRID)=0
virtual int loadCRMult(int CRMultID, int numCRNodes, const GlobalID *CRNodeIDs, const int *CRFieldIDs, const double *CRWeights, double CRValue)=0
virtual int initFields(int numFields, const int *fieldSizes, const int *fieldIDs, const int *fieldTypes=NULL)=0
virtual int loadComplete(bool applyBCs=true, bool globalAssemble=true)=0
virtual int getNumLocalNodes(int &numNodes)=0
virtual int sumInElemRHS(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn, const double *elemLoad)=0
virtual int setIDLists(int numMatrices, const int *matrixIDs, int numRHSs, const int *rhsIDs)=0
virtual int setCurrentRHS(int rhsID)=0
virtual int resetMatrix(double s=0.0)=0
virtual int version(const char *&versionString)=0
virtual int setRHSScalars(int numScalars, const int *IDs, const double *scalars)=0
virtual int parameters(int numParams, const char *const *paramStrings)=0
virtual int resetRHSVector(double s=0.0)=0
virtual int initSharedNodes(int numSharedNodes, const GlobalID *sharedNodeIDs, const int *numProcsPerNode, const int *const *sharingProcIDs)=0
virtual int initSlaveVariable(GlobalID slaveNodeID, int slaveFieldID, int offsetIntoSlaveField, int numMasterNodes, const GlobalID *masterNodeIDs, const int *masterFieldIDs, const double *weights, double rhsValue)=0
virtual int resetSystem(double s=0.0)=0
virtual int getNumBlockActNodes(GlobalID elemBlockID, int &numNodes) const =0
virtual int setSolveType(int solveType)=0
virtual int solve(int &status)=0
virtual int loadNodeBCs(int numNodes, const GlobalID *nodeIDs, int fieldID, const int *offsetsIntoField, const double *prescribedValues)=0
virtual int initElem(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn)=0
int localProc(MPI_Comm comm)
std::ostream & console_out()
fei::SharedPtr< LibraryWrapper > create_LibraryWrapper(MPI_Comm comm, const char *libraryName)
int numProcs(MPI_Comm comm)