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 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
237 meshUnstr->readMeshEntity(
"node");
239 meshUnstr->pointsRep_.reset();
241 meshUnstr->readMeshEntity(
"element");
243 meshUnstr->readMeshEntity(
"surface");
245 meshUnstr->readMeshEntity(
"line");
249 bool verbose ( comm_->getRank() == 0 );
250 bool buildEdges = pList_->get(
"Build Edge List",
true);
251 bool buildSurfaces = pList_->get(
"Build Surface List",
true);
255 this->setSurfacesToElements( meshNumber );
257 meshUnstr->deleteSurfaceElements();
260 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
263 idx_t options[METIS_NOPTIONS];
264 METIS_SetDefaultOptions(options);
265 options[METIS_OPTION_NUMBERING] = 0;
266 options[METIS_OPTION_SEED] = 666;
267 options[METIS_OPTION_CONTIG] = pList_->get(
"Contiguous",
false);
268 options[METIS_OPTION_MINCONN] = 0;
269 options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_CUT;
271 options[METIS_OPTION_NITER] = 50;
272 options[METIS_OPTION_CCORDER] = 1;
273 idx_t ne = meshUnstr->getNumElementsGlobal();
274 idx_t nn = meshUnstr->getNumGlobalNodes();
275 idx_t ned = meshUnstr->getEdgeElements()->numberElements();
278 int dim = meshUnstr->getDimension();
279 std::string FEType = domains_[meshNumber]->getFEType();
282 vec_idx_Type eptr_vec(0);
283 vec_idx_Type eind_vec(0);
285 makeContinuousElements(elementsMesh, eind_vec, eptr_vec);
287 idx_t *eptr = &eptr_vec.at(0);
288 idx_t *eind = &eind_vec.at(0);
296 else if(FEType==
"P2"){
304 else if(FEType==
"P2"){
309 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Wrong Dimension.");
312 vec_idx_Type epart(ne,-1);
313 vec_idx_Type npart(nn,-1);
317 std::cout <<
"-- Start partitioning with Metis ... " << std::flush;
320 FEDD_TIMER_START(partitionTimer,
" : MeshPartitioner : Partition Elements");
321 idx_t nparts = std::get<1>( rankRanges_[meshNumber] ) - std::get<0>( rankRanges_[meshNumber] ) + 1;
323 int rank = this->comm_->getRank();
325 idx_t returnCode = METIS_PartMeshDual(&ne, &nn, eptr, eind, NULL, NULL, &ncommon, &nparts, NULL, options, &objval, &epart[0], &npart[0]);
327 std::cout <<
"\n--\t Metis return code: " << returnCode;
330 for (
int i=0; i<ne; i++)
336 std::cout <<
"\n--\t objval: " << objval << std::endl;
337 std::cout <<
"-- done!" << std::endl;
341 std::cout <<
"-- Set Elements ... " << std::flush;
343 vec_GO_Type locepart(0);
344 vec_GO_Type pointsRepIndices(0);
346 vec_GO_Type locedpart(0);
349 for (
int i=0; i<ne; i++) {
350 if (epart[i] == comm_->getRank() - std::get<0>( rankRanges_[meshNumber] ) ){
351 locepart.push_back(i);
352 for (
int j=eptr[i]; j<eptr[i+1]; j++)
353 pointsRepIndices.push_back( eind[j] );
357 eind_vec.erase(eind_vec.begin(), eind_vec.end());
358 eptr_vec.erase(eptr_vec.begin(), eptr_vec.end());
361 make_unique(pointsRepIndices);
363 std::cout <<
"done!" << std::endl;
366 Teuchos::ArrayView<GO> pointsRepGlobMapping = Teuchos::arrayViewFromVector( pointsRepIndices );
367 meshUnstr->mapRepeated_.reset(
new Map<LO,GO,NO>(OTGO::invalid(), pointsRepGlobMapping, 0, this->comm_) );
368 MapConstPtr_Type mapRepeated = meshUnstr->mapRepeated_;
371 ElementsPtr_Type elementsGlobal = Teuchos::rcp(
new Elements_Type( *elementsMesh ) );
374 meshUnstr->elementsC_.reset(
new Elements ( FEType, dim ) );
376 Teuchos::ArrayView<GO> elementsGlobalMapping = Teuchos::arrayViewFromVector( locepart );
379 meshUnstr->elementMap_.reset(
new Map<LO,GO,NO>( (GO) -1, elementsGlobalMapping, 0, this->comm_) );
382 int localSurfaceCounter = 0;
383 for (
int i=0; i<locepart.size(); i++) {
384 std::vector<int> tmpElement;
385 for (
int j=eptr[locepart.at(i)]; j<eptr[locepart.at(i)+1]; j++) {
387 int index = mapRepeated->getLocalElement( (
long long) eind[j] );
388 tmpElement.push_back(index);
391 FiniteElement fe( tmpElement, elementsGlobal->getElement( locepart.at(i) ).getFlag() );
394 FiniteElement feGlobalIDs = elementsGlobal->getElement( locepart.at(i) );
395 if (feGlobalIDs.subElementsInitialized()){
396 ElementsPtr_Type subEl = feGlobalIDs.getSubElements();
397 subEl->globalToLocalIDs( mapRepeated );
398 fe.setSubElements( subEl );
401 meshUnstr->elementsC_->addElement( fe );
409 meshUnstr->readMeshEntity(
"node");
412 std::cout <<
"-- Build Repeated Points Volume ... " << std::flush;
415 meshUnstr->mapUnique_ = meshUnstr->mapRepeated_->buildUniqueMap( rankRanges_[meshNumber] );
419 std::cout <<
"-- Building unique & repeated points ... " << std::flush;
421 vec2D_dbl_Type points = *meshUnstr->getPointsRepeated();
422 vec_int_Type flags = *meshUnstr->getBCFlagRepeated();
423 meshUnstr->pointsRep_.reset(
new std::vector<std::vector<double> >( meshUnstr->mapRepeated_->getNodeNumElements(), std::vector<double>(dim,-1.) ) );
424 meshUnstr->bcFlagRep_.reset(
new std::vector<int> ( meshUnstr->mapRepeated_->getNodeNumElements(), 0 ) );
427 for (
int i=0; i<pointsRepIndices.size() ; i++) {
428 pointIDcont = pointsRepIndices.at(i);
429 for (
int j=0; j<dim; j++)
430 meshUnstr->pointsRep_->at(i).at(j) = points[pointIDcont][j];
431 meshUnstr->bcFlagRep_->at(i) = flags[pointIDcont];
436 meshUnstr->pointsUni_.reset(
new std::vector<std::vector<double> >( meshUnstr->mapUnique_->getNodeNumElements(), std::vector<double>(dim,-1.) ) );
437 meshUnstr->bcFlagUni_.reset(
new std::vector<int> ( meshUnstr->mapUnique_->getNodeNumElements(), 0) );
439 MapConstPtr_Type map = meshUnstr->getMapRepeated();
440 vec2D_dbl_ptr_Type pointsRep = meshUnstr->pointsRep_;
441 for (
int i=0; i<meshUnstr->mapUnique_->getNodeNumElements() ; i++) {
442 indexGlobal = meshUnstr->mapUnique_->getGlobalElement(i);
443 for (
int j=0; j<dim; j++) {
444 meshUnstr->pointsUni_->at(i).at(j) = pointsRep->at( map->getLocalElement( indexGlobal) ).at(j);
446 meshUnstr->bcFlagUni_->at(i) = meshUnstr->bcFlagRep_->at( map->getLocalElement( indexGlobal) );
452 elementsGlobal.reset();
454 locepart.erase(locepart.begin(),locepart.end());
456 std::cout <<
"done!" << std::endl;
459 this->setEdgesToSurfaces( meshNumber );
462 meshUnstr->deleteSurfaceElements();
466 std::cout <<
"-- Build edge element list ... " << std::endl << std::flush;
468 buildEdgeListParallel( meshUnstr, elementsGlobal );
471 std::cout << std::endl <<
" done!"<< std::endl;
473 MapConstPtr_Type elementMap = meshUnstr->getElementMap();
475 FEDD_TIMER_START(partitionEdgesTimer,
" : MeshPartitioner : Partition Edges");
476 meshUnstr->getEdgeElements()->partitionEdges( elementMap, mapRepeated );
477 FEDD_TIMER_STOP(partitionEdgesTimer);
480 for(
int i=0; i<meshUnstr->getEdgeElements()->numberElements() ; i++){
481 locedpart.push_back(meshUnstr->getEdgeElements()->getGlobalID((LO) i));
485 Teuchos::ArrayView<GO> edgesGlobalMapping = Teuchos::arrayViewFromVector( locedpart );
486 meshUnstr->edgeMap_.reset(
new Map<LO,GO,NO>( (GO) -1, edgesGlobalMapping, 0, this->comm_) );
491 std::cout <<
"done!" << std::endl;
494 std::cout <<
"-- Partition interface ... " << std::flush;
495 meshUnstr->partitionInterface();
498 std::cout <<
"done!" << std::endl;
505template <
class SC,
class LO,
class GO,
class NO>
507 bool verbose ( comm_->getRank() == 0 );
508 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
509 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
510 MapConstPtr_Type mapRepeated = meshUnstr->mapRepeated_;
512 std::cout <<
"-- Set edges of surfaces of elements ... " << std::flush;
514 FEDD_TIMER_START(surfacesTimer,
" : MeshPartitioner : Set Surfaces of Edge Elements");
515 vec2D_int_Type localEdgeIDPermutation;
518 int volumeID = meshUnstr->volumeID_;
520 ElementsPtr_Type elements = meshUnstr->getElementsC();
521 ElementsPtr_Type edgeElements = meshUnstr->getSurfaceEdgeElements();
525 vec2D_int_Type edgeElements_vec( edgeElements->numberElements() );
526 vec_int_Type edgeElementsFlag_vec( edgeElements->numberElements() );
527 for (
int i=0; i<edgeElements_vec.size(); i++){
528 vec_int_Type edge = edgeElements->getElement(i).getVectorNodeListNonConst();
529 std::sort( edge.begin(), edge.end() );
530 edgeElements_vec.at(i) = edge;
531 edgeElementsFlag_vec.at(i) = edgeElements->getElement(i).getFlag();
534 vec_int_ptr_Type flags = meshUnstr->bcFlagRep_;
535 int elementEdgeSurfaceCounter;
536 for (
int i=0; i<elements->numberElements(); i++) {
537 elementEdgeSurfaceCounter = 0;
539 for (
int j=0; j<elements->getElement( i ).size(); j++) {
540 if ( flags->at( elements->getElement( i ).getNode( j ) ) < volumeID )
541 elementEdgeSurfaceCounter++;
543 if (elementEdgeSurfaceCounter >= meshUnstr->getEdgeElementOrder()){
545 findAndSetSurfaceEdges( edgeElements_vec, edgeElementsFlag_vec, elements->getElement(i), localEdgeIDPermutation, mapRepeated );
549 std::cout <<
"done!" << std::endl;
554template <
class SC,
class LO,
class GO,
class NO>
557 bool verbose ( comm_->getRank() == 0 );
558 MeshUnstrPtr_Type meshUnstr = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domains_[meshNumber]->getMesh() );
559 ElementsPtr_Type elementsMesh = meshUnstr->getElementsC();
562 std::cout <<
"-- Set surfaces of elements ... " << std::flush;
564 FEDD_TIMER_START(surfacesTimer,
" : MeshPartitioner : Set Surfaces of Elements");
566 vec2D_int_Type localSurfaceIDPermutation;
568 setLocalSurfaceIndices( localSurfaceIDPermutation, meshUnstr->getSurfaceElementOrder() );
570 int volumeID = meshUnstr->volumeID_;
571 ElementsPtr_Type surfaceElements = meshUnstr->getSurfaceElements();
578 int size = this->comm_->getSize();
580 LO numSurfaceEl = surfaceElements->numberElements();
594 vec2D_int_Type surfElements_vec( numSurfaceEl );
595 vec2D_int_Type surfElements_vec_sorted( numSurfaceEl );
597 vec_int_Type surfElementsFlag_vec( numSurfaceEl );
598 vec_GO_Type offsetVec(size);
599 int offset = offsetVec[this->comm_->getRank()];
601 for (
int i=0; i<surfElements_vec.size(); i++){
602 vec_int_Type surface = surfaceElements->getElement(i ).getVectorNodeListNonConst();
603 surfElements_vec.at(i) = surface;
604 std::sort( surface.begin(), surface.end() );
605 surfElements_vec_sorted.at(i) = surface;
606 surfElementsFlag_vec.at(i) = surfaceElements->getElement(i).getFlag();
611 surfaceElements.reset();
612 vec_int_ptr_Type flags = meshUnstr->bcFlagRep_;
614 int elementSurfaceCounter;
615 int surfaceElOrder = meshUnstr->getSurfaceElementOrder();
616 for (
int i=0; i<elementsMesh->numberElements(); i++) {
617 elementSurfaceCounter = 0;
618 for (
int j=0; j<elementsMesh->getElement( i ).size(); j++) {
619 if ( flags->at( elementsMesh->getElement( i ).getNode( j ) ) < volumeID )
620 elementSurfaceCounter++;
623 if (elementSurfaceCounter >= surfaceElOrder){
624 FEDD_TIMER_START(findSurfacesTimer,
" : MeshPartitioner : Find and Set Surfaces");
626 this->
findAndSetSurfacesPartitioned( surfElements_vec_sorted, surfElements_vec, surfElementsFlag_vec, elementsMesh->getElement(i), localSurfaceIDPermutation, offsetVec, i );
631 std::cout <<
"done!" << std::endl;
636template <
class SC,
class LO,
class GO,
class NO>
644 int loc, id1Glob, id2Glob, id3Glob;
645 int size = this->comm_->getSize();
646 vec_int_Type locAll(size);
648 for (
int j=0; j<permutation.size(); j++) {
649 id1Glob = element.getNode( permutation.at(j).at(0) ) ;
650 id2Glob = element.getNode( permutation.at(j).at(1) ) ;
652 vec_int_Type tmpSurface(2);
653 if (id1Glob > id2Glob){
654 tmpSurface[0] = id2Glob;
655 tmpSurface[1] = id1Glob;
658 tmpSurface[0] = id1Glob;
659 tmpSurface[1] = id2Glob;
664 Teuchos::gatherAll<int,int>( *this->comm_, 1, &loc, locAll.size(), &locAll[0] );
666 int surfaceRank = -1;
668 while (surfaceRank<0 && counter<size) {
669 if (locAll[counter] > -1)
670 surfaceRank = counter;
675 surfFlag = surfElementsFlag_vec[loc];
677 if (surfaceRank>-1) {
678 Teuchos::broadcast<int,int>(*this->comm_,surfaceRank,1,&loc);
679 Teuchos::broadcast<int,int>(*this->comm_,surfaceRank,1,&surfFlag);
682 if ( !element.subElementsInitialized() )
683 element.initializeSubElements(
"P1", 1 );
685 element.addSubElement( feSurface );
690 for (
int j=0; j<permutation.size(); j++) {
692 id1Glob = element.getNode( permutation.at(j).at(0) ) ;
693 id2Glob = element.getNode( permutation.at(j).at(1) ) ;
694 id3Glob = element.getNode( permutation.at(j).at(2) ) ;
696 vec_int_Type tmpSurface = {id1Glob , id2Glob , id3Glob};
697 sort( tmpSurface.begin(), tmpSurface.end() );
717 int surfFlag = surfElementsFlag_vec[loc];
719 FiniteElement feSurface( surfElements_vec_unsorted[loc], surfFlag);
720 if ( !element.subElementsInitialized() )
721 element.initializeSubElements(
"P1", 2 );
723 element.addSubElement( feSurface );
731template <
class SC,
class LO,
class GO,
class NO>
733 FEDD_TIMER_START(edgeListTimer,
" : MeshReader : Build Edge List");
734 ElementsPtr_Type elements = mesh->getElementsC();
736 TEUCHOS_TEST_FOR_EXCEPTION( elements->getFiniteElementType() !=
"P1", std::runtime_error ,
"Unknown discretization for method buildEdgeList(...).");
737 CommConstPtr_Type comm = mesh->getComm();
738 bool verbose(comm->getRank()==0);
740 MapConstPtr_Type repeatedMap = mesh->getMapRepeated();
742 vec2D_int_Type localEdgeIndices(0);
744 EdgeElementsPtr_Type edges = Teuchos::rcp(
new EdgeElements_Type() );
745 for (
int i=0; i<elementsGlobal->numberElements(); i++) {
746 for (
int j=0; j<localEdgeIndices.size(); j++) {
748 int id1 = elementsGlobal->getElement( i ).getNode( localEdgeIndices[j][0] );
749 int id2 = elementsGlobal->getElement( i ).getNode( localEdgeIndices[j][1] );
750 vec_int_Type edgeVec(2);
761 edges->addEdge( edge, i );
765 elementsGlobal.reset();
767 vec2D_GO_Type combinedEdgeElements;
768 FEDD_TIMER_START(edgeListUniqueTimer,
" : MeshReader : Make Edge List Unique");
769 edges->sortUniqueAndSetGlobalIDs( combinedEdgeElements );
770 FEDD_TIMER_STOP(edgeListUniqueTimer);
773 edges->setElementsEdges( combinedEdgeElements );
775 mesh->setEdgeElements( edges );
779template <
class SC,
class LO,
class GO,
class NO>
782 localEdgeIndices.resize(3,vec_int_Type(2,-1));
783 localEdgeIndices.at(0).at(0) = 0;
784 localEdgeIndices.at(0).at(1) = 1;
785 localEdgeIndices.at(1).at(0) = 0;
786 localEdgeIndices.at(1).at(1) = 2;
787 localEdgeIndices.at(2).at(0) = 1;
788 localEdgeIndices.at(2).at(1) = 2;
790 else if( dim_ == 3) {
791 localEdgeIndices.resize(6,vec_int_Type(2,-1));
792 localEdgeIndices.at(0).at(0) = 0;
793 localEdgeIndices.at(0).at(1) = 1;
794 localEdgeIndices.at(1).at(0) = 0;
795 localEdgeIndices.at(1).at(1) = 2;
796 localEdgeIndices.at(2).at(0) = 1;
797 localEdgeIndices.at(2).at(1) = 2;
798 localEdgeIndices.at(3).at(0) = 0;
799 localEdgeIndices.at(3).at(1) = 3;
800 localEdgeIndices.at(4).at(0) = 1;
801 localEdgeIndices.at(4).at(1) = 3;
802 localEdgeIndices.at(5).at(0) = 2;
803 localEdgeIndices.at(5).at(1) = 3;
808template <
class SC,
class LO,
class GO,
class NO>
809void MeshPartitioner<SC,LO,GO,NO>::makeContinuousElements(ElementsPtr_Type elements, vec_idx_Type& eind_vec, vec_idx_Type& eptr_vec ){
811 int nodesPerElement = elements->nodesPerElement();
814 for (
int i=0; i<elements->numberElements(); i++) {
815 for (
int j=0; j<nodesPerElement; j++) {
816 eind_vec.push_back( elements->getElement( i ).getNode( j ) );
818 eptr_vec.push_back(elcounter);
819 elcounter += nodesPerElement;
821 eptr_vec.push_back(elcounter);
826template <
class SC,
class LO,
class GO,
class NO>
831 if (edgesElementOrder == 2) {
832 localSurfaceEdgeIndices.resize(6,vec_int_Type(2,-1));
833 localSurfaceEdgeIndices.at(0).at(0) = 0;
834 localSurfaceEdgeIndices.at(0).at(1) = 1;
835 localSurfaceEdgeIndices.at(1).at(0) = 0;
836 localSurfaceEdgeIndices.at(1).at(1) = 2;
837 localSurfaceEdgeIndices.at(2).at(0) = 0;
838 localSurfaceEdgeIndices.at(2).at(1) = 3;
839 localSurfaceEdgeIndices.at(3).at(0) = 1;
840 localSurfaceEdgeIndices.at(3).at(1) = 2;
841 localSurfaceEdgeIndices.at(4).at(0) = 1;
842 localSurfaceEdgeIndices.at(4).at(1) = 3;
843 localSurfaceEdgeIndices.at(5).at(0) = 2;
844 localSurfaceEdgeIndices.at(5).at(1) = 3;
849template <
class SC,
class LO,
class GO,
class NO>
852 int loc, id1Glob, id2Glob;
854 for (
int j=0; j<permutation.size(); j++) {
855 id1Glob = mapRepeated->getGlobalElement( element.getNode( permutation.at(j).at(0) ) );
856 id2Glob = mapRepeated->getGlobalElement( element.getNode( permutation.at(j).at(1) ) );
857 vec_int_Type tmpEdge(0);
858 if (id2Glob > id1Glob)
859 tmpEdge = {id1Glob , id2Glob};
861 tmpEdge = {id2Glob , id1Glob};
867 int id1 = element.getNode( permutation.at(j).at(0) );
868 int id2 = element.getNode( permutation.at(j).at(1) );
869 vec_int_Type tmpEdgeLocal(0);
871 tmpEdgeLocal = { id1 , id2 };
873 tmpEdgeLocal = { id2 , id1 };
876 FiniteElement feEdge( tmpEdgeLocal, edgeElementsFlag_vec[loc] );
880 if ( !element.subElementsInitialized() ){
881 element.initializeSubElements(
"P1", 1 );
882 element.addSubElement( feEdge );
885 ElementsPtr_Type surfaces = element.getSubElements();
886 if(surfaces->getDimension() == 2)
887 surfaces->setToCorrectElement( feEdge );
889 element.addSubElement( feEdge );
900template <
class SC,
class LO,
class GO,
class NO>
905 vec2D_int_Type::iterator it = find(surfaces.begin(),surfaces.end(), searchSurface);
907 if (it!=surfaces.end())
908 loc = distance(surfaces.begin(),it);
913template <
class SC,
class LO,
class GO,
class NO>
914void MeshPartitioner<SC,LO,GO,NO>::setLocalSurfaceIndices(vec2D_int_Type &localSurfaceIndices,
int surfaceElementOrder ){
918 if (surfaceElementOrder == 2) {
919 localSurfaceIndices.resize(3,vec_int_Type(3,-1));
920 localSurfaceIndices.at(0).at(0) = 0;
921 localSurfaceIndices.at(0).at(1) = 1;
922 localSurfaceIndices.at(1).at(0) = 0;
923 localSurfaceIndices.at(1).at(1) = 2;
924 localSurfaceIndices.at(2).at(0) = 1;
925 localSurfaceIndices.at(2).at(1) = 2;
928 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"No permutation for this surface yet.");
930 else if ( dim_ == 3 ){
931 if (surfaceElementOrder == 3) {
932 localSurfaceIndices.resize(4,vec_int_Type(3,-1));
933 localSurfaceIndices.at(0).at(0) = 0;
934 localSurfaceIndices.at(0).at(1) = 1;
935 localSurfaceIndices.at(0).at(2) = 2;
936 localSurfaceIndices.at(1).at(0) = 0;
937 localSurfaceIndices.at(1).at(1) = 1;
938 localSurfaceIndices.at(1).at(2) = 3;
939 localSurfaceIndices.at(2).at(0) = 1;
940 localSurfaceIndices.at(2).at(1) = 2;
941 localSurfaceIndices.at(2).at(2) = 3;
942 localSurfaceIndices.at(3).at(0) = 0;
943 localSurfaceIndices.at(3).at(1) = 2;
944 localSurfaceIndices.at(3).at(2) = 3;
947 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:637
int searchInSurfaces(vec2D_int_Type &surfaces, vec_int_Type searchSurface)
Searching on particular surface in a surface list.
Definition MeshPartitioner_def.hpp:901
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:555
void buildEdgeListParallel(MeshUnstrPtr_Type mesh, ElementsPtr_Type elementsGlobal)
Making the edge list parallel.
Definition MeshPartitioner_def.hpp:732
void setEdgesToSurfaces(int meshNumber)
Only used in 3D to set the edges as subelements to surfaces.
Definition MeshPartitioner_def.hpp:506
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:850
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:827
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:780
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:33