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