xref: /petsc/src/dm/impls/plex/plexcheckinterface.c (revision 95eb5ee5c5d2f83bb36f76a91594565dde554348)
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 ? */
6f84a5eb8SVaclav Hapla static PetscErrorCode ExchangeArrayByRank_Private(PetscObject obj, MPI_Datatype dt, PetscInt nsranks, const PetscMPIInt sranks[], PetscInt ssize[], const void *sarr[], PetscInt nrranks, const PetscMPIInt rranks[], PetscInt *rsize_out[], void **rarr_out[])
7f84a5eb8SVaclav Hapla {
8f84a5eb8SVaclav Hapla   PetscInt 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   PetscErrorCode ierr;
15f84a5eb8SVaclav Hapla 
16f84a5eb8SVaclav Hapla   PetscFunctionBegin;
17f84a5eb8SVaclav Hapla   ierr = MPI_Type_size(dt, &unitsize);CHKERRQ(ierr);
18f84a5eb8SVaclav Hapla   ierr = PetscObjectGetComm(obj, &comm);CHKERRQ(ierr);
19f84a5eb8SVaclav Hapla   ierr = PetscMalloc2(nrranks, &rsize, nrranks, &rarr);CHKERRQ(ierr);
20f84a5eb8SVaclav Hapla   ierr = PetscMalloc2(nrranks, &rreq, nsranks, &sreq);CHKERRQ(ierr);
21f84a5eb8SVaclav Hapla   /* exchange array size */
22f84a5eb8SVaclav Hapla   ierr = PetscObjectGetNewTag(obj,&tag);CHKERRQ(ierr);
23f84a5eb8SVaclav Hapla   for (r=0; r<nrranks; r++) {
24f84a5eb8SVaclav Hapla     ierr = MPI_Irecv(&rsize[r], 1, MPIU_INT, rranks[r], tag, comm, &rreq[r]);CHKERRQ(ierr);
25f84a5eb8SVaclav Hapla   }
26f84a5eb8SVaclav Hapla   for (r=0; r<nsranks; r++) {
27f84a5eb8SVaclav Hapla     ierr = MPI_Isend(&ssize[r], 1, MPIU_INT, sranks[r], tag, comm, &sreq[r]);CHKERRQ(ierr);
28f84a5eb8SVaclav Hapla   }
29f84a5eb8SVaclav Hapla   ierr = MPI_Waitall(nrranks, rreq, MPI_STATUSES_IGNORE);CHKERRQ(ierr);
3014ab0c22SVaclav Hapla   ierr = MPI_Waitall(nsranks, sreq, MPI_STATUSES_IGNORE);CHKERRQ(ierr);
31f84a5eb8SVaclav Hapla   /* exchange array */
32f84a5eb8SVaclav Hapla   ierr = PetscObjectGetNewTag(obj,&tag);CHKERRQ(ierr);
33f84a5eb8SVaclav Hapla   for (r=0; r<nrranks; r++) {
34f84a5eb8SVaclav Hapla     ierr = PetscMalloc(rsize[r]*unitsize, &rarr[r]);CHKERRQ(ierr);
35f84a5eb8SVaclav Hapla     ierr = MPI_Irecv(rarr[r], rsize[r], dt, rranks[r], tag, comm, &rreq[r]);CHKERRQ(ierr);
36f84a5eb8SVaclav Hapla   }
37f84a5eb8SVaclav Hapla   for (r=0; r<nsranks; r++) {
38f84a5eb8SVaclav Hapla     ierr = MPI_Isend(sarr[r], ssize[r], dt, sranks[r], tag, comm, &sreq[r]);CHKERRQ(ierr);
39f84a5eb8SVaclav Hapla   }
40f84a5eb8SVaclav Hapla   ierr = MPI_Waitall(nrranks, rreq, MPI_STATUSES_IGNORE);CHKERRQ(ierr);
41f84a5eb8SVaclav Hapla   ierr = MPI_Waitall(nsranks, sreq, MPI_STATUSES_IGNORE);CHKERRQ(ierr);
42f84a5eb8SVaclav Hapla   ierr = PetscFree2(rreq, sreq);CHKERRQ(ierr);
43f84a5eb8SVaclav Hapla   *rsize_out = rsize;
44f84a5eb8SVaclav Hapla   *rarr_out = rarr;
45f84a5eb8SVaclav Hapla   PetscFunctionReturn(0);
46f84a5eb8SVaclav Hapla }
47f84a5eb8SVaclav Hapla 
48f84a5eb8SVaclav Hapla /* TODO VecExchangeBegin/End */
49f84a5eb8SVaclav Hapla /* TODO move to API ? */
50f84a5eb8SVaclav Hapla static PetscErrorCode ExchangeVecByRank_Private(PetscObject obj, PetscInt nsranks, const PetscMPIInt sranks[], Vec svecs[], PetscInt nrranks, const PetscMPIInt rranks[], Vec *rvecs[])
51f84a5eb8SVaclav Hapla {
52f84a5eb8SVaclav Hapla   PetscInt r;
53f84a5eb8SVaclav Hapla   PetscInt *ssize, *rsize;
54f84a5eb8SVaclav Hapla   PetscScalar **rarr;
55f84a5eb8SVaclav Hapla   const PetscScalar **sarr;
56f84a5eb8SVaclav Hapla   Vec *rvecs_;
57f84a5eb8SVaclav Hapla   MPI_Request *sreq, *rreq;
58f84a5eb8SVaclav Hapla   PetscErrorCode ierr;
59f84a5eb8SVaclav Hapla 
60f84a5eb8SVaclav Hapla   PetscFunctionBegin;
61f84a5eb8SVaclav Hapla   ierr = PetscMalloc4(nsranks, &ssize, nsranks, &sarr, nrranks, &rreq, nsranks, &sreq);CHKERRQ(ierr);
62f84a5eb8SVaclav Hapla   for (r=0; r<nsranks; r++) {
63f84a5eb8SVaclav Hapla     ierr = VecGetLocalSize(svecs[r], &ssize[r]);CHKERRQ(ierr);
64f84a5eb8SVaclav Hapla     ierr = VecGetArrayRead(svecs[r], &sarr[r]);CHKERRQ(ierr);
65f84a5eb8SVaclav Hapla   }
66f84a5eb8SVaclav Hapla   ierr = ExchangeArrayByRank_Private(obj, MPIU_SCALAR, nsranks, sranks, ssize, (const void**)sarr, nrranks, rranks, &rsize, (void***)&rarr);CHKERRQ(ierr);
67f84a5eb8SVaclav Hapla   ierr = PetscMalloc1(nrranks, &rvecs_);CHKERRQ(ierr);
68f84a5eb8SVaclav Hapla   for (r=0; r<nrranks; r++) {
69f84a5eb8SVaclav Hapla     /* set array in two steps to mimic PETSC_OWN_POINTER */
70f84a5eb8SVaclav Hapla     ierr = VecCreateSeqWithArray(PETSC_COMM_SELF, 1, rsize[r], NULL, &rvecs_[r]);CHKERRQ(ierr);
71f84a5eb8SVaclav Hapla     ierr = VecReplaceArray(rvecs_[r], rarr[r]);CHKERRQ(ierr);
72f84a5eb8SVaclav Hapla   }
73f84a5eb8SVaclav Hapla   for (r=0; r<nsranks; r++) {
74f84a5eb8SVaclav Hapla     ierr = VecRestoreArrayRead(svecs[r], &sarr[r]);CHKERRQ(ierr);
75f84a5eb8SVaclav Hapla   }
76f84a5eb8SVaclav Hapla   ierr = PetscFree2(rsize, rarr);CHKERRQ(ierr);
77f84a5eb8SVaclav Hapla   ierr = PetscFree4(ssize, sarr, rreq, sreq);CHKERRQ(ierr);
78f84a5eb8SVaclav Hapla   *rvecs = rvecs_;
79f84a5eb8SVaclav Hapla   PetscFunctionReturn(0);
80f84a5eb8SVaclav Hapla }
81f84a5eb8SVaclav Hapla 
82f84a5eb8SVaclav Hapla static PetscErrorCode SortByRemote_Private(PetscSF sf, PetscInt *rmine1[], PetscInt *rremote1[])
83f84a5eb8SVaclav Hapla {
84f84a5eb8SVaclav Hapla   PetscInt            nleaves;
85f84a5eb8SVaclav Hapla   PetscInt            nranks;
86f84a5eb8SVaclav Hapla   const PetscMPIInt   *ranks;
87f84a5eb8SVaclav Hapla   const PetscInt      *roffset, *rmine, *rremote;
88f84a5eb8SVaclav Hapla   PetscInt            n, o, r;
89f84a5eb8SVaclav Hapla   PetscErrorCode      ierr;
90f84a5eb8SVaclav Hapla 
91f84a5eb8SVaclav Hapla   PetscFunctionBegin;
92dec1416fSJunchao Zhang   ierr = PetscSFGetRootRanks(sf, &nranks, &ranks, &roffset, &rmine, &rremote);CHKERRQ(ierr);
93f84a5eb8SVaclav Hapla   nleaves = roffset[nranks];
94f84a5eb8SVaclav Hapla   ierr = PetscMalloc2(nleaves, rmine1, nleaves, rremote1);CHKERRQ(ierr);
95f84a5eb8SVaclav Hapla   for (r=0; r<nranks; r++) {
96f84a5eb8SVaclav Hapla     /* simultaneously sort rank-wise portions of rmine & rremote by values in rremote
97f84a5eb8SVaclav Hapla        - to unify order with the other side */
98f84a5eb8SVaclav Hapla     o = roffset[r];
99f84a5eb8SVaclav Hapla     n = roffset[r+1] - o;
100580bdb30SBarry Smith     ierr = PetscArraycpy(&(*rmine1)[o], &rmine[o], n);CHKERRQ(ierr);
101580bdb30SBarry Smith     ierr = PetscArraycpy(&(*rremote1)[o], &rremote[o], n);CHKERRQ(ierr);
102f84a5eb8SVaclav Hapla     ierr = PetscSortIntWithArray(n, &(*rremote1)[o], &(*rmine1)[o]);CHKERRQ(ierr);
103f84a5eb8SVaclav Hapla   }
104f84a5eb8SVaclav Hapla   PetscFunctionReturn(0);
105f84a5eb8SVaclav Hapla }
106f84a5eb8SVaclav Hapla 
107f84a5eb8SVaclav Hapla static PetscErrorCode GetRecursiveConeCoordinatesPerRank_Private(DM dm, PetscSF sf, PetscInt rmine[], Vec *coordinatesPerRank[])
108f84a5eb8SVaclav Hapla {
109f84a5eb8SVaclav Hapla   IS                  pointsPerRank, conesPerRank;
110f84a5eb8SVaclav Hapla   PetscInt            nranks;
111f84a5eb8SVaclav Hapla   const PetscMPIInt   *ranks;
112f84a5eb8SVaclav Hapla   const PetscInt      *roffset;
113f84a5eb8SVaclav Hapla   PetscInt            n, o, r;
114f84a5eb8SVaclav Hapla   PetscErrorCode      ierr;
115f84a5eb8SVaclav Hapla 
116f84a5eb8SVaclav Hapla   PetscFunctionBegin;
117f84a5eb8SVaclav Hapla   ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr);
118dec1416fSJunchao Zhang   ierr = PetscSFGetRootRanks(sf, &nranks, &ranks, &roffset, NULL, NULL);CHKERRQ(ierr);
119f84a5eb8SVaclav Hapla   ierr = PetscMalloc1(nranks, coordinatesPerRank);CHKERRQ(ierr);
120f84a5eb8SVaclav Hapla   for (r=0; r<nranks; r++) {
121f84a5eb8SVaclav Hapla     o = roffset[r];
122f84a5eb8SVaclav Hapla     n = roffset[r+1] - o;
123f84a5eb8SVaclav Hapla     ierr = ISCreateGeneral(PETSC_COMM_SELF, n, &rmine[o], PETSC_USE_POINTER, &pointsPerRank);CHKERRQ(ierr);
124af9eab45SVaclav Hapla     ierr = DMPlexGetConeRecursiveVertices(dm, pointsPerRank, &conesPerRank);CHKERRQ(ierr);
125f84a5eb8SVaclav Hapla     ierr = DMGetCoordinatesLocalTuple(dm, conesPerRank, NULL, &(*coordinatesPerRank)[r]);CHKERRQ(ierr);
126f84a5eb8SVaclav Hapla     ierr = ISDestroy(&pointsPerRank);CHKERRQ(ierr);
127f84a5eb8SVaclav Hapla     ierr = ISDestroy(&conesPerRank);CHKERRQ(ierr);
128f84a5eb8SVaclav Hapla   }
129f84a5eb8SVaclav Hapla   PetscFunctionReturn(0);
130f84a5eb8SVaclav Hapla }
131f84a5eb8SVaclav Hapla 
132f84a5eb8SVaclav Hapla static PetscErrorCode PetscSFComputeMultiRootOriginalNumberingByRank_Private(PetscSF sf, PetscSF imsf, PetscInt *irmine1[])
133f84a5eb8SVaclav Hapla {
134f84a5eb8SVaclav Hapla   PetscInt            *mRootsOrigNumbering;
135f84a5eb8SVaclav Hapla   PetscInt            nileaves, niranks;
136f84a5eb8SVaclav Hapla   const PetscInt      *iroffset, *irmine, *degree;
137f84a5eb8SVaclav Hapla   PetscInt            i, n, o, r;
138f84a5eb8SVaclav Hapla   PetscErrorCode      ierr;
139f84a5eb8SVaclav Hapla 
140f84a5eb8SVaclav Hapla   PetscFunctionBegin;
141f84a5eb8SVaclav Hapla   ierr = PetscSFGetGraph(imsf, NULL, &nileaves, NULL, NULL);CHKERRQ(ierr);
142dec1416fSJunchao Zhang   ierr = PetscSFGetRootRanks(imsf, &niranks, NULL, &iroffset, &irmine, NULL);CHKERRQ(ierr);
143f84a5eb8SVaclav Hapla #if defined(PETSC_USE_DEBUG)
144f84a5eb8SVaclav Hapla   if (PetscUnlikely(nileaves != iroffset[niranks])) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"nileaves != iroffset[niranks])");
145f84a5eb8SVaclav Hapla #endif
146f84a5eb8SVaclav Hapla   ierr = PetscSFComputeDegreeBegin(sf, &degree);CHKERRQ(ierr);
147f84a5eb8SVaclav Hapla   ierr = PetscSFComputeDegreeEnd(sf, &degree);CHKERRQ(ierr);
14866dfcd1aSVaclav Hapla   ierr = PetscSFComputeMultiRootOriginalNumbering(sf, degree, NULL, &mRootsOrigNumbering);CHKERRQ(ierr);
149f84a5eb8SVaclav Hapla   ierr = PetscMalloc1(nileaves, irmine1);CHKERRQ(ierr);
150f84a5eb8SVaclav Hapla   for (r=0; r<niranks; r++) {
151f84a5eb8SVaclav Hapla     o = iroffset[r];
152f84a5eb8SVaclav Hapla     n = iroffset[r+1] - o;
153f84a5eb8SVaclav Hapla     for (i=0; i<n; i++) (*irmine1)[o+i] = mRootsOrigNumbering[irmine[o+i]];
154f84a5eb8SVaclav Hapla   }
155f84a5eb8SVaclav Hapla   ierr = PetscFree(mRootsOrigNumbering);CHKERRQ(ierr);
156f84a5eb8SVaclav Hapla   PetscFunctionReturn(0);
157f84a5eb8SVaclav Hapla }
158f84a5eb8SVaclav Hapla 
159124f9872SVaclav Hapla /*@
160a8432d5bSVaclav Hapla   DMPlexCheckInterfaceCones - Check that points on inter-partition interfaces have conforming order of cone points.
161124f9872SVaclav Hapla 
162124f9872SVaclav Hapla   Input Parameters:
163124f9872SVaclav Hapla . dm - The DMPlex object
164124f9872SVaclav Hapla 
165a8432d5bSVaclav Hapla   Notes:
166a8432d5bSVaclav Hapla   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 SF containts connections 0 <- (1,0), 1 <- (1,1) and 2 <- (1,2),
167a8432d5bSVaclav 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.
168124f9872SVaclav Hapla 
169a8432d5bSVaclav Hapla   This is mainly intended for debugging/testing purposes. Does not check cone orientation, for this purpose use DMPlexCheckFaces().
170a8432d5bSVaclav Hapla 
171*95eb5ee5SVaclav Hapla   For the complete list of DMPlexCheck* functions, see DMSetFromOptions().
172*95eb5ee5SVaclav Hapla 
173a8432d5bSVaclav Hapla   Developer Note:
174a8432d5bSVaclav Hapla   Interface cones are expanded into vertices and then their coordinates are compared.
175124f9872SVaclav Hapla 
176124f9872SVaclav Hapla   Level: developer
177124f9872SVaclav Hapla 
178*95eb5ee5SVaclav Hapla .seealso: DMPlexGetCone(), DMPlexGetConeSize(), DMGetPointSF(), DMGetCoordinates(), DMSetFromOptions()
179124f9872SVaclav Hapla @*/
180a8432d5bSVaclav Hapla PetscErrorCode DMPlexCheckInterfaceCones(DM dm)
181f84a5eb8SVaclav Hapla {
182f84a5eb8SVaclav Hapla   PetscSF             sf;
183f84a5eb8SVaclav Hapla   PetscInt            nleaves, nranks, nroots;
184f84a5eb8SVaclav Hapla   const PetscInt      *mine, *roffset, *rmine, *rremote;
185f84a5eb8SVaclav Hapla   const PetscSFNode   *remote;
186f84a5eb8SVaclav Hapla   const PetscMPIInt   *ranks;
187f84a5eb8SVaclav Hapla   PetscSF             msf, imsf;
188f84a5eb8SVaclav Hapla   PetscInt            nileaves, niranks;
189f84a5eb8SVaclav Hapla   const PetscMPIInt   *iranks;
190f84a5eb8SVaclav Hapla   const PetscInt      *iroffset, *irmine, *irremote;
191f84a5eb8SVaclav Hapla   PetscInt            *rmine1, *rremote1; /* rmine and rremote copies simultaneously sorted by rank and rremote */
192f84a5eb8SVaclav Hapla   PetscInt            *mine_orig_numbering;
193f84a5eb8SVaclav Hapla   Vec                 *sntCoordinatesPerRank;
194f84a5eb8SVaclav Hapla   Vec                 *refCoordinatesPerRank;
19538853f44SSatish Balay   Vec                 *recCoordinatesPerRank=0;
196f84a5eb8SVaclav Hapla   PetscInt            r;
197f84a5eb8SVaclav Hapla   PetscMPIInt         commsize, myrank;
198f84a5eb8SVaclav Hapla   PetscBool           same;
1998f2c89e7SVaclav Hapla   PetscBool           verbose=PETSC_FALSE;
200f84a5eb8SVaclav Hapla   MPI_Comm            comm;
201f84a5eb8SVaclav Hapla   PetscErrorCode      ierr;
202f84a5eb8SVaclav Hapla 
203f84a5eb8SVaclav Hapla   PetscFunctionBegin;
20410b92ba9SVaclav Hapla   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
205f84a5eb8SVaclav Hapla   ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr);
206f84a5eb8SVaclav Hapla   ierr = MPI_Comm_rank(comm, &myrank);CHKERRQ(ierr);
207f84a5eb8SVaclav Hapla   ierr = MPI_Comm_size(comm, &commsize);CHKERRQ(ierr);
208f84a5eb8SVaclav Hapla   if (commsize < 2) PetscFunctionReturn(0);
209f84a5eb8SVaclav Hapla   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
210f84a5eb8SVaclav Hapla   if (!sf) PetscFunctionReturn(0);
211f84a5eb8SVaclav Hapla   ierr = PetscSFGetGraph(sf, &nroots, &nleaves, &mine, &remote);CHKERRQ(ierr);
212f84a5eb8SVaclav Hapla   if (nroots < 0) PetscFunctionReturn(0);
21310b92ba9SVaclav Hapla   if (!dm->coordinates && !dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM coordinates must be set");
214f84a5eb8SVaclav Hapla   ierr = PetscSFSetUp(sf);CHKERRQ(ierr);
215dec1416fSJunchao Zhang   ierr = PetscSFGetRootRanks(sf, &nranks, &ranks, &roffset, &rmine, &rremote);CHKERRQ(ierr);
216f84a5eb8SVaclav Hapla 
217f84a5eb8SVaclav Hapla   /* Expand sent cones per rank */
218f84a5eb8SVaclav Hapla   ierr = SortByRemote_Private(sf, &rmine1, &rremote1);CHKERRQ(ierr);
219f84a5eb8SVaclav Hapla   ierr = GetRecursiveConeCoordinatesPerRank_Private(dm, sf, rmine1, &sntCoordinatesPerRank);CHKERRQ(ierr);
220f84a5eb8SVaclav Hapla 
221f84a5eb8SVaclav Hapla   /* Create inverse SF */
222f84a5eb8SVaclav Hapla   ierr = PetscSFGetMultiSF(sf,&msf);CHKERRQ(ierr);
223f84a5eb8SVaclav Hapla   ierr = PetscSFCreateInverseSF(msf,&imsf);CHKERRQ(ierr);
224f84a5eb8SVaclav Hapla   ierr = PetscSFSetUp(imsf);CHKERRQ(ierr);
225f84a5eb8SVaclav Hapla   ierr = PetscSFGetGraph(imsf, NULL, &nileaves, NULL, NULL);CHKERRQ(ierr);
226dec1416fSJunchao Zhang   ierr = PetscSFGetRootRanks(imsf, &niranks, &iranks, &iroffset, &irmine, &irremote);CHKERRQ(ierr);
227f84a5eb8SVaclav Hapla 
228f84a5eb8SVaclav Hapla   /* Compute original numbering of multi-roots (referenced points) */
229f84a5eb8SVaclav Hapla   ierr = PetscSFComputeMultiRootOriginalNumberingByRank_Private(sf, imsf, &mine_orig_numbering);CHKERRQ(ierr);
230f84a5eb8SVaclav Hapla 
231124f9872SVaclav Hapla   /* Expand coordinates of the referred cones per rank */
232f84a5eb8SVaclav Hapla   ierr = GetRecursiveConeCoordinatesPerRank_Private(dm, imsf, mine_orig_numbering, &refCoordinatesPerRank);CHKERRQ(ierr);
233f84a5eb8SVaclav Hapla 
234f84a5eb8SVaclav Hapla   /* Send the coordinates */
235f84a5eb8SVaclav Hapla   ierr = ExchangeVecByRank_Private((PetscObject)sf, nranks, ranks, sntCoordinatesPerRank, niranks, iranks, &recCoordinatesPerRank);CHKERRQ(ierr);
236f84a5eb8SVaclav Hapla 
2378f2c89e7SVaclav Hapla   /* verbose output */
2388f2c89e7SVaclav Hapla   ierr = PetscOptionsGetBool(((PetscObject)dm)->options, ((PetscObject)dm)->prefix, "-dm_plex_check_cones_conform_on_interfaces_verbose", &verbose, NULL);CHKERRQ(ierr);
2398f2c89e7SVaclav Hapla   if (verbose) {
2409f27a777SBarry Smith     PetscViewer sv, v = PETSC_VIEWER_STDOUT_WORLD;
241a8432d5bSVaclav Hapla     ierr = PetscViewerASCIIPrintf(v, "============\nDMPlexCheckInterfaceCones output\n============\n");CHKERRQ(ierr);
2429f27a777SBarry Smith     ierr = PetscViewerASCIIPushSynchronized(v);CHKERRQ(ierr);
2439f27a777SBarry Smith     ierr = PetscViewerASCIISynchronizedPrintf(v, "[%d] --------\n", myrank);CHKERRQ(ierr);
2448f2c89e7SVaclav Hapla     for (r=0; r<nranks; r++) {
2459f27a777SBarry Smith       ierr = PetscViewerASCIISynchronizedPrintf(v, "  r=%D ranks[r]=%d sntCoordinatesPerRank[r]:\n", r, ranks[r]);CHKERRQ(ierr);
24632423fc4SVaclav Hapla       ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
2479f27a777SBarry Smith       ierr = PetscViewerGetSubViewer(v,PETSC_COMM_SELF,&sv);CHKERRQ(ierr);
2489f27a777SBarry Smith       ierr = VecView(sntCoordinatesPerRank[r], sv);CHKERRQ(ierr);
2499f27a777SBarry Smith       ierr = PetscViewerRestoreSubViewer(v,PETSC_COMM_SELF,&sv);CHKERRQ(ierr);
25032423fc4SVaclav Hapla       ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
2518f2c89e7SVaclav Hapla     }
2529f27a777SBarry Smith     ierr = PetscViewerASCIISynchronizedPrintf(v, "  ----------\n");CHKERRQ(ierr);
2538f2c89e7SVaclav Hapla     for (r=0; r<niranks; r++) {
2549f27a777SBarry Smith       ierr = PetscViewerASCIISynchronizedPrintf(v, "  r=%D iranks[r]=%d refCoordinatesPerRank[r]:\n", r, iranks[r]);CHKERRQ(ierr);
25532423fc4SVaclav Hapla       ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
2569f27a777SBarry Smith       ierr = PetscViewerGetSubViewer(v,PETSC_COMM_SELF,&sv);CHKERRQ(ierr);
2579f27a777SBarry Smith       ierr = VecView(refCoordinatesPerRank[r], sv);CHKERRQ(ierr);
2589f27a777SBarry Smith       ierr = PetscViewerRestoreSubViewer(v,PETSC_COMM_SELF,&sv);CHKERRQ(ierr);
25932423fc4SVaclav Hapla       ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
2608f2c89e7SVaclav Hapla     }
2619f27a777SBarry Smith     ierr = PetscViewerASCIISynchronizedPrintf(v, "  ----------\n");CHKERRQ(ierr);
2628f2c89e7SVaclav Hapla     for (r=0; r<niranks; r++) {
2639f27a777SBarry Smith       ierr = PetscViewerASCIISynchronizedPrintf(v, "  r=%D iranks[r]=%d recCoordinatesPerRank[r]:\n", r, iranks[r]);CHKERRQ(ierr);
26432423fc4SVaclav Hapla       ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
2659f27a777SBarry Smith       ierr = PetscViewerGetSubViewer(v,PETSC_COMM_SELF,&sv);CHKERRQ(ierr);
2669f27a777SBarry Smith       ierr = VecView(recCoordinatesPerRank[r], sv);CHKERRQ(ierr);
2679f27a777SBarry Smith       ierr = PetscViewerRestoreSubViewer(v,PETSC_COMM_SELF,&sv);CHKERRQ(ierr);
26832423fc4SVaclav Hapla       ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
2698f2c89e7SVaclav Hapla     }
2708f2c89e7SVaclav Hapla   }
2718f2c89e7SVaclav Hapla 
272f84a5eb8SVaclav Hapla   /* Compare recCoordinatesPerRank with refCoordinatesPerRank */
273f84a5eb8SVaclav Hapla   for (r=0; r<niranks; r++) {
274f84a5eb8SVaclav Hapla     ierr = VecEqual(refCoordinatesPerRank[r], recCoordinatesPerRank[r], &same);CHKERRQ(ierr);
275f84a5eb8SVaclav Hapla     if (!same) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "interface cones do not conform for remote rank %d", iranks[r]);
276f84a5eb8SVaclav Hapla   }
277f84a5eb8SVaclav Hapla 
278f84a5eb8SVaclav Hapla   /* destroy sent stuff */
279f84a5eb8SVaclav Hapla   for (r=0; r<nranks; r++) {
280f84a5eb8SVaclav Hapla     ierr = VecDestroy(&sntCoordinatesPerRank[r]);CHKERRQ(ierr);
281f84a5eb8SVaclav Hapla   }
282f84a5eb8SVaclav Hapla   ierr = PetscFree(sntCoordinatesPerRank);CHKERRQ(ierr);
283f84a5eb8SVaclav Hapla   ierr = PetscFree2(rmine1, rremote1);CHKERRQ(ierr);
284f84a5eb8SVaclav Hapla   ierr = PetscSFDestroy(&imsf);CHKERRQ(ierr);
285f84a5eb8SVaclav Hapla 
286f84a5eb8SVaclav Hapla   /* destroy referenced stuff */
287f84a5eb8SVaclav Hapla   for (r=0; r<niranks; r++) {
288f84a5eb8SVaclav Hapla     ierr = VecDestroy(&refCoordinatesPerRank[r]);CHKERRQ(ierr);
289f84a5eb8SVaclav Hapla   }
290f84a5eb8SVaclav Hapla   ierr = PetscFree(refCoordinatesPerRank);CHKERRQ(ierr);
291f84a5eb8SVaclav Hapla   ierr = PetscFree(mine_orig_numbering);CHKERRQ(ierr);
292f84a5eb8SVaclav Hapla 
293f84a5eb8SVaclav Hapla   /* destroy received stuff */
294f84a5eb8SVaclav Hapla   for (r=0; r<niranks; r++) {
295f84a5eb8SVaclav Hapla     ierr = VecDestroy(&recCoordinatesPerRank[r]);CHKERRQ(ierr);
296f84a5eb8SVaclav Hapla   }
297f84a5eb8SVaclav Hapla   ierr = PetscFree(recCoordinatesPerRank);CHKERRQ(ierr);
298f84a5eb8SVaclav Hapla   PetscFunctionReturn(0);
299f84a5eb8SVaclav Hapla }
300