Skip to content

Commit

Permalink
Merge pull request #5676 from wthrowe/imex/actions
Browse files Browse the repository at this point in the history
Add IMEX actions
  • Loading branch information
nilsdeppe authored Jan 19, 2024
2 parents fb8eae0 + 28531a8 commit 1bea02a
Show file tree
Hide file tree
Showing 14 changed files with 899 additions and 2 deletions.
11 changes: 11 additions & 0 deletions src/Evolution/Imex/Actions/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Distributed under the MIT License.
# See LICENSE.txt for details.

spectre_target_headers(
${LIBRARY}
INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src
HEADERS
DoImplicitStep.hpp
NamespaceDocs.hpp
RecordTimeStepperData.hpp
)
90 changes: 90 additions & 0 deletions src/Evolution/Imex/Actions/DoImplicitStep.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Distributed under the MIT License.
// See LICENSE.txt for details.

#pragma once

#include <optional>

#include "DataStructures/DataBox/DataBox.hpp"
#include "Evolution/Imex/Protocols/ImexSystem.hpp"
#include "Evolution/Imex/SolveImplicitSector.hpp"
#include "Parallel/AlgorithmExecution.hpp"
#include "Time/TimeStepId.hpp"
#include "Utilities/CleanupRoutine.hpp"
#include "Utilities/Gsl.hpp"
#include "Utilities/ProtocolHelpers.hpp"
#include "Utilities/TMPL.hpp"

/// \cond
namespace Parallel {
template <typename Metavariables>
class GlobalCache;
} // namespace Parallel
namespace Tags {
template <typename Tag>
struct Next;
struct Time;
struct TimeStepId;
} // namespace Tags
namespace db {
template <typename TagsList>
class DataBox;
} // namespace db
namespace tuples {
template <class... Tags>
class TaggedTuple;
} // namespace tuples
/// \endcond

namespace imex::Actions {
/// \ingroup ActionsGroup
/// \brief Perform implicit variable updates for one substep
///
/// Uses:
/// - DataBox:
/// - Tags::Next<Tags::TimeStepId>
/// - Tags::Time
/// - Tags::TimeStep
/// - Tags::TimeStepper<ImexTimeStepper>
/// - imex::Tags::Mode
/// - imex::Tags::SolveTolerance
/// - as required by system implicit sectors
///
/// DataBox changes:
/// - variables_tag
/// - imex::Tags::ImplicitHistory<sector> for each sector
template <typename System>
struct DoImplicitStep {
template <typename DbTags, typename... InboxTags, typename Metavariables,
typename ArrayIndex, typename ActionList,
typename ParallelComponent>
static Parallel::iterable_action_return_t apply(
db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
const Parallel::GlobalCache<Metavariables>& /*cache*/,
const ArrayIndex& /*array_index*/, ActionList /*meta*/,
const ParallelComponent* const /*meta*/) {
static_assert(tt::assert_conforms_to_v<System, protocols::ImexSystem>);

const double original_time = db::get<::Tags::Time>(box);
const CleanupRoutine reset_time = [&]() {
db::mutate<::Tags::Time>(
[&](const gsl::not_null<double*> time) { *time = original_time; },
make_not_null(&box));
};
db::mutate<::Tags::Time>(
[](const gsl::not_null<double*> time,
const TimeStepId& next_time_step_id) {
*time = next_time_step_id.substep_time();
},
make_not_null(&box), db::get<::Tags::Next<::Tags::TimeStepId>>(box));

tmpl::for_each<typename System::implicit_sectors>([&](auto sector_v) {
using sector = tmpl::type_from<decltype(sector_v)>;
db::mutate_apply<
SolveImplicitSector<typename System::variables_tag, sector>>(
make_not_null(&box));
});
return {Parallel::AlgorithmExecution::Continue, std::nullopt};
}
};
} // namespace imex::Actions
7 changes: 7 additions & 0 deletions src/Evolution/Imex/Actions/NamespaceDocs.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Distributed under the MIT License.
// See LICENSE.txt for details.

#pragma once

/// Actions related to evolution using implicit-explicit time stepping.
namespace imex::Actions {}
102 changes: 102 additions & 0 deletions src/Evolution/Imex/Actions/RecordTimeStepperData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Distributed under the MIT License.
// See LICENSE.txt for details.

#pragma once

#include <cstddef>
#include <optional>

#include "DataStructures/DataBox/DataBox.hpp"
#include "DataStructures/DataBox/PrefixHelpers.hpp"
#include "DataStructures/DataBox/Prefixes.hpp"
#include "DataStructures/Variables.hpp"
#include "Evolution/Imex/Protocols/ImexSystem.hpp"
#include "Evolution/Imex/Tags/ImplicitHistory.hpp"
#include "Parallel/AlgorithmExecution.hpp"
#include "Utilities/Gsl.hpp"
#include "Utilities/ProtocolHelpers.hpp"
#include "Utilities/TMPL.hpp"

/// \cond
class TimeStepId;
namespace Parallel {
template <typename Metavariables>
class GlobalCache;
} // namespace Parallel
namespace Tags {
struct TimeStepId;
} // namespace Tags
namespace tuples {
template <class... Tags>
class TaggedTuple;
} // namespace tuples
/// \endcond

namespace imex::Actions {
/// \ingroup ActionsGroup
/// \brief Records the implicit sources in the implicit time stepper history.
///
/// Uses:
/// - GlobalCache: nothing
/// - DataBox:
/// - Tags::TimeStepId
/// - system::variables_tag
/// - as required by source terms
///
/// DataBox changes:
/// - imex::Tags::ImplicitHistory<sector> for each sector
template <typename System>
struct RecordTimeStepperData {
template <typename DbTags, typename... InboxTags, typename Metavariables,
typename ArrayIndex, typename ActionList,
typename ParallelComponent>
static Parallel::iterable_action_return_t apply(
db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
const Parallel::GlobalCache<Metavariables>& /*cache*/,
const ArrayIndex& /*array_index*/, ActionList /*meta*/,
const ParallelComponent* const /*meta*/) { // NOLINT const
static_assert(tt::assert_conforms_to_v<System, protocols::ImexSystem>);

const size_t number_of_grid_points =
db::get<typename System::variables_tag>(box).number_of_grid_points();

tmpl::for_each<typename System::implicit_sectors>([&](auto sector_v) {
using sector = tmpl::type_from<decltype(sector_v)>;
using source =
typename tmpl::front<typename sector::solve_attempts>::source;
using history_tag = Tags::ImplicitHistory<sector>;
using DtSectorVars =
Variables<db::wrap_tags_in<::Tags::dt, typename sector::tensors>>;
db::mutate_apply<
tmpl::list<history_tag>,
tmpl::push_front<typename source::argument_tags, ::Tags::TimeStepId>>(
[&](const gsl::not_null<typename history_tag::type*> history,
const TimeStepId& time_step_id, const auto&... source_arguments) {
history->insert_in_place(
time_step_id, history_tag::type::no_value,
[&](const gsl::not_null<DtSectorVars*> source_result) {
source_result->initialize(number_of_grid_points);
tmpl::as_pack<typename source::return_tags>(
[&](auto... source_tags) {
// The history stores derivatives as
// ::Tags::dt<Var>, but the source provides
// ::Tags::Source<Var>. Since the only
// implicit equations we support are source
// terms, these quantities are equal, but we
// still need to make the types match.
source::apply(
make_not_null(
&get<::Tags::dt<db::remove_tag_prefix<
tmpl::type_from<decltype(source_tags)>>>>(
*source_result))...,
source_arguments...);
});
});
},
make_not_null(&box));
});

return {Parallel::AlgorithmExecution::Continue, std::nullopt};
}
};
} // namespace imex::Actions
2 changes: 2 additions & 0 deletions src/Evolution/Imex/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ spectre_target_headers(
INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src
HEADERS
GuessResult.hpp
Initialize.hpp
Mode.hpp
NamespaceDocs.hpp
SolveImplicitSector.hpp
Expand All @@ -36,5 +37,6 @@ target_link_libraries(
Utilities
)

add_subdirectory(Actions)
add_subdirectory(Protocols)
add_subdirectory(Tags)
57 changes: 57 additions & 0 deletions src/Evolution/Imex/Initialize.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Distributed under the MIT License.
// See LICENSE.txt for details.

#pragma once

#include "Evolution/Imex/Protocols/ImexSystem.hpp"
#include "Evolution/Imex/Tags/ImplicitHistory.hpp"
#include "Evolution/Imex/Tags/Mode.hpp"
#include "Evolution/Imex/Tags/SolveFailures.hpp"
#include "Evolution/Imex/Tags/SolveTolerance.hpp"
#include "Time/History.hpp"
#include "Time/Tags/HistoryEvolvedVariables.hpp"
#include "Utilities/Gsl.hpp"
#include "Utilities/MakeWithValue.hpp"
#include "Utilities/ProtocolHelpers.hpp"
#include "Utilities/TMPL.hpp"

namespace imex {
/// Create the IMEX structures and options.
template <typename System, typename = typename System::implicit_sectors>
struct Initialize;

/// \cond
template <typename System, typename... Sectors>
struct Initialize<System, tmpl::list<Sectors...>> {
static_assert(tt::assert_conforms_to_v<System, protocols::ImexSystem>);

using example_tensor_tag =
tmpl::front<typename tmpl::front<tmpl::list<Sectors...>>::tensors>;

using const_global_cache_tags = tmpl::list<Tags::Mode, Tags::SolveTolerance>;
using mutable_global_cache_tags = tmpl::list<>;
using simple_tags_from_options = tmpl::list<>;
using simple_tags = tmpl::list<Tags::ImplicitHistory<Sectors>...,
Tags::SolveFailures<Sectors>...>;
using compute_tags = tmpl::list<>;

using return_tags = simple_tags;
using argument_tags =
tmpl::list<::Tags::HistoryEvolvedVariables<>, example_tensor_tag>;

static void apply(
const gsl::not_null<
typename Tags::ImplicitHistory<Sectors>::type*>... histories,
const gsl::not_null<
typename Tags::SolveFailures<Sectors>::type*>... solve_failures,
const TimeSteppers::History<typename System::variables_tag::type>&
explicit_history,
const typename example_tensor_tag::type& example_tensor) {
const auto order = explicit_history.integration_order();
expand_pack((histories->integration_order(order), 0)...);
expand_pack(*solve_failures = make_with_value<Scalar<DataVector>>(
example_tensor, 0.0)...);
}
};
/// \endcond
} // namespace imex
8 changes: 8 additions & 0 deletions tests/Unit/Evolution/Imex/Actions/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Distributed under the MIT License.
# See LICENSE.txt for details.

set(LIBRARY_SOURCES
${LIBRARY_SOURCES}
Actions/Test_DoImplicitStep.cpp
Actions/Test_RecordTimeStepperData.cpp
PARENT_SCOPE)
Loading

0 comments on commit 1bea02a

Please sign in to comment.