Ifpack2 Templated Preconditioning Package Version 1.0
Ifpack2_Factory.hpp
00001 /*@HEADER
00002 // ***********************************************************************
00003 //
00004 //       Ifpack2: Tempated Object-Oriented Algebraic Preconditioner Package
00005 //                 Copyright (2009) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
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 Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 //@HEADER
00041 */
00042 
00043 #ifndef IFPACK2_FACTORY_HPP
00044 #define IFPACK2_FACTORY_HPP
00045 
00046 #include "Ifpack2_ConfigDefs.hpp"
00047 #include "Ifpack2_Preconditioner.hpp"
00048 #include "Ifpack2_Relaxation.hpp"
00049 #include "Ifpack2_Diagonal.hpp"
00050 #include "Ifpack2_Chebyshev.hpp"
00051 #include "Ifpack2_RILUK.hpp"
00052 #include "Ifpack2_ILUT.hpp"
00053 #include "Ifpack2_Krylov.hpp"
00054 #include "Ifpack2_AdditiveSchwarz.hpp"
00055 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
00056 #include "Ifpack2_SupportGraph.hpp"
00057 #endif
00058 #include <locale>
00059 
00060 
00061 namespace Ifpack2 {
00062 
00064 bool supportsUnsymmetric (const std::string& prec_type);
00065 
00067 
00119 class Factory {
00120 public:
00132   template<class MatrixType>
00133   static
00134   Teuchos::RCP<Ifpack2::Preconditioner<typename MatrixType::scalar_type,
00135                                        typename MatrixType::local_ordinal_type,
00136                                        typename MatrixType::global_ordinal_type,
00137                                        typename MatrixType::node_type> >
00138   create(const std::string& prec_type,
00139          const Teuchos::RCP<const MatrixType>& matrix,
00140          const int overlap = 0);
00141 
00142 
00144   template<class MatrixType, class M2>
00145   static
00146   Teuchos::RCP<Ifpack2::Preconditioner<typename M2::scalar_type,
00147                                        typename M2::local_ordinal_type,
00148                                        typename M2::global_ordinal_type,
00149                                        typename M2::node_type> >
00150   clone(const Teuchos::RCP<Ifpack2::Preconditioner<typename MatrixType::scalar_type,
00151                                        typename MatrixType::local_ordinal_type,
00152                                        typename MatrixType::global_ordinal_type,
00153                                        typename MatrixType::node_type> >& prec,
00154     const Teuchos::RCP<const M2>& matrix, const Teuchos::ParameterList& params = Teuchos::ParameterList());
00155 
00156 };
00157 
00160 
00161 template<class MatrixType>
00162 Teuchos::RCP<Ifpack2::Preconditioner<typename MatrixType::scalar_type,typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type> >
00163 Factory::create(const std::string& prec_type,
00164                 const Teuchos::RCP<const MatrixType>& matrix,
00165                 const int overlap)
00166 {
00167   using Teuchos::RCP;
00168   using Teuchos::rcp;
00169   typedef typename MatrixType::scalar_type Scalar;
00170   typedef typename MatrixType::local_ordinal_type LocalOrdinal;
00171   typedef typename MatrixType::global_ordinal_type GlobalOrdinal;
00172   typedef typename MatrixType::node_type Node;
00173   RCP<Ifpack2::Preconditioner<Scalar,LocalOrdinal,GlobalOrdinal,Node> > prec;
00174 
00175   // precTypeUpper is the upper-case version of prec_type.
00176   std::string precTypeUpper (prec_type);
00177   if (precTypeUpper.size () > 0) {
00178     std::locale locale;
00179     for (size_t k = 0; k < precTypeUpper.size (); ++k) {
00180       precTypeUpper[k] = std::toupper<char> (precTypeUpper[k], locale);
00181     }
00182   }
00183 
00184   const bool one_mpi_rank = (matrix->getComm ()->getSize () == 1);
00185 
00186   if (precTypeUpper == "ILUT") {
00187     // Note: ILUT doesn't work for multiple MPI ranks... you have to use AdditiveSchwarz.
00188     if (one_mpi_rank) {
00189       prec = rcp (new Ifpack2::ILUT<MatrixType> (matrix));
00190     }
00191     else {
00192       prec = rcp (new Ifpack2::AdditiveSchwarz<MatrixType, Ifpack2::ILUT<MatrixType> > (matrix, overlap));
00193     }
00194   }
00195   else if (precTypeUpper == "RILUK") {
00196     prec = rcp (new Ifpack2::RILUK<MatrixType> (matrix));
00197   }
00198   else if (precTypeUpper == "RELAXATION") {
00199     prec = rcp (new Ifpack2::Relaxation<MatrixType> (matrix));
00200   }
00201   else if (precTypeUpper == "CHEBYSHEV") {
00202     prec = rcp (new Ifpack2::Chebyshev<MatrixType> (matrix));
00203   }
00204   else if (precTypeUpper == "DIAGONAL") {
00205     prec = rcp (new Ifpack2::Diagonal<MatrixType> (matrix));
00206   }
00207   else if (precTypeUpper == "SCHWARZ") {
00208     prec = rcp (new Ifpack2::AdditiveSchwarz<MatrixType,Ifpack2::ILUT<MatrixType> > (matrix, overlap));
00209   }
00210   else if (precTypeUpper == "KRYLOV") {
00211     prec = rcp (new Ifpack2::Krylov<MatrixType, Ifpack2::Preconditioner<Scalar, LocalOrdinal, GlobalOrdinal, Node> > (matrix));
00212   }
00213 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
00214   else if (precTypeUpper == "SUPPORTGRAPH") {
00215     if (one_mpi_rank) {
00216       prec = rcp (new Ifpack2::SupportGraph<MatrixType> (matrix));
00217     }
00218     else {
00219       prec = rcp (new Ifpack2::AdditiveSchwarz<MatrixType, Ifpack2::SupportGraph<MatrixType> > (matrix, overlap));
00220     }
00221   }
00222 #endif
00223   else {
00224     TEUCHOS_TEST_FOR_EXCEPTION(
00225       true, std::invalid_argument, "Ifpack2::Factory::create: "
00226       "Invalid preconditioner type \"" << prec_type << "\".");
00227   }
00228   return prec;
00229 }
00230 
00231 template<class MatrixType, class M2>
00232 Teuchos::RCP<Ifpack2::Preconditioner<typename M2::scalar_type, typename M2::local_ordinal_type,typename M2::global_ordinal_type,typename M2::node_type> >
00233 Factory::clone(const Teuchos::RCP<Ifpack2::Preconditioner<typename MatrixType::scalar_type,
00234                 typename MatrixType::local_ordinal_type,
00235                 typename MatrixType::global_ordinal_type,
00236                 typename MatrixType::node_type> >& prec,
00237                 const Teuchos::RCP<const M2>& matrix, const Teuchos::ParameterList& params) {
00238   typedef typename M2::scalar_type scalar_type;
00239   typedef typename M2::local_ordinal_type local_ordinal_type;
00240   typedef typename M2::global_ordinal_type global_ordinal_type;
00241   typedef typename M2::node_type new_node_type;
00242 
00243   Teuchos::RCP<Ifpack2::Preconditioner<scalar_type, local_ordinal_type,global_ordinal_type, new_node_type> > new_prec;
00244   Teuchos::RCP<Ifpack2::Chebyshev<MatrixType> > chebyPrec;
00245   chebyPrec = Teuchos::rcp_dynamic_cast<Ifpack2::Chebyshev<MatrixType> >(prec);
00246   if (chebyPrec != Teuchos::null){
00247   new_prec = chebyPrec->clone(matrix, params);
00248   return new_prec;
00249   }
00250   Teuchos::RCP<Ifpack2::RILUK<MatrixType> > luPrec;
00251   luPrec = Teuchos::rcp_dynamic_cast<Ifpack2::RILUK<MatrixType> >(prec);
00252   if (luPrec != Teuchos::null){ 
00253   new_prec = luPrec->clone(matrix);
00254   return new_prec;
00255   }
00256   TEUCHOS_TEST_FOR_EXCEPTION(
00257     true, std::invalid_argument, "Ifpack2::Factory::clone: "
00258     "Invalid preconditioner type to clone \""); 
00259 }
00260 
00261 } //namespace Ifpack2
00262 
00263 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends