28 using namespace MoFEM;
37 #include <VolumeLengthQuality.hpp>
43 #define SolveFunctionBegin \
50 CPSolvers::query_interface(boost::typeindex::type_index type_index,
58 if (!LogManager::checkIfChannelExist(
"CPSolverWorld")) {
59 auto core_log = logging::core::get();
62 LogManager::createSink(LogManager::getStrmWorld(),
"CPSolverWorld"));
64 LogManager::createSink(LogManager::getStrmSync(),
"CPSolverSync"));
66 LogManager::createSink(LogManager::getStrmSelf(),
"CPSolverSelf"));
68 LogManager::setLog(
"CPSolverWorld");
69 LogManager::setLog(
"CPSolverSync");
70 LogManager::setLog(
"CPSolverSelf");
77 MOFEM_LOG(
"CPSolverWorld", Sev::noisy) <<
"CPSolve created";
91 const double load_factor) {
104 auto solve_elastic_problem = [&](
auto init_x) {
110 boost::shared_ptr<ArcLengthCtx> arc_ctx;
111 if (problem_ptr->
getName() ==
"ELASTIC")
113 if (problem_ptr->
getName() ==
"EIGEN_ELASTIC")
117 boost::shared_ptr<SimpleArcLengthControl> arc_method(
122 PETSC_NULL, arc_method, arc_ctx,
125 CHKERR arc_ctx->setAlphaBeta(0, 1);
127 arc_ctx->getFieldData() = load_factor;
139 boost::shared_ptr<AnalyticalDisp> testing_function =
145 "MESH_NODE_POSITIONS");
162 CHKERR VecCopy(q_elastic, init_x);
168 CHKERR MatDestroy(&shell_m);
175 if (problem_ptr->
getName() ==
"EIGEN_ELASTIC")
177 if (problem_ptr->
getName() ==
"ELASTIC")
187 DM dm_surface_projection,
188 DM dm_crack_srf_area,
189 const std::vector<int> &surface_ids) {
194 Vec q_material, f_material;
195 CHKERR DMCreateGlobalVector(dm_material_forces, &q_material);
196 CHKERR VecDuplicate(q_material, &f_material);
197 Vec f_material_proj, f_griffith, f_griffith_proj;
198 CHKERR VecDuplicate(f_material, &f_material_proj);
199 CHKERR VecDuplicate(f_material, &f_griffith);
200 CHKERR VecDuplicate(f_griffith, &f_griffith_proj);
213 dm_surface_projection, dm_material_forces, surface_ids,
VERBOSE,
false);
215 dm_material_forces,
VERBOSE,
false);
220 f_griffith_proj,
VERBOSE,
false);
230 f_material_proj,
VERBOSE,
false);
236 CHKERR VecDestroy(&q_material);
237 CHKERR VecDestroy(&f_material);
238 CHKERR VecDestroy(&f_material_proj);
239 CHKERR VecDestroy(&f_griffith);
240 CHKERR VecDestroy(&f_griffith_proj);
241 CHKERR VecDestroy(&f_lambda);
248 DM dm_material, DM dm_material_forces,
249 DM dm_surface_projection, DM dm_crack_srf_area,
250 const std::vector<int> &surface_ids,
251 int cut_mesh_it,
const bool set_cut_surface) {
257 cP.
arcCtx = boost::make_shared<ArcLengthCtx>(
259 auto arc_snes_ctx = boost::make_shared<CrackPropagation::ArcLengthSnesCtx>(
266 <<
"Solve ELASTIC problem in solvePropagation";
274 struct StepAdaptivity {
282 PetscBool minStepFlg;
283 PetscBool maxStepFlg;
286 :
cP(cp), itsD(its_d), gAmma(gamma), minStep(0), maxStep(0) {
288 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
294 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Fracture options",
"none");
297 CHKERR PetscOptionsInt(
"-adapt_step_its_d",
298 "number of desired iterations",
"", itsD, &itsD,
300 CHKERR PetscOptionsScalar(
"-adapt_step_min_s",
"minimal setp",
"",
301 minStep, &minStep, &minStepFlg);
302 CHKERR PetscOptionsScalar(
"-adapt_step_max_s",
"maximal setp",
"",
303 maxStep, &maxStep, &maxStepFlg);
305 ierr = PetscOptionsEnd();
309 "### Input parameter: -adapt_step_its_d %d", itsD);
311 "### Input parameter: -adapt_step_min_s %6.4e", minStep);
313 "### Input parameter: -adapt_step_max_s %6.4e", maxStep);
315 if (minStepFlg == PETSC_TRUE && maxStepFlg == PETSC_TRUE)
316 if (minStep > maxStep) {
318 "Minimal step size cannot be bigger than maximal step size");
324 boost::shared_ptr<ArcLengthCtx> arc_ctx,
328 auto min_max = [
this](
const double s) {
330 if (minStepFlg == PETSC_TRUE) {
331 new_s = std::max(new_s, minStep);
333 if (maxStepFlg == PETSC_TRUE) {
334 new_s = std::min(new_s, maxStep);
339 SNESConvergedReason reason;
340 CHKERR SNESGetConvergedReason(snes, &reason);
342 s = min_max(0.25 * s);
345 "Setting reduced load step arc_s = %3.4g",
352 CHKERR SNESGetIterationNumber(snes, &its);
353 s = min_max(s * pow((
double)itsD / (
double)(its + 1), gAmma));
359 struct SmoothingAlphaAdaptivity {
366 double incrementAlpha;
369 const double d_alpha,
const double m_alpha)
370 :
cP(cp), gAmma(gamma), dAlpha(d_alpha), minAlpha(m_alpha) {
372 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
378 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Fracture options",
"none");
380 CHKERR PetscOptionsScalar(
"-adapt_min_smoother_alpha",
381 "minimal smoother alpha",
"", minAlpha,
382 &minAlpha, PETSC_NULL);
384 CHKERR PetscOptionsScalar(
"-adapt_max_smoother_alpha",
385 "minimal smoother alpha",
"", maxAlpha,
386 &maxAlpha, PETSC_NULL);
388 CHKERR PetscOptionsScalar(
"-adapt_incitement_smoother_alpha",
389 "minimal smoother alpha",
"", incrementAlpha,
390 &incrementAlpha, PETSC_NULL);
392 CHKERR PetscOptionsScalar(
393 "-adapt_desired_alpha",
394 "Desired alpha (allowed error for gc calculation)",
"", dAlpha,
395 &dAlpha, PETSC_NULL);
398 "### Input parameter: -adapt_min_smoother_alpha %6.4e",
401 "### Input parameter: -adapt_max_smoother_alpha %6.4e",
404 "### Input parameter: -adapt_desired_alpha %6.4e", dAlpha);
406 ierr = PetscOptionsEnd();
415 SNESConvergedReason reason;
416 CHKERR SNESGetConvergedReason(snes, &reason);
422 "Increase smoothing alpha = %6.5g (old %6.5e)",
436 double max_alpha = 0;
438 max_alpha = std::max(max_alpha, kv.second);
444 "Set smoothing alpha = %6.5g (old %6.5e)",
467 auto cp_arc_ctx = boost::make_shared<ArcLengthCtx>(
468 m_field, problem_cp_ptr->
getName(),
"LAMBDA_ARC_LENGTH");
471 problem_cp_ptr->
getName(),
COL, cp_arc_ctx->x0);
473 arc_snes_ctx = boost::make_shared<CrackPropagation::ArcLengthSnesCtx>(
474 m_field, problem_cp_ptr->
getName(), cp_arc_ctx);
477 boost::shared_ptr<FEMethod> arc_method =
483 cp_arc_ctx, surface_ids, 1,
false);
493 CHKERR SNESAppendOptionsPrefix(snes_crack_propagation,
"propagation_");
500 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"\n\nLoad step %d ( %d ) [ %d ]\n\n",
508 CHKERR VecCopy(q, cp_arc_ctx->x0);
511 auto solve_problem = [&]() {
514 const double arc_s =
cP.
arcS;
520 snes_crack_propagation,
m, q,
f);
526 dm_crack_propagation, snes_crack_propagation, cp_arc_ctx,
cP.
arcS);
527 CHKERR SmoothingAlphaAdaptivity(
cP, 0.25, 1e-2,
529 dm_crack_propagation, snes_crack_propagation, q);
535 auto if_not_converged = [&](
Vec q) {
537 SNESConvergedReason reason;
538 CHKERR SNESGetConvergedReason(snes_crack_propagation, &reason);
540 CHKERR VecCopy(cp_arc_ctx->x0, q);
546 CHKERR if_not_converged(q);
548 auto scatter_forward_vec = [](
Vec q) {
550 CHKERR VecGhostUpdateBegin(q, INSERT_VALUES, SCATTER_FORWARD);
551 CHKERR VecGhostUpdateEnd(q, INSERT_VALUES, SCATTER_FORWARD);
554 CHKERR scatter_forward_vec(q);
557 CHKERR VecAYPX(cp_arc_ctx->x0, -1, q);
563 "MESH_NODE_POSITIONS",
ROW, ent_front_disp, 0,
570 SNESConvergedReason reason;
571 CHKERR SNESGetConvergedReason(snes_crack_propagation, &reason);
572 std::string step_msg;
574 step_msg =
"Not Converged Propagation step " +
575 boost::lexical_cast<std::string>(step) +
" ( " +
576 boost::lexical_cast<std::string>(ll) +
" )";
578 step_msg =
"Propagation step " +
579 boost::lexical_cast<std::string>(step) +
" ( " +
580 boost::lexical_cast<std::string>(ll) +
" )";
585 dm_crack_srf_area, surface_ids);
590 false || run_step == 0);
595 auto save_positions_on_mesh_tags_from_field =
596 [
this, problem_cp_ptr, &q](
const std::string
field_name) {
601 ROW, ent_post_proc, 0,
605 CHKERR save_positions_on_mesh_tags_from_field(
"MESH_NODE_POSITIONS");
606 CHKERR save_positions_on_mesh_tags_from_field(
"SPATIAL_POSITION");
611 auto save_restart_file = [&]() {
620 Range ents_on_last_bits;
626 Range ents_spatial_domain;
627 CHKERR bit_interface->getEntitiesByRefLevel(
629 ents_spatial_domain);
631 Range entities_on_skin;
636 entities_on_skin = intersect(ents_spatial_domain, entities_on_skin);
640 ents_spatial_domain);
643 entities_bit.merge(ents_on_last_bits);
644 entities_bit.merge(ents_spatial_domain);
646 auto add_field = [&](
auto field_name,
auto &tags_list) {
663 Tag th_field_name_data_name_prefix;
665 "_FieldName_DataNamePrefix", th_field_name_data_name_prefix);
667 tags_list.push_back(th_field_id);
668 tags_list.push_back(th_field_base);
669 tags_list.push_back(th_field_space);
670 tags_list.push_back(th_field_name);
671 tags_list.push_back(th_field_name_data_name_prefix);
672 tags_list.push_back(field_ptr->th_FieldDataVerts);
673 tags_list.push_back(field_ptr->th_FieldData);
674 tags_list.push_back(field_ptr->th_AppOrder);
675 tags_list.push_back(field_ptr->th_FieldRank);
679 auto add_fe = [&](
auto fe_name,
auto &tags_list) {
681 auto arc_length_finite_element =
684 *meshset_ptr, &arc_length_finite_element, 1);
689 Tag th_fe_id_col, th_fe_id_row, th_fe_id_data;
694 tags_list.push_back(th_fe_id);
695 tags_list.push_back(th_fe_name);
696 tags_list.push_back(th_fe_id_col);
697 tags_list.push_back(th_fe_id_row);
698 tags_list.push_back(th_fe_id_data);
702 auto arc_field_meshset =
704 auto arc_length_finite_element =
707 &arc_field_meshset, 1);
709 &arc_length_finite_element, 1);
711 auto get_tags_list = [&]() {
712 Tag th_griffith_force;
715 Tag th_griffith_force_projected;
717 "GRIFFITH_FORCE_PROJECTED", th_griffith_force_projected);
720 Tag th_material_force;
723 Tag th_interface_side;
733 std::vector<Tag> tags_list;
734 tags_list.push_back(bit_interface->get_th_RefBitLevel());
736 tags_list.push_back(th_version);
737 tags_list.push_back(th_griffith_force);
738 tags_list.push_back(th_griffith_force_projected);
739 tags_list.push_back(th_w);
740 tags_list.push_back(th_material_force);
741 tags_list.push_back(th_interface_side);
742 tags_list.push_back(th_org_pos);
746 auto add_meshsets = [&](
Range bit,
auto &tags_list) {
748 std::vector<boost::shared_ptr<TempMeshset>> meshses_tmp_list;
750 for (
auto &
m : list) {
751 meshses_tmp_list.push_back(
754 auto meshset =
m.getMeshset();
755 std::vector<Tag> tmp_tags_list;
761 ents = intersect(ents,
bit);
763 for (
auto t : tmp_tags_list) {
767 t, &meshset, 1, (
const void **)tag_vals, tag_size);
772 std::vector<std::string> remove_tags;
773 remove_tags.push_back(
"CATEGORY");
774 remove_tags.push_back(
"OBB");
775 remove_tags.push_back(
"ROOTSETSURF");
776 remove_tags.push_back(
"__PARALLEL_");
778 for (
auto t : tmp_tags_list) {
780 std::string tag_name;
784 for (
auto &p : remove_tags) {
785 if (tag_name.compare(0, p.size(), p) == 0) {
792 tags_list.push_back(
t);
795 return meshses_tmp_list;
798 auto tags_list = get_tags_list();
799 CHKERR add_field(
"LAMBDA_ARC_LENGTH", tags_list);
800 CHKERR add_fe(
"ARC_LENGTH", tags_list);
802 auto meshses_tmp_list = add_meshsets(entities_bit, tags_list);
803 for (
auto &m_ptr : meshses_tmp_list) {
813 Range verts_ents = entities_bit.subset_by_type(MBVERTEX);
815 for (
auto v : verts_ents) {
821 std::sort(tags_list.begin(), tags_list.end());
822 auto new_end = std::unique(tags_list.begin(), tags_list.end());
823 tags_list.resize(std::distance(tags_list.begin(), new_end));
825 for (
auto t : tags_list) {
826 std::string tag_name;
829 <<
"Add tag to restart file: " << tag_name;
833 const std::string file_name =
834 "restart_" + boost::lexical_cast<std::string>(step) +
".h5m";
836 &save_meshset, 1, &tags_list[0],
843 CHKERR save_restart_file();
857 std::vector<int> &surface_ids,
861 auto calculate_load_factor = [
this]() {
867 cP.
getArcCtx()->getFieldData() = calculate_load_factor();
868 MOFEM_LOG_C(
"CPSolverWorld", Sev::inform,
"Calculated load factor %g",
870 MOFEM_LOG_C(
"CPSolverSync", Sev::noisy,
"Calculated load factor %g",
874 auto save_position_on_mesh_tags_from_coords =
875 [
this](
const std::string tag_name) {
879 if (
rval != MB_SUCCESS) {
880 double def[] = {0, 0, 0};
882 tag_name.c_str(), 3, MB_TYPE_DOUBLE,
th,
883 MB_TAG_CREAT | MB_TAG_SPARSE, def);
887 ->getEntitiesByTypeAndRefLevel(
cP.
mapBitLevel[
"spatial_domain"],
890 std::vector<double> coords(verts.size() * 3);
899 CHKERR save_position_on_mesh_tags_from_coords(
"MESH_NODE_POSITIONS");
901 dm_material_forces, dm_surface_projection,
902 dm_crack_srf_area, surface_ids, nb_cuts,
true);
905 auto reset_dms = [&]() {
906 dm_crack_propagation.reset();
908 dm_eigen_elastic.reset();
910 dm_material_forces.reset();
911 dm_surface_projection.reset();
912 dm_crack_srf_area.reset();
915 auto reset_fes = [&]() {
916 std::vector<std::pair<boost::weak_ptr<FEMethod>, std::string>> vec_fe;
918 std::pair<boost::weak_ptr<NonlinearElasticElement>, std::string>>
921 auto push_fes = [&]() {
922 v_elastic_ele_str.emplace_back(
924 v_elastic_ele_str.emplace_back(
926 vec_fe.emplace_back(std::make_pair(
cP.
feLhs,
"feLhs"));
927 vec_fe.emplace_back(std::make_pair(
cP.
feRhs,
"feRhs"));
928 vec_fe.emplace_back(std::make_pair(
cP.
feMaterialRhs,
"feMaterialRhs"));
929 vec_fe.emplace_back(std::make_pair(
cP.
feMaterialLhs,
"feMaterialLhs"));
930 vec_fe.emplace_back(std::make_pair(
cP.
feEnergy,
"feEnergy"));
935 vec_fe.emplace_back(std::make_pair(
cP.
feSmootherRhs,
"feSmootherRhs"));
936 vec_fe.emplace_back(std::make_pair(
cP.
feSmootherLhs,
"feSmootherLhs"));
940 "feGriffithConstrainsDelta"));
942 "feGriffithConstrainsRhs"));
944 "feGriffithConstrainsLhs"));
954 "feMaterialAnaliticalTraction"));
961 "bothSidesContactConstrains"));
970 vec_fe.emplace_back(std::make_pair(
cP.
zeroFlambda,
"zeroFlambda"));
1021 auto check = [&]() {
1022 for (
auto v : vec_fe)
1023 if (
auto a =
v.first.lock()) {
1025 <<
"fe " <<
v.second <<
" not destroyed " <<
a.use_count();
1028 for (
auto v : v_elastic_ele_str)
1029 if (
auto a =
v.first.lock()) {
1031 <<
"fe elastic " <<
v.second <<
" not destroyed "
1037 <<
"dm_crack_propagation not destroyed "
1041 <<
"dm_elastic not destroyed" << dm_elastic.
use_count();
1044 <<
"dm_material_forces not destroyed "
1048 <<
"dm_surface_projection not destroyed "
1052 <<
"dm_crack_srf_area not destroyed "
1057 <<
"tangentConstrains not destroyed";
1060 <<
"skinOrientation not destroyed";
1063 <<
"crackOrientation not destroyed";
1066 <<
"contactOrientation not destroyed";
1068 if (
m.second.use_count())
1070 <<
"surfaceConstrain not destroyed : " <<
m.first;
1072 if (
m.second.use_count())
1074 <<
"edgeConstrains not destroyed : " <<
m.first;
1080 <<
"projSurfaceCtx not destroyed";
1083 <<
"projFrontCtx not destroyed";
1096 <<
"Resest MWLS approximation coefficients. Coefficients will be "
1097 "recalulated for current material positions.";
1111 std::vector<Tag> tag_handles;
1113 for (
auto th : tag_handles)
1119 CHKERR PetscBarrier(PETSC_NULL);
1120 const std::string file_name =
1121 "restart_" + boost::lexical_cast<std::string>(
cP.
startStep - 1) +
1124 auto add_bits_tets = [&]() {
1127 ->addToDatabaseBitRefLevelByType(MBTET,
BitRefLevel().set(),
1132 std::vector<int> surface_ids;
1134 std::vector<std::string> fe_surf_proj_list;
1135 fe_surf_proj_list.push_back(
"SURFACE");
1137 ParallelComm *pcomm =
1145 const char *option =
"";
1152 ParallelComm *pcomm_read =
1154 if (pcomm_read == NULL)
1158 const char *option =
"";
1159 CHKERR moab_read.load_file(file_name.c_str(), 0, option);
1161 CHKERR moab_read.get_entities_by_handle(0, ents,
false);
1162 CHKERR moab_read.get_entities_by_type(0, MBENTITYSET, ents,
false);
1181 ->getAllEntitiesNotInDatabase(ents);
1185 for (
auto m : meshsets)
1189 string cutting_surface_name =
1190 "cutting_surface_" + boost::lexical_cast<std::string>(
cP.
startStep) +
1217 dm_crack_propagation, dm_material_forces,
1218 dm_surface_projection, dm_crack_srf_area, surface_ids,
1221 auto set_up_arc_length = [&]() {
1229 boost::make_shared<CrackPropagation::ArcLengthSnesCtx>(
1235 CHKERR set_up_arc_length();
1241 const auto load_factor = std::abs(
cP.
getArcCtx()->getFieldData());
1242 MOFEM_LOG(
"CPSolverSync", Sev::noisy) <<
"Lambda factor " << load_factor;
1245 MOFEM_LOG(
"CPSolverWorld", Sev::verbose)
1246 <<
"Solve Eigen ELASTIC problem";
1254 <<
"Solve ELASTIC problem and calculate g";
1267 dm_material_forces, dm_surface_projection, dm_crack_srf_area,
1269 cP.
getArcCtx()->getFieldData() = calculate_load_factor();
1270 MOFEM_LOG_C(
"CPSolverWorld", Sev::inform,
"Calculated load factor %g",