xref: /petsc/src/tao/interface/taosolver_hj.c (revision aaa7dc30da3270cff6cb10b1db605b2ca746f216)
1 #include <petsc-private/taosolverimpl.h> /*I "taosolver.h" I*/
2 
3 #undef __FUNCT__
4 #define __FUNCT__ "TaoSetHessianRoutine"
5 /*@C
6    TaoSetHessianRoutine - Sets the function to compute the Hessian as well as the location to store the matrix.
7 
8    Logically collective on TaoSolver
9 
10    Input Parameters:
11 +  tao - the TaoSolver context
12 .  H - Matrix used for the hessian
13 .  Hpre - Matrix that will be used operated on by preconditioner, can be same as H
14 .  hess - Hessian evaluation routine
15 -  ctx - [optional] user-defined context for private data for the
16          Hessian evaluation routine (may be NULL)
17 
18    Calling sequence of hess:
19 $    hess (TaoSolver tao,Vec x,Mat *H,Mat *Hpre,MatStructure *flag,void *ctx);
20 
21 +  tao - the TaoSolver  context
22 .  x - input vector
23 .  H - Hessian matrix
24 .  Hpre - preconditioner matrix, usually the same as H
25 .  flag - flag indicating information about the preconditioner matrix
26    structure (see below)
27 -  ctx - [optional] user-defined Hessian context
28 
29 
30    Notes:
31 
32    The function hess() takes Mat * as the matrix arguments rather than Mat.
33    This allows the Hessian evaluation routine to replace A and/or B with a
34    completely new new matrix structure (not just different matrix elements)
35    when appropriate, for instance, if the nonzero structure is changing
36    throughout the global iterations.
37 
38    The flag can be used to eliminate unnecessary work in the preconditioner
39    during the repeated solution of linear systems of the same size.  The
40    available options are
41 $    SAME_PRECONDITIONER -
42 $      Hpre is identical during successive linear solves.
43 $      This option is intended for folks who are using
44 $      different Amat and Pmat matrices and want to reuse the
45 $      same preconditioner matrix.  For example, this option
46 $      saves work by not recomputing incomplete factorization
47 $      for ILU/ICC preconditioners.
48 $    SAME_NONZERO_PATTERN -
49 $      Hpre has the same nonzero structure during
50 $      successive linear solves.
51 $    DIFFERENT_NONZERO_PATTERN -
52 $      Hpre does not have the same nonzero structure.
53 
54    Caution:
55    If you specify SAME_NONZERO_PATTERN, the software believes your assertion
56    and does not check the structure of the matrix.  If you erroneously
57    claim that the structure is the same when it actually is not, the new
58    preconditioner will not function correctly.  Thus, use this optimization
59    feature carefully!
60 
61    If in doubt about whether your preconditioner matrix has changed
62    structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
63 
64    Level: beginner
65 
66 @*/
67 PetscErrorCode TaoSetHessianRoutine(TaoSolver tao, Mat H, Mat Hpre, PetscErrorCode (*func)(TaoSolver, Vec, Mat*, Mat *, MatStructure *, void*), void *ctx)
68 {
69   PetscErrorCode ierr;
70   PetscFunctionBegin;
71   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
72   if (H) {
73     PetscValidHeaderSpecific(H,MAT_CLASSID,2);
74     PetscCheckSameComm(tao,1,H,2);
75   }
76   if (Hpre) {
77     PetscValidHeaderSpecific(Hpre,MAT_CLASSID,3);
78     PetscCheckSameComm(tao,1,Hpre,3);
79   }
80   if (ctx) {
81     tao->user_hessP = ctx;
82   }
83   if (func) {
84     tao->ops->computehessian = func;
85   }
86 
87   if (H) {
88     ierr = PetscObjectReference((PetscObject)H);CHKERRQ(ierr);
89     if (tao->hessian) {   ierr = MatDestroy(&tao->hessian);CHKERRQ(ierr);}
90     tao->hessian = H;
91   }
92   if (Hpre) {
93     ierr = PetscObjectReference((PetscObject)Hpre);CHKERRQ(ierr);
94     if (tao->hessian_pre) { ierr = MatDestroy(&tao->hessian_pre);CHKERRQ(ierr);}
95     tao->hessian_pre=Hpre;
96   }
97   PetscFunctionReturn(0);
98 }
99 
100 #undef __FUNCT__
101 #define __FUNCT__ "TaoComputeHessian"
102 /*@C
103    TaoComputeHessian - Computes the Hessian matrix that has been
104    set with TaoSetHessianRoutine().
105 
106    Collective on TaoSolver
107 
108    Input Parameters:
109 +  solver - the TaoSolver solver context
110 -  xx - input vector
111 
112    Output Parameters:
113 +  H - Hessian matrix
114 .  Hpre - Preconditioning matrix
115 -  flag - flag indicating matrix structure (SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN, or SAME_PRECONDITIONER)
116 
117    Notes:
118    Most users should not need to explicitly call this routine, as it
119    is used internally within the minimization solvers.
120 
121    TaoComputeHessian() is typically used within minimization
122    implementations, so most users would not generally call this routine
123    themselves.
124 
125    Level: developer
126 
127 .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetHessian()
128 
129 @*/
130 PetscErrorCode TaoComputeHessian(TaoSolver tao, Vec X, Mat *H, Mat *Hpre, MatStructure *flg)
131 {
132   PetscErrorCode ierr;
133 
134   PetscFunctionBegin;
135   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
136   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
137   PetscValidPointer(flg,5);
138   PetscCheckSameComm(tao,1,X,2);
139 
140   if (!tao->ops->computehessian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetHessian() first");
141   *flg = DIFFERENT_NONZERO_PATTERN;
142   ++tao->nhess;
143   ierr = PetscLogEventBegin(TaoSolver_HessianEval,tao,X,*H,*Hpre);CHKERRQ(ierr);
144   PetscStackPush("TaoSolver user Hessian function");
145   CHKMEMQ;
146   ierr = (*tao->ops->computehessian)(tao,X,H,Hpre,flg,tao->user_hessP);CHKERRQ(ierr);
147   CHKMEMQ;
148   PetscStackPop;
149   ierr = PetscLogEventEnd(TaoSolver_HessianEval,tao,X,*H,*Hpre);CHKERRQ(ierr);
150   PetscFunctionReturn(0);
151 }
152 
153 #undef __FUNCT__
154 #define __FUNCT__ "TaoComputeJacobian"
155 /*@C
156    TaoComputeJacobian - Computes the Jacobian matrix that has been
157    set with TaoSetJacobianRoutine().
158 
159    Collective on TaoSolver
160 
161    Input Parameters:
162 +  solver - the TaoSolver solver context
163 -  xx - input vector
164 
165    Output Parameters:
166 +  H - Jacobian matrix
167 .  Hpre - Preconditioning matrix
168 -  flag - flag indicating matrix structure (SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN, or SAME_PRECONDITIONER)
169 
170    Notes:
171    Most users should not need to explicitly call this routine, as it
172    is used internally within the minimization solvers.
173 
174    TaoComputeJacobian() is typically used within minimization
175    implementations, so most users would not generally call this routine
176    themselves.
177 
178    Level: developer
179 
180 .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobian()
181 
182 @*/
183 PetscErrorCode TaoComputeJacobian(TaoSolver tao, Vec X, Mat *J, Mat *Jpre, MatStructure *flg)
184 {
185   PetscErrorCode ierr;
186 
187   PetscFunctionBegin;
188   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
189   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
190   PetscValidPointer(flg,5);
191   PetscCheckSameComm(tao,1,X,2);
192 
193   if (!tao->ops->computejacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobian() first");
194   *flg = DIFFERENT_NONZERO_PATTERN;
195   ++tao->njac;
196   ierr = PetscLogEventBegin(TaoSolver_JacobianEval,tao,X,*J,*Jpre);CHKERRQ(ierr);
197   PetscStackPush("TaoSolver user Jacobian function");
198   CHKMEMQ;
199   ierr = (*tao->ops->computejacobian)(tao,X,J,Jpre,flg,tao->user_jacP);CHKERRQ(ierr);
200   CHKMEMQ;
201   PetscStackPop;
202   ierr = PetscLogEventEnd(TaoSolver_JacobianEval,tao,X,*J,*Jpre);CHKERRQ(ierr);
203   PetscFunctionReturn(0);
204 }
205 
206 #undef __FUNCT__
207 #define __FUNCT__ "TaoComputeJacobianState"
208 /*@C
209    TaoComputeJacobianState - Computes the Jacobian matrix that has been
210    set with TaoSetJacobianStateRoutine().
211 
212    Collective on TaoSolver
213 
214    Input Parameters:
215 +  solver - the TaoSolver solver context
216 -  xx - input vector
217 
218    Output Parameters:
219 +  H - Jacobian matrix
220 .  Hpre - Preconditioning matrix
221 -  flag - flag indicating matrix structure (SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN, or SAME_PRECONDITIONER)
222 
223    Notes:
224    Most users should not need to explicitly call this routine, as it
225    is used internally within the minimization solvers.
226 
227    TaoComputeJacobianState() is typically used within minimization
228    implementations, so most users would not generally call this routine
229    themselves.
230 
231    Level: developer
232 
233 .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
234 
235 @*/
236 PetscErrorCode TaoComputeJacobianState(TaoSolver tao, Vec X, Mat *J, Mat *Jpre, Mat *Jinv, MatStructure *flg)
237 {
238   PetscErrorCode ierr;
239   PetscFunctionBegin;
240   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
241   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
242   PetscValidPointer(flg,5);
243   PetscCheckSameComm(tao,1,X,2);
244 
245   if (!tao->ops->computejacobianstate) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianState() first");
246   *flg = DIFFERENT_NONZERO_PATTERN;
247   ++tao->njac_state;
248   ierr = PetscLogEventBegin(TaoSolver_JacobianEval,tao,X,*J,*Jpre);CHKERRQ(ierr);
249   PetscStackPush("TaoSolver user Jacobian(state) function");
250   CHKMEMQ;
251   ierr = (*tao->ops->computejacobianstate)(tao,X,J,Jpre,Jinv,flg,tao->user_jac_stateP);CHKERRQ(ierr);
252   CHKMEMQ;
253   PetscStackPop;
254   ierr = PetscLogEventEnd(TaoSolver_JacobianEval,tao,X,*J,*Jpre);CHKERRQ(ierr);
255   PetscFunctionReturn(0);
256 }
257 
258 #undef __FUNCT__
259 #define __FUNCT__ "TaoComputeJacobianDesign"
260 /*@C
261    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
262    set with TaoSetJacobianDesignRoutine().
263 
264    Collective on TaoSolver
265 
266    Input Parameters:
267 +  solver - the TaoSolver solver context
268 -  xx - input vector
269 
270    Output Parameters:
271 .  H - Jacobian matrix
272 
273    Notes:
274    Most users should not need to explicitly call this routine, as it
275    is used internally within the minimization solvers.
276 
277    TaoComputeJacobianDesign() is typically used within minimization
278    implementations, so most users would not generally call this routine
279    themselves.
280 
281    Level: developer
282 
283 .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianDesignRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
284 
285 @*/
286 PetscErrorCode TaoComputeJacobianDesign(TaoSolver tao, Vec X, Mat *J)
287 {
288   PetscErrorCode ierr;
289 
290   PetscFunctionBegin;
291   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
292   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
293   PetscCheckSameComm(tao,1,X,2);
294 
295   if (!tao->ops->computejacobiandesign) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianDesign() first");
296   ++tao->njac_design;
297   ierr = PetscLogEventBegin(TaoSolver_JacobianEval,tao,X,*J,NULL);CHKERRQ(ierr);
298   PetscStackPush("TaoSolver user Jacobian(design) function");
299   CHKMEMQ;
300   ierr = (*tao->ops->computejacobiandesign)(tao,X,J,tao->user_jac_designP);CHKERRQ(ierr);
301   CHKMEMQ;
302   PetscStackPop;
303   ierr = PetscLogEventEnd(TaoSolver_JacobianEval,tao,X,*J,NULL);CHKERRQ(ierr);
304   PetscFunctionReturn(0);
305 }
306 
307 
308 
309 #undef __FUNCT__
310 #define __FUNCT__ "TaoSetJacobianRoutine"
311 /*@C
312    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
313 
314    Logically collective on TaoSolver
315 
316    Input Parameters:
317 +  tao - the TaoSolver context
318 .  J - Matrix used for the jacobian
319 .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
320 .  jac - Jacobian evaluation routine
321 -  ctx - [optional] user-defined context for private data for the
322          Jacobian evaluation routine (may be NULL)
323 
324    Calling sequence of jac:
325 $    jac (TaoSolver tao,Vec x,Mat *J,Mat *Jpre,MatStructure *flag,void *ctx);
326 
327 +  tao - the TaoSolver  context
328 .  x - input vector
329 .  J - Jacobian matrix
330 .  Jpre - preconditioner matrix, usually the same as J
331 .  flag - flag indicating information about the preconditioner matrix
332    structure (see below)
333 -  ctx - [optional] user-defined Jacobian context
334 
335 
336    Notes:
337 
338    The function jac() takes Mat * as the matrix arguments rather than Mat.
339    This allows the Jacobian evaluation routine to replace A and/or B with a
340    completely new new matrix structure (not just different matrix elements)
341    when appropriate, for instance, if the nonzero structure is changing
342    throughout the global iterations.
343 
344    The flag can be used to eliminate unnecessary work in the preconditioner
345    during the repeated solution of linear systems of the same size.  The
346    available options are
347 $    SAME_PRECONDITIONER -
348 $      Jpre is identical during successive linear solves.
349 $      This option is intended for folks who are using
350 $      different Amat and Pmat matrices and want to reuse the
351 $      same preconditioner matrix.  For example, this option
352 $      saves work by not recomputing incomplete factorization
353 $      for ILU/ICC preconditioners.
354 $    SAME_NONZERO_PATTERN -
355 $      Jpre has the same nonzero structure during
356 $      successive linear solves.
357 $    DIFFERENT_NONZERO_PATTERN -
358 $      Jpre does not have the same nonzero structure.
359 
360    Caution:
361    If you specify SAME_NONZERO_PATTERN, the software believes your assertion
362    and does not check the structure of the matrix.  If you erroneously
363    claim that the structure is the same when it actually is not, the new
364    preconditioner will not function correctly.  Thus, use this optimization
365    feature carefully!
366 
367    If in doubt about whether your preconditioner matrix has changed
368    structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
369 
370    Level: intermediate
371 
372 @*/
373 PetscErrorCode TaoSetJacobianRoutine(TaoSolver tao, Mat J, Mat Jpre, PetscErrorCode (*func)(TaoSolver, Vec, Mat*, Mat *, MatStructure *, void*), void *ctx)
374 {
375     PetscErrorCode ierr;
376     PetscFunctionBegin;
377     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
378     if (J) {
379         PetscValidHeaderSpecific(J,MAT_CLASSID,2);
380         PetscCheckSameComm(tao,1,J,2);
381     }
382     if (Jpre) {
383         PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
384         PetscCheckSameComm(tao,1,Jpre,3);
385     }
386     if (ctx) {
387         tao->user_jacP = ctx;
388     }
389     if (func) {
390         tao->ops->computejacobian = func;
391     }
392 
393 
394     if (J) {
395         ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
396         if (tao->jacobian) {   ierr = MatDestroy(&tao->jacobian);CHKERRQ(ierr);}
397         tao->jacobian = J;
398     }
399     if (Jpre) {
400         ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
401         if (tao->jacobian_pre) { ierr = MatDestroy(&tao->jacobian_pre);CHKERRQ(ierr);}
402         tao->jacobian_pre=Jpre;
403     }
404     PetscFunctionReturn(0);
405 }
406 
407 
408 #undef __FUNCT__
409 #define __FUNCT__ "TaoSetJacobianStateRoutine"
410 /*@C
411    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
412    (and its inverse) of the constraint function with respect to the state variables.
413    Used only for pde-constrained optimization.
414 
415    Logically collective on TaoSolver
416 
417    Input Parameters:
418 +  tao - the TaoSolver context
419 .  J - Matrix used for the jacobian
420 .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
421 .  Jinv - [optional] Matrix used to apply the inverse of the state jacobian. Use NULL to default to PETSc KSP solvers to apply the inverse.
422 .  jac - Jacobian evaluation routine
423 -  ctx - [optional] user-defined context for private data for the
424          Jacobian evaluation routine (may be NULL)
425 
426    Calling sequence of jac:
427 $    jac (TaoSolver tao,Vec x,Mat *J,Mat *Jpre,MatStructure *flag,void *ctx);
428 
429 +  tao - the TaoSolver  context
430 .  x - input vector
431 .  J - Jacobian matrix
432 .  Jpre - preconditioner matrix, usually the same as J
433 .  Jinv - inverse of J
434 .  flag - flag indicating information about the preconditioner matrix
435    structure (see below)
436 -  ctx - [optional] user-defined Jacobian context
437 
438 
439    Notes:
440    Because of the structure of the jacobian matrix,
441    It may be more efficient for a pde-constrained application to provide
442    its own Jinv matrix.
443 
444    The function jac() takes Mat * as the matrix arguments rather than Mat.
445    This allows the Jacobian evaluation routine to replace A and/or B with a
446    completely new new maitrix structure (not just different matrix elements)
447    when appropriate, for instance, if the nonzero structure is changing
448    throughout the global iterations.
449 
450    The flag can be used to eliminate unnecessary work in the preconditioner
451    during the repeated solution of linear systems of the same size.  The
452    available options are
453 $    SAME_PRECONDITIONER -
454 $      Jpre is identical during successive linear solves.
455 $      This option is intended for folks who are using
456 $      different Amat and Pmat matrices and want to reuse the
457 $      same preconditioner matrix.  For example, this option
458 $      saves work by not recomputing incomplete factorization
459 $      for ILU/ICC preconditioners.
460 $    SAME_NONZERO_PATTERN -
461 $      Jpre has the same nonzero structure during
462 $      successive linear solves.
463 $    DIFFERENT_NONZERO_PATTERN -
464 $      Jpre does not have the same nonzero structure.
465 
466    Caution:
467    If you specify SAME_NONZERO_PATTERN, the software believes your assertion
468    and does not check the structure of the matrix.  If you erroneously
469    claim that the structure is the same when it actually is not, the new
470    preconditioner will not function correctly.  Thus, use this optimization
471    feature carefully!
472 
473    If in doubt about whether your preconditioner matrix has changed
474    structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
475 
476    Level: intermediate
477 .seealse: TaoComputeJacobianState(), TaoSetJacobianDesignRoutine(), TaoSetStateDesignIS()
478 @*/
479 PetscErrorCode TaoSetJacobianStateRoutine(TaoSolver tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(TaoSolver, Vec, Mat*, Mat *, Mat *, MatStructure *, void*), void *ctx)
480 {
481     PetscErrorCode ierr;
482     PetscFunctionBegin;
483     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
484     if (J) {
485         PetscValidHeaderSpecific(J,MAT_CLASSID,2);
486         PetscCheckSameComm(tao,1,J,2);
487     }
488     if (Jpre) {
489         PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
490         PetscCheckSameComm(tao,1,Jpre,3);
491     }
492     if (Jinv) {
493       PetscValidHeaderSpecific(Jinv,MAT_CLASSID,4);
494       PetscCheckSameComm(tao,1,Jinv,4);
495     }
496     if (ctx) {
497         tao->user_jac_stateP = ctx;
498     }
499     if (func) {
500         tao->ops->computejacobianstate = func;
501     }
502 
503 
504     if (J) {
505         ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
506         if (tao->jacobian_state) {   ierr = MatDestroy(&tao->jacobian_state);CHKERRQ(ierr);}
507         tao->jacobian_state = J;
508     }
509     if (Jpre) {
510         ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
511         if (tao->jacobian_state_pre) { ierr = MatDestroy(&tao->jacobian_state_pre);CHKERRQ(ierr);}
512         tao->jacobian_state_pre=Jpre;
513     }
514     if (Jinv) {
515       ierr = PetscObjectReference((PetscObject)Jinv);CHKERRQ(ierr);
516       if (tao->jacobian_state_inv) {ierr = MatDestroy(&tao->jacobian_state_inv);CHKERRQ(ierr);}
517       tao->jacobian_state_inv=Jinv;
518     }
519     PetscFunctionReturn(0);
520 }
521 
522 #undef __FUNCT__
523 #define __FUNCT__ "TaoSetJacobianDesignRoutine"
524 /*@C
525    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
526    the constraint function with respect to the design variables.  Used only for
527    pde-constrained optimization.
528 
529    Logically collective on TaoSolver
530 
531    Input Parameters:
532 +  tao - the TaoSolver context
533 .  J - Matrix used for the jacobian
534 .  jac - Jacobian evaluation routine
535 -  ctx - [optional] user-defined context for private data for the
536          Jacobian evaluation routine (may be NULL)
537 
538    Calling sequence of jac:
539 $    jac (TaoSolver tao,Vec x,Mat *J,void *ctx);
540 
541 +  tao - the TaoSolver  context
542 .  x - input vector
543 .  J - Jacobian matrix
544 -  ctx - [optional] user-defined Jacobian context
545 
546 
547    Notes:
548 
549    The function jac() takes Mat * as the matrix arguments rather than Mat.
550    This allows the Jacobian evaluation routine to replace A and/or B with a
551    completely new new matrix structure (not just different matrix elements)
552    when appropriate, for instance, if the nonzero structure is changing
553    throughout the global iterations.
554 
555    Level: intermediate
556 .seealso: TaoComputeJacobianDesign(), TaoSetJacobianStateRoutine(), TaoSetStateDesignIS()
557 @*/
558 PetscErrorCode TaoSetJacobianDesignRoutine(TaoSolver tao, Mat J, PetscErrorCode (*func)(TaoSolver, Vec, Mat*, void*), void *ctx)
559 {
560     PetscErrorCode ierr;
561     PetscFunctionBegin;
562     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
563     if (J) {
564         PetscValidHeaderSpecific(J,MAT_CLASSID,2);
565         PetscCheckSameComm(tao,1,J,2);
566     }
567     if (ctx) {
568         tao->user_jac_designP = ctx;
569     }
570     if (func) {
571         tao->ops->computejacobiandesign = func;
572     }
573 
574 
575     if (J) {
576         ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
577         if (tao->jacobian_design) {   ierr = MatDestroy(&tao->jacobian_design);CHKERRQ(ierr);}
578         tao->jacobian_design = J;
579     }
580     PetscFunctionReturn(0);
581 }
582 
583 #undef __FUNCT__
584 #define __FUNCT__ "TaoSetStateDesignIS"
585 /*@
586    TaoSetStateDesignIS - Indicate to the TaoSolver which variables in the
587    solution vector are state variables and which are design.  Only applies to
588    pde-constrained optimization.
589 
590    Logically Collective on TaoSolver
591 
592    Input Parameters:
593 +  tao - The TaoSolver context
594 .  s_is - the index set corresponding to the state variables
595 -  d_is - the index set corresponding to the design variables
596 
597    Level: intermediate
598 
599 .seealso: TaoSetJacobianStateRoutine(), TaoSetJacobianDesignRoutine()
600 @*/
601 PetscErrorCode TaoSetStateDesignIS(TaoSolver tao, IS s_is, IS d_is)
602 {
603   PetscErrorCode ierr;
604   if (tao->state_is) {
605     ierr = PetscObjectDereference((PetscObject)(tao->state_is));CHKERRQ(ierr);
606   }
607   if (tao->design_is) {
608     ierr = PetscObjectDereference((PetscObject)(tao->design_is));CHKERRQ(ierr);
609   }
610   tao->state_is = s_is;
611   tao->design_is = d_is;
612   if (s_is) {
613     ierr = PetscObjectReference((PetscObject)(tao->state_is));CHKERRQ(ierr);
614   }
615   if (d_is) {
616     ierr = PetscObjectReference((PetscObject)(tao->design_is));CHKERRQ(ierr);
617   }
618   PetscFunctionReturn(0);
619 }
620 
621 
622 #undef __FUNCT__
623 #define __FUNCT__ "TaoComputeJacobianEquality"
624 /*@C
625    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
626    set with TaoSetJacobianEqualityRoutine().
627 
628    Collective on TaoSolver
629 
630    Input Parameters:
631 +  solver - the TaoSolver solver context
632 -  xx - input vector
633 
634    Output Parameters:
635 +  H - Jacobian matrix
636 .  Hpre - Preconditioning matrix
637 -  flag - flag indicating matrix structure (SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN, or SAME_PRECONDITIONER)
638 
639    Notes:
640    Most users should not need to explicitly call this routine, as it
641    is used internally within the minimization solvers.
642 
643    Level: developer
644 
645 .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
646 
647 @*/
648 PetscErrorCode TaoComputeJacobianEquality(TaoSolver tao, Vec X, Mat *J, Mat *Jpre, MatStructure *flg)
649 {
650   PetscErrorCode ierr;
651   PetscFunctionBegin;
652   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
653   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
654   PetscValidPointer(flg,5);
655   PetscCheckSameComm(tao,1,X,2);
656 
657   if (!tao->ops->computejacobianequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianEquality() first");
658   *flg = DIFFERENT_NONZERO_PATTERN;
659   ++tao->njac_equality;
660   ierr = PetscLogEventBegin(TaoSolver_JacobianEval,tao,X,*J,*Jpre);CHKERRQ(ierr);
661   PetscStackPush("TaoSolver user Jacobian(equality) function");
662   CHKMEMQ;
663   ierr = (*tao->ops->computejacobianequality)(tao,X,J,Jpre,flg,tao->user_jac_equalityP);CHKERRQ(ierr);
664   CHKMEMQ;
665   PetscStackPop;
666   ierr = PetscLogEventEnd(TaoSolver_JacobianEval,tao,X,*J,*Jpre);CHKERRQ(ierr);
667   PetscFunctionReturn(0);
668 }
669 
670 #undef __FUNCT__
671 #define __FUNCT__ "TaoComputeJacobianInequality"
672 /*@C
673    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
674    set with TaoSetJacobianInequalityRoutine().
675 
676    Collective on TaoSolver
677 
678    Input Parameters:
679 +  solver - the TaoSolver solver context
680 -  xx - input vector
681 
682    Output Parameters:
683 +  H - Jacobian matrix
684 .  Hpre - Preconditioning matrix
685 -  flag - flag indicating matrix structure (SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN, or SAME_PRECONDITIONER)
686 
687    Notes:
688    Most users should not need to explicitly call this routine, as it
689    is used internally within the minimization solvers.
690 
691    Level: developer
692 
693 .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
694 
695 @*/
696 PetscErrorCode TaoComputeJacobianInequality(TaoSolver tao, Vec X, Mat *J, Mat *Jpre, MatStructure *flg)
697 {
698   PetscErrorCode ierr;
699 
700   PetscFunctionBegin;
701   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
702   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
703   PetscValidPointer(flg,5);
704   PetscCheckSameComm(tao,1,X,2);
705 
706   if (!tao->ops->computejacobianinequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianInequality() first");
707   *flg = DIFFERENT_NONZERO_PATTERN;
708   ++tao->njac_inequality;
709   ierr = PetscLogEventBegin(TaoSolver_JacobianEval,tao,X,*J,*Jpre);CHKERRQ(ierr);
710   PetscStackPush("TaoSolver user Jacobian(inequality) function");
711   CHKMEMQ;
712   ierr = (*tao->ops->computejacobianinequality)(tao,X,J,Jpre,flg,tao->user_jac_inequalityP);CHKERRQ(ierr);
713   CHKMEMQ;
714   PetscStackPop;
715   ierr = PetscLogEventEnd(TaoSolver_JacobianEval,tao,X,*J,*Jpre);CHKERRQ(ierr);
716   PetscFunctionReturn(0);
717 }
718 
719 #undef __FUNCT__
720 #define __FUNCT__ "TaoSetJacobianEqualityRoutine"
721 /*@C
722    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
723    (and its inverse) of the constraint function with respect to the equality variables.
724    Used only for pde-constrained optimization.
725 
726    Logically collective on TaoSolver
727 
728    Input Parameters:
729 +  tao - the TaoSolver context
730 .  J - Matrix used for the jacobian
731 .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
732 .  jac - Jacobian evaluation routine
733 -  ctx - [optional] user-defined context for private data for the
734          Jacobian evaluation routine (may be NULL)
735 
736    Calling sequence of jac:
737 $    jac (TaoSolver tao,Vec x,Mat *J,Mat *Jpre,MatStructure *flag,void *ctx);
738 
739 +  tao - the TaoSolver  context
740 .  x - input vector
741 .  J - Jacobian matrix
742 .  Jpre - preconditioner matrix, usually the same as J
743 .  flag - flag indicating information about the preconditioner matrix
744    structure (see below)
745 -  ctx - [optional] user-defined Jacobian context
746 
747 
748    Notes:
749    Because of the structure of the jacobian matrix,
750    It may be more efficient for a pde-constrained application to provide
751    its own Jinv matrix.
752 
753    The function jac() takes Mat * as the matrix arguments rather than Mat.
754    This allows the Jacobian evaluation routine to replace A and/or B with a
755    completely new new maitrix structure (not just different matrix elements)
756    when appropriate, for instance, if the nonzero structure is changing
757    throughout the global iterations.
758 
759    The flag can be used to eliminate unnecessary work in the preconditioner
760    during the repeated solution of linear systems of the same size.  The
761    available options are
762 $    SAME_PRECONDITIONER -
763 $      Jpre is identical during successive linear solves.
764 $      This option is intended for folks who are using
765 $      different Amat and Pmat matrices and want to reuse the
766 $      same preconditioner matrix.  For example, this option
767 $      saves work by not recomputing incomplete factorization
768 $      for ILU/ICC preconditioners.
769 $    SAME_NONZERO_PATTERN -
770 $      Jpre has the same nonzero structure during
771 $      successive linear solves.
772 $    DIFFERENT_NONZERO_PATTERN -
773 $      Jpre does not have the same nonzero structure.
774 
775    Caution:
776    If you specify SAME_NONZERO_PATTERN, the software believes your assertion
777    and does not check the structure of the matrix.  If you erroneously
778    claim that the structure is the same when it actually is not, the new
779    preconditioner will not function correctly.  Thus, use this optimization
780    feature carefully!
781 
782    If in doubt about whether your preconditioner matrix has changed
783    structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
784 
785    Level: intermediate
786 .seealse: TaoComputeJacobianEquality(), TaoSetJacobianDesignRoutine(), TaoSetEqualityDesignIS()
787 @*/
788 PetscErrorCode TaoSetJacobianEqualityRoutine(TaoSolver tao, Mat J, Mat Jpre, PetscErrorCode (*func)(TaoSolver, Vec, Mat*, Mat *, MatStructure *, void*), void *ctx)
789 {
790     PetscErrorCode ierr;
791     PetscFunctionBegin;
792     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
793     if (J) {
794         PetscValidHeaderSpecific(J,MAT_CLASSID,2);
795         PetscCheckSameComm(tao,1,J,2);
796     }
797     if (Jpre) {
798         PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
799         PetscCheckSameComm(tao,1,Jpre,3);
800     }
801     if (ctx) {
802         tao->user_jac_equalityP = ctx;
803     }
804     if (func) {
805         tao->ops->computejacobianequality = func;
806     }
807 
808 
809     if (J) {
810         ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
811         if (tao->jacobian_equality) {   ierr = MatDestroy(&tao->jacobian_equality);CHKERRQ(ierr);}
812         tao->jacobian_equality = J;
813     }
814     if (Jpre) {
815         ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
816         if (tao->jacobian_equality_pre) { ierr = MatDestroy(&tao->jacobian_equality_pre);CHKERRQ(ierr);}
817         tao->jacobian_equality_pre=Jpre;
818     }
819     PetscFunctionReturn(0);
820 }
821 
822 #undef __FUNCT__
823 #define __FUNCT__ "TaoSetJacobianInequalityRoutine"
824 /*@C
825    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
826    (and its inverse) of the constraint function with respect to the inequality variables.
827    Used only for pde-constrained optimization.
828 
829    Logically collective on TaoSolver
830 
831    Input Parameters:
832 +  tao - the TaoSolver context
833 .  J - Matrix used for the jacobian
834 .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
835 .  jac - Jacobian evaluation routine
836 -  ctx - [optional] user-defined context for private data for the
837          Jacobian evaluation routine (may be NULL)
838 
839    Calling sequence of jac:
840 $    jac (TaoSolver tao,Vec x,Mat *J,Mat *Jpre,MatStructure *flag,void *ctx);
841 
842 +  tao - the TaoSolver  context
843 .  x - input vector
844 .  J - Jacobian matrix
845 .  Jpre - preconditioner matrix, usually the same as J
846 .  flag - flag indicating information about the preconditioner matrix
847    structure (see below)
848 -  ctx - [optional] user-defined Jacobian context
849 
850 
851    Notes:
852    Because of the structure of the jacobian matrix,
853    It may be more efficient for a pde-constrained application to provide
854    its own Jinv matrix.
855 
856    The function jac() takes Mat * as the matrix arguments rather than Mat.
857    This allows the Jacobian evaluation routine to replace A and/or B with a
858    completely new new maitrix structure (not just different matrix elements)
859    when appropriate, for instance, if the nonzero structure is changing
860    throughout the global iterations.
861 
862    The flag can be used to eliminate unnecessary work in the preconditioner
863    during the repeated solution of linear systems of the same size.  The
864    available options are
865 $    SAME_PRECONDITIONER -
866 $      Jpre is identical during successive linear solves.
867 $      This option is intended for folks who are using
868 $      different Amat and Pmat matrices and want to reuse the
869 $      same preconditioner matrix.  For example, this option
870 $      saves work by not recomputing incomplete factorization
871 $      for ILU/ICC preconditioners.
872 $    SAME_NONZERO_PATTERN -
873 $      Jpre has the same nonzero structure during
874 $      successive linear solves.
875 $    DIFFERENT_NONZERO_PATTERN -
876 $      Jpre does not have the same nonzero structure.
877 
878    Caution:
879    If you specify SAME_NONZERO_PATTERN, the software believes your assertion
880    and does not check the structure of the matrix.  If you erroneously
881    claim that the structure is the same when it actually is not, the new
882    preconditioner will not function correctly.  Thus, use this optimization
883    feature carefully!
884 
885    If in doubt about whether your preconditioner matrix has changed
886    structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
887 
888    Level: intermediate
889 .seealse: TaoComputeJacobianInequality(), TaoSetJacobianDesignRoutine(), TaoSetInequalityDesignIS()
890 @*/
891 PetscErrorCode TaoSetJacobianInequalityRoutine(TaoSolver tao, Mat J, Mat Jpre, PetscErrorCode (*func)(TaoSolver, Vec, Mat*, Mat *, MatStructure *, void*), void *ctx)
892 {
893     PetscErrorCode ierr;
894     PetscFunctionBegin;
895     PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
896     if (J) {
897         PetscValidHeaderSpecific(J,MAT_CLASSID,2);
898         PetscCheckSameComm(tao,1,J,2);
899     }
900     if (Jpre) {
901         PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
902         PetscCheckSameComm(tao,1,Jpre,3);
903     }
904     if (ctx) {
905         tao->user_jac_inequalityP = ctx;
906     }
907     if (func) {
908         tao->ops->computejacobianinequality = func;
909     }
910 
911 
912     if (J) {
913         ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
914         if (tao->jacobian_inequality) {   ierr = MatDestroy(&tao->jacobian_inequality);CHKERRQ(ierr);}
915         tao->jacobian_inequality = J;
916     }
917     if (Jpre) {
918         ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
919         if (tao->jacobian_inequality_pre) { ierr = MatDestroy(&tao->jacobian_inequality_pre);CHKERRQ(ierr);}
920         tao->jacobian_inequality_pre=Jpre;
921     }
922     PetscFunctionReturn(0);
923 }
924