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