v0.15.0
Loading...
Searching...
No Matches
EshelbianADOL-C.cpp
Go to the documentation of this file.
1/**
2 * \file EshelbianPlasticity.cpp
3 * \brief Implementation of automatic differentiation
4 */
5
6#include <MoFEM.hpp>
7using namespace MoFEM;
8
9#include <MatrixFunction.hpp>
10
12
13#include <EshelbianAux.hpp>
14
15#include <boost/math/constants/constants.hpp>
16
17constexpr double third = boost::math::constants::third<double>();
18
19namespace EshelbianPlasticity {
20
22
23 OpSpatialPhysical(const std::string &field_name,
24 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
25 const double alpha_u)
26 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u) {}
27
29
30private:
31 const double alphaU;
32};
33
36
38 auto t_L = symm_L_tensor();
39
40 int nb_dofs = data.getIndices().size();
41 int nb_integration_pts = data.getN().size1();
42 auto v = getVolume();
44 auto t_approx_P_adjoint_log_du =
45 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
46 auto t_P = getFTensor2FromMat<3, 3>(dataAtPts->PAtPts);
47 auto t_dot_log_u =
48 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
49 auto t_diff_u =
50 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
51
52 FTensor::Index<'i', 3> i;
53 FTensor::Index<'j', 3> j;
54 FTensor::Index<'k', 3> k;
55 FTensor::Index<'l', 3> l;
56 auto get_ftensor2 = [](auto &v) {
58 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
59 };
60
61 int nb_base_functions = data.getN().size2();
62 auto t_row_base_fun = data.getFTensor0N();
63 for (int gg = 0; gg != nb_integration_pts; ++gg) {
64 double a = v * t_w;
65 auto t_nf = get_ftensor2(nF);
66
68 t_Ldiff_u(i, j, L) = t_diff_u(i, j, k, l) * t_L(k, l, L);
69
71 t_viscous_P(i, j) =
72 alphaU *
73 t_dot_log_u(i,
74 j); // That is cheat, should be split on axial and deviator
75
77 t_residual(L) =
78 a * (t_approx_P_adjoint_log_du(L) - t_Ldiff_u(i, j, L) * t_P(i, j) -
79 t_L(i, j, L) * t_viscous_P(i, j));
80
81 int bb = 0;
82 for (; bb != nb_dofs / 6; ++bb) {
83 t_nf(L) -= t_row_base_fun * t_residual(L);
84 ++t_nf;
85 ++t_row_base_fun;
86 }
87 for (; bb != nb_base_functions; ++bb)
88 ++t_row_base_fun;
89
90 ++t_w;
91 ++t_approx_P_adjoint_log_du;
92 ++t_P;
93 ++t_dot_log_u;
94 ++t_diff_u;
95 }
97}
98
100 const std::string &field_name,
101 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha_u) {
102 return new OpSpatialPhysical(field_name, data_ptr, alpha_u);
103}
104
106 OpSpatialPhysical_du_du(std::string row_field, std::string col_field,
107 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
108 const double alpha)
109 : OpAssembleVolume(row_field, col_field, data_ptr, OPROWCOL, false),
110 alphaU(alpha) {
111 sYmm = false;
112 }
113 MoFEMErrorCode integrate(EntData &row_data, EntData &col_data);
114 MoFEMErrorCode integratePiola(EntData &row_data, EntData &col_data);
115
116private:
117 const double alphaU;
119
120};
121
123 EntData &col_data) {
124 return integratePiola(row_data, col_data);
125}
126
128 EntData &col_data) {
130
133 auto t_L = symm_L_tensor();
134 auto t_diff = diff_tensor();
135
136 int nb_integration_pts = row_data.getN().size1();
137 int row_nb_dofs = row_data.getIndices().size();
138 int col_nb_dofs = col_data.getIndices().size();
139
140 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
142 size_symm>(
143
144 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
145 &m(r + 0, c + 4), &m(r + 0, c + 5),
146
147 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
148 &m(r + 1, c + 4), &m(r + 1, c + 5),
149
150 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
151 &m(r + 2, c + 4), &m(r + 2, c + 5),
152
153 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
154 &m(r + 3, c + 4), &m(r + 3, c + 5),
155
156 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
157 &m(r + 4, c + 4), &m(r + 4, c + 5),
158
159 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
160 &m(r + 5, c + 4), &m(r + 5, c + 5)
161
162 );
163 };
164 FTensor::Index<'i', 3> i;
165 FTensor::Index<'j', 3> j;
166 FTensor::Index<'k', 3> k;
167 FTensor::Index<'l', 3> l;
168 FTensor::Index<'m', 3> m;
169 FTensor::Index<'n', 3> n;
170
171 auto v = getVolume();
172 auto t_w = getFTensor0IntegrationWeight();
173
174 auto get_dP = [&]() {
175 dP.resize(size_symm * size_symm, nb_integration_pts, false);
176 auto ts_a = getTSa();
177
178 auto t_P = getFTensor2FromMat<3, 3>(dataAtPts->PAtPts);
179 auto r_P_du = getFTensor4FromMat<3, 3, 3, 3>(dataAtPts->P_du);
180 auto t_approx_P_adjoint_dstretch =
181 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
182 auto t_dot_log_u =
183 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
184 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
185 auto t_diff_u =
186 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
187 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
188 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
189 auto &nbUniq = dataAtPts->nbUniq;
190
191 auto t_dP = getFTensor2FromMat<size_symm, size_symm>(dP);
192 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
193
195 t_deltaP(i, j) = t_approx_P_adjoint_dstretch(i, j) - t_P(i, j);
196
198 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
199 t_dP(L, J) =
200 -t_Ldiff_u(i, j, L) * (r_P_du(i, j, k, l) * t_Ldiff_u(k, l, J));
201 // viscous stress derivative
202 t_dP(L, J) -= (alphaU * ts_a) *
203 (t_L(i, j, L) * (t_diff(i, j, k, l) * t_L(k, l, J)));
204
208 t_deltaP_sym(i, j) = (t_deltaP(i, j) || t_deltaP(j, i));
209 t_deltaP_sym(i, j) /= 2.0;
210 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
211 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
212 EshelbianCore::dd_f, t_deltaP_sym, nbUniq[gg]);
213 t_dP(L, J) += t_L(i, j, L) * (t_diff2_uP2(i, j, k, l) * t_L(k, l, J));
214 }
215
216 ++t_P;
217 ++t_dP;
218 ++r_P_du;
219 ++t_approx_P_adjoint_dstretch;
220 ++t_dot_log_u;
221 ++t_u;
222 ++t_diff_u;
223 ++t_eigen_vals;
224 ++t_eigen_vecs;
225 }
226
227 return getFTensor2FromMat<size_symm, size_symm>(dP);
228 };
229
230 int row_nb_base_functions = row_data.getN().size2();
231 auto t_row_base_fun = row_data.getFTensor0N();
232
233 auto t_dP = get_dP();
234 for (int gg = 0; gg != nb_integration_pts; ++gg) {
235 double a = v * t_w;
236
237 int rr = 0;
238 for (; rr != row_nb_dofs / 6; ++rr) {
239 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
240 auto t_m = get_ftensor2(K, 6 * rr, 0);
241 for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
242 const double b = a * t_row_base_fun * t_col_base_fun;
243 t_m(L, J) -= b * t_dP(L, J);
244 ++t_m;
245 ++t_col_base_fun;
246 }
247 ++t_row_base_fun;
248 }
249
250 for (; rr != row_nb_base_functions; ++rr) {
251 ++t_row_base_fun;
252 }
253
254 ++t_w;
255 ++t_dP;
256 }
258}
259
261 std::string row_field, std::string col_field,
262 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha) {
263 return new OpSpatialPhysical_du_du(row_field, col_field, data_ptr, alpha);
264}
265
267 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
268 boost::shared_ptr<double> total_energy_ptr) {
269 return nullptr;
270}
271
273 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
274 boost::shared_ptr<PhysicalEquations> physics_ptr) {
275 return nullptr;
276}
277
279 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
280 boost::shared_ptr<PhysicalEquations> physics_ptr) {
281 return nullptr;
282};
283
285 OpGetScale(boost::shared_ptr<double> scale_ptr)
287 scalePtr(scale_ptr) {}
288
289 MoFEMErrorCode doWork(int side, EntityType type,
292 *(scalePtr) = 1.;
294 }
295
296private:
297 boost::shared_ptr<double> scalePtr;
298};
299
301 boost::shared_ptr<double> scale_ptr,
302 boost::shared_ptr<PhysicalEquations> physics_ptr) {
303 return new OpGetScale(scale_ptr);
304};
305
306struct OpHMHH : public OpJacobian {
307 OpHMHH(const int tag, const bool eval_rhs, const bool eval_lhs,
308 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
309 boost::shared_ptr<PhysicalEquations> physics_ptr)
310 : OpJacobian(tag, eval_rhs, eval_lhs, data_ptr, physics_ptr) {}
311
314};
315
318 FTensor::Index<'i', 3> i;
319 FTensor::Index<'j', 3> j;
320 FTensor::Index<'k', 3> k;
321 FTensor::Index<'l', 3> l;
322 FTensor::Index<'m', 3> m;
323 FTensor::Index<'n', 3> n;
324
325 const auto nb_integration_pts = getGaussPts().size2();
326 auto iu = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
327 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
328
329 auto create_data_vec = [nb_integration_pts](auto &v) {
330 v.resize(nb_integration_pts, false);
331 };
332 auto create_data_mat = [nb_integration_pts](auto &m) {
333 m.resize(9, nb_integration_pts, false);
334 };
335
336 create_data_mat(dataAtPts->PAtPts);
337
338 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
339 auto r_P = getFTensor2FromMat<3, 3>(dataAtPts->PAtPts);
340 for (unsigned int gg = 0; gg != nb_integration_pts; ++gg) {
341
343
346 t_h1(i, j) = t_kd(i, j);
347 physicsPtr->get_h()(i, j) = iu(i, j);
348 break;
349 case LARGE_ROT:
350 case MODERATE_ROT:
351 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
352 physicsPtr->get_h()(i, j) = iu(i, k) * t_h1(k, j);
353 break;
354 case SMALL_ROT:
355 physicsPtr->get_h()(i, j) = iu(i, j);
356 break;
357 };
358
359 int r = ::function(tAg, physicsPtr->dependentVariablesPiola.size(),
360 physicsPtr->activeVariables.size(),
361 &physicsPtr->activeVariables[0],
362 &physicsPtr->dependentVariablesPiola[0]);
363 if (r < 0) { // function is locally analytic
364 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
365 "ADOL-C function evaluation with error r = %d", r);
366 }
367
370 r_P(i, j) = physicsPtr->get_P()(i, j);
371 break;
372 case LARGE_ROT:
373 case MODERATE_ROT: {
375 t_h1_du(i, j, m, n) = t_kd(i, m) * (t_kd(k, n) * t_h1(k, j));
376 r_P(k, l) = physicsPtr->get_P()(i, j) * t_h1_du(i, j, k, l);
377 }; break;
378 case SMALL_ROT:
379 r_P(i, j) = physicsPtr->get_P()(i, j);
380 break;
381 };
382
383 ++iu;
384 ++t_grad_h1;
385 ++r_P;
386 }
388}
389
392 FTensor::Index<'i', 3> i;
393 FTensor::Index<'j', 3> j;
394 FTensor::Index<'k', 3> k;
395 FTensor::Index<'l', 3> l;
396 FTensor::Index<'m', 3> m;
397 FTensor::Index<'n', 3> n;
398 FTensor::Index<'o', 3> o;
399 FTensor::Index<'p', 3> p;
400
401 const int number_of_active_variables = physicsPtr->activeVariables.size();
402 const int number_of_dependent_variables =
403 physicsPtr->dependentVariablesPiola.size();
404 std::vector<double *> jac_ptr(number_of_dependent_variables);
405 for (unsigned int n = 0; n != number_of_dependent_variables; ++n) {
406 jac_ptr[n] =
407 &(physicsPtr
408 ->dependentVariablesPiolaDirevatives[n *
409 number_of_active_variables]);
410 }
411
412 const auto nb_integration_pts = getGaussPts().size2();
413
414 auto create_data_mat = [nb_integration_pts](auto &m) {
415 m.resize(9, nb_integration_pts, false);
416 };
417
418 dataAtPts->P_du.resize(81, nb_integration_pts, false);
419
420 auto iu = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
421 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
422 auto r_P_du = getFTensor4FromMat<3, 3, 3, 3>(dataAtPts->P_du);
423
427
428 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
429
430 for (unsigned int gg = 0; gg != nb_integration_pts; ++gg) {
431
433
436 t_h1(i, j) = t_kd(i, j);
437 physicsPtr->get_h()(i, j) = iu(i, k) * t_h1(k, j);
438 break;
439 case LARGE_ROT:
440 case MODERATE_ROT:
441 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
442 physicsPtr->get_h()(i, j) = iu(i, k) * t_h1(k, j);
443 break;
444 case SMALL_ROT:
445 physicsPtr->get_h()(i, j) = iu(i, j);
446 break;
447 };
448
449 // play recorder for jacobians
450 int r = ::jacobian(tAg, number_of_dependent_variables,
451 number_of_active_variables,
452 &physicsPtr->activeVariables[0], &jac_ptr[0]);
453 if (r < 0) {
454 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
455 "ADOL-C function evaluation with error");
456 }
457
459 t_P_dh_tmp(i, j, N0, k) = physicsPtr->get_P_dh0()(i, j, k);
460 t_P_dh_tmp(i, j, N1, k) = physicsPtr->get_P_dh1()(i, j, k);
461 t_P_dh_tmp(i, j, N2, k) = physicsPtr->get_P_dh2()(i, j, k);
462
464 case NO_H1_CONFIGURATION: {
466 t_h1_du(i, j, m, n) = t_kd(i, m) * t_kd(j, n);
467 r_P_du(k, l, m, n) =
468 (t_P_dh_tmp(i, j, o, p) * t_h1_du(o, p, m, n)) * t_h1_du(i, j, k, l);
469 } break;
470 case LARGE_ROT: {
472 t_h1_du(i, j, m, n) = t_kd(i, m) * (t_kd(k, n) * t_h1(k, j));
473 r_P_du(k, l, m, n) =
474 (t_P_dh_tmp(i, j, o, p) * t_h1_du(o, p, m, n)) * t_h1_du(i, j, k, l);
475 } break;
476 case MODERATE_ROT:
477 case SMALL_ROT:
478 r_P_du(i, j, m, n) = t_P_dh_tmp(i, j, m, n);
479 break;
480 };
481
482 ++iu;
483 ++t_grad_h1;
484 ++r_P_du;
485 }
487}
488
489} // namespace EshelbianPlasticity
490
492#include <impl/HMHNeohookean.cpp>
494#include <impl/HMHHencky.cpp>
495
496namespace EshelbianPlasticity {
497
499 const int tape, const double lambda, const double mu,
500 const double sigma_y) {
502 physicalEquations = boost::make_shared<HMHStVenantKirchhoff>(lambda, mu);
503 CHKERR physicalEquations->recordTape(tape, nullptr);
505}
506
508 const int tape, const double alpha, const double beta, const double lambda,
509 const double sigma_y) {
511 physicalEquations =
512 boost::make_shared<HMHPMooneyRivlinWriggersEq63>(alpha, beta, lambda);
513 CHKERR physicalEquations->recordTape(tape, nullptr);
515}
517 const double c10,
518 const double K) {
520 physicalEquations = boost::make_shared<HMHNeohookean>(mField, c10, K);
521 CHKERR physicalEquations->recordTape(tape, nullptr);
523}
524
527 physicalEquations = boost::make_shared<HMHHencky>(mField, E, nu);
529}
530
531}; // namespace EshelbianPlasticity
constexpr double third
Auxilary functions for Eshelbian plasticity.
Eshelbian plasticity interface.
Implementation StVenantKirchhoff.
Implementation of NeoHookean material.
Implement of MooneyRivlinWriggersEq63.
constexpr double a
Kronecker Delta class.
@ 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
#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
FTensor::Index< 'i', SPACE_DIM > i
static double lambda
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.
static constexpr auto size_symm
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static enum StretchSelector stretchSelector
MoFEMErrorCode addMaterial_Hencky(double E, double nu)
MoFEMErrorCode addMaterial_HMHHStVenantKirchhoff(const int tape, const double lambda, const double mu, const double sigma_y)
MoFEMErrorCode addMaterial_HMHMooneyRivlin(const int tape, const double alpha, const double beta, const double lambda, const double sigma_y)
static enum RotSelector gradApproximator
static boost::function< double(const double)> f
static boost::function< double(const double)> dd_f
static boost::function< double(const double)> d_f
MoFEMErrorCode addMaterial_HMHNeohookean(const int tape, const double c10, const double K)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< double > scalePtr
OpGetScale(boost::shared_ptr< double > scale_ptr)
OpHMHH(const int tag, const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
MoFEMErrorCode evaluateLhs(EntData &data)
MoFEMErrorCode evaluateRhs(EntData &data)
MoFEMErrorCode integratePiola(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
OpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
OpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
MoFEMErrorCode integrate(EntData &data)
virtual VolUserDataOperator * returnOpCalculateVarStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
virtual VolUserDataOperator * returnOpCalculateEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< double > total_energy_ptr)
virtual VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
virtual VolUserDataOperator * returnOpCalculateStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
virtual VolUserDataOperator * returnOpSetScale(boost::shared_ptr< double > scale_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
virtual VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
bool sYmm
If true assume that matrix is symmetric structure.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorInt & getIndices() const
Get global indices of dofs on entity.
auto getFTensor0IntegrationWeight()
Get integration weights.
@ OPROW
operator doWork function is executed on FE rows
@ OPROWCOL
operator doWork is executed on FE rows &columns
@ OPSPACE
operator do Work is execute on space data
MatrixDouble K
local tangent matrix
VectorDouble nF
local right hand side vector
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts