Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ifpack2_Details_Factory_def.hpp
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 */
42 
43 #ifndef IFPACK2_DETAILS_FACTORY_DEF_HPP
44 #define IFPACK2_DETAILS_FACTORY_DEF_HPP
45 
46 #include "Ifpack2_Factory.hpp"
47 #include "Ifpack2_Utilities.hpp"
48 #include "Ifpack2_Details_OneLevelFactory.hpp"
49 #include "Ifpack2_AdditiveSchwarz.hpp"
50 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
51 # include "Ifpack2_SupportGraph.hpp"
52 #endif // defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
53 
54 namespace Ifpack2 {
55 namespace Details {
56 
57 template<class SC, class LO, class GO, class NT>
60 create (const std::string& precType,
62  const int overlap)
63 {
64  using Teuchos::RCP;
65  using Teuchos::rcp;
66  RCP<prec_type> prec;
67 
68  // precTypeUpper is the upper-case version of precType.
69  std::string precTypeUpper = canonicalize(precType);
70 
71  if (precTypeUpper == "SCHWARZ") {
72  // Discussion related to Bug 5987: The line of code below will
73  // give AdditiveSchwarz a default subdomain solver by default.
74  // However, you can change it later via setParameters() or
75  // setInnerPreconditioner(). In the former case, AdditiveSchwarz
76  // will not create the subdomain solver until you call
77  // initialize(), so there is no performance loss in waiting after
78  // calling AdditiveSchwarz's constructor before specifying the
79  // subdomain solver's type.
80  //
81  // FIXME (mfh 14 Jan 2014) Use of "CUSTOM" in AdditiveSchwarz may
82  // destroy information needed for fixing Bug 5987. In particular,
83  // the input ParameterList needs to keep its subdomain solver
84  // info. setInnerPreconditioner must _not_ destroy that info _if_
85  // the Factory creates the AdditiveSchwarz instance.
86  prec = rcp (new AdditiveSchwarz<row_matrix_type> (matrix, overlap));
87  }
88  else if (precTypeUpper == "KRYLOV") {
90  (true, std::invalid_argument, "The \"KRYLOV\" preconditioner option has "
91  "been deprecated and removed. If you want a Krylov solver, use the "
92  "Belos package.");
93  }
94 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
95  else if (precTypeUpper == "SUPPORTGRAPH") {
96  prec = rcp (new SupportGraph<row_matrix_type> (matrix));
97  }
98 #endif
99  else {
100  try {
101  Details::OneLevelFactory<row_matrix_type> factory;
102  prec = factory.create (precType, matrix);
103  } catch (std::invalid_argument&) {
105  true, std::invalid_argument, "Ifpack2::Factory::create: "
106  "Invalid preconditioner type \"" << precType << "\".");
107  }
108  }
109  return prec;
110 }
111 
112 template<class SC, class LO, class GO, class NT>
115 create (const std::string& precType,
117 {
118  using Teuchos::RCP;
119  using Teuchos::rcp;
120  RCP<prec_type> prec;
121 
122  // precTypeUpper is the upper-case version of precType.
123  std::string precTypeUpper (precType);
124  if (precTypeUpper.size () > 0) {
125  for (size_t k = 0; k < precTypeUpper.size (); ++k) {
126  precTypeUpper[k] = ::toupper(precTypeUpper[k]);
127  }
128  }
129 
130  if (precTypeUpper == "SCHWARZ") {
131  // Discussion related to Bug 5987: The line of code below will
132  // give AdditiveSchwarz a default subdomain solver by default.
133  // However, you can change it later via setParameters() or
134  // setInnerPreconditioner(). In the former case, AdditiveSchwarz
135  // will not create the subdomain solver until you call
136  // initialize(), so there is no performance loss in waiting after
137  // calling AdditiveSchwarz's constructor before specifying the
138  // subdomain solver's type.
139  //
140  // FIXME (mfh 14 Jan 2014) Use of "CUSTOM" in AdditiveSchwarz may
141  // destroy information needed for fixing Bug 5987. In particular,
142  // the input ParameterList needs to keep its subdomain solver
143  // info. setInnerPreconditioner must _not_ destroy that info _if_
144  // the Factory creates the AdditiveSchwarz instance.
145  //
146  // "CUSTOM" isn't necessary. If Inverse_ is not null, then
147  // AdditiveSchwarz's initialize() should just use the inner
148  // preconditioner as it is. If Inverse_ is null, then we assume
149  // you want the default inner preconditioner. You shouldn't have
150  // called setInnerPreconditioner() with a null argument if that's
151  // not what you meant!
152  prec = rcp (new AdditiveSchwarz<row_matrix_type> (matrix));
153  }
154  else if (precTypeUpper == "KRYLOV") {
156  (true, std::invalid_argument, "The \"KRYLOV\" preconditioner option has "
157  "been deprecated and removed. If you want a Krylov solver, use the "
158  "Belos package.");
159  }
160 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
161  else if (precTypeUpper == "SUPPORTGRAPH") {
162  prec = rcp (new SupportGraph<row_matrix_type> (matrix));
163  }
164 #endif
165  else {
166  bool success = false;
167  std::ostringstream err;
168  try {
169  Details::OneLevelFactory<row_matrix_type> factory;
170  prec = factory.create (precType, matrix);
171  success = true;
172  } catch (std::invalid_argument& e) {
173  err << "Ifpack2::Factory::create: Invalid preconditioner type \""
174  << precType << "\". More information for Ifpack2 developers: "
175  << e.what ();
176  }
177  TEUCHOS_TEST_FOR_EXCEPTION(! success, std::invalid_argument, err.str ());
178  }
179 
181  prec.is_null (), std::logic_error, "Ifpack2::Factory::create: "
182  "Return value is null right before return. This should never happen. "
183  "Please report this bug to the Ifpack2 developers.");
184  return prec;
185 }
186 
187 
188 template<class SC, class LO, class GO, class NT>
189 bool
190 Factory<SC, LO, GO, NT>::
191 isSupported (const std::string& precType)
192 {
193  // precTypeUpper is the upper-case version of precType.
194  std::string precTypeUpper = canonicalize(precType);
195 
196  std::vector<std::string> supportedNames = {
197  "SCHWARZ",
198 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
199  "SUPPORTGRAPH"
200 #endif
201  };
202  auto it = std::find(std::begin(supportedNames), std::end(supportedNames), precTypeUpper);
203 
204  if (it != std::end(supportedNames)) {
205  return true;
206  } else {
207  Details::OneLevelFactory<row_matrix_type> factory;
208  return factory.isSupported (precType);
209  }
210 }
211 
212 } // namespace Details
213 } // namespace Ifpack2
214 
215 #define IFPACK2_DETAILS_FACTORY_INSTANT(S, LO, GO, N) \
216  template class Ifpack2::Details::Factory<S, LO, GO, N>;
217 
218 #endif // IFPACK2_DETAILS_FACTORY_DEF_HPP
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
File for utility functions.
static Teuchos::RCP< Preconditioner< typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type > > create(const std::string &precType, const Teuchos::RCP< const MatrixType > &matrix)
Create an instance of Ifpack2_Preconditioner given the string name of the preconditioner type...
Definition: Ifpack2_Factory_decl.hpp:133