Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
04_Adding_SolutionHistory.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#include "Tempus_SolutionHistory.hpp"
24
25
26using namespace std;
27using Teuchos::RCP;
28
79int main(int argc, char *argv[])
80{
81 bool verbose = true;
82 bool success = false;
83 try {
84 // Construct ModelEvaluator
85 Teuchos::RCP<const Thyra::ModelEvaluator<double> >
86 model = Teuchos::rcp(new VanDerPol_ModelEvaluator_02<double>());
87
88 // Setup initial condition SolutionState
89 auto solState = Tempus::createSolutionStateX(
90 model->getNominalValues().get_x()->clone_v());
91 solState->setIndex (0);
92 solState->setTime (0.0);
93 solState->setTimeStep(0.0); // By convention, the IC has dt = 0.
94 solState->setSolutionStatus(Tempus::Status::PASSED); // ICs are considered passed.
95 RCP<Thyra::VectorBase<double> > xDot_n =
96 model->getNominalValues().get_x_dot()->clone_v();
97
98 // Create SolutionHistory
99 auto solHistory = Tempus::createSolutionHistoryState<double>(solState);
100
101 // Timestep size
102 double finalTime = 2.0;
103 int nTimeSteps = 2000;
104 const double constDT = finalTime/nTimeSteps;
105
106 // Advance the solution to the next timestep.
107 while (solHistory->getCurrentState()->getSolutionStatus() == Tempus::Status::PASSED &&
108 solHistory->getCurrentState()->getTime() < finalTime &&
109 solHistory->getCurrentState()->getIndex() < nTimeSteps) {
110
111 // Initialize next time step using SolutionHistory
112 solHistory->initWorkingState();
113 auto currentState = solHistory->getCurrentState();
114 auto workingState = solHistory->getWorkingState();
115 RCP<Thyra::VectorBase<double> > x_n = currentState->getX();
116 RCP<Thyra::VectorBase<double> > x_np1 = workingState->getX();
117
118 // Set the timestep and time for the working solution, i.e., n+1.
119 int index = workingState->getIndex(); // Already incremented by initWorkingState()
120 double dt = constDT;
121 double time = index*dt;
122 workingState->setTime(time);
123 workingState->setTimeStep(dt);
124
125 // For explicit ODE formulation, xDot = f(x, t),
126 // xDot is part of the outArgs.
127 auto inArgs = model->createInArgs();
128 auto outArgs = model->createOutArgs();
129 inArgs.set_t(time);
130 inArgs.set_x(x_n);
131 inArgs.set_x_dot(Teuchos::null);
132 outArgs.set_f(xDot_n);
133
134 // Righthand side evaluation and time-derivative at n.
135 model->evalModel(inArgs, outArgs);
136
137 // Take the timestep - Forward Euler
138 Thyra::V_VpStV(x_np1.ptr(), *x_n, dt, *xDot_n);
139
140 // Test if solution has passed.
141 if ( std::isnan(Thyra::norm(*x_np1)) ) {
142 workingState->setSolutionStatus(Tempus::Status::FAILED);
143 } else {
144 workingState->setSolutionStatus(Tempus::Status::PASSED);
145 }
146 // Promote working state to current state
147 solHistory->promoteWorkingState();
148
149 // Output
150 if (solHistory->getCurrentState()->getIndex() % 100 == 0) {
151 currentState = solHistory->getCurrentState();
152 cout << currentState->getIndex() << " " << currentState->getTime()
153 << " " << Thyra::get_ele(*(currentState->getX()), 0)
154 << " " << Thyra::get_ele(*(currentState->getX()), 1) << endl;
155 }
156 }
157
158 // Test for regression.
159 auto finalState = solHistory->getCurrentState();
160 RCP<Thyra::VectorBase<double> > x_n = finalState->getX();
161 RCP<Thyra::VectorBase<double> > x_regress = x_n->clone_v();
162 {
163 Thyra::DetachedVectorView<double> x_regress_view(*x_regress);
164 x_regress_view[0] = -1.59496108218721311;
165 x_regress_view[1] = 0.96359412806611255;
166 }
167
168 RCP<Thyra::VectorBase<double> > x_error = x_n->clone_v();
169 Thyra::V_VmV(x_error.ptr(), *x_n, *x_regress);
170 double x_L2norm_error = Thyra::norm_2(*x_error );
171 double x_L2norm_regress = Thyra::norm_2(*x_regress);
172
173 cout << "Relative L2 Norm of the error (regression) = "
174 << x_L2norm_error/x_L2norm_regress << endl;
175 if ( x_L2norm_error > 1.0e-08*x_L2norm_regress) {
176 finalState->setSolutionStatus(Tempus::Status::FAILED);
177 cout << "FAILED regression constraint!" << endl;
178 }
179 if (finalState->getSolutionStatus() == Tempus::Status::PASSED) success = true;
180 }
181 TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);
182
183 if(success)
184 cout << "\nEnd Result: Test Passed!" << std::endl;
185
186 return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
187}
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.