Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_DAEStructure.hpp
Go to the documentation of this file.
1//@HEADER
2// *****************************************************************************
3// Tempus: Time Integration and Sensitivity Analysis Package
4//
5// Copyright 2017 NTESS and the Tempus contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8//@HEADER
9
10#ifndef Tempus_DAEStructure_hpp
11#define Tempus_DAEStructure_hpp
12
13#include <algorithm>
14#include <string>
15
16#include "Teuchos_ParameterList.hpp"
17#include "Teuchos_RCP.hpp"
18#include "Teuchos_ScalarTraits.hpp"
19#include "Teuchos_TestForException.hpp"
20#include "Thyra_ModelEvaluator.hpp"
21#include "Thyra_MultiVectorBase.hpp"
22#include "Thyra_VectorStdOps.hpp"
23
24namespace Tempus {
25
54template <class Scalar>
56 public:
59 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType Mag;
60
62 static const std::string& algebraicMaskName()
63 {
64 static const std::string name("Algebraic Equations Mask");
65 return name;
66 }
67
69 explicit DAEStructure(const Teuchos::RCP<const Vector>& algebraic_mask)
70 : algebraic_mask_(algebraic_mask)
71 {
72 typedef Teuchos::ScalarTraits<Scalar> ST;
73 TEUCHOS_TEST_FOR_EXCEPTION(
74 algebraic_mask_ == Teuchos::null, std::invalid_argument,
75 "Error - Tempus::DAEStructure: null \"" << algebraicMaskName() << "\".\n");
76
77 // The entries must be 0 or 1: m.*m - m = 0
78 Teuchos::RCP<Vector> w = algebraic_mask_->clone_v();
79 Thyra::ele_wise_scale(*algebraic_mask_, w.ptr());
80 Thyra::Vp_StV(w.ptr(), -ST::one(), *algebraic_mask_);
81 TEUCHOS_TEST_FOR_EXCEPTION(
82 Thyra::norm_inf(*w) != Teuchos::ScalarTraits<Mag>::zero(),
83 std::invalid_argument,
84 "Error - Tempus::DAEStructure: the entries of \""
86 << "\" must be 1 (algebraic equations) or 0 (other equations).\n");
87
88 Teuchos::RCP<Vector> d = Thyra::createMember(algebraic_mask_->space());
89 Thyra::put_scalar(ST::one(), d.ptr());
90 Thyra::Vp_StV(d.ptr(), -ST::one(), *algebraic_mask_);
92 }
93
95 Teuchos::RCP<const Vector> getAlgebraicMask() const
96 {
97 return algebraic_mask_;
98 }
99
101 Teuchos::RCP<const Vector> getDifferentialMask() const
102 {
103 return differential_mask_;
104 }
105
108 {
109 for (int j = 0; j < v.domain()->dim(); ++j)
110 Thyra::ele_wise_scale(*differential_mask_, v.col(j).ptr());
111 }
112
115 {
116 for (int j = 0; j < v.domain()->dim(); ++j)
117 Thyra::ele_wise_scale(*algebraic_mask_, v.col(j).ptr());
118 }
119
127 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs,
128 const std::string& caller) const
129 {
130 typedef Thyra::ModelEvaluatorBase MEB;
131 MEB::OutArgs<Scalar> outArgs = model.createOutArgs();
132 if (!outArgs.supports(MEB::OUT_ARG_W_op)) return;
133
134 MEB::InArgs<Scalar> massInArgs = inArgs;
135 if (massInArgs.supports(MEB::IN_ARG_alpha))
136 massInArgs.set_alpha(Scalar(1.0));
137 if (massInArgs.supports(MEB::IN_ARG_beta)) massInArgs.set_beta(Scalar(0.0));
138 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > W_op = model.create_W_op();
139 outArgs.set_W_op(W_op);
140 model.evalModel(massInArgs, outArgs);
141
142 Teuchos::RCP<Vector> v = Thyra::createMember(model.get_x_space());
143 Thyra::randomize(Scalar(0.5), Scalar(1.5), v.ptr());
144 Teuchos::RCP<Vector> r = Thyra::createMember(model.get_f_space());
145 W_op->apply(Thyra::NOTRANS, *v, r.ptr(), Scalar(1.0), Scalar(0.0));
146 const Mag scale = Thyra::norm_inf(*r);
147 Thyra::ele_wise_scale(*algebraic_mask_, r.ptr()); // algebraic rows only
148 const Mag err = Thyra::norm_inf(*r);
149 TEUCHOS_TEST_FOR_EXCEPTION(
150 err > Mag(1.0e-12) * scale, std::logic_error,
151 "Error - " << caller << ": the rows of the mass matrix df/dx_dot "
152 << "(model evaluated with alpha = 1, beta = 0) flagged by \""
153 << algebraicMaskName() << "\" are not zero (|E v| = " << err
154 << " on these rows, " << scale
155 << " on all rows). Only equations that do not depend on "
156 << "x_dot can be flagged as algebraic.\n");
157 }
158
159 private:
160 Teuchos::RCP<const Vector> algebraic_mask_;
161 Teuchos::RCP<const Vector> differential_mask_;
162};
163
170template <class Scalar>
171Teuchos::RCP<const DAEStructure<Scalar> > getDAEStructure(
172 const Teuchos::ParameterList& pl)
173{
174 typedef Teuchos::RCP<const Thyra::VectorBase<Scalar> > ConstVec;
175 typedef Teuchos::RCP<Thyra::VectorBase<Scalar> > Vec;
176 const std::string& name = DAEStructure<Scalar>::algebraicMaskName();
177 if (!pl.isParameter(name)) return Teuchos::null;
178 ConstVec mask;
179 if (pl.isType<ConstVec>(name))
180 mask = pl.get<ConstVec>(name);
181 else if (pl.isType<Vec>(name))
182 mask = pl.get<Vec>(name);
183 else
184 TEUCHOS_TEST_FOR_EXCEPTION(
185 true, std::invalid_argument,
186 "Error - the parameter \""
187 << name
188 << "\" must be a Teuchos::RCP<const Thyra::VectorBase<Scalar> >.\n");
189 if (mask == Teuchos::null) return Teuchos::null;
190 return Teuchos::rcp(new DAEStructure<Scalar>(mask));
191}
192
193} // namespace Tempus
194
195#endif // Tempus_DAEStructure_hpp
Structure of an index-1 differential-algebraic system.
Teuchos::RCP< const Vector > differential_mask_
Thyra::MultiVectorBase< Scalar > MultiVector
void zeroDifferentialComponents(MultiVector &v) const
v <- P_a v: zero the differential components of each column of v
Teuchos::RCP< const Vector > algebraic_mask_
void checkMassMatrix(const Thyra::ModelEvaluator< Scalar > &model, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const std::string &caller) const
Check that the rows of the algebraic equations of the mass matrix df/dx_dot (model evaluated with alp...
DAEStructure(const Teuchos::RCP< const Vector > &algebraic_mask)
Constructor from the mask of the algebraic equations (entries 0 or 1).
Teuchos::RCP< const Vector > getAlgebraicMask() const
Mask of the algebraic equations (1 on the algebraic equations).
Thyra::VectorBase< Scalar > Vector
Teuchos::RCP< const Vector > getDifferentialMask() const
Mask of the other equations (1 - mask of the algebraic equations).
static const std::string & algebraicMaskName()
Name of the parameter giving the mask of the algebraic equations.
void zeroAlgebraicComponents(MultiVector &v) const
v <- P_d v: zero the algebraic components of each column of v
Teuchos::ScalarTraits< Scalar >::magnitudeType Mag
Teuchos::RCP< const DAEStructure< Scalar > > getDAEStructure(const Teuchos::ParameterList &pl)
The DAE structure given by the "Algebraic Equations Mask" parameter of pl, or null if the parameter i...