13 #include "smith/smith_config.hpp"
15 #ifdef SMITH_USE_ENZYME
30 class LumpedMassExplicitNewmark {
32 LumpedMassExplicitNewmark(
const std::shared_ptr<WeakForm>& weak_form,
const std::shared_ptr<WeakForm>& mass_weak_form,
33 std::shared_ptr<BoundaryConditionManager> bc_manager)
34 : weak_form_(weak_form), mass_weak_form_(mass_weak_form), bc_manager_(bc_manager)
38 std::tuple<std::vector<FiniteElementState>,
double> advanceState(
const std::vector<ConstFieldPtr>& states,
39 const std::vector<ConstFieldPtr>& params,
40 double time,
double dt)
42 SLIC_ERROR_ROOT_IF(states.size() != 4,
"Expected 4 states: displacement, velocity, acceleration, and coordinates");
57 const auto& u = *states[DISPLACEMENT];
58 const auto& v = *states[VELOCITY];
59 const auto& a = *states[ACCELERATION];
62 v_pred.Add(0.5 * dt, a);
64 u_pred.Add(dt, v_pred);
67 u_pred.SetSubVector(bc_manager_->allEssentialTrueDofs(), 0.0);
70 TimeInfo time_info(time, dt);
72 auto m_inv = mass_weak_form_->residual(time_info, &u, {states[COORDINATES], params[DENSITY]});
75 std::vector<ConstFieldPtr> pred_states = {&u_pred, &v_pred, &a, states[COORDINATES], params[DENSITY]};
77 auto force_resid = weak_form_->residual(time_info, &u_pred, pred_states);
79 FiniteElementState a_pred(a.space(),
"acceleration_pred");
80 auto a_pred_ptr = a_pred.Write();
81 auto m_inv_ptr = m_inv.Read();
82 auto force_resid_ptr = force_resid.Read();
83 mfem::forall_switch(a_pred.UseDevice(), a_pred.Size(),
84 [=] MFEM_HOST_DEVICE(
int i) { a_pred_ptr[i] = m_inv_ptr[i] * force_resid_ptr[i]; });
86 v_pred.Add(0.5 * dt, a_pred);
88 return {{u_pred, v_pred, a_pred, *states[COORDINATES]}, time + dt};
92 std::shared_ptr<WeakForm> weak_form_;
93 std::shared_ptr<WeakForm> mass_weak_form_;
94 std::shared_ptr<BoundaryConditionManager> bc_manager_;
97 template <
int MassDim,
int SpatialDim>
98 auto create_solid_mass_weak_form(
const std::string& physics_name, std::shared_ptr<smith::Mesh>& mesh,
99 const FiniteElementState& lumped_field,
const FiniteElementState& density,
100 const mfem::IntegrationRule& ir)
109 auto residual = std::make_shared<DfemWeakForm>(
110 physics_name, mesh, lumped_field.space(),
111 DfemWeakForm::SpacesT{static_cast<mfem::ParFiniteElementSpace*>(mesh->mfemParMesh().GetNodes()->FESpace()),
114 mfem::future::tuple<mfem::future::Gradient<COORDINATES>, mfem::future::Weight, mfem::future::Value<DENSITY>>
115 mass_integral_inputs{};
116 mfem::future::tuple<mfem::future::Value<TEST>> mass_integral_outputs{};
118 residual->addBodyIntegral(
119 mesh->mfemParMesh().attributes,
120 [](mfem::future::tensor<mfem::real_t, SpatialDim, SpatialDim> dX_dxi, mfem::real_t weight,
double rho) {
121 auto ones = mfem::future::make_tensor<MassDim>([](int) { return 1.0; });
125 mass_integral_inputs, mass_integral_outputs, ir, std::index_sequence<>{});
This file contains the declaration of the boundary condition manager class.
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.
tuple(T...) -> tuple< T... >
Class template argument deduction rule for tuples.
constexpr SMITH_HOST_DEVICE auto det(const isotropic_tensor< T, m, m > &I)
compute the determinant of an isotropic tensor