Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
functional_objective.hpp
Go to the documentation of this file.
1 // Copyright Lawrence Livermore National Security, LLC and
2 // other Serac 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 "serac/physics/mesh.hpp"
20 
21 namespace serac {
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  axom::fmt::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(serac::Dimension<spatial_dim>{}, serac::DependsOn<active_parameters...>{}, qfunction,
75  mesh_->domain(body_name));
76  }
77 
79  virtual double evaluate(double time, double dt, ConstFieldPtr shape_disp,
80  const std::vector<ConstFieldPtr>& fields) const override
81  {
82  dt_ = dt;
83  return evaluateObjective(std::make_integer_sequence<int, sizeof...(parameter_indices)>{}, time, shape_disp, fields);
84  }
85 
87  virtual mfem::Vector gradient(double time, double dt, ConstFieldPtr shape_disp,
88  const std::vector<ConstFieldPtr>& fields, int field_ordinal) const override
89  {
90  dt_ = dt;
91  auto grads =
92  gradientEvaluators(std::make_integer_sequence<int, sizeof...(parameter_indices)>{}, time, shape_disp, fields);
93  auto g = serac::get<DERIVATIVE>(grads[static_cast<size_t>(field_ordinal)](time, shape_disp, fields));
94  return *assemble(g);
95  }
96 
98  virtual mfem::Vector mesh_coordinate_gradient(double time, double dt, ConstFieldPtr shape_disp,
99  const std::vector<ConstFieldPtr>& fields) const override
100  {
101  dt_ = dt;
102  auto g =
103  serac::get<DERIVATIVE>((*objective_)(DifferentiateWRT<0>{}, time, *shape_disp, *fields[parameter_indices]...));
104  return *assemble(g);
105  }
106 
107  private:
109  template <int... i>
110  auto evaluateObjective(std::integer_sequence<int, i...>, double time, ConstFieldPtr shape_disp,
111  const std::vector<ConstFieldPtr>& fs) const
112  {
113  return (*objective_)(time, *shape_disp, *fs[i]...);
114  };
115 
117  template <int... i>
118  auto gradientEvaluators(std::integer_sequence<int, i...>, double time, ConstFieldPtr shape_disp,
119  const std::vector<ConstFieldPtr>& fs) const
120  {
121  using JacFuncType = std::function<decltype((*objective_)(DifferentiateWRT<1>{}, time, *shape_disp, *fs[i]...))(
122  double, ConstFieldPtr, const std::vector<ConstFieldPtr>&)>;
123  return std::array<JacFuncType, sizeof...(i)>{
124  [=](double _time, ConstFieldPtr _shape_disp, const std::vector<ConstFieldPtr>& _fs) {
125  return (*objective_)(DifferentiateWRT<i + 1>{}, _time, *_shape_disp, *_fs[i]...);
126  }...};
127  };
128 
130  mutable double dt_ = std::numeric_limits<double>::max();
131 
133  std::shared_ptr<Mesh> mesh_;
134 
136  std::unique_ptr<ShapeAwareFunctional<ShapeDispSpace, double(InputSpaces...)>> objective_;
137 };
138 
139 } // namespace serac
virtual mfem::Vector gradient(double time, double dt, ConstFieldPtr shape_disp, const std::vector< ConstFieldPtr > &fields, int 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(double time, double dt, 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
FunctionalObjective(const std::string &physics_name, std::shared_ptr< Mesh > mesh, const SpacesT &input_mfem_spaces)
construct a FunctionalObjective
virtual double evaluate(double time, double dt, 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...
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 ...
Serac mesh class which assists in constructing the appropriate parallel mfem meshes and registering a...
constexpr SERAC_HOST_DEVICE void for_constexpr(const lambda &f)
multidimensional loop tool that evaluates the lambda body inside the innermost loop.
Accelerator functionality.
Definition: serac.cpp:36
SERAC_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 serac::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:21