FEI Version of the Day
snl_fei_Factory.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 #ifndef _snl_fei_Factory_cpp_
00044 #define _snl_fei_Factory_cpp_
00045 
00046 #include <fei_macros.hpp>
00047 
00048 #include <snl_fei_Factory.hpp>
00049 
00050 //----------------------------------------------------------------------------
00051 snl_fei::Factory::Factory(MPI_Comm comm,
00052                           fei::SharedPtr<LibraryWrapper> wrapper)
00053   : fei::Factory(comm),
00054     comm_(comm),
00055     broker_(),
00056     matrixGraph_(),
00057     nodeIDType_(0),
00058     lsc_(),
00059     feData_(),
00060     wrapper_(wrapper),
00061     outputLevel_(0),
00062     blockMatrix_(false)
00063 {
00064   if (wrapper_.get() != NULL) {
00065     lsc_ = wrapper->getLinearSystemCore();
00066     feData_ = wrapper->getFiniteElementData();
00067   }
00068 }
00069 
00070 //----------------------------------------------------------------------------
00071 snl_fei::Factory::Factory(MPI_Comm comm,
00072                           fei::SharedPtr<LinearSystemCore> lsc)
00073   : fei::Factory(comm),
00074     comm_(comm),
00075     broker_(),
00076     matrixGraph_(),
00077     nodeIDType_(0),
00078     lsc_(lsc),
00079     feData_(),
00080     wrapper_(),
00081     outputLevel_(0),
00082     blockMatrix_(false)
00083 {
00084 }
00085 
00086 //----------------------------------------------------------------------------
00087 snl_fei::Factory::Factory(MPI_Comm comm,
00088                           fei::SharedPtr<FiniteElementData> feData, int nodeIDType)
00089   : fei::Factory(comm),
00090     comm_(comm),
00091     broker_(),
00092     matrixGraph_(),
00093     nodeIDType_(nodeIDType),
00094     lsc_(),
00095     feData_(feData),
00096     wrapper_(NULL),
00097     outputLevel_(0),
00098     blockMatrix_(false)
00099 {
00100 }
00101 
00102 //----------------------------------------------------------------------------
00103 snl_fei::Factory::~Factory()
00104 {
00105 }
00106 
00107 //----------------------------------------------------------------------------
00108 fei::SharedPtr<fei::Factory>
00109 snl_fei::Factory::clone() const
00110 {
00111   fei::SharedPtr<fei::Factory> factory;
00112   if (wrapper_.get() != NULL) {
00113     factory.reset(new snl_fei::Factory(comm_, wrapper_));
00114   }
00115   else if (lsc_.get() != NULL) {
00116     factory.reset(new snl_fei::Factory(comm_, lsc_));
00117   }
00118   else if (feData_.get() != NULL) {
00119     factory.reset(new snl_fei::Factory(comm_, feData_, nodeIDType_));
00120   }
00121 
00122   return(factory);
00123 }
00124 
00125 //----------------------------------------------------------------------------
00126 void
00127 snl_fei::Factory::parameters(const fei::ParameterSet& parameterset)
00128 {
00129   fei::Factory::parameters(parameterset);
00130 
00131   int err = 0;
00132   if (lsc_.get() != NULL || feData_.get() != NULL) {
00133     int numParams = 0;
00134     const char** paramStrings = NULL;
00135     std::vector<std::string> stdstrings;
00136     fei::utils::convert_ParameterSet_to_strings(&parameterset, stdstrings);
00137     fei::utils::strings_to_char_ptrs(stdstrings, numParams, paramStrings);
00138     char** nc_paramStrings = const_cast<char**>(paramStrings);
00139     if (lsc_.get() != NULL) {
00140       err += lsc_->parameters(numParams, nc_paramStrings);
00141     }
00142     if (feData_.get() != NULL) {
00143       err += feData_->parameters(numParams, nc_paramStrings);
00144     }
00145 
00146     delete [] paramStrings;
00147 
00148     if (err != 0) {
00149       FEI_OSTRINGSTREAM osstr;
00150       osstr << "snl_fei::Factory::parameters received err="<<err
00151             << " from either feiData_->parameters or lsc_->parameters.";
00152       throw std::runtime_error(osstr.str());
00153     }
00154   }
00155 
00156   parameterset.getIntParamValue("outputLevel", outputLevel_);
00157 
00158   const fei::Param* param = 0;
00159   fei::Param::ParamType ptype = fei::Param::BAD_TYPE;
00160 
00161   param = parameterset.get("BLOCK_GRAPH");
00162   ptype = param != NULL ? param->getType() : fei::Param::BAD_TYPE;
00163   if (ptype != fei::Param::BAD_TYPE) {
00164     blockMatrix_ = true;
00165   }
00166 
00167   param = parameterset.get("BLOCK_MATRIX");
00168   ptype = param != NULL ? param->getType() : fei::Param::BAD_TYPE;
00169   if (ptype != fei::Param::BAD_TYPE) {
00170     if (ptype == fei::Param::BOOL) {
00171       blockMatrix_ = param->getBoolValue();
00172     }
00173     else {
00174       blockMatrix_ = true;
00175     }
00176   }
00177 
00178   param = parameterset.get("AZ_matrix_type");
00179   ptype = param != NULL ? param->getType() : fei::Param::BAD_TYPE;
00180   if (ptype != fei::Param::BAD_TYPE) {
00181     if (ptype == fei::Param::STRING) {
00182       if (param->getStringValue() == "AZ_VBR_MATRIX") {
00183         blockMatrix_ = true;
00184       }
00185     }
00186   }
00187 }
00188 
00189 //----------------------------------------------------------------------------
00190 fei::SharedPtr<fei::MatrixGraph>
00191 snl_fei::Factory::createMatrixGraph(fei::SharedPtr<fei::VectorSpace> rowSpace,
00192                         fei::SharedPtr<fei::VectorSpace> columnSpace,
00193                         const char* name)
00194 {
00195   static fei::MatrixGraph_Impl2::Factory factory;
00196   matrixGraph_ = factory.createMatrixGraph(rowSpace, columnSpace, name);
00197   return(matrixGraph_);
00198 }
00199 
00200 //----------------------------------------------------------------------------
00201 fei::SharedPtr<fei::Vector>
00202 snl_fei::Factory::createVector(fei::SharedPtr<fei::VectorSpace> vecSpace,
00203                    int numVectors)
00204 {
00205   (void)vecSpace;
00206   fei::SharedPtr<fei::Vector> dummy;
00207   if (matrixGraph_.get() == NULL) {
00208     fei::console_out() << "snl_fei::Factory ERROR: when using LinearSystemCore or FiniteElementData"
00209          << ", you must create a MatrixGraph before you can create vectors"<<FEI_ENDL;
00210     return(dummy);
00211   }
00212 
00213   if (matrixGraph_->getGlobalNumSlaveConstraints() > 0 &&
00214       reducer_.get() == NULL) {
00215     reducer_ = matrixGraph_->getReducer();
00216   }
00217 
00218   createBroker(matrixGraph_);
00219 
00220   return( broker_->createVector() );
00221 }
00222 
00223 //----------------------------------------------------------------------------
00224 fei::SharedPtr<fei::Vector>
00225 snl_fei::Factory::createVector(fei::SharedPtr<fei::VectorSpace> vecSpace,
00226                                                      bool isSolutionVector,
00227                                                      int numVectors)
00228 {
00229   fei::SharedPtr<fei::Vector> dummy;
00230   (void)vecSpace;
00231   if (matrixGraph_.get() == NULL) {
00232     fei::console_out() << "snl_fei::Factory ERROR: when using LinearSystemCore"
00233          << ", you must create a MatrixGraph before you can create vectors"<<FEI_ENDL;
00234     return(dummy);
00235   }
00236 
00237   if (matrixGraph_->getGlobalNumSlaveConstraints() > 0 &&
00238       reducer_.get() == NULL) {
00239     reducer_ = matrixGraph_->getReducer();
00240   }
00241 
00242   createBroker(matrixGraph_);
00243 
00244   return( broker_->createVector(isSolutionVector) );
00245 }
00246 
00247 //----------------------------------------------------------------------------
00248 fei::SharedPtr<fei::Vector>
00249 snl_fei::Factory::createVector(fei::SharedPtr<fei::MatrixGraph> matrixGraph,
00250                                                      int numVectors)
00251 {
00252   matrixGraph_ = matrixGraph;
00253 
00254   if (matrixGraph_->getGlobalNumSlaveConstraints() > 0 &&
00255       reducer_.get() == NULL) {
00256     reducer_ = matrixGraph_->getReducer();
00257   }
00258 
00259   createBroker(matrixGraph_);
00260 
00261   return( broker_->createVector() );
00262 }
00263 
00264 //----------------------------------------------------------------------------
00265 fei::SharedPtr<fei::Vector>
00266 snl_fei::Factory::createVector(fei::SharedPtr<fei::MatrixGraph> matrixGraph,
00267                      bool isSolutionVector,
00268                      int numVectors)
00269 {
00270   matrixGraph_ = matrixGraph;
00271 
00272   if (matrixGraph_->getGlobalNumSlaveConstraints() > 0 &&
00273       reducer_.get() == NULL) {
00274     reducer_ = matrixGraph_->getReducer();
00275   }
00276 
00277   createBroker(matrixGraph_);
00278 
00279   return( broker_->createVector(isSolutionVector) );
00280 }
00281 
00282 //----------------------------------------------------------------------------
00283 fei::SharedPtr<fei::Matrix>
00284 snl_fei::Factory::createMatrix(fei::SharedPtr<fei::MatrixGraph> matrixGraph)
00285 {
00286   matrixGraph_ = matrixGraph;
00287   fei::SharedPtr<fei::Matrix> mptr;
00288 
00289   if (matrixGraph_.get() == NULL) {
00290     fei::console_out() << "snl_fei::Factory ERROR: when using LinearSystemCore"
00291          << ", you must create a MatrixGraph before you can create matrices"<<FEI_ENDL;
00292     return(mptr);
00293   }
00294 
00295   if (matrixGraph_->getGlobalNumSlaveConstraints() > 0 &&
00296       reducer_.get() == NULL) {
00297     reducer_ = matrixGraph_->getReducer();
00298   }
00299 
00300   createBroker(matrixGraph_);
00301 
00302   broker_->setMatrixGraph(matrixGraph);
00303 
00304   return(broker_->createMatrix());
00305 }
00306 
00307 //----------------------------------------------------------------------------
00308 fei::SharedPtr<fei::LinearSystem>
00309 snl_fei::Factory::createLinearSystem(fei::SharedPtr<fei::MatrixGraph>& matrixGraph)
00310 {
00311   matrixGraph_ = matrixGraph;
00312 
00313   if (matrixGraph_.get() == NULL) {
00314     fei::console_out() << "snl_fei::Factory ERROR: you may not create a LinearSystem with "
00315          << "a NULL MatrixGraph object." << FEI_ENDL;
00316     fei::SharedPtr<fei::LinearSystem> linsys;
00317     return(linsys);
00318   }
00319 
00320   if (matrixGraph_->getGlobalNumSlaveConstraints() > 0 &&
00321       reducer_.get() == NULL) {
00322     reducer_ = matrixGraph_->getReducer();
00323   }
00324 
00325   createBroker(matrixGraph_);
00326 
00327   broker_->setMatrixGraph(matrixGraph);
00328 
00329   return( broker_->createLinearSystem() );
00330 }
00331 
00332 //----------------------------------------------------------------------------
00333 fei::SharedPtr<fei::Solver>
00334 snl_fei::Factory::createSolver(const char* name)
00335 {
00336   fei::SharedPtr<fei::Solver> solver(new fei::Solver);
00337   return(solver);
00338 }
00339 
00340 //----------------------------------------------------------------------------
00341 fei::SharedPtr<LibraryWrapper>
00342 snl_fei::Factory::get_LibraryWrapper() const
00343 {
00344   return( wrapper_ );
00345 }
00346 
00347 //----------------------------------------------------------------------------
00348 int snl_fei::Factory::getOutputLevel() const
00349 {
00350   return(outputLevel_);
00351 }
00352 
00353 //----------------------------------------------------------------------------
00354 int
00355 snl_fei::Factory::createBroker(fei::SharedPtr<fei::MatrixGraph> matrixGraph)
00356 {
00357   int err = -1;
00358   if (lsc_.get() != NULL) {
00359     err = createBroker_LinSysCore(matrixGraph, lsc_);
00360   }
00361   if (feData_.get() != NULL) {
00362     err = createBroker_FEData(matrixGraph, feData_);
00363   }
00364 
00365   return(err);
00366 }
00367 
00368 //----------------------------------------------------------------------------
00369 int
00370 snl_fei::Factory::createBroker_LinSysCore(fei::SharedPtr<fei::MatrixGraph> matrixGraph,
00371                                 fei::SharedPtr<LinearSystemCore> lsc)
00372 {
00373   if (broker_.get() == NULL) {
00374     fei::SharedPtr<snl_fei::Broker> brokerptr(new snl_fei::Broker_LinSysCore(lsc, matrixGraph, reducer_, blockMatrix_));
00375     broker_ = brokerptr;
00376   }
00377 
00378   return(0);
00379 }
00380 
00381 //----------------------------------------------------------------------------
00382 int
00383 snl_fei::Factory::createBroker_FEData(fei::SharedPtr<fei::MatrixGraph> matrixGraph,
00384                             fei::SharedPtr<FiniteElementData> feData)
00385 {
00386   if (broker_.get() == NULL) {
00387     fei::SharedPtr<snl_fei::Broker>
00388       brokerptr(new snl_fei::Broker_FEData(feData, matrixGraph,
00389                                            nodeIDType_));
00390     broker_ = brokerptr;
00391   }
00392 
00393   return(0);
00394 }
00395 
00396 
00397 #endif
00398 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends