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