18#ifndef __HOOKE_ELEMENT_HPP
19#define __HOOKE_ELEMENT_HPP
21#ifndef __BASICFINITEELEMENTS_HPP__
25#ifndef __NONLINEAR_ELASTIC_HPP
56#ifndef __CONVECTIVE_MASS_ELEMENT_HPP
77 VolumeElementForcesAndSourcesCore::UserDataOperator;
82 boost::shared_ptr<MatrixDouble>
hMat;
83 boost::shared_ptr<MatrixDouble>
FMat;
85 boost::shared_ptr<MatrixDouble>
HMat;
98 smallStrainMat = boost::shared_ptr<MatrixDouble>(
new MatrixDouble());
99 hMat = boost::shared_ptr<MatrixDouble>(
new MatrixDouble());
100 FMat = boost::shared_ptr<MatrixDouble>(
new MatrixDouble());
102 HMat = boost::shared_ptr<MatrixDouble>(
new MatrixDouble());
103 detHVec = boost::shared_ptr<VectorDouble>(
new VectorDouble());
104 invHMat = boost::shared_ptr<MatrixDouble>(
new MatrixDouble());
106 cauchyStressMat = boost::shared_ptr<MatrixDouble>(
new MatrixDouble());
107 stiffnessMat = boost::shared_ptr<MatrixDouble>(
new MatrixDouble());
108 energyVec = boost::shared_ptr<VectorDouble>(
new VectorDouble());
109 eshelbyStressMat = boost::shared_ptr<MatrixDouble>(
new MatrixDouble());
111 eshelbyStress_dx = boost::shared_ptr<MatrixDouble>(
new MatrixDouble());
118 template <
bool D = false>
122 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
133 const std::string col_field,
134 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
142#define MAT_TO_DDG(SM) \
143 &(*SM)(0, 0), &(*SM)(1, 0), &(*SM)(2, 0), &(*SM)(3, 0), &(*SM)(4, 0), \
144 &(*SM)(5, 0), &(*SM)(6, 0), &(*SM)(7, 0), &(*SM)(8, 0), &(*SM)(9, 0), \
145 &(*SM)(10, 0), &(*SM)(11, 0), &(*SM)(12, 0), &(*SM)(13, 0), \
146 &(*SM)(14, 0), &(*SM)(15, 0), &(*SM)(16, 0), &(*SM)(17, 0), \
147 &(*SM)(18, 0), &(*SM)(19, 0), &(*SM)(20, 0), &(*SM)(21, 0), \
148 &(*SM)(22, 0), &(*SM)(23, 0), &(*SM)(24, 0), &(*SM)(25, 0), \
149 &(*SM)(26, 0), &(*SM)(27, 0), &(*SM)(28, 0), &(*SM)(29, 0), \
150 &(*SM)(30, 0), &(*SM)(31, 0), &(*SM)(32, 0), &(*SM)(33, 0), \
151 &(*SM)(34, 0), &(*SM)(35, 0)
156 boost::shared_ptr<DataAtIntegrationPts> data_at_pts);
167 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
180 const std::string row_field,
const std::string col_field,
181 boost::shared_ptr<DataAtIntegrationPts> data_at_pts);
193 const std::string row_field,
const std::string col_field,
194 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
195 boost::shared_ptr<DataAtIntegrationPts> data_at_pts);
200 boost::shared_ptr<map<int, BlockData>>
223 const std::string col_field,
BlockData &data,
225 boost::shared_ptr<DataAtIntegrationPts> &common_data,
228 row_field, col_field, OPROWCOL, symm),
229 commonData(common_data), dAta(data), massData(mass_data) {}
231 PetscErrorCode
doWork(
int row_side,
int col_side, EntityType row_type,
237 auto get_tensor2 = [](
MatrixDouble &
m,
const int r,
const int c) {
239 &
m(3 * r + 0, 3 *
c + 0), &
m(3 * r + 0, 3 *
c + 1),
240 &
m(3 * r + 0, 3 *
c + 2), &
m(3 * r + 1, 3 *
c + 0),
241 &
m(3 * r + 1, 3 *
c + 1), &
m(3 * r + 1, 3 *
c + 2),
242 &
m(3 * r + 2, 3 *
c + 0), &
m(3 * r + 2, 3 *
c + 1),
243 &
m(3 * r + 2, 3 *
c + 2));
246 const int row_nb_dofs = row_data.
getIndices().size();
249 const int col_nb_dofs = col_data.
getIndices().size();
252 if (dAta.tEts.find(getFEEntityHandle()) == dAta.tEts.end()) {
255 if (massData.
tEts.find(getFEEntityHandle()) == massData.
tEts.end()) {
259 const bool diagonal_block =
260 (row_type == col_type) && (row_side == col_side);
263 locK.resize(row_nb_dofs, col_nb_dofs,
false);
266 const int row_nb_gauss_pts = row_data.
getN().size1();
267 const int row_nb_base_functions = row_data.
getN().size2();
274 double density = massData.
rho0;
277 auto t_w = getFTensor0IntegrationWeight();
280 for (
int gg = 0; gg != row_nb_gauss_pts; gg++) {
285 double w = getVolume() * t_w;
287 for (
int row_bb = 0; row_bb != row_nb_dofs / 3; row_bb++) {
289 for (
int col_bb = 0; col_bb != col_nb_dofs / 3; col_bb++) {
290 auto t_assemble = get_tensor2(locK, row_bb, col_bb);
291 t_assemble(
i,
j) += density * t_row_base_func * t_col_base_func * w;
306 if (row_type != col_type || row_side != col_side) {
307 translocK.resize(col_nb_dofs, row_nb_dofs,
false);
308 noalias(translocK) = trans(locK);
320 boost::shared_ptr<map<int, BlockData>>
331 const std::string row_field,
const std::string col_field,
332 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
333 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
334 boost::shared_ptr<VectorDouble> rho_at_gauss_pts,
const double rho_n,
342 OpAssemble(
const std::string row_field,
const std::string col_field,
343 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
344 const char type,
bool symm =
false);
356 MoFEMErrorCode doWork(
int row_side,
int col_side, EntityType row_type,
357 EntityType col_type,
EntData &row_data,
403 OpRhs_dx(
const std::string row_field,
const std::string col_field,
404 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
412 OpLhs_dx_dx(
const std::string row_field,
const std::string col_field,
413 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
427 OpAleRhs_dx(
const std::string row_field,
const std::string col_field,
428 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
436 OpAleLhs_dx_dx(
const std::string row_field,
const std::string col_field,
437 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
451 OpAleLhs_dx_dX(
const std::string row_field,
const std::string col_field,
452 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
472 const std::string row_field,
const std::string col_field,
473 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
474 boost::shared_ptr<VectorDouble> rho_at_gauss_pts,
475 boost::shared_ptr<MatrixDouble> rho_grad_at_gauss_pts,
476 const double rho_n,
const double rho_0);
496 const std::string row_field,
const std::string col_field,
497 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
498 boost::shared_ptr<VectorDouble> rho_at_gauss_pts,
499 boost::shared_ptr<MatrixDouble> rho_grad_at_gauss_pts,
500 const double rho_n,
const double rho_0);
514 OpAleRhs_dX(
const std::string row_field,
const std::string col_field,
515 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
523 OpAleLhs_dX_dX(
const std::string row_field,
const std::string col_field,
524 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
539 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
550 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
551 :
OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, false) {}
565 typedef boost::function<
577 const std::string row_field,
578 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
588 typedef boost::function<
600 const std::string row_field,
601 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
603 boost::shared_ptr<MatrixDouble> mat_pos_at_pts_ptr);
613 typedef boost::function<
625 const std::string row_field,
626 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
628 boost::shared_ptr<MatrixDouble> mat_pos_at_pts_ptr);
636 template <
class ELEMENT>
647 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
648 map<int, BlockData> &block_sets_ptr,
649 moab::Interface &post_proc_mesh,
650 std::vector<EntityHandle> &map_gauss_pts,
651 bool is_ale =
false,
bool is_field_disp =
true);
659 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr);
663 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
664 const std::string element_name,
const std::string x_field,
665 const std::string X_field,
const bool ale);
669 boost::shared_ptr<ForcesAndSourcesCore> fe_rhs_ptr,
670 boost::shared_ptr<map<int, BlockData>> block_sets_ptr,
671 const std::string x_field,
const std::string X_field,
672 const bool ale,
const bool field_disp,
673 const EntityType
type = MBTET,
674 boost::shared_ptr<DataAtIntegrationPts> data_at_pts =
nullptr);
678 const std::string x_field,
const std::string X_field,
679 const bool ale,
const bool field_disp,
687HookeElement::OpCalculateStrain<D>::OpCalculateStrain(
688 const std::string row_field,
const std::string col_field,
689 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
691 dataAtPts(data_at_pts) {
703 const int nb_integration_pts = getGaussPts().size2();
704 dataAtPts->smallStrainMat->resize(6, nb_integration_pts,
false);
706 *(dataAtPts->smallStrainMat));
708 getFTensor2FromMat<3, 3>(*(dataAtPts->hMat));
710 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
711 t_strain(
i,
j) = (t_h(
i,
j) || t_h(
j,
i)) / 2.;
727HookeElement::OpAleLhs_dx_dx<S>::OpAleLhs_dx_dx(
728 const std::string row_field,
const std::string col_field,
729 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
730 :
OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, true) {}
739 auto get_tensor2 = [](
MatrixDouble &
m,
const int r,
const int c) {
741 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 1,
c + 0),
742 &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 2,
c + 0), &
m(r + 2,
c + 1),
752 double vol = getVolume();
755 auto t_w = getFTensor0IntegrationWeight();
759 const int row_nb_base_fun = row_data.
getN().size2();
768 auto &det_H = *dataAtPts->detHVec;
771 for (
int gg = 0; gg != nbIntegrationPts; ++gg) {
774 double a = t_w * vol * det_H[gg];
778 for (; rr != nbRows / 3; ++rr) {
781 auto t_m = get_tensor2(
K, 3 * rr, 0);
784 t_row_diff_base_pulled(
i) = t_row_diff_base(
j) * t_invH(
j,
i);
790 t_rowD(
l,
j,
k) = t_D(
i,
j,
k,
l) * (
a * t_row_diff_base_pulled(
i));
796 for (
int cc = 0; cc != nbCols / 3; ++cc) {
799 t_col_diff_base_pulled(
j) = t_col_diff_base(
i) * t_invH(
i,
j);
802 t_m(
i,
j) += t_rowD(
i,
j,
k) * t_col_diff_base_pulled(
k);
815 for (; rr != row_nb_base_fun; ++rr)
828HookeElement::OpCalculateHomogeneousStiffness<S>::
829 OpCalculateHomogeneousStiffness(
830 const std::string row_field,
const std::string col_field,
831 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
832 boost::shared_ptr<DataAtIntegrationPts> data_at_pts)
834 blockSetsPtr(block_sets_ptr), dataAtPts(data_at_pts) {
840 int row_side, EntityType row_type,
EntData &row_data) {
843 for (
auto &
m : (*blockSetsPtr)) {
844 if (
m.second.tEts.find(getFEEntityHandle()) !=
m.second.tEts.end()) {
846 dataAtPts->stiffnessMat->resize(36, 1,
false);
849 const double young =
m.second.E;
850 const double poisson =
m.second.PoissonRatio;
853 const double coefficient = young / ((1 + poisson) * (1 - 2 * poisson));
860 t_D(
i,
j,
k,
l) = 0.;
862 t_D(0, 0, 0, 0) = 1 - poisson;
863 t_D(1, 1, 1, 1) = 1 - poisson;
864 t_D(2, 2, 2, 2) = 1 - poisson;
866 t_D(0, 1, 0, 1) = 0.5 * (1 - 2 * poisson);
867 t_D(0, 2, 0, 2) = 0.5 * (1 - 2 * poisson);
868 t_D(1, 2, 1, 2) = 0.5 * (1 - 2 * poisson);
870 t_D(0, 0, 1, 1) = poisson;
871 t_D(1, 1, 0, 0) = poisson;
872 t_D(0, 0, 2, 2) = poisson;
873 t_D(2, 2, 0, 0) = poisson;
874 t_D(1, 1, 2, 2) = poisson;
875 t_D(2, 2, 1, 1) = poisson;
877 t_D(
i,
j,
k,
l) *= coefficient;
887HookeElement::OpCalculateStress<S>::OpCalculateStress(
888 const std::string row_field,
const std::string col_field,
889 boost::shared_ptr<DataAtIntegrationPts> data_at_pts)
891 dataAtPts(data_at_pts) {
901 const int nb_integration_pts = getGaussPts().size2();
903 *(dataAtPts->smallStrainMat));
904 dataAtPts->cauchyStressMat->resize(6, nb_integration_pts,
false);
905 auto t_cauchy_stress =
907 *(dataAtPts->cauchyStressMat));
918 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
919 t_cauchy_stress(
i,
j) = t_D(
i,
j,
k,
l) * t_strain(
k,
l);
928HookeElement::OpLhs_dx_dx<S>::OpLhs_dx_dx(
929 const std::string row_field,
const std::string col_field,
930 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
931 :
OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, true) {}
940 auto get_tensor2 = [](
MatrixDouble &
m,
const int r,
const int c) {
942 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 1,
c + 0),
943 &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 2,
c + 0), &
m(r + 2,
c + 1),
953 double vol = getVolume();
956 auto t_w = getFTensor0IntegrationWeight();
960 const int row_nb_base_fun = row_data.
getN().size2();
968 for (
int gg = 0; gg != nbIntegrationPts; ++gg) {
971 double a = t_w * vol;
975 for (; rr != nbRows / 3; ++rr) {
978 auto t_m = get_tensor2(
K, 3 * rr, 0);
987 t_rowD(
l,
j,
k) = t_D(
i,
j,
k,
l) * (
a * t_row_diff_base(
i));
990 for (
int cc = 0; cc != nbCols / 3; ++cc) {
993 t_m(
i,
j) += t_rowD(
i,
j,
k) * t_col_diff_base(
k);
1006 for (; rr != row_nb_base_fun; ++rr)
1018HookeElement::OpAleLhs_dx_dX<S>::OpAleLhs_dx_dX(
1019 const std::string row_field,
const std::string col_field,
1020 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
1021 :
OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, false) {}
1030 auto get_tensor2 = [](
MatrixDouble &
m,
const int r,
const int c) {
1032 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 1,
c + 0),
1033 &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 2,
c + 0), &
m(r + 2,
c + 1),
1045 double vol = getVolume();
1048 auto t_w = getFTensor0IntegrationWeight();
1052 const int row_nb_base_fun = row_data.
getN().size2();
1059 auto t_cauchy_stress =
1061 *(dataAtPts->cauchyStressMat));
1062 auto t_h = getFTensor2FromMat<3, 3>(*dataAtPts->hMat);
1065 auto &det_H = *dataAtPts->detHVec;
1068 for (
int gg = 0; gg != nbIntegrationPts; ++gg) {
1071 double a = t_w * vol * det_H[gg];
1074 t_F_dX(
i,
j,
k,
l) = -(t_h(
i,
m) * t_invH(
m,
k)) * t_invH(
l,
j);
1078 for (; rr != nbRows / 3; ++rr) {
1081 auto t_m = get_tensor2(
K, 3 * rr, 0);
1084 t_row_diff_base_pulled(
i) = t_row_diff_base(
j) * t_invH(
j,
i);
1087 t_row_stress(
i) =
a * t_row_diff_base_pulled(
j) * t_cauchy_stress(
i,
j);
1090 t_row_diff_base_pulled_dX(
j,
k,
l) =
1091 -(t_invH(
i,
k) * t_row_diff_base(
i)) * t_invH(
l,
j);
1094 t_row_dX_stress(
i,
k,
l) =
1095 a * (t_row_diff_base_pulled_dX(
j,
k,
l) * t_cauchy_stress(
j,
i));
1098 t_row_D(
l,
j,
k) = (
a * t_row_diff_base_pulled(
i)) * t_D(
i,
j,
k,
l);
1103 t_row_stress_dX(
i,
j,
k) = 0;
1104 for (
int ii = 0; ii != 3; ++ii)
1105 for (
int mm = 0; mm != 3; ++mm)
1106 for (
int nn = 0; nn != 3; ++nn) {
1107 auto &
v = t_row_stress_dX(ii, mm, nn);
1108 for (
int kk = 0; kk != 3; ++kk)
1109 for (
int ll = 0; ll != 3; ++ll)
1110 v += t_row_D(ii, kk, ll) * t_F_dX(kk, ll, mm, nn);
1117 for (
int cc = 0; cc != nbCols / 3; ++cc) {
1119 t_m(
i,
k) += t_row_stress(
i) * (t_invH(
j,
k) * t_col_diff_base(
j));
1120 t_m(
i,
k) += t_row_dX_stress(
i,
k,
l) * t_col_diff_base(
l);
1121 t_m(
i,
k) += t_row_stress_dX(
i,
k,
l) * t_col_diff_base(
l);
1134 for (; rr != row_nb_base_fun; ++rr)
1149HookeElement::OpAleLhs_dX_dX<S>::OpAleLhs_dX_dX(
1150 const std::string row_field,
const std::string col_field,
1151 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
1152 :
OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, true) {}
1161 auto get_tensor2 = [](
MatrixDouble &
m,
const int r,
const int c) {
1163 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 1,
c + 0),
1164 &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 2,
c + 0), &
m(r + 2,
c + 1),
1176 double vol = getVolume();
1179 auto t_w = getFTensor0IntegrationWeight();
1183 const int row_nb_base_fun = row_data.
getN().size2();
1189 auto t_cauchy_stress =
1191 *(dataAtPts->cauchyStressMat));
1193 *(dataAtPts->smallStrainMat));
1194 auto t_eshelby_stress =
1196 *dataAtPts->eshelbyStressMat);
1197 auto t_h = getFTensor2FromMat<3, 3>(*dataAtPts->hMat);
1201 auto &det_H = *dataAtPts->detHVec;
1204 for (
int gg = 0; gg != nbIntegrationPts; ++gg) {
1207 double a = t_w * vol * det_H[gg];
1210 t_F_dX(
i,
j,
k,
l) = -(t_h(
i,
m) * t_invH(
m,
k)) * t_invH(
l,
j);
1213 t_D_strain_dX(
i,
j,
m,
n) = 0.;
1214 for (
int ii = 0; ii != 3; ++ii)
1215 for (
int jj = 0; jj != 3; ++jj)
1216 for (
int ll = 0; ll != 3; ++ll)
1217 for (
int kk = 0; kk != 3; ++kk) {
1218 auto &
v = t_D_strain_dX(ii, jj, kk, ll);
1219 for (
int mm = 0; mm != 3; ++mm)
1220 for (
int nn = 0; nn != 3; ++nn)
1221 v += t_D(ii, jj, mm, nn) * t_F_dX(mm, nn, kk, ll);
1225 t_eshelby_stress_dX(
i,
j,
m,
n) = t_F(
k,
i) * t_D_strain_dX(
k,
j,
m,
n);
1227 for (
int ii = 0; ii != 3; ++ii)
1228 for (
int jj = 0; jj != 3; ++jj)
1229 for (
int mm = 0; mm != 3; ++mm)
1230 for (
int nn = 0; nn != 3; ++nn) {
1231 auto &
v = t_eshelby_stress_dX(ii, jj, mm, nn);
1232 for (
int kk = 0; kk != 3; ++kk)
1233 v += t_F_dX(kk, ii, mm, nn) * t_cauchy_stress(kk, jj);
1236 t_eshelby_stress_dX(
i,
j,
k,
l) *= -1;
1239 t_energy_dX(
k,
l) = t_F_dX(
i,
j,
k,
l) * t_cauchy_stress(
i,
j);
1240 t_energy_dX(
k,
l) +=
1241 (t_strain(
m,
n) * t_D(
m,
n,
i,
j)) * t_F_dX(
i,
j,
k,
l);
1242 t_energy_dX(
k,
l) /= 2.;
1244 for (
int kk = 0; kk != 3; ++kk)
1245 for (
int ll = 0; ll != 3; ++ll) {
1246 auto v = t_energy_dX(kk, ll);
1247 for (
int ii = 0; ii != 3; ++ii)
1248 t_eshelby_stress_dX(ii, ii, kk, ll) +=
v;
1253 for (; rr != nbRows / 3; ++rr) {
1256 auto t_m = get_tensor2(
K, 3 * rr, 0);
1259 t_row_diff_base_pulled(
i) = t_row_diff_base(
j) * t_invH(
j,
i);
1262 t_row_stress(
i) =
a * t_row_diff_base_pulled(
j) * t_eshelby_stress(
i,
j);
1265 t_row_diff_base_pulled_dX(
j,
k,
l) =
1266 -(t_row_diff_base(
i) * t_invH(
i,
k)) * t_invH(
l,
j);
1269 t_row_dX_stress(
i,
k,
l) =
1270 a * (t_row_diff_base_pulled_dX(
j,
k,
l) * t_eshelby_stress(
i,
j));
1273 t_row_stress_dX(
i,
m,
n) =
1274 a * t_row_diff_base_pulled(
j) * t_eshelby_stress_dX(
i,
j,
m,
n);
1280 for (
int cc = 0; cc != nbCols / 3; ++cc) {
1282 t_m(
i,
k) += t_row_stress(
i) * (t_invH(
j,
k) * t_col_diff_base(
j));
1283 t_m(
i,
k) += t_row_dX_stress(
i,
k,
l) * t_col_diff_base(
l);
1284 t_m(
i,
k) += t_row_stress_dX(
i,
k,
l) * t_col_diff_base(
l);
1297 for (; rr != row_nb_base_fun; ++rr)
1315HookeElement::OpAleLhsPre_dX_dx<S>::OpAleLhsPre_dX_dx(
1316 const std::string row_field,
const std::string col_field,
1317 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
1319 dataAtPts(data_at_pts) {
1325 EntityType row_type,
1329 const int nb_integration_pts = row_data.
getN().size1();
1331 auto get_eshelby_stress_dx = [
this, nb_integration_pts]() {
1333 t_eshelby_stress_dx;
1334 dataAtPts->eshelbyStress_dx->resize(81, nb_integration_pts,
false);
1336 for (
int ii = 0; ii != 3; ++ii)
1337 for (
int jj = 0; jj != 3; ++jj)
1338 for (
int kk = 0; kk != 3; ++kk)
1339 for (
int ll = 0; ll != 3; ++ll)
1340 t_eshelby_stress_dx.ptr(ii, jj, kk, ll) =
1341 &(*dataAtPts->eshelbyStress_dx)(mm++, 0);
1342 return t_eshelby_stress_dx;
1345 auto t_eshelby_stress_dx = get_eshelby_stress_dx();
1358 auto t_cauchy_stress =
1360 *(dataAtPts->cauchyStressMat));
1365 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1367 t_eshelby_stress_dx(
i,
j,
m,
n) =
1368 (t_F(
k,
i) * t_D(
k,
j,
m,
l)) * t_invH(
n,
l);
1369 for (
int ii = 0; ii != 3; ++ii)
1370 for (
int jj = 0; jj != 3; ++jj)
1371 for (
int mm = 0; mm != 3; ++mm)
1372 for (
int nn = 0; nn != 3; ++nn) {
1373 auto &
v = t_eshelby_stress_dx(ii, jj, mm, nn);
1374 v += t_invH(nn, ii) * t_cauchy_stress(mm, jj);
1376 t_eshelby_stress_dx(
i,
j,
k,
l) *= -1;
1379 t_energy_dx(
m,
n) = t_invH(
n,
j) * t_cauchy_stress(
m,
j);
1381 for (
int mm = 0; mm != 3; ++mm)
1382 for (
int nn = 0; nn != 3; ++nn) {
1383 auto v = t_energy_dx(mm, nn);
1384 for (
int ii = 0; ii != 3; ++ii)
1385 t_eshelby_stress_dx(ii, ii, mm, nn) +=
v;
1391 ++t_eshelby_stress_dx;
1398template <
class ELEMENT>
1399HookeElement::OpPostProcHookeElement<ELEMENT>::OpPostProcHookeElement(
1400 const string row_field, boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
1401 map<int, BlockData> &block_sets_ptr, moab::Interface &post_proc_mesh,
1402 std::vector<EntityHandle> &map_gauss_pts,
bool is_ale,
bool is_field_disp)
1404 dataAtPts(data_at_pts), blockSetsPtr(block_sets_ptr),
1405 postProcMesh(post_proc_mesh), mapGaussPts(map_gauss_pts), isALE(is_ale),
1406 isFieldDisp(is_field_disp) {}
1408template <
class ELEMENT>
1413 if (
type != MBVERTEX) {
1417 auto tensor_to_tensor = [](
const auto &t1,
auto &t2) {
1418 t2(0, 0) = t1(0, 0);
1419 t2(1, 1) = t1(1, 1);
1420 t2(2, 2) = t1(2, 2);
1421 t2(0, 1) = t2(1, 0) = t1(1, 0);
1422 t2(0, 2) = t2(2, 0) = t1(2, 0);
1423 t2(1, 2) = t2(2, 1) = t1(2, 1);
1426 std::array<double, 9> def_val;
1429 auto make_tag = [&](
auto name,
auto size) {
1431 CHKERR postProcMesh.tag_get_handle(name, size, MB_TYPE_DOUBLE,
th,
1432 MB_TAG_CREAT | MB_TAG_SPARSE,
1437 auto th_stress = make_tag(
"STRESS", 9);
1438 auto th_psi = make_tag(
"ENERGY", 1);
1440 const int nb_integration_pts = mapGaussPts.size();
1447 auto t_h = getFTensor2FromMat<3, 3>(*dataAtPts->hMat);
1448 auto t_H = getFTensor2FromMat<3, 3>(*dataAtPts->HMat);
1450 dataAtPts->stiffnessMat->resize(36, 1,
false);
1454 EntityHandle ent = this->getFEEntityHandle();
1456 EntityHandle ent_3d = ent;
1457 if (
type == MBTRI ||
type == MBQUAD) {
1459 auto &m_field = this->getPtrFE()->mField;
1460 CHKERR m_field.get_moab().get_adjacencies(&ent, 1, 3,
false, ents,
1461 moab::Interface::UNION);
1465 "Could not find a 3D element adjacent to a given face element");
1467 ent_3d = ents.front();
1470 bool found_block =
false;
1472 for (
auto &
m : (blockSetsPtr)) {
1473 if (
m.second.tEts.find(ent_3d) !=
m.second.tEts.end()) {
1474 const double young =
m.second.E;
1475 const double poisson =
m.second.PoissonRatio;
1476 const double coefficient = young / ((1 + poisson) * (1 - 2 * poisson));
1477 block_id =
m.second.iD;
1479 t_D(
i,
j,
k,
l) = 0.;
1480 t_D(0, 0, 0, 0) = t_D(1, 1, 1, 1) = t_D(2, 2, 2, 2) = 1 - poisson;
1481 t_D(0, 1, 0, 1) = t_D(0, 2, 0, 2) = t_D(1, 2, 1, 2) =
1482 0.5 * (1 - 2 * poisson);
1483 t_D(0, 0, 1, 1) = t_D(1, 1, 0, 0) = t_D(0, 0, 2, 2) = t_D(2, 2, 0, 0) =
1484 t_D(1, 1, 2, 2) = t_D(2, 2, 1, 1) = poisson;
1485 t_D(
i,
j,
k,
l) *= coefficient;
1493 "Element not found in any of material blocksets");
1495 int def_val_int = 0;
1497 CHKERR postProcMesh.tag_get_handle(
"MAT_ELASTIC", 1, MB_TYPE_INTEGER, tag_mat,
1498 MB_TAG_CREAT | MB_TAG_SPARSE, &def_val_int);
1507 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1516 t_small_strain_symm(
i,
j) = (t_h(
i,
j) || t_h(
j,
i)) / 2.;
1520 t_F(
i,
j) = t_h(
i,
k) * t_invH(
k,
j);
1521 t_small_strain_symm(
i,
j) = (t_F(
i,
j) || t_F(
j,
i)) / 2.;
1525 t_small_strain_symm(0, 0) -= 1;
1526 t_small_strain_symm(1, 1) -= 1;
1527 t_small_strain_symm(2, 2) -= 1;
1530 t_stress_symm(
i,
j) = t_D(
i,
j,
k,
l) * t_small_strain_symm(
k,
l);
1531 tensor_to_tensor(t_stress_symm, t_stress);
1533 const double psi = 0.5 * t_stress_symm(
i,
j) * t_small_strain_symm(
i,
j);
1535 CHKERR postProcMesh.tag_set_data(th_psi, &mapGaussPts[gg], 1, &psi);
1536 CHKERR postProcMesh.tag_set_data(th_stress, &mapGaussPts[gg], 1,
1538 CHKERR postProcMesh.tag_set_data(tag_mat, &mapGaussPts[gg], 1,
1548HookeElement::OpAnalyticalInternalStrain_dx<S>::OpAnalyticalInternalStrain_dx(
1549 const std::string row_field,
1550 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
1552 :
OpAssemble(row_field, row_field, data_at_pts, OPROW, true),
1553 strainFun(strain_fun) {}
1557HookeElement::OpAnalyticalInternalStrain_dx<S>::iNtegrate(
EntData &row_data) {
1566 &
v(r + 0), &
v(r + 1), &
v(r + 2));
1569 const int nb_integration_pts = getGaussPts().size2();
1570 auto t_coords = getFTensor1CoordsAtGaussPts();
1573 double vol = getVolume();
1574 auto t_w = getFTensor0IntegrationWeight();
1576 nF.resize(nbRows,
false);
1586 const int row_nb_base_fun = row_data.
getN().size2();
1588 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
1590 auto t_fun_strain = strainFun(t_coords);
1592 t_stress(
i,
j) = -t_D(
i,
j,
k,
l) * t_fun_strain(
k,
l);
1595 double a = t_w * vol;
1597 auto t_nf = get_tensor1(nF, 0);
1600 for (; rr != nbRows / 3; ++rr) {
1601 t_nf(
i) +=
a * t_row_diff_base(
j) * t_stress(
i,
j);
1606 for (; rr != row_nb_base_fun; ++rr)
1618HookeElement::OpAnalyticalInternalAleStrain_dX<S>::
1619 OpAnalyticalInternalAleStrain_dX(
1620 const std::string row_field,
1621 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
1623 boost::shared_ptr<MatrixDouble> mat_pos_at_pts_ptr)
1624 :
OpAssemble(row_field, row_field, data_at_pts, OPROW, true),
1625 strainFun(strain_fun), matPosAtPtsPtr(mat_pos_at_pts_ptr) {}
1638 &
v(r + 0), &
v(r + 1), &
v(r + 2));
1641 const int nb_integration_pts = getGaussPts().size2();
1643 auto get_coords = [&]() {
1644 return getFTensor1FromMat<3>(*matPosAtPtsPtr);
1646 auto t_coords = get_coords();
1649 double vol = getVolume();
1650 auto t_w = getFTensor0IntegrationWeight();
1652 nF.resize(nbRows,
false);
1660 *(dataAtPts->FMat));
1661 auto &det_H = *dataAtPts->detHVec;
1667 const int row_nb_base_fun = row_data.
getN().size2();
1669 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
1671 auto t_fun_strain = strainFun(t_coords);
1673 t_stress(
i,
j) = -t_D(
i,
j,
k,
l) * t_fun_strain(
k,
l);
1675 t_eshelby_stress(
i,
j) = -t_F(
k,
i) * t_stress(
k,
j);
1678 double a = t_w * vol * det_H[gg];
1680 auto t_nf = get_tensor1(nF, 0);
1683 for (; rr != nbRows / 3; ++rr) {
1685 t_row_diff_base_pulled(
i) = t_row_diff_base(
j) * t_invH(
j,
i);
1686 t_nf(
i) +=
a * t_row_diff_base_pulled(
j) * t_eshelby_stress(
i,
j);
1691 for (; rr != row_nb_base_fun; ++rr)
1705HookeElement::OpAnalyticalInternalAleStrain_dx<S>::
1706 OpAnalyticalInternalAleStrain_dx(
1707 const std::string row_field,
1708 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
1710 boost::shared_ptr<MatrixDouble> mat_pos_at_pts_ptr)
1711 :
OpAssemble(row_field, row_field, data_at_pts, OPROW, true),
1712 strainFun(strain_fun), matPosAtPtsPtr(mat_pos_at_pts_ptr) {}
1725 &
v(r + 0), &
v(r + 1), &
v(r + 2));
1728 const int nb_integration_pts = getGaussPts().size2();
1730 auto get_coords = [&]() {
1731 return getFTensor1FromMat<3>(*matPosAtPtsPtr);
1733 auto t_coords = get_coords();
1736 double vol = getVolume();
1737 auto t_w = getFTensor0IntegrationWeight();
1739 nF.resize(nbRows,
false);
1746 auto &det_H = *dataAtPts->detHVec;
1752 const int row_nb_base_fun = row_data.
getN().size2();
1754 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
1756 auto t_fun_strain = strainFun(t_coords);
1758 t_stress(
i,
j) = -t_D(
i,
j,
k,
l) * t_fun_strain(
k,
l);
1761 double a = t_w * vol * det_H[gg];
1763 auto t_nf = get_tensor1(nF, 0);
1766 for (; rr != nbRows / 3; ++rr) {
1768 t_row_diff_base_pulled(
i) = t_row_diff_base(
j) * t_invH(
j,
i);
1769 t_nf(
i) +=
a * t_row_diff_base_pulled(
j) * t_stress(
i,
j);
1774 for (; rr != row_nb_base_fun; ++rr)
static MoFEMErrorCode addElasticElement(MoFEM::Interface &m_field, boost::shared_ptr< map< int, BlockData > > &block_sets_ptr, const std::string element_name, const std::string x_field, const std::string X_field, const bool ale)
static MoFEMErrorCode setOperators(boost::shared_ptr< ForcesAndSourcesCore > fe_lhs_ptr, boost::shared_ptr< ForcesAndSourcesCore > fe_rhs_ptr, boost::shared_ptr< map< int, BlockData > > block_sets_ptr, const std::string x_field, const std::string X_field, const bool ale, const bool field_disp, const EntityType type=MBTET, boost::shared_ptr< DataAtIntegrationPts > data_at_pts=nullptr)
static MoFEMErrorCode setBlocks(MoFEM::Interface &m_field, boost::shared_ptr< map< int, BlockData > > &block_sets_ptr)
static MoFEMErrorCode calculateEnergy(DM dm, boost::shared_ptr< map< int, BlockData > > block_sets_ptr, const std::string x_field, const std::string X_field, const bool ale, const bool field_disp, SmartPetscObj< Vec > &v_energy_ptr)
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#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.
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< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
UBlasVector< double > VectorDouble
UBlasVector< int > VectorInt
auto type_from_handle(const EntityHandle h)
get type from entity handle
auto getFTensor2FromMat(M &data)
Get tensor rank 2 (matrix) form data matrix.
static auto getFTensor2SymmetricFromMat(M &data)
Get symmetric tensor rank 2 (matrix) form data matrix.
MoFEMErrorCode invertTensor3by3(ublas::matrix< T, L, A > &jac_data, ublas::vector< T, A > &det_data, ublas::matrix< T, L, A > &inv_jac_data)
Calculate inverse of tensor rank 2 at integration points.
MoFEMErrorCode MatSetValues(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const double *ptr, InsertMode iora)
Assemble PETSc matrix.
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
FTensor::Index< 'm', 3 > m
data for calculation inertia forces
Range tEts
elements in block set
double rho0
reference density
VectorDouble a0
constant acceleration
structure grouping operators and data used for calculation of mass (convective) element \ nonlinear_e...
boost::shared_ptr< MatrixDouble > HMat
boost::shared_ptr< MatrixDouble > invHMat
Range forcesOnlyOnEntitiesRow
boost::shared_ptr< MatrixDouble > smallStrainMat
boost::shared_ptr< MatrixDouble > cauchyStressMat
boost::shared_ptr< MatrixDouble > eshelbyStress_dx
boost::shared_ptr< MatrixDouble > FMat
Range forcesOnlyOnEntitiesCol
boost::shared_ptr< MatrixDouble > eshelbyStressMat
boost::shared_ptr< MatrixDouble > stiffnessMat
boost::shared_ptr< MatrixDouble > hMat
boost::shared_ptr< VectorDouble > energyVec
boost::shared_ptr< VectorDouble > detHVec
std::array< bool, MBMAXTYPE > doEntities
If true operator is executed for entity.
Deprecated interface functions.
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.
auto getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
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 degrees of freedom on entity.
intrusive_ptr for managing petsc objects
Volume finite element base.
data for calculation heat conductivity and heat capacity elements
Range forcesOnlyOnEntitiesRow
Range forcesOnlyOnEntitiesCol
Range tEts
constrains elements in block set
structure grouping operators and data used for calculation of nonlinear elastic element
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< VectorDouble > rhoAtGaussPtsPtr
boost::shared_ptr< MatrixDouble > rhoGradAtGaussPtsPtr
boost::shared_ptr< VectorDouble > rhoAtGaussPtsPtr
boost::shared_ptr< MatrixDouble > rhoGradAtGaussPtsPtr
OpAleLhs_dX_dx(const std::string row_field, const std::string col_field, boost::shared_ptr< DataAtIntegrationPts > &data_at_pts)
boost::shared_ptr< MatrixDouble > matPosAtPtsPtr
boost::function< FTensor::Tensor2_symmetric< double, 3 >(FTensor::Tensor1< FTensor::PackPtr< double *, 1 >, 3 > &t_coords) > StrainFunction
boost::shared_ptr< MatrixDouble > matPosAtPtsPtr
boost::function< FTensor::Tensor2_symmetric< double, 3 >(FTensor::Tensor1< FTensor::PackPtr< double *, 1 >, 3 > &t_coords) > StrainFunction
boost::function< FTensor::Tensor2_symmetric< double, 3 >(FTensor::Tensor1< FTensor::PackPtr< double *, 3 >, 3 > &t_coords) > StrainFunction
int nbCols
number if dof on column
bool isDiag
true if this block is on diagonal
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
int nbIntegrationPts
number of integration points
int nbRows
number of dofs on rows
SmartPetscObj< Vec > ghostVec
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
boost::shared_ptr< map< int, BlockData > > blockSetsPtr
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
Assemble mass matrix for elastic element TODO: CHANGE FORMULA *.
OpCalculateMassMatrix(const std::string row_field, const std::string col_field, BlockData &data, MassBlockData &mass_data, boost::shared_ptr< DataAtIntegrationPts > &common_data, bool symm=true)
PetscErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
boost::shared_ptr< DataAtIntegrationPts > commonData
const double rHo0
p_0 reference density in E(p) = E * (p / p_0)^n
boost::shared_ptr< map< int, BlockData > > blockSetsPtr
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< VectorDouble > rhoAtGaussPtsPtr
const double rhoN
exponent n in E(p) = E * (p / p_0)^n
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
std::vector< EntityHandle > & mapGaussPts
map< int, BlockData > & blockSetsPtr
moab::Interface & postProcMesh
boost::shared_ptr< DataAtIntegrationPts > dataAtPts