45 : m_trace(trace), m_interface(interfaceShPtr), m_movement(movementShPtr)
57 : m_graph(meshGraph), m_movement(meshGraph->GetMovement()), m_trace(trace)
59 auto comm =
m_trace->GetComm()->GetSpaceComm();
60 auto interfaceCollection =
m_movement->GetInterfaces();
66 std::map<int, int> myIndxLRMap;
71 std::map<int, std::pair<InterfaceTraceSharedPtr, InterfaceTraceSharedPtr>>
81 for (
const auto &interface : interfaceCollection)
83 indxToInterfaceID[cnt] = interface.first.first;
84 myIndxLRMap[interface.first.first] = 0;
86 if (!interface.second->GetLeftInterface()->IsEmpty())
88 myIndxLRMap[interface.first.first] += 1;
90 localInterfaces[interface.first.first].first =
92 trace, interface.second->GetLeftInterface(),
m_movement);
94 localInterfaces[interface.first.first].first);
97 if (!interface.second->GetRightInterface()->IsEmpty())
99 myIndxLRMap[interface.first.first] += 2;
101 localInterfaces[interface.first.first].second =
103 trace, interface.second->GetRightInterface(),
m_movement);
105 localInterfaces[interface.first.first].second);
112 int nRanks = comm->GetSize();
117 for (
auto pres : myIndxLRMap)
119 interfaceEdges[cnt++] = pres.second;
122 comm->AllGather(interfaceEdges, rankLocalInterfaceIds);
125 std::map<int, std::vector<InterfaceTraceSharedPtr>> oppRankSharedInterface;
129 size_t myRank = comm->GetRank();
130 size_t numInterfaces = interfaceCollection.size();
131 for (
int i = 0; i < nRanks; ++i)
133 for (
size_t j = 0; j < numInterfaces; ++j)
135 int otherId = indxToInterfaceID[j];
139 int otherCode = rankLocalInterfaceIds[i * numInterfaces + j];
143 int myCode = myIndxLRMap[otherId];
151 localInterfaces[otherId].first->SetCheckLocal(
true);
152 localInterfaces[otherId].second->SetCheckLocal(
true);
159 if ((myCode == 1 && otherCode == 2) ||
160 (myCode == 1 && otherCode == 3) ||
161 (myCode == 3 && otherCode == 2))
163 oppRankSharedInterface[i].emplace_back(
164 localInterfaces[otherId].first);
167 else if ((myCode == 2 && otherCode == 1) ||
168 (myCode == 2 && otherCode == 3) ||
169 (myCode == 3 && otherCode == 1))
171 oppRankSharedInterface[i].emplace_back(
172 localInterfaces[otherId].second);
175 else if (myCode == 3 && otherCode == 3)
177 oppRankSharedInterface[i].emplace_back(
178 localInterfaces[otherId].first);
179 oppRankSharedInterface[i].emplace_back(
180 localInterfaces[otherId].second);
187 for (
auto &rank : oppRankSharedInterface)
203 auto comm =
m_trace->GetComm();
210 interfaceTrace->CalcLocalMissing();
221 auto requestSend = comm->CreateRequest(
m_exchange.size());
222 auto requestRecv = comm->CreateRequest(
m_exchange.size());
226 m_exchange[i]->RankFillSizes(requestSend, requestRecv, i);
228 comm->WaitAll(requestSend);
229 comm->WaitAll(requestRecv);
233 m_exchange[i]->SendMissing(requestSend, requestRecv, i);
235 comm->WaitAll(requestSend);
236 comm->WaitAll(requestRecv);
240 i->CalcRankDistances();
281 for (
auto &childId : childEdge)
283 auto childElmt =
m_trace->GetExpFromGeomId(childId.first);
284 size_t nq = childElmt->GetTotPoints();
286 childElmt->GetCoords(xc, yc, zc);
289 for (
int i = 0; i < nq; ++i, ++cnt)
326 for (
auto &childId : childEdge)
328 auto childElmt =
m_trace->GetExpFromGeomId(childId.first);
329 size_t nq = childElmt->GetTotPoints();
331 childElmt->GetCoords(xc, yc, zc);
334 for (
int i = 0; i < nq; ++i)
357 if (foundLocalCoordsCopy.find(offset + i) !=
358 foundLocalCoordsCopy.end())
360 auto edge =
m_interface->GetOppInterface()->GetEdge(
361 foundLocalCoordsCopy[offset + i].first);
362 NekDouble dist = edge->FindDistance(xs, foundLocCoord);
366 std::make_pair(edge->GetGlobalID(), foundLocCoord);
373 auto parentEdge =
m_interface->GetOppInterface()->GetEdge();
374 for (
auto &edge : parentEdge)
377 if (!edge.second->MinMaxCheck(xs))
383 edge.second->FindDistance(xs, foundLocCoord);
388 edge.second->GetGlobalID(), foundLocCoord);
408 " coordinates on interface ID " +
410 " linked to interface ID " +
411 std::to_string(
m_interface->GetOppInterface()->GetId()) +
412 ". Check both sides of the interface line up.");
431 m_zones[localInterface->GetInterface()->GetId()]->GetMoved();
440 if (
m_zones[interface->GetInterface()->GetId()]->GetMoved())
446 interface->GetMissingCoords().size() * 3;
452 requestSend, requestNum);
454 requestRecv, requestNum);
474 if (
m_zones[interface->GetInterface()->GetId()]->GetMoved())
476 auto missing = interface->GetMissingCoords();
477 for (
auto coord : missing)
481 for (
int k = 0; k < 3; ++k, ++cnt)
510 auto comm =
m_trace->GetComm();
518 m_localInterface->FillLocalBwdTrace(Fwd, Bwd);
523 auto requestSend = comm->CreateRequest(
m_exchange.size());
524 auto requestRecv = comm->CreateRequest(
m_exchange.size());
527 m_exchange[i]->SendFwdTrace(requestSend, requestRecv, i, Fwd);
533 m_localInterface->FillLocalBwdTrace(Fwd, Bwd);
536 comm->WaitAll(requestSend);
537 comm->WaitAll(requestRecv);
542 i->FillRankBwdTraceExchange(Bwd);
555 int traceId =
m_trace->GetElmtToExpId(foundLocCoord.second.first);
559 Fwd +
m_trace->GetPhys_Offset(traceId);
561 Bwd[foundLocCoord.first] =
562 m_trace->GetExp(traceId)->StdPhysEvaluate(locCoord, edgePhys);
573 for (
int i = 0; i < dim; ++i)
575 vecLocs[0][i] = 1 + i;
579 auto zone = std::static_pointer_cast<SpatialDomains::ZoneRotate>(zones[
id]);
586 int traceId = phyRotAngle.first;
590 for (
int i = 0; i < dim; ++i)
592 tmpVelocity[i] = Bwd[vecLocs[0][i]][traceId];
594 zone->Rotate(tmpVelocity, -angle);
595 for (
int i = 0; i < dim; ++i)
597 Bwd[vecLocs[0][i]][traceId] = tmpVelocity[i];
608 size_t nVariables = Bwd[0].size();
611 auto zone = std::static_pointer_cast<SpatialDomains::ZoneRotate>(zones[
id]);
613 auto axis = zone->GetAxis();
615 if (axis[0] == 0 && axis[1] == 0 && axis[2] == 1)
619 else if (axis[0] == 1 && axis[1] == 0 && axis[2] == 0)
623 else if (axis[0] == 0 && axis[1] == 1 && axis[2] == 0)
635 int traceId = phyRotAngle.first;
641 for (
int j = 0; j < dim; ++j)
644 for (
int i = 0; i < nVariables; ++i)
650 for (
int j = 0; j < dim; ++j)
652 for (
int i = 0; i < nVariables; ++i)
654 tmpBwd[j][i][0] = Bwd[j][i][traceId];
660 for (
int j = 0; j < dim; ++j)
662 for (
int i = 0; i < dim; ++i)
664 Bwd[j][i][traceId] = tmpBwd[j][i][0];
691 if (!std::isnan(trace[i]))
710 int traceId =
m_trace->GetElmtToExpId(i.second.first.second);
714 Fwd +
m_trace->GetPhys_Offset(traceId);
717 m_trace->GetExp(traceId)->StdPhysEvaluate(locCoord, edgePhys);
763 for (
int j = disp[i]; j < disp[i + 1]; j += 3)
772 if ((foundRankCoordsCopy.find(j / 3) !=
773 foundRankCoordsCopy.end()) &&
774 (foundRankCoordsCopy[j / 3].first.first == i))
777 foundRankCoordsCopy[j / 3].first.second);
778 NekDouble dist = edge->FindDistance(xs, foundLocCoord);
783 std::make_pair(i, edge->GetGlobalID()), foundLocCoord);
788 for (
auto &edge : localEdge)
791 if (!edge.second->MinMaxCheck(xs))
796 NekDouble dist = edge.second->FindDistance(xs, foundLocCoord);
801 std::make_pair(i, edge.second->GetGlobalID()),
815 int oppid =
m_interface->GetOppInterface()->GetId();
822 auto disp = zones[id]->v_GetDisp();
823 auto oppdisp = zones[oppid]->v_GetDisp();
828 if (zones[
id]->GetMovementType() ==
831 auto zone = std::static_pointer_cast<SpatialDomains::ZoneTranslate>(
833 box = zone->GetZoneBox();
834 length = zone->GetZoneLength();
836 else if (zones[oppid]->GetMovementType() ==
839 auto zone = std::static_pointer_cast<SpatialDomains::ZoneTranslate>(
841 box = zone->GetZoneBox();
842 length = zone->GetZoneLength();
850 for (
int i = 0; i < disp.size(); ++i)
854 ExactMove = std::fmod(disp[i], length[i]);
855 ExactOppMove = std::fmod(oppdisp[i], length[i]);
856 tmp = oppdisp[i] / length[i];
857 gloCoord[i] = gloCoord[i] - disp[i] + ExactMove;
860 if (oppdisp[i] - disp[i] < 0)
862 if (gloCoord[i] > box[i + 3] + ExactOppMove + 1e-8)
864 gloCoord[i] = gloCoord[i] - length[i] + tmp * length[i];
868 gloCoord[i] = gloCoord[i] + tmp * length[i];
873 if (gloCoord[i] < box[i] + ExactOppMove - 1e-8)
875 gloCoord[i] = gloCoord[i] + length[i] + tmp * length[i];
879 gloCoord[i] = gloCoord[i] + tmp * length[i];
889 std::static_pointer_cast<SpatialDomains::ZoneRotate>(zones[
id]);
891 std::static_pointer_cast<SpatialDomains::ZoneRotate>(zones[oppid]);
895 auto angle = zone->v_GetAngle();
896 auto oppAngle = zone2->v_GetAngle();
899 NekDouble SectorAngle = zone->GetSectorAngle();
912 angle = std::fmod(angle, 2 * M_PI);
917 oppAngle = std::fmod(oppAngle, 2 * M_PI);
920 oppAngle += 2 * M_PI;
924 ExactOppMove = std::fmod(oppAngle, SectorAngle);
925 tmp1 =
static_cast<int>(std::floor(angle / SectorAngle));
926 tmp2 =
static_cast<int>(std::floor(oppAngle / SectorAngle));
930 auto axis = zone->GetAxis();
932 if (axis[0] == 0 && axis[1] == 0 && axis[2] == 1)
934 diff = atan2(gloCoord[1], gloCoord[0]) - atan2(base[1], base[0]);
936 else if (axis[0] == 1 && axis[1] == 0 && axis[2] == 0)
938 diff = atan2(gloCoord[2], gloCoord[1]) - atan2(base[2], base[1]);
940 else if (axis[0] == 0 && axis[1] == 1 && axis[2] == 0)
942 diff = atan2(gloCoord[0], gloCoord[2]) - atan2(base[0], base[2]);
954 tmp3 =
static_cast<int>(std::floor(diff / SectorAngle));
958 NekDouble Exactdiff = std::fmod(diff, SectorAngle);
961 if (oppAngle - angle < 0)
963 if (ExactOppMove < Exactdiff && tmp3 != tmp1)
966 -SectorAngle + tmp2 * SectorAngle - tmp1 * SectorAngle;
968 zone->Rotate(gloCoord, RotateAngle);
972 RotateAngle = -tmp1 * SectorAngle + tmp2 * SectorAngle;
973 zone->Rotate(gloCoord, RotateAngle);
978 if (Exactdiff < ExactOppMove && tmp3 == tmp1)
981 SectorAngle + tmp2 * SectorAngle - tmp1 * SectorAngle;
982 zone->Rotate(gloCoord, RotateAngle);
986 RotateAngle = -tmp1 * SectorAngle + tmp2 * SectorAngle;
987 zone->Rotate(gloCoord, RotateAngle);
1044 "Invalid rotation axis for first-order derivative transformation.");
1051 gradU[0] = Bwd[0][1][0];
1052 gradU[3] = Bwd[1][1][0];
1053 gradU[6] = Bwd[2][1][0];
1055 gradU[1] = Bwd[0][2][0];
1056 gradU[4] = Bwd[1][2][0];
1057 gradU[7] = Bwd[2][2][0];
1059 gradU[2] = Bwd[0][3][0];
1060 gradU[5] = Bwd[1][3][0];
1061 gradU[8] = Bwd[2][3][0];
1068 Blas::Dgemm(
'N',
'N', 3, 3, 3, 1.0, R.data(), 3, gradU.data(), 3, 0.0,
1077 Blas::Dgemm(
'N',
'T', 3, 3, 3, 1.0, R_gradU.data(), 3, R.data(), 3, 0.0,
1078 gradU_rotated.data(), 3);
1081 Bwd[0][1][0] = gradU_rotated[0];
1082 Bwd[1][1][0] = gradU_rotated[3];
1083 Bwd[2][1][0] = gradU_rotated[6];
1085 Bwd[0][2][0] = gradU_rotated[1];
1086 Bwd[1][2][0] = gradU_rotated[4];
1087 Bwd[2][2][0] = gradU_rotated[7];
1089 Bwd[0][3][0] = gradU_rotated[2];
1090 Bwd[1][3][0] = gradU_rotated[5];
1091 Bwd[2][3][0] = gradU_rotated[8];
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
void AccumulateRegion(std::string, int iolevel=0)
Accumulate elapsed time for a region.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::map< int, Array< OneD, int > > m_sendSize
Map of rank to array of size of send buffer for each interface.
void RankFillSizes(LibUtilities::CommRequestSharedPtr &requestSend, LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum)
std::map< int, SpatialDomains::ZoneBaseShPtr > m_zones
Map of zone IDs to zone bases.
const ExpListSharedPtr m_trace
Trace expansion list.
void FillRankBwdTraceExchange(Array< OneD, NekDouble > &Bwd)
const std::vector< InterfaceTraceSharedPtr > m_interfaceTraces
Vector of interface traces i.e. every interface side present on m_rank.
const LibUtilities::CommSharedPtr m_comm
Communicator.
void SendFwdTrace(LibUtilities::CommRequestSharedPtr &requestSend, LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum, Array< OneD, NekDouble > &Fwd)
Array< OneD, NekDouble > m_send
Send buffer for coord exchange.
std::map< int, int > m_totSendSize
Map of rank to total size of send buffer for all interfaces.
void CalcRankDistances()
Populates m_foundRankCoords using the FindDistance function.
std::map< int, int > m_totRecvSize
Map of rank to total size of receive buffer for all interfaces.
std::map< int, Array< OneD, int > > m_recvSize
Map of rank to array of size of receive buffer for each interface.
Array< OneD, NekDouble > m_recv
Receive buffer for coord exchange.
void SendMissing(LibUtilities::CommRequestSharedPtr &requestSend, LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum)
Array< OneD, NekDouble > m_recvTrace
Receive buffer for trace exchange.
std::map< int, std::map< int, std::pair< std::pair< int, int >, Array< OneD, NekDouble > > > > m_foundRankCoords
Array< OneD, NekDouble > m_sendTrace
Send buffer for trace exchange.
const ExpListSharedPtr m_trace
Trace expansion list.
void ExchangeTrace(Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
Perform the trace exchange between processors, given the forwards and backwards spaces.
std::vector< InterfaceExchangeSharedPtr > m_exchange
Vector of interface exchanges, i.e. every rank-to-rank comm needed.
void ExchangeCoords()
Perform the coordinate exchange between processors. This is where the missing coordinates on the inte...
SpatialDomains::MovementSharedPtr m_movement
Movement object associated with the non-conformal interfaces.
InterfaceMapDG(const SpatialDomains::MeshGraphSharedPtr &graph, const ExpListSharedPtr &trace)
std::vector< InterfaceTraceSharedPtr > m_localInterfaces
Interface sides present on current process.
ExpListSharedPtr m_trace
Trace expansion list.
InterfaceTrace(const ExpListSharedPtr &trace, const SpatialDomains::InterfaceShPtr &interfaceShPtr, SpatialDomains::MovementSharedPtr movementShPtr)
Constructor.
void RotLocalBwdTrace(Array< OneD, Array< OneD, NekDouble > > &Bwd, const int &dim)
Rotates the interface velocity for sector rotation.
std::map< int, std::pair< int, Array< OneD, NekDouble > > > m_foundLocalCoords
Map of found coordinates present locally.
std::vector< int > m_mapMissingCoordToTrace
Vector of indices corresponding to m_missingCoord locations in trace.
SpatialDomains::InterfaceShPtr m_interface
Local interface object.
std::vector< Array< OneD, NekDouble > > m_missingCoords
Vector of coordinates on interface missing from the other side locally.
void DomainCheck(Array< OneD, NekDouble > &gloCoord, NekDouble &angle)
Update the coordiniates after movement.
void FillRankBwdTrace(Array< OneD, NekDouble > &trace, Array< OneD, NekDouble > &Bwd)
Fills the Bwd trace from partitioned trace.
void CalcLocalMissing()
Calculates what coordinates on the interface are missing locally.
void RotLocalBwdDeriveTrace(TensorOfArray3D< NekDouble > &Bwd, const int &dim)
Rotates the interface derivative velocity for sector rotation.
SpatialDomains::MovementSharedPtr m_movement
Movement object associated with the non-conformal interfaces.
std::map< int, std::pair< int, NekDouble > > m_phyRotAngle
Map of phy rotate angle for sector rotate interfaces.
void FillLocalBwdTrace(Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
Fills the Bwd trace by interpolating from the Fwd for local interfaces.
bool m_checkLocal
Flag whether the opposite side of the interface is present locally.
void DeriveRotate(TensorOfArray3D< NekDouble > &Bwd, const int dir, const NekDouble angle)
Rotate the 3D vector field in Bwd around the axis 'dir' by 'angle'.
static void Dgemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where op(A)[m x k], op(B)[k x n], C[m x n] DGEMM perfo...
std::shared_ptr< CommRequest > CommRequestSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
static const NekDouble kFindDistanceMin
std::shared_ptr< Interface > InterfaceShPtr
std::shared_ptr< Movement > MovementSharedPtr
std::shared_ptr< MeshGraph > MeshGraphSharedPtr