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