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