v0.16.3
Loading...
Searching...
No Matches
MatMooneyRivlinWriggersEq63.cpp
Go to the documentation of this file.
1/**
2 * @file MatMooneyRivlinWriggersEq63.cpp
3 * @author your name (you@domain.com)
4 * @brief
5 * @version 0.1
6 * @date 2026-03-26
7 *
8 * @copyright Copyright (c) 2026
9 *
10 */
11
12namespace MatOps {
13
14template <int DIM>
16 using MatElasticImpl<DIM>::MatElasticImpl;
17
19
20 MoFEMErrorCode getOptions(MoFEM::Interface *m_field_ptr = nullptr) override {
22
23 MOFEM_LOG_CHANNEL("WORLD");
24
25 PetscOptionsBegin(PETSC_COMM_WORLD, "mooneyrivlin_", "", "none");
26 CHKERR PetscOptionsScalar("-alpha", "Alpha", "", alpha, &alpha,
27 PETSC_NULLPTR);
28 CHKERR PetscOptionsScalar("-beta", "Beta", "", beta, &beta, PETSC_NULLPTR);
29
30 CHKERR PetscOptionsScalar("-lambda", "Lambda", "", lambda, &lambda,
31 PETSC_NULLPTR);
32
33 CHKERR PetscOptionsScalar("-epsilon", "Epsilon", "", epsilon, &epsilon,
34 PETSC_NULLPTR);
35 PetscOptionsEnd();
36
37 if (!std::isfinite(epsilon) ||
38 std::abs(epsilon) <= std::sqrt(std::numeric_limits<double>::epsilon()))
39 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
40 "Mooney-Rivlin epsilon must be finite and nonzero");
41
42 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "Default Mooney-Rivlin parameters:")
43 << " alpha = " << alpha << " beta = " << beta << " lambda = " << lambda
44 << " epsilon = " << epsilon;
46
47 std::string block_name = "MAT_MOONEY_RIVLIN";
48
49 for (auto &m :
50
51 m_field_ptr->getInterface<MeshsetsManager>()->
52
53 getCubitMeshsetPtr(
54 std::regex((boost::format("%s(.*)") % block_name).str()))
55
56 ) {
57
58 std::vector<double> block_data;
59 CHKERR m->getAttributes(block_data);
60 auto get_block_ents = [&]() {
61 Range ents;
62 CHK_MOAB_THROW(m_field_ptr->get_moab().get_entities_by_handle(
63 m->meshset, ents, true),
64 "can not get block entities");
65 return ents;
66 };
67
68 CHKERR addBlockParameters(*m_field_ptr, m->getName(), m->getMeshsetId(),
69 get_block_ents(), block_data);
70 }
71
73 };
74
76 addBlockParameters(MoFEM::Interface &, const std::string &block_name, int,
77 const Range &block_entities,
78 const std::vector<double> &block_data) override {
80
81 if (block_data.size() < 4) {
83 "Expected that block has four attributes (alpha, "
84 "beta, lambda, epsilon), but given " +
85 std::to_string(block_data.size()));
86 }
87 if (!std::isfinite(block_data[3]) ||
88 std::abs(block_data[3]) <=
89 std::sqrt(std::numeric_limits<double>::epsilon()))
90 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
91 "MAT_MOONEY_RIVLIN epsilon must be finite and nonzero");
92 std::vector<double> params = {block_data[0], block_data[1], block_data[2],
93 block_data[3]};
94
95 A::paramVecByRange.push_back({block_entities, params});
96
97 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock for Mooney-Rivlin")
98 << block_name << " alpha = " << params[0] << " beta = " << params[1]
99 << " lambda = " << params[2] << " epsilon = " << params[3];
100
102 }
103
104 MoFEMErrorCode setParams(FEMethod *fe_ptr, int gg) override {
105 (void)gg;
106 const auto ent = fe_ptr->getFEEntityHandle();
107 for (auto &[range, param_vec] : A::paramVecByRange) {
108 if (std::find(range.begin(), range.end(), ent) != range.end()) {
109 set_param_vec(A::tAg, param_vec.size(), param_vec.data());
110 return 0;
111 }
112 }
113 set_param_vec(A::tAg, defaultMaterialParameters.size(),
115 return 0;
116 }
117
120
121 A::matOpsDataPtr->insertCommonData("grad", MatrixDouble());
122 A::matOpsDataPtr->insertCommonData("P", MatrixDouble());
123 A::matOpsDataPtr->insertCommonData("P_dF", MatrixDouble());
124
125 A::matOpsDataPtr->insertActiveData("F", MatrixDouble());
126 A::matOpsDataPtr->insertDependentData("P", MatrixDouble());
127 A::matOpsDataPtr->insertDependentData("energy", MatrixDouble());
128 A::matOpsDataPtr->insertDependentDerivativesData("P_dF", MatrixDouble());
129 A::matOpsDataPtr->insertDependentDerivativesData("energy_dF",
130 MatrixDouble());
131
132 A::matOpsDataPtr->getActiveDataPtr("F")->resize(DIM, DIM, false);
133 A::matOpsDataPtr->getDependentDataPtr("P")->resize(DIM, DIM, false);
134 A::matOpsDataPtr->getDependentDataPtr("energy")->resize(1, 1, false);
135 A::matOpsDataPtr->getDependentDerivativesDataPtr("energy_dF")
136 ->resize(1, DIM * DIM, false);
137
138 auto t_F = getFTensor2FromPtr<DIM, DIM>(
139 A::matOpsDataPtr->getActiveDataPtr("F")->data().data());
140 auto t_P = getFTensor2FromPtr<DIM, DIM>(
141 A::matOpsDataPtr->getDependentDataPtr("P")->data().data());
142 auto energy_ptr = A::matOpsDataPtr->getDependentDataPtr("energy");
143
145
146 FTENSOR_INDEX(DIM, i);
147 FTENSOR_INDEX(DIM, j);
148 FTENSOR_INDEX(DIM, I);
149 FTENSOR_INDEX(DIM, J);
150 FTENSOR_INDEX(DIM, k);
151 FTENSOR_INDEX(DIM, K);
152
153 t_F(i, J) = 0;
154
160 adouble ta_Bj, A, B, ta_energy;
161
162 adouble det_aF;
164
165 trace_on(A::tAg);
166 auto p_alpha = mkparam(alpha);
167 auto p_beta = mkparam(beta);
168 auto p_lambda = mkparam(lambda);
169 auto p_epsilon = mkparam(epsilon);
170 const auto ta_alpha = 1 * p_alpha;
171 const auto ta_beta = 1 * p_beta;
172 const auto ta_lambda = 1 * p_lambda;
173 const auto ta_epsilon = 1 * p_epsilon;
174
175 ta_F(i, J) <<= t_F(i, J);
176 // assume that gradient from approximated displacement, that why we add diagonal
178 ta_F(i, J) += t_kd(i, J);
179 }
180
181 det_aF = determinantTensor(ta_F);
182 CHKERR invertTensor(ta_F, det_aF, ta_invF);
183
184 ta_Cof(i, I) = det_aF * ta_invF(I, i);
185
186 A = ta_F(k, K) * ta_F(k, K);
187 B = ta_Cof(k, K) * ta_Cof(k, K);
188
189 ta_BF(i, I) = 4 * ta_alpha * (A * ta_F(i, I));
190 ta_BCof(i, I) = 4 * ta_beta * (B * ta_Cof(i, I));
191 ta_Bj = (-12 * ta_alpha - 24 * ta_beta) / det_aF +
192 0.5 * (ta_lambda / ta_epsilon) *
193 (pow(det_aF, ta_epsilon - 1) - pow(det_aF, -ta_epsilon - 1));
194
195 ta_P(i, I) = ta_BF(i, I);
196 ta_P(i, I) += (levi_civita(i, j, k) * ta_BCof(j, J)) *
197 (levi_civita(I, J, K) * ta_F(k, K));
198 ta_P(i, I) += ta_Cof(i, I) * ta_Bj;
199
200 ta_energy = ta_alpha * A * A + ta_beta * B * B +
201 (-12 * ta_alpha - 24 * ta_beta) * log(det_aF) +
202 0.5 * (ta_lambda / (ta_epsilon * ta_epsilon)) *
203 (pow(det_aF, ta_epsilon) + pow(det_aF, -ta_epsilon) - 2.) -
204 (DIM * DIM) * (ta_alpha + ta_beta);
205
206 // Set dependent variables to ADOL-C
207 ta_P(i, I) >>= t_P(i, I);
208 ta_energy >>= (*energy_ptr)(0, 0);
209
210 trace_off();
211
213 }
214
215protected:
216 double alpha = 1;
217 double beta = 1;
218 double lambda = 1;
219 double epsilon = 2;
220 std::vector<double> defaultMaterialParameters = {alpha, beta, lambda,
221 epsilon};
222};
223
224template <>
225boost::shared_ptr<PhysicalEquations>
226createMatOpsPhysicalEquationsPtr<ELASTICITY::MOONEYRIVLINWRIGGERSEQ63,
227 MODEL_3D>(
228 boost::shared_ptr<MatOpsData> mat_ops_data_ptr, int tag) {
229 return boost::make_shared<MatMooneyRivlinWriggersEq63<3>>(mat_ops_data_ptr,
230 tag);
231}
232
233} // namespace MatOps
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
Kronecker Delta class.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_INVALID_DATA
Definition definitions.h:36
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr auto t_kd
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
@ MODEL_3D
Definition MatOps.hpp:209
boost::shared_ptr< PhysicalEquations > createMatOpsPhysicalEquationsPtr(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
static MoFEMErrorCode invertTensor(FTensor::Tensor2< T1, DIM, DIM > &t, T2 &det, FTensor::Tensor2< T3, DIM, DIM > &inv_t)
static auto determinantTensor(FTensor::Tensor2< T, DIM, DIM > &t)
Calculate the determinant of a tensor of rank DIM.
constexpr IntegrationType I
FTensor::Index< 'm', 3 > m
MoFEMErrorCode getOptions(MoFEM::Interface *m_field_ptr=nullptr) override
MoFEMErrorCode setParams(FEMethod *fe_ptr, int gg) override
MoFEMErrorCode addBlockParameters(MoFEM::Interface &, const std::string &block_name, int, const Range &block_entities, const std::vector< double > &block_data) override
static bool useDeformationGradient
Otherwise the displacement gradient is supplied and I is added.
Definition MatOps.hpp:189
std::vector< std::pair< Range, std::vector< double > > > paramVecByRange
Definition MatOps.hpp:174
boost::shared_ptr< MatOpsData > matOpsDataPtr
Definition MatOps.hpp:176
Deprecated interface functions.
Structure for user loop methods on finite elements.
EntityHandle getFEEntityHandle() const
Get the entity handle of the current finite element.
Interface for managing meshsets containing materials and boundary conditions.