9 : c1_(
"c1"), c2_(
"c2"), c3_(
"c3"), d1_(
"d1")
16 Eigen::Matrix<double, Eigen::Dynamic, 1> gradient;
25 compute_energy_aux_gradient_fast<3, 2>(data, gradient);
31 compute_energy_aux_gradient_fast<6, 2>(data, gradient);
37 compute_energy_aux_gradient_fast<10, 2>(data, gradient);
43 compute_energy_aux_gradient_fast<Eigen::Dynamic, 2>(data, gradient);
56 compute_energy_aux_gradient_fast<4, 3>(data, gradient);
62 compute_energy_aux_gradient_fast<10, 3>(data, gradient);
68 compute_energy_aux_gradient_fast<20, 3>(data, gradient);
74 compute_energy_aux_gradient_fast<Eigen::Dynamic, 3>(data, gradient);
86 Eigen::MatrixXd hessian;
96 compute_energy_hessian_aux_fast<3, 2>(data, hessian);
101 hessian.resize(12, 12);
103 compute_energy_hessian_aux_fast<6, 2>(data, hessian);
108 hessian.resize(20, 20);
110 compute_energy_hessian_aux_fast<10, 2>(data, hessian);
117 compute_energy_hessian_aux_fast<Eigen::Dynamic, 2>(data, hessian);
129 hessian.resize(12, 12);
131 compute_energy_hessian_aux_fast<4, 3>(data, hessian);
136 hessian.resize(30, 30);
138 compute_energy_hessian_aux_fast<10, 3>(data, hessian);
143 hessian.resize(60, 60);
145 compute_energy_hessian_aux_fast<20, 3>(data, hessian);
152 compute_energy_hessian_aux_fast<Eigen::Dynamic, 3>(data, hessian);
164 Eigen::MatrixXd &all,
165 const std::function<Eigen::MatrixXd(
const Eigen::MatrixXd &)> &fun)
const
167 const auto &displacement = data.
fun;
169 const auto &bs = data.
bs;
170 const auto &gbs = data.
gbs;
171 const auto el_id = data.
el_id;
172 const auto t = data.
t;
174 Eigen::MatrixXd displacement_grad(
size(),
size());
176 assert(displacement.cols() == 1);
178 all.resize(local_pts.rows(), all_size);
182 const auto I = Eigen::MatrixXd::Identity(
size(),
size());
184 for (
long p = 0; p < local_pts.rows(); ++p)
188 const Eigen::MatrixXd def_grad = I + displacement_grad;
189 const Eigen::MatrixXd def_grad_T = def_grad.transpose();
192 all.row(p) = fun(def_grad);
197 const double c1 =
c1_(local_pts.row(p), t,
vals.element_id);
198 const double c2 =
c2_(local_pts.row(p), t,
vals.element_id);
199 const double c3 =
c3_(local_pts.row(p), t,
vals.element_id);
200 const double d1 =
d1_(local_pts.row(p), t,
vals.element_id);
202 Eigen::MatrixXd stress_tensor;
205 stress_tensor = 1.0 / def_grad.determinant() * stress_tensor * def_grad.transpose();
211 all.row(p) = fun(stress_tensor);
217 const Eigen::MatrixXd &mat,
218 Eigen::MatrixXd &stress,
219 Eigen::MatrixXd &result)
const
221 const double t = data.
t;
222 const int el_id = data.
el_id;
223 const Eigen::MatrixXd &local_pts = data.
local_pts;
224 const Eigen::MatrixXd &global_pts = data.
global_pts;
225 const Eigen::MatrixXd &grad_u_i = data.
grad_u_i;
227 Eigen::MatrixXd
F = grad_u_i;
228 for (
int d = 0; d <
size(); ++d)
230 Eigen::MatrixXd F_T =
F.transpose();
232 const double c1 =
c1_(global_pts, t, el_id);
233 const double c2 =
c2_(global_pts, t, el_id);
234 const double c3 =
c3_(global_pts, t, el_id);
235 const double d1 =
d1_(global_pts, t, el_id);
237 Eigen::MatrixXd grad, hess;
244 result = (hess * mat.reshaped(
size() *
size(), 1)).reshaped(
size(),
size());
249 Eigen::MatrixXd &stress,
250 Eigen::MatrixXd &result)
const
252 const double t = data.
t;
253 const int el_id = data.
el_id;
254 const Eigen::MatrixXd &local_pts = data.
local_pts;
255 const Eigen::MatrixXd &global_pts = data.
global_pts;
256 const Eigen::MatrixXd &grad_u_i = data.
grad_u_i;
258 Eigen::MatrixXd
F = grad_u_i;
259 for (
int d = 0; d <
size(); ++d)
262 const double c1 =
c1_(global_pts, t, el_id);
263 const double c2 =
c2_(global_pts, t, el_id);
264 const double c3 =
c3_(global_pts, t, el_id);
265 const double d1 =
d1_(global_pts, t, el_id);
267 Eigen::MatrixXd grad, hess;
274 result = (hess * stress.reshaped(
size() *
size(), 1)).reshaped(
size(),
size());
279 const Eigen::MatrixXd &vect,
280 Eigen::MatrixXd &stress,
281 Eigen::MatrixXd &result)
const
284 const double t = data.
t;
285 const int el_id = data.
el_id;
286 const Eigen::MatrixXd &local_pts = data.
local_pts;
287 const Eigen::MatrixXd &global_pts = data.
global_pts;
288 const Eigen::MatrixXd &grad_u_i = data.
grad_u_i;
290 Eigen::MatrixXd
F = grad_u_i;
291 for (
int d = 0; d <
size(); ++d)
293 Eigen::MatrixXd F_T =
F.transpose();
295 const double c1 =
c1_(global_pts, t, el_id);
296 const double c2 =
c2_(global_pts, t, el_id);
297 const double c3 =
c3_(global_pts, t, el_id);
298 const double d1 =
d1_(global_pts, t, el_id);
300 Eigen::MatrixXd grad, hess;
306 result.resize(hess.rows(), vect.size());
307 for (
int i = 0; i < hess.rows(); ++i)
308 if (vect.rows() == 1)
310 result.row(i) = vect * hess.row(i).reshaped(
size(),
size());
313 result.row(i) = hess.row(i).reshaped(
size(),
size()) * vect;
316 template <
typename T>
324 const double c1 =
c1_(p, t, el_id);
325 const double c2 =
c2_(p, t, el_id);
326 const double c3 =
c3_(p, t, el_id);
327 const double d1 =
d1_(p, t, el_id);
330 const T log_J = log(J);
331 const auto F_tilde = def_grad;
332 const auto right_cauchy_green = F_tilde * F_tilde.transpose();
337 const T
val =
c1 * (I1_tilde -
size()) +
c2 * (I2_tilde -
size()) +
c3 * (I1_tilde -
size()) * (I2_tilde -
size()) +
d1 * log_J * log_J;
344 Eigen::MatrixXd F_T =
F.transpose();
358 Eigen::Matrix<Diff, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> def_grad(
size(),
size());
360 for (
int i = 0; i <
size(); ++i)
361 for (
int j = 0; j <
size(); ++j)
362 def_grad(i, j) =
Diff(i + j *
size(),
F(i, j));
367 grad = energy.getGradient().reshaped(
size(),
size());
369 hess = energy.getHessian();
374 return compute_energy_aux<double>(data);
377 template <
typename T>
387 const int n_pts = data.
da.size();
388 for (
long p = 0; p < n_pts; ++p)
393 for (
int d = 0; d <
size(); ++d)
394 def_grad(d, d) += T(1);
398 energy +=
val * data.
da(p);
403 template <
int n_basis,
int dim>
406 assert(data.
x.cols() == 1);
408 const int n_pts = data.
da.size();
411 local_disp.setZero();
415 for (
size_t ii = 0; ii < bs.global.size(); ++ii)
417 for (
int d = 0; d <
size(); ++d)
419 local_disp(i, d) += bs.global[ii].val * data.
x(bs.global[ii].index *
size() + d);
424 Eigen::Matrix<double, dim, dim> def_grad(
size(),
size());
425 Eigen::Matrix<double, dim, dim> def_grad_T(
size(),
size());
430 for (
long p = 0; p < n_pts; ++p)
439 Eigen::Matrix<double, dim, dim> jac_it = data.
vals.
jac_it[p];
442 def_grad = local_disp.transpose() * grad * jac_it + Eigen::Matrix<double, dim, dim>::Identity(
size(),
size());
443 def_grad_T = def_grad.transpose();
451 Eigen::Matrix<double, dim, dim> gradient_temp;
452 autogen::generate_gradient_templated<dim>(
c1,
c2,
c3,
d1, def_grad_T, gradient_temp);
454 Eigen::Matrix<double, n_basis, dim> delF_delU = grad * jac_it;
455 Eigen::Matrix<double, n_basis, dim> gradient = delF_delU * gradient_temp.transpose();
456 G.noalias() += gradient * data.
da(p);
459 Eigen::Matrix<double, dim, n_basis> G_T = G.transpose();
461 constexpr int N = (n_basis == Eigen::Dynamic) ? Eigen::Dynamic : n_basis * dim;
462 Eigen::Matrix<double, N, 1> temp(Eigen::Map<Eigen::Matrix<double, N, 1>>(G_T.data(), G_T.size()));
466 template <
int n_basis,
int dim>
469 assert(data.
x.cols() == 1);
471 constexpr int N = (n_basis == Eigen::Dynamic) ? Eigen::Dynamic : n_basis * dim;
472 const int n_pts = data.
da.size();
475 local_disp.setZero();
479 for (
size_t ii = 0; ii < bs.global.size(); ++ii)
481 for (
int d = 0; d <
size(); ++d)
483 local_disp(i, d) += bs.global[ii].val * data.
x(bs.global[ii].index *
size() + d);
488 Eigen::Matrix<double, dim, dim> def_grad(
size(),
size());
490 for (
long p = 0; p < n_pts; ++p)
499 Eigen::Matrix<double, dim, dim> jac_it = data.
vals.
jac_it[p];
502 def_grad = local_disp.transpose() * grad * jac_it + Eigen::Matrix<double, dim, dim>::Identity(
size(),
size());
510 Eigen::Matrix<double, dim * dim, dim * dim> hessian_temp;
511 autogen::generate_hessian_templated<dim>(
c1,
c2,
c3,
d1, def_grad, hessian_temp);
538 Eigen::Matrix<double, dim * dim, N> delF_delU_tensor(jac_it.size(), grad.size());
540 for (
size_t i = 0; i < local_disp.rows(); ++i)
542 for (
size_t j = 0; j < local_disp.cols(); ++j)
544 Eigen::Matrix<double, dim, dim> temp(
size(),
size());
546 temp.row(j) = grad.row(i);
547 temp = temp * jac_it;
548 Eigen::Matrix<double, dim * dim, 1> temp_flattened(Eigen::Map<Eigen::Matrix<double, dim * dim, 1>>(temp.data(), temp.size()));
549 delF_delU_tensor.col(i *
size() + j) = temp_flattened;
553 Eigen::Matrix<double, N, N> hessian = delF_delU_tensor.transpose() * hessian_temp * delF_delU_tensor;
555 H += hessian * data.
da(p);
569 std::map<std::string, ParamFunc> res;
570 const auto &
c1 = this->
c1();
571 const auto &
c2 = this->
c2();
572 const auto &
c3 = this->
c3();
573 const auto &
d1 = this->
d1();
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,...
std::vector< Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3 > > jac_it
void add_multimaterial(const int index, const json ¶ms, const std::string &unit_type)
void compute_stress_grad_multiply_stress(const OptAssemblerData &data, Eigen::MatrixXd &stress, Eigen::MatrixXd &result) const override
T compute_energy_aux(const NonLinearAssemblerData &data) const
T elastic_energy(const RowVectorNd &p, const int el_id, const AutoDiffGradMat< T > &def_grad) const
double compute_energy(const NonLinearAssemblerData &data) const override
void get_grad_hess_symbolic(const double c1, const double c2, const double c3, const double d1, const Eigen::MatrixXd &def_grad, Eigen::MatrixXd &grad, Eigen::MatrixXd &hess) const
Eigen::VectorXd assemble_gradient(const NonLinearAssemblerData &data) const override
const GenericMatParam & c1() const
void compute_energy_aux_gradient_fast(const NonLinearAssemblerData &data, Eigen::VectorXd &G_flattened) const
std::map< std::string, ParamFunc > parameters() const override
void compute_stress_grad_multiply_vect(const OptAssemblerData &data, const Eigen::MatrixXd &vect, Eigen::MatrixXd &stress, Eigen::MatrixXd &result) const override
MooneyRivlin3ParamSymbolic()
void add_multimaterial(const int index, const json ¶ms, const Units &units) override
void get_grad_hess_autodiff(const double c1, const double c2, const double c3, const double d1, const Eigen::MatrixXd &global_pts, const int el_id, const Eigen::MatrixXd &F, Eigen::MatrixXd &grad, Eigen::MatrixXd &hess) const
const GenericMatParam & c3() const
const GenericMatParam & d1() const
void compute_energy_hessian_aux_fast(const NonLinearAssemblerData &data, Eigen::MatrixXd &H) const
const GenericMatParam & c2() const
void compute_stress_grad_multiply_mat(const OptAssemblerData &data, const Eigen::MatrixXd &mat, Eigen::MatrixXd &stress, Eigen::MatrixXd &result) const override
Eigen::MatrixXd assemble_hessian(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 ElementAssemblyValues & vals
const Eigen::MatrixXd & x
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 generate_hessian(const double c1, const double c2, const double c3, const double d1, const Eigen::MatrixXd &def_grad, Eigen::MatrixXd &hessian)
void generate_gradient(const double c1, const double c2, const double c3, const double d1, const Eigen::MatrixXd &def_grad, Eigen::MatrixXd &gradient)
DScalar1< double, Eigen::Matrix< double, Eigen::Dynamic, 1 > > Diff
T determinant(const Eigen::Matrix< T, rows, cols, option, maxRow, maxCol > &mat)
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)
AutoDiffGradMat::Scalar second_invariant(const AutoDiffGradMat &B)
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)
AutoDiffGradMat::Scalar first_invariant(const AutoDiffGradMat &B)
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
Automatic differentiation scalar with first- and second-order derivatives.
static void setVariableCount(size_t value)
Set the independent variable count used by the automatic differentiation layer.