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