Actual source code: projection.c
petsc-3.10.5 2019-03-28
1: #include <petsc/private/vecimpl.h>
3: /*@
4: VecWhichEqual - Creates an index set containing the indices
5: where the vectors Vec1 and Vec2 have identical elements.
7: Collective on Vec
9: Input Parameters:
10: . Vec1, Vec2 - the two vectors to compare
12: OutputParameter:
13: . S - The index set containing the indices i where vec1[i] == vec2[i]
15: Notes:
16: the two vectors must have the same parallel layout
18: Level: advanced
19: @*/
20: PetscErrorCode VecWhichEqual(Vec Vec1, Vec Vec2, IS *S)
21: {
22: PetscErrorCode ierr;
23: PetscInt i,n_same=0;
24: PetscInt n,low,high;
25: PetscInt *same=NULL;
26: const PetscScalar *v1,*v2;
32: VecCheckSameSize(Vec1,1,Vec2,2);
34: VecGetOwnershipRange(Vec1,&low,&high);
35: VecGetLocalSize(Vec1,&n);
36: if (n>0){
37: if (Vec1 == Vec2){
38: VecGetArrayRead(Vec1,&v1);
39: v2=v1;
40: } else {
41: VecGetArrayRead(Vec1,&v1);
42: VecGetArrayRead(Vec2,&v2);
43: }
45: PetscMalloc1(n,&same);
47: for (i=0; i<n; ++i){
48: if (v1[i] == v2[i]) {same[n_same]=low+i; ++n_same;}
49: }
51: if (Vec1 == Vec2){
52: VecRestoreArrayRead(Vec1,&v1);
53: } else {
54: VecRestoreArrayRead(Vec1,&v1);
55: VecRestoreArrayRead(Vec2,&v2);
56: }
57: }
58: ISCreateGeneral(PetscObjectComm((PetscObject)Vec1),n_same,same,PETSC_OWN_POINTER,S);
59: return(0);
60: }
62: /*@
63: VecWhichLessThan - Creates an index set containing the indices
64: where the vectors Vec1 < Vec2
66: Collective on S
68: Input Parameters:
69: . Vec1, Vec2 - the two vectors to compare
71: OutputParameter:
72: . S - The index set containing the indices i where vec1[i] < vec2[i]
74: Notes:
75: The two vectors must have the same parallel layout
77: For complex numbers this only compares the real part
79: Level: advanced
80: @*/
81: PetscErrorCode VecWhichLessThan(Vec Vec1, Vec Vec2, IS *S)
82: {
83: PetscErrorCode ierr;
84: PetscInt i,n_lt=0;
85: PetscInt n,low,high;
86: PetscInt *lt=NULL;
87: const PetscScalar *v1,*v2;
93: VecCheckSameSize(Vec1,1,Vec2,2);
95: VecGetOwnershipRange(Vec1,&low,&high);
96: VecGetLocalSize(Vec1,&n);
97: if (n>0){
98: if (Vec1 == Vec2){
99: VecGetArrayRead(Vec1,&v1);
100: v2=v1;
101: } else {
102: VecGetArrayRead(Vec1,&v1);
103: VecGetArrayRead(Vec2,&v2);
104: }
106: PetscMalloc1(n,<);
108: for (i=0; i<n; ++i){
109: if (PetscRealPart(v1[i]) < PetscRealPart(v2[i])) {lt[n_lt]=low+i; ++n_lt;}
110: }
112: if (Vec1 == Vec2){
113: VecRestoreArrayRead(Vec1,&v1);
114: } else {
115: VecRestoreArrayRead(Vec1,&v1);
116: VecRestoreArrayRead(Vec2,&v2);
117: }
118: }
119: ISCreateGeneral(PetscObjectComm((PetscObject)Vec1),n_lt,lt,PETSC_OWN_POINTER,S);
120: return(0);
121: }
123: /*@
124: VecWhichGreaterThan - Creates an index set containing the indices
125: where the vectors Vec1 > Vec2
127: Collective on S
129: Input Parameters:
130: . Vec1, Vec2 - the two vectors to compare
132: OutputParameter:
133: . S - The index set containing the indices i where vec1[i] > vec2[i]
135: Notes:
136: The two vectors must have the same parallel layout
138: For complex numbers this only compares the real part
140: Level: advanced
141: @*/
142: PetscErrorCode VecWhichGreaterThan(Vec Vec1, Vec Vec2, IS *S)
143: {
144: PetscErrorCode ierr;
145: PetscInt i,n_gt=0;
146: PetscInt n,low,high;
147: PetscInt *gt=NULL;
148: const PetscScalar *v1,*v2;
154: VecCheckSameSize(Vec1,1,Vec2,2);
156: VecGetOwnershipRange(Vec1,&low,&high);
157: VecGetLocalSize(Vec1,&n);
158: if (n>0){
159: if (Vec1 == Vec2){
160: VecGetArrayRead(Vec1,&v1);
161: v2=v1;
162: } else {
163: VecGetArrayRead(Vec1,&v1);
164: VecGetArrayRead(Vec2,&v2);
165: }
167: PetscMalloc1(n,>);
169: for (i=0; i<n; ++i){
170: if (PetscRealPart(v1[i]) > PetscRealPart(v2[i])) {gt[n_gt]=low+i; ++n_gt;}
171: }
173: if (Vec1 == Vec2){
174: VecRestoreArrayRead(Vec1,&v1);
175: } else {
176: VecRestoreArrayRead(Vec1,&v1);
177: VecRestoreArrayRead(Vec2,&v2);
178: }
179: }
180: ISCreateGeneral(PetscObjectComm((PetscObject)Vec1),n_gt,gt,PETSC_OWN_POINTER,S);
181: return(0);
182: }
184: /*@
185: VecWhichBetween - Creates an index set containing the indices
186: where VecLow < V < VecHigh
188: Collective on S
190: Input Parameters:
191: + VecLow - lower bound
192: . V - Vector to compare
193: - VecHigh - higher bound
195: OutputParameter:
196: . S - The index set containing the indices i where veclow[i] < v[i] < vechigh[i]
198: Notes:
199: The vectors must have the same parallel layout
201: For complex numbers this only compares the real part
203: Level: advanced
204: @*/
205: PetscErrorCode VecWhichBetween(Vec VecLow, Vec V, Vec VecHigh, IS *S)
206: {
208: PetscErrorCode ierr;
209: PetscInt i,n_vm=0;
210: PetscInt n,low,high;
211: PetscInt *vm=NULL;
212: const PetscScalar *v1,*v2,*vmiddle;
220: VecCheckSameSize(V,2,VecLow,1);
221: VecCheckSameSize(V,2,VecHigh,3);
223: VecGetOwnershipRange(VecLow,&low,&high);
224: VecGetLocalSize(VecLow,&n);
225: if (n>0){
226: VecGetArrayRead(VecLow,&v1);
227: if (VecLow != VecHigh){
228: VecGetArrayRead(VecHigh,&v2);
229: } else {
230: v2=v1;
231: }
232: if (V != VecLow && V != VecHigh){
233: VecGetArrayRead(V,&vmiddle);
234: } else if (V==VecLow){
235: vmiddle=v1;
236: } else {
237: vmiddle=v2;
238: }
240: PetscMalloc1(n,&vm);
242: for (i=0; i<n; ++i){
243: if (PetscRealPart(v1[i]) < PetscRealPart(vmiddle[i]) && PetscRealPart(vmiddle[i]) < PetscRealPart(v2[i])) {vm[n_vm]=low+i; ++n_vm;}
244: }
246: VecRestoreArrayRead(VecLow,&v1);
247: if (VecLow != VecHigh){
248: VecRestoreArrayRead(VecHigh,&v2);
249: }
250: if (V != VecLow && V != VecHigh){
251: VecRestoreArrayRead(V,&vmiddle);
252: }
253: }
254: ISCreateGeneral(PetscObjectComm((PetscObject)V),n_vm,vm,PETSC_OWN_POINTER,S);
255: return(0);
256: }
259: /*@
260: VecWhichBetweenOrEqual - Creates an index set containing the indices
261: where VecLow <= V <= VecHigh
263: Collective on S
265: Input Parameters:
266: + VecLow - lower bound
267: . V - Vector to compare
268: - VecHigh - higher bound
270: OutputParameter:
271: . S - The index set containing the indices i where veclow[i] <= v[i] <= vechigh[i]
273: Level: advanced
274: @*/
276: PetscErrorCode VecWhichBetweenOrEqual(Vec VecLow, Vec V, Vec VecHigh, IS * S)
277: {
278: PetscErrorCode ierr;
279: PetscInt i,n_vm=0;
280: PetscInt n,low,high;
281: PetscInt *vm=NULL;
282: const PetscScalar *v1,*v2,*vmiddle;
290: VecCheckSameSize(V,2,VecLow,1);
291: VecCheckSameSize(V,2,VecHigh,3);
293: VecGetOwnershipRange(VecLow,&low,&high);
294: VecGetLocalSize(VecLow,&n);
295: if (n>0){
296: VecGetArrayRead(VecLow,&v1);
297: if (VecLow != VecHigh){
298: VecGetArrayRead(VecHigh,&v2);
299: } else {
300: v2=v1;
301: }
302: if (V != VecLow && V != VecHigh){
303: VecGetArrayRead(V,&vmiddle);
304: } else if (V==VecLow){
305: vmiddle=v1;
306: } else {
307: vmiddle =v2;
308: }
310: PetscMalloc1(n,&vm);
312: for (i=0; i<n; ++i){
313: if (PetscRealPart(v1[i]) <= PetscRealPart(vmiddle[i]) && PetscRealPart(vmiddle[i]) <= PetscRealPart(v2[i])) {vm[n_vm]=low+i; ++n_vm;}
314: }
316: VecRestoreArrayRead(VecLow,&v1);
317: if (VecLow != VecHigh){
318: VecRestoreArrayRead(VecHigh,&v2);
319: }
320: if (V != VecLow && V != VecHigh){
321: VecRestoreArrayRead(V,&vmiddle);
322: }
323: }
324: ISCreateGeneral(PetscObjectComm((PetscObject)V),n_vm,vm,PETSC_OWN_POINTER,S);
325: return(0);
326: }
328: /*@
329: VecWhichInactive - Creates an index set containing the indices
330: where one of the following holds:
331: a) VecLow(i) < V(i) < VecHigh(i)
332: b) VecLow(i) = V(i) and D(i) <= 0 (< 0 when Strong is true)
333: c) VecHigh(i) = V(i) and D(i) >= 0 (> 0 when Strong is true)
335: Collective on S
337: Input Parameters:
338: + VecLow - lower bound
339: . V - Vector to compare
340: . D - Direction to compare
341: . VecHigh - higher bound
342: - Strong - indicator for applying strongly inactive test
344: OutputParameter:
345: . S - The index set containing the indices i where the bound is inactive
347: Level: advanced
348: @*/
350: PetscErrorCode VecWhichInactive(Vec VecLow, Vec V, Vec D, Vec VecHigh, PetscBool Strong, IS * S)
351: {
352: PetscErrorCode ierr;
353: PetscInt i,n_vm=0;
354: PetscInt n,low,high;
355: PetscInt *vm=NULL;
356: const PetscScalar *v1,*v2,*v,*d;
366: VecCheckSameSize(V,2,VecLow,1);
367: VecCheckSameSize(V,2,D,3);
368: VecCheckSameSize(V,2,VecHigh,4);
370: VecGetOwnershipRange(VecLow,&low,&high);
371: VecGetLocalSize(VecLow,&n);
372: if (n>0){
373: VecGetArrayRead(VecLow,&v1);
374: if (VecLow != VecHigh){
375: VecGetArrayRead(VecHigh,&v2);
376: } else {
377: v2=v1;
378: }
379: if (V != VecLow && V != VecHigh){
380: VecGetArrayRead(V,&v);
381: } else if (V==VecLow){
382: v = v1;
383: } else {
384: v = v2;
385: }
386: if (D != VecLow && D != VecHigh && D != V){
387: VecGetArrayRead(D,&d);
388: } else if (D==VecLow){
389: d = v1;
390: } else if (D==VecHigh){
391: d = v2;
392: } else {
393: d = v;
394: }
396: PetscMalloc1(n,&vm);
398: if (Strong){
399: for (i=0; i<n; ++i) {
400: if (PetscRealPart(v1[i]) < PetscRealPart(v[i]) && PetscRealPart(v[i]) < PetscRealPart(v2[i])){
401: vm[n_vm]=low+i; ++n_vm;
402: } else if (PetscRealPart(v1[i]) == PetscRealPart(v[i]) && PetscRealPart(d[i]) < 0){
403: vm[n_vm]=low+i; ++n_vm;
404: } else if (PetscRealPart(v2[i]) == PetscRealPart(v[i]) && PetscRealPart(d[i]) > 0){
405: vm[n_vm]=low+i; ++n_vm;
406: }
407: }
408: } else {
409: for (i=0; i<n; ++i) {
410: if (PetscRealPart(v1[i]) < PetscRealPart(v[i]) && PetscRealPart(v[i]) < PetscRealPart(v2[i])){
411: vm[n_vm]=low+i; ++n_vm;
412: } else if (PetscRealPart(v1[i]) == PetscRealPart(v[i]) && PetscRealPart(d[i]) <= 0){
413: vm[n_vm]=low+i; ++n_vm;
414: } else if (PetscRealPart(v2[i]) == PetscRealPart(v[i]) && PetscRealPart(d[i]) >= 0){
415: vm[n_vm]=low+i; ++n_vm;
416: }
417: }
418: }
420: VecRestoreArrayRead(VecLow,&v1);
421: if (VecLow != VecHigh){
422: VecRestoreArrayRead(VecHigh,&v2);
423: }
424: if (V != VecLow && V != VecHigh){
425: VecRestoreArrayRead(V,&v);
426: }
427: if (D != VecLow && D != VecHigh && D != V){
428: VecRestoreArrayRead(D,&d);
429: }
430: }
431: ISCreateGeneral(PetscObjectComm((PetscObject)V),n_vm,vm,PETSC_OWN_POINTER,S);
432: return(0);
433: }
436: /*@
437: VecISAXPY - Adds a reduced vector to the appropriate elements of a full-space vector.
438: vfull[is[i]] += alpha*vreduced[i]
440: Input Parameters:
441: + vfull - the full-space vector
442: . is - the index set for the reduced space
443: . alpha - the scalar coefficient
444: - vreduced - the reduced-space vector
446: Output Parameters:
447: . vfull - the sum of the full-space vector and reduced-space vector
449: Level: advanced
451: .seealso: VecAXPY()
452: @*/
453: PetscErrorCode VecISAXPY(Vec vfull, IS is, PetscScalar alpha, Vec vreduced)
454: {
455: PetscInt nfull,nreduced;
462: VecGetSize(vfull,&nfull);
463: VecGetSize(vreduced,&nreduced);
465: if (nfull == nreduced) { /* Also takes care of masked vectors */
466: VecAXPY(vfull,alpha,vreduced);
467: } else {
468: PetscScalar *y;
469: const PetscScalar *x;
470: PetscInt i,n,m,rstart;
471: const PetscInt *id;
473: VecGetArray(vfull,&y);
474: VecGetArrayRead(vreduced,&x);
475: ISGetIndices(is,&id);
476: ISGetLocalSize(is,&n);
477: VecGetLocalSize(vreduced,&m);
478: if (m != n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"IS local length not equal to Vec local length");
479: VecGetOwnershipRange(vfull,&rstart,NULL);
480: y -= rstart;
481: if (alpha == 1.0) {
482: for (i=0; i<n; ++i) {
483: y[id[i]] += x[i];
484: }
485: } else {
486: for (i=0; i<n; ++i) {
487: y[id[i]] += alpha*x[i];
488: }
489: }
490: y += rstart;
491: ISRestoreIndices(is,&id);
492: VecRestoreArray(vfull,&y);
493: VecRestoreArrayRead(vreduced,&x);
494: }
495: return(0);
496: }
498: /*@
499: VecISCopy - Copies between a reduced vector and the appropriate elements of a full-space vector.
500: vfull[is[i]] = vreduced[i]
502: Input Parameters:
503: + vfull - the full-space vector
504: . is - the index set for the reduced space
505: . mode - the direction of copying, SCATTER_FORWARD or SCATTER_REVERSE
506: - vreduced - the reduced-space vector
508: Output Parameters:
509: . vfull - the sum of the full-space vector and reduced-space vector
511: Level: advanced
513: .seealso: VecAXPY()
514: @*/
515: PetscErrorCode VecISCopy(Vec vfull, IS is, ScatterMode mode, Vec vreduced)
516: {
517: PetscInt nfull, nreduced;
524: VecGetSize(vfull, &nfull);
525: VecGetSize(vreduced, &nreduced);
527: if (nfull == nreduced) { /* Also takes care of masked vectors */
528: VecCopy(vreduced, vfull);
529: } else {
530: const PetscInt *id;
531: PetscInt i, n, m, rstart;
533: ISGetIndices(is, &id);
534: ISGetLocalSize(is, &n);
535: VecGetLocalSize(vreduced, &m);
536: VecGetOwnershipRange(vfull, &rstart, NULL);
537: if (m != n) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "IS local length %D not equal to Vec local length %D", n, m);
538: if (mode == SCATTER_FORWARD) {
539: PetscScalar *y;
540: const PetscScalar *x;
542: VecGetArray(vfull, &y);
543: VecGetArrayRead(vreduced, &x);
544: y -= rstart;
545: for (i = 0; i < n; ++i) {
546: y[id[i]] = x[i];
547: }
548: y += rstart;
549: VecRestoreArrayRead(vreduced, &x);
550: VecRestoreArray(vfull, &y);
551: } else if (mode == SCATTER_REVERSE) {
552: PetscScalar *x;
553: const PetscScalar *y;
555: VecGetArrayRead(vfull, &y);
556: VecGetArray(vreduced, &x);
557: for (i = 0; i < n; ++i) {
558: x[i] = y[id[i]-rstart];
559: }
560: VecRestoreArray(vreduced, &x);
561: VecRestoreArrayRead(vfull, &y);
562: } else SETERRQ(PetscObjectComm((PetscObject) vfull), PETSC_ERR_ARG_WRONG, "Only forward or reverse modes are legal");
563: ISRestoreIndices(is, &id);
564: }
565: return(0);
566: }
568: /*@
569: ISComplementVec - Creates the complement of the index set relative to a layout defined by a Vec
571: Collective on IS
573: Input Parameter:
574: + S - a PETSc IS
575: - V - the reference vector space
577: Output Parameter:
578: . T - the complement of S
580: .seealso ISCreateGeneral()
582: Level: advanced
583: @*/
584: PetscErrorCode ISComplementVec(IS S, Vec V, IS *T)
585: {
587: PetscInt start, end;
590: VecGetOwnershipRange(V,&start,&end);
591: ISComplement(S,start,end,T);
592: return(0);
593: }
595: /*@
596: VecISSet - Sets the elements of a vector, specified by an index set, to a constant
598: Input Parameter:
599: + V - the vector
600: . S - the locations in the vector
601: - c - the constant
603: .seealso VecSet()
605: Level: advanced
606: @*/
607: PetscErrorCode VecISSet(Vec V,IS S, PetscScalar c)
608: {
610: PetscInt nloc,low,high,i;
611: const PetscInt *s;
612: PetscScalar *v;
615: if (!S) return(0); /* simply return with no-op if the index set is NULL */
621: VecGetOwnershipRange(V,&low,&high);
622: ISGetLocalSize(S,&nloc);
623: ISGetIndices(S,&s);
624: VecGetArray(V,&v);
625: for (i=0; i<nloc; ++i){
626: v[s[i]-low] = c;
627: }
628: ISRestoreIndices(S,&s);
629: VecRestoreArray(V,&v);
630: return(0);
631: }
633: #if !defined(PETSC_USE_COMPLEX)
634: /*@C
635: VecBoundGradientProjection - Projects vector according to this definition.
636: If XL[i] < X[i] < XU[i], then GP[i] = G[i];
637: If X[i] <= XL[i], then GP[i] = min(G[i],0);
638: If X[i] >= XU[i], then GP[i] = max(G[i],0);
640: Input Parameters:
641: + G - current gradient vector
642: . X - current solution vector with XL[i] <= X[i] <= XU[i]
643: . XL - lower bounds
644: - XU - upper bounds
646: Output Parameter:
647: . GP - gradient projection vector
649: Notes:
650: GP may be the same vector as G
652: Level: advanced
653: @*/
654: PetscErrorCode VecBoundGradientProjection(Vec G, Vec X, Vec XL, Vec XU, Vec GP)
655: {
657: PetscErrorCode ierr;
658: PetscInt n,i;
659: const PetscReal *xptr,*xlptr,*xuptr;
660: PetscReal *gptr,*gpptr;
661: PetscReal xval,gpval;
663: /* Project variables at the lower and upper bound */
671: VecGetLocalSize(X,&n);
673: VecGetArrayRead(X,&xptr);
674: VecGetArrayRead(XL,&xlptr);
675: VecGetArrayRead(XU,&xuptr);
676: VecGetArrayPair(G,GP,&gptr,&gpptr);
678: for (i=0; i<n; ++i){
679: gpval = gptr[i]; xval = xptr[i];
680: if (gpval>0.0 && xval<=xlptr[i]){
681: gpval = 0.0;
682: } else if (gpval<0.0 && xval>=xuptr[i]){
683: gpval = 0.0;
684: }
685: gpptr[i] = gpval;
686: }
688: VecRestoreArrayRead(X,&xptr);
689: VecRestoreArrayRead(XL,&xlptr);
690: VecRestoreArrayRead(XU,&xuptr);
691: VecRestoreArrayPair(G,GP,&gptr,&gpptr);
692: return(0);
693: }
694: #endif
696: /*@
697: VecStepMaxBounded - See below
699: Collective on Vec
701: Input Parameters:
702: + X - vector with no negative entries
703: . XL - lower bounds
704: . XU - upper bounds
705: - DX - step direction, can have negative, positive or zero entries
707: Output Parameter:
708: . stepmax - minimum value so that X[i] + stepmax*DX[i] <= XL[i] or XU[i] <= X[i] + stepmax*DX[i]
710: Level: intermediate
712: @*/
713: PetscErrorCode VecStepMaxBounded(Vec X, Vec DX, Vec XL, Vec XU, PetscReal *stepmax)
714: {
715: PetscErrorCode ierr;
716: PetscInt i,nn;
717: const PetscScalar *xx,*dx,*xl,*xu;
718: PetscReal localmax=0;
726: VecGetArrayRead(X,&xx);
727: VecGetArrayRead(XL,&xl);
728: VecGetArrayRead(XU,&xu);
729: VecGetArrayRead(DX,&dx);
730: VecGetLocalSize(X,&nn);
731: for (i=0;i<nn;i++){
732: if (PetscRealPart(dx[i]) > 0){
733: localmax=PetscMax(localmax,PetscRealPart((xu[i]-xx[i])/dx[i]));
734: } else if (PetscRealPart(dx[i])<0){
735: localmax=PetscMax(localmax,PetscRealPart((xl[i]-xx[i])/dx[i]));
736: }
737: }
738: VecRestoreArrayRead(X,&xx);
739: VecRestoreArrayRead(XL,&xl);
740: VecRestoreArrayRead(XU,&xu);
741: VecRestoreArrayRead(DX,&dx);
742: MPIU_Allreduce(&localmax,stepmax,1,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)X));
743: return(0);
744: }
746: /*@
747: VecStepBoundInfo - See below
749: Collective on Vec
751: Input Parameters:
752: + X - vector with no negative entries
753: . XL - lower bounds
754: . XU - upper bounds
755: - DX - step direction, can have negative, positive or zero entries
757: Output Parameter:
758: + boundmin - (may be NULL this it is not computed) maximum value so that XL[i] <= X[i] + boundmax*DX[i] <= XU[i]
759: . wolfemin - (may be NULL this it is not computed)
760: - boundmax - (may be NULL this it is not computed) minimum value so that X[i] + boundmax*DX[i] <= XL[i] or XU[i] <= X[i] + boundmax*DX[i]
762: Notes:
763: For complex numbers only compares the real part
765: Level: advanced
766: @*/
767: PetscErrorCode VecStepBoundInfo(Vec X, Vec DX, Vec XL, Vec XU, PetscReal *boundmin, PetscReal *wolfemin, PetscReal *boundmax)
768: {
769: PetscErrorCode ierr;
770: PetscInt n,i;
771: const PetscScalar *x,*xl,*xu,*dx;
772: PetscReal t;
773: PetscReal localmin=PETSC_INFINITY,localwolfemin=PETSC_INFINITY,localmax=-1;
774: MPI_Comm comm;
782: VecGetArrayRead(X,&x);
783: VecGetArrayRead(XL,&xl);
784: VecGetArrayRead(XU,&xu);
785: VecGetArrayRead(DX,&dx);
786: VecGetLocalSize(X,&n);
787: for (i=0; i<n; ++i){
788: if (PetscRealPart(dx[i])>0 && PetscRealPart(xu[i]) < PETSC_INFINITY) {
789: t=PetscRealPart((xu[i]-x[i])/dx[i]);
790: localmin=PetscMin(t,localmin);
791: if (localmin>0){
792: localwolfemin = PetscMin(t,localwolfemin);
793: }
794: localmax = PetscMax(t,localmax);
795: } else if (PetscRealPart(dx[i])<0 && PetscRealPart(xl[i]) > PETSC_NINFINITY) {
796: t=PetscRealPart((xl[i]-x[i])/dx[i]);
797: localmin = PetscMin(t,localmin);
798: if (localmin>0){
799: localwolfemin = PetscMin(t,localwolfemin);
800: }
801: localmax = PetscMax(t,localmax);
802: }
803: }
805: VecRestoreArrayRead(X,&x);
806: VecRestoreArrayRead(XL,&xl);
807: VecRestoreArrayRead(XU,&xu);
808: VecRestoreArrayRead(DX,&dx);
809: ierr=PetscObjectGetComm((PetscObject)X,&comm);
811: if (boundmin){
812: MPIU_Allreduce(&localmin,boundmin,1,MPIU_REAL,MPIU_MIN,comm);
813: PetscInfo1(X,"Step Bound Info: Closest Bound: %20.19e\n",(double)*boundmin);
814: }
815: if (wolfemin){
816: MPIU_Allreduce(&localwolfemin,wolfemin,1,MPIU_REAL,MPIU_MIN,comm);
817: PetscInfo1(X,"Step Bound Info: Wolfe: %20.19e\n",(double)*wolfemin);
818: }
819: if (boundmax) {
820: MPIU_Allreduce(&localmax,boundmax,1,MPIU_REAL,MPIU_MAX,comm);
821: if (*boundmax < 0) *boundmax=PETSC_INFINITY;
822: PetscInfo1(X,"Step Bound Info: Max: %20.19e\n",(double)*boundmax);
823: }
824: return(0);
825: }
827: /*@
828: VecStepMax - Returns the largest value so that x[i] + step*DX[i] >= 0 for all i
830: Collective on Vec
832: Input Parameters:
833: + X - vector with no negative entries
834: - DX - a step direction, can have negative, positive or zero entries
836: Output Parameter:
837: . step - largest value such that x[i] + step*DX[i] >= 0 for all i
839: Notes:
840: For complex numbers only compares the real part
842: Level: advanced
843: @*/
844: PetscErrorCode VecStepMax(Vec X, Vec DX, PetscReal *step)
845: {
846: PetscErrorCode ierr;
847: PetscInt i,nn;
848: PetscReal stepmax=PETSC_INFINITY;
849: const PetscScalar *xx,*dx;
855: VecGetLocalSize(X,&nn);
856: VecGetArrayRead(X,&xx);
857: VecGetArrayRead(DX,&dx);
858: for (i=0;i<nn;++i){
859: if (PetscRealPart(xx[i]) < 0) SETERRQ(PETSC_COMM_SELF,1,"Vector must be positive");
860: else if (PetscRealPart(dx[i])<0) stepmax=PetscMin(stepmax,PetscRealPart(-xx[i]/dx[i]));
861: }
862: VecRestoreArrayRead(X,&xx);
863: VecRestoreArrayRead(DX,&dx);
864: MPIU_Allreduce(&stepmax,step,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)X));
865: return(0);
866: }
868: /*@
869: VecPow - Replaces each component of a vector by x_i^p
871: Logically Collective on v
873: Input Parameter:
874: + v - the vector
875: - p - the exponent to use on each element
877: Output Parameter:
878: . v - the vector
880: Level: intermediate
882: @*/
883: PetscErrorCode VecPow(Vec v, PetscScalar p)
884: {
886: PetscInt n,i;
887: PetscScalar *v1;
892: VecGetArray(v,&v1);
893: VecGetLocalSize(v,&n);
895: if (1.0 == p) {
896: } else if (-1.0 == p) {
897: for (i = 0; i < n; ++i){
898: v1[i] = 1.0 / v1[i];
899: }
900: } else if (0.0 == p) {
901: for (i = 0; i < n; ++i){
902: /* Not-a-number left alone
903: Infinity set to one */
904: if (v1[i] == v1[i]) {
905: v1[i] = 1.0;
906: }
907: }
908: } else if (0.5 == p) {
909: for (i = 0; i < n; ++i) {
910: if (PetscRealPart(v1[i]) >= 0) {
911: v1[i] = PetscSqrtScalar(v1[i]);
912: } else {
913: v1[i] = PETSC_INFINITY;
914: }
915: }
916: } else if (-0.5 == p) {
917: for (i = 0; i < n; ++i) {
918: if (PetscRealPart(v1[i]) >= 0) {
919: v1[i] = 1.0 / PetscSqrtScalar(v1[i]);
920: } else {
921: v1[i] = PETSC_INFINITY;
922: }
923: }
924: } else if (2.0 == p) {
925: for (i = 0; i < n; ++i){
926: v1[i] *= v1[i];
927: }
928: } else if (-2.0 == p) {
929: for (i = 0; i < n; ++i){
930: v1[i] = 1.0 / (v1[i] * v1[i]);
931: }
932: } else {
933: for (i = 0; i < n; ++i) {
934: if (PetscRealPart(v1[i]) >= 0) {
935: v1[i] = PetscPowScalar(v1[i],p);
936: } else {
937: v1[i] = PETSC_INFINITY;
938: }
939: }
940: }
941: VecRestoreArray(v,&v1);
942: return(0);
943: }
945: /*@
946: VecMedian - Computes the componentwise median of three vectors
947: and stores the result in this vector. Used primarily for projecting
948: a vector within upper and lower bounds.
950: Logically Collective
952: Input Parameters:
953: . Vec1, Vec2, Vec3 - The three vectors
955: Output Parameter:
956: . VMedian - The median vector (this can be any one of the input vectors)
958: Level: advanced
959: @*/
960: PetscErrorCode VecMedian(Vec Vec1, Vec Vec2, Vec Vec3, Vec VMedian)
961: {
962: PetscErrorCode ierr;
963: PetscInt i,n,low1,high1;
964: const PetscScalar *v1,*v2,*v3;
965: PetscScalar *vmed;
973: if (Vec1==Vec2 || Vec1==Vec3){
974: VecCopy(Vec1,VMedian);
975: return(0);
976: }
977: if (Vec2==Vec3){
978: VecCopy(Vec2,VMedian);
979: return(0);
980: }
982: /* Assert that Vec1 != Vec2 and Vec2 != Vec3 */
993: VecCheckSameSize(Vec1,1,Vec2,2);
994: VecCheckSameSize(Vec1,1,Vec3,3);
995: VecCheckSameSize(Vec1,1,VMedian,4);
997: VecGetOwnershipRange(Vec1,&low1,&high1);
998: VecGetLocalSize(Vec1,&n);
999: if (n>0){
1000: VecGetArray(VMedian,&vmed);
1001: if (Vec1 != VMedian){
1002: VecGetArrayRead(Vec1,&v1);
1003: } else {
1004: v1=vmed;
1005: }
1006: if (Vec2 != VMedian){
1007: VecGetArrayRead(Vec2,&v2);
1008: } else {
1009: v2=vmed;
1010: }
1011: if (Vec3 != VMedian){
1012: VecGetArrayRead(Vec3,&v3);
1013: } else {
1014: v3=vmed;
1015: }
1017: for (i=0;i<n;++i){
1018: vmed[i]=PetscMax(PetscMax(PetscMin(PetscRealPart(v1[i]),PetscRealPart(v2[i])),PetscMin(PetscRealPart(v1[i]),PetscRealPart(v3[i]))),PetscMin(PetscRealPart(v2[i]),PetscRealPart(v3[i])));
1019: }
1021: VecRestoreArray(VMedian,&vmed);
1022: if (VMedian != Vec1){
1023: VecRestoreArrayRead(Vec1,&v1);
1024: }
1025: if (VMedian != Vec2){
1026: VecRestoreArrayRead(Vec2,&v2);
1027: }
1028: if (VMedian != Vec3){
1029: VecRestoreArrayRead(Vec3,&v3);
1030: }
1031: }
1032: return(0);
1033: }