int main(int argc, char *argv[]) { int my_rank = 0; #ifdef HAVE_MPI MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); #endif Skinner::Interface interface; interface.parse_options(argc, argv); std::string in_type = "exodusII"; codename = argv[0]; size_t ind = codename.find_last_of("/", codename.size()); if (ind != std::string::npos) codename = codename.substr(ind+1, codename.size()); Ioss::Init::Initializer io; if (my_rank == 0) { OUTPUT << "Input: '" << interface.input_filename() << "', Type: " << interface.input_type() << '\n'; if (!interface.no_output()) { OUTPUT << "Output: '" << interface.output_filename() << "', Type: " << interface.output_type() << '\n'; } } if (interface.ints_64_bit()) { skinner(interface, (int64_t)0); } else { skinner(interface, (int)0); } if (my_rank == 0) { OUTPUT << "\n" << codename << " execution successful.\n"; } #ifdef HAVE_MPI MPI_Finalize(); #endif return EXIT_SUCCESS; }
moab::ErrorCode MergeMesh::merge_entities(moab::Range &elems, const double merge_tol, const int do_merge, const int , moab::Tag merge_tag, bool merge_higher_dim) { //If merge_higher_dim is true, do_merge must also be true if(merge_higher_dim && !do_merge){ return moab::MB_FAILURE; } mergeTol = merge_tol; mergeTolSq = merge_tol*merge_tol; // get the skin of the entities moab::Skinner skinner(mbImpl); moab::Range skin_range; moab::ErrorCode result = skinner.find_skin(0, elems, 0, skin_range, false, false); if (moab::MB_SUCCESS != result) return result; // create a tag to mark merged-to entity; reuse tree_root moab::EntityHandle tree_root = 0; if (0 == merge_tag) { result = mbImpl->tag_get_handle("__merge_tag", 1, moab::MB_TYPE_HANDLE, mbMergeTag, moab::MB_TAG_DENSE|moab::MB_TAG_EXCL, &tree_root); if (moab::MB_SUCCESS != result) return result; } else mbMergeTag = merge_tag; // build a kd tree with the vertices moab::AdaptiveKDTree kd(mbImpl); result = kd.build_tree(skin_range, &tree_root); if (moab::MB_SUCCESS != result) return result; // find matching vertices, mark them result = find_merged_to(tree_root, kd, mbMergeTag); if (moab::MB_SUCCESS != result) return result; // merge them if requested if (do_merge) { result = perform_merge(mbMergeTag); if (moab::MB_SUCCESS != result) return result; } if(merge_higher_dim && deadEnts.size() != 0){ result = merge_higher_dimensions(elems); if(moab::MB_SUCCESS != result) return result; } return moab::MB_SUCCESS; }
//This function doesn't normally get called, but is here for debugging //and verifying that merge is working. void print_output(moab::ParallelComm *pc, moab::Core *mb, int myID, int /* numprocs */, bool perform){ moab::Range ents, skin; int o_ct=0, no_ct=0, tmp=0, o_tot=0, no_tot=0; if(perform){ if(myID==0)std::cout<<"------------------------------------------"<<std::endl; //Check the count of total vertices mb->get_entities_by_dimension(0,0,ents); for(moab::Range::iterator rit = ents.begin(); rit != ents.end(); rit++){ pc->get_owner(*rit, tmp); if(tmp==myID){ o_ct++; } } MPI_Reduce(&o_ct, &o_tot, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if(myID==0){ std::cout<<"There are " << o_tot << " vertices."<<std::endl; std::cout<<"------------------------------------------"<<std::endl; } //Check the count of owned and not owned skin faces. //owned-not owned == total skin faces moab::Skinner skinner(mb); o_ct=0; no_ct=0; o_tot=0; no_tot=0; skin.clear(); ents.clear(); mb->get_entities_by_dimension(0,3,ents); skinner.find_skin(0, ents, 2, skin); for(moab::Range::iterator s_rit = skin.begin(); s_rit != skin.end(); s_rit++){ pc->get_owner(*s_rit, tmp); if(tmp==myID){ o_ct++; } else{ no_ct++; } } MPI_Reduce(&o_ct, &o_tot, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Reduce(&no_ct, &no_tot, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if(myID == 0){ std::cout<<"There are " << o_tot << " owned skin faces."<<std::endl; std::cout<<"There are " << no_tot << " not owned skin faces."<<std::endl; std::cout<<"The difference (Global Skin Faces) is " << (o_tot-no_tot) << "." << std::endl; std::cout<<"------------------------------------------"<<std::endl; } } }
//Sets mySkinEnts with all of the skin entities on the processor ErrorCode ParallelMergeMesh::PopulateMySkinEnts(const EntityHandle meshset, int dim, bool skip_local_merge) { /*Merge Mesh Locally*/ //Get all dim dimensional entities Range ents; ErrorCode rval = myMB->get_entities_by_dimension(meshset,dim,ents);MB_CHK_ERR(rval); if (ents.empty() && dim==3) { dim--; rval = myMB->get_entities_by_dimension(meshset,dim,ents);MB_CHK_ERR(rval);// maybe dimension 2 } //Merge Mesh Locally if (!skip_local_merge) { MergeMesh merger(myMB, false); merger.merge_entities(ents,myEps); //We can return if there is only 1 proc if(rval != MB_SUCCESS || myPcomm->size() == 1){ return rval; } //Rebuild the ents range ents.clear(); rval = myMB->get_entities_by_dimension(meshset,dim,ents);MB_CHK_ERR(rval); } /*Get Skin -Get Range of all dimensional entities -skinEnts[i] is the skin entities of dimension i*/ Skinner skinner(myMB); for(int skin_dim = dim; skin_dim >= 0; skin_dim--){ rval = skinner.find_skin(meshset,ents,skin_dim,mySkinEnts[skin_dim]);MB_CHK_ERR(rval); } return MB_SUCCESS; }
//Determine which higher dimensional entities should be merged moab::ErrorCode MergeMesh::merge_higher_dimensions(moab::Range &elems) { Range skinEnts, adj, matches, moreDeadEnts; moab::ErrorCode result; moab::Skinner skinner(mbImpl); //Go through each dimension for(int dim = 1; dim <3; dim++){ skinEnts.clear(); moreDeadEnts.clear(); result = skinner.find_skin(0, elems, dim, skinEnts, false, false); //Go through each skin entity and see if it shares adjacancies with another entity for(moab::Range::iterator skinIt = skinEnts.begin(); skinIt != skinEnts.end(); skinIt++){ adj.clear(); //Get the adjacencies 1 dimension lower result = mbImpl->get_adjacencies(&(*skinIt), 1, dim-1, false, adj); if(result != moab::MB_SUCCESS) return result; //See what other entities share these adjacencies matches.clear(); result = mbImpl->get_adjacencies(adj, dim, false, matches, moab::Interface::INTERSECT); if(result != moab::MB_SUCCESS) return result; //If there is more than one entity, then we have some to merge and erase if(matches.size() > 1){ for(moab::Range::iterator matchIt = matches.begin(); matchIt != matches.end(); matchIt++){ if(*matchIt != *skinIt){ moreDeadEnts.insert(*matchIt); result = mbImpl->merge_entities(*skinIt, *matchIt, false, false); if(result != moab::MB_SUCCESS) return result; skinEnts.erase(*matchIt); } } } } //Delete the entities result = mbImpl->delete_entities(moreDeadEnts); if(result != moab::MB_SUCCESS)return result; } return moab::MB_SUCCESS; }