1#ifndef MeshPartitioner_def_hpp
2#define MeshPartitioner_def_hpp
4#include "MeshPartitioner_decl.hpp"
16template <
class SC,
class LO,
class GO,
class NO>
17MeshPartitioner<SC,LO,GO,NO>::MeshPartitioner()
22template <
class SC,
class LO,
class GO,
class NO>
23MeshPartitioner<SC,LO,GO,NO>::MeshPartitioner( DomainPtrArray_Type domains, ParameterListPtr_Type pL, std::string feType,
int dimension )
28 comm_ = domains_[0]->getComm();
29 rankRanges_.resize( domains_.size() );
33template <
class SC,
class LO,
class GO,
class NO>
34MeshPartitioner<SC,LO,GO,NO>::~MeshPartitioner(){
40template <
class SC,
class LO,
class GO,
class NO>
44 if(this->comm_->getRank()==0){
45 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;
49 std::string delimiter = pList_->get(
"Delimiter",
" " );
50 for (
int i=0; i<domains_.size(); i++) {
51 std::string meshName = pList_->get(
"Mesh " + std::to_string(i+1) +
" Name",
"noName" );
52 TEUCHOS_TEST_FOR_EXCEPTION( meshName ==
"noName", std::runtime_error,
"No mesh name given.");
53 domains_[i]->initializeUnstructuredMesh( domains_[i]->getDimension(),
"P1",volumeID );
54 domains_[i]->readMeshSize( meshName, delimiter );
57 this->determineRanks();
59 for (
int i=0; i<domains_.size(); i++){
60 this->readAndPartitionMesh( i );
61 domains_[i]->getMesh()->rankRange_ = rankRanges_[i];
65template <
class SC,
class LO,
class GO,
class NO>
66void MeshPartitioner<SC,LO,GO,NO>::determineRanks(){
67 bool verbose ( comm_->getRank() == 0 );
68 vec_int_Type fractions( domains_.size(), 0 );
69 bool autoPartition = pList_->get(
"Automatic partition",
false );
70 if ( autoPartition ) {
73 for (
int i=0; i<domains_.size(); i++)
74 sumElements += domains_[i]->getNumElementsGlobal();
76 for (
int i=0; i<fractions.size(); i++)
77 fractions[i] = (domains_[i]->getNumElementsGlobal()*100) / sumElements;
79 int diff = std::accumulate(fractions.begin(), fractions.end(), 0) - 100;
80 auto iterator = fractions.begin();
86 iterator = fractions.begin();
93 this->determineRanksFromFractions( fractions );
96 std::cout <<
"\t --- ---------------- ---" << std::endl;
97 std::cout <<
"\t --- Mesh Partitioner ---" << std::endl;
98 std::cout <<
"\t --- ---------------- ---" << std::endl;
99 std::cout <<
"\t --- Automatic partition for "<< comm_->getSize() <<
" ranks" << std::endl;
100 for (
int i=0; i<domains_.size(); i++) {
101 std::cout <<
"\t --- Fraction mesh "<<std::to_string(i+1) <<
" : " << fractions[i] <<
102 " of 100; rank range: " << std::get<0>( rankRanges_[i] )<<
" to "<< std::get<1>( rankRanges_[i] ) << std::endl;
107 else if( autoPartition ==
false && pList_->get(
"Mesh 1 fraction ranks",-1) >= 0 ){
108 for (
int i=0; fractions.size(); i++)
109 fractions[i] = pList_->get(
"Mesh " + std::to_string(i+1) +
" fraction ranks", -1);
111 TEUCHOS_TEST_FOR_EXCEPTION( std::accumulate(fractions.begin(), fractions.end(), 0) != 100, std::runtime_error,
"Fractions do not sum up to 100!");
112 this->determineRanksFromFractions( fractions );
115 std::cout <<
"\t --- ---------------- ---" << std::endl;
116 std::cout <<
"\t --- Mesh Partitioner ---" << std::endl;
117 std::cout <<
"\t --- ---------------- ---" << std::endl;
118 std::cout <<
"\t --- Fraction partition for "<< comm_->getSize() <<
" ranks" << std::endl;
119 for (
int i=0; i<domains_.size(); i++) {
120 std::cout <<
"\t --- Fraction mesh "<<std::to_string(i+1) <<
" : " << fractions[i] <<
121 " of 100; rank range: " << std::get<0>( rankRanges_[i] )<<
" to "<< std::get<1>( rankRanges_[i] ) << std::endl;
125 else if( autoPartition ==
false && pList_->get(
"Mesh 1 fraction ranks",-1) < 0 && pList_->get(
"Mesh 1 number ranks",-1) > 0 ){
126 int size = comm_->getSize();
127 vec_int_Type numberRanks(domains_.size());
128 for (
int i=0; i<numberRanks.size(); i++)
129 numberRanks[i] = pList_->get(
"Mesh " + std::to_string(i+1) +
" number ranks",0);
131 TEUCHOS_TEST_FOR_EXCEPTION( std::accumulate(numberRanks.begin(), numberRanks.end(), 0) > size, std::runtime_error,
"Too many ranks requested for mesh partition!");
132 this->determineRanksFromNumberRanks( numberRanks );
134 std::cout <<
"\t --- ---------------- ---" << std::endl;
135 std::cout <<
"\t --- Mesh Partitioner ---" << std::endl;
136 std::cout <<
"\t --- ---------------- ---" << std::endl;
137 std::cout <<
"\t --- Rank number partition for "<< comm_->getSize() <<
" ranks" << std::endl;
138 for (
int i=0; i<domains_.size(); i++) {
139 std::cout <<
"\t --- Rank range mesh "<<std::to_string(i+1) <<
" :" << std::get<0>( rankRanges_[i] )<<
" to "<< std::get<1>( rankRanges_[i] ) << std::endl;
145 for (
int i=0; i<domains_.size(); i++)
146 rankRanges_[i] = std::make_tuple( 0, comm_->getSize()-1 );
148 std::cout <<
"\t --- ---------------- ---" << std::endl;
149 std::cout <<
"\t --- Mesh Partitioner ---" << std::endl;
150 std::cout <<
"\t --- ---------------- ---" << std::endl;
151 std::cout <<
"\t --- Every mesh on every rank" << std::endl;
156template <
class SC,
class LO,
class GO,
class NO>
157void MeshPartitioner<SC,LO,GO,NO>::determineRanksFromFractions( vec_int_Type& fractions ){
159 int lowerRank = 0;
int size = comm_->getSize();
161 for (
int i=0; i<fractions.size(); i++){
162 upperRank = lowerRank + fractions[i] / 100. * size - 1;
163 if (upperRank<lowerRank)
165 rankRanges_[i] = std::make_tuple( lowerRank, upperRank );
167 lowerRank = upperRank + 1;
169 lowerRank = upperRank;
172 while ( upperRank > size-1 ) {
173 for (
int i=startLoc; i<rankRanges_.size(); i++){
175 std::get<0>( rankRanges_[i] )--;
176 std::get<1>( rankRanges_[i] )--;
182 while ( upperRank < size-1 ) {
183 for (
int i=startLoc; i<rankRanges_.size(); i++){
185 std::get<0>( rankRanges_[i] )++;
186 std::get<1>( rankRanges_[i] )++;
193template <
class SC,
class LO,
class GO,
class NO>
194void MeshPartitioner<SC,LO,GO,NO>::determineRanksFromNumberRanks( vec_int_Type& numberRanks ){
196 int lowerRank = 0;
int size = comm_->getSize();
198 for (
int i=0; i<numberRanks.size(); i++){
199 upperRank = lowerRank + numberRanks[i] - 1;
200 rankRanges_[i] = std::make_tuple( lowerRank, upperRank );
201 lowerRank = upperRank + 1;
205 while ( upperRank > size-1 ) {
206 for (
int i=startLoc; i<rankRanges_.size(); i++){
208 std::get<0>( rankRanges_[i] )--;
209 std::get<1>( rankRanges_[i] )--;
215 while ( upperRank < size-1 ) {
216 for (
int i=startLoc; i<rankRanges_.size(); i++){
218 std::get<0>( rankRanges_[i] )++;
219 std::get<1>( rankRanges_[i] )++;
229template <
class SC,
class LO,
class GO,
class NO>
230void MeshPartitioner<SC,LO,GO,NO>::readAndPartitionMesh(
int meshNumber ){
232 typedef Teuchos::OrdinalTraits<GO> OTGO;
234#ifdef UNDERLYING_LIB_TPETRA
235 std::string underlyingLib =
"Tpetra";
238 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
241 meshUnstr->readMeshEntity(
"node");
243 meshUnstr->pointsRep_.reset();
245 meshUnstr->readMeshEntity(
"element");
247 meshUnstr->readMeshEntity(
"surface");
249 meshUnstr->readMeshEntity(
"line");
253 bool verbose ( comm_->getRank() == 0 );
254 bool buildEdges = pList_->get(
"Build Edge List",
true);
255 bool buildSurfaces = pList_->get(
"Build Surface List",
true);
259 this->setSurfacesToElements( meshNumber );
261 meshUnstr->deleteSurfaceElements();
264 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
267 idx_t options[METIS_NOPTIONS];
268 METIS_SetDefaultOptions(options);
269 options[METIS_OPTION_NUMBERING] = 0;
270 options[METIS_OPTION_SEED] = 666;
271 options[METIS_OPTION_CONTIG] = pList_->get(
"Contiguous",
false);
272 options[METIS_OPTION_MINCONN] = 0;
273 options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_CUT;
275 options[METIS_OPTION_NITER] = 50;
276 options[METIS_OPTION_CCORDER] = 1;
277 idx_t ne = meshUnstr->getNumElementsGlobal();
278 idx_t nn = meshUnstr->getNumGlobalNodes();
279 idx_t ned = meshUnstr->getEdgeElements()->numberElements();
282 int dim = meshUnstr->getDimension();
283 std::string FEType = domains_[meshNumber]->getFEType();
286 vec_idx_Type eptr_vec(0);
287 vec_idx_Type eind_vec(0);
289 makeContinuousElements(elementsMesh, eind_vec, eptr_vec);
291 idx_t *eptr = &eptr_vec.at(0);
292 idx_t *eind = &eind_vec.at(0);
300 else if(FEType==
"P2"){
308 else if(FEType==
"P2"){
313 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Wrong Dimension.");
316 vec_idx_Type epart(ne,-1);
317 vec_idx_Type npart(nn,-1);
321 std::cout <<
"-- Start partitioning with Metis ... " << std::flush;
324 FEDD_TIMER_START(partitionTimer,
" : MeshPartitioner : Partition Elements");
325 idx_t nparts = std::get<1>( rankRanges_[meshNumber] ) - std::get<0>( rankRanges_[meshNumber] ) + 1;
327 int rank = this->comm_->getRank();
329 idx_t returnCode = METIS_PartMeshDual(&ne, &nn, eptr, eind, NULL, NULL, &ncommon, &nparts, NULL, options, &objval, &epart[0], &npart[0]);
331 std::cout <<
"\n--\t Metis return code: " << returnCode;
334 for (
int i=0; i<ne; i++)
340 std::cout <<
"\n--\t objval: " << objval << std::endl;
341 std::cout <<
"-- done!" << std::endl;
345 std::cout <<
"-- Set Elements ... " << std::flush;
347 vec_GO_Type locepart(0);
348 vec_GO_Type pointsRepIndices(0);
350 vec_GO_Type locedpart(0);
353 for (
int i=0; i<ne; i++) {
354 if (epart[i] == comm_->getRank() - std::get<0>( rankRanges_[meshNumber] ) ){
355 locepart.push_back(i);
356 for (
int j=eptr[i]; j<eptr[i+1]; j++)
357 pointsRepIndices.push_back( eind[j] );
361 eind_vec.erase(eind_vec.begin(), eind_vec.end());
362 eptr_vec.erase(eptr_vec.begin(), eptr_vec.end());
365 make_unique(pointsRepIndices);
367 std::cout <<
"done!" << std::endl;
370 Teuchos::ArrayView<GO> pointsRepGlobMapping = Teuchos::arrayViewFromVector( pointsRepIndices );
371 meshUnstr->mapRepeated_.reset(
new Map<LO,GO,NO>(OTGO::invalid(), pointsRepGlobMapping, 0, this->comm_) );
372 MapConstPtr_Type mapRepeated = meshUnstr->mapRepeated_;
375 ElementsPtr_Type elementsGlobal = Teuchos::rcp(
new Elements_Type( *elementsMesh ) );
378 meshUnstr->elementsC_.reset(
new Elements ( FEType, dim ) );
380 Teuchos::ArrayView<GO> elementsGlobalMapping = Teuchos::arrayViewFromVector( locepart );
383 meshUnstr->elementMap_.reset(
new Map<LO,GO,NO>( (GO) -1, elementsGlobalMapping, 0, this->comm_) );
386 int localSurfaceCounter = 0;
387 for (
int i=0; i<locepart.size(); i++) {
388 std::vector<int> tmpElement;
389 for (
int j=eptr[locepart.at(i)]; j<eptr[locepart.at(i)+1]; j++) {
391 int index = mapRepeated->getLocalElement( (
long long) eind[j] );
392 tmpElement.push_back(index);
395 FiniteElement fe( tmpElement, elementsGlobal->getElement( locepart.at(i) ).getFlag() );
398 FiniteElement feGlobalIDs = elementsGlobal->getElement( locepart.at(i) );
399 if (feGlobalIDs.subElementsInitialized()){
400 ElementsPtr_Type subEl = feGlobalIDs.getSubElements();
401 subEl->globalToLocalIDs( mapRepeated );
402 fe.setSubElements( subEl );
405 meshUnstr->elementsC_->addElement( fe );
413 meshUnstr->readMeshEntity(
"node");
416 std::cout <<
"-- Build Repeated Points Volume ... " << std::flush;
419 meshUnstr->mapUnique_ = meshUnstr->mapRepeated_->buildUniqueMap( rankRanges_[meshNumber] );
423 std::cout <<
"-- Building unique & repeated points ... " << std::flush;
425 vec2D_dbl_Type points = *meshUnstr->getPointsRepeated();
426 vec_int_Type flags = *meshUnstr->getBCFlagRepeated();
427 meshUnstr->pointsRep_.reset(
new std::vector<std::vector<double> >( meshUnstr->mapRepeated_->getNodeNumElements(), std::vector<double>(dim,-1.) ) );
428 meshUnstr->bcFlagRep_.reset(
new std::vector<int> ( meshUnstr->mapRepeated_->getNodeNumElements(), 0 ) );
431 for (
int i=0; i<pointsRepIndices.size() ; i++) {
432 pointIDcont = pointsRepIndices.at(i);
433 for (
int j=0; j<dim; j++)
434 meshUnstr->pointsRep_->at(i).at(j) = points[pointIDcont][j];
435 meshUnstr->bcFlagRep_->at(i) = flags[pointIDcont];
440 meshUnstr->pointsUni_.reset(
new std::vector<std::vector<double> >( meshUnstr->mapUnique_->getNodeNumElements(), std::vector<double>(dim,-1.) ) );
441 meshUnstr->bcFlagUni_.reset(
new std::vector<int> ( meshUnstr->mapUnique_->getNodeNumElements(), 0) );
443 MapConstPtr_Type map = meshUnstr->getMapRepeated();
444 vec2D_dbl_ptr_Type pointsRep = meshUnstr->pointsRep_;
445 for (
int i=0; i<meshUnstr->mapUnique_->getNodeNumElements() ; i++) {
446 indexGlobal = meshUnstr->mapUnique_->getGlobalElement(i);
447 for (
int j=0; j<dim; j++) {
448 meshUnstr->pointsUni_->at(i).at(j) = pointsRep->at( map->getLocalElement( indexGlobal) ).at(j);
450 meshUnstr->bcFlagUni_->at(i) = meshUnstr->bcFlagRep_->at( map->getLocalElement( indexGlobal) );
456 elementsGlobal.reset();
458 locepart.erase(locepart.begin(),locepart.end());
460 std::cout <<
"done!" << std::endl;
463 this->setEdgesToSurfaces( meshNumber );
466 meshUnstr->deleteSurfaceElements();
470 std::cout <<
"-- Build edge element list ... " << std::endl << std::flush;
472 buildEdgeListParallel( meshUnstr, elementsGlobal );
475 std::cout << std::endl <<
" done!"<< std::endl;
477 MapConstPtr_Type elementMap = meshUnstr->getElementMap();
479 FEDD_TIMER_START(partitionEdgesTimer,
" : MeshPartitioner : Partition Edges");
480 meshUnstr->getEdgeElements()->partitionEdges( elementMap, mapRepeated );
481 FEDD_TIMER_STOP(partitionEdgesTimer);
484 for(
int i=0; i<meshUnstr->getEdgeElements()->numberElements() ; i++){
485 locedpart.push_back(meshUnstr->getEdgeElements()->getGlobalID((LO) i));
489 Teuchos::ArrayView<GO> edgesGlobalMapping = Teuchos::arrayViewFromVector( locedpart );
490 meshUnstr->edgeMap_.reset(
new Map<LO,GO,NO>( (GO) -1, edgesGlobalMapping, 0, this->comm_) );
495 std::cout <<
"done!" << std::endl;
498 std::cout <<
"-- Partition interface ... " << std::flush;
499 meshUnstr->partitionInterface();
502 std::cout <<
"done!" << std::endl;
509template <
class SC,
class LO,
class GO,
class NO>
511 bool verbose ( comm_->getRank() == 0 );
512 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
513 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
514 MapConstPtr_Type mapRepeated = meshUnstr->mapRepeated_;
516 std::cout <<
"-- Set edges of surfaces of elements ... " << std::flush;
518 FEDD_TIMER_START(surfacesTimer,
" : MeshPartitioner : Set Surfaces of Edge Elements");
519 vec2D_int_Type localEdgeIDPermutation;
522 int volumeID = meshUnstr->volumeID_;
524 ElementsPtr_Type elements = meshUnstr->getElementsC();
525 ElementsPtr_Type edgeElements = meshUnstr->getSurfaceEdgeElements();
529 vec2D_int_Type edgeElements_vec( edgeElements->numberElements() );
530 vec_int_Type edgeElementsFlag_vec( edgeElements->numberElements() );
531 for (
int i=0; i<edgeElements_vec.size(); i++){
532 vec_int_Type edge = edgeElements->getElement(i).getVectorNodeListNonConst();
533 std::sort( edge.begin(), edge.end() );
534 edgeElements_vec.at(i) = edge;
535 edgeElementsFlag_vec.at(i) = edgeElements->getElement(i).getFlag();
538 vec_int_ptr_Type flags = meshUnstr->bcFlagRep_;
539 int elementEdgeSurfaceCounter;
540 for (
int i=0; i<elements->numberElements(); i++) {
541 elementEdgeSurfaceCounter = 0;
543 for (
int j=0; j<elements->getElement( i ).size(); j++) {
544 if ( flags->at( elements->getElement( i ).getNode( j ) ) < volumeID )
545 elementEdgeSurfaceCounter++;
547 if (elementEdgeSurfaceCounter >= meshUnstr->getEdgeElementOrder()){
549 findAndSetSurfaceEdges( edgeElements_vec, edgeElementsFlag_vec, elements->getElement(i), localEdgeIDPermutation, mapRepeated );
553 std::cout <<
"done!" << std::endl;
558template <
class SC,
class LO,
class GO,
class NO>
561 bool verbose ( comm_->getRank() == 0 );
562 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
563 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
566 std::cout <<
"-- Set surfaces of elements ... " << std::flush;
568 FEDD_TIMER_START(surfacesTimer,
" : MeshPartitioner : Set Surfaces of Elements");
570 vec2D_int_Type localSurfaceIDPermutation;
572 setLocalSurfaceIndices( localSurfaceIDPermutation, meshUnstr->getSurfaceElementOrder() );
574 int volumeID = meshUnstr->volumeID_;
575 ElementsPtr_Type surfaceElements = meshUnstr->getSurfaceElements();
582 int size = this->comm_->getSize();
584 LO numSurfaceEl = surfaceElements->numberElements();
598 vec2D_int_Type surfElements_vec( numSurfaceEl );
599 vec2D_int_Type surfElements_vec_sorted( numSurfaceEl );
601 vec_int_Type surfElementsFlag_vec( numSurfaceEl );
602 vec_GO_Type offsetVec(size);
603 int offset = offsetVec[this->comm_->getRank()];
605 for (
int i=0; i<surfElements_vec.size(); i++){
606 vec_int_Type surface = surfaceElements->getElement(i ).getVectorNodeListNonConst();
607 surfElements_vec.at(i) = surface;
608 std::sort( surface.begin(), surface.end() );
609 surfElements_vec_sorted.at(i) = surface;
610 surfElementsFlag_vec.at(i) = surfaceElements->getElement(i).getFlag();
615 surfaceElements.reset();
616 vec_int_ptr_Type flags = meshUnstr->bcFlagRep_;
618 int elementSurfaceCounter;
619 int surfaceElOrder = meshUnstr->getSurfaceElementOrder();
620 for (
int i=0; i<elementsMesh->numberElements(); i++) {
621 elementSurfaceCounter = 0;
622 for (
int j=0; j<elementsMesh->getElement( i ).size(); j++) {
623 if ( flags->at( elementsMesh->getElement( i ).getNode( j ) ) < volumeID )
624 elementSurfaceCounter++;
627 if (elementSurfaceCounter >= surfaceElOrder){
628 FEDD_TIMER_START(findSurfacesTimer,
" : MeshPartitioner : Find and Set Surfaces");
630 this->
findAndSetSurfacesPartitioned( surfElements_vec_sorted, surfElements_vec, surfElementsFlag_vec, elementsMesh->getElement(i), localSurfaceIDPermutation, offsetVec, i );
635 std::cout <<
"done!" << std::endl;
640template <
class SC,
class LO,
class GO,
class NO>
648 int loc, id1Glob, id2Glob, id3Glob;
649 int size = this->comm_->getSize();
650 vec_int_Type locAll(size);
652 for (
int j=0; j<permutation.size(); j++) {
653 id1Glob = element.getNode( permutation.at(j).at(0) ) ;
654 id2Glob = element.getNode( permutation.at(j).at(1) ) ;
656 vec_int_Type tmpSurface(2);
657 if (id1Glob > id2Glob){
658 tmpSurface[0] = id2Glob;
659 tmpSurface[1] = id1Glob;
662 tmpSurface[0] = id1Glob;
663 tmpSurface[1] = id2Glob;
668 Teuchos::gatherAll<int,int>( *this->comm_, 1, &loc, locAll.size(), &locAll[0] );
670 int surfaceRank = -1;
672 while (surfaceRank<0 && counter<size) {
673 if (locAll[counter] > -1)
674 surfaceRank = counter;
679 surfFlag = surfElementsFlag_vec[loc];
681 if (surfaceRank>-1) {
682 Teuchos::broadcast<int,int>(*this->comm_,surfaceRank,1,&loc);
683 Teuchos::broadcast<int,int>(*this->comm_,surfaceRank,1,&surfFlag);
686 if ( !element.subElementsInitialized() )
687 element.initializeSubElements(
"P1", 1 );
689 element.addSubElement( feSurface );
694 for (
int j=0; j<permutation.size(); j++) {
696 id1Glob = element.getNode( permutation.at(j).at(0) ) ;
697 id2Glob = element.getNode( permutation.at(j).at(1) ) ;
698 id3Glob = element.getNode( permutation.at(j).at(2) ) ;
700 vec_int_Type tmpSurface = {id1Glob , id2Glob , id3Glob};
701 sort( tmpSurface.begin(), tmpSurface.end() );
721 int surfFlag = surfElementsFlag_vec[loc];
723 FiniteElement feSurface( surfElements_vec_unsorted[loc], surfFlag);
724 if ( !element.subElementsInitialized() )
725 element.initializeSubElements(
"P1", 2 );
727 element.addSubElement( feSurface );
735template <
class SC,
class LO,
class GO,
class NO>
737 FEDD_TIMER_START(edgeListTimer,
" : MeshReader : Build Edge List");
738 ElementsPtr_Type elements = mesh->getElementsC();
740 TEUCHOS_TEST_FOR_EXCEPTION( elements->getFiniteElementType() !=
"P1", std::runtime_error ,
"Unknown discretization for method buildEdgeList(...).");
741 CommConstPtr_Type comm = mesh->getComm();
742 bool verbose(comm->getRank()==0);
744 MapConstPtr_Type repeatedMap = mesh->getMapRepeated();
746 vec2D_int_Type localEdgeIndices(0);
748 EdgeElementsPtr_Type edges = Teuchos::rcp(
new EdgeElements_Type() );
749 for (
int i=0; i<elementsGlobal->numberElements(); i++) {
750 for (
int j=0; j<localEdgeIndices.size(); j++) {
752 int id1 = elementsGlobal->getElement( i ).getNode( localEdgeIndices[j][0] );
753 int id2 = elementsGlobal->getElement( i ).getNode( localEdgeIndices[j][1] );
754 vec_int_Type edgeVec(2);
765 edges->addEdge( edge, i );
769 elementsGlobal.reset();
771 vec2D_GO_Type combinedEdgeElements;
772 FEDD_TIMER_START(edgeListUniqueTimer,
" : MeshReader : Make Edge List Unique");
773 edges->sortUniqueAndSetGlobalIDs( combinedEdgeElements );
774 FEDD_TIMER_STOP(edgeListUniqueTimer);
777 edges->setElementsEdges( combinedEdgeElements );
779 mesh->setEdgeElements( edges );
783template <
class SC,
class LO,
class GO,
class NO>
786 localEdgeIndices.resize(3,vec_int_Type(2,-1));
787 localEdgeIndices.at(0).at(0) = 0;
788 localEdgeIndices.at(0).at(1) = 1;
789 localEdgeIndices.at(1).at(0) = 0;
790 localEdgeIndices.at(1).at(1) = 2;
791 localEdgeIndices.at(2).at(0) = 1;
792 localEdgeIndices.at(2).at(1) = 2;
794 else if( dim_ == 3) {
795 localEdgeIndices.resize(6,vec_int_Type(2,-1));
796 localEdgeIndices.at(0).at(0) = 0;
797 localEdgeIndices.at(0).at(1) = 1;
798 localEdgeIndices.at(1).at(0) = 0;
799 localEdgeIndices.at(1).at(1) = 2;
800 localEdgeIndices.at(2).at(0) = 1;
801 localEdgeIndices.at(2).at(1) = 2;
802 localEdgeIndices.at(3).at(0) = 0;
803 localEdgeIndices.at(3).at(1) = 3;
804 localEdgeIndices.at(4).at(0) = 1;
805 localEdgeIndices.at(4).at(1) = 3;
806 localEdgeIndices.at(5).at(0) = 2;
807 localEdgeIndices.at(5).at(1) = 3;
812template <
class SC,
class LO,
class GO,
class NO>
813void MeshPartitioner<SC,LO,GO,NO>::makeContinuousElements(ElementsPtr_Type elements, vec_idx_Type& eind_vec, vec_idx_Type& eptr_vec ){
815 int nodesPerElement = elements->nodesPerElement();
818 for (
int i=0; i<elements->numberElements(); i++) {
819 for (
int j=0; j<nodesPerElement; j++) {
820 eind_vec.push_back( elements->getElement( i ).getNode( j ) );
822 eptr_vec.push_back(elcounter);
823 elcounter += nodesPerElement;
825 eptr_vec.push_back(elcounter);
830template <
class SC,
class LO,
class GO,
class NO>
835 if (edgesElementOrder == 2) {
836 localSurfaceEdgeIndices.resize(6,vec_int_Type(2,-1));
837 localSurfaceEdgeIndices.at(0).at(0) = 0;
838 localSurfaceEdgeIndices.at(0).at(1) = 1;
839 localSurfaceEdgeIndices.at(1).at(0) = 0;
840 localSurfaceEdgeIndices.at(1).at(1) = 2;
841 localSurfaceEdgeIndices.at(2).at(0) = 0;
842 localSurfaceEdgeIndices.at(2).at(1) = 3;
843 localSurfaceEdgeIndices.at(3).at(0) = 1;
844 localSurfaceEdgeIndices.at(3).at(1) = 2;
845 localSurfaceEdgeIndices.at(4).at(0) = 1;
846 localSurfaceEdgeIndices.at(4).at(1) = 3;
847 localSurfaceEdgeIndices.at(5).at(0) = 2;
848 localSurfaceEdgeIndices.at(5).at(1) = 3;
853template <
class SC,
class LO,
class GO,
class NO>
856 int loc, id1Glob, id2Glob;
858 for (
int j=0; j<permutation.size(); j++) {
859 id1Glob = mapRepeated->getGlobalElement( element.getNode( permutation.at(j).at(0) ) );
860 id2Glob = mapRepeated->getGlobalElement( element.getNode( permutation.at(j).at(1) ) );
861 vec_int_Type tmpEdge(0);
862 if (id2Glob > id1Glob)
863 tmpEdge = {id1Glob , id2Glob};
865 tmpEdge = {id2Glob , id1Glob};
871 int id1 = element.getNode( permutation.at(j).at(0) );
872 int id2 = element.getNode( permutation.at(j).at(1) );
873 vec_int_Type tmpEdgeLocal(0);
875 tmpEdgeLocal = { id1 , id2 };
877 tmpEdgeLocal = { id2 , id1 };
880 FiniteElement feEdge( tmpEdgeLocal, edgeElementsFlag_vec[loc] );
884 if ( !element.subElementsInitialized() ){
885 element.initializeSubElements(
"P1", 1 );
886 element.addSubElement( feEdge );
889 ElementsPtr_Type surfaces = element.getSubElements();
890 if(surfaces->getDimension() == 2)
891 surfaces->setToCorrectElement( feEdge );
893 element.addSubElement( feEdge );
904template <
class SC,
class LO,
class GO,
class NO>
909 vec2D_int_Type::iterator it = find(surfaces.begin(),surfaces.end(), searchSurface);
911 if (it!=surfaces.end())
912 loc = distance(surfaces.begin(),it);
917template <
class SC,
class LO,
class GO,
class NO>
918void MeshPartitioner<SC,LO,GO,NO>::setLocalSurfaceIndices(vec2D_int_Type &localSurfaceIndices,
int surfaceElementOrder ){
922 if (surfaceElementOrder == 2) {
923 localSurfaceIndices.resize(3,vec_int_Type(3,-1));
924 localSurfaceIndices.at(0).at(0) = 0;
925 localSurfaceIndices.at(0).at(1) = 1;
926 localSurfaceIndices.at(1).at(0) = 0;
927 localSurfaceIndices.at(1).at(1) = 2;
928 localSurfaceIndices.at(2).at(0) = 1;
929 localSurfaceIndices.at(2).at(1) = 2;
932 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"No permutation for this surface yet.");
934 else if ( dim_ == 3 ){
935 if (surfaceElementOrder == 3) {
936 localSurfaceIndices.resize(4,vec_int_Type(3,-1));
937 localSurfaceIndices.at(0).at(0) = 0;
938 localSurfaceIndices.at(0).at(1) = 1;
939 localSurfaceIndices.at(0).at(2) = 2;
940 localSurfaceIndices.at(1).at(0) = 0;
941 localSurfaceIndices.at(1).at(1) = 1;
942 localSurfaceIndices.at(1).at(2) = 3;
943 localSurfaceIndices.at(2).at(0) = 1;
944 localSurfaceIndices.at(2).at(1) = 2;
945 localSurfaceIndices.at(2).at(2) = 3;
946 localSurfaceIndices.at(3).at(0) = 0;
947 localSurfaceIndices.at(3).at(1) = 2;
948 localSurfaceIndices.at(3).at(2) = 3;
951 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"No permutation for this surface yet.");
Definition Elements.hpp:22
Definition FiniteElement.hpp:17
Definition Map_decl.hpp:36
void readAndPartition(int volumeID=10)
Main Function of partitioner. Called with volume ID in order to set in case it is not equal to ten....
Definition MeshPartitioner_def.hpp:41
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:641
int searchInSurfaces(vec2D_int_Type &surfaces, vec_int_Type searchSurface)
Searching on particular surface in a surface list.
Definition MeshPartitioner_def.hpp:905
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:559
void buildEdgeListParallel(MeshUnstrPtr_Type mesh, ElementsPtr_Type elementsGlobal)
Making the edge list parallel.
Definition MeshPartitioner_def.hpp:736
void setEdgesToSurfaces(int meshNumber)
Only used in 3D to set the edges as subelements to surfaces.
Definition MeshPartitioner_def.hpp:510
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:854
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:831
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:784
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5