Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_UnitTest_Subcycling.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 
9 #include "Teuchos_UnitTestHarness.hpp"
10 #include "Teuchos_XMLParameterListHelpers.hpp"
11 #include "Teuchos_TimeMonitor.hpp"
12 #include "Teuchos_DefaultComm.hpp"
13 
14 #include "Thyra_VectorStdOps.hpp"
15 
23 
24 #include "../TestModels/SinCosModel.hpp"
25 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
26 
27 #include <fstream>
28 #include <vector>
29 
30 namespace Tempus_Unit_Test {
31 
32 using Teuchos::RCP;
33 using Teuchos::rcp;
34 using Teuchos::rcp_const_cast;
35 using Teuchos::rcp_dynamic_cast;
36 using Teuchos::ParameterList;
37 using Teuchos::sublist;
38 using Teuchos::getParametersFromXmlFile;
39 
42 
43 
44 // ************************************************************
45 // ************************************************************
46 TEUCHOS_UNIT_TEST(Subcycling, Default_Construction)
47 {
48  auto model = rcp(new Tempus_Test::SinCosModel<double>());
49 
50  // Default construction.
51  auto stepper = rcp(new Tempus::StepperSubcycling<double>());
52  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
53  auto stepperBE = sf->createStepperBackwardEuler(model, Teuchos::null);
54  stepper->setSubcyclingStepper(stepperBE);
55  stepper->initialize();
56  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
57 
58  // Default values for construction.
59 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
60  auto obs = rcp(new Tempus::StepperSubcyclingObserver<double>());
61 #endif
62  auto modifier = rcp(new Tempus::StepperSubcyclingModifierDefault<double>());
63  auto modifierX = rcp(new Tempus::StepperSubcyclingModifierXDefault<double>());
64  auto observer = rcp(new Tempus::StepperSubcyclingObserverDefault<double>());
65  auto solver = rcp(new Thyra::NOXNonlinearSolver());
66  solver->setParameterList(Tempus::defaultSolverParameters());
67 
68  bool useFSAL = stepper->getUseFSALDefault();
69  std::string ICConsistency = stepper->getICConsistencyDefault();
70  bool ICConsistencyCheck = stepper->getICConsistencyCheckDefault();
71 
72  // Test the set functions
73  stepper->setSolver(solver); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
74 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
75  stepper->setObserver(obs); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
76 #endif
77  stepper->setAppAction(modifier); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
78  stepper->setAppAction(modifierX); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
79  stepper->setAppAction(observer); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
80  stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
81  stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
82  stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
83 
84 
85  // Full argument list construction.
86  auto scIntegrator = Teuchos::rcp(new Tempus::IntegratorBasic<double>());
87  auto stepperFE = sf->createStepperForwardEuler(model, Teuchos::null);
88  scIntegrator->setStepperWStepper(stepperFE);
89  scIntegrator->initialize();
90 
91 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
92  stepper = rcp(new Tempus::StepperSubcycling<double>(
93  model, obs, scIntegrator, useFSAL, ICConsistency, ICConsistencyCheck));
94  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
95 #endif
96 
97  stepper = rcp(new Tempus::StepperSubcycling<double>(
98  model,scIntegrator, useFSAL, ICConsistency, ICConsistencyCheck,modifier));
99  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
100 
101  // Test stepper properties.
102  TEUCHOS_ASSERT(stepper->getOrder() == 1);
103 }
104 
105 
106 // ************************************************************
107 // ************************************************************
108 TEUCHOS_UNIT_TEST(Subcycling, MaxTimeStepDoesNotChangeDuring_takeStep)
109 {
110  // Setup the stepper ----------------------------------------
111  auto model = rcp(new Tempus_Test::SinCosModel<double>());
112  auto stepper = rcp(new Tempus::StepperSubcycling<double>());
113  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
114  auto stepperBE = sf->createStepperBackwardEuler(model, Teuchos::null);
115  stepper->setSubcyclingStepper(stepperBE);
116  stepper->initialize();
117 
118  // Setup SolutionHistory ------------------------------------
119  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
120  stepper->getModel()->getNominalValues();
121  auto icSolution =rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x());
122  auto icState = Tempus::createSolutionStateX(icSolution);
123  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
124  solutionHistory->addState(icState);
125  solutionHistory->initWorkingState();
126 
127  // Test
128  stepper->setSubcyclingMaxTimeStep(0.5);
129  double maxTimeStep_Set = stepper->getSubcyclingMaxTimeStep();
130  stepper->takeStep(solutionHistory);
131  double maxTimeStep_After = stepper->getSubcyclingMaxTimeStep();
132 
133  TEST_FLOATING_EQUALITY(maxTimeStep_Set, maxTimeStep_After, 1.0e-14 );
134 }
135 
136 
137 // ************************************************************
138 // ************************************************************
140  : virtual public Tempus::StepperSubcyclingModifierBase<double>
141 {
142 public:
143 
144  /// Constructor
146  : testBEGIN_STEP(false), testEND_STEP(false),
147  testCurrentValue(-0.99), testWorkingValue(-0.99),
148  testDt(1.5), testType("")
149  {}
150  /// Destructor
152 
153  /// Modify Subcycling Stepper at action location.
154  virtual void modify(
155  Teuchos::RCP<Tempus::SolutionHistory<double> > sh,
156  Teuchos::RCP<Tempus::StepperSubcycling<double> > stepper,
158  {
159  switch(actLoc) {
161  {
162  testBEGIN_STEP = true;
163  auto x = sh->getCurrentState()->getX();
164  testCurrentValue = get_ele(*(x), 0);
165  testType = "Subcycling - Modifier";
166  stepper->setStepperType(testType);
167  break;
168  }
170  {
171  testEND_STEP = true;
172  auto x = sh->getWorkingState()->getX();
173  testWorkingValue = get_ele(*(x), 0);
174  testDt = sh->getWorkingState()->getTimeStep()/10.0;
175  sh->getWorkingState()->setTimeStep(testDt);
176  break;
177  }
178  default:
179  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
180  "Error - unknown action location.\n");
181  }
182  }
183 
188  double testDt;
189  std::string testType;
190 };
191 
192 TEUCHOS_UNIT_TEST(Subcycling, AppAction_Modifier)
193 {
194  // Setup the SinCosModel ------------------------------------
195  auto model = rcp(new Tempus_Test::SinCosModel<double>());
196 
197  // Setup Stepper for field solve ----------------------------
198  auto stepper = rcp(new Tempus::StepperSubcycling<double>());
199  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
200  auto stepperFE = sf->createStepperForwardEuler(model, Teuchos::null);
201  auto modifier = rcp(new StepperSubcyclingModifierTest());
202  stepper->setAppAction(modifier);
203  stepper->setSubcyclingStepper(stepperFE);
204 
205  stepper->setSubcyclingMinTimeStep (15);
206  stepper->setSubcyclingInitTimeStep (15.0);
207  stepper->setSubcyclingMaxTimeStep (15.0);
208  stepper->setSubcyclingStepType ("Constant");
209  stepper->setSubcyclingMaxFailures (10);
210  stepper->setSubcyclingMaxConsecFailures(5);
211  stepper->setSubcyclingScreenOutputIndexInterval(1);
212  stepper->setSubcyclingPrintDtChanges(true);
213  stepper->initialize();
214 
215  // Setup TimeStepControl ------------------------------------
216  auto timeStepControl = rcp(new Tempus::TimeStepControl<double>());
217  timeStepControl->setStepType ("Constant");
218  timeStepControl->setInitIndex(0);
219  timeStepControl->setInitTime (0.0);
220  timeStepControl->setFinalTime(1.0);
221  timeStepControl->setInitTimeStep(15.0);
222  timeStepControl->initialize();
223 
224  // Setup initial condition SolutionState --------------------
225  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
226  stepper->getModel()->getNominalValues();
227  auto icSolution = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
228  auto icState = Tempus::createSolutionStateX(icSolution);
229  icState->setTime (timeStepControl->getInitTime());;
230  icState->setIndex (timeStepControl->getInitIndex());
231  icState->setTimeStep(0.0); // dt for ICs are indicated by zero.
232  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
233 
234  // Setup SolutionHistory ------------------------------------
235  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
236  solutionHistory->setName("Forward States");
237  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
238  solutionHistory->setStorageLimit(2);
239  solutionHistory->addState(icState);
240 
241  // Take one time step.
242  stepper->setInitialConditions(solutionHistory);
243  solutionHistory->initWorkingState();
244  solutionHistory->getWorkingState()->setTimeStep(15.0);
245  stepper->takeStep(solutionHistory);
246 
247  // Testing that each ACTION_LOCATION has been called.
248  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
249  TEST_COMPARE(modifier->testEND_STEP, ==, true);
250 
251  // Testing that values can be set through the Modifier.
252  auto x = solutionHistory->getCurrentState()->getX();
253  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-15);
254  x = solutionHistory->getWorkingState()->getX();
255  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-15);
256  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
257  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-15);
258 
259  TEST_COMPARE(modifier->testType, ==, "Subcycling - Modifier");
260 }
261 
262 // ************************************************************
263 // ************************************************************
265  : virtual public Tempus::StepperSubcyclingObserverBase<double>
266 {
267 public:
268 
269  /// Constructor
271  : testBEGIN_STEP(false), testEND_STEP(false),
272  testCurrentValue(-0.99), testWorkingValue(-0.99),
273  testDt(15.0), testType("Subcyling")
274  {}
275 
276  /// Destructor
278 
279  /// Observe Subcycling Stepper at action location.
280  virtual void observe(
281  Teuchos::RCP<const Tempus::SolutionHistory<double> > sh,
282  Teuchos::RCP<const Tempus::StepperSubcycling<double> > stepper,
284  {
285  switch(actLoc) {
287  {
288  testBEGIN_STEP = true;
289  auto x = sh->getCurrentState()->getX();
290  testCurrentValue = get_ele(*(x), 0);
291  break;
292  }
294  {
295  testEND_STEP = true;
296  auto x = sh->getWorkingState()->getX();
297  testWorkingValue = get_ele(*(x), 0);
298  break;
299  }
300  default:
301  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
302  "Error - unknown action location.\n");
303  }
304  }
305 
310  double testDt;
311  std::string testType;
312 };
313 
314 TEUCHOS_UNIT_TEST(Subcycling, AppAction_Observer)
315 {
316  // Setup the SinCosModel ------------------------------------
317  auto model = rcp(new Tempus_Test::SinCosModel<double>());
318 
319  // Setup Stepper for field solve ----------------------------
320  auto stepper = rcp(new Tempus::StepperSubcycling<double>());
321  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
322  auto stepperFE = sf->createStepperForwardEuler(model, Teuchos::null);
323  auto observer = rcp(new StepperSubcyclingObserverTest());
324  stepper->setAppAction(observer);
325  stepper->setSubcyclingStepper(stepperFE);
326 
327  stepper->setSubcyclingMinTimeStep (15);
328  stepper->setSubcyclingInitTimeStep (15.0);
329  stepper->setSubcyclingMaxTimeStep (15.0);
330  stepper->setSubcyclingStepType ("Constant");
331  stepper->setSubcyclingMaxFailures (10);
332  stepper->setSubcyclingMaxConsecFailures(5);
333  stepper->setSubcyclingScreenOutputIndexInterval(1);
334  stepper->setSubcyclingPrintDtChanges(true);
335  stepper->initialize();
336 
337  // Setup TimeStepControl ------------------------------------
338  auto timeStepControl = rcp(new Tempus::TimeStepControl<double>());
339  timeStepControl->setStepType ("Constant");
340  timeStepControl->setInitIndex(0);
341  timeStepControl->setInitTime (0.0);
342  timeStepControl->setFinalTime(1.0);
343  timeStepControl->setInitTimeStep(15.0);
344  timeStepControl->initialize();
345 
346  // Setup initial condition SolutionState --------------------
347  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
348  stepper->getModel()->getNominalValues();
349  auto icSolution = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
350  auto icState = Tempus::createSolutionStateX(icSolution);
351  icState->setTime (timeStepControl->getInitTime());;
352  icState->setIndex (timeStepControl->getInitIndex());
353  icState->setTimeStep(0.0); // dt for ICs are indicated by zero.
354  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
355 
356  // Setup SolutionHistory ------------------------------------
357  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
358  solutionHistory->setName("Forward States");
359  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
360  solutionHistory->setStorageLimit(2);
361  solutionHistory->addState(icState);
362 
363  // Take one time step.
364  stepper->setInitialConditions(solutionHistory);
365  solutionHistory->initWorkingState();
366  solutionHistory->getWorkingState()->setTimeStep(15.0);
367  stepper->takeStep(solutionHistory);
368 
369  // Testing that each ACTION_LOCATION has been called.
370  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
371  TEST_COMPARE(observer->testEND_STEP, ==, true);
372 
373  // Testing that values can be observed through the observer.
374  auto x = solutionHistory->getCurrentState()->getX();
375  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-15);
376  x = solutionHistory->getWorkingState()->getX();
377  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-15);
378  TEST_FLOATING_EQUALITY(observer->testDt, 15.0, 1.0e-15);
379 
380  TEST_COMPARE(observer->testType, ==, "Subcyling");
381 }
382 
383  // ************************************************************
384  // ************************************************************
386  : virtual public Tempus::StepperSubcyclingModifierXBase<double>
387 {
388 public:
389 
390  /// Constructor
392  : testX_BEGIN_STEP(false), testXDOT_END_STEP(false),
393  testX(-0.99), testXDot(-0.99),
394  testDt(1.5), testTime(1.5)
395  {}
396 
397  /// Destructor
399 
400  /// Modify Subcycling Stepper at action location.
401  virtual void modify(
402  Teuchos::RCP<Thyra::VectorBase<double> > x,
403  const double time, const double dt,
405  {
406  switch(modType) {
408  {
409  testX_BEGIN_STEP = true;
410  testX = get_ele(*(x), 0);
411  testDt = dt;
412  break;
413  }
415  {
416  testXDOT_END_STEP = true;
417  testXDot = get_ele(*(x), 0);
418  testTime = time;
419  break;
420  }
421  default:
422  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
423  "Error - unknown action location.\n");
424  }
425  }
426 
429  double testX;
430  double testXDot;
431  double testDt;
432  double testTime;
433 };
434 
435 TEUCHOS_UNIT_TEST(Subcycling, AppAction_ModifierX)
436 {
437  // Setup the SinCosModel ------------------------------------
438  auto model = rcp(new Tempus_Test::SinCosModel<double>());
439 
440  // Setup Stepper for field solve ----------------------------
441  auto stepper = rcp(new Tempus::StepperSubcycling<double>());
442  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
443  auto stepperFE = sf->createStepperForwardEuler(model, Teuchos::null);
444  auto modifierX = rcp(new StepperSubcyclingModifierXTest());
445  stepper->setAppAction(modifierX);
446  stepper->setSubcyclingStepper(stepperFE);
447 
448  stepper->setSubcyclingMinTimeStep (15);
449  stepper->setSubcyclingInitTimeStep (15.0);
450  stepper->setSubcyclingMaxTimeStep (15.0);
451  stepper->setSubcyclingStepType ("Constant");
452  stepper->setSubcyclingMaxFailures (10);
453  stepper->setSubcyclingMaxConsecFailures(5);
454  stepper->setSubcyclingScreenOutputIndexInterval(1);
455  stepper->setSubcyclingPrintDtChanges(true);
456  stepper->initialize();
457 
458  // Setup TimeStepControl ------------------------------------
459  auto timeStepControl = rcp(new Tempus::TimeStepControl<double>());
460  timeStepControl->setStepType ("Constant");
461  timeStepControl->setInitIndex(0);
462  timeStepControl->setInitTime (0.0);
463  timeStepControl->setFinalTime(1.0);
464  timeStepControl->setInitTimeStep(15.0);
465  timeStepControl->initialize();
466 
467  // Setup initial condition SolutionState --------------------
468  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
469  stepper->getModel()->getNominalValues();
470  auto icSolution = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
471  auto icSolutionDot = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
472  auto icState = Tempus::createSolutionStateX(icSolution,icSolutionDot);
473  icState->setTime (timeStepControl->getInitTime());;
474  icState->setIndex (timeStepControl->getInitIndex());
475  icState->setTimeStep(0.0); // dt for ICs are indicated by zero.
476  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
477 
478  // Setup SolutionHistory ------------------------------------
479  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
480  solutionHistory->setName("Forward States");
481  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
482  solutionHistory->setStorageLimit(2);
483  solutionHistory->addState(icState);
484 
485  // Take one time step.
486  stepper->setInitialConditions(solutionHistory);
487  solutionHistory->initWorkingState();
488  solutionHistory->getWorkingState()->setTimeStep(15.0);
489  stepper->takeStep(solutionHistory);
490 
491  // Take one time step.
492  stepper->setInitialConditions(solutionHistory);
493  solutionHistory->initWorkingState();
494  solutionHistory->getWorkingState()->setTimeStep(15.0);
495  stepper->takeStep(solutionHistory);
496 
497  // Testing that each ACTION_LOCATION has been called.
498  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
499  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
500 
501  // Testing that values can be set through the Modifier.
502  auto x = solutionHistory->getCurrentState()->getX();
503  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-15);
504  // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
505  auto xDot = stepper->getStepperXDot(solutionHistory->getWorkingState());
506  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-15);
507  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
508  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-15);
509 
510  auto time = solutionHistory->getWorkingState()->getTime();
511  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-15);
512 }
513 
514 } // namespace Tempus_Test
Teuchos::RCP< SolutionState< Scalar > > createSolutionStateX(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdot=Teuchos::null, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdotdot=Teuchos::null)
Nonmember constructor from non-const solution vectors, x.
Explicit Runge-Kutta time stepper.
virtual void observe(Teuchos::RCP< const Tempus::SolutionHistory< double > > sh, Teuchos::RCP< const Tempus::StepperSubcycling< double > > stepper, const typename Tempus::StepperSubcyclingAppAction< double >::ACTION_LOCATION actLoc)
Observe Subcycling Stepper at action location.
Sine-Cosine model problem from Rythmos. This is a canonical Sine-Cosine differential equation with a...
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.
virtual void modify(Teuchos::RCP< Thyra::VectorBase< double > > x, const double time, const double dt, const typename Tempus::StepperSubcyclingModifierXBase< double >::MODIFIER_TYPE modType)
Modify Subcycling Stepper at action location.
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
TimeStepControl manages the time step size. There several mechanicisms that effect the time step size...
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual void modify(Teuchos::RCP< Tempus::SolutionHistory< double > > sh, Teuchos::RCP< Tempus::StepperSubcycling< double > > stepper, const typename Tempus::StepperSubcyclingAppAction< double >::ACTION_LOCATION actLoc)
Modify Subcycling Stepper at action location.
ACTION_LOCATION
Indicates the location of application action (see algorithm).
Keep a fix number of states.
StepperSubcyclingObserver class for StepperSubcycling.
MODIFIER_TYPE
Indicates the location of application action (see algorithm).