FEI Version of the Day
test_Utils.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_Utils.hpp>
00046 
00047 #include <fei_ArrayUtils.hpp>
00048 #include <fei_utils.hpp>
00049 #include <fei_CommUtils.hpp>
00050 #include <snl_fei_Utils.hpp>
00051 #include <fei_Param.hpp>
00052 #include <fei_ParameterSet.hpp>
00053 #include <fei_SharedPtr.hpp>
00054 #include <cmath>
00055 
00056 #undef fei_file
00057 #define fei_file "test_Utils.cpp"
00058 #include <fei_ErrMacros.hpp>
00059 
00060 test_Utils::test_Utils(MPI_Comm comm)
00061   : tester(comm)
00062 {
00063 }
00064 
00065 test_Utils::~test_Utils()
00066 {
00067 }
00068 
00069 void test_Utils_binarySearch()
00070 {
00071   std::vector<int> intarray;
00072   intarray.push_back(1);
00073   intarray.push_back(2);
00074   intarray.push_back(5);
00075   intarray.push_back(6);
00076   intarray.push_back(9);
00077 
00078   int offset = 0;
00079   int insertPoint = -1;
00080 
00081   FEI_COUT << "testing correctness of fei::binarySearch(int,int*,int,int)...";
00082 
00083   offset = fei::binarySearch(0, &intarray[0], intarray.size(),
00084          insertPoint);
00085   if (offset != -1 || insertPoint != 0) {
00086     throw std::runtime_error("fei::binarySearch test failed 1.");
00087   }
00088 
00089   offset = fei::binarySearch(2, &intarray[0], intarray.size(),
00090          insertPoint);
00091   if (offset != 1) {
00092     throw std::runtime_error("fei::binarySearch test failed 2.");
00093   }
00094 
00095   offset = fei::binarySearch(3, &intarray[0], intarray.size(),
00096          insertPoint);
00097   if (offset != -1 || insertPoint != 2) {
00098     throw std::runtime_error("fei::binarySearch test failed 3.");
00099   }
00100 
00101   offset = fei::binarySearch(4, &intarray[0], intarray.size(),
00102          insertPoint);
00103   if (offset != -1 || insertPoint != 2) {
00104     throw std::runtime_error("fei::binarySearch test failed 4.");
00105   }
00106 
00107   offset = fei::binarySearch(9, &intarray[0], intarray.size(),
00108          insertPoint);
00109   if (offset != 4) {
00110     throw std::runtime_error("fei::binarySearch test failed 5.");
00111   }
00112 
00113   offset = fei::binarySearch(8, &intarray[0], intarray.size(),
00114          insertPoint);
00115   if (offset != -1 || insertPoint != 4) {
00116     throw std::runtime_error("fei::binarySearch test failed 6.");
00117   }
00118 
00119   offset = fei::binarySearch(10, &intarray[0], intarray.size(),
00120          insertPoint);
00121   if (offset != -1 || insertPoint != 5) {
00122     throw std::runtime_error("fei::binarySearch test failed 7.");
00123   }
00124 
00125   FEI_COUT << "ok"<<FEI_ENDL;
00126 }
00127 
00128 int test_Utils::runtests()
00129 {
00130   if (numProcs_ < 2) {
00131     test_Utils_binarySearch();
00132 
00133     CHK_ERR( serialtest1() );
00134     CHK_ERR( serialtest2() );
00135     CHK_ERR( serialtest3() );
00136   }
00137 
00138   CHK_ERR( test1() );
00139   CHK_ERR( test2() );
00140   CHK_ERR( test3() );
00141   CHK_ERR( test4() );
00142   return(0);
00143 }
00144 
00145 int test_Utils::serialtest1()
00146 {
00147   FEI_COUT << "testing snl_fei::leading_substring_length...";
00148 
00149   static char string1[] = "test ";
00150   string1[4] = '\0';
00151   if (snl_fei::leading_substring_length(string1) != 4) {
00152     ERReturn(-1);
00153   }
00154 
00155   static char string2[] = "second test";
00156   if (snl_fei::leading_substring_length(string2) != 6) {
00157     ERReturn(-1);
00158   }
00159 
00160   static char string3[] = "third test";
00161   string3[5] = '\t';
00162   if (snl_fei::leading_substring_length(string3) != 5) {
00163     ERReturn(-1);
00164   }
00165 
00166   FEI_COUT << "ok"<<FEI_ENDL;
00167 
00168   return(0);
00169 }
00170 
00171 int test_Utils::serialtest2()
00172 {
00173   FEI_COUT << "testing snl_fei::getDoubleParamValue...";
00174 
00175   static char string1[] = "DOUBLE1 1.0";
00176   static char string2[] = "DOUBLE2 1.0e+0";
00177   static char string3[] = "DOUBLE3 1.0E+0";
00178   static char string4[] = "DOUBLE4 1";
00179 
00180   std::vector<char*> params;
00181   params.push_back(string1);
00182   params.push_back(string2);
00183   params.push_back(string3);
00184   params.push_back(string4);
00185 
00186   double d1,d2,d3,d4;
00187 
00188   CHK_ERR( snl_fei::getDoubleParamValue("DOUBLE1",
00189           params.size(), &params[0],d1));
00190   CHK_ERR( snl_fei::getDoubleParamValue("DOUBLE2",
00191           params.size(), &params[0],d2));
00192   CHK_ERR( snl_fei::getDoubleParamValue("DOUBLE3",
00193           params.size(), &params[0],d3));
00194   CHK_ERR( snl_fei::getDoubleParamValue("DOUBLE4",
00195           params.size(), &params[0],d4));
00196 
00197   if (std::abs(d1 - 1.0) > 1.e-49 || std::abs(d2 - 1.0) > 1.e-49 ||
00198       std::abs(d3 - 1.0) > 1.e-49 || std::abs(d4 - 1.0) > 1.e-49) {
00199     ERReturn(-1);
00200   }
00201 
00202   FEI_COUT <<"ok"<<FEI_ENDL;
00203 
00204   return(0);
00205 }
00206 
00207 int test_Utils::serialtest3()
00208 {
00209   FEI_COUT << "testing fei::Param and fei::ParameterSet...";
00210 
00211   fei::Param param1("string-param", "garbage value");
00212   fei::Param param2("double-param", 2.5);
00213   fei::Param param3("int-param", 1);
00214 
00215   if (param1.getType() != fei::Param::STRING) {
00216     ERReturn(-1);
00217   }
00218 
00219   if (param2.getType() != fei::Param::DOUBLE) {
00220     ERReturn(-1);
00221   }
00222 
00223   if (param3.getType() != fei::Param::INT) {
00224     ERReturn(-1);
00225   }
00226 
00227   fei::ParameterSet paramset;
00228   paramset.add(fei::Param("string-param", "garbage value"));
00229   paramset.add(param2);
00230   paramset.add(param3);
00231 
00232   if (paramset.size() != 3) {
00233     ERReturn(-1);
00234   }
00235 
00236   fei::ParameterSet::const_iterator
00237     iter = paramset.begin(),
00238     iter_end = paramset.end();
00239 
00240   int i=0;
00241   for(; iter != iter_end; ++iter) {
00242     if (i==3) {
00243       ERReturn(-1);
00244     }
00245     ++i;
00246   }
00247  
00248   if (paramset.get("int-param") == NULL) {
00249     ERReturn(-1);
00250   }
00251 
00252   int dummy;
00253   int err = paramset.getIntParamValue("int-param", dummy);
00254   if (err != 0) {
00255     ERReturn(-1);
00256   }
00257 
00258   if (dummy != 1) {
00259     ERReturn(-1);
00260   }
00261 
00262   std::string dummychars;
00263   err = paramset.getStringParamValue("string-param", dummychars);
00264   if (err != 0) {
00265     ERReturn(-1);
00266   }
00267 
00268   if ("garbage value" != dummychars) {
00269     ERReturn(-1);
00270   }
00271 
00272   //if (!snl_fei::leadingSubstring("garbage-value", "garbage")) {
00273   //  ERReturn(-1);
00274   //}
00275 
00276   //if (snl_fei::leadingSubstring("garb-value", "garbage")) {
00277   //  ERReturn(-1);
00278   //}
00279 
00280   std::vector<std::string> stdstrings;
00281   std::string tempstr;
00282 
00283   tempstr = "string-param garbage value";
00284   stdstrings.push_back(tempstr);
00285 
00286   tempstr = "int-param 58";
00287   stdstrings.push_back(tempstr);
00288 
00289   tempstr = "real-param 45.e-2";
00290   stdstrings.push_back(tempstr);
00291 
00292   fei::ParameterSet pset;
00293   fei::utils::parse_strings(stdstrings, " ", pset);
00294 
00295   err = pset.getStringParamValue("string-param", dummychars);
00296   if ("value" != dummychars) {
00297     ERReturn(-1);
00298   }
00299 
00300   err = pset.getIntParamValue("int-param", dummy);
00301   if (dummy != 58) {
00302     ERReturn(-1);
00303   }
00304 
00305   double ddummy;
00306   err = pset.getDoubleParamValue("real-param", ddummy);
00307   if (std::abs(ddummy - 45.e-2) > 1.e-49) {
00308     ERReturn(-1);
00309   }
00310 
00311   FEI_COUT << "ok"<<FEI_ENDL;
00312 
00313   return(0);
00314 }
00315 
00316 void test_Utils_function_that_throws()
00317 {
00318   throw std::runtime_error("testing...");
00319 }
00320 
00321 int test_Utils::test1()
00322 {
00323   FEI_COUT << "testing std::runtime_error...";
00324 
00325   bool exc_thrown_and_caught = false;
00326 
00327   try {
00328     test_Utils_function_that_throws();
00329   }
00330   catch(std::runtime_error& exc) {
00331     std::string str(exc.what());
00332     if (str == "testing...") {
00333       exc_thrown_and_caught = true;
00334     }
00335   }
00336 
00337   if (!exc_thrown_and_caught) {
00338     ERReturn(-1);
00339   }
00340 
00341   FEI_COUT << "ok"<<FEI_ENDL;
00342   return(0);
00343 }
00344 
00345 bool test_Utils_dummy_destroyed = true;
00346 
00347 class test_Utils_dummy {
00348 public:
00349   test_Utils_dummy() {test_Utils_dummy_destroyed = false;}
00350   ~test_Utils_dummy()
00351   {
00352     test_Utils_dummy_destroyed = true;
00353   }
00354 };
00355 
00356 int test_Utils_test_SharedPtr()
00357 {
00358   //In this function, make sure the global bool is set to true, then create
00359   //the fei::SharedPtr and make sure that the global bool has been set to false.
00360   //If so, return 0, otherwise return -1.
00361   //When we return, the SharedPtr goes out of scope which should destroy the
00362   //test-dummy and cause the global bool to get set back to true. The code 
00363   //that's calling this function will verify that.
00364 
00365   test_Utils_dummy_destroyed = true;
00366   fei::SharedPtr<test_Utils_dummy> ptr(new test_Utils_dummy);
00367   if (test_Utils_dummy_destroyed == true) return(-1);
00368   else return(0);
00369 }
00370 
00371 int test_Utils::test2()
00372 {
00373   FEI_COUT << "testing fei::SharedPtr...";
00374   int err = test_Utils_test_SharedPtr();
00375   if (err != 0) {
00376     ERReturn(-1);
00377   }
00378 
00379   if (test_Utils_dummy_destroyed != true) {
00380     ERReturn(-1);
00381   }
00382 
00383   FEI_COUT << "ok"<<FEI_ENDL;
00384  return(0);
00385 }
00386 
00387 int test_Utils::test3()
00388 {
00389   FEI_COUT << "testing snl_fei::copy2DToColumnContig...";
00390 
00391   int numrows1 = 3;
00392   int numcols1 = 4;
00393   int numrows2 = 4;
00394   int numcols2 = 3;
00395 
00396   int i, j;
00397   int len1 = numrows1*numcols1;
00398   int len2 = numrows2*numcols2;
00399 
00400   double** table2d_1 = new double*[numrows1];
00401   for(i=0; i<numrows1; ++i) {
00402     table2d_1[i] = new double[numcols1];
00403     for(j=0; j<numcols1; ++j) {
00404       table2d_1[i][j] = j*numrows1+i;
00405     }
00406   }
00407 
00408   double** table2d_2 = new double*[numcols2];
00409   for(j=0; j<numcols2; ++j) {
00410     table2d_2[j] = new double[numrows2];
00411     for(i=0; i<numrows2; ++i) {
00412       table2d_2[j][i] = j*numrows2+i;
00413     }
00414   }
00415 
00416   double* cc1 = new double[len1];
00417   double* cc2 = new double[len2];
00418 
00419   snl_fei::copy2DToColumnContig(numrows1, numcols1, table2d_1,
00420         FEI_DENSE_ROW, cc1);
00421 
00422   snl_fei::copy2DToColumnContig(numrows2, numcols2, table2d_2,
00423         FEI_DENSE_COL, cc2);
00424 
00425   for(i=0; i<len1; ++i) {
00426     if (std::abs(cc1[i] - cc2[i]) > 1.e-49) {
00427       throw std::runtime_error("column-contig arrays not equal.");
00428     }
00429   }
00430 
00431   for(j=0; j<numrows1; ++j) delete [] table2d_1[j];
00432   delete [] table2d_1;
00433   delete [] cc1;
00434   delete [] cc2;
00435 
00436   FEI_COUT << "ok"<<FEI_ENDL;
00437 
00438   FEI_COUT << "testing snl_fei::copy2DBlockDiagToColumnContig...";
00439 
00440   numrows1 = 12;
00441   int numBlocks = 3;
00442   int* blockSizes = new int[numBlocks];
00443   for(i=0; i<numBlocks; ++i) {
00444     blockSizes[i] = 4;
00445   }
00446 
00447   table2d_1 = new double*[numrows1];
00448   for(i=0; i<numrows1; ++i) {
00449     table2d_1[i] = new double[4];
00450     for(j=0; j<4; ++j) {
00451       table2d_1[i][j] = 1.0*i*4+j;
00452     }
00453   }
00454 
00455   len1 = numrows1*4;
00456   cc1 = new double[len1];
00457 
00458   snl_fei::copy2DBlockDiagToColumnContig(numBlocks, blockSizes, table2d_1,
00459            FEI_BLOCK_DIAGONAL_ROW, cc1);
00460 
00461   for(i=0; i<len1; ++i) {
00462     if (std::abs(1.0*i - cc1[i]) > 1.e-49) {
00463       throw std::runtime_error("copy2DBlockDiagToColumnContig row test failed.");
00464     }
00465   }
00466 
00467   for(j=0; j<numrows1; ++j) delete [] table2d_1[j];
00468   delete [] table2d_1;
00469   for(j=0; j<numcols2; ++j) delete [] table2d_2[j];
00470   delete [] table2d_2;
00471 
00472   delete [] cc1;
00473   delete [] blockSizes;
00474 
00475   FEI_COUT << "ok"<<FEI_ENDL;
00476   return(0);
00477 }
00478 
00479 int test_Utils::test4()
00480 {
00481   return(0);
00482 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends