xref: /petsc/src/tao/util/tao_util.c (revision a7e14dcfba0d07adf6226a919460249440ec94c7)
1*a7e14dcfSSatish Balay #include "petsc-private/petscimpl.h"
2*a7e14dcfSSatish Balay #include "tao.h" /*I "tao.h" I*/
3*a7e14dcfSSatish Balay #include "tao_util.h" /*I "tao_util.h" I*/
4*a7e14dcfSSatish Balay 
5*a7e14dcfSSatish Balay #undef __FUNCT__
6*a7e14dcfSSatish Balay #define __FUNCT__ "VecPow"
7*a7e14dcfSSatish Balay /*@
8*a7e14dcfSSatish Balay   VecPow - Replaces each component of a vector by x_i^p
9*a7e14dcfSSatish Balay 
10*a7e14dcfSSatish Balay   Logically Collective on v
11*a7e14dcfSSatish Balay 
12*a7e14dcfSSatish Balay   Input Parameter:
13*a7e14dcfSSatish Balay + v - the vector
14*a7e14dcfSSatish Balay - p - the exponent to use on each element
15*a7e14dcfSSatish Balay 
16*a7e14dcfSSatish Balay   Output Parameter:
17*a7e14dcfSSatish Balay . v - the vector
18*a7e14dcfSSatish Balay 
19*a7e14dcfSSatish Balay   Level: intermediate
20*a7e14dcfSSatish Balay 
21*a7e14dcfSSatish Balay @*/
22*a7e14dcfSSatish Balay PetscErrorCode VecPow(Vec v, PetscReal p)
23*a7e14dcfSSatish Balay {
24*a7e14dcfSSatish Balay   PetscErrorCode ierr;
25*a7e14dcfSSatish Balay   PetscInt n,i;
26*a7e14dcfSSatish Balay   PetscReal *v1;
27*a7e14dcfSSatish Balay 
28*a7e14dcfSSatish Balay   PetscFunctionBegin;
29*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
30*a7e14dcfSSatish Balay 
31*a7e14dcfSSatish Balay   ierr = VecGetArray(v, &v1); CHKERRQ(ierr);
32*a7e14dcfSSatish Balay   ierr = VecGetLocalSize(v, &n); CHKERRQ(ierr);
33*a7e14dcfSSatish Balay 
34*a7e14dcfSSatish Balay   if (1.0 == p) {
35*a7e14dcfSSatish Balay   }
36*a7e14dcfSSatish Balay   else if (-1.0 == p) {
37*a7e14dcfSSatish Balay     for (i = 0; i < n; ++i){
38*a7e14dcfSSatish Balay       v1[i] = 1.0 / v1[i];
39*a7e14dcfSSatish Balay     }
40*a7e14dcfSSatish Balay   }
41*a7e14dcfSSatish Balay   else if (0.0 == p) {
42*a7e14dcfSSatish Balay     for (i = 0; i < n; ++i){
43*a7e14dcfSSatish Balay       /*  Not-a-number left alone
44*a7e14dcfSSatish Balay 	  Infinity set to one  */
45*a7e14dcfSSatish Balay       if (v1[i] == v1[i]) {
46*a7e14dcfSSatish Balay         v1[i] = 1.0;
47*a7e14dcfSSatish Balay       }
48*a7e14dcfSSatish Balay     }
49*a7e14dcfSSatish Balay   }
50*a7e14dcfSSatish Balay   else if (0.5 == p) {
51*a7e14dcfSSatish Balay     for (i = 0; i < n; ++i) {
52*a7e14dcfSSatish Balay       if (v1[i] >= 0) {
53*a7e14dcfSSatish Balay         v1[i] = PetscSqrtScalar(v1[i]);
54*a7e14dcfSSatish Balay       }
55*a7e14dcfSSatish Balay       else {
56*a7e14dcfSSatish Balay         v1[i] = TAO_INFINITY;
57*a7e14dcfSSatish Balay       }
58*a7e14dcfSSatish Balay     }
59*a7e14dcfSSatish Balay   }
60*a7e14dcfSSatish Balay   else if (-0.5 == p) {
61*a7e14dcfSSatish Balay     for (i = 0; i < n; ++i) {
62*a7e14dcfSSatish Balay       if (v1[i] >= 0) {
63*a7e14dcfSSatish Balay         v1[i] = 1.0 / PetscSqrtScalar(v1[i]);
64*a7e14dcfSSatish Balay       }
65*a7e14dcfSSatish Balay       else {
66*a7e14dcfSSatish Balay         v1[i] = TAO_INFINITY;
67*a7e14dcfSSatish Balay       }
68*a7e14dcfSSatish Balay     }
69*a7e14dcfSSatish Balay   }
70*a7e14dcfSSatish Balay   else if (2.0 == p) {
71*a7e14dcfSSatish Balay     for (i = 0; i < n; ++i){
72*a7e14dcfSSatish Balay       v1[i] *= v1[i];
73*a7e14dcfSSatish Balay     }
74*a7e14dcfSSatish Balay   }
75*a7e14dcfSSatish Balay   else if (-2.0 == p) {
76*a7e14dcfSSatish Balay     for (i = 0; i < n; ++i){
77*a7e14dcfSSatish Balay       v1[i] = 1.0 / (v1[i] * v1[i]);
78*a7e14dcfSSatish Balay     }
79*a7e14dcfSSatish Balay   }
80*a7e14dcfSSatish Balay   else {
81*a7e14dcfSSatish Balay     for (i = 0; i < n; ++i) {
82*a7e14dcfSSatish Balay       if (v1[i] >= 0) {
83*a7e14dcfSSatish Balay         v1[i] = PetscPowScalar(v1[i], p);
84*a7e14dcfSSatish Balay       }
85*a7e14dcfSSatish Balay       else {
86*a7e14dcfSSatish Balay         v1[i] = TAO_INFINITY;
87*a7e14dcfSSatish Balay       }
88*a7e14dcfSSatish Balay     }
89*a7e14dcfSSatish Balay   }
90*a7e14dcfSSatish Balay 
91*a7e14dcfSSatish Balay   ierr = VecRestoreArray(v,&v1); CHKERRQ(ierr);
92*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
93*a7e14dcfSSatish Balay }
94*a7e14dcfSSatish Balay 
95*a7e14dcfSSatish Balay #undef __FUNCT__
96*a7e14dcfSSatish Balay #define __FUNCT__ "VecMedian"
97*a7e14dcfSSatish Balay /*@
98*a7e14dcfSSatish Balay   VecMedian - Computes the componentwise median of three vectors
99*a7e14dcfSSatish Balay   and stores the result in this vector.  Used primarily for projecting
100*a7e14dcfSSatish Balay   a vector within upper and lower bounds.
101*a7e14dcfSSatish Balay 
102*a7e14dcfSSatish Balay   Logically Collective
103*a7e14dcfSSatish Balay 
104*a7e14dcfSSatish Balay   Input Parameters:
105*a7e14dcfSSatish Balay . Vec1, Vec2, Vec3 - The three vectors
106*a7e14dcfSSatish Balay 
107*a7e14dcfSSatish Balay   Output Parameter:
108*a7e14dcfSSatish Balay . VMedian - The median vector
109*a7e14dcfSSatish Balay 
110*a7e14dcfSSatish Balay   Level: advanced
111*a7e14dcfSSatish Balay @*/
112*a7e14dcfSSatish Balay PetscErrorCode VecMedian(Vec Vec1, Vec Vec2, Vec Vec3, Vec VMedian)
113*a7e14dcfSSatish Balay {
114*a7e14dcfSSatish Balay   PetscErrorCode ierr;
115*a7e14dcfSSatish Balay   PetscInt i,n,low1,low2,low3,low4,high1,high2,high3,high4;
116*a7e14dcfSSatish Balay   PetscReal *v1,*v2,*v3,*vmed;
117*a7e14dcfSSatish Balay 
118*a7e14dcfSSatish Balay   PetscFunctionBegin;
119*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(Vec1,VEC_CLASSID,1);
120*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(Vec2,VEC_CLASSID,2);
121*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(Vec3,VEC_CLASSID,3);
122*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(VMedian,VEC_CLASSID,4);
123*a7e14dcfSSatish Balay 
124*a7e14dcfSSatish Balay   if (Vec1==Vec2 || Vec1==Vec3){
125*a7e14dcfSSatish Balay     ierr=VecCopy(Vec1,VMedian); CHKERRQ(ierr);
126*a7e14dcfSSatish Balay     PetscFunctionReturn(0);
127*a7e14dcfSSatish Balay   }
128*a7e14dcfSSatish Balay   if (Vec2==Vec3){
129*a7e14dcfSSatish Balay     ierr=VecCopy(Vec2,VMedian); CHKERRQ(ierr);
130*a7e14dcfSSatish Balay     PetscFunctionReturn(0);
131*a7e14dcfSSatish Balay   }
132*a7e14dcfSSatish Balay 
133*a7e14dcfSSatish Balay   PetscValidType(Vec1,1);
134*a7e14dcfSSatish Balay   PetscValidType(Vec2,2);
135*a7e14dcfSSatish Balay   PetscValidType(VMedian,4);
136*a7e14dcfSSatish Balay   PetscCheckSameType(Vec1,1,Vec2,2); PetscCheckSameType(Vec1,1,VMedian,4);
137*a7e14dcfSSatish Balay   PetscCheckSameComm(Vec1,1,Vec2,2); PetscCheckSameComm(Vec1,1,VMedian,4);
138*a7e14dcfSSatish Balay 
139*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(Vec1, &low1, &high1); CHKERRQ(ierr);
140*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(Vec2, &low2, &high2); CHKERRQ(ierr);
141*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(Vec3, &low3, &high3); CHKERRQ(ierr);
142*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(VMedian, &low4, &high4); CHKERRQ(ierr);
143*a7e14dcfSSatish Balay   if ( low1!= low2 || low1!= low3 || low1!= low4 ||
144*a7e14dcfSSatish Balay        high1!= high2 || high1!= high3 || high1!= high4)
145*a7e14dcfSSatish Balay     SETERRQ(PETSC_COMM_SELF,1,"InCompatible vector local lengths");
146*a7e14dcfSSatish Balay 
147*a7e14dcfSSatish Balay   ierr = VecGetArray(Vec1,&v1); CHKERRQ(ierr);
148*a7e14dcfSSatish Balay   ierr = VecGetArray(Vec2,&v2); CHKERRQ(ierr);
149*a7e14dcfSSatish Balay   ierr = VecGetArray(Vec3,&v3); CHKERRQ(ierr);
150*a7e14dcfSSatish Balay 
151*a7e14dcfSSatish Balay   if ( VMedian != Vec1 && VMedian != Vec2 && VMedian != Vec3){
152*a7e14dcfSSatish Balay     ierr = VecGetArray(VMedian,&vmed); CHKERRQ(ierr);
153*a7e14dcfSSatish Balay   } else if ( VMedian==Vec1 ){
154*a7e14dcfSSatish Balay     vmed=v1;
155*a7e14dcfSSatish Balay   } else if ( VMedian==Vec2 ){
156*a7e14dcfSSatish Balay     vmed=v2;
157*a7e14dcfSSatish Balay   } else {
158*a7e14dcfSSatish Balay     vmed=v3;
159*a7e14dcfSSatish Balay   }
160*a7e14dcfSSatish Balay 
161*a7e14dcfSSatish Balay   ierr=VecGetLocalSize(Vec1,&n); CHKERRQ(ierr);
162*a7e14dcfSSatish Balay 
163*a7e14dcfSSatish Balay   for (i=0;i<n;i++){
164*a7e14dcfSSatish Balay     vmed[i]=PetscMax(PetscMax(PetscMin(v1[i],v2[i]),PetscMin(v1[i],v3[i])),PetscMin(v2[i],v3[i]));
165*a7e14dcfSSatish Balay   }
166*a7e14dcfSSatish Balay 
167*a7e14dcfSSatish Balay   ierr = VecRestoreArray(Vec1,&v1); CHKERRQ(ierr);
168*a7e14dcfSSatish Balay   ierr = VecRestoreArray(Vec2,&v2); CHKERRQ(ierr);
169*a7e14dcfSSatish Balay   ierr = VecRestoreArray(Vec3,&v2); CHKERRQ(ierr);
170*a7e14dcfSSatish Balay 
171*a7e14dcfSSatish Balay   if (VMedian!=Vec1 && VMedian != Vec2 && VMedian != Vec3){
172*a7e14dcfSSatish Balay     ierr = VecRestoreArray(VMedian,&vmed); CHKERRQ(ierr);
173*a7e14dcfSSatish Balay   }
174*a7e14dcfSSatish Balay 
175*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
176*a7e14dcfSSatish Balay }
177*a7e14dcfSSatish Balay 
178*a7e14dcfSSatish Balay PETSC_STATIC_INLINE PetscReal Fischer(PetscReal a, PetscReal b)
179*a7e14dcfSSatish Balay {
180*a7e14dcfSSatish Balay   /* Method suggested by Bob Vanderbei */
181*a7e14dcfSSatish Balay    if (a + b <= 0) {
182*a7e14dcfSSatish Balay      return PetscSqrtScalar(a*a + b*b) - (a + b);
183*a7e14dcfSSatish Balay    }
184*a7e14dcfSSatish Balay    return -2.0*a*b / (PetscSqrtScalar(a*a + b*b) + (a + b));
185*a7e14dcfSSatish Balay }
186*a7e14dcfSSatish Balay 
187*a7e14dcfSSatish Balay #undef __FUNCT__
188*a7e14dcfSSatish Balay #define __FUNCT__ "VecFischer"
189*a7e14dcfSSatish Balay /*@
190*a7e14dcfSSatish Balay    VecFischer - Evaluates the Fischer-Burmeister function for complementarity
191*a7e14dcfSSatish Balay    problems.
192*a7e14dcfSSatish Balay 
193*a7e14dcfSSatish Balay    Logically Collective on vectors
194*a7e14dcfSSatish Balay 
195*a7e14dcfSSatish Balay    Input Parameters:
196*a7e14dcfSSatish Balay +  X - current point
197*a7e14dcfSSatish Balay .  F - function evaluated at x
198*a7e14dcfSSatish Balay .  L - lower bounds
199*a7e14dcfSSatish Balay -  U - upper bounds
200*a7e14dcfSSatish Balay 
201*a7e14dcfSSatish Balay    Output Parameters:
202*a7e14dcfSSatish Balay .  FB - The Fischer-Burmeister function vector
203*a7e14dcfSSatish Balay 
204*a7e14dcfSSatish Balay    Notes:
205*a7e14dcfSSatish Balay    The Fischer-Burmeister function is defined as
206*a7e14dcfSSatish Balay $        phi(a,b) := sqrt(a*a + b*b) - a - b
207*a7e14dcfSSatish Balay    and is used reformulate a complementarity problem as a semismooth
208*a7e14dcfSSatish Balay    system of equations.
209*a7e14dcfSSatish Balay 
210*a7e14dcfSSatish Balay    The result of this function is done by cases:
211*a7e14dcfSSatish Balay +  l[i] == -infinity, u[i] == infinity  -- fb[i] = -f[i]
212*a7e14dcfSSatish Balay .  l[i] == -infinity, u[i] finite       -- fb[i] = phi(u[i]-x[i], -f[i])
213*a7e14dcfSSatish Balay .  l[i] finite,       u[i] == infinity  -- fb[i] = phi(x[i]-l[i],  f[i])
214*a7e14dcfSSatish Balay .  l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u]))
215*a7e14dcfSSatish Balay -  otherwise l[i] == u[i] -- fb[i] = l[i] - x[i]
216*a7e14dcfSSatish Balay 
217*a7e14dcfSSatish Balay    Level: developer
218*a7e14dcfSSatish Balay 
219*a7e14dcfSSatish Balay @*/
220*a7e14dcfSSatish Balay PetscErrorCode VecFischer(Vec X, Vec F, Vec L, Vec U, Vec FB)
221*a7e14dcfSSatish Balay {
222*a7e14dcfSSatish Balay   PetscReal *x, *f, *l, *u, *fb;
223*a7e14dcfSSatish Balay   PetscReal xval, fval, lval, uval;
224*a7e14dcfSSatish Balay   PetscErrorCode ierr;
225*a7e14dcfSSatish Balay   PetscInt low[5], high[5], n, i;
226*a7e14dcfSSatish Balay 
227*a7e14dcfSSatish Balay   PetscFunctionBegin;
228*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,1);
229*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F, VEC_CLASSID,2);
230*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(L, VEC_CLASSID,3);
231*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(U, VEC_CLASSID,4);
232*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(FB, VEC_CLASSID,4);
233*a7e14dcfSSatish Balay 
234*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(X, low, high); CHKERRQ(ierr);
235*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(F, low + 1, high + 1); CHKERRQ(ierr);
236*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(L, low + 2, high + 2); CHKERRQ(ierr);
237*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(U, low + 3, high + 3); CHKERRQ(ierr);
238*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(FB, low + 4, high + 4); CHKERRQ(ierr);
239*a7e14dcfSSatish Balay 
240*a7e14dcfSSatish Balay   for (i = 1; i < 4; ++i) {
241*a7e14dcfSSatish Balay     if (low[0] != low[i] || high[0] != high[i])
242*a7e14dcfSSatish Balay       SETERRQ(PETSC_COMM_SELF,1,"Vectors must be identically loaded over processors");
243*a7e14dcfSSatish Balay   }
244*a7e14dcfSSatish Balay 
245*a7e14dcfSSatish Balay   ierr = VecGetArray(X, &x); CHKERRQ(ierr);
246*a7e14dcfSSatish Balay   ierr = VecGetArray(F, &f); CHKERRQ(ierr);
247*a7e14dcfSSatish Balay   ierr = VecGetArray(L, &l); CHKERRQ(ierr);
248*a7e14dcfSSatish Balay   ierr = VecGetArray(U, &u); CHKERRQ(ierr);
249*a7e14dcfSSatish Balay   ierr = VecGetArray(FB, &fb); CHKERRQ(ierr);
250*a7e14dcfSSatish Balay 
251*a7e14dcfSSatish Balay   ierr = VecGetLocalSize(X, &n); CHKERRQ(ierr);
252*a7e14dcfSSatish Balay 
253*a7e14dcfSSatish Balay   for (i = 0; i < n; ++i) {
254*a7e14dcfSSatish Balay     xval = x[i]; fval = f[i];
255*a7e14dcfSSatish Balay     lval = l[i]; uval = u[i];
256*a7e14dcfSSatish Balay 
257*a7e14dcfSSatish Balay     if ((lval <= -TAO_INFINITY) && (uval >= TAO_INFINITY)) {
258*a7e14dcfSSatish Balay       fb[i] = -fval;
259*a7e14dcfSSatish Balay     }
260*a7e14dcfSSatish Balay     else if (lval <= -TAO_INFINITY) {
261*a7e14dcfSSatish Balay       fb[i] = -Fischer(uval - xval, -fval);
262*a7e14dcfSSatish Balay     }
263*a7e14dcfSSatish Balay     else if (uval >=  TAO_INFINITY) {
264*a7e14dcfSSatish Balay       fb[i] =  Fischer(xval - lval,  fval);
265*a7e14dcfSSatish Balay     }
266*a7e14dcfSSatish Balay     else if (lval == uval) {
267*a7e14dcfSSatish Balay       fb[i] = lval - xval;
268*a7e14dcfSSatish Balay     }
269*a7e14dcfSSatish Balay     else {
270*a7e14dcfSSatish Balay       fval  =  Fischer(uval - xval, -fval);
271*a7e14dcfSSatish Balay       fb[i] =  Fischer(xval - lval,  fval);
272*a7e14dcfSSatish Balay     }
273*a7e14dcfSSatish Balay   }
274*a7e14dcfSSatish Balay 
275*a7e14dcfSSatish Balay   ierr = VecRestoreArray(X, &x); CHKERRQ(ierr);
276*a7e14dcfSSatish Balay   ierr = VecRestoreArray(F, &f); CHKERRQ(ierr);
277*a7e14dcfSSatish Balay   ierr = VecRestoreArray(L, &l); CHKERRQ(ierr);
278*a7e14dcfSSatish Balay   ierr = VecRestoreArray(U, &u); CHKERRQ(ierr);
279*a7e14dcfSSatish Balay   ierr = VecRestoreArray(FB, &fb); CHKERRQ(ierr);
280*a7e14dcfSSatish Balay 
281*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
282*a7e14dcfSSatish Balay }
283*a7e14dcfSSatish Balay 
284*a7e14dcfSSatish Balay PETSC_STATIC_INLINE PetscReal SFischer(PetscReal a, PetscReal b, PetscReal c)
285*a7e14dcfSSatish Balay {
286*a7e14dcfSSatish Balay   /* Method suggested by Bob Vanderbei */
287*a7e14dcfSSatish Balay    if (a + b <= 0) {
288*a7e14dcfSSatish Balay      return PetscSqrtScalar(a*a + b*b + 2.0*c*c) - (a + b);
289*a7e14dcfSSatish Balay    }
290*a7e14dcfSSatish Balay    return 2.0*(c*c - a*b) / (PetscSqrtScalar(a*a + b*b + 2.0*c*c) + (a + b));
291*a7e14dcfSSatish Balay }
292*a7e14dcfSSatish Balay 
293*a7e14dcfSSatish Balay #undef __FUNCT__
294*a7e14dcfSSatish Balay #define __FUNCT__ "VecSFischer"
295*a7e14dcfSSatish Balay /*@
296*a7e14dcfSSatish Balay    VecSFischer - Evaluates the Smoothed Fischer-Burmeister function for
297*a7e14dcfSSatish Balay    complementarity problems.
298*a7e14dcfSSatish Balay 
299*a7e14dcfSSatish Balay    Logically Collective on vectors
300*a7e14dcfSSatish Balay 
301*a7e14dcfSSatish Balay    Input Parameters:
302*a7e14dcfSSatish Balay +  X - current point
303*a7e14dcfSSatish Balay .  F - function evaluated at x
304*a7e14dcfSSatish Balay .  L - lower bounds
305*a7e14dcfSSatish Balay .  U - upper bounds
306*a7e14dcfSSatish Balay -  mu - smoothing parameter
307*a7e14dcfSSatish Balay 
308*a7e14dcfSSatish Balay    Output Parameters:
309*a7e14dcfSSatish Balay .  FB - The Smoothed Fischer-Burmeister function vector
310*a7e14dcfSSatish Balay 
311*a7e14dcfSSatish Balay    Notes:
312*a7e14dcfSSatish Balay    The Smoothed Fischer-Burmeister function is defined as
313*a7e14dcfSSatish Balay $        phi(a,b) := sqrt(a*a + b*b + 2*mu*mu) - a - b
314*a7e14dcfSSatish Balay    and is used reformulate a complementarity problem as a semismooth
315*a7e14dcfSSatish Balay    system of equations.
316*a7e14dcfSSatish Balay 
317*a7e14dcfSSatish Balay    The result of this function is done by cases:
318*a7e14dcfSSatish Balay +  l[i] == -infinity, u[i] == infinity  -- fb[i] = -f[i] - 2*mu*x[i]
319*a7e14dcfSSatish Balay .  l[i] == -infinity, u[i] finite       -- fb[i] = phi(u[i]-x[i], -f[i], mu)
320*a7e14dcfSSatish Balay .  l[i] finite,       u[i] == infinity  -- fb[i] = phi(x[i]-l[i],  f[i], mu)
321*a7e14dcfSSatish Balay .  l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u], mu), mu)
322*a7e14dcfSSatish Balay -  otherwise l[i] == u[i] -- fb[i] = l[i] - x[i]
323*a7e14dcfSSatish Balay 
324*a7e14dcfSSatish Balay    Level: developer
325*a7e14dcfSSatish Balay 
326*a7e14dcfSSatish Balay .seealso  VecFischer()
327*a7e14dcfSSatish Balay @*/
328*a7e14dcfSSatish Balay PetscErrorCode VecSFischer(Vec X, Vec F, Vec L, Vec U, PetscReal mu, Vec FB)
329*a7e14dcfSSatish Balay {
330*a7e14dcfSSatish Balay   PetscReal *x, *f, *l, *u, *fb;
331*a7e14dcfSSatish Balay   PetscReal xval, fval, lval, uval;
332*a7e14dcfSSatish Balay   PetscErrorCode ierr;
333*a7e14dcfSSatish Balay   PetscInt low[5], high[5], n, i;
334*a7e14dcfSSatish Balay 
335*a7e14dcfSSatish Balay   PetscFunctionBegin;
336*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,1);
337*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(F, VEC_CLASSID,2);
338*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(L, VEC_CLASSID,3);
339*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(U, VEC_CLASSID,4);
340*a7e14dcfSSatish Balay   PetscValidHeaderSpecific(FB, VEC_CLASSID,6);
341*a7e14dcfSSatish Balay 
342*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(X, low, high); CHKERRQ(ierr);
343*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(F, low + 1, high + 1); CHKERRQ(ierr);
344*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(L, low + 2, high + 2); CHKERRQ(ierr);
345*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(U, low + 3, high + 3); CHKERRQ(ierr);
346*a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(FB, low + 4, high + 4); CHKERRQ(ierr);
347*a7e14dcfSSatish Balay 
348*a7e14dcfSSatish Balay   for (i = 1; i < 4; ++i) {
349*a7e14dcfSSatish Balay     if (low[0] != low[i] || high[0] != high[i])
350*a7e14dcfSSatish Balay       SETERRQ(PETSC_COMM_SELF,1,"Vectors must be identically loaded over processors");
351*a7e14dcfSSatish Balay   }
352*a7e14dcfSSatish Balay 
353*a7e14dcfSSatish Balay   ierr = VecGetArray(X, &x); CHKERRQ(ierr);
354*a7e14dcfSSatish Balay   ierr = VecGetArray(F, &f); CHKERRQ(ierr);
355*a7e14dcfSSatish Balay   ierr = VecGetArray(L, &l); CHKERRQ(ierr);
356*a7e14dcfSSatish Balay   ierr = VecGetArray(U, &u); CHKERRQ(ierr);
357*a7e14dcfSSatish Balay   ierr = VecGetArray(FB, &fb); CHKERRQ(ierr);
358*a7e14dcfSSatish Balay 
359*a7e14dcfSSatish Balay   ierr = VecGetLocalSize(X, &n); CHKERRQ(ierr);
360*a7e14dcfSSatish Balay 
361*a7e14dcfSSatish Balay   for (i = 0; i < n; ++i) {
362*a7e14dcfSSatish Balay     xval = (*x++); fval = (*f++);
363*a7e14dcfSSatish Balay     lval = (*l++); uval = (*u++);
364*a7e14dcfSSatish Balay 
365*a7e14dcfSSatish Balay     if ((lval <= -TAO_INFINITY) && (uval >= TAO_INFINITY)) {
366*a7e14dcfSSatish Balay       (*fb++) = -fval - mu*xval;
367*a7e14dcfSSatish Balay     }
368*a7e14dcfSSatish Balay     else if (lval <= -TAO_INFINITY) {
369*a7e14dcfSSatish Balay       (*fb++) = -SFischer(uval - xval, -fval, mu);
370*a7e14dcfSSatish Balay     }
371*a7e14dcfSSatish Balay     else if (uval >=  TAO_INFINITY) {
372*a7e14dcfSSatish Balay       (*fb++) =  SFischer(xval - lval,  fval, mu);
373*a7e14dcfSSatish Balay     }
374*a7e14dcfSSatish Balay     else if (lval == uval) {
375*a7e14dcfSSatish Balay       (*fb++) = lval - xval;
376*a7e14dcfSSatish Balay     }
377*a7e14dcfSSatish Balay     else {
378*a7e14dcfSSatish Balay       fval    =  SFischer(uval - xval, -fval, mu);
379*a7e14dcfSSatish Balay       (*fb++) =  SFischer(xval - lval,  fval, mu);
380*a7e14dcfSSatish Balay     }
381*a7e14dcfSSatish Balay   }
382*a7e14dcfSSatish Balay   x -= n; f -= n; l -=n; u -= n; fb -= n;
383*a7e14dcfSSatish Balay 
384*a7e14dcfSSatish Balay   ierr = VecRestoreArray(X, &x); CHKERRQ(ierr);
385*a7e14dcfSSatish Balay   ierr = VecRestoreArray(F, &f); CHKERRQ(ierr);
386*a7e14dcfSSatish Balay   ierr = VecRestoreArray(L, &l); CHKERRQ(ierr);
387*a7e14dcfSSatish Balay   ierr = VecRestoreArray(U, &u); CHKERRQ(ierr);
388*a7e14dcfSSatish Balay   ierr = VecRestoreArray(FB, &fb); CHKERRQ(ierr);
389*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
390*a7e14dcfSSatish Balay }
391*a7e14dcfSSatish Balay 
392*a7e14dcfSSatish Balay PETSC_STATIC_INLINE PetscReal fischnorm(PetscReal a, PetscReal b)
393*a7e14dcfSSatish Balay {
394*a7e14dcfSSatish Balay   return PetscSqrtScalar(a*a + b*b);
395*a7e14dcfSSatish Balay }
396*a7e14dcfSSatish Balay 
397*a7e14dcfSSatish Balay PETSC_STATIC_INLINE PetscReal fischsnorm(PetscReal a, PetscReal b, PetscReal c)
398*a7e14dcfSSatish Balay {
399*a7e14dcfSSatish Balay   return PetscSqrtScalar(a*a + b*b + 2.0*c*c);
400*a7e14dcfSSatish Balay }
401*a7e14dcfSSatish Balay 
402*a7e14dcfSSatish Balay #undef __FUNCT__
403*a7e14dcfSSatish Balay #define __FUNCT__ "D_Fischer"
404*a7e14dcfSSatish Balay /*@
405*a7e14dcfSSatish Balay    D_Fischer - Calculates an element of the B-subdifferential of the
406*a7e14dcfSSatish Balay    Fischer-Burmeister function for complementarity problems.
407*a7e14dcfSSatish Balay 
408*a7e14dcfSSatish Balay    Collective on jac
409*a7e14dcfSSatish Balay 
410*a7e14dcfSSatish Balay    Input Parameters:
411*a7e14dcfSSatish Balay +  jac - the jacobian of f at X
412*a7e14dcfSSatish Balay .  X - current point
413*a7e14dcfSSatish Balay .  Con - constraints function evaluated at X
414*a7e14dcfSSatish Balay .  XL - lower bounds
415*a7e14dcfSSatish Balay .  XU - upper bounds
416*a7e14dcfSSatish Balay .  t1 - work vector
417*a7e14dcfSSatish Balay -  t2 - work vector
418*a7e14dcfSSatish Balay 
419*a7e14dcfSSatish Balay    Output Parameters:
420*a7e14dcfSSatish Balay +  Da - diagonal perturbation component of the result
421*a7e14dcfSSatish Balay -  Db - row scaling component of the result
422*a7e14dcfSSatish Balay 
423*a7e14dcfSSatish Balay    Level: developer
424*a7e14dcfSSatish Balay 
425*a7e14dcfSSatish Balay .seealso: VecFischer()
426*a7e14dcfSSatish Balay @*/
427*a7e14dcfSSatish Balay PetscErrorCode D_Fischer(Mat jac, Vec X, Vec Con, Vec XL, Vec XU,
428*a7e14dcfSSatish Balay 		      Vec T1, Vec T2, Vec Da, Vec Db)
429*a7e14dcfSSatish Balay {
430*a7e14dcfSSatish Balay   PetscErrorCode ierr;
431*a7e14dcfSSatish Balay   PetscInt i,nn;
432*a7e14dcfSSatish Balay   PetscReal *x,*f,*l,*u,*da,*db,*t1,*t2;
433*a7e14dcfSSatish Balay   PetscReal ai,bi,ci,di,ei;
434*a7e14dcfSSatish Balay 
435*a7e14dcfSSatish Balay   PetscFunctionBegin;
436*a7e14dcfSSatish Balay 
437*a7e14dcfSSatish Balay   ierr = VecGetLocalSize(X,&nn); CHKERRQ(ierr);
438*a7e14dcfSSatish Balay 
439*a7e14dcfSSatish Balay   ierr = VecGetArray(X,&x);CHKERRQ(ierr);
440*a7e14dcfSSatish Balay   ierr = VecGetArray(Con,&f);CHKERRQ(ierr);
441*a7e14dcfSSatish Balay   ierr = VecGetArray(XL,&l);CHKERRQ(ierr);
442*a7e14dcfSSatish Balay   ierr = VecGetArray(XU,&u);CHKERRQ(ierr);
443*a7e14dcfSSatish Balay   ierr = VecGetArray(Da,&da);CHKERRQ(ierr);
444*a7e14dcfSSatish Balay   ierr = VecGetArray(Db,&db);CHKERRQ(ierr);
445*a7e14dcfSSatish Balay   ierr = VecGetArray(T1,&t1);CHKERRQ(ierr);
446*a7e14dcfSSatish Balay   ierr = VecGetArray(T2,&t2);CHKERRQ(ierr);
447*a7e14dcfSSatish Balay 
448*a7e14dcfSSatish Balay   for (i = 0; i < nn; i++) {
449*a7e14dcfSSatish Balay     da[i] = 0;
450*a7e14dcfSSatish Balay     db[i] = 0;
451*a7e14dcfSSatish Balay     t1[i] = 0;
452*a7e14dcfSSatish Balay 
453*a7e14dcfSSatish Balay     if (PetscAbsReal(f[i]) <= PETSC_MACHINE_EPSILON) {
454*a7e14dcfSSatish Balay       if (l[i] > TAO_NINFINITY && PetscAbsReal(x[i] - l[i]) <= PETSC_MACHINE_EPSILON) {
455*a7e14dcfSSatish Balay         t1[i] = 1;
456*a7e14dcfSSatish Balay         da[i] = 1;
457*a7e14dcfSSatish Balay       }
458*a7e14dcfSSatish Balay 
459*a7e14dcfSSatish Balay       if (u[i] <  TAO_INFINITY && PetscAbsReal(u[i] - x[i]) <= PETSC_MACHINE_EPSILON) {
460*a7e14dcfSSatish Balay         t1[i] = 1;
461*a7e14dcfSSatish Balay         db[i] = 1;
462*a7e14dcfSSatish Balay       }
463*a7e14dcfSSatish Balay     }
464*a7e14dcfSSatish Balay   }
465*a7e14dcfSSatish Balay 
466*a7e14dcfSSatish Balay   ierr = VecRestoreArray(T1,&t1); CHKERRQ(ierr);
467*a7e14dcfSSatish Balay   ierr = VecRestoreArray(T2,&t2); CHKERRQ(ierr);
468*a7e14dcfSSatish Balay   ierr = MatMult(jac,T1,T2); CHKERRQ(ierr);
469*a7e14dcfSSatish Balay   ierr = VecGetArray(T2,&t2); CHKERRQ(ierr);
470*a7e14dcfSSatish Balay 
471*a7e14dcfSSatish Balay   for (i = 0; i < nn; i++) {
472*a7e14dcfSSatish Balay     if ((l[i] <= TAO_NINFINITY) && (u[i] >= TAO_INFINITY)) {
473*a7e14dcfSSatish Balay       da[i] = 0;
474*a7e14dcfSSatish Balay       db[i] = -1;
475*a7e14dcfSSatish Balay     }
476*a7e14dcfSSatish Balay     else if (l[i] <= TAO_NINFINITY) {
477*a7e14dcfSSatish Balay       if (db[i] >= 1) {
478*a7e14dcfSSatish Balay         ai = fischnorm(1, t2[i]);
479*a7e14dcfSSatish Balay 
480*a7e14dcfSSatish Balay         da[i] = -1/ai - 1;
481*a7e14dcfSSatish Balay         db[i] = -t2[i]/ai - 1;
482*a7e14dcfSSatish Balay       }
483*a7e14dcfSSatish Balay       else {
484*a7e14dcfSSatish Balay         bi = u[i] - x[i];
485*a7e14dcfSSatish Balay         ai = fischnorm(bi, f[i]);
486*a7e14dcfSSatish Balay         ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
487*a7e14dcfSSatish Balay 
488*a7e14dcfSSatish Balay         da[i] = bi / ai - 1;
489*a7e14dcfSSatish Balay         db[i] = -f[i] / ai - 1;
490*a7e14dcfSSatish Balay       }
491*a7e14dcfSSatish Balay     }
492*a7e14dcfSSatish Balay     else if (u[i] >=  TAO_INFINITY) {
493*a7e14dcfSSatish Balay       if (da[i] >= 1) {
494*a7e14dcfSSatish Balay         ai = fischnorm(1, t2[i]);
495*a7e14dcfSSatish Balay 
496*a7e14dcfSSatish Balay         da[i] = 1 / ai - 1;
497*a7e14dcfSSatish Balay         db[i] = t2[i] / ai - 1;
498*a7e14dcfSSatish Balay       }
499*a7e14dcfSSatish Balay       else {
500*a7e14dcfSSatish Balay         bi = x[i] - l[i];
501*a7e14dcfSSatish Balay         ai = fischnorm(bi, f[i]);
502*a7e14dcfSSatish Balay         ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
503*a7e14dcfSSatish Balay 
504*a7e14dcfSSatish Balay         da[i] = bi / ai - 1;
505*a7e14dcfSSatish Balay         db[i] = f[i] / ai - 1;
506*a7e14dcfSSatish Balay       }
507*a7e14dcfSSatish Balay     }
508*a7e14dcfSSatish Balay     else if (l[i] == u[i]) {
509*a7e14dcfSSatish Balay       da[i] = -1;
510*a7e14dcfSSatish Balay       db[i] = 0;
511*a7e14dcfSSatish Balay     }
512*a7e14dcfSSatish Balay     else {
513*a7e14dcfSSatish Balay       if (db[i] >= 1) {
514*a7e14dcfSSatish Balay         ai = fischnorm(1, t2[i]);
515*a7e14dcfSSatish Balay 
516*a7e14dcfSSatish Balay         ci = 1 / ai + 1;
517*a7e14dcfSSatish Balay         di = t2[i] / ai + 1;
518*a7e14dcfSSatish Balay       }
519*a7e14dcfSSatish Balay       else {
520*a7e14dcfSSatish Balay         bi = x[i] - u[i];
521*a7e14dcfSSatish Balay         ai = fischnorm(bi, f[i]);
522*a7e14dcfSSatish Balay         ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
523*a7e14dcfSSatish Balay 
524*a7e14dcfSSatish Balay         ci = bi / ai + 1;
525*a7e14dcfSSatish Balay         di = f[i] / ai + 1;
526*a7e14dcfSSatish Balay       }
527*a7e14dcfSSatish Balay 
528*a7e14dcfSSatish Balay       if (da[i] >= 1) {
529*a7e14dcfSSatish Balay         bi = ci + di*t2[i];
530*a7e14dcfSSatish Balay         ai = fischnorm(1, bi);
531*a7e14dcfSSatish Balay 
532*a7e14dcfSSatish Balay         bi = bi / ai - 1;
533*a7e14dcfSSatish Balay         ai = 1 / ai - 1;
534*a7e14dcfSSatish Balay       }
535*a7e14dcfSSatish Balay       else {
536*a7e14dcfSSatish Balay         ei = Fischer(u[i] - x[i], -f[i]);
537*a7e14dcfSSatish Balay         ai = fischnorm(x[i] - l[i], ei);
538*a7e14dcfSSatish Balay         ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
539*a7e14dcfSSatish Balay 
540*a7e14dcfSSatish Balay         bi = ei / ai - 1;
541*a7e14dcfSSatish Balay         ai = (x[i] - l[i]) / ai - 1;
542*a7e14dcfSSatish Balay       }
543*a7e14dcfSSatish Balay 
544*a7e14dcfSSatish Balay       da[i] = ai + bi*ci;
545*a7e14dcfSSatish Balay       db[i] = bi*di;
546*a7e14dcfSSatish Balay     }
547*a7e14dcfSSatish Balay   }
548*a7e14dcfSSatish Balay 
549*a7e14dcfSSatish Balay   ierr = VecRestoreArray(Da,&da); CHKERRQ(ierr);
550*a7e14dcfSSatish Balay   ierr = VecRestoreArray(Db,&db); CHKERRQ(ierr);
551*a7e14dcfSSatish Balay   ierr = VecRestoreArray(X,&x); CHKERRQ(ierr);
552*a7e14dcfSSatish Balay   ierr = VecRestoreArray(Con,&f); CHKERRQ(ierr);
553*a7e14dcfSSatish Balay   ierr = VecRestoreArray(XL,&l); CHKERRQ(ierr);
554*a7e14dcfSSatish Balay   ierr = VecRestoreArray(XU,&u); CHKERRQ(ierr);
555*a7e14dcfSSatish Balay   ierr = VecRestoreArray(T2,&t2); CHKERRQ(ierr);
556*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
557*a7e14dcfSSatish Balay };
558*a7e14dcfSSatish Balay 
559*a7e14dcfSSatish Balay #undef __FUNCT__
560*a7e14dcfSSatish Balay #define __FUNCT__ "D_SFischer"
561*a7e14dcfSSatish Balay /*@
562*a7e14dcfSSatish Balay    D_SFischer - Calculates an element of the B-subdifferential of the
563*a7e14dcfSSatish Balay    smoothed Fischer-Burmeister function for complementarity problems.
564*a7e14dcfSSatish Balay 
565*a7e14dcfSSatish Balay    Collective on jac
566*a7e14dcfSSatish Balay 
567*a7e14dcfSSatish Balay    Input Parameters:
568*a7e14dcfSSatish Balay +  jac - the jacobian of f at X
569*a7e14dcfSSatish Balay .  X - current point
570*a7e14dcfSSatish Balay .  F - constraint function evaluated at X
571*a7e14dcfSSatish Balay .  XL - lower bounds
572*a7e14dcfSSatish Balay .  XU - upper bounds
573*a7e14dcfSSatish Balay .  mu - smoothing parameter
574*a7e14dcfSSatish Balay .  T1 - work vector
575*a7e14dcfSSatish Balay -  T2 - work vector
576*a7e14dcfSSatish Balay 
577*a7e14dcfSSatish Balay    Output Parameter:
578*a7e14dcfSSatish Balay +  Da - diagonal perturbation component of the result
579*a7e14dcfSSatish Balay .  Db - row scaling component of the result
580*a7e14dcfSSatish Balay -  Dm - derivative with respect to scaling parameter
581*a7e14dcfSSatish Balay 
582*a7e14dcfSSatish Balay    Level: developer
583*a7e14dcfSSatish Balay 
584*a7e14dcfSSatish Balay .seealso D_Fischer()
585*a7e14dcfSSatish Balay @*/
586*a7e14dcfSSatish Balay PetscErrorCode D_SFischer(Mat jac, Vec X, Vec Con,
587*a7e14dcfSSatish Balay                        Vec XL, Vec XU, PetscReal mu,
588*a7e14dcfSSatish Balay                        Vec T1, Vec T2,
589*a7e14dcfSSatish Balay                        Vec Da, Vec Db, Vec Dm)
590*a7e14dcfSSatish Balay {
591*a7e14dcfSSatish Balay   PetscErrorCode ierr;
592*a7e14dcfSSatish Balay   PetscInt i,nn;
593*a7e14dcfSSatish Balay   PetscReal *x, *f, *l, *u, *da, *db, *dm;
594*a7e14dcfSSatish Balay   PetscReal ai, bi, ci, di, ei, fi;
595*a7e14dcfSSatish Balay 
596*a7e14dcfSSatish Balay   PetscFunctionBegin;
597*a7e14dcfSSatish Balay 
598*a7e14dcfSSatish Balay   if (PetscAbsReal(mu) <= PETSC_MACHINE_EPSILON) {
599*a7e14dcfSSatish Balay     ierr = VecZeroEntries(Dm); CHKERRQ(ierr);
600*a7e14dcfSSatish Balay     ierr = D_Fischer(jac, X, Con, XL, XU, T1, T2, Da, Db); CHKERRQ(ierr);
601*a7e14dcfSSatish Balay   }
602*a7e14dcfSSatish Balay   else {
603*a7e14dcfSSatish Balay     ierr = VecGetLocalSize(X,&nn); CHKERRQ(ierr);
604*a7e14dcfSSatish Balay     ierr = VecGetArray(X,&x); CHKERRQ(ierr);
605*a7e14dcfSSatish Balay     ierr = VecGetArray(Con,&f); CHKERRQ(ierr);
606*a7e14dcfSSatish Balay     ierr = VecGetArray(XL,&l); CHKERRQ(ierr);
607*a7e14dcfSSatish Balay     ierr = VecGetArray(XU,&u); CHKERRQ(ierr);
608*a7e14dcfSSatish Balay     ierr = VecGetArray(Da,&da); CHKERRQ(ierr);
609*a7e14dcfSSatish Balay     ierr = VecGetArray(Db,&db); CHKERRQ(ierr);
610*a7e14dcfSSatish Balay     ierr = VecGetArray(Dm,&dm); CHKERRQ(ierr);
611*a7e14dcfSSatish Balay 
612*a7e14dcfSSatish Balay     for (i = 0; i < nn; ++i) {
613*a7e14dcfSSatish Balay       if ((l[i] <= TAO_NINFINITY) && (u[i] >= TAO_INFINITY)) {
614*a7e14dcfSSatish Balay         da[i] = -mu;
615*a7e14dcfSSatish Balay         db[i] = -1;
616*a7e14dcfSSatish Balay         dm[i] = -x[i];
617*a7e14dcfSSatish Balay       }
618*a7e14dcfSSatish Balay       else if (l[i] <= TAO_NINFINITY) {
619*a7e14dcfSSatish Balay         bi = u[i] - x[i];
620*a7e14dcfSSatish Balay         ai = fischsnorm(bi, f[i], mu);
621*a7e14dcfSSatish Balay         ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
622*a7e14dcfSSatish Balay 
623*a7e14dcfSSatish Balay         da[i] = bi / ai - 1;
624*a7e14dcfSSatish Balay         db[i] = -f[i] / ai - 1;
625*a7e14dcfSSatish Balay         dm[i] = 2.0 * mu / ai;
626*a7e14dcfSSatish Balay       }
627*a7e14dcfSSatish Balay       else if (u[i] >=  TAO_INFINITY) {
628*a7e14dcfSSatish Balay         bi = x[i] - l[i];
629*a7e14dcfSSatish Balay         ai = fischsnorm(bi, f[i], mu);
630*a7e14dcfSSatish Balay         ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
631*a7e14dcfSSatish Balay 
632*a7e14dcfSSatish Balay         da[i] = bi / ai - 1;
633*a7e14dcfSSatish Balay         db[i] = f[i] / ai - 1;
634*a7e14dcfSSatish Balay         dm[i] = 2.0 * mu / ai;
635*a7e14dcfSSatish Balay       }
636*a7e14dcfSSatish Balay       else if (l[i] == u[i]) {
637*a7e14dcfSSatish Balay         da[i] = -1;
638*a7e14dcfSSatish Balay         db[i] = 0;
639*a7e14dcfSSatish Balay         dm[i] = 0;
640*a7e14dcfSSatish Balay       }
641*a7e14dcfSSatish Balay       else {
642*a7e14dcfSSatish Balay         bi = x[i] - u[i];
643*a7e14dcfSSatish Balay         ai = fischsnorm(bi, f[i], mu);
644*a7e14dcfSSatish Balay         ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
645*a7e14dcfSSatish Balay 
646*a7e14dcfSSatish Balay         ci = bi / ai + 1;
647*a7e14dcfSSatish Balay         di = f[i] / ai + 1;
648*a7e14dcfSSatish Balay         fi = 2.0 * mu / ai;
649*a7e14dcfSSatish Balay 
650*a7e14dcfSSatish Balay         ei = SFischer(u[i] - x[i], -f[i], mu);
651*a7e14dcfSSatish Balay         ai = fischsnorm(x[i] - l[i], ei, mu);
652*a7e14dcfSSatish Balay         ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
653*a7e14dcfSSatish Balay 
654*a7e14dcfSSatish Balay         bi = ei / ai - 1;
655*a7e14dcfSSatish Balay         ei = 2.0 * mu / ei;
656*a7e14dcfSSatish Balay         ai = (x[i] - l[i]) / ai - 1;
657*a7e14dcfSSatish Balay 
658*a7e14dcfSSatish Balay         da[i] = ai + bi*ci;
659*a7e14dcfSSatish Balay         db[i] = bi*di;
660*a7e14dcfSSatish Balay         dm[i] = ei + bi*fi;
661*a7e14dcfSSatish Balay       }
662*a7e14dcfSSatish Balay     }
663*a7e14dcfSSatish Balay 
664*a7e14dcfSSatish Balay     ierr = VecRestoreArray(X,&x); CHKERRQ(ierr);
665*a7e14dcfSSatish Balay     ierr = VecRestoreArray(Con,&f); CHKERRQ(ierr);
666*a7e14dcfSSatish Balay     ierr = VecRestoreArray(XL,&l); CHKERRQ(ierr);
667*a7e14dcfSSatish Balay     ierr = VecRestoreArray(XU,&u); CHKERRQ(ierr);
668*a7e14dcfSSatish Balay     ierr = VecRestoreArray(Da,&da); CHKERRQ(ierr);
669*a7e14dcfSSatish Balay     ierr = VecRestoreArray(Db,&db); CHKERRQ(ierr);
670*a7e14dcfSSatish Balay     ierr = VecRestoreArray(Dm,&dm); CHKERRQ(ierr);
671*a7e14dcfSSatish Balay 
672*a7e14dcfSSatish Balay   }
673*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
674*a7e14dcfSSatish Balay }
675*a7e14dcfSSatish Balay 
676