FEI Version of the Day
fei_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_fstream.hpp"
00044 
00045 #include "fei_utils.hpp"
00046 #include "snl_fei_Utils.hpp"
00047 #include "fei_MatrixReducer.hpp"
00048 #include "fei_Matrix_Impl.hpp"
00049 #include "fei_LinearSystemCore.hpp"
00050 #include "fei_ParameterSet.hpp"
00051 
00052 #include "fei_version.h"
00053 
00054 #ifdef FEI_HAVE_TIME_H
00055 #include <time.h>
00056 #endif
00057 
00058 //----------------------------------------------------------------------------
00059 const char* fei_VERSION::version()
00060 {
00061   static int times_called = 0;
00062 
00063   static std::string static_fei_version_string;
00064 
00065   if (times_called == 0) {
00066     FEI_OSTRINGSTREAM osstr;
00067 
00068     osstr << FEI_MAJOR_VERSION << "."
00069           << FEI_MINOR_VERSION << "."
00070           << FEI_PATCH_VERSION;
00071 
00072     static_fei_version_string = osstr.str();
00073 
00074     times_called = 1;
00075   }
00076 
00077   return( static_fei_version_string.c_str() );
00078 }
00079 
00080 //----------------------------------------------------------------------------
00081 double fei::utils::cpu_time()
00082 {
00083   double cpu_seconds = 0.0;
00084 
00085 #ifdef FEI_HAVE_TIME_H
00086   cpu_seconds = (1.0*clock())/CLOCKS_PER_SEC;
00087 #endif
00088 
00089   return(cpu_seconds);
00090 }
00091 
00092 //----------------------------------------------------------------------------
00093 fei::OutputLevel fei::utils::string_to_output_level(const std::string& str)
00094 {
00095   if (str == "STATS" || str == "fei::STATS") {
00096     return fei::STATS;
00097   }
00098   else if (str == "BRIEF_LOGS" || str == "fei::BRIEF_LOGS") {
00099     return fei::BRIEF_LOGS;
00100   }
00101   else if (str == "MATRIX_FILES" || str == "fei::MATRIX_FILES") {
00102     return fei::MATRIX_FILES;
00103   }
00104   else if (str == "FULL_LOGS" || str == "fei::FULL_LOGS") {
00105     return fei::FULL_LOGS;
00106   }
00107   else if (str == "ALL" || str == "fei::ALL") {
00108     return fei::ALL;
00109   }
00110 
00111   return fei::NONE;
00112 }
00113 
00114 //----------------------------------------------------------------------------
00115 LinearSystemCore*
00116 fei::utils::get_LinearSystemCore(fei::Matrix* matrix)
00117 {
00118   fei::Matrix* matptr = matrix;
00119   fei::MatrixReducer* matred = dynamic_cast<fei::MatrixReducer*>(matptr);
00120   if (matred != NULL) matptr = matred->getTargetMatrix().get();
00121 
00122   fei::Matrix_Impl<LinearSystemCore>* mat_lsc =
00123     dynamic_cast<fei::Matrix_Impl<LinearSystemCore>*>(matptr);
00124 
00125   if (mat_lsc != NULL) {
00126     return mat_lsc->getMatrix().get();
00127   }
00128 
00129   return(NULL);
00130 }
00131 
00132 //----------------------------------------------------------------------------
00133 void fei::utils::getConnectivityArrays(fei::MatrixGraph& matrixGraph,
00134                                        std::vector<int>& nodes,
00135                                        std::vector<int>& elem_offsets)
00136 {
00137   //first, iterate over the connectivity-blocks and count how many nodes
00138   //and elements there are.
00139   int num_elems = 0;
00140   int num_nodes = 0;
00141 
00142   std::map<int,fei::ConnectivityBlock*>& cBlocks =
00143     matrixGraph.getConnectivityBlocks();
00144   std::map<int,fei::ConnectivityBlock*>::iterator
00145     iter = cBlocks.begin(),
00146     iter_end = cBlocks.end();
00147 
00148   for(; iter != iter_end; ++iter) {
00149     fei::ConnectivityBlock* cblk = iter->second;
00150 
00151     //if not symmetric, then assume it's not an element-block.
00152     if (!cblk->isSymmetric()) continue;
00153 
00154     num_elems += cblk->getConnectivityIDs().size();
00155 
00156     fei::Pattern* pattern = cblk->getRowPattern();
00157     num_nodes += num_elems*pattern->getNumIDs();
00158   }
00159 
00160   nodes.resize(num_nodes);
00161   elem_offsets.resize(num_elems+1);
00162 
00163   iter = cBlocks.begin(),
00164   iter_end = cBlocks.end();
00165 
00166   int node_offset = 0;
00167   int elem_offset = 0;
00168   int elem_counter = 0;
00169 
00170   int nodeType = 0;
00171   snl_fei::RecordCollection* nodeRecords = NULL;
00172   matrixGraph.getRowSpace()->getRecordCollection(nodeType, nodeRecords);
00173 
00174   for(; iter != iter_end; ++iter) {
00175     fei::ConnectivityBlock* cblk = iter->second;
00176 
00177     //if not symmetric, then assume it's not an element-block.
00178     if (!cblk->isSymmetric()) continue;
00179 
00180     fei::Pattern* pattern = cblk->getRowPattern();
00181 
00182     int ne = cblk->getConnectivityIDs().size();
00183     int nn = pattern->getNumIDs();
00184     std::vector<int>& cblk_nodes = cblk->getRowConnectivities();
00185     for(unsigned i=0; i<cblk_nodes.size(); ++i) {
00186       nodes[node_offset++] = nodeRecords->getRecordWithLocalID(cblk_nodes[i])->getID();
00187     }
00188 
00189     for(int i=0; i<ne; ++i) {
00190       elem_offsets[elem_counter++] = elem_offset;
00191       elem_offset += nn;
00192     }
00193   }
00194 
00195   elem_offsets[elem_counter] = elem_offset;
00196 }
00197 
00198 //----------------------------------------------------------------------------
00199 void fei::utils::char_ptrs_to_strings(int numStrings,
00200                                      const char*const* charstrings,
00201                                      std::vector<std::string>& stdstrings)
00202 {
00203   stdstrings.resize(0);
00204   for(int i=0; i<numStrings; ++i) {
00205     if (charstrings[i] != NULL) {
00206       std::string tempstr(charstrings[i]);
00207       stdstrings.push_back(tempstr);
00208     }
00209   }
00210 }
00211 
00212 //----------------------------------------------------------------------------
00213 void fei::utils::strings_to_char_ptrs(std::vector<std::string>& stdstrings,
00214                                       int& numStrings,
00215                                       const char**& charPtrs)
00216 {
00217   numStrings = stdstrings.size();
00218   charPtrs = numStrings > 0 ? new const char*[numStrings] : NULL;
00219 
00220   for(int i=0; i<numStrings; ++i) {
00221     charPtrs[i] = stdstrings[i].c_str();
00222   }
00223 }
00224 
00225 //----------------------------------------------------------------------------
00226 void fei::utils::parse_strings(std::vector<std::string>& stdstrings,
00227                               const char* separator_string,
00228                               fei::ParameterSet& paramset)
00229 {
00230   std::vector<std::string>::iterator
00231     s_iter = stdstrings.begin(),
00232     s_end = stdstrings.end();
00233 
00234   int intval = 0;
00235   double doubleval = 0.0;
00236   const char* charstring_key = NULL;
00237   const char* charstring_val = NULL;
00238   int key_len = 0;
00239   int val_len = 0;
00240 
00241   for(; s_iter != s_end; ++s_iter) {
00242     snl_fei::separate_string((*s_iter).c_str(), separator_string,
00243                     charstring_key, key_len, charstring_val, val_len);
00244     if (key_len == 0) {
00245       continue;
00246     }
00247 
00248     std::string keystr(charstring_key, key_len);
00249 
00250     if (val_len == 0) {
00251       fei::Param vparam(keystr.c_str(), true);
00252       paramset.add(vparam, false);
00253       continue;
00254     }
00255 
00256     std::string valstr(charstring_val);
00257 
00258     if (valstr == "true" || valstr == "True" || valstr == "TRUE") {
00259       fei::Param bparam(keystr.c_str(), true);
00260       paramset.add(bparam, false);
00261       continue;
00262     }
00263 
00264     if (valstr == "false" || valstr == "False" || valstr == "FALSE") {
00265       fei::Param bparam(keystr.c_str(), false);
00266       paramset.add(bparam, false);
00267       continue;
00268     }
00269 
00270     FEI_ISTRINGSTREAM isstr(valstr);
00271 
00272     //Does charstring_val contain a floating-point value?
00273     //If so, we'll store it as a double.
00274     std::string::size_type i = valstr.find(".");
00275     std::string::size_type valstrsize = valstr.size();
00276 
00277     if (i < valstrsize) {
00278       isstr >> doubleval;
00279       if (!isstr.fail()) {
00280         fei::Param dparam(keystr.c_str(), doubleval);
00281         paramset.add(dparam, false);
00282         continue;
00283       }
00284       isstr.clear();
00285     }
00286 
00287     //Does charstring_val contain an int?
00288     isstr >> intval;
00289     if (!isstr.fail()) {
00290       fei::Param iparam(keystr.c_str(), intval);
00291       paramset.add(iparam, false);
00292       continue;
00293     }
00294     isstr.clear();
00295 
00296     //If charstring_val doesn't contain an int or a real, we'll just store
00297     //it as a string.
00298     fei::Param sparam(keystr.c_str(), charstring_val);
00299     paramset.add(sparam, false);
00300   }
00301 }
00302 
00303 //----------------------------------------------------------------------------
00304 void
00305 fei::utils::convert_ParameterSet_to_strings(const fei::ParameterSet* paramset,
00306                                         std::vector<std::string>& paramStrings)
00307 {
00308   paramStrings.resize(0);
00309 
00310   fei::ParameterSet::const_iterator
00311     iter = paramset->begin(),
00312     iter_end = paramset->end();
00313 
00314   for(; iter != iter_end; ++iter) {
00315     const fei::Param& param = *iter;
00316     fei::Param::ParamType ptype = param.getType();
00317 
00318     FEI_OSTRINGSTREAM osstr;
00319     osstr << param.getName();
00320 
00321     switch(ptype) {
00322     case fei::Param::STRING:
00323       osstr << " " << param.getStringValue();
00324       break;
00325     case fei::Param::DOUBLE:
00326       osstr << " " << param.getDoubleValue();
00327       break;
00328     case fei::Param::INT:
00329       osstr << " " << param.getIntValue();
00330       break;
00331     case fei::Param::VOID:
00332       break;
00333     case fei::Param::BOOL:
00334       if (param.getBoolValue()) osstr << " true";
00335       else osstr << " false";
00336       break;
00337     default:
00338       break;
00339     }
00340 
00341     paramStrings.push_back(osstr.str());
00342   }
00343 }
00344 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends