PolyFEM
Loading...
Searching...
No Matches
MooneyRivlin3ParamSymbolic.cpp
Go to the documentation of this file.
2
4
5namespace polyfem::assembler
6{
7
9 : c1_("c1"), c2_("c2"), c3_("c3"), d1_("d1")
10 {
11 }
12
13 Eigen::VectorXd
15 {
16 Eigen::Matrix<double, Eigen::Dynamic, 1> gradient;
17
18 if (size() == 2)
19 {
20 switch (data.vals.basis_values.size())
21 {
22 case 3:
23 {
24 gradient.resize(6);
25 compute_energy_aux_gradient_fast<3, 2>(data, gradient);
26 break;
27 }
28 case 6:
29 {
30 gradient.resize(12);
31 compute_energy_aux_gradient_fast<6, 2>(data, gradient);
32 break;
33 }
34 case 10:
35 {
36 gradient.resize(20);
37 compute_energy_aux_gradient_fast<10, 2>(data, gradient);
38 break;
39 }
40 default:
41 {
42 gradient.resize(data.vals.basis_values.size() * 2);
43 compute_energy_aux_gradient_fast<Eigen::Dynamic, 2>(data, gradient);
44 break;
45 }
46 }
47 }
48 else // if (size() == 3)
49 {
50 assert(size() == 3);
51 switch (data.vals.basis_values.size())
52 {
53 case 4:
54 {
55 gradient.resize(12);
56 compute_energy_aux_gradient_fast<4, 3>(data, gradient);
57 break;
58 }
59 case 10:
60 {
61 gradient.resize(30);
62 compute_energy_aux_gradient_fast<10, 3>(data, gradient);
63 break;
64 }
65 case 20:
66 {
67 gradient.resize(60);
68 compute_energy_aux_gradient_fast<20, 3>(data, gradient);
69 break;
70 }
71 default:
72 {
73 gradient.resize(data.vals.basis_values.size() * 3);
74 compute_energy_aux_gradient_fast<Eigen::Dynamic, 3>(data, gradient);
75 break;
76 }
77 }
78 }
79
80 return gradient;
81 }
82
83 Eigen::MatrixXd
85 {
86 Eigen::MatrixXd hessian;
87
88 if (size() == 2)
89 {
90 switch (data.vals.basis_values.size())
91 {
92 case 3:
93 {
94 hessian.resize(6, 6);
95 hessian.setZero();
96 compute_energy_hessian_aux_fast<3, 2>(data, hessian);
97 break;
98 }
99 case 6:
100 {
101 hessian.resize(12, 12);
102 hessian.setZero();
103 compute_energy_hessian_aux_fast<6, 2>(data, hessian);
104 break;
105 }
106 case 10:
107 {
108 hessian.resize(20, 20);
109 hessian.setZero();
110 compute_energy_hessian_aux_fast<10, 2>(data, hessian);
111 break;
112 }
113 default:
114 {
115 hessian.resize(data.vals.basis_values.size() * 2, data.vals.basis_values.size() * 2);
116 hessian.setZero();
117 compute_energy_hessian_aux_fast<Eigen::Dynamic, 2>(data, hessian);
118 break;
119 }
120 }
121 }
122 else // if (size() == 3)
123 {
124 assert(size() == 3);
125 switch (data.vals.basis_values.size())
126 {
127 case 4:
128 {
129 hessian.resize(12, 12);
130 hessian.setZero();
131 compute_energy_hessian_aux_fast<4, 3>(data, hessian);
132 break;
133 }
134 case 10:
135 {
136 hessian.resize(30, 30);
137 hessian.setZero();
138 compute_energy_hessian_aux_fast<10, 3>(data, hessian);
139 break;
140 }
141 case 20:
142 {
143 hessian.resize(60, 60);
144 hessian.setZero();
145 compute_energy_hessian_aux_fast<20, 3>(data, hessian);
146 break;
147 }
148 default:
149 {
150 hessian.resize(data.vals.basis_values.size() * 3, data.vals.basis_values.size() * 3);
151 hessian.setZero();
152 compute_energy_hessian_aux_fast<Eigen::Dynamic, 3>(data, hessian);
153 break;
154 }
155 }
156 }
157
158 return hessian;
159 }
160
162 const int all_size,
163 const ElasticityTensorType &type,
164 Eigen::MatrixXd &all,
165 const std::function<Eigen::MatrixXd(const Eigen::MatrixXd &)> &fun) const
166 {
167 const auto &displacement = data.fun;
168 const auto &local_pts = data.local_pts;
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;
173
174 Eigen::MatrixXd displacement_grad(size(), size());
175
176 assert(displacement.cols() == 1);
177
178 all.resize(local_pts.rows(), all_size);
179
181 vals.compute(el_id, size() == 3, local_pts, bs, gbs);
182 const auto I = Eigen::MatrixXd::Identity(size(), size());
183
184 for (long p = 0; p < local_pts.rows(); ++p)
185 {
186 compute_diplacement_grad(size(), bs, vals, local_pts, p, displacement, displacement_grad);
187
188 const Eigen::MatrixXd def_grad = I + displacement_grad;
189 const Eigen::MatrixXd def_grad_T = def_grad.transpose();
190 if (type == ElasticityTensorType::F)
191 {
192 all.row(p) = fun(def_grad);
193 continue;
194 }
195
196 const double t = 0;
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);
201
202 Eigen::MatrixXd stress_tensor;
203 autogen::generate_gradient(c1, c2, c3, d1, def_grad_T, stress_tensor);
204
205 stress_tensor = 1.0 / def_grad.determinant() * stress_tensor * def_grad.transpose();
206 if (type == ElasticityTensorType::PK1)
207 stress_tensor = pk1_from_cauchy(stress_tensor, def_grad);
208 else if (type == ElasticityTensorType::PK2)
209 stress_tensor = pk2_from_cauchy(stress_tensor, def_grad);
210
211 all.row(p) = fun(stress_tensor);
212 }
213 }
214
216 const OptAssemblerData &data,
217 const Eigen::MatrixXd &mat,
218 Eigen::MatrixXd &stress,
219 Eigen::MatrixXd &result) const
220 {
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;
226
227 Eigen::MatrixXd F = grad_u_i;
228 for (int d = 0; d < size(); ++d)
229 F(d, d) += 1.;
230 Eigen::MatrixXd F_T = F.transpose();
231
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);
236
237 Eigen::MatrixXd grad, hess;
238 get_grad_hess_symbolic(c1, c2, c3, d1, F, grad, hess);
239 // get_grad_hess_autodiff(c1, c2, c3, d1, global_pts, el_id, F, grad, hess);
240
241 // Stress is S_ij = ∂W(F)/∂F_ij
242 stress = grad;
243 // Compute ∂S_ij/∂F_kl * M_kl, same as M_ij * ∂S_ij/∂F_kl since the hessian is symmetric
244 result = (hess * mat.reshaped(size() * size(), 1)).reshaped(size(), size());
245 }
246
248 const OptAssemblerData &data,
249 Eigen::MatrixXd &stress,
250 Eigen::MatrixXd &result) const
251 {
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;
257
258 Eigen::MatrixXd F = grad_u_i;
259 for (int d = 0; d < size(); ++d)
260 F(d, d) += 1.;
261
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);
266
267 Eigen::MatrixXd grad, hess;
268 get_grad_hess_symbolic(c1, c2, c3, d1, F, grad, hess);
269 // get_grad_hess_autodiff(c1, c2, c3, d1, global_pts, el_id, F, grad, hess);
270
271 // Stress is S_ij = ∂W(F)/∂F_ij
272 stress = grad;
273 // Compute ∂S_ij/∂F_kl * S_kl, same as S_ij * ∂S_ij/∂F_kl since the hessian is symmetric
274 result = (hess * stress.reshaped(size() * size(), 1)).reshaped(size(), size());
275 }
276
278 const OptAssemblerData &data,
279 const Eigen::MatrixXd &vect,
280 Eigen::MatrixXd &stress,
281 Eigen::MatrixXd &result) const
282 {
283
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;
289
290 Eigen::MatrixXd F = grad_u_i;
291 for (int d = 0; d < size(); ++d)
292 F(d, d) += 1.;
293 Eigen::MatrixXd F_T = F.transpose();
294
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);
299
300 Eigen::MatrixXd grad, hess;
301 get_grad_hess_symbolic(c1, c2, c3, d1, F, grad, hess);
302 // get_grad_hess_autodiff(c1, c2, c3, d1, global_pts, el_id, F, grad, hess);
303
304 // Stress is S_ij = ∂W(F)/∂F_ij
305 stress = grad;
306 result.resize(hess.rows(), vect.size());
307 for (int i = 0; i < hess.rows(); ++i)
308 if (vect.rows() == 1)
309 // Compute ∂S_ij/∂F_kl * v_k, same as ∂S_ij/∂F_kl * v_i since the hessian is symmetric
310 result.row(i) = vect * hess.row(i).reshaped(size(), size());
311 else
312 // Compute ∂S_ij/∂F_kl * v_l, same as ∂S_ij/∂F_kl * v_j since the hessian is symmetric
313 result.row(i) = hess.row(i).reshaped(size(), size()) * vect;
314 }
315
316 template <typename T>
318 const RowVectorNd &p,
319 const int el_id,
320 const AutoDiffGradMat<T> &def_grad) const
321 {
322 const double t = 0; // TODO
323
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);
328
329 const T J = polyfem::utils::determinant(def_grad);
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();
333
334 const auto I1_tilde = pow(J, -2. / size()) * first_invariant(right_cauchy_green);
335 const auto I2_tilde = pow(J, -4. / size()) * second_invariant(right_cauchy_green);
336
337 const T val = c1 * (I1_tilde - size()) + c2 * (I2_tilde - size()) + c3 * (I1_tilde - size()) * (I2_tilde - size()) + d1 * log_J * log_J;
338
339 return val;
340 }
341
342 void MooneyRivlin3ParamSymbolic::get_grad_hess_symbolic(const double c1, const double c2, const double c3, const double d1, const Eigen::MatrixXd &F, Eigen::MatrixXd &grad, Eigen::MatrixXd &hess) const
343 {
344 Eigen::MatrixXd F_T = F.transpose();
345
346 // Grad is ∂W(F)/∂F_ij
347 autogen::generate_gradient(c1, c2, c3, d1, F_T, grad);
348 // Hessian is ∂W(F)/(∂F_ij*∂F_kl)
350 }
351
352 void MooneyRivlin3ParamSymbolic::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
353 {
355
357
358 Eigen::Matrix<Diff, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> def_grad(size(), size());
359
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));
363
364 const auto energy = elastic_energy(global_pts, el_id, def_grad);
365
366 // Grad is ∂W(F)/∂F_ij
367 grad = energy.getGradient().reshaped(size(), size());
368 // Hessian is ∂W(F)/(∂F_ij*∂F_kl)
369 hess = energy.getHessian();
370 }
371
373 {
374 return compute_energy_aux<double>(data);
375 }
376
377 template <typename T>
379 {
380 AutoDiffVect<T> local_disp;
381 get_local_disp(data, size(), local_disp);
382
383 AutoDiffGradMat<T> def_grad(size(), size());
384
385 T energy = T(0.0);
386
387 const int n_pts = data.da.size();
388 for (long p = 0; p < n_pts; ++p)
389 {
390 compute_disp_grad_at_quad(data, local_disp, p, size(), def_grad);
391
392 // Id + grad d
393 for (int d = 0; d < size(); ++d)
394 def_grad(d, d) += T(1);
395
396 const T val = elastic_energy(data.vals.val.row(p), data.vals.element_id, def_grad);
397
398 energy += val * data.da(p);
399 }
400 return energy;
401 }
402
403 template <int n_basis, int dim>
404 void MooneyRivlin3ParamSymbolic::compute_energy_aux_gradient_fast(const NonLinearAssemblerData &data, Eigen::Matrix<double, Eigen::Dynamic, 1> &G_flattened) const
405 {
406 assert(data.x.cols() == 1);
407
408 const int n_pts = data.da.size();
409
410 Eigen::Matrix<double, n_basis, dim> local_disp(data.vals.basis_values.size(), size());
411 local_disp.setZero();
412 for (size_t i = 0; i < data.vals.basis_values.size(); ++i)
413 {
414 const auto &bs = data.vals.basis_values[i];
415 for (size_t ii = 0; ii < bs.global.size(); ++ii)
416 {
417 for (int d = 0; d < size(); ++d)
418 {
419 local_disp(i, d) += bs.global[ii].val * data.x(bs.global[ii].index * size() + d);
420 }
421 }
422 }
423
424 Eigen::Matrix<double, dim, dim> def_grad(size(), size());
425 Eigen::Matrix<double, dim, dim> def_grad_T(size(), size());
426
427 Eigen::Matrix<double, n_basis, dim> G(data.vals.basis_values.size(), size());
428 G.setZero();
429
430 for (long p = 0; p < n_pts; ++p)
431 {
432 Eigen::Matrix<double, n_basis, dim> grad(data.vals.basis_values.size(), size());
433
434 for (size_t i = 0; i < data.vals.basis_values.size(); ++i)
435 {
436 grad.row(i) = data.vals.basis_values[i].grad.row(p);
437 }
438
439 Eigen::Matrix<double, dim, dim> jac_it = data.vals.jac_it[p];
440
441 // Id + grad d
442 def_grad = local_disp.transpose() * grad * jac_it + Eigen::Matrix<double, dim, dim>::Identity(size(), size());
443 def_grad_T = def_grad.transpose();
444
445 const double t = 0;
446 const double c1 = c1_(data.vals.val.row(p), t, data.vals.element_id);
447 const double c2 = c2_(data.vals.val.row(p), t, data.vals.element_id);
448 const double c3 = c3_(data.vals.val.row(p), t, data.vals.element_id);
449 const double d1 = d1_(data.vals.val.row(p), t, data.vals.element_id);
450
451 Eigen::Matrix<double, dim, dim> gradient_temp;
452 autogen::generate_gradient_templated<dim>(c1, c2, c3, d1, def_grad_T, gradient_temp);
453
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);
457 }
458
459 Eigen::Matrix<double, dim, n_basis> G_T = G.transpose();
460
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()));
463 G_flattened = temp;
464 }
465
466 template <int n_basis, int dim>
468 {
469 assert(data.x.cols() == 1);
470
471 constexpr int N = (n_basis == Eigen::Dynamic) ? Eigen::Dynamic : n_basis * dim;
472 const int n_pts = data.da.size();
473
474 Eigen::Matrix<double, n_basis, dim> local_disp(data.vals.basis_values.size(), size());
475 local_disp.setZero();
476 for (size_t i = 0; i < data.vals.basis_values.size(); ++i)
477 {
478 const auto &bs = data.vals.basis_values[i];
479 for (size_t ii = 0; ii < bs.global.size(); ++ii)
480 {
481 for (int d = 0; d < size(); ++d)
482 {
483 local_disp(i, d) += bs.global[ii].val * data.x(bs.global[ii].index * size() + d);
484 }
485 }
486 }
487
488 Eigen::Matrix<double, dim, dim> def_grad(size(), size());
489
490 for (long p = 0; p < n_pts; ++p)
491 {
492 Eigen::Matrix<double, n_basis, dim> grad(data.vals.basis_values.size(), size());
493
494 for (size_t i = 0; i < data.vals.basis_values.size(); ++i)
495 {
496 grad.row(i) = data.vals.basis_values[i].grad.row(p);
497 }
498
499 Eigen::Matrix<double, dim, dim> jac_it = data.vals.jac_it[p];
500
501 // Id + grad d
502 def_grad = local_disp.transpose() * grad * jac_it + Eigen::Matrix<double, dim, dim>::Identity(size(), size());
503
504 const double t = 0;
505 const double c1 = c1_(data.vals.val.row(p), t, data.vals.element_id);
506 const double c2 = c2_(data.vals.val.row(p), t, data.vals.element_id);
507 const double c3 = c3_(data.vals.val.row(p), t, data.vals.element_id);
508 const double d1 = d1_(data.vals.val.row(p), t, data.vals.element_id);
509
510 Eigen::Matrix<double, dim * dim, dim * dim> hessian_temp;
511 autogen::generate_hessian_templated<dim>(c1, c2, c3, d1, def_grad, hessian_temp);
512
513 // Check by FD
514 /*
515 {
516 double eps = 1e-7;
517 Eigen::MatrixXd gradient_temp, gradient_temp_plus;
518 autogen::generate_gradient(c1, c2, c3, d1, def_grad, gradient_temp);
519 Eigen::MatrixXd x_ = def_grad;
520 for (int j = 0; j < hessian_temp.cols(); ++j)
521 {
522 x_(j / dim, j % dim) += eps;
523 autogen::generate_gradient(c1, c2, c3, d1, x_, gradient_temp_plus);
524 Eigen::MatrixXd fd = (gradient_temp_plus - gradient_temp) / eps;
525
526 std::cout << "hess " << fd.transpose() << "\t" << hessian_temp.col(j).transpose() << std::endl;
527 // for (int i = 0; i < hessian_temp.rows(); ++i)
528 // {
529 // double fd = (gradient_temp_plus(i) - gradient_temp(i)) / eps;
530 // if (abs(fd - hessian_temp(i, j)) > 1e-7)
531 // std::cout << "mismatch " << abs(fd - hessian_temp(i, j)) << std::endl;
532 // }
533 x_(j / dim, j % dim) -= eps;
534 }
535 }
536 */
537
538 Eigen::Matrix<double, dim * dim, N> delF_delU_tensor(jac_it.size(), grad.size());
539
540 for (size_t i = 0; i < local_disp.rows(); ++i)
541 {
542 for (size_t j = 0; j < local_disp.cols(); ++j)
543 {
544 Eigen::Matrix<double, dim, dim> temp(size(), size());
545 temp.setZero();
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;
550 }
551 }
552
553 Eigen::Matrix<double, N, N> hessian = delF_delU_tensor.transpose() * hessian_temp * delF_delU_tensor;
554
555 H += hessian * data.da(p);
556 }
557 }
558
559 void MooneyRivlin3ParamSymbolic::add_multimaterial(const int index, const json &params, const Units &units)
560 {
561 c1_.add_multimaterial(index, params, units.stress());
562 c2_.add_multimaterial(index, params, units.stress());
563 c3_.add_multimaterial(index, params, units.stress());
564 d1_.add_multimaterial(index, params, units.stress());
565 }
566
567 std::map<std::string, Assembler::ParamFunc> MooneyRivlin3ParamSymbolic::parameters() const
568 {
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();
574
575 res["c1"] = [&c1](const RowVectorNd &, const RowVectorNd &p, double t, int e) {
576 return c1(p, t, e);
577 };
578
579 res["c2"] = [&c2](const RowVectorNd &, const RowVectorNd &p, double t, int e) {
580 return c2(p, t, e);
581 };
582
583 res["c3"] = [&c3](const RowVectorNd &, const RowVectorNd &p, double t, int e) {
584 return c3(p, t, e);
585 };
586
587 res["d1"] = [&d1](const RowVectorNd &, const RowVectorNd &p, double t, int e) {
588 return d1(p, t, e);
589 };
590
591 return res;
592 }
593
594} // namespace polyfem::assembler
double val
Definition Assembler.cpp:86
ElementAssemblyValues vals
Definition Assembler.cpp:22
Eigen::MatrixXd mat
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,...
std::vector< Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3 > > jac_it
void add_multimaterial(const int index, const json &params, const std::string &unit_type)
Definition MatParams.cpp:28
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
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
void add_multimaterial(const int index, const json &params, 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
void compute_energy_hessian_aux_fast(const NonLinearAssemblerData &data, Eigen::MatrixXd &H) 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 basis::ElementBases & bs
const Eigen::MatrixXd & fun
const Eigen::MatrixXd & local_pts
const basis::ElementBases & gbs
Used for test only.
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)
T determinant(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3 > &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)
nlohmann::json json
Definition Common.hpp:9
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
Definition Types.hpp:11
Automatic differentiation scalar with first- and second-order derivatives.
Definition autodiff.h:493
static void setVariableCount(size_t value)
Set the independent variable count used by the automatic differentiation layer.
Definition autodiff.h:54