Actual source code: vinv.c

  1: /*$Id: vinv.c,v 1.71 2001/09/11 16:31:37 bsmith Exp $*/
  2: /*
  3:      Some useful vector utility functions.
  4: */
 5:  #include vecimpl.h

  9: /*@C
 10:    VecStrideScale - Scales a subvector of a vector defined 
 11:    by a starting point and a stride.

 13:    Collective on Vec

 15:    Input Parameter:
 16: +  v - the vector 
 17: .  start - starting point of the subvector (defined by a stride)
 18: -  scale - value to multiply each subvector entry by

 20:    Notes:
 21:    One must call VecSetBlockSize() before this routine to set the stride 
 22:    information, or use a vector created from a multicomponent DA.

 24:    This will only work if the desire subvector is a stride subvector

 26:    Level: advanced

 28:    Concepts: scale^on stride of vector
 29:    Concepts: stride^scale

 31: .seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideScale()
 32: @*/
 33: int VecStrideScale(Vec v,int start,PetscScalar *scale)
 34: {
 35:   int         i,n,ierr,bs;
 36:   PetscScalar *x,xscale = *scale;

 41:   VecGetLocalSize(v,&n);
 42:   VecGetArray(v,&x);

 44:   bs   = v->bs;
 45:   if (start >= bs) {
 46:     SETERRQ2(1,"Start of stride subvector (%d) is too large for stride\n\
 47:             Have you set the vector blocksize (%d) correctly with VecSetBlockSize()?",start,bs);
 48:   }
 49:   x += start;

 51:   for (i=0; i<n; i+=bs) {
 52:     x[i] *= xscale;
 53:   }
 54:   x -= start;
 55:   VecRestoreArray(v,&x);
 56:   return(0);
 57: }

 61: /*@C
 62:    VecStrideNorm - Computes the norm of subvector of a vector defined 
 63:    by a starting point and a stride.

 65:    Collective on Vec

 67:    Input Parameter:
 68: +  v - the vector 
 69: .  start - starting point of the subvector (defined by a stride)
 70: -  ntype - type of norm, one of NORM_1, NORM_2, NORM_INFINITY

 72:    Output Parameter:
 73: .  norm - the norm

 75:    Notes:
 76:    One must call VecSetBlockSize() before this routine to set the stride 
 77:    information, or use a vector created from a multicomponent DA.

 79:    If x is the array representing the vector x then this computes the norm 
 80:    of the array (x[start],x[start+stride],x[start+2*stride], ....)

 82:    This is useful for computing, say the norm of the pressure variable when
 83:    the pressure is stored (interlaced) with other variables, say density etc.

 85:    This will only work if the desire subvector is a stride subvector

 87:    Level: advanced

 89:    Concepts: norm^on stride of vector
 90:    Concepts: stride^norm

 92: .seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax()
 93: @*/
 94: int VecStrideNorm(Vec v,int start,NormType ntype,PetscReal *nrm)
 95: {
 96:   int         i,n,ierr,bs;
 97:   PetscScalar *x;
 98:   PetscReal   tnorm;
 99:   MPI_Comm    comm;

104:   VecGetLocalSize(v,&n);
105:   VecGetArray(v,&x);
106:   PetscObjectGetComm((PetscObject)v,&comm);

108:   bs   = v->bs;
109:   if (start >= bs) {
110:     SETERRQ2(1,"Start of stride subvector (%d) is too large for stride\n\
111:             Have you set the vector blocksize (%d) correctly with VecSetBlockSize()?",start,bs);
112:   }
113:   x += start;

115:   if (ntype == NORM_2) {
116:     PetscScalar sum = 0.0;
117:     for (i=0; i<n; i+=bs) {
118:       sum += x[i]*(PetscConj(x[i]));
119:     }
120:     tnorm  = PetscRealPart(sum);
121:     MPI_Allreduce(&tnorm,nrm,1,MPIU_REAL,MPI_SUM,comm);
122:     *nrm = sqrt(*nrm);
123:   } else if (ntype == NORM_1) {
124:     tnorm = 0.0;
125:     for (i=0; i<n; i+=bs) {
126:       tnorm += PetscAbsScalar(x[i]);
127:     }
128:     MPI_Allreduce(&tnorm,nrm,1,MPIU_REAL,MPI_SUM,comm);
129:   } else if (ntype == NORM_INFINITY) {
130:     PetscReal tmp;
131:     tnorm = 0.0;

133:     for (i=0; i<n; i+=bs) {
134:       if ((tmp = PetscAbsScalar(x[i])) > tnorm) tnorm = tmp;
135:       /* check special case of tmp == NaN */
136:       if (tmp != tmp) {tnorm = tmp; break;}
137:     }
138:     MPI_Allreduce(&tnorm,nrm,1,MPIU_REAL,MPI_MAX,comm);
139:   } else {
140:     SETERRQ(1,"Unknown norm type");
141:   }

143:   VecRestoreArray(v,&x);
144:   return(0);
145: }

149: /*@
150:    VecStrideMax - Computes the maximum of subvector of a vector defined 
151:    by a starting point and a stride and optionally its location.

153:    Collective on Vec

155:    Input Parameter:
156: +  v - the vector 
157: -  start - starting point of the subvector (defined by a stride)

159:    Output Parameter:
160: +  index - the location where the maximum occurred (not supported, pass PETSC_NULL,
161:            if you need this, send mail to petsc-maint@mcs.anl.gov to request it)
162: -  nrm - the max

164:    Notes:
165:    One must call VecSetBlockSize() before this routine to set the stride 
166:    information, or use a vector created from a multicomponent DA.

168:    If xa is the array representing the vector x, then this computes the max
169:    of the array (xa[start],xa[start+stride],xa[start+2*stride], ....)

171:    This is useful for computing, say the maximum of the pressure variable when
172:    the pressure is stored (interlaced) with other variables, e.g., density, etc.
173:    This will only work if the desire subvector is a stride subvector.

175:    Level: advanced

177:    Concepts: maximum^on stride of vector
178:    Concepts: stride^maximum

180: .seealso: VecMax(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin()
181: @*/
182: int VecStrideMax(Vec v,int start,int *idex,PetscReal *nrm)
183: {
184:   int         i,n,ierr,bs;
185:   PetscScalar *x;
186:   PetscReal   max,tmp;
187:   MPI_Comm    comm;

192:   if (idex) {
193:     SETERRQ(1,"No support yet for returning index; send mail to petsc-maint@mcs.anl.gov asking for it");
194:   }
195:   VecGetLocalSize(v,&n);
196:   VecGetArray(v,&x);
197:   PetscObjectGetComm((PetscObject)v,&comm);

199:   bs   = v->bs;
200:   if (start >= bs) {
201:     SETERRQ2(1,"Start of stride subvector (%d) is too large for stride\n\
202:             Have you set the vector blocksize (%d) correctly with VecSetBlockSize()?",start,bs);
203:   }
204:   x += start;

206:   if (!n) {
207:     max = PETSC_MIN;
208:   } else {
209: #if defined(PETSC_USE_COMPLEX)
210:     max = PetscRealPart(x[0]);
211: #else
212:     max = x[0];
213: #endif
214:     for (i=bs; i<n; i+=bs) {
215: #if defined(PETSC_USE_COMPLEX)
216:       if ((tmp = PetscRealPart(x[i])) > max) { max = tmp;}
217: #else
218:       if ((tmp = x[i]) > max) { max = tmp; }
219: #endif
220:     }
221:   }
222:   MPI_Allreduce(&max,nrm,1,MPIU_REAL,MPI_MAX,comm);

224:   VecRestoreArray(v,&x);
225:   return(0);
226: }

230: /*@C
231:    VecStrideMin - Computes the minimum of subvector of a vector defined 
232:    by a starting point and a stride and optionally its location.

234:    Collective on Vec

236:    Input Parameter:
237: +  v - the vector 
238: -  start - starting point of the subvector (defined by a stride)

240:    Output Parameter:
241: +  idex - the location where the minimum occurred (not supported, pass PETSC_NULL,
242:            if you need this, send mail to petsc-maint@mcs.anl.gov to request it)
243: -  nrm - the min

245:    Level: advanced

247:    Notes:
248:    One must call VecSetBlockSize() before this routine to set the stride 
249:    information, or use a vector created from a multicomponent DA.

251:    If xa is the array representing the vector x, then this computes the min
252:    of the array (xa[start],xa[start+stride],xa[start+2*stride], ....)

254:    This is useful for computing, say the minimum of the pressure variable when
255:    the pressure is stored (interlaced) with other variables, e.g., density, etc.
256:    This will only work if the desire subvector is a stride subvector.

258:    Concepts: minimum^on stride of vector
259:    Concepts: stride^minimum

261: .seealso: VecMin(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMax()
262: @*/
263: int VecStrideMin(Vec v,int start,int *idex,PetscReal *nrm)
264: {
265:   int         i,n,ierr,bs;
266:   PetscScalar *x;
267:   PetscReal   min,tmp;
268:   MPI_Comm    comm;

273:   if (idex) {
274:     SETERRQ(1,"No support yet for returning index; send mail to petsc-maint@mcs.anl.gov asking for it");
275:   }
276:   VecGetLocalSize(v,&n);
277:   VecGetArray(v,&x);
278:   PetscObjectGetComm((PetscObject)v,&comm);

280:   bs   = v->bs;
281:   if (start >= bs) {
282:     SETERRQ2(1,"Start of stride subvector (%d) is too large for stride\n\
283:             Have you set the vector blocksize (%d) correctly with VecSetBlockSize()?",start,bs);
284:   }
285:   x += start;

287:   if (!n) {
288:     min = PETSC_MAX;
289:   } else {
290: #if defined(PETSC_USE_COMPLEX)
291:     min = PetscRealPart(x[0]);
292: #else
293:     min = x[0];
294: #endif
295:     for (i=bs; i<n; i+=bs) {
296: #if defined(PETSC_USE_COMPLEX)
297:       if ((tmp = PetscRealPart(x[i])) < min) { min = tmp;}
298: #else
299:       if ((tmp = x[i]) < min) { min = tmp; }
300: #endif
301:     }
302:   }
303:   MPI_Allreduce(&min,nrm,1,MPIU_REAL,MPI_MIN,comm);

305:   VecRestoreArray(v,&x);
306:   return(0);
307: }

311: /*@C
312:    VecStrideScaleAll - Scales the subvectors of a vector defined 
313:    by a starting point and a stride.

315:    Collective on Vec

317:    Input Parameter:
318: +  v - the vector 
319: -  scales - values to multiply each subvector entry by

321:    Notes:
322:    One must call VecSetBlockSize() before this routine to set the stride 
323:    information, or use a vector created from a multicomponent DA.


326:    Level: advanced

328:    Concepts: scale^on stride of vector
329:    Concepts: stride^scale

331: .seealso: VecNorm(), VecStrideScale(), VecScale(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax()
332: @*/
333: int VecStrideScaleAll(Vec v,PetscScalar *scales)
334: {
335:   int         i,j,n,ierr,bs;
336:   PetscScalar *x;

341:   VecGetLocalSize(v,&n);
342:   VecGetArray(v,&x);

344:   bs   = v->bs;

346:   /* need to provide optimized code for each bs */
347:   for (i=0; i<n; i+=bs) {
348:     for (j=0; j<bs; j++) {
349:       x[i+j] *= scales[j];
350:     }
351:   }
352:   VecRestoreArray(v,&x);
353:   return(0);
354: }

358: /*@C
359:    VecStrideNormAll - Computes the norms  subvectors of a vector defined 
360:    by a starting point and a stride.

362:    Collective on Vec

364:    Input Parameter:
365: +  v - the vector 
366: -  ntype - type of norm, one of NORM_1, NORM_2, NORM_INFINITY

368:    Output Parameter:
369: .  nrm - the norms

371:    Notes:
372:    One must call VecSetBlockSize() before this routine to set the stride 
373:    information, or use a vector created from a multicomponent DA.

375:    If x is the array representing the vector x then this computes the norm 
376:    of the array (x[start],x[start+stride],x[start+2*stride], ....)

378:    This is useful for computing, say the norm of the pressure variable when
379:    the pressure is stored (interlaced) with other variables, say density etc.

381:    This will only work if the desire subvector is a stride subvector

383:    Level: advanced

385:    Concepts: norm^on stride of vector
386:    Concepts: stride^norm

388: .seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax()
389: @*/
390: int VecStrideNormAll(Vec v,NormType ntype,PetscReal *nrm)
391: {
392:   int         i,j,n,ierr,bs;
393:   PetscScalar *x;
394:   PetscReal   tnorm[128];
395:   MPI_Comm    comm;

400:   VecGetLocalSize(v,&n);
401:   VecGetArray(v,&x);
402:   PetscObjectGetComm((PetscObject)v,&comm);

404:   bs   = v->bs;
405:   if (bs > 128) SETERRQ(1,"Currently supports only blocksize up to 128");

407:   if (ntype == NORM_2) {
408:     PetscScalar sum[128];
409:     for (j=0; j<bs; j++) sum[j] = 0.0;
410:     for (i=0; i<n; i+=bs) {
411:       for (j=0; j<bs; j++) {
412:         sum[j] += x[i+j]*(PetscConj(x[i+j]));
413:       }
414:     }
415:     for (j=0; j<bs; j++) {
416:       tnorm[j]  = PetscRealPart(sum[j]);
417:     }
418:     MPI_Allreduce(tnorm,nrm,bs,MPIU_REAL,MPI_SUM,comm);
419:     for (j=0; j<bs; j++) {
420:       nrm[j] = sqrt(nrm[j]);
421:     }
422:   } else if (ntype == NORM_1) {
423:     for (j=0; j<bs; j++) {
424:       tnorm[j] = 0.0;
425:     }
426:     for (i=0; i<n; i+=bs) {
427:       for (j=0; j<bs; j++) {
428:         tnorm[j] += PetscAbsScalar(x[i+j]);
429:       }
430:     }
431:     MPI_Allreduce(tnorm,nrm,bs,MPIU_REAL,MPI_SUM,comm);
432:   } else if (ntype == NORM_INFINITY) {
433:     PetscReal tmp;
434:     for (j=0; j<bs; j++) {
435:       tnorm[j] = 0.0;
436:     }

438:     for (i=0; i<n; i+=bs) {
439:       for (j=0; j<bs; j++) {
440:         if ((tmp = PetscAbsScalar(x[i+j])) > tnorm[j]) tnorm[j] = tmp;
441:         /* check special case of tmp == NaN */
442:         if (tmp != tmp) {tnorm[j] = tmp; break;}
443:       }
444:     }
445:     MPI_Allreduce(tnorm,nrm,bs,MPIU_REAL,MPI_MAX,comm);
446:   } else {
447:     SETERRQ(1,"Unknown norm type");
448:   }

450:   VecRestoreArray(v,&x);
451:   return(0);
452: }

456: /*@C
457:    VecStrideMaxAll - Computes the maximums of subvectors of a vector defined 
458:    by a starting point and a stride and optionally its location.

460:    Collective on Vec

462:    Input Parameter:
463: .  v - the vector 

465:    Output Parameter:
466: +  index - the location where the maximum occurred (not supported, pass PETSC_NULL,
467:            if you need this, send mail to petsc-maint@mcs.anl.gov to request it)
468: -  nrm - the maximums

470:    Notes:
471:    One must call VecSetBlockSize() before this routine to set the stride 
472:    information, or use a vector created from a multicomponent DA.

474:    This is useful for computing, say the maximum of the pressure variable when
475:    the pressure is stored (interlaced) with other variables, e.g., density, etc.
476:    This will only work if the desire subvector is a stride subvector.

478:    Level: advanced

480:    Concepts: maximum^on stride of vector
481:    Concepts: stride^maximum

483: .seealso: VecMax(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin()
484: @*/
485: int VecStrideMaxAll(Vec v,int *idex,PetscReal *nrm)
486: {
487:   int         i,j,n,ierr,bs;
488:   PetscScalar *x;
489:   PetscReal   max[128],tmp;
490:   MPI_Comm    comm;

495:   if (idex) {
496:     SETERRQ(1,"No support yet for returning index; send mail to petsc-maint@mcs.anl.gov asking for it");
497:   }
498:   VecGetLocalSize(v,&n);
499:   VecGetArray(v,&x);
500:   PetscObjectGetComm((PetscObject)v,&comm);

502:   bs   = v->bs;
503:   if (bs > 128) SETERRQ(1,"Currently supports only blocksize up to 128");

505:   if (!n) {
506:     for (j=0; j<bs; j++) {
507:       max[j] = PETSC_MIN;
508:     }
509:   } else {
510:     for (j=0; j<bs; j++) {
511: #if defined(PETSC_USE_COMPLEX)
512:       max[j] = PetscRealPart(x[j]);
513: #else
514:       max[j] = x[j];
515: #endif
516:     }
517:     for (i=bs; i<n; i+=bs) {
518:       for (j=0; j<bs; j++) {
519: #if defined(PETSC_USE_COMPLEX)
520:         if ((tmp = PetscRealPart(x[i+j])) > max[j]) { max[j] = tmp;}
521: #else
522:         if ((tmp = x[i+j]) > max[j]) { max[j] = tmp; }
523: #endif
524:       }
525:     }
526:   }
527:   MPI_Allreduce(max,nrm,bs,MPIU_REAL,MPI_MAX,comm);

529:   VecRestoreArray(v,&x);
530:   return(0);
531: }

535: /*@C
536:    VecStrideMinAll - Computes the minimum of subvector of a vector defined 
537:    by a starting point and a stride and optionally its location.

539:    Collective on Vec

541:    Input Parameter:
542: .  v - the vector 

544:    Output Parameter:
545: +  idex - the location where the minimum occurred (not supported, pass PETSC_NULL,
546:            if you need this, send mail to petsc-maint@mcs.anl.gov to request it)
547: -  nrm - the minimums

549:    Level: advanced

551:    Notes:
552:    One must call VecSetBlockSize() before this routine to set the stride 
553:    information, or use a vector created from a multicomponent DA.

555:    This is useful for computing, say the minimum of the pressure variable when
556:    the pressure is stored (interlaced) with other variables, e.g., density, etc.
557:    This will only work if the desire subvector is a stride subvector.

559:    Concepts: minimum^on stride of vector
560:    Concepts: stride^minimum

562: .seealso: VecMin(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMax()
563: @*/
564: int VecStrideMinAll(Vec v,int *idex,PetscReal *nrm)
565: {
566:   int         i,n,ierr,bs,j;
567:   PetscScalar *x;
568:   PetscReal   min[128],tmp;
569:   MPI_Comm    comm;

574:   if (idex) {
575:     SETERRQ(1,"No support yet for returning index; send mail to petsc-maint@mcs.anl.gov asking for it");
576:   }
577:   VecGetLocalSize(v,&n);
578:   VecGetArray(v,&x);
579:   PetscObjectGetComm((PetscObject)v,&comm);

581:   bs   = v->bs;
582:   if (bs > 128) SETERRQ(1,"Currently supports only blocksize up to 128");

584:   if (!n) {
585:     for (j=0; j<bs; j++) {
586:       min[j] = PETSC_MAX;
587:     }
588:   } else {
589:     for (j=0; j<bs; j++) {
590: #if defined(PETSC_USE_COMPLEX)
591:       min[j] = PetscRealPart(x[j]);
592: #else
593:       min[j] = x[j];
594: #endif
595:     }
596:     for (i=bs; i<n; i+=bs) {
597:       for (j=0; j<bs; j++) {
598: #if defined(PETSC_USE_COMPLEX)
599:         if ((tmp = PetscRealPart(x[i+j])) < min[j]) { min[j] = tmp;}
600: #else
601:         if ((tmp = x[i+j]) < min[j]) { min[j] = tmp; }
602: #endif
603:       }
604:     }
605:   }
606:   MPI_Allreduce(min,nrm,bs,MPIU_REAL,MPI_MIN,comm);

608:   VecRestoreArray(v,&x);
609:   return(0);
610: }

612: /*----------------------------------------------------------------------------------------------*/
615: /*@
616:    VecStrideGatherAll - Gathers all the single components from a multi-component vector into
617:    seperate vectors.

619:    Collective on Vec

621:    Input Parameter:
622: +  v - the vector 
623: -  addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES

625:    Output Parameter:
626: .  s - the location where the subvectors are stored

628:    Notes:
629:    One must call VecSetBlockSize() before this routine to set the stride 
630:    information, or use a vector created from a multicomponent DA.

632:    If x is the array representing the vector x then this gathers
633:    the arrays (x[start],x[start+stride],x[start+2*stride], ....)
634:    for start=0,1,2,...bs-1

636:    The parallel layout of the vector and the subvector must be the same;
637:    i.e., nlocal of v = stride*(nlocal of s) 

639:    Not optimized; could be easily

641:    Level: advanced

643:    Concepts: gather^into strided vector

645: .seealso: VecStrideNorm(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideGather(),
646:           VecStrideScatterAll()
647: @*/
648: int VecStrideGatherAll(Vec v,Vec *s,InsertMode addv)
649: {
650:   int          i,n,ierr,bs,j,k,*bss,nv,jj,nvc;
651:   PetscScalar  *x,**y;

656:   VecGetLocalSize(v,&n);
657:   VecGetArray(v,&x);
658:   bs   = v->bs;

660:   PetscMalloc(bs*sizeof(PetscReal*),&y);
661:   PetscMalloc(bs*sizeof(int),&bss);
662:   nv   = 0;
663:   nvc  = 0;
664:   for (i=0; i<bs; i++) {
665:     VecGetBlockSize(s[i],&bss[i]);
666:     if (bss[i] < 1) bss[i] = 1; /* if user never set it then assume 1  Re: [PETSC #8241] VecStrideGatherAll */
667:     VecGetArray(s[i],&y[i]);
668:     nvc  += bss[i];
669:     nv++;
670:     if (nvc > bs)  SETERRQ(1,"Number of subvectors in subvectors > number of vectors in main vector");
671:     if (nvc == bs) break;
672:   }

674:   n =  n/bs;

676:   jj = 0;
677:   if (addv == INSERT_VALUES) {
678:     for (j=0; j<nv; j++) {
679:       for (k=0; k<bss[j]; k++) {
680:         for (i=0; i<n; i++) {
681:           y[j][i*bss[j] + k] = x[bs*i+jj+k];
682:         }
683:       }
684:       jj += bss[j];
685:     }
686:   } else if (addv == ADD_VALUES) {
687:     for (j=0; j<nv; j++) {
688:       for (k=0; k<bss[j]; k++) {
689:         for (i=0; i<n; i++) {
690:           y[j][i*bss[j] + k] += x[bs*i+jj+k];
691:         }
692:       }
693:       jj += bss[j];
694:     }
695: #if !defined(PETSC_USE_COMPLEX)
696:   } else if (addv == MAX_VALUES) {
697:     for (j=0; j<nv; j++) {
698:       for (k=0; k<bss[j]; k++) {
699:         for (i=0; i<n; i++) {
700:           y[j][i*bss[j] + k] = PetscMax(y[j][i*bss[j] + k],x[bs*i+jj+k]);
701:         }
702:       }
703:       jj += bss[j];
704:     }
705: #endif
706:   } else {
707:     SETERRQ(1,"Unknown insert type");
708:   }

710:   VecRestoreArray(v,&x);
711:   for (i=0; i<nv; i++) {
712:     VecRestoreArray(s[i],&y[i]);
713:   }
714:   PetscFree(y);
715:   PetscFree(bss);
716:   return(0);
717: }

721: /*@
722:    VecStrideScatterAll - Scatters all the single components from seperate vectors into 
723:      a multi-component vector.

725:    Collective on Vec

727:    Input Parameter:
728: +  s - the location where the subvectors are stored
729: -  addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES

731:    Output Parameter:
732: .  v - the multicomponent vector 

734:    Notes:
735:    One must call VecSetBlockSize() before this routine to set the stride 
736:    information, or use a vector created from a multicomponent DA.

738:    The parallel layout of the vector and the subvector must be the same;
739:    i.e., nlocal of v = stride*(nlocal of s) 

741:    Not optimized; could be easily

743:    Level: advanced

745:    Concepts:  scatter^into strided vector

747: .seealso: VecStrideNorm(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideGather(),
748:           VecStrideScatterAll()
749: @*/
750: int VecStrideScatterAll(Vec *s,Vec v,InsertMode addv)
751: {
752:   int          i,n,ierr,bs,j,jj,k,*bss,nv,nvc;
753:   PetscScalar  *x,**y;

758:   VecGetLocalSize(v,&n);
759:   VecGetArray(v,&x);
760:   bs   = v->bs;

762:   PetscMalloc(bs*sizeof(PetscReal*),&y);
763:   PetscMalloc(bs*sizeof(int*),&bss);
764:   nv  = 0;
765:   nvc = 0;
766:   for (i=0; i<bs; i++) {
767:     VecGetBlockSize(s[i],&bss[i]);
768:     if (bss[i] < 1) bss[i] = 1; /* if user never set it then assume 1  Re: [PETSC #8241] VecStrideGatherAll */
769:     VecGetArray(s[i],&y[i]);
770:     nvc  += bss[i];
771:     nv++;
772:     if (nvc > bs)  SETERRQ(1,"Number of subvectors in subvectors > number of vectors in main vector");
773:     if (nvc == bs) break;
774:   }

776:   n =  n/bs;

778:   jj = 0;
779:   if (addv == INSERT_VALUES) {
780:     for (j=0; j<nv; j++) {
781:       for (k=0; k<bss[j]; k++) {
782:         for (i=0; i<n; i++) {
783:           x[bs*i+jj+k] = y[j][i*bss[j] + k];
784:         }
785:       }
786:       jj += bss[j];
787:     }
788:   } else if (addv == ADD_VALUES) {
789:     for (j=0; j<nv; j++) {
790:       for (k=0; k<bss[j]; k++) {
791:         for (i=0; i<n; i++) {
792:           x[bs*i+jj+k] += y[j][i*bss[j] + k];
793:         }
794:       }
795:       jj += bss[j];
796:     }
797: #if !defined(PETSC_USE_COMPLEX)
798:   } else if (addv == MAX_VALUES) {
799:     for (j=0; j<nv; j++) {
800:       for (k=0; k<bss[j]; k++) {
801:         for (i=0; i<n; i++) {
802:           x[bs*i+jj+k] = PetscMax(x[bs*i+jj+k],y[j][i*bss[j] + k]);
803:         }
804:       }
805:       jj += bss[j];
806:     }
807: #endif
808:   } else {
809:     SETERRQ(1,"Unknown insert type");
810:   }

812:   VecRestoreArray(v,&x);
813:   for (i=0; i<nv; i++) {
814:     VecRestoreArray(s[i],&y[i]);
815:   }
816:   PetscFree(y);
817:   PetscFree(bss);
818:   return(0);
819: }

823: /*@
824:    VecStrideGather - Gathers a single component from a multi-component vector into
825:    another vector.

827:    Collective on Vec

829:    Input Parameter:
830: +  v - the vector 
831: .  start - starting point of the subvector (defined by a stride)
832: -  addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES

834:    Output Parameter:
835: .  s - the location where the subvector is stored

837:    Notes:
838:    One must call VecSetBlockSize() before this routine to set the stride 
839:    information, or use a vector created from a multicomponent DA.

841:    If x is the array representing the vector x then this gathers
842:    the array (x[start],x[start+stride],x[start+2*stride], ....)

844:    The parallel layout of the vector and the subvector must be the same;
845:    i.e., nlocal of v = stride*(nlocal of s) 

847:    Not optimized; could be easily

849:    Level: advanced

851:    Concepts: gather^into strided vector

853: .seealso: VecStrideNorm(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideGatherAll(),
854:           VecStrideScatterAll()
855: @*/
856: int VecStrideGather(Vec v,int start,Vec s,InsertMode addv)
857: {
858:   int          i,n,ierr,bs,ns;
859:   PetscScalar  *x,*y;

864:   VecGetLocalSize(v,&n);
865:   VecGetLocalSize(s,&ns);
866:   VecGetArray(v,&x);
867:   VecGetArray(s,&y);

869:   bs   = v->bs;
870:   if (start >= bs) {
871:     SETERRQ2(1,"Start of stride subvector (%d) is too large for stride\n\
872:             Have you set the vector blocksize (%d) correctly with VecSetBlockSize()?",start,bs);
873:   }
874:   if (n != ns*bs) {
875:     SETERRQ2(1,"Subvector length * blocksize %d not correct for gather from original vector %d",ns*bs,n);
876:   }
877:   x += start;
878:   n =  n/bs;

880:   if (addv == INSERT_VALUES) {
881:     for (i=0; i<n; i++) {
882:       y[i] = x[bs*i];
883:     }
884:   } else if (addv == ADD_VALUES) {
885:     for (i=0; i<n; i++) {
886:       y[i] += x[bs*i];
887:     }
888: #if !defined(PETSC_USE_COMPLEX)
889:   } else if (addv == MAX_VALUES) {
890:     for (i=0; i<n; i++) {
891:       y[i] = PetscMax(y[i],x[bs*i]);
892:     }
893: #endif
894:   } else {
895:     SETERRQ(1,"Unknown insert type");
896:   }

898:   VecRestoreArray(v,&x);
899:   VecRestoreArray(s,&y);
900:   return(0);
901: }

905: /*@
906:    VecStrideScatter - Scatters a single component from a vector into a multi-component vector.

908:    Collective on Vec

910:    Input Parameter:
911: +  s - the single-component vector 
912: .  start - starting point of the subvector (defined by a stride)
913: -  addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES

915:    Output Parameter:
916: .  v - the location where the subvector is scattered (the multi-component vector)

918:    Notes:
919:    One must call VecSetBlockSize() on the multi-component vector before this
920:    routine to set the stride  information, or use a vector created from a multicomponent DA.

922:    The parallel layout of the vector and the subvector must be the same;
923:    i.e., nlocal of v = stride*(nlocal of s) 

925:    Not optimized; could be easily

927:    Level: advanced

929:    Concepts: scatter^into strided vector

931: .seealso: VecStrideNorm(), VecStrideGather(), VecStrideMin(), VecStrideMax(), VecStrideGatherAll(),
932:           VecStrideScatterAll()
933: @*/
934: int VecStrideScatter(Vec s,int start,Vec v,InsertMode addv)
935: {
936:   int          i,n,ierr,bs,ns;
937:   PetscScalar  *x,*y;

942:   VecGetLocalSize(v,&n);
943:   VecGetLocalSize(s,&ns);
944:   VecGetArray(v,&x);
945:   VecGetArray(s,&y);

947:   bs   = v->bs;
948:   if (start >= bs) {
949:     SETERRQ2(1,"Start of stride subvector (%d) is too large for stride\n\
950:             Have you set the vector blocksize (%d) correctly with VecSetBlockSize()?",start,bs);
951:   }
952:   if (n != ns*bs) {
953:     SETERRQ2(1,"Subvector length * blocksize %d not correct for scatter to multicomponent vector %d",ns*bs,n);
954:   }
955:   x += start;
956:   n =  n/bs;


959:   if (addv == INSERT_VALUES) {
960:     for (i=0; i<n; i++) {
961:       x[bs*i] = y[i];
962:     }
963:   } else if (addv == ADD_VALUES) {
964:     for (i=0; i<n; i++) {
965:       x[bs*i] += y[i];
966:     }
967: #if !defined(PETSC_USE_COMPLEX)
968:   } else if (addv == MAX_VALUES) {
969:     for (i=0; i<n; i++) {
970:       x[bs*i] = PetscMax(y[i],x[bs*i]);
971:     }
972: #endif
973:   } else {
974:     SETERRQ(1,"Unknown insert type");
975:   }


978:   VecRestoreArray(v,&x);
979:   VecRestoreArray(s,&y);
980:   return(0);
981: }

985: int VecReciprocal_Default(Vec v)
986: {
987:   int         i,n,ierr;
988:   PetscScalar *x;

991:   VecGetLocalSize(v,&n);
992:   VecGetArray(v,&x);
993:   for (i=0; i<n; i++) {
994:     if (x[i] != 0.0) x[i] = 1.0/x[i];
995:   }
996:   VecRestoreArray(v,&x);
997:   return(0);
998: }

1002: /*@
1003:   VecSqrt - Replaces each component of a vector by the square root of its magnitude.

1005:   Not collective

1007:   Input Parameter:
1008: . v - The vector

1010:   Output Parameter:
1011: . v - The vector square root

1013:   Level: beginner

1015:   Note: The actual function is sqrt(|x_i|)

1017: .keywords: vector, sqrt, square root
1018: @*/
1019: int VecSqrt(Vec v)
1020: {
1021:   PetscScalar *x;
1022:   int         i, n;
1023:   int         ierr;

1027:   VecGetLocalSize(v, &n);
1028:   VecGetArray(v, &x);
1029:   for(i = 0; i < n; i++) {
1030:     x[i] = sqrt(PetscAbsScalar(x[i]));
1031:   }
1032:   VecRestoreArray(v, &x);
1033:   return(0);
1034: }

1038: /*@
1039:    VecSum - Computes the sum of all the components of a vector.

1041:    Collective on Vec

1043:    Input Parameter:
1044: .  v - the vector 

1046:    Output Parameter:
1047: .  sum - the result

1049:    Level: beginner

1051:    Concepts: sum^of vector entries

1053: .seealso: VecNorm()
1054: @*/
1055: int VecSum(Vec v,PetscScalar *sum)
1056: {
1057:   int         i,n,ierr;
1058:   PetscScalar *x,lsum = 0.0;

1063:   VecGetLocalSize(v,&n);
1064:   VecGetArray(v,&x);
1065:   for (i=0; i<n; i++) {
1066:     lsum += x[i];
1067:   }
1068:   MPI_Allreduce(&lsum,sum,1,MPIU_SCALAR,PetscSum_Op,v->comm);
1069:   VecRestoreArray(v,&x);
1070:   return(0);
1071: }

1075: /*@
1076:    VecShift - Shifts all of the components of a vector by computing
1077:    x[i] = x[i] + shift.

1079:    Collective on Vec

1081:    Input Parameters:
1082: +  v - the vector 
1083: -  shift - the shift

1085:    Output Parameter:
1086: .  v - the shifted vector 

1088:    Level: intermediate

1090:    Concepts: vector^adding constant

1092: @*/
1093: int VecShift(const PetscScalar *shift,Vec v)
1094: {
1095:   int         i,n,ierr;
1096:   PetscScalar *x,lsum = *shift;

1101:   VecGetLocalSize(v,&n);
1102:   VecGetArray(v,&x);
1103:   for (i=0; i<n; i++) {
1104:     x[i] += lsum;
1105:   }
1106:   VecRestoreArray(v,&x);
1107:   return(0);
1108: }

1112: /*@
1113:    VecAbs - Replaces every element in a vector with its absolute value.

1115:    Collective on Vec

1117:    Input Parameters:
1118: .  v - the vector 

1120:    Level: intermediate

1122:    Concepts: vector^absolute value

1124: @*/
1125: int VecAbs(Vec v)
1126: {
1127:   int         i,n,ierr;
1128:   PetscScalar *x;

1132:   VecGetLocalSize(v,&n);
1133:   VecGetArray(v,&x);
1134:   for (i=0; i<n; i++) {
1135:     x[i] = PetscAbsScalar(x[i]);
1136:   }
1137:   VecRestoreArray(v,&x);
1138:   return(0);
1139: }

1143: /*@
1144:   VecPermute - Permutes a vector in place using the given ordering.

1146:   Input Parameters:
1147: + vec   - The vector
1148: . order - The ordering
1149: - inv   - The flag for inverting the permutation

1151:   Level: beginner

1153:   Note: This function does not yet support parallel Index Sets

1155: .seealso: MatPermute()
1156: .keywords: vec, permute
1157: @*/
1158: int VecPermute(Vec x, IS row, PetscTruth inv)
1159: {
1160:   PetscScalar *array, *newArray;
1161:   int         *idx;
1162:   int          i;
1163:   int          ierr;

1166:   ISGetIndices(row, &idx);
1167:   VecGetArray(x, &array);
1168:   PetscMalloc((x->n+1) * sizeof(PetscScalar), &newArray);
1169: #ifdef PETSC_USE_BOPT_g
1170:   for(i = 0; i < x->n; i++) {
1171:     if ((idx[i] < 0) || (idx[i] >= x->n)) {
1172:       SETERRQ2(PETSC_ERR_ARG_CORRUPT, "Permutation index %d is out of bounds: %d", i, idx[i]);
1173:     }
1174:   }
1175: #endif
1176:   if (inv == PETSC_FALSE) {
1177:     for(i = 0; i < x->n; i++) newArray[i]      = array[idx[i]];
1178:   } else {
1179:     for(i = 0; i < x->n; i++) newArray[idx[i]] = array[i];
1180:   }
1181:   VecRestoreArray(x, &array);
1182:   ISRestoreIndices(row, &idx);
1183:   VecReplaceArray(x, newArray);
1184:   return(0);
1185: }

1189: /*@
1190:    VecEqual - Compares two vectors.

1192:    Collective on Vec

1194:    Input Parameters:
1195: +  vec1 - the first matrix
1196: -  vec2 - the second matrix

1198:    Output Parameter:
1199: .  flg - PETSC_TRUE if the vectors are equal; PETSC_FALSE otherwise.

1201:    Level: intermediate

1203:    Concepts: equal^two vectors
1204:    Concepts: vector^equality

1206: @*/
1207: int VecEqual(Vec vec1,Vec vec2,PetscTruth *flg)
1208: {
1209:   PetscScalar  *v1,*v2;
1210:   int          n1,n2,ierr;
1211:   PetscTruth   flg1;

1214:   VecGetSize(vec1,&n1);
1215:   VecGetSize(vec2,&n2);
1216:   if (vec1 == vec2) {
1217:     flg1 = PETSC_TRUE;
1218:   } else if (n1 != n2) {
1219:     flg1 = PETSC_FALSE;
1220:   } else {
1221:     VecGetArray(vec1,&v1);
1222:     VecGetArray(vec2,&v2);
1223:     PetscMemcmp(v1,v2,n1*sizeof(PetscScalar),&flg1);
1224:     VecRestoreArray(vec1,&v1);
1225:     VecRestoreArray(vec2,&v2);
1226:   }

1228:   /* combine results from all processors */
1229:   MPI_Allreduce(&flg1,flg,1,MPI_INT,MPI_MIN,vec1->comm);
1230: 

1232:   return(0);
1233: }