12#define NEOHOOKEAN_OFF_INVERSE
25 "extract block data failed");
27#ifdef NEOHOOKEAN_SCALING
41 "Stretch selector is not equal to LOG");
45 "Exponent base is not equal to exp(1)");
52 if (b.blockEnts.find(ent) != b.blockEnts.end()) {
53 return std::make_pair(b.c10, b.K);
58 "Block not found for entity handle. If you mat set "
59 "block, set it to all elements");
65 boost::shared_ptr<PhysicalEquations> physics_ptr)
69 MoFEMErrorCode
doWork(
int side, EntityType type,
70 EntitiesFieldData::EntData &data) {
73 boost::dynamic_pointer_cast<HMHNeohookean>(
physicsPtr);
74 *(
scalePtr) = neohookean_ptr->eqScaling;
85 boost::shared_ptr<PhysicalEquations> physics_ptr) {
90 struct OpJacobian :
public EshelbianPlasticity::OpJacobian {
91 using EshelbianPlasticity::OpJacobian::OpJacobian;
96 virtual EshelbianPlasticity::OpJacobian *
98 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
99 boost::shared_ptr<PhysicalEquations> physics_ptr) {
100 return (
new OpJacobian(tag, eval_rhs, eval_lhs, data_ptr, physics_ptr));
105 PetscOptionsBegin(PETSC_COMM_WORLD,
"neo_hookean_",
"",
"none");
115 CHKERR PetscOptionsScalar(
"-viscosity_alpha_grad_u",
"viscosity",
"",
132 (boost::format(
"%s(.*)") %
"MAT_NEOHOOKEAN").str()
144 for (
auto m : meshset_vec_ptr) {
146 std::vector<double> block_data;
147 CHKERR m->getAttributes(block_data);
148 if (block_data.size() < 2) {
150 "Expected that block has atleast two attributes");
152 auto get_block_ents = [&]() {
158 double c10 = block_data[0];
159 double K = block_data[1];
161 blockData.push_back({c10, K, get_block_ents()});
163 MOFEM_LOG(
"EP", sev) <<
"MatBlock Neo-Hookean c10 = "
165 <<
" K = " <<
blockData.back().K <<
" nb ents. = "
179 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
180 const double alpha_u);
190 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
191 const double alpha_u) {
197 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
206 std::string row_field, std::string col_field,
207 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
const double alpha) {
230 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
const double alpha_u)
236 auto neohookean_ptr =
237 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
238 if (!neohookean_ptr) {
240 "Pointer to HMHNeohookean is null");
242 auto [def_c10, def_K] =
243 neohookean_ptr->getMaterialParameters(getFEEntityHandle());
245 double c10 = def_c10 / neohookean_ptr->eqScaling;
246 double alpha_u = alphaU / neohookean_ptr->eqScaling;
247 double K = def_K / neohookean_ptr->eqScaling;
249 double alpha_grad_u = neohookean_ptr->alphaGradU / neohookean_ptr->eqScaling;
258 int nb_integration_pts = data.
getN().size1();
259 auto v = getVolume();
260 auto t_w = getFTensor0IntegrationWeight();
261 auto t_approx_P_adjoint_log_du =
262 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
263 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
264 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
266 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
268 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
270 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
272 getFTensor2FromMat<6, 3>(dataAtPts->gradLogStretchDotTensorAtPts);
274 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
276 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
277 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
278 auto &nbUniq = dataAtPts->nbUniq;
291 auto get_ftensor2 = [](
auto &
v) {
293 &
v[0], &
v[1], &
v[2], &
v[3], &
v[4], &
v[5]);
296 int nb_base_functions = data.
getN().size2();
303 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
314 t_Ldiff_u(
i,
j, L) = t_diff_u(
i,
j,
k,
l) * t_L(
k,
l, L);
318 t_Sigma_u(
i,
j) = 2.0 * c10 * (t_u(
i,
j) - t_inv_u(
i,
j));
319 const double tr = t_log_u(
i,
i);
320 const double Sigma_J = K * tr;
324 alpha_u * (t_dot_log_u(
i,
j) -
325 t_dot_log_u(
k,
l) * t_kd_sym(
k,
l) * t_kd_sym(
i,
j));
328 t_residual(L) = t_approx_P_adjoint_log_du(L);
329 t_residual(L) -= t_Ldiff_u(
i,
j, L) * t_Sigma_u(
i,
j);
330 t_residual(L) -= (t_L(
i,
j, L) *
t_kd(
i,
j)) * Sigma_J;
331 t_residual(L) -= t_L(
i,
j, L) * t_viscous_P(
i,
j);
335 t_grad_residual(L,
i) = alpha_grad_u * t_grad_log_u(L,
i);
336 t_grad_residual(L,
i) *=
a;
338 ++t_approx_P_adjoint_log_du;
344 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
346 for (; bb != nb_dofs /
size_symm; ++bb) {
347 t_nf(L) -= t_row_base_fun * t_residual(L);
348 t_nf(L) += t_grad_base_fun(
i) * t_grad_residual(L,
i);
353 for (; bb != nb_base_functions; ++bb) {
365 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
372 t_Ldiff_u(
i,
j, L) = (t_diff_u(
i,
m,
k,
l) * t_h1(
m,
j)) * t_L(
k,
l, L);
377 const double tr_h1 = t_log_u2_h1(
i,
j) * t_kd_sym(
i,
j) / 2;
378 const double tr_u = t_log_u(
i,
j) * t_kd_sym(
i,
j);
379 const double tr = tr_h1 + tr_u;
382 t_total_u(
i,
j) = t_u(
i,
m) * t_h1(
m,
j);
383#ifndef NEOHOOKEAN_OFF_INVERSE
385 invertTensor3by3(t_total_u,
J, t_inv_total_u);
388#ifndef NEOHOOKEAN_OFF_INVERSE
389 t_Sigma_u(
i,
j) = 2.0 * c10 * (t_total_u(
i,
j) - t_inv_total_u(
i,
j));
391 t_Sigma_u(
i,
j) = 2.0 * c10 * t_total_u(
i,
j);
394#ifndef NEOHOOKEAN_OFF_INVERSE
395 const double Sigma_J = K * tr;
397 const double Sigma_J = K * (tr - 2.0 * c10 / K);
402 alpha_u * (t_dot_log_u(
i,
j) -
403 t_dot_log_u(
k,
l) * t_kd_sym(
k,
l) * t_kd_sym(
i,
j));
406 t_residual(L) = t_approx_P_adjoint_log_du(L);
407 t_residual(L) -= t_Ldiff_u(
i,
j, L) * t_Sigma_u(
i,
j);
408 t_residual(L) -= (t_L(
i,
j, L) *
t_kd(
i,
j)) * Sigma_J;
409 t_residual(L) -= t_L(
i,
j, L) * t_viscous_P(
i,
j);
413 t_grad_residual(L,
i) = alpha_grad_u * t_grad_log_u(L,
i);
414 t_grad_residual(L,
i) *=
a;
416 ++t_approx_P_adjoint_log_du;
423 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
425 for (; bb != nb_dofs /
size_symm; ++bb) {
426 t_nf(L) -= t_row_base_fun * t_residual(L);
427 t_nf(L) += t_grad_base_fun(
i) * t_grad_residual(L,
i);
432 for (; bb != nb_base_functions; ++bb) {
451 "gradApproximator not handled");
458 std::string row_field, std::string col_field,
459 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
const double alpha)
471 auto neohookean_ptr =
472 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
473 if (!neohookean_ptr) {
475 "Pointer to HMHNeohookean is null");
477 auto [def_c10, def_K] =
478 neohookean_ptr->getMaterialParameters(getFEEntityHandle());
480 double c10 = def_c10 / neohookean_ptr->eqScaling;
481 double alpha_u = alphaU / neohookean_ptr->eqScaling;
482 double lambda = def_K / neohookean_ptr->eqScaling;
484 double alpha_grad_u = neohookean_ptr->alphaGradU / neohookean_ptr->eqScaling;
495 int nb_integration_pts = row_data.
getN().size1();
496 int row_nb_dofs = row_data.
getIndices().size();
497 int col_nb_dofs = col_data.
getIndices().size();
499 auto get_ftensor2 = [](MatrixDouble &
m,
const int r,
const int c) {
503 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 0,
c + 3),
504 &
m(r + 0,
c + 4), &
m(r + 0,
c + 5),
506 &
m(r + 1,
c + 0), &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 1,
c + 3),
507 &
m(r + 1,
c + 4), &
m(r + 1,
c + 5),
509 &
m(r + 2,
c + 0), &
m(r + 2,
c + 1), &
m(r + 2,
c + 2), &
m(r + 2,
c + 3),
510 &
m(r + 2,
c + 4), &
m(r + 2,
c + 5),
512 &
m(r + 3,
c + 0), &
m(r + 3,
c + 1), &
m(r + 3,
c + 2), &
m(r + 3,
c + 3),
513 &
m(r + 3,
c + 4), &
m(r + 3,
c + 5),
515 &
m(r + 4,
c + 0), &
m(r + 4,
c + 1), &
m(r + 4,
c + 2), &
m(r + 4,
c + 3),
516 &
m(r + 4,
c + 4), &
m(r + 4,
c + 5),
518 &
m(r + 5,
c + 0), &
m(r + 5,
c + 1), &
m(r + 5,
c + 2), &
m(r + 5,
c + 3),
519 &
m(r + 5,
c + 4), &
m(r + 5,
c + 5)
531 auto v = getVolume();
532 auto ts_a = getTSa();
533 auto t_w = getFTensor0IntegrationWeight();
535 int row_nb_base_functions = row_data.
getN().size2();
539 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
541 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
543 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
545 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
546 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
547 auto t_approx_P_adjoint_dstretch =
548 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
549 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
550 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
551 auto &nbUniq = dataAtPts->nbUniq;
558 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
563 t_Ldiff_u(
i,
j, L) = t_diff_u(
i,
j,
k,
l) * t_L(
k,
l, L);
566 const double tr = t_log_u(
i,
i);
574 inv_f, inv_d_f, t_nb_uniq);
576 t_Ldiff_inv_u(
i,
j, L) = t_diff_inv_u(
i,
j,
k,
l) * t_L(
k,
l, L);
584 (t_Ldiff_u(
i,
j, L) * (t_Ldiff_u(
i,
j,
J) - t_Ldiff_inv_u(
i,
j,
J)));
585 t_dP(L,
J) -= (t_L(
i,
j, L) *
t_kd(
i,
j)) * Sigma_J_dtr(
J);
586 t_dP(L,
J) -= (alpha_u * ts_a) *
587 (t_L(
i,
j, L) * (t_diff(
i,
j,
k,
l) * t_L(
k,
l,
J) -
588 (t_diff(
m,
n,
k,
l) * t_kd_sym(
m,
n)) *
589 t_kd_sym(
i,
j) * t_L(
k,
l,
J)));
592 t_Sigma_u(
i,
j) = 2.0 * c10 * (t_u(
i,
j) - t_inv_u(
i,
j));
597 t_deltaP(
i,
j) = (t_approx_P_adjoint_dstretch(
i,
j) ||
598 t_approx_P_adjoint_dstretch(
i,
j)) /
604 t_dP(L,
J) += t_L(
i,
j, L) * (t_diff2_uP(
i,
j,
k,
l) * t_L(
k,
l,
J));
606 ++t_approx_P_adjoint_dstretch;
612 for (; rr != row_nb_dofs /
size_symm; ++rr) {
616 auto t_m = get_ftensor2(K, 6 * rr, 0);
617 for (
int cc = 0; cc != col_nb_dofs /
size_symm; ++cc) {
618 double b =
a * t_row_base_fun * t_col_base_fun;
619 double c = (
a * alpha_grad_u * ts_a) *
620 (t_row_grad_fun(
i) * t_col_grad_fun(
i));
621 t_m(L,
J) -= b * t_dP(L,
J);
622 t_m(L,
J) +=
c * t_kd_sym(L,
J);
632 for (; rr != row_nb_base_functions; ++rr) {
644 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
654 t_Ldiff_u(
i,
j, L) = t_diff_u(
i,
j,
k,
l) * t_L(
k,
l, L);
659 t_Ldiff_u(
i,
j, L) = (t_diff_u(
i,
m,
k,
l) * t_h1(
m,
j)) * t_L(
k,
l, L);
663 "gradApproximator not handled");
668 const double tr_h1 = t_log_u2_h1(
i,
j) * t_kd_sym(
i,
j) / 2;
669 const double tr_u = t_log_u(
i,
j) * t_kd_sym(
i,
j);
670 const double tr = tr_h1 + tr_u;
679 t_total_u(
i,
j) = t_u(
i,
m) * t_h1(
m,
j);
680#ifndef NEOHOOKEAN_OFF_INVERSE
682 invertTensor3by3(t_total_u, det_u, t_inv_total_u);
687#ifndef NEOHOOKEAN_OFF_INVERSE
689 t_Sigma_u_du(
i,
j,
J) = t_Ldiff_u(
i,
j,
J) + t_inv_total_u(
i,
k) *
692 t_dP(L,
J) = (-2.0 * c10) * (t_Ldiff_u(
i,
j, L) * t_Sigma_u_du(
i,
j,
J));
694 t_dP(L,
J) = (-2.0 * c10) * (t_Ldiff_u(
i,
j, L) * t_Ldiff_u(
i,
j,
J));
697 t_dP(L,
J) -= (t_L(
i,
j, L) *
t_kd(
i,
j)) * Sigma_J_dtr(
J);
698 t_dP(L,
J) -= (alpha_u * ts_a) *
699 (t_L(
i,
j, L) * (t_diff(
i,
j,
k,
l) * t_L(
k,
l,
J) -
700 (t_diff(
m,
n,
k,
l) * t_kd_sym(
m,
n)) *
701 t_kd_sym(
i,
j) * t_L(
k,
l,
J)));
704#ifndef NEOHOOKEAN_OFF_INVERSE
705 t_Sigma_u(
i,
j) = 2.0 * c10 * (t_total_u(
i,
j) - t_inv_total_u(
i,
j));
707 t_Sigma_u(
i,
j) = 2.0 * c10 * t_total_u(
i,
j);
714 t_approx_P_adjoint_dstretch(
i,
j) - t_h1(
j,
n) * t_Sigma_u(
i,
n);
717 t_deltaP(
i,
j) = -t_h1(
j,
n) * t_Sigma_u(
i,
n);
721 "gradApproximator not handled");
723 ++t_approx_P_adjoint_dstretch;
727 t_deltaP_sym(
i,
j) = (t_deltaP(
i,
j) || t_deltaP(
j,
i));
728 t_deltaP_sym(
i,
j) /= 2.0;
732 t_dP(L,
J) += t_L(
i,
j, L) * (t_diff2_uP2(
i,
j,
k,
l) * t_L(
k,
l,
J));
738 for (; rr != row_nb_dofs /
size_symm; ++rr) {
742 auto t_m = get_ftensor2(K, 6 * rr, 0);
743 for (
int cc = 0; cc != col_nb_dofs /
size_symm; ++cc) {
744 double b =
a * t_row_base_fun * t_col_base_fun;
745 double c = (
a * alpha_grad_u * ts_a) *
746 (t_row_grad_fun(
i) * t_col_grad_fun(
i));
747 t_m(L,
J) -= b * t_dP(L,
J);
748 t_m(L,
J) +=
c * t_kd_sym(L,
J);
758 for (; rr != row_nb_base_functions; ++rr) {
777 "gradApproximator not handled");
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
Kronecker Delta class symmetric.
#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_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
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
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto getMat(A &&t_val, B &&t_vec, Fun< double > f)
Get the Mat object.
auto getDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
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
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static enum StretchSelector stretchSelector
static enum RotSelector gradApproximator
static double exponentBase
static boost::function< double(const double)> f
static boost::function< double(const double)> dd_f
static boost::function< double(const double)> d_f
OpGetScale(boost::shared_ptr< double > scale_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
boost::shared_ptr< double > scalePtr
boost::shared_ptr< PhysicalEquations > physicsPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
MoFEMErrorCode evaluateRhs(EntData &data)
MoFEMErrorCode evaluateLhs(EntData &data)
OpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
OpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
MoFEMErrorCode integrate(EntData &data)
virtual EshelbianPlasticity::OpJacobian * returnOpJacobian(const int tag, const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
virtual VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
std::vector< BlockData > blockData
MoFEMErrorCode extractBlockData(std::vector< const CubitMeshSets * > meshset_vec_ptr, Sev sev)
MoFEMErrorCode extractBlockData(Sev sev)
static constexpr int numberOfDependentVariables
VolUserDataOperator * returnOpSetScale(boost::shared_ptr< double > scale_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
MoFEMErrorCode getOptions()
MoFEM::Interface & mField
auto getMaterialParameters(EntityHandle ent)
static constexpr int numberOfActiveVariables
HMHNeohookean(MoFEM::Interface &m_field, const double c10, const double K)
VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
MoFEMErrorCode recordTape(const int tape, DTensor2Ptr *t_h_ptr)
virtual moab::Interface & get_moab()=0
bool sYmm
If true assume that matrix is symmetric structure.
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
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.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.