15 #include "smith/smith_config.hpp"
17 #ifdef SMITH_USE_ENZYME
26 struct ScalarParameter {
27 static constexpr
int index = Idx;
28 using QFunctionInput = double;
29 template <
int FieldId>
30 using QFunctionFieldOp = mfem::future::Value<FieldId>;
33 template <
typename Material,
typename... Parameters>
34 struct StressDivQFunction {
37 const mfem::future::tensor<mfem::real_t, Material::dim, Material::dim>& du_dxi,
38 const mfem::future::tensor<mfem::real_t, Material::dim, Material::dim>& dv_dxi,
39 const mfem::future::tensor<mfem::real_t, Material::dim, Material::dim>&,
40 const mfem::future::tensor<mfem::real_t, Material::dim, Material::dim>& dX_dxi, mfem::real_t weight,
41 typename Parameters::QFunctionInput... params)
const
47 auto P = mfem::future::get<0>(material.pkStress(dt, du_dX, dv_dX, params...));
60 class DfemSolidWeakForm :
public DfemWeakForm {
65 using qdata_type = std::shared_ptr<QuadratureData<T>>;
68 static constexpr
int NUM_STATE_VARS = 4;
88 DfemSolidWeakForm(std::string physics_name, std::shared_ptr<Mesh> mesh,
const mfem::ParFiniteElementSpace& test_space,
89 std::vector<const mfem::ParFiniteElementSpace*> parameter_fe_spaces = {})
90 : DfemWeakForm(physics_name, mesh, test_space, makeInputSpaces(test_space, mesh, parameter_fe_spaces))
111 template <
typename MaterialType,
typename... ParameterTypes>
112 void setMaterial(
const mfem::Array<int>& domain_attributes,
const MaterialType& material,
113 const mfem::IntegrationRule& displacement_ir)
115 SLIC_ERROR_IF(material.dim != DfemWeakForm::mesh_->mfemParMesh().Dimension(),
116 "Material model dimension does not match mesh dimension.");
117 auto stress_div_integral = StressDivQFunction<MaterialType, ParameterTypes...>{.material = material};
118 mfem::future::tuple<mfem::future::Gradient<DISPLACEMENT>, mfem::future::Gradient<VELOCITY>,
119 mfem::future::Gradient<ACCELERATION>, mfem::future::Gradient<COORDINATES>, mfem::future::Weight,
120 typename ParameterTypes::template QFunctionFieldOp<NUM_STATE_VARS + ParameterTypes::index>...>
121 stress_div_integral_inputs{};
123 stress_div_integral_outputs{};
124 DfemWeakForm::addBodyIntegral(domain_attributes, stress_div_integral, stress_div_integral_inputs,
125 stress_div_integral_outputs, displacement_ir,
126 std::index_sequence<DISPLACEMENT, NUM_STATE_VARS + ParameterTypes::index...>{});
138 std::vector<const mfem::ParFiniteElementSpace*> makeInputSpaces(
139 const mfem::ParFiniteElementSpace& test_space,
const std::shared_ptr<Mesh>& mesh,
140 const std::vector<const mfem::ParFiniteElementSpace*>& parameter_fe_spaces)
142 std::vector<const mfem::ParFiniteElementSpace*> input_spaces;
143 input_spaces.reserve(NUM_STATE_VARS + parameter_fe_spaces.size());
144 for (
int i = 0; i < 3; ++i) {
145 input_spaces.push_back(&test_space);
147 input_spaces.push_back(
static_cast<const mfem::ParFiniteElementSpace*
>(mesh->mfemParMesh().GetNodalFESpace()));
148 for (
auto space : parameter_fe_spaces) {
149 input_spaces.push_back(
space);
This file contains the interface used for initializing/terminating any hardware accelerator-related f...
#define SMITH_HOST_DEVICE
Macro that evaluates to __host__ __device__ when compiling with nvcc or amdclang and does nothing on ...
Accelerator functionality.
tuple(T...) -> tuple< T... >
Class template argument deduction rule for tuples.
constexpr SMITH_HOST_DEVICE auto inv(const isotropic_tensor< T, m, m > &I)
return the inverse of an isotropic tensor
constexpr SMITH_HOST_DEVICE auto transpose(const isotropic_tensor< T, m, m > &I)
return the transpose of an isotropic tensor
constexpr SMITH_HOST_DEVICE auto det(const isotropic_tensor< T, m, m > &I)
compute the determinant of an isotropic tensor
mfem::ParFiniteElementSpace & space(FieldState field)
Get the space from the primal field of a field states.
constexpr SMITH_HOST_DEVICE auto dot(const isotropic_tensor< S, m, m > &I, const tensor< T, m, n... > &A)
dot product between an isotropic and (nonisotropic) tensor