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 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
4 //
5 // Copyright 2009 NTESS and the Ifpack2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef IFPACK2_DETAILS_FACTORY_DEF_HPP
11 #define IFPACK2_DETAILS_FACTORY_DEF_HPP
12 
13 #include "Ifpack2_Factory.hpp"
14 #include "Ifpack2_Utilities.hpp"
15 #include "Ifpack2_Details_OneLevelFactory.hpp"
16 #include "Ifpack2_AdditiveSchwarz.hpp"
17 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
18 # include "Ifpack2_SupportGraph.hpp"
19 #endif // defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
20 
21 namespace Ifpack2 {
22 namespace Details {
23 
24 template<class SC, class LO, class GO, class NT>
27 create (const std::string& precType,
29  const int overlap)
30 {
31  using Teuchos::RCP;
32  using Teuchos::rcp;
33  RCP<prec_type> prec;
34 
35  // precTypeUpper is the upper-case version of precType.
36  std::string precTypeUpper = canonicalize(precType);
37 
38  if (precTypeUpper == "SCHWARZ") {
39  // Discussion related to Bug 5987: The line of code below will
40  // give AdditiveSchwarz a default subdomain solver by default.
41  // However, you can change it later via setParameters() or
42  // setInnerPreconditioner(). In the former case, AdditiveSchwarz
43  // will not create the subdomain solver until you call
44  // initialize(), so there is no performance loss in waiting after
45  // calling AdditiveSchwarz's constructor before specifying the
46  // subdomain solver's type.
47  //
48  // FIXME (mfh 14 Jan 2014) Use of "CUSTOM" in AdditiveSchwarz may
49  // destroy information needed for fixing Bug 5987. In particular,
50  // the input ParameterList needs to keep its subdomain solver
51  // info. setInnerPreconditioner must _not_ destroy that info _if_
52  // the Factory creates the AdditiveSchwarz instance.
53  prec = rcp (new AdditiveSchwarz<row_matrix_type> (matrix, overlap));
54  }
55  else if (precTypeUpper == "KRYLOV") {
57  (true, std::invalid_argument, "The \"KRYLOV\" preconditioner option has "
58  "been deprecated and removed. If you want a Krylov solver, use the "
59  "Belos package.");
60  }
61 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
62  else if (precTypeUpper == "SUPPORTGRAPH") {
63  prec = rcp (new SupportGraph<row_matrix_type> (matrix));
64  }
65 #endif
66  else {
67  try {
68  Details::OneLevelFactory<row_matrix_type> factory;
69  prec = factory.create (precType, matrix);
70  } catch (std::invalid_argument&) {
72  true, std::invalid_argument, "Ifpack2::Factory::create: "
73  "Invalid preconditioner type \"" << precType << "\".");
74  }
75  }
76  return prec;
77 }
78 
79 template<class SC, class LO, class GO, class NT>
82 create (const std::string& precType,
84 {
85  using Teuchos::RCP;
86  using Teuchos::rcp;
87  RCP<prec_type> prec;
88 
89  // precTypeUpper is the upper-case version of precType.
90  std::string precTypeUpper (precType);
91  if (precTypeUpper.size () > 0) {
92  for (size_t k = 0; k < precTypeUpper.size (); ++k) {
93  precTypeUpper[k] = ::toupper(precTypeUpper[k]);
94  }
95  }
96 
97  if (precTypeUpper == "SCHWARZ") {
98  // Discussion related to Bug 5987: The line of code below will
99  // give AdditiveSchwarz a default subdomain solver by default.
100  // However, you can change it later via setParameters() or
101  // setInnerPreconditioner(). In the former case, AdditiveSchwarz
102  // will not create the subdomain solver until you call
103  // initialize(), so there is no performance loss in waiting after
104  // calling AdditiveSchwarz's constructor before specifying the
105  // subdomain solver's type.
106  //
107  // FIXME (mfh 14 Jan 2014) Use of "CUSTOM" in AdditiveSchwarz may
108  // destroy information needed for fixing Bug 5987. In particular,
109  // the input ParameterList needs to keep its subdomain solver
110  // info. setInnerPreconditioner must _not_ destroy that info _if_
111  // the Factory creates the AdditiveSchwarz instance.
112  //
113  // "CUSTOM" isn't necessary. If Inverse_ is not null, then
114  // AdditiveSchwarz's initialize() should just use the inner
115  // preconditioner as it is. If Inverse_ is null, then we assume
116  // you want the default inner preconditioner. You shouldn't have
117  // called setInnerPreconditioner() with a null argument if that's
118  // not what you meant!
119  prec = rcp (new AdditiveSchwarz<row_matrix_type> (matrix));
120  }
121  else if (precTypeUpper == "KRYLOV") {
123  (true, std::invalid_argument, "The \"KRYLOV\" preconditioner option has "
124  "been deprecated and removed. If you want a Krylov solver, use the "
125  "Belos package.");
126  }
127 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
128  else if (precTypeUpper == "SUPPORTGRAPH") {
129  prec = rcp (new SupportGraph<row_matrix_type> (matrix));
130  }
131 #endif
132  else {
133  bool success = false;
134  std::ostringstream err;
135  try {
136  Details::OneLevelFactory<row_matrix_type> factory;
137  prec = factory.create (precType, matrix);
138  success = true;
139  } catch (std::invalid_argument& e) {
140  err << "Ifpack2::Factory::create: Invalid preconditioner type \""
141  << precType << "\". More information for Ifpack2 developers: "
142  << e.what ();
143  }
144  TEUCHOS_TEST_FOR_EXCEPTION(! success, std::invalid_argument, err.str ());
145  }
146 
148  prec.is_null (), std::logic_error, "Ifpack2::Factory::create: "
149  "Return value is null right before return. This should never happen. "
150  "Please report this bug to the Ifpack2 developers.");
151  return prec;
152 }
153 
154 
155 template<class SC, class LO, class GO, class NT>
156 bool
157 Factory<SC, LO, GO, NT>::
158 isSupported (const std::string& precType)
159 {
160  // precTypeUpper is the upper-case version of precType.
161  std::string precTypeUpper = canonicalize(precType);
162 
163  std::vector<std::string> supportedNames = {
164  "SCHWARZ",
165 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
166  "SUPPORTGRAPH"
167 #endif
168  };
169  auto it = std::find(std::begin(supportedNames), std::end(supportedNames), precTypeUpper);
170 
171  if (it != std::end(supportedNames)) {
172  return true;
173  } else {
174  Details::OneLevelFactory<row_matrix_type> factory;
175  return factory.isSupported (precType);
176  }
177 }
178 
179 } // namespace Details
180 } // namespace Ifpack2
181 
182 #define IFPACK2_DETAILS_FACTORY_INSTANT(S, LO, GO, N) \
183  template class Ifpack2::Details::Factory<S, LO, GO, N>;
184 
185 #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:100