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: }