23 template <
int spatial_dim,
typename parameters = Parameters<>,
24 typename parameter_indices = std::make_
integer_sequence<
int, parameters::n>>
30 template <
int spatial_dim,
typename... InputSpaces,
int... parameter_indices>
34 using SpacesT = std::vector<const mfem::ParFiniteElementSpace*>;
46 std::array<
const mfem::ParFiniteElementSpace*,
sizeof...(InputSpaces)> mfem_spaces;
49 sizeof...(InputSpaces) != input_mfem_spaces.size(),
50 std::format(
"{} parameter spaces given in the template argument but {} parameter names were supplied.",
51 sizeof...(InputSpaces), input_mfem_spaces.size()));
53 if constexpr (
sizeof...(InputSpaces) > 0) {
54 for_constexpr<
sizeof...(InputSpaces)>([&](
auto i) { mfem_spaces[i] = input_mfem_spaces[i]; });
57 const auto& shape_disp_space = mesh_->shapeDisplacementSpace();
60 std::make_unique<ShapeAwareFunctional<
ShapeDispSpace, double(InputSpaces...)>>(&shape_disp_space, mfem_spaces);
70 template <
typename FuncOfTimeSpaceAndParams,
int... all_params>
72 std::integer_sequence<int, all_params...>)
74 const double* dt = &dt_;
75 const size_t* cycle = &cycle_;
76 objective_->AddDomainIntegral(
78 [dt, cycle, qfunction](
double time,
auto X,
auto... params) {
79 return qfunction(
TimeInfo(time, *dt, *cycle), X, params...);
81 mesh_->domain(body_name));
85 template <
int... active_parameters,
typename FuncOfTimeSpaceAndParams>
87 const FuncOfTimeSpaceAndParams& qfunction)
89 addBodyIntegralImpl(body_name, qfunction, std::integer_sequence<int, active_parameters...>{});
93 template <
typename FuncOfTimeSpaceAndParams>
94 void addBodyIntegral(std::string body_name,
const FuncOfTimeSpaceAndParams& qfunction)
96 addBodyIntegralImpl(body_name, qfunction, std::make_integer_sequence<
int,
sizeof...(InputSpaces)>{});
106 template <
typename FuncOfTimeSpaceAndParams,
int... all_params>
108 std::integer_sequence<int, all_params...>)
110 const double* dt = &dt_;
111 const size_t* cycle = &cycle_;
112 objective_->AddBoundaryIntegral(
114 [dt, cycle, qfunction](
double time,
auto X,
auto... params) {
115 return qfunction(
TimeInfo(time, *dt, *cycle), X, params...);
117 mesh_->domain(boundary_name));
121 template <
int... active_parameters,
typename FuncOfTimeSpaceAndParams>
123 const FuncOfTimeSpaceAndParams& qfunction)
125 addBoundaryIntegralImpl(boundary_name, qfunction, std::integer_sequence<int, active_parameters...>{});
129 template <
typename FuncOfTimeSpaceAndParams>
132 addBoundaryIntegralImpl(boundary_name, qfunction, std::make_integer_sequence<
int,
sizeof...(InputSpaces)>{});
137 const std::vector<ConstFieldPtr>& fields)
const override
139 dt_ = time_info.
dt();
140 cycle_ = time_info.
cycle();
142 return evaluateObjective(std::make_integer_sequence<
int,
sizeof...(parameter_indices)>{}, time_info.
time(),
148 size_t field_ordinal)
const override
150 dt_ = time_info.
dt();
151 cycle_ = time_info.
cycle();
153 auto grads = gradientEvaluators(std::make_integer_sequence<
int,
sizeof...(parameter_indices)>{}, time_info.
time(),
155 auto g = smith::get<DERIVATIVE>(grads[field_ordinal](time_info.
time(), shape_disp, fields));
161 const std::vector<ConstFieldPtr>& fields)
const override
163 dt_ = time_info.
dt();
164 cycle_ = time_info.
cycle();
166 auto g = smith::get<DERIVATIVE>(
175 const std::vector<ConstFieldPtr>& fs)
const
177 return (*objective_)(time, *shape_disp, *fs[i]...);
182 auto gradientEvaluators(std::integer_sequence<int, i...>,
double time,
ConstFieldPtr shape_disp,
183 const std::vector<ConstFieldPtr>& fs)
const
185 using JacFuncType = std::function<decltype((*objective_)(DifferentiateWRT<1>{}, time, *shape_disp, *fs[i]...))(
187 return std::array<JacFuncType,
sizeof...(i)>{
188 [
this](
double _time,
ConstFieldPtr _shape_disp,
const std::vector<ConstFieldPtr>& _fs) {
189 return (*objective_)(DifferentiateWRT<i + 1>{}, _time, *_shape_disp, *_fs[i]...);
197 mutable size_t cycle_ = 0;
200 std::shared_ptr<Mesh> mesh_;
203 std::unique_ptr<ShapeAwareFunctional<ShapeDispSpace, double(InputSpaces...)>> objective_;
This contains a class that represents the dual of a finite element vector space, i....
This file contains the declaration of structure that manages the MFEM objects that make up the state ...
Smith mesh class which assists in constructing the appropriate parallel mfem meshes and registering a...
Accelerator functionality.
DoubleState evaluateObjective(const ScalarObjective &objective, const FieldState &shape_disp, const std::vector< FieldState > &inputs, const TimeInfo &time_info)
Evaluates a DoubleState using a provided ScalarObjective reference, and the input arguments to that o...
SMITH_HOST_DEVICE auto max(dual< gradient_type > a, double b)
Implementation of max for dual numbers.
FiniteElementState const * ConstFieldPtr
using
Specifies interface for evaluating scalar objective from fields and their field gradients.
Wrapper of smith::Functional for evaluating integrals and derivatives of quantities with shape displa...
Compile-time alias for a dimension.
a struct that is used in the physics modules to clarify which template arguments are user-controlled ...
struct storing time and timestep information
double dt() const
accessor for dt
size_t cycle() const
accessor for cycle
double time() const
accessor for the current time