25 #include <boost/program_options.hpp>
27 namespace po = boost::program_options;
30 using namespace MoFEM;
35 #error "MoFEM need to be compiled with ADOL-C"
38 #define TENSOR1_VEC_PTR(VEC) &VEC[0], &VEC[1], &VEC[2]
40 #define SYMMETRIC_TENSOR4_MAT_PTR(MAT) \
41 &MAT(0, 0), &MAT(0, 1), &MAT(0, 2), &MAT(0, 3), &MAT(0, 4), &MAT(0, 5), \
42 &MAT(1, 0), &MAT(1, 1), &MAT(1, 2), &MAT(1, 3), &MAT(1, 4), &MAT(1, 5), \
43 &MAT(2, 0), &MAT(2, 1), &MAT(2, 2), &MAT(2, 3), &MAT(2, 4), &MAT(2, 5), \
44 &MAT(3, 0), &MAT(3, 1), &MAT(3, 2), &MAT(3, 3), &MAT(3, 4), &MAT(3, 5), \
45 &MAT(4, 0), &MAT(4, 1), &MAT(4, 2), &MAT(4, 3), &MAT(4, 4), &MAT(4, 5), \
46 &MAT(5, 0), &MAT(5, 1), &MAT(5, 2), &MAT(5, 3), &MAT(5, 4), &MAT(5, 5)
48 #define TENSOR4_MAT_PTR(MAT) &MAT(0, 0), MAT.size2()
50 #define TENSOR2_MAT_PTR(MAT) \
51 &MAT(0, 0), &MAT(1, 0), &MAT(2, 0), &MAT(3, 0), &MAT(4, 0), &MAT(5, 0), \
52 &MAT(6, 0), &MAT(7, 0), &MAT(8, 0)
54 #define SYMMETRIC_TENSOR2_MAT_PTR(MAT) \
55 &MAT(0, 0), &MAT(0, 1), &MAT(0, 2), &MAT(0, 3), &MAT(0, 4), &MAT(0, 5)
57 #define SYMMETRIC_TENSOR2_VEC_PTR(VEC) \
58 &VEC[0], &VEC[1], &VEC[2], &VEC[3], &VEC[4], &VEC[5]
64 PetscBool flg_config = PETSC_FALSE;
65 is_atom_testing = PETSC_FALSE;
66 with_adol_c = PETSC_FALSE;
67 char my_config_file_name[255];
77 rHo_max = rHo_ref + 0.5 * rHo_ref;
78 rHo_min = rHo_ref - 0.5 * rHo_ref;
83 nOremodellingBlock =
false;
84 less_post_proc = PETSC_FALSE;
87 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Bone remodeling parameters",
91 CHKERR PetscOptionsString(
"-my_config",
"configuration file name",
"",
92 "my_config.in", my_config_file_name, 255,
96 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"Config file: %s loaded.\n",
99 ifstream ini_file(my_config_file_name);
100 if (!ini_file.is_open()) {
101 SETERRQ(PETSC_COMM_SELF, 1,
"*** -my_config does not exist ***");
103 po::variables_map vm;
104 po::options_description config_file_options;
107 config_file_options.add_options()(
108 "young_modulus", po::value<double>(&
young_modulus)->default_value(1));
109 config_file_options.add_options()(
110 "poisson_ratio", po::value<double>(&
poisson_ratio)->default_value(1));
111 config_file_options.add_options()(
112 "c", po::value<double>(&
c)->default_value(1));
113 config_file_options.add_options()(
114 "m", po::value<double>(&
m)->default_value(1));
115 config_file_options.add_options()(
116 "n", po::value<double>(&
n)->default_value(1));
117 config_file_options.add_options()(
118 "rHo_ref", po::value<double>(&rHo_ref)->default_value(1));
119 config_file_options.add_options()(
120 "pSi_ref", po::value<double>(&pSi_ref)->default_value(1));
121 config_file_options.add_options()(
122 "R0", po::value<double>(&R0)->default_value(1));
124 po::parsed_options parsed =
125 parse_config_file(ini_file, config_file_options,
true);
129 }
catch (
const std::exception &ex) {
130 std::ostringstream ss;
131 ss << ex.what() << std::endl;
136 CHKERR PetscOptionsScalar(
"-young_modulus",
"get young modulus",
"",
139 CHKERR PetscOptionsScalar(
"-poisson_ratio",
"get poisson_ratio",
"",
142 CHKERR PetscOptionsScalar(
"-c",
"density evolution (growth) velocity [d/m^2]",
143 "",
c, &
c, PETSC_NULL);
145 CHKERR PetscOptionsScalar(
"-m",
"algorithmic exponent",
"",
m, &
m,
148 CHKERR PetscOptionsScalar(
"-n",
"porosity exponent",
"",
n, &
n, PETSC_NULL);
150 CHKERR PetscOptionsInt(
"-b",
"bell function exponent",
"", b, &b, PETSC_NULL);
152 CHKERR PetscOptionsScalar(
"-rho_ref",
"reference bone density",
"", rHo_ref,
153 &rHo_ref, PETSC_NULL);
155 CHKERR PetscOptionsScalar(
"-rho_max",
"reference bone density",
"", rHo_max,
156 &rHo_max, PETSC_NULL);
157 CHKERR PetscOptionsScalar(
"-rho_min",
"reference bone density",
"", rHo_min,
158 &rHo_min, PETSC_NULL);
160 CHKERR PetscOptionsScalar(
"-psi_ref",
"reference energy density",
"", pSi_ref,
161 &pSi_ref, PETSC_NULL);
163 CHKERR PetscOptionsScalar(
"-r0",
"mass source",
"", R0, &R0, PETSC_NULL);
165 CHKERR PetscOptionsBool(
"-my_is_atom_test",
166 "is used with testing, exit with error when diverged",
167 "", is_atom_testing, &is_atom_testing, PETSC_NULL);
169 CHKERR PetscOptionsBool(
"-less_post_proc",
170 "is used to reduce output file size",
"",
171 less_post_proc, &less_post_proc, PETSC_NULL);
175 "calculate the material tangent with automatic differentiation",
"",
176 with_adol_c, &with_adol_c, PETSC_NULL);
181 CHKERR PetscPrintf(PETSC_COMM_WORLD,
182 "Young's modulus E[Pa]: %4.3g\n",
184 CHKERR PetscPrintf(PETSC_COMM_WORLD,
185 "Poisson ratio nu[-] %4.3g\n",
187 CHKERR PetscPrintf(PETSC_COMM_WORLD,
188 "Lame coefficient lambda[Pa]: %4.3g\n",
lambda);
189 CHKERR PetscPrintf(PETSC_COMM_WORLD,
190 "Lame coefficient mu[Pa]: %4.3g\n",
mu);
191 CHKERR PetscPrintf(PETSC_COMM_WORLD,
192 "Density growth velocity [d/m2] %4.3g\n",
c);
193 CHKERR PetscPrintf(PETSC_COMM_WORLD,
194 "Algorithmic exponent m[-]: %4.3g\n",
m);
195 CHKERR PetscPrintf(PETSC_COMM_WORLD,
196 "Porosity exponent n[-]: %4.3g\n",
n);
197 CHKERR PetscPrintf(PETSC_COMM_WORLD,
198 "Reference density rHo_ref[kg/m3]: %4.3g\n", rHo_ref);
199 CHKERR PetscPrintf(PETSC_COMM_WORLD,
200 "Reference energy pSi_ref[Pa]: %4.3g\n", pSi_ref);
201 CHKERR PetscPrintf(PETSC_COMM_WORLD,
202 "Mass conduction R0[kg/m3s]: %4.3g\n", R0);
203 CHKERR PetscPrintf(PETSC_COMM_WORLD,
204 "Bell function coefficent b[-]: %4.3g\n", b);
206 CHKERR PetscPrintf(PETSC_COMM_WORLD,
207 "Max density rHo_max[kg/m3]: %4.3g\n", rHo_max);
208 CHKERR PetscPrintf(PETSC_COMM_WORLD,
209 "Min density rHo_min[kg/m3]: %4.3g\n", rHo_min);
212 ierr = PetscOptionsEnd();
218 inline double Remodeling::CommonData::getCFromDensity(
const double &
rho) {
219 double mid_rho = 0.5 * (rHo_max + rHo_min);
220 double var_h = (
rho - mid_rho) / (rHo_max - mid_rho);
222 return 1 / (1 + (b != 0) * pow(var_h, 2 * b));
225 inline double Remodeling::CommonData::getCFromDensityDiff(
const double &
rho) {
226 double mid_rho = 0.5 * (rHo_max + rHo_min);
227 double var_h = (
rho - mid_rho) / (rHo_max - mid_rho);
228 return (b != 0) * (-2) * b * pow(var_h, 2 * b - 1) /
229 ((rHo_max - mid_rho) * pow(pow(var_h, 2 * b) + 1, 2));
232 OpGetRhoTimeDirevative::OpGetRhoTimeDirevative(
236 commonData(common_data) {}
244 const int nb_gauss_pts = data.getN().size1();
247 const int nb_base_functions = data.getN().size2();
249 auto base_function = data.getFTensor0N();
251 if (
type == MBVERTEX) {
255 int nb_dofs = data.getIndices().size();
262 for (
int gg = 0; gg < nb_gauss_pts; gg++) {
264 for (; bb < nb_dofs; bb++) {
265 const double field_data = array[data.getLocalIndices()[bb]];
266 drho_dt += field_data * base_function;
270 for (; bb != nb_base_functions; bb++)
283 commonData(common_data) {
299 if (
type != MBVERTEX)
304 "Gradient at integration points of displacement is not calculated");
311 "Density at integration points is not calculated");
326 matS.resize(nb_gauss_pts, 6,
false);
331 matF.resize(9, nb_gauss_pts,
false);
345 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
348 F(
i,
I) = grad(
i,
I);
356 const double log_det = log(det_f);
357 psi =
F(
i,
J) *
F(
i,
J) - 3 - 2 * log_det;
359 psi += 0.5 *
lambda * log_det * log_det;
361 const double coef =
lambda * log_det -
mu;
363 S(
i,
I) = invF(
i,
J) ^
P(
J,
I);
366 R =
c * kp * (pow(
rho / rho_ref,
n -
m) * psi - psi_ref);
386 commonData(common_data) {
401 if (
type != MBVERTEX)
407 vecC.resize(6,
false);
410 dS_dC.resize(6, 6 * nb_gauss_pts,
false);
415 matS.resize(nb_gauss_pts, 6,
false);
418 dP_dF.resize(81, nb_gauss_pts,
false);
420 matF.resize(9, nb_gauss_pts,
false);
435 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
438 F(
i,
I) = grad(
i,
I);
449 CHKERR recordFreeEnergy_dC<FTensor::Tensor0<FTensor::PackPtr<double *, 1>>,
458 "ADOL-C function evaluation with error");
469 const int is = 6 * gg;
470 double *hessian_ptr[6] = {&dS_dC(0, is), &dS_dC(1, is), &dS_dC(2, is),
471 &dS_dC(3, is), &dS_dC(4, is), &dS_dC(5, is)};
477 "ADOL-C function evaluation with error");
494 for (
int ii = 0; ii < 6; ii++) {
495 for (
int jj = 0; jj < ii; jj++) {
496 dS_dC(jj, is + ii) = dS_dC(ii, is + jj);
551 std::vector<EntityHandle> &map_gauss_pts,
555 commonData(common_data), postProcMesh(post_proc_mesh),
556 mapGaussPts(map_gauss_pts) {
572 if (
type != MBVERTEX)
575 bzero(def_VAL, 9 *
sizeof(
double));
579 th_piola2, MB_TAG_CREAT | MB_TAG_SPARSE,
584 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
588 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
592 Tag th_prin_stress_vect1, th_prin_stress_vect2, th_prin_stress_vect3;
598 th_piola1, MB_TAG_CREAT | MB_TAG_SPARSE,
602 principal, MB_TAG_CREAT | MB_TAG_SPARSE,
606 th_prin_stress_vect1,
607 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
609 th_prin_stress_vect2,
610 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
612 th_prin_stress_vect3,
613 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
616 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
620 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
637 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
646 for (
int ii = 0; ii != 3; ii++) {
647 for (
int jj = 0; jj != 3; jj++) {
648 stress(ii, jj) = S(ii, jj);
656 for (
int ii = 0; ii != 3; ii++) {
657 for (
int jj = 0; jj != 3; jj++) {
658 stress(ii, jj) =
P(ii, jj);
665 const double t2[] = {grad_rho(0), grad_rho(1), grad_rho(2)};
669 noalias(eigen_vectors) = stress;
675 int n = 3, lda = 3, info, lwork = -1;
677 info =
lapack_dsyev(
'V',
'U',
n, &(eigen_vectors.data()[0]), lda,
678 &(eigen_values.data()[0]), &wkopt, lwork);
680 SETERRQ1(PETSC_COMM_SELF, 1,
681 "something is wrong with lapack_dsyev info = %d", info);
684 info =
lapack_dsyev(
'V',
'U',
n, &(eigen_vectors.data()[0]), lda,
685 &(eigen_values.data()[0]), work, lwork);
687 SETERRQ1(PETSC_COMM_SELF, 1,
688 "something is wrong with lapack_dsyev info = %d", info);
690 for (
int ii = 0; ii < 3; ii++) {
691 prin_stress_vect1[ii] = eigen_vectors(0, ii);
692 prin_stress_vect2[ii] = eigen_vectors(1, ii);
693 prin_stress_vect3[ii] = eigen_vectors(2, ii);
699 1, &*prin_stress_vect1.begin());
701 1, &*prin_stress_vect2.begin());
703 1, &*prin_stress_vect3.begin());
721 commonData(common_data) {
737 if (
type != MBVERTEX)
749 dP_dF.resize(81, nb_gauss_pts,
false);
751 matF.resize(9, nb_gauss_pts,
false);
767 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
770 F(
i,
I) = grad(
i,
I);
778 const double log_det = log(det_f);
779 psi =
F(
i,
J) *
F(
i,
J) - 3 - 2 * log_det;
781 psi += 0.5 *
lambda * log_det * log_det;
783 const double var =
lambda * log_det -
mu;
786 const double coef =
mu -
lambda * log_det;
790 invF(
J,
i) * (invF(
L,
k) *
lambda) + invF(
L,
i) * (invF(
J,
k) * coef);
792 D2(0, 0, 0, 0) +=
mu;
793 D2(0, 1, 0, 1) +=
mu;
794 D2(0, 2, 0, 2) +=
mu;
795 D2(1, 0, 1, 0) +=
mu;
796 D2(1, 1, 1, 1) +=
mu;
797 D2(1, 2, 1, 2) +=
mu;
798 D2(2, 0, 2, 0) +=
mu;
799 D2(2, 1, 2, 1) +=
mu;
800 D2(2, 2, 2, 2) +=
mu;
817 commonData(common_data) {}
825 const int nb_dofs = data.getIndices().size();
828 nF.resize(nb_dofs,
false);
831 const int nb_gauss_pts = data.getN().size1();
832 const int nb_base_functions = data.getN().size2();
833 auto diff_base_functions = data.getFTensor1DiffN<3>();
849 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
853 double a =
w * pow(
rho / rho_ref,
n);
856 for (; bb != nb_dofs / 3; bb++) {
857 double *ptr = &
nF[3 * bb];
859 t1(
i) +=
a *
P(
i,
I) * diff_base_functions(
I);
862 ++diff_base_functions;
866 for (; bb != nb_base_functions; bb++) {
867 ++diff_base_functions;
878 nb_dofs, &*data.getIndices().begin(), &*
nF.begin(), ADD_VALUES);
886 commonData(common_data) {}
894 const int nb_dofs = data.getIndices().size();
897 nF.resize(nb_dofs,
false);
900 const int nb_gauss_pts = data.getN().size1();
901 const int nb_base_functions = data.getN().size2();
902 auto base_functions = data.getFTensor0N();
903 auto diff_base_functions = data.getFTensor1DiffN<3>();
926 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
932 for (; bb != nb_dofs; bb++) {
933 nF[bb] +=
w * base_functions * drho_dt;
934 nF[bb] -=
w * base_functions *
R;
935 nF[bb] -=
w * R0 * diff_base_functions(
I) * grad_rho(
I);
937 ++diff_base_functions;
941 for (; bb != nb_base_functions; bb++) {
943 ++diff_base_functions;
956 nb_dofs, &*data.getIndices().begin(), &*
nF.begin(), ADD_VALUES);
964 commonData(common_data) {
976 const int row_nb_dofs = row_data.getIndices().size();
979 const int col_nb_dofs = col_data.getIndices().size();
987 const int row_nb_gauss_pts = row_data.getN().size1();
988 if (!row_nb_gauss_pts)
990 const int row_nb_base_functions = row_data.getN().size2();
1004 auto row_base_functions = row_data.getFTensor0N();
1005 auto row_diff_base_functions = row_data.getFTensor1DiffN<3>();
1007 for (
int gg = 0; gg != row_nb_gauss_pts; gg++) {
1014 const double a =
c * kp * ((
n -
m) /
rho) * pow(
rho / rho_ref,
n -
m) * psi;
1015 const double a_diff =
1016 c * kp_diff * (pow(
rho / rho_ref,
n -
m) * psi - psi_ref);
1019 for (; row_bb != row_nb_dofs; row_bb++) {
1020 auto col_base_functions = col_data.getFTensor0N(gg, 0);
1021 auto col_diff_base_functions = col_data.getFTensor1DiffN<3>(gg, 0);
1022 for (
int col_bb = 0; col_bb != col_nb_dofs; col_bb++) {
1024 ts_a *
w * row_base_functions * col_base_functions;
1026 w * R0 * row_diff_base_functions(
I) * col_diff_base_functions(
I);
1028 a *
w * row_base_functions * col_base_functions;
1030 a_diff *
w * row_base_functions * col_base_functions;
1032 ++col_base_functions;
1033 ++col_diff_base_functions;
1035 ++row_base_functions;
1036 ++row_diff_base_functions;
1038 for (; row_bb != row_nb_base_functions; row_bb++) {
1039 ++row_base_functions;
1040 ++row_diff_base_functions;
1049 &*row_data.getIndices().begin(), col_nb_dofs,
1054 if (row_side != col_side || row_type != col_type) {
1058 &*col_data.getIndices().begin(), row_nb_dofs,
1059 &*row_data.getIndices().begin(),
1069 commonData(common_data) {
1075 EntityType col_type,
1081 const int row_nb_dofs = row_data.getIndices().size();
1084 const int col_nb_dofs = col_data.getIndices().size();
1089 locK_rho_F.resize(row_nb_dofs, col_nb_dofs,
false);
1092 const int row_nb_gauss_pts = row_data.getN().size1();
1093 const int col_nb_base_functions = col_data.getN().size2();
1107 auto col_diff_base_functions = col_data.getFTensor1DiffN<3>();
1109 for (
int gg = 0; gg != row_nb_gauss_pts; gg++) {
1114 const double a =
w *
c * kp * pow(
rho / rho_ref,
n -
m);
1117 for (; col_bb != col_nb_dofs / 3; col_bb++) {
1118 t1(
i) =
a *
P(
i,
I) * col_diff_base_functions(
I);
1119 auto row_base_functions = row_data.getFTensor0N(gg, 0);
1120 for (
int row_bb = 0; row_bb != row_nb_dofs; row_bb++) {
1124 k(
i) -= row_base_functions * t1(
i);
1125 ++row_base_functions;
1127 ++col_diff_base_functions;
1129 for (; col_bb != col_nb_base_functions; col_bb++) {
1130 ++col_diff_base_functions;
1138 &*row_data.getIndices().begin(), col_nb_dofs,
1139 &*col_data.getIndices().begin(), &
locK_rho_F(0, 0),
1144 template <
bool ADOLC>
1149 commonData(common_data) {
1152 template <
bool ADOLC>
1154 int row_side,
int col_side, EntityType row_type, EntityType col_type,
1160 const int row_nb_dofs = row_data.getIndices().size();
1163 const int col_nb_dofs = col_data.getIndices().size();
1167 const bool diagonal_block = (row_type == col_type) && (row_side == col_side);
1170 locK_P_F.resize(row_nb_dofs, col_nb_dofs,
false);
1173 const int row_nb_gauss_pts = row_data.getN().size1();
1174 const int row_nb_base_functions = row_data.getN().size2();
1177 MatrixDouble &dP_dF = commonData.data.matPushedMaterialTangent;
1183 const double n = commonData.n;
1184 const double rho_ref = commonData.rHo_ref;
1194 auto row_diff_base_functions = row_data.getFTensor1DiffN<3>();
1202 for (
int gg = 0; gg != row_nb_gauss_pts; gg++) {
1205 double w = getVolume() * getGaussPts()(3, gg);
1206 const double a =
w * pow(
rho / rho_ref,
n);
1209 for (; row_bb != row_nb_dofs / 3; row_bb++) {
1211 auto col_diff_base_functions = col_data.getFTensor1DiffN<3>(gg, 0);
1213 const int final_bb = diagonal_block ? row_bb + 1 : col_nb_dofs / 3;
1215 for (; col_bb != final_bb; col_bb++) {
1218 &locK_P_F(3 * row_bb + 0, 3 * col_bb + 0),
1219 &locK_P_F(3 * row_bb + 0, 3 * col_bb + 1),
1220 &locK_P_F(3 * row_bb + 0, 3 * col_bb + 2),
1221 &locK_P_F(3 * row_bb + 1, 3 * col_bb + 0),
1222 &locK_P_F(3 * row_bb + 1, 3 * col_bb + 1),
1223 &locK_P_F(3 * row_bb + 1, 3 * col_bb + 2),
1224 &locK_P_F(3 * row_bb + 2, 3 * col_bb + 0),
1225 &locK_P_F(3 * row_bb + 2, 3 * col_bb + 1),
1226 &locK_P_F(3 * row_bb + 2, 3 * col_bb + 2));
1229 a * row_diff_base_functions(
J) * col_diff_base_functions(
L);
1234 t_assemble(
i,
k) += diffDiff(
J,
L) * D2(
i,
J,
k,
L);
1239 t0 = diffDiff(
J,
L) * S(
J,
L);
1240 t_assemble(0, 0) += t0;
1241 t_assemble(1, 1) += t0;
1242 t_assemble(2, 2) += t0;
1246 ++col_diff_base_functions;
1249 ++row_diff_base_functions;
1251 for (; row_bb != row_nb_base_functions; row_bb++) {
1252 ++row_diff_base_functions;
1263 if (diagonal_block) {
1264 for (
int row_bb = 0; row_bb != row_nb_dofs / 3; row_bb++) {
1266 for (; col_bb != row_bb + 1; col_bb++) {
1268 &locK_P_F(3 * row_bb + 0, 3 * col_bb + 0),
1269 &locK_P_F(3 * row_bb + 0, 3 * col_bb + 1),
1270 &locK_P_F(3 * row_bb + 0, 3 * col_bb + 2),
1271 &locK_P_F(3 * row_bb + 1, 3 * col_bb + 0),
1272 &locK_P_F(3 * row_bb + 1, 3 * col_bb + 1),
1273 &locK_P_F(3 * row_bb + 1, 3 * col_bb + 2),
1274 &locK_P_F(3 * row_bb + 2, 3 * col_bb + 0),
1275 &locK_P_F(3 * row_bb + 2, 3 * col_bb + 1),
1276 &locK_P_F(3 * row_bb + 2, 3 * col_bb + 2));
1278 &locK_P_F(3 * col_bb + 0, 3 * row_bb + 0),
1279 &locK_P_F(3 * col_bb + 0, 3 * row_bb + 1),
1280 &locK_P_F(3 * col_bb + 0, 3 * row_bb + 2),
1281 &locK_P_F(3 * col_bb + 1, 3 * row_bb + 0),
1282 &locK_P_F(3 * col_bb + 1, 3 * row_bb + 1),
1283 &locK_P_F(3 * col_bb + 1, 3 * row_bb + 2),
1284 &locK_P_F(3 * col_bb + 2, 3 * row_bb + 0),
1285 &locK_P_F(3 * col_bb + 2, 3 * row_bb + 1),
1286 &locK_P_F(3 * col_bb + 2, 3 * row_bb + 2));
1287 t_off_side(
i,
k) = t_assemble(
k,
i);
1292 const int *row_ind = &*row_data.getIndices().begin();
1293 const int *col_ind = &*col_data.getIndices().begin();
1295 col_ind, &locK_P_F(0, 0), ADD_VALUES);
1297 if (row_type != col_type || row_side != col_side) {
1298 transLocK_P_F.resize(col_nb_dofs, row_nb_dofs,
false);
1299 noalias(transLocK_P_F) = trans(locK_P_F);
1301 row_ind, &transLocK_P_F(0, 0), ADD_VALUES);
1311 commonData(common_data) {
1317 EntityType col_type,
1323 const int row_nb_dofs = row_data.getIndices().size();
1326 const int col_nb_dofs = col_data.getIndices().size();
1331 locK_P_RHO.resize(row_nb_dofs, col_nb_dofs,
false);
1345 const int row_nb_gauss_pts = row_data.getN().size1();
1346 const int row_nb_base_functions = row_data.getN().size2();
1347 auto row_diff_base_functions = row_data.getFTensor1DiffN<3>();
1349 for (
int gg = 0; gg != row_nb_gauss_pts; gg++) {
1353 double a =
w * (
n /
rho) * pow(
rho / rho_ref,
n);
1356 for (; row_bb != row_nb_dofs / 3; row_bb++) {
1357 t1(
i) =
a * row_diff_base_functions(
I) *
P(
i,
I);
1358 auto base_functions = col_data.getFTensor0N(gg, 0);
1359 for (
int col_bb = 0; col_bb != col_nb_dofs; col_bb++) {
1366 k(
i) += t1(
i) * base_functions;
1369 ++row_diff_base_functions;
1371 for (; row_bb != row_nb_base_functions; row_bb++) {
1372 ++row_diff_base_functions;
1380 &*row_data.getIndices().begin(), col_nb_dofs,
1381 &*col_data.getIndices().begin(), &
locK_P_RHO(0, 0),
1389 : mField(m_field), commonData(common_data), postProc(m_field),
1390 postProcElastic(m_field),
1409 PetscBool analysis_mesh_flg = PETSC_FALSE;
1412 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Bone remodeling post-process",
1417 "is used for testing, calculates mass and energy at each time step",
"",
1420 CHKERR PetscOptionsBool(
"-analysis_mesh",
1421 "saves analysis mesh at each time step",
"",
1422 analysis_mesh_flg, &analysis_mesh_flg, PETSC_NULL);
1424 CHKERR PetscOptionsScalar(
1425 "-equilibrium_stop_rate",
1426 "is used to stop calculations when equilibium state is achieved",
"",
1428 ierr = PetscOptionsEnd();
1433 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
1434 "Bone remodeling post-process",
"none");
1437 CHKERR PetscOptionsInt(
"-my_output_prt",
1438 "frequncy how often results are dumped on hard disk",
1440 ierr = PetscOptionsEnd();
1455 list_of_operators.push_back(
1471 std::map<int, NonlinearElasticElement::BlockData>::iterator sit =
1485 int mass_vec_ghost[] = {0};
1487 1, 1, mass_vec_ghost, &mass_vec);
1489 CHKERR VecZeroEntries(mass_vec);
1490 CHKERR VecDuplicate(mass_vec, &energ_vec);
1508 CHKERR VecAssemblyBegin(mass_vec);
1509 CHKERR VecAssemblyEnd(mass_vec);
1511 CHKERR VecSum(mass_vec, &mass_sum);
1513 CHKERR VecAssemblyBegin(energ_vec);
1514 CHKERR VecAssemblyEnd(energ_vec);
1516 CHKERR VecSum(energ_vec, &energ_sum);
1518 CHKERR PetscPrintf(PETSC_COMM_WORLD,
1519 "Time: %g Mass: %6.5g Elastic energy: %6.5g \n", ts_t,
1520 mass_sum, energ_sum);
1521 CHKERR VecDestroy(&mass_vec);
1522 CHKERR VecDestroy(&energ_vec);
1525 double equilibrium_rate =
1527 double equilibrium_mass_rate =
1529 if (equilibrium_rate <
rate) {
1532 "Energy equilibrium state is achieved! Difference = %0.6g %%. \n",
1533 equilibrium_rate * 100);
1535 if (equilibrium_mass_rate <
rate) {
1538 "Mass equilibrium state is achieved! Difference = %0.6g %%. \n",
1539 equilibrium_mass_rate * 100);
1547 #if PETSC_VERSION_LE(3, 8, 0)
1548 CHKERR TSGetTimeStepNumber(ts, &step);
1550 CHKERR TSGetStepNumber(ts, &step);
1553 if ((step) %
pRT == 0) {
1556 sss <<
"out_" << step <<
".h5m";
1559 "PARALLEL=WRITE_PART");
1560 if (analysis_mesh_flg) {
1562 ttt <<
"analysis_mesh_" << step <<
".h5m";
1564 "PARALLEL=WRITE_PART");
1571 ss <<
"out_elastic_" << step <<
".h5m";
1573 "PARALLEL=WRITE_PART");
1582 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Bone remodeling",
"none");
1585 CHKERR PetscOptionsInt(
"-my_order",
"default approximation order",
"", 2,
1588 ierr = PetscOptionsEnd();
1593 string name = it->getName();
1594 if (name.compare(0, 14,
"NO_REMODELLING") == 0) {
1628 bool add_rho_field =
false;
1636 add_rho_field =
true;
1676 if (add_rho_field) {
1688 "MESH_NODE_POSITIONS");
1706 "MESH_NODE_POSITIONS");
1718 "MESH_NODE_POSITIONS");
1733 "DISPLACEMENTS",
"MESH_NODE_POSITIONS",
false,
true);
1751 list_of_operators_rhs.push_back(
1753 list_of_operators_rhs.push_back(
1768 list_of_operators_lhs.push_back(
1770 list_of_operators_rhs.push_back(
1776 list_of_operators_lhs.push_back(
1778 list_of_operators_lhs.push_back(
1782 list_of_operators_lhs.push_back(
1796 CHKERR MetaNeummanForces::addNeumannBCElements(
mField,
"DISPLACEMENTS");
1801 CHKERR MetaNeummanForces::setMomentumFluxOperators(
1805 PETSC_NULL,
"DISPLACEMENTS");
1810 for (boost::ptr_map<string, NeummanForcesSurface>::iterator mit =
1813 mit->second->methodsOp.push_back(
1816 for (boost::ptr_map<string, NodalForce>::iterator mit =
1819 mit->second->methodsOp.push_back(
1822 for (boost::ptr_map<string, EdgeForce>::iterator mit =
1825 mit->second->methodsOp.push_back(
1873 CHKERR TSSetIFunction(ts,
F, PETSC_NULL, PETSC_NULL);
1874 CHKERR TSSetIJacobian(ts,
A,
A, PETSC_NULL, PETSC_NULL);
1876 #if PETSC_VERSION_GE(3, 8, 0)
1877 CHKERR TSSetMaxTime(ts, ftime);
1879 CHKERR TSSetFromOptions(ts);
1883 CHKERR TSGetSNES(ts, &snes);
1885 CHKERR SNESGetKSP(snes, &ksp);
1887 CHKERR KSPGetPC(ksp, &pc);
1888 PetscBool is_pcfs = PETSC_FALSE;
1889 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1893 if (is_pcfs == PETSC_TRUE) {
1898 problem_ptr->
getName(),
ROW,
"DISPLACEMENTS", 0, 3, &is_disp);
1900 problem_ptr->
getName(),
ROW,
"RHO", 0, 1, &is_rho);
1903 CHKERR PCFieldSplitSetIS(pc, NULL, is_disp);
1904 CHKERR PCFieldSplitSetIS(pc, NULL, is_rho);
1905 CHKERR ISDestroy(&is_disp);
1906 CHKERR ISDestroy(&is_rho);
1918 #if PETSC_VERSION_GE(3, 7, 0)
1919 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER);
1922 CHKERR TSGetTime(ts, &ftime);
1923 PetscInt steps, snesfails, rejects, nonlinits, linits;
1924 #if PETSC_VERSION_LE(3, 8, 0)
1925 CHKERR TSGetTimeStepNumber(ts, &steps);
1927 CHKERR TSGetStepNumber(ts, &steps);
1930 CHKERR TSGetSNESFailures(ts, &snesfails);
1931 CHKERR TSGetStepRejections(ts, &rejects);
1932 CHKERR TSGetSNESIterations(ts, &nonlinits);
1933 CHKERR TSGetKSPIterations(ts, &linits);
1934 PetscPrintf(PETSC_COMM_WORLD,
1935 "steps %D (%D rejected, %D SNES fails), ftime %g, nonlinits %D, "
1937 steps, rejects, snesfails, ftime, nonlinits, linits);
1948 int row_side, EntityType row_type,
1952 if (row_type != MBVERTEX)
1955 const int nb_gauss_pts = row_data.getN().size1();
1962 for (
int gg = 0; gg < nb_gauss_pts; gg++) {
1965 energy += vol * psi;