OGS
TimeLoop.cpp
Go to the documentation of this file.
1
11#include "TimeLoop.h"
12
13#include <range/v3/algorithm/any_of.hpp>
14#include <range/v3/algorithm/contains.hpp>
15
16#include "BaseLib/Error.h"
17#include "BaseLib/RunTime.h"
23#include "ProcessData.h"
24
25namespace
26{
28 std::vector<std::unique_ptr<ProcessLib::ProcessData>> const&
29 per_process_data,
30 double const t)
31{
32 for (auto& process_data : per_process_data)
33 {
34 process_data->process.updateDeactivatedSubdomains(
35 t, process_data->process_id);
36 }
37}
38
39bool isOutputStep(std::vector<ProcessLib::Output> const& outputs,
40 const int timestep, const double t, const double end_time)
41{
42 if (std::abs(end_time - t) < std::numeric_limits<double>::epsilon())
43 {
44 // the last timestep is an output step
45 return true;
46 }
47
48 return ranges::any_of(outputs, [timestep, t](auto const& output)
49 { return output.isOutputStep(timestep, t); });
50}
51
53 int const timestep, double const t, double const dt, const double end_time,
54 std::vector<std::unique_ptr<ProcessLib::ProcessData>> const&
55 per_process_data,
56 std::vector<GlobalVector*> const& process_solutions,
57 std::vector<GlobalVector*> const& process_solutions_prev,
58 std::vector<ProcessLib::Output> const& outputs)
59{
60 if (!isOutputStep(outputs, timestep, t, end_time))
61 {
62 return;
63 }
64
65 for (auto& process_data : per_process_data)
66 {
67 auto const process_id = process_data->process_id;
68 auto& pcs = process_data->process;
69
70 pcs.preOutput(t, dt, process_solutions, process_solutions_prev,
71 process_id);
72 }
73}
74} // namespace
75
76namespace ProcessLib
77{
79 double const t, double const dt,
80 std::vector<std::unique_ptr<ProcessData>> const& per_process_data,
81 std::vector<GlobalVector*> const& _process_solutions)
82{
83 for (auto& process_data : per_process_data)
84 {
85 auto const process_id = process_data->process_id;
86 auto& pcs = process_data->process;
87 pcs.preTimestep(_process_solutions, t, dt, process_id);
88 }
89}
90
92 double const t, double const dt,
93 std::vector<std::unique_ptr<ProcessData>> const& per_process_data,
94 std::vector<GlobalVector*> const& process_solutions,
95 std::vector<GlobalVector*> const& process_solutions_prev)
96{
97 for (auto& process_data : per_process_data)
98 {
99 auto const process_id = process_data->process_id;
100 auto& pcs = process_data->process;
101
102 pcs.computeSecondaryVariable(t, dt, process_solutions,
103 *process_solutions_prev[process_id],
104 process_id);
105 pcs.postTimestep(process_solutions, process_solutions_prev, t, dt,
106 process_id);
107 }
108}
109
110template <NumLib::ODESystemTag ODETag>
112 ProcessData& process_data,
114{
115 using Tag = NumLib::NonlinearSolverTag;
116 // A concrete Picard solver
117 using NonlinearSolverPicard = NumLib::NonlinearSolver<Tag::Picard>;
118 // A concrete Newton solver
119 using NonlinearSolverNewton = NumLib::NonlinearSolver<Tag::Newton>;
120
121 if (dynamic_cast<NonlinearSolverPicard*>(&process_data.nonlinear_solver))
122 {
123 // The Picard solver can also work with a Newton-ready ODE,
124 // because the Newton ODESystem derives from the Picard ODESystem.
125 // So no further checks are needed here.
126
127 process_data.tdisc_ode_sys = std::make_unique<
129 process_data.process_id, ode_sys, *process_data.time_disc);
130 }
131 // TODO (naumov) Provide a function to nonlinear_solver to distinguish the
132 // types. Could be handy, because a nonlinear solver could handle both types
133 // like PETScSNES.
134 else if ((dynamic_cast<NonlinearSolverNewton*>(
135 &process_data.nonlinear_solver) != nullptr)
136#ifdef USE_PETSC
137 || (dynamic_cast<NumLib::PETScNonlinearSolver*>(
138 &process_data.nonlinear_solver) != nullptr)
139#endif // USE_PETSC
140 )
141 {
142 // The Newton-Raphson method needs a Newton-ready ODE.
143
145 if (auto* ode_newton = dynamic_cast<ODENewton*>(&ode_sys))
146 {
147 process_data.tdisc_ode_sys = std::make_unique<
149 process_data.process_id, *ode_newton, *process_data.time_disc);
150 }
151 else
152 {
153 OGS_FATAL(
154 "You are trying to solve a non-Newton-ready ODE with the"
155 " Newton-Raphson method. Aborting");
156 }
157 }
158 else
159 {
160 OGS_FATAL("Encountered unknown nonlinear solver type. Aborting");
161 }
162}
163
165{
166 setTimeDiscretizedODESystem(process_data, process_data.process);
167}
168
169std::pair<std::vector<GlobalVector*>, std::vector<GlobalVector*>>
171 double const t0,
172 std::vector<std::unique_ptr<ProcessData>> const& per_process_data)
173{
174 std::vector<GlobalVector*> process_solutions;
175 std::vector<GlobalVector*> process_solutions_prev;
176
177 for (auto const& process_data : per_process_data)
178 {
179 auto const process_id = process_data->process_id;
180 auto& ode_sys = *process_data->tdisc_ode_sys;
181
182 // append a solution vector of suitable size
183 process_solutions.emplace_back(
185 ode_sys.getMatrixSpecifications(process_id)));
186 process_solutions_prev.emplace_back(
188 ode_sys.getMatrixSpecifications(process_id)));
189 }
190
191 for (auto const& process_data : per_process_data)
192 {
193 auto& pcs = process_data->process;
194 auto const process_id = process_data->process_id;
195 pcs.setInitialConditions(process_solutions, process_solutions_prev, t0,
196 process_id);
197
198 auto& time_disc = *process_data->time_disc;
199 time_disc.setInitialState(t0); // push IC
200 }
201
202 return {process_solutions, process_solutions_prev};
203}
204
206 std::vector<std::unique_ptr<ProcessData>> const& per_process_data,
207 std::vector<GlobalVector*> const& process_solutions,
208 std::vector<GlobalVector*> const& process_solutions_prev)
209{
210 for (auto const& process_data : per_process_data)
211 {
212 auto& nonlinear_solver = process_data->nonlinear_solver;
213
214 setEquationSystem(*process_data);
215 nonlinear_solver.calculateNonEquilibriumInitialResiduum(
216 process_solutions, process_solutions_prev,
217 process_data->process_id);
218 }
219}
220
222 std::vector<GlobalVector*>& x, std::vector<GlobalVector*> const& x_prev,
223 std::size_t const timestep, double const t, double const delta_t,
224 ProcessData const& process_data, std::vector<Output> const& outputs)
225{
226 auto& process = process_data.process;
227 int const process_id = process_data.process_id;
228 auto& time_disc = *process_data.time_disc;
229 auto& nonlinear_solver = process_data.nonlinear_solver;
230
231 setEquationSystem(process_data);
232
233 // Note: Order matters!
234 // First advance to the next timestep, then set known solutions at that
235 // time, afterwards pass the right solution vector and time to the
236 // preTimestep() hook.
237
238 time_disc.nextTimestep(t, delta_t);
239
240 auto const post_iteration_callback =
241 [&](int iteration, std::vector<GlobalVector*> const& x)
242 {
243 // Note: We don't call the postNonLinearSolver(), preOutput(),
244 // computeSecondaryVariable() and postTimestep() hooks here. This might
245 // lead to some inconsistencies in the data compared to regular output.
246 for (auto const& output : outputs)
247 {
248 output.doOutputNonlinearIteration(process, process_id, timestep, t,
249 iteration, x);
250 }
251 };
252
253 auto const nonlinear_solver_status =
254 nonlinear_solver.solve(x, x_prev, post_iteration_callback, process_id);
255
256 if (!nonlinear_solver_status.error_norms_met)
257 {
258 return nonlinear_solver_status;
259 }
260
261 process.postNonLinearSolver(x, x_prev, t, delta_t, process_id);
262
263 return nonlinear_solver_status;
264}
265
267 std::vector<Output>&& outputs,
268 std::vector<std::unique_ptr<ProcessData>>&& per_process_data,
269 std::unique_ptr<NumLib::StaggeredCoupling>&& staggered_coupling,
270 const double start_time, const double end_time)
271 : _outputs{std::move(outputs)},
272 _per_process_data(std::move(per_process_data)),
273 _start_time(start_time),
274 _end_time(end_time),
275 _staggered_coupling(std::move(staggered_coupling))
276{
277}
278
280 NumLib::TimeStepAlgorithm const& timestep_algorithm, double const time)
281{
282 // for the first time step we can't compute the changes to the previous
283 // time step
284 if (time == timestep_algorithm.begin())
285 {
286 return false;
287 }
288 return timestep_algorithm.isSolutionErrorComputationNeeded();
289}
290
291std::pair<double, bool> TimeLoop::computeTimeStepping(
292 const double prev_dt, double& t, std::size_t& accepted_steps,
293 std::size_t& rejected_steps,
294 std::vector<std::function<double(double, double)>> const&
295 time_step_constraints)
296{
297 bool all_process_steps_accepted = true;
298 // Get minimum time step size among step sizes of all processes.
299 double dt = std::numeric_limits<double>::max();
300 constexpr double eps = std::numeric_limits<double>::epsilon();
301
302 bool const is_initial_step =
303 std::any_of(_per_process_data.begin(), _per_process_data.end(),
304 [](auto const& ppd) -> bool
305 { return ppd->timestep_current.timeStepNumber() == 0; });
306
307 for (std::size_t i = 0; i < _per_process_data.size(); i++)
308 {
309 auto& ppd = *_per_process_data[i];
310 auto& timestep_algorithm = *ppd.timestep_algorithm.get();
311
312 auto const& x = *_process_solutions[i];
313 auto const& x_prev = *_process_solutions_prev[i];
314
315 const double solution_error =
316 computationOfChangeNeeded(timestep_algorithm, t)
318 x, x_prev,
319 ppd.conv_crit.get() ? ppd.conv_crit->getVectorNormType()
321 : 0.0;
322
323 ppd.timestep_current.setAccepted(
324 ppd.nonlinear_solver_status.error_norms_met);
325
326 auto [previous_step_accepted, timestepper_dt] = timestep_algorithm.next(
327 solution_error, ppd.nonlinear_solver_status.number_iterations,
328 ppd.timestep_previous, ppd.timestep_current);
329
330 if (!previous_step_accepted &&
331 // In case of FixedTimeStepping, which makes
332 // timestep_algorithm.next(...) return false when the ending time
333 // is reached.
334 t + eps < timestep_algorithm.end())
335 {
336 // Not all processes have accepted steps.
337 all_process_steps_accepted = false;
338 }
339
340 if (!ppd.nonlinear_solver_status.error_norms_met)
341 {
342 WARN(
343 "Time step will be rejected due to nonlinear solver "
344 "divergence.");
345 all_process_steps_accepted = false;
346 }
347
348 if (timestepper_dt > eps ||
349 std::abs(t - timestep_algorithm.end()) < eps)
350 {
351 dt = std::min(timestepper_dt, dt);
352 }
353 }
354
355 if (all_process_steps_accepted)
356 {
358 }
359 else
360 {
362 }
363
364 bool last_step_rejected = false;
365 if (!is_initial_step)
366 {
367 if (all_process_steps_accepted)
368 {
369 accepted_steps++;
370 last_step_rejected = false;
371 }
372 else
373 {
374 if (t < _end_time || std::abs(t - _end_time) < eps)
375 {
376 t -= prev_dt;
377 rejected_steps++;
378 last_step_rejected = true;
379 }
380 }
381 }
382
383 // adjust step size considering external communciation_point_calculators
384 for (auto const& time_step_constain : time_step_constraints)
385 {
386 dt = std::min(dt, time_step_constain(t, dt));
387 }
388
389 // Check whether the time stepping is stabilized
390 if (std::abs(dt - prev_dt) < eps)
391 {
392 if (last_step_rejected)
393 {
394 OGS_FATAL(
395 "The new step size of {:g} is the same as that of the previous "
396 "rejected time step. \nPlease re-run ogs with a proper "
397 "adjustment in the numerical settings, \ne.g those for time "
398 "stepper, local or global non-linear solver.",
399 dt);
400 }
401 else
402 {
403 DBUG("The time stepping is stabilized with the step size of {:g}.",
404 dt);
405 }
406 }
407
408 // Reset the time step with the minimum step size, dt
409 // Update the solution of the previous time step.
410 for (std::size_t i = 0; i < _per_process_data.size(); i++)
411 {
412 if (all_process_steps_accepted)
413 {
414 auto& ppd = *_per_process_data[i];
415 NumLib::updateTimeSteps(dt, ppd.timestep_previous,
416 ppd.timestep_current);
417 auto& timestep_algorithm = ppd.timestep_algorithm;
418 timestep_algorithm->resetCurrentTimeStep(dt, ppd.timestep_previous,
419 ppd.timestep_current);
420 }
421
422 auto& x = *_process_solutions[i];
423 auto& x_prev = *_process_solutions_prev[i];
424 if (all_process_steps_accepted)
425 {
426 MathLib::LinAlg::copy(x, x_prev); // pushState
427 }
428 else
429 {
430 if (t < _end_time || std::abs(t - _end_time) < eps)
431 {
432 WARN(
433 "Time step {:d} was rejected {:d} times and it will be "
434 "repeated with a reduced step size.",
435 accepted_steps + 1, _repeating_times_of_rejected_step);
436 MathLib::LinAlg::copy(x_prev, x); // popState
437 }
438 }
439 }
440
441 return {dt, last_step_rejected};
442}
443
444std::vector<std::function<double(double, double)>>
446 std::vector<double>&& fixed_times) const
447{
448 std::vector<std::function<double(double, double)>> const
449 time_step_constraints{
450 [fixed_times = std::move(fixed_times)](double t, double dt) {
452 fixed_times);
453 },
454 [this](double t, double dt)
455 {
456 if (t < _end_time && t + dt > _end_time)
457 {
458 return _end_time - t;
459 }
460 return dt;
461 }};
462 return time_step_constraints;
463}
464
467{
468 for (auto const& process_data : _per_process_data)
469 {
470 auto& pcs = process_data->process;
471 for (auto& output : _outputs)
472 {
473 output.addProcess(pcs);
474 }
475
476 setTimeDiscretizedODESystem(*process_data);
477
478 if (auto* conv_crit =
480 process_data->conv_crit.get()))
481 {
482 int const process_id = process_data->process_id;
483 conv_crit->setDOFTable(pcs.getDOFTable(process_id), pcs.getMesh());
484 }
485 }
486
487 // initial solution storage
490
492 {
493 _staggered_coupling->initializeCoupledSolutions(_process_solutions);
494 }
495
496 updateDeactivatedSubdomains(_per_process_data, _start_time);
497
498 // Output initial conditions
499 {
502 }
503
504 auto const time_step_constraints = generateOutputTimeStepConstraints(
506
507 std::tie(_dt, _last_step_rejected) =
509 _rejected_steps, time_step_constraints);
510
513}
514
516{
517 BaseLib::RunTime time_timestep;
518 time_timestep.start();
519
521
522 const std::size_t timesteps = _accepted_steps + 1;
523 // TODO(wenqing): , input option for time unit.
524 INFO(
525 "=== Time stepping at step #{:d} and time {:.15g} with step size "
526 "{:.15g}",
527 timesteps, _current_time, _dt);
528
529 updateDeactivatedSubdomains(_per_process_data, _current_time);
530
533 INFO("[time] Time step #{:d} took {:g} s.", timesteps,
534 time_timestep.elapsed());
536}
537
539{
540 const double prev_dt = _dt;
541 double const current_time = _current_time;
542
543 const std::size_t timesteps = _accepted_steps + 1;
544
545 auto const time_step_constraints = generateOutputTimeStepConstraints(
547
548 // _last_step_rejected is also checked in computeTimeStepping.
549 std::tie(_dt, _last_step_rejected) =
551 _rejected_steps, time_step_constraints);
552
554 {
555 outputSolutions(timesteps, current_time, &Output::doOutput);
556 }
557
558 if (std::abs(_current_time - _end_time) <
559 std::numeric_limits<double>::epsilon() ||
561 {
562 return false;
563 }
564
565 if (_dt < std::numeric_limits<double>::epsilon())
566 {
567 WARN(
568 "Time step size of {:g} is too small.\n"
569 "Time stepping stops at step {:d} and at time of {:g}.",
570 _dt, timesteps, _current_time);
571 return false;
572 }
573
574 return true;
575}
576
578{
579 INFO(
580 "The whole computation of the time stepping took {:d} steps, in which\n"
581 "\t the accepted steps are {:d}, and the rejected steps are {:d}.\n",
583
584 // output last time step
586 {
589 }
590}
591
592bool TimeLoop::preTsNonlinearSolvePostTs(double const t, double const dt,
593 std::size_t const timesteps)
594{
596
597 NumLib::NonlinearSolverStatus nonlinear_solver_status;
598
600 {
601 nonlinear_solver_status =
603 }
604 else
605 {
606 nonlinear_solver_status =
607 solveUncoupledEquationSystems(t, dt, timesteps);
608 }
609
610 // Run post time step only if the last iteration was successful.
611 // Otherwise it runs the risks to get the same errors as in the last
612 // iteration, an exception thrown in assembly, for example.
613 if (nonlinear_solver_status.error_norms_met)
614 {
615 // Later on, the timestep_algorithm might reject the timestep. We assume
616 // that this is a rare case, so still, we call preOutput() here. We
617 // don't expect a large overhead from it.
618 preOutputForAllProcesses(timesteps, t, dt, _end_time, _per_process_data,
620 _outputs);
621
625 }
626 return nonlinear_solver_status.error_norms_met;
627}
628
630 const double t, const double dt, const std::size_t timestep_id,
631 ProcessData const& process_data, std::vector<GlobalVector*>& x,
632 std::vector<GlobalVector*> const& x_prev,
633 std::vector<Output> const& outputs)
634{
635 BaseLib::RunTime time_timestep_process;
636 time_timestep_process.start();
637
638 auto const nonlinear_solver_status = solveOneTimeStepOneProcess(
639 x, x_prev, timestep_id, t, dt, process_data, outputs);
640
641 INFO("[time] Solving process #{:d} took {:g} s in time step #{:d}",
642 process_data.process_id, time_timestep_process.elapsed(), timestep_id);
643
644 return nonlinear_solver_status;
645}
646
647static constexpr std::string_view timestepper_cannot_reduce_dt =
648 "Time stepper cannot reduce the time step size further.";
649
651 const double t, const double dt, const std::size_t timestep_id)
652{
653 NumLib::NonlinearSolverStatus nonlinear_solver_status;
654
655 for (auto const& process_data : _per_process_data)
656 {
657 auto const process_id = process_data->process_id;
658 nonlinear_solver_status = solveMonolithicProcess(
659 t, dt, timestep_id, *process_data, _process_solutions,
661
662 process_data->nonlinear_solver_status = nonlinear_solver_status;
663 if (!nonlinear_solver_status.error_norms_met)
664 {
665 ERR("The nonlinear solver failed in time step #{:d} at t = {:g} s "
666 "for process #{:d}.",
667 timestep_id, t, process_id);
668
669 if (!process_data->timestep_algorithm->canReduceTimestepSize(
670 process_data->timestep_current,
671 process_data->timestep_previous))
672 {
673 // save unsuccessful solution
674 for (auto const& output : _outputs)
675 {
676 output.doOutputAlways(
677 process_data->process, process_id, timestep_id, t,
678 process_data->nonlinear_solver_status.number_iterations,
680 }
682 }
683
684 return nonlinear_solver_status;
685 }
686 }
687
688 return nonlinear_solver_status;
689}
690
693 const double t, const double dt, const std::size_t timestep_id)
694{
695 auto const nonlinear_solver_status =
697 t, dt, timestep_id, _process_solutions, _process_solutions_prev,
699
700 _last_step_rejected = nonlinear_solver_status.error_norms_met;
701
702 {
703 for (auto const& process_data : _per_process_data)
704 {
705 auto& pcs = process_data->process;
706 int const process_id = process_data->process_id;
707 auto& ode_sys = *process_data->tdisc_ode_sys;
708 pcs.solveReactionEquation(_process_solutions,
709 _process_solutions_prev, t, dt, ode_sys,
710 process_id);
711 }
712 }
713
714 return nonlinear_solver_status;
715}
716
717template <typename OutputClassMember>
718void TimeLoop::outputSolutions(unsigned timestep, const double t,
719 OutputClassMember output_class_member) const
720{
721 for (auto const& process_data : _per_process_data)
722 {
723 // If nonlinear solver diverged, the solution has already been
724 // saved.
725 if (!process_data->nonlinear_solver_status.error_norms_met)
726 {
727 continue;
728 }
729
730 auto const process_id = process_data->process_id;
731 auto const& pcs = process_data->process;
732
733 for (auto const& output_object : _outputs)
734 {
735 (output_object.*output_class_member)(
736 pcs, process_id, timestep, t,
737 process_data->nonlinear_solver_status.number_iterations,
739 }
740 }
741}
742
754
755void TimeLoop::preOutputInitialConditions(const double t) const
756{
757 for (auto const& process_data : _per_process_data)
758 {
759 // If nonlinear solver diverged, the solution has already been
760 // saved.
761 if (!process_data->nonlinear_solver_status.error_norms_met)
762 {
763 continue;
764 }
765
766 auto const process_id = process_data->process_id;
767 auto& pcs = process_data->process;
768
769 // dummy value to handle the time derivative terms more or less
770 // correctly, i.e. to ignore them.
771 double const dt = 1;
772 process_data->time_disc->nextTimestep(t, dt);
773
774 pcs.preTimestep(_process_solutions, _start_time, dt, process_id);
775
776 pcs.preOutput(_start_time, dt, _process_solutions,
777 _process_solutions_prev, process_id);
778
779 // Update secondary variables, which might be uninitialized, before
780 // output.
781 pcs.computeSecondaryVariable(_start_time, dt, _process_solutions,
782 *_process_solutions_prev[process_id],
783 process_id);
784 }
785}
786} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
Definition of the RunTime class.
Count the running time.
Definition RunTime.h:29
double elapsed() const
Get the elapsed time in seconds.
Definition RunTime.h:42
void start()
Start the timer.
Definition RunTime.h:32
Interface of time stepping algorithms.
virtual bool isSolutionErrorComputationNeeded() const
double begin() const
return the beginning of time steps
virtual void releaseVector(GlobalVector const &x)=0
void doOutputLastTimestep(Process const &process, const int process_id, int const timestep, const double t, int const iteration, std::vector< GlobalVector * > const &xs) const
Definition Output.cpp:354
void doOutput(Process const &process, const int process_id, int const timestep, const double t, int const iteration, std::vector< GlobalVector * > const &xs) const
Definition Output.cpp:335
std::vector< std::function< double(double, double)> > generateOutputTimeStepConstraints(std::vector< double > &&fixed_times) const
Definition TimeLoop.cpp:445
std::pair< double, bool > computeTimeStepping(const double prev_dt, double &t, std::size_t &accepted_steps, std::size_t &rejected_steps, std::vector< std::function< double(double, double)> > const &time_step_constraints)
Definition TimeLoop.cpp:291
TimeLoop(std::vector< Output > &&outputs, std::vector< std::unique_ptr< ProcessData > > &&per_process_data, std::unique_ptr< NumLib::StaggeredCoupling > &&staggered_coupling, const double start_time, const double end_time)
Definition TimeLoop.cpp:266
void outputLastTimeStep() const
Definition TimeLoop.cpp:577
const double _start_time
Definition TimeLoop.h:131
NumLib::NonlinearSolverStatus solveUncoupledEquationSystems(const double t, const double dt, const std::size_t timestep_id)
Member to solver non coupled systems of equations, which can be a single system of equations,...
Definition TimeLoop.cpp:650
std::vector< std::unique_ptr< ProcessData > > _per_process_data
Definition TimeLoop.h:129
void outputSolutions(unsigned timestep, const double t, OutputClassMember output_class_member) const
Definition TimeLoop.cpp:718
const double _end_time
Definition TimeLoop.h:132
std::vector< Output > _outputs
Definition TimeLoop.h:128
std::size_t _accepted_steps
Definition TimeLoop.h:134
std::vector< GlobalVector * > _process_solutions
Definition TimeLoop.h:126
std::unique_ptr< NumLib::StaggeredCoupling > _staggered_coupling
Definition TimeLoop.h:140
void initialize()
initialize output, convergence criterion, etc.
Definition TimeLoop.cpp:466
bool preTsNonlinearSolvePostTs(double const t, double const dt, std::size_t const timesteps)
Definition TimeLoop.cpp:592
int _repeating_times_of_rejected_step
Definition TimeLoop.h:137
std::size_t _rejected_steps
Definition TimeLoop.h:135
void preOutputInitialConditions(const double t) const
Definition TimeLoop.cpp:755
std::vector< GlobalVector * > _process_solutions_prev
Definition TimeLoop.h:127
NumLib::NonlinearSolverStatus solveCoupledEquationSystemsByStaggeredScheme(const double t, const double dt, const std::size_t timestep_id)
Member to solver coupled systems of equations by the staggered scheme.
Definition TimeLoop.cpp:692
NonlinearSolverTag
Tag used to specify which nonlinear solver will be used.
Definition Types.h:20
void copy(PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:37
double computeRelativeNorm(VectorType const &x, VectorType const &y, MathLib::VecNormType norm_type)
Definition LinAlg.h:286
void updateTimeSteps(double const dt, TimeStep &previous_timestep, TimeStep &current_timestep)
Definition TimeStep.h:112
double possiblyClampDtToNextFixedTime(double const t, double const dt, std::vector< double > const &fixed_output_times)
static constexpr std::string_view timestepper_cannot_reduce_dt
Definition TimeLoop.cpp:647
void setTimeDiscretizedODESystem(ProcessData &process_data, NumLib::ODESystem< ODETag, NumLib::NonlinearSolverTag::Picard > &ode_sys)
Definition TimeLoop.cpp:111
void calculateNonEquilibriumInitialResiduum(std::vector< std::unique_ptr< ProcessData > > const &per_process_data, std::vector< GlobalVector * > const &process_solutions, std::vector< GlobalVector * > const &process_solutions_prev)
Definition TimeLoop.cpp:205
NumLib::NonlinearSolverStatus solveOneTimeStepOneProcess(std::vector< GlobalVector * > &x, std::vector< GlobalVector * > const &x_prev, std::size_t const timestep, double const t, double const delta_t, ProcessData const &process_data, std::vector< Output > const &outputs)
Definition TimeLoop.cpp:221
static NumLib::NonlinearSolverStatus solveMonolithicProcess(const double t, const double dt, const std::size_t timestep_id, ProcessData const &process_data, std::vector< GlobalVector * > &x, std::vector< GlobalVector * > const &x_prev, std::vector< Output > const &outputs)
Definition TimeLoop.cpp:629
void preTimestepForAllProcesses(double const t, double const dt, std::vector< std::unique_ptr< ProcessData > > const &per_process_data, std::vector< GlobalVector * > const &_process_solutions)
Definition TimeLoop.cpp:78
void postTimestepForAllProcesses(double const t, double const dt, std::vector< std::unique_ptr< ProcessData > > const &per_process_data, std::vector< GlobalVector * > const &process_solutions, std::vector< GlobalVector * > const &process_solutions_prev)
Definition TimeLoop.cpp:91
void setEquationSystem(ProcessData const &process_data)
bool computationOfChangeNeeded(NumLib::TimeStepAlgorithm const &timestep_algorithm, double const time)
Definition TimeLoop.cpp:279
std::vector< double > calculateUniqueFixedTimesForAllOutputs(std::vector< Output > const &outputs)
Definition Output.cpp:432
std::pair< std::vector< GlobalVector * >, std::vector< GlobalVector * > > setInitialConditions(double const t0, std::vector< std::unique_ptr< ProcessData > > const &per_process_data)
Definition TimeLoop.cpp:170
void updateDeactivatedSubdomains(std::vector< std::unique_ptr< ProcessLib::ProcessData > > const &per_process_data, double const t)
Definition TimeLoop.cpp:27
void preOutputForAllProcesses(int const timestep, double const t, double const dt, const double end_time, std::vector< std::unique_ptr< ProcessLib::ProcessData > > const &per_process_data, std::vector< GlobalVector * > const &process_solutions, std::vector< GlobalVector * > const &process_solutions_prev, std::vector< ProcessLib::Output > const &outputs)
Definition TimeLoop.cpp:52
bool isOutputStep(std::vector< ProcessLib::Output > const &outputs, const int timestep, const double t, const double end_time)
Definition TimeLoop.cpp:39
static NUMLIB_EXPORT VectorProvider & provider
Status of the non-linear solver.
std::unique_ptr< NumLib::TimeDiscretization > time_disc
Definition ProcessData.h:62
NumLib::NonlinearSolverBase & nonlinear_solver
Definition ProcessData.h:58
std::unique_ptr< NumLib::EquationSystem > tdisc_ode_sys
type-erased time-discretized ODE system
Definition ProcessData.h:64