524 {
525
527
528 try {
529
530 char mesh_file_name[255] = "mesh.h5m";
531 char mesh_out_file[255] = "out.h5m";
532 char master_prefix[255] = "TIE_MASTER_";
533 char slave_prefix[255] = "TIE_SLAVE_";
534 PetscBool flg_my_file = PETSC_FALSE;
535 PetscBool flg_ray_length = PETSC_FALSE;
536 PetscInt ref_level = 1;
537 PetscReal ray_length_option = 0;
538
539 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Insert constraint prisms", "none");
540 CHKERR PetscOptionsString(
"-my_file",
"mesh file name",
"",
"mesh.h5m",
541 mesh_file_name, 255, &flg_my_file);
542 if (flg_my_file != PETSC_TRUE)
543 CHKERR PetscOptionsString(
"-file_name",
"mesh file name",
"",
"mesh.h5m",
544 mesh_file_name, 255, &flg_my_file);
545 CHKERR PetscOptionsString(
"-output_file",
"output mesh file name",
"",
546 "out.h5m", mesh_out_file, 255, PETSC_NULLPTR);
547 CHKERR PetscOptionsString(
"-master_prefix",
"master meshset name prefix",
548 "", "TIE_MASTER_", master_prefix, 255,
549 PETSC_NULLPTR);
550 CHKERR PetscOptionsString(
"-slave_prefix",
"slave meshset name prefix",
"",
551 "TIE_SLAVE_", slave_prefix, 255, PETSC_NULLPTR);
552 CHKERR PetscOptionsInt(
"-tie_ref_level",
553 "virtual recursive refinement level on slave "
554 "triangles",
555 "", ref_level, &ref_level, PETSC_NULLPTR);
556 CHKERR PetscOptionsReal(
"-ray_length",
"absolute ray length",
"",
557 ray_length_option, &ray_length_option,
558 &flg_ray_length);
559 PetscOptionsEnd();
560
561 if (flg_my_file != PETSC_TRUE) {
563 "error -my_file (-file_name) (mesh file needed)");
564 }
565 if (ref_level < 1) {
567 "-tie_ref_level must be greater than or equal to 1");
568 }
569 if (flg_ray_length == PETSC_TRUE && ray_length_option <= 0) {
571 "-ray_length must be greater than 0");
572 }
573
574 moab::Core mb_instance;
575 moab::Interface &moab = mb_instance;
576 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
577 if (pcomm == NULL)
578 pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
579
580 CHKERR moab.load_file(mesh_file_name);
581
584
586 CHKERR moab.get_entities_by_type(0, MBTET, tets,
false);
587 if (tets.empty()) {
589 "No tetrahedra found. Only tet meshes are currently supported");
590 }
591
593 CHKERR moab.get_entities_by_dimension(0, 3, other_vols,
false);
594 other_vols = subtract(other_vols, tets);
595 if (!other_vols.empty()) {
597 "Only tetrahedral volume meshes are currently supported");
598 }
599
601 {
602 Skinner skinner(&moab);
603 CHKERR skinner.find_skin(0, tets,
false, tet_skin);
604 tet_skin = tet_skin.subset_by_type(MBTRI);
605 }
606
607 const std::string master_prefix_str(master_prefix);
608 const std::string slave_prefix_str(slave_prefix);
609
610 std::map<std::string, const CubitMeshSets *> master_sets;
611 std::map<std::string, const CubitMeshSets *> slave_sets;
612
614 const std::string name = it->getName();
615
616 if (name.compare(0, master_prefix_str.size(), master_prefix_str) == 0) {
617 const auto suffix = name.substr(master_prefix_str.size());
618 if (!master_sets.emplace(suffix, &*it).second) {
620 "More than one master meshset uses suffix %s", suffix.c_str());
621 }
622 }
623
624 if (name.compare(0, slave_prefix_str.size(), slave_prefix_str) == 0) {
625 const auto suffix = name.substr(slave_prefix_str.size());
626 if (!slave_sets.emplace(suffix, &*it).second) {
628 "More than one slave meshset uses suffix %s", suffix.c_str());
629 }
630 }
631 }
632
633 if (master_sets.empty()) {
635 "No master meshsets found with prefix %s",
636 master_prefix_str.c_str());
637 }
638
639 for (const auto &slave_pair : slave_sets) {
640 const auto &suffix = slave_pair.first;
641 if (master_sets.find(suffix) == master_sets.end()) {
643 "Found slave meshset with suffix %s but no matching master "
644 "meshset",
645 suffix.c_str());
646 }
647 }
648
651
653 CHKERR collect_virtual_refined_triangle_centroids(ref_level,
654 reference_child_centroids);
655
657
658 for (const auto &[suffix, master_ptr] : master_sets) {
659 auto slave_it = slave_sets.find(suffix);
660 if (slave_it == slave_sets.end()) {
662 "Found master meshset with suffix %s but no matching slave "
663 "meshset",
664 suffix.c_str());
665 }
666
667 const auto *slave_ptr = slave_it->second;
668
669 if (master_ptr->getBcType() != slave_ptr->getBcType()) {
671 "Master/slave meshset types differ for suffix %s",
672 suffix.c_str());
673 }
674
675 SurfaceMeshsetData master_surface;
676 CHKERR validate_surface_meshset(moab, *master_ptr, tet_skin,
677 master_surface);
678
679 SurfaceMeshsetData slave_surface;
680 CHKERR validate_surface_meshset(moab, *slave_ptr, tet_skin, slave_surface);
681
682 const auto master_tri_count = master_surface.tris.size();
683 const auto slave_tri_count = slave_surface.tris.size();
684 double bbox_diag = 0;
685 CHKERR get_range_bbox_diag(moab,
686 unite(master_surface.tris, slave_surface.tris),
687 bbox_diag);
688
689 const double geom_eps =
690 std::max(1e-12 * std::max(1., bbox_diag), 10. *
691 std::numeric_limits<double>::epsilon());
692 const double ray_tol = geom_eps;
693 const double ray_length =
694 (flg_ray_length == PETSC_TRUE) ? ray_length_option
695 :
std::max(10. * bbox_diag, 1.);
696
697 OrientedBoxTreeTool master_tree(&moab, "ROOTSET_CONSTRAINT_PRISMS", true);
698 EntityHandle master_root = 0;
699 CHKERR master_tree.build(master_surface.tris, master_root);
700
702 size_t unmatched_slave_tris = 0;
703
704 for (auto slave_tri : slave_surface.tris) {
705 std::array<double, SPACE_DIM> slave_normal;
706 CHKERR get_skin_triangle_data(moab, slave_tri,
nullptr, slave_normal);
707
708 std::array<double, 9> slave_coords;
709 CHKERR get_triangle_coords(moab, slave_tri, slave_coords);
711 CHKERR map_reference_centroids_to_triangle(reference_child_centroids,
712 slave_coords,
713 child_centroids);
714
715 std::set<EntityHandle> hit_master_tris;
716 for (size_t rr = 0; rr != child_centroids.size1(); ++rr) {
717 std::array<double, 3> child_centroid = {
718 child_centroids(rr, 0), child_centroids(rr, 1),
719 child_centroids(rr, 2)};
720 CHKERR collect_target_triangles(master_tree, master_root,
721 child_centroid, slave_normal,
722 ray_length, ray_tol,
723 hit_master_tris);
724 }
725
726 if (hit_master_tris.empty()) {
727 ++unmatched_slave_tris;
728 continue;
729 }
730
731 for (auto master_tri : hit_master_tris) {
732 EntityHandle prism = 0;
733 CHKERR create_prism_from_triangle_pair(*prisms_from_surface, slave_tri,
734 master_tri, prism);
735 pair_prisms.insert(prism);
736 }
737 }
738
741
742 CHKERR set_surface_meshset_triangles(moab, master_surface,
743 master_surface.tris);
744 CHKERR set_surface_meshset_triangles(moab, slave_surface,
745 slave_surface.tris);
746
747 all_prisms.merge(pair_prisms);
748
750 << "Inserted " << pair_prisms.size()
751 << " prisms for master/slave suffix " << suffix;
752 if (master_tri_count > slave_tri_count) {
754 << "Master surface has more triangles than slave surface for "
755 "suffix "
756 << suffix << " (" << master_tri_count << " > "
757 << slave_tri_count
758 << "); consider renaming the TIE blocks so the finer surface is "
759 "named TIE_SLAVE_"
760 << suffix;
761 }
763 << "Skipped " << unmatched_slave_tris
764 << " slave triangles without master hits for suffix "
765 << suffix;
766 }
767
769 << "Inserted total " << all_prisms.size() << " constraint prisms";
770
771 CHKERR moab.write_file(mesh_out_file);
772 }
774
776
777 return 0;
778}
#define CATCH_ERRORS
Catch errors.
#define MYPCOMM_INDEX
default communicator number PCOMM
@ MOFEM_DATA_INCONSISTENCY
#define CHKERR
Inline error check.
#define MOFEM_LOG(channel, severity)
Log.
#define _IT_CUBITMESHSETS_FOR_LOOP_(MESHSET_MANAGER, IT)
Iterator that loops over all the Cubit MeshSets in a moFEM field.
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
merge node from two bit levels
MoFEMErrorCode updateMeshestByEdgeBlock(const Range &prisms)
Add quads to bockset.
MoFEMErrorCode updateMeshestByTriBlock(const Range &prisms)
Add prism to bockset.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.