Skip to content

Commit f9b009b

Browse files
authored
Merge pull request #6804 from wthrowe/tolerance_compute
Reorganize time-stepper tolerance compute tags
2 parents c0f00c5 + aad3636 commit f9b009b

23 files changed

+947
-632
lines changed

src/Time/Actions/AdvanceTime.hpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ template <typename Metavariables>
2727
class GlobalCache;
2828
} // namespace Parallel
2929
namespace Tags {
30-
struct IsUsingTimeSteppingErrorControl;
3130
template <typename Tag>
3231
struct Next;
32+
struct StepperErrorEstimatesEnabled;
3333
struct Time;
3434
struct TimeStep;
3535
struct TimeStepId;
@@ -68,11 +68,9 @@ struct AdvanceTime {
6868
const ArrayIndex& /*array_index*/, ActionList /*meta*/,
6969
const ParallelComponent* const /*meta*/) { // NOLINT const
7070
bool is_using_error_control = false;
71-
if constexpr (db::tag_is_retrievable_v<
72-
Tags::IsUsingTimeSteppingErrorControl,
73-
db::DataBox<DbTags>>) {
74-
is_using_error_control =
75-
db::get<Tags::IsUsingTimeSteppingErrorControl>(box);
71+
if constexpr (db::tag_is_retrievable_v<Tags::StepperErrorEstimatesEnabled,
72+
db::DataBox<DbTags>>) {
73+
is_using_error_control = db::get<Tags::StepperErrorEstimatesEnabled>(box);
7674
}
7775

7876
db::mutate<Tags::TimeStepId, Tags::Next<Tags::TimeStepId>, Tags::TimeStep,

src/Time/Actions/UpdateU.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class GlobalCache;
3131
namespace Tags {
3232
template <typename Tag>
3333
struct HistoryEvolvedVariables;
34-
struct IsUsingTimeSteppingErrorControl;
34+
struct StepperErrorEstimatesEnabled;
3535
template <typename Tag>
3636
struct StepperErrorTolerances;
3737
struct TimeStep;
@@ -46,10 +46,9 @@ template <typename System, typename VariablesTag, typename DbTags>
4646
void update_one_variables(const gsl::not_null<db::DataBox<DbTags>*> box) {
4747
using history_tag = Tags::HistoryEvolvedVariables<VariablesTag>;
4848
bool is_using_error_control = false;
49-
if constexpr (db::tag_is_retrievable_v<Tags::IsUsingTimeSteppingErrorControl,
49+
if constexpr (db::tag_is_retrievable_v<Tags::StepperErrorEstimatesEnabled,
5050
db::DataBox<DbTags>>) {
51-
is_using_error_control =
52-
db::get<Tags::IsUsingTimeSteppingErrorControl>(*box);
51+
is_using_error_control = db::get<Tags::StepperErrorEstimatesEnabled>(*box);
5352
}
5453
if (is_using_error_control) {
5554
using error_tag = ::Tags::StepperErrors<VariablesTag>;
@@ -148,7 +147,7 @@ namespace Actions {
148147
/// - Tags::HistoryEvolvedVariables<variables_tag>
149148
/// - Tags::TimeStep
150149
/// - Tags::TimeStepper<TimeStepper>
151-
/// - Tags::IsUsingTimeSteppingErrorControl
150+
/// - Tags::StepperErrorEstimatesEnabled
152151
///
153152
/// DataBox changes:
154153
/// - Adds: nothing

src/Time/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ spectre_target_headers(
3939
EvolutionOrdering.hpp
4040
History.hpp
4141
LargestStepperError.hpp
42+
RequestsStepperErrorTolerances.hpp
4243
SelfStart.hpp
4344
Slab.hpp
4445
SlabRoundingError.hpp
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Distributed under the MIT License.
2+
// See LICENSE.txt for details.
3+
4+
#pragma once
5+
6+
#include <typeindex>
7+
#include <unordered_map>
8+
9+
#include "Time/StepperErrorTolerances.hpp"
10+
11+
/// \ingroup TimeGroup
12+
/// Base class for requesting time stepper error tolerances.
13+
struct RequestsStepperErrorTolerances {
14+
public:
15+
/// A map from the type of a variables tag to the tolerances for
16+
/// that variable.
17+
virtual std::unordered_map<std::type_index, StepperErrorTolerances>
18+
tolerances() const = 0;
19+
20+
protected:
21+
RequestsStepperErrorTolerances() = default;
22+
~RequestsStepperErrorTolerances() = default;
23+
};

src/Time/StepChoosers/ErrorControl.hpp

Lines changed: 15 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -5,64 +5,29 @@
55

66
#include <algorithm>
77
#include <cmath>
8-
#include <cstdint>
98
#include <limits>
10-
#include <memory>
11-
#include <optional>
129
#include <pup.h>
1310
#include <string>
1411
#include <type_traits>
15-
#include <vector>
12+
#include <typeindex>
13+
#include <typeinfo>
14+
#include <unordered_map>
1615

17-
#include "DataStructures/DataBox/DataBoxTag.hpp"
18-
#include "DataStructures/TaggedVariant.hpp"
1916
#include "Options/String.hpp"
20-
#include "ParallelAlgorithms/EventsAndTriggers/EventsAndTriggers.hpp"
21-
#include "ParallelAlgorithms/EventsAndTriggers/WhenToCheck.hpp"
22-
#include "Time/ChangeSlabSize/Event.hpp"
17+
#include "Time/RequestsStepperErrorTolerances.hpp"
2318
#include "Time/StepChoosers/StepChooser.hpp"
2419
#include "Time/StepperErrorTolerances.hpp"
25-
#include "Time/Tags/IsUsingTimeSteppingErrorControl.hpp"
26-
#include "Time/Tags/StepperErrorTolerances.hpp"
20+
#include "Time/Tags/StepperErrorTolerancesCompute.hpp"
2721
#include "Time/Tags/StepperErrors.hpp"
2822
#include "Time/TimeStepRequest.hpp"
29-
#include "Time/TimeSteppers/TimeStepper.hpp"
30-
#include "Time/VariableOrderAlgorithm.hpp"
31-
#include "Utilities/ErrorHandling/Assert.hpp"
32-
#include "Utilities/ErrorHandling/Error.hpp"
33-
#include "Utilities/Gsl.hpp"
3423
#include "Utilities/Serialization/CharmPupable.hpp"
3524
#include "Utilities/TMPL.hpp"
3625

3726
/// \cond
38-
namespace Tags {
39-
template <Triggers::WhenToCheck WhenToCheck>
40-
struct EventsAndTriggers;
41-
template <bool LocalTimeStepping>
42-
struct IsUsingTimeSteppingErrorControlCompute;
43-
struct StepChoosers;
44-
template <typename EvolvedVariableTag, bool LocalTimeStepping>
45-
struct StepperErrorTolerancesCompute;
46-
template <typename StepperInterface>
47-
struct TimeStepper;
48-
struct VariableOrderAlgorithm;
49-
} // namespace Tags
27+
struct NoSuchType;
5028
/// \endcond
5129

5230
namespace StepChoosers {
53-
namespace ErrorControl_detail {
54-
struct IsAnErrorControl {};
55-
template <typename EvolvedVariableTag>
56-
struct ErrorControlBase : IsAnErrorControl {
57-
public:
58-
virtual StepperErrorTolerances tolerances() const = 0;
59-
60-
protected:
61-
ErrorControlBase() = default;
62-
~ErrorControlBase() = default;
63-
};
64-
} // namespace ErrorControl_detail
65-
6631
/*!
6732
* \brief Sets a goal based on time-stepper truncation error.
6833
*
@@ -133,9 +98,8 @@ struct ErrorControlBase : IsAnErrorControl {
13398
*/
13499
template <typename StepChooserUse, typename EvolvedVariableTag,
135100
typename ErrorControlSelector = NoSuchType>
136-
class ErrorControl
137-
: public StepChooser<StepChooserUse>,
138-
public ErrorControl_detail::ErrorControlBase<EvolvedVariableTag> {
101+
class ErrorControl : public StepChooser<StepChooserUse>,
102+
public RequestsStepperErrorTolerances {
139103
public:
140104
/// \cond
141105
ErrorControl() = default;
@@ -204,7 +168,7 @@ class ErrorControl
204168
using simple_tags = tmpl::list<::Tags::StepperErrors<EvolvedVariableTag>>;
205169

206170
using compute_tags = tmpl::list<
207-
Tags::IsUsingTimeSteppingErrorControlCompute<
171+
Tags::StepperErrorEstimatesEnabledCompute<
208172
std::is_same_v<StepChooserUse, ::StepChooserUse::LtsStep>>,
209173
Tags::StepperErrorTolerancesCompute<
210174
EvolvedVariableTag,
@@ -249,10 +213,12 @@ class ErrorControl
249213
bool uses_local_data() const override { return true; }
250214
bool can_be_delayed() const override { return true; }
251215

252-
StepperErrorTolerances tolerances() const override {
253-
return {.estimates = StepperErrorTolerances::Estimates::StepperOrder,
254-
.absolute = absolute_tolerance_,
255-
.relative = relative_tolerance_};
216+
std::unordered_map<std::type_index, StepperErrorTolerances> tolerances()
217+
const override {
218+
return {{typeid(EvolvedVariableTag),
219+
{.estimates = StepperErrorTolerances::Estimates::StepperOrder,
220+
.absolute = absolute_tolerance_,
221+
.relative = relative_tolerance_}}};
256222
}
257223

258224
void pup(PUP::er& p) override { // NOLINT
@@ -278,146 +244,3 @@ PUP::able::PUP_ID ErrorControl<StepChooserUse, EvolvedVariableTag,
278244
ErrorControlSelector>::my_PUP_ID = 0; // NOLINT
279245
/// \endcond
280246
} // namespace StepChoosers
281-
282-
namespace Tags {
283-
/// \ingroup TimeGroup
284-
/// \brief A tag that is true if the `ErrorControl` step chooser is one of the
285-
/// option-created `Event`s.
286-
template <bool LocalTimeStepping>
287-
struct IsUsingTimeSteppingErrorControlCompute
288-
: db::ComputeTag,
289-
IsUsingTimeSteppingErrorControl {
290-
using base = IsUsingTimeSteppingErrorControl;
291-
using return_type = type;
292-
using argument_tags = tmpl::conditional_t<
293-
LocalTimeStepping, tmpl::list<::Tags::StepChoosers>,
294-
tmpl::list<::Tags::EventsAndTriggers<Triggers::WhenToCheck::AtSlabs>>>;
295-
296-
// local time stepping
297-
static void function(
298-
const gsl::not_null<bool*> is_using_error_control,
299-
const std::vector<
300-
std::unique_ptr<::StepChooser<StepChooserUse::LtsStep>>>&
301-
step_choosers) {
302-
*is_using_error_control = false;
303-
for (const auto& step_chooser : step_choosers) {
304-
if (dynamic_cast<
305-
const ::StepChoosers::ErrorControl_detail::IsAnErrorControl*>(
306-
&*step_chooser) != nullptr) {
307-
*is_using_error_control = true;
308-
return;
309-
}
310-
}
311-
}
312-
313-
// global time stepping
314-
static void function(const gsl::not_null<bool*> is_using_error_control,
315-
const ::EventsAndTriggers& events_and_triggers) {
316-
// In principle the slab size could be changed based on a dense
317-
// trigger, but it's not clear that there is ever a good reason to
318-
// do so, and it wouldn't make sense to use error control in that
319-
// context in any case.
320-
*is_using_error_control = false;
321-
events_and_triggers.for_each_event([&](const auto& event) {
322-
if (*is_using_error_control) {
323-
return;
324-
}
325-
if (const auto* const change_slab_size =
326-
dynamic_cast<const ::Events::ChangeSlabSize*>(&event)) {
327-
change_slab_size->for_each_step_chooser(
328-
[&](const StepChooser<StepChooserUse::Slab>& step_chooser) {
329-
if (*is_using_error_control) {
330-
return;
331-
}
332-
if (dynamic_cast<const ::StepChoosers::ErrorControl_detail::
333-
IsAnErrorControl*>(&step_chooser) !=
334-
nullptr) {
335-
*is_using_error_control = true;
336-
}
337-
});
338-
}
339-
});
340-
}
341-
};
342-
343-
/// \ingroup TimeGroup
344-
/// \brief A tag that contains the error tolerances if the
345-
/// `ErrorControl` step chooser is one of the option-created `Event`s.
346-
template <typename EvolvedVariableTag, bool LocalTimeStepping>
347-
struct StepperErrorTolerancesCompute
348-
: db::ComputeTag,
349-
StepperErrorTolerances<EvolvedVariableTag> {
350-
using base = StepperErrorTolerances<EvolvedVariableTag>;
351-
using return_type = typename base::type;
352-
using argument_tags = tmpl::conditional_t<
353-
LocalTimeStepping,
354-
tmpl::list<::Tags::StepChoosers, ::Tags::TimeStepper<::TimeStepper>,
355-
::Tags::VariableOrderAlgorithm>,
356-
tmpl::list<::Tags::EventsAndTriggers<Triggers::WhenToCheck::AtSlabs>>>;
357-
358-
// local time stepping
359-
static void function(
360-
const gsl::not_null<::StepperErrorTolerances*> tolerances,
361-
const std::vector<
362-
std::unique_ptr<::StepChooser<StepChooserUse::LtsStep>>>&
363-
step_choosers,
364-
const ::TimeStepper& time_stepper,
365-
const ::VariableOrderAlgorithm& variable_order_algorithm) {
366-
*tolerances = ::StepperErrorTolerances{};
367-
for (const auto& step_chooser : step_choosers) {
368-
set_tolerances_if_error_control(tolerances, *step_chooser);
369-
}
370-
// Error-based variable-order requires some variable to be
371-
// controlled using error control, but in a split-variable system
372-
// a different variable might be controlled, so no control on this
373-
// variable is not an error.
374-
if (tolerances->estimates != ::StepperErrorTolerances::Estimates::None and
375-
variants::holds_alternative<TimeSteppers::Tags::VariableOrder>(
376-
time_stepper.order())) {
377-
tolerances->estimates = std::max(
378-
tolerances->estimates, variable_order_algorithm.required_estimates());
379-
}
380-
}
381-
382-
// global time stepping
383-
static void function(
384-
const gsl::not_null<::StepperErrorTolerances*> tolerances,
385-
const ::EventsAndTriggers& events_and_triggers) {
386-
*tolerances = ::StepperErrorTolerances{};
387-
// In principle the slab size could be changed based on a dense
388-
// trigger, but it's not clear that there is ever a good reason to
389-
// do so, and it wouldn't make sense to use error control in that
390-
// context in any case.
391-
events_and_triggers.for_each_event([&](const auto& event) {
392-
if (const auto* const change_slab_size =
393-
dynamic_cast<const ::Events::ChangeSlabSize*>(&event)) {
394-
change_slab_size->for_each_step_chooser(
395-
[&](const StepChooser<StepChooserUse::Slab>& step_chooser) {
396-
set_tolerances_if_error_control(tolerances, step_chooser);
397-
});
398-
}
399-
});
400-
}
401-
402-
private:
403-
template <typename StepChooserUse>
404-
static void set_tolerances_if_error_control(
405-
const gsl::not_null<::StepperErrorTolerances*> tolerances,
406-
const StepChooser<StepChooserUse>& step_chooser) {
407-
if (const auto* const error_control =
408-
dynamic_cast<const ::StepChoosers::ErrorControl_detail::
409-
ErrorControlBase<EvolvedVariableTag>*>(
410-
&step_chooser);
411-
error_control != nullptr) {
412-
const auto this_tolerances = error_control->tolerances();
413-
if (tolerances->estimates != ::StepperErrorTolerances::Estimates::None and
414-
*tolerances != this_tolerances) {
415-
ERROR_NO_TRACE("All ErrorControl events for "
416-
<< db::tag_name<EvolvedVariableTag>()
417-
<< " must use the same tolerances.");
418-
}
419-
*tolerances = this_tolerances;
420-
}
421-
}
422-
};
423-
} // namespace Tags

src/Time/StepChoosers/FixedLtsRatio.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ class FixedLtsRatio : public StepChooser<StepChooserUse::Slab> {
119119
bool uses_local_data() const override;
120120
bool can_be_delayed() const override;
121121

122+
template <typename F>
123+
void for_each_step_chooser(F&& f) const {
124+
for (const auto& step_chooser : step_choosers_) {
125+
f(*step_chooser);
126+
}
127+
}
128+
122129
void pup(PUP::er& p) override;
123130

124131
private:

src/Time/Tags/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
# Distributed under the MIT License.
22
# See LICENSE.txt for details.
33

4+
spectre_target_sources(
5+
${LIBRARY}
6+
PRIVATE
7+
StepperErrorTolerancesCompute.cpp
8+
)
9+
410
spectre_target_headers(
511
${LIBRARY}
612
INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src
713
HEADERS
814
AdaptiveSteppingDiagnostics.hpp
915
FixedLtsRatio.hpp
1016
HistoryEvolvedVariables.hpp
11-
IsUsingTimeSteppingErrorControl.hpp
1217
MinimumTimeStep.hpp
1318
StepChoosers.hpp
1419
StepNumberWithinSlab.hpp
20+
StepperErrorEstimatesEnabled.hpp
1521
StepperErrorTolerances.hpp
22+
StepperErrorTolerancesCompute.hpp
1623
StepperErrors.hpp
1724
Time.hpp
1825
TimeAndPrevious.hpp

0 commit comments

Comments
 (0)