1af0996ceSBarry Smith #include <petsc/private/petscimpl.h> 2ba92ff59SBarry Smith #include <petsctao.h> /*I "petsctao.h" I*/ 38370d7cdSHansol Suh #include <petscsys.h> 4a7e14dcfSSatish Balay 59fbee547SJacob Faibussowitsch static inline PetscReal Fischer(PetscReal a, PetscReal b) 6a7e14dcfSSatish Balay { 7a7e14dcfSSatish Balay /* Method suggested by Bob Vanderbei */ 8a7e14dcfSSatish Balay if (a + b <= 0) { 946bdf8c8SLisandro Dalcin return PetscSqrtReal(a*a + b*b) - (a + b); 10a7e14dcfSSatish Balay } 1146bdf8c8SLisandro Dalcin return -2.0*a*b / (PetscSqrtReal(a*a + b*b) + (a + b)); 12a7e14dcfSSatish Balay } 13a7e14dcfSSatish Balay 14a7e14dcfSSatish Balay /*@ 15a7e14dcfSSatish Balay VecFischer - Evaluates the Fischer-Burmeister function for complementarity 16a7e14dcfSSatish Balay problems. 17a7e14dcfSSatish Balay 18a7e14dcfSSatish Balay Logically Collective on vectors 19a7e14dcfSSatish Balay 20a7e14dcfSSatish Balay Input Parameters: 21a7e14dcfSSatish Balay + X - current point 22a7e14dcfSSatish Balay . F - function evaluated at x 23a7e14dcfSSatish Balay . L - lower bounds 24a7e14dcfSSatish Balay - U - upper bounds 25a7e14dcfSSatish Balay 26f899ff85SJose E. Roman Output Parameter: 27a7e14dcfSSatish Balay . FB - The Fischer-Burmeister function vector 28a7e14dcfSSatish Balay 29a7e14dcfSSatish Balay Notes: 30a7e14dcfSSatish Balay The Fischer-Burmeister function is defined as 31a7e14dcfSSatish Balay $ phi(a,b) := sqrt(a*a + b*b) - a - b 32a7e14dcfSSatish Balay and is used reformulate a complementarity problem as a semismooth 33a7e14dcfSSatish Balay system of equations. 34a7e14dcfSSatish Balay 35a7e14dcfSSatish Balay The result of this function is done by cases: 36a7e14dcfSSatish Balay + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i] 37a7e14dcfSSatish Balay . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i]) 38a7e14dcfSSatish Balay . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i]) 39a7e14dcfSSatish Balay . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u])) 40a7e14dcfSSatish Balay - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i] 41a7e14dcfSSatish Balay 42a7e14dcfSSatish Balay Level: developer 43a7e14dcfSSatish Balay 44a7e14dcfSSatish Balay @*/ 45a7e14dcfSSatish Balay PetscErrorCode VecFischer(Vec X, Vec F, Vec L, Vec U, Vec FB) 46a7e14dcfSSatish Balay { 4746bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u; 4846bdf8c8SLisandro Dalcin PetscScalar *fb; 49a7e14dcfSSatish Balay PetscReal xval, fval, lval, uval; 50a7e14dcfSSatish Balay PetscInt low[5], high[5], n, i; 51a7e14dcfSSatish Balay 52a7e14dcfSSatish Balay PetscFunctionBegin; 53a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID,1); 54a7e14dcfSSatish Balay PetscValidHeaderSpecific(F, VEC_CLASSID,2); 55a7e14dcfSSatish Balay PetscValidHeaderSpecific(L, VEC_CLASSID,3); 56a7e14dcfSSatish Balay PetscValidHeaderSpecific(U, VEC_CLASSID,4); 57064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(FB, VEC_CLASSID,5); 58a7e14dcfSSatish Balay 59*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(X, low, high)); 60*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(F, low + 1, high + 1)); 61*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(L, low + 2, high + 2)); 62*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(U, low + 3, high + 3)); 63*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(FB, low + 4, high + 4)); 64a7e14dcfSSatish Balay 65a7e14dcfSSatish Balay for (i = 1; i < 4; ++i) { 663c859ba3SBarry Smith PetscCheck(low[0] == low[i] && high[0] == high[i],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Vectors must be identically loaded over processors"); 67a7e14dcfSSatish Balay } 68a7e14dcfSSatish Balay 69*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 70*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(F, &f)); 71*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(L, &l)); 72*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(U, &u)); 73*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(FB, &fb)); 74a7e14dcfSSatish Balay 75*9566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &n)); 76a7e14dcfSSatish Balay 77a7e14dcfSSatish Balay for (i = 0; i < n; ++i) { 78658c1fc4SLisandro Dalcin xval = PetscRealPart(x[i]); fval = PetscRealPart(f[i]); 79658c1fc4SLisandro Dalcin lval = PetscRealPart(l[i]); uval = PetscRealPart(u[i]); 80a7e14dcfSSatish Balay 81e270355aSBarry Smith if ((lval <= -PETSC_INFINITY) && (uval >= PETSC_INFINITY)) { 82a7e14dcfSSatish Balay fb[i] = -fval; 83e270355aSBarry Smith } else if (lval <= -PETSC_INFINITY) { 84a7e14dcfSSatish Balay fb[i] = -Fischer(uval - xval, -fval); 85e270355aSBarry Smith } else if (uval >= PETSC_INFINITY) { 86a7e14dcfSSatish Balay fb[i] = Fischer(xval - lval, fval); 872d0e5244SBarry Smith } else if (lval == uval) { 88a7e14dcfSSatish Balay fb[i] = lval - xval; 892d0e5244SBarry Smith } else { 90a7e14dcfSSatish Balay fval = Fischer(uval - xval, -fval); 91a7e14dcfSSatish Balay fb[i] = Fischer(xval - lval, fval); 92a7e14dcfSSatish Balay } 93a7e14dcfSSatish Balay } 94a7e14dcfSSatish Balay 95*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 96*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(F, &f)); 97*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(L, &l)); 98*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(U, &u)); 99*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(FB, &fb)); 100a7e14dcfSSatish Balay PetscFunctionReturn(0); 101a7e14dcfSSatish Balay } 102a7e14dcfSSatish Balay 1039fbee547SJacob Faibussowitsch static inline PetscReal SFischer(PetscReal a, PetscReal b, PetscReal c) 104a7e14dcfSSatish Balay { 105a7e14dcfSSatish Balay /* Method suggested by Bob Vanderbei */ 106a7e14dcfSSatish Balay if (a + b <= 0) { 1073f6ba705SLisandro Dalcin return PetscSqrtReal(a*a + b*b + 2.0*c*c) - (a + b); 108a7e14dcfSSatish Balay } 1093f6ba705SLisandro Dalcin return 2.0*(c*c - a*b) / (PetscSqrtReal(a*a + b*b + 2.0*c*c) + (a + b)); 110a7e14dcfSSatish Balay } 111a7e14dcfSSatish Balay 112a7e14dcfSSatish Balay /*@ 113a7e14dcfSSatish Balay VecSFischer - Evaluates the Smoothed Fischer-Burmeister function for 114a7e14dcfSSatish Balay complementarity problems. 115a7e14dcfSSatish Balay 116a7e14dcfSSatish Balay Logically Collective on vectors 117a7e14dcfSSatish Balay 118a7e14dcfSSatish Balay Input Parameters: 119a7e14dcfSSatish Balay + X - current point 120a7e14dcfSSatish Balay . F - function evaluated at x 121a7e14dcfSSatish Balay . L - lower bounds 122a7e14dcfSSatish Balay . U - upper bounds 123a7e14dcfSSatish Balay - mu - smoothing parameter 124a7e14dcfSSatish Balay 125f899ff85SJose E. Roman Output Parameter: 126a7e14dcfSSatish Balay . FB - The Smoothed Fischer-Burmeister function vector 127a7e14dcfSSatish Balay 128a7e14dcfSSatish Balay Notes: 129a7e14dcfSSatish Balay The Smoothed Fischer-Burmeister function is defined as 130a7e14dcfSSatish Balay $ phi(a,b) := sqrt(a*a + b*b + 2*mu*mu) - a - b 131a7e14dcfSSatish Balay and is used reformulate a complementarity problem as a semismooth 132a7e14dcfSSatish Balay system of equations. 133a7e14dcfSSatish Balay 134a7e14dcfSSatish Balay The result of this function is done by cases: 135a7e14dcfSSatish Balay + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i] - 2*mu*x[i] 136a7e14dcfSSatish Balay . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i], mu) 137a7e14dcfSSatish Balay . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i], mu) 138a7e14dcfSSatish Balay . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u], mu), mu) 139a7e14dcfSSatish Balay - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i] 140a7e14dcfSSatish Balay 141a7e14dcfSSatish Balay Level: developer 142a7e14dcfSSatish Balay 143a7e14dcfSSatish Balay .seealso VecFischer() 144a7e14dcfSSatish Balay @*/ 145a7e14dcfSSatish Balay PetscErrorCode VecSFischer(Vec X, Vec F, Vec L, Vec U, PetscReal mu, Vec FB) 146a7e14dcfSSatish Balay { 14746bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u; 14846bdf8c8SLisandro Dalcin PetscScalar *fb; 149a7e14dcfSSatish Balay PetscReal xval, fval, lval, uval; 150a7e14dcfSSatish Balay PetscInt low[5], high[5], n, i; 151a7e14dcfSSatish Balay 152a7e14dcfSSatish Balay PetscFunctionBegin; 153a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID,1); 154a7e14dcfSSatish Balay PetscValidHeaderSpecific(F, VEC_CLASSID,2); 155a7e14dcfSSatish Balay PetscValidHeaderSpecific(L, VEC_CLASSID,3); 156a7e14dcfSSatish Balay PetscValidHeaderSpecific(U, VEC_CLASSID,4); 157a7e14dcfSSatish Balay PetscValidHeaderSpecific(FB, VEC_CLASSID,6); 158a7e14dcfSSatish Balay 159*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(X, low, high)); 160*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(F, low + 1, high + 1)); 161*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(L, low + 2, high + 2)); 162*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(U, low + 3, high + 3)); 163*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(FB, low + 4, high + 4)); 164a7e14dcfSSatish Balay 165a7e14dcfSSatish Balay for (i = 1; i < 4; ++i) { 1663c859ba3SBarry Smith PetscCheck(low[0] == low[i] && high[0] == high[i],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Vectors must be identically loaded over processors"); 167a7e14dcfSSatish Balay } 168a7e14dcfSSatish Balay 169*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 170*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(F, &f)); 171*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(L, &l)); 172*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(U, &u)); 173*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(FB, &fb)); 174a7e14dcfSSatish Balay 175*9566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &n)); 176a7e14dcfSSatish Balay 177a7e14dcfSSatish Balay for (i = 0; i < n; ++i) { 178658c1fc4SLisandro Dalcin xval = PetscRealPart(*x++); fval = PetscRealPart(*f++); 179658c1fc4SLisandro Dalcin lval = PetscRealPart(*l++); uval = PetscRealPart(*u++); 180a7e14dcfSSatish Balay 181e270355aSBarry Smith if ((lval <= -PETSC_INFINITY) && (uval >= PETSC_INFINITY)) { 182a7e14dcfSSatish Balay (*fb++) = -fval - mu*xval; 183e270355aSBarry Smith } else if (lval <= -PETSC_INFINITY) { 184a7e14dcfSSatish Balay (*fb++) = -SFischer(uval - xval, -fval, mu); 185e270355aSBarry Smith } else if (uval >= PETSC_INFINITY) { 186a7e14dcfSSatish Balay (*fb++) = SFischer(xval - lval, fval, mu); 1872d0e5244SBarry Smith } else if (lval == uval) { 188a7e14dcfSSatish Balay (*fb++) = lval - xval; 1892d0e5244SBarry Smith } else { 190a7e14dcfSSatish Balay fval = SFischer(uval - xval, -fval, mu); 191a7e14dcfSSatish Balay (*fb++) = SFischer(xval - lval, fval, mu); 192a7e14dcfSSatish Balay } 193a7e14dcfSSatish Balay } 194a7e14dcfSSatish Balay x -= n; f -= n; l -=n; u -= n; fb -= n; 195a7e14dcfSSatish Balay 196*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 197*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(F, &f)); 198*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(L, &l)); 199*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(U, &u)); 200*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(FB, &fb)); 201a7e14dcfSSatish Balay PetscFunctionReturn(0); 202a7e14dcfSSatish Balay } 203a7e14dcfSSatish Balay 2049fbee547SJacob Faibussowitsch static inline PetscReal fischnorm(PetscReal a, PetscReal b) 205a7e14dcfSSatish Balay { 206658c1fc4SLisandro Dalcin return PetscSqrtReal(a*a + b*b); 207a7e14dcfSSatish Balay } 208a7e14dcfSSatish Balay 2099fbee547SJacob Faibussowitsch static inline PetscReal fischsnorm(PetscReal a, PetscReal b, PetscReal c) 210a7e14dcfSSatish Balay { 211658c1fc4SLisandro Dalcin return PetscSqrtReal(a*a + b*b + 2.0*c*c); 212a7e14dcfSSatish Balay } 213a7e14dcfSSatish Balay 214a7e14dcfSSatish Balay /*@ 215235fd6e6SBarry Smith MatDFischer - Calculates an element of the B-subdifferential of the 216a7e14dcfSSatish Balay Fischer-Burmeister function for complementarity problems. 217a7e14dcfSSatish Balay 218a7e14dcfSSatish Balay Collective on jac 219a7e14dcfSSatish Balay 220a7e14dcfSSatish Balay Input Parameters: 221a7e14dcfSSatish Balay + jac - the jacobian of f at X 222a7e14dcfSSatish Balay . X - current point 223a7e14dcfSSatish Balay . Con - constraints function evaluated at X 224a7e14dcfSSatish Balay . XL - lower bounds 225a7e14dcfSSatish Balay . XU - upper bounds 226a7e14dcfSSatish Balay . t1 - work vector 227a7e14dcfSSatish Balay - t2 - work vector 228a7e14dcfSSatish Balay 229a7e14dcfSSatish Balay Output Parameters: 230a7e14dcfSSatish Balay + Da - diagonal perturbation component of the result 231a7e14dcfSSatish Balay - Db - row scaling component of the result 232a7e14dcfSSatish Balay 233a7e14dcfSSatish Balay Level: developer 234a7e14dcfSSatish Balay 235a7e14dcfSSatish Balay .seealso: VecFischer() 236a7e14dcfSSatish Balay @*/ 237235fd6e6SBarry Smith PetscErrorCode MatDFischer(Mat jac, Vec X, Vec Con, Vec XL, Vec XU, Vec T1, Vec T2, Vec Da, Vec Db) 238a7e14dcfSSatish Balay { 239a7e14dcfSSatish Balay PetscInt i,nn; 24046bdf8c8SLisandro Dalcin const PetscScalar *x,*f,*l,*u,*t2; 24146bdf8c8SLisandro Dalcin PetscScalar *da,*db,*t1; 242a7e14dcfSSatish Balay PetscReal ai,bi,ci,di,ei; 243a7e14dcfSSatish Balay 244a7e14dcfSSatish Balay PetscFunctionBegin; 245*9566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X,&nn)); 246*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&x)); 247*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Con,&f)); 248*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XL,&l)); 249*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XU,&u)); 250*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(Da,&da)); 251*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(Db,&db)); 252*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(T1,&t1)); 253*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(T2,&t2)); 254a7e14dcfSSatish Balay 255a7e14dcfSSatish Balay for (i = 0; i < nn; i++) { 25646bdf8c8SLisandro Dalcin da[i] = 0.0; 25746bdf8c8SLisandro Dalcin db[i] = 0.0; 25846bdf8c8SLisandro Dalcin t1[i] = 0.0; 259a7e14dcfSSatish Balay 26046bdf8c8SLisandro Dalcin if (PetscAbsScalar(f[i]) <= PETSC_MACHINE_EPSILON) { 26146bdf8c8SLisandro Dalcin if (PetscRealPart(l[i]) > PETSC_NINFINITY && PetscAbsScalar(x[i] - l[i]) <= PETSC_MACHINE_EPSILON) { 26246bdf8c8SLisandro Dalcin t1[i] = 1.0; 26346bdf8c8SLisandro Dalcin da[i] = 1.0; 264a7e14dcfSSatish Balay } 265a7e14dcfSSatish Balay 26646bdf8c8SLisandro Dalcin if (PetscRealPart(u[i]) < PETSC_INFINITY && PetscAbsScalar(u[i] - x[i]) <= PETSC_MACHINE_EPSILON) { 26746bdf8c8SLisandro Dalcin t1[i] = 1.0; 26846bdf8c8SLisandro Dalcin db[i] = 1.0; 269a7e14dcfSSatish Balay } 270a7e14dcfSSatish Balay } 271a7e14dcfSSatish Balay } 272a7e14dcfSSatish Balay 273*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(T1,&t1)); 274*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(T2,&t2)); 275*9566063dSJacob Faibussowitsch PetscCall(MatMult(jac,T1,T2)); 276*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(T2,&t2)); 277a7e14dcfSSatish Balay 278a7e14dcfSSatish Balay for (i = 0; i < nn; i++) { 27946bdf8c8SLisandro Dalcin if ((PetscRealPart(l[i]) <= PETSC_NINFINITY) && (PetscRealPart(u[i]) >= PETSC_INFINITY)) { 28046bdf8c8SLisandro Dalcin da[i] = 0.0; 28146bdf8c8SLisandro Dalcin db[i] = -1.0; 28246bdf8c8SLisandro Dalcin } else if (PetscRealPart(l[i]) <= PETSC_NINFINITY) { 28346bdf8c8SLisandro Dalcin if (PetscRealPart(db[i]) >= 1) { 284658c1fc4SLisandro Dalcin ai = fischnorm(1.0, PetscRealPart(t2[i])); 285a7e14dcfSSatish Balay 28646bdf8c8SLisandro Dalcin da[i] = -1.0 / ai - 1.0; 28746bdf8c8SLisandro Dalcin db[i] = -t2[i] / ai - 1.0; 2882d0e5244SBarry Smith } else { 289658c1fc4SLisandro Dalcin bi = PetscRealPart(u[i]) - PetscRealPart(x[i]); 290658c1fc4SLisandro Dalcin ai = fischnorm(bi, PetscRealPart(f[i])); 291a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 292a7e14dcfSSatish Balay 29346bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0; 29446bdf8c8SLisandro Dalcin db[i] = -f[i] / ai - 1.0; 295a7e14dcfSSatish Balay } 29646bdf8c8SLisandro Dalcin } else if (PetscRealPart(u[i]) >= PETSC_INFINITY) { 29746bdf8c8SLisandro Dalcin if (PetscRealPart(da[i]) >= 1) { 298658c1fc4SLisandro Dalcin ai = fischnorm(1.0, PetscRealPart(t2[i])); 299a7e14dcfSSatish Balay 30046bdf8c8SLisandro Dalcin da[i] = 1.0 / ai - 1.0; 30146bdf8c8SLisandro Dalcin db[i] = t2[i] / ai - 1.0; 3022d0e5244SBarry Smith } else { 303658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(l[i]); 304658c1fc4SLisandro Dalcin ai = fischnorm(bi, PetscRealPart(f[i])); 305a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 306a7e14dcfSSatish Balay 30746bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0; 30846bdf8c8SLisandro Dalcin db[i] = f[i] / ai - 1.0; 309a7e14dcfSSatish Balay } 310658c1fc4SLisandro Dalcin } else if (PetscRealPart(l[i]) == PetscRealPart(u[i])) { 31146bdf8c8SLisandro Dalcin da[i] = -1.0; 31246bdf8c8SLisandro Dalcin db[i] = 0.0; 3132d0e5244SBarry Smith } else { 31446bdf8c8SLisandro Dalcin if (PetscRealPart(db[i]) >= 1) { 315658c1fc4SLisandro Dalcin ai = fischnorm(1.0, PetscRealPart(t2[i])); 316a7e14dcfSSatish Balay 31746bdf8c8SLisandro Dalcin ci = 1.0 / ai + 1.0; 318658c1fc4SLisandro Dalcin di = PetscRealPart(t2[i]) / ai + 1.0; 3192d0e5244SBarry Smith } else { 320658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(u[i]); 321658c1fc4SLisandro Dalcin ai = fischnorm(bi, PetscRealPart(f[i])); 322a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 323a7e14dcfSSatish Balay 32446bdf8c8SLisandro Dalcin ci = bi / ai + 1.0; 325658c1fc4SLisandro Dalcin di = PetscRealPart(f[i]) / ai + 1.0; 326a7e14dcfSSatish Balay } 327a7e14dcfSSatish Balay 32846bdf8c8SLisandro Dalcin if (PetscRealPart(da[i]) >= 1) { 329658c1fc4SLisandro Dalcin bi = ci + di*PetscRealPart(t2[i]); 330658c1fc4SLisandro Dalcin ai = fischnorm(1.0, bi); 331a7e14dcfSSatish Balay 33246bdf8c8SLisandro Dalcin bi = bi / ai - 1.0; 33346bdf8c8SLisandro Dalcin ai = 1.0 / ai - 1.0; 3342d0e5244SBarry Smith } else { 335658c1fc4SLisandro Dalcin ei = Fischer(PetscRealPart(u[i]) - PetscRealPart(x[i]), -PetscRealPart(f[i])); 336658c1fc4SLisandro Dalcin ai = fischnorm(PetscRealPart(x[i]) - PetscRealPart(l[i]), ei); 337a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 338a7e14dcfSSatish Balay 33946bdf8c8SLisandro Dalcin bi = ei / ai - 1.0; 340658c1fc4SLisandro Dalcin ai = (PetscRealPart(x[i]) - PetscRealPart(l[i])) / ai - 1.0; 341a7e14dcfSSatish Balay } 342a7e14dcfSSatish Balay 343a7e14dcfSSatish Balay da[i] = ai + bi*ci; 344a7e14dcfSSatish Balay db[i] = bi*di; 345a7e14dcfSSatish Balay } 346a7e14dcfSSatish Balay } 347a7e14dcfSSatish Balay 348*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Da,&da)); 349*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Db,&db)); 350*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&x)); 351*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Con,&f)); 352*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XL,&l)); 353*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XU,&u)); 354*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(T2,&t2)); 355a7e14dcfSSatish Balay PetscFunctionReturn(0); 3568e3154b5SSatish Balay } 357a7e14dcfSSatish Balay 358a7e14dcfSSatish Balay /*@ 359235fd6e6SBarry Smith MatDSFischer - Calculates an element of the B-subdifferential of the 360a7e14dcfSSatish Balay smoothed Fischer-Burmeister function for complementarity problems. 361a7e14dcfSSatish Balay 362a7e14dcfSSatish Balay Collective on jac 363a7e14dcfSSatish Balay 364a7e14dcfSSatish Balay Input Parameters: 365a7e14dcfSSatish Balay + jac - the jacobian of f at X 366a7e14dcfSSatish Balay . X - current point 367a7e14dcfSSatish Balay . F - constraint function evaluated at X 368a7e14dcfSSatish Balay . XL - lower bounds 369a7e14dcfSSatish Balay . XU - upper bounds 370a7e14dcfSSatish Balay . mu - smoothing parameter 371a7e14dcfSSatish Balay . T1 - work vector 372a7e14dcfSSatish Balay - T2 - work vector 373a7e14dcfSSatish Balay 374d8d19677SJose E. Roman Output Parameters: 375a7e14dcfSSatish Balay + Da - diagonal perturbation component of the result 376a7e14dcfSSatish Balay . Db - row scaling component of the result 377a7e14dcfSSatish Balay - Dm - derivative with respect to scaling parameter 378a7e14dcfSSatish Balay 379a7e14dcfSSatish Balay Level: developer 380a7e14dcfSSatish Balay 381235fd6e6SBarry Smith .seealso MatDFischer() 382a7e14dcfSSatish Balay @*/ 383235fd6e6SBarry Smith PetscErrorCode MatDSFischer(Mat jac, Vec X, Vec Con,Vec XL, Vec XU, PetscReal mu,Vec T1, Vec T2,Vec Da, Vec Db, Vec Dm) 384a7e14dcfSSatish Balay { 385a7e14dcfSSatish Balay PetscInt i,nn; 38646bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u; 38746bdf8c8SLisandro Dalcin PetscScalar *da, *db, *dm; 388a7e14dcfSSatish Balay PetscReal ai, bi, ci, di, ei, fi; 389a7e14dcfSSatish Balay 390a7e14dcfSSatish Balay PetscFunctionBegin; 391a7e14dcfSSatish Balay if (PetscAbsReal(mu) <= PETSC_MACHINE_EPSILON) { 392*9566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Dm)); 393*9566063dSJacob Faibussowitsch PetscCall(MatDFischer(jac, X, Con, XL, XU, T1, T2, Da, Db)); 3942d0e5244SBarry Smith } else { 395*9566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X,&nn)); 396*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&x)); 397*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Con,&f)); 398*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XL,&l)); 399*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XU,&u)); 400*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(Da,&da)); 401*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(Db,&db)); 402*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(Dm,&dm)); 403a7e14dcfSSatish Balay 404a7e14dcfSSatish Balay for (i = 0; i < nn; ++i) { 40546bdf8c8SLisandro Dalcin if ((PetscRealPart(l[i]) <= PETSC_NINFINITY) && (PetscRealPart(u[i]) >= PETSC_INFINITY)) { 406a7e14dcfSSatish Balay da[i] = -mu; 40746bdf8c8SLisandro Dalcin db[i] = -1.0; 408a7e14dcfSSatish Balay dm[i] = -x[i]; 40946bdf8c8SLisandro Dalcin } else if (PetscRealPart(l[i]) <= PETSC_NINFINITY) { 410658c1fc4SLisandro Dalcin bi = PetscRealPart(u[i]) - PetscRealPart(x[i]); 411658c1fc4SLisandro Dalcin ai = fischsnorm(bi, PetscRealPart(f[i]), mu); 412a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 413a7e14dcfSSatish Balay 41446bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0; 415658c1fc4SLisandro Dalcin db[i] = -PetscRealPart(f[i]) / ai - 1.0; 416a7e14dcfSSatish Balay dm[i] = 2.0 * mu / ai; 41746bdf8c8SLisandro Dalcin } else if (PetscRealPart(u[i]) >= PETSC_INFINITY) { 418658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(l[i]); 419658c1fc4SLisandro Dalcin ai = fischsnorm(bi, PetscRealPart(f[i]), mu); 420a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 421a7e14dcfSSatish Balay 42246bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0; 423658c1fc4SLisandro Dalcin db[i] = PetscRealPart(f[i]) / ai - 1.0; 424a7e14dcfSSatish Balay dm[i] = 2.0 * mu / ai; 425658c1fc4SLisandro Dalcin } else if (PetscRealPart(l[i]) == PetscRealPart(u[i])) { 42646bdf8c8SLisandro Dalcin da[i] = -1.0; 42746bdf8c8SLisandro Dalcin db[i] = 0.0; 42846bdf8c8SLisandro Dalcin dm[i] = 0.0; 4292d0e5244SBarry Smith } else { 430658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(u[i]); 431658c1fc4SLisandro Dalcin ai = fischsnorm(bi, PetscRealPart(f[i]), mu); 432a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 433a7e14dcfSSatish Balay 43446bdf8c8SLisandro Dalcin ci = bi / ai + 1.0; 435658c1fc4SLisandro Dalcin di = PetscRealPart(f[i]) / ai + 1.0; 436a7e14dcfSSatish Balay fi = 2.0 * mu / ai; 437a7e14dcfSSatish Balay 438658c1fc4SLisandro Dalcin ei = SFischer(PetscRealPart(u[i]) - PetscRealPart(x[i]), -PetscRealPart(f[i]), mu); 439658c1fc4SLisandro Dalcin ai = fischsnorm(PetscRealPart(x[i]) - PetscRealPart(l[i]), ei, mu); 440a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 441a7e14dcfSSatish Balay 44246bdf8c8SLisandro Dalcin bi = ei / ai - 1.0; 443a7e14dcfSSatish Balay ei = 2.0 * mu / ei; 444658c1fc4SLisandro Dalcin ai = (PetscRealPart(x[i]) - PetscRealPart(l[i])) / ai - 1.0; 445a7e14dcfSSatish Balay 446a7e14dcfSSatish Balay da[i] = ai + bi*ci; 447a7e14dcfSSatish Balay db[i] = bi*di; 448a7e14dcfSSatish Balay dm[i] = ei + bi*fi; 449a7e14dcfSSatish Balay } 450a7e14dcfSSatish Balay } 451a7e14dcfSSatish Balay 452*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&x)); 453*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Con,&f)); 454*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XL,&l)); 455*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XU,&u)); 456*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Da,&da)); 457*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Db,&db)); 458*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Dm,&dm)); 459a7e14dcfSSatish Balay } 460a7e14dcfSSatish Balay PetscFunctionReturn(0); 461a7e14dcfSSatish Balay } 462a7e14dcfSSatish Balay 4639fbee547SJacob Faibussowitsch static inline PetscReal ST_InternalPN(PetscScalar in, PetscReal lb, PetscReal ub) 4648370d7cdSHansol Suh { 4658370d7cdSHansol Suh return PetscMax(0,(PetscReal)PetscRealPart(in)-ub) - PetscMax(0,-(PetscReal)PetscRealPart(in)-PetscAbsReal(lb)); 4668370d7cdSHansol Suh } 4678370d7cdSHansol Suh 4689fbee547SJacob Faibussowitsch static inline PetscReal ST_InternalNN(PetscScalar in, PetscReal lb, PetscReal ub) 4698370d7cdSHansol Suh { 4708370d7cdSHansol Suh return PetscMax(0,(PetscReal)PetscRealPart(in) + PetscAbsReal(ub)) - PetscMax(0,-(PetscReal)PetscRealPart(in) - PetscAbsReal(lb)); 4718370d7cdSHansol Suh } 4728370d7cdSHansol Suh 4739fbee547SJacob Faibussowitsch static inline PetscReal ST_InternalPP(PetscScalar in, PetscReal lb, PetscReal ub) 4748370d7cdSHansol Suh { 4758370d7cdSHansol Suh return PetscMax(0, (PetscReal)PetscRealPart(in)-ub) + PetscMin(0, (PetscReal)PetscRealPart(in) - lb); 4768370d7cdSHansol Suh } 4778370d7cdSHansol Suh 4788370d7cdSHansol Suh /*@ 4798370d7cdSHansol Suh TaoSoftThreshold - Calculates soft thresholding routine with input vector 4808370d7cdSHansol Suh and given lower and upper bound and returns it to output vector. 4818370d7cdSHansol Suh 4828370d7cdSHansol Suh Input Parameters: 4838370d7cdSHansol Suh + in - input vector to be thresholded 4848370d7cdSHansol Suh . lb - lower bound 485f0fc11ceSJed Brown - ub - upper bound 4868370d7cdSHansol Suh 48797bb3fdcSJose E. Roman Output Parameter: 4888370d7cdSHansol Suh . out - Soft thresholded output vector 4898370d7cdSHansol Suh 4908370d7cdSHansol Suh Notes: 4918370d7cdSHansol Suh Soft thresholding is defined as 4928370d7cdSHansol Suh \[ S(input,lb,ub) = 4938370d7cdSHansol Suh \begin{cases} 4948370d7cdSHansol Suh input - ub \text{input > ub} \\ 4958370d7cdSHansol Suh 0 \text{lb =< input <= ub} \\ 4968370d7cdSHansol Suh input + lb \text{input < lb} \\ 4978370d7cdSHansol Suh \] 4988370d7cdSHansol Suh 4998370d7cdSHansol Suh Level: developer 5008370d7cdSHansol Suh 5018370d7cdSHansol Suh @*/ 5028370d7cdSHansol Suh PetscErrorCode TaoSoftThreshold(Vec in, PetscReal lb, PetscReal ub, Vec out) 5038370d7cdSHansol Suh { 5048370d7cdSHansol Suh PetscInt i, nlocal, mlocal; 5058370d7cdSHansol Suh PetscScalar *inarray, *outarray; 5068370d7cdSHansol Suh 5078370d7cdSHansol Suh PetscFunctionBegin; 508*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayPair(in, out, &inarray, &outarray)); 509*9566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(in, &nlocal)); 510*9566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(in, &mlocal)); 5118370d7cdSHansol Suh 5123c859ba3SBarry Smith PetscCheck(nlocal == mlocal,PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Input and output vectors need to be of same size."); 5133c859ba3SBarry Smith PetscCheck(lb < ub,PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Lower bound needs to be lower than upper bound."); 5148370d7cdSHansol Suh 5158370d7cdSHansol Suh if (ub >= 0 && lb < 0) { 5168370d7cdSHansol Suh for (i=0; i<nlocal; i++) outarray[i] = ST_InternalPN(inarray[i], lb, ub); 5178370d7cdSHansol Suh } else if (ub < 0 && lb < 0) { 5188370d7cdSHansol Suh for (i=0; i<nlocal; i++) outarray[i] = ST_InternalNN(inarray[i], lb, ub); 5198370d7cdSHansol Suh } else { 5208370d7cdSHansol Suh for (i=0; i<nlocal; i++) outarray[i] = ST_InternalPP(inarray[i], lb, ub); 5218370d7cdSHansol Suh } 5228370d7cdSHansol Suh 523*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayPair(in, out, &inarray, &outarray)); 5248370d7cdSHansol Suh PetscFunctionReturn(0); 5258370d7cdSHansol Suh } 526