Belos Package Browser (Single Doxygen Collection) Development
Loading...
Searching...
No Matches
Factory.cpp
Go to the documentation of this file.
1//@HEADER
2// ************************************************************************
3//
4// Belos: Block Linear Solvers Package
5// Copyright 2004 Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
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#include "Teuchos_UnitTestHarness.hpp"
43#include "Teuchos_CommandLineProcessor.hpp"
46
47#include "BelosGCRODRSolMgr.hpp"
53#include "BelosLSQRSolMgr.hpp"
54#include "BelosPCPGSolMgr.hpp"
55#include "BelosRCGSolMgr.hpp"
57
58#include "MyMultiVec.hpp"
59#include "MyBetterOperator.hpp"
60#include "MyOperator.hpp"
61
62
63template<class ScalarType, class FactoryType, class SolverBaseType, class SolverImplType>
64void
65testSolver (bool& success, Teuchos::FancyOStream& out, const std::string& solverName)
66{
67 using Teuchos::ParameterEntry;
68 using Teuchos::ParameterList;
69 using Teuchos::parameterList;
70 using Teuchos::RCP;
71 using Teuchos::rcp;
72 using Teuchos::rcp_dynamic_cast;
73 using Teuchos::TypeNameTraits;
74 using std::endl;
75 typedef ScalarType ST;
76 typedef SolverBaseType solver_base_type;
77 typedef SolverImplType solver_impl_type;
78 typedef FactoryType factory_type;
79 typedef typename Teuchos::ScalarTraits<ST>::magnitudeType MT;
80
81 const bool testOutputFreq = false;
82
83 Teuchos::OSTab tab0 (out);
84 out << "Test Belos::SolverFactory::create for solver \"" << solverName << "\"" << endl;
85 Teuchos::OSTab tab1 (out);
86
87 out << "ScalarType: " << TypeNameTraits<ScalarType>::name () << endl
88 << "FactoryType: " << TypeNameTraits<FactoryType>::name () << endl
89 << "SolverBaseType: " << TypeNameTraits<SolverBaseType>::name () << endl
90 << "SolverImplType: " << TypeNameTraits<SolverImplType>::name () << endl;
91
92 RCP<factory_type> pFactory;
93 RCP<solver_base_type> solver;
94
95 out << "Test whether creating a Belos::SolverFactory works" << endl;
96 try {
97 pFactory = rcp (new factory_type ());
98 }
99 catch (std::exception& e) {
100 out << "Belos::SolverFactory constructor threw an exception: "
101 << e.what () << endl;
102 success = false;
103 return; // doesn't make sense to continue
104 }
105 catch (...) {
106 out << "Belos::SolverFactory constructor threw an exception not a subclass "
107 "of std::exception" << endl;
108 success = false;
109 return; // doesn't make sense to continue
110 }
111 factory_type& factory = *pFactory;
112
113 out << "Test whether factory works when input ParameterList is null" << endl;
114
115 // It must work when the parameter list is null.
116 TEST_NOTHROW( solver = factory.create (solverName, Teuchos::null) );
117 TEST_ASSERT( ! solver.is_null () );
118 if (! solver.is_null ()) {
119 // Did we actually get the solver for which we asked?
120 RCP<solver_impl_type> solverImpl = rcp_dynamic_cast<solver_impl_type> (solver);
121 TEST_ASSERT( ! solverImpl.is_null () );
122 }
123
124 out << "Test whether factory works when input ParameterList is nonnull" << endl;
125
126 // The factory must work when the parameter list is nonnull, and the
127 // solver must actually read the provided parameters.
128 RCP<ParameterList> plist = parameterList ("Belos");
129 const MT tol = 0.99; // definitely a nondefault value
130 const int maxNumIters = 42; // definitely a nondefault value
131 const int verbosity = static_cast<int> (Belos::Errors) + static_cast<int> (Belos::Warnings);
132 const int outputStyle = Belos::Brief; // not default (imitates AztecOO)
133 const int outputFreq = 3; // definitely not default
134
135 // Both of these parameters start out as "unused."
136 plist->set ("Convergence Tolerance", tol);
137 plist->set ("Maximum Iterations", maxNumIters);
138 plist->set ("Verbosity", verbosity);
139 plist->set ("Output Style", outputStyle);
140 if (testOutputFreq) {
141 plist->set ("Output Frequency", outputFreq);
142 }
143 TEST_ASSERT( ! plist->getEntry ("Convergence Tolerance").isUsed () );
144 TEST_ASSERT( ! plist->getEntry ("Maximum Iterations").isUsed () );
145 TEST_ASSERT( ! plist->getEntry ("Verbosity").isUsed () );
146 TEST_ASSERT( ! plist->getEntry ("Output Style").isUsed () );
147 if (testOutputFreq) {
148 TEST_ASSERT( ! plist->getEntry ("Output Frequency").isUsed () );
149 }
150
151 out << "Input ParameterList: " << endl;
152 {
153 Teuchos::OSTab tab2 (out);
154 plist->print (out);
155 out << endl;
156 }
157
158 solver = factory.create (solverName, plist);
159 TEST_ASSERT( ! solver.is_null () );
160 if (! solver.is_null ()) {
161 // Did we actually get the solver for which we asked?
162 RCP<solver_impl_type> solverImpl = rcp_dynamic_cast<solver_impl_type> (solver);
163 TEST_ASSERT( ! solverImpl.is_null () );
164
165 // Did the solver (or the factory) actually read the parameters that we set?
166 TEST_ASSERT( plist->getEntry ("Convergence Tolerance").isUsed () );
167 TEST_ASSERT( plist->getEntry ("Maximum Iterations").isUsed () );
168 TEST_ASSERT( plist->getEntry ("Verbosity").isUsed () );
169 TEST_ASSERT( plist->getEntry ("Output Style").isUsed () );
170 if (testOutputFreq) {
171 TEST_ASSERT( plist->getEntry ("Output Frequency").isUsed () );
172 }
173
174 // Did the solver get the parameters that we set on input?
175 RCP<const ParameterList> curParams = solver->getCurrentParameters ();
176 TEST_ASSERT( ! curParams.is_null () );
177 if (! curParams.is_null ()) {
178 // Are the parameters' values correct?
179 MT curTol = Teuchos::ScalarTraits<MT>::zero ();
180 TEST_NOTHROW( curTol = curParams->get<MT> ("Convergence Tolerance") );
181 TEST_EQUALITY( curTol, tol );
182 int curMaxNumIters = 0;
183 TEST_NOTHROW( curMaxNumIters = curParams->get<int> ("Maximum Iterations") );
184 TEST_EQUALITY( curMaxNumIters, maxNumIters );
185 int curVerbosity = 0;
186 TEST_NOTHROW( curVerbosity = curParams->get<int> ("Verbosity") );
187 TEST_EQUALITY( curVerbosity, verbosity );
188 int curOutputStyle = 0;
189 TEST_NOTHROW( curOutputStyle = curParams->get<int> ("Output Style") );
190 TEST_EQUALITY( curOutputStyle, outputStyle );
191 if (testOutputFreq) {
192 int curOutputFreq = 0;
193 TEST_NOTHROW( curOutputFreq = curParams->get<int> ("Output Frequency") );
194 TEST_EQUALITY( curOutputFreq, outputFreq );
195 }
196
197 // The solver (or the factory) doesn't actually need to have
198 // read ("used") the parameters in curParams. curParams could
199 // be (generally is, for Belos) a deep copy of plist.
200 }
201 }
202}
203
204
205
206// Unfortunately, the preprocessor doesn't let me do pasting like this:
207//
208// typedef Belos:: ## SOLVER_CLASS ## <ST, MV, OP> solver_impl_type;
209//
210// That's why I still have to do the typedef outside of the macro.
211#define BELOS_TEST_SOLVER( SOLVER_NAME ) \
212do { \
213 const std::string solverName (SOLVER_NAME); \
214 try { \
215 bool curSuccess = true; \
216 testSolver<ST, factory_type, solver_base_type, solver_impl_type> (curSuccess, out, solverName); \
217 if (! curSuccess) { \
218 failedSolvers.push_back (solverName); \
219 } \
220 success = success && curSuccess; \
221 } catch (std::exception& e) { \
222 out << "*** Solver \"" << solverName << "\" threw an exception: " \
223 << e.what () << std::endl; \
224 success = false; \
225 failedSolvers.push_back (solverName); \
226 } \
227} while (false)
228
229
230// Test that Belos::SolverFactory returns a solver of the right type,
231// and that the solver (or the factory) read and respected the input
232// parameters.
233TEUCHOS_UNIT_TEST( Factory, Bug6383 )
234{
235 using std::endl;
236 typedef double ST;
237 typedef Belos::MultiVec<ST> MV;
238 typedef Belos::Operator<ST> OP;
239 typedef Belos::SolverManager<ST, MV, OP> solver_base_type;
240 typedef Belos::SolverFactory<ST, MV, OP> factory_type;
241
242 Teuchos::OSTab tab0 (out);
243 out << "Test for Bug 6383" << endl;
244 Teuchos::OSTab tab1 (out);
245
246 // List of names of solvers that failed the test.
247 std::vector<std::string> failedSolvers;
248
249 {
250 typedef Belos::GCRODRSolMgr<ST, MV, OP> solver_impl_type;
251 BELOS_TEST_SOLVER( "GCRODR" );
252 }
253 {
254 typedef Belos::PseudoBlockGmresSolMgr<ST, MV, OP> solver_impl_type;
255 BELOS_TEST_SOLVER( "GMRES" );
256 }
257 // Make sure that the factory is case insensitive (Bug 6388).
258 {
259 typedef Belos::PseudoBlockGmresSolMgr<ST, MV, OP> solver_impl_type;
260 BELOS_TEST_SOLVER( "gmres" );
261 }
262 {
263 typedef Belos::PseudoBlockCGSolMgr<ST, MV, OP> solver_impl_type;
264 BELOS_TEST_SOLVER( "CG" );
265 }
266 // Make sure that the factory is case insensitive (Bug 6388).
267 {
268 typedef Belos::PseudoBlockCGSolMgr<ST, MV, OP> solver_impl_type;
269 BELOS_TEST_SOLVER( "cg" );
270 }
271 {
272 typedef Belos::BlockGmresSolMgr<ST, MV, OP> solver_impl_type;
273 BELOS_TEST_SOLVER( "Block GMRES" );
274 }
275 {
276 typedef Belos::BlockGmresSolMgr<ST, MV, OP> solver_impl_type;
277 BELOS_TEST_SOLVER( "Block GMRES" );
278 }
279 {
280 typedef Belos::BlockCGSolMgr<ST, MV, OP> solver_impl_type;
281 BELOS_TEST_SOLVER( "Block CG" );
282 }
283 {
284 typedef Belos::FixedPointSolMgr<ST, MV, OP> solver_impl_type;
285 BELOS_TEST_SOLVER( "Fixed Point" );
286 }
287
288 // FIXME (mfh 05 Aug 2015) When setting "Verbosity" and/or "Output
289 // Style", LSQR throws:
290 //
291 // .../packages/belos/src/BelosStatusTestResNormOutput.hpp:232:
292 //
293 // Throw test that evaluated to true: tmpComboTest == Teuchos::null
294 // StatusTestResNormOutput(): test must be Belos::StatusTest[MaxIters|ResNorm|Combo].
295 if (false) {
296 typedef Belos::LSQRSolMgr<ST, MV, OP> solver_impl_type;
297 BELOS_TEST_SOLVER( "LSQR" );
298 }
299
300 {
301 typedef Belos::PCPGSolMgr<ST, MV, OP> solver_impl_type;
302 BELOS_TEST_SOLVER( "PCPG" );
303 }
304 {
305 typedef Belos::RCGSolMgr<ST, MV, OP> solver_impl_type;
306 BELOS_TEST_SOLVER( "RCG" );
307 }
308 {
309 typedef Belos::BiCGStabSolMgr<ST, MV, OP> solver_impl_type;
310 BELOS_TEST_SOLVER( "BiCGStab" );
311 }
312 // Make sure that the factory is case insensitive (Bug 6388).
313 {
314 typedef Belos::BiCGStabSolMgr<ST, MV, OP> solver_impl_type;
315 BELOS_TEST_SOLVER( "bicgstab" );
316 }
317
318#if 1
319 if (success) {
320 out << endl << "Test SUCCEEDED!" << endl;
321 }
322 else {
323 out << endl << "Test FAILED!" << endl
324 << "Solvers that failed: [";
325 for (size_t k = 0; k < failedSolvers.size (); ++k) {
326 out << "\"" << failedSolvers[k] << "\"";
327 if (k + 1 < failedSolvers.size ()) {
328 out << ", ";
329 }
330 }
331 out << "]" << endl;
332 }
333#else
334 if (! success) {
335 out << endl << "*** Solvers that failed: ";
336 out << "[";
337 for (size_t k = 0; k < failedSolvers.size (); ++k) {
338 out << "\"" << failedSolvers[k] << "\"";
339 if (k + 1 < failedSolvers.size ()) {
340 out << ", ";
341 }
342 }
343 out << "]" << endl;
344 }
345#endif // 0
346}
347
348// Repeat the above test for the float scalar type.
349TEUCHOS_UNIT_TEST( Factory, Bug6383_Float )
350{
351 using std::endl;
352 typedef float ST;
353 typedef Belos::MultiVec<ST> MV;
354 typedef Belos::Operator<ST> OP;
355 typedef Belos::SolverManager<ST, MV, OP> solver_base_type;
356 typedef Belos::SolverFactory<ST, MV, OP> factory_type;
357
358 Teuchos::OSTab tab0 (out);
359 out << "Test for Bug 6383" << endl;
360 Teuchos::OSTab tab1 (out);
361
362 // List of names of solvers that failed the test.
363 std::vector<std::string> failedSolvers;
364
365 {
366 typedef Belos::GCRODRSolMgr<ST, MV, OP> solver_impl_type;
367 BELOS_TEST_SOLVER( "GCRODR" );
368 }
369 {
370 typedef Belos::PseudoBlockGmresSolMgr<ST, MV, OP> solver_impl_type;
371 BELOS_TEST_SOLVER( "GMRES" );
372 }
373 // Make sure that the factory is case insensitive (Bug 6388).
374 {
375 typedef Belos::PseudoBlockGmresSolMgr<ST, MV, OP> solver_impl_type;
376 BELOS_TEST_SOLVER( "gmres" );
377 }
378 {
379 typedef Belos::PseudoBlockCGSolMgr<ST, MV, OP> solver_impl_type;
380 BELOS_TEST_SOLVER( "CG" );
381 }
382 // Make sure that the factory is case insensitive (Bug 6388).
383 {
384 typedef Belos::PseudoBlockCGSolMgr<ST, MV, OP> solver_impl_type;
385 BELOS_TEST_SOLVER( "cg" );
386 }
387 {
388 typedef Belos::BlockGmresSolMgr<ST, MV, OP> solver_impl_type;
389 BELOS_TEST_SOLVER( "Block GMRES" );
390 }
391 {
392 typedef Belos::BlockGmresSolMgr<ST, MV, OP> solver_impl_type;
393 BELOS_TEST_SOLVER( "Block GMRES" );
394 }
395 {
396 typedef Belos::BlockCGSolMgr<ST, MV, OP> solver_impl_type;
397 BELOS_TEST_SOLVER( "Block CG" );
398 }
399 {
400 typedef Belos::FixedPointSolMgr<ST, MV, OP> solver_impl_type;
401 BELOS_TEST_SOLVER( "Fixed Point" );
402 }
403
404 // FIXME (mfh 05 Aug 2015) When setting "Verbosity" and/or "Output
405 // Style", LSQR throws:
406 //
407 // .../packages/belos/src/BelosStatusTestResNormOutput.hpp:232:
408 //
409 // Throw test that evaluated to true: tmpComboTest == Teuchos::null
410 // StatusTestResNormOutput(): test must be Belos::StatusTest[MaxIters|ResNorm|Combo].
411 if (false) {
412 typedef Belos::LSQRSolMgr<ST, MV, OP> solver_impl_type;
413 BELOS_TEST_SOLVER( "LSQR" );
414 }
415
416 {
417 typedef Belos::PCPGSolMgr<ST, MV, OP> solver_impl_type;
418 BELOS_TEST_SOLVER( "PCPG" );
419 }
420 {
421 typedef Belos::RCGSolMgr<ST, MV, OP> solver_impl_type;
422 BELOS_TEST_SOLVER( "RCG" );
423 }
424 {
425 typedef Belos::BiCGStabSolMgr<ST, MV, OP> solver_impl_type;
426 BELOS_TEST_SOLVER( "BiCGStab" );
427 }
428 // Make sure that the factory is case insensitive (Bug 6388).
429 {
430 typedef Belos::BiCGStabSolMgr<ST, MV, OP> solver_impl_type;
431 BELOS_TEST_SOLVER( "bicgstab" );
432 }
433
434#if 1
435 if (success) {
436 out << endl << "Test SUCCEEDED!" << endl;
437 }
438 else {
439 out << endl << "Test FAILED!" << endl
440 << "Solvers that failed: [";
441 for (size_t k = 0; k < failedSolvers.size (); ++k) {
442 out << "\"" << failedSolvers[k] << "\"";
443 if (k + 1 < failedSolvers.size ()) {
444 out << ", ";
445 }
446 }
447 out << "]" << endl;
448 }
449#else
450 if (! success) {
451 out << endl << "*** Solvers that failed: ";
452 out << "[";
453 for (size_t k = 0; k < failedSolvers.size (); ++k) {
454 out << "\"" << failedSolvers[k] << "\"";
455 if (k + 1 < failedSolvers.size ()) {
456 out << ", ";
457 }
458 }
459 out << "]" << endl;
460 }
461#endif // 0
462}
The Belos::BiCGStabSolMgr provides a solver manager for the BiCGStab linear solver.
The Belos::BlockCGSolMgr provides a solver manager for the BlockCG linear solver.
The Belos::BlockGmresSolMgr provides a solver manager for the BlockGmres linear solver.
The Belos::FixedPointSolMgr provides a solver manager for the FixedPoint linear solver.
Declaration and definition of Belos::GCRODRSolMgr, which implements the GCRODR (recycling GMRES) solv...
LSQRSolMgr: interface to the LSQR method.
Class which describes the linear problem to be solved by the iterative solver.
Declaration and definition of Belos::PCPGSolMgr (PCPG iterative linear solver).
The Belos::PseudoBlockCGSolMgr provides a solver manager for the BlockCG linear solver.
The Belos::PseudoBlockGmresSolMgr provides a solver manager for the BlockGmres linear solver.
The Belos::RCGSolMgr provides a solver manager for the RCG (Recycling Conjugate Gradient) linear solv...
TEUCHOS_UNIT_TEST(Factory, Bug6383)
Definition Factory.cpp:233
#define BELOS_TEST_SOLVER(SOLVER_NAME)
Definition Factory.cpp:211
void testSolver(bool &success, Teuchos::FancyOStream &out, const std::string &solverName)
Definition Factory.cpp:65
The Belos::BiCGStabSolMgr provides a powerful and fully-featured solver manager over the pseudo-block...
The Belos::BlockCGSolMgr provides a powerful and fully-featured solver manager over the CG and BlockC...
Interface to Block GMRES and Flexible GMRES.
The Belos::FixedPointSolMgr provides a powerful and fully-featured solver manager over the FixedPoint...
Implementation of the GCRODR (Recycling GMRES) iterative linear solver.
LSQR method (for linear systems and linear least-squares problems).
Interface for multivectors used by Belos' linear solvers.
Alternative run-time polymorphic interface for operators.
PCPG iterative linear solver.
The Belos::PseudoBlockCGSolMgr provides a powerful and fully-featured solver manager over the pseudo-...
Interface to standard and "pseudoblock" GMRES.
Implementation of the RCG (Recycling Conjugate Gradient) iterative linear solver.
The Belos::SolverManager is a templated virtual base class that defines the basic interface that any ...
typename ::Belos::Impl::SolverFactorySelector< SC, MV, OP >::type SolverFactory