12#include <unordered_map>
13#include <unordered_set>
60 const std::vector<DNDS::index> &pushIndex,
61 const std::vector<DNDS::index> &pushIndexStart,
65 Serial2Global.
InitPair(
"Serial2Global", mpi);
66 Serial2Global.
father->Resize(localSize);
68 Serial2Global.
trans.createFatherGlobalMapping();
69 Serial2Global.
trans.createGhostMapping(pushIndex, pushIndexStart);
70 Serial2Global.
trans.createMPITypes();
71 Serial2Global.
son->createGlobalMapping();
74 (*Serial2Global.
son)[iSon] = Serial2Global.
son->pLGlobalMapping->operator()(mpi.rank, iSon);
75 Serial2Global.
trans.pushOnce();
76 serial2Global.resize(localSize);
78 serial2Global[iFat] = Serial2Global.
father->operator[](iFat);
95 DNDS::log() <<
"UnstructuredMeshSerialRW === Doing PartitionReorderToMeshCell2Cell" << std::endl;
100 for (
DNDS::rowsize ic2n = 0; ic2n < (*cell2nodeSerial).RowSize(iCell); ic2n++)
107 std::vector<DNDS::index> cell_push, cell_pushStart, node_push, node_pushStart, bnd_push, bnd_pushStart;
111 std::vector<DNDS::index> cell_Serial2Global, node_Serial2Global, bnd_Serial2Global;
119 DNDS::log() <<
"UnstructuredMeshSerialRW === Doing PartitionReorderToMeshCell2Cell ConvertAdjSerial2Global" << std::endl;
126 mesh->coords.InitPair(
"coords",
mesh->getMPI());
129 mesh->cell2node.InitPair(
"cell2node",
mesh->getMPI());
130 mesh->cell2cellOrig.InitPair(
"cell2cellOrig",
mesh->getMPI());
131 mesh->node2nodeOrig.InitPair(
"node2nodeOrig",
mesh->getMPI());
132 mesh->bnd2bndOrig.InitPair(
"bnd2bndOrig",
mesh->getMPI());
133 if (
mesh->isPeriodic)
134 mesh->cell2nodePbi.InitPair(
"cell2nodePbi",
mesh->getMPI());
136 mesh->bnd2node.InitPair(
"bnd2node",
mesh->getMPI());
137 mesh->bnd2cell.InitPair(
"bnd2cell",
mesh->getMPI());
138 if (
mesh->isPeriodic)
139 mesh->bnd2nodePbi.InitPair(
"bnd2nodePbi",
mesh->getMPI());
143 DNDS::log() <<
"UnstructuredMeshSerialRW === Doing PartitionReorderToMeshCell2Cell Trasfer Data Coord" << std::endl;
148 DNDS::log() <<
"UnstructuredMeshSerialRW === Doing PartitionReorderToMeshCell2Cell Trasfer Data Cell" << std::endl;
154 if (
mesh->isPeriodic)
158 DNDS::log() <<
"UnstructuredMeshSerialRW === Doing PartitionReorderToMeshCell2Cell Trasfer Data Bnd" << std::endl;
164 if (
mesh->isPeriodic)
169 { log() <<
"[" << mesh->getMPI().rank <<
": nCell " << mesh->cell2node.father->Size() <<
"] " << (((mesh->getMPI().rank + 1) % 10) ?
"" :
"\n") << std::flush; });
171 if (
mesh->getMPI().rank == 0)
174 { log() <<
"[" << mesh->getMPI().rank <<
": nNode " << mesh->coords.father->Size() <<
"] " << (((mesh->getMPI().rank + 1) % 10) ?
"" :
"\n") << std::flush; });
176 if (
mesh->getMPI().rank == 0)
179 { log() <<
"[" << mesh->getMPI().rank <<
": nBnd " << mesh->bnd2node.father->Size() <<
"] " << (((mesh->getMPI().rank + 1) % 10) ?
"" :
"\n") << std::flush; });
181 if (
mesh->getMPI().rank == 0)
185 mesh->cell2node.idx.markGlobal();
186 mesh->bnd2node.idx.markGlobal();
187 mesh->bnd2cell.idx.markGlobal();
189 DNDS::log() <<
"UnstructuredMeshSerialRW === Done PartitionReorderToMeshCell2Cell" << std::endl;
201 std::vector<DNDS::index> serialPullCell;
202 std::vector<DNDS::index> serialPullNode;
211 serialPullCell.resize(numCellGlobal);
212 serialPullNode.resize(numNodeGlobal);
215 serialPullCell[
i] =
i;
217 serialPullNode[
i] =
i;
222 if (
mesh->isPeriodic)
229 if (
mesh->isPeriodic)
239 auto reuseOrCreateFatherGlobalMapping = [](
auto &
trans)
241 if (
trans.father->pLGlobalMapping)
242 trans.pLGlobalMapping =
trans.father->pLGlobalMapping;
244 trans.createFatherGlobalMapping();
248 if (
mesh->isPeriodic)
256 if (
mesh->isPeriodic)
267 if (
mesh->isPeriodic)
275 if (
mesh->isPeriodic)
282 DNDS::log() <<
"UnstructuredMeshSerialRW === BuildSerialOut Done " << std::endl;
293 using namespace Elem;
298 if (
eType == ElemType::Line2 ||
299 eType == ElemType::Tri3 ||
300 eType == ElemType::Quad4 ||
301 eType == ElemType::Tet4 ||
302 eType == ElemType::Hex8 ||
303 eType == ElemType::Prism6 ||
304 eType == ElemType::Pyramid5)
321 using namespace Elem;
326 if (
eType == ElemType::Line3 ||
327 eType == ElemType::Tri6 ||
328 eType == ElemType::Quad9 ||
329 eType == ElemType::Tet10 ||
330 eType == ElemType::Hex27 ||
331 eType == ElemType::Prism18 ||
332 eType == ElemType::Pyramid14)
348 const tPoint &translation1,
351 const tPoint &translation2,
354 const tPoint &translation3,
398 cell2node.trans.createFatherGlobalMapping();
408 if (!
bnd2node.father->pLGlobalMapping)
409 bnd2node.father->createGlobalMapping();
411 bnd2node.trans.createFatherGlobalMapping();
437 cell2node.trans.createFatherGlobalMapping();
440 bnd2node.trans.createFatherGlobalMapping();
463 node2cell.trans.createFatherGlobalMapping();
470 std::unordered_map<index, index>
nodeG2L;
531 const std::vector<index> & ) ->
bool
594 std::vector<Geom::NodePeriodicBits>
pbi0,
pbi1;
622 if (
bndElemInfo(
i, 0).zone == Geom::BC_ID_PERIODIC_1_DONOR)
624 else if (
bndElemInfo(
i, 0).zone == Geom::BC_ID_PERIODIC_2_DONOR)
626 else if (
bndElemInfo(
i, 0).zone == Geom::BC_ID_PERIODIC_3_DONOR)
657 ?
"this periodic bnd matches both sides"
658 :
"this periodic bnd matches no sides");
695 cell2cell.trans.createFatherGlobalMapping();
697 bnd2cell.trans.createFatherGlobalMapping();
698 node2bnd.trans.createFatherGlobalMapping();
1137 for (
int i = 0;
i <
eParent.GetNumNodes();
i++)
1141 for (
int i = 0;
i <
eFace.GetNumNodes();
i++)
1162 using idx_pbi = std::pair<index, NodePeriodicBits>;
1165 :
L.first <
R.first; };
1186 std::vector<NodePeriodicBits>
pPbi(
eParent.GetNumNodes());
1187 for (
int i = 0;
i <
eParent.GetNumNodes();
i++)
1189 std::vector<NodePeriodicBits>
fPbi(
eFace.GetNumNodes());
1191 for (
int i = 0;
i <
eFace.GetNumNodes();
i++)
1198 [
this](
const std::vector<index> &
parents,
1214 std::vector<MPI_int>
peers;
1220 return {
true, std::move(
peers)};
1237 face2node.trans.createFatherGlobalMapping();
1259 log() <<
"UnstructuredMesh === InterpolateFace: total faces " <<
gSize << std::endl;
1288 face2cell.trans.createFatherGlobalMapping();
1397 "Face {} is internal, but f2c[1] is null, at {},{},{} - {},{},{}",
iFace,
1439 serializerP->WriteString(
"mesh",
"UnstructuredMesh");
1545 log() <<
"UnstructuredMesh === ReadSerialize "
1546 <<
"Global NumCell [ " << nCellG <<
" ]" << std::endl;
1547 log() <<
"UnstructuredMesh === ReadSerialize "
1548 <<
"Global NumNode [ " <<
nNodeG <<
" ]" << std::endl;
1549 log() <<
"UnstructuredMesh === ReadSerialize "
1550 <<
"Global NumBnd [ " <<
nNodeB <<
" ]" << std::endl;
1572 bMesh.cell2cellOrig.InitPair(
"bMesh.cell2cellOrig",
mpi);
1573 bMesh.node2nodeOrig.InitPair(
"bMesh.node2nodeOrig",
mpi);
1578 bMesh.bnd2bndOrig.InitPair(
"bMesh.bnd2bndOrig",
mpi);
1650 bMesh.node2nodeOrig.TransAttach();
1652 bMesh.node2nodeOrig.trans.createMPITypes();
1723 bMesh.cell2cellOrig.father->createGlobalMapping();
1731 log() <<
"UnstructuredMesh === ConstructBndMesh Done" << std::endl;
1751 const std::unordered_set<AdjKind, AdjKindHash> &
skip)
const
1758 if (pair.father &&
skip.find(kind) ==
skip.end())
1759 dag.registerAdj(kind, pair);
1801 if (pair.father && pair.father->pLGlobalMapping)
1802 return pair.father->pLGlobalMapping;
1816 dag.registerGlobalMapping(kind,
gm);
1824 fmt::format(
"fillRegistry: no pLGlobalMapping found for EntityKind {} "
1825 "but adj {} requires it",
1864 << fmt::format(
"UnstructuredMesh === ReorderLocalCells, nPart0 [{}], got reordering, bw [{}] to [{}]",
nParts,
perm.bwOld,
perm.bwNew) << std::endl;
2044 log() << fmt::format(
"UnstructuredMesh === ReorderLocalCells finished") << std::endl;
Reserved for template implementations of #DeviceStorage primitives.
Pre-compiled-header style shim that includes the heavy Eigen headers under DNDSR's warning suppressio...
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
#define DNDS_check_throw_info(expr, info)
Same as DNDS_check_throw but attaches a user-supplied info message to the thrown std::runtime_error.
#define DNDS_check_throw(expr)
Runtime check active in both debug and release builds. Throws std::runtime_error if expr evaluates to...
Layered DAG of mesh adjacency relations with composable DSL operations.
Thin free-function wrappers over MeshConnectivity DSL methods that assert per-adjacency state (AdjPai...
Helper for computing cell reordering permutations via Metis.
Internal helpers for mesh partition redistribution.
constexpr AdjKind Bnd2Node
constexpr AdjKind Cell2Node
constexpr AdjKind Node2Cell
constexpr AdjKind Face2Cell
constexpr AdjKind Cell2Face
constexpr AdjKind Cell2CellFace
constexpr AdjKind Node2Bnd
constexpr AdjKind Bnd2Face
constexpr AdjKind Cell2Cell
constexpr AdjKind Face2Node
constexpr AdjKind Face2Bnd
constexpr AdjKind Bnd2Cell
CellPermutationResult ComputeCellPermutation(tLocalMatStruct &cell2cellFaceV, const tAdjPair &cell2cell, index nCell, int nParts, int nPartsInner)
void PushInfo2Serial2Global(std::vector< DNDS::index > &serial2Global, DNDS::index localSize, const std::vector< DNDS::index > &pushIndex, const std::vector< DNDS::index > &pushIndexStart, const DNDS::MPIInfo &mpi)
Reserved skeleton for parallel topology interpolation.
void Partition2LocalIdx(const std::vector< TPartitionIdx > &partition, std::vector< DNDS::index > &localPush, std::vector< DNDS::index > &localPushStart, const DNDS::MPIInfo &mpi)
void Partition2Serial2Global(const std::vector< TPartitionIdx > &partition, std::vector< DNDS::index > &serial2Global, const DNDS::MPIInfo &mpi, DNDS::MPI_int nPart)
DNDS_DEVICE_CALLABLE bool FaceIDIsInternal(t_index id)
AdjPairTracked< ArrayAdjacencyPair< out_rs > > CheckedComposeFiltered(const AdjPairTracked< ArrayAdjacencyPair< rs_AB > > &AB, const AdjPairTracked< ArrayAdjacencyPair< rs_BC > > &BC, const std::unordered_map< index, index > &bGlobal2Local, Predicate &&pred, TArgs &&...args)
std::function< OwnershipDecision(const std::vector< index > &parents, const std::vector< MPI_int > &parentRanks, index nLocalParents)> OwnershipResolverMulti
DNDS_DEVICE_CALLABLE bool FaceIDIsPeriodic(t_index id)
AdjPairTracked< tAdjPair > CheckedInverse(const AdjPairTracked< ArrayAdjacencyPair< cone_rs > > &cone, const ToPair &toPair, index nToLocal, const MPIInfo &mpi)
void TransferDataSerial2Global(TArr &arraySerial, TArr &arrayDist, const std::vector< DNDS::index > &pushIndex, const std::vector< DNDS::index > &pushIndexStart, const DNDS::MPIInfo &mpi)
void ConvertAdjSerial2Global(TAdj &arraySerialAdj, const std::vector< DNDS::index > &partitionJSerial2Global, const DNDS::MPIInfo &mpi)
DNDS_DEVICE_CALLABLE bool FaceIDIsPeriodic3(t_index id)
DNDS_DEVICE_CALLABLE bool FaceIDIsPeriodic2(t_index id)
std::string adjKindName(const AdjKind &kind)
Format an AdjKind as a diagnostic string, e.g. "Cell2Node", "Cell2Cell(Node)".
DNDS_DEVICE_CALLABLE bool FaceIDIsPeriodic1(t_index id)
MPI_int Scan(const void *sendbuf, void *recvbuf, MPI_int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
Wrapper over MPI_Scan (inclusive prefix reduction).
MPI_int Allreduce(const void *sendbuf, void *recvbuf, MPI_int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
Wrapper over MPI_Allreduce.
MPI_int Barrier(MPI_Comm comm)
Wrapper over MPI_Barrier.
void AllreduceOneIndex(index &v, MPI_Op op, const MPIInfo &mpi)
Single-scalar Allreduce helper for indices (in-place, count = 1).
ssp< SerializerBase > SerializerBaseSSP
the host side operators are provided as implemented
const MPI_Datatype DNDS_MPI_INDEX
MPI datatype matching index (= MPI_INT64_T).
DNDS_CONSTANT const index UnInitIndex
Sentinel "not initialised" index value (= INT64_MIN).
void MPISerialDo(const MPIInfo &mpi, F f)
Execute f on each rank serially, in rank order.
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
constexpr MPI_int UnInitMPIInt
Sentinel "not initialised" MPI_int value (= -1, invalid rank).
index size_to_index(size_t v)
Range-checked conversion from size_t to DNDS::index.
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
ssp< T > make_ssp(Args &&...args)
Type-safe replacement for DNDS_MAKE_SSP. Creates ssp<T> with forwarded args.
std::ostream & log()
Return the current DNDSR log stream (either std::cout or the installed file).
int MPI_int
MPI counterpart type for MPI_int (= C int). Used for counts and ranks in MPI calls.
DNDS_DEVICE_CALLABLE index Size() const
Combined father + son row count.
Convenience bundle of a father, son, and attached ArrayTransformer.
void TransAttach()
Bind the transformer to the current father / son pointers.
ssp< TArray > father
Owned-side array (must be resized before ghost setup).
void WriteSerialize(Serializer::SerializerBaseSSP serializerP, const std::string &name, bool includePIG=true, bool includeSon=true)
Writes the ArrayPair (father, optional son, optional ghost mapping).
index Size() const
Combined row count (father->Size() + son->Size()).
void InitPair(const std::string &name, Args &&...args)
Allocate both father and son arrays, forwarding all args to TArray constructor.
ssp< TArray > son
Ghost-side array (sized automatically by createMPITypes / BorrowAndPull).
void BorrowAndPull(TPrimaryPair &primary)
Attach, borrow ghost indexing from a primary pair, create MPI types, and pull once.
void ReadSerialize(Serializer::SerializerBaseSSP serializerP, const std::string &name, bool includePIG=true, bool includeSon=true)
Reads an ArrayPair written by WriteSerialize (same partition count).
TTrans trans
Ghost-communication engine bound to father and son.
void ObtainSymmetricSymbolicFactorization(const TAdj &cell2cellFaceV, const std::vector< index > localPartStarts_in, int iluCode)
get symmetric symbolic matrix factorization over cell2cellFaceV
AdjIndexInfoDeviceView idx
static CompiledGhostTree compile(const GhostSpec &spec)
static MPI_Datatype CommType()
static GhostSpec defaultPrimary()
static MPI_Datatype CommType()
DNDS_HOST void WriteSerializer(Serializer::SerializerBaseSSP serializerP, const std::string &name)
std::array< tPointPortable, 4 > rotationCenter
std::array< tPointPortable, 4 > translation
std::array< tGPointPortable, 4 > rotation
DNDS_HOST void ReadSerializer(Serializer::SerializerBaseSSP serializerP, const std::string &name)
std::function< int(index iParent)> numSubEntities
Number of sub-entities for parent iParent.
AdjPairTrackedDeviceView< B, tAdjPair::t_arr > bnd2node
tCoordPair::t_deviceView< B > coords
reader
tElemInfoArrayPair::t_deviceView< B > cellElemInfo
tPbiPair::t_deviceView< B > cell2nodePbi
periodic only, after reader
AdjPairTrackedDeviceView< B, tAdj2Pair::t_arr > bnd2cell
MeshAdjState adjPrimaryState
tPbiPair::t_deviceView< B > bnd2nodePbi
tElemInfoArrayPair::t_deviceView< B > bndElemInfo
AdjPairTrackedDeviceView< B, tAdjPair::t_arr > cell2node
DNDS::ArrayTransformerType< tCoord::element_type >::Type coordSerialOutTrans
DNDS::ArrayTransformerType< tElemInfoArray::element_type >::Type cellElemInfoSerialOutTrans
void BuildSerialOut()
should be called to build data for serial out
DNDS::ArrayTransformerType< tAdj::element_type >::Type cell2nodeSerialOutTrans
tElemInfoArray bndElemInfoSerial
DNDS::ssp< UnstructuredMesh > mesh
void PartitionReorderToMeshCell2Cell()
DNDS::ArrayTransformerType< tPbi::element_type >::Type cell2nodePbiSerialOutTrans
std::vector< DNDS::MPI_int > cellPartition
std::vector< DNDS::MPI_int > bndPartition
tAdj1 node2nodeOrigSerial
tAdj1 cell2cellOrigSerial
tElemInfoArray cellElemInfoSerial
std::vector< DNDS::MPI_int > nodePartition
void AdjLocal2GlobalN2CB()
UnstructuredMeshDeviceView< B > t_deviceView
tPbiPair cell2nodePbi
periodic only, after reader
AdjPairTracked< tAdjPair > cell2cellFace
constructed on demand
void fillRegistry(MeshConnectivity &dag) const
Populate a MeshConnectivity registry from this mesh's currently-built adjacencies.
std::unordered_map< index, index > face2bndM
void ReorderLocalCellsLegacy(int nParts=1, int nPartsInner=1)
Legacy implementation preserved for reference/fallback.
index NumNodeProc() const
index CellIndexLocal2Global_NoSon(index i)
tPbiPair face2nodePbi
periodic only, after interpolated
AdjPairTracked< tAdj1Pair > face2bnd
std::vector< index > node2bndNode
index NumNodeGhost() const
void AdjGlobal2LocalN2CB()
void AdjLocal2GlobalC2F()
void AdjGlobal2LocalPrimaryForBnd()
MeshAdjState adjC2CFaceState
std::vector< index > node2parentNode
parent built
AdjPairTracked< tAdj2Pair > face2cell
index NumCellProc() const
void AdjLocal2GlobalFacial()
void AdjGlobal2LocalPrimary()
tLocalMatStruct cell2cellFaceVLocalParts
for cell local factorization
tLocalMatStruct GetCell2CellFaceVLocal(bool onLocalPartition=false)
void RecoverNode2CellAndNode2Bnd()
only requires father part of cell2node, bnd2node and coords generates node2cell and node2bnd (father ...
MeshAdjState adjN2CBState
AdjPairTracked< tAdjPair > cell2face
interpolated
void AdjGlobal2LocalC2F()
void BuildGhostPrimary(int nGhostLayers=1)
building ghost (son) from primary (currently only cell2cell)
void ReadSerialize(Serializer::SerializerBaseSSP serializerP, const std::string &name)
index CellIndexGlobal2Local_NoSon(index i)
AdjPairTracked< tAdjPair > cell2cell
std::vector< index > bnd2faceV
index CellIndexLocal2Global(DNDS::index i)
void AdjLocal2GlobalPrimary()
AdjPairTracked< tAdjPair > face2node
MeshAdjState adjPrimaryState
void ObtainSymmetricSymbolicFactorization(Direct::SerialSymLUStructure &symLU, Direct::DirectPrecControl control) const
AdjPairTracked< tAdj1Pair > bnd2face
index CellFaceOther(index iCell, index iFace) const
tElemInfoArrayPair faceElemInfo
void SetPeriodicGeometry(const tPoint &translation1, const tPoint &rotationCenter1, const tPoint &eulerAngles1, const tPoint &translation2, const tPoint &rotationCenter2, const tPoint &eulerAngles2, const tPoint &translation3, const tPoint &rotationCenter3, const tPoint &eulerAngles3)
void BuildCell2CellFace()
void AdjGlobal2LocalC2CFace()
std::vector< index > localPartitionStarts
MeshAdjState adjFacialState
index BndIndexGlobal2Local(DNDS::index i)
AdjPairTracked< tAdjPair > cell2node
void RecoverCell2CellAndBnd2Cell()
needs to use RecoverNode2CellAndNode2Bnd before doing this. Requires node2cell.father and builds a ve...
void WriteSerialize(Serializer::SerializerBaseSSP serializerP, const std::string &name)
tElemInfoArrayPair cellElemInfo
AdjPairTracked< tAdjPair > node2bnd
index NumCellGhost() const
void AdjLocal2GlobalC2CFace()
static void PermuteRows(TPair &pair, index nRows, TFn &&old2new)
Permute the father rows of an ArrayPair according to a mapping function.
AdjPairTracked< tAdjPair > bnd2node
AdjPairTracked< tAdjPair > node2cell
inverse relations
void AdjGlobal2LocalFacial()
void ConstructBndMesh(UnstructuredMesh &bMesh)
tElemInfoArrayPair bndElemInfo
void AdjLocal2GlobalPrimaryForBnd()
void EnsureGhostMapping(TPair &pair)
Ensure a pair has a ghost mapping on its transformer.
AdjPairTracked< tAdj2Pair > bnd2cell
Lightweight bundle of an MPI communicator and the calling rank's coordinates.
int size
Number of ranks in comm (-1 until initialised).
int rank
This rank's 0-based index within comm (-1 until initialised).
MPI_Comm comm
The underlying MPI communicator handle.
Tag type for naming objects created via make_ssp.
std::vector< DNDS::index > ghostNodes(ghostNodeSet.begin(), ghostNodeSet.end())
std::unordered_map< DNDS::index, DNDS::index > nodeG2L
std::vector< GhostCell > ghostCells
solverDOF father pLGlobalMapping
const tPoint const tPoint const tPoint & p