SpECTRE Documentation Coverage Report
Current view: top level - Time/ChangeSlabSize - ChangeSlabSize.hpp Hit Total Coverage
Commit: b04c5fe44fd10d490a64c0d2eb862cb5e7d7fda2 Lines: 1 2 50.0 %
Date: 2025-03-13 21:46:42
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include "DataStructures/DataBox/DataBox.hpp"
       7             : #include "Time/AdaptiveSteppingDiagnostics.hpp"
       8             : #include "Time/Slab.hpp"
       9             : #include "Time/Tags/HistoryEvolvedVariables.hpp"
      10             : #include "Time/Time.hpp"
      11             : #include "Time/TimeStepId.hpp"
      12             : #include "Utilities/ErrorHandling/Assert.hpp"
      13             : #include "Utilities/Gsl.hpp"
      14             : #include "Utilities/TMPL.hpp"
      15             : 
      16             : /// \cond
      17             : namespace Tags {
      18             : struct AdaptiveSteppingDiagnostics;
      19             : struct MinimumTimeStep;
      20             : template <typename Tag>
      21             : struct Next;
      22             : struct TimeStep;
      23             : struct TimeStepId;
      24             : template <typename StepperInterface>
      25             : struct TimeStepper;
      26             : }  // namespace Tags
      27             : class TimeStepper;
      28             : /// \endcond
      29             : 
      30             : /// \ingroup TimeGroup
      31             : /// Change the slab size, updating all quantities in the DataBox
      32             : /// depending on it.
      33             : ///
      34             : /// The end of the slab (in the appropriate direction for the
      35             : /// evolution's flow of time) will be set to \p new_slab_end.  The
      36             : /// time step is set to the same fraction of the new slab as it was of
      37             : /// the old.
      38             : template <typename DbTags>
      39           1 : void change_slab_size(const gsl::not_null<db::DataBox<DbTags>*> box,
      40             :                       const double new_slab_end) {
      41             :   const TimeStepId& old_time_step_id = db::get<Tags::TimeStepId>(*box);
      42             : 
      43             :   ASSERT(old_time_step_id.is_at_slab_boundary(),
      44             :          "Cannot change slab size in middle of slab: " << old_time_step_id);
      45             : 
      46             :   const Slab old_slab = old_time_step_id.step_time().slab();
      47             :   const double old_slab_end = old_time_step_id.time_runs_forward()
      48             :                                   ? old_slab.end().value()
      49             :                                   : old_slab.start().value();
      50             : 
      51             :   if (new_slab_end == old_slab_end) {
      52             :     return;
      53             :   }
      54             : 
      55             :   const TimeDelta& old_time_step = db::get<Tags::TimeStep>(*box);
      56             : 
      57             :   const Slab new_slab = old_time_step_id.time_runs_forward()
      58             :                             ? Slab(old_slab.start().value(), new_slab_end)
      59             :                             : Slab(new_slab_end, old_slab.end().value());
      60             :   // We are at a slab boundary, so the substep is 0.
      61             :   const TimeStepId new_time_step_id(
      62             :       old_time_step_id.time_runs_forward(), old_time_step_id.slab_number(),
      63             :       old_time_step_id.step_time().with_slab(new_slab));
      64             :   const auto new_time_step = old_time_step.with_slab(new_slab);
      65             : 
      66             :   if (std::abs(new_time_step.value()) <
      67             :       db::get<::Tags::MinimumTimeStep>(*box)) {
      68             :     ERROR_NO_TRACE(
      69             :         "Chosen step size "
      70             :         << new_time_step.value() << " is smaller than the MinimumTimeStep of "
      71             :         << db::get<::Tags::MinimumTimeStep>(*box)
      72             :         << " while changing the slab size to " << new_slab.duration().value()
      73             :         << ".\n"
      74             :            "\n"
      75             :            "This can indicate a flaw in the step chooser, the grid, or a "
      76             :            "simulation instability that an error-based stepper is naively "
      77             :            "attempting to resolve. A possible issue is an aliasing-driven "
      78             :            "instability that could be cured by more aggressive filtering if "
      79             :            "you are using DG.");
      80             :   }
      81             : 
      82             :   const auto new_next_time_step_id =
      83             :       db::get<Tags::TimeStepper<TimeStepper>>(*box).next_time_id(
      84             :           new_time_step_id, new_time_step);
      85             : 
      86             :   db::mutate_apply<
      87             :       tmpl::push_front<Tags::get_all_history_tags<DbTags>,
      88             :                        ::Tags::Next<::Tags::TimeStepId>, ::Tags::TimeStep,
      89             :                        ::Tags::Next<::Tags::TimeStep>, ::Tags::TimeStepId,
      90             :                        ::Tags::AdaptiveSteppingDiagnostics>,
      91             :       tmpl::list<>>(
      92             :       [&new_next_time_step_id, &new_time_step, &new_time_step_id](
      93             :           const gsl::not_null<TimeStepId*> next_time_step_id,
      94             :           const gsl::not_null<TimeDelta*> time_step,
      95             :           const gsl::not_null<TimeDelta*> next_time_step,
      96             :           const gsl::not_null<TimeStepId*> local_time_step_id,
      97             :           const gsl::not_null<AdaptiveSteppingDiagnostics*> diags,
      98             :           const auto... histories) {
      99             :         const auto update_history = [&](const auto history) {
     100             :           if (not history->empty() and
     101             :               history->back().time_step_id == *local_time_step_id) {
     102             :             ASSERT(history->at_step_start(),
     103             :                    "Cannot change step size with substep data.");
     104             :             history->back().time_step_id = new_time_step_id;
     105             :           }
     106             :           return 0;
     107             :         };
     108             :         expand_pack(update_history(histories)...);
     109             : 
     110             :         *next_time_step_id = new_next_time_step_id;
     111             :         *time_step = new_time_step;
     112             :         *next_time_step = new_time_step;
     113             :         *local_time_step_id = new_time_step_id;
     114             :         ++diags->number_of_slab_size_changes;
     115             :       },
     116             :       box);
     117             : }

Generated by: LCOV version 1.14