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