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