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