Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_Test_BDF2_CDR.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 
12 #include "Teuchos_TimeMonitor.hpp"
13 #include "Teuchos_DefaultComm.hpp"
14 
15 #include "Tempus_config.hpp"
16 #include "Tempus_IntegratorBasic.hpp"
17 #include "Tempus_StepperBDF2.hpp"
18 
19 #ifdef TEMPUS_ENABLE_EPETRA_STACK
20 #include "../TestModels/CDR_Model.hpp"
21 #ifdef Tempus_ENABLE_MPI
22 #include "Epetra_MpiComm.h"
23 #else
24 #include "Epetra_SerialComm.h"
25 #endif
26 #endif
27 #ifdef TEMPUS_ENABLE_TPETRA_STACK
28 #include "../TestModels/CDR_Model_Tpetra.hpp"
29 #include "Tpetra_Core.hpp"
30 #endif
31 #include "../TestModels/VanDerPolModel.hpp"
32 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
33 
34 #include "Stratimikos_DefaultLinearSolverBuilder.hpp"
35 
36 #include <fstream>
37 #include <limits>
38 #include <sstream>
39 #include <vector>
40 
41 namespace Tempus_Test {
42 
43 using Teuchos::getParametersFromXmlFile;
45 using Teuchos::RCP;
46 using Teuchos::rcp;
47 using Teuchos::rcp_const_cast;
48 using Teuchos::sublist;
49 
53 
54 // ************************************************************
55 // ************************************************************
56 template <typename SC, typename Model, typename Comm>
57 void CDR_Test(const Comm& comm, const int commSize, Teuchos::FancyOStream& out,
58  bool& success)
59 {
60  RCP<Tempus::IntegratorBasic<double>> integrator;
61  std::vector<RCP<Thyra::VectorBase<double>>> solutions;
62  std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
63  std::vector<double> StepSize;
64 
65  // Read params from .xml file
66  auto pList = getParametersFromXmlFile("Tempus_BDF2_CDR.xml");
67  // Set initial time step = 2*dt specified in input file (for convergence
68  // study)
69  //
70  auto pl = sublist(pList, "Tempus", true);
71  auto dt = pl->sublist("Demo Integrator")
72  .sublist("Time Step Control")
73  .get<double>("Initial Time Step");
74  dt *= 2.0;
75  auto model_pl = sublist(pList, "CDR Model", true);
76 
77  const auto nTimeStepSizes =
78  model_pl->get<int>("Number of Time Step Sizes", 5);
79 
80  for (int n = 0; n < nTimeStepSizes; n++) {
81  // Create CDR Model
82  const int num_elements = model_pl->get<int>("num elements");
83  const auto left_end = model_pl->get<SC>("left end");
84  const auto right_end = model_pl->get<SC>("right end");
85  const auto a_convection = model_pl->get<SC>("a (convection)");
86  const auto k_source = model_pl->get<SC>("k (source)");
87 
88  auto model = rcp(new Model(comm, num_elements, left_end, right_end,
89  a_convection, k_source));
90 
91  // Set the factory
92  ::Stratimikos::DefaultLinearSolverBuilder builder;
93 
94  auto p = rcp(new ParameterList);
95  p->set("Linear Solver Type", "Belos");
96  p->set("Preconditioner Type", "None");
97  builder.setParameterList(p);
98 
99  auto lowsFactory = builder.createLinearSolveStrategy("");
100 
101  model->set_W_factory(lowsFactory);
102 
103  // Set the step size
104  dt /= 2;
105 
106  // Setup the Integrator and reset initial time step
107  pl->sublist("Demo Integrator")
108  .sublist("Time Step Control")
109  .set("Initial Time Step", dt);
110  integrator = Tempus::createIntegratorBasic<double>(pl, model);
111 
112  // Integrate to timeMax
113  bool integratorStatus = integrator->advanceTime();
114  TEST_ASSERT(integratorStatus)
115 
116  // Test if at 'Final Time'
117  double time = integrator->getTime();
118  double timeFinal = pl->sublist("Demo Integrator")
119  .sublist("Time Step Control")
120  .get<double>("Final Time");
121  double tol = 100.0 * std::numeric_limits<double>::epsilon();
122  TEST_FLOATING_EQUALITY(time, timeFinal, tol);
123 
124  // Store off the final solution and step size
125  StepSize.push_back(dt);
126  auto solution = Thyra::createMember(model->get_x_space());
127  Thyra::copy(*(integrator->getX()), solution.ptr());
128  solutions.push_back(solution);
129  auto solutionDot = Thyra::createMember(model->get_x_space());
130  Thyra::copy(*(integrator->getXDot()), solutionDot.ptr());
131  solutionsDot.push_back(solutionDot);
132 
133  // Output finest temporal solution for plotting
134  // This only works for ONE MPI process
135  if ((n == nTimeStepSizes - 1) && (commSize == 1)) {
136  std::ofstream ftmp("Tempus_BDF2_CDR.dat");
137  ftmp << "TITLE=\"BDF2 Solution to CDR\"\n"
138  << "VARIABLES=\"z\",\"T\"\n";
139  const auto dx =
140  std::fabs(left_end - right_end) / static_cast<double>(num_elements);
141  auto solutionHistory = integrator->getSolutionHistory();
142  int nStates = solutionHistory->getNumStates();
143  for (int i = 0; i < nStates; i++) {
144  auto solutionState = (*solutionHistory)[i];
145  auto x = solutionState->getX();
146  auto ttime = solutionState->getTime();
147  ftmp << "ZONE T=\"Time=" << ttime << "\", I=" << num_elements + 1
148  << ", F=BLOCK\n";
149  for (int j = 0; j < num_elements + 1; j++) {
150  const auto x_coord = left_end + static_cast<double>(j) * dx;
151  ftmp << x_coord << " ";
152  }
153  ftmp << std::endl;
154  for (int j = 0; j < num_elements + 1; j++)
155  ftmp << get_ele(*x, j) << " ";
156  ftmp << std::endl;
157  }
158  ftmp.close();
159  }
160  }
161 
162  // Check the order and intercept
163  if (nTimeStepSizes > 2) {
164  double xSlope = 0.0;
165  double xDotSlope = 0.0;
166  std::vector<double> xErrorNorm;
167  std::vector<double> xDotErrorNorm;
168  auto stepper = integrator->getStepper();
169  auto order = stepper->getOrder();
170  writeOrderError("Tempus_BDF2_CDR-Error.dat", stepper, StepSize, solutions,
171  xErrorNorm, xSlope, solutionsDot, xDotErrorNorm, xDotSlope,
172  out);
173  TEST_FLOATING_EQUALITY(xSlope, order, 0.35);
174  TEST_COMPARE(xSlope, >, 0.95);
175  TEST_FLOATING_EQUALITY(xDotSlope, order, 0.35);
176  TEST_COMPARE(xDotSlope, >, 0.95);
177 
178  TEST_FLOATING_EQUALITY(xErrorNorm[0], 0.0145747, 1.0e-4);
179  TEST_FLOATING_EQUALITY(xDotErrorNorm[0], 0.0563621, 1.0e-4);
180  }
181 
182  // Write fine mesh solution at final time
183  // This only works for ONE MPI process
184  if (commSize == 1) {
185  auto pListCDR = getParametersFromXmlFile("Tempus_BDF2_CDR.xml");
186  auto model_pl_CDR = sublist(pListCDR, "CDR Model", true);
187  const auto num_elements = model_pl_CDR->get<int>("num elements");
188  const auto left_end = model_pl_CDR->get<double>("left end");
189  const auto right_end = model_pl_CDR->get<double>("right end");
190 
191  const auto& x = *(solutions[solutions.size() - 1]);
192 
193  std::ofstream ftmp("Tempus_BDF2_CDR-Solution.dat");
194  for (int n = 0; n < num_elements + 1; n++) {
195  const auto dx =
196  std::fabs(left_end - right_end) / static_cast<double>(num_elements);
197  const auto x_coord = left_end + static_cast<double>(n) * dx;
198  ftmp << x_coord << " " << Thyra::get_ele(x, n) << std::endl;
199  }
200  ftmp.close();
201  }
202 
204 }
205 
206 #ifdef TEMPUS_ENABLE_EPETRA_STACK
207 // ************************************************************
208 // ************************************************************
209 TEUCHOS_UNIT_TEST(BDF2, CDR)
210 {
211  // Create a communicator for Epetra objects
212  RCP<Epetra_Comm> comm;
213 #ifdef Tempus_ENABLE_MPI
214  comm = rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
215 #else
216  comm = rcp(new Epetra_SerialComm);
217 #endif
218 
219  CDR_Test<double, Tempus_Test::CDR_Model<double>>(comm, comm->NumProc(), out,
220  success);
221 }
222 #endif
223 
224 #ifdef TEMPUS_ENABLE_TPETRA_STACK
225 // ************************************************************
226 // ************************************************************
227 TEUCHOS_UNIT_TEST(BDF2, CDR_Tpetra)
228 {
229  // Get default Tpetra template types
230  using SC = Tpetra::Vector<>::scalar_type;
231  using LO = Tpetra::Vector<>::local_ordinal_type;
232  using GO = Tpetra::Vector<>::global_ordinal_type;
233  using Node = Tpetra::Vector<>::node_type;
234 
235  auto comm = Tpetra::getDefaultComm();
236 
237  CDR_Test<SC, Tempus_Test::CDR_Model_Tpetra<SC, LO, GO, Node>>(
238  comm, comm->getSize(), out, success);
239 }
240 #endif
241 
242 } // namespace Tempus_Test
#define TEST_COMPARE(v1, comp, v2)
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)
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)
void CDR_Test(const Comm &comm, const int commSize, Teuchos::FancyOStream &out, bool &success)
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Solution state for integrators and steppers.