Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_ExplicitRK_ASA.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 #include "Teuchos_DefaultComm.hpp"
13 
14 #include "Thyra_VectorStdOps.hpp"
15 #include "Thyra_MultiVectorStdOps.hpp"
16 
17 #include "Tempus_IntegratorBasic.hpp"
18 #include "Tempus_IntegratorAdjointSensitivity.hpp"
19 
20 #include "Thyra_DefaultMultiVectorProductVector.hpp"
21 #include "Thyra_DefaultProductVector.hpp"
22 
23 #include "../TestModels/SinCosModel.hpp"
24 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
25 
26 #include <fstream>
27 #include <vector>
28 
29 namespace Tempus_Test {
30 
31 using Teuchos::getParametersFromXmlFile;
33 using Teuchos::RCP;
34 using Teuchos::sublist;
35 
39 
40 // ************************************************************
41 // ************************************************************
42 TEUCHOS_UNIT_TEST(ExplicitRK, SinCos_ASA)
43 {
44  std::vector<std::string> RKMethods;
45  RKMethods.push_back("RK Forward Euler");
46  RKMethods.push_back("RK Explicit 4 Stage");
47  RKMethods.push_back("RK Explicit 3/8 Rule");
48  RKMethods.push_back("RK Explicit 4 Stage 3rd order by Runge");
49  RKMethods.push_back("RK Explicit 5 Stage 3rd order by Kinnmark and Gray");
50  RKMethods.push_back("RK Explicit 3 Stage 3rd order");
51  RKMethods.push_back("RK Explicit 3 Stage 3rd order TVD");
52  RKMethods.push_back("RK Explicit 3 Stage 3rd order by Heun");
53  RKMethods.push_back("RK Explicit Midpoint");
54  RKMethods.push_back("RK Explicit Trapezoidal");
55  RKMethods.push_back("Heuns Method");
56  RKMethods.push_back("General ERK");
57 
58  std::vector<double> RKMethodErrors;
59  RKMethodErrors.push_back(0.154904);
60  RKMethodErrors.push_back(4.55982e-06);
61  RKMethodErrors.push_back(4.79132e-06);
62  RKMethodErrors.push_back(0.000113603);
63  RKMethodErrors.push_back(4.98796e-05);
64  RKMethodErrors.push_back(0.00014564);
65  RKMethodErrors.push_back(0.000121968);
66  RKMethodErrors.push_back(0.000109495);
67  RKMethodErrors.push_back(0.00559871);
68  RKMethodErrors.push_back(0.00710492);
69  RKMethodErrors.push_back(0.00710492);
70  RKMethodErrors.push_back(4.55982e-06);
71 
74 
75  for (std::vector<std::string>::size_type m = 0; m != RKMethods.size(); m++) {
76  std::string RKMethod_ = RKMethods[m];
77  std::replace(RKMethod_.begin(), RKMethod_.end(), ' ', '_');
78  std::replace(RKMethod_.begin(), RKMethod_.end(), '/', '.');
79  std::vector<double> StepSize;
80  std::vector<double> ErrorNorm;
81  const int nTimeStepSizes = 6;
82  double dt = 0.2;
83  double order = 0.0;
84  for (int n = 0; n < nTimeStepSizes; n++) {
85  // Read params from .xml file
86  RCP<ParameterList> pList =
87  getParametersFromXmlFile("Tempus_ExplicitRK_SinCos.xml");
88 
89  // Setup the SinCosModel
90  RCP<ParameterList> scm_pl = sublist(pList, "SinCosModel", true);
91  RCP<SinCosModel<double> > model =
92  Teuchos::rcp(new SinCosModel<double>(scm_pl));
93 
94  // Set the Stepper
95  RCP<ParameterList> pl = sublist(pList, "Tempus", true);
96  if (RKMethods[m] == "General ERK") {
97  pl->sublist("Demo Integrator").set("Stepper Name", "Demo Stepper 2");
98  pl->sublist("Demo Stepper 2")
99  .set("Initial Condition Consistency", "None");
100  pl->sublist("Demo Stepper 2")
101  .set("Initial Condition Consistency Check", false);
102  }
103  else {
104  pl->sublist("Demo Stepper").set("Stepper Type", RKMethods[m]);
105  pl->sublist("Demo Stepper")
106  .set("Initial Condition Consistency", "None");
107  pl->sublist("Demo Stepper")
108  .set("Initial Condition Consistency Check", false);
109  }
110 
111  dt /= 2;
112 
113  // Setup sensitivities
114  ParameterList& sens_pl = pl->sublist("Sensitivities");
115  sens_pl.set("Mass Matrix Is Identity", true); // Necessary for explicit
116  ParameterList& interp_pl = pl->sublist("Demo Integrator")
117  .sublist("Solution History")
118  .sublist("Interpolator");
119  interp_pl.set("Interpolator Type", "Lagrange");
120  interp_pl.set("Order", 3); // All RK methods here are at most 4th order
121 
122  // Setup the Integrator and reset initial time step
123  pl->sublist("Demo Integrator")
124  .sublist("Time Step Control")
125  .set("Initial Time Step", dt);
127  Tempus::createIntegratorAdjointSensitivity<double>(pl, model);
128  order = integrator->getStepper()->getOrder();
129 
130  // Initial Conditions
131  double t0 = pl->sublist("Demo Integrator")
132  .sublist("Time Step Control")
133  .get<double>("Initial Time");
134  // RCP<const Thyra::VectorBase<double> > x0 =
135  // model->getExactSolution(t0).get_x()->clone_v();
137  model->getNominalValues().get_x()->clone_v();
138  const int num_param = model->get_p_space(0)->dim();
140  Thyra::createMembers(model->get_x_space(), num_param);
141  for (int i = 0; i < num_param; ++i)
142  Thyra::assign(DxDp0->col(i).ptr(),
143  *(model->getExactSensSolution(i, t0).get_x()));
144  integrator->initializeSolutionHistory(t0, x0, Teuchos::null,
145  Teuchos::null, DxDp0, Teuchos::null,
146  Teuchos::null);
147 
148  // Integrate to timeMax
149  bool integratorStatus = integrator->advanceTime();
150  TEST_ASSERT(integratorStatus)
151 
152  // Test if at 'Final Time'
153  double time = integrator->getTime();
154  double timeFinal = pl->sublist("Demo Integrator")
155  .sublist("Time Step Control")
156  .get<double>("Final Time");
157  TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
158 
159  // Time-integrated solution and the exact solution along with
160  // sensitivities (relying on response g(x) = x). Note we must transpose
161  // dg/dp since the integrator returns it in gradient form.
162  RCP<const Thyra::VectorBase<double> > x = integrator->getX();
163  RCP<const Thyra::MultiVectorBase<double> > DgDp = integrator->getDgDp();
165  Thyra::createMembers(model->get_x_space(), num_param);
166  {
169  const int num_g = DgDp->domain()->dim();
170  for (int i = 0; i < num_g; ++i)
171  for (int j = 0; j < num_param; ++j) dxdp_view(i, j) = dgdp_view(j, i);
172  }
174  model->getExactSolution(time).get_x();
176  Thyra::createMembers(model->get_x_space(), num_param);
177  for (int i = 0; i < num_param; ++i)
178  Thyra::assign(DxDp_exact->col(i).ptr(),
179  *(model->getExactSensSolution(i, time).get_x()));
180 
181  // Plot sample solution, exact solution, and adjoint solution
182  if (comm->getRank() == 0 && n == nTimeStepSizes - 1) {
185 
186  std::ofstream ftmp("Tempus_" + RKMethod_ + "_SinCos_AdjSens.dat");
187  RCP<const SolutionHistory<double> > solutionHistory =
188  integrator->getSolutionHistory();
189  for (int i = 0; i < solutionHistory->getNumStates(); i++) {
190  RCP<const SolutionState<double> > solutionState =
191  (*solutionHistory)[i];
192  const double time_i = solutionState->getTime();
193  RCP<const DPV> x_prod_plot =
194  Teuchos::rcp_dynamic_cast<const DPV>(solutionState->getX());
196  x_prod_plot->getVectorBlock(0);
197  RCP<const DMVPV> adjoint_prod_plot =
198  Teuchos::rcp_dynamic_cast<const DMVPV>(
199  x_prod_plot->getVectorBlock(1));
201  adjoint_prod_plot->getMultiVector();
202  RCP<const Thyra::VectorBase<double> > x_exact_plot =
203  model->getExactSolution(time_i).get_x();
204  ftmp << std::fixed << std::setprecision(7) << time_i << std::setw(11)
205  << get_ele(*(x_plot), 0) << std::setw(11)
206  << get_ele(*(x_plot), 1) << std::setw(11)
207  << get_ele(*(adjoint_plot->col(0)), 0) << std::setw(11)
208  << get_ele(*(adjoint_plot->col(0)), 1) << std::setw(11)
209  << get_ele(*(adjoint_plot->col(1)), 0) << std::setw(11)
210  << get_ele(*(adjoint_plot->col(1)), 1) << std::setw(11)
211  << get_ele(*(x_exact_plot), 0) << std::setw(11)
212  << get_ele(*(x_exact_plot), 1) << std::endl;
213  }
214  ftmp.close();
215  }
216 
217  // Calculate the error
218  RCP<Thyra::VectorBase<double> > xdiff = x->clone_v();
219  RCP<Thyra::MultiVectorBase<double> > DxDpdiff = DxDp->clone_mv();
220  Thyra::V_StVpStV(xdiff.ptr(), 1.0, *x_exact, -1.0, *(x));
221  Thyra::V_VmV(DxDpdiff.ptr(), *DxDp_exact, *DxDp);
222  StepSize.push_back(dt);
223  double L2norm = Thyra::norm_2(*xdiff);
224  L2norm *= L2norm;
225  Teuchos::Array<double> L2norm_DxDp(num_param);
226  Thyra::norms_2(*DxDpdiff, L2norm_DxDp());
227  for (int i = 0; i < num_param; ++i)
228  L2norm += L2norm_DxDp[i] * L2norm_DxDp[i];
229  L2norm = std::sqrt(L2norm);
230  ErrorNorm.push_back(L2norm);
231 
232  // out << " n = " << n << " dt = " << dt << " error = " << L2norm
233  // << std::endl;
234  }
235 
236  // Check the order and intercept
237  double slope = computeLinearRegressionLogLog<double>(StepSize, ErrorNorm);
238  out << " Stepper = " << RKMethods[m] << std::endl;
239  out << " =========================" << std::endl;
240  out << " Expected order: " << order << std::endl;
241  out << " Observed order: " << slope << std::endl;
242  out << " =========================" << std::endl;
243  TEST_FLOATING_EQUALITY(slope, order, 0.015);
244  TEST_FLOATING_EQUALITY(ErrorNorm[0], RKMethodErrors[m], 1.0e-4);
245 
246  if (comm->getRank() == 0) {
247  std::ofstream ftmp("Tempus_" + RKMethod_ + "_SinCos_AdjSens-Error.dat");
248  double error0 = 0.8 * ErrorNorm[0];
249  for (int n = 0; n < nTimeStepSizes; n++) {
250  ftmp << StepSize[n] << " " << ErrorNorm[n] << " "
251  << error0 * (pow(StepSize[n] / StepSize[0], order)) << std::endl;
252  }
253  ftmp.close();
254  }
255  }
256 
258 }
259 
260 } // namespace Tempus_Test
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEST_FLOATING_EQUALITY(v1, v2, tol)
#define TEST_ASSERT(v1)
T * get() const
Sine-Cosine model problem from Rythmos. This is a canonical Sine-Cosine differential equation with a...
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
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)
Ptr< T > ptr() const
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Solution state for integrators and steppers.