|
Ifpack2 Templated Preconditioning Package
Version 1.0
|
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_DEF_HPP 00044 #define IFPACK2_FACTORY_DEF_HPP 00045 00046 #include "Ifpack2_Details_OneLevelFactory.hpp" 00047 #include "Ifpack2_AdditiveSchwarz.hpp" 00048 #include "Ifpack2_Krylov.hpp" 00049 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH) 00050 # include "Ifpack2_SupportGraph.hpp" 00051 #endif // defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH) 00052 #include "Ifpack2_RILUK.hpp" 00053 00054 namespace Ifpack2 { 00055 00056 template<class MatrixType> 00057 Teuchos::RCP<Preconditioner<typename MatrixType::scalar_type, 00058 typename MatrixType::local_ordinal_type, 00059 typename MatrixType::global_ordinal_type, 00060 typename MatrixType::node_type> > 00061 Factory::create (const std::string& precType, 00062 const Teuchos::RCP<const MatrixType>& matrix, 00063 const int overlap) 00064 { 00065 using Teuchos::RCP; 00066 using Teuchos::rcp; 00067 typedef typename MatrixType::scalar_type scalar_type; 00068 typedef typename MatrixType::local_ordinal_type local_ordinal_type; 00069 typedef typename MatrixType::global_ordinal_type global_ordinal_type; 00070 typedef typename MatrixType::node_type node_type; 00071 typedef Preconditioner<scalar_type, local_ordinal_type, 00072 global_ordinal_type, node_type> prec_base_type; 00073 00074 RCP<prec_base_type> prec; 00075 00076 // precTypeUpper is the upper-case version of precType. 00077 std::string precTypeUpper (precType); 00078 if (precTypeUpper.size () > 0) { 00079 std::locale locale; 00080 for (size_t k = 0; k < precTypeUpper.size (); ++k) { 00081 precTypeUpper[k] = std::toupper<char> (precTypeUpper[k], locale); 00082 } 00083 } 00084 00085 const bool one_mpi_rank = (matrix->getComm ()->getSize () == 1); 00086 // Forestall "unused variable" warnings. 00087 (void) one_mpi_rank; 00088 00089 if (precTypeUpper == "SCHWARZ") { 00090 // Discussion related to Bug 5987: The line of code below will 00091 // give AdditiveSchwarz a default subdomain solver by default. 00092 // However, you can change it later via setParameters() or 00093 // setInnerPreconditioner(). In the former case, AdditiveSchwarz 00094 // will not create the subdomain solver until you call 00095 // initialize(), so there is no performance loss in waiting after 00096 // calling AdditiveSchwarz's constructor before specifying the 00097 // subdomain solver's type. 00098 // 00099 // FIXME (mfh 14 Jan 2014) Use of "CUSTOM" in AdditiveSchwarz may 00100 // destroy information needed for fixing Bug 5987. In particular, 00101 // the input ParameterList needs to keep its subdomain solver 00102 // info. setInnerPreconditioner must _not_ destroy that info _if_ 00103 // the Factory creates the AdditiveSchwarz instance. 00104 prec = rcp (new AdditiveSchwarz<MatrixType> (matrix, overlap)); 00105 } 00106 else if (precTypeUpper == "KRYLOV") { 00107 prec = rcp (new Krylov<MatrixType> (matrix)); 00108 } 00109 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH) 00110 else if (precTypeUpper == "SUPPORTGRAPH") { 00111 prec = rcp (new SupportGraph<MatrixType> (matrix)); 00112 } 00113 #endif 00114 else { 00115 try { 00116 Details::OneLevelFactory<MatrixType> factory; 00117 prec = factory.create (precType, matrix); 00118 } catch (std::invalid_argument&) { 00119 TEUCHOS_TEST_FOR_EXCEPTION( 00120 true, std::invalid_argument, "Ifpack2::Factory::create: " 00121 "Invalid preconditioner type \"" << precType << "\"."); 00122 } 00123 } 00124 return prec; 00125 } 00126 00127 00128 template<class MatrixType> 00129 Teuchos::RCP<Preconditioner<typename MatrixType::scalar_type, 00130 typename MatrixType::local_ordinal_type, 00131 typename MatrixType::global_ordinal_type, 00132 typename MatrixType::node_type> > 00133 Factory::create (const std::string& precType, 00134 const Teuchos::RCP<const MatrixType>& matrix) 00135 { 00136 using Teuchos::RCP; 00137 using Teuchos::rcp; 00138 typedef typename MatrixType::scalar_type scalar_type; 00139 typedef typename MatrixType::local_ordinal_type local_ordinal_type; 00140 typedef typename MatrixType::global_ordinal_type global_ordinal_type; 00141 typedef typename MatrixType::node_type node_type; 00142 typedef Preconditioner<scalar_type, 00143 local_ordinal_type, 00144 global_ordinal_type, 00145 node_type> prec_base_type; 00146 00147 RCP<prec_base_type> prec; 00148 00149 // precTypeUpper is the upper-case version of precType. 00150 std::string precTypeUpper (precType); 00151 if (precTypeUpper.size () > 0) { 00152 std::locale locale; 00153 for (size_t k = 0; k < precTypeUpper.size (); ++k) { 00154 precTypeUpper[k] = std::toupper<char> (precTypeUpper[k], locale); 00155 } 00156 } 00157 00158 const bool one_mpi_rank = (matrix->getComm ()->getSize () == 1); 00159 // Forestall "unused variable" warnings. 00160 (void) one_mpi_rank; 00161 00162 if (precTypeUpper == "SCHWARZ") { 00163 // Discussion related to Bug 5987: The line of code below will 00164 // give AdditiveSchwarz a default subdomain solver by default. 00165 // However, you can change it later via setParameters() or 00166 // setInnerPreconditioner(). In the former case, AdditiveSchwarz 00167 // will not create the subdomain solver until you call 00168 // initialize(), so there is no performance loss in waiting after 00169 // calling AdditiveSchwarz's constructor before specifying the 00170 // subdomain solver's type. 00171 // 00172 // FIXME (mfh 14 Jan 2014) Use of "CUSTOM" in AdditiveSchwarz may 00173 // destroy information needed for fixing Bug 5987. In particular, 00174 // the input ParameterList needs to keep its subdomain solver 00175 // info. setInnerPreconditioner must _not_ destroy that info _if_ 00176 // the Factory creates the AdditiveSchwarz instance. 00177 // 00178 // "CUSTOM" isn't necessary. If Inverse_ is not null, then 00179 // AdditiveSchwarz's initialize() should just use the inner 00180 // preconditioner as it is. If Inverse_ is null, then we assume 00181 // you want the default inner preconditioner. You shouldn't have 00182 // called setInnerPreconditioner() with a null argument if that's 00183 // not what you meant! 00184 prec = rcp (new AdditiveSchwarz<MatrixType> (matrix)); 00185 } 00186 else if (precTypeUpper == "KRYLOV") { 00187 prec = rcp (new Krylov<MatrixType> (matrix)); 00188 } 00189 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH) 00190 else if (precTypeUpper == "SUPPORTGRAPH") { 00191 prec = rcp (new SupportGraph<MatrixType> (matrix)); 00192 } 00193 #endif 00194 else { 00195 bool success = false; 00196 std::ostringstream err; 00197 try { 00198 Details::OneLevelFactory<MatrixType> factory; 00199 prec = factory.create (precType, matrix); 00200 success = true; 00201 } catch (std::invalid_argument& e) { 00202 err << "Ifpack2::Factory::create: Invalid preconditioner type \"" 00203 << precType << "\". More information for Ifpack2 developers: " 00204 << e.what (); 00205 } 00206 TEUCHOS_TEST_FOR_EXCEPTION(! success, std::invalid_argument, err.str ()); 00207 } 00208 00209 TEUCHOS_TEST_FOR_EXCEPTION( 00210 prec.is_null (), std::logic_error, "Ifpack2::Factory::create: " 00211 "Return value is null right before return. This should never happen. " 00212 "Please report this bug to the Ifpack2 developers."); 00213 return prec; 00214 } 00215 00216 template<class InputMatrixType, class OutputMatrixType> 00217 Teuchos::RCP<Preconditioner<typename OutputMatrixType::scalar_type, 00218 typename OutputMatrixType::local_ordinal_type, 00219 typename OutputMatrixType::global_ordinal_type, 00220 typename OutputMatrixType::node_type> > 00221 Factory::clone (const Teuchos::RCP<Preconditioner<typename InputMatrixType::scalar_type, 00222 typename InputMatrixType::local_ordinal_type, 00223 typename InputMatrixType::global_ordinal_type, 00224 typename InputMatrixType::node_type> >& prec, 00225 const Teuchos::RCP<const OutputMatrixType>& matrix, 00226 const Teuchos::ParameterList& params) 00227 { 00228 using Teuchos::null; 00229 using Teuchos::RCP; 00230 using Teuchos::rcp; 00231 using Teuchos::rcp_dynamic_cast; 00232 00233 // FIXME (mfh 09 Nov 2013) The code below assumes that the old and 00234 // new scalar, local ordinal, and global ordinal types are the same. 00235 00236 typedef typename OutputMatrixType::scalar_type scalar_type; 00237 typedef typename OutputMatrixType::local_ordinal_type local_ordinal_type; 00238 typedef typename OutputMatrixType::global_ordinal_type global_ordinal_type; 00239 typedef typename OutputMatrixType::node_type new_node_type; 00240 typedef Preconditioner<scalar_type, local_ordinal_type, 00241 global_ordinal_type, new_node_type> output_prec_type; 00242 00243 // FIXME (mfh 09 Nov 2013) The code below only knows how to clone 00244 // two different kinds of preconditioners. This is probably because 00245 // only two subclasses of Preconditioner implement a clone() method. 00246 00247 RCP<output_prec_type> new_prec; 00248 RCP<Chebyshev<InputMatrixType> > chebyPrec; 00249 chebyPrec = rcp_dynamic_cast<Chebyshev<InputMatrixType> > (prec); 00250 if (chebyPrec != null) { 00251 new_prec = chebyPrec->clone (matrix, params); 00252 return new_prec; 00253 } 00254 RCP<RILUK<InputMatrixType> > luPrec; 00255 luPrec = rcp_dynamic_cast<RILUK<InputMatrixType> > (prec); 00256 if (luPrec != null) { 00257 new_prec = luPrec->clone (matrix); 00258 return new_prec; 00259 } 00260 TEUCHOS_TEST_FOR_EXCEPTION( 00261 true, std::logic_error, "Ifpack2::Factory::clone: Not implemented for the " 00262 "current preconditioner type. The only supported types thus far are " 00263 "Chebyshev and RILUK."); 00264 } 00265 00266 } // namespace Ifpack2 00267 00268 #define IFPACK2_FACTORY_INSTANT(S,LO,GO,N) \ 00269 template Teuchos::RCP<Ifpack2::Preconditioner<S, LO, GO, N> > \ 00270 Ifpack2::Factory::create<Tpetra::CrsMatrix< S, LO, GO, N> > ( \ 00271 const std::string&, \ 00272 const Teuchos::RCP<const Tpetra::CrsMatrix<S, LO, GO, N> >&); \ 00273 template Teuchos::RCP<Ifpack2::Preconditioner<S, LO, GO, N> > \ 00274 Ifpack2::Factory::create<Tpetra::CrsMatrix< S, LO, GO, N> > ( \ 00275 const std::string&, \ 00276 const Teuchos::RCP<const Tpetra::CrsMatrix<S, LO, GO, N> >&, \ 00277 const int); 00278 00279 #endif // IFPACK2_FACTORY_DEF_HPP
1.7.6.1