Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
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
21namespace Ifpack2 {
22namespace Details {
23
24template<class SC, class LO, class GO, class NT>
25Teuchos::RCP<typename Factory<SC, LO, GO, NT>::prec_type>
26Factory<SC, LO, GO, NT>::
27create (const std::string& precType,
28 const Teuchos::RCP<const row_matrix_type>& matrix,
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") {
56 TEUCHOS_TEST_FOR_EXCEPTION
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&) {
71 TEUCHOS_TEST_FOR_EXCEPTION(
72 true, std::invalid_argument, "Ifpack2::Factory::create: "
73 "Invalid preconditioner type \"" << precType << "\".");
74 }
75 }
76 return prec;
77}
78
79template<class SC, class LO, class GO, class NT>
80Teuchos::RCP<typename Factory<SC, LO, GO, NT>::prec_type>
81Factory<SC, LO, GO, NT>::
82create (const std::string& precType,
83 const Teuchos::RCP<const row_matrix_type>& matrix)
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") {
122 TEUCHOS_TEST_FOR_EXCEPTION
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
147 TEUCHOS_TEST_FOR_EXCEPTION(
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
155template<class SC, class LO, class GO, class NT>
156bool
157Factory<SC, LO, GO, NT>::
158isSupported (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
File for utility functions.
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:41