Skip to content

Commit

Permalink
Add Number of Orbits Trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexCarpenter46 committed May 20, 2024
1 parent 8f6d7ed commit 04433f0
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include "Evolution/Systems/GeneralizedHarmonic/System.hpp"
#include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
#include "Evolution/Tags/Filter.hpp"
#include "Evolution/Triggers/NumberOfOrbits.hpp"
#include "Evolution/Triggers/SeparationLessThan.hpp"
#include "Evolution/TypeTraits.hpp"
#include "IO/Importers/Actions/RegisterWithElementDataReader.hpp"
Expand Down Expand Up @@ -500,7 +501,8 @@ struct EvolutionMetavars {
tmpl::pair<
Trigger,
tmpl::append<Triggers::logical_triggers, Triggers::time_triggers,
tmpl::list<Triggers::SeparationLessThan>>>>;
tmpl::list<Triggers::SeparationLessThan>,
tmpl::list<Triggers::NumberOfOrbits>>>>;
};

// A tmpl::list of tags to be added to the GlobalCache by the
Expand Down
2 changes: 2 additions & 0 deletions src/Evolution/Triggers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ spectre_target_sources(
${LIBRARY}
PRIVATE
SeparationLessThan.cpp
NumberOfOrbits.cpp
)

spectre_target_headers(
${LIBRARY}
INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src
HEADERS
SeparationLessThan.hpp
NumberOfOrbits.hpp
)

target_link_libraries(
Expand Down
42 changes: 42 additions & 0 deletions src/Evolution/Triggers/NumberOfOrbits.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Distributed under the MIT License.
// See LICENSE.txt for details.

#include "Evolution/Triggers/NumberOfOrbits.hpp"

#include <cmath>
#include <cstddef>
#include <memory>
#include <pup.h>
#include <string>
#include <unordered_map>

#include "Domain/FunctionsOfTime/QuaternionFunctionOfTime.hpp"

namespace Triggers {
NumberOfOrbits::NumberOfOrbits(const double orbits)
: number_of_orbits_(orbits) {}

bool NumberOfOrbits::operator()(
const double time,
const std::unordered_map<
std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
functions_of_time) const {
for (auto i = functions_of_time.begin(); i != functions_of_time.end(); i++) {

Check failure on line 24 in src/Evolution/Triggers/NumberOfOrbits.cpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Debug)

use range-based for loop instead

Check failure on line 24 in src/Evolution/Triggers/NumberOfOrbits.cpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Release)

use range-based for loop instead
const auto* const rot_f_of_t = dynamic_cast<
const domain::FunctionsOfTime::QuaternionFunctionOfTime<3>*>(
(i->second.get()));
if (rot_f_of_t != nullptr) {
const double calculated_orbits =
rot_f_of_t->angle_func(time)[0][2] / (2.0 * M_PI);
return calculated_orbits >= number_of_orbits_;
}
}
ERROR(
"NumberOfOrbits trigger can only be used when the rotation map is "
"active");
}

void NumberOfOrbits::pup(PUP::er& p) { p | number_of_orbits_; }

PUP::able::PUP_ID NumberOfOrbits::my_PUP_ID = 0; // NOLINT
} // namespace Triggers
61 changes: 61 additions & 0 deletions src/Evolution/Triggers/NumberOfOrbits.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Distributed under the MIT License.
// See LICENSE.txt for details.

#pragma once

#include <memory>
#include <pup.h>
#include <string>

#include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
#include "Options/String.hpp"
#include "ParallelAlgorithms/EventsAndTriggers/Trigger.hpp"
#include "Utilities/Serialization/CharmPupable.hpp"
#include "Utilities/TMPL.hpp"

namespace domain::Tags {
template <size_t VolumeDim>
struct Domain;
struct FunctionsOfTime;
} // namespace domain::Tags
namespace Tags {
struct Time;
} // namespace Tags

namespace Triggers {
class NumberOfOrbits : public Trigger {
public:
/// \cond
NumberOfOrbits() = default;
explicit NumberOfOrbits(CkMigrateMessage* /*unused*/) {}
using PUP::able::register_constructor;
WRAPPED_PUPable_decl_template(NumberOfOrbits); // NOLINT
/// \endcond

struct Value {
using type = double;
static constexpr Options::String help = {
"Number of orbits to compare against."};
};

using options = tmpl::list<Value>;
static constexpr Options::String help{
"Trigger when the evolution has reached a desired number of orbits."};

explicit NumberOfOrbits(double number_of_orbits);

using argument_tags = tmpl::list<Tags::Time, domain::Tags::FunctionsOfTime>;

bool operator()(const double time,

Check failure on line 49 in src/Evolution/Triggers/NumberOfOrbits.hpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Debug)

parameter 'time' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions

Check failure on line 49 in src/Evolution/Triggers/NumberOfOrbits.hpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Release)

parameter 'time' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions
const std::unordered_map<
std::string,
std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
functions_of_time) const;

// NOLINENEXTLINE(google-runtime-references)
void pup(PUP::er& p) override;

private:
double number_of_orbits_{};
};
} // namespace Triggers
1 change: 1 addition & 0 deletions tests/Unit/Evolution/Triggers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(LIBRARY "Test_EvolutionTriggers")

set(LIBRARY_SOURCES
Test_SeparationLessThan.cpp
Test_NumberOfOrbits.cpp
)

add_test_library(${LIBRARY} "${LIBRARY_SOURCES}")
Expand Down
92 changes: 92 additions & 0 deletions tests/Unit/Evolution/Triggers/Test_NumberOfOrbits.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Distributed under the MIT License.
// See LICENSE.txt for details.

#include "Framework/TestingFramework.hpp"

#include <cmath>

#include "Domain/CoordinateMaps/TimeDependent/Rotation.hpp"
#include "Domain/Domain.hpp"
#include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
#include "Domain/FunctionsOfTime/QuaternionFunctionOfTime.hpp"
#include "Evolution/Triggers/NumberOfOrbits.hpp"
#include "Framework/TestCreation.hpp"
#include "Framework/TestHelpers.hpp"
#include "Options/Protocols/FactoryCreation.hpp"
#include "ParallelAlgorithms/EventsAndTriggers/Trigger.hpp"

#include <cmath>

Check failure on line 18 in tests/Unit/Evolution/Triggers/Test_NumberOfOrbits.cpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Release)

duplicate include

namespace {
struct Metavariables {
using component_list = tmpl::list<>;
struct factory_creation
: tt::ConformsTo<Options::protocols::FactoryCreation> {
using factory_classes =
tmpl::map<tmpl::pair<Trigger, tmpl::list<Triggers::NumberOfOrbits>>>;
};
};

using RotationMap = domain::CoordinateMaps::TimeDependent::Rotation<3>;

void test() {
const std::string f_of_t_name = "Rotation";
std::unordered_map<std::string,
std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>
functions_of_time{};
DataVector axis{{0.0, 0.0, 1.0}};
std::array<DataVector, 4> init_func = {axis, axis * 0.6, axis * 0.0,
axis * 0.0};
const std::array<DataVector, 1> init_quat{DataVector{
{cos(0.5), axis[0] * sin(0.5), axis[1] * sin(0.5), axis[2] * sin(0.5)}}};
domain::FunctionsOfTime::QuaternionFunctionOfTime<3> quat_f_of_t{
0.0, init_quat, init_func, 20.0};
functions_of_time[f_of_t_name] =
std::make_unique<domain::FunctionsOfTime::QuaternionFunctionOfTime<3>>(
quat_f_of_t);
const std::array<double, 3> number_of_orbits{0.5, 1.0, 2.0};
for (size_t i = 0; i < 3; i++) {
double time = 1.0;
Triggers::NumberOfOrbits trigger{number_of_orbits[i]};

Check failure on line 50 in tests/Unit/Evolution/Triggers/Test_NumberOfOrbits.cpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Release)

do not use array subscript when the index is not an integer constant expression
while (time <= 20.0) {
bool is_triggered = trigger(time, functions_of_time);
bool expected_is_triggered =
(quat_f_of_t.angle_func(time)[0][2] / (2.0 * M_PI) >=
number_of_orbits[i]);

Check failure on line 55 in tests/Unit/Evolution/Triggers/Test_NumberOfOrbits.cpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Release)

do not use array subscript when the index is not an integer constant expression
CHECK(is_triggered == expected_is_triggered);
time += 1.0;
}
}

TestHelpers::test_creation<std::unique_ptr<Trigger>, Metavariables>(
"NumberOfOrbits:\n"
" Value: 3.0");
}

void test_errors() {
const std::string f_of_t_name = "NeonPegasus";
std::unordered_map<std::string,
std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>
functions_of_time{};
DataVector axis{{0.0, 0.0, 1.0}};
std::array<DataVector, 3> init_func = {axis, axis, axis};
const std::array<DataVector, 1> init_quat{
DataVector{{0.0, axis[0], axis[1], axis[2]}}};
functions_of_time[f_of_t_name] =
std::make_unique<domain::FunctionsOfTime::QuaternionFunctionOfTime<2>>(
0.0, init_quat, init_func, 20.0);

Triggers::NumberOfOrbits trigger{0.1};

CHECK_THROWS_WITH(trigger(0.0, functions_of_time),
Catch::Matchers::ContainsSubstring(
"NumberOfOrbits trigger can only be used when the "
"rotation map is active"));
}

SPECTRE_TEST_CASE("Unit.Evolution.Triggers.NumberOfOrbits",
"[Unit][Evolution]") {
test();
test_errors();
}
} // namespace

0 comments on commit 04433f0

Please sign in to comment.