Skip to content

Conversation

@moxcodes
Copy link
Contributor

Proposed changes

Previously, CCE did not participate in self-start. We seem to have 'gotten away' with it in cases of multistep methods on the rare standalone run that used it, but it's definitely not the right way to do things.
This makes a few tweaks to the self start procedure necessary to support CCE, and includes the self start procedure in the CCE actions.

Upgrade instructions

Any changes to the CCE initialization procedure involving the time step will likely need to be rethought in light of these changes.

Code review checklist

  • The code is documented and the documentation renders correctly. Run
    make doc to generate the documentation locally into BUILD_DIR/docs/html.
    Then open index.html.
  • The code follows the stylistic and code quality guidelines listed in the
    code review guide.
  • The PR lists upgrade instructions and is labeled bugfix or
    major new feature if appropriate.


template <typename TagList>
struct get_all_history_tags {
using type =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for this to be a lazy metafunction rather than an eager one?

// Returns true if the last action jumped.
template <typename Stop, typename Whitelist, bool HasPrimitives>
template <typename Stop, typename Whitelist, bool MultipleHistories = false,
bool HasPrimitives>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default isn't useful here. If HasPrimitives can be deduced, then so can MultipleHistories.

/// \see is_a
template <template <typename...> class U, typename... Args>
using is_a_t = typename is_a<U, Args...>::type;
/// @}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in commit message: "tt::is_a lambda" -> "tt::is_a_lambda"

Comment on lines -173 to +179
l_max, end_time, start_time, number_of_radial_points,
std::make_unique<::TimeSteppers::DormandPrince5>()}};
l_max, end_time, start_time,
std::make_unique<::TimeSteppers::DormandPrince5>(),
number_of_radial_points}};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my understanding, this is because of the change in InitializeWorldtubeBoundary::const_global_cache_tags, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's right -- in this case, the runtime system needed the time stepper regardless, but adding it to InitializeWorldtubeBoundary::const_global_cache_tags reordered the tag list.

db::get<::Tags::TimeStepId>(box)
.substep_time()
.fraction()
.numerator() != 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think just .fraction() != 0 is clearer.


size_t get_l_max() const noexcept { return l_max_; }

const std::unique_ptr<Solutions::WorldtubeData>& get_generator()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you actually need the unique_ptr, or can you just return a reference to the contained value?

Also, I think this should be in the "Allow non-monotonic steps in RT analytic solution for self-start" commit.

@moxcodes
Copy link
Contributor Author

fixups posted.
Cheers!

@wthrowe
Copy link
Member

wthrowe commented Jun 23, 2021

Fixups look fine, but apparently something went wrong because some configurations are segfaulting now.

moxcodes added 3 commits June 23, 2021 14:47
Sometimes (particularly in CCE), we need to store multiple histories because the
underlying variable types differ.
This change permits using multiple histories during self-start, under the
constraint that the integration order of the histories must match.
@moxcodes
Copy link
Contributor Author

fixups squashed in, along with a fix for the segfault.
The mistake was I used the & operator on the returned lvalue ref -- I need to use std::addressof for that. The diff for that change (applied to Allow non-monotonic... commit) is:

--- a/src/Evolution/Systems/Cce/Actions/InitializeWorldtubeBoundary.hpp
+++ b/src/Evolution/Systems/Cce/Actions/InitializeWorldtubeBoundary.hpp
@@ -60,9 +60,9 @@ struct InitializeWorldtubeBoundaryBase {
                     const ParallelComponent* const /*meta*/) noexcept {
     if constexpr (std::is_same_v<Tags::AnalyticBoundaryDataManager,
                                  tmpl::front<ManagerTags>>) {
-      if (dynamic_cast<const Solutions::RobinsonTrautman*>(
-              &(db::get<Tags::AnalyticBoundaryDataManager>(box)
-                    .get_generator())) != nullptr) {
+      if (dynamic_cast<const Solutions::RobinsonTrautman*>(std::addressof(
+              (db::get<Tags::AnalyticBoundaryDataManager>(box)
+               .get_generator()))) != nullptr) {
         if(db::get<::Tags::TimeStepper<>>(box).number_of_substeps() != 1) {
           ERROR(
               "Do not use RobinsonTrautman analytic solution with a "

Cheers!

@wthrowe
Copy link
Member

wthrowe commented Jun 25, 2021

Why is that different here?

@moxcodes
Copy link
Contributor Author

moxcodes commented Jun 25, 2021

hm, you're right, the edge case was more peculiar. I don't properly understand the failure, because the case that caused a segfault in the dynamic_cast, when printed out, both of the versions were null pointers. However, it was my understanding that dynamic_cast was supposed to work fine with a null pointer (just returning a null pointer as well). And why std::addressof should work differently from & here is also mysterious now that I look into it further...
The better fix was updating the test to actually construct the object with a generator so the dynamic cast is actually applied to a pointer to a polymorphic type:

diff --git a/src/Evolution/Systems/Cce/Actions/InitializeWorldtubeBoundary.hpp b/src/Evolution/Systems/Cce/Actions/InitializeWorldtubeBoundary.hpp
index db638051a0..761b6f4ba3 100644
--- a/src/Evolution/Systems/Cce/Actions/InitializeWorldtubeBoundary.hpp
+++ b/src/Evolution/Systems/Cce/Actions/InitializeWorldtubeBoundary.hpp
@@ -61,8 +61,8 @@ struct InitializeWorldtubeBoundaryBase {
     if constexpr (std::is_same_v<Tags::AnalyticBoundaryDataManager,
                                  tmpl::front<ManagerTags>>) {
       if (dynamic_cast<const Solutions::RobinsonTrautman*>(
-              std::addressof((db::get<Tags::AnalyticBoundaryDataManager>(box)
-                                  .get_generator()))) != nullptr) {
+              &(db::get<Tags::AnalyticBoundaryDataManager>(box)
+                    .get_generator())) != nullptr) {
         if(db::get<::Tags::TimeStepper<>>(box).number_of_substeps() != 1) {
           ERROR(
               "Do not use RobinsonTrautman analytic solution with a "
diff --git a/tests/Unit/Evolution/Systems/Cce/Actions/Test_InitializeWorldtubeBoundary.cpp b/tests/Unit/Evolution/Systems/Cce/Actions/Test_InitializeWorldtubeBoundary.cpp
index 1f593c7eab..634af40ac8 100644
--- a/tests/Unit/Evolution/Systems/Cce/Actions/Test_InitializeWorldtubeBoundary.cpp
+++ b/tests/Unit/Evolution/Systems/Cce/Actions/Test_InitializeWorldtubeBoundary.cpp
@@ -14,6 +14,7 @@
 #include "Domain/Structure/ElementId.hpp"
 #include "Evolution/Systems/Cce/Actions/InitializeWorldtubeBoundary.hpp"
 #include "Evolution/Systems/Cce/AnalyticSolutions/RobinsonTrautman.hpp"
+#include "Evolution/Systems/Cce/AnalyticSolutions/RotatingSchwarzschild.hpp"
 #include "Evolution/Systems/Cce/BoundaryData.hpp"
 #include "Evolution/Systems/Cce/Components/WorldtubeBoundary.hpp"
 #include "Evolution/Systems/Cce/InterfaceManagers/GhLockstep.hpp"
@@ -209,8 +210,10 @@ void test_analytic_initialization() noexcept {
       {l_max, 100.0, 0.0, std::make_unique<::TimeSteppers::RungeKutta3>()}};
 
   runner.set_phase(AnalyticMetavariables::Phase::Initialization);
-  ActionTesting::emplace_component<component>(&runner, 0,
-                                              AnalyticBoundaryDataManager{});
+  ActionTesting::emplace_component<component>(
+      &runner, 0,
+      AnalyticBoundaryDataManager{
+          12_st, 20.0, std::make_unique<Solutions::RotatingSchwarzschild>()});
   // this should run the initialization
   for (size_t i = 0; i < 3; ++i) {
     ActionTesting::next_action<component>(make_not_null(&runner), 0);

I also added a commit "Include ExpectedOutput in CCE Robinson-Trautman test" to fix a test failure that appeared on the most recent CI run.

Cheers!

moxcodes added a commit to moxcodes/spectre that referenced this pull request Jun 25, 2021
@moxcodes
Copy link
Contributor Author

a test failed again, this time with a timeout on the RT test case, so I tweaked the parameters to make it run a bit more quickly. I guess now that it does self-start, it's a little slower because it needs to take more steps.
Cheers!

moxcodes added a commit to moxcodes/spectre that referenced this pull request Jun 26, 2021
moxcodes added a commit to moxcodes/spectre that referenced this pull request Jun 26, 2021
@moxcodes moxcodes mentioned this pull request Jun 28, 2021
4 tasks
wthrowe
wthrowe previously approved these changes Jun 28, 2021
Copy link
Member

@wthrowe wthrowe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see anything wrong with either version of the code, so I'm going to call it a compiler bug and not worry about it.

nilsdeppe
nilsdeppe previously approved these changes Jun 28, 2021
Copy link
Member

@nilsdeppe nilsdeppe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just one question. If you decide to change anything, please squash immediately :)

ERROR(
"Do not use RobinsonTrautman analytic solution with a "
"substep-based timestepper. This is to prevent severe slowdowns "
"in the current RobinsonTrautman implementation");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is what these slowdowns are documented somewhere? If not, would it be useful to list them in the error message here so that if someone really wants to use a substep integrator they can?

@moxcodes moxcodes dismissed stale reviews from nilsdeppe and wthrowe via 69c123c June 28, 2021 23:58
moxcodes added 3 commits June 28, 2021 16:59
But also prohibit using substep methods, because that will cause
performance problems
- tweak parameters to make run faster for fewer timeouts
- include `ExpectedOutput` so directories are cleaned up before
  re-running the test
@moxcodes
Copy link
Contributor Author

Added an additional note to the RobinsonTrautman solution better explaining the trouble with substep methods, and referred to that documentation in the error message.
Cheers!

moxcodes added a commit to moxcodes/spectre that referenced this pull request Jul 1, 2021
@wthrowe wthrowe merged commit 08973d0 into sxs-collaboration:develop Jul 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants