Actual source code: rvector.c
1: #define PETSCVEC_DLL
3: /*
4: Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
5: These are the vector functions the user calls.
6: */
7: #include private/vecimpl.h
11: /*@
12: VecMaxPointwiseDivide - Computes the maximum of the componentwise division max = max_i abs(x_i/y_i).
14: Collective on Vec
16: Input Parameters:
17: . x, y - the vectors
19: Output Parameter:
20: . max - the result
22: Level: advanced
24: Notes: any subset of the x and may be the same vector.
25: if a particular y_i is zero, it is treated as 1 in the above formula
27: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
28: @*/
29: PetscErrorCode VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
30: {
40: if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
41: if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
43: (*x->ops->maxpointwisedivide)(x,y,max);
44: return(0);
45: }
49: /*@
50: VecDot - Computes the vector dot product.
52: Collective on Vec
54: Input Parameters:
55: . x, y - the vectors
57: Output Parameter:
58: . val - the dot product
60: Performance Issues:
61: + per-processor memory bandwidth
62: . interprocessor latency
63: - work load inbalance that causes certain processes to arrive much earlier than
64: others
66: Notes for Users of Complex Numbers:
67: For complex vectors, VecDot() computes
68: $ val = (x,y) = y^H x,
69: where y^H denotes the conjugate transpose of y.
71: Use VecTDot() for the indefinite form
72: $ val = (x,y) = y^T x,
73: where y^T denotes the transpose of y.
75: Level: intermediate
77: Concepts: inner product
78: Concepts: vector^inner product
80: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd()
81: @*/
82: PetscErrorCode VecDot(Vec x,Vec y,PetscScalar *val)
83: {
93: if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
94: if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
97: (*x->ops->dot)(x,y,val);
99: return(0);
100: }
104: /*@
105: VecNorm - Computes the vector norm.
107: Collective on Vec
109: Input Parameters:
110: + x - the vector
111: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
112: NORM_1_AND_2, which computes both norms and stores them
113: in a two element array.
115: Output Parameter:
116: . val - the norm
118: Notes:
119: $ NORM_1 denotes sum_i |x_i|
120: $ NORM_2 denotes sqrt(sum_i (x_i)^2)
121: $ NORM_INFINITY denotes max_i |x_i|
123: Level: intermediate
125: Performance Issues:
126: + per-processor memory bandwidth
127: . interprocessor latency
128: - work load inbalance that causes certain processes to arrive much earlier than
129: others
131: Compile Option:
132: PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
133: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
134: (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow.
136: Concepts: norm
137: Concepts: vector^norm
139: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(),
140: VecNormBegin(), VecNormEnd()
142: @*/
143: PetscErrorCode VecNorm(Vec x,NormType type,PetscReal *val)
144: {
145: PetscTruth flg;
153: /*
154: * Cached data?
155: */
156: if (type!=NORM_1_AND_2) {
157: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,flg);
158: if (flg) return(0);
159: }
162: (*x->ops->norm)(x,type,val);
165: if (type!=NORM_1_AND_2) {
166: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
167: }
168: return(0);
169: }
173: /*@
174: VecNormalize - Normalizes a vector by 2-norm.
176: Collective on Vec
178: Input Parameters:
179: + x - the vector
181: Output Parameter:
182: . x - the normalized vector
183: - val - the vector norm before normalization
185: Level: intermediate
187: Concepts: vector^normalizing
188: Concepts: normalizing^vector
190: @*/
191: PetscErrorCode VecNormalize(Vec x,PetscReal *val)
192: {
200: VecNorm(x,NORM_2,val);
201: if (!*val) {
202: PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
203: } else if (*val != 1.0) {
204: PetscScalar tmp = 1.0/(*val);
205: VecScale(x,tmp);
206: }
208: return(0);
209: }
213: /*@C
214: VecMax - Determines the maximum vector component and its location.
216: Collective on Vec
218: Input Parameter:
219: . x - the vector
221: Output Parameters:
222: + val - the maximum component
223: - p - the location of val
225: Notes:
226: Returns the value PETSC_MIN and p = -1 if the vector is of length 0.
228: Level: intermediate
230: Concepts: maximum^of vector
231: Concepts: vector^maximum value
233: .seealso: VecNorm(), VecMin()
234: @*/
235: PetscErrorCode VecMax(Vec x,PetscInt *p,PetscReal *val)
236: {
244: (*x->ops->max)(x,p,val);
246: return(0);
247: }
251: /*@
252: VecMin - Determines the minimum vector component and its location.
254: Collective on Vec
256: Input Parameters:
257: . x - the vector
259: Output Parameter:
260: + val - the minimum component
261: - p - the location of val
263: Level: intermediate
265: Notes:
266: Returns the value PETSC_MAX and p = -1 if the vector is of length 0.
268: Concepts: minimum^of vector
269: Concepts: vector^minimum entry
271: .seealso: VecMax()
272: @*/
273: PetscErrorCode VecMin(Vec x,PetscInt *p,PetscReal *val)
274: {
282: (*x->ops->min)(x,p,val);
284: return(0);
285: }
289: /*@
290: VecTDot - Computes an indefinite vector dot product. That is, this
291: routine does NOT use the complex conjugate.
293: Collective on Vec
295: Input Parameters:
296: . x, y - the vectors
298: Output Parameter:
299: . val - the dot product
301: Notes for Users of Complex Numbers:
302: For complex vectors, VecTDot() computes the indefinite form
303: $ val = (x,y) = y^T x,
304: where y^T denotes the transpose of y.
306: Use VecDot() for the inner product
307: $ val = (x,y) = y^H x,
308: where y^H denotes the conjugate transpose of y.
310: Level: intermediate
312: Concepts: inner product^non-Hermitian
313: Concepts: vector^inner product
314: Concepts: non-Hermitian inner product
316: .seealso: VecDot(), VecMTDot()
317: @*/
318: PetscErrorCode VecTDot(Vec x,Vec y,PetscScalar *val)
319: {
329: if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
330: if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
333: (*x->ops->tdot)(x,y,val);
335: return(0);
336: }
340: /*@
341: VecScale - Scales a vector.
343: Collective on Vec
345: Input Parameters:
346: + x - the vector
347: - alpha - the scalar
349: Output Parameter:
350: . x - the scaled vector
352: Note:
353: For a vector with n components, VecScale() computes
354: $ x[i] = alpha * x[i], for i=1,...,n.
356: Level: intermediate
358: Concepts: vector^scaling
359: Concepts: scaling^vector
361: @*/
362: PetscErrorCode VecScale (Vec x, PetscScalar alpha)
363: {
364: PetscReal norms[4] = {0.0,0.0,0.0, 0.0};
365: PetscTruth flgs[4];
367: PetscInt i;
372: if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
374: (*x->ops->scale)(x,alpha);
376: /*
377: * Update cached data
378: */
379: for (i=0; i<4; i++) {
380: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
381: }
383: /* in general we consider this object touched */
384: PetscObjectStateIncrease((PetscObject)x);
386: for (i=0; i<4; i++) {
387: if (flgs[i]) {
388: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
389: }
390: }
393: return(0);
394: }
399: /*@
400: VecSet - Sets all components of a vector to a single scalar value.
402: Collective on Vec
404: Input Parameters:
405: + x - the vector
406: - alpha - the scalar
408: Output Parameter:
409: . x - the vector
411: Note:
412: For a vector of dimension n, VecSet() computes
413: $ x[i] = alpha, for i=1,...,n,
414: so that all vector entries then equal the identical
415: scalar value, alpha. Use the more general routine
416: VecSetValues() to set different vector entries.
418: You CANNOT call this after you have called VecSetValues() but before you call
419: VecAssemblyBegin/End().
421: Level: beginner
423: .seealso VecSetValues(), VecSetValuesBlocked(), VecSetRandom()
425: Concepts: vector^setting to constant
427: @*/
428: PetscErrorCode VecSet(Vec x,PetscScalar alpha)
429: {
430: PetscReal val;
436: if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"You cannot call this after you have called VecSetValues() but\n before you have called VecAssemblyBegin/End()");
437: #if defined (PETSC_USE_DEBUG)
438: {
439: PetscReal alpha_local,alpha_max;
440: alpha_local = PetscAbsScalar(alpha);
441: MPI_Allreduce(&alpha_local,&alpha_max,1,MPIU_REAL,MPI_MAX,x->comm);
442: if (alpha_local != alpha_max) SETERRQ(PETSC_ERR_ARG_WRONG,"Same value should be used across all processors");
443: }
444: #endif
447: (*x->ops->set)(x,alpha);
450: /*
451: * Update cached data
452: */
453: /* in general we consider this object touched */
454: PetscObjectStateIncrease((PetscObject)x);
456: /* however, norms can be simply set */
457: val = PetscAbsScalar(alpha);
458: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map.N * val);
459: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
460: val = sqrt((double)x->map.N) * val;
461: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
462: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
463: return(0);
464: }
469: /*@
470: VecAXPY - Computes y = alpha x + y.
472: Collective on Vec
474: Input Parameters:
475: + alpha - the scalar
476: - x, y - the vectors
478: Output Parameter:
479: . y - output vector
481: Level: intermediate
483: Concepts: vector^BLAS
484: Concepts: BLAS
486: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY()
487: @*/
488: PetscErrorCode VecAXPY(Vec y,PetscScalar alpha,Vec x)
489: {
498: if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
499: if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
502: (*y->ops->axpy)(y,alpha,x);
504: PetscObjectStateIncrease((PetscObject)y);
505: return(0);
506: }
510: /*@
511: VecAXPBY - Computes y = alpha x + beta y.
513: Collective on Vec
515: Input Parameters:
516: + alpha,beta - the scalars
517: - x, y - the vectors
519: Output Parameter:
520: . y - output vector
522: Level: intermediate
524: Concepts: BLAS
525: Concepts: vector^BLAS
527: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
528: @*/
529: PetscErrorCode VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
530: {
539: if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
540: if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
543: (*y->ops->axpby)(y,alpha,beta,x);
545: PetscObjectStateIncrease((PetscObject)y);
546: return(0);
547: }
551: /*@
552: VecAYPX - Computes y = x + alpha y.
554: Collective on Vec
556: Input Parameters:
557: + alpha - the scalar
558: - x, y - the vectors
560: Output Parameter:
561: . y - output vector
563: Level: intermediate
565: Concepts: vector^BLAS
566: Concepts: BLAS
568: .seealso: VecAXPY(), VecWAXPY()
569: @*/
570: PetscErrorCode VecAYPX(Vec y,PetscScalar alpha,Vec x)
571: {
580: if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
581: if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
584: (*y->ops->aypx)(y,alpha,x);
586: PetscObjectStateIncrease((PetscObject)y);
587: return(0);
588: }
593: /*@
594: VecWAXPY - Computes w = alpha x + y.
596: Collective on Vec
598: Input Parameters:
599: + alpha - the scalar
600: - x, y - the vectors
602: Output Parameter:
603: . w - the result
605: Level: intermediate
607: Concepts: vector^BLAS
608: Concepts: BLAS
610: .seealso: VecAXPY(), VecAYPX(), VecAXPBY()
611: @*/
612: PetscErrorCode VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
613: {
625: if (x->map.N != y->map.N || x->map.N != w->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
626: if (x->map.n != y->map.n || x->map.n != w->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
629: (*w->ops->waxpy)(w,alpha,x,y);
631: PetscObjectStateIncrease((PetscObject)w);
632: return(0);
633: }
638: /*@
639: VecSetValues - Inserts or adds values into certain locations of a vector.
641: Not Collective
643: Input Parameters:
644: + x - vector to insert in
645: . ni - number of elements to add
646: . ix - indices where to add
647: . y - array of values
648: - iora - either INSERT_VALUES or ADD_VALUES, where
649: ADD_VALUES adds values to any existing entries, and
650: INSERT_VALUES replaces existing entries with new values
652: Notes:
653: VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.
655: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
656: options cannot be mixed without intervening calls to the assembly
657: routines.
659: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
660: MUST be called after all calls to VecSetValues() have been completed.
662: VecSetValues() uses 0-based indices in Fortran as well as in C.
664: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES),
665: negative indices may be passed in ix. These rows are
666: simply ignored. This allows easily inserting element load matrices
667: with homogeneous Dirchlet boundary conditions that you don't want represented
668: in the vector.
670: Level: beginner
672: Concepts: vector^setting values
674: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
675: VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
676: @*/
677: PetscErrorCode VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
678: {
687: (*x->ops->setvalues)(x,ni,ix,y,iora);
689: PetscObjectStateIncrease((PetscObject)x);
690: return(0);
691: }
695: /*@
696: VecGetValues - Gets values from certain locations of a vector. Currently
697: can only get values on the same processor
699: Collective on Vec
700:
701: Input Parameters:
702: + x - vector to get values from
703: . ni - number of elements to get
704: - ix - indices where to get them from (in global 1d numbering)
706: Output Parameter:
707: . y - array of values
709: Notes:
710: The user provides the allocated array y; it is NOT allocated in this routine
712: VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.
714: VecAssemblyBegin() and VecAssemblyEnd() MUST be called before calling this
716: VecGetValues() uses 0-based indices in Fortran as well as in C.
718: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES),
719: negative indices may be passed in ix. These rows are
720: simply ignored.
722: Level: beginner
724: Concepts: vector^getting values
726: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecGetValuesLocal(),
727: VecGetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecSetValues()
728: @*/
729: PetscErrorCode VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
730: {
738: (*x->ops->getvalues)(x,ni,ix,y);
739: return(0);
740: }
744: /*@
745: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
747: Not Collective
749: Input Parameters:
750: + x - vector to insert in
751: . ni - number of blocks to add
752: . ix - indices where to add in block count, rather than element count
753: . y - array of values
754: - iora - either INSERT_VALUES or ADD_VALUES, where
755: ADD_VALUES adds values to any existing entries, and
756: INSERT_VALUES replaces existing entries with new values
758: Notes:
759: VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j],
760: for j=0,...,bs, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
762: Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
763: options cannot be mixed without intervening calls to the assembly
764: routines.
766: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
767: MUST be called after all calls to VecSetValuesBlocked() have been completed.
769: VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.
771: Negative indices may be passed in ix, these rows are
772: simply ignored. This allows easily inserting element load matrices
773: with homogeneous Dirchlet boundary conditions that you don't want represented
774: in the vector.
776: Level: intermediate
778: Concepts: vector^setting values blocked
780: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
781: VecSetValues()
782: @*/
783: PetscErrorCode VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
784: {
793: (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
795: PetscObjectStateIncrease((PetscObject)x);
796: return(0);
797: }
802: /*@
803: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
804: using a local ordering of the nodes.
806: Not Collective
808: Input Parameters:
809: + x - vector to insert in
810: . ni - number of elements to add
811: . ix - indices where to add
812: . y - array of values
813: - iora - either INSERT_VALUES or ADD_VALUES, where
814: ADD_VALUES adds values to any existing entries, and
815: INSERT_VALUES replaces existing entries with new values
817: Level: intermediate
819: Notes:
820: VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.
822: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
823: options cannot be mixed without intervening calls to the assembly
824: routines.
826: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
827: MUST be called after all calls to VecSetValuesLocal() have been completed.
829: VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.
831: Concepts: vector^setting values with local numbering
833: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
834: VecSetValuesBlockedLocal()
835: @*/
836: PetscErrorCode VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
837: {
839: PetscInt lixp[128],*lix = lixp;
848: if (!x->ops->setvalueslocal) {
849: if (!x->mapping) {
850: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
851: }
852: if (ni > 128) {
853: PetscMalloc(ni*sizeof(PetscInt),&lix);
854: }
855: ISLocalToGlobalMappingApply(x->mapping,ni,(PetscInt*)ix,lix);
856: (*x->ops->setvalues)(x,ni,lix,y,iora);
857: if (ni > 128) {
858: PetscFree(lix);
859: }
860: } else {
861: (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
862: }
864: PetscObjectStateIncrease((PetscObject)x);
865: return(0);
866: }
870: /*@
871: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
872: using a local ordering of the nodes.
874: Not Collective
876: Input Parameters:
877: + x - vector to insert in
878: . ni - number of blocks to add
879: . ix - indices where to add in block count, not element count
880: . y - array of values
881: - iora - either INSERT_VALUES or ADD_VALUES, where
882: ADD_VALUES adds values to any existing entries, and
883: INSERT_VALUES replaces existing entries with new values
885: Level: intermediate
887: Notes:
888: VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j],
889: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().
891: Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
892: options cannot be mixed without intervening calls to the assembly
893: routines.
895: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
896: MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.
898: VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.
901: Concepts: vector^setting values blocked with local numbering
903: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
904: VecSetLocalToGlobalMappingBlock()
905: @*/
906: PetscErrorCode VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
907: {
909: PetscInt lixp[128],*lix = lixp;
916: if (!x->bmapping) {
917: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMappingBlock()");
918: }
919: if (ni > 128) {
920: PetscMalloc(ni*sizeof(PetscInt),&lix);
921: }
924: ISLocalToGlobalMappingApply(x->bmapping,ni,(PetscInt*)ix,lix);
925: (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
927: if (ni > 128) {
928: PetscFree(lix);
929: }
930: PetscObjectStateIncrease((PetscObject)x);
931: return(0);
932: }
938: /*@
939: VecMTDot - Computes indefinite vector multiple dot products.
940: That is, it does NOT use the complex conjugate.
942: Collective on Vec
944: Input Parameters:
945: + x - one vector
946: . nv - number of vectors
947: - y - array of vectors. Note that vectors are pointers
949: Output Parameter:
950: . val - array of the dot products
952: Notes for Users of Complex Numbers:
953: For complex vectors, VecMTDot() computes the indefinite form
954: $ val = (x,y) = y^T x,
955: where y^T denotes the transpose of y.
957: Use VecMDot() for the inner product
958: $ val = (x,y) = y^H x,
959: where y^H denotes the conjugate transpose of y.
961: Level: intermediate
963: Concepts: inner product^multiple
964: Concepts: vector^multiple inner products
966: .seealso: VecMDot(), VecTDot()
967: @*/
968: PetscErrorCode VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar *val)
969: {
980: if (x->map.N != (*y)->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
981: if (x->map.n != (*y)->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
984: (*x->ops->mtdot)(x,nv,y,val);
986: return(0);
987: }
991: /*@
992: VecMDot - Computes vector multiple dot products.
994: Collective on Vec
996: Input Parameters:
997: + x - one vector
998: . nv - number of vectors
999: - y - array of vectors.
1001: Output Parameter:
1002: . val - array of the dot products
1004: Notes for Users of Complex Numbers:
1005: For complex vectors, VecMDot() computes
1006: $ val = (x,y) = y^H x,
1007: where y^H denotes the conjugate transpose of y.
1009: Use VecMTDot() for the indefinite form
1010: $ val = (x,y) = y^T x,
1011: where y^T denotes the transpose of y.
1013: Level: intermediate
1015: Concepts: inner product^multiple
1016: Concepts: vector^multiple inner products
1018: .seealso: VecMTDot(), VecDot()
1019: @*/
1020: PetscErrorCode VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar *val)
1021: {
1026: if (!nv) return(0);
1027: if (nv < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1034: if (x->map.N != (*y)->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
1035: if (x->map.n != (*y)->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
1038: (*x->ops->mdot)(x,nv,y,val);
1040: return(0);
1041: }
1045: /*@
1046: VecMAXPY - Computes y = y + sum alpha[j] x[j]
1048: Collective on Vec
1050: Input Parameters:
1051: + nv - number of scalars and x-vectors
1052: . alpha - array of scalars
1053: . y - one vector
1054: - x - array of vectors
1056: Level: intermediate
1058: Concepts: BLAS
1060: .seealso: VecAXPY(), VecWAXPY(), VecAYPX()
1061: @*/
1062: PetscErrorCode VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec *x)
1063: {
1068: if (!nv) return(0);
1069: if (nv < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1076: if (y->map.N != (*x)->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
1077: if (y->map.n != (*x)->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
1080: (*y->ops->maxpy)(y,nv,alpha,x);
1082: PetscObjectStateIncrease((PetscObject)y);
1083: return(0);
1084: }
1086: /*MC
1087: VecGetArray - Returns a pointer to a contiguous array that contains this
1088: processor's portion of the vector data. For the standard PETSc
1089: vectors, VecGetArray() returns a pointer to the local data array and
1090: does not use any copies. If the underlying vector data is not stored
1091: in a contiquous array this routine will copy the data to a contiquous
1092: array and return a pointer to that. You MUST call VecRestoreArray()
1093: when you no longer need access to the array.
1095: Synopsis:
1096: PetscErrorCode VecGetArray(Vec x,PetscScalar *a[])
1098: Not Collective
1100: Input Parameter:
1101: . x - the vector
1103: Output Parameter:
1104: . a - location to put pointer to the array
1106: Fortran Note:
1107: This routine is used differently from Fortran 77
1108: $ Vec x
1109: $ PetscScalar x_array(1)
1110: $ PetscOffset i_x
1111: $ PetscErrorCode ierr
1112: $ call VecGetArray(x,x_array,i_x,ierr)
1113: $
1114: $ Access first local entry in vector with
1115: $ value = x_array(i_x + 1)
1116: $
1117: $ ...... other code
1118: $ call VecRestoreArray(x,x_array,i_x,ierr)
1119: For Fortran 90 see VecGetArrayF90()
1121: See the Fortran chapter of the users manual and
1122: petsc/src/snes/examples/tutorials/ex5f.F for details.
1124: Level: beginner
1126: Concepts: vector^accessing local values
1128: .seealso: VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(), VecGetArray2d()
1129: M*/
1132: PetscErrorCode VecGetArray_Private(Vec x,PetscScalar *a[])
1133: {
1140: (*x->ops->getarray)(x,a);
1141: return(0);
1142: }
1147: /*@C
1148: VecGetArrays - Returns a pointer to the arrays in a set of vectors
1149: that were created by a call to VecDuplicateVecs(). You MUST call
1150: VecRestoreArrays() when you no longer need access to the array.
1152: Not Collective
1154: Input Parameter:
1155: + x - the vectors
1156: - n - the number of vectors
1158: Output Parameter:
1159: . a - location to put pointer to the array
1161: Fortran Note:
1162: This routine is not supported in Fortran.
1164: Level: intermediate
1166: .seealso: VecGetArray(), VecRestoreArrays()
1167: @*/
1168: PetscErrorCode VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1169: {
1171: PetscInt i;
1172: PetscScalar **q;
1178: if (n <= 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1179: PetscMalloc(n*sizeof(PetscScalar*),&q);
1180: for (i=0; i<n; ++i) {
1181: VecGetArray(x[i],&q[i]);
1182: }
1183: *a = q;
1184: return(0);
1185: }
1189: /*@C
1190: VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1191: has been called.
1193: Not Collective
1195: Input Parameters:
1196: + x - the vector
1197: . n - the number of vectors
1198: - a - location of pointer to arrays obtained from VecGetArrays()
1200: Notes:
1201: For regular PETSc vectors this routine does not involve any copies. For
1202: any special vectors that do not store local vector data in a contiguous
1203: array, this routine will copy the data back into the underlying
1204: vector data structure from the arrays obtained with VecGetArrays().
1206: Fortran Note:
1207: This routine is not supported in Fortran.
1209: Level: intermediate
1211: .seealso: VecGetArrays(), VecRestoreArray()
1212: @*/
1213: PetscErrorCode VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1214: {
1216: PetscInt i;
1217: PetscScalar **q = *a;
1224: for(i=0;i<n;++i) {
1225: VecRestoreArray(x[i],&q[i]);
1226: }
1227: PetscFree(q);
1228: return(0);
1229: }
1231: /*MC
1232: VecRestoreArray - Restores a vector after VecGetArray() has been called.
1234: Not Collective
1236: Synopsis:
1237: PetscErrorCode VecRestoreArray(Vec x,PetscScalar *a[])
1239: Input Parameters:
1240: + x - the vector
1241: - a - location of pointer to array obtained from VecGetArray()
1243: Level: beginner
1245: Notes:
1246: For regular PETSc vectors this routine does not involve any copies. For
1247: any special vectors that do not store local vector data in a contiguous
1248: array, this routine will copy the data back into the underlying
1249: vector data structure from the array obtained with VecGetArray().
1251: This routine actually zeros out the a pointer. This is to prevent accidental
1252: us of the array after it has been restored. If you pass null for a it will
1253: not zero the array pointer a.
1255: Fortran Note:
1256: This routine is used differently from Fortran 77
1257: $ Vec x
1258: $ PetscScalar x_array(1)
1259: $ PetscOffset i_x
1260: $ PetscErrorCode ierr
1261: $ call VecGetArray(x,x_array,i_x,ierr)
1262: $
1263: $ Access first local entry in vector with
1264: $ value = x_array(i_x + 1)
1265: $
1266: $ ...... other code
1267: $ call VecRestoreArray(x,x_array,i_x,ierr)
1269: See the Fortran chapter of the users manual and
1270: petsc/src/snes/examples/tutorials/ex5f.F for details.
1271: For Fortran 90 see VecRestoreArrayF90()
1273: .seealso: VecGetArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(), VecRestoreArray2d()
1274: M*/
1277: PetscErrorCode VecRestoreArray_Private(Vec x,PetscScalar *a[])
1278: {
1285: #if defined(PETSC_USE_DEBUG)
1286: CHKMEMQ;
1287: #endif
1288: if (x->ops->restorearray) {
1289: (*x->ops->restorearray)(x,a);
1290: }
1291: PetscObjectStateIncrease((PetscObject)x);
1292: return(0);
1293: }
1298: /*@
1299: VecPlaceArray - Allows one to replace the array in a vector with an
1300: array provided by the user. This is useful to avoid copying an array
1301: into a vector.
1303: Not Collective
1305: Input Parameters:
1306: + vec - the vector
1307: - array - the array
1309: Notes:
1310: You can return to the original array with a call to VecResetArray()
1312: Level: developer
1314: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray()
1316: @*/
1317: PetscErrorCode VecPlaceArray(Vec vec,const PetscScalar array[])
1318: {
1325: if (vec->ops->placearray) {
1326: (*vec->ops->placearray)(vec,array);
1327: } else {
1328: SETERRQ(PETSC_ERR_SUP,"Cannot place array in this type of vector");
1329: }
1330: PetscObjectStateIncrease((PetscObject)vec);
1331: return(0);
1332: }
1337: /*@C
1338: VecReplaceArray - Allows one to replace the array in a vector with an
1339: array provided by the user. This is useful to avoid copying an array
1340: into a vector.
1342: Not Collective
1344: Input Parameters:
1345: + vec - the vector
1346: - array - the array
1348: Notes:
1349: This permanently replaces the array and frees the memory associated
1350: with the old array.
1352: The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
1353: freed by the user. It will be freed when the vector is destroy.
1355: Not supported from Fortran
1357: Level: developer
1359: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray()
1361: @*/
1362: PetscErrorCode VecReplaceArray(Vec vec,const PetscScalar array[])
1363: {
1369: if (vec->ops->replacearray) {
1370: (*vec->ops->replacearray)(vec,array);
1371: } else {
1372: SETERRQ(PETSC_ERR_SUP,"Cannot replace array in this type of vector");
1373: }
1374: PetscObjectStateIncrease((PetscObject)vec);
1375: return(0);
1376: }
1378: /*MC
1379: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
1380: and makes them accessible via a Fortran90 pointer.
1382: Synopsis:
1383: VecDuplicateVecsF90(Vec x,int n,{Vec, pointer :: y(:)},integer ierr)
1385: Collective on Vec
1387: Input Parameters:
1388: + x - a vector to mimic
1389: - n - the number of vectors to obtain
1391: Output Parameters:
1392: + y - Fortran90 pointer to the array of vectors
1393: - ierr - error code
1395: Example of Usage:
1396: .vb
1397: Vec x
1398: Vec, pointer :: y(:)
1399: ....
1400: call VecDuplicateVecsF90(x,2,y,ierr)
1401: call VecSet(y(2),alpha,ierr)
1402: call VecSet(y(2),alpha,ierr)
1403: ....
1404: call VecDestroyVecsF90(y,2,ierr)
1405: .ve
1407: Notes:
1408: Not yet supported for all F90 compilers
1410: Use VecDestroyVecsF90() to free the space.
1412: Level: beginner
1414: .seealso: VecDestroyVecsF90(), VecDuplicateVecs()
1416: M*/
1418: /*MC
1419: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
1420: VecGetArrayF90().
1422: Synopsis:
1423: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
1425: Not collective
1427: Input Parameters:
1428: + x - vector
1429: - xx_v - the Fortran90 pointer to the array
1431: Output Parameter:
1432: . ierr - error code
1434: Example of Usage:
1435: .vb
1436: PetscScalar, pointer :: xx_v(:)
1437: ....
1438: call VecGetArrayF90(x,xx_v,ierr)
1439: a = xx_v(3)
1440: call VecRestoreArrayF90(x,xx_v,ierr)
1441: .ve
1442:
1443: Notes:
1444: Not yet supported for all F90 compilers
1446: Level: beginner
1448: .seealso: VecGetArrayF90(), VecGetArray(), VecRestoreArray()
1450: M*/
1452: /*MC
1453: VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().
1455: Synopsis:
1456: VecDestroyVecsF90({Vec, pointer :: x(:)},integer n,integer ierr)
1458: Input Parameters:
1459: + x - pointer to array of vector pointers
1460: - n - the number of vectors previously obtained
1462: Output Parameter:
1463: . ierr - error code
1465: Notes:
1466: Not yet supported for all F90 compilers
1468: Level: beginner
1470: .seealso: VecDestroyVecs(), VecDuplicateVecsF90()
1472: M*/
1474: /*MC
1475: VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
1476: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
1477: this routine is implementation dependent. You MUST call VecRestoreArrayF90()
1478: when you no longer need access to the array.
1480: Synopsis:
1481: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
1483: Not Collective
1485: Input Parameter:
1486: . x - vector
1488: Output Parameters:
1489: + xx_v - the Fortran90 pointer to the array
1490: - ierr - error code
1492: Example of Usage:
1493: .vb
1494: PetscScalar, pointer :: xx_v(:)
1495: ....
1496: call VecGetArrayF90(x,xx_v,ierr)
1497: a = xx_v(3)
1498: call VecRestoreArrayF90(x,xx_v,ierr)
1499: .ve
1501: Notes:
1502: Not yet supported for all F90 compilers
1504: Level: beginner
1506: .seealso: VecRestoreArrayF90(), VecGetArray(), VecRestoreArray()
1508: M*/
1513: /*@C
1514: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
1515: processor's portion of the vector data. You MUST call VecRestoreArray2d()
1516: when you no longer need access to the array.
1518: Not Collective
1520: Input Parameter:
1521: + x - the vector
1522: . m - first dimension of two dimensional array
1523: . n - second dimension of two dimensional array
1524: . mstart - first index you will use in first coordinate direction (often 0)
1525: - nstart - first index in the second coordinate direction (often 0)
1527: Output Parameter:
1528: . a - location to put pointer to the array
1530: Level: developer
1532: Notes:
1533: For a vector obtained from DACreateLocalVector() mstart and nstart are likely
1534: obtained from the corner indices obtained from DAGetGhostCorners() while for
1535: DACreateGlobalVector() they are the corner indices from DAGetCorners(). In both cases
1536: the arguments from DAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
1537:
1538: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
1540: Concepts: vector^accessing local values as 2d array
1542: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1543: VecRestoreArray2d(), DAVecGetArray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1544: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1545: @*/
1546: PetscErrorCode VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1547: {
1549: PetscInt i,N;
1550: PetscScalar *aa;
1556: VecGetLocalSize(x,&N);
1557: if (m*n != N) SETERRQ3(PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
1558: VecGetArray(x,&aa);
1560: PetscMalloc(m*sizeof(PetscScalar*),a);
1561: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
1562: *a -= mstart;
1563: return(0);
1564: }
1568: /*@C
1569: VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.
1571: Not Collective
1573: Input Parameters:
1574: + x - the vector
1575: . m - first dimension of two dimensional array
1576: . n - second dimension of the two dimensional array
1577: . mstart - first index you will use in first coordinate direction (often 0)
1578: . nstart - first index in the second coordinate direction (often 0)
1579: - a - location of pointer to array obtained from VecGetArray2d()
1581: Level: developer
1583: Notes:
1584: For regular PETSc vectors this routine does not involve any copies. For
1585: any special vectors that do not store local vector data in a contiguous
1586: array, this routine will copy the data back into the underlying
1587: vector data structure from the array obtained with VecGetArray().
1589: This routine actually zeros out the a pointer.
1591: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1592: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1593: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1594: @*/
1595: PetscErrorCode VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1596: {
1598: void *dummy;
1604: dummy = (void*)(*a + mstart);
1605: PetscFree(dummy);
1606: VecRestoreArray(x,PETSC_NULL);
1607: return(0);
1608: }
1612: /*@C
1613: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
1614: processor's portion of the vector data. You MUST call VecRestoreArray1d()
1615: when you no longer need access to the array.
1617: Not Collective
1619: Input Parameter:
1620: + x - the vector
1621: . m - first dimension of two dimensional array
1622: - mstart - first index you will use in first coordinate direction (often 0)
1624: Output Parameter:
1625: . a - location to put pointer to the array
1627: Level: developer
1629: Notes:
1630: For a vector obtained from DACreateLocalVector() mstart are likely
1631: obtained from the corner indices obtained from DAGetGhostCorners() while for
1632: DACreateGlobalVector() they are the corner indices from DAGetCorners().
1633:
1634: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
1636: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1637: VecRestoreArray2d(), DAVecGetArray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1638: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1639: @*/
1640: PetscErrorCode VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
1641: {
1643: PetscInt N;
1649: VecGetLocalSize(x,&N);
1650: if (m != N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
1651: VecGetArray(x,a);
1652: *a -= mstart;
1653: return(0);
1654: }
1658: /*@C
1659: VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.
1661: Not Collective
1663: Input Parameters:
1664: + x - the vector
1665: . m - first dimension of two dimensional array
1666: . mstart - first index you will use in first coordinate direction (often 0)
1667: - a - location of pointer to array obtained from VecGetArray21()
1669: Level: developer
1671: Notes:
1672: For regular PETSc vectors this routine does not involve any copies. For
1673: any special vectors that do not store local vector data in a contiguous
1674: array, this routine will copy the data back into the underlying
1675: vector data structure from the array obtained with VecGetArray1d().
1677: This routine actually zeros out the a pointer.
1679: Concepts: vector^accessing local values as 1d array
1681: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1682: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1683: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
1684: @*/
1685: PetscErrorCode VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
1686: {
1692: VecRestoreArray(x,PETSC_NULL);
1693: return(0);
1694: }
1699: /*@C
1700: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
1701: processor's portion of the vector data. You MUST call VecRestoreArray3d()
1702: when you no longer need access to the array.
1704: Not Collective
1706: Input Parameter:
1707: + x - the vector
1708: . m - first dimension of three dimensional array
1709: . n - second dimension of three dimensional array
1710: . p - third dimension of three dimensional array
1711: . mstart - first index you will use in first coordinate direction (often 0)
1712: . nstart - first index in the second coordinate direction (often 0)
1713: - pstart - first index in the third coordinate direction (often 0)
1715: Output Parameter:
1716: . a - location to put pointer to the array
1718: Level: developer
1720: Notes:
1721: For a vector obtained from DACreateLocalVector() mstart, nstart, and pstart are likely
1722: obtained from the corner indices obtained from DAGetGhostCorners() while for
1723: DACreateGlobalVector() they are the corner indices from DAGetCorners(). In both cases
1724: the arguments from DAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
1725:
1726: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
1728: Concepts: vector^accessing local values as 3d array
1730: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1731: VecRestoreArray2d(), DAVecGetarray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1732: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1733: @*/
1734: PetscErrorCode VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
1735: {
1737: PetscInt i,N,j;
1738: PetscScalar *aa,**b;
1744: VecGetLocalSize(x,&N);
1745: if (m*n*p != N) SETERRQ4(PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
1746: VecGetArray(x,&aa);
1748: PetscMalloc(m*sizeof(PetscScalar**)+m*n*sizeof(PetscScalar*),a);
1749: b = (PetscScalar **)((*a) + m);
1750: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
1751: for (i=0; i<m; i++) {
1752: for (j=0; j<n; j++) {
1753: b[i*n+j] = aa + i*n*p + j*p - pstart;
1754: }
1755: }
1756: *a -= mstart;
1757: return(0);
1758: }
1762: /*@C
1763: VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.
1765: Not Collective
1767: Input Parameters:
1768: + x - the vector
1769: . m - first dimension of three dimensional array
1770: . n - second dimension of the three dimensional array
1771: . p - third dimension of the three dimensional array
1772: . mstart - first index you will use in first coordinate direction (often 0)
1773: . nstart - first index in the second coordinate direction (often 0)
1774: . pstart - first index in the third coordinate direction (often 0)
1775: - a - location of pointer to array obtained from VecGetArray3d()
1777: Level: developer
1779: Notes:
1780: For regular PETSc vectors this routine does not involve any copies. For
1781: any special vectors that do not store local vector data in a contiguous
1782: array, this routine will copy the data back into the underlying
1783: vector data structure from the array obtained with VecGetArray().
1785: This routine actually zeros out the a pointer.
1787: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1788: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1789: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
1790: @*/
1791: PetscErrorCode VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
1792: {
1794: void *dummy;
1800: dummy = (void*)(*a + mstart);
1801: PetscFree(dummy);
1802: VecRestoreArray(x,PETSC_NULL);
1803: return(0);
1804: }
1808: /*@C
1809: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
1810: processor's portion of the vector data. You MUST call VecRestoreArray4d()
1811: when you no longer need access to the array.
1813: Not Collective
1815: Input Parameter:
1816: + x - the vector
1817: . m - first dimension of four dimensional array
1818: . n - second dimension of four dimensional array
1819: . p - third dimension of four dimensional array
1820: . q - fourth dimension of four dimensional array
1821: . mstart - first index you will use in first coordinate direction (often 0)
1822: . nstart - first index in the second coordinate direction (often 0)
1823: . pstart - first index in the third coordinate direction (often 0)
1824: - qstart - first index in the fourth coordinate direction (often 0)
1826: Output Parameter:
1827: . a - location to put pointer to the array
1829: Level: beginner
1831: Notes:
1832: For a vector obtained from DACreateLocalVector() mstart, nstart, and pstart are likely
1833: obtained from the corner indices obtained from DAGetGhostCorners() while for
1834: DACreateGlobalVector() they are the corner indices from DAGetCorners(). In both cases
1835: the arguments from DAGet[Ghost}Corners() are reversed in the call to VecGetArray3d().
1836:
1837: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
1839: Concepts: vector^accessing local values as 3d array
1841: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1842: VecRestoreArray2d(), DAVecGetarray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1843: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1844: @*/
1845: PetscErrorCode VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
1846: {
1848: PetscInt i,N,j,k;
1849: PetscScalar *aa,***b,**c;
1855: VecGetLocalSize(x,&N);
1856: if (m*n*p*q != N) SETERRQ5(PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 4d array dimensions %D by %D by %D by %D",N,m,n,p,q);
1857: VecGetArray(x,&aa);
1859: PetscMalloc(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p*sizeof(PetscScalar*),a);
1860: b = (PetscScalar ***)((*a) + m);
1861: c = (PetscScalar **)(b + m*n);
1862: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
1863: for (i=0; i<m; i++) {
1864: for (j=0; j<n; j++) {
1865: b[i*n+j] = c + i*n*p + j*p - pstart;
1866: }
1867: }
1868: for (i=0; i<m; i++) {
1869: for (j=0; j<n; j++) {
1870: for (k=0; k<p; k++) {
1871: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
1872: }
1873: }
1874: }
1875: *a -= mstart;
1876: return(0);
1877: }
1881: /*@C
1882: VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.
1884: Not Collective
1886: Input Parameters:
1887: + x - the vector
1888: . m - first dimension of four dimensional array
1889: . n - second dimension of the four dimensional array
1890: . p - third dimension of the four dimensional array
1891: . q - fourth dimension of the four dimensional array
1892: . mstart - first index you will use in first coordinate direction (often 0)
1893: . nstart - first index in the second coordinate direction (often 0)
1894: . pstart - first index in the third coordinate direction (often 0)
1895: . qstart - first index in the fourth coordinate direction (often 0)
1896: - a - location of pointer to array obtained from VecGetArray4d()
1898: Level: beginner
1900: Notes:
1901: For regular PETSc vectors this routine does not involve any copies. For
1902: any special vectors that do not store local vector data in a contiguous
1903: array, this routine will copy the data back into the underlying
1904: vector data structure from the array obtained with VecGetArray().
1906: This routine actually zeros out the a pointer.
1908: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1909: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1910: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
1911: @*/
1912: PetscErrorCode VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
1913: {
1915: void *dummy;
1921: dummy = (void*)(*a + mstart);
1922: PetscFree(dummy);
1923: VecRestoreArray(x,PETSC_NULL);
1924: return(0);
1925: }