FEI Version of the Day
test_FEI_Impl.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 #include <fei_sstream.hpp>
00045 
00046 #include <test_utils/test_FEI_Impl.hpp>
00047 
00048 #include <fei_FEI_Impl.hpp>
00049 #ifdef HAVE_FEI_AZTECOO
00050 #include <fei_Aztec_LinSysCore.hpp>
00051 #endif
00052 #include <test_utils/FEData.hpp>
00053 #include <fei_LibraryWrapper.hpp>
00054 
00055 #include <test_utils/testData.hpp>
00056 
00057 #undef fei_file
00058 #define fei_file "test_FEI_Impl.cpp"
00059 #include <fei_ErrMacros.hpp>
00060 
00061 test_FEI_Impl::test_FEI_Impl(MPI_Comm comm)
00062  : tester(comm)
00063 {
00064 }
00065 
00066 test_FEI_Impl::~test_FEI_Impl()
00067 {
00068 }
00069 
00070 int test_FEI_Impl::runtests()
00071 {
00072   if (numProcs_<2) {
00073     CHK_ERR( serialtest1() );
00074   }
00075 
00076   CHK_ERR( test1() );
00077   CHK_ERR( test2() );
00078   CHK_ERR( test3() );
00079   CHK_ERR( test4() );
00080   return(0);
00081 }
00082 
00083 int test_FEI_Impl::serialtest1()
00084 {
00085   return(0);
00086 }
00087 
00088 int test_FEI_Impl::compareCoefs(int n,
00089            const double*const* coefs1,
00090            const double*const* coefs2)
00091 {
00092   for(int i=0; i<n; ++i) {
00093     for(int j=0; j<n; ++j) {
00094       double diff = coefs1[i][j] - coefs2[i][j];
00095       if (diff > 1.e-20 || diff < -1.e-20) {
00096   return(-1);
00097       }
00098     }
00099   }
00100 
00101   return(0);
00102 }
00103 
00104 int test_FEI_Impl::test1()
00105 {
00106   if (numProcs_ > 1) {
00107     return(0);
00108   }
00109 #ifdef HAVE_FEI_AZTECOO
00110   testData* testdata = new testData(localProc_, numProcs_);
00111 
00112   fei::SharedPtr<LinearSystemCore> linSys(new fei_trilinos::Aztec_LinSysCore(comm_));
00113   fei::SharedPtr<LibraryWrapper> wrapper(new LibraryWrapper(linSys));
00114   fei::SharedPtr<fei::FEI_Impl> fei(new fei::FEI_Impl(wrapper, comm_, 0));
00115 
00116   std::string param0("name test1");
00117   FEI_OSTRINGSTREAM osstr;
00118   osstr << "debugOutput ";
00119   if (path_.empty()) osstr << ".";
00120   else osstr << path_;
00121 
00122   std::string param1 = osstr.str();
00123 
00124   int numParams = 2;
00125   char** params = new char*[numParams];
00126   params[0] = const_cast<char*>(param0.c_str());
00127   params[1] = const_cast<char*>(param1.c_str());
00128 
00129   //call the parameters function a couple of times to test the fei's internal
00130   //method for merging string lists when parameters is called more than once.
00131   CHK_ERR( fei->parameters(1, &params[0]) );
00132   CHK_ERR( fei->parameters(1, &params[1]) );
00133   CHK_ERR( fei->parameters(2, params) );
00134 
00135   delete [] params;
00136 
00137   CHK_ERR( fei->setIDLists(1, &(testdata->ids[0]),
00138          1, &(testdata->ids[0])) );
00139 
00140   CHK_ERR( fei->initFields(testdata->fieldIDs.size(),
00141         &(testdata->fieldSizes[0]),
00142         &(testdata->fieldIDs[0])) );
00143 
00144   int numNodesPerElem = testdata->ids.size();
00145   std::vector<int> numFieldsPerNode(numNodesPerElem, 1);
00146   std::vector<int*>nodalFieldIDs(numNodesPerElem, &(testdata->fieldIDs[0]));
00147 
00148   CHK_ERR( fei->initElemBlock(0, //blockID
00149            1, //numElements
00150            numNodesPerElem,
00151            &numFieldsPerNode[0],
00152            &nodalFieldIDs[0],
00153            0, //numElemDofFieldsPerElement
00154            NULL, //elemDofFieldIDs
00155            0)); //interleaveStrategy
00156 
00157   CHK_ERR( fei->initElem(0, //blockID
00158             0, //elemID
00159             &(testdata->ids[0])) );
00160 
00161   std::vector<int*> sharingProcs2D(testdata->sharedIDs.size());
00162   int offset = 0;
00163   for(int i=0; i<(int)testdata->numSharingProcsPerID.size(); ++i) {
00164     sharingProcs2D[i] = &(testdata->sharingProcs[offset]);
00165     offset += testdata->numSharingProcsPerID[i];
00166   }
00167 
00168   if (testdata->sharedIDs.size() > 0) {
00169     CHK_ERR( fei->initSharedNodes(testdata->sharedIDs.size(),
00170              &(testdata->sharedIDs[0]),
00171              &(testdata->numSharingProcsPerID[0]),
00172              &sharingProcs2D[0]) );
00173   }
00174 
00175   CHK_ERR( fei->initComplete() );
00176 
00177   std::vector<double> rhsData(testdata->ids.size(), 1.0);
00178 
00179   double one = 1.0;
00180   CHK_ERR( fei->setMatScalars(1, &(testdata->ids[0]), &one) );
00181   CHK_ERR( fei->setRHSScalars(1, &(testdata->ids[0]), &one) );
00182 
00183   CHK_ERR( fei->setCurrentMatrix(testdata->ids[0]) );
00184   CHK_ERR( fei->setCurrentRHS(testdata->ids[0]) );
00185 
00186   CHK_ERR( fei->putIntoRHS(FEI_NODE, testdata->fieldIDs[0],
00187          testdata->ids.size(),
00188          &(testdata->ids[0]),
00189          &rhsData[0]) );
00190 
00191   int numBCNodes = 2;
00192   GlobalID* BCNodeIDs = &(testdata->ids[0]);
00193   int BCFieldID = testdata->fieldIDs[0];
00194   double* values = new double[numBCNodes];
00195   int* offsetsIntoField = new int[numBCNodes];
00196   for(int ii=0; ii<numBCNodes; ++ii) {
00197     values[ii] = 1.0;
00198     offsetsIntoField[ii] = 0;
00199   }
00200 
00201   CHK_ERR( fei->loadNodeBCs(numBCNodes, BCNodeIDs, BCFieldID,
00202           offsetsIntoField, values) );
00203 
00204   delete [] offsetsIntoField;
00205   delete [] values;
00206 
00207   CHK_ERR( fei->loadComplete() );
00208 
00209   int numActiveNodes = 0;
00210   CHK_ERR( fei->getNumLocalNodes(numActiveNodes) );
00211   if (numActiveNodes != (int)testdata->ids.size()) {
00212     ERReturn(-1);
00213   }
00214 
00215   GlobalID* localNodes = new GlobalID[numActiveNodes];
00216   CHK_ERR( fei->getLocalNodeIDList(numActiveNodes, localNodes, numActiveNodes) );
00217 
00218   int totalFieldSize = 0;
00219   for(int ii=0; ii<(int)testdata->fieldSizes.size(); ++ii) {
00220     totalFieldSize += testdata->fieldSizes[ii];
00221   }
00222 
00223   double* soln = new double[numActiveNodes*totalFieldSize];
00224   int* offsets = new int[numActiveNodes+1];
00225 
00226   CHK_ERR( fei->getNodalSolution(numActiveNodes, localNodes,
00227          offsets, soln) );
00228   delete [] offsets;
00229   delete [] soln;
00230   delete [] localNodes;
00231 
00232   CHK_ERR( fei->resetInitialGuess() );
00233 
00234   int fieldSize = 0;
00235   CHK_ERR( fei->getFieldSize(testdata->fieldIDs[0], fieldSize) );
00236 
00237   double initTime, loadTime, solveTime, solnReturnTime;
00238   CHK_ERR( fei->cumulative_cpu_times(initTime, loadTime, solveTime,
00239               solnReturnTime) );
00240 
00241   delete testdata;
00242 #endif
00243   return(0);
00244 }
00245 
00246 int test_FEI_Impl::test2()
00247 {
00248   fei::SharedPtr<testData> testdata(new testData(localProc_, numProcs_));
00249   fei::SharedPtr<FiniteElementData> fedata(new FEData(comm_));
00250   fei::SharedPtr<LibraryWrapper> wrapper(new LibraryWrapper(fedata));
00251   fei::SharedPtr<fei::FEI_Impl> fei(new fei::FEI_Impl(wrapper, comm_, 0));
00252 
00253   std::string param0("name test1");
00254   FEI_OSTRINGSTREAM osstr;
00255   osstr << "debugOutput ";
00256   if (path_.empty()) osstr << ".";
00257   else osstr << path_;
00258 
00259   std::string param1 = osstr.str();
00260 
00261   int numParams = 2;
00262   char** params = new char*[numParams];
00263   params[0] = const_cast<char*>(param0.c_str());
00264   params[1] = const_cast<char*>(param1.c_str());
00265 
00266   //call the parameters function a couple of times to test the fei's internal
00267   //method for merging string lists when parameters is called more than once.
00268   CHK_ERR( fei->parameters(1, &params[0]) );
00269   CHK_ERR( fei->parameters(1, &params[1]) );
00270   CHK_ERR( fei->parameters(2, params) );
00271 
00272   delete [] params;
00273 
00274   CHK_ERR( fei->setIDLists(1, &(testdata->ids[0]),
00275          1, &(testdata->ids[0])) );
00276   CHK_ERR( fei->initFields(testdata->fieldIDs.size(),
00277         &(testdata->fieldSizes[0]),
00278         &(testdata->fieldIDs[0])) );
00279 
00280   int numNodesPerElem = testdata->ids.size();
00281   std::vector<int> numFieldsPerNode(numNodesPerElem, 1);
00282   std::vector<int*>nodalFieldIDs(numNodesPerElem, &(testdata->fieldIDs[0]));
00283 
00284   CHK_ERR( fei->initElemBlock(0, //blockID
00285            1, //numElements
00286            numNodesPerElem,
00287            &numFieldsPerNode[0],
00288            &nodalFieldIDs[0],
00289            0, //numElemDofFieldsPerElement
00290            NULL, //elemDofFieldIDs
00291            0)); //interleaveStrategy
00292 
00293   CHK_ERR( fei->initElem(0, //blockID
00294             0, //elemID
00295             &(testdata->ids[0])) );
00296 
00297   std::vector<int*> sharingProcs2D(testdata->sharedIDs.size());
00298   int i, offset = 0;
00299   for(i=0; i<(int)testdata->numSharingProcsPerID.size(); ++i) {
00300     sharingProcs2D[i] = &(testdata->sharingProcs[offset]);
00301     offset += testdata->numSharingProcsPerID[i];
00302   }
00303 
00304   if (testdata->sharedIDs.size() > 0) {
00305     CHK_ERR( fei->initSharedNodes(testdata->sharedIDs.size(),
00306              &(testdata->sharedIDs[0]),
00307              &(testdata->numSharingProcsPerID[0]),
00308              &sharingProcs2D[0]) );
00309   }
00310 
00311   CHK_ERR( fei->initComplete() );
00312 
00313   std::vector<double> rhsData(testdata->ids.size(), 1.0);
00314 
00315   double one = 1.0;
00316   CHK_ERR( fei->setMatScalars(1, &(testdata->ids[0]), &one) );
00317   CHK_ERR( fei->setRHSScalars(1, &(testdata->ids[0]), &one) );
00318 
00319   CHK_ERR( fei->setCurrentMatrix(testdata->ids[0]) );
00320   CHK_ERR( fei->setCurrentRHS(testdata->ids[0]) );
00321 
00322   int ii;
00323 
00324   int numBCNodes = 2;
00325   GlobalID* BCNodeIDs = &(testdata->ids[0]);
00326   int BCFieldID = testdata->fieldIDs[0];
00327   double* values = new double[numBCNodes];
00328   int* offsetsIntoField = new int[numBCNodes];
00329   for(ii=0; ii<numBCNodes; ++ii) {
00330     values[ii] = 1.0;
00331     offsetsIntoField[ii] = 0;
00332   }
00333 
00334   CHK_ERR( fei->loadNodeBCs(numBCNodes, BCNodeIDs, BCFieldID,
00335           offsetsIntoField, values) );
00336 
00337   delete [] values;
00338   delete [] offsetsIntoField;
00339 
00340   CHK_ERR( fei->loadComplete() );
00341 
00342   int numActiveNodes = 0;
00343   CHK_ERR( fei->getNumLocalNodes(numActiveNodes) );
00344   if (numActiveNodes != (int)testdata->ids.size()) {
00345     ERReturn(-1);
00346   }
00347 
00348   GlobalID* localNodes = new GlobalID[numActiveNodes];
00349   CHK_ERR( fei->getLocalNodeIDList(numActiveNodes, localNodes, numActiveNodes) );
00350 
00351   int totalFieldSize = 0;
00352   for(ii=0; ii<(int)testdata->fieldSizes.size(); ++ii) {
00353     totalFieldSize += testdata->fieldSizes[ii];
00354   }
00355 
00356   double* soln = new double[numActiveNodes*totalFieldSize];
00357   int* offsets = new int[numActiveNodes+1];
00358 
00359   CHK_ERR( fei->getNodalSolution(numActiveNodes, localNodes,
00360          offsets, soln) );
00361   delete [] offsets;
00362   delete [] soln;
00363   delete [] localNodes;
00364 
00365   CHK_ERR( fei->resetInitialGuess() );
00366 
00367   int fieldSize = 0;
00368   CHK_ERR( fei->getFieldSize(testdata->fieldIDs[0], fieldSize) );
00369 
00370   double initTime, loadTime, solveTime, solnReturnTime;
00371   CHK_ERR( fei->cumulative_cpu_times(initTime, loadTime, solveTime,
00372               solnReturnTime) );
00373 
00374   return(0);
00375 }
00376 
00377 int test_FEI_Impl::test3()
00378 {
00379   return(0);
00380 }
00381 
00382 int test_FEI_Impl::test4()
00383 {
00384   return(0);
00385 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends