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