From 66b4ccbaf8baf21047c857c75b3d778ba8267a28 Mon Sep 17 00:00:00 2001 From: Kyle Nelli Date: Wed, 14 Feb 2024 23:09:44 -0800 Subject: [PATCH] Prevent NumGridPointsAndGridSpacing element dist when using GTS --- src/Domain/ElementDistribution.cpp | 18 ------ src/Domain/ElementDistribution.hpp | 33 +++++++++-- src/Domain/Tags/ElementDistribution.hpp | 9 +++ .../InputTimeDependent3D.yaml | 2 +- .../Domain/Tags/Test_ElementDistribution.cpp | 56 ++++++++++++++++--- 5 files changed, 84 insertions(+), 34 deletions(-) diff --git a/src/Domain/ElementDistribution.cpp b/src/Domain/ElementDistribution.cpp index 820d4afe0bed..69b39354c4cc 100644 --- a/src/Domain/ElementDistribution.cpp +++ b/src/Domain/ElementDistribution.cpp @@ -28,7 +28,6 @@ #include "NumericalAlgorithms/Spectral/Mesh.hpp" #include "NumericalAlgorithms/Spectral/Quadrature.hpp" #include "Options/Options.hpp" -#include "Options/ParseError.hpp" #include "Options/ParseOptions.hpp" #include "Utilities/Algorithm.hpp" #include "Utilities/ConstantExpressions.hpp" @@ -343,20 +342,3 @@ GENERATE_INSTANTIATIONS(INSTANTIATION, (1, 2, 3)) #undef GET_DIM #undef INSTANTIATION } // namespace domain - -template <> -domain::ElementWeight -Options::create_from_yaml::create( - const Options::Option& options) { - const auto ordering = options.parse_as(); - if (ordering == "Uniform") { - return domain::ElementWeight::Uniform; - } else if (ordering == "NumGridPoints") { - return domain::ElementWeight::NumGridPoints; - } else if (ordering == "NumGridPointsAndGridSpacing") { - return domain::ElementWeight::NumGridPointsAndGridSpacing; - } - PARSE_ERROR(options.context(), - "ElementWeight must be 'Uniform', 'NumGridPoints', or, " - "'NumGridPointsAndGridSpacing'"); -} diff --git a/src/Domain/ElementDistribution.hpp b/src/Domain/ElementDistribution.hpp index eb89eb620032..39dc715f73cc 100644 --- a/src/Domain/ElementDistribution.hpp +++ b/src/Domain/ElementDistribution.hpp @@ -6,12 +6,15 @@ #include #include #include +#include #include #include #include #include #include "Options/Options.hpp" +#include "Options/ParseError.hpp" +#include "Utilities/TypeTraits/CreateGetStaticMemberVariableOrDefault.hpp" /// \cond template @@ -173,15 +176,33 @@ struct BlockZCurveProcDistribution { }; } // namespace domain +namespace element_weight_detail { +CREATE_GET_STATIC_MEMBER_VARIABLE_OR_DEFAULT(local_time_stepping) +} // namespace element_weight_detail + template <> struct Options::create_from_yaml { template static domain::ElementWeight create(const Options::Option& options) { - return create(options); + const auto ordering = options.parse_as(); + if (ordering == "Uniform") { + return domain::ElementWeight::Uniform; + } else if (ordering == "NumGridPoints") { + return domain::ElementWeight::NumGridPoints; + } else if (ordering == "NumGridPointsAndGridSpacing") { + if constexpr (not element_weight_detail:: + get_local_time_stepping_or_default_v) { + PARSE_ERROR( + options.context(), + "When not using local time stepping, you cannot use " + "NumGridPointsAndGridSpacing for the element distribution. Please " + "choose another element distribution."); + } + return domain::ElementWeight::NumGridPointsAndGridSpacing; + } + PARSE_ERROR(options.context(), + "ElementWeight must be 'Uniform', 'NumGridPoints', or, " + "'NumGridPointsAndGridSpacing'"); } }; - -template <> -domain::ElementWeight -Options::create_from_yaml::create( - const Options::Option& options); diff --git a/src/Domain/Tags/ElementDistribution.hpp b/src/Domain/Tags/ElementDistribution.hpp index 203e42211028..10f536d39f3e 100644 --- a/src/Domain/Tags/ElementDistribution.hpp +++ b/src/Domain/Tags/ElementDistribution.hpp @@ -35,6 +35,15 @@ struct ElementDistribution { } // namespace OptionTags namespace Tags { +/// \ingroup DataBoxTagsGroup +/// \ingroup ComputationalDomainGroup +/// Tag that holds method for how to distribute the elements on the given +/// resources. +/// +/// \note When not using local time stepping (LTS), a user cannot choose the +/// NumGridPointsAndGridSpacing element distribution because grid spacing does +/// not affect the computational cost at all. Therefore, if a user does choose +/// NumGridPointsAndGridSpacing when not using LTS, an error will occur. struct ElementDistribution : db::SimpleTag { using type = std::optional; using option_tags = tmpl::list; diff --git a/tests/InputFiles/ExportCoordinates/InputTimeDependent3D.yaml b/tests/InputFiles/ExportCoordinates/InputTimeDependent3D.yaml index 6f750aebd0b2..47da016ba2bb 100644 --- a/tests/InputFiles/ExportCoordinates/InputTimeDependent3D.yaml +++ b/tests/InputFiles/ExportCoordinates/InputTimeDependent3D.yaml @@ -13,7 +13,7 @@ ExpectedOutput: --- Parallelization: - ElementDistribution: NumGridPointsAndGridSpacing + ElementDistribution: NumGridPoints Amr: Criteria: diff --git a/tests/Unit/Domain/Tags/Test_ElementDistribution.cpp b/tests/Unit/Domain/Tags/Test_ElementDistribution.cpp index fcefadce33dc..39d71875f0d4 100644 --- a/tests/Unit/Domain/Tags/Test_ElementDistribution.cpp +++ b/tests/Unit/Domain/Tags/Test_ElementDistribution.cpp @@ -12,19 +12,57 @@ #include "Helpers/DataStructures/DataBox/TestHelpers.hpp" #include "Parallel/Tags/Parallelization.hpp" +namespace { +template +struct TestMetavars { + static constexpr bool local_time_stepping = UseLTS; +}; + +template +std::optional make_option( + const std::string& option_string) { + return TestHelpers::test_option_tag>(option_string); +} + +std::optional make_option_without_lts_metavars( + const std::string& option_string) { + return TestHelpers::test_option_tag( + option_string); +} +} // namespace + SPECTRE_TEST_CASE("Unit.Domain.Tags.ElementDistribution", "[Unit][Domain]") { TestHelpers::db::test_simple_tag( "ElementDistribution"); - const auto make_option = [](const std::string& option_string) - -> std::optional { - return TestHelpers::test_option_tag< - domain::OptionTags::ElementDistribution>(option_string); - }; - CHECK(make_option("Uniform") == + CHECK(make_option("Uniform") == std::optional{domain::ElementWeight::Uniform}); - CHECK(make_option("NumGridPoints") == + CHECK(make_option("NumGridPoints") == std::optional{domain::ElementWeight::NumGridPoints}); - CHECK(make_option("NumGridPointsAndGridSpacing") == + CHECK(make_option("NumGridPointsAndGridSpacing") == std::optional{domain::ElementWeight::NumGridPointsAndGridSpacing}); - CHECK(make_option("RoundRobin") == std::nullopt); + CHECK(make_option("RoundRobin") == std::nullopt); + + CHECK(make_option("Uniform") == + std::optional{domain::ElementWeight::Uniform}); + CHECK(make_option("NumGridPoints") == + std::optional{domain::ElementWeight::NumGridPoints}); + CHECK_THROWS_WITH(make_option("NumGridPointsAndGridSpacing"), + Catch::Matchers::ContainsSubstring( + "When not using local time stepping") and + Catch::Matchers::ContainsSubstring( + "Please choose another element distribution.")); + CHECK(make_option("RoundRobin") == std::nullopt); + + CHECK(make_option_without_lts_metavars("Uniform") == + std::optional{domain::ElementWeight::Uniform}); + CHECK(make_option_without_lts_metavars("NumGridPoints") == + std::optional{domain::ElementWeight::NumGridPoints}); + CHECK_THROWS_WITH( + make_option_without_lts_metavars("NumGridPointsAndGridSpacing"), + Catch::Matchers::ContainsSubstring( + "When not using local time stepping") and + Catch::Matchers::ContainsSubstring( + "Please choose another element distribution.")); + CHECK(make_option_without_lts_metavars("RoundRobin") == std::nullopt); }