1af0996ceSBarry Smith #include <petsc/private/petscimpl.h> 2ba92ff59SBarry Smith #include <petsctao.h> /*I "petsctao.h" I*/ 38370d7cdSHansol Suh #include <petscsys.h> 4a7e14dcfSSatish Balay 5*d71ae5a4SJacob Faibussowitsch static inline PetscReal Fischer(PetscReal a, PetscReal b) 6*d71ae5a4SJacob Faibussowitsch { 7a7e14dcfSSatish Balay /* Method suggested by Bob Vanderbei */ 8ad540459SPierre Jolivet if (a + b <= 0) return PetscSqrtReal(a * a + b * b) - (a + b); 946bdf8c8SLisandro Dalcin return -2.0 * a * b / (PetscSqrtReal(a * a + b * b) + (a + b)); 10a7e14dcfSSatish Balay } 11a7e14dcfSSatish Balay 12a7e14dcfSSatish Balay /*@ 13a7e14dcfSSatish Balay VecFischer - Evaluates the Fischer-Burmeister function for complementarity 14a7e14dcfSSatish Balay problems. 15a7e14dcfSSatish Balay 16a7e14dcfSSatish Balay Logically Collective on vectors 17a7e14dcfSSatish Balay 18a7e14dcfSSatish Balay Input Parameters: 19a7e14dcfSSatish Balay + X - current point 20a7e14dcfSSatish Balay . F - function evaluated at x 21a7e14dcfSSatish Balay . L - lower bounds 22a7e14dcfSSatish Balay - U - upper bounds 23a7e14dcfSSatish Balay 24f899ff85SJose E. Roman Output Parameter: 25a7e14dcfSSatish Balay . FB - The Fischer-Burmeister function vector 26a7e14dcfSSatish Balay 27a7e14dcfSSatish Balay Notes: 28a7e14dcfSSatish Balay The Fischer-Burmeister function is defined as 29a7e14dcfSSatish Balay $ phi(a,b) := sqrt(a*a + b*b) - a - b 30a7e14dcfSSatish Balay and is used reformulate a complementarity problem as a semismooth 31a7e14dcfSSatish Balay system of equations. 32a7e14dcfSSatish Balay 33a7e14dcfSSatish Balay The result of this function is done by cases: 34a7e14dcfSSatish Balay + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i] 35a7e14dcfSSatish Balay . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i]) 36a7e14dcfSSatish Balay . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i]) 37a7e14dcfSSatish Balay . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u])) 38a7e14dcfSSatish Balay - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i] 39a7e14dcfSSatish Balay 40a7e14dcfSSatish Balay Level: developer 41a7e14dcfSSatish Balay 42a7e14dcfSSatish Balay @*/ 43*d71ae5a4SJacob Faibussowitsch PetscErrorCode VecFischer(Vec X, Vec F, Vec L, Vec U, Vec FB) 44*d71ae5a4SJacob Faibussowitsch { 4546bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u; 4646bdf8c8SLisandro Dalcin PetscScalar *fb; 47a7e14dcfSSatish Balay PetscReal xval, fval, lval, uval; 48a7e14dcfSSatish Balay PetscInt low[5], high[5], n, i; 49a7e14dcfSSatish Balay 50a7e14dcfSSatish Balay PetscFunctionBegin; 51a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID, 1); 52a7e14dcfSSatish Balay PetscValidHeaderSpecific(F, VEC_CLASSID, 2); 5376be6f4fSStefano Zampini if (L) PetscValidHeaderSpecific(L, VEC_CLASSID, 3); 5476be6f4fSStefano Zampini if (U) PetscValidHeaderSpecific(U, VEC_CLASSID, 4); 55064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(FB, VEC_CLASSID, 5); 56a7e14dcfSSatish Balay 5776be6f4fSStefano Zampini if (!L && !U) { 5876be6f4fSStefano Zampini PetscCall(VecAXPBY(FB, -1.0, 0.0, F)); 5976be6f4fSStefano Zampini PetscFunctionReturn(0); 6076be6f4fSStefano Zampini } 6176be6f4fSStefano Zampini 629566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(X, low, high)); 639566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(F, low + 1, high + 1)); 649566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(L, low + 2, high + 2)); 659566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(U, low + 3, high + 3)); 669566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(FB, low + 4, high + 4)); 67a7e14dcfSSatish Balay 68ad540459SPierre Jolivet for (i = 1; i < 4; ++i) PetscCheck(low[0] == low[i] && high[0] == high[i], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Vectors must be identically loaded over processors"); 69a7e14dcfSSatish Balay 709566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 719566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(F, &f)); 729566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(L, &l)); 739566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(U, &u)); 749566063dSJacob Faibussowitsch PetscCall(VecGetArray(FB, &fb)); 75a7e14dcfSSatish Balay 769566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &n)); 77a7e14dcfSSatish Balay 78a7e14dcfSSatish Balay for (i = 0; i < n; ++i) { 7976be6f4fSStefano Zampini xval = PetscRealPart(x[i]); 8076be6f4fSStefano Zampini fval = PetscRealPart(f[i]); 8176be6f4fSStefano Zampini lval = PetscRealPart(l[i]); 8276be6f4fSStefano Zampini uval = PetscRealPart(u[i]); 83a7e14dcfSSatish Balay 8476be6f4fSStefano Zampini if (lval <= -PETSC_INFINITY && uval >= PETSC_INFINITY) { 85a7e14dcfSSatish Balay fb[i] = -fval; 86e270355aSBarry Smith } else if (lval <= -PETSC_INFINITY) { 87a7e14dcfSSatish Balay fb[i] = -Fischer(uval - xval, -fval); 88e270355aSBarry Smith } else if (uval >= PETSC_INFINITY) { 89a7e14dcfSSatish Balay fb[i] = Fischer(xval - lval, fval); 902d0e5244SBarry Smith } else if (lval == uval) { 91a7e14dcfSSatish Balay fb[i] = lval - xval; 922d0e5244SBarry Smith } else { 93a7e14dcfSSatish Balay fval = Fischer(uval - xval, -fval); 94a7e14dcfSSatish Balay fb[i] = Fischer(xval - lval, fval); 95a7e14dcfSSatish Balay } 96a7e14dcfSSatish Balay } 97a7e14dcfSSatish Balay 989566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 999566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(F, &f)); 1009566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(L, &l)); 1019566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(U, &u)); 1029566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(FB, &fb)); 103a7e14dcfSSatish Balay PetscFunctionReturn(0); 104a7e14dcfSSatish Balay } 105a7e14dcfSSatish Balay 106*d71ae5a4SJacob Faibussowitsch static inline PetscReal SFischer(PetscReal a, PetscReal b, PetscReal c) 107*d71ae5a4SJacob Faibussowitsch { 108a7e14dcfSSatish Balay /* Method suggested by Bob Vanderbei */ 109ad540459SPierre Jolivet if (a + b <= 0) return PetscSqrtReal(a * a + b * b + 2.0 * c * c) - (a + b); 1103f6ba705SLisandro Dalcin return 2.0 * (c * c - a * b) / (PetscSqrtReal(a * a + b * b + 2.0 * c * c) + (a + b)); 111a7e14dcfSSatish Balay } 112a7e14dcfSSatish Balay 113a7e14dcfSSatish Balay /*@ 114a7e14dcfSSatish Balay VecSFischer - Evaluates the Smoothed Fischer-Burmeister function for 115a7e14dcfSSatish Balay complementarity problems. 116a7e14dcfSSatish Balay 117a7e14dcfSSatish Balay Logically Collective on vectors 118a7e14dcfSSatish Balay 119a7e14dcfSSatish Balay Input Parameters: 120a7e14dcfSSatish Balay + X - current point 121a7e14dcfSSatish Balay . F - function evaluated at x 122a7e14dcfSSatish Balay . L - lower bounds 123a7e14dcfSSatish Balay . U - upper bounds 124a7e14dcfSSatish Balay - mu - smoothing parameter 125a7e14dcfSSatish Balay 126f899ff85SJose E. Roman Output Parameter: 127a7e14dcfSSatish Balay . FB - The Smoothed Fischer-Burmeister function vector 128a7e14dcfSSatish Balay 129a7e14dcfSSatish Balay Notes: 130a7e14dcfSSatish Balay The Smoothed Fischer-Burmeister function is defined as 131a7e14dcfSSatish Balay $ phi(a,b) := sqrt(a*a + b*b + 2*mu*mu) - a - b 132a7e14dcfSSatish Balay and is used reformulate a complementarity problem as a semismooth 133a7e14dcfSSatish Balay system of equations. 134a7e14dcfSSatish Balay 135a7e14dcfSSatish Balay The result of this function is done by cases: 136a7e14dcfSSatish Balay + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i] - 2*mu*x[i] 137a7e14dcfSSatish Balay . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i], mu) 138a7e14dcfSSatish Balay . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i], mu) 139a7e14dcfSSatish Balay . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u], mu), mu) 140a7e14dcfSSatish Balay - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i] 141a7e14dcfSSatish Balay 142a7e14dcfSSatish Balay Level: developer 143a7e14dcfSSatish Balay 144db781477SPatrick Sanan .seealso `VecFischer()` 145a7e14dcfSSatish Balay @*/ 146*d71ae5a4SJacob Faibussowitsch PetscErrorCode VecSFischer(Vec X, Vec F, Vec L, Vec U, PetscReal mu, Vec FB) 147*d71ae5a4SJacob Faibussowitsch { 14846bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u; 14946bdf8c8SLisandro Dalcin PetscScalar *fb; 150a7e14dcfSSatish Balay PetscReal xval, fval, lval, uval; 151a7e14dcfSSatish Balay PetscInt low[5], high[5], n, i; 152a7e14dcfSSatish Balay 153a7e14dcfSSatish Balay PetscFunctionBegin; 154a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID, 1); 155a7e14dcfSSatish Balay PetscValidHeaderSpecific(F, VEC_CLASSID, 2); 156a7e14dcfSSatish Balay PetscValidHeaderSpecific(L, VEC_CLASSID, 3); 157a7e14dcfSSatish Balay PetscValidHeaderSpecific(U, VEC_CLASSID, 4); 158a7e14dcfSSatish Balay PetscValidHeaderSpecific(FB, VEC_CLASSID, 6); 159a7e14dcfSSatish Balay 1609566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(X, low, high)); 1619566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(F, low + 1, high + 1)); 1629566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(L, low + 2, high + 2)); 1639566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(U, low + 3, high + 3)); 1649566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(FB, low + 4, high + 4)); 165a7e14dcfSSatish Balay 166ad540459SPierre Jolivet for (i = 1; i < 4; ++i) 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 1689566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 1699566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(F, &f)); 1709566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(L, &l)); 1719566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(U, &u)); 1729566063dSJacob Faibussowitsch PetscCall(VecGetArray(FB, &fb)); 173a7e14dcfSSatish Balay 1749566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &n)); 175a7e14dcfSSatish Balay 176a7e14dcfSSatish Balay for (i = 0; i < n; ++i) { 1779371c9d4SSatish Balay xval = PetscRealPart(*x++); 1789371c9d4SSatish Balay fval = PetscRealPart(*f++); 1799371c9d4SSatish Balay lval = PetscRealPart(*l++); 1809371c9d4SSatish Balay uval = PetscRealPart(*u++); 181a7e14dcfSSatish Balay 182e270355aSBarry Smith if ((lval <= -PETSC_INFINITY) && (uval >= PETSC_INFINITY)) { 183a7e14dcfSSatish Balay (*fb++) = -fval - mu * xval; 184e270355aSBarry Smith } else if (lval <= -PETSC_INFINITY) { 185a7e14dcfSSatish Balay (*fb++) = -SFischer(uval - xval, -fval, mu); 186e270355aSBarry Smith } else if (uval >= PETSC_INFINITY) { 187a7e14dcfSSatish Balay (*fb++) = SFischer(xval - lval, fval, mu); 1882d0e5244SBarry Smith } else if (lval == uval) { 189a7e14dcfSSatish Balay (*fb++) = lval - xval; 1902d0e5244SBarry Smith } else { 191a7e14dcfSSatish Balay fval = SFischer(uval - xval, -fval, mu); 192a7e14dcfSSatish Balay (*fb++) = SFischer(xval - lval, fval, mu); 193a7e14dcfSSatish Balay } 194a7e14dcfSSatish Balay } 1959371c9d4SSatish Balay x -= n; 1969371c9d4SSatish Balay f -= n; 1979371c9d4SSatish Balay l -= n; 1989371c9d4SSatish Balay u -= n; 1999371c9d4SSatish Balay fb -= n; 200a7e14dcfSSatish Balay 2019566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 2029566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(F, &f)); 2039566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(L, &l)); 2049566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(U, &u)); 2059566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(FB, &fb)); 206a7e14dcfSSatish Balay PetscFunctionReturn(0); 207a7e14dcfSSatish Balay } 208a7e14dcfSSatish Balay 209*d71ae5a4SJacob Faibussowitsch static inline PetscReal fischnorm(PetscReal a, PetscReal b) 210*d71ae5a4SJacob Faibussowitsch { 211658c1fc4SLisandro Dalcin return PetscSqrtReal(a * a + b * b); 212a7e14dcfSSatish Balay } 213a7e14dcfSSatish Balay 214*d71ae5a4SJacob Faibussowitsch static inline PetscReal fischsnorm(PetscReal a, PetscReal b, PetscReal c) 215*d71ae5a4SJacob Faibussowitsch { 216658c1fc4SLisandro Dalcin return PetscSqrtReal(a * a + b * b + 2.0 * c * c); 217a7e14dcfSSatish Balay } 218a7e14dcfSSatish Balay 219a7e14dcfSSatish Balay /*@ 220235fd6e6SBarry Smith MatDFischer - Calculates an element of the B-subdifferential of the 221a7e14dcfSSatish Balay Fischer-Burmeister function for complementarity problems. 222a7e14dcfSSatish Balay 223a7e14dcfSSatish Balay Collective on jac 224a7e14dcfSSatish Balay 225a7e14dcfSSatish Balay Input Parameters: 226a7e14dcfSSatish Balay + jac - the jacobian of f at X 227a7e14dcfSSatish Balay . X - current point 228a7e14dcfSSatish Balay . Con - constraints function evaluated at X 229a7e14dcfSSatish Balay . XL - lower bounds 230a7e14dcfSSatish Balay . XU - upper bounds 231a7e14dcfSSatish Balay . t1 - work vector 232a7e14dcfSSatish Balay - t2 - work vector 233a7e14dcfSSatish Balay 234a7e14dcfSSatish Balay Output Parameters: 235a7e14dcfSSatish Balay + Da - diagonal perturbation component of the result 236a7e14dcfSSatish Balay - Db - row scaling component of the result 237a7e14dcfSSatish Balay 238a7e14dcfSSatish Balay Level: developer 239a7e14dcfSSatish Balay 240db781477SPatrick Sanan .seealso: `VecFischer()` 241a7e14dcfSSatish Balay @*/ 242*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDFischer(Mat jac, Vec X, Vec Con, Vec XL, Vec XU, Vec T1, Vec T2, Vec Da, Vec Db) 243*d71ae5a4SJacob Faibussowitsch { 244a7e14dcfSSatish Balay PetscInt i, nn; 24546bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u, *t2; 24646bdf8c8SLisandro Dalcin PetscScalar *da, *db, *t1; 247a7e14dcfSSatish Balay PetscReal ai, bi, ci, di, ei; 248a7e14dcfSSatish Balay 249a7e14dcfSSatish Balay PetscFunctionBegin; 2509566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &nn)); 2519566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 2529566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Con, &f)); 2539566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XL, &l)); 2549566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XU, &u)); 2559566063dSJacob Faibussowitsch PetscCall(VecGetArray(Da, &da)); 2569566063dSJacob Faibussowitsch PetscCall(VecGetArray(Db, &db)); 2579566063dSJacob Faibussowitsch PetscCall(VecGetArray(T1, &t1)); 2589566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(T2, &t2)); 259a7e14dcfSSatish Balay 260a7e14dcfSSatish Balay for (i = 0; i < nn; i++) { 26146bdf8c8SLisandro Dalcin da[i] = 0.0; 26246bdf8c8SLisandro Dalcin db[i] = 0.0; 26346bdf8c8SLisandro Dalcin t1[i] = 0.0; 264a7e14dcfSSatish Balay 26546bdf8c8SLisandro Dalcin if (PetscAbsScalar(f[i]) <= PETSC_MACHINE_EPSILON) { 26646bdf8c8SLisandro Dalcin if (PetscRealPart(l[i]) > PETSC_NINFINITY && PetscAbsScalar(x[i] - l[i]) <= PETSC_MACHINE_EPSILON) { 26746bdf8c8SLisandro Dalcin t1[i] = 1.0; 26846bdf8c8SLisandro Dalcin da[i] = 1.0; 269a7e14dcfSSatish Balay } 270a7e14dcfSSatish Balay 27146bdf8c8SLisandro Dalcin if (PetscRealPart(u[i]) < PETSC_INFINITY && PetscAbsScalar(u[i] - x[i]) <= PETSC_MACHINE_EPSILON) { 27246bdf8c8SLisandro Dalcin t1[i] = 1.0; 27346bdf8c8SLisandro Dalcin db[i] = 1.0; 274a7e14dcfSSatish Balay } 275a7e14dcfSSatish Balay } 276a7e14dcfSSatish Balay } 277a7e14dcfSSatish Balay 2789566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(T1, &t1)); 2799566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(T2, &t2)); 2809566063dSJacob Faibussowitsch PetscCall(MatMult(jac, T1, T2)); 2819566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(T2, &t2)); 282a7e14dcfSSatish Balay 283a7e14dcfSSatish Balay for (i = 0; i < nn; i++) { 28446bdf8c8SLisandro Dalcin if ((PetscRealPart(l[i]) <= PETSC_NINFINITY) && (PetscRealPart(u[i]) >= PETSC_INFINITY)) { 28546bdf8c8SLisandro Dalcin da[i] = 0.0; 28646bdf8c8SLisandro Dalcin db[i] = -1.0; 28746bdf8c8SLisandro Dalcin } else if (PetscRealPart(l[i]) <= PETSC_NINFINITY) { 28846bdf8c8SLisandro Dalcin if (PetscRealPart(db[i]) >= 1) { 289658c1fc4SLisandro Dalcin ai = fischnorm(1.0, PetscRealPart(t2[i])); 290a7e14dcfSSatish Balay 29146bdf8c8SLisandro Dalcin da[i] = -1.0 / ai - 1.0; 29246bdf8c8SLisandro Dalcin db[i] = -t2[i] / ai - 1.0; 2932d0e5244SBarry Smith } else { 294658c1fc4SLisandro Dalcin bi = PetscRealPart(u[i]) - PetscRealPart(x[i]); 295658c1fc4SLisandro Dalcin ai = fischnorm(bi, PetscRealPart(f[i])); 296a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 297a7e14dcfSSatish Balay 29846bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0; 29946bdf8c8SLisandro Dalcin db[i] = -f[i] / ai - 1.0; 300a7e14dcfSSatish Balay } 30146bdf8c8SLisandro Dalcin } else if (PetscRealPart(u[i]) >= PETSC_INFINITY) { 30246bdf8c8SLisandro Dalcin if (PetscRealPart(da[i]) >= 1) { 303658c1fc4SLisandro Dalcin ai = fischnorm(1.0, PetscRealPart(t2[i])); 304a7e14dcfSSatish Balay 30546bdf8c8SLisandro Dalcin da[i] = 1.0 / ai - 1.0; 30646bdf8c8SLisandro Dalcin db[i] = t2[i] / ai - 1.0; 3072d0e5244SBarry Smith } else { 308658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(l[i]); 309658c1fc4SLisandro Dalcin ai = fischnorm(bi, PetscRealPart(f[i])); 310a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 311a7e14dcfSSatish Balay 31246bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0; 31346bdf8c8SLisandro Dalcin db[i] = f[i] / ai - 1.0; 314a7e14dcfSSatish Balay } 315658c1fc4SLisandro Dalcin } else if (PetscRealPart(l[i]) == PetscRealPart(u[i])) { 31646bdf8c8SLisandro Dalcin da[i] = -1.0; 31746bdf8c8SLisandro Dalcin db[i] = 0.0; 3182d0e5244SBarry Smith } else { 31946bdf8c8SLisandro Dalcin if (PetscRealPart(db[i]) >= 1) { 320658c1fc4SLisandro Dalcin ai = fischnorm(1.0, PetscRealPart(t2[i])); 321a7e14dcfSSatish Balay 32246bdf8c8SLisandro Dalcin ci = 1.0 / ai + 1.0; 323658c1fc4SLisandro Dalcin di = PetscRealPart(t2[i]) / ai + 1.0; 3242d0e5244SBarry Smith } else { 325658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(u[i]); 326658c1fc4SLisandro Dalcin ai = fischnorm(bi, PetscRealPart(f[i])); 327a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 328a7e14dcfSSatish Balay 32946bdf8c8SLisandro Dalcin ci = bi / ai + 1.0; 330658c1fc4SLisandro Dalcin di = PetscRealPart(f[i]) / ai + 1.0; 331a7e14dcfSSatish Balay } 332a7e14dcfSSatish Balay 33346bdf8c8SLisandro Dalcin if (PetscRealPart(da[i]) >= 1) { 334658c1fc4SLisandro Dalcin bi = ci + di * PetscRealPart(t2[i]); 335658c1fc4SLisandro Dalcin ai = fischnorm(1.0, bi); 336a7e14dcfSSatish Balay 33746bdf8c8SLisandro Dalcin bi = bi / ai - 1.0; 33846bdf8c8SLisandro Dalcin ai = 1.0 / ai - 1.0; 3392d0e5244SBarry Smith } else { 340658c1fc4SLisandro Dalcin ei = Fischer(PetscRealPart(u[i]) - PetscRealPart(x[i]), -PetscRealPart(f[i])); 341658c1fc4SLisandro Dalcin ai = fischnorm(PetscRealPart(x[i]) - PetscRealPart(l[i]), ei); 342a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 343a7e14dcfSSatish Balay 34446bdf8c8SLisandro Dalcin bi = ei / ai - 1.0; 345658c1fc4SLisandro Dalcin ai = (PetscRealPart(x[i]) - PetscRealPart(l[i])) / ai - 1.0; 346a7e14dcfSSatish Balay } 347a7e14dcfSSatish Balay 348a7e14dcfSSatish Balay da[i] = ai + bi * ci; 349a7e14dcfSSatish Balay db[i] = bi * di; 350a7e14dcfSSatish Balay } 351a7e14dcfSSatish Balay } 352a7e14dcfSSatish Balay 3539566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Da, &da)); 3549566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Db, &db)); 3559566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 3569566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Con, &f)); 3579566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XL, &l)); 3589566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XU, &u)); 3599566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(T2, &t2)); 360a7e14dcfSSatish Balay PetscFunctionReturn(0); 3618e3154b5SSatish Balay } 362a7e14dcfSSatish Balay 363a7e14dcfSSatish Balay /*@ 364235fd6e6SBarry Smith MatDSFischer - Calculates an element of the B-subdifferential of the 365a7e14dcfSSatish Balay smoothed Fischer-Burmeister function for complementarity problems. 366a7e14dcfSSatish Balay 367a7e14dcfSSatish Balay Collective on jac 368a7e14dcfSSatish Balay 369a7e14dcfSSatish Balay Input Parameters: 370a7e14dcfSSatish Balay + jac - the jacobian of f at X 371a7e14dcfSSatish Balay . X - current point 372a7e14dcfSSatish Balay . F - constraint function evaluated at X 373a7e14dcfSSatish Balay . XL - lower bounds 374a7e14dcfSSatish Balay . XU - upper bounds 375a7e14dcfSSatish Balay . mu - smoothing parameter 376a7e14dcfSSatish Balay . T1 - work vector 377a7e14dcfSSatish Balay - T2 - work vector 378a7e14dcfSSatish Balay 379d8d19677SJose E. Roman Output Parameters: 380a7e14dcfSSatish Balay + Da - diagonal perturbation component of the result 381a7e14dcfSSatish Balay . Db - row scaling component of the result 382a7e14dcfSSatish Balay - Dm - derivative with respect to scaling parameter 383a7e14dcfSSatish Balay 384a7e14dcfSSatish Balay Level: developer 385a7e14dcfSSatish Balay 386db781477SPatrick Sanan .seealso `MatDFischer()` 387a7e14dcfSSatish Balay @*/ 388*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDSFischer(Mat jac, Vec X, Vec Con, Vec XL, Vec XU, PetscReal mu, Vec T1, Vec T2, Vec Da, Vec Db, Vec Dm) 389*d71ae5a4SJacob Faibussowitsch { 390a7e14dcfSSatish Balay PetscInt i, nn; 39146bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u; 39246bdf8c8SLisandro Dalcin PetscScalar *da, *db, *dm; 393a7e14dcfSSatish Balay PetscReal ai, bi, ci, di, ei, fi; 394a7e14dcfSSatish Balay 395a7e14dcfSSatish Balay PetscFunctionBegin; 396a7e14dcfSSatish Balay if (PetscAbsReal(mu) <= PETSC_MACHINE_EPSILON) { 3979566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Dm)); 3989566063dSJacob Faibussowitsch PetscCall(MatDFischer(jac, X, Con, XL, XU, T1, T2, Da, Db)); 3992d0e5244SBarry Smith } else { 4009566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &nn)); 4019566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 4029566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Con, &f)); 4039566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XL, &l)); 4049566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XU, &u)); 4059566063dSJacob Faibussowitsch PetscCall(VecGetArray(Da, &da)); 4069566063dSJacob Faibussowitsch PetscCall(VecGetArray(Db, &db)); 4079566063dSJacob Faibussowitsch PetscCall(VecGetArray(Dm, &dm)); 408a7e14dcfSSatish Balay 409a7e14dcfSSatish Balay for (i = 0; i < nn; ++i) { 41046bdf8c8SLisandro Dalcin if ((PetscRealPart(l[i]) <= PETSC_NINFINITY) && (PetscRealPart(u[i]) >= PETSC_INFINITY)) { 411a7e14dcfSSatish Balay da[i] = -mu; 41246bdf8c8SLisandro Dalcin db[i] = -1.0; 413a7e14dcfSSatish Balay dm[i] = -x[i]; 41446bdf8c8SLisandro Dalcin } else if (PetscRealPart(l[i]) <= PETSC_NINFINITY) { 415658c1fc4SLisandro Dalcin bi = PetscRealPart(u[i]) - PetscRealPart(x[i]); 416658c1fc4SLisandro Dalcin ai = fischsnorm(bi, PetscRealPart(f[i]), mu); 417a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 418a7e14dcfSSatish Balay 41946bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0; 420658c1fc4SLisandro Dalcin db[i] = -PetscRealPart(f[i]) / ai - 1.0; 421a7e14dcfSSatish Balay dm[i] = 2.0 * mu / ai; 42246bdf8c8SLisandro Dalcin } else if (PetscRealPart(u[i]) >= PETSC_INFINITY) { 423658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(l[i]); 424658c1fc4SLisandro Dalcin ai = fischsnorm(bi, PetscRealPart(f[i]), mu); 425a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 426a7e14dcfSSatish Balay 42746bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0; 428658c1fc4SLisandro Dalcin db[i] = PetscRealPart(f[i]) / ai - 1.0; 429a7e14dcfSSatish Balay dm[i] = 2.0 * mu / ai; 430658c1fc4SLisandro Dalcin } else if (PetscRealPart(l[i]) == PetscRealPart(u[i])) { 43146bdf8c8SLisandro Dalcin da[i] = -1.0; 43246bdf8c8SLisandro Dalcin db[i] = 0.0; 43346bdf8c8SLisandro Dalcin dm[i] = 0.0; 4342d0e5244SBarry Smith } else { 435658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(u[i]); 436658c1fc4SLisandro Dalcin ai = fischsnorm(bi, PetscRealPart(f[i]), mu); 437a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 438a7e14dcfSSatish Balay 43946bdf8c8SLisandro Dalcin ci = bi / ai + 1.0; 440658c1fc4SLisandro Dalcin di = PetscRealPart(f[i]) / ai + 1.0; 441a7e14dcfSSatish Balay fi = 2.0 * mu / ai; 442a7e14dcfSSatish Balay 443658c1fc4SLisandro Dalcin ei = SFischer(PetscRealPart(u[i]) - PetscRealPart(x[i]), -PetscRealPart(f[i]), mu); 444658c1fc4SLisandro Dalcin ai = fischsnorm(PetscRealPart(x[i]) - PetscRealPart(l[i]), ei, mu); 445a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai); 446a7e14dcfSSatish Balay 44746bdf8c8SLisandro Dalcin bi = ei / ai - 1.0; 448a7e14dcfSSatish Balay ei = 2.0 * mu / ei; 449658c1fc4SLisandro Dalcin ai = (PetscRealPart(x[i]) - PetscRealPart(l[i])) / ai - 1.0; 450a7e14dcfSSatish Balay 451a7e14dcfSSatish Balay da[i] = ai + bi * ci; 452a7e14dcfSSatish Balay db[i] = bi * di; 453a7e14dcfSSatish Balay dm[i] = ei + bi * fi; 454a7e14dcfSSatish Balay } 455a7e14dcfSSatish Balay } 456a7e14dcfSSatish Balay 4579566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 4589566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Con, &f)); 4599566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XL, &l)); 4609566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XU, &u)); 4619566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Da, &da)); 4629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Db, &db)); 4639566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Dm, &dm)); 464a7e14dcfSSatish Balay } 465a7e14dcfSSatish Balay PetscFunctionReturn(0); 466a7e14dcfSSatish Balay } 467a7e14dcfSSatish Balay 468*d71ae5a4SJacob Faibussowitsch static inline PetscReal ST_InternalPN(PetscScalar in, PetscReal lb, PetscReal ub) 469*d71ae5a4SJacob Faibussowitsch { 4708370d7cdSHansol Suh return PetscMax(0, (PetscReal)PetscRealPart(in) - ub) - PetscMax(0, -(PetscReal)PetscRealPart(in) - PetscAbsReal(lb)); 4718370d7cdSHansol Suh } 4728370d7cdSHansol Suh 473*d71ae5a4SJacob Faibussowitsch static inline PetscReal ST_InternalNN(PetscScalar in, PetscReal lb, PetscReal ub) 474*d71ae5a4SJacob Faibussowitsch { 4758370d7cdSHansol Suh return PetscMax(0, (PetscReal)PetscRealPart(in) + PetscAbsReal(ub)) - PetscMax(0, -(PetscReal)PetscRealPart(in) - PetscAbsReal(lb)); 4768370d7cdSHansol Suh } 4778370d7cdSHansol Suh 478*d71ae5a4SJacob Faibussowitsch static inline PetscReal ST_InternalPP(PetscScalar in, PetscReal lb, PetscReal ub) 479*d71ae5a4SJacob Faibussowitsch { 4808370d7cdSHansol Suh return PetscMax(0, (PetscReal)PetscRealPart(in) - ub) + PetscMin(0, (PetscReal)PetscRealPart(in) - lb); 4818370d7cdSHansol Suh } 4828370d7cdSHansol Suh 4838370d7cdSHansol Suh /*@ 4848370d7cdSHansol Suh TaoSoftThreshold - Calculates soft thresholding routine with input vector 4858370d7cdSHansol Suh and given lower and upper bound and returns it to output vector. 4868370d7cdSHansol Suh 4878370d7cdSHansol Suh Input Parameters: 4888370d7cdSHansol Suh + in - input vector to be thresholded 4898370d7cdSHansol Suh . lb - lower bound 490f0fc11ceSJed Brown - ub - upper bound 4918370d7cdSHansol Suh 49297bb3fdcSJose E. Roman Output Parameter: 4938370d7cdSHansol Suh . out - Soft thresholded output vector 4948370d7cdSHansol Suh 4958370d7cdSHansol Suh Notes: 4968370d7cdSHansol Suh Soft thresholding is defined as 4978370d7cdSHansol Suh \[ S(input,lb,ub) = 4988370d7cdSHansol Suh \begin{cases} 4998370d7cdSHansol Suh input - ub \text{input > ub} \\ 5008370d7cdSHansol Suh 0 \text{lb =< input <= ub} \\ 5018370d7cdSHansol Suh input + lb \text{input < lb} \\ 5028370d7cdSHansol Suh \] 5038370d7cdSHansol Suh 5048370d7cdSHansol Suh Level: developer 5058370d7cdSHansol Suh 5068370d7cdSHansol Suh @*/ 507*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSoftThreshold(Vec in, PetscReal lb, PetscReal ub, Vec out) 508*d71ae5a4SJacob Faibussowitsch { 5098370d7cdSHansol Suh PetscInt i, nlocal, mlocal; 5108370d7cdSHansol Suh PetscScalar *inarray, *outarray; 5118370d7cdSHansol Suh 5128370d7cdSHansol Suh PetscFunctionBegin; 5139566063dSJacob Faibussowitsch PetscCall(VecGetArrayPair(in, out, &inarray, &outarray)); 5149566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(in, &nlocal)); 5159566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(in, &mlocal)); 5168370d7cdSHansol Suh 5173c859ba3SBarry Smith PetscCheck(nlocal == mlocal, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Input and output vectors need to be of same size."); 5183c859ba3SBarry Smith PetscCheck(lb < ub, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Lower bound needs to be lower than upper bound."); 5198370d7cdSHansol Suh 5208370d7cdSHansol Suh if (ub >= 0 && lb < 0) { 5218370d7cdSHansol Suh for (i = 0; i < nlocal; i++) outarray[i] = ST_InternalPN(inarray[i], lb, ub); 5228370d7cdSHansol Suh } else if (ub < 0 && lb < 0) { 5238370d7cdSHansol Suh for (i = 0; i < nlocal; i++) outarray[i] = ST_InternalNN(inarray[i], lb, ub); 5248370d7cdSHansol Suh } else { 5258370d7cdSHansol Suh for (i = 0; i < nlocal; i++) outarray[i] = ST_InternalPP(inarray[i], lb, ub); 5268370d7cdSHansol Suh } 5278370d7cdSHansol Suh 5289566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayPair(in, out, &inarray, &outarray)); 5298370d7cdSHansol Suh PetscFunctionReturn(0); 5308370d7cdSHansol Suh } 531