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