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