Solve crack propagation problem.
251 {
254
257 cP.
arcCtx = boost::make_shared<ArcLengthCtx>(
259 auto arc_snes_ctx = boost::make_shared<CrackPropagation::ArcLengthSnesCtx>(
262
263
266 << "Solve ELASTIC problem in solvePropagation";
269
273
274 struct StepAdaptivity {
275
276 CrackPropagation &cP;
277
278 int itsD;
279 double gAmma;
280 double minStep;
281 double maxStep;
282 PetscBool minStepFlg;
283 PetscBool maxStepFlg;
284
285 StepAdaptivity(CrackPropagation &cp, int its_d, double gamma)
286 : cP(cp), itsD(its_d), gAmma(gamma), minStep(0), maxStep(0) {
288 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
289 }
290
294 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Fracture options", "none");
296 {
297 CHKERR PetscOptionsInt(
"-adapt_step_its_d",
298 "number of desired iterations", "", itsD, &itsD,
299 PETSC_NULL);
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);
304 }
305 ierr = PetscOptionsEnd();
307
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);
314
315 if (minStepFlg == PETSC_TRUE && maxStepFlg == PETSC_TRUE)
316 if (minStep > maxStep) {
318 "Minimal step size cannot be bigger than maximal step size");
319 }
321 }
322
324 boost::shared_ptr<ArcLengthCtx> arc_ctx,
325 double &s) const {
327
328 auto min_max = [this](const double s) {
329 double new_s = s;
330 if (minStepFlg == PETSC_TRUE) {
331 new_s = std::max(new_s, minStep);
332 }
333 if (maxStepFlg == PETSC_TRUE) {
334 new_s = std::min(new_s, maxStep);
335 }
336 return new_s;
337 };
338
339 SNESConvergedReason reason;
340 CHKERR SNESGetConvergedReason(snes, &reason);
341 if (reason < 0) {
342 s = min_max(0.25 * s);
344 "*** Diverged ***"
345 "Setting reduced load step arc_s = %3.4g",
346 s);
348 SCATTER_REVERSE);
349
350 } else {
351 int its;
352 CHKERR SNESGetIterationNumber(snes, &its);
353 s = min_max(s * pow((double)itsD / (double)(its + 1), gAmma));
354 }
356 }
357 };
358
359 struct SmoothingAlphaAdaptivity {
360
361 CrackPropagation &cP;
362 double gAmma;
363 double dAlpha;
364 double minAlpha;
365 double maxAlpha;
366 double incrementAlpha;
367
368 SmoothingAlphaAdaptivity(CrackPropagation &cp, const double gamma,
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);
373 }
374
378 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Fracture options", "none");
380 CHKERR PetscOptionsScalar(
"-adapt_min_smoother_alpha",
381 "minimal smoother alpha", "", minAlpha,
382 &minAlpha, PETSC_NULL);
383 maxAlpha = 1e3;
384 CHKERR PetscOptionsScalar(
"-adapt_max_smoother_alpha",
385 "minimal smoother alpha", "", maxAlpha,
386 &maxAlpha, PETSC_NULL);
387 incrementAlpha = 10;
388 CHKERR PetscOptionsScalar(
"-adapt_incitement_smoother_alpha",
389 "minimal smoother alpha", "", incrementAlpha,
390 &incrementAlpha, PETSC_NULL);
391
392 CHKERR PetscOptionsScalar(
393 "-adapt_desired_alpha",
394 "Desired alpha (allowed error for gc calculation)", "", dAlpha,
395 &dAlpha, PETSC_NULL);
396
398 "### Input parameter: -adapt_min_smoother_alpha %6.4e",
399 minAlpha);
401 "### Input parameter: -adapt_max_smoother_alpha %6.4e",
402 maxAlpha);
404 "### Input parameter: -adapt_desired_alpha %6.4e", dAlpha);
405
406 ierr = PetscOptionsEnd();
407
409 }
410
413
414 if (cP.smootherFe->smootherData.sTabilised) {
415 SNESConvergedReason reason;
416 CHKERR SNESGetConvergedReason(snes, &reason);
417 if (reason < 0) {
418 const double old_alpha = cP.smootherAlpha;
419 cP.smootherAlpha =
420 std::min(incrementAlpha * cP.smootherAlpha, maxAlpha);
422 "Increase smoothing alpha = %6.5g (old %6.5e)",
423 cP.smootherAlpha, old_alpha);
424 } else {
427
428 CHKERR cP.calculateGriffithForce(dm, cP.gC ? cP.gC : 1, f_griffith,
430
432 CHKERR cP.calculateSmoothingForcesDM(dm, q, f_smoothing,
VERBOSE,
433 false);
435
436 double max_alpha = 0;
437 for (const auto &kv : cP.mapSmoothingForceFactor)
438 max_alpha = std::max(max_alpha, kv.second);
439
440 const double old_alpha = cP.smootherAlpha;
441 cP.smootherAlpha *= pow(dAlpha / max_alpha, gAmma);
442 cP.smootherAlpha = std::max(cP.smootherAlpha, minAlpha);
444 "Set smoothing alpha = %6.5g (old %6.5e)",
445 cP.smootherAlpha, old_alpha);
446 }
447
448 cP.volumeLengthAdouble->aLpha = cP.smootherAlpha;
449 cP.volumeLengthDouble->aLpha = cP.smootherAlpha;
450 for (auto &kv : cP.surfaceConstrain)
451 kv.second->aLpha = cP.smootherAlpha;
452
453 for (auto &kv : cP.edgeConstrains)
454 kv.second->aLpha = cP.smootherAlpha;
455
456 cP.bothSidesConstrains->aLpha = cP.smootherAlpha;
457 cP.bothSidesContactConstrains->aLpha = cP.smootherAlpha;
458 }
459
461 }
462 };
463
466
467 auto cp_arc_ctx = boost::make_shared<ArcLengthCtx>(
468 m_field, problem_cp_ptr->
getName(),
"LAMBDA_ARC_LENGTH");
469
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);
476
477 boost::shared_ptr<FEMethod> arc_method =
479
480
481
483 cp_arc_ctx, surface_ids, 1, false);
484
485 {
486
490
491
493 CHKERR SNESAppendOptionsPrefix(snes_crack_propagation,
"propagation_");
494
496
499
500 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"\n\nLoad step %d ( %d ) [ %d ]\n\n",
501 ll, run_step, step);
502
503
506 SCATTER_FORWARD);
507
508 CHKERR VecCopy(q, cp_arc_ctx->x0);
510
511 auto solve_problem = [&]() {
513
514 const double arc_s =
cP.
arcS;
515
518
520 snes_crack_propagation,
m, q, f);
523
524
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);
531 };
532
534
535 auto if_not_converged = [&](
Vec q) {
537 SNESConvergedReason reason;
538 CHKERR SNESGetConvergedReason(snes_crack_propagation, &reason);
539 if (reason < 0) {
540 CHKERR VecCopy(cp_arc_ctx->x0, q);
542 SCATTER_FORWARD);
543 }
545 };
546 CHKERR if_not_converged(q);
547
548 auto scatter_forward_vec = [](
Vec q) {
550 CHKERR VecGhostUpdateBegin(q, INSERT_VALUES, SCATTER_FORWARD);
551 CHKERR VecGhostUpdateEnd(q, INSERT_VALUES, SCATTER_FORWARD);
553 };
554 CHKERR scatter_forward_vec(q);
555
556
557 CHKERR VecAYPX(cp_arc_ctx->x0, -1, q);
559
560 CrackPropagation::PostProcVertexMethod ent_front_disp(
563 "MESH_NODE_POSITIONS",
ROW, ent_front_disp, 0,
565
566
568
569
570 SNESConvergedReason reason;
571 CHKERR SNESGetConvergedReason(snes_crack_propagation, &reason);
572 std::string step_msg;
573 if (reason < 0) {
574 step_msg = "Not Converged Propagation step " +
575 boost::lexical_cast<std::string>(step) + " ( " +
576 boost::lexical_cast<std::string>(ll) + " )";
577 } else {
578 step_msg = "Propagation step " +
579 boost::lexical_cast<std::string>(step) + " ( " +
580 boost::lexical_cast<std::string>(ll) + " )";
581 }
583
585 dm_crack_srf_area, surface_ids);
587
588
590 false || run_step == 0);
591
593
594
595 auto save_positions_on_mesh_tags_from_field =
596 [
this, problem_cp_ptr, &q](
const std::string
field_name) {
598 CrackPropagation::PostProcVertexMethod ent_post_proc(
cP.
mField, q,
601 ROW, ent_post_proc, 0,
604 };
605 CHKERR save_positions_on_mesh_tags_from_field(
"MESH_NODE_POSITIONS");
606 CHKERR save_positions_on_mesh_tags_from_field(
"SPATIAL_POSITION");
607
608
610
611 auto save_restart_file = [&]() {
613
615
619
620 Range ents_on_last_bits;
622 ents_on_last_bits);
624 ents_on_last_bits);
625
626 Range ents_spatial_domain;
627 CHKERR bit_interface->getEntitiesByRefLevel(
629 ents_spatial_domain);
630
631 Range entities_on_skin;
635
636 entities_on_skin = intersect(ents_spatial_domain, entities_on_skin);
638 entities_on_skin);
640 ents_spatial_domain);
641
643 entities_bit.merge(ents_on_last_bits);
644 entities_bit.merge(ents_spatial_domain);
645
646 auto add_field = [&](
auto field_name,
auto &tags_list) {
651
652 Tag th_field_id;
654 Tag th_field_base;
656 th_field_base);
657 Tag th_field_space;
659 th_field_space);
660 Tag th_field_name;
662 th_field_name);
663 Tag th_field_name_data_name_prefix;
665 "_FieldName_DataNamePrefix", th_field_name_data_name_prefix);
666
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);
677 };
678
679 auto add_fe = [&](auto fe_name, auto &tags_list) {
681 auto arc_length_finite_element =
684 *meshset_ptr, &arc_length_finite_element, 1);
685 Tag th_fe_id;
687 Tag th_fe_name;
689 Tag th_fe_id_col, th_fe_id_row, th_fe_id_data;
693 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);
700 };
701
702 auto arc_field_meshset =
704 auto arc_length_finite_element =
707 &arc_field_meshset, 1);
709 &arc_length_finite_element, 1);
710
711 auto get_tags_list = [&]() {
712 Tag th_griffith_force;
714 th_griffith_force);
715 Tag th_griffith_force_projected;
717 "GRIFFITH_FORCE_PROJECTED", th_griffith_force_projected);
718 Tag th_w;
720 Tag th_material_force;
722 th_material_force);
723 Tag th_interface_side;
725 th_interface_side);
726 Tag th_org_pos;
728 th_org_pos);
729 Tag th_version;
731 th_version);
732
733 std::vector<Tag> tags_list;
734 tags_list.push_back(bit_interface->get_th_RefBitLevel());
735
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);
743 return tags_list;
744 };
745
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;
757 tmp_tags_list);
760 true);
761 ents = intersect(ents,
bit);
763 for (
auto t : tmp_tags_list) {
764 void *tag_vals[1];
765 int tag_size[1];
767 t, &meshset, 1, (
const void **)tag_vals, tag_size);
769 tag_vals, tag_size);
770 }
771
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_");
777
778 for (
auto t : tmp_tags_list) {
779
780 std::string tag_name;
782 bool add = true;
783
784 for (
auto &
p : remove_tags) {
785 if (tag_name.compare(0,
p.size(),
p) == 0) {
786 add = false;
787 break;
788 }
789 }
790
791 if (add)
792 tags_list.push_back(
t);
793 }
794 }
795 return meshses_tmp_list;
796 };
797
798 auto tags_list = get_tags_list();
799 CHKERR add_field(
"LAMBDA_ARC_LENGTH", tags_list);
800 CHKERR add_fe(
"ARC_LENGTH", tags_list);
801
802 auto meshses_tmp_list = add_meshsets(entities_bit, tags_list);
803 for (auto &m_ptr : meshses_tmp_list) {
806 }
807
808 {
810 int negative = -1;
812 &negative);
813 Range verts_ents = entities_bit.subset_by_type(MBVERTEX);
814 int gid = 1;
815 for (
auto v : verts_ents) {
817 gid++;
818 }
819 }
820
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));
824
825 for (
auto t : tags_list) {
826 std::string tag_name;
829 << "Add tag to restart file: " << tag_name;
830 }
831
833 const std::string file_name =
834 "restart_" + boost::lexical_cast<std::string>(step) + ".h5m";
836 &save_meshset, 1, &tags_list[0],
837 tags_list.size());
838
840 };
841
843 CHKERR save_restart_file();
844 }
845 }
846
848}
#define BITREFLEVEL_SIZE
max number of refinements
@ MOFEM_DATA_INCONSISTENCY
virtual EntityHandle get_finite_element_meshset(const std::string name) const =0
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
constexpr double t
plate stiffness
constexpr auto field_name
MoFEMErrorCode zeroLambdaFields()
Zero fields with lagrange multipliers.
MoFEMErrorCode solvePropagationDM(DM dm, DM dm_elastic, SNES snes, Mat m, Vec q, Vec f)
solve crack propagation problem
MoFEMErrorCode postProcessDM(DM dm, const int step, const std::string fe_name, const bool approx_internal_stress)
post-process results for elastic solution
MoFEMErrorCode savePositionsOnCrackFrontDM(DM dm, Vec q, const int verb=QUIET, const bool debug=false)
boost::shared_ptr< FEMethod > getFrontArcLengthControl(boost::shared_ptr< ArcLengthCtx > arc_ctx)
double fractionOfFixedNodes
MoFEMErrorCode updateMaterialFixedNode(const bool fix_front, const bool fix_small_g, const bool debug=false)
Update fixed nodes.
MoFEMErrorCode setCoordsFromField(const std::string field_name="MESH_NODE_POSITIONS")
set coordinates from field
double initialSmootherAlpha
MoFEMErrorCode writeCrackFont(const BitRefLevel &bit, const int step)
MoFEMErrorCode addPropagationFEInstancesToSnes(DM dm, boost::shared_ptr< FEMethod > arc_method, boost::shared_ptr< ArcLengthCtx > arc_ctx, const std::vector< int > &surface_ids, const int verb=QUIET, const bool debug=false)
add finite element to SNES for crack propagation problem
virtual EntityHandle get_field_meshset(const std::string name) const =0
get field meshset
EntityHandle getMeshset() const
Get field meshset.
Interface for managing meshsets containing materials and boundary conditions.
CubitMeshSet_multiIndex & getMeshsetsMultindex()