Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
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
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_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
41namespace Tempus_Test {
42
43using Teuchos::getParametersFromXmlFile;
44using Teuchos::ParameterList;
45using Teuchos::RCP;
46using Teuchos::rcp;
47using Teuchos::rcp_const_cast;
48using Teuchos::sublist;
49
53
54// ************************************************************
55// ************************************************************
56template <typename SC, typename Model, typename Comm>
57void 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
203 Teuchos::TimeMonitor::summarize();
204}
205
206#ifdef TEMPUS_ENABLE_EPETRA_STACK
207// ************************************************************
208// ************************************************************
209TEUCHOS_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// ************************************************************
227TEUCHOS_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
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)