Actual source code: bvec2.c

  1: /*$Id: bvec2.c,v 1.195 2001/04/10 19:34:56 bsmith Exp $*/
  2: /*
  3:    Implements the sequential vectors.
  4: */

 6:  #include src/vec/vecimpl.h
 7:  #include src/vec/impls/dvecimpl.h
 8:  #include petscblaslapack.h
  9: #if defined(PETSC_HAVE_AMS)
 10: EXTERN int PetscViewerAMSGetAMSComm(PetscViewer,AMS_Comm *);
 11: #endif

 13: int VecNorm_Seq(Vec xin,NormType type,PetscReal* z)
 14: {
 15:   Vec_Seq *x = (Vec_Seq*)xin->data;
 16:   int     ierr,one = 1;

 19:   if (type == NORM_2) {
 20:     /*
 21:       This is because the Fortran BLAS 1 Norm is very slow! 
 22:     */
 23: #if defined(PETSC_HAVE_SLOW_NRM2)
 24:     {
 25:       int i;
 26:       Scalar sum=0.0;
 27:       for (i=0; i<xin->n; i++) {
 28:         sum += (x->array[i])*(PetscConj(x->array[i]));
 29:       }
 30:       *z = sqrt(PetscRealPart(sum));
 31:     }
 32: #else
 33:     *z = BLnrm2_(&xin->n,x->array,&one);
 34: #endif
 35:     PetscLogFlops(2*xin->n-1);
 36:   } else if (type == NORM_INFINITY) {
 37:     int       i,n = xin->n;
 38:     PetscReal max = 0.0,tmp;
 39:     Scalar    *xx = x->array;

 41:     for (i=0; i<n; i++) {
 42:       if ((tmp = PetscAbsScalar(*xx)) > max) max = tmp;
 43:       /* check special case of tmp == NaN */
 44:       if (tmp != tmp) {max = tmp; break;}
 45:       xx++;
 46:     }
 47:     *z   = max;
 48:   } else if (type == NORM_1) {
 49:     *z = BLasum_(&xin->n,x->array,&one);
 50:     PetscLogFlops(xin->n-1);
 51:   } else if (type == NORM_1_AND_2) {
 52:     VecNorm_Seq(xin,NORM_1,z);
 53:     VecNorm_Seq(xin,NORM_2,z+1);
 54:   }
 55:   return(0);
 56: }

 58: int VecGetOwnershipRange_Seq(Vec xin,int *low,int *high)
 59: {
 61:   *low = 0; *high = xin->n;
 62:   return(0);
 63: }
 64:  #include petscviewer.h
 65:  #include petscsys.h

 67: int VecView_Seq_File(Vec xin,PetscViewer viewer)
 68: {
 69:   Vec_Seq           *x = (Vec_Seq *)xin->data;
 70:   int               i,n = xin->n,ierr;
 71:   char              *name;
 72:   PetscViewerFormat format;

 75:   PetscViewerGetFormat(viewer,&format);
 76:   if (format == PETSC_VIEWER_ASCII_MATLAB) {
 77:     PetscObjectGetName((PetscObject)viewer,&name);
 78:     PetscViewerASCIIPrintf(viewer,"%s = [n",name);
 79:     for (i=0; i<n; i++) {
 80: #if defined(PETSC_USE_COMPLEX)
 81:       if (PetscImaginaryPart(x->array[i]) > 0.0) {
 82:         PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ein",PetscRealPart(x->array[i]),PetscImaginaryPart(x->array[i]));
 83:       } else if (PetscImaginaryPart(x->array[i]) < 0.0) {
 84:         PetscViewerASCIIPrintf(viewer,"%18.16e - %18.16ein",PetscRealPart(x->array[i]),-PetscImaginaryPart(x->array[i]));
 85:       } else {
 86:         PetscViewerASCIIPrintf(viewer,"%18.16en",PetscRealPart(x->array[i]));
 87:       }
 88: #else
 89:       PetscViewerASCIIPrintf(viewer,"%18.16en",x->array[i]);
 90: #endif
 91:     }
 92:     PetscViewerASCIIPrintf(viewer,"];n");
 93:   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
 94:     for (i=0; i<n; i++) {
 95: #if defined(PETSC_USE_COMPLEX)
 96:       PetscViewerASCIIPrintf(viewer,"%18.16e %18.16en",PetscRealPart(x->array[i]),PetscImaginaryPart(x->array[i]));
 97: #else
 98:       PetscViewerASCIIPrintf(viewer,"%18.16en",x->array[i]);
 99: #endif
100:     }
101:   } else {
102:     for (i=0; i<n; i++) {
103:       if (format == PETSC_VIEWER_ASCII_INDEX) {
104:         PetscViewerASCIIPrintf(viewer,"%d: ",i);
105:       }
106: #if defined(PETSC_USE_COMPLEX)
107:       if (PetscImaginaryPart(x->array[i]) > 0.0) {
108:         PetscViewerASCIIPrintf(viewer,"%g + %g in",PetscRealPart(x->array[i]),PetscImaginaryPart(x->array[i]));
109:       } else if (PetscImaginaryPart(x->array[i]) < 0.0) {
110:         PetscViewerASCIIPrintf(viewer,"%g - %g in",PetscRealPart(x->array[i]),-PetscImaginaryPart(x->array[i]));
111:       } else {
112:         PetscViewerASCIIPrintf(viewer,"%gn",PetscRealPart(x->array[i]));
113:       }
114: #else
115:       PetscViewerASCIIPrintf(viewer,"%gn",x->array[i]);
116: #endif
117:     }
118:   }
119:   PetscViewerFlush(viewer);
120:   return(0);
121: }

123: static int VecView_Seq_Draw_LG(Vec xin,PetscViewer v)
124: {
125:   Vec_Seq     *x = (Vec_Seq *)xin->data;
126:   int         i,n = xin->n,ierr;
127:   PetscDraw   win;
128:   PetscReal   *xx;
129:   PetscDrawLG lg;

132:   PetscViewerDrawGetDrawLG(v,0,&lg);
133:   PetscDrawLGGetDraw(lg,&win);
134:   PetscDrawCheckResizedWindow(win);
135:   PetscDrawLGReset(lg);
136:   PetscMalloc((n+1)*sizeof(PetscReal),&xx);
137:   for (i=0; i<n; i++) {
138:     xx[i] = (PetscReal) i;
139:   }
140: #if !defined(PETSC_USE_COMPLEX)
141:   PetscDrawLGAddPoints(lg,n,&xx,&x->array);
142: #else 
143:   {
144:     PetscReal *yy;
145:     PetscMalloc((n+1)*sizeof(PetscReal),&yy);
146:     for (i=0; i<n; i++) {
147:       yy[i] = PetscRealPart(x->array[i]);
148:     }
149:     PetscDrawLGAddPoints(lg,n,&xx,&yy);
150:     PetscFree(yy);
151:   }
152: #endif
153:   PetscFree(xx);
154:   PetscDrawLGDraw(lg);
155:   PetscDrawSynchronizedFlush(win);
156:   return(0);
157: }

159: static int VecView_Seq_Draw(Vec xin,PetscViewer v)
160: {
161:   int               ierr;
162:   PetscDraw         draw;
163:   PetscTruth        isnull;
164:   PetscViewerFormat format;

167:   PetscViewerDrawGetDraw(v,0,&draw);
168:   PetscDrawIsNull(draw,&isnull); if (isnull) return(0);
169: 
170:   PetscViewerGetFormat(v,&format);
171:   /*
172:      Currently it only supports drawing to a line graph */
173:   if (format != PETSC_VIEWER_DRAW_LG) {
174:     PetscViewerPushFormat(v,PETSC_VIEWER_DRAW_LG);
175:   }
176:   VecView_Seq_Draw_LG(xin,v);
177:   if (format != PETSC_VIEWER_DRAW_LG) {
178:     PetscViewerPopFormat(v);
179:   }

181:   return(0);
182: }

184: static int VecView_Seq_Binary(Vec xin,PetscViewer viewer)
185: {
186:   Vec_Seq  *x = (Vec_Seq *)xin->data;
187:   int      ierr,fdes,n = xin->n;
188:   FILE     *file;

191:   ierr  = PetscViewerBinaryGetDescriptor(viewer,&fdes);
192:   /* Write vector header */
193:   PetscBinaryWrite(fdes,&xin->cookie,1,PETSC_INT,0);
194:   PetscBinaryWrite(fdes,&n,1,PETSC_INT,0);

196:   /* Write vector contents */
197:   PetscBinaryWrite(fdes,x->array,n,PETSC_SCALAR,0);

199:   PetscViewerBinaryGetInfoPointer(viewer,&file);
200:   if (file && xin->bs > 1) {
201:     fprintf(file,"-vecload_block_size %dn",xin->bs);
202:   }
203:   return(0);
204: }


207: int VecView_Seq(Vec xin,PetscViewer viewer)
208: {
209:   Vec_Seq     *x = (Vec_Seq *)xin->data;
210:   int         ierr;
211:   PetscTruth  isdraw,isascii,issocket,isbinary;

214:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
215:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
216:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
217:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);
218:   if (isdraw){
219:     VecView_Seq_Draw(xin,viewer);
220:   } else if (isascii){
221:     VecView_Seq_File(xin,viewer);
222:   } else if (issocket) {
223:     PetscViewerSocketPutScalar(viewer,xin->n,1,x->array);
224:   } else if (isbinary) {
225:     VecView_Seq_Binary(xin,viewer);
226:   } else {
227:     SETERRQ1(1,"Viewer type %s not supported by this vector object",((PetscObject)viewer)->type_name);
228:   }
229:   return(0);
230: }

232: int VecSetValues_Seq(Vec xin,int ni,const int ix[],const Scalar y[],InsertMode m)
233: {
234:   Vec_Seq  *x = (Vec_Seq *)xin->data;
235:   Scalar   *xx = x->array;
236:   int      i;

239:   if (m == INSERT_VALUES) {
240:     for (i=0; i<ni; i++) {
241:       if (ix[i] < 0) continue;
242: #if defined(PETSC_USE_BOPT_g)
243:       if (ix[i] >= xin->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %d maximum %d",ix[i],xin->n);
244: #endif
245:       xx[ix[i]] = y[i];
246:     }
247:   } else {
248:     for (i=0; i<ni; i++) {
249:       if (ix[i] < 0) continue;
250: #if defined(PETSC_USE_BOPT_g)
251:       if (ix[i] >= xin->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %d maximum %d",ix[i],xin->n);
252: #endif
253:       xx[ix[i]] += y[i];
254:     }
255:   }
256:   return(0);
257: }

259: int VecSetValuesBlocked_Seq(Vec xin,int ni,const int ix[],const Scalar yin[],InsertMode m)
260: {
261:   Vec_Seq  *x = (Vec_Seq *)xin->data;
262:   Scalar   *xx = x->array,*y = (Scalar*)yin;
263:   int      i,bs = xin->bs,start,j;

265:   /*
266:        For optimization could treat bs = 2, 3, 4, 5 as special cases with loop unrolling
267:   */
269:   if (m == INSERT_VALUES) {
270:     for (i=0; i<ni; i++) {
271:       start = bs*ix[i];
272:       if (start < 0) continue;
273: #if defined(PETSC_USE_BOPT_g)
274:       if (start >= xin->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %d maximum %d",start,xin->n);
275: #endif
276:       for (j=0; j<bs; j++) {
277:         xx[start+j] = y[j];
278:       }
279:       y += bs;
280:     }
281:   } else {
282:     for (i=0; i<ni; i++) {
283:       start = bs*ix[i];
284:       if (start < 0) continue;
285: #if defined(PETSC_USE_BOPT_g)
286:       if (start >= xin->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %d maximum %d",start,xin->n);
287: #endif
288:       for (j=0; j<bs; j++) {
289:         xx[start+j] += y[j];
290:       }
291:       y += bs;
292:     }
293:   }
294:   return(0);
295: }


298: int VecDestroy_Seq(Vec v)
299: {
300:   Vec_Seq *vs = (Vec_Seq*)v->data;
301:   int     ierr;


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

308: #if defined(PETSC_USE_LOG)
309:   PetscLogObjectState((PetscObject)v,"Length=%d",v->n);
310: #endif
311:   if (vs->array_allocated) {PetscFree(vs->array_allocated);}
312:   PetscFree(vs);

314:   return(0);
315: }

317: static int VecPublish_Seq(PetscObject obj)
318: {
319: #if defined(PETSC_HAVE_AMS)
320:   Vec          v = (Vec) obj;
321:   Vec_Seq      *s = (Vec_Seq*)v->data;
322:   int          ierr,(*f)(AMS_Memory,char *,Vec);
323: #endif


327: #if defined(PETSC_HAVE_AMS)
328:   /* if it is already published then return */
329:   if (v->amem >=0) return(0);

331:   /* if array in vector was not allocated (for example PCSetUp_BJacobi_Singleblock()) then
332:      cannot AMS publish the object*/
333:   if (!s->array) return(0);

335:   PetscObjectPublishBaseBegin(obj);
336:   AMS_Memory_add_field((AMS_Memory)v->amem,"values",s->array,v->n,AMS_DOUBLE,AMS_READ,
337:                                 AMS_DISTRIBUTED,AMS_REDUCT_UNDEF);

339:   /* if the vector knows its "layout" let it set it*/
340:   PetscObjectQueryFunction(obj,"AMSSetFieldBlock_C",(void (**)())&f);
341:   if (f) {
342:     (*f)((AMS_Memory)v->amem,"values",v);
343:   }
344:   PetscObjectPublishBaseEnd(obj);
345: #endif

347:   return(0);
348: }

350: static struct _VecOps DvOps = {VecDuplicate_Seq,
351:             VecDuplicateVecs_Default,
352:             VecDestroyVecs_Default,
353:             VecDot_Seq,
354:             VecMDot_Seq,
355:             VecNorm_Seq,
356:             VecTDot_Seq,
357:             VecMTDot_Seq,
358:             VecScale_Seq,
359:             VecCopy_Seq,
360:             VecSet_Seq,
361:             VecSwap_Seq,
362:             VecAXPY_Seq,
363:             VecAXPBY_Seq,
364:             VecMAXPY_Seq,
365:             VecAYPX_Seq,
366:             VecWAXPY_Seq,
367:             VecPointwiseMult_Seq,
368:             VecPointwiseDivide_Seq,
369:             VecSetValues_Seq,0,0,
370:             VecGetArray_Seq,
371:             VecGetSize_Seq,
372:             VecGetSize_Seq,
373:             VecGetOwnershipRange_Seq,
374:             VecRestoreArray_Seq,
375:             VecMax_Seq,
376:             VecMin_Seq,
377:             VecSetRandom_Seq,0,
378:             VecSetValuesBlocked_Seq,
379:             VecDestroy_Seq,
380:             VecView_Seq,
381:             VecPlaceArray_Seq,
382:             VecReplaceArray_Seq,
383:             VecGetMap_Seq,
384:             VecDot_Seq,
385:             VecTDot_Seq,
386:             VecNorm_Seq,
387:             VecLoadIntoVector_Default,
388:             VecReciprocal_Default,
389:             0, /* VecViewNative */
390:             VecConjugate_Seq,
391:             0,
392:             0,
393:             VecResetArray_Seq};


396: /*
397:       This is called by VecCreate_Seq() (i.e. VecCreateSeq()) and VecCreateSeqWithArray()
398: */
399: static int VecCreate_Seq_Private(Vec v,const Scalar array[])
400: {
401:   Vec_Seq *s;
402:   int     ierr;

405:   PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));
406:   PetscMalloc(sizeof(Vec_Seq),&s);
407:   v->data            = (void*)s;
408:   v->bops->publish   = VecPublish_Seq;
409:   v->n               = PetscMax(v->n,v->N);
410:   v->N               = PetscMax(v->n,v->N);
411:   v->bs              = -1;
412:   s->array           = (Scalar *)array;
413:   s->array_allocated = 0;
414:   if (!v->map) {
415:     MapCreateMPI(v->comm,v->n,v->N,&v->map);
416:   }
417:   PetscObjectChangeTypeName((PetscObject)v,VEC_SEQ);
418: #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX)
419:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscMatlabEnginePut_C","VecMatlabEnginePut_Default",VecMatlabEnginePut_Default);
420:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscMatlabEngineGet_C","VecMatlabEngineGet_Default",VecMatlabEngineGet_Default);
421: #endif
422:   PetscPublishAll(v);
423:   return(0);
424: }

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

430:    Collective on MPI_Comm

432:    Input Parameter:
433: +  comm - the communicator, should be PETSC_COMM_SELF
434: .  n - the vector length 
435: -  array - memory where the vector elements are to be stored.

437:    Output Parameter:
438: .  V - the vector

440:    Notes:
441:    Use VecDuplicate() or VecDuplicateVecs() to form additional vectors of the
442:    same type as an existing vector.

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

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

450:    Level: intermediate

452:    Concepts: vectors^creating with array

454: .seealso: VecCreateMPIWithArray(), VecCreate(), VecDuplicate(), VecDuplicateVecs(), 
455:           VecCreateGhost(), VecCreateSeq(), VecPlaceArray()
456: @*/
457: int VecCreateSeqWithArray(MPI_Comm comm,int n,const Scalar array[],Vec *V)
458: {
459:   int  ierr;

462:   VecCreate(comm,n,n,V);
463:   VecCreate_Seq_Private(*V,array);
464:   return(0);
465: }

467: EXTERN_C_BEGIN
468: int VecCreate_Seq(Vec V)
469: {
470:   Vec_Seq *s;
471:   Scalar  *array;
472:   int     ierr,n = PetscMax(V->n,V->N);

475:   PetscMalloc((n+1)*sizeof(Scalar),&array);
476:   PetscMemzero(array,n*sizeof(Scalar));
477:   VecCreate_Seq_Private(V,array);
478:   s    = (Vec_Seq*)V->data;
479:   s->array_allocated = array;
480:   return(0);
481: }
482: EXTERN_C_END


485: int VecGetMap_Seq(Vec win,Map *m)
486: {
488:   *m = win->map;
489:   return(0);
490: }

492: int VecDuplicate_Seq(Vec win,Vec *V)
493: {
494:   int     ierr;

497:   VecCreateSeq(win->comm,win->n,V);
498:   if (win->mapping) {
499:     (*V)->mapping = win->mapping;
500:     PetscObjectReference((PetscObject)win->mapping);
501:   }
502:   if (win->bmapping) {
503:     (*V)->bmapping = win->bmapping;
504:     PetscObjectReference((PetscObject)win->bmapping);
505:   }
506:   (*V)->bs = win->bs;
507:   PetscOListDuplicate(win->olist,&(*V)->olist);
508:   PetscFListDuplicate(win->qlist,&(*V)->qlist);
509:   return(0);
510: }