PolyFEM
Loading...
Searching...
No Matches
OgdenElasticity.tpp
Go to the documentation of this file.
1#pragma once
2#include "OgdenElasticity.hpp"
3
4#include <polyfem/autogen/auto_eigs.hpp>
5
6namespace polyfem::assembler
7{
8 template <typename T>
9 T UnconstrainedOgdenElasticity::elastic_energy(
10 const RowVectorNd &p,
11 const double t,
12 const int el_id,
13 const DefGradMatrix<T> &def_grad) const
14 {
15 Eigen::Matrix<T, Eigen::Dynamic, 1, 0, 3, 1> eigs;
16
17 if (size() == 2)
18 {
19 // No need to symmetrize F to compute eigen values analytically
20 autogen::eigs_2d<T>(def_grad, eigs);
21 }
22 else
23 {
24 assert(size() == 3);
25 // Symmetrize F to compute eigen values analytically
26 autogen::eigs_3d<T>(def_grad.transpose() * def_grad, eigs);
27 eigs = sqrt(eigs.array());
28 }
29
30 const T J = utils::determinant(def_grad);
31 const T Jdenom = pow(J, -1. / size());
32
33 for (long i = 0; i < eigs.size(); ++i)
34 eigs(i) = eigs(i) * Jdenom;
35
36 auto val = T(0);
37 for (long N = 0; N < alphas_.size(); ++N)
38 {
39 auto tmp = T(-size());
40 const double alpha = alphas_[N](p, t, el_id);
41 const double mu = mus_[N](p, t, el_id);
42
43 for (long i = 0; i < eigs.size(); ++i)
44 tmp += pow(eigs(i), alpha);
45
46 val += 2 * mu / (alpha * alpha) * tmp;
47 }
48
49 for (long N = 0; N < Ds_.size(); ++N)
50 {
51 const double D = Ds_[N](p, t, el_id);
52
53 val += 1. / D * pow(J - T(1), 2 * (N + 1));
54 }
55
56 return val;
57 }
58
59 template <typename T>
60 T IncompressibleOgdenElasticity::elastic_energy(
61 const RowVectorNd &p,
62 const double t,
63 const int el_id,
64 const DefGradMatrix<T> &def_grad) const
65 {
66 Eigen::Matrix<T, Eigen::Dynamic, 1, 0, 3, 1> eigs;
67
68 const T J = polyfem::utils::determinant(def_grad);
69 const T log_J = log(J);
70
71 const auto F_tilde = def_grad / pow(J, 1.0 / size());
72 const auto C_tilde = F_tilde * F_tilde.transpose();
73
74 if (size() == 2)
75 autogen::eigs_2d<T>(C_tilde, eigs);
76 else if (size() == 3)
77 autogen::eigs_3d<T>(C_tilde, eigs);
78 else
79 assert(false);
80 eigs = sqrt(eigs.array());
81
82 T val = T(0);
83 for (long i = 0; i < num_terms(); ++i)
84 {
85 const double c = coefficients_[i](p, t, el_id);
86 const double m = expoenents_[i](p, t, el_id);
87
88 auto tmp = T(-size());
89 for (long j = 0; j < eigs.size(); ++j)
90 tmp += pow(eigs(j), m);
91
92 val += c / (m * m) * tmp;
93 }
94 val += 0.5 * bulk_modulus_(p, t, el_id) * log_J * log_J;
95
96 return val;
97 }
98} // namespace polyfem::assembler