1 #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/ 2 3 /*@ 4 TaoSetVariableBounds - Sets the upper and lower bounds 5 6 Logically collective on Tao 7 8 Input Parameters: 9 + tao - the Tao context 10 . XL - vector of lower bounds 11 - XU - vector of upper bounds 12 13 Level: beginner 14 15 .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetVariableBounds()` 16 @*/ 17 PetscErrorCode TaoSetVariableBounds(Tao tao, Vec XL, Vec XU) 18 { 19 PetscFunctionBegin; 20 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 21 if (XL) PetscValidHeaderSpecific(XL,VEC_CLASSID,2); 22 if (XU) PetscValidHeaderSpecific(XU,VEC_CLASSID,3); 23 PetscCall(PetscObjectReference((PetscObject)XL)); 24 PetscCall(PetscObjectReference((PetscObject)XU)); 25 PetscCall(VecDestroy(&tao->XL)); 26 PetscCall(VecDestroy(&tao->XU)); 27 tao->XL = XL; 28 tao->XU = XU; 29 tao->bounded = (PetscBool)(XL || XU); 30 PetscFunctionReturn(0); 31 } 32 33 /*@C 34 TaoSetVariableBoundsRoutine - Sets a function to be used to compute variable bounds 35 36 Logically collective on Tao 37 38 Input Parameters: 39 + tao - the Tao context 40 . func - the bounds computation routine 41 - ctx - [optional] user-defined context for private data for the bounds computation (may be NULL) 42 43 Calling sequence of func: 44 $ func (Tao tao, Vec xl, Vec xu); 45 46 + tao - the Tao 47 . xl - vector of lower bounds 48 . xu - vector of upper bounds 49 - ctx - the (optional) user-defined function context 50 51 Level: beginner 52 53 .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()` 54 55 Note: The func passed in to TaoSetVariableBoundsRoutine() takes 56 precedence over any values set in TaoSetVariableBounds(). 57 58 @*/ 59 PetscErrorCode TaoSetVariableBoundsRoutine(Tao tao, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx) 60 { 61 PetscFunctionBegin; 62 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 63 tao->user_boundsP = ctx; 64 tao->ops->computebounds = func; 65 tao->bounded = func ? PETSC_TRUE : PETSC_FALSE; 66 PetscFunctionReturn(0); 67 } 68 69 /*@ 70 TaoGetVariableBounds - Gets the upper and lower bounds vectors set with TaoSetVariableBounds 71 72 Not collective 73 74 Input Parameter: 75 . tao - the Tao context 76 77 Output Parametrs: 78 + XL - vector of lower bounds 79 - XU - vector of upper bounds 80 81 Level: beginner 82 83 .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()` 84 @*/ 85 PetscErrorCode TaoGetVariableBounds(Tao tao, Vec *XL, Vec *XU) 86 { 87 PetscFunctionBegin; 88 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 89 if (XL) *XL = tao->XL; 90 if (XU) *XU = tao->XU; 91 PetscFunctionReturn(0); 92 } 93 94 /*@C 95 TaoComputeVariableBounds - Compute the variable bounds using the 96 routine set by TaoSetVariableBoundsRoutine(). 97 98 Collective on Tao 99 100 Input Parameter: 101 . tao - the Tao context 102 103 Level: developer 104 105 .seealso: `TaoSetVariableBoundsRoutine()`, `TaoSetVariableBounds()` 106 @*/ 107 108 PetscErrorCode TaoComputeVariableBounds(Tao tao) 109 { 110 PetscFunctionBegin; 111 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 112 if (tao->ops->computebounds) { 113 if (!tao->XL) { 114 PetscCall(VecDuplicate(tao->solution, &tao->XL)); 115 PetscCall(VecSet(tao->XL, PETSC_NINFINITY)); 116 } 117 if (!tao->XU) { 118 PetscCall(VecDuplicate(tao->solution, &tao->XU)); 119 PetscCall(VecSet(tao->XU, PETSC_INFINITY)); 120 } 121 PetscStackPush("Tao compute variable bounds"); 122 PetscCall((*tao->ops->computebounds)(tao,tao->XL,tao->XU,tao->user_boundsP)); 123 PetscStackPop; 124 } 125 PetscFunctionReturn(0); 126 } 127 128 /*@ 129 TaoSetInequalityBounds - Sets the upper and lower bounds 130 131 Logically collective on Tao 132 133 Input Parameters: 134 + tao - the Tao context 135 . IL - vector of lower bounds 136 - IU - vector of upper bounds 137 138 Level: beginner 139 140 .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoGetInequalityBounds()` 141 @*/ 142 PetscErrorCode TaoSetInequalityBounds(Tao tao, Vec IL, Vec IU) 143 { 144 PetscFunctionBegin; 145 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 146 if (IL) PetscValidHeaderSpecific(IL,VEC_CLASSID,2); 147 if (IU) PetscValidHeaderSpecific(IU,VEC_CLASSID,3); 148 PetscCall(PetscObjectReference((PetscObject)IL)); 149 PetscCall(PetscObjectReference((PetscObject)IU)); 150 PetscCall(VecDestroy(&tao->IL)); 151 PetscCall(VecDestroy(&tao->IU)); 152 tao->IL = IL; 153 tao->IU = IU; 154 tao->ineq_doublesided = (PetscBool)(IL || IU); 155 PetscFunctionReturn(0); 156 } 157 158 /*@ 159 TaoGetInequalityBounds - Gets the upper and lower bounds set via TaoSetInequalityBounds 160 161 Logically collective on Tao 162 163 Input Parameter: 164 . tao - the Tao context 165 166 Output Parameters: 167 + IL - vector of lower bounds 168 - IU - vector of upper bounds 169 170 Level: beginner 171 172 .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetInequalityBounds()` 173 @*/ 174 PetscErrorCode TaoGetInequalityBounds(Tao tao, Vec *IL, Vec *IU) 175 { 176 PetscFunctionBegin; 177 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 178 if (IL) *IL = tao->IL; 179 if (IU) *IU = tao->IU; 180 PetscFunctionReturn(0); 181 } 182 183 /*@C 184 TaoComputeConstraints - Compute the variable bounds using the 185 routine set by TaoSetConstraintsRoutine(). 186 187 Collective on Tao 188 189 Input Parameters: 190 . tao - the Tao context 191 192 Level: developer 193 194 .seealso: `TaoSetConstraintsRoutine()`, `TaoComputeJacobian()` 195 @*/ 196 197 PetscErrorCode TaoComputeConstraints(Tao tao, Vec X, Vec C) 198 { 199 PetscFunctionBegin; 200 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 201 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 202 PetscValidHeaderSpecific(C,VEC_CLASSID,3); 203 PetscCheckSameComm(tao,1,X,2); 204 PetscCheckSameComm(tao,1,C,3); 205 PetscCheck(tao->ops->computeconstraints,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetConstraintsRoutine() has not been called"); 206 PetscCall(PetscLogEventBegin(TAO_ConstraintsEval,tao,X,C,NULL)); 207 PetscStackPush("Tao constraints evaluation routine"); 208 PetscCall((*tao->ops->computeconstraints)(tao,X,C,tao->user_conP)); 209 PetscStackPop; 210 PetscCall(PetscLogEventEnd(TAO_ConstraintsEval,tao,X,C,NULL)); 211 tao->nconstraints++; 212 PetscFunctionReturn(0); 213 } 214 215 /*@C 216 TaoSetConstraintsRoutine - Sets a function to be used to compute constraints. TAO only handles constraints under certain conditions, see manual for details 217 218 Logically collective on Tao 219 220 Input Parameters: 221 + tao - the Tao context 222 . c - A vector that will be used to store constraint evaluation 223 . func - the bounds computation routine 224 - ctx - [optional] user-defined context for private data for the constraints computation (may be NULL) 225 226 Calling sequence of func: 227 $ func (Tao tao, Vec x, Vec c, void *ctx); 228 229 + tao - the Tao 230 . x - point to evaluate constraints 231 . c - vector constraints evaluated at x 232 - ctx - the (optional) user-defined function context 233 234 Level: intermediate 235 236 .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariablevBounds()` 237 238 @*/ 239 PetscErrorCode TaoSetConstraintsRoutine(Tao tao, Vec c, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx) 240 { 241 PetscFunctionBegin; 242 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 243 if (c) PetscValidHeaderSpecific(c,VEC_CLASSID,2); 244 PetscCall(PetscObjectReference((PetscObject)c)); 245 PetscCall(VecDestroy(&tao->constraints)); 246 tao->constrained = func ? PETSC_TRUE : PETSC_FALSE; 247 tao->constraints = c; 248 tao->user_conP = ctx; 249 tao->ops->computeconstraints = func; 250 PetscFunctionReturn(0); 251 } 252 253 /*@ 254 TaoComputeDualVariables - Computes the dual vectors corresponding to the bounds 255 of the variables 256 257 Collective on Tao 258 259 Input Parameter: 260 . tao - the Tao context 261 262 Output Parameters: 263 + DL - dual variable vector for the lower bounds 264 - DU - dual variable vector for the upper bounds 265 266 Level: advanced 267 268 Note: 269 DL and DU should be created before calling this routine. If calling 270 this routine after using an unconstrained solver, DL and DU are set to all 271 zeros. 272 273 Level: advanced 274 275 .seealso: `TaoComputeObjective()`, `TaoSetVariableBounds()` 276 @*/ 277 PetscErrorCode TaoComputeDualVariables(Tao tao, Vec DL, Vec DU) 278 { 279 PetscFunctionBegin; 280 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 281 PetscValidHeaderSpecific(DL,VEC_CLASSID,2); 282 PetscValidHeaderSpecific(DU,VEC_CLASSID,3); 283 PetscCheckSameComm(tao,1,DL,2); 284 PetscCheckSameComm(tao,1,DU,3); 285 if (tao->ops->computedual) { 286 PetscCall((*tao->ops->computedual)(tao,DL,DU)); 287 } else { 288 PetscCall(VecSet(DL,0.0)); 289 PetscCall(VecSet(DU,0.0)); 290 } 291 PetscFunctionReturn(0); 292 } 293 294 /*@ 295 TaoGetDualVariables - Gets pointers to the dual vectors 296 297 Collective on Tao 298 299 Input Parameter: 300 . tao - the Tao context 301 302 Output Parameters: 303 + DE - dual variable vector for the lower bounds 304 - DI - dual variable vector for the upper bounds 305 306 Level: advanced 307 308 .seealso: `TaoComputeDualVariables()` 309 @*/ 310 PetscErrorCode TaoGetDualVariables(Tao tao, Vec *DE, Vec *DI) 311 { 312 PetscFunctionBegin; 313 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 314 if (DE) *DE = tao->DE; 315 if (DI) *DI = tao->DI; 316 PetscFunctionReturn(0); 317 } 318 319 /*@C 320 TaoSetEqualityConstraintsRoutine - Sets a function to be used to compute constraints. TAO only handles constraints under certain conditions, see manual for details 321 322 Logically collective on Tao 323 324 Input Parameters: 325 + tao - the Tao context 326 . ce - A vector that will be used to store equality constraint evaluation 327 . func - the bounds computation routine 328 - ctx - [optional] user-defined context for private data for the equality constraints computation (may be NULL) 329 330 Calling sequence of func: 331 $ func (Tao tao, Vec x, Vec ce, void *ctx); 332 333 + tao - the Tao 334 . x - point to evaluate equality constraints 335 . ce - vector of equality constraints evaluated at x 336 - ctx - the (optional) user-defined function context 337 338 Level: intermediate 339 340 .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()` 341 342 @*/ 343 PetscErrorCode TaoSetEqualityConstraintsRoutine(Tao tao, Vec ce, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx) 344 { 345 PetscFunctionBegin; 346 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 347 if (ce) PetscValidHeaderSpecific(ce,VEC_CLASSID,2); 348 PetscCall(PetscObjectReference((PetscObject)ce)); 349 PetscCall(VecDestroy(&tao->constraints_equality)); 350 tao->eq_constrained = func ? PETSC_TRUE : PETSC_FALSE; 351 tao->constraints_equality = ce; 352 tao->user_con_equalityP = ctx; 353 tao->ops->computeequalityconstraints = func; 354 PetscFunctionReturn(0); 355 } 356 357 /*@C 358 TaoSetInequalityConstraintsRoutine - Sets a function to be used to compute constraints. TAO only handles constraints under certain conditions, see manual for details 359 360 Logically collective on Tao 361 362 Input Parameters: 363 + tao - the Tao context 364 . ci - A vector that will be used to store inequality constraint evaluation 365 . func - the bounds computation routine 366 - ctx - [optional] user-defined context for private data for the inequality constraints computation (may be NULL) 367 368 Calling sequence of func: 369 $ func (Tao tao, Vec x, Vec ci, void *ctx); 370 371 + tao - the Tao 372 . x - point to evaluate inequality constraints 373 . ci - vector of inequality constraints evaluated at x 374 - ctx - the (optional) user-defined function context 375 376 Level: intermediate 377 378 .seealso: `TaoSetObjective()`, `TaoSetHessian()`, `TaoSetObjectiveAndGradient()`, `TaoSetVariableBounds()` 379 380 @*/ 381 PetscErrorCode TaoSetInequalityConstraintsRoutine(Tao tao, Vec ci, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx) 382 { 383 PetscFunctionBegin; 384 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 385 if (ci) PetscValidHeaderSpecific(ci,VEC_CLASSID,2); 386 PetscCall(PetscObjectReference((PetscObject)ci)); 387 PetscCall(VecDestroy(&tao->constraints_inequality)); 388 tao->constraints_inequality = ci; 389 tao->ineq_constrained = func ? PETSC_TRUE : PETSC_FALSE; 390 tao->user_con_inequalityP = ctx; 391 tao->ops->computeinequalityconstraints = func; 392 PetscFunctionReturn(0); 393 } 394 395 /*@C 396 TaoComputeEqualityConstraints - Compute the variable bounds using the 397 routine set by TaoSetEqualityConstraintsRoutine(). 398 399 Collective on Tao 400 401 Input Parameters: 402 . tao - the Tao context 403 404 Level: developer 405 406 .seealso: `TaoSetEqualityConstraintsRoutine()`, `TaoComputeJacobianEquality()` 407 @*/ 408 409 PetscErrorCode TaoComputeEqualityConstraints(Tao tao, Vec X, Vec CE) 410 { 411 PetscFunctionBegin; 412 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 413 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 414 PetscValidHeaderSpecific(CE,VEC_CLASSID,3); 415 PetscCheckSameComm(tao,1,X,2); 416 PetscCheckSameComm(tao,1,CE,3); 417 PetscCheck(tao->ops->computeequalityconstraints,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetEqualityConstraintsRoutine() has not been called"); 418 PetscCall(PetscLogEventBegin(TAO_ConstraintsEval,tao,X,CE,NULL)); 419 PetscStackPush("Tao equality constraints evaluation routine"); 420 PetscCall((*tao->ops->computeequalityconstraints)(tao,X,CE,tao->user_con_equalityP)); 421 PetscStackPop; 422 PetscCall(PetscLogEventEnd(TAO_ConstraintsEval,tao,X,CE,NULL)); 423 tao->nconstraints++; 424 PetscFunctionReturn(0); 425 } 426 427 /*@C 428 TaoComputeInequalityConstraints - Compute the variable bounds using the 429 routine set by TaoSetInequalityConstraintsRoutine(). 430 431 Collective on Tao 432 433 Input Parameters: 434 . tao - the Tao context 435 436 Level: developer 437 438 .seealso: `TaoSetInequalityConstraintsRoutine()`, `TaoComputeJacobianInequality()` 439 @*/ 440 441 PetscErrorCode TaoComputeInequalityConstraints(Tao tao, Vec X, Vec CI) 442 { 443 PetscFunctionBegin; 444 PetscValidHeaderSpecific(tao,TAO_CLASSID,1); 445 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 446 PetscValidHeaderSpecific(CI,VEC_CLASSID,3); 447 PetscCheckSameComm(tao,1,X,2); 448 PetscCheckSameComm(tao,1,CI,3); 449 PetscCheck(tao->ops->computeinequalityconstraints,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetInequalityConstraintsRoutine() has not been called"); 450 PetscCall(PetscLogEventBegin(TAO_ConstraintsEval,tao,X,CI,NULL)); 451 PetscStackPush("Tao inequality constraints evaluation routine"); 452 PetscCall((*tao->ops->computeinequalityconstraints)(tao,X,CI,tao->user_con_inequalityP)); 453 PetscStackPop; 454 PetscCall(PetscLogEventEnd(TAO_ConstraintsEval,tao,X,CI,NULL)); 455 tao->nconstraints++; 456 PetscFunctionReturn(0); 457 } 458