v0.16.0
Loading...
Searching...
No Matches
EshelbianMatCore.cpp
Go to the documentation of this file.
1/**
2 * @file EshelbianMatCore.cpp
3 * @author your name (you@domain.com)
4 * @brief
5 * @version 0.1
6 * @date 2026-04-14
7 *
8 * @copyright Copyright (c) 2026
9 *
10 */
11
12namespace EshelbianPlasticity {
13
15
17 boost::shared_ptr<MatOps::PhysicalEquations> mat_physical_equations_ptr)
19 matPhysicalEquationsPtr(mat_physical_equations_ptr) {
20 CHK_THROW_MESSAGE(getOptions(), "get options failed");
21 }
22
23 MoFEMErrorCode getOptions() {
25 PetscOptionsBegin(PETSC_COMM_WORLD, "meta_", "", "none");
26 alphaGradU = 0;
27 CHKERR PetscOptionsScalar("-viscosity_alpha_grad_u", "viscosity", "",
28 alphaGradU, &alphaGradU, PETSC_NULLPTR);
29 PetscOptionsEnd();
30 MOFEM_LOG("EP", Sev::inform) << "Mat core grad alpha u = " << alphaGradU;
32 }
33
35 returnOpJacobian(const bool eval_rhs, const bool eval_lhs,
36 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
37 boost::shared_ptr<PhysicalEquations> physics_ptr) override {
38 return matPhysicalEquationsPtr->createOp(matPhysicalEquationsPtr, eval_rhs,
39 eval_lhs, false);
40 }
41
44 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
45 const double alpha) override {
48 }
49
51 std::string row_field, std::string col_field,
52 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha) {
53 return new OpSpatialPhysical_du_du(row_field, col_field,
56 }
57
59
61 const std::string &field_name,
62 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
63 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
64 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
65
66 MoFEMErrorCode integrate(EntData &data);
67
68 private:
69 boost::shared_ptr<ExternalStrainVec> externalStrainVecPtr;
70 std::map<std::string, boost::shared_ptr<ScalingMethod>> scalingMethodsMap;
71 };
72
74 const std::string &field_name,
75 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
76 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
77 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv) {
79 external_strain_vec_ptr, smv);
80 }
81
82protected:
83 boost::shared_ptr<MatOps::PhysicalEquations> matPhysicalEquationsPtr;
84 double alphaGradU = 0;
85
87
88 OpSpatialPhysical(const std::string &field_name,
89 boost::weak_ptr<MatOps::PhysicalEquations> physics_ptr,
90 const double alpha, const double alpha_grad_u)
91 : OpAssembleVolume(field_name, nullptr, OPROW), alphaU(alpha),
92 alphaGradU(alpha_grad_u), physicsPtr(physics_ptr) {}
93
94 MoFEMErrorCode integrate(EntData &data);
95
96 private:
97 const double alphaU;
98 const double alphaGradU;
99 boost::shared_ptr<MatOps::PhysicalEquations>
100 physicsPtr; ///< material physical equations
101 };
102
105 std::string row_field, std::string col_field,
106 boost::shared_ptr<MatOps::PhysicalEquations> physics_ptr,
107 const double alpha, const double alpha_grad_u)
108 : OpAssembleVolume(row_field, col_field, nullptr, OPROWCOL, false),
109 alphaU(alpha), alphaGradU(alpha_grad_u), physicsPtr(physics_ptr) {
110 sYmm = false;
111 }
112
113 MoFEMErrorCode integrate(EntData &row_data, EntData &col_data);
114
115 private:
116 const double alphaU;
117 const double alphaGradU;
118 boost::shared_ptr<MatOps::PhysicalEquations>
119 physicsPtr; ///< material physical equations
120 };
121};
122
123MoFEMErrorCode
126
127 auto physics_ptr = physicsPtr;
128 auto mat_ops_data = physics_ptr->matOpsDataPtr;
129
132
133 int nb_dofs = data.getIndices().size();
134 int nb_integration_pts = data.getN().size1();
135 auto v = getVolume();
136 auto t_w = getFTensor0IntegrationWeight();
137
138 auto t_P = getFTensor2FromMat<3, 3, -1, DL>(
139 mat_ops_data->getCommonDataPtr("PAtPts"));
140 auto t_approx_P_adjoint_log_du = getFTensor1FromMat<size_symm, -1, DL>(
141 mat_ops_data->getCommonDataPtr("adjointPdUAtPts"));
142 auto t_diff_u = getFTensor4FromMat<3, 3, 3, 3, -1, DL>(
143 mat_ops_data->getCommonDataPtr("diffStretchH1AtPts"));
144 auto t_dot_log_u = getFTensor2SymmetricFromMat<3, -1, DL>(
145 mat_ops_data->getCommonDataPtr("logStretchDotTensorAtPts"));
146 auto t_grad_dot_log_u = getFTensor2FromMat<size_symm, 3, -1, DL>(
147 mat_ops_data->getCommonDataPtr("gradLogStretchDotTensorAtPts"));
148
149 FTENSOR_INDEX(3, i);
150 FTENSOR_INDEX(3, j);
151 FTENSOR_INDEX(3, k);
152 FTENSOR_INDEX(3, l);
153 FTENSOR_INDEX(3, m);
154 FTENSOR_INDEX(3, n);
155
156 auto get_ftensor2 = [](auto &v) {
158 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
159 };
160
161 int nb_base_functions = data.getN().size2();
162 auto t_row_base_fun = data.getFTensor0N();
163 auto t_row_grad_fun = data.getFTensor1DiffN<3>();
164 for (int gg = 0; gg != nb_integration_pts; ++gg) {
165 double a = v * t_w;
166 auto t_nf = get_ftensor2(nF);
167
169 t_Ldiff_u(i, j, L) = t_diff_u(i, j, k, l) * t_L(k, l, L);
170
172 t_residual(L) =
173 a * (t_approx_P_adjoint_log_du(L) - t_Ldiff_u(i, j, L) * t_P(i, j));
174 t_residual(L) += (a * alphaU) * (t_dot_log_u(i, j) * t_L(i, j, L));
175
177 t_grad_residual(L, i) = (a * alphaGradU) * t_grad_dot_log_u(L, i);
178
179 int bb = 0;
180 for (; bb != nb_dofs / size_symm; ++bb) {
181 t_nf(L) -= t_row_base_fun * t_residual(L);
182 t_nf(L) += t_row_grad_fun(i) * t_grad_residual(L, i);
183 ++t_nf;
184 ++t_row_base_fun;
185 ++t_row_grad_fun;
186 }
187 for (; bb != nb_base_functions; ++bb) {
188 ++t_row_base_fun;
189 ++t_row_grad_fun;
190 }
191
192 ++t_w;
193 ++t_approx_P_adjoint_log_du;
194 ++t_P;
195 ++t_diff_u;
196 ++t_dot_log_u;
197 ++t_grad_dot_log_u;
198 }
200}
201
202
203MoFEMErrorCode
205 EntData &col_data) {
207
211 auto t_diff = FTensor::DiffTensor<double>();
212 constexpr auto t_kd_sym = FTensor::Kronecker_Delta_symmetric<int>();
213
214 int nb_integration_pts = row_data.getN().size1();
215 int row_nb_dofs = row_data.getIndices().size();
216 int col_nb_dofs = col_data.getIndices().size();
217
218 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
220 size_symm>(
221
222 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
223 &m(r + 0, c + 4), &m(r + 0, c + 5),
224
225 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
226 &m(r + 1, c + 4), &m(r + 1, c + 5),
227
228 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
229 &m(r + 2, c + 4), &m(r + 2, c + 5),
230
231 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
232 &m(r + 3, c + 4), &m(r + 3, c + 5),
233
234 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
235 &m(r + 4, c + 4), &m(r + 4, c + 5),
236
237 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
238 &m(r + 5, c + 4), &m(r + 5, c + 5)
239
240 );
241 };
242
243 FTENSOR_INDEX(3, i);
244 FTENSOR_INDEX(3, j);
245 FTENSOR_INDEX(3, k);
246 FTENSOR_INDEX(3, l);
247 FTENSOR_INDEX(3, m);
248 FTENSOR_INDEX(3, n);
249
250 MatrixDouble dP;
251
252 auto get_dP = [&]() {
253 auto get_tensor_for_dP =
254 MatrixSizeHelper<GetFTensor2FromMatType<size_symm, size_symm, -1, DL>,
255 DL>::size(dP, nb_integration_pts);
256
257 auto mat_ops_data = physicsPtr->matOpsDataPtr;
258
259 auto t_P = getFTensor2FromMat<3, 3, -1, DL>(
260 mat_ops_data->getCommonDataPtr("PAtPts"));
261 auto t_P_du = getFTensor4FromMat<3, 3, 3, 3, -1, DL>(
262 mat_ops_data->getCommonDataPtr("PAtPts_du"));
263 auto t_approx_P_adjoint_dstretch = getFTensor2FromMat<3, 3, -1, DL>(
264 mat_ops_data->getCommonDataPtr("adjointPdstretchAtPts"));
265 auto t_u = getFTensor2FromMat<3, 3, -1, DL>(
266 mat_ops_data->getCommonDataPtr("stretchH1AtPts"));
267 auto t_diff_u = getFTensor4FromMat<3, 3, 3, 3, -1, DL>(
268 mat_ops_data->getCommonDataPtr("diffStretchH1AtPts"));
269 auto t_grad_h1 = getFTensor2FromMat<3, 3, -1, DL>(
270 mat_ops_data->getCommonDataPtr("wGradH1AtPts"));
271 auto t_eigen_vals = getFTensor1FromMat<3, -1, DL>(
272 mat_ops_data->getCommonDataPtr("eigenVals"));
273 auto t_eigen_vecs = getFTensor2FromMat<3, 3, -1, DL>(
274 mat_ops_data->getCommonDataPtr("eigenVecs"));
275
276 auto ts_a = getTSa();
278
279 auto t_dP = get_tensor_for_dP();
280 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
281
283
285 case LARGE_ROT:
286 case MODERATE_ROT:
287 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
288 break;
289 default:
290 t_h1(i, j) = t_kd(i, j);
291 }
292
294 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
295 t_dP(L, J) =
296 -t_Ldiff_u(i, j, L) * (t_P_du(i, j, k, l) * t_Ldiff_u(k, l, J));
297 t_dP(L, J) += (ts_a * alphaU) *
298 (t_L(i, j, L) * (t_diff(i, j, k, l) * t_L(k, l, J)));
299
303 t_deltaP(i, j) =
304 t_approx_P_adjoint_dstretch(i, j) - t_P(i, k) * t_h1(j, k);
306 t_deltaP_sym(i, j) = (t_deltaP(i, j) || t_deltaP(j, i));
307 t_deltaP_sym(i, j) /= 2.0;
308 auto nb_uniq =
309 getUniqNb<3>(getVectorAdaptor(&t_eigen_vals(0), 3),
311 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
312 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
313 EshelbianCore::dd_f, t_deltaP_sym, nb_uniq);
314 t_dP(L, J) += t_L(i, j, L) * (t_diff2_uP2(i, j, k, l) * t_L(k, l, J));
315 }
316
317 ++t_P;
318 ++t_dP;
319 ++t_P_du;
320 ++t_approx_P_adjoint_dstretch;
321 ++t_u;
322 ++t_diff_u;
323 ++t_grad_h1;
324 ++t_eigen_vals;
325 ++t_eigen_vecs;
326 }
327
328 return get_tensor_for_dP();
329 };
330
331 int row_nb_base_functions = row_data.getN().size2();
332 auto t_row_base_fun = row_data.getFTensor0N();
333 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
334
335 auto t_dP = get_dP();
336 auto v = getVolume();
337 auto ts_a = getTSa();
338 auto t_w = getFTensor0IntegrationWeight();
339
340 for (int gg = 0; gg != nb_integration_pts; ++gg) {
341 double a = v * t_w;
342
343 int rr = 0;
344 for (; rr != row_nb_dofs / size_symm; ++rr) {
345 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
346 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
347 auto t_m = get_ftensor2(K, size_symm * rr, 0);
348 for (int cc = 0; cc != col_nb_dofs / size_symm; ++cc) {
349 const double b = a * t_row_base_fun * t_col_base_fun;
350 t_m(L, J) -= b * t_dP(L, J);
351 const double c = (a * alphaGradU * ts_a) *
352 (t_row_grad_fun(i) * t_col_grad_fun(i));
353 t_m(L, J) += c * t_kd_sym(L, J);
354 ++t_m;
355 ++t_col_base_fun;
356 ++t_col_grad_fun;
357 }
358 ++t_row_base_fun;
359 ++t_row_grad_fun;
360 }
361
362 for (; rr != row_nb_base_functions; ++rr) {
363 ++t_row_base_fun;
364 ++t_row_grad_fun;
365 }
366
367 ++t_w;
368 ++t_dP;
369 }
371}
372
375 const std::string &field_name,
376 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
377 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
378 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
379 : OpAssembleVolume(field_name, data_ptr, OPROW),
380 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap{smv} {}
381
383 EntData &data) {
385
386
387
388 double time = OpAssembleVolume::getFEMethod()->ts_t;
391 }
392 // get entity of tet
394 // iterate over all block data
395
396 for (auto &ext_strain_block : (*externalStrainVecPtr)) {
397 auto block_name = "(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
398 std::regex reg_name(block_name);
399 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
400 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
401 "Analytical external strain not implemented for Neo-Hookean "
402 "material.");
403 }
404 // check if finite element entity is part of the EXTERNALSTRAIN block
405 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
406 double scale = 1;
407 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
408 scalingMethodsMap.end()) {
409 scale *=
410 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
411 } else {
412 MOFEM_LOG("SELF", Sev::warning)
413 << "No scaling method found for " << ext_strain_block.blockName;
414 }
415
416 // get ExternalStrain block data
417 double external_strain_val = scale * ext_strain_block.val;
418 double K = ext_strain_block.bulkModulusK;
419
422 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
423
424 int nb_dofs = data.getIndices().size();
425 int nb_integration_pts = data.getN().size1();
426 auto vol = getVolume();
427 auto t_w = getFTensor0IntegrationWeight();
428
435
436 int nb_base_functions = data.getN().size2();
437 auto t_row_base_fun = data.getFTensor0N();
438
439 const double bulk_modulus = K;
440 const double diag_val =
441 EshelbianCore::inv_f(std::exp(external_strain_val));
442 auto fun_neohookean_bulk = [](double K, double tr) { return K * tr; };
443 const double sigma_J = fun_neohookean_bulk(bulk_modulus, 3 * diag_val);
444
445 for (int gg = 0; gg != nb_integration_pts; ++gg) {
446 double a = vol * t_w;
447 ++t_w;
448
450 t_residual(L) = (t_L(i, j, L) * t_kd(i, j)) * sigma_J;
451 t_residual(L) *= a;
452
453 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
454 int bb = 0;
455 for (; bb != nb_dofs / size_symm; ++bb) {
456 t_nf(L) -= t_row_base_fun * t_residual(L);
457 ++t_nf;
458 ++t_row_base_fun;
459 }
460 for (; bb != nb_base_functions; ++bb) {
461 ++t_row_base_fun;
462 }
463 }
464 }
465 }
467}
468
469} // namespace EshelbianPlasticity
#define FTENSOR_INDEX(DIM, I)
constexpr double a
constexpr int SPACE_DIM
Fourth-order differential tensor symmetric in both index pairs.
Kronecker Delta class symmetric.
Kronecker Delta class.
Mapping from symmetric tensor indices to packed storage index.
#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 ...
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#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, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto getDiffDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, Fun< double > dd_f, C &&t_S, const int nb)
Get the Diff Diff Mat object.
EntitiesFieldData::EntData EntData
ForcesAndSourcesCore::UserDataOperator UserDataOperator
static constexpr auto size_symm
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static enum StretchSelector stretchSelector
static enum RotSelector gradApproximator
static PetscBool physicalTimeFlg
static double currentPhysicalTime
static boost::function< double(const double)> f
static boost::function< double(const double)> dd_f
static boost::function< double(const double)> d_f
static boost::function< double(const double)> inv_f
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
OpSpatialPhysicalExternalStrain(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, std::map< std::string, boost::shared_ptr< ScalingMethod > > smv)
OpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< MatOps::PhysicalEquations > physics_ptr, const double alpha, const double alpha_grad_u)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
boost::shared_ptr< MatOps::PhysicalEquations > physicsPtr
material physical equations
boost::shared_ptr< MatOps::PhysicalEquations > physicsPtr
material physical equations
OpSpatialPhysical(const std::string &field_name, boost::weak_ptr< MatOps::PhysicalEquations > physics_ptr, const double alpha, const double alpha_grad_u)
VolUserDataOperator * returnOpSpatialPhysicalExternalStrain(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, std::map< std::string, boost::shared_ptr< ScalingMethod > > smv)
VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha) override
VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
MatPhysicalEquations(boost::shared_ptr< MatOps::PhysicalEquations > mat_physical_equations_ptr)
boost::shared_ptr< MatOps::PhysicalEquations > matPhysicalEquationsPtr
UserDataOperator * returnOpJacobian(const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr) override
bool sYmm
If true assume that matrix is symmetric structure.
Data on single entity (This is passed as argument to DataOperator::doWork)
EntityHandle getFEEntityHandle() const
Return finite element entity handle.
auto getFTensor0IntegrationWeight()
Get integration weights.
@ OPROW
operator doWork function is executed on FE rows
@ OPROWCOL
operator doWork is executed on FE rows &columns
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
PetscReal ts_t
Current time value.
VectorDouble nF
local right hand side vector
double scale
Definition plastic.cpp:124