PolyFEM
Loading...
Searching...
No Matches
HGODispersion.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace polyfem::assembler
7{
8 // Modified GOH anisotropic fiber model: adds fiber dispersion (kappa) and a
9 // smooth (C-infinity) distension/compression switch, built on the FULL
10 // invariants I1 = tr(C) and I4 = a0.C a0. It is intentionally kept separate
11 // from HGOFiber (the classic aligned HGO-2000 decoupled form, isochoric I4,
12 // hard tension-only cutoff), which is left unchanged. Implemented energy:
13 //
14 // psi = (k1 / (2 k2)) * X(E4) * ( exp(k2 * E4^2) - 1 )
15 // E4 = kappa * I1 + (1 - d*kappa) * I4 - 1 (d = spatial dimension)
16 // X = 1 / ( 1 + exp(-k_chi * E4) ) (logistic, centered at E4 = 0)
17 //
18 // Parameter naming: k1 == manuscript a_f, k2 == manuscript b_f (names kept to
19 // match HGOFiber and existing inputs).
20 class HGODispersion : public GenericFiber<HGODispersion>
21 {
22 public:
24
25 // sets material params
26 void add_multimaterial(const int index, const json &params, const Units &units, const std::string &root_path) override;
27
28 std::string name() const override { return "HGODispersion"; }
29 std::map<std::string, ParamFunc> parameters() const override;
30
31 template <typename T>
33 const RowVectorNd &p,
34 const double t,
35 const int el_id,
36 const DefGradMatrix<T> &def_grad) const
37 {
38 const double k1 = k1_(p, t, el_id); // fiber stiffness (manuscript a_f)
39 const double k2 = k2_(p, t, el_id); // exp. stiffening (manuscript b_f)
40 const double kappa = kappa_(p, t, el_id); // dispersion in [0, 1/d]; absent => 0
41
42 // Modified-anisotropy GOH invariant from the FULL invariants:
43 // E4 = kappa * I1 + (1 - d*kappa) * I4 - 1
44 // The (1 - d*kappa) factor keeps the generalized structure tensor
45 // unit-trace; at kappa = 0 this collapses to I4 - 1 (aligned limit).
46 const double d = static_cast<double>(this->size());
47 const T i1 = I1(def_grad);
48 const T i4 = I4(p, t, el_id, def_grad);
49 const T E4 = kappa * i1 + (1.0 - d * kappa) * i4 - 1.0;
50
51 // Smooth logistic distension/compression switch, centered at E4 = 0
52 // (unloaded state I1 = d, I4 = 1 => E4 = 0). Replaces the C0 hard
53 // tension-only cutoff so the energy (and its autodiff gradient and
54 // Hessian) is C-infinity.
55 const T chi = 1.0 / (1.0 + exp(-k_chi_ * E4));
56
57 return (k1 / (2.0 * k2)) * chi * (exp(k2 * E4 * E4) - 1.0);
58 }
59
60 private:
61 // Full first invariant I1 = tr(C) = tr(F^T F) = sum_ij F_ij^2 (NOT isochoric).
62 template <typename T>
63 T I1(const DefGradMatrix<T> &def_grad) const
64 {
65 T res = T(0);
66 for (int i = 0; i < def_grad.rows(); ++i)
67 for (int j = 0; j < def_grad.cols(); ++j)
68 res += def_grad(i, j) * def_grad(i, j);
69 return res;
70 }
71
72 // Full fourth invariant I4 = a0 . C a0 with a0 normalized to unit length
73 // (normalize = true) and the FULL C (isocoric = false, no J^{-2/3}).
74 // Reuses the tested GenericFiber::I4Bar_generic machinery; normalizing
75 // makes the term independent of the input fiber vector's magnitude.
76 template <typename T>
77 T I4(const RowVectorNd &p,
78 const double t,
79 const int el_id,
80 const DefGradMatrix<T> &def_grad) const
81 {
82 return this->I4Bar_generic(p, t, el_id, def_grad, /*normalize=*/true, /*isocoric=*/false);
83 }
84
85 GenericMatParam k1_; // fiber stiffness (manuscript a_f)
86 GenericMatParam k2_; // exp. stiffening (manuscript b_f)
87 GenericMatParam kappa_; // fiber dispersion kappa (in [0, 1/d]); absent => 0
88 double k_chi_ = 100.0; // logistic smoothness k_X; manuscript fixes 100
89 };
90} // namespace polyfem::assembler
T I4Bar_generic(const RowVectorNd &p, const double t, const int el_id, const DefGradMatrix< T > &def_grad, const bool normalize, const bool isocoric) const
T I4(const RowVectorNd &p, const double t, const int el_id, const DefGradMatrix< T > &def_grad) const
std::map< std::string, ParamFunc > parameters() const override
T elastic_energy(const RowVectorNd &p, const double t, const int el_id, const DefGradMatrix< T > &def_grad) const
T I1(const DefGradMatrix< T > &def_grad) const
std::string name() const override
void add_multimaterial(const int index, const json &params, const Units &units, const std::string &root_path) override
Used for test only.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3 > DefGradMatrix
nlohmann::json json
Definition Common.hpp:9
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd
Definition Types.hpp:13