20 template <
int order,
int dim,
typename InputSpaces = Parameters<>>
32 template <
int order,
int dim,
typename... InputSpaces>
35 Parameters<H1<order, dim>, H1<order, dim>, H1<order, dim>, InputSpaces...>> {
47 static constexpr
int NUM_STATE_VARS = 3;
66 SolidWeakForm(std::string physics_name, std::shared_ptr<Mesh> mesh,
const mfem::ParFiniteElementSpace& test_space,
67 std::vector<const mfem::ParFiniteElementSpace*> parameter_fe_spaces = {})
68 : BaseWeakFormT(physics_name, mesh, test_space, constructAllSpaces(test_space, parameter_fe_spaces))
96 template <
int... active_parameters,
typename MaterialType,
typename StateType = Empty>
100 static_assert(std::is_same_v<StateType, Empty> || std::is_same_v<StateType, typename MaterialType::State>,
101 "invalid quadrature data provided in setMaterial()");
102 MaterialStressFunctor<MaterialType> material_functor(material);
103 BaseWeakFormT::weak_form_->AddDomainIntegral(
105 BaseWeakFormT::mesh_->domain(body_name), qdata);
107 BaseWeakFormT::v_dot_weak_form_residual_->AddDomainIntegral(
109 [material_functor](
double t,
auto X,
auto state,
auto V,
auto... params) {
110 auto flux = material_functor(t, X, state, params...);
112 smith::inner(get<DERIVATIVE>(V), get<DERIVATIVE>(flux));
114 BaseWeakFormT::mesh_->domain(body_name), qdata);
118 template <
typename MaterialType,
typename StateType = Empty>
119 void setMaterial(std::string body_name,
const MaterialType& material,
122 setMaterial(
DependsOn<>{}, body_name, material, qdata);
149 template <
int... active_parameters,
typename MaterialType,
typename StateType =
Empty>
153 static_assert(std::is_same_v<StateType, Empty> || std::is_same_v<StateType, typename MaterialType::State>,
154 "invalid quadrature data provided in setMaterial()");
155 RateMaterialStressFunctor<MaterialType> material_functor(material, &this->dt_);
156 BaseWeakFormT::weak_form_->AddDomainIntegral(
158 BaseWeakFormT::mesh_->domain(body_name), qdata);
160 BaseWeakFormT::v_dot_weak_form_residual_->AddDomainIntegral(
162 [material_functor, qdata](
double t,
auto X,
auto state,
auto V,
auto... params) {
163 auto flux = material_functor(t, X, state, params...);
165 smith::inner(get<DERIVATIVE>(V), get<DERIVATIVE>(flux));
167 BaseWeakFormT::mesh_->domain(body_name), qdata);
171 template <
typename MaterialType,
typename StateType = Empty>
175 setRateMaterial(
DependsOn<>{}, body_name, material, qdata);
200 template <
int... active_parameters,
typename PressureType>
203 BaseWeakFormT::weak_form_->AddBoundaryIntegral(
205 [pressure_function](
double t,
auto X,
auto displacement,
auto... params) {
207 auto x = X + displacement;
208 auto n =
cross(get<DERIVATIVE>(x));
221 return pressure_function(t, get<VALUE>(X), params...) * (n /
norm(
cross(get<DERIVATIVE>(X))));
223 BaseWeakFormT::mesh_->domain(boundary_name));
225 BaseWeakFormT::v_dot_weak_form_residual_->AddBoundaryIntegral(
227 [pressure_function](
double t,
auto X,
auto V,
auto displacement,
auto... params) {
228 auto x = X + displacement;
229 auto n =
cross(get<DERIVATIVE>(x));
230 auto pressure = pressure_function(t, get<VALUE>(X), params...) * (n /
norm(
cross(get<DERIVATIVE>(X))));
231 return inner(get<VALUE>(V), pressure);
233 BaseWeakFormT::mesh_->domain(boundary_name));
237 template <
typename PressureType>
238 void addPressure(std::string boundary_name, PressureType pressure_function)
240 addPressure(
DependsOn<>{}, boundary_name, pressure_function);
250 const mfem::ParFiniteElementSpace& state_space,
const std::vector<const mfem::ParFiniteElementSpace*>&
spaces)
252 std::vector<const mfem::ParFiniteElementSpace*> all_spaces{&state_space, &state_space, &state_space};
254 all_spaces.push_back(s);
263 template <
typename Material>
264 struct MaterialStressFunctor {
286 template <
typename X,
typename State,
typename Displacement,
typename Acceleration,
typename... Params>
288 Params... params)
const
290 auto du_dX = get<DERIVATIVE>(displacement);
291 auto d2u_dt2 = get<VALUE>(acceleration);
292 auto stress = material_.pkStress(state, du_dX, params...);
293 return smith::tuple{material_.density(params...) * d2u_dt2, stress};
301 template <
typename Material>
302 struct RateMaterialStressFunctor {
329 template <
typename X,
typename State,
typename Displacement,
typename Velocity,
typename Acceleration,
332 Acceleration acceleration, Params... params)
const
334 auto du_dX = get<DERIVATIVE>(displacement);
335 auto dv_dX = get<DERIVATIVE>(velocity);
336 auto d2u_dt2 = get<VALUE>(acceleration);
337 auto stress = material_.pkStress(*dt_, state, du_dX, dv_dX, params...);
338 return smith::tuple{material_.density(params...) * d2u_dt2, stress};
346 template <
int order,
int dim,
typename... ParameterSpaces>
348 const std::vector<const smith::FiniteElementState*>& states,
349 const std::vector<const smith::FiniteElementState*>& params)
359 std::vector<const mfem::ParFiniteElementSpace*> parameter_fe_spaces;
361 if constexpr (
sizeof...(ParameterSpaces) > 0) {
362 for_constexpr<
sizeof...(ParameterSpaces)>([&](
auto i) { parameter_fe_spaces.push_back(¶ms[i]->
space()); });
367 return std::make_shared<WeakFormT>(physics_name, mesh, states[DISP]->
space(), parameter_fe_spaces);
#define SMITH_HOST_DEVICE
Macro that evaluates to __host__ __device__ when compiling with nvcc or amdclang and does nothing on ...
Accelerator functionality.
std::vector< const mfem::ParFiniteElementSpace * > spaces(const std::vector< FieldState > &states, const std::vector< FieldState > ¶ms={})
Get the spaces from the primal fields of a vector of field states.
auto create_solid_weak_form(const std::string &physics_name, std::shared_ptr< smith::Mesh > mesh, const std::vector< const smith::FiniteElementState * > &states, const std::vector< const smith::FiniteElementState * > ¶ms)
Utility function for creating a shared_ptr<SolidWeakForm<>>
SMITH_HOST_DEVICE auto cross(const tensor< T, 3, 2 > &A)
compute the cross product of the columns of A: A(:,1) x A(:,2)
constexpr SMITH_HOST_DEVICE auto norm(const isotropic_tensor< T, m, m > &I)
compute the Frobenius norm (sqrt(tr(dot(transpose(I), I)))) of an isotropic tensor
std::shared_ptr< QuadratureData< Empty > > EmptyQData
a single instance of a QuadratureData container of Emptys, since they are all interchangeable
constexpr SMITH_HOST_DEVICE auto inner(const dual< S > &A, const dual< T > &B)
mfem::ParFiniteElementSpace & space(FieldState field)
Get the space from the primal field of a field states.
Compile-time alias for a dimension.
see Nothing for a complete description of this class and when to use it
a struct that is used in the physics modules to clarify which template arguments are user-controlled ...
A class for storing and access user-defined types at quadrature points.
This is a class that mimics most of std::tuple's interface, except that it is usable in CUDA kernels ...