23int main(
int argc,
char *argv[]) {
25 const string default_options =
"-ksp_type fgmres \n"
27 "-pc_factor_mat_solver_type mumps \n"
28 "-mat_mumps_icntl_20 0 \n"
32 "-snes_type newtonls \n"
33 "-snes_linesearch_type basic \n"
40 string param_file =
"param_file.petsc";
41 if (!
static_cast<bool>(ifstream(param_file))) {
42 std::ofstream file(param_file.c_str(), std::ios::ate);
44 file << default_options;
54 moab::Core mb_instance;
55 moab::Interface &moab = mb_instance;
57 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
59 boost::make_shared<WrapMPIComm>(PETSC_COMM_WORLD,
false);
61 pcomm =
new ParallelComm(&moab, moab_comm_wrap->get_comm());
63 PetscBool flg = PETSC_TRUE;
64 char mesh_file_name[255];
66 mesh_file_name, 255, &flg);
67 if (flg != PETSC_TRUE) {
68 SETERRQ(PETSC_COMM_SELF, 1,
"*** ERROR -my_file (MESH FILE NEEDED)");
74 if (flg != PETSC_TRUE) {
80 PetscBool is_partitioned = PETSC_FALSE;
82 &is_partitioned, &flg);
84 if (is_partitioned == PETSC_TRUE) {
87 option =
"PARALLEL=BCAST_DELETE;PARALLEL_RESOLVE_SHARED_ENTS;PARTITION="
88 "PARALLEL_PARTITION;";
89 CHKERR moab.load_file(mesh_file_name, 0, option);
93 CHKERR moab.load_file(mesh_file_name, 0, option);
97 Tag th_step_size, th_step;
98 double def_step_size = 1;
99 CHKERR moab.tag_get_handle(
"_STEPSIZE", 1, MB_TYPE_DOUBLE, th_step_size,
100 MB_TAG_CREAT | MB_TAG_MESH, &def_step_size);
101 if (
rval == MB_ALREADY_ALLOCATED)
105 CHKERR moab.tag_get_handle(
"_STEP", 1, MB_TYPE_INTEGER, th_step,
106 MB_TAG_CREAT | MB_TAG_MESH, &def_step);
107 if (
rval == MB_ALREADY_ALLOCATED)
110 const void *tag_data_step_size[1];
111 EntityHandle root = moab.get_root_set();
112 CHKERR moab.tag_get_by_ptr(th_step_size, &root, 1, tag_data_step_size);
113 double &step_size = *(
double *)tag_data_step_size[0];
114 const void *tag_data_step[1];
115 CHKERR moab.tag_get_by_ptr(th_step, &root, 1, tag_data_step);
116 int &step = *(
int *)tag_data_step[0];
118 CHKERR PetscPrintf(PETSC_COMM_WORLD,
119 "Start step %D and step_size = %6.4e\n", step,
128 std::vector<BitRefLevel> bit_levels;
134 problem_bit_level = bit_levels.back();
155 "MESH_NODE_POSITIONS");
164 "ELASTIC",
"LAMBDA");
168 "ELASTIC",
"MESH_NODE_POSITIONS");
204 EntityHandle no_field_vertex;
206 const double coords[] = {0, 0, 0};
208 Range range_no_field_vertex;
209 range_no_field_vertex.insert(no_field_vertex);
214 range_no_field_vertex);
217 EntityHandle meshset_fe_arc_length;
219 CHKERR moab.create_meshset(MESHSET_SET, meshset_fe_arc_length);
220 CHKERR moab.add_entities(meshset_fe_arc_length, &no_field_vertex, 1);
226 meshset_fe_arc_length,
"ARC_LENGTH",
false);
254 "NEUMANN_FE",
"MESH_NODE_POSITIONS");
260 CHKERR moab.get_entities_by_type(it->meshset, MBTRI, tris,
true);
267 CHKERR moab.get_entities_by_type(it->meshset, MBTRI, tris,
true);
279 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ptr(
281 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_rhs_ptr(
285 m_field, fe_spring_lhs_ptr, fe_spring_rhs_ptr,
"SPATIAL_POSITION",
286 "MESH_NODE_POSITIONS");
297 "MESH_NODE_POSITIONS");
299 "MESH_NODE_POSITIONS");
302 "MESH_NODE_POSITIONS");
309 "MESH_NODE_POSITIONS");
310 auto spatial_pos_ptr = boost::make_shared<MatrixDouble>();
311 auto mesh_pos_ptr = boost::make_shared<MatrixDouble>();
312 auto spatial_pos_grad_ptr = boost::make_shared<MatrixDouble>();
313 post_proc.getOpPtrVector().push_back(
316 post_proc.getOpPtrVector().push_back(
319 post_proc.getOpPtrVector().push_back(
321 spatial_pos_grad_ptr));
322 std::map<int, NonlinearElasticElement::BlockData>::iterator sit =
326 post_proc.getPostProcMesh(), post_proc.getMapGaussPts(),
327 post_proc.getPostProcElements(),
"SPATIAL_POSITION", sit->second,
328 spatial_pos_ptr, mesh_pos_ptr, spatial_pos_grad_ptr));
331 post_proc.getOpPtrVector().push_back(
new OpPPMap(
332 post_proc.getPostProcMesh(), post_proc.getMapGaussPts(), {},
333 {{
"SPATIAL_POSITION", spatial_pos_ptr},
334 {
"MESH_NODE_POSITIONS", mesh_pos_ptr}},
335 {{
"SPATIAL_POSITION_GRAD", spatial_pos_grad_ptr}}, {}));
338 CHKERR m_field.build_fields();
342 "MESH_NODE_POSITIONS");
343 CHKERR m_field.loop_dofs(
"MESH_NODE_POSITIONS", ent_method_material, 0);
349 1.,
"MESH_NODE_POSITIONS",
"SPATIAL_POSITION");
357 CHKERR m_field.build_finite_elements();
360 CHKERR m_field.build_adjacencies(problem_bit_level);
365 if (is_partitioned) {
366 SETERRQ(PETSC_COMM_SELF, 1,
367 "Not implemented, problem with arc-length force multiplayer");
386 "ELASTIC_MECHANICS",
COL, &
F);
391 ->createMPIAIJWithArrays<PetscGlobalIdx_mi_tag>(
"ELASTIC_MECHANICS",
394 boost::shared_ptr<ArcLengthCtx> arc_ctx = boost::shared_ptr<ArcLengthCtx>(
400 CHKERR MatGetLocalSize(Aij, &
m, &
n);
401 boost::scoped_ptr<ArcLengthMatShell> mat_ctx(
405 CHKERR MatCreateShell(PETSC_COMM_WORLD,
m,
n,
M,
N, mat_ctx.get(),
407 CHKERR MatShellSetOperation(ShellAij, MATOP_MULT,
410 ArcLengthSnesCtx snes_ctx(m_field,
"ELASTIC_MECHANICS", arc_ctx);
414 EntityHandle meshset = cit->getMeshset();
416 CHKERR moab.get_entities_by_type(meshset, MBVERTEX, nodes,
true);
418 node_set.merge(nodes);
420 PetscPrintf(PETSC_COMM_WORLD,
"Nb. nodes in load path: %u\n",
425 double scaled_reference_load = 1;
426 double *scale_lhs = &(arc_ctx->getFieldData());
427 double *scale_rhs = &(scaled_reference_load);
429 m_field, Aij, arc_ctx->F_lambda, scale_lhs, scale_rhs);
436 fe_neumann.
uSeF =
true;
446 boost::shared_ptr<FEMethod> my_dirichlet_bc =
448 m_field,
"SPATIAL_POSITION", Aij,
D,
F));
449 CHKERR m_field.get_problem(
"ELASTIC_MECHANICS",
450 &(my_dirichlet_bc->problemPtr));
454 struct AssembleRhsVectors :
public FEMethod {
456 boost::shared_ptr<ArcLengthCtx> arcPtr;
459 AssembleRhsVectors(boost::shared_ptr<ArcLengthCtx> &arc_ptr,
461 : arcPtr(arc_ptr), nodeSet(node_set) {}
469 CHKERR VecZeroEntries(snes_f);
470 CHKERR VecGhostUpdateBegin(snes_f, INSERT_VALUES, SCATTER_FORWARD);
471 CHKERR VecGhostUpdateEnd(snes_f, INSERT_VALUES, SCATTER_FORWARD);
472 CHKERR VecZeroEntries(arcPtr->F_lambda);
473 CHKERR VecGhostUpdateBegin(arcPtr->F_lambda, INSERT_VALUES,
475 CHKERR VecGhostUpdateEnd(arcPtr->F_lambda, INSERT_VALUES,
479 SETERRQ(PETSC_COMM_SELF, 1,
"not implemented");
490 CHKERR VecGhostUpdateBegin(snes_f, ADD_VALUES, SCATTER_REVERSE);
491 CHKERR VecGhostUpdateEnd(snes_f, ADD_VALUES, SCATTER_REVERSE);
492 CHKERR VecAssemblyBegin(snes_f);
493 CHKERR VecAssemblyEnd(snes_f);
496 SETERRQ(PETSC_COMM_SELF, 1,
"not implemented");
503 boost::shared_ptr<NumeredDofEntity_multiIndex> numered_dofs_rows =
504 problemPtr->getNumeredRowDofsPtr();
505 Range::iterator nit = nodeSet.begin();
506 for (; nit != nodeSet.end(); nit++) {
507 NumeredDofEntityByEnt::iterator dit, hi_dit;
508 dit = numered_dofs_rows->get<
Ent_mi_tag>().lower_bound(*nit);
509 hi_dit = numered_dofs_rows->get<
Ent_mi_tag>().upper_bound(*nit);
510 for (; dit != hi_dit; dit++) {
511 PetscPrintf(PETSC_COMM_WORLD,
"%s [ %d ] %6.4e -> ",
"LAMBDA", 0,
512 arcPtr->getFieldData());
513 PetscPrintf(PETSC_COMM_WORLD,
"%s [ %d ] %6.4e\n",
514 dit->get()->getName().c_str(),
515 dit->get()->getDofCoeffIdx(),
516 dit->get()->getFieldData());
523 struct AddLambdaVectorToFInternal :
public FEMethod {
525 boost::shared_ptr<ArcLengthCtx> arcPtr;
526 boost::shared_ptr<DirichletSpatialPositionsBc> bC;
528 AddLambdaVectorToFInternal(boost::shared_ptr<ArcLengthCtx> &arc_ptr,
529 boost::shared_ptr<FEMethod> &bc)
531 bC(boost::shared_ptr<DirichletSpatialPositionsBc>(
547 CHKERR VecGhostUpdateBegin(arcPtr->F_lambda, ADD_VALUES,
549 CHKERR VecGhostUpdateEnd(arcPtr->F_lambda, ADD_VALUES,
551 CHKERR VecAssemblyBegin(arcPtr->F_lambda);
552 CHKERR VecAssemblyEnd(arcPtr->F_lambda);
553 for (std::vector<int>::iterator vit = bC->dofsIndices.begin();
554 vit != bC->dofsIndices.end(); vit++) {
555 CHKERR VecSetValue(arcPtr->F_lambda, *vit, 0, INSERT_VALUES);
557 CHKERR VecAssemblyBegin(arcPtr->F_lambda);
558 CHKERR VecAssemblyEnd(arcPtr->F_lambda);
559 CHKERR VecDot(arcPtr->F_lambda, arcPtr->F_lambda, &arcPtr->F_lambda2);
560 PetscPrintf(PETSC_COMM_WORLD,
"\tFlambda2 = %6.4e\n",
563 CHKERR VecAssemblyBegin(snes_f);
564 CHKERR VecAssemblyEnd(snes_f);
565 CHKERR VecAXPY(snes_f, arcPtr->getFieldData(), arcPtr->F_lambda);
566 PetscPrintf(PETSC_COMM_WORLD,
"\tlambda = %6.4e\n",
567 arcPtr->getFieldData());
569 CHKERR VecNorm(snes_f, NORM_2, &fnorm);
570 PetscPrintf(PETSC_COMM_WORLD,
"\tfnorm = %6.4e\n", fnorm);
573 SETERRQ(PETSC_COMM_SELF, 1,
"not implemented");
579 AssembleRhsVectors pre_post_method(arc_ctx, node_set);
580 AddLambdaVectorToFInternal assemble_F_lambda(arc_ctx, my_dirichlet_bc);
583 CHKERR SNESCreate(PETSC_COMM_WORLD, &snes);
584 CHKERR SNESSetApplicationContext(snes, &snes_ctx);
586 CHKERR SNESSetJacobian(snes, ShellAij, Aij,
SnesMat, &snes_ctx);
587 CHKERR SNESSetFromOptions(snes);
594 if (flg == PETSC_TRUE) {
595 PetscReal atol, rtol, stol;
596 PetscInt maxit, maxf;
597 CHKERR SNESGetTolerances(snes, &atol, &rtol, &stol, &maxit, &maxf);
600 CHKERR SNESSetTolerances(snes, atol, rtol, stol, maxit, maxf);
604 CHKERR SNESGetKSP(snes, &ksp);
606 CHKERR KSPGetPC(ksp, &pc);
607 boost::scoped_ptr<PCArcLengthCtx> pc_ctx(
609 CHKERR PCSetType(pc, PCSHELL);
610 CHKERR PCShellSetContext(pc, pc_ctx.get());
614 if (flg == PETSC_TRUE) {
615 PetscReal rtol, atol, dtol;
617 CHKERR KSPGetTolerances(ksp, &rtol, &atol, &dtol, &maxits);
618 atol = my_tol * 1e-2;
620 CHKERR KSPSetTolerances(ksp, rtol, atol, dtol, maxits);
624 snes_ctx.getComputeRhs();
625 snes_ctx.getPreProcComputeRhs().push_back(my_dirichlet_bc);
626 snes_ctx.getPreProcComputeRhs().push_back(&pre_post_method);
627 loops_to_do_Rhs.push_back(
630 loops_to_do_Rhs.push_back(
634 loops_to_do_Rhs.push_back(
638 boost::ptr_map<std::string, EdgeForce> edge_forces;
639 string fe_name_str =
"FORCE_FE";
640 edge_forces.insert(fe_name_str,
new EdgeForce(m_field));
643 CHKERR edge_forces.at(fe_name_str)
644 .addForce(
"SPATIAL_POSITION", arc_ctx->F_lambda, it->getMeshsetId());
646 for (boost::ptr_map<std::string, EdgeForce>::iterator eit =
648 eit != edge_forces.end(); eit++) {
649 loops_to_do_Rhs.push_back(
654 boost::ptr_map<std::string, NodalForce> nodal_forces;
656 nodal_forces.insert(fe_name_str,
new NodalForce(m_field));
659 CHKERR nodal_forces.at(fe_name_str)
660 .addForce(
"SPATIAL_POSITION", arc_ctx->F_lambda, it->getMeshsetId());
662 for (boost::ptr_map<std::string, NodalForce>::iterator fit =
663 nodal_forces.begin();
664 fit != nodal_forces.end(); fit++) {
665 loops_to_do_Rhs.push_back(
670 loops_to_do_Rhs.push_back(
672 loops_to_do_Rhs.push_back(
674 snes_ctx.getPostProcComputeRhs().push_back(&pre_post_method);
675 snes_ctx.getPostProcComputeRhs().push_back(my_dirichlet_bc);
678 snes_ctx.getSetOperators();
679 snes_ctx.getPreProcSetOperators().push_back(my_dirichlet_bc);
680 loops_to_do_Mat.push_back(
683 loops_to_do_Mat.push_back(
686 loops_to_do_Mat.push_back(
688 loops_to_do_Mat.push_back(
690 snes_ctx.getPostProcSetOperators().push_back(my_dirichlet_bc);
693 "ELASTIC_MECHANICS",
COL,
D, INSERT_VALUES, SCATTER_FORWARD);
694 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
695 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
697 PetscScalar step_size_reduction;
699 &step_size_reduction, &flg);
700 if (flg != PETSC_TRUE) {
701 step_size_reduction = 1.;
707 if (flg != PETSC_TRUE) {
714 if (flg != PETSC_TRUE) {
717 PetscScalar max_reduction = 10, min_reduction = 0.1;
719 &max_reduction, &flg);
721 &min_reduction, &flg);
723 double gamma = 0.5, reduction = 1;
726 step_size = step_size_reduction;
728 reduction = step_size_reduction;
731 double step_size0 = step_size;
735 "ELASTIC_MECHANICS",
"SPATIAL_POSITION",
"X0_SPATIAL_POSITION",
COL,
736 arc_ctx->x0, INSERT_VALUES, SCATTER_FORWARD);
738 CHKERR VecNorm(arc_ctx->x0, NORM_2, &x0_nrm);
739 CHKERR PetscPrintf(PETSC_COMM_WORLD,
740 "\tRead x0_nrm = %6.4e dlambda = %6.4e\n", x0_nrm,
742 CHKERR arc_ctx->setAlphaBeta(1, 0);
744 CHKERR arc_ctx->setS(step_size);
745 CHKERR arc_ctx->setAlphaBeta(0, 1);
752 CHKERR VecDuplicate(arc_ctx->x0, &x00);
753 bool converged_state =
false;
755 for (
int jj = 0; step < max_steps; step++, jj++) {
758 CHKERR VecCopy(arc_ctx->x0, x00);
762 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"Load Step %D step_size = %6.4e\n",
764 CHKERR arc_ctx->setS(step_size);
765 CHKERR arc_ctx->setAlphaBeta(0, 1);
766 CHKERR VecCopy(
D, arc_ctx->x0);
771 }
else if (step == 2) {
773 CHKERR arc_ctx->setAlphaBeta(1, 0);
776 step_size0 = step_size;
777 CHKERR arc_ctx->setS(step_size);
778 double dlambda = arc_ctx->dLambda;
780 CHKERR VecNorm(arc_ctx->dx, NORM_2, &dx_nrm);
781 CHKERR PetscPrintf(PETSC_COMM_WORLD,
782 "Load Step %D step_size = %6.4e dlambda0 = %6.4e "
783 "dx_nrm = %6.4e dx2 = %6.4e\n",
784 step, step_size, dlambda, dx_nrm, arc_ctx->dx2);
785 CHKERR VecCopy(
D, arc_ctx->x0);
786 CHKERR VecAXPY(
D, 1., arc_ctx->dx);
792 step_size0 = step_size;
796 step_size *= reduction;
797 if (step_size > max_reduction * step_size0) {
798 step_size = max_reduction * step_size0;
799 }
else if (step_size < min_reduction * step_size0) {
800 step_size = min_reduction * step_size0;
802 CHKERR arc_ctx->setS(step_size);
803 double dlambda = reduction * arc_ctx->dLambda;
805 CHKERR VecScale(arc_ctx->dx, reduction);
806 CHKERR VecNorm(arc_ctx->dx, NORM_2, &dx_nrm);
807 CHKERR PetscPrintf(PETSC_COMM_WORLD,
808 "Load Step %D step_size = %6.4e dlambda0 = %6.4e "
809 "dx_nrm = %6.4e dx2 = %6.4e\n",
810 step, step_size, dlambda, dx_nrm, arc_ctx->dx2);
811 CHKERR VecCopy(
D, arc_ctx->x0);
812 CHKERR VecAXPY(
D, 1., arc_ctx->dx);
816 CHKERR SNESSolve(snes, PETSC_NULLPTR,
D);
818 CHKERR SNESGetIterationNumber(snes, &its);
819 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"number of Newton iterations = %D\n",
822 SNESConvergedReason reason;
823 CHKERR SNESGetConvergedReason(snes, &reason);
827 CHKERR VecCopy(x00, arc_ctx->x0);
830 CHKERR VecNorm(arc_ctx->x0, NORM_2, &x0_nrm);
831 CHKERR PetscPrintf(PETSC_COMM_WORLD,
832 "\tRead x0_nrm = %6.4e dlambda = %6.4e\n", x0_nrm,
834 CHKERR arc_ctx->setAlphaBeta(1, 0);
837 converged_state =
false;
843 if (step > 1 && converged_state) {
845 reduction = pow((
double)its_d / (
double)(its + 1), gamma);
846 if (step_size >= max_reduction * step_size0 && reduction > 1) {
848 }
else if (step_size <= min_reduction * step_size0 && reduction < 1) {
851 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"reduction step_size = %6.4e\n",
857 "ELASTIC_MECHANICS",
COL,
D, INSERT_VALUES, SCATTER_REVERSE);
859 "ELASTIC_MECHANICS",
"SPATIAL_POSITION",
"X0_SPATIAL_POSITION",
COL,
860 arc_ctx->x0, INSERT_VALUES, SCATTER_REVERSE);
861 converged_state =
true;
875 CHKERR m_field.loop_finite_elements(
"ELASTIC_MECHANICS",
"ELASTIC",
877 std::ostringstream o1;
878 o1 <<
"out_" << step <<
".h5m";
879 CHKERR post_proc.writeFile(o1.str().c_str());
882 CHKERR pre_post_method.potsProcessLoadPath();
892 CHKERR MatDestroy(&ShellAij);
893 CHKERR SNESDestroy(&snes);