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