1#ifndef MeshPartitioner_def_hpp
2#define MeshPartitioner_def_hpp
14template <
class SC,
class LO,
class GO,
class NO>
15MeshPartitioner<SC,LO,GO,NO>::MeshPartitioner()
20template <
class SC,
class LO,
class GO,
class NO>
21MeshPartitioner<SC,LO,GO,NO>::MeshPartitioner( DomainPtrArray_Type domains, ParameterListPtr_Type pL, std::string feType,
int dimension )
26 comm_ = domains_[0]->getComm();
27 rankRanges_.resize( domains_.size() );
31template <
class SC,
class LO,
class GO,
class NO>
32MeshPartitioner<SC,LO,GO,NO>::~MeshPartitioner(){
38template <
class SC,
class LO,
class GO,
class NO>
42 if(this->comm_->getRank()==0){
43 std::cout <<
" #### WARNING: The volumeID was set manually and is no longer 10. Please make sure your volumeID corresponds to the volumeID in your mesh file. #### " << std::endl;
47 std::string delimiter = pList_->get(
"Delimiter",
" " );
48 for (
int i=0; i<domains_.size(); i++) {
49 std::string meshName = pList_->get(
"Mesh " + std::to_string(i+1) +
" Name",
"noName" );
50 TEUCHOS_TEST_FOR_EXCEPTION( meshName ==
"noName", std::runtime_error,
"No mesh name given.");
51 domains_[i]->initializeUnstructuredMesh( domains_[i]->getDimension(),
"P1",volumeID, meshUnit, convertToCM );
52 domains_[i]->readMeshSize( meshName, delimiter );
55 this->determineRanks();
57 for (
int i=0; i<domains_.size(); i++){
58 this->readAndPartitionMesh( i );
59 domains_[i]->getMesh()->rankRange_ = rankRanges_[i];
63template <
class SC,
class LO,
class GO,
class NO>
64void MeshPartitioner<SC,LO,GO,NO>::determineRanks(){
65 bool verbose ( comm_->getRank() == 0 );
66 vec_int_Type fractions( domains_.size(), 0 );
67 bool autoPartition = pList_->get(
"Automatic partition",
false );
68 if ( autoPartition ) {
71 for (
int i=0; i<domains_.size(); i++)
72 sumElements += domains_[i]->getNumElementsGlobal();
74 for (
int i=0; i<fractions.size(); i++)
75 fractions[i] = (domains_[i]->getNumElementsGlobal()*100) / sumElements;
77 int diff = std::accumulate(fractions.begin(), fractions.end(), 0) - 100;
78 auto iterator = fractions.begin();
84 iterator = fractions.begin();
91 this->determineRanksFromFractions( fractions );
94 std::cout <<
"\t --- ---------------- ---" << std::endl;
95 std::cout <<
"\t --- Mesh Partitioner ---" << std::endl;
96 std::cout <<
"\t --- ---------------- ---" << std::endl;
97 std::cout <<
"\t --- Automatic partition for "<< comm_->getSize() <<
" ranks" << std::endl;
98 for (
int i=0; i<domains_.size(); i++) {
99 std::cout <<
"\t --- Fraction mesh "<<std::to_string(i+1) <<
" : " << fractions[i] <<
100 " of 100; rank range: " << std::get<0>( rankRanges_[i] )<<
" to "<< std::get<1>( rankRanges_[i] ) << std::endl;
105 else if( autoPartition ==
false && pList_->get(
"Mesh 1 fraction ranks",-1) >= 0 ){
106 for (
int i=0; fractions.size(); i++)
107 fractions[i] = pList_->get(
"Mesh " + std::to_string(i+1) +
" fraction ranks", -1);
109 TEUCHOS_TEST_FOR_EXCEPTION( std::accumulate(fractions.begin(), fractions.end(), 0) != 100, std::runtime_error,
"Fractions do not sum up to 100!");
110 this->determineRanksFromFractions( fractions );
113 std::cout <<
"\t --- ---------------- ---" << std::endl;
114 std::cout <<
"\t --- Mesh Partitioner ---" << std::endl;
115 std::cout <<
"\t --- ---------------- ---" << std::endl;
116 std::cout <<
"\t --- Fraction partition for "<< comm_->getSize() <<
" ranks" << std::endl;
117 for (
int i=0; i<domains_.size(); i++) {
118 std::cout <<
"\t --- Fraction mesh "<<std::to_string(i+1) <<
" : " << fractions[i] <<
119 " of 100; rank range: " << std::get<0>( rankRanges_[i] )<<
" to "<< std::get<1>( rankRanges_[i] ) << std::endl;
123 else if( autoPartition ==
false && pList_->get(
"Mesh 1 fraction ranks",-1) < 0 && pList_->get(
"Mesh 1 number ranks",-1) > 0 ){
124 int size = comm_->getSize();
125 vec_int_Type numberRanks(domains_.size());
126 for (
int i=0; i<numberRanks.size(); i++)
127 numberRanks[i] = pList_->get(
"Mesh " + std::to_string(i+1) +
" number ranks",0);
129 TEUCHOS_TEST_FOR_EXCEPTION( std::accumulate(numberRanks.begin(), numberRanks.end(), 0) > size, std::runtime_error,
"Too many ranks requested for mesh partition!");
130 this->determineRanksFromNumberRanks( numberRanks );
132 std::cout <<
"\t --- ---------------- ---" << std::endl;
133 std::cout <<
"\t --- Mesh Partitioner ---" << std::endl;
134 std::cout <<
"\t --- ---------------- ---" << std::endl;
135 std::cout <<
"\t --- Rank number partition for "<< comm_->getSize() <<
" ranks" << std::endl;
136 for (
int i=0; i<domains_.size(); i++) {
137 std::cout <<
"\t --- Rank range mesh "<<std::to_string(i+1) <<
" :" << std::get<0>( rankRanges_[i] )<<
" to "<< std::get<1>( rankRanges_[i] ) << std::endl;
143 for (
int i=0; i<domains_.size(); i++)
144 rankRanges_[i] = std::make_tuple( 0, comm_->getSize()-1 );
146 std::cout <<
"\t --- ---------------- ---" << std::endl;
147 std::cout <<
"\t --- Mesh Partitioner ---" << std::endl;
148 std::cout <<
"\t --- ---------------- ---" << std::endl;
149 std::cout <<
"\t --- Every mesh on every rank" << std::endl;
154template <
class SC,
class LO,
class GO,
class NO>
155void MeshPartitioner<SC,LO,GO,NO>::determineRanksFromFractions( vec_int_Type& fractions ){
157 int lowerRank = 0;
int size = comm_->getSize();
159 for (
int i=0; i<fractions.size(); i++){
160 upperRank = lowerRank + fractions[i] / 100. * size - 1;
161 if (upperRank<lowerRank)
163 rankRanges_[i] = std::make_tuple( lowerRank, upperRank );
165 lowerRank = upperRank + 1;
167 lowerRank = upperRank;
170 while ( upperRank > size-1 ) {
171 for (
int i=startLoc; i<rankRanges_.size(); i++){
173 std::get<0>( rankRanges_[i] )--;
174 std::get<1>( rankRanges_[i] )--;
180 while ( upperRank < size-1 ) {
181 for (
int i=startLoc; i<rankRanges_.size(); i++){
183 std::get<0>( rankRanges_[i] )++;
184 std::get<1>( rankRanges_[i] )++;
191template <
class SC,
class LO,
class GO,
class NO>
192void MeshPartitioner<SC,LO,GO,NO>::determineRanksFromNumberRanks( vec_int_Type& numberRanks ){
194 int lowerRank = 0;
int size = comm_->getSize();
196 for (
int i=0; i<numberRanks.size(); i++){
197 upperRank = lowerRank + numberRanks[i] - 1;
198 rankRanges_[i] = std::make_tuple( lowerRank, upperRank );
199 lowerRank = upperRank + 1;
203 while ( upperRank > size-1 ) {
204 for (
int i=startLoc; i<rankRanges_.size(); i++){
206 std::get<0>( rankRanges_[i] )--;
207 std::get<1>( rankRanges_[i] )--;
213 while ( upperRank < size-1 ) {
214 for (
int i=startLoc; i<rankRanges_.size(); i++){
216 std::get<0>( rankRanges_[i] )++;
217 std::get<1>( rankRanges_[i] )++;
227template <
class SC,
class LO,
class GO,
class NO>
228void MeshPartitioner<SC,LO,GO,NO>::readAndPartitionMesh(
int meshNumber ){
230 typedef Teuchos::OrdinalTraits<GO> OTGO;
232 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
235 meshUnstr->readMeshEntity(
"node");
237 meshUnstr->pointsRep_.reset();
239 meshUnstr->readMeshEntity(
"element");
241 meshUnstr->readMeshEntity(
"surface");
243 meshUnstr->readMeshEntity(
"line");
247 bool verbose ( comm_->getRank() == 0 );
248 bool buildEdges = pList_->get(
"Build Edge List",
true);
249 bool buildSurfaces = pList_->get(
"Build Surface List",
true);
253 this->setSurfacesToElements( meshNumber );
255 meshUnstr->deleteSurfaceElements();
258 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
261 idx_t options[METIS_NOPTIONS];
262 METIS_SetDefaultOptions(options);
273 options[METIS_OPTION_NUMBERING] = 0;
279 options[METIS_OPTION_SEED] = 666;
286 options[METIS_OPTION_CONTIG] = pList_->get(
"Contiguous",
false);
293 options[METIS_OPTION_NCUTS] = pList_->get(
"NCUTS",1);
300 options[METIS_OPTION_MINCONN] = pList_->get(
"MINCONN",1);
307 idx_t objtype = METIS_OBJTYPE_CUT;
308 if( pList_->get(
"OBJTYPE",
"METIS_OBJTYPE_CUT") ==
"METIS_OBJTYPE_CUT")
309 objtype =METIS_OBJTYPE_CUT;
310 else if(pList_->get(
"OBJTYPE",
"METIS_OBJTYPE_CUT") ==
"METIS_OBJTYPE_VOL")
311 objtype = METIS_OBJTYPE_VOL;
312 options[METIS_OPTION_OBJTYPE] =objtype;
322 idx_t rtype = METIS_RTYPE_FM;
323 if(pList_->get(
"RTYPE",
"METIS_RTYPE_FM")==
"METIS_RTYPE_FM")
324 rtype = METIS_RTYPE_FM;
325 else if(pList_->get(
"RTYPE",
"METIS_RTYPE_FM")==
"METIS_RTYPE_GREEDY")
326 rtype = METIS_RTYPE_GREEDY;
327 else if(pList_->get(
"RTYPE",
"METIS_RTYPE_FM") ==
"METIS_RTYPE_SEP2SIDED")
328 rtype = METIS_RTYPE_SEP2SIDED;
329 else if(pList_->get(
"RTYPE",
"METIS_RTYPE_FM") ==
"METIS_RTYPE_SEP1SIDED")
330 rtype = METIS_RTYPE_SEP1SIDED;
332 options[METIS_OPTION_RTYPE] = rtype;
339 options[METIS_OPTION_NITER] = pList_->get(
"NITER",50);
345 options[METIS_OPTION_CCORDER] = pList_->get(
"CCORDER",1);
352 options[METIS_OPTION_DBGLVL] = pList_->get(
"DBGLVL",0);
354 idx_t ne = meshUnstr->getNumElementsGlobal();
355 idx_t nn = meshUnstr->getNumGlobalNodes();
356 idx_t ned = meshUnstr->getEdgeElements()->numberElements();
359 int dim = meshUnstr->getDimension();
360 std::string FEType = domains_[meshNumber]->getFEType();
363 vec_idx_Type eptr_vec(0);
364 vec_idx_Type eind_vec(0);
366 makeContinuousElements(elementsMesh, eind_vec, eptr_vec);
374 else if(FEType==
"P2"){
382 else if(FEType==
"P2"){
387 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Wrong Dimension.");
390 vec_idx_Type epart(ne,-1);
391 vec_idx_Type npart(nn,-1);
395 std::cout <<
"-- Start partitioning with Metis ... " << std::flush;
398 FEDD_TIMER_START(partitionTimer,
" : MeshPartitioner : Partition Elements");
399 idx_t nparts = std::get<1>( rankRanges_[meshNumber] ) - std::get<0>( rankRanges_[meshNumber] ) + 1;
401 int rank = this->comm_->getRank();
403 idx_t returnCode = METIS_PartMeshDual(&ne, &nn, eptr_vec.data(), eind_vec.data(), NULL, NULL, &ncommon, &nparts, NULL, options, &objval, epart.data(), npart.data());
405 std::cout <<
"\n--\t Metis return code: " << returnCode;
408 for (
int i=0; i<ne; i++)
414 std::cout <<
"\n--\t objval: " << objval << std::endl;
415 std::cout <<
"-- done!" << std::endl;
419 std::cout <<
"-- Set Elements ... " << std::flush;
421 vec_GO_Type locepart(0);
422 vec_GO_Type pointsRepIndices(0);
424 vec_GO_Type locedpart(0);
427 for (
int i=0; i<ne; i++) {
428 if (epart.at(i) == comm_->getRank() - std::get<0>( rankRanges_[meshNumber] ) ){
429 locepart.push_back(i);
430 for (
int j=eptr_vec.at(i); j<eptr_vec.at(i+1); j++)
431 pointsRepIndices.push_back( eind_vec.at(j) );
435 make_unique(pointsRepIndices);
437 std::cout <<
"done!" << std::endl;
440 Teuchos::ArrayView<GO> pointsRepGlobMapping = Teuchos::arrayViewFromVector( pointsRepIndices );
441 meshUnstr->mapRepeated_.reset(
new Map<LO,GO,NO>(OTGO::invalid(), pointsRepGlobMapping, 0, this->comm_) );
442 MapConstPtr_Type mapRepeated = meshUnstr->mapRepeated_;
445 ElementsPtr_Type elementsGlobal = Teuchos::rcp(
new Elements_Type( *elementsMesh ) );
448 meshUnstr->elementsC_.reset(
new Elements ( FEType, dim ) );
450 Teuchos::ArrayView<GO> elementsGlobalMapping = Teuchos::arrayViewFromVector( locepart );
453 meshUnstr->elementMap_.reset(
new Map<LO,GO,NO>( (GO) -1, elementsGlobalMapping, 0, this->comm_) );
456 int localSurfaceCounter = 0;
457 for (
int i=0; i<locepart.size(); i++) {
458 std::vector<int> tmpElement;
459 for (
int j = eptr_vec.at(locepart.at(i)); j < eptr_vec.at(locepart.at(i) + 1); j++) {
461 int index = mapRepeated->getLocalElement(
static_cast<GO
>(eind_vec.at(j)));
462 tmpElement.push_back(index);
465 FiniteElement fe( tmpElement, elementsGlobal->getElement( locepart.at(i) ).getFlag() );
468 FiniteElement feGlobalIDs = elementsGlobal->getElement( locepart.at(i) );
469 if (feGlobalIDs.subElementsInitialized()){
470 ElementsPtr_Type subEl = feGlobalIDs.getSubElements();
471 subEl->globalToLocalIDs( mapRepeated );
472 fe.setSubElements( subEl );
475 meshUnstr->elementsC_->addElement( fe );
483 meshUnstr->readMeshEntity(
"node");
486 std::cout <<
"-- Build Repeated Points Volume ... " << std::flush;
489 meshUnstr->mapUnique_ = meshUnstr->mapRepeated_->buildUniqueMap( rankRanges_[meshNumber] );
493 std::cout <<
"-- Building unique & repeated points ... " << std::flush;
495 vec2D_dbl_Type points = *meshUnstr->getPointsRepeated();
496 vec_int_Type flags = *meshUnstr->getBCFlagRepeated();
497 meshUnstr->pointsRep_.reset(
new std::vector<std::vector<double> >( meshUnstr->mapRepeated_->getNodeNumElements(), std::vector<double>(dim,-1.) ) );
498 meshUnstr->bcFlagRep_.reset(
new std::vector<int> ( meshUnstr->mapRepeated_->getNodeNumElements(), 0 ) );
501 for (
int i=0; i<pointsRepIndices.size() ; i++) {
502 pointIDcont = pointsRepIndices.at(i);
503 for (
int j=0; j<dim; j++)
504 meshUnstr->pointsRep_->at(i).at(j) = points[pointIDcont][j];
505 meshUnstr->bcFlagRep_->at(i) = flags[pointIDcont];
510 meshUnstr->pointsUni_.reset(
new std::vector<std::vector<double> >( meshUnstr->mapUnique_->getNodeNumElements(), std::vector<double>(dim,-1.) ) );
511 meshUnstr->bcFlagUni_.reset(
new std::vector<int> ( meshUnstr->mapUnique_->getNodeNumElements(), 0) );
513 MapConstPtr_Type map = meshUnstr->getMapRepeated();
514 vec2D_dbl_ptr_Type pointsRep = meshUnstr->pointsRep_;
515 for (
int i=0; i<meshUnstr->mapUnique_->getNodeNumElements() ; i++) {
516 indexGlobal = meshUnstr->mapUnique_->getGlobalElement(i);
517 for (
int j=0; j<dim; j++) {
518 meshUnstr->pointsUni_->at(i).at(j) = pointsRep->at( map->getLocalElement( indexGlobal) ).at(j);
520 meshUnstr->bcFlagUni_->at(i) = meshUnstr->bcFlagRep_->at( map->getLocalElement( indexGlobal) );
526 elementsGlobal.reset();
528 locepart.erase(locepart.begin(),locepart.end());
530 std::cout <<
"done!" << std::endl;
533 this->setEdgesToSurfaces( meshNumber );
536 meshUnstr->deleteSurfaceElements();
540 std::cout <<
"-- Build edge element list ... " << std::endl << std::flush;
542 buildEdgeListParallel( meshUnstr, elementsGlobal );
545 std::cout << std::endl <<
" done!"<< std::endl;
547 MapConstPtr_Type elementMap = meshUnstr->getElementMap();
549 FEDD_TIMER_START(partitionEdgesTimer,
" : MeshPartitioner : Partition Edges");
550 meshUnstr->getEdgeElements()->partitionEdges( elementMap, mapRepeated );
551 FEDD_TIMER_STOP(partitionEdgesTimer);
554 for(
int i=0; i<meshUnstr->getEdgeElements()->numberElements() ; i++){
555 locedpart.push_back(meshUnstr->getEdgeElements()->getGlobalID((LO) i));
559 Teuchos::ArrayView<GO> edgesGlobalMapping = Teuchos::arrayViewFromVector( locedpart );
560 meshUnstr->edgeMap_.reset(
new Map<LO,GO,NO>( (GO) -1, edgesGlobalMapping, 0, this->comm_) );
565 std::cout <<
"done!" << std::endl;
568 std::cout <<
"-- Partition interface ... " << std::flush;
569 meshUnstr->partitionInterface();
572 std::cout <<
"done!" << std::endl;
579template <
class SC,
class LO,
class GO,
class NO>
581 bool verbose ( comm_->getRank() == 0 );
582 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
583 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
584 MapConstPtr_Type mapRepeated = meshUnstr->mapRepeated_;
586 std::cout <<
"-- Set edges of surfaces of elements ... " << std::flush;
588 FEDD_TIMER_START(surfacesTimer,
" : MeshPartitioner : Set Surfaces of Edge Elements");
589 vec2D_int_Type localEdgeIDPermutation;
592 int volumeID = meshUnstr->volumeID_;
594 ElementsPtr_Type elements = meshUnstr->getElementsC();
595 ElementsPtr_Type edgeElements = meshUnstr->getSurfaceEdgeElements();
599 vec2D_int_Type edgeElements_vec( edgeElements->numberElements() );
600 vec_int_Type edgeElementsFlag_vec( edgeElements->numberElements() );
601 for (
int i=0; i<edgeElements_vec.size(); i++){
602 vec_int_Type edge = edgeElements->getElement(i).getVectorNodeListNonConst();
603 std::sort( edge.begin(), edge.end() );
604 edgeElements_vec.at(i) = edge;
605 edgeElementsFlag_vec.at(i) = edgeElements->getElement(i).getFlag();
608 vec_int_ptr_Type flags = meshUnstr->bcFlagRep_;
609 int elementEdgeSurfaceCounter;
610 for (
int i=0; i<elements->numberElements(); i++) {
611 elementEdgeSurfaceCounter = 0;
613 for (
int j=0; j<elements->getElement( i ).size(); j++) {
614 if ( flags->at( elements->getElement( i ).getNode( j ) ) < volumeID )
615 elementEdgeSurfaceCounter++;
617 if (elementEdgeSurfaceCounter >= meshUnstr->getEdgeElementOrder()){
619 findAndSetSurfaceEdges( edgeElements_vec, edgeElementsFlag_vec, elements->getElement(i), localEdgeIDPermutation, mapRepeated );
623 std::cout <<
"done!" << std::endl;
628template <
class SC,
class LO,
class GO,
class NO>
631 bool verbose ( comm_->getRank() == 0 );
632 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
633 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
636 std::cout <<
"-- Set surfaces of elements ... " << std::flush;
638 FEDD_TIMER_START(surfacesTimer,
" : MeshPartitioner : Set Surfaces of Elements");
640 vec2D_int_Type localSurfaceIDPermutation;
642 setLocalSurfaceIndices( localSurfaceIDPermutation, meshUnstr->getSurfaceElementOrder() );
644 int volumeID = meshUnstr->volumeID_;
645 ElementsPtr_Type surfaceElements = meshUnstr->getSurfaceElements();
652 int size = this->comm_->getSize();
654 LO numSurfaceEl = surfaceElements->numberElements();
668 vec2D_int_Type surfElements_vec( numSurfaceEl );
669 vec2D_int_Type surfElements_vec_sorted( numSurfaceEl );
671 vec_int_Type surfElementsFlag_vec( numSurfaceEl );
672 vec_GO_Type offsetVec(size);
673 int offset = offsetVec[this->comm_->getRank()];
675 for (
int i=0; i<surfElements_vec.size(); i++){
676 vec_int_Type surface = surfaceElements->getElement(i ).getVectorNodeListNonConst();
677 surfElements_vec.at(i) = surface;
678 std::sort( surface.begin(), surface.end() );
679 surfElements_vec_sorted.at(i) = surface;
680 surfElementsFlag_vec.at(i) = surfaceElements->getElement(i).getFlag();
685 surfaceElements.reset();
686 vec_int_ptr_Type flags = meshUnstr->bcFlagRep_;
688 int elementSurfaceCounter;
689 int surfaceElOrder = meshUnstr->getSurfaceElementOrder();
690 for (
int i=0; i<elementsMesh->numberElements(); i++) {
691 elementSurfaceCounter = 0;
692 for (
int j=0; j<elementsMesh->getElement( i ).size(); j++) {
693 if ( flags->at( elementsMesh->getElement( i ).getNode( j ) ) < volumeID )
694 elementSurfaceCounter++;
697 if (elementSurfaceCounter >= surfaceElOrder){
698 FEDD_TIMER_START(findSurfacesTimer,
" : MeshPartitioner : Find and Set Surfaces");
700 this->
findAndSetSurfacesPartitioned( surfElements_vec_sorted, surfElements_vec, surfElementsFlag_vec, elementsMesh->getElement(i), localSurfaceIDPermutation, offsetVec, i );
705 std::cout <<
"done!" << std::endl;
710template <
class SC,
class LO,
class GO,
class NO>
718 int loc, id1Glob, id2Glob, id3Glob;
719 int size = this->comm_->getSize();
720 vec_int_Type locAll(size);
722 for (
int j=0; j<permutation.size(); j++) {
723 id1Glob = element.getNode( permutation.at(j).at(0) ) ;
724 id2Glob = element.getNode( permutation.at(j).at(1) ) ;
726 vec_int_Type tmpSurface(2);
727 if (id1Glob > id2Glob){
728 tmpSurface[0] = id2Glob;
729 tmpSurface[1] = id1Glob;
732 tmpSurface[0] = id1Glob;
733 tmpSurface[1] = id2Glob;
738 Teuchos::gatherAll<int,int>( *this->comm_, 1, &loc, locAll.size(), &locAll[0] );
740 int surfaceRank = -1;
742 while (surfaceRank<0 && counter<size) {
743 if (locAll[counter] > -1)
744 surfaceRank = counter;
749 surfFlag = surfElementsFlag_vec[loc];
751 if (surfaceRank>-1) {
752 Teuchos::broadcast<int,int>(*this->comm_,surfaceRank,1,&loc);
753 Teuchos::broadcast<int,int>(*this->comm_,surfaceRank,1,&surfFlag);
756 if ( !element.subElementsInitialized() )
757 element.initializeSubElements(
"P1", 1 );
759 element.addSubElement( feSurface );
764 for (
int j=0; j<permutation.size(); j++) {
766 id1Glob = element.getNode( permutation.at(j).at(0) ) ;
767 id2Glob = element.getNode( permutation.at(j).at(1) ) ;
768 id3Glob = element.getNode( permutation.at(j).at(2) ) ;
770 vec_int_Type tmpSurface = {id1Glob , id2Glob , id3Glob};
771 sort( tmpSurface.begin(), tmpSurface.end() );
791 int surfFlag = surfElementsFlag_vec[loc];
793 FiniteElement feSurface( surfElements_vec_unsorted[loc], surfFlag);
794 if ( !element.subElementsInitialized() )
795 element.initializeSubElements(
"P1", 2 );
797 element.addSubElement( feSurface );
805template <
class SC,
class LO,
class GO,
class NO>
807 FEDD_TIMER_START(edgeListTimer,
" : MeshReader : Build Edge List");
808 ElementsPtr_Type elements = mesh->getElementsC();
810 TEUCHOS_TEST_FOR_EXCEPTION( elements->getFiniteElementType() !=
"P1", std::runtime_error ,
"Unknown discretization for method buildEdgeList(...).");
811 CommConstPtr_Type comm = mesh->getComm();
812 bool verbose(comm->getRank()==0);
814 MapConstPtr_Type repeatedMap = mesh->getMapRepeated();
816 vec2D_int_Type localEdgeIndices(0);
818 EdgeElementsPtr_Type edges = Teuchos::rcp(
new EdgeElements_Type() );
819 for (
int i=0; i<elementsGlobal->numberElements(); i++) {
820 for (
int j=0; j<localEdgeIndices.size(); j++) {
822 int id1 = elementsGlobal->getElement( i ).getNode( localEdgeIndices[j][0] );
823 int id2 = elementsGlobal->getElement( i ).getNode( localEdgeIndices[j][1] );
824 vec_int_Type edgeVec(2);
835 edges->addEdge( edge, i );
839 elementsGlobal.reset();
841 vec2D_GO_Type combinedEdgeElements;
842 FEDD_TIMER_START(edgeListUniqueTimer,
" : MeshReader : Make Edge List Unique");
843 edges->sortUniqueAndSetGlobalIDs( combinedEdgeElements );
844 FEDD_TIMER_STOP(edgeListUniqueTimer);
847 edges->setElementsEdges( combinedEdgeElements );
849 mesh->setEdgeElements( edges );
853template <
class SC,
class LO,
class GO,
class NO>
856 localEdgeIndices.resize(3,vec_int_Type(2,-1));
857 localEdgeIndices.at(0).at(0) = 0;
858 localEdgeIndices.at(0).at(1) = 1;
859 localEdgeIndices.at(1).at(0) = 0;
860 localEdgeIndices.at(1).at(1) = 2;
861 localEdgeIndices.at(2).at(0) = 1;
862 localEdgeIndices.at(2).at(1) = 2;
864 else if( dim_ == 3) {
865 localEdgeIndices.resize(6,vec_int_Type(2,-1));
866 localEdgeIndices.at(0).at(0) = 0;
867 localEdgeIndices.at(0).at(1) = 1;
868 localEdgeIndices.at(1).at(0) = 0;
869 localEdgeIndices.at(1).at(1) = 2;
870 localEdgeIndices.at(2).at(0) = 1;
871 localEdgeIndices.at(2).at(1) = 2;
872 localEdgeIndices.at(3).at(0) = 0;
873 localEdgeIndices.at(3).at(1) = 3;
874 localEdgeIndices.at(4).at(0) = 1;
875 localEdgeIndices.at(4).at(1) = 3;
876 localEdgeIndices.at(5).at(0) = 2;
877 localEdgeIndices.at(5).at(1) = 3;
882template <
class SC,
class LO,
class GO,
class NO>
883void MeshPartitioner<SC,LO,GO,NO>::makeContinuousElements(ElementsPtr_Type elements, vec_idx_Type& eind_vec, vec_idx_Type& eptr_vec ){
885 int nodesPerElement = elements->nodesPerElement();
888 for (
int i=0; i<elements->numberElements(); i++) {
889 for (
int j=0; j<nodesPerElement; j++) {
890 eind_vec.push_back( elements->getElement( i ).getNode( j ) );
892 eptr_vec.push_back(elcounter);
893 elcounter += nodesPerElement;
895 eptr_vec.push_back(elcounter);
900template <
class SC,
class LO,
class GO,
class NO>
905 if (edgesElementOrder == 2) {
906 localSurfaceEdgeIndices.resize(6,vec_int_Type(2,-1));
907 localSurfaceEdgeIndices.at(0).at(0) = 0;
908 localSurfaceEdgeIndices.at(0).at(1) = 1;
909 localSurfaceEdgeIndices.at(1).at(0) = 0;
910 localSurfaceEdgeIndices.at(1).at(1) = 2;
911 localSurfaceEdgeIndices.at(2).at(0) = 0;
912 localSurfaceEdgeIndices.at(2).at(1) = 3;
913 localSurfaceEdgeIndices.at(3).at(0) = 1;
914 localSurfaceEdgeIndices.at(3).at(1) = 2;
915 localSurfaceEdgeIndices.at(4).at(0) = 1;
916 localSurfaceEdgeIndices.at(4).at(1) = 3;
917 localSurfaceEdgeIndices.at(5).at(0) = 2;
918 localSurfaceEdgeIndices.at(5).at(1) = 3;
923template <
class SC,
class LO,
class GO,
class NO>
926 int loc, id1Glob, id2Glob;
928 for (
int j=0; j<permutation.size(); j++) {
929 id1Glob = mapRepeated->getGlobalElement( element.getNode( permutation.at(j).at(0) ) );
930 id2Glob = mapRepeated->getGlobalElement( element.getNode( permutation.at(j).at(1) ) );
931 vec_int_Type tmpEdge(0);
932 if (id2Glob > id1Glob)
933 tmpEdge = {id1Glob , id2Glob};
935 tmpEdge = {id2Glob , id1Glob};
941 int id1 = element.getNode( permutation.at(j).at(0) );
942 int id2 = element.getNode( permutation.at(j).at(1) );
943 vec_int_Type tmpEdgeLocal(0);
945 tmpEdgeLocal = { id1 , id2 };
947 tmpEdgeLocal = { id2 , id1 };
950 FiniteElement feEdge( tmpEdgeLocal, edgeElementsFlag_vec[loc] );
954 if ( !element.subElementsInitialized() ){
955 element.initializeSubElements(
"P1", 1 );
956 element.addSubElement( feEdge );
959 ElementsPtr_Type surfaces = element.getSubElements();
960 if(surfaces->getDimension() == 2)
961 surfaces->setToCorrectElement( feEdge );
963 element.addSubElement( feEdge );
974template <
class SC,
class LO,
class GO,
class NO>
979 vec2D_int_Type::iterator it = find(surfaces.begin(),surfaces.end(), searchSurface);
981 if (it!=surfaces.end())
982 loc = distance(surfaces.begin(),it);
987template <
class SC,
class LO,
class GO,
class NO>
988void MeshPartitioner<SC,LO,GO,NO>::setLocalSurfaceIndices(vec2D_int_Type &localSurfaceIndices,
int surfaceElementOrder ){
992 if (surfaceElementOrder == 2) {
993 localSurfaceIndices.resize(3,vec_int_Type(3,-1));
994 localSurfaceIndices.at(0).at(0) = 0;
995 localSurfaceIndices.at(0).at(1) = 1;
996 localSurfaceIndices.at(1).at(0) = 0;
997 localSurfaceIndices.at(1).at(1) = 2;
998 localSurfaceIndices.at(2).at(0) = 1;
999 localSurfaceIndices.at(2).at(1) = 2;
1002 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"No permutation for this surface yet.");
1004 else if ( dim_ == 3 ){
1005 if (surfaceElementOrder == 3) {
1006 localSurfaceIndices.resize(4,vec_int_Type(3,-1));
1007 localSurfaceIndices.at(0).at(0) = 0;
1008 localSurfaceIndices.at(0).at(1) = 1;
1009 localSurfaceIndices.at(0).at(2) = 2;
1010 localSurfaceIndices.at(1).at(0) = 0;
1011 localSurfaceIndices.at(1).at(1) = 1;
1012 localSurfaceIndices.at(1).at(2) = 3;
1013 localSurfaceIndices.at(2).at(0) = 1;
1014 localSurfaceIndices.at(2).at(1) = 2;
1015 localSurfaceIndices.at(2).at(2) = 3;
1016 localSurfaceIndices.at(3).at(0) = 0;
1017 localSurfaceIndices.at(3).at(1) = 2;
1018 localSurfaceIndices.at(3).at(2) = 3;
1021 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"No permutation for this surface yet.");
Definition Elements.hpp:23
Definition FiniteElement.hpp:17
Definition Map_decl.hpp:30
void readAndPartition(int volumeID=10, std::string meshUnit="cm", bool convertToCM=false)
Main Function of partitioner. Called with volume ID in order to set in case it is not equal to ten....
Definition MeshPartitioner_def.hpp:39
void findAndSetSurfacesPartitioned(vec2D_int_Type &surfElements_vec, vec2D_int_Type &surfElements_vec_unsorted, vec_int_Type &surfElementsFlag_vec, FiniteElement &element, vec2D_int_Type &permutation, vec_GO_Type &linearSurfacePartitionOffset, int globalElID)
Finding the surfaces corresponding to a specfic element and then setting subelements.
Definition MeshPartitioner_def.hpp:711
int searchInSurfaces(vec2D_int_Type &surfaces, vec_int_Type searchSurface)
Searching on particular surface in a surface list.
Definition MeshPartitioner_def.hpp:975
void setSurfacesToElements(int meshNumber)
Setting surfaces, i.e. edges in 2D and triangles in 3D, as subelements to the corresponding elements.
Definition MeshPartitioner_def.hpp:629
void buildEdgeListParallel(MeshUnstrPtr_Type mesh, ElementsPtr_Type elementsGlobal)
Making the edge list parallel.
Definition MeshPartitioner_def.hpp:806
void setEdgesToSurfaces(int meshNumber)
Only used in 3D to set the edges as subelements to surfaces.
Definition MeshPartitioner_def.hpp:580
void findAndSetSurfaceEdges(vec2D_int_Type &edgeElements_vec, vec_int_Type &edgeElementsFlag_vec, FiniteElement &element, vec2D_int_Type &permutation, MapConstPtr_Type mapRepeated)
Only relevant in 3D. Finding the edges corresponding to the specfic element and then setting as subsu...
Definition MeshPartitioner_def.hpp:924
void setLocalSurfaceEdgeIndices(vec2D_int_Type &localSurfaceEdgeIndices, int edgesElementOrder)
Setting local IDs to the edges in 3D case with respect to the local numbering of elements.
Definition MeshPartitioner_def.hpp:901
void setLocalEdgeIndices(vec2D_int_Type &localEdgeIndices)
Setting surfaces, i.e. edges in 2D and triangles in 3D, as subelements to the corresponding elements.
Definition MeshPartitioner_def.hpp:854
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36