Actual source code: bvec2.c


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

  6: #include <../src/vec/vec/impls/dvecimpl.h>
  7: #include <../src/vec/vec/impls/mpi/pvecimpl.h>
  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: {
 18:   PetscInt       n = win->map->n,i;
 19:   PetscScalar    *ww,*xx,*yy; /* cannot make xx or yy const since might be ww */

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

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

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

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

 39:   VecGetArrayRead(xin,(const PetscScalar**)&xx);
 40:   VecGetArrayRead(yin,(const PetscScalar**)&yy);
 41:   VecGetArray(win,&ww);

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

 45:   VecRestoreArrayRead(xin,(const PetscScalar**)&xx);
 46:   VecRestoreArrayRead(yin,(const PetscScalar**)&yy);
 47:   VecRestoreArray(win,&ww);
 48:   PetscLogFlops(n);
 49:   return 0;
 50: }

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

 57:   VecGetArrayRead(xin,(const PetscScalar**)&xx);
 58:   VecGetArrayRead(yin,(const PetscScalar**)&yy);
 59:   VecGetArray(win,&ww);

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

 63:   PetscLogFlops(n);
 64:   VecRestoreArrayRead(xin,(const PetscScalar**)&xx);
 65:   VecRestoreArrayRead(yin,(const PetscScalar**)&yy);
 66:   VecRestoreArray(win,&ww);
 67:   return 0;
 68: }

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

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

 77:   VecGetArrayRead(xin,(const PetscScalar**)&xx);
 78:   VecGetArrayRead(yin,(const PetscScalar**)&yy);
 79:   VecGetArray(win,&ww);
 80:   if (ww == xx) {
 81:     for (i=0; i<n; i++) ww[i] *= yy[i];
 82:   } else if (ww == yy) {
 83:     for (i=0; i<n; i++) ww[i] *= xx[i];
 84:   } else {
 85: #if defined(PETSC_USE_FORTRAN_KERNEL_XTIMESY)
 86:     fortranxtimesy_(xx,yy,ww,&n);
 87: #else
 88:     for (i=0; i<n; i++) ww[i] = xx[i] * yy[i];
 89: #endif
 90:   }
 91:   VecRestoreArrayRead(xin,(const PetscScalar**)&xx);
 92:   VecRestoreArrayRead(yin,(const PetscScalar**)&yy);
 93:   VecRestoreArray(win,&ww);
 94:   PetscLogFlops(n);
 95:   return 0;
 96: }

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

103:   VecGetArrayRead(xin,(const PetscScalar**)&xx);
104:   VecGetArrayRead(yin,(const PetscScalar**)&yy);
105:   VecGetArray(win,&ww);

107:   for (i=0; i<n; i++) {
108:     if (yy[i] != 0.0) ww[i] = xx[i] / yy[i];
109:     else ww[i] = 0.0;
110:   }

112:   PetscLogFlops(n);
113:   VecRestoreArrayRead(xin,(const PetscScalar**)&xx);
114:   VecRestoreArrayRead(yin,(const PetscScalar**)&yy);
115:   VecRestoreArray(win,&ww);
116:   return 0;
117: }

119: PetscErrorCode VecSetRandom_Seq(Vec xin,PetscRandom r)
120: {
121:   PetscInt       n = xin->map->n,i;
122:   PetscScalar    *xx;

124:   VecGetArrayWrite(xin,&xx);
125:   for (i=0; i<n; i++) PetscRandomGetValue(r,&xx[i]);
126:   VecRestoreArrayWrite(xin,&xx);
127:   return 0;
128: }

130: PetscErrorCode VecGetSize_Seq(Vec vin,PetscInt *size)
131: {
132:   *size = vin->map->n;
133:   return 0;
134: }

136: PetscErrorCode VecConjugate_Seq(Vec xin)
137: {
138:   PetscScalar    *x;
139:   PetscInt       n = xin->map->n;

141:   VecGetArray(xin,&x);
142:   while (n-->0) {
143:     *x = PetscConj(*x);
144:     x++;
145:   }
146:   VecRestoreArray(xin,&x);
147:   return 0;
148: }

150: PetscErrorCode VecResetArray_Seq(Vec vin)
151: {
152:   Vec_Seq *v = (Vec_Seq*)vin->data;

154:   v->array         = v->unplacedarray;
155:   v->unplacedarray = NULL;
156:   return 0;
157: }

159: PetscErrorCode VecCopy_Seq(Vec xin,Vec yin)
160: {
161:   PetscScalar       *ya;
162:   const PetscScalar *xa;

164:   if (xin != yin) {
165:     VecGetArrayRead(xin,&xa);
166:     VecGetArray(yin,&ya);
167:     PetscArraycpy(ya,xa,xin->map->n);
168:     VecRestoreArrayRead(xin,&xa);
169:     VecRestoreArray(yin,&ya);
170:   }
171:   return 0;
172: }

174: PetscErrorCode VecSwap_Seq(Vec xin,Vec yin)
175: {
176:   PetscScalar    *ya, *xa;
177:   PetscBLASInt   one = 1,bn;

179:   if (xin != yin) {
180:     PetscBLASIntCast(xin->map->n,&bn);
181:     VecGetArray(xin,&xa);
182:     VecGetArray(yin,&ya);
183:     PetscStackCallBLAS("BLASswap",BLASswap_(&bn,xa,&one,ya,&one));
184:     VecRestoreArray(xin,&xa);
185:     VecRestoreArray(yin,&ya);
186:   }
187:   return 0;
188: }

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

192: PetscErrorCode VecNorm_Seq(Vec xin,NormType type,PetscReal *z)
193: {
194:   const PetscScalar *xx;
195:   PetscInt          n = xin->map->n;
196:   PetscBLASInt      one = 1, bn = 0;

198:   PetscBLASIntCast(n,&bn);
199:   if (type == NORM_2 || type == NORM_FROBENIUS) {
200:     VecGetArrayRead(xin,&xx);
201: #if defined(PETSC_USE_REAL___FP16)
202:     PetscStackCallBLAS("BLASnrm2",*z = BLASnrm2_(&bn,xx,&one));
203: #else
204:     PetscStackCallBLAS("BLASdot",*z   = PetscRealPart(BLASdot_(&bn,xx,&one,xx,&one)));
205:     *z   = PetscSqrtReal(*z);
206: #endif
207:     VecRestoreArrayRead(xin,&xx);
208:     PetscLogFlops(PetscMax(2.0*n-1,0.0));
209:   } else if (type == NORM_INFINITY) {
210:     PetscInt  i;
211:     PetscReal max = 0.0,tmp;

213:     VecGetArrayRead(xin,&xx);
214:     for (i=0; i<n; i++) {
215:       if ((tmp = PetscAbsScalar(*xx)) > max) max = tmp;
216:       /* check special case of tmp == NaN */
217:       if (tmp != tmp) {max = tmp; break;}
218:       xx++;
219:     }
220:     VecRestoreArrayRead(xin,&xx);
221:     *z   = max;
222:   } else if (type == NORM_1) {
223: #if defined(PETSC_USE_COMPLEX)
224:     PetscReal tmp = 0.0;
225:     PetscInt    i;
226: #endif
227:     VecGetArrayRead(xin,&xx);
228: #if defined(PETSC_USE_COMPLEX)
229:     /* BLASasum() returns the nonstandard 1 norm of the 1 norm of the complex entries so we provide a custom loop instead */
230:     for (i=0; i<n; i++) {
231:       tmp += PetscAbsScalar(xx[i]);
232:     }
233:     *z = tmp;
234: #else
235:     PetscStackCallBLAS("BLASasum",*z   = BLASasum_(&bn,xx,&one));
236: #endif
237:     VecRestoreArrayRead(xin,&xx);
238:     PetscLogFlops(PetscMax(n-1.0,0.0));
239:   } else if (type == NORM_1_AND_2) {
240:     VecNorm_Seq(xin,NORM_1,z);
241:     VecNorm_Seq(xin,NORM_2,z+1);
242:   }
243:   return 0;
244: }

246: PetscErrorCode VecView_Seq_ASCII(Vec xin,PetscViewer viewer)
247: {
248:   PetscInt          i,n = xin->map->n;
249:   const char        *name;
250:   PetscViewerFormat format;
251:   const PetscScalar *xv;

253:   VecGetArrayRead(xin,&xv);
254:   PetscViewerGetFormat(viewer,&format);
255:   if (format == PETSC_VIEWER_ASCII_MATLAB) {
256:     PetscObjectGetName((PetscObject)xin,&name);
257:     PetscViewerASCIIPrintf(viewer,"%s = [\n",name);
258:     for (i=0; i<n; i++) {
259: #if defined(PETSC_USE_COMPLEX)
260:       if (PetscImaginaryPart(xv[i]) > 0.0) {
261:         PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei\n",(double)PetscRealPart(xv[i]),(double)PetscImaginaryPart(xv[i]));
262:       } else if (PetscImaginaryPart(xv[i]) < 0.0) {
263:         PetscViewerASCIIPrintf(viewer,"%18.16e - %18.16ei\n",(double)PetscRealPart(xv[i]),-(double)PetscImaginaryPart(xv[i]));
264:       } else {
265:         PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)PetscRealPart(xv[i]));
266:       }
267: #else
268:       PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double) xv[i]);
269: #endif
270:     }
271:     PetscViewerASCIIPrintf(viewer,"];\n");
272:   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
273:     for (i=0; i<n; i++) {
274: #if defined(PETSC_USE_COMPLEX)
275:       PetscViewerASCIIPrintf(viewer,"%18.16e %18.16e\n",(double)PetscRealPart(xv[i]),(double)PetscImaginaryPart(xv[i]));
276: #else
277:       PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)xv[i]);
278: #endif
279:     }
280:   } else if (format == PETSC_VIEWER_ASCII_VTK_DEPRECATED || format == PETSC_VIEWER_ASCII_VTK_CELL_DEPRECATED) {
281:     /*
282:        state 0: No header has been output
283:        state 1: Only POINT_DATA has been output
284:        state 2: Only CELL_DATA has been output
285:        state 3: Output both, POINT_DATA last
286:        state 4: Output both, CELL_DATA last
287:     */
288:     static PetscInt stateId = -1;
289:     int outputState = 0;
290:     PetscBool  hasState;
291:     int doOutput = 0;
292:     PetscInt bs, b;

294:     if (stateId < 0) {
295:       PetscObjectComposedDataRegister(&stateId);
296:     }
297:     PetscObjectComposedDataGetInt((PetscObject) viewer, stateId, outputState, hasState);
298:     if (!hasState) outputState = 0;
299:     PetscObjectGetName((PetscObject) xin, &name);
300:     VecGetBlockSize(xin, &bs);
302:     if (format == PETSC_VIEWER_ASCII_VTK_DEPRECATED) {
303:       if (outputState == 0) {
304:         outputState = 1;
305:         doOutput = 1;
306:       } else if (outputState == 1) doOutput = 0;
307:       else if (outputState == 2) {
308:         outputState = 3;
309:         doOutput = 1;
310:       } else if (outputState == 3) doOutput = 0;

313:       if (doOutput) {
314:         PetscViewerASCIIPrintf(viewer, "POINT_DATA %" PetscInt_FMT "\n", n/bs);
315:       }
316:     } else {
317:       if (outputState == 0) {
318:         outputState = 2;
319:         doOutput = 1;
320:       } else if (outputState == 1) {
321:         outputState = 4;
322:         doOutput = 1;
323:       } else if (outputState == 2) doOutput = 0;
325:       else if (outputState == 4) doOutput = 0;

327:       if (doOutput) {
328:         PetscViewerASCIIPrintf(viewer, "CELL_DATA %" PetscInt_FMT "\n", n);
329:       }
330:     }
331:     PetscObjectComposedDataSetInt((PetscObject) viewer, stateId, outputState);
332:     if (name) {
333:       if (bs == 3) {
334:         PetscViewerASCIIPrintf(viewer, "VECTORS %s double\n", name);
335:       } else {
336:         PetscViewerASCIIPrintf(viewer, "SCALARS %s double %" PetscInt_FMT "\n", name, bs);
337:       }
338:     } else {
339:       PetscViewerASCIIPrintf(viewer, "SCALARS scalars double %" PetscInt_FMT "\n", bs);
340:     }
341:     if (bs != 3) {
342:       PetscViewerASCIIPrintf(viewer, "LOOKUP_TABLE default\n");
343:     }
344:     for (i=0; i<n/bs; i++) {
345:       for (b=0; b<bs; b++) {
346:         if (b > 0) {
347:           PetscViewerASCIIPrintf(viewer," ");
348:         }
349: #if !defined(PETSC_USE_COMPLEX)
350:         PetscViewerASCIIPrintf(viewer,"%g",(double)xv[i*bs+b]);
351: #endif
352:       }
353:       PetscViewerASCIIPrintf(viewer,"\n");
354:     }
355:   } else if (format == PETSC_VIEWER_ASCII_VTK_COORDS_DEPRECATED) {
356:     PetscInt bs, b;

358:     VecGetBlockSize(xin, &bs);
360:     for (i=0; i<n/bs; i++) {
361:       for (b=0; b<bs; b++) {
362:         if (b > 0) {
363:           PetscViewerASCIIPrintf(viewer," ");
364:         }
365: #if !defined(PETSC_USE_COMPLEX)
366:         PetscViewerASCIIPrintf(viewer,"%g",(double)xv[i*bs+b]);
367: #endif
368:       }
369:       for (b=bs; b<3; b++) {
370:         PetscViewerASCIIPrintf(viewer," 0.0");
371:       }
372:       PetscViewerASCIIPrintf(viewer,"\n");
373:     }
374:   } else if (format == PETSC_VIEWER_ASCII_PCICE) {
375:     PetscInt bs, b;

377:     VecGetBlockSize(xin, &bs);
379:     PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT "\n", xin->map->N/bs);
380:     for (i=0; i<n/bs; i++) {
381:       PetscViewerASCIIPrintf(viewer,"%7" PetscInt_FMT "   ", i+1);
382:       for (b=0; b<bs; b++) {
383:         if (b > 0) {
384:           PetscViewerASCIIPrintf(viewer," ");
385:         }
386: #if !defined(PETSC_USE_COMPLEX)
387:         PetscViewerASCIIPrintf(viewer,"% 12.5E",(double)xv[i*bs+b]);
388: #endif
389:       }
390:       PetscViewerASCIIPrintf(viewer,"\n");
391:     }
392:   } else if (format == PETSC_VIEWER_ASCII_GLVIS) {
393:     /* GLVis ASCII visualization/dump: this function mimics mfem::GridFunction::Save() */
394:     const PetscScalar       *array;
395:     PetscInt                i,n,vdim, ordering = 1; /* mfem::FiniteElementSpace::Ordering::byVDIM */
396:     PetscContainer          glvis_container;
397:     PetscViewerGLVisVecInfo glvis_vec_info;
398:     PetscViewerGLVisInfo    glvis_info;

400:     /* mfem::FiniteElementSpace::Save() */
401:     VecGetBlockSize(xin,&vdim);
402:     PetscViewerASCIIPrintf(viewer,"FiniteElementSpace\n");
403:     PetscObjectQuery((PetscObject)xin,"_glvis_info_container",(PetscObject*)&glvis_container);
405:     PetscContainerGetPointer(glvis_container,(void**)&glvis_vec_info);
406:     PetscViewerASCIIPrintf(viewer,"%s\n",glvis_vec_info->fec_type);
407:     PetscViewerASCIIPrintf(viewer,"VDim: %" PetscInt_FMT "\n",vdim);
408:     PetscViewerASCIIPrintf(viewer,"Ordering: %" PetscInt_FMT "\n",ordering);
409:     PetscViewerASCIIPrintf(viewer,"\n");
410:     /* mfem::Vector::Print() */
411:     PetscObjectQuery((PetscObject)viewer,"_glvis_info_container",(PetscObject*)&glvis_container);
413:     PetscContainerGetPointer(glvis_container,(void**)&glvis_info);
414:     if (glvis_info->enabled) {
415:       VecGetLocalSize(xin,&n);
416:       VecGetArrayRead(xin,&array);
417:       for (i=0;i<n;i++) {
418:         PetscViewerASCIIPrintf(viewer,glvis_info->fmt,(double)PetscRealPart(array[i]));
419:         PetscViewerASCIIPrintf(viewer,"\n");
420:       }
421:       VecRestoreArrayRead(xin,&array);
422:     }
423:   } else if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
424:     /* No info */
425:   } else {
426:     for (i=0; i<n; i++) {
427:       if (format == PETSC_VIEWER_ASCII_INDEX) {
428:         PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT ": ",i);
429:       }
430: #if defined(PETSC_USE_COMPLEX)
431:       if (PetscImaginaryPart(xv[i]) > 0.0) {
432:         PetscViewerASCIIPrintf(viewer,"%g + %g i\n",(double)PetscRealPart(xv[i]),(double)PetscImaginaryPart(xv[i]));
433:       } else if (PetscImaginaryPart(xv[i]) < 0.0) {
434:         PetscViewerASCIIPrintf(viewer,"%g - %g i\n",(double)PetscRealPart(xv[i]),-(double)PetscImaginaryPart(xv[i]));
435:       } else {
436:         PetscViewerASCIIPrintf(viewer,"%g\n",(double)PetscRealPart(xv[i]));
437:       }
438: #else
439:       PetscViewerASCIIPrintf(viewer,"%g\n",(double)xv[i]);
440: #endif
441:     }
442:   }
443:   PetscViewerFlush(viewer);
444:   VecRestoreArrayRead(xin,&xv);
445:   return 0;
446: }

448: #include <petscdraw.h>
449: PetscErrorCode VecView_Seq_Draw_LG(Vec xin,PetscViewer v)
450: {
451:   PetscDraw         draw;
452:   PetscBool         isnull;
453:   PetscDrawLG       lg;
454:   PetscInt          i,c,bs = PetscAbs(xin->map->bs),n = xin->map->n/bs;
455:   const PetscScalar *xv;
456:   PetscReal         *xx,*yy,xmin,xmax,h;
457:   int               colors[] = {PETSC_DRAW_RED};
458:   PetscViewerFormat format;
459:   PetscDrawAxis     axis;

461:   PetscViewerDrawGetDraw(v,0,&draw);
462:   PetscDrawIsNull(draw,&isnull);
463:   if (isnull) return 0;

465:   PetscViewerGetFormat(v,&format);
466:   PetscMalloc2(n,&xx,n,&yy);
467:   VecGetArrayRead(xin,&xv);
468:   for (c=0; c<bs; c++) {
469:     PetscViewerDrawGetDrawLG(v,c,&lg);
470:     PetscDrawLGReset(lg);
471:     PetscDrawLGSetDimension(lg,1);
472:     PetscDrawLGSetColors(lg,colors);
473:     if (format == PETSC_VIEWER_DRAW_LG_XRANGE) {
474:       PetscDrawLGGetAxis(lg,&axis);
475:       PetscDrawAxisGetLimits(axis,&xmin,&xmax,NULL,NULL);
476:       h = (xmax - xmin)/n;
477:       for (i=0; i<n; i++) xx[i] = i*h + 0.5*h; /* cell center */
478:     } else {
479:       for (i=0; i<n; i++) xx[i] = (PetscReal)i;
480:     }
481:     for (i=0; i<n; i++) yy[i] = PetscRealPart(xv[c + i*bs]);

483:     PetscDrawLGAddPoints(lg,n,&xx,&yy);
484:     PetscDrawLGDraw(lg);
485:     PetscDrawLGSave(lg);
486:   }
487:   VecRestoreArrayRead(xin,&xv);
488:   PetscFree2(xx,yy);
489:   return 0;
490: }

492: PetscErrorCode VecView_Seq_Draw(Vec xin,PetscViewer v)
493: {
494:   PetscDraw         draw;
495:   PetscBool         isnull;

497:   PetscViewerDrawGetDraw(v,0,&draw);
498:   PetscDrawIsNull(draw,&isnull);
499:   if (isnull) return 0;

501:   VecView_Seq_Draw_LG(xin,v);
502:   return 0;
503: }

505: PetscErrorCode VecView_Seq_Binary(Vec xin,PetscViewer viewer)
506: {
507:   return VecView_Binary(xin,viewer);
508: }

510: #if defined(PETSC_HAVE_MATLAB_ENGINE)
511: #include <petscmatlab.h>
512: #include <mat.h>   /* MATLAB include file */
513: PetscErrorCode VecView_Seq_Matlab(Vec vec,PetscViewer viewer)
514: {
515:   PetscInt          n;
516:   const PetscScalar *array;

518:   VecGetLocalSize(vec,&n);
519:   PetscObjectName((PetscObject)vec);
520:   VecGetArrayRead(vec,&array);
521:   PetscViewerMatlabPutArray(viewer,n,1,array,((PetscObject)vec)->name);
522:   VecRestoreArrayRead(vec,&array);
523:   return 0;
524: }
525: #endif

527: PETSC_EXTERN PetscErrorCode VecView_Seq(Vec xin,PetscViewer viewer)
528: {
529:   PetscBool      isdraw,iascii,issocket,isbinary;
530: #if defined(PETSC_HAVE_MATHEMATICA)
531:   PetscBool      ismathematica;
532: #endif
533: #if defined(PETSC_HAVE_MATLAB_ENGINE)
534:   PetscBool      ismatlab;
535: #endif
536: #if defined(PETSC_HAVE_HDF5)
537:   PetscBool      ishdf5;
538: #endif
539:   PetscBool      isglvis;
540: #if defined(PETSC_HAVE_ADIOS)
541:   PetscBool      isadios;
542: #endif

544:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
545:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
546:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSOCKET,&issocket);
547:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
548: #if defined(PETSC_HAVE_MATHEMATICA)
549:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERMATHEMATICA,&ismathematica);
550: #endif
551: #if defined(PETSC_HAVE_HDF5)
552:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
553: #endif
554: #if defined(PETSC_HAVE_MATLAB_ENGINE)
555:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERMATLAB,&ismatlab);
556: #endif
557:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERGLVIS,&isglvis);
558: #if defined(PETSC_HAVE_ADIOS)
559:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERADIOS,&isadios);
560: #endif

562:   if (isdraw) {
563:     VecView_Seq_Draw(xin,viewer);
564:   } else if (iascii) {
565:     VecView_Seq_ASCII(xin,viewer);
566:   } else if (isbinary) {
567:     VecView_Seq_Binary(xin,viewer);
568: #if defined(PETSC_HAVE_MATHEMATICA)
569:   } else if (ismathematica) {
570:     PetscViewerMathematicaPutVector(viewer,xin);
571: #endif
572: #if defined(PETSC_HAVE_HDF5)
573:   } else if (ishdf5) {
574:     VecView_MPI_HDF5(xin,viewer); /* Reusing VecView_MPI_HDF5 ... don't want code duplication*/
575: #endif
576: #if defined(PETSC_HAVE_ADIOS)
577:   } else if (isadios) {
578:     VecView_MPI_ADIOS(xin,viewer); /* Reusing VecView_MPI_ADIOS ... don't want code duplication*/
579: #endif
580: #if defined(PETSC_HAVE_MATLAB_ENGINE)
581:   } else if (ismatlab) {
582:     VecView_Seq_Matlab(xin,viewer);
583: #endif
584:   } else if (isglvis) {
585:     VecView_GLVis(xin,viewer);
586:   }
587:   return 0;
588: }

590: PetscErrorCode VecGetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],PetscScalar y[])
591: {
592:   const PetscScalar *xx;
593:   PetscInt          i;

595:   VecGetArrayRead(xin,&xx);
596:   for (i=0; i<ni; i++) {
597:     if (xin->stash.ignorenegidx && ix[i] < 0) continue;
598:     if (PetscDefined(USE_DEBUG)) {
601:     }
602:     y[i] = xx[ix[i]];
603:   }
604:   VecRestoreArrayRead(xin,&xx);
605:   return 0;
606: }

608: PetscErrorCode VecSetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode m)
609: {
610:   PetscScalar    *xx;
611:   PetscInt       i;

613:   VecGetArray(xin,&xx);
614:   if (m == INSERT_VALUES) {
615:     for (i=0; i<ni; i++) {
616:       if (xin->stash.ignorenegidx && ix[i] < 0) continue;
617:       if (PetscDefined(USE_DEBUG)) {
620:       }
621:       xx[ix[i]] = y[i];
622:     }
623:   } else {
624:     for (i=0; i<ni; i++) {
625:       if (xin->stash.ignorenegidx && ix[i] < 0) continue;
626:       if (PetscDefined(USE_DEBUG)) {
629:       }
630:       xx[ix[i]] += y[i];
631:     }
632:   }
633:   VecRestoreArray(xin,&xx);
634:   return 0;
635: }

637: PetscErrorCode VecSetValuesBlocked_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar yin[],InsertMode m)
638: {
639:   PetscScalar    *xx,*y = (PetscScalar*)yin;
640:   PetscInt       i,bs,start,j;

642:   /*
643:        For optimization could treat bs = 2, 3, 4, 5 as special cases with loop unrolling
644:   */
645:   VecGetBlockSize(xin,&bs);
646:   VecGetArray(xin,&xx);
647:   if (m == INSERT_VALUES) {
648:     for (i=0; i<ni; i++, y+=bs) {
649:       start = bs*ix[i];
650:       if (start < 0) continue;
652:       for (j=0; j<bs; j++) xx[start+j] = y[j];
653:     }
654:   } else {
655:     for (i=0; i<ni; i++, y+=bs) {
656:       start = bs*ix[i];
657:       if (start < 0) continue;
659:       for (j=0; j<bs; j++) xx[start+j] += y[j];
660:     }
661:   }
662:   VecRestoreArray(xin,&xx);
663:   return 0;
664: }

666: PetscErrorCode VecDestroy_Seq(Vec v)
667: {
668:   Vec_Seq        *vs = (Vec_Seq*)v->data;

670: #if defined(PETSC_USE_LOG)
671:   PetscLogObjectState((PetscObject)v,"Length=%" PetscInt_FMT,v->map->n);
672: #endif
673:   if (vs) PetscFree(vs->array_allocated);
674:   PetscFree(v->data);
675:   return 0;
676: }

678: PetscErrorCode VecSetOption_Seq(Vec v,VecOption op,PetscBool flag)
679: {
680:   if (op == VEC_IGNORE_NEGATIVE_INDICES) v->stash.ignorenegidx = flag;
681:   return 0;
682: }

684: PetscErrorCode VecDuplicate_Seq(Vec win,Vec *V)
685: {
686:   VecCreate(PetscObjectComm((PetscObject)win),V);
687:   VecSetSizes(*V,win->map->n,win->map->n);
688:   VecSetType(*V,((PetscObject)win)->type_name);
689:   PetscLayoutReference(win->map,&(*V)->map);
690:   PetscObjectListDuplicate(((PetscObject)win)->olist,&((PetscObject)(*V))->olist);
691:   PetscFunctionListDuplicate(((PetscObject)win)->qlist,&((PetscObject)(*V))->qlist);

693:   (*V)->ops->view          = win->ops->view;
694:   (*V)->stash.ignorenegidx = win->stash.ignorenegidx;
695:   return 0;
696: }

698: static struct _VecOps DvOps = {
699:   PetscDesignatedInitializer(duplicate,VecDuplicate_Seq), /* 1 */
700:   PetscDesignatedInitializer(duplicatevecs,VecDuplicateVecs_Default),
701:   PetscDesignatedInitializer(destroyvecs,VecDestroyVecs_Default),
702:   PetscDesignatedInitializer(dot,VecDot_Seq),
703:   PetscDesignatedInitializer(mdot,VecMDot_Seq),
704:   PetscDesignatedInitializer(norm,VecNorm_Seq),
705:   PetscDesignatedInitializer(tdot,VecTDot_Seq),
706:   PetscDesignatedInitializer(mtdot,VecMTDot_Seq),
707:   PetscDesignatedInitializer(scale,VecScale_Seq),
708:   PetscDesignatedInitializer(copy,VecCopy_Seq), /* 10 */
709:   PetscDesignatedInitializer(set,VecSet_Seq),
710:   PetscDesignatedInitializer(swap,VecSwap_Seq),
711:   PetscDesignatedInitializer(axpy,VecAXPY_Seq),
712:   PetscDesignatedInitializer(axpby,VecAXPBY_Seq),
713:   PetscDesignatedInitializer(maxpy,VecMAXPY_Seq),
714:   PetscDesignatedInitializer(aypx,VecAYPX_Seq),
715:   PetscDesignatedInitializer(waxpy,VecWAXPY_Seq),
716:   PetscDesignatedInitializer(axpbypcz,VecAXPBYPCZ_Seq),
717:   PetscDesignatedInitializer(pointwisemult,VecPointwiseMult_Seq),
718:   PetscDesignatedInitializer(pointwisedivide,VecPointwiseDivide_Seq),
719:   PetscDesignatedInitializer(setvalues,VecSetValues_Seq), /* 20 */
720:   PetscDesignatedInitializer(assemblybegin,NULL),
721:   PetscDesignatedInitializer(assemblyend,NULL),
722:   PetscDesignatedInitializer(getarray,NULL),
723:   PetscDesignatedInitializer(getsize,VecGetSize_Seq),
724:   PetscDesignatedInitializer(getlocalsize,VecGetSize_Seq),
725:   PetscDesignatedInitializer(restorearray,NULL),
726:   PetscDesignatedInitializer(max,VecMax_Seq),
727:   PetscDesignatedInitializer(min,VecMin_Seq),
728:   PetscDesignatedInitializer(setrandom,VecSetRandom_Seq),
729:   PetscDesignatedInitializer(setoption,VecSetOption_Seq), /* 30 */
730:   PetscDesignatedInitializer(setvaluesblocked,VecSetValuesBlocked_Seq),
731:   PetscDesignatedInitializer(destroy,VecDestroy_Seq),
732:   PetscDesignatedInitializer(view,VecView_Seq),
733:   PetscDesignatedInitializer(placearray,VecPlaceArray_Seq),
734:   PetscDesignatedInitializer(replacearray,VecReplaceArray_Seq),
735:   PetscDesignatedInitializer(dot_local,VecDot_Seq),
736:   PetscDesignatedInitializer(tdot_local,VecTDot_Seq),
737:   PetscDesignatedInitializer(norm_local,VecNorm_Seq),
738:   PetscDesignatedInitializer(mdot_local,VecMDot_Seq),
739:   PetscDesignatedInitializer(mtdot_local,VecMTDot_Seq), /* 40 */
740:   PetscDesignatedInitializer(load,VecLoad_Default),
741:   PetscDesignatedInitializer(reciprocal,VecReciprocal_Default),
742:   PetscDesignatedInitializer(conjugate,VecConjugate_Seq),
743:   PetscDesignatedInitializer(setlocaltoglobalmapping,NULL),
744:   PetscDesignatedInitializer(setvalueslocal,NULL),
745:   PetscDesignatedInitializer(resetarray,VecResetArray_Seq),
746:   PetscDesignatedInitializer(setfromoptions,NULL),
747:   PetscDesignatedInitializer(maxpointwisedivide,VecMaxPointwiseDivide_Seq),
748:   PetscDesignatedInitializer(pointwisemax,VecPointwiseMax_Seq),
749:   PetscDesignatedInitializer(pointwisemaxabs,VecPointwiseMaxAbs_Seq),
750:   PetscDesignatedInitializer(pointwisemin,VecPointwiseMin_Seq),
751:   PetscDesignatedInitializer(getvalues,VecGetValues_Seq),
752:   PetscDesignatedInitializer(sqrt,NULL),
753:   PetscDesignatedInitializer(abs,NULL),
754:   PetscDesignatedInitializer(exp,NULL),
755:   PetscDesignatedInitializer(log,NULL),
756:   PetscDesignatedInitializer(shift,NULL),
757:   PetscDesignatedInitializer(create,NULL),
758:   PetscDesignatedInitializer(stridegather,VecStrideGather_Default),
759:   PetscDesignatedInitializer(stridescatter,VecStrideScatter_Default),
760:   PetscDesignatedInitializer(dotnorm2,NULL),
761:   PetscDesignatedInitializer(getsubvector,NULL),
762:   PetscDesignatedInitializer(restoresubvector,NULL),
763:   PetscDesignatedInitializer(getarrayread,NULL),
764:   PetscDesignatedInitializer(restorearrayread,NULL),
765:   PetscDesignatedInitializer(stridesubsetgather,VecStrideSubSetGather_Default),
766:   PetscDesignatedInitializer(stridesubsetscatter,VecStrideSubSetScatter_Default),
767:   PetscDesignatedInitializer(viewnative,VecView_Seq),
768:   PetscDesignatedInitializer(loadnative,NULL),
769:   PetscDesignatedInitializer(getlocalvector,NULL),
770: };

772: /*
773:       This is called by VecCreate_Seq() (i.e. VecCreateSeq()) and VecCreateSeqWithArray()
774: */
775: PetscErrorCode VecCreate_Seq_Private(Vec v,const PetscScalar array[])
776: {
777:   Vec_Seq        *s;

779:   PetscNewLog(v,&s);
780:   PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));

782:   v->data            = (void*)s;
783:   v->petscnative     = PETSC_TRUE;
784:   s->array           = (PetscScalar*)array;
785:   s->array_allocated = NULL;
786:   if (array) v->offloadmask = PETSC_OFFLOAD_CPU;

788:   PetscLayoutSetUp(v->map);
789:   PetscObjectChangeTypeName((PetscObject)v,VECSEQ);
790: #if defined(PETSC_HAVE_MATLAB_ENGINE)
791:   PetscObjectComposeFunction((PetscObject)v,"PetscMatlabEnginePut_C",VecMatlabEnginePut_Default);
792:   PetscObjectComposeFunction((PetscObject)v,"PetscMatlabEngineGet_C",VecMatlabEngineGet_Default);
793: #endif
794:   return 0;
795: }

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

801:    Collective

803:    Input Parameters:
804: +  comm - the communicator, should be PETSC_COMM_SELF
805: .  bs - the block size
806: .  n - the vector length
807: -  array - memory where the vector elements are to be stored.

809:    Output Parameter:
810: .  V - the vector

812:    Notes:
813:    Use VecDuplicate() or VecDuplicateVecs() to form additional vectors of the
814:    same type as an existing vector.

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

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

822:    Level: intermediate

824: .seealso: VecCreateMPIWithArray(), VecCreate(), VecDuplicate(), VecDuplicateVecs(),
825:           VecCreateGhost(), VecCreateSeq(), VecPlaceArray()
826: @*/
827: PetscErrorCode  VecCreateSeqWithArray(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscScalar array[],Vec *V)
828: {
829:   PetscMPIInt    size;

831:   VecCreate(comm,V);
832:   VecSetSizes(*V,n,n);
833:   VecSetBlockSize(*V,bs);
834:   MPI_Comm_size(comm,&size);
836:   VecCreate_Seq_Private(*V,array);
837:   return 0;
838: }