Actual source code: plexnatural.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      1: #include <petsc/private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/

      5: /*@
      6:   DMPlexCreateGlobalToNaturalSF - Creates the SF for mapping Global Vec to the Natural Vec

      8:   Input Parameters:
      9: + dm          - The DM
     10: . section     - The PetscSection before the mesh was distributed
     11: - sfMigration - The PetscSF used to distribute the mesh

     13:   Output Parameters:
     14: . sfNatural - PetscSF for mapping the Vec in PETSc ordering to the canonical ordering

     16:   Level: intermediate

     18: .seealso: DMPlexDistribute(), DMPlexDistributeField()
     19:  @*/
     20: PetscErrorCode DMPlexCreateGlobalToNaturalSF(DM dm, PetscSection section, PetscSF sfMigration, PetscSF *sfNatural)
     21: {
     22:   MPI_Comm       comm;
     23:   Vec            gv;
     24:   PetscSF        sf, sfEmbed, sfSeqToNatural, sfField, sfFieldInv;
     25:   PetscSection   gSection, sectionDist, gLocSection;
     26:   PetscInt      *spoints, *remoteOffsets;
     27:   PetscInt       ssize, pStart, pEnd, p;

     31:   PetscObjectGetComm((PetscObject) dm, &comm);
     32:   /* PetscPrintf(comm, "Point migration SF\n");
     33:    PetscSFView(sfMigration, 0); */
     34:   /* Create a new section from distributing the original section */
     35:   PetscSectionCreate(comm, &sectionDist);
     36:   PetscSFDistributeSection(sfMigration, section, &remoteOffsets, sectionDist);
     37:   /* PetscPrintf(comm, "Distributed Section\n");
     38:    PetscSectionView(sectionDist, PETSC_VIEWER_STDOUT_WORLD); */
     39:   DMSetDefaultSection(dm, sectionDist);
     40:   /* Get a pruned version of migration SF */
     41:   DMGetDefaultGlobalSection(dm, &gSection);
     42:   PetscSectionGetChart(gSection, &pStart, &pEnd);
     43:   for (p = pStart, ssize = 0; p < pEnd; ++p) {
     44:     PetscInt dof, off;

     46:     PetscSectionGetDof(gSection, p, &dof);
     47:     PetscSectionGetOffset(gSection, p, &off);
     48:     if ((dof > 0) && (off >= 0)) ++ssize;
     49:   }
     50:   PetscMalloc1(ssize, &spoints);
     51:   for (p = pStart, ssize = 0; p < pEnd; ++p) {
     52:     PetscInt dof, off;

     54:     PetscSectionGetDof(gSection, p, &dof);
     55:     PetscSectionGetOffset(gSection, p, &off);
     56:     if ((dof > 0) && (off >= 0)) spoints[ssize++] = p;
     57:   }
     58:   PetscSFCreateEmbeddedLeafSF(sfMigration, ssize, spoints, &sfEmbed);
     59:   PetscFree(spoints);
     60:   /* PetscPrintf(comm, "Embedded SF\n");
     61:    PetscSFView(sfEmbed, 0); */
     62:   /* Create the SF for seq to natural */
     63:   DMGetGlobalVector(dm, &gv);
     64:   PetscSFCreateFromZero(comm, gv, &sfSeqToNatural);
     65:   DMRestoreGlobalVector(dm, &gv);
     66:   /* PetscPrintf(comm, "Seq-to-Natural SF\n");
     67:    PetscSFView(sfSeqToNatural, 0); */
     68:   /* Create the SF associated with this section */
     69:   DMGetPointSF(dm, &sf);
     70:   PetscSectionCreateGlobalSection(sectionDist, sf, PETSC_FALSE, PETSC_TRUE, &gLocSection);
     71:   PetscSFCreateSectionSF(sfEmbed, section, remoteOffsets, gLocSection, &sfField);
     72:   PetscFree(remoteOffsets);
     73:   PetscSFDestroy(&sfEmbed);
     74:   PetscSectionDestroy(&gLocSection);
     75:   PetscSectionDestroy(&sectionDist);
     76:   /* PetscPrintf(comm, "Field SF\n");
     77:    PetscSFView(sfField, 0); */
     78:   /* Invert the field SF so it's now from distributed to sequential */
     79:   PetscSFCreateInverseSF(sfField, &sfFieldInv);
     80:   PetscSFDestroy(&sfField);
     81:   /* PetscPrintf(comm, "Inverse Field SF\n");
     82:    PetscSFView(sfFieldInv, 0); */
     83:   /* Multiply the sfFieldInv with the */
     84:   PetscSFCompose(sfFieldInv, sfSeqToNatural, sfNatural);
     85:   PetscObjectViewFromOptions((PetscObject) *sfNatural, NULL, "-globaltonatural_sf_view");
     86:   /* Clean up */
     87:   PetscSFDestroy(&sfFieldInv);
     88:   PetscSFDestroy(&sfSeqToNatural);
     89:   return(0);
     90: }

     94: /*@
     95:   DMPlexGlobalToNaturalBegin - Rearranges a global Vector in the natural order.

     97:   Collective on dm

     99:   Input Parameters:
    100: + dm - The distributed DMPlex
    101: - gv - The global Vec

    103:   Output Parameters:
    104: . nv - Vec in the canonical ordering distributed over all processors associated with gv

    106:   Note: The user must call DMPlexSetUseNaturalSF(dm, PETSC_TRUE) before DMPlexDistribute().

    108:   Level: intermediate

    110: .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexNaturalToGlobalBegin(), DMPlexGlobalToNaturalEnd()
    111: @*/
    112: PetscErrorCode DMPlexGlobalToNaturalBegin(DM dm, Vec gv, Vec nv)
    113: {
    114:   const PetscScalar *inarray;
    115:   PetscScalar       *outarray;
    116:   PetscErrorCode     ierr;

    119:   PetscLogEventBegin(DMPLEX_GlobalToNaturalBegin,dm,0,0,0);
    120:   if (dm->sfNatural) {
    121:     VecGetArray(nv, &outarray);
    122:     VecGetArrayRead(gv, &inarray);
    123:     PetscSFBcastBegin(dm->sfNatural, MPIU_SCALAR, (PetscScalar *) inarray, outarray);
    124:     VecRestoreArrayRead(gv, &inarray);
    125:     VecRestoreArray(nv, &outarray);
    126:   } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created.\nYou must call DMSetUseNatural() before DMPlexDistribute().\n");
    127:   PetscLogEventEnd(DMPLEX_GlobalToNaturalBegin,dm,0,0,0);
    128:   return(0);
    129: }

    133: /*@
    134:   DMPlexGlobalToNaturalEnd - Rearranges a global Vector in the natural order.

    136:   Collective on dm

    138:   Input Parameters:
    139: + dm - The distributed DMPlex
    140: - gv - The global Vec

    142:   Output Parameters:
    143: . nv - The natural Vec

    145:   Note: The user must call DMPlexSetUseNaturalSF(dm, PETSC_TRUE) before DMPlexDistribute().

    147:   Level: intermediate

    149:  .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexNaturalToGlobalBegin(), DMPlexGlobalToNaturalBegin()
    150:  @*/
    151: PetscErrorCode DMPlexGlobalToNaturalEnd(DM dm, Vec gv, Vec nv)
    152: {
    153:   const PetscScalar *inarray;
    154:   PetscScalar       *outarray;
    155:   PetscErrorCode     ierr;

    158:   PetscLogEventBegin(DMPLEX_GlobalToNaturalEnd,dm,0,0,0);
    159:   if (dm->sfNatural) {
    160:     VecGetArrayRead(gv, &inarray);
    161:     VecGetArray(nv, &outarray);
    162:     PetscSFBcastEnd(dm->sfNatural, MPIU_SCALAR, (PetscScalar *) inarray, outarray);
    163:     VecRestoreArrayRead(gv, &inarray);
    164:     VecRestoreArray(nv, &outarray);
    165:   }
    166:   PetscLogEventEnd(DMPLEX_GlobalToNaturalEnd,dm,0,0,0);
    167:   return(0);
    168: }

    172: /*@
    173:   DMPlexNaturalToGlobalBegin - Rearranges a Vector in the natural order to the Global order.

    175:   Collective on dm

    177:   Input Parameters:
    178: + dm - The distributed DMPlex
    179: - nv - The natural Vec

    181:   Output Parameters:
    182: . gv - The global Vec

    184:   Note: The user must call DMPlexSetUseNaturalSF(dm, PETSC_TRUE) before DMPlexDistribute().

    186:   Level: intermediate

    188: .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexNaturalToGlobalBegin(),DMPlexGlobalToNaturalEnd()
    189: @*/
    190: PetscErrorCode DMPlexNaturalToGlobalBegin(DM dm, Vec nv, Vec gv)
    191: {
    192:   const PetscScalar *inarray;
    193:   PetscScalar       *outarray;
    194:   PetscErrorCode     ierr;

    197:   PetscLogEventBegin(DMPLEX_NaturalToGlobalBegin,dm,0,0,0);
    198:   if (dm->sfNatural) {
    199:     VecGetArray(gv, &outarray);
    200:     VecGetArrayRead(nv, &inarray);
    201:     PetscSFReduceBegin(dm->sfNatural, MPIU_SCALAR, (PetscScalar *) inarray, outarray, MPI_SUM);
    202:     VecRestoreArrayRead(nv, &inarray);
    203:     VecRestoreArray(gv, &outarray);
    204:   } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created.\nYou must call DMPlexSetUseNaturalSF() before DMPlexDistribute().\n");
    205:   PetscLogEventEnd(DMPLEX_NaturalToGlobalBegin,dm,0,0,0);
    206:   return(0);
    207: }

    211: /*@
    212:   DMPlexNaturalToGlobalEnd - Rearranges a Vector in the natural order to the Global order.

    214:   Collective on dm

    216:   Input Parameters:
    217: + dm - The distributed DMPlex
    218: - nv - The natural Vec

    220:   Output Parameters:
    221: . gv - The global Vec

    223:   Note: The user must call DMPlexSetUseNaturalSF(dm, PETSC_TRUE) before DMPlexDistribute().

    225:   Level: intermediate

    227: .seealso: DMPlexDistribute(), DMPlexDistributeField(), DMPlexNaturalToGlobalBegin(), DMPlexGlobalToNaturalBegin()
    228:  @*/
    229: PetscErrorCode DMPlexNaturalToGlobalEnd(DM dm, Vec nv, Vec gv)
    230: {
    231:   const PetscScalar *inarray;
    232:   PetscScalar       *outarray;
    233:   PetscErrorCode     ierr;

    236:   PetscLogEventBegin(DMPLEX_NaturalToGlobalEnd,dm,0,0,0);
    237:   if (dm->sfNatural) {
    238:     VecGetArrayRead(nv, &inarray);
    239:     VecGetArray(gv, &outarray);
    240:     PetscSFReduceEnd(dm->sfNatural, MPIU_SCALAR, (PetscScalar *) inarray, outarray, MPI_SUM);
    241:     VecRestoreArrayRead(nv, &inarray);
    242:     VecRestoreArray(gv, &outarray);
    243:   }
    244:   PetscLogEventEnd(DMPLEX_NaturalToGlobalEnd,dm,0,0,0);
    245:   return(0);
    246: }