xref: /petsc/src/tao/interface/taosolver_bounds.c (revision 503c0ea9b45bcfbcebbb1ea5341243bbc69f0bea)
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->XL || !tao->XU) {
113     PetscCheck(tao->solution,PetscObjectComm((PetscObject)tao),PETSC_ERR_ORDER,"TaoSetSolution must be called before TaoComputeVariableBounds");
114     PetscCall(VecDuplicate(tao->solution, &tao->XL));
115     PetscCall(VecSet(tao->XL, PETSC_NINFINITY));
116     PetscCall(VecDuplicate(tao->solution, &tao->XU));
117     PetscCall(VecSet(tao->XU, PETSC_INFINITY));
118   }
119   if (tao->ops->computebounds) {
120     PetscStackPush("Tao compute variable bounds");
121     PetscCall((*tao->ops->computebounds)(tao,tao->XL,tao->XU,tao->user_boundsP));
122     PetscStackPop;
123   }
124   PetscFunctionReturn(0);
125 }
126 
127 /*@
128   TaoSetInequalityBounds - Sets the upper and lower bounds
129 
130   Logically collective on Tao
131 
132   Input Parameters:
133 + tao - the Tao context
134 . IL  - vector of lower bounds
135 - IU  - vector of upper bounds
136 
137   Level: beginner
138 
139 .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoGetInequalityBounds()
140 @*/
141 PetscErrorCode TaoSetInequalityBounds(Tao tao, Vec IL, Vec IU)
142 {
143   PetscFunctionBegin;
144   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
145   if (IL) PetscValidHeaderSpecific(IL,VEC_CLASSID,2);
146   if (IU) PetscValidHeaderSpecific(IU,VEC_CLASSID,3);
147   PetscCall(PetscObjectReference((PetscObject)IL));
148   PetscCall(PetscObjectReference((PetscObject)IU));
149   PetscCall(VecDestroy(&tao->IL));
150   PetscCall(VecDestroy(&tao->IU));
151   tao->IL = IL;
152   tao->IU = IU;
153   tao->ineq_doublesided = (PetscBool)(IL || IU);
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158   TaoGetInequalityBounds - Gets the upper and lower bounds set via TaoSetInequalityBounds
159 
160   Logically collective on Tao
161 
162   Input Parameter:
163 . tao - the Tao context
164 
165   Output Parameters:
166 + IL  - vector of lower bounds
167 - IU  - vector of upper bounds
168 
169   Level: beginner
170 
171 .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoSetInequalityBounds()
172 @*/
173 PetscErrorCode TaoGetInequalityBounds(Tao tao, Vec *IL, Vec *IU)
174 {
175   PetscFunctionBegin;
176   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
177   if (IL) *IL = tao->IL;
178   if (IU) *IU = tao->IU;
179   PetscFunctionReturn(0);
180 }
181 
182 /*@C
183    TaoComputeConstraints - Compute the variable bounds using the
184    routine set by TaoSetConstraintsRoutine().
185 
186    Collective on Tao
187 
188    Input Parameters:
189 .  tao - the Tao context
190 
191    Level: developer
192 
193 .seealso: TaoSetConstraintsRoutine(), TaoComputeJacobian()
194 @*/
195 
196 PetscErrorCode TaoComputeConstraints(Tao tao, Vec X, Vec C)
197 {
198   PetscFunctionBegin;
199   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
200   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
201   PetscValidHeaderSpecific(C,VEC_CLASSID,3);
202   PetscCheckSameComm(tao,1,X,2);
203   PetscCheckSameComm(tao,1,C,3);
204   PetscCheck(tao->ops->computeconstraints,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetConstraintsRoutine() has not been called");
205   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval,tao,X,C,NULL));
206   PetscStackPush("Tao constraints evaluation routine");
207   PetscCall((*tao->ops->computeconstraints)(tao,X,C,tao->user_conP));
208   PetscStackPop;
209   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval,tao,X,C,NULL));
210   tao->nconstraints++;
211   PetscFunctionReturn(0);
212 }
213 
214 /*@C
215   TaoSetConstraintsRoutine - Sets a function to be used to compute constraints.  TAO only handles constraints under certain conditions, see manual for details
216 
217   Logically collective on Tao
218 
219   Input Parameters:
220 + tao - the Tao context
221 . c   - A vector that will be used to store constraint evaluation
222 . func - the bounds computation routine
223 - ctx - [optional] user-defined context for private data for the constraints computation (may be NULL)
224 
225   Calling sequence of func:
226 $      func (Tao tao, Vec x, Vec c, void *ctx);
227 
228 + tao - the Tao
229 . x   - point to evaluate constraints
230 . c   - vector constraints evaluated at x
231 - ctx - the (optional) user-defined function context
232 
233   Level: intermediate
234 
235 .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoSetVariablevBounds()
236 
237 @*/
238 PetscErrorCode TaoSetConstraintsRoutine(Tao tao, Vec c, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx)
239 {
240   PetscFunctionBegin;
241   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
242   if (c) PetscValidHeaderSpecific(c,VEC_CLASSID,2);
243   PetscCall(PetscObjectReference((PetscObject)c));
244   PetscCall(VecDestroy(&tao->constraints));
245   tao->constrained = func ? PETSC_TRUE : PETSC_FALSE;
246   tao->constraints = c;
247   tao->user_conP = ctx;
248   tao->ops->computeconstraints = func;
249   PetscFunctionReturn(0);
250 }
251 
252 /*@
253   TaoComputeDualVariables - Computes the dual vectors corresponding to the bounds
254   of the variables
255 
256   Collective on Tao
257 
258   Input Parameter:
259 . tao - the Tao context
260 
261   Output Parameters:
262 + DL - dual variable vector for the lower bounds
263 - DU - dual variable vector for the upper bounds
264 
265   Level: advanced
266 
267   Note:
268   DL and DU should be created before calling this routine.  If calling
269   this routine after using an unconstrained solver, DL and DU are set to all
270   zeros.
271 
272   Level: advanced
273 
274 .seealso: TaoComputeObjective(), TaoSetVariableBounds()
275 @*/
276 PetscErrorCode TaoComputeDualVariables(Tao tao, Vec DL, Vec DU)
277 {
278   PetscFunctionBegin;
279   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
280   PetscValidHeaderSpecific(DL,VEC_CLASSID,2);
281   PetscValidHeaderSpecific(DU,VEC_CLASSID,3);
282   PetscCheckSameComm(tao,1,DL,2);
283   PetscCheckSameComm(tao,1,DU,3);
284   if (tao->ops->computedual) {
285     PetscCall((*tao->ops->computedual)(tao,DL,DU));
286   } else {
287     PetscCall(VecSet(DL,0.0));
288     PetscCall(VecSet(DU,0.0));
289   }
290   PetscFunctionReturn(0);
291 }
292 
293 /*@
294   TaoGetDualVariables - Gets pointers to the dual vectors
295 
296   Collective on Tao
297 
298   Input Parameter:
299 . tao - the Tao context
300 
301   Output Parameters:
302 + DE - dual variable vector for the lower bounds
303 - DI - dual variable vector for the upper bounds
304 
305   Level: advanced
306 
307 .seealso: TaoComputeDualVariables()
308 @*/
309 PetscErrorCode TaoGetDualVariables(Tao tao, Vec *DE, Vec *DI)
310 {
311   PetscFunctionBegin;
312   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
313   if (DE) *DE = tao->DE;
314   if (DI) *DI = tao->DI;
315   PetscFunctionReturn(0);
316 }
317 
318 /*@C
319   TaoSetEqualityConstraintsRoutine - Sets a function to be used to compute constraints.  TAO only handles constraints under certain conditions, see manual for details
320 
321   Logically collective on Tao
322 
323   Input Parameters:
324 + tao - the Tao context
325 . ce   - A vector that will be used to store equality constraint evaluation
326 . func - the bounds computation routine
327 - ctx - [optional] user-defined context for private data for the equality constraints computation (may be NULL)
328 
329   Calling sequence of func:
330 $      func (Tao tao, Vec x, Vec ce, void *ctx);
331 
332 + tao - the Tao
333 . x   - point to evaluate equality constraints
334 . ce   - vector of equality constraints evaluated at x
335 - ctx - the (optional) user-defined function context
336 
337   Level: intermediate
338 
339 .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoSetVariableBounds()
340 
341 @*/
342 PetscErrorCode TaoSetEqualityConstraintsRoutine(Tao tao, Vec ce, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx)
343 {
344   PetscFunctionBegin;
345   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
346   if (ce) PetscValidHeaderSpecific(ce,VEC_CLASSID,2);
347   PetscCall(PetscObjectReference((PetscObject)ce));
348   PetscCall(VecDestroy(&tao->constraints_equality));
349   tao->eq_constrained = func ? PETSC_TRUE : PETSC_FALSE;
350   tao->constraints_equality = ce;
351   tao->user_con_equalityP = ctx;
352   tao->ops->computeequalityconstraints = func;
353   PetscFunctionReturn(0);
354 }
355 
356 /*@C
357   TaoSetInequalityConstraintsRoutine - Sets a function to be used to compute constraints.  TAO only handles constraints under certain conditions, see manual for details
358 
359   Logically collective on Tao
360 
361   Input Parameters:
362 + tao - the Tao context
363 . ci   - A vector that will be used to store inequality constraint evaluation
364 . func - the bounds computation routine
365 - ctx - [optional] user-defined context for private data for the inequality constraints computation (may be NULL)
366 
367   Calling sequence of func:
368 $      func (Tao tao, Vec x, Vec ci, void *ctx);
369 
370 + tao - the Tao
371 . x   - point to evaluate inequality constraints
372 . ci   - vector of inequality constraints evaluated at x
373 - ctx - the (optional) user-defined function context
374 
375   Level: intermediate
376 
377 .seealso: TaoSetObjective(), TaoSetHessian(), TaoSetObjectiveAndGradient(), TaoSetVariableBounds()
378 
379 @*/
380 PetscErrorCode TaoSetInequalityConstraintsRoutine(Tao tao, Vec ci, PetscErrorCode (*func)(Tao, Vec, Vec, void*), void *ctx)
381 {
382   PetscFunctionBegin;
383   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
384   if (ci) PetscValidHeaderSpecific(ci,VEC_CLASSID,2);
385   PetscCall(PetscObjectReference((PetscObject)ci));
386   PetscCall(VecDestroy(&tao->constraints_inequality));
387   tao->constraints_inequality = ci;
388   tao->ineq_constrained = func ? PETSC_TRUE : PETSC_FALSE;
389   tao->user_con_inequalityP = ctx;
390   tao->ops->computeinequalityconstraints = func;
391   PetscFunctionReturn(0);
392 }
393 
394 /*@C
395    TaoComputeEqualityConstraints - Compute the variable bounds using the
396    routine set by TaoSetEqualityConstraintsRoutine().
397 
398    Collective on Tao
399 
400    Input Parameters:
401 .  tao - the Tao context
402 
403    Level: developer
404 
405 .seealso: TaoSetEqualityConstraintsRoutine(), TaoComputeJacobianEquality()
406 @*/
407 
408 PetscErrorCode TaoComputeEqualityConstraints(Tao tao, Vec X, Vec CE)
409 {
410   PetscFunctionBegin;
411   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
412   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
413   PetscValidHeaderSpecific(CE,VEC_CLASSID,3);
414   PetscCheckSameComm(tao,1,X,2);
415   PetscCheckSameComm(tao,1,CE,3);
416   PetscCheck(tao->ops->computeequalityconstraints,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetEqualityConstraintsRoutine() has not been called");
417   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval,tao,X,CE,NULL));
418   PetscStackPush("Tao equality constraints evaluation routine");
419   PetscCall((*tao->ops->computeequalityconstraints)(tao,X,CE,tao->user_con_equalityP));
420   PetscStackPop;
421   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval,tao,X,CE,NULL));
422   tao->nconstraints++;
423   PetscFunctionReturn(0);
424 }
425 
426 /*@C
427    TaoComputeInequalityConstraints - Compute the variable bounds using the
428    routine set by TaoSetInequalityConstraintsRoutine().
429 
430    Collective on Tao
431 
432    Input Parameters:
433 .  tao - the Tao context
434 
435    Level: developer
436 
437 .seealso: TaoSetInequalityConstraintsRoutine(), TaoComputeJacobianInequality()
438 @*/
439 
440 PetscErrorCode TaoComputeInequalityConstraints(Tao tao, Vec X, Vec CI)
441 {
442   PetscFunctionBegin;
443   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
444   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
445   PetscValidHeaderSpecific(CI,VEC_CLASSID,3);
446   PetscCheckSameComm(tao,1,X,2);
447   PetscCheckSameComm(tao,1,CI,3);
448   PetscCheck(tao->ops->computeinequalityconstraints,PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"TaoSetInequalityConstraintsRoutine() has not been called");
449   PetscCall(PetscLogEventBegin(TAO_ConstraintsEval,tao,X,CI,NULL));
450   PetscStackPush("Tao inequality constraints evaluation routine");
451   PetscCall((*tao->ops->computeinequalityconstraints)(tao,X,CI,tao->user_con_inequalityP));
452   PetscStackPop;
453   PetscCall(PetscLogEventEnd(TAO_ConstraintsEval,tao,X,CI,NULL));
454   tao->nconstraints++;
455   PetscFunctionReturn(0);
456 }
457