Actual source code: bvec2.c

      1: #define PETSCVEC_DLL
      2: /*
      3:    Implements the sequential vectors.
      4: */

     6:  #include vecimpl.h
     7:  #include src/vec/impls/dvecimpl.h
     8:  #include src/inline/dot.h
     9:  #include petscblaslapack.h
     10: #if defined(PETSC_HAVE_PNETCDF)
     12: #include "pnetcdf.h"
     14: #endif

     18: PetscErrorCode VecNorm_Seq(Vec xin,NormType type,PetscReal* z)
     19: {
     20:   PetscScalar    *xx;
     22:   PetscInt       n = xin->n;
     23:   PetscBLASInt   bn = (PetscBLASInt)n,one = 1;

     26:   if (type == NORM_2 || type == NORM_FROBENIUS) {
     27:     VecGetArray(xin,&xx);
     28:     /*
     29:       This is because the Fortran BLAS 1 Norm is very slow!
     30:     */
     31: #if defined(PETSC_HAVE_SLOW_BLAS_NORM2)
     32: #if defined(PETSC_USE_FORTRAN_KERNEL_NORM)
     33:     fortrannormsqr_(xx,&n,z);
     34:     *z = sqrt(*z);
     35: #elif defined(PETSC_USE_UNROLLED_NORM)
     36:     {
     37:     PetscReal work = 0.0;
     38:     switch (n & 0x3) {
     39:       case 3: work += PetscRealPart(xx[0]*PetscConj(xx[0])); xx++;
     40:       case 2: work += PetscRealPart(xx[0]*PetscConj(xx[0])); xx++;
     41:       case 1: work += PetscRealPart(xx[0]*PetscConj(xx[0])); xx++; n -= 4;
     42:     }
     43:     while (n>0) {
     44:       work += PetscRealPart(xx[0]*PetscConj(xx[0])+xx[1]*PetscConj(xx[1])+
     45:                         xx[2]*PetscConj(xx[2])+xx[3]*PetscConj(xx[3]));
     46:       xx += 4; n -= 4;
     47:     }
     48:     *z = sqrt(work);}
     49: #else
     50:     {
     51:       PetscInt         i;
     52:       PetscScalar sum=0.0;
     53:       for (i=0; i<n; i++) {
     54:         sum += (xx[i])*(PetscConj(xx[i]));
     55:       }
     56:       *z = sqrt(PetscRealPart(sum));
     57:     }
     58: #endif
     59: #else
     60:     *z = BLASnrm2_(&bn,xx,&one);
     61: #endif
     62:     VecRestoreArray(xin,&xx);
     63:     PetscLogFlops(2*n-1);
     64:   } else if (type == NORM_INFINITY) {
     65:     PetscInt          i;
     66:     PetscReal    max = 0.0,tmp;

     68:     VecGetArray(xin,&xx);
     69:     for (i=0; i<n; i++) {
     70:       if ((tmp = PetscAbsScalar(*xx)) > max) max = tmp;
     71:       /* check special case of tmp == NaN */
     72:       if (tmp != tmp) {max = tmp; break;}
     73:       xx++;
     74:     }
     75:     VecRestoreArray(xin,&xx);
     76:     *z   = max;
     77:   } else if (type == NORM_1) {
     78:     VecGetArray(xin,&xx);
     79:     *z = BLASasum_(&bn,xx,&one);
     80:     VecRestoreArray(xin,&xx);
     81:     PetscLogFlops(n-1);
     82:   } else if (type == NORM_1_AND_2) {
     83:     VecNorm_Seq(xin,NORM_1,z);
     84:     VecNorm_Seq(xin,NORM_2,z+1);
     85:   }
     86:   return(0);
     87: }

     91: PetscErrorCode VecView_Seq_File(Vec xin,PetscViewer viewer)
     92: {
     93:   Vec_Seq           *x = (Vec_Seq *)xin->data;
     94:   PetscErrorCode    ierr;
     95:   PetscInt          i,n = xin->n;
     96:   const char        *name;
     97:   PetscViewerFormat format;

    100:   PetscViewerGetFormat(viewer,&format);
    101:   if (format == PETSC_VIEWER_ASCII_MATLAB) {
    102:     PetscObjectGetName((PetscObject)xin,&name);
    103:     PetscViewerASCIIPrintf(viewer,"%s = [\n",name);
    104:     for (i=0; i<n; i++) {
    105: #if defined(PETSC_USE_COMPLEX)
    106:       if (PetscImaginaryPart(x->array[i]) > 0.0) {
    107:         PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei\n",PetscRealPart(x->array[i]),PetscImaginaryPart(x->array[i]));
    108:       } else if (PetscImaginaryPart(x->array[i]) < 0.0) {
    109:         PetscViewerASCIIPrintf(viewer,"%18.16e - %18.16ei\n",PetscRealPart(x->array[i]),-PetscImaginaryPart(x->array[i]));
    110:       } else {
    111:         PetscViewerASCIIPrintf(viewer,"%18.16e\n",PetscRealPart(x->array[i]));
    112:       }
    113: #else
    114:       PetscViewerASCIIPrintf(viewer,"%18.16e\n",x->array[i]);
    115: #endif
    116:     }
    117:     PetscViewerASCIIPrintf(viewer,"];\n");
    118:   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
    119:     for (i=0; i<n; i++) {
    120: #if defined(PETSC_USE_COMPLEX)
    121:       PetscViewerASCIIPrintf(viewer,"%18.16e %18.16e\n",PetscRealPart(x->array[i]),PetscImaginaryPart(x->array[i]));
    122: #else
    123:       PetscViewerASCIIPrintf(viewer,"%18.16e\n",x->array[i]);
    124: #endif
    125:     }
    126:   } else {
    127:     for (i=0; i<n; i++) {
    128:       if (format == PETSC_VIEWER_ASCII_INDEX) {
    129:         PetscViewerASCIIPrintf(viewer,"%D: ",i);
    130:       }
    131: #if defined(PETSC_USE_COMPLEX)
    132:       if (PetscImaginaryPart(x->array[i]) > 0.0) {
    133:         PetscViewerASCIIPrintf(viewer,"%g + %g i\n",PetscRealPart(x->array[i]),PetscImaginaryPart(x->array[i]));
    134:       } else if (PetscImaginaryPart(x->array[i]) < 0.0) {
    135:         PetscViewerASCIIPrintf(viewer,"%g - %g i\n",PetscRealPart(x->array[i]),-PetscImaginaryPart(x->array[i]));
    136:       } else {
    137:         PetscViewerASCIIPrintf(viewer,"%g\n",PetscRealPart(x->array[i]));
    138:       }
    139: #else
    140:       PetscViewerASCIIPrintf(viewer,"%g\n",x->array[i]);
    141: #endif
    142:     }
    143:   }
    144:   PetscViewerFlush(viewer);
    145:   return(0);
    146: }

    150: static PetscErrorCode VecView_Seq_Draw_LG(Vec xin,PetscViewer v)
    151: {
    152:   Vec_Seq        *x = (Vec_Seq *)xin->data;
    154:   PetscInt       i,n = xin->n;
    155:   PetscDraw      win;
    156:   PetscReal      *xx;
    157:   PetscDrawLG    lg;

    160:   PetscViewerDrawGetDrawLG(v,0,&lg);
    161:   PetscDrawLGGetDraw(lg,&win);
    162:   PetscDrawCheckResizedWindow(win);
    163:   PetscDrawLGReset(lg);
    164:   PetscMalloc((n+1)*sizeof(PetscReal),&xx);
    165:   for (i=0; i<n; i++) {
    166:     xx[i] = (PetscReal) i;
    167:   }
    168: #if !defined(PETSC_USE_COMPLEX)
    169:   PetscDrawLGAddPoints(lg,n,&xx,&x->array);
    170: #else
    171:   {
    172:     PetscReal *yy;
    173:     PetscMalloc((n+1)*sizeof(PetscReal),&yy);
    174:     for (i=0; i<n; i++) {
    175:       yy[i] = PetscRealPart(x->array[i]);
    176:     }
    177:     PetscDrawLGAddPoints(lg,n,&xx,&yy);
    178:     PetscFree(yy);
    179:   }
    180: #endif
    181:   PetscFree(xx);
    182:   PetscDrawLGDraw(lg);
    183:   PetscDrawSynchronizedFlush(win);
    184:   return(0);
    185: }

    189: static PetscErrorCode VecView_Seq_Draw(Vec xin,PetscViewer v)
    190: {
    191:   PetscErrorCode    ierr;
    192:   PetscDraw         draw;
    193:   PetscTruth        isnull;
    194:   PetscViewerFormat format;

    197:   PetscViewerDrawGetDraw(v,0,&draw);
    198:   PetscDrawIsNull(draw,&isnull); if (isnull) return(0);
    199:
    200:   PetscViewerGetFormat(v,&format);
    201:   /*
    202:      Currently it only supports drawing to a line graph */
    203:   if (format != PETSC_VIEWER_DRAW_LG) {
    204:     PetscViewerPushFormat(v,PETSC_VIEWER_DRAW_LG);
    205:   }
    206:   VecView_Seq_Draw_LG(xin,v);
    207:   if (format != PETSC_VIEWER_DRAW_LG) {
    208:     PetscViewerPopFormat(v);
    209:   }

    211:   return(0);
    212: }

    216: static PetscErrorCode VecView_Seq_Binary(Vec xin,PetscViewer viewer)
    217: {
    218:   Vec_Seq        *x = (Vec_Seq *)xin->data;
    220:   int            fdes;
    221:   PetscInt       n = xin->n,cookie=VEC_FILE_COOKIE;
    222:   FILE           *file;

    225:   PetscViewerBinaryGetDescriptor(viewer,&fdes);
    226:   /* Write vector header */
    227:   PetscBinaryWrite(fdes,&cookie,1,PETSC_INT,PETSC_FALSE);
    228:   PetscBinaryWrite(fdes,&n,1,PETSC_INT,PETSC_FALSE);

    230:   /* Write vector contents */
    231:   PetscBinaryWrite(fdes,x->array,n,PETSC_SCALAR,PETSC_FALSE);

    233:   PetscViewerBinaryGetInfoPointer(viewer,&file);
    234:   if (file && xin->bs > 1) {
    235:     if (xin->prefix) {
    236:       PetscFPrintf(PETSC_COMM_SELF,file,"-%s_vecload_block_size %D\n",xin->prefix,xin->bs);
    237:     } else {
    238:       PetscFPrintf(PETSC_COMM_SELF,file,"-vecload_block_size %D\n",xin->bs);
    239:     }
    240:   }
    241:   return(0);
    242: }

    244: #if defined(PETSC_HAVE_PNETCDF)
    247: PetscErrorCode VecView_Seq_Netcdf(Vec xin,PetscViewer v)
    248: {
    250:   int            n = xin->n,ncid,xdim,xdim_num=1,xin_id,xstart=0;
    251:   MPI_Comm       comm = xin->comm;
    252:   PetscScalar    *values,*xarray;

    255: #if !defined(PETSC_USE_COMPLEX)
    256:   VecGetArray(xin,&xarray);
    257:   PetscViewerNetcdfGetID(v,&ncid);
    258:   if (ncid < 0) SETERRQ(PETSC_ERR_ORDER,"First call PetscViewerNetcdfOpen to create NetCDF dataset");
    259:   /* define dimensions */
    260:   ncmpi_def_dim(ncid,"PETSc_Vector_Global_Size",n,&xdim);
    261:   /* define variables */
    262:   ncmpi_def_var(ncid,"PETSc_Vector_Seq",NC_DOUBLE,xdim_num,&xdim,&xin_id);
    263:   /* leave define mode */
    264:   ncmpi_enddef(ncid);
    265:   /* store the vector */
    266:   VecGetOwnershipRange(xin,&xstart,PETSC_NULL);
    267:   ncmpi_put_vara_double_all(ncid,xin_id,(const size_t*)&xstart,(const size_t*)&n,xarray);
    268: #else
    269:     PetscPrintf(PETSC_COMM_WORLD,"NetCDF viewer not supported for complex numbers\n");
    270: #endif
    271:   return(0);
    272: }
    273: #endif

    275: #if defined(PETSC_HAVE_MATLAB)
    276: #include "mat.h"   /* Matlab include file */
    280: PetscErrorCode VecView_Seq_Matlab(Vec vec,PetscViewer viewer)
    281: {
    283:   PetscInt       n;
    284:   PetscScalar    *array;
    285:
    287:   VecGetLocalSize(vec,&n);
    288:   PetscObjectName((PetscObject)vec);
    289:   VecGetArray(vec,&array);
    290:   PetscViewerMatlabPutArray(viewer,n,1,array,vec->name);
    291:   VecRestoreArray(vec,&array);
    292:   return(0);
    293: }
    295: #endif

    299: PetscErrorCode VecView_Seq(Vec xin,PetscViewer viewer)
    300: {
    302:   PetscTruth     isdraw,iascii,issocket,isbinary;
    303: #if defined(PETSC_HAVE_MATHEMATICA)
    304:   PetscTruth     ismathematica;
    305: #endif
    306: #if defined(PETSC_HAVE_PNETCDF)
    307:   PetscTruth     isnetcdf;
    308: #endif
    309: #if defined(PETSC_HAVE_MATLAB)
    310:   PetscTruth     ismatlab;
    311: #endif

    314:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
    315:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
    316:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
    317:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);
    318: #if defined(PETSC_HAVE_MATHEMATICA)
    319:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_MATHEMATICA,&ismathematica);
    320: #endif
    321: #if defined(PETSC_HAVE_PNETCDF)
    322:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_NETCDF,&isnetcdf);
    323: #endif
    324: #if defined(PETSC_HAVE_MATLAB)
    325:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_MATLAB,&ismatlab);
    326: #endif

    328:   if (isdraw){
    329:     VecView_Seq_Draw(xin,viewer);
    330:   } else if (iascii){
    331:     VecView_Seq_File(xin,viewer);
    332: #if defined(PETSC_USE_SOCKET_VIEWER)
    333:   } else if (issocket) {
    334:     Vec_Seq        *x = (Vec_Seq *)xin->data;
    335:     PetscViewerSocketPutScalar(viewer,xin->n,1,x->array);
    336: #endif
    337:   } else if (isbinary) {
    338:     VecView_Seq_Binary(xin,viewer);
    339: #if defined(PETSC_HAVE_MATHEMATICA)
    340:   } else if (ismathematica) {
    341:     PetscViewerMathematicaPutVector(viewer,xin);
    342: #endif
    343: #if defined(PETSC_HAVE_PNETCDF)
    344:   } else if (isnetcdf) {
    345:     VecView_Seq_Netcdf(xin,viewer);
    346: #endif
    347: #if defined(PETSC_HAVE_MATLAB)
    348:   } else if (ismatlab) {
    349:     VecView_Seq_Matlab(xin,viewer);
    350: #endif
    351:   } else {
    352:     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this vector object",((PetscObject)viewer)->type_name);
    353:   }
    354:   return(0);
    355: }

    359: PetscErrorCode VecGetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],PetscScalar y[])
    360: {
    361:   Vec_Seq     *x = (Vec_Seq *)xin->data;
    362:   PetscScalar *xx = x->array;
    363:   PetscInt    i;

    366:   for (i=0; i<ni; i++) {
    367: #if defined(PETSC_USE_DEBUG)
    368:     if (ix[i] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D cannot be negative",ix[i]);
    369:     if (ix[i] >= xin->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D to large maximum allowed %D",ix[i],xin->n);
    370: #endif
    371:     y[i] = xx[ix[i]];
    372:   }
    373:   return(0);
    374: }

    378: PetscErrorCode VecSetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode m)
    379: {
    380:   Vec_Seq     *x = (Vec_Seq *)xin->data;
    381:   PetscScalar *xx = x->array;
    382:   PetscInt    i;

    385:   if (m == INSERT_VALUES) {
    386:     for (i=0; i<ni; i++) {
    387:       if (ix[i] < 0) continue;
    388: #if defined(PETSC_USE_DEBUG)
    389:       if (ix[i] >= xin->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",ix[i],xin->n);
    390: #endif
    391:       xx[ix[i]] = y[i];
    392:     }
    393:   } else {
    394:     for (i=0; i<ni; i++) {
    395:       if (ix[i] < 0) continue;
    396: #if defined(PETSC_USE_DEBUG)
    397:       if (ix[i] >= xin->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",ix[i],xin->n);
    398: #endif
    399:       xx[ix[i]] += y[i];
    400:     }
    401:   }
    402:   return(0);
    403: }

    407: PetscErrorCode VecSetValuesBlocked_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar yin[],InsertMode m)
    408: {
    409:   Vec_Seq     *x = (Vec_Seq *)xin->data;
    410:   PetscScalar *xx = x->array,*y = (PetscScalar*)yin;
    411:   PetscInt    i,bs = xin->bs,start,j;

    413:   /*
    414:        For optimization could treat bs = 2, 3, 4, 5 as special cases with loop unrolling
    415:   */
    417:   if (m == INSERT_VALUES) {
    418:     for (i=0; i<ni; i++) {
    419:       start = bs*ix[i];
    420:       if (start < 0) continue;
    421: #if defined(PETSC_USE_DEBUG)
    422:       if (start >= xin->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",start,xin->n);
    423: #endif
    424:       for (j=0; j<bs; j++) {
    425:         xx[start+j] = y[j];
    426:       }
    427:       y += bs;
    428:     }
    429:   } else {
    430:     for (i=0; i<ni; i++) {
    431:       start = bs*ix[i];
    432:       if (start < 0) continue;
    433: #if defined(PETSC_USE_DEBUG)
    434:       if (start >= xin->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",start,xin->n);
    435: #endif
    436:       for (j=0; j<bs; j++) {
    437:         xx[start+j] += y[j];
    438:       }
    439:       y += bs;
    440:     }
    441:   }
    442:   return(0);
    443: }

    448: PetscErrorCode VecDestroy_Seq(Vec v)
    449: {
    450:   Vec_Seq        *vs = (Vec_Seq*)v->data;

    455:   /* if memory was published with AMS then destroy it */
    456:   PetscObjectDepublish(v);

    458: #if defined(PETSC_USE_LOG)
    459:   PetscLogObjectState((PetscObject)v,"Length=%D",v->n);
    460: #endif
    461:   if (vs->array_allocated) {PetscFree(vs->array_allocated);}
    462:   PetscFree(vs);

    464:   return(0);
    465: }

    469: static PetscErrorCode VecPublish_Seq(PetscObject obj)
    470: {
    472:   return(0);
    473: }

    475: EXTERN PetscErrorCode VecLoad_Binary(PetscViewer, VecType, Vec*);

    477: static struct _VecOps DvOps = {VecDuplicate_Seq,
    478:             VecDuplicateVecs_Default,
    479:             VecDestroyVecs_Default,
    480:             VecDot_Seq,
    481:             VecMDot_Seq,
    482:             VecNorm_Seq,
    483:             VecTDot_Seq,
    484:             VecMTDot_Seq,
    485:             VecScale_Seq,
    486:             VecCopy_Seq,
    487:             VecSet_Seq,
    488:             VecSwap_Seq,
    489:             VecAXPY_Seq,
    490:             VecAXPBY_Seq,
    491:             VecMAXPY_Seq,
    492:             VecAYPX_Seq,
    493:             VecWAXPY_Seq,
    494:             VecPointwiseMult_Seq,
    495:             VecPointwiseDivide_Seq,
    496:             VecSetValues_Seq,0,0,
    497:             VecGetArray_Seq,
    498:             VecGetSize_Seq,
    499:             VecGetSize_Seq,
    500:             VecRestoreArray_Seq,
    501:             VecMax_Seq,
    502:             VecMin_Seq,
    503:             VecSetRandom_Seq,0,
    504:             VecSetValuesBlocked_Seq,
    505:             VecDestroy_Seq,
    506:             VecView_Seq,
    507:             VecPlaceArray_Seq,
    508:             VecReplaceArray_Seq,
    509:             VecDot_Seq,
    510:             VecTDot_Seq,
    511:             VecNorm_Seq,
    512:             VecLoadIntoVector_Default,
    513:             VecReciprocal_Default,
    514:             0, /* VecViewNative */
    515:             VecConjugate_Seq,
    516:             0,
    517:             0,
    518:             VecResetArray_Seq,
    519:             0,
    520:             VecMaxPointwiseDivide_Seq,
    521:             VecLoad_Binary,
    522:             VecPointwiseMax_Seq,
    523:             VecPointwiseMaxAbs_Seq,
    524:             VecPointwiseMin_Seq,
    525:             VecGetValues_Seq
    526:           };

    529: /*
    530:       This is called by VecCreate_Seq() (i.e. VecCreateSeq()) and VecCreateSeqWithArray()
    531: */
    534: static PetscErrorCode VecCreate_Seq_Private(Vec v,const PetscScalar array[])
    535: {
    536:   Vec_Seq        *s;

    540:   PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));
    541:   PetscNew(Vec_Seq,&s);
    542:   v->data            = (void*)s;
    543:   v->bops->publish   = VecPublish_Seq;
    544:   v->n               = PetscMax(v->n,v->N);
    545:   v->N               = PetscMax(v->n,v->N);
    546:   v->petscnative     = PETSC_TRUE;
    547:   s->array           = (PetscScalar *)array;
    548:   s->array_allocated = 0;
    549:   if (!v->map) {
    550:     PetscMapCreateMPI(v->comm,v->n,v->N,&v->map);
    551:   }
    552:   PetscObjectChangeTypeName((PetscObject)v,VECSEQ);
    553: #if defined(PETSC_HAVE_MATLAB)
    554:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscMatlabEnginePut_C","VecMatlabEnginePut_Default",VecMatlabEnginePut_Default);
    555:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscMatlabEngineGet_C","VecMatlabEngineGet_Default",VecMatlabEngineGet_Default);
    556: #endif
    557:   PetscPublishAll(v);
    558:   return(0);
    559: }

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

    567:    Collective on MPI_Comm

    569:    Input Parameter:
    570: +  comm - the communicator, should be PETSC_COMM_SELF
    571: .  n - the vector length
    572: -  array - memory where the vector elements are to be stored.

    574:    Output Parameter:
    575: .  V - the vector

    577:    Notes:
    578:    Use VecDuplicate() or VecDuplicateVecs() to form additional vectors of the
    579:    same type as an existing vector.

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

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

    587:    Level: intermediate

    589:    Concepts: vectors^creating with array

    591: .seealso: VecCreateMPIWithArray(), VecCreate(), VecDuplicate(), VecDuplicateVecs(),
    592:           VecCreateGhost(), VecCreateSeq(), VecPlaceArray()
    593: @*/
    594: PetscErrorCode PETSCVEC_DLLEXPORT VecCreateSeqWithArray(MPI_Comm comm,PetscInt n,const PetscScalar array[],Vec *V)
    595: {

    599:   VecCreate(comm,V);
    600:   VecSetSizes(*V,n,n);
    601:   VecCreate_Seq_Private(*V,array);
    602:   return(0);
    603: }

    605: /*MC
    606:    VECSEQ - VECSEQ = "seq" - The basic sequential vector

    608:    Options Database Keys:
    609: . -vec_type seq - sets the vector type to VECSEQ during a call to VecSetFromOptions()

    611:   Level: beginner

    613: .seealso: VecCreate(), VecSetType(), VecSetFromOptions(), VecCreateSeqWithArray(), VECMPI, VecType, VecCreateMPI(), VecCreateSeq()
    614: M*/

    619: PetscErrorCode PETSCVEC_DLLEXPORT VecCreate_Seq(Vec V)
    620: {
    621:   Vec_Seq        *s;
    622:   PetscScalar    *array;
    624:   PetscInt       n = PetscMax(V->n,V->N);
    625:   PetscMPIInt    size;

    628:   MPI_Comm_size(V->comm,&size);
    629:   if (size > 1) {
    630:     SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot create VECSEQ on more than one process");
    631:   }
    632:   PetscMalloc( n*sizeof(PetscScalar),&array);
    633:   PetscMemzero(array,n*sizeof(PetscScalar));
    634:   VecCreate_Seq_Private(V,array);
    635:   s    = (Vec_Seq*)V->data;
    636:   s->array_allocated = array;
    637:   return(0);
    638: }

    644: PetscErrorCode VecDuplicate_Seq(Vec win,Vec *V)
    645: {

    649:   VecCreateSeq(win->comm,win->n,V);
    650:   if (win->mapping) {
    651:     (*V)->mapping = win->mapping;
    652:     PetscObjectReference((PetscObject)win->mapping);
    653:   }
    654:   if (win->bmapping) {
    655:     (*V)->bmapping = win->bmapping;
    656:     PetscObjectReference((PetscObject)win->bmapping);
    657:   }
    658:   (*V)->bs = win->bs;
    659:   PetscOListDuplicate(win->olist,&(*V)->olist);
    660:   PetscFListDuplicate(win->qlist,&(*V)->qlist);
    661:   return(0);
    662: }