Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_UnitTest_ScaledIdentityLinearOpWithSolve.cpp
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#include "Teuchos_UnitTestHarness.hpp"
11
12#include "Thyra_DefaultBlockedLinearOp.hpp"
13#include "Thyra_DefaultSpmdVectorSpace.hpp"
14#include "Thyra_DetachedMultiVectorView.hpp"
16#include "Thyra_MultiVectorStdOps.hpp"
18#include "Thyra_VectorStdOps.hpp"
19
20namespace Tempus_Unit_Test {
21
22using Teuchos::RCP;
23using Teuchos::rcp_dynamic_cast;
24using Thyra::RowStatLinearOpBaseUtils::ROW_STAT_COL_SUM;
25using Thyra::RowStatLinearOpBaseUtils::ROW_STAT_INV_COL_SUM;
26using Thyra::RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM;
27using Thyra::RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM;
28
29typedef Thyra::VectorSpaceBase<double> VectorSpace;
32
33static const double tol = 1.0e-14;
34
35// ************************************************************
36// Row statistics of s*I: |s|, and 1/|s| for the inverses (s != 0).
37TEUCHOS_UNIT_TEST(ScaledIdentityLinearOpWithSolve, RowStats)
38{
39 RCP<const VectorSpace> space = Thyra::defaultSpmdVectorSpace<double>(3);
40 RCP<ScaledIdentity> op = Thyra::scaledIdentity(space, -2.0);
41 RCP<Vector> v = Thyra::createMember(space);
42
43 op->getRowStat(ROW_STAT_ROW_SUM, v.ptr());
44 TEST_FLOATING_EQUALITY(Thyra::min(*v), 2.0, tol);
45 TEST_FLOATING_EQUALITY(Thyra::max(*v), 2.0, tol);
46 op->getRowStat(ROW_STAT_COL_SUM, v.ptr());
47 TEST_FLOATING_EQUALITY(Thyra::min(*v), 2.0, tol);
48 TEST_FLOATING_EQUALITY(Thyra::max(*v), 2.0, tol);
49 op->getRowStat(ROW_STAT_INV_ROW_SUM, v.ptr());
50 TEST_FLOATING_EQUALITY(Thyra::min(*v), 0.5, tol);
51 TEST_FLOATING_EQUALITY(Thyra::max(*v), 0.5, tol);
52 op->getRowStat(ROW_STAT_INV_COL_SUM, v.ptr());
53 TEST_FLOATING_EQUALITY(Thyra::min(*v), 0.5, tol);
54 TEST_FLOATING_EQUALITY(Thyra::max(*v), 0.5, tol);
55
56 op->setScale(0.0);
57 TEST_ASSERT(op->rowStatIsSupported(ROW_STAT_ROW_SUM));
58 TEST_ASSERT(!op->rowStatIsSupported(ROW_STAT_INV_ROW_SUM));
59 TEST_ASSERT(!op->rowStatIsSupported(ROW_STAT_INV_COL_SUM));
60}
61
62// ************************************************************
63// Left and right scaling by uniform vectors: diag(d) s I = (d s) I.
64TEUCHOS_UNIT_TEST(ScaledIdentityLinearOpWithSolve, UniformScaling)
65{
66 RCP<const VectorSpace> space = Thyra::defaultSpmdVectorSpace<double>(3);
67 RCP<ScaledIdentity> op = Thyra::scaledIdentity(space, -2.0);
68 TEST_ASSERT(op->supportsScaleLeft());
69 TEST_ASSERT(op->supportsScaleRight());
70
71 RCP<Vector> d = Thyra::createMember(space);
72 Thyra::put_scalar(3.0, d.ptr());
73 op->scaleLeft(*d);
74 TEST_FLOATING_EQUALITY(op->scale(), -6.0, tol);
75 Thyra::put_scalar(0.5, d.ptr());
76 op->scaleRight(*d);
77 TEST_FLOATING_EQUALITY(op->scale(), -3.0, tol);
78
79 // Apply and solve with the scaled operator
80 RCP<Vector> x = Thyra::createMember(space);
81 for (int i = 0; i < 3; ++i) Thyra::set_ele(i, i + 1.0, x.ptr());
82 RCP<Vector> y = Thyra::createMember(space);
83 Thyra::apply<double>(*op, Thyra::NOTRANS, *x, y.ptr());
84 RCP<Vector> r = y->clone_v();
85 Thyra::Vp_StV(r.ptr(), 3.0, *x); // y + 3 x = 0
86 TEST_COMPARE(Thyra::norm_inf(*r), <=, tol);
87 RCP<Vector> z = Thyra::createMember(space);
88 op->solve(Thyra::NOTRANS, *y, z.ptr());
89 Thyra::Vp_StV(z.ptr(), -1.0, *x); // z - x = 0
90 TEST_COMPARE(Thyra::norm_inf(*z), <=, tol);
91
92 // A nonuniform scaling is not a scaled identity
93 Thyra::set_ele(1, 4.0, d.ptr());
94 TEST_THROW(op->scaleLeft(*d), std::logic_error);
95 TEST_THROW(op->scaleRight(*d), std::logic_error);
96 TEST_FLOATING_EQUALITY(op->scale(), -3.0, tol);
97}
98
99// ************************************************************
100// Row sum scaling (as done by NOX with "Function Scaling" = "Row Sum") of
101// the operator of AdjointAuxSensitivityModelEvaluator, [A 0; 0 alpha I], with
102// A a MultiVectorLinearOp and null off-diagonal blocks: after the scaling by
103// the inverse absolute row sums, all the absolute row sums are 1.
104TEUCHOS_UNIT_TEST(ScaledIdentityLinearOpWithSolve, BlockedRowSumScaling)
105{
106 RCP<const VectorSpace> space = Thyra::defaultSpmdVectorSpace<double>(2);
107 RCP<Thyra::MultiVectorBase<double> > A = Thyra::createMembers(space, 2);
108 {
109 Thyra::DetachedMultiVectorView<double> Av(*A);
110 Av(0, 0) = 2.0;
111 Av(0, 1) = -1.0;
112 Av(1, 0) = 0.5;
113 Av(1, 1) = 4.0;
114 }
115 const int num_adjoint = 2;
116 RCP<Thyra::LinearOpBase<double> > mv_op = Thyra::nonconstMultiVectorLinearOp<double>(A, num_adjoint);
117 RCP<const VectorSpace> z_space = Thyra::defaultSpmdVectorSpace<double>(3);
118 const double alpha = -4.0;
119 RCP<ScaledIdentity> si_op = Thyra::scaledIdentity(z_space, alpha);
120 RCP<Thyra::LinearOpBase<double> > null_op;
121 RCP<Thyra::LinearOpBase<double> > W =
122 Thyra::nonconstBlock2x2<double>(mv_op, null_op, null_op, si_op);
123
124 RCP<const Thyra::RowStatLinearOpBase<double> > W_rs =
125 rcp_dynamic_cast<const Thyra::RowStatLinearOpBase<double> >(W, true);
126 RCP<Thyra::ScaledLinearOpBase<double> > W_sc =
127 rcp_dynamic_cast<Thyra::ScaledLinearOpBase<double> >(W, true);
128 TEST_ASSERT(W_rs->rowStatIsSupported(ROW_STAT_INV_ROW_SUM));
129 TEST_ASSERT(W_sc->supportsScaleLeft());
130
131 RCP<Vector> inv_row_sum = Thyra::createMember(W->range());
132 W_rs->getRowStat(ROW_STAT_INV_ROW_SUM, inv_row_sum.ptr());
133 W_sc->scaleLeft(*inv_row_sum);
134
135 RCP<Vector> row_sum = Thyra::createMember(W->range());
136 W_rs->getRowStat(ROW_STAT_ROW_SUM, row_sum.ptr());
137 TEST_FLOATING_EQUALITY(Thyra::min(*row_sum), 1.0, tol);
138 TEST_FLOATING_EQUALITY(Thyra::max(*row_sum), 1.0, tol);
139 TEST_FLOATING_EQUALITY(si_op->scale(), -1.0, tol);
140}
141
142} // namespace Tempus_Unit_Test
RCP< MultiVectorLinearOp< Scalar > > nonconstMultiVectorLinearOp(const RCP< LinearOpBase< Scalar > > &op, const RCP< const DefaultMultiVectorProductVectorSpace< Scalar > > &multiVecRange, const RCP< const DefaultMultiVectorProductVectorSpace< Scalar > > &multiVecDomain)
Nonmember constructor function.
Scaled identity operator s*I, with its solve.
RCP< ScaledIdentityLinearOpWithSolve< Scalar > > scaledIdentity()
Nonmember constructor function.
Thyra::ScaledIdentityLinearOpWithSolve< double > ScaledIdentity
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)