Stratimikos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_Amesos2LinearOpWithSolveFactory_def.hpp
Go to the documentation of this file.
1 /*
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Stratimikos: Thyra-based strategies for linear solvers
6 // Copyright (2006) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
39 //
40 // ***********************************************************************
41 // @HEADER
42 */
43 
44 #ifndef THYRA_AMESOS2_LINEAR_OP_WITH_SOLVE_FACTORY_HPP
45 #define THYRA_AMESOS2_LINEAR_OP_WITH_SOLVE_FACTORY_HPP
46 
48 
49 #include "Thyra_Amesos2LinearOpWithSolve.hpp"
50 #include "Amesos2.hpp"
51 #include "Amesos2_Details_LinearSolverFactory.hpp"
52 #include "Amesos2_Version.hpp"
53 #include "Amesos2_Factory.hpp"
54 #include "Thyra_TpetraLinearOp.hpp"
56 #include "Thyra_DefaultDiagonalLinearOp.hpp"
57 #include "Teuchos_dyn_cast.hpp"
58 #include "Teuchos_TimeMonitor.hpp"
61 
62 namespace Thyra {
63 
64 
65 // Parameter names for Paramter List
66 
67 template<typename Scalar>
68 const std::string Amesos2LinearOpWithSolveFactory<Scalar>::SolverType_name
69  = "Solver Type";
70 
71 template<typename Scalar>
72 const std::string Amesos2LinearOpWithSolveFactory<Scalar>::RefactorizationPolicy_name
73  = "Refactorization Policy";
74 
75 template<typename Scalar>
76 const std::string Amesos2LinearOpWithSolveFactory<Scalar>::ThrowOnPreconditionerInput_name
77  = "Throw on Preconditioner Input";
78 
79 template<typename Scalar>
80 const std::string Amesos2LinearOpWithSolveFactory<Scalar>::Amesos2_Settings_name
81  = "Amesos2 Settings";
82 
83 // Constructors/initializers/accessors
84 
85 template<typename Scalar>
87 {
88 #ifdef TEUCHOS_DEBUG
89  if(paramList_.get())
90  paramList_->validateParameters(
91  *this->getValidParameters(),0 // Only validate this level for now!
92  );
93 #endif
94 }
95 
96 template<typename Scalar>
98  const Amesos2::ESolverType solverType,
99  const Amesos2::ERefactorizationPolicy refactorizationPolicy,
100  const bool throwOnPrecInput
101  )
102  :solverType_(solverType)
103  ,refactorizationPolicy_(refactorizationPolicy)
104  ,throwOnPrecInput_(throwOnPrecInput)
105 {
106 }
107 
108 // Overridden from LinearOpWithSolveFactoryBase
109 
110 template<typename Scalar>
112  const LinearOpSourceBase<Scalar> &fwdOpSrc
113  ) const
114 {
116  fwdOp = fwdOpSrc.getOp();
117  auto tpetraFwdOp = ConverterT::getConstTpetraOperator(fwdOp);
118  if ( ! dynamic_cast<const MAT * >(&*tpetraFwdOp) )
119  return false;
120  return true;
121 }
122 
123 template<typename Scalar>
126 {
128 }
129 
130 template<typename Scalar>
132  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
133  LinearOpWithSolveBase<Scalar> *Op,
134  const ESupportSolveUse /* supportSolveUse */
135  ) const
136 {
137  THYRA_FUNC_TIME_MONITOR("Stratimikos: Amesos2LOWSF");
138 
139  TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
140  TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
141  TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc->getOp().get()==NULL);
142  RCP<const LinearOpBase<Scalar> > fwdOp = fwdOpSrc->getOp();
143 
145  out = Teuchos::VerboseObjectBase::getDefaultOStream();
146 
147  //
148  // Unwrap and get the forward Tpetra::Operator object
149  //
150  auto tpetraFwdOp = ConverterT::getConstTpetraOperator(fwdOp);
151  auto tpetraCrsMat = Teuchos::rcp_dynamic_cast<const MAT>(tpetraFwdOp);
152  // Get the Amesos2LinearOpWithSolve object
155 
156  //
157  // Determine if we must start over or not
158  //
159  bool startOver = ( amesos2Op->get_amesos2Solver()==Teuchos::null );
160  if (!startOver) {
161  auto oldTpetraFwdOp = ConverterT::getConstTpetraOperator(amesos2Op->get_fwdOp());
162  startOver =
163  (
164  tpetraFwdOp.get() != oldTpetraFwdOp.get()
165  // Assuming that, like Amesos, Amesos2 must start over if the matrix changes
166  );
167  }
168  //
169  // Update the amesos2 solver
170  //
171  if (startOver) {
172  //
173  // This LOWS object has not be initialized yet or is not compatible with the existing
174  //
175  // so this is where we setup everything from the ground up.
176 
177  // Create the concrete solver
178  Teuchos::RCP<Solver> amesos2Solver;
179  {
180  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:InitConstruct",
181  InitConstruct);
182  switch(solverType_) {
184  amesos2Solver = ::Amesos2::create<MAT,MV>("klu2", tpetraCrsMat);
185  break;
186 #ifdef HAVE_AMESOS2_LAPACK
188  amesos2Solver = ::Amesos2::create<MAT,MV>("lapack", tpetraCrsMat);
189  break;
190 #endif
191 #ifdef HAVE_AMESOS2_SUPERLU
192  case Thyra::Amesos2::SUPERLU:
193  amesos2Solver = ::Amesos2::create<MAT,MV>("superlu", tpetraCrsMat);
194  break;
195 #endif
196 #ifdef HAVE_AMESOS2_SUPERLUMT
197  case Thyra::Amesos2::SUPERLUMT:
198  amesos2Solver = ::Amesos2::create<MAT,MV>("superlumt", tpetraCrsMat);
199  break;
200 #endif
201 #ifdef HAVE_AMESOS2_SUPERLUDIST
202  case Thyra::Amesos2::SUPERLUDIST:
203  amesos2Solver = ::Amesos2::create<MAT,MV>("superludist", tpetraCrsMat);
204  break;
205 # endif
206 #ifdef HAVE_AMESOS2_PARDISO_MKL
207  case Thyra::Amesos2::PARDISO_MKL:
208  amesos2Solver = ::Amesos2::create<MAT,MV>("pardiso_mkl", tpetraCrsMat);
209  break;
210 #endif
211 #ifdef HAVE_AMESOS2_CHOLMOD
212  case Thyra::Amesos2::CHOLMOD:
213  amesos2Solver = ::Amesos2::create<MAT,MV>("cholmod", tpetraCrsMat);
214  break;
215 #endif
216 #ifdef HAVE_AMESOS2_BASKER
217  case Thyra::Amesos2::BASKER:
218  amesos2Solver = ::Amesos2::create<MAT,MV>("basker", tpetraCrsMat);
219  break;
220 #endif
221 #ifdef HAVE_AMESOS2_MUMPS
222  case Thyra::Amesos2::MUMPS:
223  amesos2Solver = ::Amesos2::create<MAT,MV>("mumps", tpetraCrsMat);
224  break;
225 #endif
226  default:
228  true, std::logic_error
229  ,"Error, the solver type ID = " << solverType_ << " is invalid!"
230  );
231  }
232  }
233 
234  // Do the initial factorization
235  {
236  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:Symbolic", Symbolic);
237  amesos2Solver->symbolicFactorization();
238  }
239  {
240  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:Factor", Factor);
241  amesos2Solver->numericFactorization();
242  }
243 
244  // filter out the Stratimikos adapter parameters and hand
245  // parameters down into the Solver
247  = Teuchos::rcp(new Teuchos::ParameterList(*paramList_));
248  dup_list->remove(SolverType_name);
249  dup_list->remove(RefactorizationPolicy_name);
250  dup_list->remove(ThrowOnPreconditionerInput_name);
251  dup_list->remove("VerboseObject");
252  amesos2Solver->setParameters(dup_list);
253 
254  // Initialize the LOWS object and we are done!
255  amesos2Op->initialize(fwdOp,fwdOpSrc,amesos2Solver);
256  }
257  else {
258  //
259  // This LOWS object has already be initialized once so we must just reset
260  // the matrix and refactor it.
261  auto amesos2Solver = amesos2Op->get_amesos2Solver();
262 
263  // set
264  amesos2Solver->setA(tpetraCrsMat);
265 
266  // Do the initial factorization
267  if(refactorizationPolicy_ == Amesos2::REPIVOT_ON_REFACTORIZATION) {
268  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:Symbolic", Symbolic);
269  amesos2Solver->symbolicFactorization();
270  }
271  {
272  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF::Factor", Factor);
273  amesos2Solver->numericFactorization();
274  }
275 
276  // Initialize the LOWS object and we are done!
277  amesos2Op->initialize(fwdOp,fwdOpSrc,amesos2Solver);
278  }
279  amesos2Op->setOStream(this->getOStream());
280  amesos2Op->setVerbLevel(this->getVerbLevel());
281 }
282 
283 template<typename Scalar>
284 bool Amesos2LinearOpWithSolveFactory<Scalar>::supportsPreconditionerInputType(const EPreconditionerInputType /* precOpType */) const
285 {
286  return false;
287 }
288 
289 template<typename Scalar>
291  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
292  const RCP<const PreconditionerBase<Scalar> > &/* prec */,
293  LinearOpWithSolveBase<Scalar> *Op,
294  const ESupportSolveUse supportSolveUse
295  ) const
296 {
298  this->throwOnPrecInput_, std::logic_error,
299  "Error, the concrete implementation described as \'"<<this->description()
300  <<"\' does not support preconditioners"
301  " and has been configured to throw this exception when the"
302  " initializePreconditionedOp(...) function is called!"
303  );
304  this->initializeOp(fwdOpSrc,Op,supportSolveUse); // Ignore the preconditioner!
305 }
306 
307 template<typename Scalar>
309  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
310  const RCP<const LinearOpSourceBase<Scalar> > &/* approxFwdOpSrc */,
311  LinearOpWithSolveBase<Scalar> *Op,
312  const ESupportSolveUse supportSolveUse
313  ) const
314 {
316  this->throwOnPrecInput_, std::logic_error,
317  "Error, the concrete implementation described as \'"<<this->description()
318  <<"\' does not support preconditioners"
319  " and has been configured to throw this exception when the"
320  " initializePreconditionedOp(...) function is called!"
321  );
322  this->initializeOp(fwdOpSrc,Op,supportSolveUse); // Ignore the preconditioner!
323 }
324 
325 template<typename Scalar>
327  LinearOpWithSolveBase<Scalar> *Op,
328  RCP<const LinearOpSourceBase<Scalar> > *fwdOpSrc,
329  RCP<const PreconditionerBase<Scalar> > *prec,
330  RCP<const LinearOpSourceBase<Scalar> > *approxFwdOpSrc,
331  ESupportSolveUse * /* supportSolveUse */
332  ) const
333 {
334 #ifdef TEUCHOS_DEBUG
335  TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
336 #endif
340  _fwdOpSrc = amesos2Op->extract_fwdOpSrc(); // Will be null if uninitialized!
341  if(fwdOpSrc) *fwdOpSrc = _fwdOpSrc; // It is fine if the client does not want this object back!
342  if(prec) *prec = Teuchos::null; // We never keep a preconditioner!
343  if(approxFwdOpSrc) *approxFwdOpSrc = Teuchos::null; // never keep approx fwd op!
344 }
345 
346 // Overridden from ParameterListAcceptor
347 
348 template<typename Scalar>
350  RCP<Teuchos::ParameterList> const& paramList
351  )
352 {
353  TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
354  // Only validate this level for now here (expect Amesos2 to do its own
355  // validation?)
356  paramList->validateParameters(*this->getValidParameters(),0);
357  paramList_ = paramList;
358  solverType_ =
360  paramList_->get(
361  SolverType_name
362  ,Amesos2::toString(solverType_)
363  )
364  ,paramList_->name()+"->"+SolverType_name
365  );
366  refactorizationPolicy_ =
368  paramList_->get(
369  RefactorizationPolicy_name
370  ,Amesos2::toString(refactorizationPolicy_)
371  )
372  ,paramList_->name()+"->"+RefactorizationPolicy_name
373  );
374  throwOnPrecInput_ = paramList_->get(ThrowOnPreconditionerInput_name,throwOnPrecInput_);
375  Teuchos::readVerboseObjectSublist(&*paramList_,this);
376 }
377 
378 template<typename Scalar>
381 {
382  return paramList_;
383 }
384 
385 template<typename Scalar>
388 {
389  RCP<Teuchos::ParameterList> _paramList = paramList_;
390  paramList_ = Teuchos::null;
391  return _paramList;
392 }
393 
394 template<typename Scalar>
397 {
398  return paramList_;
399 }
400 
401 template<typename Scalar>
404 {
405  return generateAndGetValidParameters();
406 }
407 
408 // Public functions overridden from Teuchos::Describable
409 
410 template<typename Scalar>
412 {
413  std::ostringstream oss;
414  oss << "Thyra::Amesos2LinearOpWithSolveFactory{";
415  oss << "solverType=" << toString(solverType_);
416  oss << "}";
417  return oss.str();
418 }
419 
420 // private
421 
422 template<typename Scalar>
425 {
426  static RCP<Teuchos::ParameterList> validParamList;
427  if (validParamList.get()==NULL) {
428  validParamList = Teuchos::rcp(new Teuchos::ParameterList("Amesos2"));
429  validParamList->set(SolverType_name, Thyra::Amesos2::solverTypeNames[0]);
430  validParamList->set(RefactorizationPolicy_name,
432  validParamList->set(ThrowOnPreconditionerInput_name,bool(true));
433  Teuchos::setupVerboseObjectSublist(&*validParamList);
434  }
435  return validParamList;
436 }
437 
438 } // namespace Thyra
439 
440 #endif // THYRA_AMESOS2_LINEAR_OP_WITH_SOLVE_FACTORY_HPP
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
const std::string toString(const EAdjointEpetraOp adjointEpetraOp)
static Teuchos::RCP< const Teuchos::ParameterList > generateAndGetValidParameters()
Teuchos::RCP< LinearOpWithSolveBase< Scalar > > createOp() const
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void initializeOp(const Teuchos::RCP< const LinearOpSourceBase< Scalar > > &fwdOpSrc, LinearOpWithSolveBase< Scalar > *Op, const ESupportSolveUse supportSolveUse) const
Concrete LinearOpWithSolveBase subclass in terms of Amesos2.
T * get() const
void initializePreconditionedOp(const Teuchos::RCP< const LinearOpSourceBase< Scalar > > &fwdOpSrc, const Teuchos::RCP< const PreconditionerBase< Scalar > > &prec, LinearOpWithSolveBase< Scalar > *Op, const ESupportSolveUse supportSolveUse) const
Throws exception if this-&gt;throwOnPrecInput()==true and calls this-&gt;initializeOp(fwdOpSrc,Op) otherwise.
Completely new pivoting will be used on refactorizations!
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
ERefactorizationPolicy
The policy used on refactoring a matrix.
int get(const std::string &option, const std::string &groupName="") const
typename Amesos2LinearOpWithSolve< Scalar >::MAT MAT
bool remove(std::string const &name, bool throwIfNotExists=true)
const char * solverTypeNames[numSolverTypes]
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const &paramList)
T_To & dyn_cast(T_From &from)
const char * toString(const ESolverType solverType)
Teuchos::StringToIntMap refactorizationPolicyNameToEnumMap
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
bool isCompatible(const LinearOpSourceBase< Scalar > &fwdOpSrc) const
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
bool supportsPreconditionerInputType(const EPreconditionerInputType precOpType) const
Returns false .
Teuchos::StringToIntMap solverTypeNameToEnumMap
Amesos2LinearOpWithSolveFactory(const Amesos2::ESolverType solverType=Amesos2::LAPACK, const Amesos2::ERefactorizationPolicy refactorizationPolicy=Amesos2::REPIVOT_ON_REFACTORIZATION, const bool throwOnPrecInput=true)
Constructor which sets the defaults.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
void uninitializeOp(LinearOpWithSolveBase< Scalar > *Op, Teuchos::RCP< const LinearOpSourceBase< Scalar > > *fwdOpSrc, Teuchos::RCP< const PreconditionerBase< Scalar > > *prec, Teuchos::RCP< const LinearOpSourceBase< Scalar > > *approxFwdOpSrc, ESupportSolveUse *supportSolveUse) const
Teuchos::RCP< const LinearOpSourceBase< Scalar > > extract_fwdOpSrc()
Extract the forward LinearOpSourceBase&lt;double&gt; object so that it can be modified and remove it from t...