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);
368 idx_t *eptr = &eptr_vec.at(0);
369 idx_t *eind = &eind_vec.at(0);
377 else if(FEType==
"P2"){
385 else if(FEType==
"P2"){
390 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Wrong Dimension.");
393 vec_idx_Type epart(ne,-1);
394 vec_idx_Type npart(nn,-1);
398 std::cout <<
"-- Start partitioning with Metis ... " << std::flush;
401 FEDD_TIMER_START(partitionTimer,
" : MeshPartitioner : Partition Elements");
402 idx_t nparts = std::get<1>( rankRanges_[meshNumber] ) - std::get<0>( rankRanges_[meshNumber] ) + 1;
404 int rank = this->comm_->getRank();
406 idx_t returnCode = METIS_PartMeshDual(&ne, &nn, eptr, eind, NULL, NULL, &ncommon, &nparts, NULL, options, &objval, &epart[0], &npart[0]);
408 std::cout <<
"\n--\t Metis return code: " << returnCode;
411 for (
int i=0; i<ne; i++)
417 std::cout <<
"\n--\t objval: " << objval << std::endl;
418 std::cout <<
"-- done!" << std::endl;
422 std::cout <<
"-- Set Elements ... " << std::flush;
424 vec_GO_Type locepart(0);
425 vec_GO_Type pointsRepIndices(0);
427 vec_GO_Type locedpart(0);
430 for (
int i=0; i<ne; i++) {
431 if (epart[i] == comm_->getRank() - std::get<0>( rankRanges_[meshNumber] ) ){
432 locepart.push_back(i);
433 for (
int j=eptr[i]; j<eptr[i+1]; j++)
434 pointsRepIndices.push_back( eind[j] );
438 eind_vec.erase(eind_vec.begin(), eind_vec.end());
439 eptr_vec.erase(eptr_vec.begin(), eptr_vec.end());
442 make_unique(pointsRepIndices);
444 std::cout <<
"done!" << std::endl;
447 Teuchos::ArrayView<GO> pointsRepGlobMapping = Teuchos::arrayViewFromVector( pointsRepIndices );
448 meshUnstr->mapRepeated_.reset(
new Map<LO,GO,NO>(OTGO::invalid(), pointsRepGlobMapping, 0, this->comm_) );
449 MapConstPtr_Type mapRepeated = meshUnstr->mapRepeated_;
452 ElementsPtr_Type elementsGlobal = Teuchos::rcp(
new Elements_Type( *elementsMesh ) );
455 meshUnstr->elementsC_.reset(
new Elements ( FEType, dim ) );
457 Teuchos::ArrayView<GO> elementsGlobalMapping = Teuchos::arrayViewFromVector( locepart );
460 meshUnstr->elementMap_.reset(
new Map<LO,GO,NO>( (GO) -1, elementsGlobalMapping, 0, this->comm_) );
463 int localSurfaceCounter = 0;
464 for (
int i=0; i<locepart.size(); i++) {
465 std::vector<int> tmpElement;
466 for (
int j=eptr[locepart.at(i)]; j<eptr[locepart.at(i)+1]; j++) {
468 int index = mapRepeated->getLocalElement( (
long long) eind[j] );
469 tmpElement.push_back(index);
472 FiniteElement fe( tmpElement, elementsGlobal->getElement( locepart.at(i) ).getFlag() );
475 FiniteElement feGlobalIDs = elementsGlobal->getElement( locepart.at(i) );
476 if (feGlobalIDs.subElementsInitialized()){
477 ElementsPtr_Type subEl = feGlobalIDs.getSubElements();
478 subEl->globalToLocalIDs( mapRepeated );
479 fe.setSubElements( subEl );
482 meshUnstr->elementsC_->addElement( fe );
490 meshUnstr->readMeshEntity(
"node");
493 std::cout <<
"-- Build Repeated Points Volume ... " << std::flush;
496 meshUnstr->mapUnique_ = meshUnstr->mapRepeated_->buildUniqueMap( rankRanges_[meshNumber] );
500 std::cout <<
"-- Building unique & repeated points ... " << std::flush;
502 vec2D_dbl_Type points = *meshUnstr->getPointsRepeated();
503 vec_int_Type flags = *meshUnstr->getBCFlagRepeated();
504 meshUnstr->pointsRep_.reset(
new std::vector<std::vector<double> >( meshUnstr->mapRepeated_->getNodeNumElements(), std::vector<double>(dim,-1.) ) );
505 meshUnstr->bcFlagRep_.reset(
new std::vector<int> ( meshUnstr->mapRepeated_->getNodeNumElements(), 0 ) );
508 for (
int i=0; i<pointsRepIndices.size() ; i++) {
509 pointIDcont = pointsRepIndices.at(i);
510 for (
int j=0; j<dim; j++)
511 meshUnstr->pointsRep_->at(i).at(j) = points[pointIDcont][j];
512 meshUnstr->bcFlagRep_->at(i) = flags[pointIDcont];
517 meshUnstr->pointsUni_.reset(
new std::vector<std::vector<double> >( meshUnstr->mapUnique_->getNodeNumElements(), std::vector<double>(dim,-1.) ) );
518 meshUnstr->bcFlagUni_.reset(
new std::vector<int> ( meshUnstr->mapUnique_->getNodeNumElements(), 0) );
520 MapConstPtr_Type map = meshUnstr->getMapRepeated();
521 vec2D_dbl_ptr_Type pointsRep = meshUnstr->pointsRep_;
522 for (
int i=0; i<meshUnstr->mapUnique_->getNodeNumElements() ; i++) {
523 indexGlobal = meshUnstr->mapUnique_->getGlobalElement(i);
524 for (
int j=0; j<dim; j++) {
525 meshUnstr->pointsUni_->at(i).at(j) = pointsRep->at( map->getLocalElement( indexGlobal) ).at(j);
527 meshUnstr->bcFlagUni_->at(i) = meshUnstr->bcFlagRep_->at( map->getLocalElement( indexGlobal) );
533 elementsGlobal.reset();
535 locepart.erase(locepart.begin(),locepart.end());
537 std::cout <<
"done!" << std::endl;
540 this->setEdgesToSurfaces( meshNumber );
543 meshUnstr->deleteSurfaceElements();
547 std::cout <<
"-- Build edge element list ... " << std::endl << std::flush;
549 buildEdgeListParallel( meshUnstr, elementsGlobal );
552 std::cout << std::endl <<
" done!"<< std::endl;
554 MapConstPtr_Type elementMap = meshUnstr->getElementMap();
556 FEDD_TIMER_START(partitionEdgesTimer,
" : MeshPartitioner : Partition Edges");
557 meshUnstr->getEdgeElements()->partitionEdges( elementMap, mapRepeated );
558 FEDD_TIMER_STOP(partitionEdgesTimer);
561 for(
int i=0; i<meshUnstr->getEdgeElements()->numberElements() ; i++){
562 locedpart.push_back(meshUnstr->getEdgeElements()->getGlobalID((LO) i));
566 Teuchos::ArrayView<GO> edgesGlobalMapping = Teuchos::arrayViewFromVector( locedpart );
567 meshUnstr->edgeMap_.reset(
new Map<LO,GO,NO>( (GO) -1, edgesGlobalMapping, 0, this->comm_) );
572 std::cout <<
"done!" << std::endl;
575 std::cout <<
"-- Partition interface ... " << std::flush;
576 meshUnstr->partitionInterface();
579 std::cout <<
"done!" << std::endl;
586template <
class SC,
class LO,
class GO,
class NO>
588 bool verbose ( comm_->getRank() == 0 );
589 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
590 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
591 MapConstPtr_Type mapRepeated = meshUnstr->mapRepeated_;
593 std::cout <<
"-- Set edges of surfaces of elements ... " << std::flush;
595 FEDD_TIMER_START(surfacesTimer,
" : MeshPartitioner : Set Surfaces of Edge Elements");
596 vec2D_int_Type localEdgeIDPermutation;
599 int volumeID = meshUnstr->volumeID_;
601 ElementsPtr_Type elements = meshUnstr->getElementsC();
602 ElementsPtr_Type edgeElements = meshUnstr->getSurfaceEdgeElements();
606 vec2D_int_Type edgeElements_vec( edgeElements->numberElements() );
607 vec_int_Type edgeElementsFlag_vec( edgeElements->numberElements() );
608 for (
int i=0; i<edgeElements_vec.size(); i++){
609 vec_int_Type edge = edgeElements->getElement(i).getVectorNodeListNonConst();
610 std::sort( edge.begin(), edge.end() );
611 edgeElements_vec.at(i) = edge;
612 edgeElementsFlag_vec.at(i) = edgeElements->getElement(i).getFlag();
615 vec_int_ptr_Type flags = meshUnstr->bcFlagRep_;
616 int elementEdgeSurfaceCounter;
617 for (
int i=0; i<elements->numberElements(); i++) {
618 elementEdgeSurfaceCounter = 0;
620 for (
int j=0; j<elements->getElement( i ).size(); j++) {
621 if ( flags->at( elements->getElement( i ).getNode( j ) ) < volumeID )
622 elementEdgeSurfaceCounter++;
624 if (elementEdgeSurfaceCounter >= meshUnstr->getEdgeElementOrder()){
626 findAndSetSurfaceEdges( edgeElements_vec, edgeElementsFlag_vec, elements->getElement(i), localEdgeIDPermutation, mapRepeated );
630 std::cout <<
"done!" << std::endl;
635template <
class SC,
class LO,
class GO,
class NO>
638 bool verbose ( comm_->getRank() == 0 );
639 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
640 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
643 std::cout <<
"-- Set surfaces of elements ... " << std::flush;
645 FEDD_TIMER_START(surfacesTimer,
" : MeshPartitioner : Set Surfaces of Elements");
647 vec2D_int_Type localSurfaceIDPermutation;
649 setLocalSurfaceIndices( localSurfaceIDPermutation, meshUnstr->getSurfaceElementOrder() );
651 int volumeID = meshUnstr->volumeID_;
652 ElementsPtr_Type surfaceElements = meshUnstr->getSurfaceElements();
659 int size = this->comm_->getSize();
661 LO numSurfaceEl = surfaceElements->numberElements();
675 vec2D_int_Type surfElements_vec( numSurfaceEl );
676 vec2D_int_Type surfElements_vec_sorted( numSurfaceEl );
678 vec_int_Type surfElementsFlag_vec( numSurfaceEl );
679 vec_GO_Type offsetVec(size);
680 int offset = offsetVec[this->comm_->getRank()];
682 for (
int i=0; i<surfElements_vec.size(); i++){
683 vec_int_Type surface = surfaceElements->getElement(i ).getVectorNodeListNonConst();
684 surfElements_vec.at(i) = surface;
685 std::sort( surface.begin(), surface.end() );
686 surfElements_vec_sorted.at(i) = surface;
687 surfElementsFlag_vec.at(i) = surfaceElements->getElement(i).getFlag();
692 surfaceElements.reset();
693 vec_int_ptr_Type flags = meshUnstr->bcFlagRep_;
695 int elementSurfaceCounter;
696 int surfaceElOrder = meshUnstr->getSurfaceElementOrder();
697 for (
int i=0; i<elementsMesh->numberElements(); i++) {
698 elementSurfaceCounter = 0;
699 for (
int j=0; j<elementsMesh->getElement( i ).size(); j++) {
700 if ( flags->at( elementsMesh->getElement( i ).getNode( j ) ) < volumeID )
701 elementSurfaceCounter++;
704 if (elementSurfaceCounter >= surfaceElOrder){
705 FEDD_TIMER_START(findSurfacesTimer,
" : MeshPartitioner : Find and Set Surfaces");
707 this->
findAndSetSurfacesPartitioned( surfElements_vec_sorted, surfElements_vec, surfElementsFlag_vec, elementsMesh->getElement(i), localSurfaceIDPermutation, offsetVec, i );
712 std::cout <<
"done!" << std::endl;
717template <
class SC,
class LO,
class GO,
class NO>
725 int loc, id1Glob, id2Glob, id3Glob;
726 int size = this->comm_->getSize();
727 vec_int_Type locAll(size);
729 for (
int j=0; j<permutation.size(); j++) {
730 id1Glob = element.getNode( permutation.at(j).at(0) ) ;
731 id2Glob = element.getNode( permutation.at(j).at(1) ) ;
733 vec_int_Type tmpSurface(2);
734 if (id1Glob > id2Glob){
735 tmpSurface[0] = id2Glob;
736 tmpSurface[1] = id1Glob;
739 tmpSurface[0] = id1Glob;
740 tmpSurface[1] = id2Glob;
745 Teuchos::gatherAll<int,int>( *this->comm_, 1, &loc, locAll.size(), &locAll[0] );
747 int surfaceRank = -1;
749 while (surfaceRank<0 && counter<size) {
750 if (locAll[counter] > -1)
751 surfaceRank = counter;
756 surfFlag = surfElementsFlag_vec[loc];
758 if (surfaceRank>-1) {
759 Teuchos::broadcast<int,int>(*this->comm_,surfaceRank,1,&loc);
760 Teuchos::broadcast<int,int>(*this->comm_,surfaceRank,1,&surfFlag);
763 if ( !element.subElementsInitialized() )
764 element.initializeSubElements(
"P1", 1 );
766 element.addSubElement( feSurface );
771 for (
int j=0; j<permutation.size(); j++) {
773 id1Glob = element.getNode( permutation.at(j).at(0) ) ;
774 id2Glob = element.getNode( permutation.at(j).at(1) ) ;
775 id3Glob = element.getNode( permutation.at(j).at(2) ) ;
777 vec_int_Type tmpSurface = {id1Glob , id2Glob , id3Glob};
778 sort( tmpSurface.begin(), tmpSurface.end() );
798 int surfFlag = surfElementsFlag_vec[loc];
800 FiniteElement feSurface( surfElements_vec_unsorted[loc], surfFlag);
801 if ( !element.subElementsInitialized() )
802 element.initializeSubElements(
"P1", 2 );
804 element.addSubElement( feSurface );
812template <
class SC,
class LO,
class GO,
class NO>
814 FEDD_TIMER_START(edgeListTimer,
" : MeshReader : Build Edge List");
815 ElementsPtr_Type elements = mesh->getElementsC();
817 TEUCHOS_TEST_FOR_EXCEPTION( elements->getFiniteElementType() !=
"P1", std::runtime_error ,
"Unknown discretization for method buildEdgeList(...).");
818 CommConstPtr_Type comm = mesh->getComm();
819 bool verbose(comm->getRank()==0);
821 MapConstPtr_Type repeatedMap = mesh->getMapRepeated();
823 vec2D_int_Type localEdgeIndices(0);
825 EdgeElementsPtr_Type edges = Teuchos::rcp(
new EdgeElements_Type() );
826 for (
int i=0; i<elementsGlobal->numberElements(); i++) {
827 for (
int j=0; j<localEdgeIndices.size(); j++) {
829 int id1 = elementsGlobal->getElement( i ).getNode( localEdgeIndices[j][0] );
830 int id2 = elementsGlobal->getElement( i ).getNode( localEdgeIndices[j][1] );
831 vec_int_Type edgeVec(2);
842 edges->addEdge( edge, i );
846 elementsGlobal.reset();
848 vec2D_GO_Type combinedEdgeElements;
849 FEDD_TIMER_START(edgeListUniqueTimer,
" : MeshReader : Make Edge List Unique");
850 edges->sortUniqueAndSetGlobalIDs( combinedEdgeElements );
851 FEDD_TIMER_STOP(edgeListUniqueTimer);
854 edges->setElementsEdges( combinedEdgeElements );
856 mesh->setEdgeElements( edges );
860template <
class SC,
class LO,
class GO,
class NO>
863 localEdgeIndices.resize(3,vec_int_Type(2,-1));
864 localEdgeIndices.at(0).at(0) = 0;
865 localEdgeIndices.at(0).at(1) = 1;
866 localEdgeIndices.at(1).at(0) = 0;
867 localEdgeIndices.at(1).at(1) = 2;
868 localEdgeIndices.at(2).at(0) = 1;
869 localEdgeIndices.at(2).at(1) = 2;
871 else if( dim_ == 3) {
872 localEdgeIndices.resize(6,vec_int_Type(2,-1));
873 localEdgeIndices.at(0).at(0) = 0;
874 localEdgeIndices.at(0).at(1) = 1;
875 localEdgeIndices.at(1).at(0) = 0;
876 localEdgeIndices.at(1).at(1) = 2;
877 localEdgeIndices.at(2).at(0) = 1;
878 localEdgeIndices.at(2).at(1) = 2;
879 localEdgeIndices.at(3).at(0) = 0;
880 localEdgeIndices.at(3).at(1) = 3;
881 localEdgeIndices.at(4).at(0) = 1;
882 localEdgeIndices.at(4).at(1) = 3;
883 localEdgeIndices.at(5).at(0) = 2;
884 localEdgeIndices.at(5).at(1) = 3;
889template <
class SC,
class LO,
class GO,
class NO>
890void MeshPartitioner<SC,LO,GO,NO>::makeContinuousElements(ElementsPtr_Type elements, vec_idx_Type& eind_vec, vec_idx_Type& eptr_vec ){
892 int nodesPerElement = elements->nodesPerElement();
895 for (
int i=0; i<elements->numberElements(); i++) {
896 for (
int j=0; j<nodesPerElement; j++) {
897 eind_vec.push_back( elements->getElement( i ).getNode( j ) );
899 eptr_vec.push_back(elcounter);
900 elcounter += nodesPerElement;
902 eptr_vec.push_back(elcounter);
907template <
class SC,
class LO,
class GO,
class NO>
912 if (edgesElementOrder == 2) {
913 localSurfaceEdgeIndices.resize(6,vec_int_Type(2,-1));
914 localSurfaceEdgeIndices.at(0).at(0) = 0;
915 localSurfaceEdgeIndices.at(0).at(1) = 1;
916 localSurfaceEdgeIndices.at(1).at(0) = 0;
917 localSurfaceEdgeIndices.at(1).at(1) = 2;
918 localSurfaceEdgeIndices.at(2).at(0) = 0;
919 localSurfaceEdgeIndices.at(2).at(1) = 3;
920 localSurfaceEdgeIndices.at(3).at(0) = 1;
921 localSurfaceEdgeIndices.at(3).at(1) = 2;
922 localSurfaceEdgeIndices.at(4).at(0) = 1;
923 localSurfaceEdgeIndices.at(4).at(1) = 3;
924 localSurfaceEdgeIndices.at(5).at(0) = 2;
925 localSurfaceEdgeIndices.at(5).at(1) = 3;
930template <
class SC,
class LO,
class GO,
class NO>
933 int loc, id1Glob, id2Glob;
935 for (
int j=0; j<permutation.size(); j++) {
936 id1Glob = mapRepeated->getGlobalElement( element.getNode( permutation.at(j).at(0) ) );
937 id2Glob = mapRepeated->getGlobalElement( element.getNode( permutation.at(j).at(1) ) );
938 vec_int_Type tmpEdge(0);
939 if (id2Glob > id1Glob)
940 tmpEdge = {id1Glob , id2Glob};
942 tmpEdge = {id2Glob , id1Glob};
948 int id1 = element.getNode( permutation.at(j).at(0) );
949 int id2 = element.getNode( permutation.at(j).at(1) );
950 vec_int_Type tmpEdgeLocal(0);
952 tmpEdgeLocal = { id1 , id2 };
954 tmpEdgeLocal = { id2 , id1 };
957 FiniteElement feEdge( tmpEdgeLocal, edgeElementsFlag_vec[loc] );
961 if ( !element.subElementsInitialized() ){
962 element.initializeSubElements(
"P1", 1 );
963 element.addSubElement( feEdge );
966 ElementsPtr_Type surfaces = element.getSubElements();
967 if(surfaces->getDimension() == 2)
968 surfaces->setToCorrectElement( feEdge );
970 element.addSubElement( feEdge );
981template <
class SC,
class LO,
class GO,
class NO>
986 vec2D_int_Type::iterator it = find(surfaces.begin(),surfaces.end(), searchSurface);
988 if (it!=surfaces.end())
989 loc = distance(surfaces.begin(),it);
994template <
class SC,
class LO,
class GO,
class NO>
995void MeshPartitioner<SC,LO,GO,NO>::setLocalSurfaceIndices(vec2D_int_Type &localSurfaceIndices,
int surfaceElementOrder ){
999 if (surfaceElementOrder == 2) {
1000 localSurfaceIndices.resize(3,vec_int_Type(3,-1));
1001 localSurfaceIndices.at(0).at(0) = 0;
1002 localSurfaceIndices.at(0).at(1) = 1;
1003 localSurfaceIndices.at(1).at(0) = 0;
1004 localSurfaceIndices.at(1).at(1) = 2;
1005 localSurfaceIndices.at(2).at(0) = 1;
1006 localSurfaceIndices.at(2).at(1) = 2;
1009 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"No permutation for this surface yet.");
1011 else if ( dim_ == 3 ){
1012 if (surfaceElementOrder == 3) {
1013 localSurfaceIndices.resize(4,vec_int_Type(3,-1));
1014 localSurfaceIndices.at(0).at(0) = 0;
1015 localSurfaceIndices.at(0).at(1) = 1;
1016 localSurfaceIndices.at(0).at(2) = 2;
1017 localSurfaceIndices.at(1).at(0) = 0;
1018 localSurfaceIndices.at(1).at(1) = 1;
1019 localSurfaceIndices.at(1).at(2) = 3;
1020 localSurfaceIndices.at(2).at(0) = 1;
1021 localSurfaceIndices.at(2).at(1) = 2;
1022 localSurfaceIndices.at(2).at(2) = 3;
1023 localSurfaceIndices.at(3).at(0) = 0;
1024 localSurfaceIndices.at(3).at(1) = 2;
1025 localSurfaceIndices.at(3).at(2) = 3;
1028 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:718
int searchInSurfaces(vec2D_int_Type &surfaces, vec_int_Type searchSurface)
Searching on particular surface in a surface list.
Definition MeshPartitioner_def.hpp:982
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:636
void buildEdgeListParallel(MeshUnstrPtr_Type mesh, ElementsPtr_Type elementsGlobal)
Making the edge list parallel.
Definition MeshPartitioner_def.hpp:813
void setEdgesToSurfaces(int meshNumber)
Only used in 3D to set the edges as subelements to surfaces.
Definition MeshPartitioner_def.hpp:587
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:931
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:908
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:861
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36