Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Thyra_ScaledIdentityLinearOpWithSolve.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 Thyra_ScaledIdentityLinearOpWithSolve_hpp
11#define Thyra_ScaledIdentityLinearOpWithSolve_hpp
12
13#include <string>
14
15#include "Thyra_LinearOpWithSolveBase.hpp"
16#include "Thyra_MultiVectorStdOps.hpp"
17#include "Thyra_RowStatLinearOpBase.hpp"
18#include "Thyra_ScaledLinearOpBase.hpp"
19#include "Thyra_VectorStdOps.hpp"
20
21namespace Thyra {
22
33template <class Scalar>
35 : virtual public LinearOpWithSolveBase<Scalar>,
36 virtual public RowStatLinearOpBase<Scalar>,
37 virtual public ScaledLinearOpBase<Scalar> {
38 public:
41
44
45 void initialize(const RCP<const VectorSpaceBase<Scalar> >& space,
46 const Scalar& s)
47 {
49 space_ = space;
50 s_ = s;
51 }
52
53 void uninitialize() { space_ = Teuchos::null; }
54
55 RCP<const VectorSpaceBase<Scalar> > space() const { return space_; }
56 Scalar scale() const { return s_; }
57 void setScale(const Scalar& s) { s_ = s; }
58
60
63
64 RCP<const VectorSpaceBase<Scalar> > range() const { return space_; }
65
66 RCP<const VectorSpaceBase<Scalar> > domain() const { return space_; }
67
68 RCP<const LinearOpBase<Scalar> > clone() const
69 {
70 RCP<ScaledIdentityLinearOpWithSolve<Scalar> > op =
72 op->initialize(space_, s_);
73 return op;
74 }
75
76
77 protected:
80 bool opSupportedImpl(EOpTransp /* M_trans */) const { return true; }
81
82 void applyImpl(const EOpTransp M_trans, const MultiVectorBase<Scalar>& X,
83 const Ptr<MultiVectorBase<Scalar> >& Y, const Scalar alpha,
84 const Scalar beta) const
85 {
86 typedef Teuchos::ScalarTraits<Scalar> ST;
87 Thyra::scale(beta, Y);
88 if (M_trans == CONJ || M_trans == CONJTRANS)
89 V_StVpV(Y, ST::conjugate(s_) * alpha, X, *Y);
90 else
91 V_StVpV(Y, s_ * alpha, X, *Y);
92 }
93
94
97 bool solveSupportsImpl(EOpTransp /* M_trans */) const { return true; }
98
100 EOpTransp /* M_trans */,
101 const Ptr<const SolveCriteria<Scalar> > /* solveCriteria */) const
102 {
103 return true;
104 }
105
107 EOpTransp /* M_trans */,
108 const SolveMeasureType& /* solveMeasureType */) const
109 {
110 return true;
111 }
112
113 SolveStatus<Scalar> solveImpl(
114 const EOpTransp M_trans, const MultiVectorBase<Scalar>& B,
115 const Ptr<MultiVectorBase<Scalar> >& X,
116 const Ptr<const SolveCriteria<Scalar> > /* solveCriteria */) const
117 {
118 typedef Teuchos::ScalarTraits<Scalar> ST;
119 assign(X, ST::zero());
120 if (M_trans == CONJ || M_trans == CONJTRANS)
121 V_StVpV(X, ST::one() / ST::conjugate(s_), B, *X);
122 else
123 V_StVpV(X, ST::one() / s_, B, *X);
124 SolveStatus<Scalar> solveStatus;
125 solveStatus.solveStatus = SOLVE_STATUS_CONVERGED;
126 return solveStatus;
127 }
128
129
132
136 const RowStatLinearOpBaseUtils::ERowStat rowStat) const
137 {
138 switch (rowStat) {
139 case RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM:
140 case RowStatLinearOpBaseUtils::ROW_STAT_COL_SUM: return true;
141 case RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM:
142 case RowStatLinearOpBaseUtils::ROW_STAT_INV_COL_SUM:
143 return s_ != Teuchos::ScalarTraits<Scalar>::zero();
144 }
145 return false;
146 }
147
148 void getRowStatImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat,
149 const Ptr<VectorBase<Scalar> >& rowStatVec) const
150 {
151 typedef Teuchos::ScalarTraits<Scalar> ST;
152 TEUCHOS_ASSERT(this->rowStatIsSupported(rowStat));
153 const Scalar abs_s = ST::magnitude(s_);
154 if (rowStat == RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM ||
155 rowStat == RowStatLinearOpBaseUtils::ROW_STAT_INV_COL_SUM)
156 put_scalar(ST::one() / abs_s, rowStatVec);
157 else
158 put_scalar(abs_s, rowStatVec);
159 }
160
161
164
165 bool supportsScaleLeftImpl() const { return true; }
166
167 bool supportsScaleRightImpl() const { return true; }
168
170 void scaleLeftImpl(const VectorBase<Scalar>& row_scaling)
171 {
172 s_ *= uniformValue(row_scaling, "scaleLeft");
173 }
174
176 void scaleRightImpl(const VectorBase<Scalar>& col_scaling)
177 {
178 s_ *= uniformValue(col_scaling, "scaleRight");
179 }
180
181
182 private:
183 // //////////////////////////////
184 // Private data members
185
186 RCP<const VectorSpaceBase<Scalar> > space_;
187 Scalar s_;
188
189 // //////////////////////////////
190 // Private member functions
191
193 static Scalar uniformValue(const VectorBase<Scalar>& v,
194 const std::string& caller)
195 {
196 typedef Teuchos::ScalarTraits<Scalar> ST;
197 typedef typename ST::magnitudeType Mag;
198 if (v.space()->dim() == 0) return ST::one();
199 const Scalar d = get_ele(v, 0);
200 RCP<VectorBase<Scalar> > diff = v.clone_v();
201 add_scalar(-d, diff.ptr());
202 TEUCHOS_TEST_FOR_EXCEPTION(
203 norm_inf(*diff) > Mag(100) * ST::eps() * ST::magnitude(d),
204 std::logic_error,
205 "Error - Thyra::ScaledIdentityLinearOpWithSolve::"
206 << caller
207 << ": only a scaling by a uniform vector (all entries equal) "
208 "keeps the operator a scaled identity.\n");
209 return d;
210 }
211
213 const RCP<const VectorSpaceBase<Scalar> >& space)
214 {
215#ifdef TEUCHOS_DEBUG
216 TEUCHOS_TEST_FOR_EXCEPT(is_null(space));
217#else
218 (void)space;
219#endif
220 }
221};
222
227template <class Scalar>
228RCP<ScaledIdentityLinearOpWithSolve<Scalar> > scaledIdentity()
229{
230 return Teuchos::rcp(new ScaledIdentityLinearOpWithSolve<Scalar>());
231}
232
237template <class Scalar>
238RCP<ScaledIdentityLinearOpWithSolve<Scalar> > scaledIdentity(
239 const RCP<const VectorSpaceBase<Scalar> >& space, const Scalar& s)
240{
241 RCP<ScaledIdentityLinearOpWithSolve<Scalar> > op =
242 Teuchos::rcp(new ScaledIdentityLinearOpWithSolve<Scalar>());
243 op->initialize(space, s);
244 return op;
245}
246
247} // end namespace Thyra
248
249#endif
bool solveSupportsSolveMeasureTypeImpl(EOpTransp, const SolveMeasureType &) const
void initialize(const RCP< const VectorSpaceBase< Scalar > > &space, const Scalar &s)
void getRowStatImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat, const Ptr< VectorBase< Scalar > > &rowStatVec) const
SolveStatus< Scalar > solveImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &B, const Ptr< MultiVectorBase< Scalar > > &X, const Ptr< const SolveCriteria< Scalar > >) const
RCP< ScaledIdentityLinearOpWithSolve< Scalar > > scaledIdentity(const RCP< const VectorSpaceBase< Scalar > > &space, const Scalar &s)
Nonmember constructor function.
static void validateInitialize(const RCP< const VectorSpaceBase< Scalar > > &space)
static Scalar uniformValue(const VectorBase< Scalar > &v, const std::string &caller)
The value d of the entries of a uniform vector (throws otherwise).
void scaleLeftImpl(const VectorBase< Scalar > &row_scaling)
diag(d) * s*I = (d*s) I, for a uniform vector d.
RCP< ScaledIdentityLinearOpWithSolve< Scalar > > scaledIdentity()
Nonmember constructor function.
bool rowStatIsSupportedImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat) const
The absolute row and column sums are |s|; their inverses require s != 0.
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
void scaleRightImpl(const VectorBase< Scalar > &col_scaling)
s*I * diag(d) = (d*s) I, for a uniform vector d.
RCP< const LinearOpBase< Scalar > > clone() const
RCP< const VectorSpaceBase< Scalar > > domain() const
RCP< const VectorSpaceBase< Scalar > > range() const
bool solveSupportsNewImpl(EOpTransp, const Ptr< const SolveCriteria< Scalar > >) const