PolyFEM
Loading...
Searching...
No Matches
GenericElastic.cpp
Go to the documentation of this file.
1// Shared template implementation, included by the GenericElastic material groups.
2// This file is not compiled separately.
3#include "GenericElastic.hpp"
4
6
7namespace polyfem::assembler
8{
9
10 template <typename Derived>
11 template <int dim>
12 Eigen::Matrix<double, dim * dim, dim> GenericElastic<Derived>::compute_B_block(const Eigen::Matrix<double, 1, dim> &g) const
13 {
14 Eigen::Matrix<double, dim * dim, dim> B(size() * size(), size());
15 B.setZero();
16
17 for (int i = 0; i < dim; ++i) // displacement component
18 for (int j = 0; j < dim; ++j) // gradient direction
19 B(i * dim + j, i) = g(j);
20
21 return B;
22 }
23
24 template <typename Derived>
28
29 template <typename Derived>
31 const OutputData &data,
32 const int all_size,
34 Eigen::MatrixXd &all,
35 const std::function<Eigen::MatrixXd(const Eigen::MatrixXd &)> &fun) const
36 {
37 Eigen::MatrixXd deformation_grad(size(), size());
38 Eigen::MatrixXd stress_tensor(size(), size());
39
41
42 const auto &displacement = data.fun;
43 const auto &local_pts = data.local_pts;
44 const auto &bs = data.bs;
45 const auto &gbs = data.gbs;
46 const auto el_id = data.el_id;
47
48 assert(displacement.cols() == 1);
49
50 all.resize(local_pts.rows(), all_size);
51 DiffScalarBase::setVariableCount(deformation_grad.size());
53 Eigen::Matrix<Diff, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> def_grad(size(), size());
54
56 vals.compute(el_id, size() == 3, local_pts, bs, gbs);
57
58 for (long p = 0; p < local_pts.rows(); ++p)
59 {
60 compute_diplacement_grad(size(), bs, vals, local_pts, p, displacement, deformation_grad);
61
62 // Id + grad d
63 for (int d = 0; d < size(); ++d)
64 deformation_grad(d, d) += 1;
65
66 if (type == ElasticityTensorType::F)
67 {
68 all.row(p) = fun(deformation_grad);
69 continue;
70 }
71
72 // Absolute mode measures distortion from the regular element, not a stress.
73 if (!derived().real_def_grad(vals.val.row(p), data.t, el_id))
74 {
75 all.row(p).setConstant(std::nan(""));
76 continue;
77 }
78
79 for (int d1 = 0; d1 < size(); ++d1)
80 {
81 for (int d2 = 0; d2 < size(); ++d2)
82 def_grad(d1, d2) = Diff(d1 * size() + d2, deformation_grad(d1, d2));
83 }
84
85 const auto val = derived().elastic_energy(local_pts.row(p), data.t, vals.element_id, def_grad);
86
87 for (int d1 = 0; d1 < size(); ++d1)
88 {
89 for (int d2 = 0; d2 < size(); ++d2)
90 stress_tensor(d1, d2) = val.getGradient()(d1 * size() + d2);
91 }
92
93 stress_tensor = 1.0 / deformation_grad.determinant() * stress_tensor * deformation_grad.transpose();
94
95 if (type == ElasticityTensorType::PK1)
96 stress_tensor = pk1_from_cauchy(stress_tensor, deformation_grad);
97 else if (type == ElasticityTensorType::PK2)
98 stress_tensor = pk2_from_cauchy(stress_tensor, deformation_grad);
99
100 all.row(p) = fun(stress_tensor);
101 }
102 }
103
104 template <typename Derived>
106 {
107 return compute_energy_aux<double>(data);
108 }
109
110 template <typename Derived>
112 {
113 if (autodiff_type_ == AutodiffType::FULL)
114 return assemble_gradient_full_ad(data);
115 else if (autodiff_type_ == AutodiffType::STRESS)
116 {
117#ifndef NDEBUG
118 auto grad = assemble_gradient_stress_ad(data);
119 auto grad_full = assemble_gradient_full_ad(data);
120 assert((std::isnan(grad.norm()) && std::isnan(grad_full.norm())) || (grad - grad_full).norm() < 1e-6);
121#endif
122 return assemble_gradient_stress_ad(data);
123 }
124 else
125 {
126#ifndef NDEBUG
127 auto grad = assemble_gradient_stress_noad(data);
128 auto grad_full = assemble_gradient_stress_ad(data);
129 assert((std::isnan(grad.norm()) && std::isnan(grad_full.norm())) || (grad - grad_full).norm() < 1e-6);
130#endif
131 return assemble_gradient_stress_noad(data);
132 }
133 }
134
135 template <typename Derived>
137 {
138 const int n_bases = data.vals.basis_values.size();
140 size(), n_bases, data,
141 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 6, 1>>>(data); },
142 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 8, 1>>>(data); },
143 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 12, 1>>>(data); },
144 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 18, 1>>>(data); },
145 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 24, 1>>>(data); },
146 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 30, 1>>>(data); },
147 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 60, 1>>>(data); },
148 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, 81, 1>>>(data); },
149 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, SMALL_N, 1>>>(data); },
150 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, BIG_N, 1>>>(data); },
151 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar1<double, Eigen::VectorXd>>(data); });
152 }
153
154 template <typename Derived>
156 {
157 Eigen::Matrix<double, Eigen::Dynamic, 1> gradient;
158
159 if (size() == 2)
160 {
161 switch (data.vals.basis_values.size())
162 {
163 case 3:
164 {
165 gradient.resize(6);
166 compute_gradient_from_stress<3, 2>(data, gradient);
167 break;
168 }
169 case 6:
170 {
171 gradient.resize(12);
172 compute_gradient_from_stress<6, 2>(data, gradient);
173 break;
175 case 10:
176 {
177 gradient.resize(20);
178 compute_gradient_from_stress<10, 2>(data, gradient);
179 break;
180 }
181 default:
182 {
183 gradient.resize(data.vals.basis_values.size() * 2);
184 compute_gradient_from_stress<Eigen::Dynamic, 2>(data, gradient);
185 break;
186 }
187 }
188 }
189 else // if (size() == 3)
190 {
191 assert(size() == 3);
192 switch (data.vals.basis_values.size())
193 {
194 case 4:
195 {
196 gradient.resize(12);
197 compute_gradient_from_stress<4, 3>(data, gradient);
198 break;
199 }
200 case 10:
201 {
202 gradient.resize(30);
203 compute_gradient_from_stress<10, 3>(data, gradient);
204 break;
205 }
206 case 20:
207 {
208 gradient.resize(60);
209 compute_gradient_from_stress<20, 3>(data, gradient);
210 break;
211 }
212 default:
213 {
214 gradient.resize(data.vals.basis_values.size() * 3);
215 compute_gradient_from_stress<Eigen::Dynamic, 3>(data, gradient);
216 break;
217 }
218 }
219 }
220
221 return gradient;
222 }
223
224 template <typename Derived>
226 {
227 Eigen::Matrix<double, Eigen::Dynamic, 1> gradient;
228
229 if (size() == 2)
230 {
231 switch (data.vals.basis_values.size())
232 {
233 case 3:
234 {
235 gradient.resize(6);
236 compute_gradient_from_stress_noad<3, 2>(data, gradient);
237 break;
238 }
239 case 6:
240 {
241 gradient.resize(12);
242 compute_gradient_from_stress_noad<6, 2>(data, gradient);
243 break;
244 }
245 case 10:
246 {
247 gradient.resize(20);
248 compute_gradient_from_stress_noad<10, 2>(data, gradient);
249 break;
250 }
251 default:
252 {
253 gradient.resize(data.vals.basis_values.size() * 2);
254 compute_gradient_from_stress_noad<Eigen::Dynamic, 2>(data, gradient);
255 break;
256 }
257 }
258 }
259 else // if (size() == 3)
260 {
261 assert(size() == 3);
262 switch (data.vals.basis_values.size())
263 {
264 case 4:
265 {
266 gradient.resize(12);
267 compute_gradient_from_stress_noad<4, 3>(data, gradient);
268 break;
269 }
270 case 10:
271 {
272 gradient.resize(30);
273 compute_gradient_from_stress_noad<10, 3>(data, gradient);
274 break;
275 }
276 case 20:
277 {
278 gradient.resize(60);
279 compute_gradient_from_stress_noad<20, 3>(data, gradient);
280 break;
281 }
282 default:
283 {
284 gradient.resize(data.vals.basis_values.size() * 3);
285 compute_gradient_from_stress_noad<Eigen::Dynamic, 3>(data, gradient);
286 break;
287 }
288 }
289 }
290
291 return gradient;
292 }
293
294 template <typename Derived>
296 {
297 if (autodiff_type_ == AutodiffType::FULL)
298 return assemble_hessian_full_ad(data);
299 else if (autodiff_type_ == AutodiffType::STRESS)
300 {
301#ifndef NDEBUG
302 auto hessian = assemble_hessian_stress_ad(data);
303 auto hessian_full = assemble_hessian_full_ad(data);
304 assert((std::isnan(hessian.norm()) && std::isnan(hessian_full.norm())) || (hessian - hessian_full).norm() < 1e-5);
305#endif
306 return assemble_hessian_stress_ad(data);
307 }
308 else
309 {
310#ifndef NDEBUG
311 auto hessian = assemble_hessian_stress_noad(data);
312 auto hessian_full = assemble_hessian_stress_ad(data);
313 assert((std::isnan(hessian.norm()) && std::isnan(hessian_full.norm())) || (hessian - hessian_full).norm() < 1e-5);
314#endif
315 return assemble_hessian_stress_noad(data);
316 }
317 }
318
319 template <typename Derived>
321 {
322 const int n_bases = data.vals.basis_values.size();
324 size(), n_bases, data,
325 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 6, 1>, Eigen::Matrix<double, 6, 6>>>(data); },
326 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 8, 1>, Eigen::Matrix<double, 8, 8>>>(data); },
327 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 12, 1>, Eigen::Matrix<double, 12, 12>>>(data); },
328 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 18, 1>, Eigen::Matrix<double, 18, 18>>>(data); },
329 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 24, 1>, Eigen::Matrix<double, 24, 24>>>(data); },
330 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 30, 1>, Eigen::Matrix<double, 30, 30>>>(data); },
331 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 60, 1>, Eigen::Matrix<double, 60, 60>>>(data); },
332 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar2<double, Eigen::Matrix<double, 81, 1>, Eigen::Matrix<double, 81, 81>>>(data); },
333 [&](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); },
334 [&](const NonLinearAssemblerData &data) { return compute_energy_aux<DScalar2<double, Eigen::VectorXd, Eigen::MatrixXd>>(data); });
335 }
336
337 template <typename Derived>
339 {
340 Eigen::MatrixXd hessian;
341
342 if (size() == 2)
343 {
344 switch (data.vals.basis_values.size())
345 {
346 case 3:
347 {
348 hessian.resize(6, 6);
349 hessian.setZero();
350 compute_hessian_from_stress<3, 2>(data, hessian);
351 break;
352 }
353 case 6:
354 {
355 hessian.resize(12, 12);
356 hessian.setZero();
357 compute_hessian_from_stress<6, 2>(data, hessian);
358 break;
359 }
360 case 10:
361 {
362 hessian.resize(20, 20);
363 hessian.setZero();
364 compute_hessian_from_stress<10, 2>(data, hessian);
365 break;
366 }
367 default:
368 {
369 hessian.resize(data.vals.basis_values.size() * 2, data.vals.basis_values.size() * 2);
370 hessian.setZero();
371 compute_hessian_from_stress<Eigen::Dynamic, 2>(data, hessian);
372 break;
373 }
374 }
375 }
376 else // if (size() == 3)
377 {
378 assert(size() == 3);
379 switch (data.vals.basis_values.size())
380 {
381 case 4:
382 {
383 hessian.resize(12, 12);
384 hessian.setZero();
385 compute_hessian_from_stress<4, 3>(data, hessian);
386 break;
387 }
388 case 10:
389 {
390 hessian.resize(30, 30);
391 hessian.setZero();
392 compute_hessian_from_stress<10, 3>(data, hessian);
393 break;
394 }
395 case 20:
396 {
397 hessian.resize(60, 60);
398 hessian.setZero();
399 compute_hessian_from_stress<20, 3>(data, hessian);
400 break;
401 }
402 default:
403 {
404 hessian.resize(data.vals.basis_values.size() * 3, data.vals.basis_values.size() * 3);
405 hessian.setZero();
406 compute_hessian_from_stress<Eigen::Dynamic, 3>(data, hessian);
407 break;
408 }
409 }
410 }
411
412 return hessian;
413 }
414
415 template <typename Derived>
417 {
418 Eigen::MatrixXd hessian;
419
420 if (size() == 2)
421 {
422 switch (data.vals.basis_values.size())
423 {
424 case 3:
425 {
426 hessian.resize(6, 6);
427 hessian.setZero();
428 compute_hessian_from_stress_noad<3, 2>(data, hessian);
429 break;
430 }
431 case 6:
432 {
433 hessian.resize(12, 12);
434 hessian.setZero();
435 compute_hessian_from_stress_noad<6, 2>(data, hessian);
436 break;
437 }
438 case 10:
439 {
440 hessian.resize(20, 20);
441 hessian.setZero();
442 compute_hessian_from_stress_noad<10, 2>(data, hessian);
443 break;
444 }
445 default:
446 {
447 hessian.resize(data.vals.basis_values.size() * 2, data.vals.basis_values.size() * 2);
448 hessian.setZero();
449 compute_hessian_from_stress_noad<Eigen::Dynamic, 2>(data, hessian);
450 break;
451 }
452 }
453 }
454 else // if (size() == 3)
455 {
456 assert(size() == 3);
457 switch (data.vals.basis_values.size())
458 {
459 case 4:
460 {
461 hessian.resize(12, 12);
462 hessian.setZero();
463 compute_hessian_from_stress_noad<4, 3>(data, hessian);
464 break;
465 }
466 case 10:
467 {
468 hessian.resize(30, 30);
469 hessian.setZero();
470 compute_hessian_from_stress_noad<10, 3>(data, hessian);
471 break;
472 }
473 case 20:
474 {
475 hessian.resize(60, 60);
476 hessian.setZero();
477 compute_hessian_from_stress_noad<20, 3>(data, hessian);
478 break;
479 }
480 default:
481 {
482 hessian.resize(data.vals.basis_values.size() * 3, data.vals.basis_values.size() * 3);
483 hessian.setZero();
484 compute_hessian_from_stress_noad<Eigen::Dynamic, 3>(data, hessian);
485 break;
486 }
487 }
488 }
489
490 return hessian;
491 }
492
493 template <typename Derived>
495 const OptAssemblerData &data,
496 const Eigen::MatrixXd &mat,
497 Eigen::MatrixXd &stress,
498 Eigen::MatrixXd &result) const
499 {
500 typedef DScalar2<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 9, 1>, Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 9, 9>> Diff;
501
502 const double t = data.t;
503 const int el_id = data.el_id;
504 if (!derived().real_def_grad(data.global_pts, t, el_id))
505 log_and_throw_error("Stress derivatives are not available in absolute mode (use_rest_pose false)");
506 const Eigen::MatrixXd &local_pts = data.local_pts;
507 const Eigen::MatrixXd &global_pts = data.global_pts;
508 const Eigen::MatrixXd &grad_u_i = data.grad_u_i;
509
510 DiffScalarBase::setVariableCount(size() * size());
511 Eigen::Matrix<Diff, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> def_grad(size(), size());
512
513 Eigen::MatrixXd F = grad_u_i;
514 for (int d = 0; d < size(); ++d)
515 F(d, d) += 1.;
516
517 assert(local_pts.rows() == 1);
518 for (int i = 0; i < size(); ++i)
519 for (int j = 0; j < size(); ++j)
520 def_grad(i, j) = Diff(i + j * size(), F(i, j));
521
522 auto energy = derived().elastic_energy(global_pts, t, el_id, def_grad);
523
524 // Grad is ∂W(F)/∂F_ij
525 Eigen::MatrixXd grad = energy.getGradient().reshaped(size(), size());
526 // Hessian is ∂W(F)/(∂F_ij*∂F_kl)
527 Eigen::MatrixXd hess = energy.getHessian();
528
529 // Stress is S_ij = ∂W(F)/∂F_ij
530 stress = grad;
531 // Compute ∂S_ij/∂F_kl * M_kl, same as M_ij * ∂S_ij/∂F_kl since the hessian is symmetric
532 result = (hess * mat.reshaped(size() * size(), 1)).reshaped(size(), size());
533 }
534
535 template <typename Derived>
537 const OptAssemblerData &data,
538 Eigen::MatrixXd &stress,
539 Eigen::MatrixXd &result) const
540 {
541 typedef DScalar2<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 9, 1>, Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 9, 9>> Diff;
542
543 const double t = data.t;
544 const int el_id = data.el_id;
545 if (!derived().real_def_grad(data.global_pts, t, el_id))
546 log_and_throw_error("Stress derivatives are not available in absolute mode (use_rest_pose false)");
547 const Eigen::MatrixXd &local_pts = data.local_pts;
548 const Eigen::MatrixXd &global_pts = data.global_pts;
549 const Eigen::MatrixXd &grad_u_i = data.grad_u_i;
550
551 DiffScalarBase::setVariableCount(size() * size());
552 Eigen::Matrix<Diff, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> def_grad(size(), size());
553
554 Eigen::MatrixXd F = grad_u_i;
555 for (int d = 0; d < size(); ++d)
556 F(d, d) += 1.;
557
558 assert(local_pts.rows() == 1);
559 for (int i = 0; i < size(); ++i)
560 for (int j = 0; j < size(); ++j)
561 def_grad(i, j) = Diff(i + j * size(), F(i, j));
562
563 auto energy = derived().elastic_energy(global_pts, t, el_id, def_grad);
564
565 // Grad is ∂W(F)/∂F_ij
566 Eigen::MatrixXd grad = energy.getGradient().reshaped(size(), size());
567 // Hessian is ∂W(F)/(∂F_ij*∂F_kl)
568 Eigen::MatrixXd hess = energy.getHessian();
569
570 // Stress is S_ij = ∂W(F)/∂F_ij
571 stress = grad;
572 // Compute ∂S_ij/∂F_kl * S_kl, same as S_ij * ∂S_ij/∂F_kl since the hessian is symmetric
573 result = (hess * stress.reshaped(size() * size(), 1)).reshaped(size(), size());
574 }
575
576 template <typename Derived>
578 const OptAssemblerData &data,
579 const Eigen::MatrixXd &vect,
580 Eigen::MatrixXd &stress,
581 Eigen::MatrixXd &result) const
582 {
583 typedef DScalar2<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 9, 1>, Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 9, 9>> Diff;
584
585 const double t = data.t;
586 const int el_id = data.el_id;
587 if (!derived().real_def_grad(data.global_pts, t, el_id))
588 log_and_throw_error("Stress derivatives are not available in absolute mode (use_rest_pose false)");
589 const Eigen::MatrixXd &local_pts = data.local_pts;
590 const Eigen::MatrixXd &global_pts = data.global_pts;
591 const Eigen::MatrixXd &grad_u_i = data.grad_u_i;
592
593 DiffScalarBase::setVariableCount(size() * size());
594 Eigen::Matrix<Diff, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> def_grad(size(), size());
595
596 Eigen::MatrixXd F = grad_u_i;
597 for (int d = 0; d < size(); ++d)
598 F(d, d) += 1.;
599
600 assert(local_pts.rows() == 1);
601 for (int i = 0; i < size(); ++i)
602 for (int j = 0; j < size(); ++j)
603 def_grad(i, j) = Diff(i + j * size(), F(i, j));
604
605 auto energy = derived().elastic_energy(global_pts, t, el_id, def_grad);
606
607 // Grad is ∂W(F)/∂F_ij
608 Eigen::MatrixXd grad = energy.getGradient().reshaped(size(), size());
609 // Hessian is ∂W(F)/(∂F_ij*∂F_kl)
610 Eigen::MatrixXd hess = energy.getHessian();
611
612 // Stress is S_ij = ∂W(F)/∂F_ij
613 stress = grad;
614 result.resize(hess.rows(), vect.size());
615 for (int i = 0; i < hess.rows(); ++i)
616 if (vect.rows() == 1)
617 // Compute ∂S_ij/∂F_kl * v_k, same as ∂S_ij/∂F_kl * v_i since the hessian is symmetric
618 result.row(i) = vect * hess.row(i).reshaped(size(), size());
619 else
620 // Compute ∂S_ij/∂F_kl * v_l, same as ∂S_ij/∂F_kl * v_j since the hessian is symmetric
621 result.row(i) = (hess.row(i).reshaped(size(), size()) * vect).transpose();
622 }
623
624} // namespace polyfem::assembler
double val
Definition Assembler.cpp:90
ElementAssemblyValues vals
Definition Assembler.cpp:26
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 compute_stress_grad_multiply_stress(const OptAssemblerData &data, Eigen::MatrixXd &stress, Eigen::MatrixXd &result) 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, dim *dim, dim > compute_B_block(const Eigen::Matrix< double, 1, dim > &g) const
Eigen::VectorXd assemble_gradient_full_ad(const NonLinearAssemblerData &data) const
Eigen::MatrixXd assemble_hessian_full_ad(const NonLinearAssemblerData &data) const
Eigen::MatrixXd assemble_hessian_stress_noad(const NonLinearAssemblerData &data) const
Eigen::VectorXd assemble_gradient_stress_noad(const NonLinearAssemblerData &data) const
Eigen::MatrixXd assemble_hessian_stress_ad(const NonLinearAssemblerData &data) const
Eigen::MatrixXd assemble_hessian(const NonLinearAssemblerData &data) const override
void compute_stress_grad_multiply_vect(const OptAssemblerData &data, const Eigen::MatrixXd &vect, Eigen::MatrixXd &stress, Eigen::MatrixXd &result) const override
Eigen::VectorXd assemble_gradient(const NonLinearAssemblerData &data) const override
Eigen::VectorXd assemble_gradient_stress_ad(const NonLinearAssemblerData &data) const
double compute_energy(const NonLinearAssemblerData &data) const override
void compute_stress_grad_multiply_mat(const OptAssemblerData &data, const Eigen::MatrixXd &mat, Eigen::MatrixXd &stress, Eigen::MatrixXd &result) const override
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)
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)
Eigen::MatrixXd pk1_from_cauchy(const Eigen::MatrixXd &stress, const Eigen::MatrixXd &F)
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)
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:73
Automatic differentiation scalar with first-order derivatives.
Definition autodiff.h:112
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