PolyFEM
Loading...
Searching...
No Matches
IncompressibleLinElast.cpp
Go to the documentation of this file.
2
3namespace polyfem::assembler
4{
5 using namespace basis;
6
7 void IncompressibleLinearElasticityDispacement::add_multimaterial(const int index, const json &params, const Units &units)
8 {
9 assert(size() == 2 || size() == 3);
10
11 params_.add_multimaterial(index, params, size() == 3, units.stress());
12
13 // std::cout<<mu_<<std::endl;
14 // std::cout<<lambda_<<std::endl;
15 }
16
17 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 9, 1>
19 {
20 // 2mu (epsi : epsj)
21 assert(size() == 2 || size() == 3);
22
23 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 9, 1> res(size() * size());
24 res.setZero();
25
26 const Eigen::MatrixXd &gradi = data.vals.basis_values[data.i].grad_t_m;
27 const Eigen::MatrixXd &gradj = data.vals.basis_values[data.j].grad_t_m;
28
29 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> epsi(size(), size());
30 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> epsj(size(), size());
31
32 for (long p = 0; p < gradi.rows(); ++p)
33 {
34
35 double lambda, mu;
36 params_.lambda_mu(data.vals.quadrature.points.row(p), data.vals.val.row(p), data.t, data.vals.element_id, lambda, mu);
37
38 for (int di = 0; di < size(); ++di)
39 {
40 epsi.setZero();
41 epsi.row(di) = gradi.row(p);
42 epsi = ((epsi + epsi.transpose()) / 2).eval();
43 for (int dj = 0; dj < size(); ++dj)
44 {
45 epsj.setZero();
46 epsj.row(dj) = gradj.row(p);
47 epsj = ((epsj + epsj.transpose()) / 2.0).eval();
48
49 res(dj * size() + di) += 2 * mu * (epsi.array() * epsj.array()).sum() * data.da(p);
50 }
51 }
52 }
53
54 return res;
55 }
56
58 const int all_size,
59 const ElasticityTensorType &type,
60 Eigen::MatrixXd &all,
61 const std::function<Eigen::MatrixXd(const Eigen::MatrixXd &)> &fun) const
62 {
63 const auto &displacement = data.fun;
64 const auto &local_pts = data.local_pts;
65 const auto &bs = data.bs;
66 const auto &gbs = data.gbs;
67 const auto el_id = data.el_id;
68
69 assert(size() == 2 || size() == 3);
70 all.resize(local_pts.rows(), all_size);
71 assert(displacement.cols() == 1);
72
73 Eigen::MatrixXd displacement_grad(size(), size());
74
76 vals.compute(el_id, size() == 3, local_pts, bs, gbs);
77
78 for (long p = 0; p < local_pts.rows(); ++p)
79 {
80 compute_diplacement_grad(size(), bs, vals, local_pts, p, displacement, displacement_grad);
81
82 if (type == ElasticityTensorType::F)
83 {
84 all.row(p) = fun(displacement_grad + Eigen::MatrixXd::Identity(size(), size()));
85 continue;
86 }
87
88 double lambda, mu;
89 params_.lambda_mu(local_pts.row(p), vals.val.row(p), data.t, vals.element_id, lambda, mu);
90
91 const Eigen::MatrixXd strain = (displacement_grad + displacement_grad.transpose()) / 2;
92 Eigen::MatrixXd stress = 2 * mu * strain + lambda * strain.trace() * Eigen::MatrixXd::Identity(size(), size());
93
94 if (type == ElasticityTensorType::PK1)
95 stress = pk1_from_cauchy(stress, displacement_grad + Eigen::MatrixXd::Identity(size(), size()));
96 else if (type == ElasticityTensorType::PK2)
97 stress = pk2_from_cauchy(stress, displacement_grad + Eigen::MatrixXd::Identity(size(), size()));
98
99 all.row(p) = fun(stress);
100 }
101 }
102
103 std::map<std::string, Assembler::ParamFunc> IncompressibleLinearElasticityDispacement::parameters() const
104 {
105 std::map<std::string, ParamFunc> res;
106 const auto &params = params_;
107 const int size = this->size();
108
109 res["lambda"] = [&params](const RowVectorNd &uv, const RowVectorNd &p, double t, int e) {
110 double lambda, mu;
111
112 params.lambda_mu(uv, p, t, e, lambda, mu);
113 return lambda;
114 };
115
116 res["mu"] = [&params](const RowVectorNd &uv, const RowVectorNd &p, double t, int e) {
117 double lambda, mu;
118
119 params.lambda_mu(uv, p, t, e, lambda, mu);
120 return mu;
121 };
122
123 res["E"] = [&params, size](const RowVectorNd &uv, const RowVectorNd &p, double t, int e) {
124 double lambda, mu;
125 params.lambda_mu(uv, p, t, e, lambda, mu);
126
127 if (size == 3)
128 return mu * (3.0 * lambda + 2.0 * mu) / (lambda + mu);
129 else
130 return 2 * mu * (2.0 * lambda + 2.0 * mu) / (lambda + 2.0 * mu);
131 };
132
133 res["nu"] = [&params, size](const RowVectorNd &uv, const RowVectorNd &p, double t, int e) {
134 double lambda, mu;
135
136 params.lambda_mu(uv, p, t, e, lambda, mu);
137
138 if (size == 3)
139 return lambda / (2.0 * (lambda + mu));
140 else
141 return lambda / (lambda + 2.0 * mu);
142 };
143
144 return res;
145 }
146
147 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1>
149 {
150 // (psii : div phij) = -psii * gradphij
151 assert(size() == 2 || size() == 3);
152 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> res(rows() * cols());
153 res.setZero();
154
155 const Eigen::MatrixXd &psii = data.psi_vals.basis_values[data.i].val;
156 const Eigen::MatrixXd &gradphij = data.phi_vals.basis_values[data.j].grad_t_m;
157 assert(psii.size() == gradphij.rows());
158 assert(gradphij.cols() == rows());
159
160 for (int k = 0; k < gradphij.rows(); ++k)
161 {
162 res -= psii(k) * gradphij.row(k) * data.da(k);
163 }
164
165 return res;
166 }
167
168 void IncompressibleLinearElasticityPressure::add_multimaterial(const int index, const json &params, const Units &units)
169 {
170 assert(disp_size_ == 2 || disp_size_ == 3);
171
172 params_.add_multimaterial(index, params, disp_size_ == 3, units.stress());
173 }
174
175 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 9, 1>
177 {
178 // -1/lambda phi_ * phi_j
179
180 const Eigen::MatrixXd &phii = data.vals.basis_values[data.i].val;
181 const Eigen::MatrixXd &phij = data.vals.basis_values[data.j].val;
182
183 double res = 0;
184
185 for (long p = 0; p < data.da.size(); ++p)
186 {
187 double lambda, mu;
188 params_.lambda_mu(data.vals.quadrature.points.row(p), data.vals.val.row(p), data.t, data.vals.element_id, lambda, mu);
189
190 res += -phii(p) * phij(p) * data.da(p) / lambda;
191 }
192
193 // double res = (phii.array() * phij.array() * da.array()).sum();
194 // res *= -1. / lambda;
195
196 return Eigen::Matrix<double, 1, 1>::Constant(res);
197 }
198} // namespace polyfem::assembler
ElementAssemblyValues vals
Definition Assembler.cpp:22
std::string stress() const
Definition Units.hpp:25
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,...
void add_multimaterial(const int index, const json &params, const Units &units) override
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 9, 1 > assemble(const LinearAssemblerData &data) const override
local assembly function that defines the bilinear form (LHS) computes and returns a single local stif...
std::map< std::string, ParamFunc > parameters() const override
void assign_stress_tensor(const OutputData &data, const int all_size, const ElasticityTensorType &type, Eigen::MatrixXd &all, const std::function< Eigen::MatrixXd(const Eigen::MatrixXd &)> &fun) const override
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 3, 1 > assemble(const MixedAssemblerData &data) const override
void add_multimaterial(const int index, const json &params, const Units &units) override
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 9, 1 > assemble(const LinearAssemblerData &data) const override
local assembly function that defines the bilinear form (LHS) computes and returns a single local stif...
void lambda_mu(double px, double py, double pz, double x, double y, double z, double t, int el_id, double &lambda, double &mu) const
void add_multimaterial(const int index, const json &params, const bool is_volume, const std::string &stress_unit)
const ElementAssemblyValues & vals
stores the evaluation for that element
const QuadratureVector & da
contains both the quadrature weight and the change of metric in the integral
const QuadratureVector & da
contains both the quadrature weight and the change of metric in the integral
const ElementAssemblyValues & phi_vals
stores the evaluation for that element
const ElementAssemblyValues & psi_vals
stores the evaluation for that element
const basis::ElementBases & bs
const Eigen::MatrixXd & fun
const Eigen::MatrixXd & local_pts
const basis::ElementBases & gbs
Used for test only.
Eigen::MatrixXd pk2_from_cauchy(const Eigen::MatrixXd &stress, const Eigen::MatrixXd &F)
nlohmann::json json
Definition Common.hpp:9
void compute_diplacement_grad(const int size, const ElementAssemblyValues &vals, const Eigen::MatrixXd &local_pts, const int p, const Eigen::MatrixXd &displacement, Eigen::MatrixXd &displacement_grad)
Eigen::MatrixXd pk1_from_cauchy(const Eigen::MatrixXd &stress, const Eigen::MatrixXd &F)
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd
Definition Types.hpp:13