xref: /petsc/src/dm/impls/plex/plexcheckinterface.c (revision d8e47b638cf8f604a99e9678e1df24f82d959cd7)
1f84a5eb8SVaclav Hapla #include <petsc/private/dmpleximpl.h> /*I      "petscdmplex.h"   I*/
2f84a5eb8SVaclav Hapla 
3f84a5eb8SVaclav Hapla /* TODO PetscArrayExchangeBegin/End */
4f84a5eb8SVaclav Hapla /* TODO blocksize */
5f84a5eb8SVaclav Hapla /* TODO move to API ? */
ExchangeArrayByRank_Private(PetscObject obj,MPI_Datatype dt,PetscMPIInt nsranks,const PetscMPIInt sranks[],PetscInt ssize[],const void * sarr[],PetscMPIInt nrranks,const PetscMPIInt rranks[],PetscInt * rsize_out[],void ** rarr_out[])6*6497c311SBarry Smith static PetscErrorCode ExchangeArrayByRank_Private(PetscObject obj, MPI_Datatype dt, PetscMPIInt nsranks, const PetscMPIInt sranks[], PetscInt ssize[], const void *sarr[], PetscMPIInt nrranks, const PetscMPIInt rranks[], PetscInt *rsize_out[], void **rarr_out[])
7d71ae5a4SJacob Faibussowitsch {
8*6497c311SBarry Smith   PetscMPIInt  r;
9f84a5eb8SVaclav Hapla   PetscInt    *rsize;
10f84a5eb8SVaclav Hapla   void       **rarr;
11f84a5eb8SVaclav Hapla   MPI_Request *sreq, *rreq;
12f84a5eb8SVaclav Hapla   PetscMPIInt  tag, unitsize;
13f84a5eb8SVaclav Hapla   MPI_Comm     comm;
14f84a5eb8SVaclav Hapla 
15f84a5eb8SVaclav Hapla   PetscFunctionBegin;
169566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Type_size(dt, &unitsize));
179566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm(obj, &comm));
189566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(nrranks, &rsize, nrranks, &rarr));
199566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(nrranks, &rreq, nsranks, &sreq));
20f84a5eb8SVaclav Hapla   /* exchange array size */
219566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetNewTag(obj, &tag));
22*6497c311SBarry Smith   for (r = 0; r < nrranks; r++) PetscCallMPI(MPIU_Irecv(&rsize[r], 1, MPIU_INT, rranks[r], tag, comm, &rreq[r]));
23*6497c311SBarry Smith   for (r = 0; r < nsranks; r++) PetscCallMPI(MPIU_Isend(&ssize[r], 1, MPIU_INT, sranks[r], tag, comm, &sreq[r]));
249566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Waitall(nrranks, rreq, MPI_STATUSES_IGNORE));
259566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Waitall(nsranks, sreq, MPI_STATUSES_IGNORE));
26f84a5eb8SVaclav Hapla   /* exchange array */
279566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetNewTag(obj, &tag));
28f84a5eb8SVaclav Hapla   for (r = 0; r < nrranks; r++) {
299566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(rsize[r] * unitsize, &rarr[r]));
30*6497c311SBarry Smith     PetscCallMPI(MPIU_Irecv(rarr[r], rsize[r], dt, rranks[r], tag, comm, &rreq[r]));
31f84a5eb8SVaclav Hapla   }
32*6497c311SBarry Smith   for (r = 0; r < nsranks; r++) PetscCallMPI(MPIU_Isend(sarr[r], ssize[r], dt, sranks[r], tag, comm, &sreq[r]));
339566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Waitall(nrranks, rreq, MPI_STATUSES_IGNORE));
349566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Waitall(nsranks, sreq, MPI_STATUSES_IGNORE));
359566063dSJacob Faibussowitsch   PetscCall(PetscFree2(rreq, sreq));
36f84a5eb8SVaclav Hapla   *rsize_out = rsize;
37f84a5eb8SVaclav Hapla   *rarr_out  = rarr;
383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39f84a5eb8SVaclav Hapla }
40f84a5eb8SVaclav Hapla 
41f84a5eb8SVaclav Hapla /* TODO VecExchangeBegin/End */
42f84a5eb8SVaclav Hapla /* TODO move to API ? */
ExchangeVecByRank_Private(PetscObject obj,PetscMPIInt nsranks,const PetscMPIInt sranks[],Vec svecs[],PetscMPIInt nrranks,const PetscMPIInt rranks[],Vec * rvecs[])43*6497c311SBarry Smith static PetscErrorCode ExchangeVecByRank_Private(PetscObject obj, PetscMPIInt nsranks, const PetscMPIInt sranks[], Vec svecs[], PetscMPIInt nrranks, const PetscMPIInt rranks[], Vec *rvecs[])
44d71ae5a4SJacob Faibussowitsch {
45*6497c311SBarry Smith   PetscMPIInt         r;
46f84a5eb8SVaclav Hapla   PetscInt           *ssize, *rsize;
47f84a5eb8SVaclav Hapla   PetscScalar       **rarr;
48f84a5eb8SVaclav Hapla   const PetscScalar **sarr;
49f84a5eb8SVaclav Hapla   Vec                *rvecs_;
50f84a5eb8SVaclav Hapla   MPI_Request        *sreq, *rreq;
51f84a5eb8SVaclav Hapla 
52f84a5eb8SVaclav Hapla   PetscFunctionBegin;
539566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(nsranks, &ssize, nsranks, &sarr, nrranks, &rreq, nsranks, &sreq));
54f84a5eb8SVaclav Hapla   for (r = 0; r < nsranks; r++) {
559566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(svecs[r], &ssize[r]));
569566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(svecs[r], &sarr[r]));
57f84a5eb8SVaclav Hapla   }
589566063dSJacob Faibussowitsch   PetscCall(ExchangeArrayByRank_Private(obj, MPIU_SCALAR, nsranks, sranks, ssize, (const void **)sarr, nrranks, rranks, &rsize, (void ***)&rarr));
599566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(nrranks, &rvecs_));
60f84a5eb8SVaclav Hapla   for (r = 0; r < nrranks; r++) {
61f84a5eb8SVaclav Hapla     /* set array in two steps to mimic PETSC_OWN_POINTER */
629566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, rsize[r], NULL, &rvecs_[r]));
639566063dSJacob Faibussowitsch     PetscCall(VecReplaceArray(rvecs_[r], rarr[r]));
64f84a5eb8SVaclav Hapla   }
6548a46eb9SPierre Jolivet   for (r = 0; r < nsranks; r++) PetscCall(VecRestoreArrayRead(svecs[r], &sarr[r]));
669566063dSJacob Faibussowitsch   PetscCall(PetscFree2(rsize, rarr));
679566063dSJacob Faibussowitsch   PetscCall(PetscFree4(ssize, sarr, rreq, sreq));
68f84a5eb8SVaclav Hapla   *rvecs = rvecs_;
693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
70f84a5eb8SVaclav Hapla }
71f84a5eb8SVaclav Hapla 
SortByRemote_Private(PetscSF sf,PetscInt * rmine1[],PetscInt * rremote1[])72d71ae5a4SJacob Faibussowitsch static PetscErrorCode SortByRemote_Private(PetscSF sf, PetscInt *rmine1[], PetscInt *rremote1[])
73d71ae5a4SJacob Faibussowitsch {
74f84a5eb8SVaclav Hapla   PetscInt           nleaves;
75*6497c311SBarry Smith   PetscMPIInt        nranks;
76f84a5eb8SVaclav Hapla   const PetscMPIInt *ranks;
77f84a5eb8SVaclav Hapla   const PetscInt    *roffset, *rmine, *rremote;
78*6497c311SBarry Smith   PetscInt           n, o;
79f84a5eb8SVaclav Hapla 
80f84a5eb8SVaclav Hapla   PetscFunctionBegin;
819566063dSJacob Faibussowitsch   PetscCall(PetscSFGetRootRanks(sf, &nranks, &ranks, &roffset, &rmine, &rremote));
82f84a5eb8SVaclav Hapla   nleaves = roffset[nranks];
839566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(nleaves, rmine1, nleaves, rremote1));
84*6497c311SBarry Smith   for (PetscMPIInt r = 0; r < nranks; r++) {
85f84a5eb8SVaclav Hapla     /* simultaneously sort rank-wise portions of rmine & rremote by values in rremote
86f84a5eb8SVaclav Hapla        - to unify order with the other side */
87f84a5eb8SVaclav Hapla     o = roffset[r];
88f84a5eb8SVaclav Hapla     n = roffset[r + 1] - o;
899566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(&(*rmine1)[o], &rmine[o], n));
909566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(&(*rremote1)[o], &rremote[o], n));
919566063dSJacob Faibussowitsch     PetscCall(PetscSortIntWithArray(n, &(*rremote1)[o], &(*rmine1)[o]));
92f84a5eb8SVaclav Hapla   }
933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
94f84a5eb8SVaclav Hapla }
95f84a5eb8SVaclav Hapla 
GetRecursiveConeCoordinatesPerRank_Private(DM dm,PetscSF sf,PetscInt rmine[],Vec * coordinatesPerRank[])96d71ae5a4SJacob Faibussowitsch static PetscErrorCode GetRecursiveConeCoordinatesPerRank_Private(DM dm, PetscSF sf, PetscInt rmine[], Vec *coordinatesPerRank[])
97d71ae5a4SJacob Faibussowitsch {
98f84a5eb8SVaclav Hapla   IS                 pointsPerRank, conesPerRank;
99*6497c311SBarry Smith   PetscMPIInt        nranks;
100f84a5eb8SVaclav Hapla   const PetscMPIInt *ranks;
101f84a5eb8SVaclav Hapla   const PetscInt    *roffset;
102*6497c311SBarry Smith   PetscInt           n, o;
103f84a5eb8SVaclav Hapla 
104f84a5eb8SVaclav Hapla   PetscFunctionBegin;
1059566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinatesLocalSetUp(dm));
1069566063dSJacob Faibussowitsch   PetscCall(PetscSFGetRootRanks(sf, &nranks, &ranks, &roffset, NULL, NULL));
1079566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(nranks, coordinatesPerRank));
108*6497c311SBarry Smith   for (PetscMPIInt r = 0; r < nranks; r++) {
109f84a5eb8SVaclav Hapla     o = roffset[r];
110f84a5eb8SVaclav Hapla     n = roffset[r + 1] - o;
1119566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, n, &rmine[o], PETSC_USE_POINTER, &pointsPerRank));
1129566063dSJacob Faibussowitsch     PetscCall(DMPlexGetConeRecursiveVertices(dm, pointsPerRank, &conesPerRank));
1139566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinatesLocalTuple(dm, conesPerRank, NULL, &(*coordinatesPerRank)[r]));
1149566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&pointsPerRank));
1159566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&conesPerRank));
116f84a5eb8SVaclav Hapla   }
1173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
118f84a5eb8SVaclav Hapla }
119f84a5eb8SVaclav Hapla 
PetscSFComputeMultiRootOriginalNumberingByRank_Private(PetscSF sf,PetscSF imsf,PetscInt * irmine1[])120d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFComputeMultiRootOriginalNumberingByRank_Private(PetscSF sf, PetscSF imsf, PetscInt *irmine1[])
121d71ae5a4SJacob Faibussowitsch {
122f84a5eb8SVaclav Hapla   PetscInt       *mRootsOrigNumbering;
123*6497c311SBarry Smith   PetscMPIInt     niranks;
124*6497c311SBarry Smith   PetscInt        nileaves;
125f84a5eb8SVaclav Hapla   const PetscInt *iroffset, *irmine, *degree;
126*6497c311SBarry Smith   PetscInt        n, o;
127f84a5eb8SVaclav Hapla 
128f84a5eb8SVaclav Hapla   PetscFunctionBegin;
1299566063dSJacob Faibussowitsch   PetscCall(PetscSFGetGraph(imsf, NULL, &nileaves, NULL, NULL));
1309566063dSJacob Faibussowitsch   PetscCall(PetscSFGetRootRanks(imsf, &niranks, NULL, &iroffset, &irmine, NULL));
13108401ef6SPierre Jolivet   PetscCheck(nileaves == iroffset[niranks], PETSC_COMM_SELF, PETSC_ERR_PLIB, "nileaves != iroffset[niranks])");
1329566063dSJacob Faibussowitsch   PetscCall(PetscSFComputeDegreeBegin(sf, &degree));
1339566063dSJacob Faibussowitsch   PetscCall(PetscSFComputeDegreeEnd(sf, &degree));
1349566063dSJacob Faibussowitsch   PetscCall(PetscSFComputeMultiRootOriginalNumbering(sf, degree, NULL, &mRootsOrigNumbering));
1359566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(nileaves, irmine1));
136*6497c311SBarry Smith   for (PetscMPIInt r = 0; r < niranks; r++) {
137f84a5eb8SVaclav Hapla     o = iroffset[r];
138f84a5eb8SVaclav Hapla     n = iroffset[r + 1] - o;
139*6497c311SBarry Smith     for (PetscInt i = 0; i < n; i++) (*irmine1)[o + i] = mRootsOrigNumbering[irmine[o + i]];
140f84a5eb8SVaclav Hapla   }
1419566063dSJacob Faibussowitsch   PetscCall(PetscFree(mRootsOrigNumbering));
1423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
143f84a5eb8SVaclav Hapla }
144f84a5eb8SVaclav Hapla 
145124f9872SVaclav Hapla /*@
146a8432d5bSVaclav Hapla   DMPlexCheckInterfaceCones - Check that points on inter-partition interfaces have conforming order of cone points.
147124f9872SVaclav Hapla 
1482fe279fdSBarry Smith   Input Parameter:
149a1cb98faSBarry Smith . dm - The `DMPLEX` object
150a1cb98faSBarry Smith 
151a1cb98faSBarry Smith   Level: developer
152124f9872SVaclav Hapla 
153a8432d5bSVaclav Hapla   Notes:
1540b87013fSBarry Smith   For example, if there is an edge (rank,index)=(0,2) connecting points cone(0,2)=[(0,0),(0,1)] in this order, and the point `PetscSF` contains connections 0 <- (1,0), 1 <- (1,1) and 2 <- (1,2),
155a8432d5bSVaclav Hapla   then this check would pass if the edge (1,2) has cone(1,2)=[(1,0),(1,1)]. By contrast, if cone(1,2)=[(1,1),(1,0)], then this check would fail.
156124f9872SVaclav Hapla 
157a1cb98faSBarry Smith   This is mainly intended for debugging/testing purposes. Does not check cone orientation, for this purpose use `DMPlexCheckFaces()`.
158a8432d5bSVaclav Hapla 
159a1cb98faSBarry Smith   For the complete list of DMPlexCheck* functions, see `DMSetFromOptions()`.
16095eb5ee5SVaclav Hapla 
16160225df5SJacob Faibussowitsch   Developer Notes:
162a8432d5bSVaclav Hapla   Interface cones are expanded into vertices and then their coordinates are compared.
163124f9872SVaclav Hapla 
1641cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexGetCone()`, `DMPlexGetConeSize()`, `DMGetPointSF()`, `DMGetCoordinates()`, `DMSetFromOptions()`
165124f9872SVaclav Hapla @*/
DMPlexCheckInterfaceCones(DM dm)166d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexCheckInterfaceCones(DM dm)
167d71ae5a4SJacob Faibussowitsch {
168f84a5eb8SVaclav Hapla   PetscSF            sf;
169*6497c311SBarry Smith   PetscInt           nleaves, nroots;
170*6497c311SBarry Smith   PetscMPIInt        nranks;
171f84a5eb8SVaclav Hapla   const PetscInt    *mine, *roffset, *rmine, *rremote;
172f84a5eb8SVaclav Hapla   const PetscSFNode *remote;
173f84a5eb8SVaclav Hapla   const PetscMPIInt *ranks;
174f84a5eb8SVaclav Hapla   PetscSF            msf, imsf;
175*6497c311SBarry Smith   PetscMPIInt        niranks;
176*6497c311SBarry Smith   PetscInt           nileaves;
177f84a5eb8SVaclav Hapla   const PetscMPIInt *iranks;
178f84a5eb8SVaclav Hapla   const PetscInt    *iroffset, *irmine, *irremote;
179f84a5eb8SVaclav Hapla   PetscInt          *rmine1, *rremote1; /* rmine and rremote copies simultaneously sorted by rank and rremote */
180f84a5eb8SVaclav Hapla   PetscInt          *mine_orig_numbering;
181f84a5eb8SVaclav Hapla   Vec               *sntCoordinatesPerRank;
182f84a5eb8SVaclav Hapla   Vec               *refCoordinatesPerRank;
183ea78f98cSLisandro Dalcin   Vec               *recCoordinatesPerRank = NULL;
184f84a5eb8SVaclav Hapla   PetscInt           r;
1850b87013fSBarry Smith   PetscMPIInt        size, rank;
186f84a5eb8SVaclav Hapla   PetscBool          same;
1878f2c89e7SVaclav Hapla   PetscBool          verbose = PETSC_FALSE;
188f84a5eb8SVaclav Hapla   MPI_Comm           comm;
189f84a5eb8SVaclav Hapla 
190f84a5eb8SVaclav Hapla   PetscFunctionBegin;
19110b92ba9SVaclav Hapla   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1929566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
1930b87013fSBarry Smith   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1940b87013fSBarry Smith   PetscCallMPI(MPI_Comm_size(comm, &size));
1950b87013fSBarry Smith   if (size < 2) PetscFunctionReturn(PETSC_SUCCESS);
1969566063dSJacob Faibussowitsch   PetscCall(DMGetPointSF(dm, &sf));
1973ba16761SJacob Faibussowitsch   if (!sf) PetscFunctionReturn(PETSC_SUCCESS);
1989566063dSJacob Faibussowitsch   PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &mine, &remote));
1993ba16761SJacob Faibussowitsch   if (nroots < 0) PetscFunctionReturn(PETSC_SUCCESS);
2006858538eSMatthew G. Knepley   PetscCheck(dm->coordinates[0].x || dm->coordinates[0].xl, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM coordinates must be set");
2019566063dSJacob Faibussowitsch   PetscCall(PetscSFSetUp(sf));
2029566063dSJacob Faibussowitsch   PetscCall(PetscSFGetRootRanks(sf, &nranks, &ranks, &roffset, &rmine, &rremote));
203f84a5eb8SVaclav Hapla 
204f84a5eb8SVaclav Hapla   /* Expand sent cones per rank */
2059566063dSJacob Faibussowitsch   PetscCall(SortByRemote_Private(sf, &rmine1, &rremote1));
2069566063dSJacob Faibussowitsch   PetscCall(GetRecursiveConeCoordinatesPerRank_Private(dm, sf, rmine1, &sntCoordinatesPerRank));
207f84a5eb8SVaclav Hapla 
208f84a5eb8SVaclav Hapla   /* Create inverse SF */
2099566063dSJacob Faibussowitsch   PetscCall(PetscSFGetMultiSF(sf, &msf));
2109566063dSJacob Faibussowitsch   PetscCall(PetscSFCreateInverseSF(msf, &imsf));
2119566063dSJacob Faibussowitsch   PetscCall(PetscSFSetUp(imsf));
2129566063dSJacob Faibussowitsch   PetscCall(PetscSFGetGraph(imsf, NULL, &nileaves, NULL, NULL));
2139566063dSJacob Faibussowitsch   PetscCall(PetscSFGetRootRanks(imsf, &niranks, &iranks, &iroffset, &irmine, &irremote));
214f84a5eb8SVaclav Hapla 
215f84a5eb8SVaclav Hapla   /* Compute original numbering of multi-roots (referenced points) */
2169566063dSJacob Faibussowitsch   PetscCall(PetscSFComputeMultiRootOriginalNumberingByRank_Private(sf, imsf, &mine_orig_numbering));
217f84a5eb8SVaclav Hapla 
218124f9872SVaclav Hapla   /* Expand coordinates of the referred cones per rank */
2199566063dSJacob Faibussowitsch   PetscCall(GetRecursiveConeCoordinatesPerRank_Private(dm, imsf, mine_orig_numbering, &refCoordinatesPerRank));
220f84a5eb8SVaclav Hapla 
221f84a5eb8SVaclav Hapla   /* Send the coordinates */
2229566063dSJacob Faibussowitsch   PetscCall(ExchangeVecByRank_Private((PetscObject)sf, nranks, ranks, sntCoordinatesPerRank, niranks, iranks, &recCoordinatesPerRank));
223f84a5eb8SVaclav Hapla 
2248f2c89e7SVaclav Hapla   /* verbose output */
2259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)dm)->options, ((PetscObject)dm)->prefix, "-dm_plex_check_cones_conform_on_interfaces_verbose", &verbose, NULL));
2268f2c89e7SVaclav Hapla   if (verbose) {
2279f27a777SBarry Smith     PetscViewer sv, v = PETSC_VIEWER_STDOUT_WORLD;
2289566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "============\nDMPlexCheckInterfaceCones output\n============\n"));
2299566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushSynchronized(v));
2300b87013fSBarry Smith     PetscCall(PetscViewerASCIISynchronizedPrintf(v, "[%d] --------\n", rank));
231455082e2SBarry Smith     for (r = 0; r < size; r++) {
232455082e2SBarry Smith       if (r < nranks) {
23363a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(v, "  r=%" PetscInt_FMT " ranks[r]=%d sntCoordinatesPerRank[r]:\n", r, ranks[r]));
2349566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPushTab(v));
2359566063dSJacob Faibussowitsch         PetscCall(PetscViewerGetSubViewer(v, PETSC_COMM_SELF, &sv));
2369566063dSJacob Faibussowitsch         PetscCall(VecView(sntCoordinatesPerRank[r], sv));
2379566063dSJacob Faibussowitsch         PetscCall(PetscViewerRestoreSubViewer(v, PETSC_COMM_SELF, &sv));
2389566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPopTab(v));
239455082e2SBarry Smith       } else {
240455082e2SBarry Smith         PetscCall(PetscViewerGetSubViewer(v, PETSC_COMM_SELF, &sv));
241455082e2SBarry Smith         PetscCall(PetscViewerRestoreSubViewer(v, PETSC_COMM_SELF, &sv));
242455082e2SBarry Smith       }
2438f2c89e7SVaclav Hapla     }
2449566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISynchronizedPrintf(v, "  ----------\n"));
245455082e2SBarry Smith     for (r = 0; r < size; r++) {
246455082e2SBarry Smith       if (r < niranks) {
24763a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(v, "  r=%" PetscInt_FMT " iranks[r]=%d refCoordinatesPerRank[r]:\n", r, iranks[r]));
2489566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPushTab(v));
2499566063dSJacob Faibussowitsch         PetscCall(PetscViewerGetSubViewer(v, PETSC_COMM_SELF, &sv));
2509566063dSJacob Faibussowitsch         PetscCall(VecView(refCoordinatesPerRank[r], sv));
2519566063dSJacob Faibussowitsch         PetscCall(PetscViewerRestoreSubViewer(v, PETSC_COMM_SELF, &sv));
2529566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPopTab(v));
253455082e2SBarry Smith       } else {
254455082e2SBarry Smith         PetscCall(PetscViewerGetSubViewer(v, PETSC_COMM_SELF, &sv));
255455082e2SBarry Smith         PetscCall(PetscViewerRestoreSubViewer(v, PETSC_COMM_SELF, &sv));
256455082e2SBarry Smith       }
2578f2c89e7SVaclav Hapla     }
2589566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISynchronizedPrintf(v, "  ----------\n"));
259455082e2SBarry Smith     for (r = 0; r < size; r++) {
260455082e2SBarry Smith       if (r < niranks) {
26163a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(v, "  r=%" PetscInt_FMT " iranks[r]=%d recCoordinatesPerRank[r]:\n", r, iranks[r]));
2629566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPushTab(v));
2639566063dSJacob Faibussowitsch         PetscCall(PetscViewerGetSubViewer(v, PETSC_COMM_SELF, &sv));
2649566063dSJacob Faibussowitsch         PetscCall(VecView(recCoordinatesPerRank[r], sv));
2659566063dSJacob Faibussowitsch         PetscCall(PetscViewerRestoreSubViewer(v, PETSC_COMM_SELF, &sv));
2669566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPopTab(v));
267455082e2SBarry Smith       } else {
268455082e2SBarry Smith         PetscCall(PetscViewerGetSubViewer(v, PETSC_COMM_SELF, &sv));
269455082e2SBarry Smith         PetscCall(PetscViewerRestoreSubViewer(v, PETSC_COMM_SELF, &sv));
2708f2c89e7SVaclav Hapla       }
271455082e2SBarry Smith     }
2729566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopSynchronized(v));
2738f2c89e7SVaclav Hapla   }
2748f2c89e7SVaclav Hapla 
275f84a5eb8SVaclav Hapla   /* Compare recCoordinatesPerRank with refCoordinatesPerRank */
276f84a5eb8SVaclav Hapla   for (r = 0; r < niranks; r++) {
2779566063dSJacob Faibussowitsch     PetscCall(VecEqual(refCoordinatesPerRank[r], recCoordinatesPerRank[r], &same));
27828b400f6SJacob Faibussowitsch     PetscCheck(same, PETSC_COMM_SELF, PETSC_ERR_PLIB, "interface cones do not conform for remote rank %d", iranks[r]);
279f84a5eb8SVaclav Hapla   }
280f84a5eb8SVaclav Hapla 
281f84a5eb8SVaclav Hapla   /* destroy sent stuff */
28248a46eb9SPierre Jolivet   for (r = 0; r < nranks; r++) PetscCall(VecDestroy(&sntCoordinatesPerRank[r]));
2839566063dSJacob Faibussowitsch   PetscCall(PetscFree(sntCoordinatesPerRank));
2849566063dSJacob Faibussowitsch   PetscCall(PetscFree2(rmine1, rremote1));
2859566063dSJacob Faibussowitsch   PetscCall(PetscSFDestroy(&imsf));
286f84a5eb8SVaclav Hapla 
287f84a5eb8SVaclav Hapla   /* destroy referenced stuff */
28848a46eb9SPierre Jolivet   for (r = 0; r < niranks; r++) PetscCall(VecDestroy(&refCoordinatesPerRank[r]));
2899566063dSJacob Faibussowitsch   PetscCall(PetscFree(refCoordinatesPerRank));
2909566063dSJacob Faibussowitsch   PetscCall(PetscFree(mine_orig_numbering));
291f84a5eb8SVaclav Hapla 
292f84a5eb8SVaclav Hapla   /* destroy received stuff */
29348a46eb9SPierre Jolivet   for (r = 0; r < niranks; r++) PetscCall(VecDestroy(&recCoordinatesPerRank[r]));
2949566063dSJacob Faibussowitsch   PetscCall(PetscFree(recCoordinatesPerRank));
2953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
296f84a5eb8SVaclav Hapla }
297