Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_OperatorSplitTest.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 
11 #include "Teuchos_TimeMonitor.hpp"
12 
13 #include "Thyra_VectorStdOps.hpp"
14 
15 #include "Tempus_IntegratorBasic.hpp"
16 #include "Tempus_StepperFactory.hpp"
17 #include "Tempus_StepperOperatorSplit.hpp"
18 #include "Tempus_StepperForwardEuler.hpp"
19 #include "Tempus_StepperBackwardEuler.hpp"
20 
21 #include "../TestModels/VanDerPol_IMEX_ExplicitModel.hpp"
22 #include "../TestModels/VanDerPol_IMEX_ImplicitModel.hpp"
23 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
24 
25 #include <fstream>
26 #include <vector>
27 
28 namespace Tempus_Test {
29 
30 using Teuchos::getParametersFromXmlFile;
32 using Teuchos::RCP;
33 using Teuchos::rcp;
34 using Teuchos::rcp_const_cast;
35 using Teuchos::sublist;
36 
40 
41 // ************************************************************
42 // ************************************************************
43 TEUCHOS_UNIT_TEST(OperatorSplit, ConstructingFromDefaults)
44 {
45  double dt = 0.05;
46 
47  // Read params from .xml file
48  RCP<ParameterList> pList =
49  getParametersFromXmlFile("Tempus_OperatorSplit_VanDerPol.xml");
50  RCP<ParameterList> pl = sublist(pList, "Tempus", true);
51 
52  // Setup the explicit VanDerPol ModelEvaluator
53  RCP<ParameterList> vdpmPL = sublist(pList, "VanDerPolModel", true);
56 
57  // Setup the implicit VanDerPol ModelEvaluator (reuse vdpmPL)
60 
61  // Setup Stepper for field solve ----------------------------
62  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
63 
64  auto subStepper1 =
65  Tempus::createStepperForwardEuler(explicitModel, Teuchos::null);
66  auto subStepper2 =
67  Tempus::createStepperBackwardEuler(implicitModel, Teuchos::null);
68 
69  stepper->addStepper(subStepper1);
70  stepper->addStepper(subStepper2);
71  stepper->initialize();
72 
73  // Setup TimeStepControl ------------------------------------
74  auto timeStepControl = rcp(new Tempus::TimeStepControl<double>());
75  ParameterList tscPL =
76  pl->sublist("Demo Integrator").sublist("Time Step Control");
77  timeStepControl->setInitIndex(tscPL.get<int>("Initial Time Index"));
78  timeStepControl->setInitTime(tscPL.get<double>("Initial Time"));
79  timeStepControl->setFinalTime(tscPL.get<double>("Final Time"));
80  timeStepControl->setInitTimeStep(dt);
81  timeStepControl->initialize();
82 
83  // Setup initial condition SolutionState --------------------
84  auto inArgsIC = stepper->getModel()->getNominalValues();
85  auto icX = rcp_const_cast<Thyra::VectorBase<double>>(inArgsIC.get_x());
86  auto icXDot = rcp_const_cast<Thyra::VectorBase<double>>(inArgsIC.get_x_dot());
87  auto icState = Tempus::createSolutionStateX(icX, icXDot);
88  icState->setTime(timeStepControl->getInitTime());
89  icState->setIndex(timeStepControl->getInitIndex());
90  icState->setTimeStep(0.0);
91  icState->setOrder(stepper->getOrder());
92  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
93 
94  // Setup SolutionHistory ------------------------------------
95  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
96  solutionHistory->setName("Forward States");
97  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
98  solutionHistory->setStorageLimit(2);
99  solutionHistory->addState(icState);
100 
101  // Setup Integrator -----------------------------------------
103  Tempus::createIntegratorBasic<double>();
104  integrator->setStepper(stepper);
105  integrator->setTimeStepControl(timeStepControl);
106  integrator->setSolutionHistory(solutionHistory);
107  // integrator->setObserver(...);
108  integrator->initialize();
109 
110  // Integrate to timeMax
111  bool integratorStatus = integrator->advanceTime();
112  TEST_ASSERT(integratorStatus)
113 
114  // Test if at 'Final Time'
115  double time = integrator->getTime();
116  double timeFinal = pl->sublist("Demo Integrator")
117  .sublist("Time Step Control")
118  .get<double>("Final Time");
119  TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
120 
121  // Time-integrated solution and the exact solution
122  RCP<Thyra::VectorBase<double>> x = integrator->getX();
123 
124  // Check the order and intercept
125  out << " Stepper = " << stepper->description() << std::endl;
126  out << " =========================" << std::endl;
127  out << " Computed solution: " << get_ele(*(x), 0) << " "
128  << get_ele(*(x), 1) << std::endl;
129  out << " =========================" << std::endl;
130  TEST_FLOATING_EQUALITY(get_ele(*(x), 0), -2.223910, 1.0e-4);
131  TEST_FLOATING_EQUALITY(get_ele(*(x), 1), 0.565441, 1.0e-4);
132 }
133 
134 // ************************************************************
135 // ************************************************************
136 TEUCHOS_UNIT_TEST(OperatorSplit, VanDerPol)
137 {
139  std::vector<RCP<Thyra::VectorBase<double>>> solutions;
140  std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
141  std::vector<double> StepSize;
142  std::vector<double> xErrorNorm;
143  std::vector<double> xDotErrorNorm;
144  const int nTimeStepSizes = 4; // 8 for Error plot
145  double dt = 0.1;
146  double time = 0.0;
147  for (int n = 0; n < nTimeStepSizes; n++) {
148  // Read params from .xml file
149  RCP<ParameterList> pList =
150  getParametersFromXmlFile("Tempus_OperatorSplit_VanDerPol.xml");
151 
152  // Setup the explicit VanDerPol ModelEvaluator
153  RCP<ParameterList> vdpmPL = sublist(pList, "VanDerPolModel", true);
154  auto explicitModel = rcp(new VanDerPol_IMEX_ExplicitModel<double>(vdpmPL));
155 
156  // Setup the implicit VanDerPol ModelEvaluator (reuse vdpmPL)
157  auto implicitModel = rcp(new VanDerPol_IMEX_ImplicitModel<double>(vdpmPL));
158 
159  // Setup vector of models
160  std::vector<RCP<const Thyra::ModelEvaluator<double>>> models;
161  models.push_back(explicitModel);
162  models.push_back(implicitModel);
163 
164  // Set the step size
165  dt /= 2;
166  if (n == nTimeStepSizes - 1) dt /= 10.0;
167 
168  // Setup the Integrator and reset initial time step
169  RCP<ParameterList> pl = sublist(pList, "Tempus", true);
170  pl->sublist("Demo Integrator")
171  .sublist("Time Step Control")
172  .set("Initial Time Step", dt);
173  integrator = Tempus::createIntegratorBasic<double>(pl, models);
174 
175  // Integrate to timeMax
176  bool integratorStatus = integrator->advanceTime();
177  TEST_ASSERT(integratorStatus)
178 
179  // Test if at 'Final Time'
180  time = integrator->getTime();
181  double timeFinal = pl->sublist("Demo Integrator")
182  .sublist("Time Step Control")
183  .get<double>("Final Time");
184  double tol = 100.0 * std::numeric_limits<double>::epsilon();
185  TEST_FLOATING_EQUALITY(time, timeFinal, tol);
186 
187  // Store off the final solution and step size
188  StepSize.push_back(dt);
189  auto solution = Thyra::createMember(implicitModel->get_x_space());
190  Thyra::copy(*(integrator->getX()), solution.ptr());
191  solutions.push_back(solution);
192  auto solutionDot = Thyra::createMember(implicitModel->get_x_space());
193  Thyra::copy(*(integrator->getXDot()), solutionDot.ptr());
194  solutionsDot.push_back(solutionDot);
195 
196  // Output finest temporal solution for plotting
197  // This only works for ONE MPI process
198  if ((n == 0) || (n == nTimeStepSizes - 1)) {
199  std::string fname = "Tempus_OperatorSplit_VanDerPol-Ref.dat";
200  if (n == 0) fname = "Tempus_OperatorSplit_VanDerPol.dat";
201  RCP<const SolutionHistory<double>> solutionHistory =
202  integrator->getSolutionHistory();
203  writeSolution(fname, solutionHistory);
204  // solutionHistory->printHistory("medium");
205  }
206  }
207 
208  // Check the order and intercept
209  double xSlope = 0.0;
210  double xDotSlope = 0.0;
211  RCP<Tempus::Stepper<double>> stepper = integrator->getStepper();
212  double order = stepper->getOrder();
213  writeOrderError("Tempus_OperatorSplit_VanDerPol-Error.dat", stepper, StepSize,
214  solutions, xErrorNorm, xSlope, solutionsDot, xDotErrorNorm,
215  xDotSlope, out);
216 
217  TEST_FLOATING_EQUALITY(xSlope, order, 0.05);
218  TEST_FLOATING_EQUALITY(xDotSlope, order, 0.05); //=order at small dt
219  TEST_FLOATING_EQUALITY(xErrorNorm[0], 1.27294, 1.0e-4);
220  TEST_FLOATING_EQUALITY(xDotErrorNorm[0], 12.7102, 1.0e-4);
221 
223 }
224 
225 } // namespace Tempus_Test
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.
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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::FancyOStream &out)
#define TEST_FLOATING_EQUALITY(v1, v2, tol)
#define TEST_ASSERT(v1)
T * get() const
void writeSolution(const std::string filename, Teuchos::RCP< const Tempus::SolutionHistory< Scalar >> solutionHistory)
OperatorSplit stepper loops through the Stepper list.
Teuchos::RCP< StepperForwardEuler< Scalar > > createStepperForwardEuler(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
TEUCHOS_UNIT_TEST(BackwardEuler, SinCos_ASA)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
TimeStepControl manages the time step size. There several mechanisms that effect the time step size a...
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Keep a fix number of states.
Teuchos::RCP< StepperBackwardEuler< Scalar > > createStepperBackwardEuler(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Solution state for integrators and steppers.