Skip to content

Commit

Permalink
Add Fraction of Orbit Trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexCarpenter46 committed Jun 12, 2024
1 parent 893a0da commit d0e1fa3
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include "Evolution/Systems/GeneralizedHarmonic/System.hpp"
#include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
#include "Evolution/Tags/Filter.hpp"
#include "Evolution/Triggers/FractionOfOrbit.hpp"
#include "Evolution/Triggers/NumberOfOrbits.hpp"
#include "Evolution/Triggers/SeparationLessThan.hpp"
#include "Evolution/TypeTraits.hpp"
Expand Down Expand Up @@ -504,6 +505,7 @@ struct EvolutionMetavars {
tmpl::pair<
Trigger,
tmpl::append<Triggers::logical_triggers, Triggers::time_triggers,
tmpl::list<Triggers::FractinoOfOrbit>,

Check failure on line 508 in src/Evolution/Executables/GeneralizedHarmonic/EvolveGhBinaryBlackHole.hpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Debug)

no member named 'FractinoOfOrbit' in namespace 'Triggers'

Check failure on line 508 in src/Evolution/Executables/GeneralizedHarmonic/EvolveGhBinaryBlackHole.hpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Release)

no member named 'FractinoOfOrbit' in namespace 'Triggers'
tmpl::list<Triggers::SeparationLessThan>,
tmpl::list<Triggers::NumberOfOrbits>>>>;

Check failure on line 510 in src/Evolution/Executables/GeneralizedHarmonic/EvolveGhBinaryBlackHole.hpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Debug)

expected ';' after alias declaration

Check failure on line 510 in src/Evolution/Executables/GeneralizedHarmonic/EvolveGhBinaryBlackHole.hpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Release)

expected ';' after alias declaration
};
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 @@ -8,6 +8,7 @@ add_spectre_library(${LIBRARY})
spectre_target_sources(
${LIBRARY}
PRIVATE
FractionOfOrbit.cpp
SeparationLessThan.cpp
NumberOfOrbits.cpp
)
Expand All @@ -16,6 +17,7 @@ spectre_target_headers(
${LIBRARY}
INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src
HEADERS
FractionOfOrbit.hpp
SeparationLessThan.hpp
NumberOfOrbits.hpp
)
Expand Down
49 changes: 49 additions & 0 deletions src/Evolution/Triggers/FractionOfOrbit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Distributed under the MIT License.
// See LICENSE.txt for details.

#include "Evolution/Triggers/FractionOfOrbit.hpp"

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

#include "Domain/FunctionsOfTime/QuaternionFunctionOfTime.hpp"

namespace Triggers {
FractionOfOrbit::FractionOfOrbit(const double fraction)
: fraction_of_orbit_(fraction) {}

bool FractionOfOrbit::operator()(
const double time,
const std::unordered_map<
std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
functions_of_time) {
for (auto i = functions_of_time.begin(); i != functions_of_time.end(); i++) {
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 orbits_since_last_trigger =
(rot_f_of_t->full_angle(time) -
rot_f_of_t->full_angle(last_trigger_time_)) /
(2.0 * M_PI);
if (orbits_since_last_trigger >= fraction_of_orbit_) {
last_trigger_time_ = time;
return true;
} else {
return false;
}
}
}
ERROR(
"FractionOfOrbit trigger can only be used when the rotation map is "
"active");
}

void FractionOfOrbit::pup(PUP::er& p) { p | fraction_of_orbit_; }

PUP::able::PUP_ID FractionOfOrbit::my_PUP_ID = 0; // NOLINT
} // namespace Triggers
63 changes: 63 additions & 0 deletions src/Evolution/Triggers/FractionOfOrbit.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// 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 FractionOfOrbit : public Trigger {
public:
/// \cond
FractionOfOrbit() = default;
explicit FractionOfOrbit(CkMigrateMessage* /*unused*/) {}
using PUP::able::register_constructor;
WRAPPED_PUPable_decl_template(FractionOfOrbit); // NOLINT
/// \endcond

struct Value {
using type = double;
static constexpr Options::String help = {
"Fraction of an orbit completed between triggers."};
};

using options = tmpl::list<Value>;
static constexpr Options::String help{
"Trigger when the evolution has reached a fraction of an orbit since the "
"trigger was last triggered."};

explicit FractionOfOrbit(double fraction_of_orbit);

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

bool operator()(const double time,
const std::unordered_map<
std::string,
std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
functions_of_time);

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

private:
double fraction_of_orbit_{};
double last_trigger_time_ = 0.0;
};
} // 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 @@ -4,6 +4,7 @@
set(LIBRARY "Test_EvolutionTriggers")

set(LIBRARY_SOURCES
Test_FractionOfOrbit.cpp
Test_SeparationLessThan.cpp
Test_NumberOfOrbits.cpp
)
Expand Down
88 changes: 88 additions & 0 deletions tests/Unit/Evolution/Triggers/Test_FractionOfOrbit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// 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/FractionOfOrbit.hpp"
#include "Framework/TestCreation.hpp"
#include "Framework/TestHelpers.hpp"
#include "Options/Protocols/FactoryCreation.hpp"
#include "ParallelAlgorithms/EventsAndTriggers/Trigger.hpp"

#include <cmath>

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::FractionOfOrbit>>>;
};
};

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 * M_PI / 10, 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);
double fraction_of_orbit = 0.25;
Triggers::FractionOfOrbit trigger{fraction_of_orbit};
int time = 0;
while (time <= 20) {
bool is_triggered = trigger(time, functions_of_time);
bool expected_is_triggered = time % 5 == 0;
CHECK(is_triggered == expected_is_triggered);
time += 1;
}

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

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::FractionOfOrbit trigger{0.1};

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

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

0 comments on commit d0e1fa3

Please sign in to comment.