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