Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IMEX actions #5676

Merged
merged 3 commits into from
Jan 19, 2024
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
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
Loading