Nektar++
Classes | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | List of all members
Nektar::SpatialDomains::MeshPartition Class Referenceabstract

#include <MeshPartition.h>

Inheritance diagram for Nektar::SpatialDomains::MeshPartition:
[legend]

Classes

struct  GraphEdgeProperties
 
struct  GraphVertexProperties
 

Public Member Functions

 MeshPartition (const LibUtilities::SessionReaderSharedPtr session, int meshDim, std::map< int, MeshEntity > element, CompositeDescriptor compMap)
 
virtual ~MeshPartition ()
 
void PartitionMesh (int nParts, bool shared=false, bool overlapping=false, int nLocal=0)
 
void PrintPartInfo (std::ostream &out)
 
void GetElementIDs (const int procid, std::vector< unsigned int > &tmp)
 

Protected Types

typedef std::vector< unsigned int > MultiWeight
 
typedef boost::adjacency_list< boost::setS, boost::vecS, boost::undirectedS, GraphVertexProperties, boost::property< boost::edge_index_t, unsigned int, GraphEdgeProperties > > BoostGraph
 
typedef boost::graph_traits< BoostGraph >::vertex_descriptor BoostVertex
 
typedef boost::graph_traits< BoostGraph >::edge_descriptor BoostEdge
 
typedef boost::graph_traits< BoostGraph >::edge_iterator BoostEdgeIterator
 
typedef boost::graph_traits< BoostGraph >::vertex_iterator BoostVertexIterator
 
typedef boost::graph_traits< BoostGraph >::adjacency_iterator BoostAdjacencyIterator
 
typedef std::vector< unsigned int > NumModes
 
typedef std::map< std::string, NumModesNummodesPerField
 

Protected Member Functions

void ReadExpansions ()
 
void ReadConditions ()
 
void WeightElements ()
 
void CreateGraph ()
 
void PartitionGraph (int nParts, bool overlapping=false)
 Partition the graph. More...
 
virtual void PartitionGraphImpl (int &nVerts, int &nVertConds, Nektar::Array< Nektar::OneD, int > &xadj, Nektar::Array< Nektar::OneD, int > &adjcy, Nektar::Array< Nektar::OneD, int > &vertWgt, Nektar::Array< Nektar::OneD, int > &vertSize, Nektar::Array< Nektar::OneD, int > &edgeWgt, int &nparts, int &volume, Nektar::Array< Nektar::OneD, int > &part)=0
 
void CheckPartitions (int nParts, Array< OneD, int > &pPart)
 
int CalculateElementWeight (LibUtilities::ShapeType elmtType, bool bndWeight, int na, int nb, int nc)
 
int CalculateEdgeWeight (LibUtilities::ShapeType elmtType, int na, int nb, int nc)
 

Protected Attributes

LibUtilities::SessionReaderSharedPtr m_session
 
int m_dim
 
int m_numFields
 
std::map< int, MeshEntitym_elements
 
std::map< int, MeshEntitym_ghostElmts
 
CompositeDescriptor m_compMap
 
std::map< int, NummodesPerFieldm_expansions
 
std::map< int, LibUtilities::ShapeTypem_shape
 
std::map< std::string, int > m_fieldNameToId
 
std::map< int, MultiWeightm_vertWeights
 
std::map< int, MultiWeightm_vertBndWeights
 
std::map< int, MultiWeightm_edgeWeights
 
BoostGraph m_graph
 
std::vector< std::vector< unsigned int > > m_localPartition
 
LibUtilities::CommSharedPtr m_comm
 
bool m_weightingRequired
 
bool m_weightBnd
 
bool m_weightDofs
 
bool m_shared
 
bool m_parallel
 

Detailed Description

Definition at line 66 of file MeshPartition.h.

Member Typedef Documentation

◆ BoostAdjacencyIterator

typedef boost::graph_traits<BoostGraph>::adjacency_iterator Nektar::SpatialDomains::MeshPartition::BoostAdjacencyIterator
protected

Definition at line 121 of file MeshPartition.h.

◆ BoostEdge

typedef boost::graph_traits<BoostGraph>::edge_descriptor Nektar::SpatialDomains::MeshPartition::BoostEdge
protected

Definition at line 116 of file MeshPartition.h.

◆ BoostEdgeIterator

typedef boost::graph_traits<BoostGraph>::edge_iterator Nektar::SpatialDomains::MeshPartition::BoostEdgeIterator
protected

Definition at line 117 of file MeshPartition.h.

◆ BoostGraph

typedef boost::adjacency_list< boost::setS, boost::vecS, boost::undirectedS, GraphVertexProperties, boost::property<boost::edge_index_t, unsigned int, GraphEdgeProperties> > Nektar::SpatialDomains::MeshPartition::BoostGraph
protected

Definition at line 113 of file MeshPartition.h.

◆ BoostVertex

typedef boost::graph_traits<BoostGraph>::vertex_descriptor Nektar::SpatialDomains::MeshPartition::BoostVertex
protected

Definition at line 115 of file MeshPartition.h.

◆ BoostVertexIterator

typedef boost::graph_traits<BoostGraph>::vertex_iterator Nektar::SpatialDomains::MeshPartition::BoostVertexIterator
protected

Definition at line 119 of file MeshPartition.h.

◆ MultiWeight

typedef std::vector<unsigned int> Nektar::SpatialDomains::MeshPartition::MultiWeight
protected

Definition at line 89 of file MeshPartition.h.

◆ NumModes

typedef std::vector<unsigned int> Nektar::SpatialDomains::MeshPartition::NumModes
protected

Definition at line 123 of file MeshPartition.h.

◆ NummodesPerField

typedef std::map<std::string, NumModes> Nektar::SpatialDomains::MeshPartition::NummodesPerField
protected

Definition at line 124 of file MeshPartition.h.

Constructor & Destructor Documentation

◆ MeshPartition()

Nektar::SpatialDomains::MeshPartition::MeshPartition ( const LibUtilities::SessionReaderSharedPtr  session,
int  meshDim,
std::map< int, MeshEntity element,
CompositeDescriptor  compMap 
)

Definition at line 76 of file MeshPartition.cpp.

References m_elements, m_ghostElmts, ReadConditions(), and ReadExpansions().

80  : m_session(session), m_dim(meshDim), m_numFields(0), m_elements(element),
81  m_compMap(compMap), m_fieldNameToId(), m_comm(session->GetComm()),
82  m_weightingRequired(false), m_weightBnd(false), m_weightDofs(false),
83  m_parallel(false)
84 {
85  // leave the meshpartition method of reading expansions and conditions
88 
89  for (auto elIt = m_elements.cbegin(); elIt != m_elements.cend();)
90  {
91  if (elIt->second.ghost)
92  {
93  m_ghostElmts[elIt->first] = elIt->second;
94  elIt = m_elements.erase(elIt);
95  }
96  else
97  {
98  ++elIt;
99  }
100  }
101 }
LibUtilities::CommSharedPtr m_comm
std::map< int, MeshEntity > m_ghostElmts
LibUtilities::SessionReaderSharedPtr m_session
std::map< int, MeshEntity > m_elements
std::map< std::string, int > m_fieldNameToId

◆ ~MeshPartition()

Nektar::SpatialDomains::MeshPartition::~MeshPartition ( )
virtual

Definition at line 103 of file MeshPartition.cpp.

104 {
105 }

Member Function Documentation

◆ CalculateEdgeWeight()

int Nektar::SpatialDomains::MeshPartition::CalculateEdgeWeight ( LibUtilities::ShapeType  elmtType,
int  na,
int  nb,
int  nc 
)
protected

Calculate the number of modes needed for communication when in partition boundary, to be used as weighting for edges. Since we do not know exactly which face this refers to, assume the max order and quad face (for prisms) as arbitrary choices

Definition at line 934 of file MeshPartition.cpp.

References Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::LibUtilities::StdTriData::getNumberOfCoefficients(), and Nektar::LibUtilities::StdQuadData::getNumberOfCoefficients().

Referenced by WeightElements().

936 {
937  int weight = 0;
938  int n = std::max(na, std::max(nb, nc));
939  switch (elmtType)
940  {
943  break;
946  break;
949  break;
952  break;
955  weight = n;
956  break;
958  weight = 1;
959  break;
960  default:
961  break;
962  }
963 
964  return weight;
965 }
int getNumberOfCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:113
int getNumberOfCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:137

◆ CalculateElementWeight()

int Nektar::SpatialDomains::MeshPartition::CalculateElementWeight ( LibUtilities::ShapeType  elmtType,
bool  bndWeight,
int  na,
int  nb,
int  nc 
)
protected

Definition at line 860 of file MeshPartition.cpp.

References Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::ePoint, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::LibUtilities::StdSegData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdTriData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdQuadData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdHexData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdTetData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdPyrData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdPrismData::getNumberOfBndCoefficients(), Nektar::LibUtilities::StdSegData::getNumberOfCoefficients(), Nektar::LibUtilities::StdTriData::getNumberOfCoefficients(), Nektar::LibUtilities::StdQuadData::getNumberOfCoefficients(), Nektar::LibUtilities::StdHexData::getNumberOfCoefficients(), Nektar::LibUtilities::StdTetData::getNumberOfCoefficients(), Nektar::LibUtilities::StdPyrData::getNumberOfCoefficients(), and Nektar::LibUtilities::StdPrismData::getNumberOfCoefficients().

Referenced by PrintPartInfo(), and WeightElements().

863 {
864  int weight = 0;
865 
866  switch (elmtType)
867  {
869  weight = bndWeight
871  na, nb, nc)
872  : LibUtilities::StdTetData::getNumberOfCoefficients(
873  na, nb, nc);
874  break;
876  weight =
877  bndWeight
879  na, nb, nc)
880  : LibUtilities::StdPrismData::getNumberOfCoefficients(
881  na, nb, nc);
882  break;
884  weight = bndWeight
886  na, nb, nc)
887  : LibUtilities::StdHexData::getNumberOfCoefficients(
888  na, nb, nc);
889  break;
891  weight = bndWeight
893  na, nb, nc)
894  : LibUtilities::StdPyrData::getNumberOfCoefficients(
895  na, nb, nc);
896  break;
898  weight =
899  bndWeight
901  nb)
902  : LibUtilities::StdQuadData::getNumberOfCoefficients(na,
903  nb);
904  break;
906  weight =
907  bndWeight
909  nb)
910  : LibUtilities::StdTriData::getNumberOfCoefficients(na, nb);
911  break;
913  weight =
914  bndWeight
916  : LibUtilities::StdSegData::getNumberOfCoefficients(na);
917  break;
919  weight = 1;
920  break;
921  default:
922  break;
923  }
924 
925  return weight;
926 }
int getNumberOfBndCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:125
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:167
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:267
int getNumberOfBndCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:147
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:298
int getNumberOfBndCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:217

◆ CheckPartitions()

void Nektar::SpatialDomains::MeshPartition::CheckPartitions ( int  nParts,
Array< OneD, int > &  pPart 
)
protected

Definition at line 817 of file MeshPartition.cpp.

Referenced by PartitionGraph().

818 {
819  unsigned int i = 0;
820  unsigned int cnt = 0;
821  bool valid = true;
822 
823  // Check that every process has at least one element assigned
824  for (i = 0; i < nParts; ++i)
825  {
826  cnt = std::count(pPart.begin(), pPart.end(), i);
827  if (cnt == 0)
828  {
829  valid = false;
830  }
831  }
832 
833  // If the graph partitioner produced an invalid partition, repartition
834  // naively. Elements are assigned to processes in a round-robin fashion.
835  // It is assumed that graph partitioner failure only occurs when the number
836  // of elements is approx. the number of processes, so this approach should
837  // not be too inefficient communication-wise.
838  if (!valid)
839  {
840  for (i = 0; i < pPart.num_elements(); ++i)
841  {
842  pPart[i] = i % nParts;
843  }
844  }
845 }

◆ CreateGraph()

void Nektar::SpatialDomains::MeshPartition::CreateGraph ( )
protected

Definition at line 510 of file MeshPartition.cpp.

References m_edgeWeights, m_elements, m_ghostElmts, m_graph, m_vertBndWeights, m_vertWeights, and m_weightingRequired.

Referenced by PartitionMesh().

511 {
512  // Maps edge/face to first mesh element id.
513  // On locating second mesh element id, graph edge is created instead.
514  std::unordered_map<int, int> vGraphEdges;
515  int vcnt = 0;
516 
517  for (auto &elmt : m_elements)
518  {
519  auto vert = boost::add_vertex(m_graph);
520  m_graph[vert].id = elmt.first;
521  m_graph[vert].partition = 0;
522 
524  {
525  m_graph[vert].weight = m_vertWeights[elmt.second.origId];
526  m_graph[vert].bndWeight = m_vertBndWeights[elmt.second.origId];
527  m_graph[vert].edgeWeight = m_edgeWeights[elmt.second.origId];
528  }
529 
530  // Process element entries and add graph edges
531  for (auto &eId : elmt.second.list)
532  {
533  // Look to see if we've examined this edge/face before
534  // If so, we've got both graph vertices so add edge
535  auto edgeIt = vGraphEdges.find(eId);
536  if (edgeIt != vGraphEdges.end())
537  {
538  BoostEdge e =
539  boost::add_edge(vcnt, edgeIt->second, m_graph).first;
540  m_graph[e].id = vcnt;
541  }
542  else
543  {
544  vGraphEdges[eId] = vcnt;
545  }
546  }
547 
548  // Increment counter for graph vertex id.
549  ++vcnt;
550  }
551 
552  // Now process ghost elements.
553  for (auto &ghost : m_ghostElmts)
554  {
555  auto vert = boost::add_vertex(m_graph);
556  m_graph[vert].id = ghost.first;
557  m_graph[vert].partition = -1;
558 
559  for (auto &facet : ghost.second.list)
560  {
561  auto edgeIt = vGraphEdges.find(facet);
562  if (edgeIt != vGraphEdges.end())
563  {
564  BoostEdge e =
565  boost::add_edge(vcnt, edgeIt->second, m_graph).first;
566  m_graph[e].id = vcnt;
567  }
568  }
569 
570  // Increment counter for graph vertex id.
571  ++vcnt;
572  }
573 }
std::map< int, MultiWeight > m_vertWeights
std::map< int, MeshEntity > m_ghostElmts
std::map< int, MultiWeight > m_vertBndWeights
std::map< int, MultiWeight > m_edgeWeights
std::map< int, MeshEntity > m_elements
boost::graph_traits< BoostGraph >::edge_descriptor BoostEdge

◆ GetElementIDs()

void Nektar::SpatialDomains::MeshPartition::GetElementIDs ( const int  procid,
std::vector< unsigned int > &  tmp 
)

Definition at line 847 of file MeshPartition.cpp.

References ASSERTL0, m_comm, m_localPartition, and m_parallel.

849 {
850  BoostVertexIterator vertit, vertit_end;
851 
852  ASSERTL0(procid < m_localPartition.size(),
853  "procid is less than the number of partitions");
854  ASSERTL0((m_parallel && procid == m_comm->GetRank()) || !m_parallel,
855  "Can only get this rank's processor IDs in parallel");
856 
857  elmtid = m_localPartition[procid];
858 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
LibUtilities::CommSharedPtr m_comm
boost::graph_traits< BoostGraph >::vertex_iterator BoostVertexIterator
std::vector< std::vector< unsigned int > > m_localPartition

◆ PartitionGraph()

void Nektar::SpatialDomains::MeshPartition::PartitionGraph ( int  nParts,
bool  overlapping = false 
)
protected

Partition the graph.

This routine partitions the graph pGraph into nParts, producing subgraphs that are populated in pLocalPartition. If the overlapping option is set (which is used for post-processing purposes), the resulting partitions are extended to cover neighbouring elements by additional vertex on the dual graph, which produces overlapping partitions (i.e. the intersection of two connected partitions is non-empty).

Parameters
nPartsNumber of partitions.
pLocalPartitionVector of sub-graphs representing each
overlappingTrue if resulting partitions should overlap.

Definition at line 590 of file MeshPartition.cpp.

References ASSERTL0, CheckPartitions(), Nektar::ErrorUtil::efatal, m_comm, m_ghostElmts, m_graph, m_localPartition, m_parallel, m_shared, m_weightBnd, m_weightDofs, m_weightingRequired, NEKERROR, PartitionGraphImpl(), and Vmath::Vsum().

Referenced by PartitionMesh().

591 {
592  int i;
593  int nGraphVerts = boost::num_vertices(m_graph);
594  int nGhost = m_ghostElmts.size();
595  int nLocal = nGraphVerts - nGhost;
596 
597  int ncon = 1;
598  if (m_weightDofs && m_weightBnd)
599  {
600  ncon = 2;
601  }
602  // Convert boost graph into CSR format
603  BoostVertexIterator vertit, vertit_end;
604  BoostAdjacencyIterator adjvertit, adjvertit_end;
605  Array<OneD, int> part(nGraphVerts, 0);
606 
607  if (m_comm->GetRowComm()->TreatAsRankZero() || m_parallel)
608  {
609  int acnt = 0;
610  int vcnt = 0;
611  int nWeight = ncon * nLocal;
612 
613  Array<OneD, int> xadj(nLocal + 1);
614  std::vector<int> adjncy_tmp, adjwgt_tmp;
615  Array<OneD, int> vwgt(nWeight, 1);
616  Array<OneD, int> vsize(nLocal, 1);
617 
618  // Initialise starting point of adjacency array.
619  xadj[0] = 0;
620 
621  for (boost::tie(vertit, vertit_end) = boost::vertices(m_graph);
622  vertit != vertit_end && vcnt < nLocal; ++vertit)
623  {
624  for (boost::tie(adjvertit, adjvertit_end) =
625  boost::adjacent_vertices(*vertit, m_graph);
626  adjvertit != adjvertit_end; ++adjvertit, ++acnt)
627  {
628  adjncy_tmp.push_back(m_graph[*adjvertit].id);
630  {
631  adjwgt_tmp.push_back(m_graph[*vertit].edgeWeight[0]);
632  }
633  else
634  {
635  adjwgt_tmp.push_back(1);
636  }
637  }
638 
639  xadj[++vcnt] = acnt;
640 
642  {
643  int ccnt = 0;
644  if (m_weightDofs)
645  {
646  vwgt[ncon * (vcnt - 1) + ccnt] = m_graph[*vertit].weight[0];
647  ccnt++;
648  }
649  if (m_weightBnd)
650  {
651  vwgt[ncon * (vcnt - 1) + ccnt] =
652  m_graph[*vertit].bndWeight[0];
653  }
654  }
655  }
656 
657  Array<OneD, int> adjncy(adjncy_tmp.size(), &adjncy_tmp[0]);
658  Array<OneD, int> adjwgt(adjwgt_tmp.size(), &adjwgt_tmp[0]);
659 
660  // Call partitioner to partition graph
661  int vol = 0;
662 
663  try
664  {
665  //////////////////////////////////////////////////////
666  // On a cartesian communicator do mesh partiotion just on the first
667  // column
668  // so there is no doubt the partitions are all the same in all the
669  // columns
670  if (m_comm->GetColumnComm()->GetRank() == 0)
671  {
672  // Attempt partitioning.
673  PartitionGraphImpl(nLocal, ncon, xadj, adjncy, vwgt, vsize,
674  adjwgt, nParts, vol, part);
675 
676  // Check the partitioner produced a valid partition and fix if
677  // not.
678  if (!m_parallel)
679  {
680  CheckPartitions(nParts, part);
681  }
682 
683  if (!m_shared)
684  {
685  // distribute among columns
686  for (i = 1; i < m_comm->GetColumnComm()->GetSize(); ++i)
687  {
688  m_comm->GetColumnComm()->Send(i, part);
689  }
690  }
691  }
692  else
693  {
694  m_comm->GetColumnComm()->Recv(0, part);
695  }
696 
697  if (!m_shared && !m_parallel)
698  {
699  m_comm->GetColumnComm()->Block();
700 
701  //////////////////////////////////
702  // distribute among rows
703  for (i = 1; i < m_comm->GetRowComm()->GetSize(); ++i)
704  {
705  m_comm->GetRowComm()->Send(i, part);
706  }
707  }
708  }
709  catch (...)
710  {
712  "Error in calling graph partitioner.");
713  }
714  }
715  else
716  {
717  m_comm->GetRowComm()->Recv(0, part);
718  }
719 
720  // Create storage for this (and possibly other) process's partitions.
721  m_localPartition.resize(nParts);
722 
723  i = 0;
724 
725  // Populate subgraph(s)
726  if (!m_parallel)
727  {
728  for (boost::tie(vertit, vertit_end) = boost::vertices(m_graph);
729  vertit != vertit_end; ++vertit, ++i)
730  {
731  m_localPartition[part[i]].push_back(m_graph[*vertit].id);
732  }
733  }
734  else
735  {
736  // Figure out how many vertices we're going to get from each processor.
737  int nproc = m_comm->GetSize();
738  std::vector<int> numToSend(nproc, 0), numToRecv(nproc);
739  std::map<int, std::vector<int>> procMap;
740 
741  for (boost::tie(vertit, vertit_end) = boost::vertices(m_graph);
742  vertit != vertit_end && i < nLocal; ++vertit, ++i)
743  {
744  int toProc = part[i];
745  numToSend[toProc]++;
746  procMap[toProc].push_back(m_graph[*vertit].id);
747  }
748 
749  m_comm->AlltoAll(numToSend, numToRecv);
750 
751  // Build offsets for all-to-all communication
752  std::vector<int> sendOffsetMap(nproc), recvOffsetMap(nproc);
753 
754  sendOffsetMap[0] = 0;
755  recvOffsetMap[0] = 0;
756  for (int i = 1; i < nproc; ++i)
757  {
758  sendOffsetMap[i] = sendOffsetMap[i-1] + numToSend[i-1];
759  recvOffsetMap[i] = recvOffsetMap[i-1] + numToRecv[i-1];
760  }
761 
762  // Build data to send
763  int totalSend = Vmath::Vsum(nproc, &numToSend[0], 1);
764  int totalRecv = Vmath::Vsum(nproc, &numToRecv[0], 1);
765 
766  std::vector<int> sendData(totalSend), recvData(totalRecv);
767 
768  int cnt = 0;
769  for (auto &verts : procMap)
770  {
771  for (auto &vert : verts.second)
772  {
773  sendData[cnt++] = vert;
774  }
775  }
776 
777  // Send ID map to processors
778  m_comm->AlltoAllv(sendData, numToSend, sendOffsetMap,
779  recvData, numToRecv, recvOffsetMap);
780 
781  // Finally, populate m_localPartition for this processor. Could contain
782  // duplicates so erase those first.
783  std::unordered_set<int> uniqueIDs;
784  for (auto &id : recvData)
785  {
786  uniqueIDs.insert(id);
787  }
788  m_localPartition[m_comm->GetRank()].insert(
789  m_localPartition[m_comm->GetRank()].begin(),
790  uniqueIDs.begin(), uniqueIDs.end());
791  }
792 
793  // If the overlapping option is set (for post-processing purposes),
794  // add vertices that correspond to the neighbouring elements.
795  if (overlapping)
796  {
797  ASSERTL0(!m_parallel, "Overlapping partitioning not supported in "
798  "parallel execution");
799 
800  for (boost::tie(vertit, vertit_end) = boost::vertices(m_graph);
801  vertit != vertit_end; ++vertit)
802  {
803  for (boost::tie(adjvertit, adjvertit_end) =
804  boost::adjacent_vertices(*vertit, m_graph);
805  adjvertit != adjvertit_end; ++adjvertit)
806  {
807  if (part[*adjvertit] != part[*vertit])
808  {
809  m_localPartition[part[*vertit]].push_back(
810  m_graph[*adjvertit].id);
811  }
812  }
813  }
814  }
815 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209
LibUtilities::CommSharedPtr m_comm
virtual void PartitionGraphImpl(int &nVerts, int &nVertConds, Nektar::Array< Nektar::OneD, int > &xadj, Nektar::Array< Nektar::OneD, int > &adjcy, Nektar::Array< Nektar::OneD, int > &vertWgt, Nektar::Array< Nektar::OneD, int > &vertSize, Nektar::Array< Nektar::OneD, int > &edgeWgt, int &nparts, int &volume, Nektar::Array< Nektar::OneD, int > &part)=0
boost::graph_traits< BoostGraph >::adjacency_iterator BoostAdjacencyIterator
std::map< int, MeshEntity > m_ghostElmts
void CheckPartitions(int nParts, Array< OneD, int > &pPart)
boost::graph_traits< BoostGraph >::vertex_iterator BoostVertexIterator
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
Definition: Vmath.cpp:740
std::vector< std::vector< unsigned int > > m_localPartition

◆ PartitionGraphImpl()

virtual void Nektar::SpatialDomains::MeshPartition::PartitionGraphImpl ( int &  nVerts,
int &  nVertConds,
Nektar::Array< Nektar::OneD, int > &  xadj,
Nektar::Array< Nektar::OneD, int > &  adjcy,
Nektar::Array< Nektar::OneD, int > &  vertWgt,
Nektar::Array< Nektar::OneD, int > &  vertSize,
Nektar::Array< Nektar::OneD, int > &  edgeWgt,
int &  nparts,
int &  volume,
Nektar::Array< Nektar::OneD, int > &  part 
)
protectedpure virtual

◆ PartitionMesh()

void Nektar::SpatialDomains::MeshPartition::PartitionMesh ( int  nParts,
bool  shared = false,
bool  overlapping = false,
int  nLocal = 0 
)

Definition at line 107 of file MeshPartition.cpp.

References ASSERTL0, CreateGraph(), m_elements, m_parallel, m_shared, m_weightingRequired, PartitionGraph(), and WeightElements().

109 {
110  boost::ignore_unused(nLocal);
111 
112  ASSERTL0(m_parallel || m_elements.size() >= nParts,
113  "Too few elements for this many processes.");
114  m_shared = shared;
115 
116  ASSERTL0(!m_parallel || shared,
117  "Parallel partitioning requires shared filesystem.");
118 
120  {
121  WeightElements();
122  }
123  CreateGraph();
124 
125  PartitionGraph(nParts, overlapping);
126 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
void PartitionGraph(int nParts, bool overlapping=false)
Partition the graph.
std::map< int, MeshEntity > m_elements

◆ PrintPartInfo()

void Nektar::SpatialDomains::MeshPartition::PrintPartInfo ( std::ostream &  out)

Definition at line 310 of file MeshPartition.cpp.

References ASSERTL0, CalculateElementWeight(), m_dim, m_expansions, m_graph, m_localPartition, and m_shape.

311 {
312  int nElmt = boost::num_vertices(m_graph);
313  int nPart = m_localPartition.size();
314 
315  out << "# Partition information:" << std::endl;
316  out << "# No. elements : " << nElmt << std::endl;
317  out << "# No. partitions: " << nPart << std::endl;
318  out << "# ID nElmt nLocDof nBndDof" << std::endl;
319 
320  BoostVertexIterator vertit, vertit_end;
321  std::vector<int> partElmtCount(nPart, 0);
322  std::vector<int> partLocCount(nPart, 0);
323  std::vector<int> partBndCount(nPart, 0);
324 
325  std::map<int, int> elmtSizes;
326  std::map<int, int> elmtBndSizes;
327 
328  for (std::map<int, NummodesPerField>::iterator expIt = m_expansions.begin();
329  expIt != m_expansions.end(); ++expIt)
330  {
331  int elid = expIt->first;
332  NummodesPerField npf = expIt->second;
333 
334  for (NummodesPerField::iterator it = npf.begin(); it != npf.end(); ++it)
335  {
336  ASSERTL0(it->second.size() == m_dim,
337  " Number of directional"
338  " modes in expansion spec for element id = " +
339  boost::lexical_cast<std::string>(elid) +
340  " and field " +
341  boost::lexical_cast<std::string>(it->first) +
342  " does not correspond to mesh dimension");
343 
344  int na = it->second[0];
345  int nb = 0;
346  int nc = 0;
347  if (m_dim >= 2)
348  {
349  nb = it->second[1];
350  }
351  if (m_dim == 3)
352  {
353  nc = it->second[2];
354  }
355 
356  elmtSizes[elid] =
357  CalculateElementWeight(m_shape[elid], false, na, nb, nc);
358  elmtBndSizes[elid] =
359  CalculateElementWeight(m_shape[elid], true, na, nb, nc);
360  }
361  }
362 
363  for (boost::tie(vertit, vertit_end) = boost::vertices(m_graph);
364  vertit != vertit_end; ++vertit)
365  {
366  int partId = m_graph[*vertit].partition;
367  partElmtCount[partId]++;
368  partLocCount[partId] += elmtSizes[m_graph[*vertit].id];
369  partBndCount[partId] += elmtBndSizes[m_graph[*vertit].id];
370  }
371 
372  for (int i = 0; i < nPart; ++i)
373  {
374  out << i << " " << partElmtCount[i] << " " << partLocCount[i] << " "
375  << partBndCount[i] << std::endl;
376  }
377 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
boost::graph_traits< BoostGraph >::vertex_iterator BoostVertexIterator
std::map< int, NummodesPerField > m_expansions
std::map< int, LibUtilities::ShapeType > m_shape
std::map< std::string, NumModes > NummodesPerField
int CalculateElementWeight(LibUtilities::ShapeType elmtType, bool bndWeight, int na, int nb, int nc)
std::vector< std::vector< unsigned int > > m_localPartition

◆ ReadConditions()

void Nektar::SpatialDomains::MeshPartition::ReadConditions ( )
protected

Definition at line 379 of file MeshPartition.cpp.

References ASSERTL0, m_session, m_weightBnd, m_weightDofs, and m_weightingRequired.

Referenced by MeshPartition().

380 {
381  if (!m_session->DefinesElement("Nektar/Conditions/SolverInfo"))
382  {
383  // No SolverInfo = no change of default action to weight
384  // mesh graph.
385  return;
386  }
387 
388  TiXmlElement *solverInfoElement =
389  m_session->GetElement("Nektar/Conditions/SolverInfo");
390 
391  TiXmlElement *solverInfo = solverInfoElement->FirstChildElement("I");
392  ASSERTL0(solverInfo, "Cannot read SolverInfo tags");
393 
394  while (solverInfo)
395  {
396  // read the property name
397  ASSERTL0(solverInfo->Attribute("PROPERTY"),
398  "Missing PROPERTY attribute in solver info "
399  "section. ");
400  std::string solverProperty = solverInfo->Attribute("PROPERTY");
401  ASSERTL0(!solverProperty.empty(),
402  "Solver info properties must have a non-empty "
403  "name. ");
404  // make sure that solver property is capitalised
405  std::string solverPropertyUpper = boost::to_upper_copy(solverProperty);
406 
407  // read the value
408  ASSERTL0(solverInfo->Attribute("VALUE"),
409  "Missing VALUE attribute in solver info section. ");
410  std::string solverValue = solverInfo->Attribute("VALUE");
411  ASSERTL0(!solverValue.empty(),
412  "Solver info properties must have a non-empty value");
413  // make sure that property value is capitalised
414  std::string propertyValueUpper = boost::to_upper_copy(solverValue);
415 
416  if (solverPropertyUpper == "WEIGHTPARTITIONS")
417  {
418  if (propertyValueUpper == "DOF")
419  {
420  m_weightingRequired = true;
421  m_weightDofs = true;
422  }
423  else if (propertyValueUpper == "BOUNDARY")
424  {
425  m_weightingRequired = true;
426  m_weightBnd = true;
427  }
428  else if (propertyValueUpper == "BOTH")
429  {
430  m_weightingRequired = true;
431  m_weightDofs = true;
432  m_weightBnd = true;
433  }
434  return;
435  }
436  solverInfo = solverInfo->NextSiblingElement("I");
437  }
438 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
LibUtilities::SessionReaderSharedPtr m_session

◆ ReadExpansions()

void Nektar::SpatialDomains::MeshPartition::ReadExpansions ( )
protected

Expansiontypes will contain plenty of data, where relevant at this stage are composite ID(s) that this expansion type describes, nummodes and a list of fields that this expansion relates to. If this does not exist the variable is only set to "DefaultVar".

Definition at line 128 of file MeshPartition.cpp.

References ASSERTL0, Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), Nektar::ParseUtils::GenerateSeqVector(), Nektar::ParseUtils::GenerateVector(), Nektar::LibUtilities::GetCommFactory(), Nektar::LibUtilities::GetFieldIOFactory(), Nektar::LibUtilities::FieldIO::GetFileType(), m_compMap, m_dim, m_expansions, m_fieldNameToId, m_numFields, m_session, and m_shape.

Referenced by MeshPartition().

129 {
130  // Find the Expansions tag
131  TiXmlElement *expansionTypes = m_session->GetElement("Nektar/Expansions");
132 
133  // Find the Expansion type
134  TiXmlElement *expansion = expansionTypes->FirstChildElement();
135  std::string expType = expansion->Value();
136 
137  /// Expansiontypes will contain plenty of data,
138  /// where relevant at this stage are composite
139  /// ID(s) that this expansion type describes,
140  /// nummodes and a list of fields that this
141  /// expansion relates to. If this does not exist
142  /// the variable is only set to "DefaultVar".
143 
144  if (expType == "E")
145  {
146  while (expansion)
147  {
148  std::vector<unsigned int> composite;
149  std::vector<unsigned int> nummodes;
150  std::vector<std::string> fieldName;
151 
152  const char *nModesStr = expansion->Attribute("NUMMODES");
153  ASSERTL0(nModesStr,
154  "NUMMODES was not defined in EXPANSION section of input");
155  std::string numModesStr = nModesStr;
156  bool valid = ParseUtils::GenerateVector(numModesStr.c_str(),
157  nummodes);
158  ASSERTL0(valid, "Unable to correctly parse the number of modes.");
159 
160  if (nummodes.size() == 1)
161  {
162  for (int i = 1; i < m_dim; i++)
163  {
164  nummodes.push_back(nummodes[0]);
165  }
166  }
167  ASSERTL0(nummodes.size() == m_dim,
168  "Number of modes should match mesh dimension");
169 
170  const char *fStr = expansion->Attribute("FIELDS");
171  if (fStr)
172  {
173  std::string fieldStr = fStr;
174  bool valid = ParseUtils::GenerateVector(
175  fieldStr.c_str(), fieldName);
176  ASSERTL0(valid, "Unable to correctly parse the field string in "
177  "ExpansionTypes.");
178 
179  for (int i = 0; i < fieldName.size(); ++i)
180  {
181  if (m_fieldNameToId.count(fieldName[i]) == 0)
182  {
183  int k = m_fieldNameToId.size();
184  m_fieldNameToId[fieldName[i]] = k;
185  m_numFields++;
186  }
187  }
188  }
189  else
190  {
191  fieldName.push_back("DefaultVar");
192  int k = m_fieldNameToId.size();
193 
194  if (m_fieldNameToId.count("DefaultVar") == 0)
195  {
196  ASSERTL0(
197  k == 0,
198  "Omitting field variables and explicitly listing "
199  "them in different ExpansionTypes is wrong practise");
200 
201  m_fieldNameToId["DefaultVar"] = k;
202  m_numFields++;
203  }
204  }
205 
206  std::string compositeStr = expansion->Attribute("COMPOSITE");
207  ASSERTL0(compositeStr.length() > 3,
208  "COMPOSITE must be specified in expansion definition");
209  int beg = compositeStr.find_first_of("[");
210  int end = compositeStr.find_first_of("]");
211  std::string compositeListStr =
212  compositeStr.substr(beg + 1, end - beg - 1);
213  bool parseGood = ParseUtils::GenerateSeqVector(
214  compositeListStr.c_str(), composite);
215  ASSERTL0(parseGood && !composite.empty(),
216  (std::string("Unable to read composite index range: ") +
217  compositeListStr)
218  .c_str());
219 
220  // construct mapping (elmt id, field name) -> nummodes
221  for (int i = 0; i < composite.size(); ++i)
222  {
223  auto &shapeType = m_compMap[composite[i]].first;
224  auto &elmtIds = m_compMap[composite[i]].second;
225 
226  for (int j = 0; j < fieldName.size(); j++)
227  {
228  for (auto &elid : elmtIds)
229  {
230  m_expansions[elid][fieldName[j]] = nummodes;
231  m_shape[elid] = shapeType;
232  }
233  }
234  }
235 
236  expansion = expansion->NextSiblingElement("E");
237  }
238  }
239  else if (expType == "F")
240  {
241  ASSERTL0(expansion->Attribute("FILE"),
242  "Attribute FILE expected for type F expansion");
243  std::string filenameStr = expansion->Attribute("FILE");
244  ASSERTL0(!filenameStr.empty(),
245  "A filename must be specified for the FILE "
246  "attribute of expansion");
247 
248  // Create fieldIO object to load file
249  // need a serial communicator to avoid problems with
250  // shared file system
253  std::string iofmt = LibUtilities::FieldIO::GetFileType(filenameStr, comm);
255  iofmt, comm, m_session->GetSharedFilesystem());
256 
257  // Load field definitions from file
258  std::vector<LibUtilities::FieldDefinitionsSharedPtr> fielddefs;
259  f->Import(filenameStr, fielddefs);
260 
261  // Parse field definitions
262  for (int i = 0; i < fielddefs.size(); ++i)
263  {
264  // Name of fields
265  for (int j = 0; j < fielddefs[i]->m_fields.size(); ++j)
266  {
267  std::string fieldName = fielddefs[i]->m_fields[j];
268  if (m_fieldNameToId.count(fieldName) == 0)
269  {
270  int k = m_fieldNameToId.size();
271  m_fieldNameToId[fieldName] = k;
272  m_numFields++;
273  }
274  }
275  // Number of modes and shape for each element
276  int numHomoDir = fielddefs[i]->m_numHomogeneousDir;
277  int cnt = 0;
278  for (int j = 0; j < fielddefs[i]->m_elementIDs.size(); ++j)
279  {
280  int elid = fielddefs[i]->m_elementIDs[j];
281  std::vector<unsigned int> nummodes;
282  for (int k = 0; k < m_dim; k++)
283  {
284  nummodes.push_back(fielddefs[i]->m_numModes[cnt++]);
285  }
286  if (fielddefs[i]->m_uniOrder)
287  {
288  cnt = 0;
289  }
290  else
291  {
292  cnt += numHomoDir;
293  }
294  for (int k = 0; k < fielddefs[i]->m_fields.size(); k++)
295  {
296  std::string fieldName = fielddefs[i]->m_fields[k];
297  m_expansions[elid][fieldName] = nummodes;
298  }
299  m_shape[elid] = fielddefs[i]->m_shapeType;
300  }
301  }
302  }
303  else
304  {
305  ASSERTL0(false,
306  "Expansion type not defined or not supported at the moment");
307  }
308 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
Definition: FieldIO.cpp:72
CommFactory & GetCommFactory()
LibUtilities::SessionReaderSharedPtr m_session
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
static const std::string GetFileType(const std::string &filename, CommSharedPtr comm)
Determine file type of given input file.
Definition: FieldIO.cpp:97
std::map< int, NummodesPerField > m_expansions
std::map< int, LibUtilities::ShapeType > m_shape
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
Definition: ParseUtils.cpp:135
std::map< std::string, int > m_fieldNameToId
std::shared_ptr< FieldIO > FieldIOSharedPtr
Definition: FieldIO.h:306
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector. ...
Definition: ParseUtils.cpp:108

◆ WeightElements()

void Nektar::SpatialDomains::MeshPartition::WeightElements ( )
protected

Definition at line 454 of file MeshPartition.cpp.

References ASSERTL0, CalculateEdgeWeight(), CalculateElementWeight(), m_dim, m_edgeWeights, m_elements, m_expansions, m_fieldNameToId, m_numFields, m_shape, m_vertBndWeights, and m_vertWeights.

Referenced by PartitionMesh().

455 {
456  std::vector<unsigned int> weight(m_numFields, 1);
457  std::map<int, MeshEntity>::iterator eIt;
458  for (eIt = m_elements.begin(); eIt != m_elements.end(); ++eIt)
459  {
460  m_vertWeights[eIt->second.origId] = weight;
461  m_vertBndWeights[eIt->second.origId] = weight;
462  m_edgeWeights[eIt->second.origId] = weight;
463  }
464 
465  for (std::map<int, NummodesPerField>::iterator expIt = m_expansions.begin();
466  expIt != m_expansions.end(); ++expIt)
467  {
468  int elid = expIt->first;
469  NummodesPerField npf = expIt->second;
470 
471  for (NummodesPerField::iterator it = npf.begin(); it != npf.end(); ++it)
472  {
473  ASSERTL0(it->second.size() == m_dim,
474  " Number of directional"
475  " modes in expansion spec for element id = " +
476  boost::lexical_cast<std::string>(elid) +
477  " and field " +
478  boost::lexical_cast<std::string>(it->first) +
479  " does not correspond to mesh dimension");
480 
481  int na = it->second[0];
482  int nb = 0;
483  int nc = 0;
484  if (m_dim >= 2)
485  {
486  nb = it->second[1];
487  }
488  if (m_dim == 3)
489  {
490  nc = it->second[2];
491  }
492 
493  // Assume for parallel partitioning that this is just missing from
494  // our partition.
495  if (m_vertWeights.find(elid) == m_vertWeights.end())
496  {
497  continue;
498  }
499 
500  m_vertWeights[elid][m_fieldNameToId[it->first]] =
501  CalculateElementWeight(m_shape[elid], false, na, nb, nc);
502  m_vertBndWeights[elid][m_fieldNameToId[it->first]] =
503  CalculateElementWeight(m_shape[elid], true, na, nb, nc);
504  m_edgeWeights[elid][m_fieldNameToId[it->first]] =
505  CalculateEdgeWeight(m_shape[elid], na, nb, nc);
506  }
507  } // for i
508 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::map< int, MultiWeight > m_vertWeights
int CalculateEdgeWeight(LibUtilities::ShapeType elmtType, int na, int nb, int nc)
std::map< int, MultiWeight > m_vertBndWeights
std::map< int, MultiWeight > m_edgeWeights
std::map< int, NummodesPerField > m_expansions
std::map< int, LibUtilities::ShapeType > m_shape
std::map< int, MeshEntity > m_elements
std::map< std::string, int > m_fieldNameToId
std::map< std::string, NumModes > NummodesPerField
int CalculateElementWeight(LibUtilities::ShapeType elmtType, bool bndWeight, int na, int nb, int nc)

Member Data Documentation

◆ m_comm

LibUtilities::CommSharedPtr Nektar::SpatialDomains::MeshPartition::m_comm
protected

◆ m_compMap

CompositeDescriptor Nektar::SpatialDomains::MeshPartition::m_compMap
protected

Definition at line 133 of file MeshPartition.h.

Referenced by ReadExpansions().

◆ m_dim

int Nektar::SpatialDomains::MeshPartition::m_dim
protected

Definition at line 128 of file MeshPartition.h.

Referenced by PrintPartInfo(), ReadExpansions(), and WeightElements().

◆ m_edgeWeights

std::map<int, MultiWeight> Nektar::SpatialDomains::MeshPartition::m_edgeWeights
protected

Definition at line 145 of file MeshPartition.h.

Referenced by CreateGraph(), and WeightElements().

◆ m_elements

std::map<int, MeshEntity> Nektar::SpatialDomains::MeshPartition::m_elements
protected

Definition at line 131 of file MeshPartition.h.

Referenced by CreateGraph(), MeshPartition(), PartitionMesh(), and WeightElements().

◆ m_expansions

std::map<int, NummodesPerField> Nektar::SpatialDomains::MeshPartition::m_expansions
protected

Definition at line 137 of file MeshPartition.h.

Referenced by PrintPartInfo(), ReadExpansions(), and WeightElements().

◆ m_fieldNameToId

std::map<std::string, int> Nektar::SpatialDomains::MeshPartition::m_fieldNameToId
protected

Definition at line 142 of file MeshPartition.h.

Referenced by ReadExpansions(), and WeightElements().

◆ m_ghostElmts

std::map<int, MeshEntity> Nektar::SpatialDomains::MeshPartition::m_ghostElmts
protected

Definition at line 132 of file MeshPartition.h.

Referenced by CreateGraph(), MeshPartition(), and PartitionGraph().

◆ m_graph

BoostGraph Nektar::SpatialDomains::MeshPartition::m_graph
protected

Definition at line 147 of file MeshPartition.h.

Referenced by CreateGraph(), PartitionGraph(), and PrintPartInfo().

◆ m_localPartition

std::vector<std::vector<unsigned int> > Nektar::SpatialDomains::MeshPartition::m_localPartition
protected

Definition at line 148 of file MeshPartition.h.

Referenced by GetElementIDs(), PartitionGraph(), and PrintPartInfo().

◆ m_numFields

int Nektar::SpatialDomains::MeshPartition::m_numFields
protected

Definition at line 129 of file MeshPartition.h.

Referenced by ReadExpansions(), and WeightElements().

◆ m_parallel

bool Nektar::SpatialDomains::MeshPartition::m_parallel
protected

◆ m_session

LibUtilities::SessionReaderSharedPtr Nektar::SpatialDomains::MeshPartition::m_session
protected

Definition at line 126 of file MeshPartition.h.

Referenced by ReadConditions(), and ReadExpansions().

◆ m_shape

std::map<int, LibUtilities::ShapeType> Nektar::SpatialDomains::MeshPartition::m_shape
protected

Definition at line 140 of file MeshPartition.h.

Referenced by PrintPartInfo(), ReadExpansions(), and WeightElements().

◆ m_shared

bool Nektar::SpatialDomains::MeshPartition::m_shared
protected

Definition at line 155 of file MeshPartition.h.

Referenced by PartitionGraph(), and PartitionMesh().

◆ m_vertBndWeights

std::map<int, MultiWeight> Nektar::SpatialDomains::MeshPartition::m_vertBndWeights
protected

Definition at line 144 of file MeshPartition.h.

Referenced by CreateGraph(), and WeightElements().

◆ m_vertWeights

std::map<int, MultiWeight> Nektar::SpatialDomains::MeshPartition::m_vertWeights
protected

Definition at line 143 of file MeshPartition.h.

Referenced by CreateGraph(), and WeightElements().

◆ m_weightBnd

bool Nektar::SpatialDomains::MeshPartition::m_weightBnd
protected

Definition at line 153 of file MeshPartition.h.

Referenced by PartitionGraph(), and ReadConditions().

◆ m_weightDofs

bool Nektar::SpatialDomains::MeshPartition::m_weightDofs
protected

Definition at line 154 of file MeshPartition.h.

Referenced by PartitionGraph(), and ReadConditions().

◆ m_weightingRequired

bool Nektar::SpatialDomains::MeshPartition::m_weightingRequired
protected

Definition at line 152 of file MeshPartition.h.

Referenced by CreateGraph(), PartitionGraph(), PartitionMesh(), and ReadConditions().