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: Copyright (2017) Sandia Corporation
4//
5// Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6// ****************************************************************************
7// @HEADER
8
9#include <iomanip>
10#include <iostream>
11#include <stdlib.h>
12#include <math.h>
13#include "Teuchos_StandardCatchMacros.hpp"
14
15#include "Thyra_VectorStdOps.hpp"
16#include "Thyra_DefaultSpmdVectorSpace.hpp"
17#include "Thyra_DetachedVectorView.hpp"
18
20
21#include "Tempus_SolutionState.hpp"
22
23
24using namespace std;
25using Teuchos::RCP;
26
28
212int main(int argc, char *argv[])
213{
214 bool verbose = true;
215 bool success = false;
216 try {
217 // Construct ModelEvaluator
218 Teuchos::RCP<const Thyra::ModelEvaluator<double> >
219 model = Teuchos::rcp(new VanDerPol_ModelEvaluator_02<double>());
220
221 // Setup initial condition SolutionState --------------------
222 auto solState = Tempus::createSolutionStateX(
223 model->getNominalValues().get_x()->clone_v());
224 solState->setIndex (0);
225 solState->setTime (0.0);
226 solState->setTimeStep(0.0); // By convention, the IC has dt=0.
227 solState->setSolutionStatus(Tempus::Status::PASSED); // ICs are considered passed.
228 RCP<Thyra::VectorBase<double> > xDot_n =
229 model->getNominalValues().get_x_dot()->clone_v();
230
231
232 // Timestep size
233 double finalTime = 2.0;
234 int nTimeSteps = 2001;
235 const double constDT = finalTime/(nTimeSteps-1);
236
237 // Advance the solution to the next timestep.
238 while (solState->getSolutionStatus() == Tempus::Status::PASSED &&
239 solState->getTime() < finalTime &&
240 solState->getIndex() < nTimeSteps) {
241
242 // Initialize next time step
243 RCP<Thyra::VectorBase<double> > x_n = solState->getX();
244 RCP<Thyra::VectorBase<double> > x_np1 = solState->getX()->clone_v(); // at time index n+1
245 solState->setSolutionStatus(Tempus::Status::WORKING);
246
247 // Set the timestep and time for the working solution i.e., n+1.
248 int index = solState->getIndex()+1;
249 double dt = constDT;
250 double time = index*dt;
251
252 // For explicit ODE formulation, xDot = f(x, t),
253 // xDot is part of the outArgs.
254 auto inArgs = model->createInArgs();
255 auto outArgs = model->createOutArgs();
256 inArgs.set_t(time);
257 inArgs.set_x(x_n);
258 inArgs.set_x_dot(Teuchos::null);
259 outArgs.set_f(xDot_n);
260
261 // Righthand side evaluation and time-derivative at n.
262 model->evalModel(inArgs, outArgs);
263
264 // Take the timestep - Forward Euler
265 Thyra::V_VpStV(x_np1.ptr(), *x_n, dt, *xDot_n);
266
267 // Test if solution has passed.
268 if ( std::isnan(Thyra::norm(*x_np1)) ) {
269 solState->setSolutionStatus(Tempus::Status::FAILED);
270 } else {
271 // Promote to next step (n <- n+1).
272 Thyra::V_V(x_n.ptr(), *x_np1);
273 solState->setIndex (index);
274 solState->setTime (time);
275 solState->setTimeStep(constDT);
276 solState->setSolutionStatus(Tempus::Status::PASSED);
277 }
278
279 // Output
280 if ( solState->getIndex()%100 == 0 )
281 cout << solState->getIndex() << " " << time
282 << " " << get_ele(*(x_n), 0)
283 << " " << get_ele(*(x_n), 1) << endl;
284 }
285
286 // Test for regression.
287 RCP<Thyra::VectorBase<double> > x_n = solState->getX();
288 RCP<Thyra::VectorBase<double> > x_regress = x_n->clone_v();
289 {
290 Thyra::DetachedVectorView<double> x_regress_view(*x_regress);
291 x_regress_view[0] = -1.59496108218721311;
292 x_regress_view[1] = 0.96359412806611255;
293 }
294
295 RCP<Thyra::VectorBase<double> > x_error = x_n->clone_v();
296 Thyra::V_VmV(x_error.ptr(), *x_n, *x_regress);
297 double x_L2norm_error = Thyra::norm_2(*x_error );
298 double x_L2norm_regress = Thyra::norm_2(*x_regress);
299
300 cout << "Relative L2 Norm of the error (regression) = "
301 << x_L2norm_error/x_L2norm_regress << endl;
302 if ( x_L2norm_error > 1.0e-08*x_L2norm_regress) {
303 solState->setSolutionStatus(Tempus::Status::FAILED);
304 cout << "FAILED regression constraint!" << endl;
305 }
306
307 RCP<Thyra::VectorBase<double> > x_best = x_n->clone_v();
308 {
309 Thyra::DetachedVectorView<double> x_best_view(*x_best);
310 x_best_view[0] = -1.59496108218721311;
311 x_best_view[1] = 0.96359412806611255;
312 }
313
314 Thyra::V_VmV(x_error.ptr(), *x_n, *x_best);
315 x_L2norm_error = Thyra::norm_2(*x_error);
316 double x_L2norm_best = Thyra::norm_2(*x_best );
317
318 cout << "Relative L2 Norm of the error (best) = "
319 << x_L2norm_error/x_L2norm_best << endl;
320 if ( x_L2norm_error > 0.02*x_L2norm_best) {
321 solState->setSolutionStatus(Tempus::Status::FAILED);
322 cout << "FAILED best constraint!" << endl;
323 }
324 if (solState->getSolutionStatus() == Tempus::Status::PASSED) success = true;
325 }
326 TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);
327
328 if(success)
329 cout << "\nEnd Result: Test Passed!" << std::endl;
330
331 return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
332}
int main(int argc, char *argv[])
Description:
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.