Date: 2015-10-02T22:02:09+00:00

Actual source code: vsection.c
petsc-3.6.2 2015-10-02
Report Typos and Errors

      1: /*
      2:    This file contains routines for section object operations on Vecs
      3: */
      4: #include <petsc/private/isimpl.h>   /*I  "petscvec.h"   I*/
      5: #include <petsc/private/vecimpl.h>   /*I  "petscvec.h"   I*/

      9: PetscErrorCode PetscSectionVecView_ASCII(PetscSection s, Vec v, PetscViewer viewer)
     10: {
     11:   PetscScalar    *array;
     12:   PetscInt       p, i;
     13:   PetscMPIInt    rank;

     17:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);
     18:   VecGetArray(v, &array);
     19:   PetscViewerASCIISynchronizedAllow(viewer, PETSC_TRUE);
     20:   PetscViewerASCIISynchronizedPrintf(viewer, "Process %d:\n", rank);
     21:   for (p = 0; p < s->pEnd - s->pStart; ++p) {
     22:     if ((s->bc) && (s->bc->atlasDof[p] > 0)) {
     23:       PetscInt b;

     25:       PetscViewerASCIISynchronizedPrintf(viewer, "  (%4d) dim %2d offset %3d", p+s->pStart, s->atlasDof[p], s->atlasOff[p]);
     26:       for (i = s->atlasOff[p]; i < s->atlasOff[p]+s->atlasDof[p]; ++i) {
     27:         PetscScalar v = array[i];
     28: #if defined(PETSC_USE_COMPLEX)
     29:         if (PetscImaginaryPart(v) > 0.0) {
     30:           PetscViewerASCIISynchronizedPrintf(viewer," %g + %g i", (double)PetscRealPart(v), (double)PetscImaginaryPart(v));
     31:         } else if (PetscImaginaryPart(v) < 0.0) {
     32:           PetscViewerASCIISynchronizedPrintf(viewer," %g - %g i", (double)PetscRealPart(v),(double)(-PetscImaginaryPart(v)));
     33:         } else {
     34:           PetscViewerASCIISynchronizedPrintf(viewer, " %g", (double)PetscRealPart(v));
     35:         }
     36: #else
     37:         PetscViewerASCIISynchronizedPrintf(viewer, " %g", (double)v);
     38: #endif
     39:       }
     40:       PetscViewerASCIISynchronizedPrintf(viewer, " constrained");
     41:       for (b = 0; b < s->bc->atlasDof[p]; ++b) {
     42:         PetscViewerASCIISynchronizedPrintf(viewer, " %d", s->bcIndices[s->bc->atlasOff[p]+b]);
     43:       }
     44:       PetscViewerASCIISynchronizedPrintf(viewer, "\n");
     45:     } else {
     46:       PetscViewerASCIISynchronizedPrintf(viewer, "  (%4d) dim %2d offset %3d", p+s->pStart, s->atlasDof[p], s->atlasOff[p]);
     47:       for (i = s->atlasOff[p]; i < s->atlasOff[p]+s->atlasDof[p]; ++i) {
     48:         PetscScalar v = array[i];
     49: #if defined(PETSC_USE_COMPLEX)
     50:         if (PetscImaginaryPart(v) > 0.0) {
     51:           PetscViewerASCIISynchronizedPrintf(viewer," %g + %g i", (double)PetscRealPart(v), (double)PetscImaginaryPart(v));
     52:         } else if (PetscImaginaryPart(v) < 0.0) {
     53:           PetscViewerASCIISynchronizedPrintf(viewer," %g - %g i", (double)PetscRealPart(v),(double)(-PetscImaginaryPart(v)));
     54:         } else {
     55:           PetscViewerASCIISynchronizedPrintf(viewer, " %g", (double)PetscRealPart(v));
     56:         }
     57: #else
     58:         PetscViewerASCIISynchronizedPrintf(viewer, " %g", (double)v);
     59: #endif
     60:       }
     61:       PetscViewerASCIISynchronizedPrintf(viewer, "\n");
     62:     }
     63:   }
     64:   PetscViewerFlush(viewer);
     65:   VecRestoreArray(v, &array);
     66:   return(0);
     67: }

     71: PetscErrorCode PetscSectionVecView(PetscSection s, Vec v, PetscViewer viewer)
     72: {
     73:   PetscBool      isascii;
     74:   PetscInt       f;

     78:   if (!viewer) {PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)v), &viewer);}
     81:   PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii);
     82:   if (isascii) {
     83:     const char *name;

     85:     PetscObjectGetName((PetscObject) v, &name);
     86:     if (s->numFields) {
     87:       PetscViewerASCIIPrintf(viewer, "%s with %d fields\n", name, s->numFields);
     88:       for (f = 0; f < s->numFields; ++f) {
     89:         PetscViewerASCIIPrintf(viewer, "  field %d with %d components\n", f, s->numFieldComponents[f]);
     90:         PetscSectionVecView_ASCII(s->field[f], v, viewer);
     91:       }
     92:     } else {
     93:       PetscViewerASCIIPrintf(viewer, "%s\n", name);
     94:       PetscSectionVecView_ASCII(s, v, viewer);
     95:     }
     96:   }
     97:   return(0);
     98: }

    102: PetscErrorCode VecGetValuesSection(Vec v, PetscSection s, PetscInt point, PetscScalar **values)
    103: {
    104:   PetscScalar    *baseArray;
    105:   const PetscInt p = point - s->pStart;

    109:   VecGetArray(v, &baseArray);
    110:   *values = &baseArray[s->atlasOff[p]];
    111:   VecRestoreArray(v, &baseArray);
    112:   return(0);
    113: }

    117: /*@C
    118:   VecSetValuesSection - Sets all the values associated with a given point, accoridng to the section, in the given Vec

    120:   Not collective

    122:   Input Parameters:
    123: + v - the Vec
    124: . s - the organizing PetscSection
    125: . point - the point
    126: . values - the array of input values
    127: - mode - the insertion mode, either ADD_VALUES or INSERT_VALUES

    129:   Level: developer

    131:   Note: This is similar to MatSetValuesStencil(). The Fortran binding is
    132: $
    133: $   VecSetValuesSectionF90(vec, section, point, values, mode, ierr)
    134: $

    136: .seealso: PetscSection, PetscSectionCreate()
    137: @*/
    138: PetscErrorCode VecSetValuesSection(Vec v, PetscSection s, PetscInt point, PetscScalar values[], InsertMode mode)
    139: {
    140:   PetscScalar     *baseArray, *array;
    141:   const PetscBool doInsert    = mode == INSERT_VALUES     || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES                          ? PETSC_TRUE : PETSC_FALSE;
    142:   const PetscBool doInterior  = mode == INSERT_ALL_VALUES || mode == ADD_ALL_VALUES    || mode == INSERT_VALUES    || mode == ADD_VALUES    ? PETSC_TRUE : PETSC_FALSE;
    143:   const PetscBool doBC        = mode == INSERT_ALL_VALUES || mode == ADD_ALL_VALUES    || mode == INSERT_BC_VALUES || mode == ADD_BC_VALUES ? PETSC_TRUE : PETSC_FALSE;
    144:   const PetscInt  p           = point - s->pStart;
    145:   const PetscInt  orientation = 0; /* Needs to be included for use in closure operations */
    146:   PetscInt        cDim        = 0;
    147:   PetscErrorCode  ierr;

    150:   PetscSectionGetConstraintDof(s, point, &cDim);
    151:   VecGetArray(v, &baseArray);
    152:   array = &baseArray[s->atlasOff[p]];
    153:   if (!cDim && doInterior) {
    154:     if (orientation >= 0) {
    155:       const PetscInt dim = s->atlasDof[p];
    156:       PetscInt       i;

    158:       if (doInsert) {
    159:         for (i = 0; i < dim; ++i) array[i] = values[i];
    160:       } else {
    161:         for (i = 0; i < dim; ++i) array[i] += values[i];
    162:       }
    163:     } else {
    164:       PetscInt offset = 0;
    165:       PetscInt j      = -1, field, i;

    167:       for (field = 0; field < s->numFields; ++field) {
    168:         const PetscInt dim = s->field[field]->atlasDof[p]; /* PetscSectionGetFieldDof() */

    170:         for (i = dim-1; i >= 0; --i) array[++j] = values[i+offset];
    171:         offset += dim;
    172:       }
    173:     }
    174:   } else if (cDim) {
    175:     if (orientation >= 0) {
    176:       const PetscInt dim  = s->atlasDof[p];
    177:       PetscInt       cInd = 0, i;
    178:       const PetscInt *cDof;

    180:       PetscSectionGetConstraintIndices(s, point, &cDof);
    181:       if (doInsert) {
    182:         for (i = 0; i < dim; ++i) {
    183:           if ((cInd < cDim) && (i == cDof[cInd])) {
    184:             if (doBC) array[i] = values[i]; /* Constrained update */
    185:             ++cInd;
    186:             continue;
    187:           }
    188:           if (doInterior) array[i] = values[i]; /* Unconstrained update */
    189:         }
    190:       } else {
    191:         for (i = 0; i < dim; ++i) {
    192:           if ((cInd < cDim) && (i == cDof[cInd])) {
    193:             if (doBC) array[i] += values[i]; /* Constrained update */
    194:             ++cInd;
    195:             continue;
    196:           }
    197:           if (doInterior) array[i] += values[i]; /* Unconstrained update */
    198:         }
    199:       }
    200:     } else {
    201:       /* TODO This is broken for add and constrained update */
    202:       const PetscInt *cDof;
    203:       PetscInt       offset  = 0;
    204:       PetscInt       cOffset = 0;
    205:       PetscInt       j       = 0, field;

    207:       PetscSectionGetConstraintIndices(s, point, &cDof);
    208:       for (field = 0; field < s->numFields; ++field) {
    209:         const PetscInt dim  = s->field[field]->atlasDof[p];     /* PetscSectionGetFieldDof() */
    210:         const PetscInt tDim = s->field[field]->bc->atlasDof[p]; /* PetscSectionGetFieldConstraintDof() */
    211:         const PetscInt sDim = dim - tDim;
    212:         PetscInt       cInd = 0, i ,k;

    214:         for (i = 0, k = dim+offset-1; i < dim; ++i, ++j, --k) {
    215:           if ((cInd < sDim) && (j == cDof[cInd+cOffset])) {++cInd; continue;}
    216:           if (doInterior) array[j] = values[k];   /* Unconstrained update */
    217:         }
    218:         offset  += dim;
    219:         cOffset += dim - tDim;
    220:       }
    221:     }
    222:   }
    223:   VecRestoreArray(v, &baseArray);
    224:   return(0);
    225: }

    229: PetscErrorCode PetscSectionGetField_Internal(PetscSection section, PetscSection sectionGlobal, Vec v, PetscInt field, PetscInt pStart, PetscInt pEnd, IS *is, Vec *subv)
    230: {
    231:   PetscInt      *subIndices;
    232:   PetscInt       Nc, subSize = 0, subOff = 0, p;

    236:   PetscSectionGetFieldComponents(section, field, &Nc);
    237:   for (p = pStart; p < pEnd; ++p) {
    238:     PetscInt gdof, fdof = 0;

    240:     PetscSectionGetDof(sectionGlobal, p, &gdof);
    241:     if (gdof > 0) {PetscSectionGetFieldDof(section, p, field, &fdof);}
    242:     subSize += fdof;
    243:   }
    244:   PetscMalloc1(subSize, &subIndices);
    245:   for (p = pStart; p < pEnd; ++p) {
    246:     PetscInt gdof, goff;

    248:     PetscSectionGetDof(sectionGlobal, p, &gdof);
    249:     if (gdof > 0) {
    250:       PetscInt fdof, fc, f2, poff = 0;

    252:       PetscSectionGetOffset(sectionGlobal, p, &goff);
    253:       /* Can get rid of this loop by storing field information in the global section */
    254:       for (f2 = 0; f2 < field; ++f2) {
    255:         PetscSectionGetFieldDof(section, p, f2, &fdof);
    256:         poff += fdof;
    257:       }
    258:       PetscSectionGetFieldDof(section, p, field, &fdof);
    259:       for (fc = 0; fc < fdof; ++fc, ++subOff) subIndices[subOff] = goff+poff+fc;
    260:     }
    261:   }
    262:   ISCreateGeneral(PetscObjectComm((PetscObject) v), subSize, subIndices, PETSC_OWN_POINTER, is);
    263:   VecGetSubVector(v, *is, subv);
    264:   VecSetBlockSize(*subv, Nc);
    265:   return(0);
    266: }

    270: PetscErrorCode PetscSectionRestoreField_Internal(PetscSection section, PetscSection sectionGlobal, Vec v, PetscInt field, PetscInt pStart, PetscInt pEnd, IS *is, Vec *subv)
    271: {

    275:   VecRestoreSubVector(v, *is, subv);
    276:   ISDestroy(is);
    277:   return(0);
    278: }

    282: /*@C
    283:   PetscSectionVecNorm - Computes the vector norm, separated into field components.

    285:   Input Parameters:
    286: + s    - the local Section
    287: . gs   - the global section
    288: . x    - the vector
    289: - type - one of NORM_1, NORM_2, NORM_INFINITY.

    291:   Output Parameter:
    292: . val  - the array of norms

    294:   Level: intermediate

    296: .seealso: VecNorm(), PetscSectionCreate()
    297: @*/
    298: PetscErrorCode PetscSectionVecNorm(PetscSection s, PetscSection gs, Vec x, NormType type, PetscReal val[])
    299: {
    300:   PetscInt       Nf, f, pStart, pEnd;

    308:   PetscSectionGetNumFields(s, &Nf);
    309:   if (Nf < 2) {VecNorm(x, type, val);}
    310:   else {
    311:     PetscSectionGetChart(s, &pStart, &pEnd);
    312:     for (f = 0; f < Nf; ++f) {
    313:       Vec subv;
    314:       IS  is;

    316:       PetscSectionGetField_Internal(s, gs, x, f, pStart, pEnd, &is, &subv);
    317:       VecNorm(subv, type, &val[f]);
    318:       PetscSectionRestoreField_Internal(s, gs, x, f, pStart, pEnd, &is, &subv);
    319:     }
    320:   }
    321:   return(0);
    322: }