xref: /petsc/src/tao/interface/taosolver_bounds.c (revision 87f595a510d358797c1cc8101e6f6c6930cb072f)
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 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);
224   CHKERRQ(ierr);
225   CHKMEMQ;
226   PetscStackPop;
227   ierr = PetscLogEventEnd(TaoSolver_ConstraintsEval,tao,X,C,NULL); CHKERRQ(ierr);
228   tao->nconstraints++;
229   PetscFunctionReturn(0);
230 }
231 
232 
233 #undef __FUNCT__
234 #define __FUNCT__ "TaoSetConstraintsRoutine"
235 /*@C
236   TaoSetConstraintsRoutine - Sets a function to be used to compute constraints.  TAO only handles constraints under certain conditions, see manual for details
237 
238   Logically collective on TaoSolver
239 
240   Input Parameters:
241 + tao - the TaoSolver context
242 . c   - A vector that will be used to store constraint evaluation
243 . func - the bounds computation routine
244 - ctx - [optional] user-defined context for private data for the constraints computation (may be NULL)
245 
246   Calling sequence of func:
247 $      func (TaoSolver tao, Vec x, Vec c, void *ctx);
248 
249 + tao - the TaoSolver
250 . x   - point to evaluate constraints
251 . c   - vector constraints evaluated at x
252 - ctx - the (optional) user-defined function context
253 
254   Level: intermediate
255 
256 .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine(), TaoSetVariablevBounds()
257 
258 @*/
259 PetscErrorCode TaoSetConstraintsRoutine(TaoSolver tao, Vec c, PetscErrorCode (*func)(TaoSolver, Vec, Vec, void*), void *ctx)
260 {
261     PetscFunctionBegin;
262     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
263     tao->constraints = c;
264     tao->user_conP = ctx;
265     tao->ops->computeconstraints = func;
266     PetscFunctionReturn(0);
267 }
268 
269 #undef __FUNCT__
270 #define __FUNCT__ "TaoComputeDualVariables"
271 /*@
272   TaoComputeDualVariables - Computes the dual vectors corresponding to the bounds
273   of the variables
274 
275   Collective on TaoSolver
276 
277   Input Parameters:
278 . tao - the TaoSolver context
279 
280   Output Parameter:
281 + DL - dual variable vector for the lower bounds
282 - DU - dual variable vector for the upper bounds
283 
284   Level: advanced
285 
286   Note:
287   DL and DU should be created before calling this routine.  If calling
288   this routine after using an unconstrained solver, DL and DU are set to all
289   zeros.
290 
291   Level: advanced
292 
293 .seealso: TaoComputeObjective(), TaoSetVariableBounds()
294 @*/
295 PetscErrorCode TaoComputeDualVariables(TaoSolver tao, Vec DL, Vec DU)
296 {
297     PetscErrorCode ierr;
298     PetscFunctionBegin;
299     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
300     PetscValidHeaderSpecific(DL,VEC_CLASSID,2);
301     PetscValidHeaderSpecific(DU,VEC_CLASSID,2);
302     PetscCheckSameComm(tao,1,DL,2);
303     PetscCheckSameComm(tao,1,DU,3);
304     if (tao->ops->computedual) {
305       ierr = (*tao->ops->computedual)(tao,DL,DU); CHKERRQ(ierr);
306     }  else {
307       ierr = VecSet(DL,0.0); CHKERRQ(ierr);
308       ierr = VecSet(DU,0.0); CHKERRQ(ierr);
309     }
310     PetscFunctionReturn(0);
311 }
312 
313 #undef __FUNCT__
314 #define __FUNCT__ "TaoGetDualVariables"
315 /*@
316   TaoGetDualVariables - Gets pointers to the dual vectors
317 
318   Collective on TaoSolver
319 
320   Input Parameters:
321 . tao - the TaoSolver context
322 
323   Output Parameter:
324 + DE - dual variable vector for the lower bounds
325 - DI - dual variable vector for the upper bounds
326 
327   Level: advanced
328 
329 .seealso: TaoComputeDualVariables()
330 @*/
331 PetscErrorCode TaoGetDualVariables(TaoSolver tao, Vec *DE, Vec *DI)
332 {
333     PetscFunctionBegin;
334      PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
335     if (DE) {
336       *DE = tao->DE;
337     }
338     if (DI) {
339       *DI = tao->DI;
340     }
341     PetscFunctionReturn(0);
342 }
343 
344 #undef __FUNCT__
345 #define __FUNCT__ "TaoSetEqualityConstraintsRoutine"
346 /*@C
347   TaoSetEqualityConstraintsRoutine - Sets a function to be used to compute constraints.  TAO only handles constraints under certain conditions, see manual for details
348 
349   Logically collective on TaoSolver
350 
351   Input Parameters:
352 + tao - the TaoSolver context
353 . ce   - A vector that will be used to store equality constraint evaluation
354 . func - the bounds computation routine
355 - ctx - [optional] user-defined context for private data for the equality constraints computation (may be NULL)
356 
357   Calling sequence of func:
358 $      func (TaoSolver tao, Vec x, Vec ce, void *ctx);
359 
360 + tao - the TaoSolver
361 . x   - point to evaluate equality constraints
362 . ce   - vector of equality constraints evaluated at x
363 - ctx - the (optional) user-defined function context
364 
365   Level: intermediate
366 
367 .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine(), TaoSetVariableBounds()
368 
369 @*/
370 PetscErrorCode TaoSetEqualityConstraintsRoutine(TaoSolver tao, Vec ce, PetscErrorCode (*func)(TaoSolver, Vec, Vec, void*), void *ctx)
371 {
372     PetscErrorCode ierr;
373 
374     PetscFunctionBegin;
375     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
376     if (ce) {
377       PetscValidHeaderSpecific(ce,VEC_CLASSID,2);
378       PetscObjectReference((PetscObject)ce);
379     }
380     ierr = VecDestroy(&tao->constraints_equality); CHKERRQ(ierr);
381 
382     tao->constraints_equality = ce;
383     tao->user_con_equalityP = ctx;
384     tao->ops->computeequalityconstraints = func;
385     PetscFunctionReturn(0);
386 }
387 
388 
389 #undef __FUNCT__
390 #define __FUNCT__ "TaoSetInequalityConstraintsRoutine"
391 /*@C
392   TaoSetInequalityConstraintsRoutine - Sets a function to be used to compute constraints.  TAO only handles constraints under certain conditions, see manual for details
393 
394   Logically collective on TaoSolver
395 
396   Input Parameters:
397 + tao - the TaoSolver context
398 . ci   - A vector that will be used to store inequality constraint evaluation
399 . func - the bounds computation routine
400 - ctx - [optional] user-defined context for private data for the inequality constraints computation (may be NULL)
401 
402   Calling sequence of func:
403 $      func (TaoSolver tao, Vec x, Vec ci, void *ctx);
404 
405 + tao - the TaoSolver
406 . x   - point to evaluate inequality constraints
407 . ci   - vector of inequality constraints evaluated at x
408 - ctx - the (optional) user-defined function context
409 
410   Level: intermediate
411 
412 .seealso: TaoSetObjectiveRoutine(), TaoSetHessianRoutine() TaoSetObjectiveAndGradientRoutine(), TaoSetVariableBounds()
413 
414 @*/
415 PetscErrorCode TaoSetInequalityConstraintsRoutine(TaoSolver tao, Vec ci, PetscErrorCode (*func)(TaoSolver, Vec, Vec, void*), void *ctx)
416 {
417     PetscErrorCode ierr;
418 
419     PetscFunctionBegin;
420     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
421     if (ci) {
422       PetscValidHeaderSpecific(ci,VEC_CLASSID,2);
423       PetscObjectReference((PetscObject)ci);
424     }
425     ierr = VecDestroy(&tao->constraints_inequality); CHKERRQ(ierr);
426     tao->constraints_inequality = ci;
427 
428     tao->user_con_inequalityP = ctx;
429     tao->ops->computeinequalityconstraints = func;
430     PetscFunctionReturn(0);
431 }
432 
433 
434 #undef __FUNCT__
435 #define __FUNCT__ "TaoComputeEqualityConstraints"
436 /*@C
437    TaoComputeEqualityConstraints - Compute the variable bounds using the
438    routine set by TaoSetEqualityConstraintsRoutine().
439 
440    Collective on TaoSolver
441 
442    Input Parameters:
443 .  tao - the TaoSolver context
444 
445    Level: developer
446 
447 .seealso: TaoSetEqualityConstraintsRoutine(), TaoComputeJacobianEquality()
448 @*/
449 
450 PetscErrorCode TaoComputeEqualityConstraints(TaoSolver tao, Vec X, Vec CE)
451 {
452   PetscErrorCode ierr;
453 
454   PetscFunctionBegin;
455   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
456   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
457   PetscValidHeaderSpecific(CE,VEC_CLASSID,2);
458   PetscCheckSameComm(tao,1,X,2);
459   PetscCheckSameComm(tao,1,CE,3);
460 
461   if (!tao->ops->computeequalityconstraints) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetEqualityConstraintsRoutine() has not been called");
462   if (!tao->solution) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetInitialVector must be called before TaoComputeEqualityConstraints");
463   ierr = PetscLogEventBegin(TaoSolver_ConstraintsEval,tao,X,CE,NULL); CHKERRQ(ierr);
464   PetscStackPush("TaoSolver equality constraints evaluation routine");
465   CHKMEMQ;
466   ierr = (*tao->ops->computeequalityconstraints)(tao,X,CE,tao->user_con_equalityP);
467   CHKERRQ(ierr);
468   CHKMEMQ;
469   PetscStackPop;
470   ierr = PetscLogEventEnd(TaoSolver_ConstraintsEval,tao,X,CE,NULL); CHKERRQ(ierr);
471   tao->nconstraints++;
472   PetscFunctionReturn(0);
473 }
474 
475 
476 #undef __FUNCT__
477 #define __FUNCT__ "TaoComputeInequalityConstraints"
478 /*@C
479    TaoComputeInequalityConstraints - Compute the variable bounds using the
480    routine set by TaoSetInequalityConstraintsRoutine().
481 
482    Collective on TaoSolver
483 
484    Input Parameters:
485 .  tao - the TaoSolver context
486 
487    Level: developer
488 
489 .seealso: TaoSetInequalityConstraintsRoutine(), TaoComputeJacobianInequality()
490 @*/
491 
492 PetscErrorCode TaoComputeInequalityConstraints(TaoSolver tao, Vec X, Vec CI)
493 {
494   PetscErrorCode ierr;
495 
496   PetscFunctionBegin;
497   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
498   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
499   PetscValidHeaderSpecific(CI,VEC_CLASSID,2);
500   PetscCheckSameComm(tao,1,X,2);
501   PetscCheckSameComm(tao,1,CI,3);
502 
503   if (!tao->ops->computeinequalityconstraints) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetInequalityConstraintsRoutine() has not been called");
504   if (!tao->solution) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"TaoSetInitialVector must be called before TaoComputeInequalityConstraints");
505   ierr = PetscLogEventBegin(TaoSolver_ConstraintsEval,tao,X,CI,NULL); CHKERRQ(ierr);
506   PetscStackPush("TaoSolver inequality constraints evaluation routine");
507   CHKMEMQ;
508   ierr = (*tao->ops->computeinequalityconstraints)(tao,X,CI,tao->user_con_inequalityP);CHKERRQ(ierr);
509   CHKMEMQ;
510   PetscStackPop;
511   ierr = PetscLogEventEnd(TaoSolver_ConstraintsEval,tao,X,CI,NULL); CHKERRQ(ierr);
512   tao->nconstraints++;
513   PetscFunctionReturn(0);
514 }
515