PolyFEM
Loading...
Searching...
No Matches
InertiaForm.cpp
Go to the documentation of this file.
1#include "InertiaForm.hpp"
2
4
7
11
12namespace polyfem::solver
13{
14 namespace
15 {
16
17 class LocalThreadVecStorage
18 {
19 public:
20 Eigen::MatrixXd vec;
21 assembler::ElementAssemblyValues vals;
23
24 LocalThreadVecStorage(const int size)
25 {
26 vec.resize(size, 1);
27 vec.setZero();
28 }
29 };
30
31 double dot(const Eigen::MatrixXd &A, const Eigen::MatrixXd &B) { return (A.array() * B.array()).sum(); }
32 } // namespace
33
35 const time_integrator::ImplicitTimeIntegrator &time_integrator)
36 : mass_(mass), time_integrator_(time_integrator)
37 {
38 assert(mass.size() != 0);
39 }
40
41 double InertiaForm::value_unweighted(const Eigen::VectorXd &x) const
42 {
43 const Eigen::VectorXd tmp = x - time_integrator_.x_tilde();
44 // FIXME: DBC on x tilde
45 const double prod = tmp.transpose() * mass_ * tmp;
46 const double energy = 0.5 * prod;
47 return energy;
48 }
49
50 void InertiaForm::first_derivative_unweighted(const Eigen::VectorXd &x, Eigen::VectorXd &gradv) const
51 {
52 gradv = mass_ * (x - time_integrator_.x_tilde());
53 }
54
55 void InertiaForm::second_derivative_unweighted(const Eigen::VectorXd &x, StiffnessMatrix &hessian) const
56 {
57 hessian = mass_;
58 }
59
61 bool is_volume,
62 const int n_geom_bases,
63 const double t,
64 const std::vector<basis::ElementBases> &bases,
65 const std::vector<basis::ElementBases> &geom_bases,
66 const assembler::Mass &assembler,
67 const assembler::AssemblyValsCache &ass_vals_cache,
68 const Eigen::MatrixXd &velocity,
69 const Eigen::MatrixXd &adjoint,
70 Eigen::VectorXd &term)
71 {
72 const int dim = is_volume ? 3 : 2;
73 const int n_elements = int(bases.size());
74 term.setZero(n_geom_bases * dim, 1);
75
76 auto storage = utils::create_thread_storage(LocalThreadVecStorage(term.size()));
77
78 utils::maybe_parallel_for(n_elements, [&](int start, int end, int thread_id) {
79 LocalThreadVecStorage &local_storage = utils::get_local_thread_storage(storage, thread_id);
80
81 for (int e = start; e < end; ++e)
82 {
83 assembler::ElementAssemblyValues &vals = local_storage.vals;
84 ass_vals_cache.compute(e, is_volume, bases[e], geom_bases[e], vals);
86 gvals.compute(e, is_volume, vals.quadrature.points, geom_bases[e], geom_bases[e]);
87
88 const quadrature::Quadrature &quadrature = vals.quadrature;
89 local_storage.da = vals.det.array() * quadrature.weights.array();
90
91 Eigen::MatrixXd vel, grad_vel, p, grad_p;
92 io::Evaluator::interpolate_at_local_vals(e, dim, dim, vals, adjoint, p, grad_p);
93 io::Evaluator::interpolate_at_local_vals(e, dim, dim, vals, velocity, vel, grad_vel);
94
95 for (int q = 0; q < local_storage.da.size(); ++q)
96 {
97 const double rho = assembler.density()(quadrature.points.row(q), vals.val.row(q), t, e);
98 const double value = rho * dot(p.row(q), vel.row(q)) * local_storage.da(q);
99 for (const auto &v : gvals.basis_values)
100 {
101 local_storage.vec.block(v.global[0].index * dim, 0, dim, 1) += v.grad_t_m.row(q).transpose() * value;
102 }
103 }
104 }
105 });
106
107 for (const LocalThreadVecStorage &local_storage : storage)
108 term += local_storage.vec;
109 }
110} // namespace polyfem::solver
Eigen::MatrixXd vec
Definition Assembler.cpp:72
QuadratureVector da
Definition Assembler.cpp:23
ElementAssemblyValues vals
Definition Assembler.cpp:22
assembler::ElementAssemblyValues gvals
Definition BodyForm.cpp:25
Quadrature quadrature
int x
Caches basis evaluation and geometric mapping at every element.
void compute(const int el_index, const bool is_volume, const basis::ElementBases &basis, const basis::ElementBases &gbasis, ElementAssemblyValues &vals) const
retrieves cached basis evaluation and geometric for the given element if it doesn't exist,...
stores per element basis values at given quadrature points and geometric mapping
void compute(const int el_index, const bool is_volume, const Eigen::MatrixXd &pts, const basis::ElementBases &basis, const basis::ElementBases &gbasis)
computes the per element values at the local (ref el) points (pts) sets basis_values,...
const Density & density() const
class that stores and compute density per point
Definition Mass.hpp:29
static void interpolate_at_local_vals(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const int el_index, const Eigen::MatrixXd &local_pts, const Eigen::MatrixXd &fun, Eigen::MatrixXd &result, Eigen::MatrixXd &result_grad)
interpolate solution and gradient at element (calls interpolate_at_local_vals with sol)
virtual double value(const Eigen::VectorXd &x) const
Compute the value of the form multiplied with the weigth.
Definition Form.hpp:24
double value_unweighted(const Eigen::VectorXd &x) const override
Compute the value of the form.
void first_derivative_unweighted(const Eigen::VectorXd &x, Eigen::VectorXd &gradv) const override
Compute the first derivative of the value wrt x.
void second_derivative_unweighted(const Eigen::VectorXd &x, StiffnessMatrix &hessian) const override
Compute the second derivative of the value wrt x.
static void force_shape_derivative(bool is_volume, const int n_geom_bases, const double t, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &geom_bases, const assembler::Mass &assembler, const assembler::AssemblyValsCache &ass_vals_cache, const Eigen::MatrixXd &velocity, const Eigen::MatrixXd &adjoint, Eigen::VectorXd &term)
InertiaForm(const StiffnessMatrix &mass, const time_integrator::ImplicitTimeIntegrator &time_integrator)
Construct a new Inertia Form object.
const time_integrator::ImplicitTimeIntegrator & time_integrator_
Time integrator.
const StiffnessMatrix & mass_
Mass matrix.
Implicit time integrator of a second order ODE (equivently a system of coupled first order ODEs).
virtual Eigen::VectorXd x_tilde() const =0
Compute the predicted solution to be used in the inertia term .
auto & get_local_thread_storage(Storages &storage, int thread_id)
auto create_thread_storage(const LocalStorage &initial_local_storage)
void maybe_parallel_for(int size, const std::function< void(int, int, int)> &partial_for)
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, MAX_QUAD_POINTS, 1 > QuadratureVector
Definition Types.hpp:15
Eigen::SparseMatrix< double, Eigen::ColMajor > StiffnessMatrix
Definition Types.hpp:20