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 // @HEADER
2 // *****************************************************************************
3 // Stratimikos: Thyra-based strategies for linear solvers
4 //
5 // Copyright 2006 NTESS and the Stratimikos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef THYRA_AMESOS2_LINEAR_OP_WITH_SOLVE_FACTORY_HPP
11 #define THYRA_AMESOS2_LINEAR_OP_WITH_SOLVE_FACTORY_HPP
12 
14 
15 #include "Thyra_Amesos2LinearOpWithSolve.hpp"
16 #include "Amesos2.hpp"
17 #include "Amesos2_Details_LinearSolverFactory.hpp"
18 #include "Amesos2_Version.hpp"
19 #include "Amesos2_Factory.hpp"
20 #include "Thyra_TpetraLinearOp.hpp"
22 #include "Thyra_DefaultDiagonalLinearOp.hpp"
23 #include "Teuchos_dyn_cast.hpp"
24 #include "Teuchos_TimeMonitor.hpp"
27 
28 namespace Thyra {
29 
30 
31 // Parameter names for Paramter List
32 
33 template<typename Scalar>
34 const std::string Amesos2LinearOpWithSolveFactory<Scalar>::SolverType_name
35  = "Solver Type";
36 
37 template<typename Scalar>
38 const std::string Amesos2LinearOpWithSolveFactory<Scalar>::RefactorizationPolicy_name
39  = "Refactorization Policy";
40 
41 template<typename Scalar>
42 const std::string Amesos2LinearOpWithSolveFactory<Scalar>::ThrowOnPreconditionerInput_name
43  = "Throw on Preconditioner Input";
44 
45 template<typename Scalar>
46 const std::string Amesos2LinearOpWithSolveFactory<Scalar>::Amesos2_Settings_name
47  = "Amesos2 Settings";
48 
49 // Constructors/initializers/accessors
50 
51 template<typename Scalar>
53 {
54 #ifdef TEUCHOS_DEBUG
55  if(paramList_.get())
56  paramList_->validateParameters(
57  *this->getValidParameters(),0 // Only validate this level for now!
58  );
59 #endif
60 }
61 
62 template<typename Scalar>
64  const Amesos2::ESolverType solverType,
65  const Amesos2::ERefactorizationPolicy refactorizationPolicy,
66  const bool throwOnPrecInput
67  )
68  :solverType_(solverType)
69  ,refactorizationPolicy_(refactorizationPolicy)
70  ,throwOnPrecInput_(throwOnPrecInput)
71 {
72 }
73 
74 // Overridden from LinearOpWithSolveFactoryBase
75 
76 template<typename Scalar>
78  const LinearOpSourceBase<Scalar> &fwdOpSrc
79  ) const
80 {
82  fwdOp = fwdOpSrc.getOp();
83  auto tpetraFwdOp = ConverterT::getConstTpetraOperator(fwdOp);
84  if ( ! dynamic_cast<const MAT * >(&*tpetraFwdOp) )
85  return false;
86  return true;
87 }
88 
89 template<typename Scalar>
92 {
94 }
95 
96 template<typename Scalar>
98  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
99  LinearOpWithSolveBase<Scalar> *Op,
100  const ESupportSolveUse /* supportSolveUse */
101  ) const
102 {
103  THYRA_FUNC_TIME_MONITOR("Stratimikos: Amesos2LOWSF");
104 
105  TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
106  TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
107  TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc->getOp().get()==NULL);
108  RCP<const LinearOpBase<Scalar> > fwdOp = fwdOpSrc->getOp();
109 
111  out = Teuchos::VerboseObjectBase::getDefaultOStream();
112 
113  //
114  // Unwrap and get the forward Tpetra::Operator object
115  //
116  auto tpetraFwdOp = ConverterT::getConstTpetraOperator(fwdOp);
117  auto tpetraCrsMat = Teuchos::rcp_dynamic_cast<const MAT>(tpetraFwdOp);
118  // Get the Amesos2LinearOpWithSolve object
121 
122  //
123  // Determine if we must start over or not
124  //
125  bool startOver = ( amesos2Op->get_amesos2Solver()==Teuchos::null );
126  if (!startOver) {
127  auto oldTpetraFwdOp = ConverterT::getConstTpetraOperator(amesos2Op->get_fwdOp());
128  startOver =
129  (
130  tpetraFwdOp.get() != oldTpetraFwdOp.get()
131  // Assuming that, like Amesos, Amesos2 must start over if the matrix changes
132  );
133  }
134  //
135  // Update the amesos2 solver
136  //
137  if (startOver) {
138  //
139  // This LOWS object has not be initialized yet or is not compatible with the existing
140  //
141  // so this is where we setup everything from the ground up.
142 
143  // Create the concrete solver
144  Teuchos::RCP<Solver> amesos2Solver;
145  {
146  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:InitConstruct",
147  InitConstruct);
148  switch(solverType_) {
150  amesos2Solver = ::Amesos2::create<MAT,MV>("klu2", tpetraCrsMat);
151  break;
152 #ifdef HAVE_AMESOS2_LAPACK
154  amesos2Solver = ::Amesos2::create<MAT,MV>("lapack", tpetraCrsMat);
155  break;
156 #endif
157 #ifdef HAVE_AMESOS2_SUPERLU
158  case Thyra::Amesos2::SUPERLU:
159  amesos2Solver = ::Amesos2::create<MAT,MV>("superlu", tpetraCrsMat);
160  break;
161 #endif
162 #ifdef HAVE_AMESOS2_SUPERLUMT
163  case Thyra::Amesos2::SUPERLUMT:
164  amesos2Solver = ::Amesos2::create<MAT,MV>("superlumt", tpetraCrsMat);
165  break;
166 #endif
167 #ifdef HAVE_AMESOS2_SUPERLUDIST
168  case Thyra::Amesos2::SUPERLUDIST:
169  amesos2Solver = ::Amesos2::create<MAT,MV>("superludist", tpetraCrsMat);
170  break;
171 # endif
172 #ifdef HAVE_AMESOS2_PARDISO_MKL
173  case Thyra::Amesos2::PARDISO_MKL:
174  amesos2Solver = ::Amesos2::create<MAT,MV>("pardiso_mkl", tpetraCrsMat);
175  break;
176 #endif
177 #ifdef HAVE_AMESOS2_CHOLMOD
178  case Thyra::Amesos2::CHOLMOD:
179  amesos2Solver = ::Amesos2::create<MAT,MV>("cholmod", tpetraCrsMat);
180  break;
181 #endif
182 #ifdef HAVE_AMESOS2_BASKER
183  case Thyra::Amesos2::BASKER:
184  amesos2Solver = ::Amesos2::create<MAT,MV>("basker", tpetraCrsMat);
185  break;
186 #endif
187 #ifdef HAVE_AMESOS2_MUMPS
188  case Thyra::Amesos2::MUMPS:
189  amesos2Solver = ::Amesos2::create<MAT,MV>("mumps", tpetraCrsMat);
190  break;
191 #endif
192  default:
194  true, std::logic_error
195  ,"Error, the solver type ID = " << solverType_ << " is invalid!"
196  );
197  }
198  }
199 
200  // Do the initial factorization
201  {
202  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:Symbolic", Symbolic);
203  amesos2Solver->symbolicFactorization();
204  }
205  {
206  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:Factor", Factor);
207  amesos2Solver->numericFactorization();
208  }
209 
210  // filter out the Stratimikos adapter parameters and hand
211  // parameters down into the Solver
213  = Teuchos::rcp(new Teuchos::ParameterList(*paramList_));
214  dup_list->remove(SolverType_name);
215  dup_list->remove(RefactorizationPolicy_name);
216  dup_list->remove(ThrowOnPreconditionerInput_name);
217  dup_list->remove("VerboseObject");
218  amesos2Solver->setParameters(dup_list);
219 
220  // Initialize the LOWS object and we are done!
221  amesos2Op->initialize(fwdOp,fwdOpSrc,amesos2Solver);
222  }
223  else {
224  //
225  // This LOWS object has already be initialized once so we must just reset
226  // the matrix and refactor it.
227  auto amesos2Solver = amesos2Op->get_amesos2Solver();
228 
229  // set
230  amesos2Solver->setA(tpetraCrsMat);
231 
232  // Do the initial factorization
233  if(refactorizationPolicy_ == Amesos2::REPIVOT_ON_REFACTORIZATION) {
234  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:Symbolic", Symbolic);
235  amesos2Solver->symbolicFactorization();
236  }
237  {
238  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF::Factor", Factor);
239  amesos2Solver->numericFactorization();
240  }
241 
242  // Initialize the LOWS object and we are done!
243  amesos2Op->initialize(fwdOp,fwdOpSrc,amesos2Solver);
244  }
245  amesos2Op->setOStream(this->getOStream());
246  amesos2Op->setVerbLevel(this->getVerbLevel());
247 }
248 
249 template<typename Scalar>
250 bool Amesos2LinearOpWithSolveFactory<Scalar>::supportsPreconditionerInputType(const EPreconditionerInputType /* precOpType */) const
251 {
252  return false;
253 }
254 
255 template<typename Scalar>
257  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
258  const RCP<const PreconditionerBase<Scalar> > &/* prec */,
259  LinearOpWithSolveBase<Scalar> *Op,
260  const ESupportSolveUse supportSolveUse
261  ) const
262 {
264  this->throwOnPrecInput_, std::logic_error,
265  "Error, the concrete implementation described as \'"<<this->description()
266  <<"\' does not support preconditioners"
267  " and has been configured to throw this exception when the"
268  " initializePreconditionedOp(...) function is called!"
269  );
270  this->initializeOp(fwdOpSrc,Op,supportSolveUse); // Ignore the preconditioner!
271 }
272 
273 template<typename Scalar>
275  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
276  const RCP<const LinearOpSourceBase<Scalar> > &/* approxFwdOpSrc */,
277  LinearOpWithSolveBase<Scalar> *Op,
278  const ESupportSolveUse supportSolveUse
279  ) const
280 {
282  this->throwOnPrecInput_, std::logic_error,
283  "Error, the concrete implementation described as \'"<<this->description()
284  <<"\' does not support preconditioners"
285  " and has been configured to throw this exception when the"
286  " initializePreconditionedOp(...) function is called!"
287  );
288  this->initializeOp(fwdOpSrc,Op,supportSolveUse); // Ignore the preconditioner!
289 }
290 
291 template<typename Scalar>
293  LinearOpWithSolveBase<Scalar> *Op,
294  RCP<const LinearOpSourceBase<Scalar> > *fwdOpSrc,
295  RCP<const PreconditionerBase<Scalar> > *prec,
296  RCP<const LinearOpSourceBase<Scalar> > *approxFwdOpSrc,
297  ESupportSolveUse * /* supportSolveUse */
298  ) const
299 {
300 #ifdef TEUCHOS_DEBUG
301  TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
302 #endif
306  _fwdOpSrc = amesos2Op->extract_fwdOpSrc(); // Will be null if uninitialized!
307  if(fwdOpSrc) *fwdOpSrc = _fwdOpSrc; // It is fine if the client does not want this object back!
308  if(prec) *prec = Teuchos::null; // We never keep a preconditioner!
309  if(approxFwdOpSrc) *approxFwdOpSrc = Teuchos::null; // never keep approx fwd op!
310 }
311 
312 // Overridden from ParameterListAcceptor
313 
314 template<typename Scalar>
316  RCP<Teuchos::ParameterList> const& paramList
317  )
318 {
319  TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
320  // Only validate this level for now here (expect Amesos2 to do its own
321  // validation?)
322  paramList->validateParameters(*this->getValidParameters(),0);
323  paramList_ = paramList;
324  solverType_ =
326  paramList_->get(
327  SolverType_name
328  ,Amesos2::toString(solverType_)
329  )
330  ,paramList_->name()+"->"+SolverType_name
331  );
332  refactorizationPolicy_ =
334  paramList_->get(
335  RefactorizationPolicy_name
336  ,Amesos2::toString(refactorizationPolicy_)
337  )
338  ,paramList_->name()+"->"+RefactorizationPolicy_name
339  );
340  throwOnPrecInput_ = paramList_->get(ThrowOnPreconditionerInput_name,throwOnPrecInput_);
341  Teuchos::readVerboseObjectSublist(&*paramList_,this);
342 }
343 
344 template<typename Scalar>
347 {
348  return paramList_;
349 }
350 
351 template<typename Scalar>
354 {
355  RCP<Teuchos::ParameterList> _paramList = paramList_;
356  paramList_ = Teuchos::null;
357  return _paramList;
358 }
359 
360 template<typename Scalar>
363 {
364  return paramList_;
365 }
366 
367 template<typename Scalar>
370 {
371  return generateAndGetValidParameters();
372 }
373 
374 // Public functions overridden from Teuchos::Describable
375 
376 template<typename Scalar>
378 {
379  std::ostringstream oss;
380  oss << "Thyra::Amesos2LinearOpWithSolveFactory{";
381  oss << "solverType=" << toString(solverType_);
382  oss << "}";
383  return oss.str();
384 }
385 
386 // private
387 
388 template<typename Scalar>
391 {
392  static RCP<Teuchos::ParameterList> validParamList;
393  if (validParamList.get()==NULL) {
394  validParamList = Teuchos::rcp(new Teuchos::ParameterList("Amesos2"));
395  validParamList->set(SolverType_name, Thyra::Amesos2::solverTypeNames[0]);
396  validParamList->set(RefactorizationPolicy_name,
398  validParamList->set(ThrowOnPreconditionerInput_name,bool(true));
399  Teuchos::setupVerboseObjectSublist(&*validParamList);
400  }
401  return validParamList;
402 }
403 
404 } // namespace Thyra
405 
406 #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
#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
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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...