Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Thyra_BlockedTriangularLinearOpWithSolveFactory.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ****************************************************************************
3 // Tempus: Copyright (2017) Sandia Corporation
4 //
5 // Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6 // ****************************************************************************
7 // @HEADER
8 
9 #ifndef Thyra_BlockedTriangularLinearOpWithSolveFactory_hpp
10 #define Thyra_BlockedTriangularLinearOpWithSolveFactory_hpp
11 
12 #include "Thyra_LinearOpWithSolveBase.hpp"
13 #include "Thyra_DefaultBlockedLinearOp.hpp"
14 #include "Thyra_DefaultBlockedTriangularLinearOpWithSolve.hpp"
15 #include "Thyra_LinearOpSourceBase.hpp"
16 #include "Teuchos_Array.hpp"
17 
18 namespace Thyra {
19 
20 /** \brief Implicit subclass that takes a blocked triangular LOWB object and
21  * turns it into a LOWSB object.
22  *
23  * This class takes any upper or lower triangular
24  * <tt>PhysicallyBlockedLinearOpBase</tt> object and compatible
25  * <tt>LinearOpWithSolveFactoryBase</tt> object(s) and creates a LOWSB version
26  * by creating LOWSB objects along the diagonal.
27  *
28  *
29  * For example, consider the lower block triangular linear operator:
30 
31  \verbatim
32 
33  [ M(0,0) ]
34  M = [ M(1,0) M(1,1) ]
35  [ M(2,0) M(2,1) M(2,2) ]
36 
37  \endverbatim
38 
39  * This class object will then create a new LOWSB object (of type
40  * <tt>DefaultBlockedTriangularLinearOpWithSolve</tt>) that looks like:
41 
42  \verbatim
43 
44  [ invM(0,0) ]
45  invM = [ M(1,0) invM(1,1) ]
46  [ M(2,0) M(2,1) invM(2,2) ]
47 
48  \endverbatim
49 
50  * where <tt>invM(k,k)</tt> are LOWSB objects created from the LOB objects
51  * <tt>M(k,k)</tt> given a LOWSFB object.
52  *
53  * This class is not very compliciated, see the function
54  * <tt>initializeOp()</tt> see what this class actually does!
55  *
56  * Note, this is basically the same as
57  * DefaultBlockedTriangularLinearOpWithSolveFactory except this version allows
58  * you to set a different LOWSF for each diagonal block.
59  */
60 template<class Scalar>
62  : virtual public LinearOpWithSolveFactoryBase<Scalar>
63 {
64 public:
65 
66  /** @name Overridden from Constructors/Initializers/Accessors */
67  //@{
68 
69  /** \brief Create given an array of non-const LOWSFB objects.
70  *
71  * \param lowsf [in,persisting] The LOWSFB objects that will be used to
72  * create the LOWSB objects for the diagonal blocks.
73  *
74  * <b>Preconditions:</b><ul>
75  * <li><tt>!is_null(lowsf)</tt>
76  * </ul>
77  *
78  */
80  const Array< RCP<LinearOpWithSolveFactoryBase<Scalar> > > &lowsf
81  );
82 
83 
84  /** \brief Create given an array of const LOWSFB objects.
85  *
86  * \param lowsf [in,persisting] The LOWSFB objects that will be used to
87  * create the LOWSB objects for the diagonal blocks.
88  *
89  * <b>Preconditions:</b><ul>
90  * <li><tt>!is_null(lowsf)</tt>
91  * </ul>
92  *
93  */
95  const Array< RCP<const LinearOpWithSolveFactoryBase<Scalar> > > &lowsf
96  );
97 
98  Array< RCP<LinearOpWithSolveFactoryBase<Scalar> > > getUnderlyingLOWSF();
99 
100  Array< RCP<const LinearOpWithSolveFactoryBase<Scalar> > > getUnderlyingLOWSF() const;
101 
102  //@}
103 
104  /** \name Overridden from Teuchos::Describable. */
105  //@{
106 
107  std::string description() const;
108 
109  //@}
110 
111  /** @name Overridden from ParameterListAcceptor (simple forwarding functions) */
112  //@{
113 
114  void setParameterList(RCP<ParameterList> const& paramList);
115  RCP<ParameterList> getNonconstParameterList();
116  RCP<ParameterList> unsetParameterList();
117  RCP<const ParameterList> getParameterList() const;
118  RCP<const ParameterList> getValidParameters() const;
119 
120  //@}
121 
122  /** \name Overridden from LinearOpWithSolveFactoyBase */
123  //@{
124 
125  /** \brief returns false. */
126  virtual bool acceptsPreconditionerFactory() const;
127 
128  /** \brief Throws exception. */
129  virtual void setPreconditionerFactory(
130  const RCP<PreconditionerFactoryBase<Scalar> > &precFactory,
131  const std::string &precFactoryName
132  );
133 
134  /** \brief Returns null . */
135  virtual RCP<PreconditionerFactoryBase<Scalar> >
136  getPreconditionerFactory() const;
137 
138  /** \brief Throws exception. */
139  virtual void unsetPreconditionerFactory(
140  RCP<PreconditionerFactoryBase<Scalar> > *precFactory,
141  std::string *precFactoryName
142  );
143 
144  virtual bool isCompatible(
145  const LinearOpSourceBase<Scalar> &fwdOpSrc
146  ) const;
147 
148  virtual RCP<LinearOpWithSolveBase<Scalar> > createOp() const;
149 
150  virtual void initializeOp(
151  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
152  LinearOpWithSolveBase<Scalar> *Op,
153  const ESupportSolveUse supportSolveUse
154  ) const;
155 
156  virtual void initializeAndReuseOp(
157  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
158  LinearOpWithSolveBase<Scalar> *Op
159  ) const;
160 
161  virtual void uninitializeOp(
162  LinearOpWithSolveBase<Scalar> *Op,
163  RCP<const LinearOpSourceBase<Scalar> > *fwdOpSrc,
164  RCP<const PreconditionerBase<Scalar> > *prec,
165  RCP<const LinearOpSourceBase<Scalar> > *approxFwdOpSrc,
166  ESupportSolveUse *supportSolveUse
167  ) const;
168 
169  virtual bool supportsPreconditionerInputType(
170  const EPreconditionerInputType precOpType
171  ) const;
172 
173  virtual void initializePreconditionedOp(
174  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
175  const RCP<const PreconditionerBase<Scalar> > &prec,
176  LinearOpWithSolveBase<Scalar> *Op,
177  const ESupportSolveUse supportSolveUse
178  ) const;
179 
181  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
182  const RCP<const LinearOpSourceBase<Scalar> > &approxFwdOpSrc,
183  LinearOpWithSolveBase<Scalar> *Op,
184  const ESupportSolveUse supportSolveUse
185  ) const;
186 
187  //@}
188 
189 protected:
190 
191  /** \brief Overridden from Teuchos::VerboseObjectBase */
192  //@{
193 
194  void informUpdatedVerbosityState() const;
195 
196  //@}
197 
198 private:
199 
200  typedef Teuchos::ConstNonconstObjectContainer<LinearOpWithSolveFactoryBase<Scalar> > LOWSF_t;
201 
202  Array<LOWSF_t> lowsf_;
203 
204  // Not defined and not to be called
206 
207 };
208 
209 
210 /** \brief Nonmember constructor.
211  *
212  * \relates BlockedTriangularLinearOpWithSolveFactory
213  */
214 template<class Scalar>
215 RCP<BlockedTriangularLinearOpWithSolveFactory<Scalar> >
217  const Array< RCP<LinearOpWithSolveFactoryBase<Scalar> > > &lowsf
218  )
219 {
220  return Teuchos::rcp(
222  );
223 }
224 
225 
226 /** \brief Nonmember constructor.
227  *
228  * \relates BlockedTriangularLinearOpWithSolveFactory
229  */
230 template<class Scalar>
231 RCP<BlockedTriangularLinearOpWithSolveFactory<Scalar> >
233  const Array< RCP<const LinearOpWithSolveFactoryBase<Scalar> > > &lowsf
234  )
235 {
236  return Teuchos::rcp(
238  );
239 }
240 
241 // Overridden from Constructors/Initializers/Accessors
242 
243 template<class Scalar>
246  const Array< RCP<LinearOpWithSolveFactoryBase<Scalar> > > &lowsf
247  ) : lowsf_(lowsf.size())
248 {
249  for (Ordinal i=0; i<lowsf.size(); ++i) {
250 #ifdef TEUCHOS_DEBUG
251  TEUCHOS_TEST_FOR_EXCEPT(is_null(lowsf[i]));
252 #endif
253  lowsf_[i].initialize(lowsf[i]);
254  }
255 }
256 
257 template<class Scalar>
260  const Array< RCP<const LinearOpWithSolveFactoryBase<Scalar> > > &lowsf
261  ) : lowsf_(lowsf.size())
262 {
263  for (Ordinal i=0; i<lowsf.size(); ++i) {
264 #ifdef TEUCHOS_DEBUG
265  TEUCHOS_TEST_FOR_EXCEPT(is_null(lowsf[i]));
266 #endif
267  lowsf_[i].initialize(lowsf[i]);
268  }
269 }
270 
271 template<class Scalar>
272 Array< RCP<LinearOpWithSolveFactoryBase<Scalar> > >
275 {
276  Array< RCP<LinearOpWithSolveFactoryBase<Scalar> > > lowsf(lowsf_.size());
277  for (Ordinal i=0; i<lowsf_.size(); ++i) {
278  lowsf[i] = lowsf_[i].getNonconstObj();
279  }
280  return lowsf;
281 }
282 
283 template<class Scalar>
284 Array< RCP<const LinearOpWithSolveFactoryBase<Scalar> > >
287 {
288  Array< RCP<const LinearOpWithSolveFactoryBase<Scalar> > > lowsf(lowsf_.size());
289  for (Ordinal i=0; i<lowsf_.size(); ++i) {
290  lowsf[i] = lowsf_[i].getConstObj();
291  }
292  return lowsf;
293 }
294 
295 // Overridden from Teuchos::Describable
296 
297 template<class Scalar>
298 std::string
300 description() const
301 {
302  std::ostringstream oss;
303  oss << this->Teuchos::Describable::description()
304  << "{";
305  for (Ordinal i=0; i<lowsf_.size(); ++i) {
306  oss << "lowsf=";
307  if (!is_null(lowsf_[i].getConstObj()))
308  oss << lowsf_[i].getConstObj()->description();
309  else
310  oss << "NULL";
311  }
312  oss << "}";
313  return oss.str();
314 }
315 
316 // Overridden from ParameterListAcceptor
317 
318 // Note, we should probably do something smarter with the parameter lists
319 
320 template<class Scalar>
321 void
324  RCP<ParameterList> const& paramList
325  )
326 {
327  for (Ordinal i=0; i<lowsf_.size(); ++i) {
328  lowsf_[i].getNonconstObj()->setParameterList(paramList);
329  }
330 }
331 
332 template<class Scalar>
333 RCP<ParameterList>
336 {
337  return lowsf_[0].getNonconstObj()->getNonconstParameterList();
338 }
339 
340 template<class Scalar>
341 RCP<ParameterList>
344 {
345  RCP<ParameterList> pl;
346  for (Ordinal i=0; i<lowsf_.size(); ++i) {
347  pl = lowsf_[i].getNonconstObj()->unsetParameterList();
348  }
349  return pl;
350 }
351 
352 template<class Scalar>
353 RCP<const ParameterList>
356 {
357  return lowsf_[0].getConstObj()->getParameterList();
358 }
359 
360 template<class Scalar>
361 RCP<const ParameterList>
364 {
365  return lowsf_[0].getConstObj()->getValidParameters();
366 }
367 
368 // Overridden from LinearOpWithSolveFactoyBase
369 
370 template<class Scalar>
371 bool
374 {
375  return false;
376 }
377 
378 template<class Scalar>
379 void
382  const RCP<PreconditionerFactoryBase<Scalar> > &/* precFactory */,
383  const std::string &/* precFactoryName */
384  )
385 {
386  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
387  "Error, we don't support a preconditioner factory!");
388 }
389 
390 template<class Scalar>
391 RCP<PreconditionerFactoryBase<Scalar> >
394 {
395  return Teuchos::null;
396 }
397 
398 template<class Scalar>
401  RCP<PreconditionerFactoryBase<Scalar> > * /* precFactory */,
402  std::string * /* precFactoryName */
403  )
404 {
405  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
406  "Error, we don't support a preconditioner factory!");
407 }
408 
409 template<class Scalar>
410 bool
413  const LinearOpSourceBase<Scalar> &/* fwdOpSrc */
414  ) const
415 {
416  TEUCHOS_TEST_FOR_EXCEPT(true);
417  TEUCHOS_UNREACHABLE_RETURN(false);
418 }
419 
420 template<class Scalar>
421 RCP<LinearOpWithSolveBase<Scalar> >
423 createOp() const
424 {
425  return defaultBlockedTriangularLinearOpWithSolve<Scalar>();
426 }
427 
428 template<class Scalar>
429 void
432  const RCP<const LinearOpSourceBase<Scalar> > &fwdOpSrc,
433  LinearOpWithSolveBase<Scalar> *Op,
434  const ESupportSolveUse /* supportSolveUse */
435  ) const
436 {
437 
438  using Teuchos::dyn_cast;
439  using Teuchos::rcp_dynamic_cast;
440 
441 #ifdef TEUCHOS_DEBUG
442  TEUCHOS_TEST_FOR_EXCEPT(0==Op);
443 #endif
444 
445  // Set the verbosity settings for the wrapped LOWSF object!
446  for (Ordinal i=0; i<lowsf_.size(); ++i) {
447  lowsf_[i].getConstObj()->setOStream(this->getOStream());
448  lowsf_[i].getConstObj()->setVerbLevel(this->getVerbLevel());
449  }
450 
451  // Get the block interface to get at the blocks
452  typedef PhysicallyBlockedLinearOpBase<Scalar> PBLOB;
453  const RCP<const PBLOB> blo =
454  rcp_dynamic_cast<const PBLOB>(fwdOpSrc->getOp().assert_not_null());
455 
456  // Dynamic cast to get the DefaultBlockedTriangularLinearOpWithSolveBase
457  // interface that we will fill.
458 
459  typedef DefaultBlockedTriangularLinearOpWithSolve<Scalar> DBTLOWS;
460  DBTLOWS &btlows = dyn_cast<DBTLOWS>(*Op);
461 
462  // Determine if this is the first time through or if we have already
463  // initialized before. This will be needed to allow efficient reuse of the
464  // LOWSB objects for the diagonal blocks.
465  const bool firstTime = is_null(btlows.range());
466 
467  // If this is the first time through, we need to fill and create the block
468  // structure
469  if (firstTime)
470  btlows.beginBlockFill(blo->productRange(),blo->productDomain());
471 
472  const int N = blo->productRange()->numBlocks();
473  for ( int k = 0; k < N; ++k ) {
474  const RCP<const LinearOpBase<Scalar> > fwdOp_k =
475  blo->getBlock(k,k).assert_not_null();
476  if (firstTime) {
477  // This is the first time through so reate and initialize a new LOWSB
478  // object for each block
479  btlows.setNonconstLOWSBlock( k, k,
480  linearOpWithSolve<Scalar>(*lowsf_[k].getConstObj(),fwdOp_k)
481  );
482  }
483  else {
484  // This is not the first time through so we need to just reinitiallize
485  // the object that is already created. This allows us to efficiently
486  // reuse precreated structure and storage.
487  RCP<LinearOpWithSolveBase<Scalar> >
488  invOp_k = btlows.getNonconstLOWSBlock(k,k).assert_not_null();
489  Thyra::initializeOp<Scalar>(*lowsf_[k].getConstObj(), fwdOp_k, invOp_k.ptr());
490  }
491  }
492 
493  // If this is the first time through, then we need to finalize the block
494  // structure.
495  if (firstTime)
496  btlows.endBlockFill();
497 
498  // After the block structure has been setup, set the off-diagonal blocks.
499  // Note that this also sets the diagonal blocks but these are ignored since
500  // the LOWSB blocks created above override these.
501  btlows.setBlocks(blo);
502 
503  // Set the verbosity settings
504  btlows.setOStream(this->getOStream());
505  btlows.setVerbLevel(this->getVerbLevel());
506 }
507 
508 template<class Scalar>
509 void
512  const RCP<const LinearOpSourceBase<Scalar> > &/* fwdOpSrc */,
513  LinearOpWithSolveBase<Scalar> * /* Op */
514  ) const
515 {
516  TEUCHOS_TEST_FOR_EXCEPT(true);
517 }
518 
519 template<class Scalar>
520 void
523  LinearOpWithSolveBase<Scalar> *Op,
524  RCP<const LinearOpSourceBase<Scalar> > *fwdOpSrc,
525  RCP<const PreconditionerBase<Scalar> > *prec,
526  RCP<const LinearOpSourceBase<Scalar> > *approxFwdOpSrc,
527  ESupportSolveUse * /* supportSolveUse */
528  ) const
529 {
530  using Teuchos::dyn_cast;
531  using Teuchos::rcp_implicit_cast;
532  using Teuchos::rcp_dynamic_cast;
533  typedef DefaultBlockedTriangularLinearOpWithSolve<Scalar> DBTLOWS;
534  TEUCHOS_TEST_FOR_EXCEPT(0==Op);
535  DBTLOWS &btlowsOp = dyn_cast<DBTLOWS>(*Op);
536  if (fwdOpSrc) {
537  const RCP<const LinearOpBase<Scalar> > fwdOp = btlowsOp.getBlocks();
538  if (!is_null(fwdOp))
539  *fwdOpSrc = defaultLinearOpSource<Scalar>(fwdOp);
540  else
541  *fwdOpSrc = Teuchos::null;
542  }
543  if (prec) *prec = Teuchos::null;
544  if (approxFwdOpSrc) *approxFwdOpSrc = Teuchos::null;
545 }
546 
547 template<class Scalar>
548 bool
551  const EPreconditionerInputType /* precOpType */
552  ) const
553 {
554  // We don't support any external preconditioners!
555  return false;
556  // 20071006: rabartl: Note: We could support external preconditioners but it
557  // will take some work. We would have to extract out the individual
558  // preconditioners from each block. This would be pretty easy to do but I
559  // am not going to do this until we have to.
560 }
561 
562 template<class Scalar>
563 void
566  const RCP<const LinearOpSourceBase<Scalar> > &/* fwdOpSrc */,
567  const RCP<const PreconditionerBase<Scalar> > &/* prec */,
568  LinearOpWithSolveBase<Scalar> * /* Op */,
569  const ESupportSolveUse /* supportSolveUse */
570  ) const
571 {
572  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
573  "Error, we don't support an external preconditioner!");
574 }
575 
576 template<class Scalar>
577 void
580  const RCP<const LinearOpSourceBase<Scalar> > &/* fwdOpSrc */,
581  const RCP<const LinearOpSourceBase<Scalar> > &/* approxFwdOpSrc */,
582  LinearOpWithSolveBase<Scalar> * /* Op */,
583  const ESupportSolveUse /* supportSolveUse */
584  ) const
585 {
586  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
587  "Error, we don't support an external preconditioner!");
588 }
589 
590 // protected
591 
592 template<class Scalar>
593 void
596 {
597  for (Ordinal i=0; i<lowsf_.size(); ++i) {
598  lowsf_[i].getConstObj()->setVerbLevel(this->getVerbLevel());
599  lowsf_[i].getConstObj()->setOStream(this->getOStream());
600  }
601 }
602 
603 } // namespace Thyra
604 
605 #endif // Thyra_BlockedTriangularLinearOpWithSolveFactory_hpp
virtual RCP< PreconditionerFactoryBase< Scalar > > getPreconditionerFactory() const
Returns null .
void informUpdatedVerbosityState() const
Overridden from Teuchos::VerboseObjectBase.
RCP< BlockedTriangularLinearOpWithSolveFactory< Scalar > > blockedTriangularLinearOpWithSolveFactory(const Array< RCP< const LinearOpWithSolveFactoryBase< Scalar > > > &lowsf)
Nonmember constructor.
Teuchos::ConstNonconstObjectContainer< LinearOpWithSolveFactoryBase< Scalar > > LOWSF_t
virtual bool isCompatible(const LinearOpSourceBase< Scalar > &fwdOpSrc) const
virtual void uninitializeOp(LinearOpWithSolveBase< Scalar > *Op, RCP< const LinearOpSourceBase< Scalar > > *fwdOpSrc, RCP< const PreconditionerBase< Scalar > > *prec, RCP< const LinearOpSourceBase< Scalar > > *approxFwdOpSrc, ESupportSolveUse *supportSolveUse) const
virtual void initializeOp(const RCP< const LinearOpSourceBase< Scalar > > &fwdOpSrc, LinearOpWithSolveBase< Scalar > *Op, const ESupportSolveUse supportSolveUse) const
virtual RCP< LinearOpWithSolveBase< Scalar > > createOp() const
virtual void initializePreconditionedOp(const RCP< const LinearOpSourceBase< Scalar > > &fwdOpSrc, const RCP< const PreconditionerBase< Scalar > > &prec, LinearOpWithSolveBase< Scalar > *Op, const ESupportSolveUse supportSolveUse) const
virtual void unsetPreconditionerFactory(RCP< PreconditionerFactoryBase< Scalar > > *precFactory, std::string *precFactoryName)
Throws exception.
virtual void setPreconditionerFactory(const RCP< PreconditionerFactoryBase< Scalar > > &precFactory, const std::string &precFactoryName)
Throws exception.
virtual void initializeAndReuseOp(const RCP< const LinearOpSourceBase< Scalar > > &fwdOpSrc, LinearOpWithSolveBase< Scalar > *Op) const
Array< RCP< LinearOpWithSolveFactoryBase< Scalar > > > getUnderlyingLOWSF()
virtual bool supportsPreconditionerInputType(const EPreconditionerInputType precOpType) const
virtual void initializeApproxPreconditionedOp(const RCP< const LinearOpSourceBase< Scalar > > &fwdOpSrc, const RCP< const LinearOpSourceBase< Scalar > > &approxFwdOpSrc, LinearOpWithSolveBase< Scalar > *Op, const ESupportSolveUse supportSolveUse) const
RCP< BlockedTriangularLinearOpWithSolveFactory< Scalar > > blockedTriangularLinearOpWithSolveFactory(const Array< RCP< LinearOpWithSolveFactoryBase< Scalar > > > &lowsf)
Nonmember constructor.
Implicit subclass that takes a blocked triangular LOWB object and turns it into a LOWSB object...