Actual source code: eptorsion1.c
1: /* Program usage: mpiexec -n 1 eptorsion1 [-help] [all TAO options] */
3: /* ----------------------------------------------------------------------
5: Elastic-plastic torsion problem.
7: The elastic plastic torsion problem arises from the determination
8: of the stress field on an infinitely long cylindrical bar, which is
9: equivalent to the solution of the following problem:
11: min{ .5 * integral(||gradient(v(x))||^2 dx) - C * integral(v(x) dx)}
13: where C is the torsion angle per unit length.
15: The multiprocessor version of this code is eptorsion2.c.
17: ---------------------------------------------------------------------- */
19: /*
20: Include "petsctao.h" so that we can use TAO solvers. Note that this
21: file automatically includes files for lower-level support, such as those
22: provided by the PETSc library:
23: petscsys.h - system routines
24: petscis.h - index sets
25: petscvec.h - vectors
26: petscmat.h - matrices
27: petscpc.h - preconditioners
28: petscksp.h - Krylov subspace methods
29: */
31: #include <petsctao.h>
33: static char help[] = "Demonstrates use of the TAO package to solve \n\
34: unconstrained minimization problems on a single processor. This example \n\
35: is based on the Elastic-Plastic Torsion (dept) problem from the MINPACK-2 \n\
36: test suite.\n\
37: The command line options are:\n\
38: -mx <xg>, where <xg> = number of grid points in the 1st coordinate direction\n\
39: -my <yg>, where <yg> = number of grid points in the 2nd coordinate direction\n\
40: -par <param>, where <param> = angle of twist per unit length\n\n";
42: /*
43: User-defined application context - contains data needed by the
44: application-provided call-back routines, FormFunction(),
45: FormGradient(), and FormHessian().
46: */
48: typedef struct {
49: PetscReal param; /* nonlinearity parameter */
50: PetscInt mx, my; /* discretization in x- and y-directions */
51: PetscInt ndim; /* problem dimension */
52: Vec s, y, xvec; /* work space for computing Hessian */
53: PetscReal hx, hy; /* mesh spacing in x- and y-directions */
54: } AppCtx;
56: /* -------- User-defined Routines --------- */
58: PetscErrorCode FormInitialGuess(AppCtx *, Vec);
59: PetscErrorCode FormFunction(Tao, Vec, PetscReal *, void *);
60: PetscErrorCode FormGradient(Tao, Vec, Vec, void *);
61: PetscErrorCode FormHessian(Tao, Vec, Mat, Mat, void *);
62: PetscErrorCode HessianProductMat(Mat, Vec, Vec);
63: PetscErrorCode HessianProduct(void *, Vec, Vec);
64: PetscErrorCode MatrixFreeHessian(Tao, Vec, Mat, Mat, void *);
65: PetscErrorCode FormFunctionGradient(Tao, Vec, PetscReal *, Vec, void *);
67: int main(int argc, char **argv)
68: {
69: PetscInt mx = 10; /* discretization in x-direction */
70: PetscInt my = 10; /* discretization in y-direction */
71: Vec x; /* solution, gradient vectors */
72: PetscBool flg; /* A return value when checking for use options */
73: Tao tao; /* Tao solver context */
74: Mat H; /* Hessian matrix */
75: AppCtx user; /* application context */
76: PetscMPIInt size; /* number of processes */
77: PetscReal one = 1.0;
79: PetscBool test_lmvm = PETSC_FALSE;
80: KSP ksp;
81: PC pc;
82: Mat M;
83: Vec in, out, out2;
84: PetscReal mult_solve_dist;
86: /* Initialize TAO,PETSc */
87: PetscFunctionBeginUser;
88: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
89: PetscCallMPI(MPI_Comm_size(MPI_COMM_WORLD, &size));
90: PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Incorrect number of processors");
92: /* Specify default parameters for the problem, check for command-line overrides */
93: user.param = 5.0;
94: PetscCall(PetscOptionsGetInt(NULL, NULL, "-my", &my, &flg));
95: PetscCall(PetscOptionsGetInt(NULL, NULL, "-mx", &mx, &flg));
96: PetscCall(PetscOptionsGetReal(NULL, NULL, "-par", &user.param, &flg));
97: PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_lmvm", &test_lmvm, &flg));
99: PetscCall(PetscPrintf(PETSC_COMM_SELF, "\n---- Elastic-Plastic Torsion Problem -----\n"));
100: PetscCall(PetscPrintf(PETSC_COMM_SELF, "mx: %" PetscInt_FMT " my: %" PetscInt_FMT " \n\n", mx, my));
101: user.ndim = mx * my;
102: user.mx = mx;
103: user.my = my;
104: user.hx = one / (mx + 1);
105: user.hy = one / (my + 1);
107: /* Allocate vectors */
108: PetscCall(VecCreateSeq(PETSC_COMM_SELF, user.ndim, &user.y));
109: PetscCall(VecDuplicate(user.y, &user.s));
110: PetscCall(VecDuplicate(user.y, &x));
112: /* Create TAO solver and set desired solution method */
113: PetscCall(TaoCreate(PETSC_COMM_SELF, &tao));
114: PetscCall(TaoSetType(tao, TAOLMVM));
116: /* Set solution vector with an initial guess */
117: PetscCall(FormInitialGuess(&user, x));
118: PetscCall(TaoSetSolution(tao, x));
120: /* Set routine for function and gradient evaluation */
121: PetscCall(TaoSetObjectiveAndGradient(tao, NULL, FormFunctionGradient, (void *)&user));
123: /* From command line options, determine if using matrix-free hessian */
124: PetscCall(PetscOptionsHasName(NULL, NULL, "-my_tao_mf", &flg));
125: if (flg) {
126: PetscCall(MatCreateShell(PETSC_COMM_SELF, user.ndim, user.ndim, user.ndim, user.ndim, (void *)&user, &H));
127: PetscCall(MatShellSetOperation(H, MATOP_MULT, (PetscErrorCodeFn *)HessianProductMat));
128: PetscCall(MatSetOption(H, MAT_SYMMETRIC, PETSC_TRUE));
130: PetscCall(TaoSetHessian(tao, H, H, MatrixFreeHessian, (void *)&user));
131: } else {
132: PetscCall(MatCreateSeqAIJ(PETSC_COMM_SELF, user.ndim, user.ndim, 5, NULL, &H));
133: PetscCall(MatSetOption(H, MAT_SYMMETRIC, PETSC_TRUE));
134: PetscCall(TaoSetHessian(tao, H, H, FormHessian, (void *)&user));
135: }
137: /* Test the LMVM matrix */
138: if (test_lmvm) {
139: PetscCall(PetscOptionsSetValue(NULL, "-tao_type", "bntr"));
140: PetscCall(PetscOptionsSetValue(NULL, "-tao_bnk_pc_type", "lmvm"));
141: }
143: /* Check for any TAO command line options */
144: PetscCall(TaoSetFromOptions(tao));
146: /* SOLVE THE APPLICATION */
147: PetscCall(TaoSolve(tao));
149: /* Test the LMVM matrix */
150: if (test_lmvm) {
151: PetscCall(TaoGetKSP(tao, &ksp));
152: PetscCall(KSPGetPC(ksp, &pc));
153: PetscCall(PCLMVMGetMatLMVM(pc, &M));
154: PetscCall(VecDuplicate(x, &in));
155: PetscCall(VecDuplicate(x, &out));
156: PetscCall(VecDuplicate(x, &out2));
157: PetscCall(VecSet(in, 5.0));
158: PetscCall(MatMult(M, in, out));
159: PetscCall(MatSolve(M, out, out2));
160: PetscCall(VecAXPY(out2, -1.0, in));
161: PetscCall(VecNorm(out2, NORM_2, &mult_solve_dist));
162: PetscCall(PetscPrintf(PetscObjectComm((PetscObject)tao), "error between MatMult and MatSolve: %e\n", (double)mult_solve_dist));
163: PetscCall(VecDestroy(&in));
164: PetscCall(VecDestroy(&out));
165: PetscCall(VecDestroy(&out2));
166: }
168: PetscCall(TaoDestroy(&tao));
169: PetscCall(VecDestroy(&user.s));
170: PetscCall(VecDestroy(&user.y));
171: PetscCall(VecDestroy(&x));
172: PetscCall(MatDestroy(&H));
174: PetscCall(PetscFinalize());
175: return 0;
176: }
178: /* ------------------------------------------------------------------- */
179: /*
180: FormInitialGuess - Computes an initial approximation to the solution.
182: Input Parameters:
183: . user - user-defined application context
184: . X - vector
186: Output Parameters:
187: . X - vector
188: */
189: PetscErrorCode FormInitialGuess(AppCtx *user, Vec X)
190: {
191: PetscReal hx = user->hx, hy = user->hy, temp;
192: PetscReal val;
193: PetscInt i, j, k, nx = user->mx, ny = user->my;
195: /* Compute initial guess */
196: PetscFunctionBeginUser;
197: for (j = 0; j < ny; j++) {
198: temp = PetscMin(j + 1, ny - j) * hy;
199: for (i = 0; i < nx; i++) {
200: k = nx * j + i;
201: val = PetscMin((PetscMin(i + 1, nx - i)) * hx, temp);
202: PetscCall(VecSetValues(X, 1, &k, &val, ADD_VALUES));
203: }
204: }
205: PetscCall(VecAssemblyBegin(X));
206: PetscCall(VecAssemblyEnd(X));
207: PetscFunctionReturn(PETSC_SUCCESS);
208: }
210: /* ------------------------------------------------------------------- */
211: /*
212: FormFunctionGradient - Evaluates the function and corresponding gradient.
214: Input Parameters:
215: tao - the Tao context
216: X - the input vector
217: ptr - optional user-defined context, as set by TaoSetFunction()
219: Output Parameters:
220: f - the newly evaluated function
221: G - the newly evaluated gradient
222: */
223: PetscErrorCode FormFunctionGradient(Tao tao, Vec X, PetscReal *f, Vec G, void *ptr)
224: {
225: PetscFunctionBeginUser;
226: PetscCall(FormFunction(tao, X, f, ptr));
227: PetscCall(FormGradient(tao, X, G, ptr));
228: PetscFunctionReturn(PETSC_SUCCESS);
229: }
231: /* ------------------------------------------------------------------- */
232: /*
233: FormFunction - Evaluates the function, f(X).
235: Input Parameters:
236: . tao - the Tao context
237: . X - the input vector
238: . ptr - optional user-defined context, as set by TaoSetFunction()
240: Output Parameters:
241: . f - the newly evaluated function
242: */
243: PetscErrorCode FormFunction(Tao tao, Vec X, PetscReal *f, void *ptr)
244: {
245: AppCtx *user = (AppCtx *)ptr;
246: PetscReal hx = user->hx, hy = user->hy, area, three = 3.0, p5 = 0.5;
247: PetscReal zero = 0.0, vb, vl, vr, vt, dvdx, dvdy, flin = 0.0, fquad = 0.0;
248: PetscReal v, cdiv3 = user->param / three;
249: const PetscScalar *x;
250: PetscInt nx = user->mx, ny = user->my, i, j, k;
252: PetscFunctionBeginUser;
253: /* Get pointer to vector data */
254: PetscCall(VecGetArrayRead(X, &x));
256: /* Compute function contributions over the lower triangular elements */
257: for (j = -1; j < ny; j++) {
258: for (i = -1; i < nx; i++) {
259: k = nx * j + i;
260: v = zero;
261: vr = zero;
262: vt = zero;
263: if (i >= 0 && j >= 0) v = x[k];
264: if (i < nx - 1 && j > -1) vr = x[k + 1];
265: if (i > -1 && j < ny - 1) vt = x[k + nx];
266: dvdx = (vr - v) / hx;
267: dvdy = (vt - v) / hy;
268: fquad += dvdx * dvdx + dvdy * dvdy;
269: flin -= cdiv3 * (v + vr + vt);
270: }
271: }
273: /* Compute function contributions over the upper triangular elements */
274: for (j = 0; j <= ny; j++) {
275: for (i = 0; i <= nx; i++) {
276: k = nx * j + i;
277: vb = zero;
278: vl = zero;
279: v = zero;
280: if (i < nx && j > 0) vb = x[k - nx];
281: if (i > 0 && j < ny) vl = x[k - 1];
282: if (i < nx && j < ny) v = x[k];
283: dvdx = (v - vl) / hx;
284: dvdy = (v - vb) / hy;
285: fquad = fquad + dvdx * dvdx + dvdy * dvdy;
286: flin = flin - cdiv3 * (vb + vl + v);
287: }
288: }
290: /* Restore vector */
291: PetscCall(VecRestoreArrayRead(X, &x));
293: /* Scale the function */
294: area = p5 * hx * hy;
295: *f = area * (p5 * fquad + flin);
297: PetscCall(PetscLogFlops(24.0 * nx * ny));
298: PetscFunctionReturn(PETSC_SUCCESS);
299: }
301: /* ------------------------------------------------------------------- */
302: /*
303: FormGradient - Evaluates the gradient, G(X).
305: Input Parameters:
306: . tao - the Tao context
307: . X - input vector
308: . ptr - optional user-defined context
310: Output Parameters:
311: . G - vector containing the newly evaluated gradient
312: */
313: PetscErrorCode FormGradient(Tao tao, Vec X, Vec G, void *ptr)
314: {
315: AppCtx *user = (AppCtx *)ptr;
316: PetscReal zero = 0.0, p5 = 0.5, three = 3.0, area, val;
317: PetscInt nx = user->mx, ny = user->my, ind, i, j, k;
318: PetscReal hx = user->hx, hy = user->hy;
319: PetscReal vb, vl, vr, vt, dvdx, dvdy;
320: PetscReal v, cdiv3 = user->param / three;
321: const PetscScalar *x;
323: PetscFunctionBeginUser;
324: /* Initialize gradient to zero */
325: PetscCall(VecSet(G, zero));
327: /* Get pointer to vector data */
328: PetscCall(VecGetArrayRead(X, &x));
330: /* Compute gradient contributions over the lower triangular elements */
331: for (j = -1; j < ny; j++) {
332: for (i = -1; i < nx; i++) {
333: k = nx * j + i;
334: v = zero;
335: vr = zero;
336: vt = zero;
337: if (i >= 0 && j >= 0) v = x[k];
338: if (i < nx - 1 && j > -1) vr = x[k + 1];
339: if (i > -1 && j < ny - 1) vt = x[k + nx];
340: dvdx = (vr - v) / hx;
341: dvdy = (vt - v) / hy;
342: if (i != -1 && j != -1) {
343: ind = k;
344: val = -dvdx / hx - dvdy / hy - cdiv3;
345: PetscCall(VecSetValues(G, 1, &ind, &val, ADD_VALUES));
346: }
347: if (i != nx - 1 && j != -1) {
348: ind = k + 1;
349: val = dvdx / hx - cdiv3;
350: PetscCall(VecSetValues(G, 1, &ind, &val, ADD_VALUES));
351: }
352: if (i != -1 && j != ny - 1) {
353: ind = k + nx;
354: val = dvdy / hy - cdiv3;
355: PetscCall(VecSetValues(G, 1, &ind, &val, ADD_VALUES));
356: }
357: }
358: }
360: /* Compute gradient contributions over the upper triangular elements */
361: for (j = 0; j <= ny; j++) {
362: for (i = 0; i <= nx; i++) {
363: k = nx * j + i;
364: vb = zero;
365: vl = zero;
366: v = zero;
367: if (i < nx && j > 0) vb = x[k - nx];
368: if (i > 0 && j < ny) vl = x[k - 1];
369: if (i < nx && j < ny) v = x[k];
370: dvdx = (v - vl) / hx;
371: dvdy = (v - vb) / hy;
372: if (i != nx && j != 0) {
373: ind = k - nx;
374: val = -dvdy / hy - cdiv3;
375: PetscCall(VecSetValues(G, 1, &ind, &val, ADD_VALUES));
376: }
377: if (i != 0 && j != ny) {
378: ind = k - 1;
379: val = -dvdx / hx - cdiv3;
380: PetscCall(VecSetValues(G, 1, &ind, &val, ADD_VALUES));
381: }
382: if (i != nx && j != ny) {
383: ind = k;
384: val = dvdx / hx + dvdy / hy - cdiv3;
385: PetscCall(VecSetValues(G, 1, &ind, &val, ADD_VALUES));
386: }
387: }
388: }
389: PetscCall(VecRestoreArrayRead(X, &x));
391: /* Assemble gradient vector */
392: PetscCall(VecAssemblyBegin(G));
393: PetscCall(VecAssemblyEnd(G));
395: /* Scale the gradient */
396: area = p5 * hx * hy;
397: PetscCall(VecScale(G, area));
398: PetscCall(PetscLogFlops(24.0 * nx * ny));
399: PetscFunctionReturn(PETSC_SUCCESS);
400: }
402: /* ------------------------------------------------------------------- */
403: /*
404: FormHessian - Forms the Hessian matrix.
406: Input Parameters:
407: . tao - the Tao context
408: . X - the input vector
409: . ptr - optional user-defined context, as set by TaoSetHessian()
411: Output Parameters:
412: . H - Hessian matrix
413: . PrecH - optionally different preconditioning Hessian
415: Notes:
416: This routine is intended simply as an example of the interface
417: to a Hessian evaluation routine. Since this example compute the
418: Hessian a column at a time, it is not particularly efficient and
419: is not recommended.
420: */
421: PetscErrorCode FormHessian(Tao tao, Vec X, Mat H, Mat Hpre, void *ptr)
422: {
423: AppCtx *user = (AppCtx *)ptr;
424: PetscInt i, j, ndim = user->ndim;
425: PetscReal *y, zero = 0.0, one = 1.0;
426: PetscBool assembled;
428: PetscFunctionBeginUser;
429: user->xvec = X;
431: /* Initialize Hessian entries and work vector to zero */
432: PetscCall(MatAssembled(H, &assembled));
433: if (assembled) PetscCall(MatZeroEntries(H));
435: PetscCall(VecSet(user->s, zero));
437: /* Loop over matrix columns to compute entries of the Hessian */
438: for (j = 0; j < ndim; j++) {
439: PetscCall(VecSetValues(user->s, 1, &j, &one, INSERT_VALUES));
440: PetscCall(VecAssemblyBegin(user->s));
441: PetscCall(VecAssemblyEnd(user->s));
443: PetscCall(HessianProduct(ptr, user->s, user->y));
445: PetscCall(VecSetValues(user->s, 1, &j, &zero, INSERT_VALUES));
446: PetscCall(VecAssemblyBegin(user->s));
447: PetscCall(VecAssemblyEnd(user->s));
449: PetscCall(VecGetArray(user->y, &y));
450: for (i = 0; i < ndim; i++) {
451: if (y[i] != zero) PetscCall(MatSetValues(H, 1, &i, 1, &j, &y[i], ADD_VALUES));
452: }
453: PetscCall(VecRestoreArray(user->y, &y));
454: }
455: PetscCall(MatAssemblyBegin(H, MAT_FINAL_ASSEMBLY));
456: PetscCall(MatAssemblyEnd(H, MAT_FINAL_ASSEMBLY));
457: PetscFunctionReturn(PETSC_SUCCESS);
458: }
460: /* ------------------------------------------------------------------- */
461: /*
462: MatrixFreeHessian - Sets a pointer for use in computing Hessian-vector
463: products.
465: Input Parameters:
466: . tao - the Tao context
467: . X - the input vector
468: . ptr - optional user-defined context, as set by TaoSetHessian()
470: Output Parameters:
471: . H - Hessian matrix
472: . PrecH - optionally different preconditioning Hessian
473: */
474: PetscErrorCode MatrixFreeHessian(Tao tao, Vec X, Mat H, Mat PrecH, void *ptr)
475: {
476: AppCtx *user = (AppCtx *)ptr;
478: /* Sets location of vector for use in computing matrix-vector products of the form H(X)*y */
479: PetscFunctionBeginUser;
480: user->xvec = X;
481: PetscFunctionReturn(PETSC_SUCCESS);
482: }
484: /* ------------------------------------------------------------------- */
485: /*
486: HessianProductMat - Computes the matrix-vector product
487: y = mat*svec.
489: Input Parameters:
490: . mat - input matrix
491: . svec - input vector
493: Output Parameters:
494: . y - solution vector
495: */
496: PetscErrorCode HessianProductMat(Mat mat, Vec svec, Vec y)
497: {
498: void *ptr;
500: PetscFunctionBeginUser;
501: PetscCall(MatShellGetContext(mat, &ptr));
502: PetscCall(HessianProduct(ptr, svec, y));
503: PetscFunctionReturn(PETSC_SUCCESS);
504: }
506: /* ------------------------------------------------------------------- */
507: /*
508: Hessian Product - Computes the matrix-vector product:
509: y = f''(x)*svec.
511: Input Parameters:
512: . ptr - pointer to the user-defined context
513: . svec - input vector
515: Output Parameters:
516: . y - product vector
517: */
518: PetscErrorCode HessianProduct(void *ptr, Vec svec, Vec y)
519: {
520: AppCtx *user = (AppCtx *)ptr;
521: PetscReal p5 = 0.5, zero = 0.0, one = 1.0, hx, hy, val, area;
522: const PetscScalar *x, *s;
523: PetscReal v, vb, vl, vr, vt, hxhx, hyhy;
524: PetscInt nx, ny, i, j, k, ind;
526: PetscFunctionBeginUser;
527: nx = user->mx;
528: ny = user->my;
529: hx = user->hx;
530: hy = user->hy;
531: hxhx = one / (hx * hx);
532: hyhy = one / (hy * hy);
534: /* Get pointers to vector data */
535: PetscCall(VecGetArrayRead(user->xvec, &x));
536: PetscCall(VecGetArrayRead(svec, &s));
538: /* Initialize product vector to zero */
539: PetscCall(VecSet(y, zero));
541: /* Compute f''(x)*s over the lower triangular elements */
542: for (j = -1; j < ny; j++) {
543: for (i = -1; i < nx; i++) {
544: k = nx * j + i;
545: v = zero;
546: vr = zero;
547: vt = zero;
548: if (i != -1 && j != -1) v = s[k];
549: if (i != nx - 1 && j != -1) {
550: vr = s[k + 1];
551: ind = k + 1;
552: val = hxhx * (vr - v);
553: PetscCall(VecSetValues(y, 1, &ind, &val, ADD_VALUES));
554: }
555: if (i != -1 && j != ny - 1) {
556: vt = s[k + nx];
557: ind = k + nx;
558: val = hyhy * (vt - v);
559: PetscCall(VecSetValues(y, 1, &ind, &val, ADD_VALUES));
560: }
561: if (i != -1 && j != -1) {
562: ind = k;
563: val = hxhx * (v - vr) + hyhy * (v - vt);
564: PetscCall(VecSetValues(y, 1, &ind, &val, ADD_VALUES));
565: }
566: }
567: }
569: /* Compute f''(x)*s over the upper triangular elements */
570: for (j = 0; j <= ny; j++) {
571: for (i = 0; i <= nx; i++) {
572: k = nx * j + i;
573: v = zero;
574: vl = zero;
575: vb = zero;
576: if (i != nx && j != ny) v = s[k];
577: if (i != nx && j != 0) {
578: vb = s[k - nx];
579: ind = k - nx;
580: val = hyhy * (vb - v);
581: PetscCall(VecSetValues(y, 1, &ind, &val, ADD_VALUES));
582: }
583: if (i != 0 && j != ny) {
584: vl = s[k - 1];
585: ind = k - 1;
586: val = hxhx * (vl - v);
587: PetscCall(VecSetValues(y, 1, &ind, &val, ADD_VALUES));
588: }
589: if (i != nx && j != ny) {
590: ind = k;
591: val = hxhx * (v - vl) + hyhy * (v - vb);
592: PetscCall(VecSetValues(y, 1, &ind, &val, ADD_VALUES));
593: }
594: }
595: }
596: /* Restore vector data */
597: PetscCall(VecRestoreArrayRead(svec, &s));
598: PetscCall(VecRestoreArrayRead(user->xvec, &x));
600: /* Assemble vector */
601: PetscCall(VecAssemblyBegin(y));
602: PetscCall(VecAssemblyEnd(y));
604: /* Scale resulting vector by area */
605: area = p5 * hx * hy;
606: PetscCall(VecScale(y, area));
607: PetscCall(PetscLogFlops(18.0 * nx * ny));
608: PetscFunctionReturn(PETSC_SUCCESS);
609: }
611: /*TEST
613: build:
614: requires: !complex
616: test:
617: suffix: 1
618: args: -tao_monitor -tao_type ntl -tao_gatol 1.e-4
620: test:
621: suffix: 2
622: args: -tao_monitor -tao_type ntr -tao_gatol 1.e-4
624: test:
625: suffix: 3
626: args: -tao_monitor -tao_type bntr -tao_gatol 1.e-4 -my_tao_mf -tao_test_hessian
628: test:
629: suffix: 4
630: args: -tao_monitor -tao_gatol 1e-3 -tao_type bqnls
632: test:
633: suffix: 5
634: args: -tao_monitor -tao_gatol 1e-3 -tao_type blmvm
636: test:
637: suffix: 6
638: args: -tao_monitor -tao_gatol 1e-3 -tao_type bqnktr -tao_bqnk_mat_type lmvmsr1
640: test:
641: suffix: snes
642: args: -snes_monitor ::ascii_info_detail -tao_type snes -snes_type newtontr -ksp_type cg -snes_atol 1.e-4 -tao_mf_hessian {{0 1}} -pc_type none
644: test:
645: suffix: snes_2
646: args: -snes_monitor ::ascii_info_detail -tao_type snes -snes_type newtontr -snes_atol 5.e-4 -tao_mf_hessian -pc_type none -snes_tr_fallback_type cauchy
648: test:
649: suffix: snes_3
650: args: -snes_monitor ::ascii_info_detail -tao_type snes -snes_type newtontr -snes_atol 5.e-4 -tao_mf_hessian -pc_type lmvm -snes_tr_fallback_type cauchy
652: TEST*/