#include /*I "petscdmplex.h" I*/ /* TODO PetscArrayExchangeBegin/End */ /* TODO blocksize */ /* TODO move to API ? */ 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[]) { PetscInt r; PetscInt *rsize; void **rarr; MPI_Request *sreq, *rreq; PetscMPIInt tag, unitsize; MPI_Comm comm; PetscFunctionBegin; PetscCallMPI(MPI_Type_size(dt, &unitsize)); PetscCall(PetscObjectGetComm(obj, &comm)); PetscCall(PetscMalloc2(nrranks, &rsize, nrranks, &rarr)); PetscCall(PetscMalloc2(nrranks, &rreq, nsranks, &sreq)); /* exchange array size */ PetscCall(PetscObjectGetNewTag(obj,&tag)); for (r=0; rcoordinates || dm->coordinatesLocal,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM coordinates must be set"); PetscCall(PetscSFSetUp(sf)); PetscCall(PetscSFGetRootRanks(sf, &nranks, &ranks, &roffset, &rmine, &rremote)); /* Expand sent cones per rank */ PetscCall(SortByRemote_Private(sf, &rmine1, &rremote1)); PetscCall(GetRecursiveConeCoordinatesPerRank_Private(dm, sf, rmine1, &sntCoordinatesPerRank)); /* Create inverse SF */ PetscCall(PetscSFGetMultiSF(sf,&msf)); PetscCall(PetscSFCreateInverseSF(msf,&imsf)); PetscCall(PetscSFSetUp(imsf)); PetscCall(PetscSFGetGraph(imsf, NULL, &nileaves, NULL, NULL)); PetscCall(PetscSFGetRootRanks(imsf, &niranks, &iranks, &iroffset, &irmine, &irremote)); /* Compute original numbering of multi-roots (referenced points) */ PetscCall(PetscSFComputeMultiRootOriginalNumberingByRank_Private(sf, imsf, &mine_orig_numbering)); /* Expand coordinates of the referred cones per rank */ PetscCall(GetRecursiveConeCoordinatesPerRank_Private(dm, imsf, mine_orig_numbering, &refCoordinatesPerRank)); /* Send the coordinates */ PetscCall(ExchangeVecByRank_Private((PetscObject)sf, nranks, ranks, sntCoordinatesPerRank, niranks, iranks, &recCoordinatesPerRank)); /* verbose output */ PetscCall(PetscOptionsGetBool(((PetscObject)dm)->options, ((PetscObject)dm)->prefix, "-dm_plex_check_cones_conform_on_interfaces_verbose", &verbose, NULL)); if (verbose) { PetscViewer sv, v = PETSC_VIEWER_STDOUT_WORLD; PetscCall(PetscViewerASCIIPrintf(v, "============\nDMPlexCheckInterfaceCones output\n============\n")); PetscCall(PetscViewerASCIIPushSynchronized(v)); PetscCall(PetscViewerASCIISynchronizedPrintf(v, "[%d] --------\n", myrank)); for (r=0; r