Tempus  Version of the Day
Time Integration
Tempus_IMEX_RK_PartitionedTest.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_IntegratorBasic.hpp"
16 #include "Tempus_WrapperModelEvaluatorPairPartIMEX_Basic.hpp"
17 #include "Tempus_StepperIMEX_RK_Partition.hpp"
18 
19 
20 #include "../TestModels/VanDerPol_IMEX_ExplicitModel.hpp"
21 #include "../TestModels/VanDerPol_IMEXPart_ImplicitModel.hpp"
22 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
23 
24 #include <fstream>
25 #include <vector>
26 
27 namespace Tempus_Test {
28 
29 using Teuchos::RCP;
30 using Teuchos::ParameterList;
31 using Teuchos::sublist;
32 using Teuchos::getParametersFromXmlFile;
33 
37 
38 // Comment out any of the following tests to exclude from build/run.
39 #define TEST_CONSTRUCTING_FROM_DEFAULTS
40 #define TEST_VANDERPOL
41 
42 
43 #ifdef TEST_CONSTRUCTING_FROM_DEFAULTS
44 // ************************************************************
45 // ************************************************************
46 TEUCHOS_UNIT_TEST(IMEX_RK_Partitioned, ConstructingFromDefaults)
47 {
48  double dt = 0.025;
49 
50  // Read params from .xml file
51  RCP<ParameterList> pList =
52  getParametersFromXmlFile("Tempus_IMEX_RK_VanDerPol.xml");
53  RCP<ParameterList> pl = sublist(pList, "Tempus", true);
54 
55  // Setup the explicit VanDerPol ModelEvaluator
56  RCP<ParameterList> vdpmPL = sublist(pList, "VanDerPolModel", true);
57  const bool useProductVector = true;
58  RCP<VanDerPol_IMEX_ExplicitModel<double> > explicitModel =
59  Teuchos::rcp(new VanDerPol_IMEX_ExplicitModel<double>(vdpmPL,
60  useProductVector));
61 
62  // Setup the implicit VanDerPol ModelEvaluator (reuse vdpmPL)
63  RCP<VanDerPol_IMEXPart_ImplicitModel<double> > implicitModel =
64  Teuchos::rcp(new VanDerPol_IMEXPart_ImplicitModel<double>(vdpmPL));
65 
66  // Setup the IMEX Pair ModelEvaluator
67  const int numExplicitBlocks = 1;
68  const int parameterIndex = 4;
69  RCP<Tempus::WrapperModelEvaluatorPairPartIMEX_Basic<double> > model =
70  Teuchos::rcp(
72  explicitModel, implicitModel,
73  numExplicitBlocks, parameterIndex));
74 
75 
76  // Setup Stepper for field solve ----------------------------
77  RCP<Tempus::StepperIMEX_RK_Partition<double> > stepper =
78  Teuchos::rcp(new Tempus::StepperIMEX_RK_Partition<double>(model));
79 
80  // Setup TimeStepControl ------------------------------------
81  RCP<Tempus::TimeStepControl<double> > timeStepControl =
82  Teuchos::rcp(new Tempus::TimeStepControl<double>());
83  ParameterList tscPL = pl->sublist("Default Integrator")
84  .sublist("Time Step Control");
85  timeStepControl->setStepType (tscPL.get<std::string>("Integrator Step Type"));
86  timeStepControl->setInitIndex(tscPL.get<int> ("Initial Time Index"));
87  timeStepControl->setInitTime (tscPL.get<double>("Initial Time"));
88  timeStepControl->setFinalTime(tscPL.get<double>("Final Time"));
89  timeStepControl->setInitTimeStep(dt);
90  timeStepControl->initialize();
91 
92  // Setup initial condition SolutionState --------------------
93  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
94  stepper->getModel()->getNominalValues();
95  RCP<Thyra::VectorBase<double> > icSolution =
96  Teuchos::rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
97  RCP<Tempus::SolutionState<double> > icState =
98  Teuchos::rcp(new Tempus::SolutionState<double>(icSolution));
99  icState->setTime (timeStepControl->getInitTime());
100  icState->setIndex (timeStepControl->getInitIndex());
101  icState->setTimeStep(0.0);
102  icState->setOrder (stepper->getOrder());
103  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
104 
105  // Setup SolutionHistory ------------------------------------
106  RCP<Tempus::SolutionHistory<double> > solutionHistory =
107  Teuchos::rcp(new Tempus::SolutionHistory<double>());
108  solutionHistory->setName("Forward States");
110  solutionHistory->setStorageLimit(2);
111  solutionHistory->addState(icState);
112 
113  // Setup Integrator -----------------------------------------
114  RCP<Tempus::IntegratorBasic<double> > integrator =
115  Tempus::integratorBasic<double>();
116  integrator->setStepperWStepper(stepper);
117  integrator->setTimeStepControl(timeStepControl);
118  integrator->setSolutionHistory(solutionHistory);
119  //integrator->setObserver(...);
120  integrator->initialize();
121 
122 
123  // Integrate to timeMax
124  bool integratorStatus = integrator->advanceTime();
125  TEST_ASSERT(integratorStatus)
126 
127 
128  // Test if at 'Final Time'
129  double time = integrator->getTime();
130  double timeFinal =pl->sublist("Default Integrator")
131  .sublist("Time Step Control").get<double>("Final Time");
132  TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
133 
134  // Time-integrated solution and the exact solution
135  RCP<Thyra::VectorBase<double> > x = integrator->getX();
136 
137  // Check the order and intercept
138  std::cout << " Stepper = " << stepper->description() << std::endl;
139  std::cout << " =========================" << std::endl;
140  std::cout << " Computed solution: " << get_ele(*(x ), 0) << " "
141  << get_ele(*(x ), 1) << std::endl;
142  std::cout << " =========================" << std::endl;
143  TEST_FLOATING_EQUALITY(get_ele(*(x), 0), 1.810210, 1.0e-4 );
144  TEST_FLOATING_EQUALITY(get_ele(*(x), 1), -0.754602, 1.0e-4 );
145 }
146 #endif // TEST_CONSTRUCTING_FROM_DEFAULTS
147 
148 
149 #ifdef TEST_VANDERPOL
150 // ************************************************************
151 // ************************************************************
152 TEUCHOS_UNIT_TEST(IMEX_RK_Partitioned, VanDerPol)
153 {
154  std::vector<std::string> stepperTypes;
155  stepperTypes.push_back("Partitioned IMEX RK 1st order");
156  stepperTypes.push_back("Partitioned IMEX RK SSP2" );
157  stepperTypes.push_back("Partitioned IMEX RK ARS 233" );
158  stepperTypes.push_back("General Partitioned IMEX RK" );
159 
160  std::vector<double> stepperOrders;
161  stepperOrders.push_back(1.07964);
162  stepperOrders.push_back(2.00408);
163  stepperOrders.push_back(2.70655);
164  stepperOrders.push_back(2.00211);
165 
166  std::vector<double> stepperErrors;
167  stepperErrors.push_back(0.0046423);
168  stepperErrors.push_back(0.0154534);
169  stepperErrors.push_back(0.000298908);
170  stepperErrors.push_back(0.0071546);
171 
172  std::vector<double> stepperInitDt;
173  stepperInitDt.push_back(0.0125);
174  stepperInitDt.push_back(0.05);
175  stepperInitDt.push_back(0.05);
176  stepperInitDt.push_back(0.05);
177 
178  std::vector<std::string>::size_type m;
179  for(m = 0; m != stepperTypes.size(); m++) {
180 
181  std::string stepperType = stepperTypes[m];
182  std::string stepperName = stepperTypes[m];
183  std::replace(stepperName.begin(), stepperName.end(), ' ', '_');
184  std::replace(stepperName.begin(), stepperName.end(), '/', '.');
185 
186  RCP<Tempus::IntegratorBasic<double> > integrator;
187  std::vector<RCP<Thyra::VectorBase<double>>> solutions;
188  std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
189  std::vector<double> StepSize;
190  std::vector<double> xErrorNorm;
191  std::vector<double> xDotErrorNorm;
192 
193  const int nTimeStepSizes = 3; // 6 for error plot
194  double dt = stepperInitDt[m];
195  double time = 0.0;
196  for (int n=0; n<nTimeStepSizes; n++) {
197 
198  // Read params from .xml file
199  RCP<ParameterList> pList =
200  getParametersFromXmlFile("Tempus_IMEX_RK_VanDerPol.xml");
201 
202  // Setup the explicit VanDerPol ModelEvaluator
203  RCP<ParameterList> vdpmPL = sublist(pList, "VanDerPolModel", true);
204  const bool useProductVector = true;
205  RCP<VanDerPol_IMEX_ExplicitModel<double> > explicitModel =
206  Teuchos::rcp(new VanDerPol_IMEX_ExplicitModel<double>(vdpmPL,
207  useProductVector));
208 
209  // Setup the implicit VanDerPol ModelEvaluator (reuse vdpmPL)
210  RCP<VanDerPol_IMEXPart_ImplicitModel<double> > implicitModel =
211  Teuchos::rcp(new VanDerPol_IMEXPart_ImplicitModel<double>(vdpmPL));
212 
213  // Setup the IMEX Pair ModelEvaluator
214  const int numExplicitBlocks = 1;
215  const int parameterIndex = 4;
216  RCP<Tempus::WrapperModelEvaluatorPairPartIMEX_Basic<double> > model =
217  Teuchos::rcp(
219  explicitModel, implicitModel,
220  numExplicitBlocks, parameterIndex));
221 
222  // Set the Stepper
223  RCP<ParameterList> pl = sublist(pList, "Tempus", true);
224 
225  if (stepperType == "General Partitioned IMEX RK"){
226  // use the appropriate stepper sublist
227  pl->sublist("Default Integrator").set("Stepper Name", "General IMEX RK");
228  } else {
229  pl->sublist("Default Stepper").set("Stepper Type", stepperType);
230  }
231 
232  // Set the step size
233  if (n == nTimeStepSizes-1) dt /= 10.0;
234  else dt /= 2;
235 
236  // Setup the Integrator and reset initial time step
237  pl->sublist("Default Integrator")
238  .sublist("Time Step Control").set("Initial Time Step", dt);
239  integrator = Tempus::integratorBasic<double>(pl, model);
240 
241  // Integrate to timeMax
242  bool integratorStatus = integrator->advanceTime();
243  TEST_ASSERT(integratorStatus)
244 
245  // Test if at 'Final Time'
246  time = integrator->getTime();
247  double timeFinal =pl->sublist("Default Integrator")
248  .sublist("Time Step Control").get<double>("Final Time");
249  double tol = 100.0 * std::numeric_limits<double>::epsilon();
250  TEST_FLOATING_EQUALITY(time, timeFinal, tol);
251 
252  // Store off the final solution and step size
253  StepSize.push_back(dt);
254  auto solution = Thyra::createMember(model->get_x_space());
255  Thyra::copy(*(integrator->getX()),solution.ptr());
256  solutions.push_back(solution);
257  auto solutionDot = Thyra::createMember(model->get_x_space());
258  Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
259  solutionsDot.push_back(solutionDot);
260 
261  // Output finest temporal solution for plotting
262  // This only works for ONE MPI process
263  if ((n == 0) or (n == nTimeStepSizes-1)) {
264  std::string fname = "Tempus_"+stepperName+"_VanDerPol-Ref.dat";
265  if (n == 0) fname = "Tempus_"+stepperName+"_VanDerPol.dat";
266  RCP<const SolutionHistory<double> > solutionHistory =
267  integrator->getSolutionHistory();
269  }
270  }
271 
272  // Check the order and intercept
273  double xSlope = 0.0;
274  double xDotSlope = 0.0;
275  RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
276  //double order = stepper->getOrder();
277  writeOrderError("Tempus_"+stepperName+"_VanDerPol-Error.dat",
278  stepper, StepSize,
279  solutions, xErrorNorm, xSlope,
280  solutionsDot, xDotErrorNorm, xDotSlope);
281 
282  TEST_FLOATING_EQUALITY( xSlope, stepperOrders[m], 0.02 );
283  TEST_FLOATING_EQUALITY( xErrorNorm[0], stepperErrors[m], 1.0e-4 );
284  // xDot not yet available for IMEX_RK_Partitioned.
285  //TEST_FLOATING_EQUALITY( xDotSlope, 1.74898, 0.02 );
286  //TEST_FLOATING_EQUALITY( xDotErrorNorm[0], 1.0038, 1.0e-4 );
287 
288  }
289  Teuchos::TimeMonitor::summarize();
290 }
291 #endif // TEST_VANDERPOL
292 
293 
294 } // namespace Tempus_Test
Tempus_Test::writeSolution
void writeSolution(const std::string filename, Teuchos::RCP< const Tempus::SolutionHistory< Scalar > > solutionHistory)
Definition: Tempus_ConvergenceTestUtils.hpp:302
Tempus_Test::writeOrderError
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)
Definition: Tempus_ConvergenceTestUtils.hpp:184
Tempus_Test
Definition: Tempus_BackwardEuler_ASA.cpp:34
Tempus::WrapperModelEvaluatorPairPartIMEX_Basic
ModelEvaluator pair for implicit and explicit (IMEX) evaulations.
Definition: Tempus_WrapperModelEvaluatorPairPartIMEX_Basic_decl.hpp:37
Tempus::solutionHistory
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
Definition: Tempus_SolutionHistory_impl.hpp:504
Tempus_Test::VanDerPol_IMEX_ExplicitModel
van der Pol model formulated for IMEX.
Definition: VanDerPol_IMEX_ExplicitModel_decl.hpp:107
Tempus::STORAGE_TYPE_STATIC
Keep a fix number of states.
Definition: Tempus_SolutionHistory_decl.hpp:30
Tempus::IntegratorBasic
Basic time integrator.
Definition: Tempus_IntegratorBasic_decl.hpp:35
Tempus::StepperIMEX_RK_Partition
Partitioned Implicit-Explicit Runge-Kutta (IMEX-RK) time stepper.
Definition: Tempus_StepperIMEX_RK_Partition_decl.hpp:228
Tempus_Test::VanDerPol_IMEXPart_ImplicitModel
van der Pol model formulated for the partitioned IMEX-RK.
Definition: VanDerPol_IMEXPart_ImplicitModel_decl.hpp:102
Tempus::SolutionState
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
Definition: Tempus_SolutionState_decl.hpp:56
Tempus_Test::TEUCHOS_UNIT_TEST
TEUCHOS_UNIT_TEST(BackwardEuler, SinCos_ASA)
Definition: Tempus_BackwardEuler_ASA.cpp:47
Tempus::TimeStepControl
TimeStepControl manages the time step size. There several mechanicisms that effect the time step size...
Definition: Tempus_Integrator.hpp:26
Tempus::PASSED
Definition: Tempus_Types.hpp:17
Tempus::SolutionHistory
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Definition: Tempus_Integrator.hpp:25