v0.16.3
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::MatPiolaResponse> mat_physical_equations_ptr,
18 const MaterialModel material_model, const Features features)
19 : PhysicalEquations(material_model, features),
20 matPhysicalEquationsPtr(mat_physical_equations_ptr) {
23 "Mat core physical equations are not allocated");
24 CHK_THROW_MESSAGE(getOptions(), "get options failed");
25 }
26
27 MoFEMErrorCode getOptions() {
29 PetscOptionsBegin(PETSC_COMM_WORLD, "meta_", "", "none");
30 alphaGradU = 0;
31 CHKERR PetscOptionsScalar("-viscosity_alpha_grad_u",
32 "Logarithmic-stretch-gradient rate viscosity", "",
33 alphaGradU, &alphaGradU, PETSC_NULLPTR);
34 PetscOptionsEnd();
35 MOFEM_LOG("EP", Sev::inform)
36 << "alphaGradU (-meta_viscosity_alpha_grad_u), "
37 "logarithmic-stretch-gradient rate viscosity: "
38 << alphaGradU;
40 }
41
43 returnOpJacobian(const bool eval_rhs, const bool eval_lhs,
44 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
45 boost::shared_ptr<PhysicalEquations> physics_ptr) override {
46 return matPhysicalEquationsPtr->createOp(matPhysicalEquationsPtr, eval_rhs,
47 eval_lhs, false);
48 }
49
51
53 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
54 boost::shared_ptr<MatOps::MatElastic> physics_ptr,
55 boost::shared_ptr<double> total_helmholtz_free_energy_ptr)
56 : VolUserDataOperator(NOSPACE, OPSPACE), dataAtPts(data_ptr),
57 physicsPtr(physics_ptr),
58 totalHelmholtzFreeEnergyPtr(total_helmholtz_free_energy_ptr) {
59 if (!dataAtPts)
61 "Mat core energy data is not allocated");
62 if (!physicsPtr)
64 "Mat core physical equations are not allocated");
65 }
66
67 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
68
69 private:
70 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
71 boost::shared_ptr<MatOps::MatElastic> physicsPtr;
72 boost::shared_ptr<double> totalHelmholtzFreeEnergyPtr;
73 };
74
77 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
78 const double alpha) override {
81 }
82
84 std::string row_field, std::string col_field,
85 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
86 const double alpha) override {
87 return new OpSpatialPhysical_du_du(
88 row_field, col_field, matPhysicalEquationsPtr, alpha, alphaGradU);
89 }
90
92
94 const std::string &field_name,
95 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
96 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
97 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
98
99 MoFEMErrorCode integrate(EntData &data);
100
101 private:
102 boost::shared_ptr<ExternalStrainVec> externalStrainVecPtr;
103 std::map<std::string, boost::shared_ptr<ScalingMethod>> scalingMethodsMap;
104 };
105
107 const std::string &field_name,
108 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
109 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
110 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv) override {
111 return new OpSpatialPhysicalExternalStrain(field_name, data_ptr,
112 external_strain_vec_ptr, smv);
113 }
114
115protected:
116 boost::shared_ptr<MatOps::MatPiolaResponse> matPhysicalEquationsPtr;
117 double alphaGradU = 0;
118
120
121 OpSpatialPhysical(const std::string &field_name,
122 boost::weak_ptr<MatOps::PhysicalEquations> physics_ptr,
123 const double alpha, const double alpha_grad_u)
124 : OpAssembleVolume(field_name, nullptr, OPROW), alphaU(alpha),
125 alphaGradU(alpha_grad_u), physicsPtr(physics_ptr) {}
126
127 MoFEMErrorCode integrate(EntData &data);
128
129 private:
130 const double alphaU;
131 const double alphaGradU;
132 boost::shared_ptr<MatOps::PhysicalEquations>
133 physicsPtr; ///< material physical equations
134 };
135
138 std::string row_field, std::string col_field,
139 boost::shared_ptr<MatOps::PhysicalEquations> physics_ptr,
140 const double alpha, const double alpha_grad_u)
141 : OpAssembleVolume(row_field, col_field, nullptr, OPROWCOL, false),
142 alphaU(alpha), alphaGradU(alpha_grad_u), physicsPtr(physics_ptr) {
143 sYmm = false;
144 }
145
146 MoFEMErrorCode integrate(EntData &row_data, EntData &col_data);
147
148 private:
149 const double alphaU;
150 const double alphaGradU;
151 boost::shared_ptr<MatOps::PhysicalEquations>
152 physicsPtr; ///< material physical equations
153 };
154};
155
157
159 boost::shared_ptr<MatOps::MatElastic> mat_elastic_ptr,
160 const MaterialModel material_model, const Features features)
161 : MatPhysicalEquations(mat_elastic_ptr, material_model, features),
162 matElasticPtr(mat_elastic_ptr) {
163 if (!matElasticPtr)
165 "Mat core elastic equations are not allocated");
166 }
167
168 bool providesHelmholtzFreeEnergy() const override { return true; }
169
172 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
173 boost::shared_ptr<double> total_helmholtz_free_energy_ptr) override {
175 data_ptr, matElasticPtr, total_helmholtz_free_energy_ptr);
176 }
177
178private:
179 boost::shared_ptr<MatOps::MatElastic> matElasticPtr;
180};
181
182MoFEMErrorCode
184 int side, EntityType type, EntData &data) {
186 (void)side;
187 (void)type;
188 (void)data;
189
190 auto mat_ops_data = physicsPtr->matOpsDataPtr;
191 if (!mat_ops_data)
192 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
193 "Mat core material data is not allocated");
194
195 const int nb_integration_pts = getGaussPts().size2();
196 if (nb_integration_pts <= 0)
197 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
198 "Mat core energy operator has no integration points");
199
200 auto mat_grad_ptr = mat_ops_data->getCommonDataPtr("grad");
201 auto mat_F_ptr = mat_ops_data->getActiveDataPtr("F");
202 auto mat_energy_ptr = physicsPtr->getEnergyDensityPtr();
203 if (!mat_grad_ptr || !mat_F_ptr || !mat_energy_ptr)
204 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
205 "Mat core energy evaluation has incomplete material data");
206 if (mat_grad_ptr->size1() != nb_integration_pts ||
207 mat_grad_ptr->size2() != SPACE_DIM * SPACE_DIM)
208 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
209 "Mat core energy gradient data has size %zu x %zu; expected %d "
210 "x %d",
211 mat_grad_ptr->size1(), mat_grad_ptr->size2(), nb_integration_pts,
213
214 mat_F_ptr->resize(SPACE_DIM, SPACE_DIM, false);
215 mat_energy_ptr->resize(1, 1, false);
216
217 const auto get_material_tag = [&]() {
218 if (physicsPtr->tagVsRangePtr) {
219 for (const auto &tag_range_pair : *physicsPtr->tagVsRangePtr) {
220 if (tag_range_pair.second.find(getFEEntityHandle()) !=
221 tag_range_pair.second.end())
222 return tag_range_pair.first;
223 }
224 }
225#ifndef NDEBUG
228 "ADOL-C tag not found " +
229 std::to_string(physicsPtr->tAg));
230#endif
231 return physicsPtr->tAg;
232 };
233
234 const int material_tag = get_material_tag();
235 auto *fe_ptr = const_cast<FEMethod *>(getFEMethod());
236 if (!fe_ptr)
237 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
238 "Mat core energy operator has no finite-element method");
239 const EntityHandle ent = fe_ptr->getFEEntityHandle();
240 if (!ent)
241 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
242 "Mat core energy operator has no finite-element entity");
243
244 using GaussLayout = DataLayoutTraits<DataLayout::GaussByCoeffs>;
245 auto get_grad_at_pts = MatrixSizeHelper<
246 GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, GaussLayout>,
247 GaussLayout>::get(*mat_grad_ptr, nb_integration_pts);
248
251 auto t_grad_at_pts = get_grad_at_pts();
252 dataAtPts->energyAtPts.resize(nb_integration_pts, false);
253 auto t_energy_at_pts = getFTensor0FromVec(dataAtPts->energyAtPts);
254
255 for (int gg = 0; gg != nb_integration_pts; ++gg) {
256 auto t_F =
257 getFTensor2FromPtr<SPACE_DIM, SPACE_DIM>(mat_F_ptr->data().data());
258 t_F(i, J) = t_grad_at_pts(i, J);
259 CHKERR physicsPtr->setParams(fe_ptr, gg);
260 CHKERR physicsPtr->evaluateVariable(material_tag, ent, gg);
261
262 auto t_energy = getFTensor0FromMat(mat_energy_ptr);
263 const double energy_density = t_energy;
264 if (!std::isfinite(energy_density))
265 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
266 "Mat core returned non-finite energy density at point %d on "
267 "entity %lu",
268 gg, static_cast<unsigned long>(ent));
269 t_energy_at_pts = energy_density;
270
271 ++t_grad_at_pts;
272 ++t_energy_at_pts;
273 }
274
276 if (!std::isfinite(*totalHelmholtzFreeEnergyPtr))
277 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
278 "Mat core accumulated energy is non-finite before integration");
279 const double element_measure = getMeasure();
280 if (!std::isfinite(element_measure) || element_measure < 0.)
281 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
282 "Mat core element measure is invalid: %.16g", element_measure);
283
284 auto t_w = getFTensor0IntegrationWeight();
285 auto t_energy_at_pts_integral = getFTensor0FromVec(dataAtPts->energyAtPts);
286 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
287 double local_energy = 0;
288 for (int gg = 0; gg != nb_integration_pts; ++gg) {
289 const double weight = t_w;
290 const double energy_density = t_energy_at_pts_integral;
291 const double det_plasticF = determinantTensor3by3(t_plasticF);
292 if (!std::isfinite(weight) || !std::isfinite(det_plasticF) ||
293 det_plasticF <= 0.)
294 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
295 "Invalid Mat core energy quadrature data at point %d on "
296 "entity %lu",
297 gg, static_cast<unsigned long>(ent));
298 local_energy += weight * det_plasticF * energy_density;
299
300 ++t_w;
301 ++t_energy_at_pts_integral;
302 ++t_plasticF;
303 }
304
305 const double element_energy = element_measure * local_energy;
306 const double accumulated_energy =
307 *totalHelmholtzFreeEnergyPtr + element_energy;
308 if (!std::isfinite(element_energy) || !std::isfinite(accumulated_energy))
309 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
310 "Mat core integrated energy is non-finite on entity %lu",
311 static_cast<unsigned long>(ent));
312 *totalHelmholtzFreeEnergyPtr = accumulated_energy;
313 }
314
316}
317
318MoFEMErrorCode
321
322 auto physics_ptr = physicsPtr;
323 auto mat_ops_data = physics_ptr->matOpsDataPtr;
324
326 auto t_L = FTensor::SymmLTensor<double, 3>();
327
328 int nb_dofs = data.getIndices().size();
329 int nb_integration_pts = data.getN().size1();
330 auto v = getVolume();
331 auto t_w = getFTensor0IntegrationWeight();
332
333 auto t_P = getFTensor2FromMat<3, 3, -1, DL>(
334 mat_ops_data->getCommonDataPtr("PAtPts"));
335 auto t_approx_P_adjoint_log_du = getFTensor1FromMat<size_symm, -1, DL>(
336 mat_ops_data->getCommonDataPtr("adjointPdUAtPts"));
337 auto t_diff_u = getFTensor4FromMat<3, 3, 3, 3, -1, DL>(
338 mat_ops_data->getCommonDataPtr("diffStretchH1AtPts"));
339 auto t_dot_log_u = getFTensor2SymmetricFromMat<3, -1, DL>(
340 mat_ops_data->getCommonDataPtr("logStretchDotTensorAtPts"));
341 auto t_grad_dot_log_u = getFTensor2FromMat<size_symm, 3, -1, DL>(
342 mat_ops_data->getCommonDataPtr("gradLogStretchDotTensorAtPts"));
343 auto t_plasticF = getFTensor2SymmetricFromMat<3, -1, DL>(
344 mat_ops_data->getCommonDataPtr("plasticF"));
345 auto t_invPlasticF = getFTensor2FromMat<3, 3, -1, DL>(
346 mat_ops_data->getCommonDataPtr("invPlasticF"));
347
348 FTENSOR_INDEX(3, i);
349 FTENSOR_INDEX(3, j);
350 FTENSOR_INDEX(3, k);
351 FTENSOR_INDEX(3, l);
352 FTENSOR_INDEX(3, m);
353 FTENSOR_INDEX(3, n);
354
355 auto get_ftensor2 = [](auto &v) {
357 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
358 };
359
360 int nb_base_functions = data.getN().size2();
361 auto t_row_base_fun = data.getFTensor0N();
362 auto t_row_grad_fun = data.getFTensor1DiffN<3>();
363 for (int gg = 0; gg != nb_integration_pts; ++gg) {
364 const double det_plasticF = determinantTensor3by3(t_plasticF);
365 const double a = v * t_w * det_plasticF;
366 auto t_nf = get_ftensor2(nF);
367
369 t_Ldiff_u(i, j, L) = t_diff_u(i, j, k, l) * t_L(k, l, L);
370
372 t_residual(L) =
373 a * (t_approx_P_adjoint_log_du(L) - t_Ldiff_u(i, j, L) * t_P(i, j));
374 t_residual(L) += (a * alphaU) * (t_dot_log_u(i, j) * t_L(i, j, L));
375
376 FTensor::Tensor2<double, size_symm, 3> t_grad_dot_log_u_intermediate;
377 t_grad_dot_log_u_intermediate(L, j) =
378 t_grad_dot_log_u(L, i) * t_invPlasticF(i, j);
380 t_grad_residual(L, j) =
381 (a * alphaGradU) * t_grad_dot_log_u_intermediate(L, j);
382
383 int bb = 0;
384 for (; bb != nb_dofs / size_symm; ++bb) {
385 FTensor::Tensor1<double, 3> t_row_grad_intermediate;
386 t_row_grad_intermediate(j) = t_row_grad_fun(i) * t_invPlasticF(i, j);
387 t_nf(L) -= t_row_base_fun * t_residual(L);
388 t_nf(L) += t_row_grad_intermediate(j) * t_grad_residual(L, j);
389 ++t_nf;
390 ++t_row_base_fun;
391 ++t_row_grad_fun;
392 }
393 for (; bb != nb_base_functions; ++bb) {
394 ++t_row_base_fun;
395 ++t_row_grad_fun;
396 }
397
398 ++t_w;
399 ++t_approx_P_adjoint_log_du;
400 ++t_P;
401 ++t_diff_u;
402 ++t_dot_log_u;
403 ++t_grad_dot_log_u;
404 ++t_plasticF;
405 ++t_invPlasticF;
406 }
408}
409
410MoFEMErrorCode
412 EntData &col_data) {
414
417 auto t_L = FTensor::SymmLTensor<double, 3>();
418 auto t_diff = FTensor::DiffTensor<double>();
419 constexpr auto t_kd_sym = FTensor::Kronecker_Delta_symmetric<int>();
420
421 int nb_integration_pts = row_data.getN().size1();
422 int row_nb_dofs = row_data.getIndices().size();
423 int col_nb_dofs = col_data.getIndices().size();
424
425 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
427 size_symm>(
428
429 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
430 &m(r + 0, c + 4), &m(r + 0, c + 5),
431
432 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
433 &m(r + 1, c + 4), &m(r + 1, c + 5),
434
435 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
436 &m(r + 2, c + 4), &m(r + 2, c + 5),
437
438 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
439 &m(r + 3, c + 4), &m(r + 3, c + 5),
440
441 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
442 &m(r + 4, c + 4), &m(r + 4, c + 5),
443
444 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
445 &m(r + 5, c + 4), &m(r + 5, c + 5)
446
447 );
448 };
449
450 FTENSOR_INDEX(3, i);
451 FTENSOR_INDEX(3, j);
452 FTENSOR_INDEX(3, k);
453 FTENSOR_INDEX(3, l);
454 FTENSOR_INDEX(3, m);
455 FTENSOR_INDEX(3, n);
456
457 MatrixDouble dP;
458
459 auto get_dP = [&]() {
460 auto get_tensor_for_dP =
461 MatrixSizeHelper<GetFTensor2FromMatType<size_symm, size_symm, -1, DL>,
462 DL>::size(dP, nb_integration_pts);
463
464 auto mat_ops_data = physicsPtr->matOpsDataPtr;
465
466 auto t_P = getFTensor2FromMat<3, 3, -1, DL>(
467 mat_ops_data->getCommonDataPtr("PAtPts"));
468 auto t_P_du = getFTensor4FromMat<3, 3, 3, 3, -1, DL>(
469 mat_ops_data->getCommonDataPtr("PAtPts_du"));
470 auto t_approx_P_adjoint_dstretch = getFTensor2FromMat<3, 3, -1, DL>(
471 mat_ops_data->getCommonDataPtr("adjointPdstretchAtPts"));
472 auto t_u = getFTensor2FromMat<3, 3, -1, DL>(
473 mat_ops_data->getCommonDataPtr("stretchH1AtPts"));
474 auto t_diff_u = getFTensor4FromMat<3, 3, 3, 3, -1, DL>(
475 mat_ops_data->getCommonDataPtr("diffStretchH1AtPts"));
476 auto t_grad_h1 = getFTensor2FromMat<3, 3, -1, DL>(
477 mat_ops_data->getCommonDataPtr("wGradH1AtPts"));
478 auto t_eigen_vals = getFTensor1FromMat<3, -1, DL>(
479 mat_ops_data->getCommonDataPtr("eigenVals"));
480 auto t_eigen_vecs = getFTensor2FromMat<3, 3, -1, DL>(
481 mat_ops_data->getCommonDataPtr("eigenVecs"));
482 auto t_invPlasticF = getFTensor2FromMat<3, 3, -1, DL>(
483 mat_ops_data->getCommonDataPtr("invPlasticF"));
484
485 auto ts_a = getTSa();
487
488 auto t_dP = get_tensor_for_dP();
489 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
490
492
494 case LARGE_ROT:
495 case MODERATE_ROT:
496 t_h1(i, j) = t_grad_h1(i, k) * t_invPlasticF(k, j) + t_kd(i, j);
497 break;
498 default:
499 t_h1(i, j) = t_kd(i, j);
500 }
501
503 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
504 t_dP(L, J) =
505 -t_Ldiff_u(i, j, L) * (t_P_du(i, j, k, l) * t_Ldiff_u(k, l, J));
506 t_dP(L, J) += (ts_a * alphaU) *
507 (t_L(i, j, L) * (t_diff(i, j, k, l) * t_L(k, l, J)));
508
512 t_deltaP(i, j) =
513 t_approx_P_adjoint_dstretch(i, j) - t_P(i, k) * t_h1(j, k);
515 t_deltaP_sym(i, j) = (t_deltaP(i, j) || t_deltaP(j, i));
516 t_deltaP_sym(i, j) /= 2.0;
517 auto nb_uniq = getUniqNb<3>(getVectorAdaptor(&t_eigen_vals(0), 3),
519 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
520 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
521 EshelbianCore::dd_f, t_deltaP_sym, nb_uniq);
522 t_dP(L, J) += t_L(i, j, L) * (t_diff2_uP2(i, j, k, l) * t_L(k, l, J));
523 }
524
525 ++t_P;
526 ++t_dP;
527 ++t_P_du;
528 ++t_approx_P_adjoint_dstretch;
529 ++t_u;
530 ++t_diff_u;
531 ++t_grad_h1;
532 ++t_eigen_vals;
533 ++t_eigen_vecs;
534 ++t_invPlasticF;
535 }
536
537 return get_tensor_for_dP();
538 };
539
540 int row_nb_base_functions = row_data.getN().size2();
541 auto t_row_base_fun = row_data.getFTensor0N();
542 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
543
544 auto t_dP = get_dP();
545 auto v = getVolume();
546 auto ts_a = getTSa();
547 auto t_w = getFTensor0IntegrationWeight();
548 auto mat_ops_data = physicsPtr->matOpsDataPtr;
549 auto t_plasticF = getFTensor2SymmetricFromMat<3, -1, DL>(
550 mat_ops_data->getCommonDataPtr("plasticF"));
551 auto t_invPlasticF = getFTensor2FromMat<3, 3, -1, DL>(
552 mat_ops_data->getCommonDataPtr("invPlasticF"));
553
554 for (int gg = 0; gg != nb_integration_pts; ++gg) {
555 const double det_plasticF = determinantTensor3by3(t_plasticF);
556 const double a = v * t_w * det_plasticF;
557
558 int rr = 0;
559 for (; rr != row_nb_dofs / size_symm; ++rr) {
560 FTensor::Tensor1<double, 3> t_row_grad_intermediate;
561 t_row_grad_intermediate(j) = t_row_grad_fun(i) * t_invPlasticF(i, j);
562 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
563 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
564 auto t_m = get_ftensor2(K, size_symm * rr, 0);
565 for (int cc = 0; cc != col_nb_dofs / size_symm; ++cc) {
566 FTensor::Tensor1<double, 3> t_col_grad_intermediate;
567 t_col_grad_intermediate(j) = t_col_grad_fun(i) * t_invPlasticF(i, j);
568 const double b = a * t_row_base_fun * t_col_base_fun;
569 t_m(L, J) -= b * t_dP(L, J);
570 const double c = (a * alphaGradU * ts_a) * (t_row_grad_intermediate(j) *
571 t_col_grad_intermediate(j));
572 t_m(L, J) += c * t_kd_sym(L, J);
573 ++t_m;
574 ++t_col_base_fun;
575 ++t_col_grad_fun;
576 }
577 ++t_row_base_fun;
578 ++t_row_grad_fun;
579 }
580
581 for (; rr != row_nb_base_functions; ++rr) {
582 ++t_row_base_fun;
583 ++t_row_grad_fun;
584 }
585
586 ++t_w;
587 ++t_dP;
588 ++t_plasticF;
589 ++t_invPlasticF;
590 }
592}
593
596 const std::string &field_name,
597 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
598 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
599 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
600 : OpAssembleVolume(field_name, data_ptr, OPROW),
601 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap{smv} {}
602
604 EntData &data) {
606
607 double time = OpAssembleVolume::getFEMethod()->ts_t;
610 }
611 // get entity of tet
612 EntityHandle fe_ent = OpAssembleVolume::getFEEntityHandle();
613 // iterate over all block data
614
615 for (auto &ext_strain_block : (*externalStrainVecPtr)) {
616 auto block_name = "(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
617 std::regex reg_name(block_name);
618 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
619 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
620 "Analytical external strain not implemented for Neo-Hookean "
621 "material.");
622 }
623 // check if finite element entity is part of the EXTERNALSTRAIN block
624 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
625 double scale = 1;
626 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
627 scalingMethodsMap.end()) {
628 scale *=
629 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
630 } else {
631 MOFEM_LOG("SELF", Sev::warning)
632 << "No scaling method found for " << ext_strain_block.blockName;
633 }
634
635 // get ExternalStrain block data
636 double external_strain_val = scale * ext_strain_block.val;
637 double K = ext_strain_block.bulkModulusK;
638
640 auto t_L = FTensor::SymmLTensor<double, 3>();
641 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
642
643 int nb_dofs = data.getIndices().size();
644 int nb_integration_pts = data.getN().size1();
645 auto vol = getVolume();
646 auto t_w = getFTensor0IntegrationWeight();
647 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
648
655
656 int nb_base_functions = data.getN().size2();
657 auto t_row_base_fun = data.getFTensor0N();
658
659 const double bulk_modulus = K;
660 const double diag_val =
661 EshelbianCore::inv_f(std::exp(external_strain_val));
662 auto fun_neohookean_bulk = [](double K, double tr) { return K * tr; };
663 const double sigma_J = fun_neohookean_bulk(bulk_modulus, 3 * diag_val);
664
665 for (int gg = 0; gg != nb_integration_pts; ++gg) {
666 const double det_plasticF = determinantTensor3by3(t_plasticF);
667 const double a = vol * t_w * det_plasticF;
668 ++t_w;
669 ++t_plasticF;
670
672 t_residual(L) = (t_L(i, j, L) * t_kd(i, j)) * sigma_J;
673 t_residual(L) *= a;
674
675 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
676 int bb = 0;
677 for (; bb != nb_dofs / size_symm; ++bb) {
678 t_nf(L) -= t_row_base_fun * t_residual(L);
679 ++t_nf;
680 ++t_row_base_fun;
681 }
682 for (; bb != nb_base_functions; ++bb) {
683 ++t_row_base_fun;
684 }
685 }
686 }
687 }
689}
690
691} // namespace EshelbianPlasticity
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
const double alphaU
std::string type
#define FTENSOR_INDEX(DIM, I)
constexpr double a
constexpr int SPACE_DIM
Kronecker Delta class symmetric.
Kronecker Delta class.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ NOSPACE
Definition definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ 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.
const char features[]
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
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
boost::shared_ptr< MatOps::MatElastic > matElasticPtr
MatElasticPhysicalEquations(boost::shared_ptr< MatOps::MatElastic > mat_elastic_ptr, const MaterialModel material_model, const Features features)
VolUserDataOperator * returnOpCalculateHelmholtzFreeEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< double > total_helmholtz_free_energy_ptr) override
OpCalculateHelmholtzFreeEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< MatOps::MatElastic > physics_ptr, boost::shared_ptr< double > total_helmholtz_free_energy_ptr)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
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) override
VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha) override
MatPhysicalEquations(boost::shared_ptr< MatOps::MatPiolaResponse > mat_physical_equations_ptr, const MaterialModel material_model, const Features features)
boost::shared_ptr< MatOps::MatPiolaResponse > matPhysicalEquationsPtr
UserDataOperator * returnOpJacobian(const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr) override
VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha) override
static std::string getTagName(int tag)
Definition MatOps.cpp:90
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.
@ 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.
double scale
Definition plastic.cpp:123