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_CHOLMOD
181  case Thyra::Amesos2::CHOLMOD:
182  amesos2Solver = ::Amesos2::create<MAT,MV>("cholmod", tpetraCrsMat);
183  break;
184 #endif
185 #ifdef HAVE_AMESOS2_BASKER
186  case Thyra::Amesos2::BASKER:
187  amesos2Solver = ::Amesos2::create<MAT,MV>("basker", tpetraCrsMat);
188  break;
189 #endif
190 #ifdef HAVE_AMESOS2_MUMPS
191  case Thyra::Amesos2::MUMPS:
192  amesos2Solver = ::Amesos2::create<MAT,MV>("mumps", tpetraCrsMat);
193  break;
194 #endif
195  default:
197  true, std::logic_error
198  ,"Error, the solver type ID = " << solverType_ << " is invalid!"
199  );
200  }
201  }
202 
203  // Do the initial factorization
204  {
205  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:Symbolic", Symbolic);
206  amesos2Solver->symbolicFactorization();
207  }
208  {
209  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:Factor", Factor);
210  amesos2Solver->numericFactorization();
211  }
212 
213  // filter out the Stratimikos adapter parameters and hand
214  // parameters down into the Solver
216  = Teuchos::rcp(new Teuchos::ParameterList(*paramList_));
217  dup_list->remove(SolverType_name);
218  dup_list->remove(RefactorizationPolicy_name);
219  dup_list->remove(ThrowOnPreconditionerInput_name);
220  dup_list->remove("VerboseObject");
221  amesos2Solver->setParameters(dup_list);
222 
223  // Initialize the LOWS object and we are done!
224  amesos2Op->initialize(fwdOp,fwdOpSrc,amesos2Solver);
225  }
226  else {
227  //
228  // This LOWS object has already be initialized once so we must just reset
229  // the matrix and refactor it.
230  auto amesos2Solver = amesos2Op->get_amesos2Solver();
231 
232  // set
233  amesos2Solver->setA(tpetraCrsMat);
234 
235  // Do the initial factorization
236  if(refactorizationPolicy_ == Amesos2::REPIVOT_ON_REFACTORIZATION) {
237  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF:Symbolic", Symbolic);
238  amesos2Solver->symbolicFactorization();
239  }
240  {
241  THYRA_FUNC_TIME_MONITOR_DIFF("Stratimikos: Amesos2LOWSF::Factor", Factor);
242  amesos2Solver->numericFactorization();
243  }
244 
245  // Initialize the LOWS object and we are done!
246  amesos2Op->initialize(fwdOp,fwdOpSrc,amesos2Solver);
247  }
248  amesos2Op->setOStream(this->getOStream());
249  amesos2Op->setVerbLevel(this->getVerbLevel());
250 }
251 
252 template<typename Scalar>
253 bool Amesos2LinearOpWithSolveFactory<Scalar>::supportsPreconditionerInputType(const EPreconditionerInputType /* precOpType */) const
254 {
255  return false;
256 }
257 
258 template<typename Scalar>
260  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
261  const RCP<const PreconditionerBase<Scalar> > &/* prec */,
262  LinearOpWithSolveBase<Scalar> *Op,
263  const ESupportSolveUse supportSolveUse
264  ) const
265 {
267  this->throwOnPrecInput_, std::logic_error,
268  "Error, the concrete implementation described as \'"<<this->description()
269  <<"\' does not support preconditioners"
270  " and has been configured to throw this exception when the"
271  " initializePreconditionedOp(...) function is called!"
272  );
273  this->initializeOp(fwdOpSrc,Op,supportSolveUse); // Ignore the preconditioner!
274 }
275 
276 template<typename Scalar>
278  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
279  const RCP<const LinearOpSourceBase<Scalar> > &/* approxFwdOpSrc */,
280  LinearOpWithSolveBase<Scalar> *Op,
281  const ESupportSolveUse supportSolveUse
282  ) const
283 {
285  this->throwOnPrecInput_, std::logic_error,
286  "Error, the concrete implementation described as \'"<<this->description()
287  <<"\' does not support preconditioners"
288  " and has been configured to throw this exception when the"
289  " initializePreconditionedOp(...) function is called!"
290  );
291  this->initializeOp(fwdOpSrc,Op,supportSolveUse); // Ignore the preconditioner!
292 }
293 
294 template<typename Scalar>
296  LinearOpWithSolveBase<Scalar> *Op,
297  RCP<const LinearOpSourceBase<Scalar> > *fwdOpSrc,
298  RCP<const PreconditionerBase<Scalar> > *prec,
299  RCP<const LinearOpSourceBase<Scalar> > *approxFwdOpSrc,
300  ESupportSolveUse * /* supportSolveUse */
301  ) const
302 {
303 #ifdef TEUCHOS_DEBUG
304  TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
305 #endif
309  _fwdOpSrc = amesos2Op->extract_fwdOpSrc(); // Will be null if uninitialized!
310  if(fwdOpSrc) *fwdOpSrc = _fwdOpSrc; // It is fine if the client does not want this object back!
311  if(prec) *prec = Teuchos::null; // We never keep a preconditioner!
312  if(approxFwdOpSrc) *approxFwdOpSrc = Teuchos::null; // never keep approx fwd op!
313 }
314 
315 // Overridden from ParameterListAcceptor
316 
317 template<typename Scalar>
319  RCP<Teuchos::ParameterList> const& paramList
320  )
321 {
322  TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
323  // Only validate this level for now here (expect Amesos2 to do its own
324  // validation?)
325  paramList->validateParameters(*this->getValidParameters(),0);
326  paramList_ = paramList;
327  solverType_ =
329  paramList_->get(
330  SolverType_name
331  ,Amesos2::toString(solverType_)
332  )
333  ,paramList_->name()+"->"+SolverType_name
334  );
335  refactorizationPolicy_ =
337  paramList_->get(
338  RefactorizationPolicy_name
339  ,Amesos2::toString(refactorizationPolicy_)
340  )
341  ,paramList_->name()+"->"+RefactorizationPolicy_name
342  );
343  throwOnPrecInput_ = paramList_->get(ThrowOnPreconditionerInput_name,throwOnPrecInput_);
344  Teuchos::readVerboseObjectSublist(&*paramList_,this);
345 }
346 
347 template<typename Scalar>
350 {
351  return paramList_;
352 }
353 
354 template<typename Scalar>
357 {
358  RCP<Teuchos::ParameterList> _paramList = paramList_;
359  paramList_ = Teuchos::null;
360  return _paramList;
361 }
362 
363 template<typename Scalar>
366 {
367  return paramList_;
368 }
369 
370 template<typename Scalar>
373 {
374  return generateAndGetValidParameters();
375 }
376 
377 // Public functions overridden from Teuchos::Describable
378 
379 template<typename Scalar>
381 {
382  std::ostringstream oss;
383  oss << "Thyra::Amesos2LinearOpWithSolveFactory{";
384  oss << "solverType=" << toString(solverType_);
385  oss << "}";
386  return oss.str();
387 }
388 
389 // private
390 
391 template<typename Scalar>
394 {
395  static RCP<Teuchos::ParameterList> validParamList;
396  if (validParamList.get()==NULL) {
397  validParamList = Teuchos::rcp(new Teuchos::ParameterList("Amesos2"));
399  for (int k = 0; k<Amesos2::numSolverTypes; ++k)
400  solverTypeNames[k] = Thyra::Amesos2::solverTypeNames[k];
401  auto validator = Teuchos::rcp(new Teuchos::StringValidator(solverTypeNames));
402  validParamList->set(SolverType_name,
404  "Type of Amesos2 solver",
405  validator
406  );
407  validParamList->set(RefactorizationPolicy_name,
409  validParamList->set(ThrowOnPreconditionerInput_name,bool(true));
410  Teuchos::setupVerboseObjectSublist(&*validParamList);
411  }
412  return validParamList;
413 }
414 
415 } // namespace Thyra
416 
417 #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...