Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
functional_objective.hpp
Go to the documentation of this file.
1 // Copyright Lawrence Livermore National Security, LLC and
2 // other Smith Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
13 #pragma once
14 
16 #include "smith/physics/mesh.hpp"
20 
21 namespace smith {
22 
23 template <int spatial_dim, typename parameters = Parameters<>,
24  typename parameter_indices = std::make_integer_sequence<int, parameters::n>>
26 
30 template <int spatial_dim, typename... InputSpaces, int... parameter_indices>
31 class FunctionalObjective<spatial_dim, Parameters<InputSpaces...>, std::integer_sequence<int, parameter_indices...>>
32  : public ScalarObjective {
33  public:
34  using SpacesT = std::vector<const mfem::ParFiniteElementSpace*>;
35 
37 
43  FunctionalObjective(const std::string& physics_name, std::shared_ptr<Mesh> mesh, const SpacesT& input_mfem_spaces)
44  : ScalarObjective(physics_name), mesh_(mesh)
45  {
46  std::array<const mfem::ParFiniteElementSpace*, sizeof...(InputSpaces)> mfem_spaces;
47 
48  SLIC_ERROR_ROOT_IF(
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()));
52 
53  if constexpr (sizeof...(InputSpaces) > 0) {
54  for_constexpr<sizeof...(InputSpaces)>([&](auto i) { mfem_spaces[i] = input_mfem_spaces[i]; });
55  }
56 
57  const auto& shape_disp_space = mesh_->shapeDisplacementSpace();
58 
59  objective_ =
60  std::make_unique<ShapeAwareFunctional<ShapeDispSpace, double(InputSpaces...)>>(&shape_disp_space, mfem_spaces);
61  }
62 
70  template <int... active_parameters, typename FuncOfTimeSpaceAndParams>
71  void addBodyIntegral(DependsOn<active_parameters...>, std::string body_name,
72  const FuncOfTimeSpaceAndParams& qfunction)
73  {
74  objective_->AddDomainIntegral(smith::Dimension<spatial_dim>{}, smith::DependsOn<active_parameters...>{}, qfunction,
75  mesh_->domain(body_name));
76  }
77 
79  virtual double evaluate(TimeInfo time_info, ConstFieldPtr shape_disp,
80  const std::vector<ConstFieldPtr>& fields) const override
81  {
82  dt_ = time_info.dt();
83  cycle_ = time_info.cycle();
84 
85  return evaluateObjective(std::make_integer_sequence<int, sizeof...(parameter_indices)>{}, time_info.time(),
86  shape_disp, fields);
87  }
88 
90  virtual mfem::Vector gradient(TimeInfo time_info, ConstFieldPtr shape_disp, const std::vector<ConstFieldPtr>& fields,
91  size_t field_ordinal) const override
92  {
93  dt_ = time_info.dt();
94  cycle_ = time_info.cycle();
95 
96  auto grads = gradientEvaluators(std::make_integer_sequence<int, sizeof...(parameter_indices)>{}, time_info.time(),
97  shape_disp, fields);
98  auto g = smith::get<DERIVATIVE>(grads[field_ordinal](time_info.time(), shape_disp, fields));
99  return *assemble(g);
100  }
101 
103  virtual mfem::Vector mesh_coordinate_gradient(TimeInfo time_info, ConstFieldPtr shape_disp,
104  const std::vector<ConstFieldPtr>& fields) const override
105  {
106  dt_ = time_info.dt();
107  cycle_ = time_info.cycle();
108 
109  auto g = smith::get<DERIVATIVE>(
110  (*objective_)(DifferentiateWRT<0>{}, time_info.time(), *shape_disp, *fields[parameter_indices]...));
111  return *assemble(g);
112  }
113 
114  private:
116  template <int... i>
117  auto evaluateObjective(std::integer_sequence<int, i...>, double time, ConstFieldPtr shape_disp,
118  const std::vector<ConstFieldPtr>& fs) const
119  {
120  return (*objective_)(time, *shape_disp, *fs[i]...);
121  }
122 
124  template <int... i>
125  auto gradientEvaluators(std::integer_sequence<int, i...>, double time, ConstFieldPtr shape_disp,
126  const std::vector<ConstFieldPtr>& fs) const
127  {
128  using JacFuncType = std::function<decltype((*objective_)(DifferentiateWRT<1>{}, time, *shape_disp, *fs[i]...))(
129  double, ConstFieldPtr, const std::vector<ConstFieldPtr>&)>;
130  return std::array<JacFuncType, sizeof...(i)>{
131  [this](double _time, ConstFieldPtr _shape_disp, const std::vector<ConstFieldPtr>& _fs) {
132  return (*objective_)(DifferentiateWRT<i + 1>{}, _time, *_shape_disp, *_fs[i]...);
133  }...};
134  }
135 
137  mutable double dt_ = std::numeric_limits<double>::max();
138 
140  mutable size_t cycle_ = 0;
141 
143  std::shared_ptr<Mesh> mesh_;
144 
146  std::unique_ptr<ShapeAwareFunctional<ShapeDispSpace, double(InputSpaces...)>> objective_;
147 };
148 
149 } // namespace smith
virtual mfem::Vector gradient(TimeInfo time_info, ConstFieldPtr shape_disp, const std::vector< ConstFieldPtr > &fields, size_t field_ordinal) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
virtual mfem::Vector mesh_coordinate_gradient(TimeInfo time_info, ConstFieldPtr shape_disp, const std::vector< ConstFieldPtr > &fields) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
FunctionalObjective(const std::string &physics_name, std::shared_ptr< Mesh > mesh, const SpacesT &input_mfem_spaces)
construct a FunctionalObjective
virtual double evaluate(TimeInfo time_info, ConstFieldPtr shape_disp, const std::vector< ConstFieldPtr > &fields) const override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void addBodyIntegral(DependsOn< active_parameters... >, std::string body_name, const FuncOfTimeSpaceAndParams &qfunction)
register a custom domain integral calculation as part of the residual
Abstract residual class.
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...
constexpr SMITH_HOST_DEVICE void for_constexpr(const lambda &f)
multidimensional loop tool that evaluates the lambda body inside the innermost loop.
Accelerator functionality.
Definition: smith.cpp:36
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.
Definition: dual.hpp:229
FiniteElementState const * ConstFieldPtr
using
Definition: field_types.hpp:36
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.
Definition: geometry.hpp:17
H1 elements of order p.
a struct that is used in the physics modules to clarify which template arguments are user-controlled ...
Definition: common.hpp:45
struct storing time and timestep information
Definition: common.hpp:18
double dt() const
accessor for dt
Definition: common.hpp:29
size_t cycle() const
accessor for cycle
Definition: common.hpp:32
double time() const
accessor for the current time
Definition: common.hpp:26