test_VectorSpace.cpp

00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 
00010 #include <fei_macros.hpp>
00011 
00012 #include <test_utils/test_VectorSpace.hpp>
00013 
00014 #include <snl_fei_Factory.hpp>
00015 #include <fei_ParameterSet.hpp>
00016 #include <fei_LibraryWrapper.hpp>
00017 #include <assert.h>
00018 
00019 #undef fei_file
00020 #define fei_file "test_VectorSpace.cpp"
00021 #include <fei_ErrMacros.hpp>
00022 
00023 test_VectorSpace::test_VectorSpace(MPI_Comm comm)
00024  : tester(comm)
00025 {
00026 }
00027 
00028 test_VectorSpace::~test_VectorSpace()
00029 {
00030 }
00031 
00032 int test_VectorSpace::runtests()
00033 {
00034   CHK_ERR( test0() );
00035   CHK_ERR( test1() );
00036   CHK_ERR( test2() );
00037   CHK_ERR( test3() );
00038   CHK_ERR( test4() );
00039   return(0);
00040 }
00041 
00042 int test_VectorSpace::test0()
00043 {
00044   int i, ID = 0;
00045   int idType = 0;
00046   std::vector<int> fieldIDs(numProcs_);
00047   int fieldSize = 2;
00048   std::vector<int> fieldSizes(numProcs_, fieldSize);
00049 
00050   for(i=0; i<numProcs_; ++i) fieldIDs[i] = i;
00051 
00052   fei::VectorSpace vspace(comm_);
00053 
00054   vspace.defineIDTypes(1, &idType);
00055   vspace.defineFields(fieldIDs.size(), &fieldIDs[0], &fieldSizes[0]);
00056 
00057   CHK_ERR( vspace.addDOFs(idType, 1, &ID) );
00058 
00059   for(i=0; i<numProcs_; ++i) {
00060     if (i == localProc_) continue;
00061 
00062     int numSharingProcsPerID = 1;
00063     int sharingProc = i;
00064 
00065     CHK_ERR( vspace.initSharedIDs(1, idType, &ID,
00066           &numSharingProcsPerID, &sharingProc) );
00067   }
00068 
00069   CHK_ERR( vspace.addDOFs(fieldIDs[localProc_], 1, idType,
00070               1, &ID) );
00071 
00072   CHK_ERR( vspace.initComplete() );
00073 
00074   std::vector<int> globalIndexOffsets;
00075 
00076   vspace.getGlobalIndexOffsets(globalIndexOffsets);
00077 
00078   return(0);
00079 }
00080 
00081 int test_VectorSpace::test1()
00082 {
00083   //A general test of fei::VectorSpace, including defining fields and
00084   //idTypes, initializing solution entries, shared ids if numProcs_ > 1, then
00085   //testing getGlobalIndexOffsets and getGlobalIndex several times.
00086 
00087   testData* testdata = new testData(localProc_, numProcs_);
00088   std::vector<int>& fieldIDs = testdata->fieldIDs;
00089   std::vector<int>& idTypes = testdata->idTypes;
00090   std::vector<int>& ids = testdata->ids;
00091 
00092   int numDOFsPerID = 4; //1 scalar field and 1 3-vector field
00093 
00094   fei::SharedPtr<LibraryWrapper> wrapper;
00095   fei::SharedPtr<fei::Factory> factory(new snl_fei::Factory(comm_, wrapper));
00096 
00097   fei::SharedPtr<fei::VectorSpace> vectorSpacePtr =
00098     test_VectorSpace::create_VectorSpace(comm_,
00099                                          testdata, localProc_, numProcs_,
00100            true, //defineBothFields
00101            true, //initSolnBothFields
00102            "U", //name
00103            factory);
00104 
00105   CHK_ERR( vectorSpacePtr->initComplete() );
00106 
00107   fei::VectorSpace& vectorSpace = *vectorSpacePtr;
00108 
00109   std::vector<int> globalOffsets;
00110 
00111   vectorSpace.getGlobalIndexOffsets(globalOffsets);
00112 
00113   if (localProc_ > 0) {
00114     if (globalOffsets[localProc_] != (localProc_+1)*2*numDOFsPerID) {
00115       ERReturn(-1);
00116     }
00117   }
00118 
00119   if (globalOffsets[localProc_+1] != (localProc_+2)*2*numDOFsPerID) {
00120     ERReturn(-1);
00121   }
00122 
00123   std::vector<int> globalBlkOffsets;
00124   vectorSpace.getGlobalBlkIndexOffsets(globalBlkOffsets);
00125   if (localProc_ > 0) {
00126     if (globalBlkOffsets[localProc_] != (localProc_+1)*2) {
00127       ERReturn(-1);
00128     }
00129   }
00130 
00131   if (globalBlkOffsets[localProc_+1] != (localProc_+2)*2) {
00132     ERReturn(-1);
00133   }
00134 
00135   int len = ids.size();
00136   int globalIndex = 0;
00137   CHK_ERR( vectorSpace.getGlobalIndex(idTypes[0], ids[0], fieldIDs[0],
00138             0, 0, globalIndex) );
00139 
00140   int correctIndex = globalOffsets[localProc_];
00141   int correctBlkIndex = globalBlkOffsets[localProc_];
00142   if (localProc_ != 0) correctIndex -= 2*numDOFsPerID;
00143   if (localProc_ != 0) correctBlkIndex -= 2;
00144 
00145   if (globalIndex != correctIndex) {
00146     ERReturn(-1);
00147   }
00148 
00149   int globalBlkIndex = 0;
00150   CHK_ERR( vectorSpace.getGlobalBlkIndex(idTypes[0], ids[0], globalBlkIndex) );
00151   if (globalBlkIndex != correctBlkIndex) {
00152     FEI_CERR << "localProc_: " << localProc_ << ", globalBlkIndex: "
00153    << globalBlkIndex << ", correctBlkIndex: " << correctBlkIndex << FEI_ENDL;
00154     ERReturn(-1);
00155   }
00156 
00157   CHK_ERR( vectorSpace.getGlobalIndex(idTypes[0],  ids[1], fieldIDs[0],
00158             0, 0, globalIndex) );
00159 
00160   correctIndex = globalOffsets[localProc_] + 4;
00161   if (localProc_ != 0) correctIndex -= 2*numDOFsPerID;
00162 
00163   if (globalIndex != correctIndex) {
00164     ERReturn(-1);
00165   }
00166 
00167   CHK_ERR( vectorSpace.getGlobalBlkIndex(idTypes[0], ids[1], globalBlkIndex) );
00168   correctBlkIndex = globalBlkOffsets[localProc_]+1;
00169   if (localProc_ != 0) correctBlkIndex -= 2;
00170 
00171   if (globalBlkIndex != correctBlkIndex) {
00172    FEI_CERR << "2localProc_: " << localProc_ << ", globalBlkIndex: "
00173    << globalBlkIndex << ", correctBlkIndex: " << correctBlkIndex << FEI_ENDL;
00174     ERReturn(-1); 
00175   }
00176 
00177   CHK_ERR( vectorSpace.getGlobalIndex(idTypes[0], ids[len-1], fieldIDs[0],
00178             0, 0, globalIndex) );
00179   correctIndex = globalOffsets[localProc_] + 12;
00180   if (localProc_ != 0) correctIndex -= 2*numDOFsPerID;
00181 
00182   if (globalIndex != correctIndex) {
00183     ERReturn(-1);
00184   }
00185 
00186   CHK_ERR( vectorSpace.getGlobalIndex(idTypes[0], ids[0], fieldIDs[1],
00187             0, 0, globalIndex) );
00188   correctIndex = globalOffsets[localProc_] + 1;
00189   if (localProc_ != 0) correctIndex -= 2*numDOFsPerID;
00190 
00191   if (globalIndex != correctIndex) {
00192     ERReturn(-1);
00193   }
00194 
00195   CHK_ERR( vectorSpace.getGlobalIndex(idTypes[0], ids[1], fieldIDs[1],
00196             0, 0, globalIndex) );
00197   correctIndex = globalOffsets[localProc_] + 5;
00198   if (localProc_ != 0) correctIndex -= 2*numDOFsPerID;
00199 
00200   if (globalIndex != correctIndex) {
00201     ERReturn(-1);
00202   }
00203 
00204   CHK_ERR( vectorSpace.getGlobalIndex(idTypes[0], ids[len-1], fieldIDs[1],
00205             0, 0, globalIndex) );
00206   correctIndex = globalOffsets[localProc_] + 13;
00207   if (localProc_ != 0) correctIndex -= 2*numDOFsPerID;
00208 
00209   if (globalIndex != correctIndex) {
00210     ERReturn(-1);
00211   }
00212 
00213   std::vector<int> globalIndices(ids.size()*numDOFsPerID);
00214 
00215   CHK_ERR( vectorSpace.getGlobalIndices(ids.size(),
00216           &(ids[0]),
00217           idTypes[0], fieldIDs[0],
00218           &globalIndices[0] ));
00219 
00220   std::vector<int> idFieldIDs(ids.size(), fieldIDs[1]);
00221   std::vector<int> idIDTypes(ids.size(), idTypes[0]);
00222 
00223   CHK_ERR( vectorSpace.getGlobalIndices(ids.size(),
00224           &ids[0],
00225           idTypes[0], fieldIDs[0],
00226           &globalIndices[0] ));
00227 
00228   CHK_ERR( vectorSpace.getGlobalBlkIndices(ids.size(),
00229              &ids[0],
00230              idTypes[0],
00231              &globalIndices[0] ));
00232 
00233   CHK_ERR( vectorSpace.getGlobalIndices(ids.size(),
00234           &ids[0],
00235           &idIDTypes[0],
00236           &idFieldIDs[0],
00237           &globalIndices[0]) );
00238 
00239   unsigned numFields = vectorSpace.getNumFields();
00240   if (numFields != fieldIDs.size()) {
00241     ERReturn(-1);
00242   }
00243 
00244   std::vector<int> testgetfields;
00245   vectorSpace.getFields(testgetfields);
00246   if (testgetfields.size() != numFields) {
00247     ERReturn(-1);
00248   }
00249 
00250   if (fieldIDs != testgetfields) {
00251     ERReturn(-1);
00252   }
00253 
00254   delete testdata;
00255 
00256   return(0);
00257 }
00258 
00259 int test_VectorSpace::test2()
00260 {
00261   //only run this test if asserts are enabled (i.e., if NDEBUG is not defined)
00262   bool run_this_test = false;
00263   assert( (run_this_test = true) == true);
00264   if (!run_this_test) return(0);
00265 
00266   //Initializes a fei::VectorSpace object using the same data as used
00267   //above, but then adds a globally inconsistent shared-id
00268   //before calling initComplete. The goal is to make sure that the shared-id
00269   //safety-check in fei::VectorSpace will catch the incorrect shared-id
00270   //data and return an error-code.
00271 
00272   testData* testdata = new testData(localProc_, numProcs_);
00273   std::vector<int>& idTypes = testdata->idTypes;
00274   std::vector<int>& ids = testdata->ids;
00275 
00276   fei::SharedPtr<LibraryWrapper> wrapper;
00277   fei::SharedPtr<fei::Factory> factory(new snl_fei::Factory(comm_, wrapper));
00278 
00279   fei::SharedPtr<fei::VectorSpace> vectorSpacePtr =
00280     test_VectorSpace::create_VectorSpace(comm_,
00281                                          testdata, localProc_,
00282            numProcs_,
00283            true, //defineBothFields
00284            true, //initSolnBothFields
00285            "U2", factory);
00286 
00287   if (localProc_ < numProcs_-1) {
00288     int numSharingProcsPerID = 1;
00289     int sharingProc = localProc_+1;
00290 
00291     CHK_ERR( vectorSpacePtr->initSharedIDs(1, idTypes[0], &ids[0],
00292              &numSharingProcsPerID,
00293              &sharingProc) );
00294   }
00295 
00296   fei::ParameterSet paramset;
00297   paramset.add(fei::Param("FEI_CHECK_SHARED_IDS", true));
00298 
00299   vectorSpacePtr->setParameters(paramset);
00300 
00301   //we just provided globally inconsistent shared-id info, so we expect the
00302   //initComplete method to return(-1) after the shared-id safety-check fails,
00303   //if we're running on more than one processor.
00304   int err = vectorSpacePtr->initComplete();
00305   if (numProcs_ > 1) if (err == 0) return(-1);
00306   delete testdata;
00307 
00308   return(0);
00309 }
00310 
00311 int test_VectorSpace::test3()
00312 {
00313   testData* testdata = new testData(localProc_, numProcs_);
00314 
00315   fei::SharedPtr<LibraryWrapper> wrapper;
00316   fei::SharedPtr<fei::Factory> factory(new snl_fei::Factory(comm_, wrapper));
00317 
00318   fei::SharedPtr<fei::VectorSpace> vectorSpacePtr =
00319     test_VectorSpace::create_VectorSpace(comm_,
00320                                          testdata, localProc_, numProcs_,
00321            true, //defineBothFields
00322            true, //initSolnBothFields
00323            "U3", factory);
00324 
00325   fei::SharedPtr<fei::VectorSpace> copy =
00326     factory->createVectorSpace(comm_, "U3copy");
00327 
00328   fei::Param param("debugOutput", ".");
00329   fei::ParameterSet paramset;
00330   paramset.add(param);
00331   copy->setParameters(paramset);
00332 
00333 
00334   CHK_ERR( copy->addVectorSpace(vectorSpacePtr.get()) );
00335 
00336   CHK_ERR( vectorSpacePtr->initComplete() );
00337 
00338   CHK_ERR( copy->initComplete() );
00339 
00340   std::vector<int> globalOffsets;
00341   std::vector<int> globalOffsetsCopy;
00342 
00343   vectorSpacePtr->getGlobalIndexOffsets(globalOffsets);
00344 
00345   copy->getGlobalIndexOffsets(globalOffsetsCopy);
00346 
00347   for(size_t i=0; i<globalOffsets.size(); ++i) {
00348     if (globalOffsets[i] != globalOffsetsCopy[i]) {
00349       ERReturn(-1);
00350     }
00351   }
00352 
00353   CHK_ERR( copy->initComplete() );
00354 
00355   copy->getGlobalIndexOffsets(globalOffsetsCopy);
00356 
00357   if (globalOffsetsCopy[numProcs_] != globalOffsets[numProcs_]) {
00358     ERReturn(-1);
00359   }
00360 
00361   delete testdata;
00362 
00363   return(0);
00364 }
00365 
00366 int test_VectorSpace::test4()
00367 {
00368   return(0);
00369 }
00370 
00371 fei::SharedPtr<fei::VectorSpace>
00372 test_VectorSpace::create_VectorSpace(MPI_Comm comm)
00373 {
00374   int localProc = 0, numProcs = 1;
00375 #ifndef FEI_SER
00376   MPI_Comm_rank(comm, &localProc);
00377   MPI_Comm_size(comm, &numProcs);
00378 #endif
00379 
00380   testData test_data(localProc, numProcs);
00381   fei::SharedPtr<fei::Factory> factory;
00382 
00383   fei::SharedPtr<fei::VectorSpace> vspace =
00384     test_VectorSpace::create_VectorSpace(comm, &test_data, localProc, numProcs,
00385            false, false, (const char*)0, factory);
00386   int err = vspace->initComplete();
00387   if (err != 0) {
00388     FEI_COUT << "ERROR, failed to create valid fei::VectorSpace." << FEI_ENDL;
00389     throw std::runtime_error("test_Vector::vector_test1: ERROR, failed to create valid fei::VectorSpace.");
00390   }
00391 
00392   return(vspace);
00393 }
00394 
00395 fei::SharedPtr<fei::VectorSpace>
00396 test_VectorSpace::create_VectorSpace(MPI_Comm comm,
00397              testData* testdata,
00398              int localProc,
00399              int numProcs,
00400              bool defineBothFields,
00401              bool initSolnBothFields,
00402              const char* name,
00403              fei::SharedPtr<fei::Factory> factory,
00404              bool turnOnDebugOutput)
00405 {
00406   //
00407   //This function creates a VectorSpace object, then initializes it as follows:
00408   //
00409   //defineFields testdata->fieldIDs, testdata->fieldSizes
00410   //defineIDTypes testdata->idTypes
00411   //addDOFs testdata->ids with associated testdata->fieldIDs[0]
00412   //addDOFs testdata->ids with testdata->fieldIDs[1] if bothFields
00413   //initSharedIDs  testdata->[shared-id-data] with testdata->idTypes[0]
00414   //
00415   fei::SharedPtr<fei::VectorSpace> vsptr;
00416 
00417   if (factory.get() == NULL) {
00418     vsptr.reset(new fei::VectorSpace(comm, name));
00419   }
00420   else {
00421     vsptr = factory->createVectorSpace(comm, name);
00422   }
00423 
00424   fei::VectorSpace& vectorSpace = *vsptr;
00425 
00426   std::vector<int>& fieldIDs = testdata->fieldIDs;
00427   std::vector<int>& fieldSizes = testdata->fieldSizes;
00428   std::vector<int>& idTypes = testdata->idTypes;
00429   std::vector<int>& ids = testdata->ids;
00430   std::vector<int>& sharedIDs = testdata->sharedIDs;
00431   std::vector<int>& numSharingProcsPerID = testdata->numSharingProcsPerID;
00432   std::vector<int>& sharingProcs = testdata->sharingProcs;
00433 
00434   fei::ParameterSet paramset;
00435   fei::Param param1("name", name);
00436   paramset.add(param1);
00437   if (turnOnDebugOutput) {
00438     fei::Param param2("debugOutput", ".");
00439     paramset.add(param2);
00440   }
00441 
00442   vectorSpace.setParameters(paramset);
00443 
00444   int numFields = defineBothFields ? 2 : 1;
00445   vectorSpace.defineFields(numFields,
00446          &fieldIDs[0],
00447          &fieldSizes[0]);
00448 
00449   vectorSpace.defineIDTypes(idTypes.size(),
00450           &idTypes[0]);
00451 
00452   vectorSpace.addDOFs(fieldIDs[0], 1,
00453           idTypes[0],
00454           ids.size(),
00455           &ids[0]);
00456 
00457   if (initSolnBothFields) {
00458     vectorSpace.addDOFs(fieldIDs[1], 1,
00459             idTypes[0],
00460             ids.size(),
00461             &ids[0]);
00462   }
00463 
00464   vectorSpace.initSharedIDs(sharedIDs.size(),
00465     idTypes[0],
00466     sharedIDs.size() ? &sharedIDs[0] : 0,
00467     numSharingProcsPerID.size() ? &numSharingProcsPerID[0] : 0,
00468     sharingProcs.size() ? &sharingProcs[0] : 0
00469     );
00470 
00471   return(vsptr);
00472 }

Generated on Wed May 12 21:30:42 2010 for FEI by  doxygen 1.4.7