Line data Source code
1 : /*
2 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 : SLEPc - Scalable Library for Eigenvalue Problem Computations
4 : Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
5 :
6 : This file is part of SLEPc.
7 : SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 : */
10 :
11 : #include <slepc/private/vecimplslepc.h> /*I "slepcvec.h" I*/
12 :
13 : /* Private MPI datatypes and operators */
14 : static MPI_Datatype MPIU_NORM2=0, MPIU_NORM1_AND_2=0;
15 : static PetscBool VecCompInitialized = PETSC_FALSE;
16 : MPI_Op MPIU_NORM2_SUM=0;
17 :
18 : /* Private functions */
19 : static inline void SumNorm2(PetscReal*,PetscReal*,PetscReal*,PetscReal*);
20 : static inline PetscReal GetNorm2(PetscReal,PetscReal);
21 : static inline void AddNorm2(PetscReal*,PetscReal*,PetscReal);
22 : static PetscErrorCode VecCompSetSubVecs_Comp(Vec,PetscInt,Vec*);
23 : static PetscErrorCode VecCompGetSubVecs_Comp(Vec,PetscInt*,const Vec**);
24 :
25 : #include "veccomp0.h"
26 :
27 : #define __WITH_MPI__
28 : #include "veccomp0.h"
29 :
30 7964 : static inline void SumNorm2(PetscReal *ssq0,PetscReal *scale0,PetscReal *ssq1,PetscReal *scale1)
31 : {
32 7964 : PetscReal q;
33 7964 : if (*scale0 > *scale1) {
34 3982 : q = *scale1/(*scale0);
35 3982 : *ssq1 = *ssq0 + q*q*(*ssq1);
36 3982 : *scale1 = *scale0;
37 : } else {
38 3982 : q = *scale0/(*scale1);
39 3982 : *ssq1 += q*q*(*ssq0);
40 : }
41 7964 : }
42 :
43 57442 : static inline PetscReal GetNorm2(PetscReal ssq,PetscReal scale)
44 : {
45 57442 : return scale*PetscSqrtReal(ssq);
46 : }
47 :
48 57454 : static inline void AddNorm2(PetscReal *ssq,PetscReal *scale,PetscReal x)
49 : {
50 57454 : PetscReal absx,q;
51 57454 : if (x != 0.0) {
52 57454 : absx = PetscAbs(x);
53 57454 : if (*scale < absx) {
54 57450 : q = *scale/absx;
55 57450 : *ssq = 1.0 + *ssq*q*q;
56 57450 : *scale = absx;
57 : } else {
58 4 : q = absx/(*scale);
59 4 : *ssq += q*q;
60 : }
61 : }
62 57454 : }
63 :
64 7964 : SLEPC_EXTERN void MPIAPI SlepcSumNorm2_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
65 : {
66 7964 : PetscInt i,count = *cnt;
67 7964 : PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
68 :
69 7964 : PetscFunctionBegin;
70 7964 : if (*datatype == MPIU_NORM2) {
71 15924 : for (i=0;i<count;i++) {
72 7962 : SumNorm2(&xin[i*2],&xin[i*2+1],&xout[i*2],&xout[i*2+1]);
73 : }
74 2 : } else if (*datatype == MPIU_NORM1_AND_2) {
75 4 : for (i=0;i<count;i++) {
76 2 : xout[i*3] += xin[i*3];
77 2 : SumNorm2(&xin[i*3+1],&xin[i*3+2],&xout[i*3+1],&xout[i*3+2]);
78 : }
79 : } else {
80 0 : (void)(*PetscErrorPrintf)("Can only handle MPIU_NORM* data types");
81 0 : MPI_Abort(PETSC_COMM_WORLD,1);
82 : }
83 7964 : PetscFunctionReturnVoid();
84 : }
85 :
86 36 : static PetscErrorCode VecCompNormEnd(void)
87 : {
88 36 : PetscFunctionBegin;
89 36 : PetscCallMPI(MPI_Type_free(&MPIU_NORM2));
90 36 : PetscCallMPI(MPI_Type_free(&MPIU_NORM1_AND_2));
91 36 : PetscCallMPI(MPI_Op_free(&MPIU_NORM2_SUM));
92 36 : VecCompInitialized = PETSC_FALSE;
93 36 : PetscFunctionReturn(PETSC_SUCCESS);
94 : }
95 :
96 36 : static PetscErrorCode VecCompNormInit(void)
97 : {
98 36 : PetscFunctionBegin;
99 36 : PetscCallMPI(MPI_Type_contiguous(2,MPIU_REAL,&MPIU_NORM2));
100 36 : PetscCallMPI(MPI_Type_commit(&MPIU_NORM2));
101 36 : PetscCallMPI(MPI_Type_contiguous(3,MPIU_REAL,&MPIU_NORM1_AND_2));
102 36 : PetscCallMPI(MPI_Type_commit(&MPIU_NORM1_AND_2));
103 36 : PetscCallMPI(MPI_Op_create(SlepcSumNorm2_Local,PETSC_TRUE,&MPIU_NORM2_SUM));
104 36 : PetscCall(PetscRegisterFinalize(VecCompNormEnd));
105 36 : PetscFunctionReturn(PETSC_SUCCESS);
106 : }
107 :
108 3680 : PetscErrorCode VecDestroy_Comp(Vec v)
109 : {
110 3680 : Vec_Comp *vs = (Vec_Comp*)v->data;
111 3680 : PetscInt i;
112 :
113 3680 : PetscFunctionBegin;
114 : #if defined(PETSC_USE_LOG)
115 3680 : PetscCall(PetscLogObjectState((PetscObject)v,"Length=%" PetscInt_FMT,v->map->n));
116 : #endif
117 7372 : for (i=0;i<vs->nx;i++) PetscCall(VecDestroy(&vs->x[i]));
118 3680 : if (--vs->n->friends <= 0) PetscCall(PetscFree(vs->n));
119 3680 : PetscCall(PetscFree(vs->x));
120 3680 : PetscCall(PetscFree(vs));
121 3680 : PetscCall(PetscObjectComposeFunction((PetscObject)v,"VecCompSetSubVecs_C",NULL));
122 3680 : PetscCall(PetscObjectComposeFunction((PetscObject)v,"VecCompGetSubVecs_C",NULL));
123 3680 : PetscFunctionReturn(PETSC_SUCCESS);
124 : }
125 :
126 : static struct _VecOps DvOps = {
127 : PetscDesignatedInitializer(duplicate,VecDuplicate_Comp),
128 : PetscDesignatedInitializer(duplicatevecs,VecDuplicateVecs_Comp),
129 : PetscDesignatedInitializer(destroyvecs,VecDestroyVecs_Comp),
130 : PetscDesignatedInitializer(dot,VecDot_Comp_MPI),
131 : PetscDesignatedInitializer(mdot,VecMDot_Comp_MPI),
132 : PetscDesignatedInitializer(norm,VecNorm_Comp_MPI),
133 : PetscDesignatedInitializer(tdot,VecTDot_Comp_MPI),
134 : PetscDesignatedInitializer(mtdot,VecMTDot_Comp_MPI),
135 : PetscDesignatedInitializer(scale,VecScale_Comp),
136 : PetscDesignatedInitializer(copy,VecCopy_Comp),
137 : PetscDesignatedInitializer(set,VecSet_Comp),
138 : PetscDesignatedInitializer(swap,VecSwap_Comp),
139 : PetscDesignatedInitializer(axpy,VecAXPY_Comp),
140 : PetscDesignatedInitializer(axpby,VecAXPBY_Comp),
141 : PetscDesignatedInitializer(maxpy,VecMAXPY_Comp),
142 : PetscDesignatedInitializer(aypx,VecAYPX_Comp),
143 : PetscDesignatedInitializer(waxpy,VecWAXPY_Comp),
144 : PetscDesignatedInitializer(axpbypcz,VecAXPBYPCZ_Comp),
145 : PetscDesignatedInitializer(pointwisemult,VecPointwiseMult_Comp),
146 : PetscDesignatedInitializer(pointwisedivide,VecPointwiseDivide_Comp),
147 : PetscDesignatedInitializer(setvalues,NULL),
148 : PetscDesignatedInitializer(assemblybegin,NULL),
149 : PetscDesignatedInitializer(assemblyend,NULL),
150 : PetscDesignatedInitializer(getarray,NULL),
151 : PetscDesignatedInitializer(getsize,VecGetSize_Comp),
152 : PetscDesignatedInitializer(getlocalsize,VecGetLocalSize_Comp),
153 : PetscDesignatedInitializer(restorearray,NULL),
154 : PetscDesignatedInitializer(max,VecMax_Comp),
155 : PetscDesignatedInitializer(min,VecMin_Comp),
156 : PetscDesignatedInitializer(setrandom,VecSetRandom_Comp),
157 : PetscDesignatedInitializer(setoption,NULL),
158 : PetscDesignatedInitializer(setvaluesblocked,NULL),
159 : PetscDesignatedInitializer(destroy,VecDestroy_Comp),
160 : PetscDesignatedInitializer(view,VecView_Comp),
161 : PetscDesignatedInitializer(placearray,NULL),
162 : PetscDesignatedInitializer(replacearray,NULL),
163 : PetscDesignatedInitializer(dot_local,VecDot_Comp_Seq),
164 : PetscDesignatedInitializer(tdot_local,VecTDot_Comp_Seq),
165 : PetscDesignatedInitializer(norm_local,VecNorm_Comp_Seq),
166 : PetscDesignatedInitializer(mdot_local,VecMDot_Comp_Seq),
167 : PetscDesignatedInitializer(mtdot_local,VecMTDot_Comp_Seq),
168 : PetscDesignatedInitializer(load,NULL),
169 : PetscDesignatedInitializer(reciprocal,VecReciprocal_Comp),
170 : PetscDesignatedInitializer(conjugate,VecConjugate_Comp),
171 : PetscDesignatedInitializer(setlocaltoglobalmapping,NULL),
172 : PetscDesignatedInitializer(getlocaltoglobalmapping,NULL),
173 : PetscDesignatedInitializer(setvalueslocal,NULL),
174 : PetscDesignatedInitializer(resetarray,NULL),
175 : PetscDesignatedInitializer(setfromoptions,NULL),
176 : PetscDesignatedInitializer(maxpointwisedivide,VecMaxPointwiseDivide_Comp),
177 : PetscDesignatedInitializer(pointwisemax,VecPointwiseMax_Comp),
178 : PetscDesignatedInitializer(pointwisemaxabs,VecPointwiseMaxAbs_Comp),
179 : PetscDesignatedInitializer(pointwisemin,VecPointwiseMin_Comp),
180 : PetscDesignatedInitializer(getvalues,NULL),
181 : PetscDesignatedInitializer(sqrt,VecSqrtAbs_Comp),
182 : PetscDesignatedInitializer(abs,VecAbs_Comp),
183 : PetscDesignatedInitializer(exp,VecExp_Comp),
184 : PetscDesignatedInitializer(log,VecLog_Comp),
185 : PetscDesignatedInitializer(shift,VecShift_Comp),
186 : PetscDesignatedInitializer(create,NULL),
187 : PetscDesignatedInitializer(stridegather,NULL),
188 : PetscDesignatedInitializer(stridescatter,NULL),
189 : PetscDesignatedInitializer(dotnorm2,VecDotNorm2_Comp_MPI),
190 : PetscDesignatedInitializer(getsubvector,NULL),
191 : PetscDesignatedInitializer(restoresubvector,NULL),
192 : PetscDesignatedInitializer(getarrayread,NULL),
193 : PetscDesignatedInitializer(restorearrayread,NULL),
194 : PetscDesignatedInitializer(stridesubsetgather,NULL),
195 : PetscDesignatedInitializer(stridesubsetscatter,NULL),
196 : PetscDesignatedInitializer(viewnative,NULL),
197 : PetscDesignatedInitializer(loadnative,NULL),
198 : PetscDesignatedInitializer(getlocalvector,NULL)
199 : };
200 :
201 39 : PetscErrorCode VecDuplicateVecs_Comp(Vec w,PetscInt m,Vec *V[])
202 : {
203 39 : PetscInt i;
204 :
205 39 : PetscFunctionBegin;
206 39 : PetscValidHeaderSpecific(w,VEC_CLASSID,1);
207 39 : PetscAssertPointer(V,3);
208 39 : PetscCheck(m>0,PetscObjectComm((PetscObject)w),PETSC_ERR_ARG_OUTOFRANGE,"m must be > 0: m = %" PetscInt_FMT,m);
209 39 : PetscCall(PetscMalloc1(m,V));
210 415 : for (i=0;i<m;i++) PetscCall(VecDuplicate(w,*V+i));
211 39 : PetscFunctionReturn(PETSC_SUCCESS);
212 : }
213 :
214 39 : PetscErrorCode VecDestroyVecs_Comp(PetscInt m,Vec v[])
215 : {
216 39 : PetscInt i;
217 :
218 39 : PetscFunctionBegin;
219 39 : PetscAssertPointer(v,2);
220 39 : PetscCheck(m>0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"m must be > 0: m = %" PetscInt_FMT,m);
221 415 : for (i=0;i<m;i++) PetscCall(VecDestroy(&v[i]));
222 39 : PetscCall(PetscFree(v));
223 39 : PetscFunctionReturn(PETSC_SUCCESS);
224 : }
225 :
226 3680 : static PetscErrorCode VecCreate_Comp_Private(Vec v,Vec *x,PetscInt nx,PetscBool x_to_me,Vec_Comp_N *n)
227 : {
228 3680 : Vec_Comp *s;
229 3680 : PetscInt N=0,lN=0,i,k;
230 :
231 3680 : PetscFunctionBegin;
232 3680 : if (!VecCompInitialized) {
233 36 : VecCompInitialized = PETSC_TRUE;
234 36 : PetscCall(VecRegister(VECCOMP,VecCreate_Comp));
235 36 : PetscCall(VecCompNormInit());
236 : }
237 :
238 : /* Allocate a new Vec_Comp */
239 3680 : if (v->data) PetscCall(PetscFree(v->data));
240 3680 : PetscCall(PetscNew(&s));
241 3680 : PetscCall(PetscMemcpy(v->ops,&DvOps,sizeof(DvOps)));
242 3680 : v->data = (void*)s;
243 3680 : v->petscnative = PETSC_FALSE;
244 :
245 : /* Allocate the array of Vec, if it is needed to be done */
246 3680 : if (!x_to_me) {
247 2202 : if (nx) PetscCall(PetscMalloc1(nx,&s->x));
248 2202 : if (x) PetscCall(PetscArraycpy(s->x,x,nx));
249 1478 : } else s->x = x;
250 :
251 3680 : s->nx = nx;
252 :
253 3680 : if (nx && x) {
254 : /* Allocate the shared structure, if it is not given */
255 3677 : if (!n) {
256 106 : for (i=0;i<nx;i++) {
257 56 : PetscCall(VecGetSize(x[i],&k));
258 56 : N+= k;
259 56 : PetscCall(VecGetLocalSize(x[i],&k));
260 56 : lN+= k;
261 : }
262 50 : PetscCall(PetscNew(&n));
263 50 : s->n = n;
264 50 : n->n = nx;
265 50 : n->N = N;
266 50 : n->lN = lN;
267 50 : n->friends = 1;
268 : } else { /* If not, check in the vector in the shared structure */
269 3627 : s->n = n;
270 3627 : s->n->friends++;
271 : }
272 :
273 : /* Set the virtual sizes as the real sizes of the vector */
274 3677 : PetscCall(VecSetSizes(v,s->n->lN,s->n->N));
275 : }
276 :
277 3680 : PetscCall(PetscObjectChangeTypeName((PetscObject)v,VECCOMP));
278 3680 : PetscCall(PetscObjectComposeFunction((PetscObject)v,"VecCompSetSubVecs_C",VecCompSetSubVecs_Comp));
279 3680 : PetscCall(PetscObjectComposeFunction((PetscObject)v,"VecCompGetSubVecs_C",VecCompGetSubVecs_Comp));
280 3680 : PetscFunctionReturn(PETSC_SUCCESS);
281 : }
282 :
283 3 : SLEPC_EXTERN PetscErrorCode VecCreate_Comp(Vec V)
284 : {
285 3 : PetscFunctionBegin;
286 3 : PetscCall(VecCreate_Comp_Private(V,NULL,0,PETSC_FALSE,NULL));
287 3 : PetscFunctionReturn(PETSC_SUCCESS);
288 : }
289 :
290 : /*@
291 : VecCreateComp - Creates a new vector containing several subvectors,
292 : each stored separately.
293 :
294 : Collective
295 :
296 : Input Parameters:
297 : + comm - communicator for the new Vec
298 : . Nx - array of (initial) global sizes of child vectors
299 : . n - number of child vectors
300 : . t - type of the child vectors
301 : - Vparent - (optional) template vector
302 :
303 : Output Parameter:
304 : . V - new vector
305 :
306 : Notes:
307 : This is similar to PETSc's VecNest but customized for SLEPc's needs. In particular,
308 : the number of child vectors can be modified dynamically, with VecCompSetSubVecs().
309 :
310 : Level: developer
311 :
312 : .seealso: VecCreateCompWithVecs(), VecCompSetSubVecs()
313 : @*/
314 3 : PetscErrorCode VecCreateComp(MPI_Comm comm,PetscInt Nx[],PetscInt n,VecType t,Vec Vparent,Vec *V)
315 : {
316 3 : Vec *x;
317 3 : PetscInt i;
318 :
319 3 : PetscFunctionBegin;
320 3 : PetscCall(VecCreate(comm,V));
321 3 : PetscCall(PetscMalloc1(n,&x));
322 9 : for (i=0;i<n;i++) {
323 6 : PetscCall(VecCreate(comm,&x[i]));
324 6 : PetscCall(VecSetSizes(x[i],PETSC_DECIDE,Nx[i]));
325 6 : PetscCall(VecSetType(x[i],t));
326 : }
327 3 : PetscCall(VecCreate_Comp_Private(*V,x,n,PETSC_TRUE,Vparent?((Vec_Comp*)Vparent->data)->n:NULL));
328 3 : PetscFunctionReturn(PETSC_SUCCESS);
329 : }
330 :
331 : /*@
332 : VecCreateCompWithVecs - Creates a new vector containing several subvectors,
333 : each stored separately, from an array of Vecs.
334 :
335 : Collective
336 :
337 : Input Parameters:
338 : + x - array of Vecs
339 : . n - number of child vectors
340 : - Vparent - (optional) template vector
341 :
342 : Output Parameter:
343 : . V - new vector
344 :
345 : Level: developer
346 :
347 : .seealso: VecCreateComp()
348 : @*/
349 2199 : PetscErrorCode VecCreateCompWithVecs(Vec x[],PetscInt n,Vec Vparent,Vec *V)
350 : {
351 2199 : PetscInt i;
352 :
353 2199 : PetscFunctionBegin;
354 2199 : PetscAssertPointer(x,1);
355 2199 : PetscValidHeaderSpecific(*x,VEC_CLASSID,1);
356 6597 : PetscValidLogicalCollectiveInt(*x,n,2);
357 2199 : PetscCall(VecCreate(PetscObjectComm((PetscObject)x[0]),V));
358 4401 : for (i=0;i<n;i++) PetscCall(PetscObjectReference((PetscObject)x[i]));
359 2199 : PetscCall(VecCreate_Comp_Private(*V,x,n,PETSC_FALSE,Vparent?((Vec_Comp*)Vparent->data)->n:NULL));
360 2199 : PetscFunctionReturn(PETSC_SUCCESS);
361 : }
362 :
363 1475 : PetscErrorCode VecDuplicate_Comp(Vec win,Vec *V)
364 : {
365 1475 : Vec *x;
366 1475 : PetscInt i;
367 1475 : Vec_Comp *s = (Vec_Comp*)win->data;
368 :
369 1475 : PetscFunctionBegin;
370 1475 : SlepcValidVecComp(win,1);
371 1475 : PetscCall(VecCreate(PetscObjectComm((PetscObject)win),V));
372 1475 : PetscCall(PetscMalloc1(s->nx,&x));
373 2953 : for (i=0;i<s->nx;i++) {
374 1478 : if (s->x[i]) PetscCall(VecDuplicate(s->x[i],&x[i]));
375 0 : else x[i] = NULL;
376 : }
377 1475 : PetscCall(VecCreate_Comp_Private(*V,x,s->nx,PETSC_TRUE,s->n));
378 1475 : PetscFunctionReturn(PETSC_SUCCESS);
379 : }
380 :
381 220644 : static PetscErrorCode VecCompGetSubVecs_Comp(Vec win,PetscInt *n,const Vec **x)
382 : {
383 220644 : Vec_Comp *s = (Vec_Comp*)win->data;
384 :
385 220644 : PetscFunctionBegin;
386 220644 : if (x) *x = s->x;
387 220644 : if (n) *n = s->n->n;
388 220644 : PetscFunctionReturn(PETSC_SUCCESS);
389 : }
390 :
391 : /*@C
392 : VecCompGetSubVecs - Returns the entire array of vectors defining a
393 : compound vector.
394 :
395 : Collective
396 :
397 : Input Parameter:
398 : . win - compound vector
399 :
400 : Output Parameters:
401 : + n - number of child vectors
402 : - x - array of child vectors
403 :
404 : Level: developer
405 :
406 : .seealso: VecCreateComp()
407 : @*/
408 220644 : PetscErrorCode VecCompGetSubVecs(Vec win,PetscInt *n,const Vec **x)
409 : {
410 220644 : PetscFunctionBegin;
411 220644 : PetscValidHeaderSpecific(win,VEC_CLASSID,1);
412 220644 : PetscUseMethod(win,"VecCompGetSubVecs_C",(Vec,PetscInt*,const Vec**),(win,n,x));
413 220644 : PetscFunctionReturn(PETSC_SUCCESS);
414 : }
415 :
416 1061 : static PetscErrorCode VecCompSetSubVecs_Comp(Vec win,PetscInt n,Vec *x)
417 : {
418 1061 : Vec_Comp *s = (Vec_Comp*)win->data;
419 1061 : PetscInt i,N,nlocal;
420 1061 : Vec_Comp_N *nn;
421 :
422 1061 : PetscFunctionBegin;
423 1061 : PetscCheck(s,PetscObjectComm((PetscObject)win),PETSC_ERR_ORDER,"Must call VecSetSizes first");
424 1061 : if (!s->nx) {
425 : /* vector has been created via VecCreate+VecSetType+VecSetSizes, so allocate data structures */
426 3 : PetscCall(PetscMalloc1(n,&s->x));
427 3 : PetscCall(VecGetSize(win,&N));
428 3 : PetscCheck(N%n==0,PetscObjectComm((PetscObject)win),PETSC_ERR_SUP,"Global dimension %" PetscInt_FMT " is not divisible by %" PetscInt_FMT,N,n);
429 3 : PetscCall(VecGetLocalSize(win,&nlocal));
430 3 : PetscCheck(nlocal%n==0,PetscObjectComm((PetscObject)win),PETSC_ERR_SUP,"Local dimension %" PetscInt_FMT " is not divisible by %" PetscInt_FMT,nlocal,n);
431 3 : s->nx = n;
432 9 : for (i=0;i<n;i++) {
433 6 : PetscCall(VecCreate(PetscObjectComm((PetscObject)win),&s->x[i]));
434 6 : PetscCall(VecSetSizes(s->x[i],nlocal/n,N/n));
435 6 : PetscCall(VecSetFromOptions(s->x[i]));
436 : }
437 3 : if (!s->n) {
438 3 : PetscCall(PetscNew(&nn));
439 3 : s->n = nn;
440 3 : nn->N = N;
441 3 : nn->lN = nlocal;
442 3 : nn->friends = 1;
443 : }
444 1058 : } else PetscCheck(n<=s->nx,PetscObjectComm((PetscObject)win),PETSC_ERR_SUP,"Number of child vectors cannot be larger than %" PetscInt_FMT,s->nx);
445 1061 : if (x) PetscCall(PetscArraycpy(s->x,x,n));
446 1061 : s->n->n = n;
447 1061 : PetscFunctionReturn(PETSC_SUCCESS);
448 : }
449 :
450 : /*@
451 : VecCompSetSubVecs - Resets the number of subvectors defining a compound vector,
452 : or replaces the subvectors.
453 :
454 : Collective
455 :
456 : Input Parameters:
457 : + win - compound vector
458 : . n - number of child vectors
459 : - x - array of child vectors
460 :
461 : Note:
462 : It is not possible to increase the number of subvectors with respect to the
463 : number set at its creation.
464 :
465 : Level: developer
466 :
467 : .seealso: VecCreateComp(), VecCompGetSubVecs()
468 : @*/
469 1061 : PetscErrorCode VecCompSetSubVecs(Vec win,PetscInt n,Vec x[])
470 : {
471 1061 : PetscFunctionBegin;
472 1061 : PetscValidHeaderSpecific(win,VEC_CLASSID,1);
473 3183 : PetscValidLogicalCollectiveInt(win,n,2);
474 1061 : PetscTryMethod(win,"VecCompSetSubVecs_C",(Vec,PetscInt,Vec*),(win,n,x));
475 1061 : PetscFunctionReturn(PETSC_SUCCESS);
476 : }
477 :
478 91637 : PetscErrorCode VecAXPY_Comp(Vec v,PetscScalar alpha,Vec w)
479 : {
480 91637 : Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
481 91637 : PetscInt i;
482 :
483 91637 : PetscFunctionBegin;
484 91637 : SlepcValidVecComp(v,1);
485 91637 : SlepcValidVecComp(w,3);
486 183274 : for (i=0;i<vs->n->n;i++) PetscCall(VecAXPY(vs->x[i],alpha,ws->x[i]));
487 91637 : PetscFunctionReturn(PETSC_SUCCESS);
488 : }
489 :
490 54122 : PetscErrorCode VecAYPX_Comp(Vec v,PetscScalar alpha,Vec w)
491 : {
492 54122 : Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
493 54122 : PetscInt i;
494 :
495 54122 : PetscFunctionBegin;
496 54122 : SlepcValidVecComp(v,1);
497 54122 : SlepcValidVecComp(w,3);
498 108244 : for (i=0;i<vs->n->n;i++) PetscCall(VecAYPX(vs->x[i],alpha,ws->x[i]));
499 54122 : PetscFunctionReturn(PETSC_SUCCESS);
500 : }
501 :
502 3 : PetscErrorCode VecAXPBY_Comp(Vec v,PetscScalar alpha,PetscScalar beta,Vec w)
503 : {
504 3 : Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
505 3 : PetscInt i;
506 :
507 3 : PetscFunctionBegin;
508 3 : SlepcValidVecComp(v,1);
509 3 : SlepcValidVecComp(w,4);
510 9 : for (i=0;i<vs->n->n;i++) PetscCall(VecAXPBY(vs->x[i],alpha,beta,ws->x[i]));
511 3 : PetscFunctionReturn(PETSC_SUCCESS);
512 : }
513 :
514 54339 : PetscErrorCode VecMAXPY_Comp(Vec v,PetscInt n,const PetscScalar *alpha,Vec *w)
515 : {
516 54339 : Vec_Comp *vs = (Vec_Comp*)v->data;
517 54339 : Vec *wx;
518 54339 : PetscInt i,j;
519 :
520 54339 : PetscFunctionBegin;
521 54339 : SlepcValidVecComp(v,1);
522 187439 : for (i=0;i<n;i++) SlepcValidVecComp(w[i],4);
523 :
524 54339 : PetscCall(PetscMalloc1(n,&wx));
525 :
526 108678 : for (j=0;j<vs->n->n;j++) {
527 187439 : for (i=0;i<n;i++) wx[i] = ((Vec_Comp*)w[i]->data)->x[j];
528 54339 : PetscCall(VecMAXPY(vs->x[j],n,alpha,wx));
529 : }
530 :
531 54339 : PetscCall(PetscFree(wx));
532 54339 : PetscFunctionReturn(PETSC_SUCCESS);
533 : }
534 :
535 1463 : PetscErrorCode VecWAXPY_Comp(Vec v,PetscScalar alpha,Vec w,Vec z)
536 : {
537 1463 : Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data,*zs = (Vec_Comp*)z->data;
538 1463 : PetscInt i;
539 :
540 1463 : PetscFunctionBegin;
541 1463 : SlepcValidVecComp(v,1);
542 1463 : SlepcValidVecComp(w,3);
543 1463 : SlepcValidVecComp(z,4);
544 2929 : for (i=0;i<vs->n->n;i++) PetscCall(VecWAXPY(vs->x[i],alpha,ws->x[i],zs->x[i]));
545 1463 : PetscFunctionReturn(PETSC_SUCCESS);
546 : }
547 :
548 1463 : PetscErrorCode VecAXPBYPCZ_Comp(Vec v,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec w,Vec z)
549 : {
550 1463 : Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data,*zs = (Vec_Comp*)z->data;
551 1463 : PetscInt i;
552 :
553 1463 : PetscFunctionBegin;
554 1463 : SlepcValidVecComp(v,1);
555 1463 : SlepcValidVecComp(w,5);
556 1463 : SlepcValidVecComp(z,6);
557 2929 : for (i=0;i<vs->n->n;i++) PetscCall(VecAXPBYPCZ(vs->x[i],alpha,beta,gamma,ws->x[i],zs->x[i]));
558 1463 : PetscFunctionReturn(PETSC_SUCCESS);
559 : }
560 :
561 9 : PetscErrorCode VecGetSize_Comp(Vec v,PetscInt *size)
562 : {
563 9 : Vec_Comp *vs = (Vec_Comp*)v->data;
564 :
565 9 : PetscFunctionBegin;
566 9 : PetscAssertPointer(size,2);
567 9 : if (vs->n) {
568 6 : SlepcValidVecComp(v,1);
569 6 : *size = vs->n->N;
570 3 : } else *size = v->map->N;
571 9 : PetscFunctionReturn(PETSC_SUCCESS);
572 : }
573 :
574 47353 : PetscErrorCode VecGetLocalSize_Comp(Vec v,PetscInt *size)
575 : {
576 47353 : Vec_Comp *vs = (Vec_Comp*)v->data;
577 :
578 47353 : PetscFunctionBegin;
579 47353 : PetscAssertPointer(size,2);
580 47353 : if (vs->n) {
581 47350 : SlepcValidVecComp(v,1);
582 47350 : *size = vs->n->lN;
583 3 : } else *size = v->map->n;
584 47353 : PetscFunctionReturn(PETSC_SUCCESS);
585 : }
586 :
587 3 : PetscErrorCode VecMax_Comp(Vec v,PetscInt *idx,PetscReal *z)
588 : {
589 3 : Vec_Comp *vs = (Vec_Comp*)v->data;
590 3 : PetscInt idxp,s=0,s0;
591 3 : PetscReal zp,z0;
592 3 : PetscInt i;
593 :
594 3 : PetscFunctionBegin;
595 3 : SlepcValidVecComp(v,1);
596 3 : if (!idx && !z) PetscFunctionReturn(PETSC_SUCCESS);
597 :
598 6 : if (vs->n->n > 0) PetscCall(VecMax(vs->x[0],idx?&idxp:NULL,&zp));
599 : else {
600 0 : zp = PETSC_MIN_REAL;
601 0 : if (idx) idxp = -1;
602 : }
603 6 : for (i=1;i<vs->n->n;i++) {
604 3 : PetscCall(VecGetSize(vs->x[i-1],&s0));
605 3 : s += s0;
606 6 : PetscCall(VecMax(vs->x[i],idx?&idxp:NULL,&z0));
607 3 : if (zp < z0) {
608 0 : if (idx) *idx = s+idxp;
609 0 : zp = z0;
610 : }
611 : }
612 3 : if (z) *z = zp;
613 3 : PetscFunctionReturn(PETSC_SUCCESS);
614 : }
615 :
616 3 : PetscErrorCode VecMin_Comp(Vec v,PetscInt *idx,PetscReal *z)
617 : {
618 3 : Vec_Comp *vs = (Vec_Comp*)v->data;
619 3 : PetscInt idxp,s=0,s0;
620 3 : PetscReal zp,z0;
621 3 : PetscInt i;
622 :
623 3 : PetscFunctionBegin;
624 3 : SlepcValidVecComp(v,1);
625 3 : if (!idx && !z) PetscFunctionReturn(PETSC_SUCCESS);
626 :
627 6 : if (vs->n->n > 0) PetscCall(VecMin(vs->x[0],idx?&idxp:NULL,&zp));
628 : else {
629 0 : zp = PETSC_MAX_REAL;
630 0 : if (idx) idxp = -1;
631 : }
632 6 : for (i=1;i<vs->n->n;i++) {
633 3 : PetscCall(VecGetSize(vs->x[i-1],&s0));
634 3 : s += s0;
635 6 : PetscCall(VecMin(vs->x[i],idx?&idxp:NULL,&z0));
636 3 : if (zp > z0) {
637 3 : if (idx) *idx = s+idxp;
638 3 : zp = z0;
639 : }
640 : }
641 3 : if (z) *z = zp;
642 3 : PetscFunctionReturn(PETSC_SUCCESS);
643 : }
644 :
645 3 : PetscErrorCode VecMaxPointwiseDivide_Comp(Vec v,Vec w,PetscReal *m)
646 : {
647 3 : Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
648 3 : PetscReal work;
649 3 : PetscInt i;
650 :
651 3 : PetscFunctionBegin;
652 3 : SlepcValidVecComp(v,1);
653 3 : SlepcValidVecComp(w,2);
654 3 : if (!m || vs->n->n == 0) PetscFunctionReturn(PETSC_SUCCESS);
655 3 : PetscCall(VecMaxPointwiseDivide(vs->x[0],ws->x[0],m));
656 6 : for (i=1;i<vs->n->n;i++) {
657 3 : PetscCall(VecMaxPointwiseDivide(vs->x[i],ws->x[i],&work));
658 4 : *m = PetscMax(*m,work);
659 : }
660 3 : PetscFunctionReturn(PETSC_SUCCESS);
661 : }
662 :
663 : #define __QUOTEME__(x) #x
664 : #define __COMPOSE2__(A,B) A##B
665 : #define __COMPOSE3__(A,B,C) A##B##C
666 :
667 : #define __FUNC_TEMPLATE1__(NAME) \
668 : PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v) \
669 : { \
670 : Vec_Comp *vs = (Vec_Comp*)v->data; \
671 : PetscInt i; \
672 : \
673 : PetscFunctionBegin; \
674 : SlepcValidVecComp(v,1); \
675 : for (i=0;i<vs->n->n;i++) { \
676 : PetscCall(__COMPOSE2__(Vec,NAME)(vs->x[i])); \
677 : } \
678 : PetscFunctionReturn(PETSC_SUCCESS);\
679 : }
680 :
681 11311 : __FUNC_TEMPLATE1__(Conjugate)
682 9 : __FUNC_TEMPLATE1__(Reciprocal)
683 9 : __FUNC_TEMPLATE1__(SqrtAbs)
684 9 : __FUNC_TEMPLATE1__(Abs)
685 9 : __FUNC_TEMPLATE1__(Exp)
686 9 : __FUNC_TEMPLATE1__(Log)
687 :
688 : #define __FUNC_TEMPLATE2__(NAME,T0) \
689 : PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,T0 __a) \
690 : { \
691 : Vec_Comp *vs = (Vec_Comp*)v->data; \
692 : PetscInt i; \
693 : \
694 : PetscFunctionBegin; \
695 : SlepcValidVecComp(v,1); \
696 : for (i=0;i<vs->n->n;i++) { \
697 : PetscCall(__COMPOSE2__(Vec,NAME)(vs->x[i],__a)); \
698 : } \
699 : PetscFunctionReturn(PETSC_SUCCESS);\
700 : }
701 :
702 4120 : __FUNC_TEMPLATE2__(Set,PetscScalar)
703 9 : __FUNC_TEMPLATE2__(View,PetscViewer)
704 3525 : __FUNC_TEMPLATE2__(Scale,PetscScalar)
705 9 : __FUNC_TEMPLATE2__(SetRandom,PetscRandom)
706 9 : __FUNC_TEMPLATE2__(Shift,PetscScalar)
707 :
708 : #define __FUNC_TEMPLATE3__(NAME) \
709 : PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,Vec w) \
710 : { \
711 : Vec_Comp *vs = (Vec_Comp*)v->data,\
712 : *ws = (Vec_Comp*)w->data; \
713 : PetscInt i; \
714 : \
715 : PetscFunctionBegin; \
716 : SlepcValidVecComp(v,1); \
717 : SlepcValidVecComp(w,2); \
718 : for (i=0;i<vs->n->n;i++) { \
719 : PetscCall(__COMPOSE2__(Vec,NAME)(vs->x[i],ws->x[i])); \
720 : } \
721 : PetscFunctionReturn(PETSC_SUCCESS);\
722 : }
723 :
724 43548 : __FUNC_TEMPLATE3__(Copy)
725 9 : __FUNC_TEMPLATE3__(Swap)
726 :
727 : #define __FUNC_TEMPLATE4__(NAME) \
728 : PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,Vec w,Vec z) \
729 : { \
730 : Vec_Comp *vs = (Vec_Comp*)v->data, \
731 : *ws = (Vec_Comp*)w->data, \
732 : *zs = (Vec_Comp*)z->data; \
733 : PetscInt i; \
734 : \
735 : PetscFunctionBegin; \
736 : SlepcValidVecComp(v,1); \
737 : SlepcValidVecComp(w,2); \
738 : SlepcValidVecComp(z,3); \
739 : for (i=0;i<vs->n->n;i++) { \
740 : PetscCall(__COMPOSE2__(Vec,NAME)(vs->x[i],ws->x[i],zs->x[i])); \
741 : } \
742 : PetscFunctionReturn(PETSC_SUCCESS);\
743 : }
744 :
745 9 : __FUNC_TEMPLATE4__(PointwiseMax)
746 9 : __FUNC_TEMPLATE4__(PointwiseMaxAbs)
747 9 : __FUNC_TEMPLATE4__(PointwiseMin)
748 9 : __FUNC_TEMPLATE4__(PointwiseMult)
749 9 : __FUNC_TEMPLATE4__(PointwiseDivide)
|