11 using namespace basis;
15 bool delta(
int i,
int j)
17 return (i == j) ? true :
false;
30 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 9, 1>
37 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 9, 1> res(
size() *
size());
40 for (
long k = 0; k < gradi.rows(); ++k)
42 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 9, 1> res_k(
size() *
size());
44 const Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> outer = gradi.row(k).transpose() * gradj.row(k);
45 const double dot = gradi.row(k).dot(gradj.row(k));
50 for (
int ii = 0; ii <
size(); ++ii)
52 for (
int jj = 0; jj <
size(); ++jj)
54 res_k(jj *
size() + ii) = outer(ii *
size() + jj) * mu + outer(jj *
size() + ii) * lambda;
56 res_k(jj *
size() + ii) += mu * dot;
59 res += res_k * data.
da(k);
67 return compute_energy_aux<double>(data);
74 size(), n_bases, data,
75 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 6, 1>>>(data); },
76 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 8, 1>>>(data); },
77 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 12, 1>>>(data); },
78 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 18, 1>>>(data); },
79 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 24, 1>>>(data); },
80 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 30, 1>>>(data); },
81 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 60, 1>>>(data); },
82 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 81, 1>>>(data); },
83 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, SMALL_N, 1>>>(data); },
84 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, BIG_N, 1>>>(data); },
85 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar1<double, Eigen::VectorXd>>(data); });
92 size(), n_bases, data,
93 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 6, 1>, Eigen::Matrix<double, 6, 6>>>(data); },
94 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 8, 1>, Eigen::Matrix<double, 8, 8>>>(data); },
95 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 12, 1>, Eigen::Matrix<double, 12, 12>>>(data); },
96 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 18, 1>, Eigen::Matrix<double, 18, 18>>>(data); },
97 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 24, 1>, Eigen::Matrix<double, 24, 24>>>(data); },
98 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 30, 1>, Eigen::Matrix<double, 30, 30>>>(data); },
99 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 60, 1>, Eigen::Matrix<double, 60, 60>>>(data); },
100 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 81, 1>, Eigen::Matrix<double, 81, 81>>>(data); },
101 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, SMALL_N, 1>, Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, SMALL_N, SMALL_N>>>(data); },
102 [&](
const NonLinearAssemblerData &data) {
return compute_energy_aux<DScalar2<double, Eigen::VectorXd, Eigen::MatrixXd>>(data); });
106 template <
typename T>
109 typedef Eigen::Matrix<T, Eigen::Dynamic, 1>
AutoDiffVect;
110 typedef Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3>
AutoDiffGradMat;
119 const int n_pts = data.
da.size();
120 for (
long p = 0; p < n_pts; ++p)
124 const AutoDiffGradMat strain = (disp_grad + disp_grad.transpose()) / T(2);
129 const T
val = mu * (strain.transpose() * strain).trace() + lambda / 2 * strain.trace() * strain.trace();
131 energy +=
val * data.
da(p);
136 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1>
139 assert(pt.size() ==
size());
140 Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> res(
size());
144 params_.
lambda_mu(0, 0, 0, pt(0).getValue(), pt(1).getValue(),
size() == 2 ? 0. : pt(2).getValue(), 0, 0, lambda, mu);
148 else if (
size() == 3)
158 const Eigen::MatrixXd &local_pts,
159 const Eigen::MatrixXd &displacement,
160 Eigen::MatrixXd &tensor)
const
163 assert(displacement.cols() == 1);
165 for (
long p = 0; p < local_pts.rows(); ++p)
170 for (
int i = 0, idx = 0; i <
size(); i++)
171 for (
int j = 0; j <
size(); j++)
172 for (
int k = 0; k <
size(); k++)
173 for (
int l = 0; l <
size(); l++)
174 tensor(p, idx++) = mu * delta(i, k) * delta(j, l) + mu * delta(i, l) * delta(j, k) + lambda * delta(i, j) * delta(k, l);
182 Eigen::MatrixXd &all,
183 const std::function<Eigen::MatrixXd(
const Eigen::MatrixXd &)> &fun)
const
185 const auto &displacement = data.
fun;
187 const auto &bs = data.
bs;
188 const auto &gbs = data.
gbs;
189 const auto el_id = data.
el_id;
190 const auto t = data.
t;
192 all.resize(local_pts.rows(), all_size);
193 assert(displacement.cols() == 1);
195 Eigen::MatrixXd displacement_grad(
size(),
size());
200 for (
long p = 0; p < local_pts.rows(); ++p)
206 all.row(p) = fun(displacement_grad + Eigen::MatrixXd::Identity(
size(),
size()));
213 const Eigen::MatrixXd strain = (displacement_grad + displacement_grad.transpose()) / 2;
214 Eigen::MatrixXd stress = 2 * mu * strain + lambda * strain.trace() * Eigen::MatrixXd::Identity(
size(),
size());
220 all.row(p) = fun(stress);
226 Eigen::Matrix<AutodiffScalarGrad, Eigen::Dynamic, 1, 0, 3, 1> res(dim);
227 assert(r.size() == dim);
229 double mu, nu, lambda;
234 nu = lambda / (lambda * (dim - 1) + 2 * mu);
238 res(0) = 1. / (8 * M_PI * mu * (1 - nu)) * ((3 - 4 * nu) * log(1. / r.norm()) + r(0) * r(0) / r.squaredNorm());
239 res(1) = 1. / (8 * M_PI * mu * (1 - nu)) * r(0) * r(1) / r.squaredNorm();
243 res(0) = 1. / (16 * M_PI * mu * (1 - nu)) * ((3 - 4 * nu) / r.norm() + r(0) * r(0) / r.norm() / r.squaredNorm());
244 res(1) = 1. / (16 * M_PI * mu * (1 - nu)) * r(0) * r(1) / r.norm() / r.squaredNorm();
245 res(2) = 1. / (16 * M_PI * mu * (1 - nu)) * r(0) * r(2) / r.norm() / r.squaredNorm();
255 const Eigen::MatrixXd &mat,
256 Eigen::MatrixXd &stress,
257 Eigen::MatrixXd &result)
const
259 const double t = data.
t;
260 const int el_id = data.
el_id;
261 const Eigen::MatrixXd &local_pts = data.
local_pts;
262 const Eigen::MatrixXd &global_pts = data.
global_pts;
263 const Eigen::MatrixXd &grad_u_i = data.
grad_u_i;
268 stress = mu * (grad_u_i + grad_u_i.transpose()) + lambda * grad_u_i.trace() * Eigen::MatrixXd::Identity(
size(),
size());
269 result = mu * (mat + mat.transpose()) + lambda * mat.trace() * Eigen::MatrixXd::Identity(
size(),
size());
274 Eigen::MatrixXd &stress,
275 Eigen::MatrixXd &result)
const
277 const double t = data.
t;
278 const int el_id = data.
el_id;
279 const Eigen::MatrixXd &local_pts = data.
local_pts;
280 const Eigen::MatrixXd &global_pts = data.
global_pts;
281 const Eigen::MatrixXd &grad_u_i = data.
grad_u_i;
286 stress = mu * (grad_u_i + grad_u_i.transpose()) + lambda * grad_u_i.trace() * Eigen::MatrixXd::Identity(
size(),
size());
287 result = mu * (stress + stress.transpose()) + lambda * stress.trace() * Eigen::MatrixXd::Identity(
size(),
size());
292 Eigen::MatrixXd &dstress_dmu,
293 Eigen::MatrixXd &dstress_dlambda)
const
295 const Eigen::MatrixXd &grad_u_i = data.
grad_u_i;
297 dstress_dmu = grad_u_i.transpose() + grad_u_i;
298 dstress_dlambda = grad_u_i.trace() * Eigen::MatrixXd::Identity(grad_u_i.rows(), grad_u_i.cols());
303 std::map<std::string, ParamFunc> res;
310 params.lambda_mu(uv, p, t, e, lambda, mu);
317 params.lambda_mu(uv, p, t, e, lambda, mu);
323 params.lambda_mu(uv, p, t, e, lambda, mu);
326 return mu * (3.0 * lambda + 2.0 * mu) / (lambda + mu);
328 return 2 * mu * (2.0 * lambda + 2.0 * mu) / (lambda + 2.0 * mu);
334 params.lambda_mu(uv, p, t, e, lambda, mu);
337 return lambda / (2.0 * (lambda + mu));
339 return lambda / (lambda + 2.0 * mu);
ElementAssemblyValues vals
std::string stress() const
stores per element basis values at given quadrature points and geometric mapping
std::vector< AssemblyValues > basis_values
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,...
quadrature::Quadrature quadrature
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 ¶ms, 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 int i
first local order
const int j
second local order
void compute_stress_grad_multiply_stress(const OptAssemblerData &data, Eigen::MatrixXd &stress, Eigen::MatrixXd &result) const override
Eigen::Matrix< AutodiffScalarGrad, Eigen::Dynamic, 1, 0, 3, 1 > kernel(const int dim, const AutodiffGradPt &r, const AutodiffScalarGrad &) const override
std::map< std::string, ParamFunc > parameters() const override
VectorNd compute_rhs(const AutodiffHessianPt &pt) const override
void add_multimaterial(const int index, const json ¶ms, const Units &units) override
void compute_dstress_dmu_dlambda(const OptAssemblerData &data, Eigen::MatrixXd &dstress_dmu, Eigen::MatrixXd &dstress_dlambda) const override
Eigen::VectorXd assemble_gradient(const NonLinearAssemblerData &data) 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
const LameParameters & lame_params() const
Eigen::MatrixXd assemble_hessian(const NonLinearAssemblerData &data) const override
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 9, 1 > assemble(const LinearAssemblerData &data) const override
computes local stiffness matrix is R^{dimĀ²} for bases i,j
double compute_energy(const NonLinearAssemblerData &data) const override
T compute_energy_aux(const NonLinearAssemblerData &data) const
void compute_stress_grad_multiply_mat(const OptAssemblerData &data, const Eigen::MatrixXd &mat, Eigen::MatrixXd &stress, Eigen::MatrixXd &result) const override
void compute_stiffness_value(const double t, const assembler::ElementAssemblyValues &vals, const Eigen::MatrixXd &local_pts, const Eigen::MatrixXd &displacement, Eigen::MatrixXd &tensor) const override
const ElementAssemblyValues & vals
const QuadratureVector & da
const Eigen::MatrixXd & local_pts
const Eigen::MatrixXd & global_pts
const Eigen::MatrixXd & grad_u_i
const basis::ElementBases & bs
const Eigen::MatrixXd & fun
const Eigen::MatrixXd & local_pts
const basis::ElementBases & gbs
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3 > AutoDiffGradMat
Eigen::Matrix< T, Eigen::Dynamic, 1 > AutoDiffVect
void linear_elasticity_3d_function(const AutodiffHessianPt &pt, const double lambda, const double mu, Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 3, 1 > &res)
void linear_elasticity_2d_function(const AutodiffHessianPt &pt, const double lambda, const double mu, Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 3, 1 > &res)
Eigen::MatrixXd pk2_from_cauchy(const Eigen::MatrixXd &stress, const Eigen::MatrixXd &F)
void compute_disp_grad_at_quad(const assembler::NonLinearAssemblerData &data, const AutoDiffVect &local_disp, const int p, const int size, AutoDiffGradMat &def_grad)
Eigen::Matrix< AutodiffScalarHessian, Eigen::Dynamic, 1, 0, 3, 1 > AutodiffHessianPt
Eigen::MatrixXd hessian_from_energy(const int size, const int n_bases, const assembler::NonLinearAssemblerData &data, const std::function< DScalar2< double, Eigen::Matrix< double, 6, 1 >, Eigen::Matrix< double, 6, 6 > >(const assembler::NonLinearAssemblerData &)> &fun6, const std::function< DScalar2< double, Eigen::Matrix< double, 8, 1 >, Eigen::Matrix< double, 8, 8 > >(const assembler::NonLinearAssemblerData &)> &fun8, const std::function< DScalar2< double, Eigen::Matrix< double, 12, 1 >, Eigen::Matrix< double, 12, 12 > >(const assembler::NonLinearAssemblerData &)> &fun12, const std::function< DScalar2< double, Eigen::Matrix< double, 18, 1 >, Eigen::Matrix< double, 18, 18 > >(const assembler::NonLinearAssemblerData &)> &fun18, const std::function< DScalar2< double, Eigen::Matrix< double, 24, 1 >, Eigen::Matrix< double, 24, 24 > >(const assembler::NonLinearAssemblerData &)> &fun24, const std::function< DScalar2< double, Eigen::Matrix< double, 30, 1 >, Eigen::Matrix< double, 30, 30 > >(const assembler::NonLinearAssemblerData &)> &fun30, const std::function< DScalar2< double, Eigen::Matrix< double, 60, 1 >, Eigen::Matrix< double, 60, 60 > >(const assembler::NonLinearAssemblerData &)> &fun60, const std::function< DScalar2< double, Eigen::Matrix< double, 81, 1 >, Eigen::Matrix< double, 81, 81 > >(const assembler::NonLinearAssemblerData &)> &fun81, const std::function< DScalar2< double, Eigen::Matrix< double, Eigen::Dynamic, 1, 0, SMALL_N, 1 >, Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, SMALL_N, SMALL_N > >(const assembler::NonLinearAssemblerData &)> &funN, const std::function< DScalar2< double, Eigen::VectorXd, Eigen::MatrixXd >(const assembler::NonLinearAssemblerData &)> &funn)
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)
void get_local_disp(const assembler::NonLinearAssemblerData &data, const int size, AutoDiffVect &local_disp)
Eigen::MatrixXd pk1_from_cauchy(const Eigen::MatrixXd &stress, const Eigen::MatrixXd &F)
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd
Eigen::VectorXd gradient_from_energy(const int size, const int n_bases, const assembler::NonLinearAssemblerData &data, const std::function< DScalar1< double, Eigen::Matrix< double, 6, 1 > >(const assembler::NonLinearAssemblerData &)> &fun6, const std::function< DScalar1< double, Eigen::Matrix< double, 8, 1 > >(const assembler::NonLinearAssemblerData &)> &fun8, const std::function< DScalar1< double, Eigen::Matrix< double, 12, 1 > >(const assembler::NonLinearAssemblerData &)> &fun12, const std::function< DScalar1< double, Eigen::Matrix< double, 18, 1 > >(const assembler::NonLinearAssemblerData &)> &fun18, const std::function< DScalar1< double, Eigen::Matrix< double, 24, 1 > >(const assembler::NonLinearAssemblerData &)> &fun24, const std::function< DScalar1< double, Eigen::Matrix< double, 30, 1 > >(const assembler::NonLinearAssemblerData &)> &fun30, const std::function< DScalar1< double, Eigen::Matrix< double, 60, 1 > >(const assembler::NonLinearAssemblerData &)> &fun60, const std::function< DScalar1< double, Eigen::Matrix< double, 81, 1 > >(const assembler::NonLinearAssemblerData &)> &fun81, const std::function< DScalar1< double, Eigen::Matrix< double, Eigen::Dynamic, 1, 0, SMALL_N, 1 > >(const assembler::NonLinearAssemblerData &)> &funN, const std::function< DScalar1< double, Eigen::Matrix< double, Eigen::Dynamic, 1, 0, BIG_N, 1 > >(const assembler::NonLinearAssemblerData &)> &funBigN, const std::function< DScalar1< double, Eigen::VectorXd >(const assembler::NonLinearAssemblerData &)> &funn)
Eigen::Matrix< AutodiffScalarGrad, Eigen::Dynamic, 1, 0, 3, 1 > AutodiffGradPt
Automatic differentiation scalar with first-order derivatives.