4
Some useful vector utility functions.
6
#include "private/vecimpl.h" /*I "petscvec.h" I*/
8
extern MPI_Op VecMax_Local_Op;
9
extern MPI_Op VecMin_Local_Op;
12
#define __FUNCT__ "VecStrideScale"
14
VecStrideScale - Scales a subvector of a vector defined
15
by a starting point and a stride.
21
. start - starting point of the subvector (defined by a stride)
22
- scale - value to multiply each subvector entry by
25
One must call VecSetBlockSize() before this routine to set the stride
26
information, or use a vector created from a multicomponent DA.
28
This will only work if the desire subvector is a stride subvector
32
Concepts: scale^on stride of vector
33
Concepts: stride^scale
35
.seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideScale()
37
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideScale(Vec v,PetscInt start,PetscScalar scale)
44
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
45
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
46
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
50
SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start);
51
} else if (start >= bs) {
52
SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Start of stride subvector (%D) is too large for stride\n\
53
Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs);
57
for (i=0; i<n; i+=bs) {
62
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
63
PetscFunctionReturn(0);
67
#define __FUNCT__ "VecStrideNorm"
69
VecStrideNorm - Computes the norm of subvector of a vector defined
70
by a starting point and a stride.
76
. start - starting point of the subvector (defined by a stride)
77
- ntype - type of norm, one of NORM_1, NORM_2, NORM_INFINITY
83
One must call VecSetBlockSize() before this routine to set the stride
84
information, or use a vector created from a multicomponent DA.
86
If x is the array representing the vector x then this computes the norm
87
of the array (x[start],x[start+stride],x[start+2*stride], ....)
89
This is useful for computing, say the norm of the pressure variable when
90
the pressure is stored (interlaced) with other variables, say density etc.
92
This will only work if the desire subvector is a stride subvector
96
Concepts: norm^on stride of vector
99
.seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax()
101
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideNorm(Vec v,PetscInt start,NormType ntype,PetscReal *nrm)
110
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
111
PetscValidDoublePointer(nrm,3);
112
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
113
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
114
ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr);
118
SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start);
119
} else if (start >= bs) {
120
SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Start of stride subvector (%D) is too large for stride\n\
121
Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs);
125
if (ntype == NORM_2) {
126
PetscScalar sum = 0.0;
127
for (i=0; i<n; i+=bs) {
128
sum += x[i]*(PetscConj(x[i]));
130
tnorm = PetscRealPart(sum);
131
ierr = MPI_Allreduce(&tnorm,nrm,1,MPIU_REAL,MPI_SUM,comm);CHKERRQ(ierr);
133
} else if (ntype == NORM_1) {
135
for (i=0; i<n; i+=bs) {
136
tnorm += PetscAbsScalar(x[i]);
138
ierr = MPI_Allreduce(&tnorm,nrm,1,MPIU_REAL,MPI_SUM,comm);CHKERRQ(ierr);
139
} else if (ntype == NORM_INFINITY) {
143
for (i=0; i<n; i+=bs) {
144
if ((tmp = PetscAbsScalar(x[i])) > tnorm) tnorm = tmp;
145
/* check special case of tmp == NaN */
146
if (tmp != tmp) {tnorm = tmp; break;}
148
ierr = MPI_Allreduce(&tnorm,nrm,1,MPIU_REAL,MPI_MAX,comm);CHKERRQ(ierr);
150
SETERRQ(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown norm type");
153
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
154
PetscFunctionReturn(0);
158
#define __FUNCT__ "VecStrideMax"
160
VecStrideMax - Computes the maximum of subvector of a vector defined
161
by a starting point and a stride and optionally its location.
167
- start - starting point of the subvector (defined by a stride)
170
+ index - the location where the maximum occurred (pass PETSC_NULL if not required)
174
One must call VecSetBlockSize() before this routine to set the stride
175
information, or use a vector created from a multicomponent DA.
177
If xa is the array representing the vector x, then this computes the max
178
of the array (xa[start],xa[start+stride],xa[start+2*stride], ....)
180
This is useful for computing, say the maximum of the pressure variable when
181
the pressure is stored (interlaced) with other variables, e.g., density, etc.
182
This will only work if the desire subvector is a stride subvector.
186
Concepts: maximum^on stride of vector
187
Concepts: stride^maximum
189
.seealso: VecMax(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin()
191
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideMax(Vec v,PetscInt start,PetscInt *idex,PetscReal *nrm)
200
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
201
PetscValidDoublePointer(nrm,3);
203
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
204
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
205
ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr);
209
SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start);
210
} else if (start >= bs) {
211
SETERRQ2(PETSC_ERR_ARG_WRONG,"Start of stride subvector (%D) is too large for stride\n\
212
Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs);
221
#if defined(PETSC_USE_COMPLEX)
222
max = PetscRealPart(x[0]);
226
for (i=bs; i<n; i+=bs) {
227
#if defined(PETSC_USE_COMPLEX)
228
if ((tmp = PetscRealPart(x[i])) > max) { max = tmp; id = i;}
230
if ((tmp = x[i]) > max) { max = tmp; id = i;}
234
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
237
ierr = MPI_Allreduce(&max,nrm,1,MPIU_REAL,MPI_MAX,comm);CHKERRQ(ierr);
239
PetscReal in[2],out[2];
242
ierr = VecGetOwnershipRange(v,&rstart,PETSC_NULL);CHKERRQ(ierr);
244
in[1] = rstart+id+start;
245
ierr = MPI_Allreduce(in,out,2,MPIU_REAL,VecMax_Local_Op,((PetscObject)v)->comm);CHKERRQ(ierr);
247
*idex = (PetscInt)out[1];
250
PetscFunctionReturn(0);
254
#define __FUNCT__ "VecStrideMin"
256
VecStrideMin - Computes the minimum of subvector of a vector defined
257
by a starting point and a stride and optionally its location.
263
- start - starting point of the subvector (defined by a stride)
266
+ idex - the location where the minimum occurred. (pass PETSC_NULL if not required)
272
One must call VecSetBlockSize() before this routine to set the stride
273
information, or use a vector created from a multicomponent DA.
275
If xa is the array representing the vector x, then this computes the min
276
of the array (xa[start],xa[start+stride],xa[start+2*stride], ....)
278
This is useful for computing, say the minimum of the pressure variable when
279
the pressure is stored (interlaced) with other variables, e.g., density, etc.
280
This will only work if the desire subvector is a stride subvector.
282
Concepts: minimum^on stride of vector
283
Concepts: stride^minimum
285
.seealso: VecMin(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMax()
287
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideMin(Vec v,PetscInt start,PetscInt *idex,PetscReal *nrm)
296
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
297
PetscValidDoublePointer(nrm,4);
299
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
300
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
301
ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr);
305
SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start);
306
} else if (start >= bs) {
307
SETERRQ2(PETSC_ERR_ARG_WRONG,"Start of stride subvector (%D) is too large for stride\n\
308
Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs);
317
#if defined(PETSC_USE_COMPLEX)
318
min = PetscRealPart(x[0]);
322
for (i=bs; i<n; i+=bs) {
323
#if defined(PETSC_USE_COMPLEX)
324
if ((tmp = PetscRealPart(x[i])) < min) { min = tmp; id = i;}
326
if ((tmp = x[i]) < min) { min = tmp; id = i;}
330
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
333
ierr = MPI_Allreduce(&min,nrm,1,MPIU_REAL,MPI_MIN,comm);CHKERRQ(ierr);
335
PetscReal in[2],out[2];
338
ierr = VecGetOwnershipRange(v,&rstart,PETSC_NULL);CHKERRQ(ierr);
341
ierr = MPI_Allreduce(in,out,2,MPIU_REAL,VecMin_Local_Op,((PetscObject)v)->comm);CHKERRQ(ierr);
343
*idex = (PetscInt)out[1];
346
PetscFunctionReturn(0);
350
#define __FUNCT__ "VecStrideScaleAll"
352
VecStrideScaleAll - Scales the subvectors of a vector defined
353
by a starting point and a stride.
359
- scales - values to multiply each subvector entry by
362
One must call VecSetBlockSize() before this routine to set the stride
363
information, or use a vector created from a multicomponent DA.
368
Concepts: scale^on stride of vector
369
Concepts: stride^scale
371
.seealso: VecNorm(), VecStrideScale(), VecScale(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax()
373
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideScaleAll(Vec v,PetscScalar *scales)
380
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
381
PetscValidScalarPointer(scales,2);
382
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
383
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
387
/* need to provide optimized code for each bs */
388
for (i=0; i<n; i+=bs) {
389
for (j=0; j<bs; j++) {
393
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
394
PetscFunctionReturn(0);
398
#define __FUNCT__ "VecStrideNormAll"
400
VecStrideNormAll - Computes the norms subvectors of a vector defined
401
by a starting point and a stride.
407
- ntype - type of norm, one of NORM_1, NORM_2, NORM_INFINITY
413
One must call VecSetBlockSize() before this routine to set the stride
414
information, or use a vector created from a multicomponent DA.
416
If x is the array representing the vector x then this computes the norm
417
of the array (x[start],x[start+stride],x[start+2*stride], ....)
419
This is useful for computing, say the norm of the pressure variable when
420
the pressure is stored (interlaced) with other variables, say density etc.
422
This will only work if the desire subvector is a stride subvector
426
Concepts: norm^on stride of vector
427
Concepts: stride^norm
429
.seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax()
431
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideNormAll(Vec v,NormType ntype,PetscReal nrm[])
436
PetscReal tnorm[128];
440
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
441
PetscValidDoublePointer(nrm,3);
442
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
443
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
444
ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr);
447
if (bs > 128) SETERRQ(PETSC_ERR_SUP,"Currently supports only blocksize up to 128");
449
if (ntype == NORM_2) {
450
PetscScalar sum[128];
451
for (j=0; j<bs; j++) sum[j] = 0.0;
452
for (i=0; i<n; i+=bs) {
453
for (j=0; j<bs; j++) {
454
sum[j] += x[i+j]*(PetscConj(x[i+j]));
457
for (j=0; j<bs; j++) {
458
tnorm[j] = PetscRealPart(sum[j]);
460
ierr = MPI_Allreduce(tnorm,nrm,bs,MPIU_REAL,MPI_SUM,comm);CHKERRQ(ierr);
461
for (j=0; j<bs; j++) {
462
nrm[j] = sqrt(nrm[j]);
464
} else if (ntype == NORM_1) {
465
for (j=0; j<bs; j++) {
468
for (i=0; i<n; i+=bs) {
469
for (j=0; j<bs; j++) {
470
tnorm[j] += PetscAbsScalar(x[i+j]);
473
ierr = MPI_Allreduce(tnorm,nrm,bs,MPIU_REAL,MPI_SUM,comm);CHKERRQ(ierr);
474
} else if (ntype == NORM_INFINITY) {
476
for (j=0; j<bs; j++) {
480
for (i=0; i<n; i+=bs) {
481
for (j=0; j<bs; j++) {
482
if ((tmp = PetscAbsScalar(x[i+j])) > tnorm[j]) tnorm[j] = tmp;
483
/* check special case of tmp == NaN */
484
if (tmp != tmp) {tnorm[j] = tmp; break;}
487
ierr = MPI_Allreduce(tnorm,nrm,bs,MPIU_REAL,MPI_MAX,comm);CHKERRQ(ierr);
489
SETERRQ(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown norm type");
492
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
493
PetscFunctionReturn(0);
497
#define __FUNCT__ "VecStrideMaxAll"
499
VecStrideMaxAll - Computes the maximums of subvectors of a vector defined
500
by a starting point and a stride and optionally its location.
508
+ index - the location where the maximum occurred (not supported, pass PETSC_NULL,
509
if you need this, send mail to petsc-maint@mcs.anl.gov to request it)
513
One must call VecSetBlockSize() before this routine to set the stride
514
information, or use a vector created from a multicomponent DA.
516
This is useful for computing, say the maximum of the pressure variable when
517
the pressure is stored (interlaced) with other variables, e.g., density, etc.
518
This will only work if the desire subvector is a stride subvector.
522
Concepts: maximum^on stride of vector
523
Concepts: stride^maximum
525
.seealso: VecMax(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin()
527
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideMaxAll(Vec v,PetscInt idex[],PetscReal nrm[])
532
PetscReal max[128],tmp;
536
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
537
PetscValidDoublePointer(nrm,3);
539
SETERRQ(PETSC_ERR_SUP,"No support yet for returning index; send mail to petsc-maint@mcs.anl.gov asking for it");
541
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
542
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
543
ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr);
546
if (bs > 128) SETERRQ(PETSC_ERR_SUP,"Currently supports only blocksize up to 128");
549
for (j=0; j<bs; j++) {
553
for (j=0; j<bs; j++) {
554
#if defined(PETSC_USE_COMPLEX)
555
max[j] = PetscRealPart(x[j]);
560
for (i=bs; i<n; i+=bs) {
561
for (j=0; j<bs; j++) {
562
#if defined(PETSC_USE_COMPLEX)
563
if ((tmp = PetscRealPart(x[i+j])) > max[j]) { max[j] = tmp;}
565
if ((tmp = x[i+j]) > max[j]) { max[j] = tmp; }
570
ierr = MPI_Allreduce(max,nrm,bs,MPIU_REAL,MPI_MAX,comm);CHKERRQ(ierr);
572
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
573
PetscFunctionReturn(0);
577
#define __FUNCT__ "VecStrideMinAll"
579
VecStrideMinAll - Computes the minimum of subvector of a vector defined
580
by a starting point and a stride and optionally its location.
588
+ idex - the location where the minimum occurred (not supported, pass PETSC_NULL,
589
if you need this, send mail to petsc-maint@mcs.anl.gov to request it)
595
One must call VecSetBlockSize() before this routine to set the stride
596
information, or use a vector created from a multicomponent DA.
598
This is useful for computing, say the minimum of the pressure variable when
599
the pressure is stored (interlaced) with other variables, e.g., density, etc.
600
This will only work if the desire subvector is a stride subvector.
602
Concepts: minimum^on stride of vector
603
Concepts: stride^minimum
605
.seealso: VecMin(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMax()
607
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideMinAll(Vec v,PetscInt idex[],PetscReal nrm[])
612
PetscReal min[128],tmp;
616
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
617
PetscValidDoublePointer(nrm,3);
619
SETERRQ(PETSC_ERR_SUP,"No support yet for returning index; send mail to petsc-maint@mcs.anl.gov asking for it");
621
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
622
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
623
ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr);
626
if (bs > 128) SETERRQ(PETSC_ERR_SUP,"Currently supports only blocksize up to 128");
629
for (j=0; j<bs; j++) {
633
for (j=0; j<bs; j++) {
634
#if defined(PETSC_USE_COMPLEX)
635
min[j] = PetscRealPart(x[j]);
640
for (i=bs; i<n; i+=bs) {
641
for (j=0; j<bs; j++) {
642
#if defined(PETSC_USE_COMPLEX)
643
if ((tmp = PetscRealPart(x[i+j])) < min[j]) { min[j] = tmp;}
645
if ((tmp = x[i+j]) < min[j]) { min[j] = tmp; }
650
ierr = MPI_Allreduce(min,nrm,bs,MPIU_REAL,MPI_MIN,comm);CHKERRQ(ierr);
652
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
653
PetscFunctionReturn(0);
656
/*----------------------------------------------------------------------------------------------*/
658
#define __FUNCT__ "VecStrideGatherAll"
660
VecStrideGatherAll - Gathers all the single components from a multi-component vector into
667
- addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES
670
. s - the location where the subvectors are stored
673
One must call VecSetBlockSize() before this routine to set the stride
674
information, or use a vector created from a multicomponent DA.
676
If x is the array representing the vector x then this gathers
677
the arrays (x[start],x[start+stride],x[start+2*stride], ....)
678
for start=0,1,2,...bs-1
680
The parallel layout of the vector and the subvector must be the same;
681
i.e., nlocal of v = stride*(nlocal of s)
683
Not optimized; could be easily
687
Concepts: gather^into strided vector
689
.seealso: VecStrideNorm(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideGather(),
690
VecStrideScatterAll()
692
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideGatherAll(Vec v,Vec s[],InsertMode addv)
695
PetscInt i,n,n2,bs,j,k,*bss = PETSC_NULL,nv,jj,nvc;
699
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
700
PetscValidPointer(s,2);
701
PetscValidHeaderSpecific(*s,VEC_COOKIE,2);
702
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
703
ierr = VecGetLocalSize(s[0],&n2);CHKERRQ(ierr);
704
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
706
if (bs < 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Input vector does not have a valid blocksize set");
708
ierr = PetscMalloc2(bs,PetscReal*,&y,bs,PetscInt,&bss);CHKERRQ(ierr);
711
for (i=0; i<bs; i++) {
712
ierr = VecGetBlockSize(s[i],&bss[i]);CHKERRQ(ierr);
713
if (bss[i] < 1) bss[i] = 1; /* if user never set it then assume 1 Re: [PETSC #8241] VecStrideGatherAll */
714
ierr = VecGetArray(s[i],&y[i]);CHKERRQ(ierr);
717
if (nvc > bs) SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of subvectors in subvectors > number of vectors in main vector");
718
if (nvc == bs) break;
724
if (addv == INSERT_VALUES) {
725
for (j=0; j<nv; j++) {
726
for (k=0; k<bss[j]; k++) {
727
for (i=0; i<n; i++) {
728
y[j][i*bss[j] + k] = x[bs*i+jj+k];
733
} else if (addv == ADD_VALUES) {
734
for (j=0; j<nv; j++) {
735
for (k=0; k<bss[j]; k++) {
736
for (i=0; i<n; i++) {
737
y[j][i*bss[j] + k] += x[bs*i+jj+k];
742
#if !defined(PETSC_USE_COMPLEX)
743
} else if (addv == MAX_VALUES) {
744
for (j=0; j<nv; j++) {
745
for (k=0; k<bss[j]; k++) {
746
for (i=0; i<n; i++) {
747
y[j][i*bss[j] + k] = PetscMax(y[j][i*bss[j] + k],x[bs*i+jj+k]);
754
SETERRQ(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown insert type");
757
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
758
for (i=0; i<nv; i++) {
759
ierr = VecRestoreArray(s[i],&y[i]);CHKERRQ(ierr);
762
ierr = PetscFree2(y,bss);CHKERRQ(ierr);
763
PetscFunctionReturn(0);
767
#define __FUNCT__ "VecStrideScatterAll"
769
VecStrideScatterAll - Scatters all the single components from separate vectors into
770
a multi-component vector.
775
+ s - the location where the subvectors are stored
776
- addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES
779
. v - the multicomponent vector
782
One must call VecSetBlockSize() before this routine to set the stride
783
information, or use a vector created from a multicomponent DA.
785
The parallel layout of the vector and the subvector must be the same;
786
i.e., nlocal of v = stride*(nlocal of s)
788
Not optimized; could be easily
792
Concepts: scatter^into strided vector
794
.seealso: VecStrideNorm(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideGather(),
795
VecStrideScatterAll()
797
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideScatterAll(Vec s[],Vec v,InsertMode addv)
800
PetscInt i,n,n2,bs,j,jj,k,*bss = PETSC_NULL,nv,nvc;
804
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
805
PetscValidPointer(s,2);
806
PetscValidHeaderSpecific(*s,VEC_COOKIE,2);
807
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
808
ierr = VecGetLocalSize(s[0],&n2);CHKERRQ(ierr);
809
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
811
if (bs < 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Input vector does not have a valid blocksize set");
813
ierr = PetscMalloc2(bs,PetscScalar**,&y,bs,PetscInt,&bss);CHKERRQ(ierr);
816
for (i=0; i<bs; i++) {
817
ierr = VecGetBlockSize(s[i],&bss[i]);CHKERRQ(ierr);
818
if (bss[i] < 1) bss[i] = 1; /* if user never set it then assume 1 Re: [PETSC #8241] VecStrideGatherAll */
819
ierr = VecGetArray(s[i],&y[i]);CHKERRQ(ierr);
822
if (nvc > bs) SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of subvectors in subvectors > number of vectors in main vector");
823
if (nvc == bs) break;
829
if (addv == INSERT_VALUES) {
830
for (j=0; j<nv; j++) {
831
for (k=0; k<bss[j]; k++) {
832
for (i=0; i<n; i++) {
833
x[bs*i+jj+k] = y[j][i*bss[j] + k];
838
} else if (addv == ADD_VALUES) {
839
for (j=0; j<nv; j++) {
840
for (k=0; k<bss[j]; k++) {
841
for (i=0; i<n; i++) {
842
x[bs*i+jj+k] += y[j][i*bss[j] + k];
847
#if !defined(PETSC_USE_COMPLEX)
848
} else if (addv == MAX_VALUES) {
849
for (j=0; j<nv; j++) {
850
for (k=0; k<bss[j]; k++) {
851
for (i=0; i<n; i++) {
852
x[bs*i+jj+k] = PetscMax(x[bs*i+jj+k],y[j][i*bss[j] + k]);
859
SETERRQ(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown insert type");
862
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
863
for (i=0; i<nv; i++) {
864
ierr = VecRestoreArray(s[i],&y[i]);CHKERRQ(ierr);
866
ierr = PetscFree2(y,bss);CHKERRQ(ierr);
867
PetscFunctionReturn(0);
871
#define __FUNCT__ "VecStrideGather"
873
VecStrideGather - Gathers a single component from a multi-component vector into
880
. start - starting point of the subvector (defined by a stride)
881
- addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES
884
. s - the location where the subvector is stored
887
One must call VecSetBlockSize() before this routine to set the stride
888
information, or use a vector created from a multicomponent DA.
890
If x is the array representing the vector x then this gathers
891
the array (x[start],x[start+stride],x[start+2*stride], ....)
893
The parallel layout of the vector and the subvector must be the same;
894
i.e., nlocal of v = stride*(nlocal of s)
896
Not optimized; could be easily
900
Concepts: gather^into strided vector
902
.seealso: VecStrideNorm(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideGatherAll(),
903
VecStrideScatterAll()
905
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideGather(Vec v,PetscInt start,Vec s,InsertMode addv)
912
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
913
PetscValidHeaderSpecific(s,VEC_COOKIE,3);
914
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
915
ierr = VecGetLocalSize(s,&ns);CHKERRQ(ierr);
916
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
917
ierr = VecGetArray(s,&y);CHKERRQ(ierr);
921
SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start);
922
} else if (start >= bs) {
923
SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Start of stride subvector (%D) is too large for stride\n\
924
Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs);
927
SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Subvector length * blocksize %D not correct for gather from original vector %D",ns*bs,n);
932
if (addv == INSERT_VALUES) {
933
for (i=0; i<n; i++) {
936
} else if (addv == ADD_VALUES) {
937
for (i=0; i<n; i++) {
940
#if !defined(PETSC_USE_COMPLEX)
941
} else if (addv == MAX_VALUES) {
942
for (i=0; i<n; i++) {
943
y[i] = PetscMax(y[i],x[bs*i]);
947
SETERRQ(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown insert type");
950
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
951
ierr = VecRestoreArray(s,&y);CHKERRQ(ierr);
952
PetscFunctionReturn(0);
956
#define __FUNCT__ "VecStrideScatter"
958
VecStrideScatter - Scatters a single component from a vector into a multi-component vector.
963
+ s - the single-component vector
964
. start - starting point of the subvector (defined by a stride)
965
- addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES
968
. v - the location where the subvector is scattered (the multi-component vector)
971
One must call VecSetBlockSize() on the multi-component vector before this
972
routine to set the stride information, or use a vector created from a multicomponent DA.
974
The parallel layout of the vector and the subvector must be the same;
975
i.e., nlocal of v = stride*(nlocal of s)
977
Not optimized; could be easily
981
Concepts: scatter^into strided vector
983
.seealso: VecStrideNorm(), VecStrideGather(), VecStrideMin(), VecStrideMax(), VecStrideGatherAll(),
984
VecStrideScatterAll()
986
PetscErrorCode PETSCVEC_DLLEXPORT VecStrideScatter(Vec s,PetscInt start,Vec v,InsertMode addv)
993
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
994
PetscValidHeaderSpecific(s,VEC_COOKIE,3);
995
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
996
ierr = VecGetLocalSize(s,&ns);CHKERRQ(ierr);
997
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
998
ierr = VecGetArray(s,&y);CHKERRQ(ierr);
1002
SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start);
1003
} else if (start >= bs) {
1004
SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Start of stride subvector (%D) is too large for stride\n\
1005
Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs);
1008
SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Subvector length * blocksize %D not correct for scatter to multicomponent vector %D",ns*bs,n);
1014
if (addv == INSERT_VALUES) {
1015
for (i=0; i<n; i++) {
1018
} else if (addv == ADD_VALUES) {
1019
for (i=0; i<n; i++) {
1022
#if !defined(PETSC_USE_COMPLEX)
1023
} else if (addv == MAX_VALUES) {
1024
for (i=0; i<n; i++) {
1025
x[bs*i] = PetscMax(y[i],x[bs*i]);
1029
SETERRQ(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown insert type");
1033
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1034
ierr = VecRestoreArray(s,&y);CHKERRQ(ierr);
1035
PetscFunctionReturn(0);
1039
#define __FUNCT__ "VecReciprocal_Default"
1040
PetscErrorCode VecReciprocal_Default(Vec v)
1042
PetscErrorCode ierr;
1047
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1048
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1049
for (i=0; i<n; i++) {
1050
if (x[i] != 0.0) x[i] = 1.0/x[i];
1052
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1053
PetscFunctionReturn(0);
1057
#define __FUNCT__ "VecExp"
1059
VecExp - Replaces each component of a vector by e^x_i
1067
. v - The vector of exponents
1071
.seealso: VecLog(), VecAbs(), VecSqrt(), VecReciprocal()
1073
.keywords: vector, sqrt, square root
1075
PetscErrorCode PETSCVEC_DLLEXPORT VecExp(Vec v)
1079
PetscErrorCode ierr;
1082
PetscValidHeaderSpecific(v, VEC_COOKIE,1);
1084
ierr = (*v->ops->exp)(v);CHKERRQ(ierr);
1086
ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr);
1087
ierr = VecGetArray(v, &x);CHKERRQ(ierr);
1088
for(i = 0; i < n; i++) {
1089
x[i] = PetscExpScalar(x[i]);
1091
ierr = VecRestoreArray(v, &x);CHKERRQ(ierr);
1093
PetscFunctionReturn(0);
1097
#define __FUNCT__ "VecLog"
1099
VecLog - Replaces each component of a vector by log(x_i), the natural logarithm
1107
. v - The vector of logs
1111
.seealso: VecExp(), VecAbs(), VecSqrt(), VecReciprocal()
1113
.keywords: vector, sqrt, square root
1115
PetscErrorCode PETSCVEC_DLLEXPORT VecLog(Vec v)
1119
PetscErrorCode ierr;
1122
PetscValidHeaderSpecific(v, VEC_COOKIE,1);
1124
ierr = (*v->ops->log)(v);CHKERRQ(ierr);
1126
ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr);
1127
ierr = VecGetArray(v, &x);CHKERRQ(ierr);
1128
for(i = 0; i < n; i++) {
1129
x[i] = PetscLogScalar(x[i]);
1131
ierr = VecRestoreArray(v, &x);CHKERRQ(ierr);
1133
PetscFunctionReturn(0);
1137
#define __FUNCT__ "VecSqrt"
1139
VecSqrt - Replaces each component of a vector by the square root of its magnitude.
1147
. v - The vector square root
1151
Note: The actual function is sqrt(|x_i|)
1153
.seealso: VecLog(), VecExp(), VecReciprocal(), VecAbs()
1155
.keywords: vector, sqrt, square root
1157
PetscErrorCode PETSCVEC_DLLEXPORT VecSqrt(Vec v)
1161
PetscErrorCode ierr;
1164
PetscValidHeaderSpecific(v, VEC_COOKIE,1);
1166
ierr = (*v->ops->sqrt)(v);CHKERRQ(ierr);
1168
ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr);
1169
ierr = VecGetArray(v, &x);CHKERRQ(ierr);
1170
for(i = 0; i < n; i++) {
1171
x[i] = sqrt(PetscAbsScalar(x[i]));
1173
ierr = VecRestoreArray(v, &x);CHKERRQ(ierr);
1175
PetscFunctionReturn(0);
1179
#define __FUNCT__ "VecDotNorm2"
1181
VecDotNorm2 - computes the inner product of two vectors and the 2-norm squared of the second vector
1195
.seealso: VecDot(), VecNorm(), VecDotBegin(), VecNormBegin(), VecDotEnd(), VecNormEnd()
1197
.keywords: vector, sqrt, square root
1199
PetscErrorCode PETSCVEC_DLLEXPORT VecDotNorm2(Vec s,Vec t,PetscScalar *dp, PetscScalar *nm)
1201
PetscScalar *sx, *tx, dpx = 0.0, nmx = 0.0,work[2],sum[2];
1203
PetscErrorCode ierr;
1206
PetscValidHeaderSpecific(s, VEC_COOKIE,1);
1207
PetscValidHeaderSpecific(t, VEC_COOKIE,2);
1208
PetscValidScalarPointer(dp,3);
1209
PetscValidScalarPointer(nm,4);
1210
PetscValidType(s,1);
1211
PetscValidType(t,2);
1212
PetscCheckSameTypeAndComm(s,1,t,2);
1213
if (s->map->N != t->map->N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
1214
if (s->map->n != t->map->n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");
1216
ierr = PetscLogEventBarrierBegin(VEC_DotNormBarrier,s,t,0,0,((PetscObject)s)->comm);CHKERRQ(ierr);
1217
if (s->ops->dotnorm2) {
1218
ierr = (*s->ops->dotnorm2)(s,t,dp,nm);CHKERRQ(ierr);
1220
ierr = VecGetLocalSize(s, &n);CHKERRQ(ierr);
1221
ierr = VecGetArray(s, &sx);CHKERRQ(ierr);
1222
ierr = VecGetArray(t, &tx);CHKERRQ(ierr);
1224
for (i = 0; i<n; i++) {
1225
dpx += sx[i]*PetscConj(tx[i]);
1226
nmx += tx[i]*PetscConj(tx[i]);
1230
ierr = MPI_Allreduce(&work,&sum,2,MPIU_SCALAR,MPIU_SUM,((PetscObject)s)->comm);CHKERRQ(ierr);
1234
ierr = VecRestoreArray(t, &tx);CHKERRQ(ierr);
1235
ierr = VecRestoreArray(s, &sx);CHKERRQ(ierr);
1236
ierr = PetscLogFlops(4.0*n);CHKERRQ(ierr);
1238
ierr = PetscLogEventBarrierEnd(VEC_DotNormBarrier,s,t,0,0,((PetscObject)s)->comm);CHKERRQ(ierr);
1239
PetscFunctionReturn(0);
1243
#define __FUNCT__ "VecSum"
1245
VecSum - Computes the sum of all the components of a vector.
1257
Concepts: sum^of vector entries
1261
PetscErrorCode PETSCVEC_DLLEXPORT VecSum(Vec v,PetscScalar *sum)
1263
PetscErrorCode ierr;
1265
PetscScalar *x,lsum = 0.0;
1268
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
1269
PetscValidScalarPointer(sum,2);
1270
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1271
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1272
for (i=0; i<n; i++) {
1275
ierr = MPI_Allreduce(&lsum,sum,1,MPIU_SCALAR,MPIU_SUM,((PetscObject)v)->comm);CHKERRQ(ierr);
1276
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1277
PetscFunctionReturn(0);
1281
#define __FUNCT__ "VecShift"
1283
VecShift - Shifts all of the components of a vector by computing
1284
x[i] = x[i] + shift.
1293
. v - the shifted vector
1297
Concepts: vector^adding constant
1300
PetscErrorCode PETSCVEC_DLLEXPORT VecShift(Vec v,PetscScalar shift)
1302
PetscErrorCode ierr;
1307
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
1308
if (v->ops->shift) {
1309
ierr = (*v->ops->shift)(v);CHKERRQ(ierr);
1311
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1312
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1313
for (i=0; i<n; i++) {
1316
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1318
PetscFunctionReturn(0);
1322
#define __FUNCT__ "VecAbs"
1324
VecAbs - Replaces every element in a vector with its absolute value.
1333
Concepts: vector^absolute value
1336
PetscErrorCode PETSCVEC_DLLEXPORT VecAbs(Vec v)
1338
PetscErrorCode ierr;
1343
PetscValidHeaderSpecific(v,VEC_COOKIE,1);
1345
ierr = (*v->ops->abs)(v);CHKERRQ(ierr);
1347
ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1348
ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1349
for (i=0; i<n; i++) {
1350
x[i] = PetscAbsScalar(x[i]);
1352
ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1354
PetscFunctionReturn(0);
1358
#define __FUNCT__ "VecPermute"
1360
VecPermute - Permutes a vector in place using the given ordering.
1364
. order - The ordering
1365
- inv - The flag for inverting the permutation
1369
Note: This function does not yet support parallel Index Sets
1371
.seealso: MatPermute()
1372
.keywords: vec, permute
1374
PetscErrorCode PETSCVEC_DLLEXPORT VecPermute(Vec x, IS row, PetscTruth inv)
1376
PetscScalar *array, *newArray;
1377
const PetscInt *idx;
1379
PetscErrorCode ierr;
1382
ierr = ISGetIndices(row, &idx);CHKERRQ(ierr);
1383
ierr = VecGetArray(x, &array);CHKERRQ(ierr);
1384
ierr = PetscMalloc(x->map->n*sizeof(PetscScalar), &newArray);CHKERRQ(ierr);
1385
#ifdef PETSC_USE_DEBUG
1386
for(i = 0; i < x->map->n; i++) {
1387
if ((idx[i] < 0) || (idx[i] >= x->map->n)) {
1388
SETERRQ2(PETSC_ERR_ARG_CORRUPT, "Permutation index %D is out of bounds: %D", i, idx[i]);
1393
for(i = 0; i < x->map->n; i++) newArray[i] = array[idx[i]];
1395
for(i = 0; i < x->map->n; i++) newArray[idx[i]] = array[i];
1397
ierr = VecRestoreArray(x, &array);CHKERRQ(ierr);
1398
ierr = ISRestoreIndices(row, &idx);CHKERRQ(ierr);
1399
ierr = VecReplaceArray(x, newArray);CHKERRQ(ierr);
1400
PetscFunctionReturn(0);
1404
#define __FUNCT__ "VecEqual"
1406
VecEqual - Compares two vectors.
1411
+ vec1 - the first vector
1412
- vec2 - the second vector
1415
. flg - PETSC_TRUE if the vectors are equal; PETSC_FALSE otherwise.
1419
Concepts: equal^two vectors
1420
Concepts: vector^equality
1423
PetscErrorCode PETSCVEC_DLLEXPORT VecEqual(Vec vec1,Vec vec2,PetscTruth *flg)
1425
PetscScalar *v1,*v2;
1426
PetscErrorCode ierr;
1427
PetscInt n1,n2,N1,N2;
1428
PetscInt state1,state2;
1432
PetscValidHeaderSpecific(vec1,VEC_COOKIE,1);
1433
PetscValidHeaderSpecific(vec2,VEC_COOKIE,2);
1434
PetscValidPointer(flg,3);
1438
ierr = VecGetSize(vec1,&N1);CHKERRQ(ierr);
1439
ierr = VecGetSize(vec2,&N2);CHKERRQ(ierr);
1443
ierr = VecGetLocalSize(vec1,&n1);CHKERRQ(ierr);
1444
ierr = VecGetLocalSize(vec2,&n2);CHKERRQ(ierr);
1448
ierr = PetscObjectStateQuery((PetscObject) vec1,&state1);CHKERRQ(ierr);
1449
ierr = PetscObjectStateQuery((PetscObject) vec2,&state2);CHKERRQ(ierr);
1450
ierr = VecGetArray(vec1,&v1);CHKERRQ(ierr);
1451
ierr = VecGetArray(vec2,&v2);CHKERRQ(ierr);
1452
#if defined(PETSC_USE_COMPLEX)
1454
for (k=0; k<n1; k++){
1455
if (PetscRealPart(v1[k]) != PetscRealPart(v2[k]) || PetscImaginaryPart(v1[k]) != PetscImaginaryPart(v2[k])){
1461
ierr = PetscMemcmp(v1,v2,n1*sizeof(PetscScalar),&flg1);CHKERRQ(ierr);
1463
ierr = VecRestoreArray(vec1,&v1);CHKERRQ(ierr);
1464
ierr = VecRestoreArray(vec2,&v2);CHKERRQ(ierr);
1465
ierr = PetscObjectSetState((PetscObject) vec1,state1);CHKERRQ(ierr);
1466
ierr = PetscObjectSetState((PetscObject) vec2,state2);CHKERRQ(ierr);
1469
/* combine results from all processors */
1470
ierr = MPI_Allreduce(&flg1,flg,1,MPI_INT,MPI_MIN,((PetscObject)vec1)->comm);CHKERRQ(ierr);
1472
PetscFunctionReturn(0);