FEI Version of the Day
beam_oldfei_main.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 
00044 //
00045 // This is a simple program to exercise the new FEI (version 3?) classes,
00046 // for the purposes of testing, code tuning and scaling studies.
00047 //
00048 
00049 #include <fei_macros.hpp> //simply includes std stuff like iostream, etc.
00050                              //users could include that stuff themselves rather
00051                              //than using this header.
00052 
00053 //Including the header fei_base.hpp gets us the declaration for
00054 //various fei classes and interfaces.
00055 
00056 #include <fei_base.hpp>
00057 #include <FEI_Implementation.hpp>
00058 
00059 //Now make provision for using any one of several solver libraries. This is
00060 //handled by the code in LibraryFactory.[hC].
00061 
00062 #include <test_utils/LibraryFactory.hpp>
00063 
00064 //And finally, we need to include some 'utils' headers which are used for
00065 //setting up the data for the example problem.
00066 
00067 #include <test_utils/HexBeam.hpp>
00068 #include <test_utils/HexBeamCR.hpp>
00069 
00070 #include <test_utils/fei_test_utils.hpp>
00071 #include <snl_fei_Utils.hpp>
00072 
00073 #undef fei_file
00074 #define fei_file "cube_main.cpp"
00075 #include <fei_ErrMacros.hpp>
00076 
00077 //==============================================================================
00078 //Here's the main...
00079 //==============================================================================
00080 int beam_oldfei_main(int argc, char** argv,
00081         MPI_Comm comm, int numProcs, int localProc){
00082 
00083   std::vector<std::string> stdstrings;
00084   CHK_ERR( fei_test_utils::get_filename_and_read_input(argc, argv,
00085             comm, localProc,
00086             stdstrings) );
00087 
00088   const char** params = NULL;
00089   int numParams = 0;
00090   fei::utils::strings_to_char_ptrs(stdstrings, numParams, params);
00091   
00092   fei::ParameterSet paramset;
00093   fei::utils::parse_strings(stdstrings, " ", paramset);
00094 
00095   std::string whichFEI;
00096   std::string solverName;
00097   std::string datasource;
00098   int W = 0;
00099   int D = 0;
00100   int DofPerNode = 0;
00101 
00102   int errcode = 0;
00103   errcode += paramset.getStringParamValue("SOLVER_LIBRARY", solverName);
00104   errcode += paramset.getStringParamValue("DATA_SOURCE", datasource);
00105   errcode += paramset.getStringParamValue("WHICH_FEI", whichFEI);
00106   errcode += paramset.getIntParamValue("W", W);
00107   errcode += paramset.getIntParamValue("D", D);
00108   errcode += paramset.getIntParamValue("DofPerNode", DofPerNode);
00109 
00110   if (errcode != 0) {
00111     fei::console_out() << "Failed to find one or more required parameters in input-file."
00112        << FEI_ENDL << "Required parameters:"<<FEI_ENDL
00113        << "SOLVER_LIBRARY" << FEI_ENDL
00114        << "DATA_SOURCE" << FEI_ENDL
00115        << "CONSTRAINT_FORM" << FEI_ENDL
00116        << "W" << FEI_ENDL << "D" << FEI_ENDL << "DofPerNode" << FEI_ENDL;
00117     return(-1);
00118   }
00119 
00120   HexBeam* hexcubeptr = NULL;
00121   if (datasource == "HexBeam") {
00122     hexcubeptr = new HexBeam(W, D, DofPerNode,
00123            HexBeam::OneD, numProcs, localProc);
00124   }
00125   else {
00126     hexcubeptr = new HexBeamCR(W, D, DofPerNode,
00127              HexBeam::OneD, numProcs, localProc);
00128   }
00129 
00130   HexBeam& hexcube = *hexcubeptr;
00131 
00132   if (localProc == 0) {
00133     int numCRs = (W+1)*(W+1)*(numProcs*2)-1;
00134     if (hexcube.getNumCRs() < 1) numCRs = 0;
00135     FEI_COUT << FEI_ENDL;
00136     FEI_COUT << "========================================================" 
00137    << FEI_ENDL;
00138     FEI_COUT << "Size W: " << W << " (num-elements-along-side-of-cube)"<<FEI_ENDL;
00139     FEI_COUT << "Size D: " << D << " (num-elements-along-depth-of-cube)"<<FEI_ENDL;
00140     FEI_COUT << "DOF per node: " << DofPerNode <<FEI_ENDL;
00141     FEI_COUT << "Num local  elements: " << hexcube.localNumElems_ << FEI_ENDL;
00142     FEI_COUT << "Num global elements: " << hexcube.totalNumElems_ << FEI_ENDL;
00143     FEI_COUT << "Num local  DOF: " << hexcube.numLocalDOF_ << FEI_ENDL;
00144     FEI_COUT << "Num global DOF: " << hexcube.numGlobalDOF_ << FEI_ENDL;
00145     FEI_COUT << "Num global CRs: " << numCRs << FEI_ENDL;
00146     FEI_COUT << "========================================================" 
00147    << FEI_ENDL;
00148   }
00149 
00150   double start_init_time = fei::utils::cpu_time();
00151 
00152   //CHK_ERR( print_cube_data(hexcube, numProcs, localProc) );
00153 
00154   fei::SharedPtr<fei::Factory> factory;
00155   fei::SharedPtr<LibraryWrapper> wrapper;
00156   fei::SharedPtr<FEI> fei;
00157 
00158   if (whichFEI == "OLDFEI") {
00159     try {
00160       wrapper = fei::create_LibraryWrapper(comm, solverName.c_str());
00161     }
00162     catch (std::runtime_error& exc) {
00163       fei::console_out() << exc.what() << FEI_ENDL;
00164       ERReturn(-1);
00165     }
00166     fei.reset(new FEI_Implementation(wrapper, comm));
00167   }
00168   else if (whichFEI == "fei::FEI_Impl") {
00169     try {
00170       factory = fei::create_fei_Factory(comm, solverName.c_str());
00171     }
00172     catch (std::runtime_error& exc) {
00173       fei::console_out() << exc.what() << FEI_ENDL;
00174       ERReturn(-1);
00175     }
00176     fei = factory->createFEI(comm);
00177   }
00178   else {
00179     fei::console_out() << "cube ERROR, value of 'WHICH_FEI' must be 'OLDFEI' or 'fei::FEI_Impl'"<< FEI_ENDL;
00180     ERReturn(-1);
00181   }
00182 
00183   //load some control parameters.
00184   CHK_ERR( fei->parameters(numParams, params) );
00185 
00186   delete [] params;
00187 
00188   CHK_ERR( fei->setSolveType(FEI_SINGLE_SYSTEM) );
00189 
00190   int fieldID = 0;
00191   int fieldSize = hexcube.numDofPerNode();
00192 
00193   CHK_ERR( fei->initFields( 1, &fieldSize, &fieldID ) );
00194 
00195   CHK_ERR( HexBeam_Functions::init_elem_connectivities( fei.get(), hexcube ) );
00196 
00197   CHK_ERR( HexBeam_Functions::init_shared_nodes( fei.get(), hexcube ) );
00198 
00199   int firstLocalCRID;
00200   CHK_ERR( HexBeam_Functions::
00201      init_constraints( fei.get(), hexcube, firstLocalCRID) );
00202 
00203   CHK_ERR( fei->initComplete() );
00204 
00205   double fei_init_time = fei::utils::cpu_time() - start_init_time;
00206 
00207   if (localProc == 0) {
00208     FEI_COUT.setf(IOS_FIXED, IOS_FLOATFIELD);
00209     FEI_COUT << "Initialization time:   " << fei_init_time << FEI_ENDL;
00210   }
00211 
00212   //Now the initialization phase is complete. Next we'll do the load phase,
00213   //which for this problem just consists of loading the element data
00214   //(element-wise stiffness arrays and load vectors) and the boundary
00215   //condition data.
00216 
00217   double start_load_time = fei::utils::cpu_time();
00218 
00219   CHK_ERR( HexBeam_Functions::load_elem_data(fei.get(), hexcube) );
00220 
00221   CHK_ERR( HexBeam_Functions::load_constraints(fei.get(), hexcube, firstLocalCRID) );
00222 
00223   //FEI_COUT << "calling load_BC_data"<<FEI_ENDL;
00224   //CHK_ERR( load_BC_data(fei, hexcube) );
00225 
00226   fei->loadComplete();
00227 
00228   double fei_load_time = fei::utils::cpu_time() - start_load_time;
00229 
00230   delete hexcubeptr;
00231 
00232   if (localProc == 0) {
00233     //IOS macros are defined in fei_macros.h
00234     FEI_COUT.setf(IOS_FIXED, IOS_FLOATFIELD);
00235     FEI_COUT << "Coef. loading  time:    " << fei_load_time << FEI_ENDL;
00236     FEI_COUT << "Total assembly time:    " << fei_init_time + fei_load_time << FEI_ENDL;
00237   }
00238 
00239   //
00240   //now the load phase is complete, so we're ready to launch the underlying
00241   //solver and solve Ax=b
00242   //
00243 
00244   int err;
00245   int status;
00246   double start_solve_time = fei::utils::cpu_time();
00247 
00248   err = fei->solve(status);
00249 
00250   if (err || status) {
00251     if (localProc==0) FEI_COUT << "solve returned status: " << status << FEI_ENDL;
00252   }
00253 
00254   double solve_time = fei::utils::cpu_time() - start_solve_time;
00255 
00256   if (localProc == 0) {
00257     FEI_COUT << "Solver time:          " << solve_time << FEI_ENDL;
00258   }
00259 
00260   int returnValue = 0;
00261   if (localProc == 0) {
00262 #if defined(FEI_PLATFORM) && defined(FEI_OPT_LEVEL)
00263     double benchmark = fei_init_time;
00264 
00265     FEI_OSTRINGSTREAM testname_init;
00266     testname_init << "cube_"<<whichFEI<<"_init_"<<W<<"_"<<D<<"_"<<DofPerNode<<"_"
00267       <<solverName<<"_np"<<numProcs<<"_"
00268       <<FEI_PLATFORM<<"_"<<FEI_OPT_LEVEL;
00269 
00270     FEI_OSTRINGSTREAM testname_load;
00271     testname_load << "cube_"<<whichFEI<<"_load_"<<W<<"_"<<D<<"_"<<DofPerNode<<"_"
00272       <<solverName<<"_np"<<numProcs<<"_"
00273       <<FEI_PLATFORM<<"_"<<FEI_OPT_LEVEL;
00274 
00275     double file_init, file_load;
00276     bool file_benchmarks_available = true;
00277     try {
00278       file_init = fei_test_utils::get_file_benchmark("./cube_timings.txt",
00279                 testname_init.str().c_str());
00280       file_load = fei_test_utils::get_file_benchmark("./cube_timings.txt",
00281                 testname_load.str().c_str());
00282     }
00283     catch (std::runtime_error& exc) {
00284       file_benchmarks_available = false;
00285     }
00286 
00287     if (file_benchmarks_available) {
00288 
00289       bool init_test_passed =
00290   fei_test_utils::check_and_cout_test_result(testname_init.str(), benchmark,
00291               file_init, 10);
00292 
00293       benchmark = fei_load_time;
00294       bool load_test_passed =
00295   fei_test_utils::check_and_cout_test_result(testname_load.str(), benchmark,
00296               file_load, 10);
00297 
00298       returnValue = init_test_passed&&load_test_passed ? 0 : 1;
00299     }
00300 #endif
00301   }
00302 
00303   bool testPassed = returnValue==0;
00304   if (testPassed && localProc == 0) {
00305     //A string for the SIERRA runtest tool to search for in test output...
00306     FEI_COUT << "cube execution successful" << FEI_ENDL;
00307   }
00308 
00309   fei.reset();
00310 
00311   return(0);
00312 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends