Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
03_Intro_SolutionState.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 <iomanip>
11#include <iostream>
12#include <stdlib.h>
13#include <math.h>
14#include "Teuchos_StandardCatchMacros.hpp"
15
16#include "Thyra_VectorStdOps.hpp"
17#include "Thyra_DefaultSpmdVectorSpace.hpp"
18#include "Thyra_DetachedVectorView.hpp"
19
20#include "../02_Use_ModelEvaluator/VanDerPol_ModelEvaluator_02.hpp"
21
22#include "Tempus_SolutionState.hpp"
23
24
25using namespace std;
26using Teuchos::RCP;
27
73int main(int argc, char *argv[])
74{
75 bool verbose = true;
76 bool success = false;
77 try {
78 // Construct ModelEvaluator
79 Teuchos::RCP<const Thyra::ModelEvaluator<double> >
80 model = Teuchos::rcp(new VanDerPol_ModelEvaluator_02<double>());
81
82 // Setup initial condition SolutionState --------------------
83 auto solState = Tempus::createSolutionStateX(
84 model->getNominalValues().get_x()->clone_v());
85 solState->setIndex (0);
86 solState->setTime (0.0);
87 solState->setTimeStep(0.0); // By convention, the IC has dt=0.
88 solState->setSolutionStatus(Tempus::Status::PASSED); // ICs are considered passed.
89 RCP<Thyra::VectorBase<double> > xDot_n =
90 model->getNominalValues().get_x_dot()->clone_v();
91
92
93 // Timestep size
94 double finalTime = 2.0;
95 int nTimeSteps = 2000;
96 const double constDT = finalTime/nTimeSteps;
97
98 // Advance the solution to the next timestep.
99 while (solState->getSolutionStatus() == Tempus::Status::PASSED &&
100 solState->getTime() < finalTime &&
101 solState->getIndex() < nTimeSteps) {
102
103 // Initialize next time step
104 RCP<Thyra::VectorBase<double> > x_n = solState->getX();
105 RCP<Thyra::VectorBase<double> > x_np1 = solState->getX()->clone_v(); // at time index n+1
106 solState->setSolutionStatus(Tempus::Status::WORKING);
107
108 // Set the timestep and time for the working solution i.e., n+1.
109 int index = solState->getIndex()+1;
110 double dt = constDT;
111 double time = index*dt;
112
113 // For explicit ODE formulation, xDot = f(x, t),
114 // xDot is part of the outArgs.
115 auto inArgs = model->createInArgs();
116 auto outArgs = model->createOutArgs();
117 inArgs.set_t(time);
118 inArgs.set_x(x_n);
119 inArgs.set_x_dot(Teuchos::null);
120 outArgs.set_f(xDot_n);
121
122 // Righthand side evaluation and time-derivative at n.
123 model->evalModel(inArgs, outArgs);
124
125 // Take the timestep - Forward Euler
126 Thyra::V_VpStV(x_np1.ptr(), *x_n, dt, *xDot_n);
127
128 // Test if solution has passed.
129 if ( std::isnan(Thyra::norm(*x_np1)) ) {
130 solState->setSolutionStatus(Tempus::Status::FAILED);
131 } else {
132 // Promote to next step (n <- n+1).
133 Thyra::V_V(x_n.ptr(), *x_np1);
134 solState->setIndex (index);
135 solState->setTime (time);
136 solState->setTimeStep(constDT);
137 solState->setSolutionStatus(Tempus::Status::PASSED);
138 }
139
140 // Output
141 if ( solState->getIndex()%100 == 0 )
142 cout << solState->getIndex() << " " << time
143 << " " << get_ele(*(x_n), 0)
144 << " " << get_ele(*(x_n), 1) << endl;
145 }
146
147 // Test for regression.
148 RCP<Thyra::VectorBase<double> > x_n = solState->getX();
149 RCP<Thyra::VectorBase<double> > x_regress = x_n->clone_v();
150 {
151 Thyra::DetachedVectorView<double> x_regress_view(*x_regress);
152 x_regress_view[0] = -1.59496108218721311;
153 x_regress_view[1] = 0.96359412806611255;
154 }
155
156 RCP<Thyra::VectorBase<double> > x_error = x_n->clone_v();
157 Thyra::V_VmV(x_error.ptr(), *x_n, *x_regress);
158 double x_L2norm_error = Thyra::norm_2(*x_error );
159 double x_L2norm_regress = Thyra::norm_2(*x_regress);
160
161 cout << "Relative L2 Norm of the error (regression) = "
162 << x_L2norm_error/x_L2norm_regress << endl;
163 if ( x_L2norm_error > 1.0e-08*x_L2norm_regress) {
164 solState->setSolutionStatus(Tempus::Status::FAILED);
165 cout << "FAILED regression constraint!" << endl;
166 }
167 if (solState->getSolutionStatus() == Tempus::Status::PASSED) success = true;
168 }
169 TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);
170
171 if(success)
172 cout << "\nEnd Result: Test Passed!" << std::endl;
173
174 return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
175}
int main(int argc, char *argv[])
ModelEvaluator implementation for the example van der Pol Problem.
Teuchos::RCP< SolutionState< Scalar > > createSolutionStateX(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdot=Teuchos::null, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdotdot=Teuchos::null)
Nonmember constructor from non-const solution vectors, x.