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>::
27 create(const std::string& precType,
28 const Teuchos::RCP<const row_matrix_type>& matrix,
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&) {
69 TEUCHOS_TEST_FOR_EXCEPTION(
70 true, std::invalid_argument,
71 "Ifpack2::Factory::create: "
72 "Invalid preconditioner type \""
73 << 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>::
82 create(const std::string& precType,
83 const Teuchos::RCP<const row_matrix_type>& matrix) {
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
145 TEUCHOS_TEST_FOR_EXCEPTION(
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
153template <class SC, class LO, class GO, class NT>
154Teuchos::RCP<typename Factory<SC, LO, GO, NT>::prec_type>
155Factory<SC, LO, GO, NT>::
156 create(const std::string& precType,
157 const Teuchos::RCP<const row_matrix_type>& matrix,
158 const Teuchos::RCP<const coord_type>& coordinates) {
159 using Teuchos::RCP;
160 using Teuchos::rcp;
161 RCP<prec_type> prec;
162
163 // precTypeUpper is the upper-case version of precType.
164 std::string precTypeUpper(precType);
165 if (precTypeUpper.size() > 0) {
166 for (size_t k = 0; k < precTypeUpper.size(); ++k) {
167 precTypeUpper[k] = ::toupper(precTypeUpper[k]);
168 }
169 }
170
171 if (precTypeUpper == "SCHWARZ") {
172 // Discussion related to Bug 5987: The line of code below will
173 // give AdditiveSchwarz a default subdomain solver by default.
174 // However, you can change it later via setParameters() or
175 // setInnerPreconditioner(). In the former case, AdditiveSchwarz
176 // will not create the subdomain solver until you call
177 // initialize(), so there is no performance loss in waiting after
178 // calling AdditiveSchwarz's constructor before specifying the
179 // subdomain solver's type.
180 //
181 // FIXME (mfh 14 Jan 2014) Use of "CUSTOM" in AdditiveSchwarz may
182 // destroy information needed for fixing Bug 5987. In particular,
183 // the input ParameterList needs to keep its subdomain solver
184 // info. setInnerPreconditioner must _not_ destroy that info _if_
185 // the Factory creates the AdditiveSchwarz instance.
186 //
187 // "CUSTOM" isn't necessary. If Inverse_ is not null, then
188 // AdditiveSchwarz's initialize() should just use the inner
189 // preconditioner as it is. If Inverse_ is null, then we assume
190 // you want the default inner preconditioner. You shouldn't have
191 // called setInnerPreconditioner() with a null argument if that's
192 // not what you meant!
193 prec = rcp(new AdditiveSchwarz<row_matrix_type>(matrix, coordinates));
194 } else {
195 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
196 "Using stream-based RILUK with RCB partitioning on "
197 "coordinates associated with matrix rows is currently "
198 "enabled only with Additive Schwarz preconditioner "
199 "and RILUK as a subdomain solver.");
200 }
201
202 TEUCHOS_TEST_FOR_EXCEPTION(
203 prec.is_null(), std::logic_error,
204 "Ifpack2::Factory::create: "
205 "Return value is null right before return. This should never happen. "
206 "Please report this bug to the Ifpack2 developers.");
207 return prec;
208}
209
210template <class SC, class LO, class GO, class NT>
211std::vector<std::string>
212Factory<SC, LO, GO, NT>::
213 getSupportedNames() const {
214 Details::OneLevelFactory<row_matrix_type> factory;
215 std::vector<std::string> supportedNames = factory.getSupportedNames();
216 supportedNames.push_back("SCHWARZ");
217#if defined(HAVE_IFPACK2_EXPERIMENTAL) && defined(HAVE_IFPACK2_SUPPORTGRAPH)
218 supportedNames.push_back("SUPPORTGRAPH");
219#endif
220 return supportedNames;
221}
222
223template <class SC, class LO, class GO, class NT>
224bool Factory<SC, LO, GO, NT>::
225 isSupported(const std::string& precType) {
226 // precTypeUpper is the upper-case version of precType.
227 std::string precTypeUpper = canonicalize(precType);
228
229 std::vector<std::string> supportedNames = getSupportedNames();
230 auto it = std::find(std::begin(supportedNames), std::end(supportedNames), precTypeUpper);
231 return it != std::end(supportedNames);
232}
233
234} // namespace Details
235} // namespace Ifpack2
236
237#define IFPACK2_DETAILS_FACTORY_INSTANT(S, LO, GO, N) \
238 template class Ifpack2::Details::Factory<S, LO, GO, N>;
239
240#endif // IFPACK2_DETAILS_FACTORY_DEF_HPP
File for utility functions.
Ifpack2 implementation details.
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40