21 #include <type_traits>
24 #include "smith/differentiable_numerics/field_store.hpp"
36 template <
int Dim,
int Order,
typename TimeRule,
typename... Spaces>
39 static constexpr
int dim = Dim;
40 static constexpr
int order = Order;
41 static constexpr std::size_t
num_fields =
sizeof...(Spaces);
43 std::tuple<FieldType<Spaces>...>
fields;
55 template <
typename... Spaces>
57 static constexpr std::size_t
num_fields =
sizeof...(Spaces);
58 std::tuple<FieldType<Spaces>...>
fields;
64 template <
typename... Spaces>
73 template <
typename... PFs>
83 template <
int D,
int O,
typename R,
typename... S>
93 template <
typename... PFs>
96 static_assert((detail::is_physics_fields_v<PFs> && ...),
"couplingFields(...) only accepts PhysicsFields packs");
103 template <
typename... ParamSpaces>
106 auto register_one = [&](
auto param_type) {
107 param_type.name =
"param_" + param_type.name;
108 field_store->addParameter(param_type);
111 return ParamFields<ParamSpaces...>{register_one(std::move(param_types))...};
116 template <
typename T>
119 template <
typename... S>
123 template <
typename T>
126 template <
typename T>
129 template <
typename... PFs>
133 template <
typename T>
137 template <
typename T>
140 template <
typename... Packs>
144 template <
typename T>
148 template <
typename T,
typename =
void>
152 template <
typename T>
153 inline constexpr
bool has_time_rule_v<T, std::enable_if_t<is_physics_fields_v<T>>> =
true;
160 template <
typename PacksTuple>
163 return std::apply([](
const auto&... pack) {
return std::tuple_cat(pack.fields...); }, packs);
169 template <
typename... PFs>
173 return coupled.
packs;
176 template <
typename... Spaces>
180 return std::make_tuple(params);
183 template <
typename... PFs,
typename... Spaces>
187 return std::tuple_cat(coupled.
packs, std::make_tuple(params));
195 template <
typename Rule,
typename TimeInfoT,
typename ArgsTuple,
typename Callback, std::size_t... StateIs,
196 std::size_t... TailIs>
198 Callback&& callback, std::index_sequence<StateIs...>,
199 std::index_sequence<TailIs...>)
201 auto interpolated = rule.interpolate(t_info, std::get<StateIs>(raw_args)...);
203 [&](
auto&&... values) -> decltype(
auto) {
204 return std::forward<Callback>(callback)(std::forward<decltype(values)>(values)...,
205 std::get<Rule::num_states + TailIs>(raw_args)...);
211 template <
typename Rule,
typename TimeInfoT,
typename Callback,
typename... RawArgs>
213 const RawArgs&... raw_args)
215 static_assert(
sizeof...(RawArgs) >= Rule::num_states,
"Not enough raw arguments for time-rule interpolation");
216 auto raw_tuple = std::forward_as_tuple(raw_args...);
217 constexpr std::size_t tail_count =
sizeof...(RawArgs) - Rule::num_states;
219 std::make_index_sequence<Rule::num_states>{},
220 std::make_index_sequence<tail_count>{});
224 template <std::size_t Offset,
typename Pack,
typename TimeInfoT,
typename RawTuple, std::size_t... Is>
226 std::index_sequence<Is...>)
228 if constexpr (is_physics_fields_v<Pack>) {
229 using Rule =
typename Pack::time_rule_type;
231 return rule.interpolate(t_info, std::get<Offset + Is>(raw_args)...);
233 return std::forward_as_tuple(std::get<Offset + Is>(raw_args)...);
238 template <std::
size_t I, std::
size_t Offset,
typename PacksTuple,
typename TimeInfoT,
typename RawTuple>
241 if constexpr (I == std::tuple_size_v<std::decay_t<PacksTuple>>) {
244 const auto& pack = std::get<I>(packs);
245 using Pack = std::decay_t<decltype(pack)>;
246 auto head = evaluateCouplingPack<Offset>(pack, t_info, raw_args, std::make_index_sequence<Pack::num_fields>{});
247 auto tail = evaluateCouplingPacks<I + 1, Offset + Pack::num_fields>(packs, t_info, raw_args);
248 return std::tuple_cat(head, tail);
253 template <
typename PacksTuple,
typename TimeInfoT,
typename Callback,
typename... RawArgs>
255 const RawArgs&... raw_args)
257 auto raw_tuple = std::forward_as_tuple(raw_args...);
258 auto interpolated_tail = evaluateCouplingPacks<0, 0>(packs, t_info, raw_tuple);
259 return std::apply(std::forward<Callback>(callback), interpolated_tail);
270 template <
typename Rule,
typename Coupling,
typename TimeInfoT,
typename Callback,
typename... RawArgs>
272 Callback&& callback, const RawArgs&... raw_args)
274 constexpr std::size_t tail_count =
sizeof...(RawArgs) - Rule::num_states;
277 [&](
auto... self_states_and_tail) {
278 constexpr std::size_t n_self =
sizeof...(self_states_and_tail) - tail_count;
279 auto all = std::forward_as_tuple(self_states_and_tail...);
280 return [&]<std::size_t... Si, std::size_t... Ti>(std::index_sequence<Si...>, std::index_sequence<Ti...>) {
283 [&](
auto... interpolated_coupling) {
284 return std::forward<Callback>(callback)(std::get<Si>(all)..., interpolated_coupling...);
286 std::get<n_self + Ti>(all)...);
287 }(std::make_index_sequence<n_self>{}, std::make_index_sequence<tail_count>{});
297 template <
typename PacksTuple>
301 template <
typename Tuple>
305 template <
typename... Spaces>
311 template <
typename Tuple>
315 template <
typename Pack>
319 template <
int D,
int O,
typename R,
typename... Spaces>
325 template <
typename... Spaces>
331 template <
typename Pack>
335 template <
typename... Tuples>
336 using tuple_cat_t = decltype(std::tuple_cat(std::declval<Tuples>()...));
339 template <
typename CouplingParams,
typename FixedParams>
343 template <
typename... Coupled,
typename... Fixed>
349 template <
typename... Packs>
357 template <
typename PacksTuple>
361 template <
typename Rule,
typename Space,
typename PacksTuple>
365 template <
typename Rule,
typename Space,
typename... CS>
371 template <
typename Rule,
typename Space,
typename PacksTuple>
375 template <
typename PacksTuple,
typename FixedParams>
379 template <
typename PacksTuple,
typename... Fixed>
decltype(auto) applyCouplingTimeRules(const PacksTuple &packs, const TimeInfoT &t_info, Callback &&callback, const RawArgs &... raw_args)
Interpolate coupling packs and invoke the callback.
constexpr bool is_coupling_fields_v
True if T is a CouplingFields type.
auto evaluateCouplingPack(const Pack &, const TimeInfoT &t_info, const RawTuple &raw_args, std::index_sequence< Is... >)
Evaluate a single coupling pack's time rule.
typename pack_tuple< std::decay_t< Pack > >::type pack_tuple_t
Typedef for extracting a tuple of spaces from a coupling pack.
constexpr bool is_coupling_packs_v
True if T is a tuple of coupling packs.
decltype(auto) applyTimeRuleAndCoupling(const Rule &rule, const Coupling &coupling, const TimeInfoT &t_info, Callback &&callback, const RawArgs &... raw_args)
Interpolate self time-rule states then coupling segments, then invoke callback.
decltype(std::tuple_cat(std::declval< Tuples >()...)) tuple_cat_t
Typedef for concatenating space tuples with std::tuple_cat.
auto collectCouplingFields()
Collect no coupling or parameter packs.
decltype(auto) applyTimeRuleToPrefixImpl(const Rule &rule, const TimeInfoT &t_info, const ArgsTuple &raw_args, Callback &&callback, std::index_sequence< StateIs... >, std::index_sequence< TailIs... >)
Implementation of time rule prefix application.
typename FlattenCoupling< std::decay_t< PacksTuple > >::parameters flatten_coupling_t
Typedef for flattened coupling parameter spaces.
constexpr bool is_physics_fields_v
True when T is a PhysicsFields pack.
typename TupleToParameters< std::decay_t< Tuple > >::type tuple_to_parameters_t
Typedef for converting a tuple of spaces into Parameters<...>.
decltype(auto) applyTimeRuleToPrefix(const Rule &rule, const TimeInfoT &t_info, Callback &&callback, const RawArgs &... raw_args)
Apply time rule interpolation to the leading prefix of raw arguments.
constexpr bool has_time_rule_v
Base case: T does not have a time rule.
typename TimeRuleParamsImpl< Rule, Space, flatten_coupling_t< PacksTuple > >::type TimeRuleParams
Typedef for TimeRuleParams.
auto evaluateCouplingPacks(const PacksTuple &packs, const TimeInfoT &t_info, const RawTuple &raw_args)
Evaluate all coupling packs over their corresponding raw arguments.
auto flattenCouplingFields(const PacksTuple &packs)
Concatenate each pack's .fields tuple — used to derive trailing weak-form parameter spaces.
constexpr bool is_parameter_pack_v
True if T is a ParamFields type.
Accelerator functionality.
mfem::future::tuple< T... > tuple
Expose MFEM tuple in the Smith namespace.
auto couplingFields(const PFs &... pfs)
Helper to construct a CouplingFields bundle.
auto registerParameterFields(const std::shared_ptr< FieldStore > &field_store, FieldType< ParamSpaces >... param_types)
Register parameter fields as type-level tokens.
decltype(detail::time_rule_params_impl< Space, Tail... >(std::make_index_sequence< Rule::num_states >{})) TimeRuleParams
Generate a Parameters<...> type with Rule::num_states copies of Space followed by additional Tail typ...
ParamFields(FieldType< Spaces >...) -> ParamFields< Spaces... >
Deduction guide for ParamFields.
Bundle of coupled PhysicsFields packs supplied to a builder as a single coupling arg.
std::tuple< PFs... > packs
The coupling packs.
Representation of a field type with a name and a flag indicating whether it is an active Jacobian unk...
Registered parameter-only field bundle.
ParamFields(FieldType< Spaces >... fs)
Constructor.
std::tuple< FieldType< Spaces >... > fields
static constexpr std::size_t num_fields
Number of fields.
a struct that is used in the physics modules to clarify which template arguments are user-controlled ...
Fields returned by a physics register function, carrying time rule type information.
static constexpr int order
Spatial order.
static constexpr int dim
Spatial dimension.
PhysicsFields(std::shared_ptr< FieldStore > fs, FieldType< Spaces >... f)
Constructor.
std::tuple< FieldType< Spaces >... > fields
The fields.
std::shared_ptr< FieldStore > field_store
Pointer to the field store.
static constexpr std::size_t num_fields
Number of fields.
TimeRule time_rule_type
The time integration rule type.
typename AppendParameters< flatten_coupling_t< PacksTuple >, Parameters< Fixed... > >::type type
The appended parameter list.
Type trait to append coupling parameter spaces to fixed parameters.
Appends coupling parameter spaces to an existing Parameters<...> list.
tuple_to_parameters_t< tuple_type > parameters
Flattened parameter spaces.
tuple_cat_t< pack_tuple_t< Packs >... > tuple_type
The flattened tuple of coupling spaces.
Flatten a tuple<Packs...> type into Parameters<all_pack_spaces...>.
smith::TimeRuleParams< Rule, Space, CS... > type
The constructed TimeRuleParams type.
Type trait to construct Parameters<Space, packed_coupling_spaces...> for a weak form's parameter list...
Converts a std::tuple<...> of spaces into Parameters<...>.
True for a std::tuple<Packs...> returned by collectCouplingFields.
std::tuple< Spaces... > type
The parameter spaces as a tuple.
std::tuple< Spaces... > type
The coupling spaces as a tuple.
Maps a coupling pack type to a std::tuple<...> of its spaces.
Defines the SystemBase struct for common system functionality.