Actual source code: bvec2.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      2: /*
      3:    Implements the sequential vectors.
      4: */

      6:  #include <../src/vec/vec/impls/dvecimpl.h>
      7: #include <../src/vec/vec/impls/mpi/pvecimpl.h>      /* For VecView_MPI_HDF5 */
      8:  #include <petsc/private/glvisviewerimpl.h>
      9:  #include <petsc/private/glvisvecimpl.h>
     10:  #include <petscblaslapack.h>

     12: #if defined(PETSC_HAVE_HDF5)
     13: extern PetscErrorCode VecView_MPI_HDF5(Vec,PetscViewer);
     14: #endif

     16: PetscErrorCode VecPointwiseMax_Seq(Vec win,Vec xin,Vec yin)
     17: {
     19:   PetscInt       n = win->map->n,i;
     20:   PetscScalar    *ww,*xx,*yy; /* cannot make xx or yy const since might be ww */

     23:   VecGetArrayRead(xin,(const PetscScalar**)&xx);
     24:   VecGetArrayRead(yin,(const PetscScalar**)&yy);
     25:   VecGetArray(win,&ww);

     27:   for (i=0; i<n; i++) ww[i] = PetscMax(PetscRealPart(xx[i]),PetscRealPart(yy[i]));

     29:   VecRestoreArrayRead(xin,(const PetscScalar**)&xx);
     30:   VecRestoreArrayRead(yin,(const PetscScalar**)&yy);
     31:   VecRestoreArray(win,&ww);
     32:   PetscLogFlops(n);
     33:   return(0);
     34: }

     36: PetscErrorCode VecPointwiseMin_Seq(Vec win,Vec xin,Vec yin)
     37: {
     39:   PetscInt       n = win->map->n,i;
     40:   PetscScalar    *ww,*xx,*yy; /* cannot make xx or yy const since might be ww */

     43:   VecGetArrayRead(xin,(const PetscScalar**)&xx);
     44:   VecGetArrayRead(yin,(const PetscScalar**)&yy);
     45:   VecGetArray(win,&ww);

     47:   for (i=0; i<n; i++) ww[i] = PetscMin(PetscRealPart(xx[i]),PetscRealPart(yy[i]));

     49:   VecRestoreArrayRead(xin,(const PetscScalar**)&xx);
     50:   VecRestoreArrayRead(yin,(const PetscScalar**)&yy);
     51:   VecRestoreArray(win,&ww);
     52:   PetscLogFlops(n);
     53:   return(0);
     54: }

     56: PetscErrorCode VecPointwiseMaxAbs_Seq(Vec win,Vec xin,Vec yin)
     57: {
     59:   PetscInt       n = win->map->n,i;
     60:   PetscScalar    *ww,*xx,*yy; /* cannot make xx or yy const since might be ww */

     63:   VecGetArrayRead(xin,(const PetscScalar**)&xx);
     64:   VecGetArrayRead(yin,(const PetscScalar**)&yy);
     65:   VecGetArray(win,&ww);

     67:   for (i=0; i<n; i++) ww[i] = PetscMax(PetscAbsScalar(xx[i]),PetscAbsScalar(yy[i]));

     69:   PetscLogFlops(n);
     70:   VecRestoreArrayRead(xin,(const PetscScalar**)&xx);
     71:   VecRestoreArrayRead(yin,(const PetscScalar**)&yy);
     72:   VecRestoreArray(win,&ww);
     73:   return(0);
     74: }

     76: #include <../src/vec/vec/impls/seq/ftn-kernels/fxtimesy.h>

     78: PetscErrorCode VecPointwiseMult_Seq(Vec win,Vec xin,Vec yin)
     79: {
     81:   PetscInt       n = win->map->n,i;
     82:   PetscScalar    *ww,*xx,*yy; /* cannot make xx or yy const since might be ww */

     85:   VecGetArrayRead(xin,(const PetscScalar**)&xx);
     86:   VecGetArrayRead(yin,(const PetscScalar**)&yy);
     87:   VecGetArray(win,&ww);
     88:   if (ww == xx) {
     89:     for (i=0; i<n; i++) ww[i] *= yy[i];
     90:   } else if (ww == yy) {
     91:     for (i=0; i<n; i++) ww[i] *= xx[i];
     92:   } else {
     93: #if defined(PETSC_USE_FORTRAN_KERNEL_XTIMESY)
     94:     fortranxtimesy_(xx,yy,ww,&n);
     95: #else
     96:     for (i=0; i<n; i++) ww[i] = xx[i] * yy[i];
     97: #endif
     98:   }
     99:   VecRestoreArrayRead(xin,(const PetscScalar**)&xx);
    100:   VecRestoreArrayRead(yin,(const PetscScalar**)&yy);
    101:   VecRestoreArray(win,&ww);
    102:   PetscLogFlops(n);
    103:   return(0);
    104: }

    106: PetscErrorCode VecPointwiseDivide_Seq(Vec win,Vec xin,Vec yin)
    107: {
    109:   PetscInt       n = win->map->n,i;
    110:   PetscScalar    *ww,*xx,*yy; /* cannot make xx or yy const since might be ww */

    113:   VecGetArrayRead(xin,(const PetscScalar**)&xx);
    114:   VecGetArrayRead(yin,(const PetscScalar**)&yy);
    115:   VecGetArray(win,&ww);

    117:   for (i=0; i<n; i++) {
    118:     if (yy[i] != 0.0) ww[i] = xx[i] / yy[i];
    119:     else ww[i] = 0.0;
    120:   }

    122:   PetscLogFlops(n);
    123:   VecRestoreArrayRead(xin,(const PetscScalar**)&xx);
    124:   VecRestoreArrayRead(yin,(const PetscScalar**)&yy);
    125:   VecRestoreArray(win,&ww);
    126:   return(0);
    127: }

    129: PetscErrorCode VecSetRandom_Seq(Vec xin,PetscRandom r)
    130: {
    132:   PetscInt       n = xin->map->n,i;
    133:   PetscScalar    *xx;

    136:   VecGetArray(xin,&xx);
    137:   for (i=0; i<n; i++) {PetscRandomGetValue(r,&xx[i]);}
    138:   VecRestoreArray(xin,&xx);
    139:   return(0);
    140: }

    142: PetscErrorCode VecGetSize_Seq(Vec vin,PetscInt *size)
    143: {
    145:   *size = vin->map->n;
    146:   return(0);
    147: }

    151: PetscErrorCode VecConjugate_Seq(Vec xin)
    152: {
    153:   PetscScalar    *x;
    154:   PetscInt       n = xin->map->n;

    158:   VecGetArray(xin,&x);
    159:   while (n-->0) {
    160:     *x = PetscConj(*x);
    161:     x++;
    162:   }
    163:   VecRestoreArray(xin,&x);
    164:   return(0);
    165: }

    167: PetscErrorCode VecResetArray_Seq(Vec vin)
    168: {
    169:   Vec_Seq *v = (Vec_Seq*)vin->data;

    172:   v->array         = v->unplacedarray;
    173:   v->unplacedarray = 0;
    174:   return(0);
    175: }

    177: PetscErrorCode VecCopy_Seq(Vec xin,Vec yin)
    178: {
    179:   PetscScalar       *ya;
    180:   const PetscScalar *xa;
    181:   PetscErrorCode    ierr;

    184:   if (xin != yin) {
    185:     VecGetArrayRead(xin,&xa);
    186:     VecGetArray(yin,&ya);
    187:     PetscMemcpy(ya,xa,xin->map->n*sizeof(PetscScalar));
    188:     VecRestoreArrayRead(xin,&xa);
    189:     VecRestoreArray(yin,&ya);
    190:   }
    191:   return(0);
    192: }

    194: PetscErrorCode VecSwap_Seq(Vec xin,Vec yin)
    195: {
    196:   PetscScalar    *ya, *xa;
    198:   PetscBLASInt   one = 1,bn;

    201:   if (xin != yin) {
    202:     PetscBLASIntCast(xin->map->n,&bn);
    203:     VecGetArray(xin,&xa);
    204:     VecGetArray(yin,&ya);
    205:     PetscStackCallBLAS("BLASswap",BLASswap_(&bn,xa,&one,ya,&one));
    206:     VecRestoreArray(xin,&xa);
    207:     VecRestoreArray(yin,&ya);
    208:   }
    209:   return(0);
    210: }

    212: #include <../src/vec/vec/impls/seq/ftn-kernels/fnorm.h>

    214: PetscErrorCode VecNorm_Seq(Vec xin,NormType type,PetscReal *z)
    215: {
    216:   const PetscScalar *xx;
    217:   PetscErrorCode    ierr;
    218:   PetscInt          n = xin->map->n;
    219:   PetscBLASInt      one = 1, bn;

    222:   PetscBLASIntCast(n,&bn);
    223:   if (type == NORM_2 || type == NORM_FROBENIUS) {
    224:     VecGetArrayRead(xin,&xx);
    225: #if defined(PETSC_USE_REAL___FP16)
    226:     *z   = BLASnrm2_(&bn,xx,&one);
    227: #else
    228:     *z   = PetscRealPart(BLASdot_(&bn,xx,&one,xx,&one));
    229:     *z   = PetscSqrtReal(*z);
    230: #endif
    231:     VecRestoreArrayRead(xin,&xx);
    232:     PetscLogFlops(PetscMax(2.0*n-1,0.0));
    233:   } else if (type == NORM_INFINITY) {
    234:     PetscInt  i;
    235:     PetscReal max = 0.0,tmp;

    237:     VecGetArrayRead(xin,&xx);
    238:     for (i=0; i<n; i++) {
    239:       if ((tmp = PetscAbsScalar(*xx)) > max) max = tmp;
    240:       /* check special case of tmp == NaN */
    241:       if (tmp != tmp) {max = tmp; break;}
    242:       xx++;
    243:     }
    244:     VecRestoreArrayRead(xin,&xx);
    245:     *z   = max;
    246:   } else if (type == NORM_1) {
    247: #if defined(PETSC_USE_COMPLEX)
    248:     PetscReal tmp = 0.0;
    249:     PetscInt    i;
    250: #endif
    251:     VecGetArrayRead(xin,&xx);
    252: #if defined(PETSC_USE_COMPLEX)
    253:     /* BLASasum() returns the nonstandard 1 norm of the 1 norm of the complex entries so we provide a custom loop instead */
    254:     for (i=0; i<n; i++) {
    255:       tmp += PetscAbsScalar(xx[i]);
    256:     }
    257:     *z = tmp;
    258: #else
    259:     PetscStackCallBLAS("BLASasum",*z   = BLASasum_(&bn,xx,&one));
    260: #endif
    261:     VecRestoreArrayRead(xin,&xx);
    262:     PetscLogFlops(PetscMax(n-1.0,0.0));
    263:   } else if (type == NORM_1_AND_2) {
    264:     VecNorm_Seq(xin,NORM_1,z);
    265:     VecNorm_Seq(xin,NORM_2,z+1);
    266:   }
    267:   return(0);
    268: }

    270: PetscErrorCode VecView_Seq_ASCII(Vec xin,PetscViewer viewer)
    271: {
    272:   PetscErrorCode    ierr;
    273:   PetscInt          i,n = xin->map->n;
    274:   const char        *name;
    275:   PetscViewerFormat format;
    276:   const PetscScalar *xv;

    279:   VecGetArrayRead(xin,&xv);
    280:   PetscViewerGetFormat(viewer,&format);
    281:   if (format == PETSC_VIEWER_ASCII_MATLAB) {
    282:     PetscObjectGetName((PetscObject)xin,&name);
    283:     PetscViewerASCIIPrintf(viewer,"%s = [\n",name);
    284:     for (i=0; i<n; i++) {
    285: #if defined(PETSC_USE_COMPLEX)
    286:       if (PetscImaginaryPart(xv[i]) > 0.0) {
    287:         PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei\n",(double)PetscRealPart(xv[i]),(double)PetscImaginaryPart(xv[i]));
    288:       } else if (PetscImaginaryPart(xv[i]) < 0.0) {
    289:         PetscViewerASCIIPrintf(viewer,"%18.16e - %18.16ei\n",(double)PetscRealPart(xv[i]),-(double)PetscImaginaryPart(xv[i]));
    290:       } else {
    291:         PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)PetscRealPart(xv[i]));
    292:       }
    293: #else
    294:       PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double) xv[i]);
    295: #endif
    296:     }
    297:     PetscViewerASCIIPrintf(viewer,"];\n");
    298:   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
    299:     for (i=0; i<n; i++) {
    300: #if defined(PETSC_USE_COMPLEX)
    301:       PetscViewerASCIIPrintf(viewer,"%18.16e %18.16e\n",(double)PetscRealPart(xv[i]),(double)PetscImaginaryPart(xv[i]));
    302: #else
    303:       PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)xv[i]);
    304: #endif
    305:     }
    306:   } else if (format == PETSC_VIEWER_ASCII_VTK || format == PETSC_VIEWER_ASCII_VTK_CELL) {
    307:     /*
    308:        state 0: No header has been output
    309:        state 1: Only POINT_DATA has been output
    310:        state 2: Only CELL_DATA has been output
    311:        state 3: Output both, POINT_DATA last
    312:        state 4: Output both, CELL_DATA last
    313:     */
    314:     static PetscInt stateId = -1;
    315:     int outputState = 0;
    316:     PetscBool  hasState;
    317:     int doOutput = 0;
    318:     PetscInt bs, b;

    320:     if (stateId < 0) {
    321:       PetscObjectComposedDataRegister(&stateId);
    322:     }
    323:     PetscObjectComposedDataGetInt((PetscObject) viewer, stateId, outputState, hasState);
    324:     if (!hasState) outputState = 0;
    325:     PetscObjectGetName((PetscObject) xin, &name);
    326:     VecGetBlockSize(xin, &bs);
    327:     if ((bs < 1) || (bs > 3)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "VTK can only handle 3D objects, but vector dimension is %d", bs);
    328:     if (format == PETSC_VIEWER_ASCII_VTK) {
    329:       if (outputState == 0) {
    330:         outputState = 1;
    331:         doOutput = 1;
    332:       } else if (outputState == 1) doOutput = 0;
    333:       else if (outputState == 2) {
    334:         outputState = 3;
    335:         doOutput = 1;
    336:       } else if (outputState == 3) doOutput = 0;
    337:       else if (outputState == 4) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Tried to output POINT_DATA again after intervening CELL_DATA");

    339:       if (doOutput) {
    340:         PetscViewerASCIIPrintf(viewer, "POINT_DATA %d\n", n/bs);
    341:       }
    342:     } else {
    343:       if (outputState == 0) {
    344:         outputState = 2;
    345:         doOutput = 1;
    346:       } else if (outputState == 1) {
    347:         outputState = 4;
    348:         doOutput = 1;
    349:       } else if (outputState == 2) doOutput = 0;
    350:       else if (outputState == 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Tried to output CELL_DATA again after intervening POINT_DATA");
    351:       else if (outputState == 4) doOutput = 0;

    353:       if (doOutput) {
    354:         PetscViewerASCIIPrintf(viewer, "CELL_DATA %d\n", n);
    355:       }
    356:     }
    357:     PetscObjectComposedDataSetInt((PetscObject) viewer, stateId, outputState);
    358:     if (name) {
    359:       if (bs == 3) {
    360:         PetscViewerASCIIPrintf(viewer, "VECTORS %s double\n", name);
    361:       } else {
    362:         PetscViewerASCIIPrintf(viewer, "SCALARS %s double %d\n", name, bs);
    363:       }
    364:     } else {
    365:       PetscViewerASCIIPrintf(viewer, "SCALARS scalars double %d\n", bs);
    366:     }
    367:     if (bs != 3) {
    368:       PetscViewerASCIIPrintf(viewer, "LOOKUP_TABLE default\n");
    369:     }
    370:     for (i=0; i<n/bs; i++) {
    371:       for (b=0; b<bs; b++) {
    372:         if (b > 0) {
    373:           PetscViewerASCIIPrintf(viewer," ");
    374:         }
    375: #if !defined(PETSC_USE_COMPLEX)
    376:         PetscViewerASCIIPrintf(viewer,"%g",(double)xv[i*bs+b]);
    377: #endif
    378:       }
    379:       PetscViewerASCIIPrintf(viewer,"\n");
    380:     }
    381:   } else if (format == PETSC_VIEWER_ASCII_VTK_COORDS) {
    382:     PetscInt bs, b;

    384:     VecGetBlockSize(xin, &bs);
    385:     if ((bs < 1) || (bs > 3)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "VTK can only handle 3D objects, but vector dimension is %d", bs);
    386:     for (i=0; i<n/bs; i++) {
    387:       for (b=0; b<bs; b++) {
    388:         if (b > 0) {
    389:           PetscViewerASCIIPrintf(viewer," ");
    390:         }
    391: #if !defined(PETSC_USE_COMPLEX)
    392:         PetscViewerASCIIPrintf(viewer,"%g",(double)xv[i*bs+b]);
    393: #endif
    394:       }
    395:       for (b=bs; b<3; b++) {
    396:         PetscViewerASCIIPrintf(viewer," 0.0");
    397:       }
    398:       PetscViewerASCIIPrintf(viewer,"\n");
    399:     }
    400:   } else if (format == PETSC_VIEWER_ASCII_PCICE) {
    401:     PetscInt bs, b;

    403:     VecGetBlockSize(xin, &bs);
    404:     if ((bs < 1) || (bs > 3)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "PCICE can only handle up to 3D objects, but vector dimension is %d", bs);
    405:     PetscViewerASCIIPrintf(viewer,"%D\n", xin->map->N/bs);
    406:     for (i=0; i<n/bs; i++) {
    407:       PetscViewerASCIIPrintf(viewer,"%7D   ", i+1);
    408:       for (b=0; b<bs; b++) {
    409:         if (b > 0) {
    410:           PetscViewerASCIIPrintf(viewer," ");
    411:         }
    412: #if !defined(PETSC_USE_COMPLEX)
    413:         PetscViewerASCIIPrintf(viewer,"% 12.5E",(double)xv[i*bs+b]);
    414: #endif
    415:       }
    416:       PetscViewerASCIIPrintf(viewer,"\n");
    417:     }
    418:   } else if (format == PETSC_VIEWER_ASCII_GLVIS) {
    419:     /* GLVis ASCII visualization/dump: this function mimicks mfem::GridFunction::Save() */
    420:     const PetscScalar       *array;
    421:     PetscInt                i,n,vdim, ordering = 1; /* mfem::FiniteElementSpace::Ordering::byVDIM */
    422:     PetscContainer          glvis_container;
    423:     PetscViewerGLVisVecInfo glvis_vec_info;
    424:     PetscViewerGLVisInfo    glvis_info;
    425:     PetscErrorCode          ierr;

    427:     /* mfem::FiniteElementSpace::Save() */
    428:     VecGetBlockSize(xin,&vdim);
    429:     PetscViewerASCIIPrintf(viewer,"FiniteElementSpace\n");
    430:     PetscObjectQuery((PetscObject)xin,"_glvis_info_container",(PetscObject*)&glvis_container);
    431:     if (!glvis_container) SETERRQ(PetscObjectComm((PetscObject)xin),PETSC_ERR_PLIB,"Missing GLVis container");
    432:     PetscContainerGetPointer(glvis_container,(void**)&glvis_vec_info);
    433:     PetscViewerASCIIPrintf(viewer,"%s\n",glvis_vec_info->fec_type);
    434:     PetscViewerASCIIPrintf(viewer,"VDim: %d\n",vdim);
    435:     PetscViewerASCIIPrintf(viewer,"Ordering: %d\n",ordering);
    436:     PetscViewerASCIIPrintf(viewer,"\n");
    437:     /* mfem::Vector::Print() */
    438:     PetscObjectQuery((PetscObject)viewer,"_glvis_info_container",(PetscObject*)&glvis_container);
    439:     if (!glvis_container) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_PLIB,"Missing GLVis container");
    440:     PetscContainerGetPointer(glvis_container,(void**)&glvis_info);
    441:     if (glvis_info->enabled) {
    442:       VecGetLocalSize(xin,&n);
    443:       VecGetArrayRead(xin,&array);
    444:       for (i=0;i<n;i++) {
    445:         PetscViewerASCIIPrintf(viewer,glvis_info->fmt,(double)PetscRealPart(array[i]));
    446:         PetscViewerASCIIPrintf(viewer,"\n");
    447:       }
    448:       VecRestoreArrayRead(xin,&array);
    449:     }
    450:   } else if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
    451:     /* No info */
    452:   } else {
    453:     for (i=0; i<n; i++) {
    454:       if (format == PETSC_VIEWER_ASCII_INDEX) {
    455:         PetscViewerASCIIPrintf(viewer,"%D: ",i);
    456:       }
    457: #if defined(PETSC_USE_COMPLEX)
    458:       if (PetscImaginaryPart(xv[i]) > 0.0) {
    459:         PetscViewerASCIIPrintf(viewer,"%g + %g i\n",(double)PetscRealPart(xv[i]),(double)PetscImaginaryPart(xv[i]));
    460:       } else if (PetscImaginaryPart(xv[i]) < 0.0) {
    461:         PetscViewerASCIIPrintf(viewer,"%g - %g i\n",(double)PetscRealPart(xv[i]),-(double)PetscImaginaryPart(xv[i]));
    462:       } else {
    463:         PetscViewerASCIIPrintf(viewer,"%g\n",(double)PetscRealPart(xv[i]));
    464:       }
    465: #else
    466:       PetscViewerASCIIPrintf(viewer,"%g\n",(double)xv[i]);
    467: #endif
    468:     }
    469:   }
    470:   PetscViewerFlush(viewer);
    471:   VecRestoreArrayRead(xin,&xv);
    472:   return(0);
    473: }

    475:  #include <petscdraw.h>
    476: PetscErrorCode VecView_Seq_Draw_LG(Vec xin,PetscViewer v)
    477: {
    478:   PetscDraw         draw;
    479:   PetscBool         isnull;
    480:   PetscDrawLG       lg;
    481:   PetscErrorCode    ierr;
    482:   PetscInt          i,c,bs = PetscAbs(xin->map->bs),n = xin->map->n/bs;
    483:   const PetscScalar *xv;
    484:   PetscReal         *xx,*yy;
    485:   int               colors[] = {PETSC_DRAW_RED};

    488:   PetscViewerDrawGetDraw(v,0,&draw);
    489:   PetscDrawIsNull(draw,&isnull);
    490:   if (isnull) return(0);

    492:   PetscMalloc2(n,&xx,n,&yy);
    493:   VecGetArrayRead(xin,&xv);
    494:   for (c=0; c<bs; c++) {
    495:     PetscViewerDrawGetDrawLG(v,c,&lg);
    496:     PetscDrawLGReset(lg);
    497:     PetscDrawLGSetDimension(lg,1);
    498:     PetscDrawLGSetColors(lg,colors);
    499:     for (i=0; i<n; i++) {
    500:       xx[i] = (PetscReal)i;
    501:       yy[i] = PetscRealPart(xv[c + i*bs]);
    502:     }
    503:     PetscDrawLGAddPoints(lg,n,&xx,&yy);
    504:     PetscDrawLGDraw(lg);
    505:     PetscDrawLGSave(lg);
    506:   }
    507:   VecRestoreArrayRead(xin,&xv);
    508:   PetscFree2(xx,yy);
    509:   return(0);
    510: }

    512: PetscErrorCode VecView_Seq_Draw(Vec xin,PetscViewer v)
    513: {
    514:   PetscErrorCode    ierr;
    515:   PetscDraw         draw;
    516:   PetscBool         isnull;

    519:   PetscViewerDrawGetDraw(v,0,&draw);
    520:   PetscDrawIsNull(draw,&isnull);
    521:   if (isnull) return(0);
    522:   PetscViewerPushFormat(v,PETSC_VIEWER_DRAW_LG);
    523:   VecView_Seq_Draw_LG(xin,v);
    524:   PetscViewerPopFormat(v);
    525:   return(0);
    526: }

    528: PetscErrorCode VecView_Seq_Binary(Vec xin,PetscViewer viewer)
    529: {
    530:   PetscErrorCode    ierr;
    531:   int               fdes;
    532:   PetscInt          n = xin->map->n,classid=VEC_FILE_CLASSID;
    533:   FILE              *file;
    534:   const PetscScalar *xv;
    535: #if defined(PETSC_HAVE_MPIIO)
    536:   PetscBool         isMPIIO;
    537: #endif
    538:   PetscBool         skipHeader;
    539:   PetscViewerFormat format;

    542:   /* Write vector header */
    543:   PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);
    544:   if (!skipHeader) {
    545:     PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);
    546:     PetscViewerBinaryWrite(viewer,&n,1,PETSC_INT,PETSC_FALSE);
    547:   }

    549:   /* Write vector contents */
    550: #if defined(PETSC_HAVE_MPIIO)
    551:   PetscViewerBinaryGetUseMPIIO(viewer,&isMPIIO);
    552:   if (!isMPIIO) {
    553: #endif
    554:     PetscViewerBinaryGetDescriptor(viewer,&fdes);
    555:     VecGetArrayRead(xin,&xv);
    556:     PetscBinaryWrite(fdes,(void*)xv,n,PETSC_SCALAR,PETSC_FALSE);
    557:     VecRestoreArrayRead(xin,&xv);
    558:     PetscViewerGetFormat(viewer,&format);
    559:     if (format == PETSC_VIEWER_BINARY_MATLAB) {
    560:       MPI_Comm   comm;
    561:       FILE       *info;
    562:       const char *name;

    564:       PetscObjectGetName((PetscObject)xin,&name);
    565:       PetscObjectGetComm((PetscObject)viewer,&comm);
    566:       PetscViewerBinaryGetInfoPointer(viewer,&info);
    567:       PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
    568:       PetscFPrintf(comm,info,"#$$ Set.%s = PetscBinaryRead(fd);\n",name);
    569:       PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
    570:     }
    571: #if defined(PETSC_HAVE_MPIIO)
    572:   } else {
    573:     MPI_Offset   off;
    574:     MPI_File     mfdes;
    575:     PetscMPIInt  lsize;

    577:     PetscMPIIntCast(n,&lsize);
    578:     PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);
    579:     PetscViewerBinaryGetMPIIOOffset(viewer,&off);
    580:     MPI_File_set_view(mfdes,off,MPIU_SCALAR,MPIU_SCALAR,(char*)"native",MPI_INFO_NULL);
    581:     VecGetArrayRead(xin,&xv);
    582:     MPIU_File_write_all(mfdes,(void*)xv,lsize,MPIU_SCALAR,MPI_STATUS_IGNORE);
    583:     VecRestoreArrayRead(xin,&xv);
    584:     PetscViewerBinaryAddMPIIOOffset(viewer,n*sizeof(PetscScalar));
    585:   }
    586: #endif

    588:   PetscViewerBinaryGetInfoPointer(viewer,&file);
    589:   if (file) {
    590:     if (((PetscObject)xin)->prefix) {
    591:       PetscFPrintf(PETSC_COMM_SELF,file,"-%svecload_block_size %D\n",((PetscObject)xin)->prefix,PetscAbs(xin->map->bs));
    592:     } else {
    593:       PetscFPrintf(PETSC_COMM_SELF,file,"-vecload_block_size %D\n",PetscAbs(xin->map->bs));
    594:     }
    595:   }
    596:   return(0);
    597: }

    599: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    600:  #include <petscmatlab.h>
    601: #include <mat.h>   /* MATLAB include file */
    602: PetscErrorCode VecView_Seq_Matlab(Vec vec,PetscViewer viewer)
    603: {
    604:   PetscErrorCode    ierr;
    605:   PetscInt          n;
    606:   const PetscScalar *array;

    609:   VecGetLocalSize(vec,&n);
    610:   PetscObjectName((PetscObject)vec);
    611:   VecGetArrayRead(vec,&array);
    612:   PetscViewerMatlabPutArray(viewer,n,1,array,((PetscObject)vec)->name);
    613:   VecRestoreArrayRead(vec,&array);
    614:   return(0);
    615: }
    616: #endif

    618: PETSC_EXTERN PetscErrorCode VecView_Seq(Vec xin,PetscViewer viewer)
    619: {
    621:   PetscBool      isdraw,iascii,issocket,isbinary;
    622: #if defined(PETSC_HAVE_MATHEMATICA)
    623:   PetscBool      ismathematica;
    624: #endif
    625: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    626:   PetscBool      ismatlab;
    627: #endif
    628: #if defined(PETSC_HAVE_HDF5)
    629:   PetscBool      ishdf5;
    630: #endif
    631:   PetscBool      isglvis;
    632: #if defined(PETSC_HAVE_ADIOS)
    633:   PetscBool      isadios;
    634: #endif
    635: #if defined(PETSC_HAVE_ADIOS2)
    636:   PetscBool      isadios2;
    637: #endif

    640:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    641:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    642:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSOCKET,&issocket);
    643:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
    644: #if defined(PETSC_HAVE_MATHEMATICA)
    645:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERMATHEMATICA,&ismathematica);
    646: #endif
    647: #if defined(PETSC_HAVE_HDF5)
    648:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
    649: #endif
    650: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    651:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERMATLAB,&ismatlab);
    652: #endif
    653:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERGLVIS,&isglvis);
    654: #if defined(PETSC_HAVE_ADIOS)
    655:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERADIOS,&isadios);
    656: #endif
    657: #if defined(PETSC_HAVE_ADIOS2)
    658:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERADIOS2,&isadios2);
    659: #endif

    661:   if (isdraw) {
    662:     VecView_Seq_Draw(xin,viewer);
    663:   } else if (iascii) {
    664:     VecView_Seq_ASCII(xin,viewer);
    665:   } else if (isbinary) {
    666:     VecView_Seq_Binary(xin,viewer);
    667: #if defined(PETSC_HAVE_MATHEMATICA)
    668:   } else if (ismathematica) {
    669:     PetscViewerMathematicaPutVector(viewer,xin);
    670: #endif
    671: #if defined(PETSC_HAVE_HDF5)
    672:   } else if (ishdf5) {
    673:     VecView_MPI_HDF5(xin,viewer); /* Reusing VecView_MPI_HDF5 ... don't want code duplication*/
    674: #endif
    675: #if defined(PETSC_HAVE_ADIOS)
    676:   } else if (isadios) {
    677:     VecView_MPI_ADIOS(xin,viewer); /* Reusing VecView_MPI_ADIOS ... don't want code duplication*/
    678: #endif
    679: #if defined(PETSC_HAVE_ADIOS2)
    680:   } else if (isadios2) {
    681:     VecView_MPI_ADIOS2(xin,viewer); /* Reusing VecView_MPI_ADIOS2 ... don't want code duplication*/
    682: #endif
    683: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    684:   } else if (ismatlab) {
    685:     VecView_Seq_Matlab(xin,viewer);
    686: #endif
    687:   } else if (isglvis) {
    688:     VecView_GLVis(xin,viewer);
    689:   }
    690:   return(0);
    691: }

    693: PetscErrorCode VecGetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],PetscScalar y[])
    694: {
    695:   const PetscScalar *xx;
    696:   PetscInt          i;
    697:   PetscErrorCode    ierr;

    700:   VecGetArrayRead(xin,&xx);
    701:   for (i=0; i<ni; i++) {
    702:     if (xin->stash.ignorenegidx && ix[i] < 0) continue;
    703: #if defined(PETSC_USE_DEBUG)
    704:     if (ix[i] < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D cannot be negative",ix[i]);
    705:     if (ix[i] >= xin->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D to large maximum allowed %D",ix[i],xin->map->n);
    706: #endif
    707:     y[i] = xx[ix[i]];
    708:   }
    709:   VecRestoreArrayRead(xin,&xx);
    710:   return(0);
    711: }

    713: PetscErrorCode VecSetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode m)
    714: {
    715:   PetscScalar    *xx;
    716:   PetscInt       i;

    720:   VecGetArray(xin,&xx);
    721:   if (m == INSERT_VALUES) {
    722:     for (i=0; i<ni; i++) {
    723:       if (xin->stash.ignorenegidx && ix[i] < 0) continue;
    724: #if defined(PETSC_USE_DEBUG)
    725:       if (ix[i] < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D cannot be negative",ix[i]);
    726:       if (ix[i] >= xin->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",ix[i],xin->map->n);
    727: #endif
    728:       xx[ix[i]] = y[i];
    729:     }
    730:   } else {
    731:     for (i=0; i<ni; i++) {
    732:       if (xin->stash.ignorenegidx && ix[i] < 0) continue;
    733: #if defined(PETSC_USE_DEBUG)
    734:       if (ix[i] < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D cannot be negative",ix[i]);
    735:       if (ix[i] >= xin->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",ix[i],xin->map->n);
    736: #endif
    737:       xx[ix[i]] += y[i];
    738:     }
    739:   }
    740:   VecRestoreArray(xin,&xx);
    741:   return(0);
    742: }

    744: PetscErrorCode VecSetValuesBlocked_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar yin[],InsertMode m)
    745: {
    746:   PetscScalar    *xx,*y = (PetscScalar*)yin;
    747:   PetscInt       i,bs,start,j;

    750:   /*
    751:        For optimization could treat bs = 2, 3, 4, 5 as special cases with loop unrolling
    752:   */
    754:   VecGetBlockSize(xin,&bs);
    755:   VecGetArray(xin,&xx);
    756:   if (m == INSERT_VALUES) {
    757:     for (i=0; i<ni; i++, y+=bs) {
    758:       start = bs*ix[i];
    759:       if (start < 0) continue;
    760: #if defined(PETSC_USE_DEBUG)
    761:       if (start >= xin->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",start,xin->map->n);
    762: #endif
    763:       for (j=0; j<bs; j++) xx[start+j] = y[j];
    764:     }
    765:   } else {
    766:     for (i=0; i<ni; i++, y+=bs) {
    767:       start = bs*ix[i];
    768:       if (start < 0) continue;
    769: #if defined(PETSC_USE_DEBUG)
    770:       if (start >= xin->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",start,xin->map->n);
    771: #endif
    772:       for (j=0; j<bs; j++) xx[start+j] += y[j];
    773:     }
    774:   }
    775:   VecRestoreArray(xin,&xx);
    776:   return(0);
    777: }

    779: PetscErrorCode VecDestroy_Seq(Vec v)
    780: {
    781:   Vec_Seq        *vs = (Vec_Seq*)v->data;

    785: #if defined(PETSC_USE_LOG)
    786:   PetscLogObjectState((PetscObject)v,"Length=%D",v->map->n);
    787: #endif
    788:   PetscFree(vs->array_allocated);
    789:   PetscFree(v->data);
    790:   return(0);
    791: }

    793: PetscErrorCode VecSetOption_Seq(Vec v,VecOption op,PetscBool flag)
    794: {
    796:   if (op == VEC_IGNORE_NEGATIVE_INDICES) v->stash.ignorenegidx = flag;
    797:   return(0);
    798: }

    800: PetscErrorCode VecDuplicate_Seq(Vec win,Vec *V)
    801: {

    805:   VecCreate(PetscObjectComm((PetscObject)win),V);
    806:   VecSetSizes(*V,win->map->n,win->map->n);
    807:   VecSetType(*V,((PetscObject)win)->type_name);
    808:   PetscLayoutReference(win->map,&(*V)->map);
    809:   PetscObjectListDuplicate(((PetscObject)win)->olist,&((PetscObject)(*V))->olist);
    810:   PetscFunctionListDuplicate(((PetscObject)win)->qlist,&((PetscObject)(*V))->qlist);

    812:   (*V)->ops->view          = win->ops->view;
    813:   (*V)->stash.ignorenegidx = win->stash.ignorenegidx;
    814:   return(0);
    815: }

    817: static struct _VecOps DvOps = {VecDuplicate_Seq, /* 1 */
    818:                                VecDuplicateVecs_Default,
    819:                                VecDestroyVecs_Default,
    820:                                VecDot_Seq,
    821:                                VecMDot_Seq,
    822:                                VecNorm_Seq,
    823:                                VecTDot_Seq,
    824:                                VecMTDot_Seq,
    825:                                VecScale_Seq,
    826:                                VecCopy_Seq, /* 10 */
    827:                                VecSet_Seq,
    828:                                VecSwap_Seq,
    829:                                VecAXPY_Seq,
    830:                                VecAXPBY_Seq,
    831:                                VecMAXPY_Seq,
    832:                                VecAYPX_Seq,
    833:                                VecWAXPY_Seq,
    834:                                VecAXPBYPCZ_Seq,
    835:                                VecPointwiseMult_Seq,
    836:                                VecPointwiseDivide_Seq,
    837:                                VecSetValues_Seq, /* 20 */
    838:                                0,0,
    839:                                0,
    840:                                VecGetSize_Seq,
    841:                                VecGetSize_Seq,
    842:                                0,
    843:                                VecMax_Seq,
    844:                                VecMin_Seq,
    845:                                VecSetRandom_Seq,
    846:                                VecSetOption_Seq, /* 30 */
    847:                                VecSetValuesBlocked_Seq,
    848:                                VecDestroy_Seq,
    849:                                VecView_Seq,
    850:                                VecPlaceArray_Seq,
    851:                                VecReplaceArray_Seq,
    852:                                VecDot_Seq,
    853:                                VecTDot_Seq,
    854:                                VecNorm_Seq,
    855:                                VecMDot_Seq,
    856:                                VecMTDot_Seq, /* 40 */
    857:                                VecLoad_Default,
    858:                                VecReciprocal_Default,
    859:                                VecConjugate_Seq,
    860:                                0,
    861:                                0,
    862:                                VecResetArray_Seq,
    863:                                0,
    864:                                VecMaxPointwiseDivide_Seq,
    865:                                VecPointwiseMax_Seq,
    866:                                VecPointwiseMaxAbs_Seq,
    867:                                VecPointwiseMin_Seq,
    868:                                VecGetValues_Seq,
    869:                                0,
    870:                                0,
    871:                                0,
    872:                                0,
    873:                                0,
    874:                                0,
    875:                                VecStrideGather_Default,
    876:                                VecStrideScatter_Default,
    877:                                0,
    878:                                0,
    879:                                0,
    880:                                0,
    881:                                0,
    882:                                VecStrideSubSetGather_Default,
    883:                                VecStrideSubSetScatter_Default,
    884:                                0,
    885:                                0
    886: };

    889: /*
    890:       This is called by VecCreate_Seq() (i.e. VecCreateSeq()) and VecCreateSeqWithArray()
    891: */
    892: PetscErrorCode VecCreate_Seq_Private(Vec v,const PetscScalar array[])
    893: {
    894:   Vec_Seq        *s;

    898:   PetscNewLog(v,&s);
    899:   PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));

    901:   v->data            = (void*)s;
    902:   v->petscnative     = PETSC_TRUE;
    903:   s->array           = (PetscScalar*)array;
    904:   s->array_allocated = 0;

    906:   PetscLayoutSetUp(v->map);
    907:   PetscObjectChangeTypeName((PetscObject)v,VECSEQ);
    908: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    909:   PetscObjectComposeFunction((PetscObject)v,"PetscMatlabEnginePut_C",VecMatlabEnginePut_Default);
    910:   PetscObjectComposeFunction((PetscObject)v,"PetscMatlabEngineGet_C",VecMatlabEngineGet_Default);
    911: #endif
    912:   return(0);
    913: }

    915: /*@C
    916:    VecCreateSeqWithArray - Creates a standard,sequential array-style vector,
    917:    where the user provides the array space to store the vector values.

    919:    Collective on MPI_Comm

    921:    Input Parameter:
    922: +  comm - the communicator, should be PETSC_COMM_SELF
    923: .  bs - the block size
    924: .  n - the vector length
    925: -  array - memory where the vector elements are to be stored.

    927:    Output Parameter:
    928: .  V - the vector

    930:    Notes:
    931:    Use VecDuplicate() or VecDuplicateVecs() to form additional vectors of the
    932:    same type as an existing vector.

    934:    If the user-provided array is NULL, then VecPlaceArray() can be used
    935:    at a later stage to SET the array for storing the vector values.

    937:    PETSc does NOT free the array when the vector is destroyed via VecDestroy().
    938:    The user should not free the array until the vector is destroyed.

    940:    Level: intermediate

    942:    Concepts: vectors^creating with array

    944: .seealso: VecCreateMPIWithArray(), VecCreate(), VecDuplicate(), VecDuplicateVecs(),
    945:           VecCreateGhost(), VecCreateSeq(), VecPlaceArray()
    946: @*/
    947: PetscErrorCode  VecCreateSeqWithArray(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscScalar array[],Vec *V)
    948: {
    950:   PetscMPIInt    size;

    953:   VecCreate(comm,V);
    954:   VecSetSizes(*V,n,n);
    955:   VecSetBlockSize(*V,bs);
    956:   MPI_Comm_size(comm,&size);
    957:   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot create VECSEQ on more than one process");
    958:   VecCreate_Seq_Private(*V,array);
    959:   return(0);
    960: }