Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_LeapfrogTest.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 "Teuchos_UnitTestHarness.hpp"
10 #include "Teuchos_XMLParameterListHelpers.hpp"
11 #include "Teuchos_TimeMonitor.hpp"
12 
13 #include "Thyra_VectorStdOps.hpp"
14 
15 #include "Tempus_config.hpp"
16 #include "Tempus_IntegratorBasic.hpp"
17 #include "Tempus_StepperLeapfrog.hpp"
18 
19 #include "../TestModels/HarmonicOscillatorModel.hpp"
20 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
21 
22 
23 #ifdef Tempus_ENABLE_MPI
24 #include "Epetra_MpiComm.h"
25 #else
26 #include "Epetra_SerialComm.h"
27 #endif
28 
29 #include <fstream>
30 #include <sstream>
31 #include <limits>
32 #include <vector>
33 
34 namespace Tempus_Test {
35 
36 using Teuchos::RCP;
37 using Teuchos::rcp;
38 using Teuchos::rcp_const_cast;
39 using Teuchos::ParameterList;
40 using Teuchos::sublist;
41 using Teuchos::getParametersFromXmlFile;
42 
46 
47 
48 // Comment out any of the following tests to exclude from build/run.
49 #define TEST_CONSTRUCTING_FROM_DEFAULTS
50 #define TEST_SINCOS
51 
52 
53 #ifdef TEST_CONSTRUCTING_FROM_DEFAULTS
54 // ************************************************************
55 // ************************************************************
56 TEUCHOS_UNIT_TEST(Leapfrog, ConstructingFromDefaults)
57 {
58  double dt = 0.1;
59 
60  // Read params from .xml file
61  RCP<ParameterList> pList =
62  getParametersFromXmlFile("Tempus_Leapfrog_SinCos.xml");
63  RCP<ParameterList> pl = sublist(pList, "Tempus", true);
64 
65  // Setup the HarmonicOscillatorModel
66  RCP<ParameterList> hom_pl = sublist(pList, "HarmonicOscillatorModel", true);
67  auto model = rcp(new HarmonicOscillatorModel<double>(hom_pl));
68 
69  // Setup Stepper for field solve ----------------------------
70  auto stepper = rcp(new Tempus::StepperLeapfrog<double>());
71  stepper->setModel(model);
72  stepper->initialize();
73 
74  // Setup TimeStepControl ------------------------------------
75  auto timeStepControl = rcp(new Tempus::TimeStepControl<double>());
76  ParameterList tscPL = pl->sublist("Default Integrator")
77  .sublist("Time Step Control");
78  timeStepControl->setStepType (tscPL.get<std::string>("Integrator Step Type"));
79  timeStepControl->setInitIndex(tscPL.get<int> ("Initial Time Index"));
80  timeStepControl->setInitTime (tscPL.get<double>("Initial Time"));
81  timeStepControl->setFinalTime(tscPL.get<double>("Final Time"));
82  timeStepControl->setInitTimeStep(dt);
83  timeStepControl->initialize();
84 
85  // Setup initial condition SolutionState --------------------
86  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
87  stepper->getModel()->getNominalValues();
88  auto icX = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
89  auto icXDot = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
90  auto icXDotDot = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot_dot());
91  auto icState = rcp(new Tempus::SolutionState<double>(icX, icXDot, icXDotDot));
92  icState->setTime (timeStepControl->getInitTime());
93  icState->setIndex (timeStepControl->getInitIndex());
94  icState->setTimeStep(0.0);
95  icState->setOrder (stepper->getOrder());
96  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
97 
98  // Setup SolutionHistory ------------------------------------
100  solutionHistory->setName("Forward States");
102  solutionHistory->setStorageLimit(2);
103  solutionHistory->addState(icState);
104 
105  // Setup Integrator -----------------------------------------
106  RCP<Tempus::IntegratorBasic<double> > integrator =
107  Tempus::integratorBasic<double>();
108  integrator->setStepperWStepper(stepper);
109  integrator->setTimeStepControl(timeStepControl);
110  integrator->setSolutionHistory(solutionHistory);
111  //integrator->setObserver(...);
112  integrator->initialize();
113 
114 
115  // Integrate to timeMax
116  bool integratorStatus = integrator->advanceTime();
117  TEST_ASSERT(integratorStatus)
118 
119 
120  // Test if at 'Final Time'
121  double time = integrator->getTime();
122  double timeFinal =pl->sublist("Default Integrator")
123  .sublist("Time Step Control").get<double>("Final Time");
124  TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
125 
126  // Time-integrated solution and the exact solution
127  RCP<Thyra::VectorBase<double> > x = integrator->getX();
128  RCP<const Thyra::VectorBase<double> > x_exact =
129  model->getExactSolution(time).get_x();
130 
131  // Calculate the error
132  RCP<Thyra::VectorBase<double> > xdiff = x->clone_v();
133  Thyra::V_StVpStV(xdiff.ptr(), 1.0, *x_exact, -1.0, *(x));
134 
135  // Check the order and intercept
136  std::cout << " Stepper = " << stepper->description() << std::endl;
137  std::cout << " =========================" << std::endl;
138  std::cout << " Exact solution : " << get_ele(*(x_exact), 0) << std::endl;
139  std::cout << " Computed solution: " << get_ele(*(x ), 0) << std::endl;
140  std::cout << " Difference : " << get_ele(*(xdiff ), 0) << std::endl;
141  std::cout << " =========================" << std::endl;
142  TEST_FLOATING_EQUALITY(get_ele(*(x), 0), 0.167158, 1.0e-4 );
143 }
144 #endif // TEST_CONSTRUCTING_FROM_DEFAULTS
145 
146 
147 #ifdef TEST_SINCOS
148 // ************************************************************
149 // ************************************************************
150 TEUCHOS_UNIT_TEST(Leapfrog, SinCos)
151 {
152  RCP<Tempus::IntegratorBasic<double> > integrator;
153  std::vector<RCP<Thyra::VectorBase<double>>> solutions;
154  std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
155  std::vector<double> StepSize;
156  std::vector<double> xErrorNorm;
157  std::vector<double> xDotErrorNorm;
158  const int nTimeStepSizes = 9;
159  double time = 0.0;
160 
161  // Read params from .xml file
162  RCP<ParameterList> pList =
163  getParametersFromXmlFile("Tempus_Leapfrog_SinCos.xml");
164 
165  // Setup the HarmonicOscillatorModel
166  RCP<ParameterList> hom_pl = sublist(pList, "HarmonicOscillatorModel", true);
167  auto model = rcp(new HarmonicOscillatorModel<double>(hom_pl));
168 
169 
170  // Setup the Integrator and reset initial time step
171  RCP<ParameterList> pl = sublist(pList, "Tempus", true);
172 
173  //Set initial time step = 2*dt specified in input file (for convergence study)
174  double dt =pl->sublist("Default Integrator")
175  .sublist("Time Step Control").get<double>("Initial Time Step");
176  dt *= 2.0;
177 
178  for (int n=0; n<nTimeStepSizes; n++) {
179 
180  //Perform time-step refinement
181  dt /= 2;
182  std::cout << "\n \n time step #" << n
183  << " (out of " << nTimeStepSizes-1 << "), dt = " << dt << "\n";
184  pl->sublist("Default Integrator")
185  .sublist("Time Step Control").set("Initial Time Step", dt);
186  integrator = Tempus::integratorBasic<double>(pl, model);
187 
188  // Integrate to timeMax
189  bool integratorStatus = integrator->advanceTime();
190  TEST_ASSERT(integratorStatus)
191 
192  // Test if at 'Final Time'
193  time = integrator->getTime();
194  double timeFinal =pl->sublist("Default Integrator")
195  .sublist("Time Step Control").get<double>("Final Time");
196  TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
197 
198  // Plot sample solution and exact solution at most-refined resolution
199  if (n == nTimeStepSizes-1) {
200  RCP<const SolutionHistory<double> > solutionHistory =
201  integrator->getSolutionHistory();
202  writeSolution("Tempus_Leapfrog_SinCos.dat", solutionHistory);
203 
204  auto solnHistExact = rcp(new Tempus::SolutionHistory<double>());
205  for (int i=0; i<solutionHistory->getNumStates(); i++) {
206  double time_i = (*solutionHistory)[i]->getTime();
207  auto state = rcp(new Tempus::SolutionState<double>(
208  model->getExactSolution(time_i).get_x(),
209  model->getExactSolution(time_i).get_x_dot()));
210  state->setTime((*solutionHistory)[i]->getTime());
211  solnHistExact->addState(state);
212  }
213  writeSolution("Tempus_Leapfrog_SinCos-Ref.dat", solnHistExact);
214  }
215 
216  // Store off the final solution and step size
217 
218 
219  StepSize.push_back(dt);
220  auto solution = Thyra::createMember(model->get_x_space());
221  Thyra::copy(*(integrator->getX()),solution.ptr());
222  solutions.push_back(solution);
223  auto solutionDot = Thyra::createMember(model->get_x_space());
224  Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
225  solutionsDot.push_back(solutionDot);
226  if (n == nTimeStepSizes-1) { // Add exact solution last in vector.
227  StepSize.push_back(0.0);
228  auto solutionExact = Thyra::createMember(model->get_x_space());
229  Thyra::copy(*(model->getExactSolution(time).get_x()),solutionExact.ptr());
230  solutions.push_back(solutionExact);
231  auto solutionDotExact = Thyra::createMember(model->get_x_space());
232  Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
233  solutionDotExact.ptr());
234  solutionsDot.push_back(solutionDotExact);
235  }
236  }
237 
238  // Check the order and intercept
239  double xSlope = 0.0;
240  double xDotSlope = 0.0;
241  RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
242  double order = stepper->getOrder();
243  writeOrderError("Tempus_Leapfrog_SinCos-Error.dat",
244  stepper, StepSize,
245  solutions, xErrorNorm, xSlope,
246  solutionsDot, xDotErrorNorm, xDotSlope);
247 
248  TEST_FLOATING_EQUALITY( xSlope, order, 0.02 );
249  TEST_FLOATING_EQUALITY( xErrorNorm[0], 0.0157928, 1.0e-4 );
250  TEST_FLOATING_EQUALITY( xDotSlope, 1.09387, 0.01 );
251  TEST_FLOATING_EQUALITY( xDotErrorNorm[0], 0.563002, 1.0e-4 );
252 
253  Teuchos::TimeMonitor::summarize();
254 }
255 #endif // TEST_SINCOS
256 
257 }
void writeSolution(const std::string filename, Teuchos::RCP< const Tempus::SolutionHistory< Scalar > > solutionHistory)
Consider the ODE: where is a constant, is a constant damping parameter, is a constant forcing par...
void writeOrderError(const std::string filename, Teuchos::RCP< Tempus::Stepper< Scalar > > stepper, std::vector< Scalar > &StepSize, std::vector< Teuchos::RCP< Thyra::VectorBase< Scalar >>> &solutions, std::vector< Scalar > &xErrorNorm, Scalar &xSlope, std::vector< Teuchos::RCP< Thyra::VectorBase< Scalar >>> &solutionsDot, std::vector< Scalar > &xDotErrorNorm, Scalar &xDotSlope, std::vector< Teuchos::RCP< Thyra::VectorBase< Scalar >>> &solutionsDotDot, std::vector< Scalar > &xDotDotErrorNorm, Scalar &xDotDotSlope)
TEUCHOS_UNIT_TEST(BackwardEuler, SinCos_ASA)
TimeStepControl manages the time step size. There several mechanicisms that effect the time step size...
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Keep a fix number of states.
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...