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