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