1 /*
2 Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
3 These are the vector functions the user calls.
4 */
5 #include "petsc/private/sfimpl.h"
6 #include <petsc/private/vecimpl.h> /*I "petscvec.h" I*/
7 #if defined(PETSC_HAVE_CUDA)
8 #include <../src/vec/vec/impls/dvecimpl.h>
9 #include <petsc/private/cudavecimpl.h>
10 #endif
11 static PetscInt VecGetSubVectorSavedStateId = -1;
12
VecValidValues(Vec vec,PetscInt argnum,PetscBool begin)13 PETSC_EXTERN PetscErrorCode VecValidValues(Vec vec,PetscInt argnum,PetscBool begin)
14 {
15 #if defined(PETSC_USE_DEBUG)
16 PetscErrorCode ierr;
17 PetscInt n,i;
18 const PetscScalar *x;
19
20 PetscFunctionBegin;
21 #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL)
22 if ((vec->petscnative || vec->ops->getarray) && (vec->offloadmask & PETSC_OFFLOAD_CPU)) {
23 #else
24 if (vec->petscnative || vec->ops->getarray) {
25 #endif
26 ierr = VecGetLocalSize(vec,&n);CHKERRQ(ierr);
27 ierr = VecGetArrayRead(vec,&x);CHKERRQ(ierr);
28 for (i=0; i<n; i++) {
29 if (begin) {
30 if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at beginning of function: Parameter number %D",i,argnum);
31 } else {
32 if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at end of function: Parameter number %D",i,argnum);
33 }
34 }
35 ierr = VecRestoreArrayRead(vec,&x);CHKERRQ(ierr);
36 }
37 #else
38 PetscFunctionBegin;
39 #endif
40 PetscFunctionReturn(0);
41 }
42
43 /*@
44 VecMaxPointwiseDivide - Computes the maximum of the componentwise division max = max_i abs(x_i/y_i).
45
46 Logically Collective on Vec
47
48 Input Parameters:
49 . x, y - the vectors
50
51 Output Parameter:
52 . max - the result
53
54 Level: advanced
55
56 Notes:
57 x and y may be the same vector
58 if a particular y_i is zero, it is treated as 1 in the above formula
59
60 .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
61 @*/
62 PetscErrorCode VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
63 {
64 PetscErrorCode ierr;
65
66 PetscFunctionBegin;
67 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
68 PetscValidHeaderSpecific(y,VEC_CLASSID,2);
69 PetscValidRealPointer(max,3);
70 PetscValidType(x,1);
71 PetscValidType(y,2);
72 PetscCheckSameTypeAndComm(x,1,y,2);
73 VecCheckSameSize(x,1,y,2);
74 ierr = (*x->ops->maxpointwisedivide)(x,y,max);CHKERRQ(ierr);
75 PetscFunctionReturn(0);
76 }
77
78 /*@
79 VecDot - Computes the vector dot product.
80
81 Collective on Vec
82
83 Input Parameters:
84 . x, y - the vectors
85
86 Output Parameter:
87 . val - the dot product
88
89 Performance Issues:
90 $ per-processor memory bandwidth
91 $ interprocessor latency
92 $ work load inbalance that causes certain processes to arrive much earlier than others
93
94 Notes for Users of Complex Numbers:
95 For complex vectors, VecDot() computes
96 $ val = (x,y) = y^H x,
97 where y^H denotes the conjugate transpose of y. Note that this corresponds to the usual "mathematicians" complex
98 inner product where the SECOND argument gets the complex conjugate. Since the BLASdot() complex conjugates the first
99 first argument we call the BLASdot() with the arguments reversed.
100
101 Use VecTDot() for the indefinite form
102 $ val = (x,y) = y^T x,
103 where y^T denotes the transpose of y.
104
105 Level: intermediate
106
107
108 .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDotRealPart()
109 @*/
110 PetscErrorCode VecDot(Vec x,Vec y,PetscScalar *val)
111 {
112 PetscErrorCode ierr;
113
114 PetscFunctionBegin;
115 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
116 PetscValidHeaderSpecific(y,VEC_CLASSID,2);
117 PetscValidScalarPointer(val,3);
118 PetscValidType(x,1);
119 PetscValidType(y,2);
120 PetscCheckSameTypeAndComm(x,1,y,2);
121 VecCheckSameSize(x,1,y,2);
122
123 ierr = PetscLogEventBegin(VEC_Dot,x,y,0,0);CHKERRQ(ierr);
124 ierr = (*x->ops->dot)(x,y,val);CHKERRQ(ierr);
125 ierr = PetscLogEventEnd(VEC_Dot,x,y,0,0);CHKERRQ(ierr);
126 PetscFunctionReturn(0);
127 }
128
129 /*@
130 VecDotRealPart - Computes the real part of the vector dot product.
131
132 Collective on Vec
133
134 Input Parameters:
135 . x, y - the vectors
136
137 Output Parameter:
138 . val - the real part of the dot product;
139
140 Performance Issues:
141 $ per-processor memory bandwidth
142 $ interprocessor latency
143 $ work load inbalance that causes certain processes to arrive much earlier than others
144
145 Notes for Users of Complex Numbers:
146 See VecDot() for more details on the definition of the dot product for complex numbers
147
148 For real numbers this returns the same value as VecDot()
149
150 For complex numbers in C^n (that is a vector of n components with a complex number for each component) this is equal to the usual real dot product on the
151 the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)
152
153 Developer Note: This is not currently optimized to compute only the real part of the dot product.
154
155 Level: intermediate
156
157
158 .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDot(), VecDotNorm2()
159 @*/
160 PetscErrorCode VecDotRealPart(Vec x,Vec y,PetscReal *val)
161 {
162 PetscErrorCode ierr;
163 PetscScalar fdot;
164
165 PetscFunctionBegin;
166 ierr = VecDot(x,y,&fdot);CHKERRQ(ierr);
167 *val = PetscRealPart(fdot);
168 PetscFunctionReturn(0);
169 }
170
171 /*@
172 VecNorm - Computes the vector norm.
173
174 Collective on Vec
175
176 Input Parameters:
177 + x - the vector
178 - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
179 NORM_1_AND_2, which computes both norms and stores them
180 in a two element array.
181
182 Output Parameter:
183 . val - the norm
184
185 Notes:
186 $ NORM_1 denotes sum_i |x_i|
187 $ NORM_2 denotes sqrt(sum_i |x_i|^2)
188 $ NORM_INFINITY denotes max_i |x_i|
189
190 For complex numbers NORM_1 will return the traditional 1 norm of the 2 norm of the complex numbers; that is the 1
191 norm of the absolutely values of the complex entries. In PETSc 3.6 and earlier releases it returned the 1 norm of
192 the 1 norm of the complex entries (what is returned by the BLAS routine asum()). Both are valid norms but most
193 people expect the former.
194
195 Level: intermediate
196
197 Performance Issues:
198 $ per-processor memory bandwidth
199 $ interprocessor latency
200 $ work load inbalance that causes certain processes to arrive much earlier than others
201
202
203 .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
204 VecNormBegin(), VecNormEnd()
205
206 @*/
207
208 PetscErrorCode VecNorm(Vec x,NormType type,PetscReal *val)
209 {
210 PetscBool flg;
211 PetscErrorCode ierr;
212
213 PetscFunctionBegin;
214 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
215 PetscValidRealPointer(val,3);
216 PetscValidType(x,1);
217
218 /*
219 * Cached data?
220 */
221 if (type!=NORM_1_AND_2) {
222 ierr = PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,flg);CHKERRQ(ierr);
223 if (flg) PetscFunctionReturn(0);
224 }
225 ierr = PetscLogEventBegin(VEC_Norm,x,0,0,0);CHKERRQ(ierr);
226 ierr = (*x->ops->norm)(x,type,val);CHKERRQ(ierr);
227 ierr = PetscLogEventEnd(VEC_Norm,x,0,0,0);CHKERRQ(ierr);
228 if (type!=NORM_1_AND_2) {
229 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);CHKERRQ(ierr);
230 }
231 PetscFunctionReturn(0);
232 }
233
234 /*@
235 VecNormAvailable - Returns the vector norm if it is already known.
236
237 Not Collective
238
239 Input Parameters:
240 + x - the vector
241 - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
242 NORM_1_AND_2, which computes both norms and stores them
243 in a two element array.
244
245 Output Parameter:
246 + available - PETSC_TRUE if the val returned is valid
247 - val - the norm
248
249 Notes:
250 $ NORM_1 denotes sum_i |x_i|
251 $ NORM_2 denotes sqrt(sum_i (x_i)^2)
252 $ NORM_INFINITY denotes max_i |x_i|
253
254 Level: intermediate
255
256 Performance Issues:
257 $ per-processor memory bandwidth
258 $ interprocessor latency
259 $ work load inbalance that causes certain processes to arrive much earlier than others
260
261 Compile Option:
262 PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
263 than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
264 (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow.
265
266
267 .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
268 VecNormBegin(), VecNormEnd()
269
270 @*/
271 PetscErrorCode VecNormAvailable(Vec x,NormType type,PetscBool *available,PetscReal *val)
272 {
273 PetscErrorCode ierr;
274
275 PetscFunctionBegin;
276 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
277 PetscValidRealPointer(val,3);
278 PetscValidType(x,1);
279
280 *available = PETSC_FALSE;
281 if (type!=NORM_1_AND_2) {
282 ierr = PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,*available);CHKERRQ(ierr);
283 }
284 PetscFunctionReturn(0);
285 }
286
287 /*@
288 VecNormalize - Normalizes a vector by 2-norm.
289
290 Collective on Vec
291
292 Input Parameters:
293 + x - the vector
294
295 Output Parameter:
296 . x - the normalized vector
297 - val - the vector norm before normalization
298
299 Level: intermediate
300
301
302 @*/
303 PetscErrorCode VecNormalize(Vec x,PetscReal *val)
304 {
305 PetscErrorCode ierr;
306 PetscReal norm;
307
308 PetscFunctionBegin;
309 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
310 PetscValidType(x,1);
311 ierr = PetscLogEventBegin(VEC_Normalize,x,0,0,0);CHKERRQ(ierr);
312 ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr);
313 if (norm == 0.0) {
314 ierr = PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");CHKERRQ(ierr);
315 } else if (norm != 1.0) {
316 PetscScalar tmp = 1.0/norm;
317 ierr = VecScale(x,tmp);CHKERRQ(ierr);
318 }
319 if (val) *val = norm;
320 ierr = PetscLogEventEnd(VEC_Normalize,x,0,0,0);CHKERRQ(ierr);
321 PetscFunctionReturn(0);
322 }
323
324 /*@C
325 VecMax - Determines the vector component with maximum real part and its location.
326
327 Collective on Vec
328
329 Input Parameter:
330 . x - the vector
331
332 Output Parameters:
333 + p - the location of val (pass NULL if you don't want this)
334 - val - the maximum component
335
336 Notes:
337 Returns the value PETSC_MIN_REAL and p = -1 if the vector is of length 0.
338
339 Returns the smallest index with the maximum value
340 Level: intermediate
341
342
343 .seealso: VecNorm(), VecMin()
344 @*/
345 PetscErrorCode VecMax(Vec x,PetscInt *p,PetscReal *val)
346 {
347 PetscErrorCode ierr;
348
349 PetscFunctionBegin;
350 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
351 PetscValidScalarPointer(val,3);
352 PetscValidType(x,1);
353 ierr = PetscLogEventBegin(VEC_Max,x,0,0,0);CHKERRQ(ierr);
354 ierr = (*x->ops->max)(x,p,val);CHKERRQ(ierr);
355 ierr = PetscLogEventEnd(VEC_Max,x,0,0,0);CHKERRQ(ierr);
356 PetscFunctionReturn(0);
357 }
358
359 /*@C
360 VecMin - Determines the vector component with minimum real part and its location.
361
362 Collective on Vec
363
364 Input Parameters:
365 . x - the vector
366
367 Output Parameter:
368 + p - the location of val (pass NULL if you don't want this location)
369 - val - the minimum component
370
371 Level: intermediate
372
373 Notes:
374 Returns the value PETSC_MAX_REAL and p = -1 if the vector is of length 0.
375
376 This returns the smallest index with the minumum value
377
378
379 .seealso: VecMax()
380 @*/
381 PetscErrorCode VecMin(Vec x,PetscInt *p,PetscReal *val)
382 {
383 PetscErrorCode ierr;
384
385 PetscFunctionBegin;
386 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
387 PetscValidScalarPointer(val,3);
388 PetscValidType(x,1);
389 ierr = PetscLogEventBegin(VEC_Min,x,0,0,0);CHKERRQ(ierr);
390 ierr = (*x->ops->min)(x,p,val);CHKERRQ(ierr);
391 ierr = PetscLogEventEnd(VEC_Min,x,0,0,0);CHKERRQ(ierr);
392 PetscFunctionReturn(0);
393 }
394
395 /*@
396 VecTDot - Computes an indefinite vector dot product. That is, this
397 routine does NOT use the complex conjugate.
398
399 Collective on Vec
400
401 Input Parameters:
402 . x, y - the vectors
403
404 Output Parameter:
405 . val - the dot product
406
407 Notes for Users of Complex Numbers:
408 For complex vectors, VecTDot() computes the indefinite form
409 $ val = (x,y) = y^T x,
410 where y^T denotes the transpose of y.
411
412 Use VecDot() for the inner product
413 $ val = (x,y) = y^H x,
414 where y^H denotes the conjugate transpose of y.
415
416 Level: intermediate
417
418 .seealso: VecDot(), VecMTDot()
419 @*/
420 PetscErrorCode VecTDot(Vec x,Vec y,PetscScalar *val)
421 {
422 PetscErrorCode ierr;
423
424 PetscFunctionBegin;
425 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
426 PetscValidHeaderSpecific(y,VEC_CLASSID,2);
427 PetscValidScalarPointer(val,3);
428 PetscValidType(x,1);
429 PetscValidType(y,2);
430 PetscCheckSameTypeAndComm(x,1,y,2);
431 VecCheckSameSize(x,1,y,2);
432
433 ierr = PetscLogEventBegin(VEC_TDot,x,y,0,0);CHKERRQ(ierr);
434 ierr = (*x->ops->tdot)(x,y,val);CHKERRQ(ierr);
435 ierr = PetscLogEventEnd(VEC_TDot,x,y,0,0);CHKERRQ(ierr);
436 PetscFunctionReturn(0);
437 }
438
439 /*@
440 VecScale - Scales a vector.
441
442 Not collective on Vec
443
444 Input Parameters:
445 + x - the vector
446 - alpha - the scalar
447
448 Output Parameter:
449 . x - the scaled vector
450
451 Note:
452 For a vector with n components, VecScale() computes
453 $ x[i] = alpha * x[i], for i=1,...,n.
454
455 Level: intermediate
456
457
458 @*/
459 PetscErrorCode VecScale(Vec x, PetscScalar alpha)
460 {
461 PetscReal norms[4] = {0.0,0.0,0.0, 0.0};
462 PetscBool flgs[4];
463 PetscErrorCode ierr;
464 PetscInt i;
465
466 PetscFunctionBegin;
467 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
468 PetscValidType(x,1);
469 if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
470 ierr = PetscLogEventBegin(VEC_Scale,x,0,0,0);CHKERRQ(ierr);
471 if (alpha != (PetscScalar)1.0) {
472 ierr = VecSetErrorIfLocked(x,1);CHKERRQ(ierr);
473 /* get current stashed norms */
474 for (i=0; i<4; i++) {
475 ierr = PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);CHKERRQ(ierr);
476 }
477 ierr = (*x->ops->scale)(x,alpha);CHKERRQ(ierr);
478 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
479 /* put the scaled stashed norms back into the Vec */
480 for (i=0; i<4; i++) {
481 if (flgs[i]) {
482 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);CHKERRQ(ierr);
483 }
484 }
485 }
486 ierr = PetscLogEventEnd(VEC_Scale,x,0,0,0);CHKERRQ(ierr);
487 PetscFunctionReturn(0);
488 }
489
490 /*@
491 VecSet - Sets all components of a vector to a single scalar value.
492
493 Logically Collective on Vec
494
495 Input Parameters:
496 + x - the vector
497 - alpha - the scalar
498
499 Output Parameter:
500 . x - the vector
501
502 Note:
503 For a vector of dimension n, VecSet() computes
504 $ x[i] = alpha, for i=1,...,n,
505 so that all vector entries then equal the identical
506 scalar value, alpha. Use the more general routine
507 VecSetValues() to set different vector entries.
508
509 You CANNOT call this after you have called VecSetValues() but before you call
510 VecAssemblyBegin/End().
511
512 Level: beginner
513
514 .seealso VecSetValues(), VecSetValuesBlocked(), VecSetRandom()
515
516 @*/
517 PetscErrorCode VecSet(Vec x,PetscScalar alpha)
518 {
519 PetscReal val;
520 PetscErrorCode ierr;
521
522 PetscFunctionBegin;
523 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
524 PetscValidType(x,1);
525 if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"You cannot call this after you have called VecSetValues() but\n before you have called VecAssemblyBegin/End()");
526 PetscValidLogicalCollectiveScalar(x,alpha,2);
527 ierr = VecSetErrorIfLocked(x,1);CHKERRQ(ierr);
528
529 ierr = PetscLogEventBegin(VEC_Set,x,0,0,0);CHKERRQ(ierr);
530 ierr = (*x->ops->set)(x,alpha);CHKERRQ(ierr);
531 ierr = PetscLogEventEnd(VEC_Set,x,0,0,0);CHKERRQ(ierr);
532 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
533
534 /* norms can be simply set (if |alpha|*N not too large) */
535 val = PetscAbsScalar(alpha);
536 if (x->map->N == 0) {
537 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],0.0l);CHKERRQ(ierr);
538 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],0.0);CHKERRQ(ierr);
539 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],0.0);CHKERRQ(ierr);
540 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],0.0);CHKERRQ(ierr);
541 } else if (val > PETSC_MAX_REAL/x->map->N) {
542 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);CHKERRQ(ierr);
543 } else {
544 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map->N * val);CHKERRQ(ierr);
545 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);CHKERRQ(ierr);
546 val = PetscSqrtReal((PetscReal)x->map->N) * val;
547 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);CHKERRQ(ierr);
548 ierr = PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);CHKERRQ(ierr);
549 }
550 PetscFunctionReturn(0);
551 }
552
553
554 /*@
555 VecAXPY - Computes y = alpha x + y.
556
557 Logically Collective on Vec
558
559 Input Parameters:
560 + alpha - the scalar
561 - x, y - the vectors
562
563 Output Parameter:
564 . y - output vector
565
566 Level: intermediate
567
568 Notes:
569 x and y MUST be different vectors
570 This routine is optimized for alpha of 0.0, otherwise it calls the BLAS routine
571
572 $ VecAXPY(y,alpha,x) y = alpha x + y
573 $ VecAYPX(y,beta,x) y = x + beta y
574 $ VecAXPBY(y,alpha,beta,x) y = alpha x + beta y
575 $ VecWAXPY(w,alpha,x,y) w = alpha x + y
576 $ VecAXPBYPCZ(w,alpha,beta,gamma,x,y) z = alpha x + beta y + gamma z
577 $ VecMAXPY(y,nv,alpha[],x[]) y = sum alpha[i] x[i] + y
578
579
580 .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPBYPCZ(), VecAXPBY()
581 @*/
582 PetscErrorCode VecAXPY(Vec y,PetscScalar alpha,Vec x)
583 {
584 PetscErrorCode ierr;
585
586 PetscFunctionBegin;
587 PetscValidHeaderSpecific(x,VEC_CLASSID,3);
588 PetscValidHeaderSpecific(y,VEC_CLASSID,1);
589 PetscValidType(x,3);
590 PetscValidType(y,1);
591 PetscCheckSameTypeAndComm(x,3,y,1);
592 VecCheckSameSize(x,1,y,3);
593 if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
594 PetscValidLogicalCollectiveScalar(y,alpha,2);
595 if (alpha == (PetscScalar)0.0) PetscFunctionReturn(0);
596 ierr = VecSetErrorIfLocked(y,1);CHKERRQ(ierr);
597
598 ierr = VecLockReadPush(x);CHKERRQ(ierr);
599 ierr = PetscLogEventBegin(VEC_AXPY,x,y,0,0);CHKERRQ(ierr);
600 ierr = (*y->ops->axpy)(y,alpha,x);CHKERRQ(ierr);
601 ierr = PetscLogEventEnd(VEC_AXPY,x,y,0,0);CHKERRQ(ierr);
602 ierr = VecLockReadPop(x);CHKERRQ(ierr);
603 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
604 PetscFunctionReturn(0);
605 }
606
607 /*@
608 VecAXPBY - Computes y = alpha x + beta y.
609
610 Logically Collective on Vec
611
612 Input Parameters:
613 + alpha,beta - the scalars
614 - x, y - the vectors
615
616 Output Parameter:
617 . y - output vector
618
619 Level: intermediate
620
621 Notes:
622 x and y MUST be different vectors
623 The implementation is optimized for alpha and/or beta values of 0.0 and 1.0
624
625
626 .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ()
627 @*/
628 PetscErrorCode VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
629 {
630 PetscErrorCode ierr;
631
632 PetscFunctionBegin;
633 PetscValidHeaderSpecific(x,VEC_CLASSID,4);
634 PetscValidHeaderSpecific(y,VEC_CLASSID,1);
635 PetscValidType(x,4);
636 PetscValidType(y,1);
637 PetscCheckSameTypeAndComm(x,4,y,1);
638 VecCheckSameSize(y,1,x,4);
639 if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
640 PetscValidLogicalCollectiveScalar(y,alpha,2);
641 PetscValidLogicalCollectiveScalar(y,beta,3);
642 if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)1.0) PetscFunctionReturn(0);
643 ierr = VecSetErrorIfLocked(y,1);CHKERRQ(ierr);
644 ierr = PetscLogEventBegin(VEC_AXPY,x,y,0,0);CHKERRQ(ierr);
645 ierr = (*y->ops->axpby)(y,alpha,beta,x);CHKERRQ(ierr);
646 ierr = PetscLogEventEnd(VEC_AXPY,x,y,0,0);CHKERRQ(ierr);
647 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
648 PetscFunctionReturn(0);
649 }
650
651 /*@
652 VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z
653
654 Logically Collective on Vec
655
656 Input Parameters:
657 + alpha,beta, gamma - the scalars
658 - x, y, z - the vectors
659
660 Output Parameter:
661 . z - output vector
662
663 Level: intermediate
664
665 Notes:
666 x, y and z must be different vectors
667 The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0
668
669
670 .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBY()
671 @*/
672 PetscErrorCode VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
673 {
674 PetscErrorCode ierr;
675
676 PetscFunctionBegin;
677 PetscValidHeaderSpecific(x,VEC_CLASSID,5);
678 PetscValidHeaderSpecific(y,VEC_CLASSID,6);
679 PetscValidHeaderSpecific(z,VEC_CLASSID,1);
680 PetscValidType(x,5);
681 PetscValidType(y,6);
682 PetscValidType(z,1);
683 PetscCheckSameTypeAndComm(x,5,y,6);
684 PetscCheckSameTypeAndComm(x,5,z,1);
685 VecCheckSameSize(x,1,y,5);
686 VecCheckSameSize(x,1,z,6);
687 if (x == y || x == z) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
688 if (y == z) SETERRQ(PetscObjectComm((PetscObject)y),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
689 PetscValidLogicalCollectiveScalar(z,alpha,2);
690 PetscValidLogicalCollectiveScalar(z,beta,3);
691 PetscValidLogicalCollectiveScalar(z,gamma,4);
692 if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)0.0 && gamma == (PetscScalar)1.0) PetscFunctionReturn(0);
693 ierr = VecSetErrorIfLocked(z,1);CHKERRQ(ierr);
694
695 ierr = PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);CHKERRQ(ierr);
696 ierr = (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);CHKERRQ(ierr);
697 ierr = PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);CHKERRQ(ierr);
698 ierr = PetscObjectStateIncrease((PetscObject)z);CHKERRQ(ierr);
699 PetscFunctionReturn(0);
700 }
701
702 /*@
703 VecAYPX - Computes y = x + beta y.
704
705 Logically Collective on Vec
706
707 Input Parameters:
708 + beta - the scalar
709 - x, y - the vectors
710
711 Output Parameter:
712 . y - output vector
713
714 Level: intermediate
715
716 Notes:
717 x and y MUST be different vectors
718 The implementation is optimized for beta of -1.0, 0.0, and 1.0
719
720
721 .seealso: VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
722 @*/
723 PetscErrorCode VecAYPX(Vec y,PetscScalar beta,Vec x)
724 {
725 PetscErrorCode ierr;
726
727 PetscFunctionBegin;
728 PetscValidHeaderSpecific(x,VEC_CLASSID,3);
729 PetscValidHeaderSpecific(y,VEC_CLASSID,1);
730 PetscValidType(x,3);
731 PetscValidType(y,1);
732 PetscCheckSameTypeAndComm(x,3,y,1);
733 VecCheckSameSize(x,1,y,3);
734 if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
735 PetscValidLogicalCollectiveScalar(y,beta,2);
736 ierr = VecSetErrorIfLocked(y,1);CHKERRQ(ierr);
737
738 ierr = PetscLogEventBegin(VEC_AYPX,x,y,0,0);CHKERRQ(ierr);
739 ierr = (*y->ops->aypx)(y,beta,x);CHKERRQ(ierr);
740 ierr = PetscLogEventEnd(VEC_AYPX,x,y,0,0);CHKERRQ(ierr);
741 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
742 PetscFunctionReturn(0);
743 }
744
745
746 /*@
747 VecWAXPY - Computes w = alpha x + y.
748
749 Logically Collective on Vec
750
751 Input Parameters:
752 + alpha - the scalar
753 - x, y - the vectors
754
755 Output Parameter:
756 . w - the result
757
758 Level: intermediate
759
760 Notes:
761 w cannot be either x or y, but x and y can be the same
762 The implementation is optimzed for alpha of -1.0, 0.0, and 1.0
763
764
765 .seealso: VecAXPY(), VecAYPX(), VecAXPBY(), VecMAXPY(), VecAXPBYPCZ()
766 @*/
767 PetscErrorCode VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
768 {
769 PetscErrorCode ierr;
770
771 PetscFunctionBegin;
772 PetscValidHeaderSpecific(w,VEC_CLASSID,1);
773 PetscValidHeaderSpecific(x,VEC_CLASSID,3);
774 PetscValidHeaderSpecific(y,VEC_CLASSID,4);
775 PetscValidType(w,1);
776 PetscValidType(x,3);
777 PetscValidType(y,4);
778 PetscCheckSameTypeAndComm(x,3,y,4);
779 PetscCheckSameTypeAndComm(y,4,w,1);
780 VecCheckSameSize(x,3,y,4);
781 VecCheckSameSize(x,3,w,1);
782 if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
783 if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");
784 PetscValidLogicalCollectiveScalar(y,alpha,2);
785 ierr = VecSetErrorIfLocked(w,1);CHKERRQ(ierr);
786
787 ierr = PetscLogEventBegin(VEC_WAXPY,x,y,w,0);CHKERRQ(ierr);
788 ierr = (*w->ops->waxpy)(w,alpha,x,y);CHKERRQ(ierr);
789 ierr = PetscLogEventEnd(VEC_WAXPY,x,y,w,0);CHKERRQ(ierr);
790 ierr = PetscObjectStateIncrease((PetscObject)w);CHKERRQ(ierr);
791 PetscFunctionReturn(0);
792 }
793
794
795 /*@C
796 VecSetValues - Inserts or adds values into certain locations of a vector.
797
798 Not Collective
799
800 Input Parameters:
801 + x - vector to insert in
802 . ni - number of elements to add
803 . ix - indices where to add
804 . y - array of values
805 - iora - either INSERT_VALUES or ADD_VALUES, where
806 ADD_VALUES adds values to any existing entries, and
807 INSERT_VALUES replaces existing entries with new values
808
809 Notes:
810 VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.
811
812 Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
813 options cannot be mixed without intervening calls to the assembly
814 routines.
815
816 These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
817 MUST be called after all calls to VecSetValues() have been completed.
818
819 VecSetValues() uses 0-based indices in Fortran as well as in C.
820
821 If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
822 negative indices may be passed in ix. These rows are
823 simply ignored. This allows easily inserting element load matrices
824 with homogeneous Dirchlet boundary conditions that you don't want represented
825 in the vector.
826
827 Level: beginner
828
829 .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
830 VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
831 @*/
832 PetscErrorCode VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
833 {
834 PetscErrorCode ierr;
835
836 PetscFunctionBeginHot;
837 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
838 if (!ni) PetscFunctionReturn(0);
839 PetscValidIntPointer(ix,3);
840 PetscValidScalarPointer(y,4);
841 PetscValidType(x,1);
842
843 ierr = PetscLogEventBegin(VEC_SetValues,x,0,0,0);CHKERRQ(ierr);
844 ierr = (*x->ops->setvalues)(x,ni,ix,y,iora);CHKERRQ(ierr);
845 ierr = PetscLogEventEnd(VEC_SetValues,x,0,0,0);CHKERRQ(ierr);
846 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
847 PetscFunctionReturn(0);
848 }
849
850 /*@C
851 VecGetValues - Gets values from certain locations of a vector. Currently
852 can only get values on the same processor
853
854 Not Collective
855
856 Input Parameters:
857 + x - vector to get values from
858 . ni - number of elements to get
859 - ix - indices where to get them from (in global 1d numbering)
860
861 Output Parameter:
862 . y - array of values
863
864 Notes:
865 The user provides the allocated array y; it is NOT allocated in this routine
866
867 VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.
868
869 VecAssemblyBegin() and VecAssemblyEnd() MUST be called before calling this
870
871 VecGetValues() uses 0-based indices in Fortran as well as in C.
872
873 If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
874 negative indices may be passed in ix. These rows are
875 simply ignored.
876
877 Level: beginner
878
879 .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues()
880 @*/
881 PetscErrorCode VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
882 {
883 PetscErrorCode ierr;
884
885 PetscFunctionBegin;
886 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
887 if (!ni) PetscFunctionReturn(0);
888 PetscValidIntPointer(ix,3);
889 PetscValidScalarPointer(y,4);
890 PetscValidType(x,1);
891 ierr = (*x->ops->getvalues)(x,ni,ix,y);CHKERRQ(ierr);
892 PetscFunctionReturn(0);
893 }
894
895 /*@C
896 VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
897
898 Not Collective
899
900 Input Parameters:
901 + x - vector to insert in
902 . ni - number of blocks to add
903 . ix - indices where to add in block count, rather than element count
904 . y - array of values
905 - iora - either INSERT_VALUES or ADD_VALUES, where
906 ADD_VALUES adds values to any existing entries, and
907 INSERT_VALUES replaces existing entries with new values
908
909 Notes:
910 VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j],
911 for j=0,...,bs-1, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
912
913 Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
914 options cannot be mixed without intervening calls to the assembly
915 routines.
916
917 These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
918 MUST be called after all calls to VecSetValuesBlocked() have been completed.
919
920 VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.
921
922 Negative indices may be passed in ix, these rows are
923 simply ignored. This allows easily inserting element load matrices
924 with homogeneous Dirchlet boundary conditions that you don't want represented
925 in the vector.
926
927 Level: intermediate
928
929 .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
930 VecSetValues()
931 @*/
932 PetscErrorCode VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
933 {
934 PetscErrorCode ierr;
935
936 PetscFunctionBeginHot;
937 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
938 if (!ni) PetscFunctionReturn(0);
939 PetscValidIntPointer(ix,3);
940 PetscValidScalarPointer(y,4);
941 PetscValidType(x,1);
942
943 ierr = PetscLogEventBegin(VEC_SetValues,x,0,0,0);CHKERRQ(ierr);
944 ierr = (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);CHKERRQ(ierr);
945 ierr = PetscLogEventEnd(VEC_SetValues,x,0,0,0);CHKERRQ(ierr);
946 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
947 PetscFunctionReturn(0);
948 }
949
950
951 /*@C
952 VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
953 using a local ordering of the nodes.
954
955 Not Collective
956
957 Input Parameters:
958 + x - vector to insert in
959 . ni - number of elements to add
960 . ix - indices where to add
961 . y - array of values
962 - iora - either INSERT_VALUES or ADD_VALUES, where
963 ADD_VALUES adds values to any existing entries, and
964 INSERT_VALUES replaces existing entries with new values
965
966 Level: intermediate
967
968 Notes:
969 VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.
970
971 Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
972 options cannot be mixed without intervening calls to the assembly
973 routines.
974
975 These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
976 MUST be called after all calls to VecSetValuesLocal() have been completed.
977
978 VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.
979
980 .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
981 VecSetValuesBlockedLocal()
982 @*/
983 PetscErrorCode VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
984 {
985 PetscErrorCode ierr;
986 PetscInt lixp[128],*lix = lixp;
987
988 PetscFunctionBeginHot;
989 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
990 if (!ni) PetscFunctionReturn(0);
991 PetscValidIntPointer(ix,3);
992 PetscValidScalarPointer(y,4);
993 PetscValidType(x,1);
994
995 ierr = PetscLogEventBegin(VEC_SetValues,x,0,0,0);CHKERRQ(ierr);
996 if (!x->ops->setvalueslocal) {
997 if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
998 if (ni > 128) {
999 ierr = PetscMalloc1(ni,&lix);CHKERRQ(ierr);
1000 }
1001 ierr = ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);CHKERRQ(ierr);
1002 ierr = (*x->ops->setvalues)(x,ni,lix,y,iora);CHKERRQ(ierr);
1003 if (ni > 128) {
1004 ierr = PetscFree(lix);CHKERRQ(ierr);
1005 }
1006 } else {
1007 ierr = (*x->ops->setvalueslocal)(x,ni,ix,y,iora);CHKERRQ(ierr);
1008 }
1009 ierr = PetscLogEventEnd(VEC_SetValues,x,0,0,0);CHKERRQ(ierr);
1010 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
1011 PetscFunctionReturn(0);
1012 }
1013
1014 /*@
1015 VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1016 using a local ordering of the nodes.
1017
1018 Not Collective
1019
1020 Input Parameters:
1021 + x - vector to insert in
1022 . ni - number of blocks to add
1023 . ix - indices where to add in block count, not element count
1024 . y - array of values
1025 - iora - either INSERT_VALUES or ADD_VALUES, where
1026 ADD_VALUES adds values to any existing entries, and
1027 INSERT_VALUES replaces existing entries with new values
1028
1029 Level: intermediate
1030
1031 Notes:
1032 VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j],
1033 for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().
1034
1035 Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1036 options cannot be mixed without intervening calls to the assembly
1037 routines.
1038
1039 These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
1040 MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.
1041
1042 VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.
1043
1044
1045 .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
1046 VecSetLocalToGlobalMapping()
1047 @*/
1048 PetscErrorCode VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1049 {
1050 PetscErrorCode ierr;
1051 PetscInt lixp[128],*lix = lixp;
1052
1053 PetscFunctionBeginHot;
1054 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
1055 if (!ni) PetscFunctionReturn(0);
1056 PetscValidIntPointer(ix,3);
1057 PetscValidScalarPointer(y,4);
1058 PetscValidType(x,1);
1059 if (ni > 128) {
1060 ierr = PetscMalloc1(ni,&lix);CHKERRQ(ierr);
1061 }
1062
1063 ierr = PetscLogEventBegin(VEC_SetValues,x,0,0,0);CHKERRQ(ierr);
1064 ierr = ISLocalToGlobalMappingApplyBlock(x->map->mapping,ni,(PetscInt*)ix,lix);CHKERRQ(ierr);
1065 ierr = (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);CHKERRQ(ierr);
1066 ierr = PetscLogEventEnd(VEC_SetValues,x,0,0,0);CHKERRQ(ierr);
1067 if (ni > 128) {
1068 ierr = PetscFree(lix);CHKERRQ(ierr);
1069 }
1070 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
1071 PetscFunctionReturn(0);
1072 }
1073
1074 /*@
1075 VecMTDot - Computes indefinite vector multiple dot products.
1076 That is, it does NOT use the complex conjugate.
1077
1078 Collective on Vec
1079
1080 Input Parameters:
1081 + x - one vector
1082 . nv - number of vectors
1083 - y - array of vectors. Note that vectors are pointers
1084
1085 Output Parameter:
1086 . val - array of the dot products
1087
1088 Notes for Users of Complex Numbers:
1089 For complex vectors, VecMTDot() computes the indefinite form
1090 $ val = (x,y) = y^T x,
1091 where y^T denotes the transpose of y.
1092
1093 Use VecMDot() for the inner product
1094 $ val = (x,y) = y^H x,
1095 where y^H denotes the conjugate transpose of y.
1096
1097 Level: intermediate
1098
1099
1100 .seealso: VecMDot(), VecTDot()
1101 @*/
1102 PetscErrorCode VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1103 {
1104 PetscErrorCode ierr;
1105
1106 PetscFunctionBegin;
1107 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
1108 PetscValidLogicalCollectiveInt(x,nv,2);
1109 if (!nv) PetscFunctionReturn(0);
1110 PetscValidPointer(y,3);
1111 PetscValidHeaderSpecific(*y,VEC_CLASSID,3);
1112 PetscValidScalarPointer(val,4);
1113 PetscValidType(x,2);
1114 PetscValidType(*y,3);
1115 PetscCheckSameTypeAndComm(x,2,*y,3);
1116 VecCheckSameSize(x,1,*y,3);
1117
1118 ierr = PetscLogEventBegin(VEC_MTDot,x,*y,0,0);CHKERRQ(ierr);
1119 ierr = (*x->ops->mtdot)(x,nv,y,val);CHKERRQ(ierr);
1120 ierr = PetscLogEventEnd(VEC_MTDot,x,*y,0,0);CHKERRQ(ierr);
1121 PetscFunctionReturn(0);
1122 }
1123
1124 /*@
1125 VecMDot - Computes vector multiple dot products.
1126
1127 Collective on Vec
1128
1129 Input Parameters:
1130 + x - one vector
1131 . nv - number of vectors
1132 - y - array of vectors.
1133
1134 Output Parameter:
1135 . val - array of the dot products (does not allocate the array)
1136
1137 Notes for Users of Complex Numbers:
1138 For complex vectors, VecMDot() computes
1139 $ val = (x,y) = y^H x,
1140 where y^H denotes the conjugate transpose of y.
1141
1142 Use VecMTDot() for the indefinite form
1143 $ val = (x,y) = y^T x,
1144 where y^T denotes the transpose of y.
1145
1146 Level: intermediate
1147
1148
1149 .seealso: VecMTDot(), VecDot()
1150 @*/
1151 PetscErrorCode VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1152 {
1153 PetscErrorCode ierr;
1154
1155 PetscFunctionBegin;
1156 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
1157 PetscValidLogicalCollectiveInt(x,nv,2);
1158 if (!nv) PetscFunctionReturn(0);
1159 if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1160 PetscValidPointer(y,3);
1161 PetscValidHeaderSpecific(*y,VEC_CLASSID,3);
1162 PetscValidScalarPointer(val,4);
1163 PetscValidType(x,2);
1164 PetscValidType(*y,3);
1165 PetscCheckSameTypeAndComm(x,2,*y,3);
1166 VecCheckSameSize(x,1,*y,3);
1167
1168 ierr = PetscLogEventBegin(VEC_MDot,x,*y,0,0);CHKERRQ(ierr);
1169 ierr = (*x->ops->mdot)(x,nv,y,val);CHKERRQ(ierr);
1170 ierr = PetscLogEventEnd(VEC_MDot,x,*y,0,0);CHKERRQ(ierr);
1171 PetscFunctionReturn(0);
1172 }
1173
1174 /*@
1175 VecMAXPY - Computes y = y + sum alpha[i] x[i]
1176
1177 Logically Collective on Vec
1178
1179 Input Parameters:
1180 + nv - number of scalars and x-vectors
1181 . alpha - array of scalars
1182 . y - one vector
1183 - x - array of vectors
1184
1185 Level: intermediate
1186
1187 Notes:
1188 y cannot be any of the x vectors
1189
1190 .seealso: VecAYPX(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
1191 @*/
1192 PetscErrorCode VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
1193 {
1194 PetscErrorCode ierr;
1195 PetscInt i;
1196 PetscBool nonzero;
1197
1198 PetscFunctionBegin;
1199 PetscValidHeaderSpecific(y,VEC_CLASSID,1);
1200 PetscValidLogicalCollectiveInt(y,nv,2);
1201 if (!nv) PetscFunctionReturn(0);
1202 if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1203 PetscValidScalarPointer(alpha,3);
1204 PetscValidPointer(x,4);
1205 PetscValidHeaderSpecific(*x,VEC_CLASSID,4);
1206 PetscValidType(y,1);
1207 PetscValidType(*x,4);
1208 PetscCheckSameTypeAndComm(y,1,*x,4);
1209 VecCheckSameSize(y,1,*x,4);
1210 for (i=0; i<nv; i++) PetscValidLogicalCollectiveScalar(y,alpha[i],3);
1211 for (i=0, nonzero = PETSC_FALSE; i<nv && !nonzero; i++) nonzero = (PetscBool)(nonzero || alpha[i] != (PetscScalar)0.0);
1212 if (!nonzero) PetscFunctionReturn(0);
1213 ierr = VecSetErrorIfLocked(y,1);CHKERRQ(ierr);
1214 ierr = PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);CHKERRQ(ierr);
1215 ierr = (*y->ops->maxpy)(y,nv,alpha,x);CHKERRQ(ierr);
1216 ierr = PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);CHKERRQ(ierr);
1217 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1218 PetscFunctionReturn(0);
1219 }
1220
1221 /*@
1222 VecGetSubVector - Gets a vector representing part of another vector
1223
1224 Collective on X and IS
1225
1226 Input Arguments:
1227 + X - vector from which to extract a subvector
1228 - is - index set representing portion of X to extract
1229
1230 Output Arguments:
1231 . Y - subvector corresponding to is
1232
1233 Level: advanced
1234
1235 Notes:
1236 The subvector Y should be returned with VecRestoreSubVector().
1237 X and is must be defined on the same communicator
1238
1239 This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1240 modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1241 The resulting subvector inherits the block size from the IS if greater than one. Otherwise, the block size is guessed from the block size of the original vec.
1242
1243 .seealso: MatCreateSubMatrix()
1244 @*/
1245 PetscErrorCode VecGetSubVector(Vec X,IS is,Vec *Y)
1246 {
1247 PetscErrorCode ierr;
1248 Vec Z;
1249
1250 PetscFunctionBegin;
1251 PetscValidHeaderSpecific(X,VEC_CLASSID,1);
1252 PetscValidHeaderSpecific(is,IS_CLASSID,2);
1253 PetscCheckSameComm(X,1,is,2);
1254 PetscValidPointer(Y,3);
1255 if (X->ops->getsubvector) {
1256 ierr = (*X->ops->getsubvector)(X,is,&Z);CHKERRQ(ierr);
1257 } else { /* Default implementation currently does no caching */
1258 PetscInt gstart,gend,start;
1259 PetscBool red[2] = { PETSC_TRUE, PETSC_TRUE };
1260 PetscInt n,N,ibs,vbs,bs = -1;
1261
1262 ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr);
1263 ierr = ISGetSize(is,&N);CHKERRQ(ierr);
1264 ierr = ISGetBlockSize(is,&ibs);CHKERRQ(ierr);
1265 ierr = VecGetBlockSize(X,&vbs);CHKERRQ(ierr);
1266 ierr = VecGetOwnershipRange(X,&gstart,&gend);CHKERRQ(ierr);
1267 ierr = ISContiguousLocal(is,gstart,gend,&start,&red[0]);CHKERRQ(ierr);
1268 /* block size is given by IS if ibs > 1; otherwise, check the vector */
1269 if (ibs > 1) {
1270 ierr = MPIU_Allreduce(MPI_IN_PLACE,red,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));CHKERRQ(ierr);
1271 bs = ibs;
1272 } else {
1273 if (n%vbs || vbs == 1) red[1] = PETSC_FALSE; /* this process invalidate the collectiveness of block size */
1274 ierr = MPIU_Allreduce(MPI_IN_PLACE,red,2,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));CHKERRQ(ierr);
1275 if (red[0] && red[1]) bs = vbs; /* all processes have a valid block size and the access will be contiguous */
1276 }
1277 if (red[0]) { /* We can do a no-copy implementation */
1278 const PetscScalar *x;
1279 PetscInt state = 0;
1280 PetscBool isstd;
1281 #if defined(PETSC_HAVE_CUDA)
1282 PetscBool iscuda;
1283 #endif
1284
1285 ierr = PetscObjectTypeCompareAny((PetscObject)X,&isstd,VECSEQ,VECMPI,VECSTANDARD,"");CHKERRQ(ierr);
1286 #if defined(PETSC_HAVE_CUDA)
1287 ierr = PetscObjectTypeCompareAny((PetscObject)X,&iscuda,VECSEQCUDA,VECMPICUDA,"");CHKERRQ(ierr);
1288 if (iscuda) {
1289 const PetscScalar *x_d;
1290 PetscMPIInt size;
1291 PetscOffloadMask flg;
1292
1293 ierr = VecCUDAGetArrays_Private(X,&x,&x_d,&flg);CHKERRQ(ierr);
1294 if (flg == PETSC_OFFLOAD_UNALLOCATED) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for PETSC_OFFLOAD_UNALLOCATED");
1295 if (n && !x && !x_d) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Missing vector data");
1296 if (x) x += start;
1297 if (x_d) x_d += start;
1298 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);CHKERRQ(ierr);
1299 if (size == 1) {
1300 ierr = VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)X),bs,n,x,x_d,&Z);CHKERRQ(ierr);
1301 } else {
1302 ierr = VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)X),bs,n,N,x,x_d,&Z);CHKERRQ(ierr);
1303 }
1304 Z->offloadmask = flg;
1305 } else if (isstd) {
1306 #else
1307 if (isstd) { /* standard CPU: use CreateWithArray pattern */
1308 #endif
1309 PetscMPIInt size;
1310
1311 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);CHKERRQ(ierr);
1312 ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr);
1313 if (x) x += start;
1314 if (size == 1) {
1315 ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)X),bs,n,x,&Z);CHKERRQ(ierr);
1316 } else {
1317 ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)X),bs,n,N,x,&Z);CHKERRQ(ierr);
1318 }
1319 ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr);
1320 } else { /* default implementation: use place array */
1321 ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr);
1322 ierr = VecCreate(PetscObjectComm((PetscObject)X),&Z);CHKERRQ(ierr);
1323 ierr = VecSetType(Z,((PetscObject)X)->type_name);CHKERRQ(ierr);
1324 ierr = VecSetSizes(Z,n,N);CHKERRQ(ierr);
1325 ierr = VecSetBlockSize(Z,bs);CHKERRQ(ierr);
1326 ierr = VecPlaceArray(Z,x ? x+start : NULL);CHKERRQ(ierr);
1327 ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr);
1328 }
1329
1330 /* this is relevant only in debug mode */
1331 ierr = VecLockGet(X,&state);CHKERRQ(ierr);
1332 if (state) {
1333 ierr = VecLockReadPush(Z);CHKERRQ(ierr);
1334 }
1335 Z->ops->placearray = NULL;
1336 Z->ops->replacearray = NULL;
1337 } else { /* Have to create a scatter and do a copy */
1338 VecScatter scatter;
1339
1340 ierr = VecCreate(PetscObjectComm((PetscObject)is),&Z);CHKERRQ(ierr);
1341 ierr = VecSetSizes(Z,n,N);CHKERRQ(ierr);
1342 ierr = VecSetBlockSize(Z,bs);CHKERRQ(ierr);
1343 ierr = VecSetType(Z,((PetscObject)X)->type_name);CHKERRQ(ierr);
1344 ierr = VecScatterCreate(X,is,Z,NULL,&scatter);CHKERRQ(ierr);
1345 ierr = VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1346 ierr = VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1347 ierr = PetscObjectCompose((PetscObject)Z,"VecGetSubVector_Scatter",(PetscObject)scatter);CHKERRQ(ierr);
1348 ierr = VecScatterDestroy(&scatter);CHKERRQ(ierr);
1349 }
1350 }
1351 /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1352 if (VecGetSubVectorSavedStateId < 0) {ierr = PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);CHKERRQ(ierr);}
1353 ierr = PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,1);CHKERRQ(ierr);
1354 *Y = Z;
1355 PetscFunctionReturn(0);
1356 }
1357
1358 /*@
1359 VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()
1360
1361 Collective on IS
1362
1363 Input Arguments:
1364 + X - vector from which subvector was obtained
1365 . is - index set representing the subset of X
1366 - Y - subvector being restored
1367
1368 Level: advanced
1369
1370 .seealso: VecGetSubVector()
1371 @*/
1372 PetscErrorCode VecRestoreSubVector(Vec X,IS is,Vec *Y)
1373 {
1374 PetscErrorCode ierr;
1375
1376 PetscFunctionBegin;
1377 PetscValidHeaderSpecific(X,VEC_CLASSID,1);
1378 PetscValidHeaderSpecific(is,IS_CLASSID,2);
1379 PetscCheckSameComm(X,1,is,2);
1380 PetscValidPointer(Y,3);
1381 PetscValidHeaderSpecific(*Y,VEC_CLASSID,3);
1382 if (X->ops->restoresubvector) {
1383 ierr = (*X->ops->restoresubvector)(X,is,Y);CHKERRQ(ierr);
1384 } else {
1385 PETSC_UNUSED PetscObjectState dummystate = 0;
1386 PetscBool valid;
1387
1388 ierr = PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,dummystate,valid);CHKERRQ(ierr);
1389 if (!valid) {
1390 VecScatter scatter;
1391 PetscInt state;
1392
1393 ierr = VecLockGet(X,&state);CHKERRQ(ierr);
1394 if (state != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vec X is locked for read-only or read/write access");
1395
1396 ierr = PetscObjectQuery((PetscObject)*Y,"VecGetSubVector_Scatter",(PetscObject*)&scatter);CHKERRQ(ierr);
1397 if (scatter) {
1398 ierr = VecScatterBegin(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1399 ierr = VecScatterEnd(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1400 } else {
1401 #if defined(PETSC_HAVE_CUDA)
1402 PetscBool iscuda;
1403
1404 ierr = PetscObjectTypeCompareAny((PetscObject)*Y,&iscuda,VECSEQCUDA,VECMPICUDA,"");CHKERRQ(ierr);
1405 if (iscuda) {
1406 PetscOffloadMask ymask = (*Y)->offloadmask;
1407
1408 /* The offloadmask of X dictates where to move memory
1409 If X GPU data is valid, then move Y data on GPU if needed
1410 Otherwise, move back to the CPU */
1411 switch (X->offloadmask) {
1412 case PETSC_OFFLOAD_BOTH:
1413 if (ymask == PETSC_OFFLOAD_CPU) {
1414 ierr = VecCUDAResetArray(*Y);CHKERRQ(ierr);
1415 } else if (ymask == PETSC_OFFLOAD_GPU) {
1416 X->offloadmask = PETSC_OFFLOAD_GPU;
1417 }
1418 break;
1419 case PETSC_OFFLOAD_GPU:
1420 if (ymask == PETSC_OFFLOAD_CPU) {
1421 ierr = VecCUDAResetArray(*Y);CHKERRQ(ierr);
1422 }
1423 break;
1424 case PETSC_OFFLOAD_CPU:
1425 if (ymask == PETSC_OFFLOAD_GPU) {
1426 ierr = VecResetArray(*Y);CHKERRQ(ierr);
1427 }
1428 break;
1429 case PETSC_OFFLOAD_UNALLOCATED:
1430 case PETSC_OFFLOAD_VECKOKKOS:
1431 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen");
1432 break;
1433 }
1434 } else {
1435 #else
1436 {
1437 #endif
1438 /* If OpenCL vecs updated the device memory, this triggers a copy on the CPU */
1439 ierr = VecResetArray(*Y);CHKERRQ(ierr);
1440 }
1441 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
1442 }
1443 }
1444 ierr = VecDestroy(Y);CHKERRQ(ierr);
1445 }
1446 PetscFunctionReturn(0);
1447 }
1448
1449 /*@
1450 VecGetLocalVectorRead - Maps the local portion of a vector into a
1451 vector. You must call VecRestoreLocalVectorRead() when the local
1452 vector is no longer needed.
1453
1454 Not collective.
1455
1456 Input parameter:
1457 . v - The vector for which the local vector is desired.
1458
1459 Output parameter:
1460 . w - Upon exit this contains the local vector.
1461
1462 Level: beginner
1463
1464 Notes:
1465 This function is similar to VecGetArrayRead() which maps the local
1466 portion into a raw pointer. VecGetLocalVectorRead() is usually
1467 almost as efficient as VecGetArrayRead() but in certain circumstances
1468 VecGetLocalVectorRead() can be much more efficient than
1469 VecGetArrayRead(). This is because the construction of a contiguous
1470 array representing the vector data required by VecGetArrayRead() can
1471 be an expensive operation for certain vector types. For example, for
1472 GPU vectors VecGetArrayRead() requires that the data between device
1473 and host is synchronized.
1474
1475 Unlike VecGetLocalVector(), this routine is not collective and
1476 preserves cached information.
1477
1478 .seealso: VecRestoreLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1479 @*/
1480 PetscErrorCode VecGetLocalVectorRead(Vec v,Vec w)
1481 {
1482 PetscErrorCode ierr;
1483 PetscScalar *a;
1484
1485 PetscFunctionBegin;
1486 PetscValidHeaderSpecific(v,VEC_CLASSID,1);
1487 PetscValidHeaderSpecific(w,VEC_CLASSID,2);
1488 VecCheckSameLocalSize(v,1,w,2);
1489 if (v->ops->getlocalvectorread) {
1490 ierr = (*v->ops->getlocalvectorread)(v,w);CHKERRQ(ierr);
1491 } else {
1492 ierr = VecGetArrayRead(v,(const PetscScalar**)&a);CHKERRQ(ierr);
1493 ierr = VecPlaceArray(w,a);CHKERRQ(ierr);
1494 }
1495 PetscFunctionReturn(0);
1496 }
1497
1498 /*@
1499 VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1500 previously mapped into a vector using VecGetLocalVectorRead().
1501
1502 Not collective.
1503
1504 Input parameter:
1505 + v - The local portion of this vector was previously mapped into w using VecGetLocalVectorRead().
1506 - w - The vector into which the local portion of v was mapped.
1507
1508 Level: beginner
1509
1510 .seealso: VecGetLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1511 @*/
1512 PetscErrorCode VecRestoreLocalVectorRead(Vec v,Vec w)
1513 {
1514 PetscErrorCode ierr;
1515 PetscScalar *a;
1516
1517 PetscFunctionBegin;
1518 PetscValidHeaderSpecific(v,VEC_CLASSID,1);
1519 PetscValidHeaderSpecific(w,VEC_CLASSID,2);
1520 if (v->ops->restorelocalvectorread) {
1521 ierr = (*v->ops->restorelocalvectorread)(v,w);CHKERRQ(ierr);
1522 } else {
1523 ierr = VecGetArrayRead(w,(const PetscScalar**)&a);CHKERRQ(ierr);
1524 ierr = VecRestoreArrayRead(v,(const PetscScalar**)&a);CHKERRQ(ierr);
1525 ierr = VecResetArray(w);CHKERRQ(ierr);
1526 }
1527 PetscFunctionReturn(0);
1528 }
1529
1530 /*@
1531 VecGetLocalVector - Maps the local portion of a vector into a
1532 vector.
1533
1534 Collective on v, not collective on w.
1535
1536 Input parameter:
1537 . v - The vector for which the local vector is desired.
1538
1539 Output parameter:
1540 . w - Upon exit this contains the local vector.
1541
1542 Level: beginner
1543
1544 Notes:
1545 This function is similar to VecGetArray() which maps the local
1546 portion into a raw pointer. VecGetLocalVector() is usually about as
1547 efficient as VecGetArray() but in certain circumstances
1548 VecGetLocalVector() can be much more efficient than VecGetArray().
1549 This is because the construction of a contiguous array representing
1550 the vector data required by VecGetArray() can be an expensive
1551 operation for certain vector types. For example, for GPU vectors
1552 VecGetArray() requires that the data between device and host is
1553 synchronized.
1554
1555 .seealso: VecRestoreLocalVector(), VecGetLocalVectorRead(), VecGetArrayRead(), VecGetArray()
1556 @*/
1557 PetscErrorCode VecGetLocalVector(Vec v,Vec w)
1558 {
1559 PetscErrorCode ierr;
1560 PetscScalar *a;
1561
1562 PetscFunctionBegin;
1563 PetscValidHeaderSpecific(v,VEC_CLASSID,1);
1564 PetscValidHeaderSpecific(w,VEC_CLASSID,2);
1565 VecCheckSameLocalSize(v,1,w,2);
1566 if (v->ops->getlocalvector) {
1567 ierr = (*v->ops->getlocalvector)(v,w);CHKERRQ(ierr);
1568 } else {
1569 ierr = VecGetArray(v,&a);CHKERRQ(ierr);
1570 ierr = VecPlaceArray(w,a);CHKERRQ(ierr);
1571 }
1572 PetscFunctionReturn(0);
1573 }
1574
1575 /*@
1576 VecRestoreLocalVector - Unmaps the local portion of a vector
1577 previously mapped into a vector using VecGetLocalVector().
1578
1579 Logically collective.
1580
1581 Input parameter:
1582 + v - The local portion of this vector was previously mapped into w using VecGetLocalVector().
1583 - w - The vector into which the local portion of v was mapped.
1584
1585 Level: beginner
1586
1587 .seealso: VecGetLocalVector(), VecGetLocalVectorRead(), VecRestoreLocalVectorRead(), LocalVectorRead(), VecGetArrayRead(), VecGetArray()
1588 @*/
1589 PetscErrorCode VecRestoreLocalVector(Vec v,Vec w)
1590 {
1591 PetscErrorCode ierr;
1592 PetscScalar *a;
1593
1594 PetscFunctionBegin;
1595 PetscValidHeaderSpecific(v,VEC_CLASSID,1);
1596 PetscValidHeaderSpecific(w,VEC_CLASSID,2);
1597 if (v->ops->restorelocalvector) {
1598 ierr = (*v->ops->restorelocalvector)(v,w);CHKERRQ(ierr);
1599 } else {
1600 ierr = VecGetArray(w,&a);CHKERRQ(ierr);
1601 ierr = VecRestoreArray(v,&a);CHKERRQ(ierr);
1602 ierr = VecResetArray(w);CHKERRQ(ierr);
1603 }
1604 PetscFunctionReturn(0);
1605 }
1606
1607 /*@C
1608 VecGetArray - Returns a pointer to a contiguous array that contains this
1609 processor's portion of the vector data. For the standard PETSc
1610 vectors, VecGetArray() returns a pointer to the local data array and
1611 does not use any copies. If the underlying vector data is not stored
1612 in a contiguous array this routine will copy the data to a contiguous
1613 array and return a pointer to that. You MUST call VecRestoreArray()
1614 when you no longer need access to the array.
1615
1616 Logically Collective on Vec
1617
1618 Input Parameter:
1619 . x - the vector
1620
1621 Output Parameter:
1622 . a - location to put pointer to the array
1623
1624 Fortran Note:
1625 This routine is used differently from Fortran 77
1626 $ Vec x
1627 $ PetscScalar x_array(1)
1628 $ PetscOffset i_x
1629 $ PetscErrorCode ierr
1630 $ call VecGetArray(x,x_array,i_x,ierr)
1631 $
1632 $ Access first local entry in vector with
1633 $ value = x_array(i_x + 1)
1634 $
1635 $ ...... other code
1636 $ call VecRestoreArray(x,x_array,i_x,ierr)
1637 For Fortran 90 see VecGetArrayF90()
1638
1639 See the Fortran chapter of the users manual and
1640 petsc/src/snes/tutorials/ex5f.F for details.
1641
1642 Level: beginner
1643
1644 .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1645 VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1646 @*/
1647 PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
1648 {
1649 PetscErrorCode ierr;
1650 #if defined(PETSC_HAVE_VIENNACL)
1651 PetscBool is_viennacltype = PETSC_FALSE;
1652 #endif
1653
1654 PetscFunctionBegin;
1655 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
1656 ierr = VecSetErrorIfLocked(x,1);CHKERRQ(ierr);
1657 if (x->petscnative) {
1658 #if defined(PETSC_HAVE_KOKKOS_KERNELS)
1659 if (x->offloadmask == PETSC_OFFLOAD_VECKOKKOS) { /* offloadmask here works as a tag quickly saying this is a VecKokkos */
1660 ierr = VecKokkosSyncHost(x);CHKERRQ(ierr);
1661 *a = *((PetscScalar**)x->data);
1662 PetscFunctionReturn(0);
1663 }
1664 #endif
1665 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1666 if (x->offloadmask == PETSC_OFFLOAD_GPU) {
1667 #if defined(PETSC_HAVE_VIENNACL)
1668 ierr = PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");CHKERRQ(ierr);
1669 if (is_viennacltype) {
1670 ierr = VecViennaCLCopyFromGPU(x);CHKERRQ(ierr);
1671 } else
1672 #endif
1673 {
1674 #if defined(PETSC_HAVE_CUDA)
1675 ierr = VecCUDACopyFromGPU(x);CHKERRQ(ierr);
1676 #endif
1677 }
1678 } else if (x->offloadmask == PETSC_OFFLOAD_UNALLOCATED) {
1679 #if defined(PETSC_HAVE_VIENNACL)
1680 ierr = PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");CHKERRQ(ierr);
1681 if (is_viennacltype) {
1682 ierr = VecViennaCLAllocateCheckHost(x);CHKERRQ(ierr);
1683 } else
1684 #endif
1685 {
1686 #if defined(PETSC_HAVE_CUDA)
1687 ierr = VecCUDAAllocateCheckHost(x);CHKERRQ(ierr);
1688 #endif
1689 }
1690 }
1691 #endif
1692 *a = *((PetscScalar**)x->data);
1693 } else {
1694 if (x->ops->getarray) {
1695 ierr = (*x->ops->getarray)(x,a);CHKERRQ(ierr);
1696 } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array for vector type \"%s\"",((PetscObject)x)->type_name);
1697 }
1698 PetscFunctionReturn(0);
1699 }
1700
1701 /*@C
1702 VecGetArrayInPlace_Internal - Like VecGetArray(), but if this is a CUDA vector and it is currently offloaded to GPU,
1703 the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
1704 vector data. Otherwise, it functions as VecGetArray().
1705
1706 Logically Collective on Vec
1707
1708 Input Parameter:
1709 . x - the vector
1710
1711 Output Parameter:
1712 . a - location to put pointer to the array
1713
1714 Level: beginner
1715
1716 .seealso: VecRestoreArrayInPlace(), VecRestoreArrayInPlace(), VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(),
1717 VecPlaceArray(), VecGetArray2d(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1718 @*/
1719 PetscErrorCode VecGetArrayInPlace(Vec x,PetscScalar **a)
1720 {
1721 PetscErrorCode ierr;
1722 PetscFunctionBegin;
1723 ierr = VecGetArrayInPlace_Internal(x,a,NULL);CHKERRQ(ierr);
1724 PetscFunctionReturn(0);
1725 }
1726
1727 PetscErrorCode VecGetArrayInPlace_Internal(Vec x,PetscScalar **a,PetscMemType *mtype)
1728 {
1729 PetscErrorCode ierr;
1730
1731 PetscFunctionBegin;
1732 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
1733 ierr = VecSetErrorIfLocked(x,1);CHKERRQ(ierr);
1734 if (mtype) *mtype = PETSC_MEMTYPE_HOST;
1735 #if defined(PETSC_HAVE_KOKKOS_KERNELS)
1736 if (x->offloadmask == PETSC_OFFLOAD_VECKOKKOS) {
1737 ierr = VecKokkosGetArrayInPlace_Internal(x,a,mtype);CHKERRQ(ierr);
1738 PetscFunctionReturn(0);
1739 }
1740 #endif
1741
1742 #if defined(PETSC_HAVE_CUDA)
1743 if (x->petscnative && (x->offloadmask & PETSC_OFFLOAD_GPU)) { /* Prefer working on GPU when offloadmask is PETSC_OFFLOAD_BOTH */
1744 PetscBool is_cudatype = PETSC_FALSE;
1745 ierr = PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");CHKERRQ(ierr);
1746 if (is_cudatype) {
1747 ierr = VecCUDAGetArray(x,a);CHKERRQ(ierr);
1748 x->offloadmask = PETSC_OFFLOAD_GPU; /* Change the mask once GPU gets write access, don't wait until restore array */
1749 if (mtype) *mtype = PETSC_MEMTYPE_DEVICE;
1750 PetscFunctionReturn(0);
1751 }
1752 }
1753 #endif
1754 ierr = VecGetArray(x,a);CHKERRQ(ierr);
1755 PetscFunctionReturn(0);
1756 }
1757
1758 /*@C
1759 VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contains this
1760 processor's portion of the vector data. The values in this array are NOT valid, the routine calling this
1761 routine is responsible for putting values into the array; any values it does not set will be invalid
1762
1763 Logically Collective on Vec
1764
1765 Input Parameter:
1766 . x - the vector
1767
1768 Output Parameter:
1769 . a - location to put pointer to the array
1770
1771 Level: intermediate
1772
1773 This is for vectors associate with GPUs, the vector is not copied up before giving access. If you need correct
1774 values in the array use VecGetArray()
1775
1776 Concepts: vector^accessing local values
1777
1778 .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1779 VecGetArrayPair(), VecRestoreArrayPair(), VecGetArray(), VecRestoreArrayWrite()
1780 @*/
1781 PetscErrorCode VecGetArrayWrite(Vec x,PetscScalar **a)
1782 {
1783 PetscErrorCode ierr;
1784
1785 PetscFunctionBegin;
1786 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
1787 ierr = VecSetErrorIfLocked(x,1);CHKERRQ(ierr);
1788 if (!x->ops->getarraywrite) {
1789 ierr = VecGetArray(x,a);CHKERRQ(ierr);
1790 } else {
1791 ierr = (*x->ops->getarraywrite)(x,a);CHKERRQ(ierr);
1792 }
1793 PetscFunctionReturn(0);
1794 }
1795
1796 /*@C
1797 VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1798
1799 Not Collective
1800
1801 Input Parameters:
1802 . x - the vector
1803
1804 Output Parameter:
1805 . a - the array
1806
1807 Level: beginner
1808
1809 Notes:
1810 The array must be returned using a matching call to VecRestoreArrayRead().
1811
1812 Unlike VecGetArray(), this routine is not collective and preserves cached information like vector norms.
1813
1814 Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1815 implementations may require a copy, but must such implementations should cache the contiguous representation so that
1816 only one copy is performed when this routine is called multiple times in sequence.
1817
1818 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1819 @*/
1820 PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
1821 {
1822 PetscErrorCode ierr;
1823 #if defined(PETSC_HAVE_VIENNACL)
1824 PetscBool is_viennacltype = PETSC_FALSE;
1825 #endif
1826
1827 PetscFunctionBegin;
1828 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
1829 if (x->petscnative) {
1830 #if defined(PETSC_HAVE_KOKKOS_KERNELS)
1831 if (x->offloadmask == PETSC_OFFLOAD_VECKOKKOS) {
1832 ierr = VecKokkosSyncHost(x);CHKERRQ(ierr);
1833 *a = *((PetscScalar **)x->data);
1834 PetscFunctionReturn(0);
1835 }
1836 #endif
1837 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1838 if (x->offloadmask == PETSC_OFFLOAD_GPU) {
1839 #if defined(PETSC_HAVE_VIENNACL)
1840 ierr = PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");CHKERRQ(ierr);
1841 if (is_viennacltype) {
1842 ierr = VecViennaCLCopyFromGPU(x);CHKERRQ(ierr);
1843 } else
1844 #endif
1845 {
1846 #if defined(PETSC_HAVE_CUDA)
1847 ierr = VecCUDACopyFromGPU(x);CHKERRQ(ierr);
1848 #endif
1849 }
1850 }
1851 #endif
1852 *a = *((PetscScalar **)x->data);
1853 } else if (x->ops->getarrayread) {
1854 ierr = (*x->ops->getarrayread)(x,a);CHKERRQ(ierr);
1855 } else {
1856 ierr = (*x->ops->getarray)(x,(PetscScalar**)a);CHKERRQ(ierr);
1857 }
1858 PetscFunctionReturn(0);
1859 }
1860
1861 /*@C
1862 VecGetArrayReadInPlace - Like VecGetArrayRead(), but if this is a CUDA vector and it is currently offloaded to GPU,
1863 the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
1864 vector data. Otherwise, it functions as VecGetArrayRead().
1865
1866 Not Collective
1867
1868 Input Parameters:
1869 . x - the vector
1870
1871 Output Parameter:
1872 . a - the array
1873
1874 Level: beginner
1875
1876 Notes:
1877 The array must be returned using a matching call to VecRestoreArrayReadInPlace().
1878
1879
1880 .seealso: VecRestoreArrayReadInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayInPlace()
1881 @*/
1882 PetscErrorCode VecGetArrayReadInPlace(Vec x,const PetscScalar **a)
1883 {
1884 PetscErrorCode ierr;
1885 PetscFunctionBegin;
1886 ierr = VecGetArrayReadInPlace_Internal(x,a,NULL);CHKERRQ(ierr);
1887 PetscFunctionReturn(0);
1888 }
1889
1890 PetscErrorCode VecGetArrayReadInPlace_Internal(Vec x,const PetscScalar **a,PetscMemType *mtype)
1891 {
1892 PetscErrorCode ierr;
1893
1894 PetscFunctionBegin;
1895 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
1896 if (mtype) *mtype = PETSC_MEMTYPE_HOST;
1897 #if defined(PETSC_HAVE_KOKKOS_KERNELS)
1898 if (x->offloadmask == PETSC_OFFLOAD_VECKOKKOS) {
1899 ierr = VecKokkosGetArrayReadInPlace_Internal(x,a,mtype);CHKERRQ(ierr);
1900 PetscFunctionReturn(0);
1901 }
1902 #endif
1903
1904 #if defined(PETSC_HAVE_CUDA)
1905 if (x->petscnative && x->offloadmask & PETSC_OFFLOAD_GPU) {
1906 PetscBool is_cudatype = PETSC_FALSE;
1907 ierr = PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");CHKERRQ(ierr);
1908 if (is_cudatype) {
1909 ierr = VecCUDAGetArrayRead(x,a);CHKERRQ(ierr);
1910 if (mtype) *mtype = PETSC_MEMTYPE_DEVICE;
1911 PetscFunctionReturn(0);
1912 }
1913 }
1914 #endif
1915 ierr = VecGetArrayRead(x,a);CHKERRQ(ierr);
1916 PetscFunctionReturn(0);
1917 }
1918
1919 /*@C
1920 VecGetArrays - Returns a pointer to the arrays in a set of vectors
1921 that were created by a call to VecDuplicateVecs(). You MUST call
1922 VecRestoreArrays() when you no longer need access to the array.
1923
1924 Logically Collective on Vec
1925
1926 Input Parameter:
1927 + x - the vectors
1928 - n - the number of vectors
1929
1930 Output Parameter:
1931 . a - location to put pointer to the array
1932
1933 Fortran Note:
1934 This routine is not supported in Fortran.
1935
1936 Level: intermediate
1937
1938 .seealso: VecGetArray(), VecRestoreArrays()
1939 @*/
1940 PetscErrorCode VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1941 {
1942 PetscErrorCode ierr;
1943 PetscInt i;
1944 PetscScalar **q;
1945
1946 PetscFunctionBegin;
1947 PetscValidPointer(x,1);
1948 PetscValidHeaderSpecific(*x,VEC_CLASSID,1);
1949 PetscValidPointer(a,3);
1950 if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1951 ierr = PetscMalloc1(n,&q);CHKERRQ(ierr);
1952 for (i=0; i<n; ++i) {
1953 ierr = VecGetArray(x[i],&q[i]);CHKERRQ(ierr);
1954 }
1955 *a = q;
1956 PetscFunctionReturn(0);
1957 }
1958
1959 /*@C
1960 VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1961 has been called.
1962
1963 Logically Collective on Vec
1964
1965 Input Parameters:
1966 + x - the vector
1967 . n - the number of vectors
1968 - a - location of pointer to arrays obtained from VecGetArrays()
1969
1970 Notes:
1971 For regular PETSc vectors this routine does not involve any copies. For
1972 any special vectors that do not store local vector data in a contiguous
1973 array, this routine will copy the data back into the underlying
1974 vector data structure from the arrays obtained with VecGetArrays().
1975
1976 Fortran Note:
1977 This routine is not supported in Fortran.
1978
1979 Level: intermediate
1980
1981 .seealso: VecGetArrays(), VecRestoreArray()
1982 @*/
1983 PetscErrorCode VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1984 {
1985 PetscErrorCode ierr;
1986 PetscInt i;
1987 PetscScalar **q = *a;
1988
1989 PetscFunctionBegin;
1990 PetscValidPointer(x,1);
1991 PetscValidHeaderSpecific(*x,VEC_CLASSID,1);
1992 PetscValidPointer(a,3);
1993
1994 for (i=0; i<n; ++i) {
1995 ierr = VecRestoreArray(x[i],&q[i]);CHKERRQ(ierr);
1996 }
1997 ierr = PetscFree(q);CHKERRQ(ierr);
1998 PetscFunctionReturn(0);
1999 }
2000
2001 /*@C
2002 VecRestoreArray - Restores a vector after VecGetArray() has been called.
2003
2004 Logically Collective on Vec
2005
2006 Input Parameters:
2007 + x - the vector
2008 - a - location of pointer to array obtained from VecGetArray()
2009
2010 Level: beginner
2011
2012 .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
2013 VecGetArrayPair(), VecRestoreArrayPair()
2014 @*/
2015 PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
2016 {
2017 PetscErrorCode ierr;
2018
2019 PetscFunctionBegin;
2020 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
2021 if (x->petscnative) {
2022 #if defined(PETSC_HAVE_KOKKOS_KERNELS)
2023 if (x->offloadmask == PETSC_OFFLOAD_VECKOKKOS) {ierr = VecKokkosModifyHost(x);CHKERRQ(ierr);}
2024 else
2025 #endif
2026 {
2027 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2028 x->offloadmask = PETSC_OFFLOAD_CPU;
2029 #endif
2030 }
2031 } else {
2032 ierr = (*x->ops->restorearray)(x,a);CHKERRQ(ierr);
2033 }
2034 if (a) *a = NULL;
2035 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2036 PetscFunctionReturn(0);
2037 }
2038
2039 /*@C
2040 VecRestoreArrayInPlace - Restores a vector after VecGetArrayInPlace() has been called.
2041
2042 Logically Collective on Vec
2043
2044 Input Parameters:
2045 + x - the vector
2046 - a - location of pointer to array obtained from VecGetArrayInPlace()
2047
2048 Level: beginner
2049
2050 .seealso: VecGetArrayInPlace(), VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(),
2051 VecPlaceArray(), VecRestoreArray2d(), VecGetArrayPair(), VecRestoreArrayPair()
2052 @*/
2053 PetscErrorCode VecRestoreArrayInPlace(Vec x,PetscScalar **a)
2054 {
2055 PetscErrorCode ierr;
2056
2057 PetscFunctionBegin;
2058 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
2059 #if defined(PETSC_HAVE_KOKKOS_KERNELS)
2060 if (x->offloadmask == PETSC_OFFLOAD_VECKOKKOS) {
2061 ierr = VecKokkosRestoreArrayInPlace(x,a);CHKERRQ(ierr);
2062 PetscFunctionReturn(0);
2063 }
2064 #endif
2065
2066 #if defined(PETSC_HAVE_CUDA)
2067 if (x->petscnative && x->offloadmask == PETSC_OFFLOAD_GPU) {
2068 PetscBool is_cudatype = PETSC_FALSE;
2069 ierr = PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");CHKERRQ(ierr);
2070 if (is_cudatype) {
2071 ierr = VecCUDARestoreArray(x,a);CHKERRQ(ierr);
2072 PetscFunctionReturn(0);
2073 }
2074 }
2075 #endif
2076 ierr = VecRestoreArray(x,a);CHKERRQ(ierr);
2077 PetscFunctionReturn(0);
2078 }
2079
2080
2081 /*@C
2082 VecRestoreArrayWrite - Restores a vector after VecGetArrayWrite() has been called.
2083
2084 Logically Collective on Vec
2085
2086 Input Parameters:
2087 + x - the vector
2088 - a - location of pointer to array obtained from VecGetArray()
2089
2090 Level: beginner
2091
2092 .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
2093 VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite()
2094 @*/
2095 PetscErrorCode VecRestoreArrayWrite(Vec x,PetscScalar **a)
2096 {
2097 PetscErrorCode ierr;
2098
2099 PetscFunctionBegin;
2100 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
2101
2102 #if defined(PETSC_HAVE_KOKKOS_KERNELS)
2103 if (x->offloadmask == PETSC_OFFLOAD_VECKOKKOS) {
2104 ierr = VecKokkosModifyHost(x);CHKERRQ(ierr);
2105 } else
2106 #endif
2107 if (x->petscnative) {
2108 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2109 x->offloadmask = PETSC_OFFLOAD_CPU;
2110 #endif
2111 } else {
2112 if (x->ops->restorearraywrite) {
2113 ierr = (*x->ops->restorearraywrite)(x,a);CHKERRQ(ierr);
2114 } else {
2115 ierr = (*x->ops->restorearray)(x,a);CHKERRQ(ierr);
2116 }
2117 }
2118
2119 if (a) *a = NULL;
2120 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
2121 PetscFunctionReturn(0);
2122 }
2123
2124 /*@C
2125 VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()
2126
2127 Not Collective
2128
2129 Input Parameters:
2130 + vec - the vector
2131 - array - the array
2132
2133 Level: beginner
2134
2135 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
2136 @*/
2137 PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
2138 {
2139 PetscErrorCode ierr;
2140
2141 PetscFunctionBegin;
2142 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
2143 if (x->petscnative) {
2144 /* nothing */
2145 } else if (x->ops->restorearrayread) {
2146 ierr = (*x->ops->restorearrayread)(x,a);CHKERRQ(ierr);
2147 } else {
2148 ierr = (*x->ops->restorearray)(x,(PetscScalar**)a);CHKERRQ(ierr);
2149 }
2150 if (a) *a = NULL;
2151 PetscFunctionReturn(0);
2152 }
2153
2154 /*@C
2155 VecRestoreArrayReadInPlace - Restore array obtained with VecGetArrayReadInPlace()
2156
2157 Not Collective
2158
2159 Input Parameters:
2160 + vec - the vector
2161 - array - the array
2162
2163 Level: beginner
2164
2165 .seealso: VecGetArrayReadInPlace(), VecRestoreArrayInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
2166 @*/
2167 PetscErrorCode VecRestoreArrayReadInPlace(Vec x,const PetscScalar **a)
2168 {
2169 PetscErrorCode ierr;
2170
2171 PetscFunctionBegin;
2172 ierr = VecRestoreArrayRead(x,a);CHKERRQ(ierr);
2173 PetscFunctionReturn(0);
2174 }
2175
2176 /*@
2177 VecPlaceArray - Allows one to replace the array in a vector with an
2178 array provided by the user. This is useful to avoid copying an array
2179 into a vector.
2180
2181 Not Collective
2182
2183 Input Parameters:
2184 + vec - the vector
2185 - array - the array
2186
2187 Notes:
2188 You can return to the original array with a call to VecResetArray()
2189
2190 Level: developer
2191
2192 .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray()
2193
2194 @*/
2195 PetscErrorCode VecPlaceArray(Vec vec,const PetscScalar array[])
2196 {
2197 PetscErrorCode ierr;
2198
2199 PetscFunctionBegin;
2200 PetscValidHeaderSpecific(vec,VEC_CLASSID,1);
2201 PetscValidType(vec,1);
2202 if (array) PetscValidScalarPointer(array,2);
2203 if (vec->ops->placearray) {
2204 ierr = (*vec->ops->placearray)(vec,array);CHKERRQ(ierr);
2205 } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
2206 ierr = PetscObjectStateIncrease((PetscObject)vec);CHKERRQ(ierr);
2207 PetscFunctionReturn(0);
2208 }
2209
2210 /*@C
2211 VecReplaceArray - Allows one to replace the array in a vector with an
2212 array provided by the user. This is useful to avoid copying an array
2213 into a vector.
2214
2215 Not Collective
2216
2217 Input Parameters:
2218 + vec - the vector
2219 - array - the array
2220
2221 Notes:
2222 This permanently replaces the array and frees the memory associated
2223 with the old array.
2224
2225 The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
2226 freed by the user. It will be freed when the vector is destroyed.
2227
2228 Not supported from Fortran
2229
2230 Level: developer
2231
2232 .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray()
2233
2234 @*/
2235 PetscErrorCode VecReplaceArray(Vec vec,const PetscScalar array[])
2236 {
2237 PetscErrorCode ierr;
2238
2239 PetscFunctionBegin;
2240 PetscValidHeaderSpecific(vec,VEC_CLASSID,1);
2241 PetscValidType(vec,1);
2242 if (vec->ops->replacearray) {
2243 ierr = (*vec->ops->replacearray)(vec,array);CHKERRQ(ierr);
2244 } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
2245 ierr = PetscObjectStateIncrease((PetscObject)vec);CHKERRQ(ierr);
2246 PetscFunctionReturn(0);
2247 }
2248
2249
2250 /*@C
2251 VecCUDAGetArray - Provides access to the CUDA buffer inside a vector.
2252
2253 This function has semantics similar to VecGetArray(): the pointer
2254 returned by this function points to a consistent view of the vector
2255 data. This may involve a copy operation of data from the host to the
2256 device if the data on the device is out of date. If the device
2257 memory hasn't been allocated previously it will be allocated as part
2258 of this function call. VecCUDAGetArray() assumes that
2259 the user will modify the vector data. This is similar to
2260 intent(inout) in fortran.
2261
2262 The CUDA device pointer has to be released by calling
2263 VecCUDARestoreArray(). Upon restoring the vector data
2264 the data on the host will be marked as out of date. A subsequent
2265 access of the host data will thus incur a data transfer from the
2266 device to the host.
2267
2268
2269 Input Parameter:
2270 . v - the vector
2271
2272 Output Parameter:
2273 . a - the CUDA device pointer
2274
2275 Fortran note:
2276 This function is not currently available from Fortran.
2277
2278 Level: intermediate
2279
2280 .seealso: VecCUDARestoreArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2281 @*/
2282 PETSC_EXTERN PetscErrorCode VecCUDAGetArray(Vec v, PetscScalar **a)
2283 {
2284 #if defined(PETSC_HAVE_CUDA)
2285 PetscErrorCode ierr;
2286 #endif
2287
2288 PetscFunctionBegin;
2289 PetscCheckTypeNames(v,VECSEQCUDA,VECMPICUDA);
2290 #if defined(PETSC_HAVE_CUDA)
2291 *a = 0;
2292 ierr = VecCUDACopyToGPU(v);CHKERRQ(ierr);
2293 *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2294 #endif
2295 PetscFunctionReturn(0);
2296 }
2297
2298 /*@C
2299 VecCUDARestoreArray - Restore a CUDA device pointer previously acquired with VecCUDAGetArray().
2300
2301 This marks the host data as out of date. Subsequent access to the
2302 vector data on the host side with for instance VecGetArray() incurs a
2303 data transfer.
2304
2305 Input Parameter:
2306 + v - the vector
2307 - a - the CUDA device pointer. This pointer is invalid after
2308 VecCUDARestoreArray() returns.
2309
2310 Fortran note:
2311 This function is not currently available from Fortran.
2312
2313 Level: intermediate
2314
2315 .seealso: VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2316 @*/
2317 PETSC_EXTERN PetscErrorCode VecCUDARestoreArray(Vec v, PetscScalar **a)
2318 {
2319 PetscErrorCode ierr;
2320
2321 PetscFunctionBegin;
2322 PetscCheckTypeNames(v,VECSEQCUDA,VECMPICUDA);
2323 #if defined(PETSC_HAVE_CUDA)
2324 v->offloadmask = PETSC_OFFLOAD_GPU;
2325 #endif
2326
2327 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
2328 PetscFunctionReturn(0);
2329 }
2330
2331 /*@C
2332 VecCUDAGetArrayRead - Provides read access to the CUDA buffer inside a vector.
2333
2334 This function is analogous to VecGetArrayRead(): The pointer
2335 returned by this function points to a consistent view of the vector
2336 data. This may involve a copy operation of data from the host to the
2337 device if the data on the device is out of date. If the device
2338 memory hasn't been allocated previously it will be allocated as part
2339 of this function call. VecCUDAGetArrayRead() assumes that the
2340 user will not modify the vector data. This is analgogous to
2341 intent(in) in Fortran.
2342
2343 The CUDA device pointer has to be released by calling
2344 VecCUDARestoreArrayRead(). If the data on the host side was
2345 previously up to date it will remain so, i.e. data on both the device
2346 and the host is up to date. Accessing data on the host side does not
2347 incur a device to host data transfer.
2348
2349 Input Parameter:
2350 . v - the vector
2351
2352 Output Parameter:
2353 . a - the CUDA pointer.
2354
2355 Fortran note:
2356 This function is not currently available from Fortran.
2357
2358 Level: intermediate
2359
2360 .seealso: VecCUDARestoreArrayRead(), VecCUDAGetArray(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2361 @*/
2362 PETSC_EXTERN PetscErrorCode VecCUDAGetArrayRead(Vec v, const PetscScalar **a)
2363 {
2364 #if defined(PETSC_HAVE_CUDA)
2365 PetscErrorCode ierr;
2366 #endif
2367
2368 PetscFunctionBegin;
2369 PetscCheckTypeNames(v,VECSEQCUDA,VECMPICUDA);
2370 #if defined(PETSC_HAVE_CUDA)
2371 *a = 0;
2372 ierr = VecCUDACopyToGPU(v);CHKERRQ(ierr);
2373 *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2374 #endif
2375 PetscFunctionReturn(0);
2376 }
2377
2378 /*@C
2379 VecCUDARestoreArrayRead - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayRead().
2380
2381 If the data on the host side was previously up to date it will remain
2382 so, i.e. data on both the device and the host is up to date.
2383 Accessing data on the host side e.g. with VecGetArray() does not
2384 incur a device to host data transfer.
2385
2386 Input Parameter:
2387 + v - the vector
2388 - a - the CUDA device pointer. This pointer is invalid after
2389 VecCUDARestoreArrayRead() returns.
2390
2391 Fortran note:
2392 This function is not currently available from Fortran.
2393
2394 Level: intermediate
2395
2396 .seealso: VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2397 @*/
2398 PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayRead(Vec v, const PetscScalar **a)
2399 {
2400 PetscFunctionBegin;
2401 PetscCheckTypeNames(v,VECSEQCUDA,VECMPICUDA);
2402 *a = NULL;
2403 PetscFunctionReturn(0);
2404 }
2405
2406 /*@C
2407 VecCUDAGetArrayWrite - Provides write access to the CUDA buffer inside a vector.
2408
2409 The data pointed to by the device pointer is uninitialized. The user
2410 may not read from this data. Furthermore, the entire array needs to
2411 be filled by the user to obtain well-defined behaviour. The device
2412 memory will be allocated by this function if it hasn't been allocated
2413 previously. This is analogous to intent(out) in Fortran.
2414
2415 The device pointer needs to be released with
2416 VecCUDARestoreArrayWrite(). When the pointer is released the
2417 host data of the vector is marked as out of data. Subsequent access
2418 of the host data with e.g. VecGetArray() incurs a device to host data
2419 transfer.
2420
2421
2422 Input Parameter:
2423 . v - the vector
2424
2425 Output Parameter:
2426 . a - the CUDA pointer
2427
2428 Fortran note:
2429 This function is not currently available from Fortran.
2430
2431 Level: advanced
2432
2433 .seealso: VecCUDARestoreArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2434 @*/
2435 PETSC_EXTERN PetscErrorCode VecCUDAGetArrayWrite(Vec v, PetscScalar **a)
2436 {
2437 #if defined(PETSC_HAVE_CUDA)
2438 PetscErrorCode ierr;
2439 #endif
2440
2441 PetscFunctionBegin;
2442 PetscCheckTypeNames(v,VECSEQCUDA,VECMPICUDA);
2443 #if defined(PETSC_HAVE_CUDA)
2444 *a = 0;
2445 ierr = VecCUDAAllocateCheck(v);CHKERRQ(ierr);
2446 *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2447 #endif
2448 PetscFunctionReturn(0);
2449 }
2450
2451 /*@C
2452 VecCUDARestoreArrayWrite - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayWrite().
2453
2454 Data on the host will be marked as out of date. Subsequent access of
2455 the data on the host side e.g. with VecGetArray() will incur a device
2456 to host data transfer.
2457
2458 Input Parameter:
2459 + v - the vector
2460 - a - the CUDA device pointer. This pointer is invalid after
2461 VecCUDARestoreArrayWrite() returns.
2462
2463 Fortran note:
2464 This function is not currently available from Fortran.
2465
2466 Level: intermediate
2467
2468 .seealso: VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2469 @*/
2470 PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayWrite(Vec v, PetscScalar **a)
2471 {
2472 PetscErrorCode ierr;
2473
2474 PetscFunctionBegin;
2475 PetscCheckTypeNames(v,VECSEQCUDA,VECMPICUDA);
2476 #if defined(PETSC_HAVE_CUDA)
2477 v->offloadmask = PETSC_OFFLOAD_GPU;
2478 #endif
2479
2480 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
2481 PetscFunctionReturn(0);
2482 }
2483
2484 /*@C
2485 VecCUDAPlaceArray - Allows one to replace the GPU array in a vector with a
2486 GPU array provided by the user. This is useful to avoid copying an
2487 array into a vector.
2488
2489 Not Collective
2490
2491 Input Parameters:
2492 + vec - the vector
2493 - array - the GPU array
2494
2495 Notes:
2496 You can return to the original GPU array with a call to VecCUDAResetArray()
2497 It is not possible to use VecCUDAPlaceArray() and VecPlaceArray() at the
2498 same time on the same vector.
2499
2500 Level: developer
2501
2502 .seealso: VecPlaceArray(), VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAReplaceArray()
2503
2504 @*/
2505 PetscErrorCode VecCUDAPlaceArray(Vec vin,const PetscScalar a[])
2506 {
2507 PetscErrorCode ierr;
2508
2509 PetscFunctionBegin;
2510 PetscCheckTypeNames(vin,VECSEQCUDA,VECMPICUDA);
2511 #if defined(PETSC_HAVE_CUDA)
2512 ierr = VecCUDACopyToGPU(vin);CHKERRQ(ierr);
2513 if (((Vec_Seq*)vin->data)->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"VecCUDAPlaceArray()/VecPlaceArray() was already called on this vector, without a call to VecCUDAResetArray()/VecResetArray()");
2514 ((Vec_Seq*)vin->data)->unplacedarray = (PetscScalar *) ((Vec_CUDA*)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2515 ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar*)a;
2516 vin->offloadmask = PETSC_OFFLOAD_GPU;
2517 #endif
2518 ierr = PetscObjectStateIncrease((PetscObject)vin);CHKERRQ(ierr);
2519 PetscFunctionReturn(0);
2520 }
2521
2522 /*@C
2523 VecCUDAReplaceArray - Allows one to replace the GPU array in a vector
2524 with a GPU array provided by the user. This is useful to avoid copying
2525 a GPU array into a vector.
2526
2527 Not Collective
2528
2529 Input Parameters:
2530 + vec - the vector
2531 - array - the GPU array
2532
2533 Notes:
2534 This permanently replaces the GPU array and frees the memory associated
2535 with the old GPU array.
2536
2537 The memory passed in CANNOT be freed by the user. It will be freed
2538 when the vector is destroyed.
2539
2540 Not supported from Fortran
2541
2542 Level: developer
2543
2544 .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAPlaceArray(), VecReplaceArray()
2545
2546 @*/
2547 PetscErrorCode VecCUDAReplaceArray(Vec vin,const PetscScalar a[])
2548 {
2549 #if defined(PETSC_HAVE_CUDA)
2550 cudaError_t err;
2551 #endif
2552 PetscErrorCode ierr;
2553
2554 PetscFunctionBegin;
2555 PetscCheckTypeNames(vin,VECSEQCUDA,VECMPICUDA);
2556 #if defined(PETSC_HAVE_CUDA)
2557 err = cudaFree(((Vec_CUDA*)vin->spptr)->GPUarray);CHKERRCUDA(err);
2558 ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar*)a;
2559 vin->offloadmask = PETSC_OFFLOAD_GPU;
2560 #endif
2561 ierr = PetscObjectStateIncrease((PetscObject)vin);CHKERRQ(ierr);
2562 PetscFunctionReturn(0);
2563 }
2564
2565 /*@C
2566 VecCUDAResetArray - Resets a vector to use its default memory. Call this
2567 after the use of VecCUDAPlaceArray().
2568
2569 Not Collective
2570
2571 Input Parameters:
2572 . vec - the vector
2573
2574 Level: developer
2575
2576 .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray(), VecResetArray(), VecCUDAPlaceArray(), VecCUDAReplaceArray()
2577
2578 @*/
2579 PetscErrorCode VecCUDAResetArray(Vec vin)
2580 {
2581 PetscErrorCode ierr;
2582
2583 PetscFunctionBegin;
2584 PetscCheckTypeNames(vin,VECSEQCUDA,VECMPICUDA);
2585 #if defined(PETSC_HAVE_CUDA)
2586 ierr = VecCUDACopyToGPU(vin);CHKERRQ(ierr);
2587 ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar *) ((Vec_Seq*)vin->data)->unplacedarray;
2588 ((Vec_Seq*)vin->data)->unplacedarray = 0;
2589 vin->offloadmask = PETSC_OFFLOAD_GPU;
2590 #endif
2591 ierr = PetscObjectStateIncrease((PetscObject)vin);CHKERRQ(ierr);
2592 PetscFunctionReturn(0);
2593 }
2594
2595 /*MC
2596 VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
2597 and makes them accessible via a Fortran90 pointer.
2598
2599 Synopsis:
2600 VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
2601
2602 Collective on Vec
2603
2604 Input Parameters:
2605 + x - a vector to mimic
2606 - n - the number of vectors to obtain
2607
2608 Output Parameters:
2609 + y - Fortran90 pointer to the array of vectors
2610 - ierr - error code
2611
2612 Example of Usage:
2613 .vb
2614 #include <petsc/finclude/petscvec.h>
2615 use petscvec
2616
2617 Vec x
2618 Vec, pointer :: y(:)
2619 ....
2620 call VecDuplicateVecsF90(x,2,y,ierr)
2621 call VecSet(y(2),alpha,ierr)
2622 call VecSet(y(2),alpha,ierr)
2623 ....
2624 call VecDestroyVecsF90(2,y,ierr)
2625 .ve
2626
2627 Notes:
2628 Not yet supported for all F90 compilers
2629
2630 Use VecDestroyVecsF90() to free the space.
2631
2632 Level: beginner
2633
2634 .seealso: VecDestroyVecsF90(), VecDuplicateVecs()
2635
2636 M*/
2637
2638 /*MC
2639 VecRestoreArrayF90 - Restores a vector to a usable state after a call to
2640 VecGetArrayF90().
2641
2642 Synopsis:
2643 VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2644
2645 Logically Collective on Vec
2646
2647 Input Parameters:
2648 + x - vector
2649 - xx_v - the Fortran90 pointer to the array
2650
2651 Output Parameter:
2652 . ierr - error code
2653
2654 Example of Usage:
2655 .vb
2656 #include <petsc/finclude/petscvec.h>
2657 use petscvec
2658
2659 PetscScalar, pointer :: xx_v(:)
2660 ....
2661 call VecGetArrayF90(x,xx_v,ierr)
2662 xx_v(3) = a
2663 call VecRestoreArrayF90(x,xx_v,ierr)
2664 .ve
2665
2666 Level: beginner
2667
2668 .seealso: VecGetArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran, VecRestoreArrayReadF90()
2669
2670 M*/
2671
2672 /*MC
2673 VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().
2674
2675 Synopsis:
2676 VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
2677
2678 Collective on Vec
2679
2680 Input Parameters:
2681 + n - the number of vectors previously obtained
2682 - x - pointer to array of vector pointers
2683
2684 Output Parameter:
2685 . ierr - error code
2686
2687 Notes:
2688 Not yet supported for all F90 compilers
2689
2690 Level: beginner
2691
2692 .seealso: VecDestroyVecs(), VecDuplicateVecsF90()
2693
2694 M*/
2695
2696 /*MC
2697 VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
2698 vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
2699 this routine is implementation dependent. You MUST call VecRestoreArrayF90()
2700 when you no longer need access to the array.
2701
2702 Synopsis:
2703 VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2704
2705 Logically Collective on Vec
2706
2707 Input Parameter:
2708 . x - vector
2709
2710 Output Parameters:
2711 + xx_v - the Fortran90 pointer to the array
2712 - ierr - error code
2713
2714 Example of Usage:
2715 .vb
2716 #include <petsc/finclude/petscvec.h>
2717 use petscvec
2718
2719 PetscScalar, pointer :: xx_v(:)
2720 ....
2721 call VecGetArrayF90(x,xx_v,ierr)
2722 xx_v(3) = a
2723 call VecRestoreArrayF90(x,xx_v,ierr)
2724 .ve
2725
2726 If you ONLY intend to read entries from the array and not change any entries you should use VecGetArrayReadF90().
2727
2728 Level: beginner
2729
2730 .seealso: VecRestoreArrayF90(), VecGetArray(), VecRestoreArray(), VecGetArrayReadF90(), UsingFortran
2731
2732 M*/
2733
2734 /*MC
2735 VecGetArrayReadF90 - Accesses a read only array from Fortran90. For default PETSc
2736 vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
2737 this routine is implementation dependent. You MUST call VecRestoreArrayReadF90()
2738 when you no longer need access to the array.
2739
2740 Synopsis:
2741 VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2742
2743 Logically Collective on Vec
2744
2745 Input Parameter:
2746 . x - vector
2747
2748 Output Parameters:
2749 + xx_v - the Fortran90 pointer to the array
2750 - ierr - error code
2751
2752 Example of Usage:
2753 .vb
2754 #include <petsc/finclude/petscvec.h>
2755 use petscvec
2756
2757 PetscScalar, pointer :: xx_v(:)
2758 ....
2759 call VecGetArrayReadF90(x,xx_v,ierr)
2760 a = xx_v(3)
2761 call VecRestoreArrayReadF90(x,xx_v,ierr)
2762 .ve
2763
2764 If you intend to write entries into the array you must use VecGetArrayF90().
2765
2766 Level: beginner
2767
2768 .seealso: VecRestoreArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(), VecGetArrayF90(), UsingFortran
2769
2770 M*/
2771
2772 /*MC
2773 VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
2774 VecGetArrayReadF90().
2775
2776 Synopsis:
2777 VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2778
2779 Logically Collective on Vec
2780
2781 Input Parameters:
2782 + x - vector
2783 - xx_v - the Fortran90 pointer to the array
2784
2785 Output Parameter:
2786 . ierr - error code
2787
2788 Example of Usage:
2789 .vb
2790 #include <petsc/finclude/petscvec.h>
2791 use petscvec
2792
2793 PetscScalar, pointer :: xx_v(:)
2794 ....
2795 call VecGetArrayReadF90(x,xx_v,ierr)
2796 a = xx_v(3)
2797 call VecRestoreArrayReadF90(x,xx_v,ierr)
2798 .ve
2799
2800 Level: beginner
2801
2802 .seealso: VecGetArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(),UsingFortran, VecRestoreArrayF90()
2803
2804 M*/
2805
2806 /*@C
2807 VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
2808 processor's portion of the vector data. You MUST call VecRestoreArray2d()
2809 when you no longer need access to the array.
2810
2811 Logically Collective
2812
2813 Input Parameter:
2814 + x - the vector
2815 . m - first dimension of two dimensional array
2816 . n - second dimension of two dimensional array
2817 . mstart - first index you will use in first coordinate direction (often 0)
2818 - nstart - first index in the second coordinate direction (often 0)
2819
2820 Output Parameter:
2821 . a - location to put pointer to the array
2822
2823 Level: developer
2824
2825 Notes:
2826 For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
2827 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2828 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2829 the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
2830
2831 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2832
2833 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2834 VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2835 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2836 @*/
2837 PetscErrorCode VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2838 {
2839 PetscErrorCode ierr;
2840 PetscInt i,N;
2841 PetscScalar *aa;
2842
2843 PetscFunctionBegin;
2844 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
2845 PetscValidPointer(a,6);
2846 PetscValidType(x,1);
2847 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
2848 if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
2849 ierr = VecGetArray(x,&aa);CHKERRQ(ierr);
2850
2851 ierr = PetscMalloc1(m,a);CHKERRQ(ierr);
2852 for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
2853 *a -= mstart;
2854 PetscFunctionReturn(0);
2855 }
2856
2857 /*@C
2858 VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
2859 processor's portion of the vector data. You MUST call VecRestoreArray2dWrite()
2860 when you no longer need access to the array.
2861
2862 Logically Collective
2863
2864 Input Parameter:
2865 + x - the vector
2866 . m - first dimension of two dimensional array
2867 . n - second dimension of two dimensional array
2868 . mstart - first index you will use in first coordinate direction (often 0)
2869 - nstart - first index in the second coordinate direction (often 0)
2870
2871 Output Parameter:
2872 . a - location to put pointer to the array
2873
2874 Level: developer
2875
2876 Notes:
2877 For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
2878 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2879 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2880 the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
2881
2882 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2883
2884 Concepts: vector^accessing local values as 2d array
2885
2886 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2887 VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2888 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2889 @*/
2890 PetscErrorCode VecGetArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2891 {
2892 PetscErrorCode ierr;
2893 PetscInt i,N;
2894 PetscScalar *aa;
2895
2896 PetscFunctionBegin;
2897 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
2898 PetscValidPointer(a,6);
2899 PetscValidType(x,1);
2900 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
2901 if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
2902 ierr = VecGetArrayWrite(x,&aa);CHKERRQ(ierr);
2903
2904 ierr = PetscMalloc1(m,a);CHKERRQ(ierr);
2905 for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
2906 *a -= mstart;
2907 PetscFunctionReturn(0);
2908 }
2909
2910 /*@C
2911 VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.
2912
2913 Logically Collective
2914
2915 Input Parameters:
2916 + x - the vector
2917 . m - first dimension of two dimensional array
2918 . n - second dimension of the two dimensional array
2919 . mstart - first index you will use in first coordinate direction (often 0)
2920 . nstart - first index in the second coordinate direction (often 0)
2921 - a - location of pointer to array obtained from VecGetArray2d()
2922
2923 Level: developer
2924
2925 Notes:
2926 For regular PETSc vectors this routine does not involve any copies. For
2927 any special vectors that do not store local vector data in a contiguous
2928 array, this routine will copy the data back into the underlying
2929 vector data structure from the array obtained with VecGetArray().
2930
2931 This routine actually zeros out the a pointer.
2932
2933 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2934 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2935 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2936 @*/
2937 PetscErrorCode VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2938 {
2939 PetscErrorCode ierr;
2940 void *dummy;
2941
2942 PetscFunctionBegin;
2943 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
2944 PetscValidPointer(a,6);
2945 PetscValidType(x,1);
2946 dummy = (void*)(*a + mstart);
2947 ierr = PetscFree(dummy);CHKERRQ(ierr);
2948 ierr = VecRestoreArray(x,NULL);CHKERRQ(ierr);
2949 PetscFunctionReturn(0);
2950 }
2951
2952 /*@C
2953 VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite() has been called.
2954
2955 Logically Collective
2956
2957 Input Parameters:
2958 + x - the vector
2959 . m - first dimension of two dimensional array
2960 . n - second dimension of the two dimensional array
2961 . mstart - first index you will use in first coordinate direction (often 0)
2962 . nstart - first index in the second coordinate direction (often 0)
2963 - a - location of pointer to array obtained from VecGetArray2d()
2964
2965 Level: developer
2966
2967 Notes:
2968 For regular PETSc vectors this routine does not involve any copies. For
2969 any special vectors that do not store local vector data in a contiguous
2970 array, this routine will copy the data back into the underlying
2971 vector data structure from the array obtained with VecGetArray().
2972
2973 This routine actually zeros out the a pointer.
2974
2975 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2976 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2977 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2978 @*/
2979 PetscErrorCode VecRestoreArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2980 {
2981 PetscErrorCode ierr;
2982 void *dummy;
2983
2984 PetscFunctionBegin;
2985 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
2986 PetscValidPointer(a,6);
2987 PetscValidType(x,1);
2988 dummy = (void*)(*a + mstart);
2989 ierr = PetscFree(dummy);CHKERRQ(ierr);
2990 ierr = VecRestoreArrayWrite(x,NULL);CHKERRQ(ierr);
2991 PetscFunctionReturn(0);
2992 }
2993
2994 /*@C
2995 VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
2996 processor's portion of the vector data. You MUST call VecRestoreArray1d()
2997 when you no longer need access to the array.
2998
2999 Logically Collective
3000
3001 Input Parameter:
3002 + x - the vector
3003 . m - first dimension of two dimensional array
3004 - mstart - first index you will use in first coordinate direction (often 0)
3005
3006 Output Parameter:
3007 . a - location to put pointer to the array
3008
3009 Level: developer
3010
3011 Notes:
3012 For a vector obtained from DMCreateLocalVector() mstart are likely
3013 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3014 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3015
3016 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3017
3018 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3019 VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3020 VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3021 @*/
3022 PetscErrorCode VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3023 {
3024 PetscErrorCode ierr;
3025 PetscInt N;
3026
3027 PetscFunctionBegin;
3028 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3029 PetscValidPointer(a,4);
3030 PetscValidType(x,1);
3031 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3032 if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
3033 ierr = VecGetArray(x,a);CHKERRQ(ierr);
3034 *a -= mstart;
3035 PetscFunctionReturn(0);
3036 }
3037
3038 /*@C
3039 VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
3040 processor's portion of the vector data. You MUST call VecRestoreArray1dWrite()
3041 when you no longer need access to the array.
3042
3043 Logically Collective
3044
3045 Input Parameter:
3046 + x - the vector
3047 . m - first dimension of two dimensional array
3048 - mstart - first index you will use in first coordinate direction (often 0)
3049
3050 Output Parameter:
3051 . a - location to put pointer to the array
3052
3053 Level: developer
3054
3055 Notes:
3056 For a vector obtained from DMCreateLocalVector() mstart are likely
3057 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3058 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3059
3060 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3061
3062 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3063 VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3064 VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3065 @*/
3066 PetscErrorCode VecGetArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3067 {
3068 PetscErrorCode ierr;
3069 PetscInt N;
3070
3071 PetscFunctionBegin;
3072 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3073 PetscValidPointer(a,4);
3074 PetscValidType(x,1);
3075 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3076 if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
3077 ierr = VecGetArrayWrite(x,a);CHKERRQ(ierr);
3078 *a -= mstart;
3079 PetscFunctionReturn(0);
3080 }
3081
3082 /*@C
3083 VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.
3084
3085 Logically Collective
3086
3087 Input Parameters:
3088 + x - the vector
3089 . m - first dimension of two dimensional array
3090 . mstart - first index you will use in first coordinate direction (often 0)
3091 - a - location of pointer to array obtained from VecGetArray21()
3092
3093 Level: developer
3094
3095 Notes:
3096 For regular PETSc vectors this routine does not involve any copies. For
3097 any special vectors that do not store local vector data in a contiguous
3098 array, this routine will copy the data back into the underlying
3099 vector data structure from the array obtained with VecGetArray1d().
3100
3101 This routine actually zeros out the a pointer.
3102
3103 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3104 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3105 VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3106 @*/
3107 PetscErrorCode VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3108 {
3109 PetscErrorCode ierr;
3110
3111 PetscFunctionBegin;
3112 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3113 PetscValidType(x,1);
3114 ierr = VecRestoreArray(x,NULL);CHKERRQ(ierr);
3115 PetscFunctionReturn(0);
3116 }
3117
3118 /*@C
3119 VecRestoreArray1dWrite - Restores a vector after VecGetArray1dWrite() has been called.
3120
3121 Logically Collective
3122
3123 Input Parameters:
3124 + x - the vector
3125 . m - first dimension of two dimensional array
3126 . mstart - first index you will use in first coordinate direction (often 0)
3127 - a - location of pointer to array obtained from VecGetArray21()
3128
3129 Level: developer
3130
3131 Notes:
3132 For regular PETSc vectors this routine does not involve any copies. For
3133 any special vectors that do not store local vector data in a contiguous
3134 array, this routine will copy the data back into the underlying
3135 vector data structure from the array obtained with VecGetArray1d().
3136
3137 This routine actually zeros out the a pointer.
3138
3139 Concepts: vector^accessing local values as 1d array
3140
3141 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3142 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3143 VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3144 @*/
3145 PetscErrorCode VecRestoreArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3146 {
3147 PetscErrorCode ierr;
3148
3149 PetscFunctionBegin;
3150 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3151 PetscValidType(x,1);
3152 ierr = VecRestoreArrayWrite(x,NULL);CHKERRQ(ierr);
3153 PetscFunctionReturn(0);
3154 }
3155
3156 /*@C
3157 VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
3158 processor's portion of the vector data. You MUST call VecRestoreArray3d()
3159 when you no longer need access to the array.
3160
3161 Logically Collective
3162
3163 Input Parameter:
3164 + x - the vector
3165 . m - first dimension of three dimensional array
3166 . n - second dimension of three dimensional array
3167 . p - third dimension of three dimensional array
3168 . mstart - first index you will use in first coordinate direction (often 0)
3169 . nstart - first index in the second coordinate direction (often 0)
3170 - pstart - first index in the third coordinate direction (often 0)
3171
3172 Output Parameter:
3173 . a - location to put pointer to the array
3174
3175 Level: developer
3176
3177 Notes:
3178 For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3179 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3180 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3181 the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3182
3183 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3184
3185 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3186 VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3187 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3188 @*/
3189 PetscErrorCode VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3190 {
3191 PetscErrorCode ierr;
3192 PetscInt i,N,j;
3193 PetscScalar *aa,**b;
3194
3195 PetscFunctionBegin;
3196 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3197 PetscValidPointer(a,8);
3198 PetscValidType(x,1);
3199 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3200 if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
3201 ierr = VecGetArray(x,&aa);CHKERRQ(ierr);
3202
3203 ierr = PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);CHKERRQ(ierr);
3204 b = (PetscScalar**)((*a) + m);
3205 for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3206 for (i=0; i<m; i++)
3207 for (j=0; j<n; j++)
3208 b[i*n+j] = aa + i*n*p + j*p - pstart;
3209
3210 *a -= mstart;
3211 PetscFunctionReturn(0);
3212 }
3213
3214 /*@C
3215 VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3216 processor's portion of the vector data. You MUST call VecRestoreArray3dWrite()
3217 when you no longer need access to the array.
3218
3219 Logically Collective
3220
3221 Input Parameter:
3222 + x - the vector
3223 . m - first dimension of three dimensional array
3224 . n - second dimension of three dimensional array
3225 . p - third dimension of three dimensional array
3226 . mstart - first index you will use in first coordinate direction (often 0)
3227 . nstart - first index in the second coordinate direction (often 0)
3228 - pstart - first index in the third coordinate direction (often 0)
3229
3230 Output Parameter:
3231 . a - location to put pointer to the array
3232
3233 Level: developer
3234
3235 Notes:
3236 For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3237 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3238 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3239 the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3240
3241 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3242
3243 Concepts: vector^accessing local values as 3d array
3244
3245 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3246 VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3247 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3248 @*/
3249 PetscErrorCode VecGetArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3250 {
3251 PetscErrorCode ierr;
3252 PetscInt i,N,j;
3253 PetscScalar *aa,**b;
3254
3255 PetscFunctionBegin;
3256 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3257 PetscValidPointer(a,8);
3258 PetscValidType(x,1);
3259 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3260 if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
3261 ierr = VecGetArrayWrite(x,&aa);CHKERRQ(ierr);
3262
3263 ierr = PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);CHKERRQ(ierr);
3264 b = (PetscScalar**)((*a) + m);
3265 for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3266 for (i=0; i<m; i++)
3267 for (j=0; j<n; j++)
3268 b[i*n+j] = aa + i*n*p + j*p - pstart;
3269
3270 *a -= mstart;
3271 PetscFunctionReturn(0);
3272 }
3273
3274 /*@C
3275 VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.
3276
3277 Logically Collective
3278
3279 Input Parameters:
3280 + x - the vector
3281 . m - first dimension of three dimensional array
3282 . n - second dimension of the three dimensional array
3283 . p - third dimension of the three dimensional array
3284 . mstart - first index you will use in first coordinate direction (often 0)
3285 . nstart - first index in the second coordinate direction (often 0)
3286 . pstart - first index in the third coordinate direction (often 0)
3287 - a - location of pointer to array obtained from VecGetArray3d()
3288
3289 Level: developer
3290
3291 Notes:
3292 For regular PETSc vectors this routine does not involve any copies. For
3293 any special vectors that do not store local vector data in a contiguous
3294 array, this routine will copy the data back into the underlying
3295 vector data structure from the array obtained with VecGetArray().
3296
3297 This routine actually zeros out the a pointer.
3298
3299 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3300 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3301 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3302 @*/
3303 PetscErrorCode VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3304 {
3305 PetscErrorCode ierr;
3306 void *dummy;
3307
3308 PetscFunctionBegin;
3309 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3310 PetscValidPointer(a,8);
3311 PetscValidType(x,1);
3312 dummy = (void*)(*a + mstart);
3313 ierr = PetscFree(dummy);CHKERRQ(ierr);
3314 ierr = VecRestoreArray(x,NULL);CHKERRQ(ierr);
3315 PetscFunctionReturn(0);
3316 }
3317
3318 /*@C
3319 VecRestoreArray3dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3320
3321 Logically Collective
3322
3323 Input Parameters:
3324 + x - the vector
3325 . m - first dimension of three dimensional array
3326 . n - second dimension of the three dimensional array
3327 . p - third dimension of the three dimensional array
3328 . mstart - first index you will use in first coordinate direction (often 0)
3329 . nstart - first index in the second coordinate direction (often 0)
3330 . pstart - first index in the third coordinate direction (often 0)
3331 - a - location of pointer to array obtained from VecGetArray3d()
3332
3333 Level: developer
3334
3335 Notes:
3336 For regular PETSc vectors this routine does not involve any copies. For
3337 any special vectors that do not store local vector data in a contiguous
3338 array, this routine will copy the data back into the underlying
3339 vector data structure from the array obtained with VecGetArray().
3340
3341 This routine actually zeros out the a pointer.
3342
3343 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3344 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3345 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3346 @*/
3347 PetscErrorCode VecRestoreArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3348 {
3349 PetscErrorCode ierr;
3350 void *dummy;
3351
3352 PetscFunctionBegin;
3353 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3354 PetscValidPointer(a,8);
3355 PetscValidType(x,1);
3356 dummy = (void*)(*a + mstart);
3357 ierr = PetscFree(dummy);CHKERRQ(ierr);
3358 ierr = VecRestoreArrayWrite(x,NULL);CHKERRQ(ierr);
3359 PetscFunctionReturn(0);
3360 }
3361
3362 /*@C
3363 VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
3364 processor's portion of the vector data. You MUST call VecRestoreArray4d()
3365 when you no longer need access to the array.
3366
3367 Logically Collective
3368
3369 Input Parameter:
3370 + x - the vector
3371 . m - first dimension of four dimensional array
3372 . n - second dimension of four dimensional array
3373 . p - third dimension of four dimensional array
3374 . q - fourth dimension of four dimensional array
3375 . mstart - first index you will use in first coordinate direction (often 0)
3376 . nstart - first index in the second coordinate direction (often 0)
3377 . pstart - first index in the third coordinate direction (often 0)
3378 - qstart - first index in the fourth coordinate direction (often 0)
3379
3380 Output Parameter:
3381 . a - location to put pointer to the array
3382
3383 Level: beginner
3384
3385 Notes:
3386 For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3387 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3388 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3389 the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3390
3391 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3392
3393 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3394 VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3395 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3396 @*/
3397 PetscErrorCode VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3398 {
3399 PetscErrorCode ierr;
3400 PetscInt i,N,j,k;
3401 PetscScalar *aa,***b,**c;
3402
3403 PetscFunctionBegin;
3404 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3405 PetscValidPointer(a,10);
3406 PetscValidType(x,1);
3407 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3408 if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,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);
3409 ierr = VecGetArray(x,&aa);CHKERRQ(ierr);
3410
3411 ierr = PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);CHKERRQ(ierr);
3412 b = (PetscScalar***)((*a) + m);
3413 c = (PetscScalar**)(b + m*n);
3414 for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3415 for (i=0; i<m; i++)
3416 for (j=0; j<n; j++)
3417 b[i*n+j] = c + i*n*p + j*p - pstart;
3418 for (i=0; i<m; i++)
3419 for (j=0; j<n; j++)
3420 for (k=0; k<p; k++)
3421 c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3422 *a -= mstart;
3423 PetscFunctionReturn(0);
3424 }
3425
3426 /*@C
3427 VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3428 processor's portion of the vector data. You MUST call VecRestoreArray4dWrite()
3429 when you no longer need access to the array.
3430
3431 Logically Collective
3432
3433 Input Parameter:
3434 + x - the vector
3435 . m - first dimension of four dimensional array
3436 . n - second dimension of four dimensional array
3437 . p - third dimension of four dimensional array
3438 . q - fourth dimension of four dimensional array
3439 . mstart - first index you will use in first coordinate direction (often 0)
3440 . nstart - first index in the second coordinate direction (often 0)
3441 . pstart - first index in the third coordinate direction (often 0)
3442 - qstart - first index in the fourth coordinate direction (often 0)
3443
3444 Output Parameter:
3445 . a - location to put pointer to the array
3446
3447 Level: beginner
3448
3449 Notes:
3450 For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3451 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3452 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3453 the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3454
3455 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3456
3457 Concepts: vector^accessing local values as 3d array
3458
3459 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3460 VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3461 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3462 @*/
3463 PetscErrorCode VecGetArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3464 {
3465 PetscErrorCode ierr;
3466 PetscInt i,N,j,k;
3467 PetscScalar *aa,***b,**c;
3468
3469 PetscFunctionBegin;
3470 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3471 PetscValidPointer(a,10);
3472 PetscValidType(x,1);
3473 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3474 if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,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);
3475 ierr = VecGetArrayWrite(x,&aa);CHKERRQ(ierr);
3476
3477 ierr = PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);CHKERRQ(ierr);
3478 b = (PetscScalar***)((*a) + m);
3479 c = (PetscScalar**)(b + m*n);
3480 for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3481 for (i=0; i<m; i++)
3482 for (j=0; j<n; j++)
3483 b[i*n+j] = c + i*n*p + j*p - pstart;
3484 for (i=0; i<m; i++)
3485 for (j=0; j<n; j++)
3486 for (k=0; k<p; k++)
3487 c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3488 *a -= mstart;
3489 PetscFunctionReturn(0);
3490 }
3491
3492 /*@C
3493 VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.
3494
3495 Logically Collective
3496
3497 Input Parameters:
3498 + x - the vector
3499 . m - first dimension of four dimensional array
3500 . n - second dimension of the four dimensional array
3501 . p - third dimension of the four dimensional array
3502 . q - fourth dimension of the four dimensional array
3503 . mstart - first index you will use in first coordinate direction (often 0)
3504 . nstart - first index in the second coordinate direction (often 0)
3505 . pstart - first index in the third coordinate direction (often 0)
3506 . qstart - first index in the fourth coordinate direction (often 0)
3507 - a - location of pointer to array obtained from VecGetArray4d()
3508
3509 Level: beginner
3510
3511 Notes:
3512 For regular PETSc vectors this routine does not involve any copies. For
3513 any special vectors that do not store local vector data in a contiguous
3514 array, this routine will copy the data back into the underlying
3515 vector data structure from the array obtained with VecGetArray().
3516
3517 This routine actually zeros out the a pointer.
3518
3519 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3520 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3521 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3522 @*/
3523 PetscErrorCode VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3524 {
3525 PetscErrorCode ierr;
3526 void *dummy;
3527
3528 PetscFunctionBegin;
3529 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3530 PetscValidPointer(a,8);
3531 PetscValidType(x,1);
3532 dummy = (void*)(*a + mstart);
3533 ierr = PetscFree(dummy);CHKERRQ(ierr);
3534 ierr = VecRestoreArray(x,NULL);CHKERRQ(ierr);
3535 PetscFunctionReturn(0);
3536 }
3537
3538 /*@C
3539 VecRestoreArray4dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3540
3541 Logically Collective
3542
3543 Input Parameters:
3544 + x - the vector
3545 . m - first dimension of four dimensional array
3546 . n - second dimension of the four dimensional array
3547 . p - third dimension of the four dimensional array
3548 . q - fourth dimension of the four dimensional array
3549 . mstart - first index you will use in first coordinate direction (often 0)
3550 . nstart - first index in the second coordinate direction (often 0)
3551 . pstart - first index in the third coordinate direction (often 0)
3552 . qstart - first index in the fourth coordinate direction (often 0)
3553 - a - location of pointer to array obtained from VecGetArray4d()
3554
3555 Level: beginner
3556
3557 Notes:
3558 For regular PETSc vectors this routine does not involve any copies. For
3559 any special vectors that do not store local vector data in a contiguous
3560 array, this routine will copy the data back into the underlying
3561 vector data structure from the array obtained with VecGetArray().
3562
3563 This routine actually zeros out the a pointer.
3564
3565 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3566 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3567 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3568 @*/
3569 PetscErrorCode VecRestoreArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3570 {
3571 PetscErrorCode ierr;
3572 void *dummy;
3573
3574 PetscFunctionBegin;
3575 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3576 PetscValidPointer(a,8);
3577 PetscValidType(x,1);
3578 dummy = (void*)(*a + mstart);
3579 ierr = PetscFree(dummy);CHKERRQ(ierr);
3580 ierr = VecRestoreArrayWrite(x,NULL);CHKERRQ(ierr);
3581 PetscFunctionReturn(0);
3582 }
3583
3584 /*@C
3585 VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3586 processor's portion of the vector data. You MUST call VecRestoreArray2dRead()
3587 when you no longer need access to the array.
3588
3589 Logically Collective
3590
3591 Input Parameter:
3592 + x - the vector
3593 . m - first dimension of two dimensional array
3594 . n - second dimension of two dimensional array
3595 . mstart - first index you will use in first coordinate direction (often 0)
3596 - nstart - first index in the second coordinate direction (often 0)
3597
3598 Output Parameter:
3599 . a - location to put pointer to the array
3600
3601 Level: developer
3602
3603 Notes:
3604 For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3605 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3606 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3607 the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3608
3609 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3610
3611 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3612 VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3613 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3614 @*/
3615 PetscErrorCode VecGetArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3616 {
3617 PetscErrorCode ierr;
3618 PetscInt i,N;
3619 const PetscScalar *aa;
3620
3621 PetscFunctionBegin;
3622 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3623 PetscValidPointer(a,6);
3624 PetscValidType(x,1);
3625 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3626 if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
3627 ierr = VecGetArrayRead(x,&aa);CHKERRQ(ierr);
3628
3629 ierr = PetscMalloc1(m,a);CHKERRQ(ierr);
3630 for (i=0; i<m; i++) (*a)[i] = (PetscScalar*) aa + i*n - nstart;
3631 *a -= mstart;
3632 PetscFunctionReturn(0);
3633 }
3634
3635 /*@C
3636 VecRestoreArray2dRead - Restores a vector after VecGetArray2dRead() has been called.
3637
3638 Logically Collective
3639
3640 Input Parameters:
3641 + x - the vector
3642 . m - first dimension of two dimensional array
3643 . n - second dimension of the two dimensional array
3644 . mstart - first index you will use in first coordinate direction (often 0)
3645 . nstart - first index in the second coordinate direction (often 0)
3646 - a - location of pointer to array obtained from VecGetArray2d()
3647
3648 Level: developer
3649
3650 Notes:
3651 For regular PETSc vectors this routine does not involve any copies. For
3652 any special vectors that do not store local vector data in a contiguous
3653 array, this routine will copy the data back into the underlying
3654 vector data structure from the array obtained with VecGetArray().
3655
3656 This routine actually zeros out the a pointer.
3657
3658 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3659 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3660 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3661 @*/
3662 PetscErrorCode VecRestoreArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3663 {
3664 PetscErrorCode ierr;
3665 void *dummy;
3666
3667 PetscFunctionBegin;
3668 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3669 PetscValidPointer(a,6);
3670 PetscValidType(x,1);
3671 dummy = (void*)(*a + mstart);
3672 ierr = PetscFree(dummy);CHKERRQ(ierr);
3673 ierr = VecRestoreArrayRead(x,NULL);CHKERRQ(ierr);
3674 PetscFunctionReturn(0);
3675 }
3676
3677 /*@C
3678 VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
3679 processor's portion of the vector data. You MUST call VecRestoreArray1dRead()
3680 when you no longer need access to the array.
3681
3682 Logically Collective
3683
3684 Input Parameter:
3685 + x - the vector
3686 . m - first dimension of two dimensional array
3687 - mstart - first index you will use in first coordinate direction (often 0)
3688
3689 Output Parameter:
3690 . a - location to put pointer to the array
3691
3692 Level: developer
3693
3694 Notes:
3695 For a vector obtained from DMCreateLocalVector() mstart are likely
3696 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3697 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3698
3699 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3700
3701 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3702 VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3703 VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3704 @*/
3705 PetscErrorCode VecGetArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3706 {
3707 PetscErrorCode ierr;
3708 PetscInt N;
3709
3710 PetscFunctionBegin;
3711 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3712 PetscValidPointer(a,4);
3713 PetscValidType(x,1);
3714 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3715 if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
3716 ierr = VecGetArrayRead(x,(const PetscScalar**)a);CHKERRQ(ierr);
3717 *a -= mstart;
3718 PetscFunctionReturn(0);
3719 }
3720
3721 /*@C
3722 VecRestoreArray1dRead - Restores a vector after VecGetArray1dRead() has been called.
3723
3724 Logically Collective
3725
3726 Input Parameters:
3727 + x - the vector
3728 . m - first dimension of two dimensional array
3729 . mstart - first index you will use in first coordinate direction (often 0)
3730 - a - location of pointer to array obtained from VecGetArray21()
3731
3732 Level: developer
3733
3734 Notes:
3735 For regular PETSc vectors this routine does not involve any copies. For
3736 any special vectors that do not store local vector data in a contiguous
3737 array, this routine will copy the data back into the underlying
3738 vector data structure from the array obtained with VecGetArray1dRead().
3739
3740 This routine actually zeros out the a pointer.
3741
3742 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3743 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3744 VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3745 @*/
3746 PetscErrorCode VecRestoreArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3747 {
3748 PetscErrorCode ierr;
3749
3750 PetscFunctionBegin;
3751 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3752 PetscValidType(x,1);
3753 ierr = VecRestoreArrayRead(x,NULL);CHKERRQ(ierr);
3754 PetscFunctionReturn(0);
3755 }
3756
3757
3758 /*@C
3759 VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
3760 processor's portion of the vector data. You MUST call VecRestoreArray3dRead()
3761 when you no longer need access to the array.
3762
3763 Logically Collective
3764
3765 Input Parameter:
3766 + x - the vector
3767 . m - first dimension of three dimensional array
3768 . n - second dimension of three dimensional array
3769 . p - third dimension of three dimensional array
3770 . mstart - first index you will use in first coordinate direction (often 0)
3771 . nstart - first index in the second coordinate direction (often 0)
3772 - pstart - first index in the third coordinate direction (often 0)
3773
3774 Output Parameter:
3775 . a - location to put pointer to the array
3776
3777 Level: developer
3778
3779 Notes:
3780 For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3781 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3782 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3783 the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3dRead().
3784
3785 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3786
3787 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3788 VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3789 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3790 @*/
3791 PetscErrorCode VecGetArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3792 {
3793 PetscErrorCode ierr;
3794 PetscInt i,N,j;
3795 const PetscScalar *aa;
3796 PetscScalar **b;
3797
3798 PetscFunctionBegin;
3799 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3800 PetscValidPointer(a,8);
3801 PetscValidType(x,1);
3802 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3803 if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
3804 ierr = VecGetArrayRead(x,&aa);CHKERRQ(ierr);
3805
3806 ierr = PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);CHKERRQ(ierr);
3807 b = (PetscScalar**)((*a) + m);
3808 for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3809 for (i=0; i<m; i++)
3810 for (j=0; j<n; j++)
3811 b[i*n+j] = (PetscScalar *)aa + i*n*p + j*p - pstart;
3812
3813 *a -= mstart;
3814 PetscFunctionReturn(0);
3815 }
3816
3817 /*@C
3818 VecRestoreArray3dRead - Restores a vector after VecGetArray3dRead() has been called.
3819
3820 Logically Collective
3821
3822 Input Parameters:
3823 + x - the vector
3824 . m - first dimension of three dimensional array
3825 . n - second dimension of the three dimensional array
3826 . p - third dimension of the three dimensional array
3827 . mstart - first index you will use in first coordinate direction (often 0)
3828 . nstart - first index in the second coordinate direction (often 0)
3829 . pstart - first index in the third coordinate direction (often 0)
3830 - a - location of pointer to array obtained from VecGetArray3dRead()
3831
3832 Level: developer
3833
3834 Notes:
3835 For regular PETSc vectors this routine does not involve any copies. For
3836 any special vectors that do not store local vector data in a contiguous
3837 array, this routine will copy the data back into the underlying
3838 vector data structure from the array obtained with VecGetArray().
3839
3840 This routine actually zeros out the a pointer.
3841
3842 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3843 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3844 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3845 @*/
3846 PetscErrorCode VecRestoreArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3847 {
3848 PetscErrorCode ierr;
3849 void *dummy;
3850
3851 PetscFunctionBegin;
3852 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3853 PetscValidPointer(a,8);
3854 PetscValidType(x,1);
3855 dummy = (void*)(*a + mstart);
3856 ierr = PetscFree(dummy);CHKERRQ(ierr);
3857 ierr = VecRestoreArrayRead(x,NULL);CHKERRQ(ierr);
3858 PetscFunctionReturn(0);
3859 }
3860
3861 /*@C
3862 VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
3863 processor's portion of the vector data. You MUST call VecRestoreArray4dRead()
3864 when you no longer need access to the array.
3865
3866 Logically Collective
3867
3868 Input Parameter:
3869 + x - the vector
3870 . m - first dimension of four dimensional array
3871 . n - second dimension of four dimensional array
3872 . p - third dimension of four dimensional array
3873 . q - fourth dimension of four dimensional array
3874 . mstart - first index you will use in first coordinate direction (often 0)
3875 . nstart - first index in the second coordinate direction (often 0)
3876 . pstart - first index in the third coordinate direction (often 0)
3877 - qstart - first index in the fourth coordinate direction (often 0)
3878
3879 Output Parameter:
3880 . a - location to put pointer to the array
3881
3882 Level: beginner
3883
3884 Notes:
3885 For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3886 obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3887 DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3888 the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3889
3890 For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3891
3892 .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3893 VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3894 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3895 @*/
3896 PetscErrorCode VecGetArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3897 {
3898 PetscErrorCode ierr;
3899 PetscInt i,N,j,k;
3900 const PetscScalar *aa;
3901 PetscScalar ***b,**c;
3902
3903 PetscFunctionBegin;
3904 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3905 PetscValidPointer(a,10);
3906 PetscValidType(x,1);
3907 ierr = VecGetLocalSize(x,&N);CHKERRQ(ierr);
3908 if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,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);
3909 ierr = VecGetArrayRead(x,&aa);CHKERRQ(ierr);
3910
3911 ierr = PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);CHKERRQ(ierr);
3912 b = (PetscScalar***)((*a) + m);
3913 c = (PetscScalar**)(b + m*n);
3914 for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3915 for (i=0; i<m; i++)
3916 for (j=0; j<n; j++)
3917 b[i*n+j] = c + i*n*p + j*p - pstart;
3918 for (i=0; i<m; i++)
3919 for (j=0; j<n; j++)
3920 for (k=0; k<p; k++)
3921 c[i*n*p+j*p+k] = (PetscScalar*) aa + i*n*p*q + j*p*q + k*q - qstart;
3922 *a -= mstart;
3923 PetscFunctionReturn(0);
3924 }
3925
3926 /*@C
3927 VecRestoreArray4dRead - Restores a vector after VecGetArray3d() has been called.
3928
3929 Logically Collective
3930
3931 Input Parameters:
3932 + x - the vector
3933 . m - first dimension of four dimensional array
3934 . n - second dimension of the four dimensional array
3935 . p - third dimension of the four dimensional array
3936 . q - fourth dimension of the four dimensional array
3937 . mstart - first index you will use in first coordinate direction (often 0)
3938 . nstart - first index in the second coordinate direction (often 0)
3939 . pstart - first index in the third coordinate direction (often 0)
3940 . qstart - first index in the fourth coordinate direction (often 0)
3941 - a - location of pointer to array obtained from VecGetArray4dRead()
3942
3943 Level: beginner
3944
3945 Notes:
3946 For regular PETSc vectors this routine does not involve any copies. For
3947 any special vectors that do not store local vector data in a contiguous
3948 array, this routine will copy the data back into the underlying
3949 vector data structure from the array obtained with VecGetArray().
3950
3951 This routine actually zeros out the a pointer.
3952
3953 .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3954 VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3955 VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3956 @*/
3957 PetscErrorCode VecRestoreArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3958 {
3959 PetscErrorCode ierr;
3960 void *dummy;
3961
3962 PetscFunctionBegin;
3963 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3964 PetscValidPointer(a,8);
3965 PetscValidType(x,1);
3966 dummy = (void*)(*a + mstart);
3967 ierr = PetscFree(dummy);CHKERRQ(ierr);
3968 ierr = VecRestoreArrayRead(x,NULL);CHKERRQ(ierr);
3969 PetscFunctionReturn(0);
3970 }
3971
3972 #if defined(PETSC_USE_DEBUG)
3973
3974 /*@
3975 VecLockGet - Gets the current lock status of a vector
3976
3977 Logically Collective on Vec
3978
3979 Input Parameter:
3980 . x - the vector
3981
3982 Output Parameter:
3983 . state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
3984 locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.
3985
3986 Level: beginner
3987
3988 .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop()
3989 @*/
3990 PetscErrorCode VecLockGet(Vec x,PetscInt *state)
3991 {
3992 PetscFunctionBegin;
3993 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
3994 *state = x->lock;
3995 PetscFunctionReturn(0);
3996 }
3997
3998 /*@
3999 VecLockReadPush - Pushes a read-only lock on a vector to prevent it from writing
4000
4001 Logically Collective on Vec
4002
4003 Input Parameter:
4004 . x - the vector
4005
4006 Notes:
4007 If this is set then calls to VecGetArray() or VecSetValues() or any other routines that change the vectors values will fail.
4008
4009 The call can be nested, i.e., called multiple times on the same vector, but each VecLockReadPush(x) has to have one matching
4010 VecLockReadPop(x), which removes the latest read-only lock.
4011
4012 Level: beginner
4013
4014 .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPop(), VecLockGet()
4015 @*/
4016 PetscErrorCode VecLockReadPush(Vec x)
4017 {
4018 PetscFunctionBegin;
4019 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
4020 if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for exclusive write access but you want to read it");
4021 x->lock++;
4022 PetscFunctionReturn(0);
4023 }
4024
4025 /*@
4026 VecLockReadPop - Pops a read-only lock from a vector
4027
4028 Logically Collective on Vec
4029
4030 Input Parameter:
4031 . x - the vector
4032
4033 Level: beginner
4034
4035 .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockGet()
4036 @*/
4037 PetscErrorCode VecLockReadPop(Vec x)
4038 {
4039 PetscFunctionBegin;
4040 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
4041 x->lock--;
4042 if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector has been unlocked from read-only access too many times");
4043 PetscFunctionReturn(0);
4044 }
4045
4046 /*@C
4047 VecLockWriteSet_Private - Lock or unlock a vector for exclusive read/write access
4048
4049 Logically Collective on Vec
4050
4051 Input Parameter:
4052 + x - the vector
4053 - flg - PETSC_TRUE to lock the vector for writing; PETSC_FALSE to unlock it.
4054
4055 Notes:
4056 The function is usefull in split-phase computations, which usually have a begin phase and an end phase.
4057 One can call VecLockWriteSet_Private(x,PETSC_TRUE) in the begin phase to lock a vector for exclusive
4058 access, and call VecLockWriteSet_Private(x,PETSC_FALSE) in the end phase to unlock the vector from exclusive
4059 access. In this way, one is ensured no other operations can access the vector in between. The code may like
4060
4061
4062 VecGetArray(x,&xdata); // begin phase
4063 VecLockWriteSet_Private(v,PETSC_TRUE);
4064
4065 Other operations, which can not acceess x anymore (they can access xdata, of course)
4066
4067 VecRestoreArray(x,&vdata); // end phase
4068 VecLockWriteSet_Private(v,PETSC_FALSE);
4069
4070 The call can not be nested on the same vector, in other words, one can not call VecLockWriteSet_Private(x,PETSC_TRUE)
4071 again before calling VecLockWriteSet_Private(v,PETSC_FALSE).
4072
4073 Level: beginner
4074
4075 .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop(), VecLockGet()
4076 @*/
4077 PetscErrorCode VecLockWriteSet_Private(Vec x,PetscBool flg)
4078 {
4079 PetscFunctionBegin;
4080 PetscValidHeaderSpecific(x,VEC_CLASSID,1);
4081 if (flg) {
4082 if (x->lock > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for read-only access but you want to write it");
4083 else if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for exclusive write access but you want to write it");
4084 else x->lock = -1;
4085 } else {
4086 if (x->lock != -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is not locked for exclusive write access but you want to unlock it from that");
4087 x->lock = 0;
4088 }
4089 PetscFunctionReturn(0);
4090 }
4091
4092 /*@
4093 VecLockPush - Pushes a read-only lock on a vector to prevent it from writing
4094
4095 Level: deprecated
4096
4097 .seealso: VecLockReadPush()
4098 @*/
4099 PetscErrorCode VecLockPush(Vec x)
4100 {
4101 PetscErrorCode ierr;
4102 PetscFunctionBegin;
4103 ierr = VecLockReadPush(x);CHKERRQ(ierr);
4104 PetscFunctionReturn(0);
4105 }
4106
4107 /*@
4108 VecLockPop - Pops a read-only lock from a vector
4109
4110 Level: deprecated
4111
4112 .seealso: VecLockReadPop()
4113 @*/
4114 PetscErrorCode VecLockPop(Vec x)
4115 {
4116 PetscErrorCode ierr;
4117 PetscFunctionBegin;
4118 ierr = VecLockReadPop(x);CHKERRQ(ierr);
4119 PetscFunctionReturn(0);
4120 }
4121
4122 #endif
4123