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  std::locale locale;
126  for (size_t k = 0; k < precTypeUpper.size (); ++k) {
127  precTypeUpper[k] = std::toupper<char> (precTypeUpper[k], locale);
128  }
129  }
130 
131  if (precTypeUpper == "SCHWARZ") {
132  // Discussion related to Bug 5987: The line of code below will
133  // give AdditiveSchwarz a default subdomain solver by default.
134  // However, you can change it later via setParameters() or
135  // setInnerPreconditioner(). In the former case, AdditiveSchwarz
136  // will not create the subdomain solver until you call
137  // initialize(), so there is no performance loss in waiting after
138  // calling AdditiveSchwarz's constructor before specifying the
139  // subdomain solver's type.
140  //
141  // FIXME (mfh 14 Jan 2014) Use of "CUSTOM" in AdditiveSchwarz may
142  // destroy information needed for fixing Bug 5987. In particular,
143  // the input ParameterList needs to keep its subdomain solver
144  // info. setInnerPreconditioner must _not_ destroy that info _if_
145  // the Factory creates the AdditiveSchwarz instance.
146  //
147  // "CUSTOM" isn't necessary. If Inverse_ is not null, then
148  // AdditiveSchwarz's initialize() should just use the inner
149  // preconditioner as it is. If Inverse_ is null, then we assume
150  // you want the default inner preconditioner. You shouldn't have
151  // called setInnerPreconditioner() with a null argument if that's
152  // not what you meant!
153  prec = rcp (new AdditiveSchwarz<row_matrix_type> (matrix));
154  }
155  else if (precTypeUpper == "KRYLOV") {
157  (true, std::invalid_argument, "The \"KRYLOV\" preconditioner option has "
158  "been deprecated and removed. If you want a Krylov solver, use the "
159  "Belos package.");
160  }
161 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
162  else if (precTypeUpper == "SUPPORTGRAPH") {
163  prec = rcp (new SupportGraph<row_matrix_type> (matrix));
164  }
165 #endif
166  else {
167  bool success = false;
168  std::ostringstream err;
169  try {
170  Details::OneLevelFactory<row_matrix_type> factory;
171  prec = factory.create (precType, matrix);
172  success = true;
173  } catch (std::invalid_argument& e) {
174  err << "Ifpack2::Factory::create: Invalid preconditioner type \""
175  << precType << "\". More information for Ifpack2 developers: "
176  << e.what ();
177  }
178  TEUCHOS_TEST_FOR_EXCEPTION(! success, std::invalid_argument, err.str ());
179  }
180 
182  prec.is_null (), std::logic_error, "Ifpack2::Factory::create: "
183  "Return value is null right before return. This should never happen. "
184  "Please report this bug to the Ifpack2 developers.");
185  return prec;
186 }
187 
188 
189 template<class SC, class LO, class GO, class NT>
190 bool
191 Factory<SC, LO, GO, NT>::
192 isSupported (const std::string& precType)
193 {
194  // precTypeUpper is the upper-case version of precType.
195  std::string precTypeUpper = canonicalize(precType);
196 
197  std::vector<std::string> supportedNames = {
198  "SCHWARZ",
199 #if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
200  "SUPPORTGRAPH"
201 #endif
202  };
203  auto it = std::find(std::begin(supportedNames), std::end(supportedNames), precTypeUpper);
204 
205  if (it != std::end(supportedNames)) {
206  return true;
207  } else {
208  Details::OneLevelFactory<row_matrix_type> factory;
209  return factory.isSupported (precType);
210  }
211 }
212 
213 } // namespace Details
214 } // namespace Ifpack2
215 
216 #define IFPACK2_DETAILS_FACTORY_INSTANT(S, LO, GO, N) \
217  template class Ifpack2::Details::Factory<S, LO, GO, N>;
218 
219 #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:132