Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
25 using namespace std;
26 using Teuchos::RCP;
27 
213 int main(int argc, char *argv[])
214 {
215  bool verbose = true;
216  bool success = false;
217  try {
218  // Construct ModelEvaluator
221 
222  // Setup initial condition SolutionState --------------------
223  auto solState = Tempus::createSolutionStateX(
224  model->getNominalValues().get_x()->clone_v());
225  solState->setIndex (0);
226  solState->setTime (0.0);
227  solState->setTimeStep(0.0); // By convention, the IC has dt=0.
228  solState->setSolutionStatus(Tempus::Status::PASSED); // ICs are considered passed.
230  model->getNominalValues().get_x_dot()->clone_v();
231 
232 
233  // Timestep size
234  double finalTime = 2.0;
235  int nTimeSteps = 2001;
236  const double constDT = finalTime/(nTimeSteps-1);
237 
238  // Advance the solution to the next timestep.
239  while (solState->getSolutionStatus() == Tempus::Status::PASSED &&
240  solState->getTime() < finalTime &&
241  solState->getIndex() < nTimeSteps) {
242 
243  // Initialize next time step
244  RCP<Thyra::VectorBase<double> > x_n = solState->getX();
245  RCP<Thyra::VectorBase<double> > x_np1 = solState->getX()->clone_v(); // at time index n+1
246  solState->setSolutionStatus(Tempus::Status::WORKING);
247 
248  // Set the timestep and time for the working solution i.e., n+1.
249  int index = solState->getIndex()+1;
250  double dt = constDT;
251  double time = index*dt;
252 
253  // For explicit ODE formulation, xDot = f(x, t),
254  // xDot is part of the outArgs.
255  auto inArgs = model->createInArgs();
256  auto outArgs = model->createOutArgs();
257  inArgs.set_t(time);
258  inArgs.set_x(x_n);
259  inArgs.set_x_dot(Teuchos::null);
260  outArgs.set_f(xDot_n);
261 
262  // Righthand side evaluation and time-derivative at n.
263  model->evalModel(inArgs, outArgs);
264 
265  // Take the timestep - Forward Euler
266  Thyra::V_VpStV(x_np1.ptr(), *x_n, dt, *xDot_n);
267 
268  // Test if solution has passed.
269  if ( std::isnan(Thyra::norm(*x_np1)) ) {
270  solState->setSolutionStatus(Tempus::Status::FAILED);
271  } else {
272  // Promote to next step (n <- n+1).
273  Thyra::V_V(x_n.ptr(), *x_np1);
274  solState->setIndex (index);
275  solState->setTime (time);
276  solState->setTimeStep(constDT);
277  solState->setSolutionStatus(Tempus::Status::PASSED);
278  }
279 
280  // Output
281  if ( solState->getIndex()%100 == 0 )
282  cout << solState->getIndex() << " " << time
283  << " " << get_ele(*(x_n), 0)
284  << " " << get_ele(*(x_n), 1) << endl;
285  }
286 
287  // Test for regression.
288  RCP<Thyra::VectorBase<double> > x_n = solState->getX();
289  RCP<Thyra::VectorBase<double> > x_regress = x_n->clone_v();
290  {
291  Thyra::DetachedVectorView<double> x_regress_view(*x_regress);
292  x_regress_view[0] = -1.59496108218721311;
293  x_regress_view[1] = 0.96359412806611255;
294  }
295 
296  RCP<Thyra::VectorBase<double> > x_error = x_n->clone_v();
297  Thyra::V_VmV(x_error.ptr(), *x_n, *x_regress);
298  double x_L2norm_error = Thyra::norm_2(*x_error );
299  double x_L2norm_regress = Thyra::norm_2(*x_regress);
300 
301  cout << "Relative L2 Norm of the error (regression) = "
302  << x_L2norm_error/x_L2norm_regress << endl;
303  if ( x_L2norm_error > 1.0e-08*x_L2norm_regress) {
304  solState->setSolutionStatus(Tempus::Status::FAILED);
305  cout << "FAILED regression constraint!" << endl;
306  }
307 
308  RCP<Thyra::VectorBase<double> > x_best = x_n->clone_v();
309  {
310  Thyra::DetachedVectorView<double> x_best_view(*x_best);
311  x_best_view[0] = -1.59496108218721311;
312  x_best_view[1] = 0.96359412806611255;
313  }
314 
315  Thyra::V_VmV(x_error.ptr(), *x_n, *x_best);
316  x_L2norm_error = Thyra::norm_2(*x_error);
317  double x_L2norm_best = Thyra::norm_2(*x_best );
318 
319  cout << "Relative L2 Norm of the error (best) = "
320  << x_L2norm_error/x_L2norm_best << endl;
321  if ( x_L2norm_error > 0.02*x_L2norm_best) {
322  solState->setSolutionStatus(Tempus::Status::FAILED);
323  cout << "FAILED best constraint!" << endl;
324  }
325  if (solState->getSolutionStatus() == Tempus::Status::PASSED) success = true;
326  }
327  TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);
328 
329  if(success)
330  cout << "\nEnd Result: Test Passed!" << std::endl;
331 
332  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
333 }
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.
int main(int argc, char *argv[])
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Ptr< T > ptr() const
ModelEvaluator implementation for the example van der Pol Problem.
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)