xref: /petsc/src/tao/interface/taosolver_bounds.c (revision 76be6f4ff3bd4e251c19fc00ebbebfd58b6e7589)
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