Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions docs/Tutorials/EventsAndTriggers.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,12 @@ consistently over the entire domain.
### Input file syntax

The `%EventsAndTriggers` (and `%EventsAndDenseTriggers`) sections of
the \ref dev_guide_option_parsing "input file" indicate structure
using a collection of `?`, `:`, and `-` characters. These are
standard, if perhaps somewhat obscure, YAML syntax. They are defining
a map from triggers to lists of events. The `?:` syntax defines an
expanded key-value pair, which allows the key to be a complicated
type, unlike the common `Key: Value` syntax. The `-` is the expanded
form of a list, which allows entries to have complicated types.
Frequently only one event is associated with a trigger, so there will
only be a single `-` after the `:`, but additional events introduced
by more `-` characters can appear afterwards:
the \ref dev_guide_option_parsing "input file" are parsed as several
nested YAML lists representing vectors and pairs. The outermost list
is a vector with one entry for each trigger. The entries in this
vector are two-element lists representing pairs whose first elements
are triggers and whose second elements are a third level of list
containing the events.

\snippet PlaneWave1DEventsAndTriggersExample.yaml multiple_events

Expand Down
78 changes: 17 additions & 61 deletions src/Evolution/EventsAndDenseTriggers/EventsAndDenseTriggers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,25 @@
#include <pup.h>
#include <utility>

#include "Utilities/ErrorHandling/FloatingPointExceptions.hpp"

namespace evolution {
void EventsAndDenseTriggers::TriggerRecord::pup(PUP::er& p) {
p | next_check;
p | is_triggered;
p | num_events_ready;
p | trigger;
p | events;
}

EventsAndDenseTriggers::EventsAndDenseTriggers(
ConstructionType events_and_triggers) {
events_and_triggers_.reserve(events_and_triggers.size());
while (not events_and_triggers.empty()) {
auto events_and_trigger =
events_and_triggers.extract(events_and_triggers.begin());
events_and_triggers_.push_back(
TriggerRecord{std::numeric_limits<double>::signaling_NaN(),
std::move(events_and_trigger.key()),
std::move(events_and_trigger.mapped())});
for (auto& events_and_trigger : events_and_triggers) {
events_and_triggers_.push_back(TriggerRecord{
std::numeric_limits<double>::signaling_NaN(), std::optional<bool>{}, 0,
std::move(events_and_trigger.first),
std::move(events_and_trigger.second)});
}
}

Expand All @@ -32,67 +34,21 @@ void EventsAndDenseTriggers::add_trigger_and_events(
std::vector<std::unique_ptr<Event>> events) {
ASSERT(not initialized(), "Cannot add events after initialization");
events_and_triggers_.reserve(events_and_triggers_.size() + 1);
events_and_triggers_.push_back(
TriggerRecord{std::numeric_limits<double>::signaling_NaN(),
std::move(trigger), std::move(events)});
events_and_triggers_.push_back(TriggerRecord{
std::numeric_limits<double>::signaling_NaN(), std::optional<bool>{}, 0,
std::move(trigger), std::move(events)});
}

void EventsAndDenseTriggers::pup(PUP::er& p) {
p | events_and_triggers_;
p | heap_size_;
p | to_run_position_;
p | processing_position_;
p | event_to_check_;
p | next_check_;
p | next_check_after_;
p | before_;
}

bool EventsAndDenseTriggers::initialized() const {
return heap_size_ != std::numeric_limits<size_t>::max();
}

void EventsAndDenseTriggers::populate_active_triggers() {
ASSERT(not events_and_triggers_.empty(), "No triggers");
ASSERT(heap_end() == events_and_triggers_.end(),
"Triggers have not all been processed.");

next_check_ = events_and_triggers_.front().next_check;
while (heap_size_ > 0 and
events_and_triggers_.front().next_check == next_check_) {
std::pop_heap(events_and_triggers_.begin(), heap_end(), next_check_after_);
--heap_size_;
}
to_run_position_ = heap_size_;
processing_position_ = heap_size_;
}

void EventsAndDenseTriggers::reschedule_next_trigger(
const double next_check_time, const bool time_runs_forward) {
if (not evolution_greater<double>{time_runs_forward}(
next_check_time, heap_end()->next_check)) {
ERROR("Trigger at time " << heap_end()->next_check
<< " rescheduled itself for earlier time "
<< next_check_time);
}
heap_end()->next_check = next_check_time;
++heap_size_;
std::push_heap(events_and_triggers_.begin(), heap_end(), next_check_after_);
}

EventsAndDenseTriggers::TriggerTimeAfter::TriggerTimeAfter(
const bool time_runs_forward)
: time_after_{time_runs_forward} {}

bool EventsAndDenseTriggers::TriggerTimeAfter::operator()(
const TriggerRecord& a, const TriggerRecord& b) const {
return time_after_(a.next_check, b.next_check);
}

double EventsAndDenseTriggers::TriggerTimeAfter::infinite_future() const {
return time_after_.infinity();
}

void EventsAndDenseTriggers::TriggerTimeAfter::pup(PUP::er& p) {
p | time_after_;
disable_floating_point_exceptions();
const bool result = not std::isnan(next_check_);
enable_floating_point_exceptions();
return result;
}
} // namespace evolution
Loading