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 "../00_Basic_Problem/Tutorial_Regression_Tester.hpp"
17
18#include "Thyra_VectorStdOps.hpp"
19#include "Thyra_DefaultSpmdVectorSpace.hpp"
20#include "Thyra_DetachedVectorView.hpp"
21
22#include "../02_Use_ModelEvaluator/VanDerPol_ModelEvaluator_02.hpp"
23
24#include "Tempus_SolutionState.hpp"
25#include "Tempus_SolutionHistory.hpp"
26
27
28using namespace std;
29using Teuchos::RCP;
30
87int main(int /*argc*/, char * /*argv*/[])
88{
89 bool verbose = true;
90 bool success = false;
91 try {
92 // Construct ModelEvaluator
93 Teuchos::RCP<const Thyra::ModelEvaluator<double> >
94 model = Teuchos::rcp(new VanDerPol_ModelEvaluator_02<double>());
95
96 // Setup initial condition SolutionState
97 auto solState = Tempus::createSolutionStateX(
98 model->getNominalValues().get_x()->clone_v());
99 solState->setIndex (0);
100 solState->setTime (0.0);
101 solState->setTimeStep(0.0); // By convention, the IC has dt = 0.
102 solState->setSolutionStatus(Tempus::Status::PASSED); // ICs are considered passed.
103 RCP<Thyra::VectorBase<double> > xDot_n =
104 model->getNominalValues().get_x_dot()->clone_v();
105
106 // Create SolutionHistory
107 auto solHistory = Tempus::createSolutionHistoryState<double>(solState);
108
109 // Timestep size
110 double finalTime = 2.0;
111 int nTimeSteps = 2000;
112 const double constDT = finalTime/nTimeSteps;
113
114 // Output
115 cout << std::fixed;
116 cout << std::setw(8) << "index"
117 << std::setw(10) << "time"
118 << std::setw(12) << "x_0"
119 << std::setw(12) << "x_1" << endl;
120
121 auto currentState = solHistory->getCurrentState();
122 cout << std::setw(8) << currentState->getIndex()
123 << std::setw(10) << std::setprecision(3) << currentState->getTime()
124 << std::setw(12) << std::setprecision(4) << Thyra::get_ele(*(currentState->getX()), 0)
125 << std::setw(12) << std::setprecision(4) << Thyra::get_ele(*(currentState->getX()), 1)
126 << endl;
127
128 // Advance the solution to the next timestep.
129 while (solHistory->getCurrentState()->getSolutionStatus() == Tempus::Status::PASSED &&
130 solHistory->getCurrentTime() < finalTime &&
131 solHistory->getCurrentIndex() < nTimeSteps ) {
132
133 // Initialize next time step using SolutionHistory
134 solHistory->initWorkingState();
135 currentState = solHistory->getCurrentState();
136 auto workingState = solHistory->getWorkingState();
137 RCP<Thyra::VectorBase<double> > x_n = currentState->getX();
138 RCP<Thyra::VectorBase<double> > x_np1 = workingState->getX();
139
140 // Set the timestep and time for the working solution, i.e., n+1.
141 int index = workingState->getIndex(); // Already incremented by initWorkingState()
142 double dt = constDT;
143 double time = index*dt;
144 workingState->setTime(time);
145 workingState->setTimeStep(dt);
146
147 // For explicit ODE formulation, xDot = f(x, t),
148 // xDot is part of the outArgs.
149 auto inArgs = model->createInArgs();
150 auto outArgs = model->createOutArgs();
151 inArgs.set_t(time);
152 inArgs.set_x(x_n);
153 inArgs.set_x_dot(Teuchos::null);
154 outArgs.set_f(xDot_n);
155
156 // Righthand side evaluation and time-derivative at n.
157 model->evalModel(inArgs, outArgs);
158
159 // Take the timestep - Forward Euler
160 Thyra::V_VpStV(x_np1.ptr(), *x_n, dt, *xDot_n);
161
162 // Test if solution has passed.
163 if ( std::isnan(Thyra::norm(*x_np1)) ) {
164 workingState->setSolutionStatus(Tempus::Status::FAILED);
165 } else {
166 workingState->setSolutionStatus(Tempus::Status::PASSED);
167 }
168 // Promote working state to current state
169 solHistory->promoteWorkingState();
170
171 // Output
172 if (solHistory->getCurrentState()->getIndex() % 100 == 0) {
173 currentState = solHistory->getCurrentState();
174 cout << std::setw(8) << currentState->getIndex()
175 << std::setw(10) << std::setprecision(3) << currentState->getTime()
176 << std::setw(12) << std::setprecision(4) << Thyra::get_ele(*(currentState->getX()), 0)
177 << std::setw(12) << std::setprecision(4) << Thyra::get_ele(*(currentState->getX()), 1)
178 << endl;
179 }
180 }
181
182 // Test for regression.
183 auto finalState = solHistory->getCurrentState();
184 bool passed = (finalState->getSolutionStatus() == Tempus::Status::PASSED);
185 bool regressionPassed = tutorialRegressionTest(finalState);
186
187 if (passed && regressionPassed) success = true;
188 }
189 TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);
190
191 if(success)
192 cout << "\nEnd Result: Test Passed!" << std::endl;
193
194 return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
195}
int main(int, char *[])
bool tutorialRegressionTest(const Teuchos::RCP< Thyra::VectorBase< double > > &x_n, std::ostream &out=std::cout, const double relTol=Teuchos::as< double >(1.0e-8))
Regression check for the Tempus tutorial van der Pol examples.
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.