1fa534816SMatthew G. Knepley #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2fa534816SMatthew G. Knepley 3fa534816SMatthew G. Knepley /*@ 4f94b4a02SBlaise Bourdin DMPlexSetMigrationSF - Sets the SF for migrating from a parent DM into this DM 5f94b4a02SBlaise Bourdin 65d3b26e6SMatthew G. Knepley Input Parameters: 7f94b4a02SBlaise Bourdin + dm - The DM 85d3b26e6SMatthew G. Knepley - naturalSF - The PetscSF 95d3b26e6SMatthew G. Knepley 105d3b26e6SMatthew G. Knepley Note: It is necessary to call this in order to have DMCreateSubDM() or DMCreateSuperDM() build the Global-To-Natural map 115d3b26e6SMatthew G. Knepley 12f94b4a02SBlaise Bourdin Level: intermediate 13f94b4a02SBlaise Bourdin 14f94b4a02SBlaise Bourdin .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexCreateMigrationSF(), DMPlexGetMigrationSF() 15f94b4a02SBlaise Bourdin @*/ 16f94b4a02SBlaise Bourdin PetscErrorCode DMPlexSetMigrationSF(DM dm, PetscSF migrationSF) 17f94b4a02SBlaise Bourdin { 18f94b4a02SBlaise Bourdin PetscFunctionBegin; 19f94b4a02SBlaise Bourdin dm->sfMigration = migrationSF; 205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject) migrationSF)); 21f94b4a02SBlaise Bourdin PetscFunctionReturn(0); 22f94b4a02SBlaise Bourdin } 23f94b4a02SBlaise Bourdin 24f94b4a02SBlaise Bourdin /*@ 25f94b4a02SBlaise Bourdin DMPlexGetMigrationSF - Gets the SF for migrating from a parent DM into this DM 26f94b4a02SBlaise Bourdin 275d3b26e6SMatthew G. Knepley Input Parameter: 285d3b26e6SMatthew G. Knepley . dm - The DM 295d3b26e6SMatthew G. Knepley 305d3b26e6SMatthew G. Knepley Output Parameter: 315d3b26e6SMatthew G. Knepley . migrationSF - The PetscSF 325d3b26e6SMatthew G. Knepley 33f94b4a02SBlaise Bourdin Level: intermediate 34f94b4a02SBlaise Bourdin 35f94b4a02SBlaise Bourdin .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexCreateMigrationSF(), DMPlexSetMigrationSF 36f94b4a02SBlaise Bourdin @*/ 37f94b4a02SBlaise Bourdin PetscErrorCode DMPlexGetMigrationSF(DM dm, PetscSF *migrationSF) 38f94b4a02SBlaise Bourdin { 39f94b4a02SBlaise Bourdin PetscFunctionBegin; 40f94b4a02SBlaise Bourdin *migrationSF = dm->sfMigration; 41f94b4a02SBlaise Bourdin PetscFunctionReturn(0); 42f94b4a02SBlaise Bourdin } 43f94b4a02SBlaise Bourdin 44f94b4a02SBlaise Bourdin /*@ 45f94b4a02SBlaise Bourdin DMPlexSetGlobalToNaturalSF - Sets the SF for mapping Global Vec to the Natural Vec 46f94b4a02SBlaise Bourdin 475d3b26e6SMatthew G. Knepley Input Parameters: 48f94b4a02SBlaise Bourdin + dm - The DM 495d3b26e6SMatthew G. Knepley - naturalSF - The PetscSF 505d3b26e6SMatthew G. Knepley 51f94b4a02SBlaise Bourdin Level: intermediate 52f94b4a02SBlaise Bourdin 53f94b4a02SBlaise Bourdin .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexCreateGlobalToNaturalSF(), DMPlexGetGlobaltoNaturalSF() 54f94b4a02SBlaise Bourdin @*/ 55f94b4a02SBlaise Bourdin PetscErrorCode DMPlexSetGlobalToNaturalSF(DM dm, PetscSF naturalSF) 56f94b4a02SBlaise Bourdin { 57f94b4a02SBlaise Bourdin PetscFunctionBegin; 58f94b4a02SBlaise Bourdin dm->sfNatural = naturalSF; 595f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject) naturalSF)); 60f94b4a02SBlaise Bourdin dm->useNatural = PETSC_TRUE; 61f94b4a02SBlaise Bourdin PetscFunctionReturn(0); 62f94b4a02SBlaise Bourdin } 63f94b4a02SBlaise Bourdin 64f94b4a02SBlaise Bourdin /*@ 65f94b4a02SBlaise Bourdin DMPlexGetGlobalToNaturalSF - Gets the SF for mapping Global Vec to the Natural Vec 66f94b4a02SBlaise Bourdin 675d3b26e6SMatthew G. Knepley Input Parameter: 685d3b26e6SMatthew G. Knepley . dm - The DM 695d3b26e6SMatthew G. Knepley 705d3b26e6SMatthew G. Knepley Output Parameter: 715d3b26e6SMatthew G. Knepley . naturalSF - The PetscSF 725d3b26e6SMatthew G. Knepley 73f94b4a02SBlaise Bourdin Level: intermediate 74f94b4a02SBlaise Bourdin 75f94b4a02SBlaise Bourdin .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexCreateGlobalToNaturalSF(), DMPlexSetGlobaltoNaturalSF 76f94b4a02SBlaise Bourdin @*/ 77f94b4a02SBlaise Bourdin PetscErrorCode DMPlexGetGlobalToNaturalSF(DM dm, PetscSF *naturalSF) 78f94b4a02SBlaise Bourdin { 79f94b4a02SBlaise Bourdin PetscFunctionBegin; 80f94b4a02SBlaise Bourdin *naturalSF = dm->sfNatural; 81f94b4a02SBlaise Bourdin PetscFunctionReturn(0); 82f94b4a02SBlaise Bourdin } 83f94b4a02SBlaise Bourdin 84f94b4a02SBlaise Bourdin /*@ 85fa534816SMatthew G. Knepley DMPlexCreateGlobalToNaturalSF - Creates the SF for mapping Global Vec to the Natural Vec 86fa534816SMatthew G. Knepley 87fa534816SMatthew G. Knepley Input Parameters: 88fa534816SMatthew G. Knepley + dm - The DM 895c3f5608SAlexisMarb . section - The PetscSection describing the Vec before the mesh was distributed, 905c3f5608SAlexisMarb or NULL if not available 915c3f5608SAlexisMarb - sfMigration - The PetscSF used to distribute the mesh, or NULL if it cannot be computed 92fa534816SMatthew G. Knepley 935d3b26e6SMatthew G. Knepley Output Parameter: 94fa534816SMatthew G. Knepley . sfNatural - PetscSF for mapping the Vec in PETSc ordering to the canonical ordering 95fa534816SMatthew G. Knepley 965d3b26e6SMatthew G. Knepley Note: This is not typically called by the user. 975d3b26e6SMatthew G. Knepley 98fa534816SMatthew G. Knepley Level: intermediate 99fa534816SMatthew G. Knepley 100fa534816SMatthew G. Knepley .seealso: DMPlexDistribute(), DMPlexDistributeField() 101fa534816SMatthew G. Knepley @*/ 102fa534816SMatthew G. Knepley PetscErrorCode DMPlexCreateGlobalToNaturalSF(DM dm, PetscSection section, PetscSF sfMigration, PetscSF *sfNatural) 103fa534816SMatthew G. Knepley { 104fa534816SMatthew G. Knepley MPI_Comm comm; 1055c3f5608SAlexisMarb Vec gv, tmpVec; 106e5b44f4fSMatthew G. Knepley PetscSF sf, sfEmbed, sfSeqToNatural, sfField, sfFieldInv; 107e5b44f4fSMatthew G. Knepley PetscSection gSection, sectionDist, gLocSection; 108fa534816SMatthew G. Knepley PetscInt *spoints, *remoteOffsets; 1095c3f5608SAlexisMarb PetscInt ssize, pStart, pEnd, p, globalSize; 1103a350576SJunchao Zhang PetscLayout map; 1115c3f5608SAlexisMarb PetscBool destroyFlag = PETSC_FALSE; 112fa534816SMatthew G. Knepley 113fa534816SMatthew G. Knepley PetscFunctionBegin; 1145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetComm((PetscObject) dm, &comm)); 1155c3f5608SAlexisMarb if (!sfMigration) { 1165c3f5608SAlexisMarb /* If sfMigration is missing, 1175c3f5608SAlexisMarb sfNatural cannot be computed and is set to NULL */ 1185c3f5608SAlexisMarb *sfNatural = NULL; 1195c3f5608SAlexisMarb PetscFunctionReturn(0); 1205c3f5608SAlexisMarb } else if (!section) { 1215c3f5608SAlexisMarb /* If the sequential section is not provided (NULL), 1225c3f5608SAlexisMarb it is reconstructed from the parallel section */ 1235c3f5608SAlexisMarb PetscSF sfMigrationInv; 1245c3f5608SAlexisMarb PetscSection localSection; 1255c3f5608SAlexisMarb 1265f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalSection(dm, &localSection)); 1275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFCreateInverseSF(sfMigration, &sfMigrationInv)); 1285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion)); 1295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFDistributeSection(sfMigrationInv, localSection, NULL, section)); 1305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFDestroy(&sfMigrationInv)); 1315c3f5608SAlexisMarb destroyFlag = PETSC_TRUE; 1325c3f5608SAlexisMarb } 1335f80ce2aSJacob Faibussowitsch /* CHKERRQ(PetscPrintf(comm, "Point migration SF\n")); 1345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFView(sfMigration, 0)); */ 135e5b44f4fSMatthew G. Knepley /* Create a new section from distributing the original section */ 1365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionCreate(comm, §ionDist)); 1375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFDistributeSection(sfMigration, section, &remoteOffsets, sectionDist)); 1385f80ce2aSJacob Faibussowitsch /* CHKERRQ(PetscPrintf(comm, "Distributed Section\n")); 1395f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionView(sectionDist, PETSC_VIEWER_STDOUT_WORLD)); */ 1405f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetLocalSection(dm, sectionDist)); 1415c3f5608SAlexisMarb /* If a sequential section is provided but no dof is affected, 1425c3f5608SAlexisMarb sfNatural cannot be computed and is set to NULL */ 1435f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateGlobalVector(dm, &tmpVec)); 1445f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetSize(tmpVec, &globalSize)); 1455f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreGlobalVector(dm, &tmpVec)); 14614744f87SBlaise Bourdin if (globalSize) { 147fa534816SMatthew G. Knepley /* Get a pruned version of migration SF */ 1485f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetGlobalSection(dm, &gSection)); 1495f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionGetChart(gSection, &pStart, &pEnd)); 150fa534816SMatthew G. Knepley for (p = pStart, ssize = 0; p < pEnd; ++p) { 151fa534816SMatthew G. Knepley PetscInt dof, off; 152fa534816SMatthew G. Knepley 1535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionGetDof(gSection, p, &dof)); 1545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionGetOffset(gSection, p, &off)); 155fa534816SMatthew G. Knepley if ((dof > 0) && (off >= 0)) ++ssize; 156fa534816SMatthew G. Knepley } 1575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(ssize, &spoints)); 158fa534816SMatthew G. Knepley for (p = pStart, ssize = 0; p < pEnd; ++p) { 159fa534816SMatthew G. Knepley PetscInt dof, off; 160fa534816SMatthew G. Knepley 1615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionGetDof(gSection, p, &dof)); 1625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionGetOffset(gSection, p, &off)); 163fa534816SMatthew G. Knepley if ((dof > 0) && (off >= 0)) spoints[ssize++] = p; 164fa534816SMatthew G. Knepley } 1655f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFCreateEmbeddedLeafSF(sfMigration, ssize, spoints, &sfEmbed)); 1665f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(spoints)); 1675f80ce2aSJacob Faibussowitsch /* CHKERRQ(PetscPrintf(comm, "Embedded SF\n")); 1685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFView(sfEmbed, 0)); */ 169fa534816SMatthew G. Knepley /* Create the SF for seq to natural */ 1705f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetGlobalVector(dm, &gv)); 1715f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLayout(gv,&map)); 1723a350576SJunchao Zhang /* Note that entries of gv are leaves in sfSeqToNatural, entries of the seq vec are roots */ 1735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFCreate(comm, &sfSeqToNatural)); 1745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFSetGraphWithPattern(sfSeqToNatural, map, PETSCSF_PATTERN_GATHER)); 1755f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreGlobalVector(dm, &gv)); 1765f80ce2aSJacob Faibussowitsch /* CHKERRQ(PetscPrintf(comm, "Seq-to-Natural SF\n")); 1775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFView(sfSeqToNatural, 0)); */ 178fa534816SMatthew G. Knepley /* Create the SF associated with this section */ 1795f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetPointSF(dm, &sf)); 1805f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionCreateGlobalSection(sectionDist, sf, PETSC_FALSE, PETSC_TRUE, &gLocSection)); 1815f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFCreateSectionSF(sfEmbed, section, remoteOffsets, gLocSection, &sfField)); 1825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFDestroy(&sfEmbed)); 1835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionDestroy(&gLocSection)); 1845f80ce2aSJacob Faibussowitsch /* CHKERRQ(PetscPrintf(comm, "Field SF\n")); 1855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFView(sfField, 0)); */ 186fa534816SMatthew G. Knepley /* Invert the field SF so it's now from distributed to sequential */ 1875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFCreateInverseSF(sfField, &sfFieldInv)); 1885f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFDestroy(&sfField)); 1895f80ce2aSJacob Faibussowitsch /* CHKERRQ(PetscPrintf(comm, "Inverse Field SF\n")); 1905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFView(sfFieldInv, 0)); */ 191fa534816SMatthew G. Knepley /* Multiply the sfFieldInv with the */ 1925f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFComposeInverse(sfFieldInv, sfSeqToNatural, sfNatural)); 1935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectViewFromOptions((PetscObject) *sfNatural, NULL, "-globaltonatural_sf_view")); 194fa534816SMatthew G. Knepley /* Clean up */ 1955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFDestroy(&sfFieldInv)); 1965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFDestroy(&sfSeqToNatural)); 19714744f87SBlaise Bourdin } else { 19814744f87SBlaise Bourdin *sfNatural = NULL; 19914744f87SBlaise Bourdin } 2005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSectionDestroy(§ionDist)); 2015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(remoteOffsets)); 2025f80ce2aSJacob Faibussowitsch if (destroyFlag) CHKERRQ(PetscSectionDestroy(§ion)); 203fa534816SMatthew G. Knepley PetscFunctionReturn(0); 204fa534816SMatthew G. Knepley } 205fa534816SMatthew G. Knepley 206fa534816SMatthew G. Knepley /*@ 207fa534816SMatthew G. Knepley DMPlexGlobalToNaturalBegin - Rearranges a global Vector in the natural order. 208fa534816SMatthew G. Knepley 209fa534816SMatthew G. Knepley Collective on dm 210fa534816SMatthew G. Knepley 211fa534816SMatthew G. Knepley Input Parameters: 212fa534816SMatthew G. Knepley + dm - The distributed DMPlex 213fa534816SMatthew G. Knepley - gv - The global Vec 214fa534816SMatthew G. Knepley 215fa534816SMatthew G. Knepley Output Parameters: 216fa534816SMatthew G. Knepley . nv - Vec in the canonical ordering distributed over all processors associated with gv 217fa534816SMatthew G. Knepley 21842ea106eSTristan Konolige Note: The user must call DMSetUseNatural(dm, PETSC_TRUE) before DMPlexDistribute(). 219fa534816SMatthew G. Knepley 220fa534816SMatthew G. Knepley Level: intermediate 221fa534816SMatthew G. Knepley 222fa534816SMatthew G. Knepley .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexNaturalToGlobalBegin(), DMPlexGlobalToNaturalEnd() 223fa534816SMatthew G. Knepley @*/ 224fa534816SMatthew G. Knepley PetscErrorCode DMPlexGlobalToNaturalBegin(DM dm, Vec gv, Vec nv) 225fa534816SMatthew G. Knepley { 226fa534816SMatthew G. Knepley const PetscScalar *inarray; 227fa534816SMatthew G. Knepley PetscScalar *outarray; 228a6a55facSMatthew G. Knepley PetscMPIInt size; 229fa534816SMatthew G. Knepley 230fa534816SMatthew G. Knepley PetscFunctionBegin; 2315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventBegin(DMPLEX_GlobalToNaturalBegin,dm,0,0,0)); 2325f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size)); 233fa534816SMatthew G. Knepley if (dm->sfNatural) { 2345f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(nv, &outarray)); 2355f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(gv, &inarray)); 2365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFBcastBegin(dm->sfNatural, MPIU_SCALAR, (PetscScalar *) inarray, outarray,MPI_REPLACE)); 2375f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(gv, &inarray)); 2385f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(nv, &outarray)); 239a6a55facSMatthew G. Knepley } else if (size == 1) { 2405f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(gv, nv)); 241*28b400f6SJacob Faibussowitsch } else PetscCheck(!dm->useNatural,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "DM global to natural SF not present.\nIf DMPlexDistribute() was called and a section was defined, report to petsc-maint@mcs.anl.gov."); 242546078acSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created.\nYou must call DMSetUseNatural() before DMPlexDistribute()."); 2435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventEnd(DMPLEX_GlobalToNaturalBegin,dm,0,0,0)); 244fa534816SMatthew G. Knepley PetscFunctionReturn(0); 245fa534816SMatthew G. Knepley } 246fa534816SMatthew G. Knepley 247fa534816SMatthew G. Knepley /*@ 248fa534816SMatthew G. Knepley DMPlexGlobalToNaturalEnd - Rearranges a global Vector in the natural order. 249fa534816SMatthew G. Knepley 250fa534816SMatthew G. Knepley Collective on dm 251fa534816SMatthew G. Knepley 252fa534816SMatthew G. Knepley Input Parameters: 253fa534816SMatthew G. Knepley + dm - The distributed DMPlex 254fa534816SMatthew G. Knepley - gv - The global Vec 255fa534816SMatthew G. Knepley 25697bb3fdcSJose E. Roman Output Parameter: 257fa534816SMatthew G. Knepley . nv - The natural Vec 258fa534816SMatthew G. Knepley 25942ea106eSTristan Konolige Note: The user must call DMSetUseNatural(dm, PETSC_TRUE) before DMPlexDistribute(). 260fa534816SMatthew G. Knepley 261fa534816SMatthew G. Knepley Level: intermediate 262fa534816SMatthew G. Knepley 263fa534816SMatthew G. Knepley .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexNaturalToGlobalBegin(), DMPlexGlobalToNaturalBegin() 264fa534816SMatthew G. Knepley @*/ 265fa534816SMatthew G. Knepley PetscErrorCode DMPlexGlobalToNaturalEnd(DM dm, Vec gv, Vec nv) 266fa534816SMatthew G. Knepley { 267fa534816SMatthew G. Knepley const PetscScalar *inarray; 268fa534816SMatthew G. Knepley PetscScalar *outarray; 269a6a55facSMatthew G. Knepley PetscMPIInt size; 270fa534816SMatthew G. Knepley 271fa534816SMatthew G. Knepley PetscFunctionBegin; 2725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventBegin(DMPLEX_GlobalToNaturalEnd,dm,0,0,0)); 2735f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size)); 274fa534816SMatthew G. Knepley if (dm->sfNatural) { 2755f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(gv, &inarray)); 2765f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(nv, &outarray)); 2775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFBcastEnd(dm->sfNatural, MPIU_SCALAR, (PetscScalar *) inarray, outarray,MPI_REPLACE)); 2785f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(gv, &inarray)); 2795f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(nv, &outarray)); 280a6a55facSMatthew G. Knepley } else if (size == 1) { 281*28b400f6SJacob Faibussowitsch } else PetscCheck(!dm->useNatural,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "DM global to natural SF not present.\nIf DMPlexDistribute() was called and a section was defined, report to petsc-maint@mcs.anl.gov."); 282546078acSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created.\nYou must call DMSetUseNatural() before DMPlexDistribute()."); 2835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventEnd(DMPLEX_GlobalToNaturalEnd,dm,0,0,0)); 284fa534816SMatthew G. Knepley PetscFunctionReturn(0); 285fa534816SMatthew G. Knepley } 286fa534816SMatthew G. Knepley 287fa534816SMatthew G. Knepley /*@ 288fa534816SMatthew G. Knepley DMPlexNaturalToGlobalBegin - Rearranges a Vector in the natural order to the Global order. 289fa534816SMatthew G. Knepley 290fa534816SMatthew G. Knepley Collective on dm 291fa534816SMatthew G. Knepley 292fa534816SMatthew G. Knepley Input Parameters: 293fa534816SMatthew G. Knepley + dm - The distributed DMPlex 294fa534816SMatthew G. Knepley - nv - The natural Vec 295fa534816SMatthew G. Knepley 296fa534816SMatthew G. Knepley Output Parameters: 297fa534816SMatthew G. Knepley . gv - The global Vec 298fa534816SMatthew G. Knepley 29942ea106eSTristan Konolige Note: The user must call DMSetUseNatural(dm, PETSC_TRUE) before DMPlexDistribute(). 300fa534816SMatthew G. Knepley 301fa534816SMatthew G. Knepley Level: intermediate 302fa534816SMatthew G. Knepley 303fa534816SMatthew G. Knepley .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexNaturalToGlobalBegin(),DMPlexGlobalToNaturalEnd() 304fa534816SMatthew G. Knepley @*/ 305fa534816SMatthew G. Knepley PetscErrorCode DMPlexNaturalToGlobalBegin(DM dm, Vec nv, Vec gv) 306fa534816SMatthew G. Knepley { 307fa534816SMatthew G. Knepley const PetscScalar *inarray; 308fa534816SMatthew G. Knepley PetscScalar *outarray; 309a6a55facSMatthew G. Knepley PetscMPIInt size; 310fa534816SMatthew G. Knepley 311fa534816SMatthew G. Knepley PetscFunctionBegin; 3125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventBegin(DMPLEX_NaturalToGlobalBegin,dm,0,0,0)); 3135f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size)); 314fa534816SMatthew G. Knepley if (dm->sfNatural) { 315a5b23f4aSJose E. Roman /* We only have access to the SF that goes from Global to Natural. 316b64f75a9SBlaise Bourdin Instead of inverting dm->sfNatural, we can call PetscSFReduceBegin/End with MPI_Op MPI_SUM. 317b64f75a9SBlaise Bourdin Here the SUM really does nothing since sfNatural is one to one, as long as gV is set to zero first. */ 3185f80ce2aSJacob Faibussowitsch CHKERRQ(VecZeroEntries(gv)); 3195f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(gv, &outarray)); 3205f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(nv, &inarray)); 3215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFReduceBegin(dm->sfNatural, MPIU_SCALAR, (PetscScalar *) inarray, outarray, MPI_SUM)); 3225f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(nv, &inarray)); 3235f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(gv, &outarray)); 324a6a55facSMatthew G. Knepley } else if (size == 1) { 3255f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(nv, gv)); 326*28b400f6SJacob Faibussowitsch } else PetscCheck(!dm->useNatural,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "DM global to natural SF not present.\nIf DMPlexDistribute() was called and a section was defined, report to petsc-maint@mcs.anl.gov."); 327546078acSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created.\nYou must call DMSetUseNatural() before DMPlexDistribute()."); 3285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventEnd(DMPLEX_NaturalToGlobalBegin,dm,0,0,0)); 329fa534816SMatthew G. Knepley PetscFunctionReturn(0); 330fa534816SMatthew G. Knepley } 331fa534816SMatthew G. Knepley 332fa534816SMatthew G. Knepley /*@ 333fa534816SMatthew G. Knepley DMPlexNaturalToGlobalEnd - Rearranges a Vector in the natural order to the Global order. 334fa534816SMatthew G. Knepley 335fa534816SMatthew G. Knepley Collective on dm 336fa534816SMatthew G. Knepley 337fa534816SMatthew G. Knepley Input Parameters: 338fa534816SMatthew G. Knepley + dm - The distributed DMPlex 339fa534816SMatthew G. Knepley - nv - The natural Vec 340fa534816SMatthew G. Knepley 341fa534816SMatthew G. Knepley Output Parameters: 342fa534816SMatthew G. Knepley . gv - The global Vec 343fa534816SMatthew G. Knepley 34442ea106eSTristan Konolige Note: The user must call DMSetUseNatural(dm, PETSC_TRUE) before DMPlexDistribute(). 345fa534816SMatthew G. Knepley 346fa534816SMatthew G. Knepley Level: intermediate 347fa534816SMatthew G. Knepley 348fa534816SMatthew G. Knepley .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexNaturalToGlobalBegin(), DMPlexGlobalToNaturalBegin() 349fa534816SMatthew G. Knepley @*/ 350fa534816SMatthew G. Knepley PetscErrorCode DMPlexNaturalToGlobalEnd(DM dm, Vec nv, Vec gv) 351fa534816SMatthew G. Knepley { 352fa534816SMatthew G. Knepley const PetscScalar *inarray; 353fa534816SMatthew G. Knepley PetscScalar *outarray; 354a6a55facSMatthew G. Knepley PetscMPIInt size; 355fa534816SMatthew G. Knepley 356fa534816SMatthew G. Knepley PetscFunctionBegin; 3575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventBegin(DMPLEX_NaturalToGlobalEnd,dm,0,0,0)); 3585f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size)); 359fa534816SMatthew G. Knepley if (dm->sfNatural) { 3605f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(nv, &inarray)); 3615f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(gv, &outarray)); 3625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFReduceEnd(dm->sfNatural, MPIU_SCALAR, (PetscScalar *) inarray, outarray, MPI_SUM)); 3635f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(nv, &inarray)); 3645f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(gv, &outarray)); 365a6a55facSMatthew G. Knepley } else if (size == 1) { 366*28b400f6SJacob Faibussowitsch } else PetscCheck(!dm->useNatural,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "DM global to natural SF not present.\nIf DMPlexDistribute() was called and a section was defined, report to petsc-maint@mcs.anl.gov."); 367546078acSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created.\nYou must call DMSetUseNatural() before DMPlexDistribute()."); 3685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventEnd(DMPLEX_NaturalToGlobalEnd,dm,0,0,0)); 369fa534816SMatthew G. Knepley PetscFunctionReturn(0); 370fa534816SMatthew G. Knepley } 371