xref: /petsc/src/tao/constrained/tutorials/ex1.c (revision 4e8208cbcbc709572b8abe32f33c78b69c819375) !
1aad13602SShrirang Abhyankar /* Program usage: mpiexec -n 2 ./ex1 [-help] [all TAO options] */
2aad13602SShrirang Abhyankar 
3aad13602SShrirang Abhyankar /* ----------------------------------------------------------------------
4628da978Sresundermann min f(x) = (x0 - 2)^2 + (x1 - 2)^2 - 2*(x0 + x1)
5aad13602SShrirang Abhyankar s.t.  x0^2 + x1 - 2 = 0
6aad13602SShrirang Abhyankar       0  <= x0^2 - x1 <= 1
7aad13602SShrirang Abhyankar       -1 <= x0, x1 <= 2
8628da978Sresundermann -->
9628da978Sresundermann       g(x)  = 0
10628da978Sresundermann       h(x) >= 0
11628da978Sresundermann       -1 <= x0, x1 <= 2
12628da978Sresundermann where
13628da978Sresundermann       g(x) = x0^2 + x1 - 2
14628da978Sresundermann       h(x) = [x0^2 - x1
15628da978Sresundermann               1 -(x0^2 - x1)]
16aad13602SShrirang Abhyankar ---------------------------------------------------------------------- */
17aad13602SShrirang Abhyankar 
18aad13602SShrirang Abhyankar #include <petsctao.h>
19aad13602SShrirang Abhyankar 
20da81f932SPierre Jolivet static char help[] = "Solves constrained optimization problem using pdipm.\n\
21aad13602SShrirang Abhyankar Input parameters include:\n\
22aad13602SShrirang Abhyankar   -tao_type pdipm    : sets Tao solver\n\
238e58fa1dSresundermann   -no_eq             : removes the equaility constraints from the problem\n\
24c8b0c2b5SHansol Suh   -no_bound          : removes the bound constraints from the problem\n\
25f560b561SHong Zhang   -init_view         : view initial object setup\n\
26aad13602SShrirang Abhyankar   -snes_fd           : snes with finite difference Jacobian (needed for pdipm)\n\
27628da978Sresundermann   -snes_compare_explicit : compare user Jacobian with finite difference Jacobian \n\
2810978b7dSBarry Smith   -tao_monitor_constraint_norm : convergence monitor with constraint norm \n\
2910978b7dSBarry Smith   -tao_monitor_solution : view exact solution at each iteration\n\
30f560b561SHong Zhang   Note: external package MUMPS is required to run pdipm in parallel. This is designed for a maximum of 2 processors, the code will error if size > 2.\n";
31aad13602SShrirang Abhyankar 
32aad13602SShrirang Abhyankar /*
33628da978Sresundermann    User-defined application context - contains data needed by the application
34aad13602SShrirang Abhyankar */
35aad13602SShrirang Abhyankar typedef struct {
36aad13602SShrirang Abhyankar   PetscInt   n;  /* Global length of x */
37aad13602SShrirang Abhyankar   PetscInt   ne; /* Global number of equality constraints */
38aad13602SShrirang Abhyankar   PetscInt   ni; /* Global number of inequality constraints */
39c8b0c2b5SHansol Suh   PetscBool  noeqflag, noboundflag, initview;
40aad13602SShrirang Abhyankar   Vec        x, xl, xu;
41aad13602SShrirang Abhyankar   Vec        ce, ci, bl, bu, Xseq;
42aad13602SShrirang Abhyankar   Mat        Ae, Ai, H;
43aad13602SShrirang Abhyankar   VecScatter scat;
44aad13602SShrirang Abhyankar } AppCtx;
45aad13602SShrirang Abhyankar 
46aad13602SShrirang Abhyankar /* -------- User-defined Routines --------- */
47aad13602SShrirang Abhyankar PetscErrorCode InitializeProblem(AppCtx *);
48aad13602SShrirang Abhyankar PetscErrorCode DestroyProblem(AppCtx *);
49aad13602SShrirang Abhyankar PetscErrorCode FormFunctionGradient(Tao, Vec, PetscReal *, Vec, void *);
5083f04556SHong Zhang PetscErrorCode FormPDIPMHessian(Tao, Vec, Mat, Mat, void *);
51aad13602SShrirang Abhyankar PetscErrorCode FormInequalityConstraints(Tao, Vec, Vec, void *);
52aad13602SShrirang Abhyankar PetscErrorCode FormEqualityConstraints(Tao, Vec, Vec, void *);
53aad13602SShrirang Abhyankar PetscErrorCode FormInequalityJacobian(Tao, Vec, Mat, Mat, void *);
54aad13602SShrirang Abhyankar PetscErrorCode FormEqualityJacobian(Tao, Vec, Mat, Mat, void *);
55aad13602SShrirang Abhyankar 
main(int argc,char ** argv)563ba16761SJacob Faibussowitsch int main(int argc, char **argv)
57d71ae5a4SJacob Faibussowitsch {
58aad13602SShrirang Abhyankar   Tao         tao;
59aad13602SShrirang Abhyankar   KSP         ksp;
60aad13602SShrirang Abhyankar   PC          pc;
61aad13602SShrirang Abhyankar   AppCtx      user; /* application context */
62f560b561SHong Zhang   Vec         x, G, CI, CE;
63f560b561SHong Zhang   PetscMPIInt size;
64f560b561SHong Zhang   PetscReal   f;
65ab76df0cSBarry Smith   PetscBool   pdipm;
66aad13602SShrirang Abhyankar 
67327415f7SBarry Smith   PetscFunctionBeginUser;
68c8025a54SPierre Jolivet   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
699566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
70ab76df0cSBarry Smith   PetscCheck(size <= 2, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "More than 2 processes detected. Example written to use at most 2 processes.");
71aad13602SShrirang Abhyankar 
729566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "---- Constrained Problem -----\n"));
739566063dSJacob Faibussowitsch   PetscCall(InitializeProblem(&user)); /* sets up problem, function below */
749a09327dSAlp Dener 
759566063dSJacob Faibussowitsch   PetscCall(TaoCreate(PETSC_COMM_WORLD, &tao));
769a09327dSAlp Dener   PetscCall(TaoSetType(tao, TAOALMM));
779a09327dSAlp Dener   PetscCall(TaoSetSolution(tao, user.x));
78c8b0c2b5SHansol Suh   if (!user.noboundflag) PetscCall(TaoSetVariableBounds(tao, user.xl, user.xu));
799566063dSJacob Faibussowitsch   PetscCall(TaoSetObjectiveAndGradient(tao, NULL, FormFunctionGradient, (void *)&user));
809a09327dSAlp Dener   PetscCall(TaoSetTolerances(tao, 1.e-4, 0.0, 0.0));
819a09327dSAlp Dener   PetscCall(TaoSetConstraintTolerances(tao, 1.e-4, 0.0));
829a09327dSAlp Dener   PetscCall(TaoSetMaximumFunctionEvaluations(tao, 1e6));
839566063dSJacob Faibussowitsch   PetscCall(TaoSetFromOptions(tao));
849a09327dSAlp Dener 
859a09327dSAlp Dener   if (!user.noeqflag) {
869a09327dSAlp Dener     PetscCall(TaoSetEqualityConstraintsRoutine(tao, user.ce, FormEqualityConstraints, (void *)&user));
879a09327dSAlp Dener     PetscCall(TaoSetJacobianEqualityRoutine(tao, user.Ae, user.Ae, FormEqualityJacobian, (void *)&user));
889a09327dSAlp Dener   }
899a09327dSAlp Dener   PetscCall(TaoSetInequalityConstraintsRoutine(tao, user.ci, FormInequalityConstraints, (void *)&user));
909a09327dSAlp Dener   PetscCall(TaoSetJacobianInequalityRoutine(tao, user.Ai, user.Ai, FormInequalityJacobian, (void *)&user));
919a09327dSAlp Dener 
929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)tao, TAOPDIPM, &pdipm));
93661095bbSAlp Dener   if (pdipm) {
949a09327dSAlp Dener     /*
959a09327dSAlp Dener       PDIPM produces an indefinite KKT matrix with some zeros along the diagonal
969a09327dSAlp Dener       Inverting this indefinite matrix requires PETSc to be configured with MUMPS
979a09327dSAlp Dener     */
98ab76df0cSBarry Smith     PetscCheck(PetscDefined(HAVE_MUMPS), PetscObjectComm((PetscObject)tao), PETSC_ERR_SUP, "TAOPDIPM requires PETSc to be configured with MUMPS (--download-mumps)");
999a09327dSAlp Dener     PetscCall(TaoGetKSP(tao, &ksp));
1009a09327dSAlp Dener     PetscCall(KSPGetPC(ksp, &pc));
1019a09327dSAlp Dener     PetscCall(PCFactorSetMatSolverType(pc, MATSOLVERMUMPS));
1029a09327dSAlp Dener     PetscCall(KSPSetType(ksp, KSPPREONLY));
10383f04556SHong Zhang     PetscCall(PCSetType(pc, PCCHOLESKY));
1049a09327dSAlp Dener     PetscCall(KSPSetFromOptions(ksp));
10583f04556SHong Zhang     PetscCall(TaoSetHessian(tao, user.H, user.H, FormPDIPMHessian, (void *)&user));
1069a09327dSAlp Dener   }
1079a09327dSAlp Dener 
1089a09327dSAlp Dener   /* Print out an initial view of the problem */
109f560b561SHong Zhang   if (user.initview) {
1109566063dSJacob Faibussowitsch     PetscCall(TaoSetUp(tao));
1119566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(user.x, &G));
1129566063dSJacob Faibussowitsch     PetscCall(FormFunctionGradient(tao, user.x, &f, G, (void *)&user));
113c8b0c2b5SHansol Suh     if (pdipm) PetscCall(FormPDIPMHessian(tao, user.x, user.H, user.H, (void *)&user));
1149566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_WORLD));
11563a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\nInitial point X:\n"));
1169566063dSJacob Faibussowitsch     PetscCall(VecView(user.x, PETSC_VIEWER_STDOUT_WORLD));
11763a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\nInitial objective f(x) = %g\n", (double)f));
11863a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\nInitial gradient and Hessian:\n"));
1199566063dSJacob Faibussowitsch     PetscCall(VecView(G, PETSC_VIEWER_STDOUT_WORLD));
120c8b0c2b5SHansol Suh     if (pdipm) PetscCall(MatView(user.H, PETSC_VIEWER_STDOUT_WORLD));
1219566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&G));
1229566063dSJacob Faibussowitsch     PetscCall(FormInequalityJacobian(tao, user.x, user.Ai, user.Ai, (void *)&user));
1239566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(user.Ai, NULL, &CI));
1249566063dSJacob Faibussowitsch     PetscCall(FormInequalityConstraints(tao, user.x, CI, (void *)&user));
12563a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\nInitial inequality constraints and Jacobian:\n"));
1269566063dSJacob Faibussowitsch     PetscCall(VecView(CI, PETSC_VIEWER_STDOUT_WORLD));
1279566063dSJacob Faibussowitsch     PetscCall(MatView(user.Ai, PETSC_VIEWER_STDOUT_WORLD));
1289566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&CI));
129f560b561SHong Zhang     if (!user.noeqflag) {
1309566063dSJacob Faibussowitsch       PetscCall(FormEqualityJacobian(tao, user.x, user.Ae, user.Ae, (void *)&user));
1319566063dSJacob Faibussowitsch       PetscCall(MatCreateVecs(user.Ae, NULL, &CE));
1329566063dSJacob Faibussowitsch       PetscCall(FormEqualityConstraints(tao, user.x, CE, (void *)&user));
13363a3b9bcSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\nInitial equality constraints and Jacobian:\n"));
1349566063dSJacob Faibussowitsch       PetscCall(VecView(CE, PETSC_VIEWER_STDOUT_WORLD));
1359566063dSJacob Faibussowitsch       PetscCall(MatView(user.Ae, PETSC_VIEWER_STDOUT_WORLD));
1369566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&CE));
137f560b561SHong Zhang     }
1389566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\n"));
1399566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_WORLD));
140f560b561SHong Zhang   }
141aad13602SShrirang Abhyankar 
1429566063dSJacob Faibussowitsch   PetscCall(TaoSolve(tao));
1439566063dSJacob Faibussowitsch   PetscCall(TaoGetSolution(tao, &x));
1449a09327dSAlp Dener   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Found solution:\n"));
1459566063dSJacob Faibussowitsch   PetscCall(VecView(x, PETSC_VIEWER_STDOUT_WORLD));
146aad13602SShrirang Abhyankar 
147aad13602SShrirang Abhyankar   /* Free objects */
1489566063dSJacob Faibussowitsch   PetscCall(DestroyProblem(&user));
1499566063dSJacob Faibussowitsch   PetscCall(TaoDestroy(&tao));
1509566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
1513ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
152aad13602SShrirang Abhyankar }
153aad13602SShrirang Abhyankar 
InitializeProblem(AppCtx * user)154d71ae5a4SJacob Faibussowitsch PetscErrorCode InitializeProblem(AppCtx *user)
155d71ae5a4SJacob Faibussowitsch {
156aad13602SShrirang Abhyankar   PetscMPIInt size;
157aad13602SShrirang Abhyankar   PetscMPIInt rank;
158aad13602SShrirang Abhyankar   PetscInt    nloc, neloc, niloc;
159aad13602SShrirang Abhyankar 
160aad13602SShrirang Abhyankar   PetscFunctionBegin;
1619566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
1629566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
1638e58fa1dSresundermann   user->noeqflag    = PETSC_FALSE;
164c8b0c2b5SHansol Suh   user->noboundflag = PETSC_FALSE;
1659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-no_eq", &user->noeqflag, NULL));
166c8b0c2b5SHansol Suh   PetscCall(PetscOptionsGetBool(NULL, NULL, "-no_bound", &user->noboundflag, NULL));
167f560b561SHong Zhang   user->initview = PETSC_FALSE;
1689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-init_view", &user->initview, NULL));
169628da978Sresundermann 
170f560b561SHong Zhang   /* Tell user the correct solution, not an error checking */
1719a09327dSAlp Dener   if (!user->noeqflag) {
172c8b0c2b5SHansol Suh     /* With equality constraint, bound or no bound makes no different to the solution */
1739a09327dSAlp Dener     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Expected solution: f(1, 1) = -2\n"));
1749a09327dSAlp Dener   } else {
175c8b0c2b5SHansol Suh     if (user->noboundflag) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Expected solution (-no_eq, -no_bound): f(2.05655, 3.22938) = -9.05728\n"));
176c8b0c2b5SHansol Suh     else PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Expected solution (-no_eq): f(1.73205, 2) = -7.3923\n"));
1778e58fa1dSresundermann   }
178aad13602SShrirang Abhyankar 
1792d4ee042Sprj-   /* create vector x and set initial values */
180aad13602SShrirang Abhyankar   user->n = 2; /* global length */
181f560b561SHong Zhang   nloc    = (size == 1) ? user->n : 1;
1829566063dSJacob Faibussowitsch   PetscCall(VecCreate(PETSC_COMM_WORLD, &user->x));
1839566063dSJacob Faibussowitsch   PetscCall(VecSetSizes(user->x, nloc, user->n));
1849566063dSJacob Faibussowitsch   PetscCall(VecSetFromOptions(user->x));
1859a09327dSAlp Dener   PetscCall(VecSet(user->x, 0.0));
186aad13602SShrirang Abhyankar 
187aad13602SShrirang Abhyankar   /* create and set lower and upper bound vectors */
1889566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(user->x, &user->xl));
1899566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(user->x, &user->xu));
1909566063dSJacob Faibussowitsch   PetscCall(VecSet(user->xl, -1.0));
1919566063dSJacob Faibussowitsch   PetscCall(VecSet(user->xu, 2.0));
192aad13602SShrirang Abhyankar 
193aad13602SShrirang Abhyankar   /* create scater to zero */
1949566063dSJacob Faibussowitsch   PetscCall(VecScatterCreateToZero(user->x, &user->scat, &user->Xseq));
195aad13602SShrirang Abhyankar 
196aad13602SShrirang Abhyankar   user->ne = 1;
197628da978Sresundermann   user->ni = 2;
198aad13602SShrirang Abhyankar   neloc    = (rank == 0) ? user->ne : 0;
199f560b561SHong Zhang   niloc    = (size == 1) ? user->ni : 1;
200aad13602SShrirang Abhyankar 
2018e58fa1dSresundermann   if (!user->noeqflag) {
2029566063dSJacob Faibussowitsch     PetscCall(VecCreate(PETSC_COMM_WORLD, &user->ce)); /* a 1x1 vec for equality constraints */
2039566063dSJacob Faibussowitsch     PetscCall(VecSetSizes(user->ce, neloc, user->ne));
2049566063dSJacob Faibussowitsch     PetscCall(VecSetFromOptions(user->ce));
2059566063dSJacob Faibussowitsch     PetscCall(VecSetUp(user->ce));
2068e58fa1dSresundermann   }
207628da978Sresundermann 
2089566063dSJacob Faibussowitsch   PetscCall(VecCreate(PETSC_COMM_WORLD, &user->ci)); /* a 2x1 vec for inequality constraints */
2099566063dSJacob Faibussowitsch   PetscCall(VecSetSizes(user->ci, niloc, user->ni));
2109566063dSJacob Faibussowitsch   PetscCall(VecSetFromOptions(user->ci));
2119566063dSJacob Faibussowitsch   PetscCall(VecSetUp(user->ci));
212aad13602SShrirang Abhyankar 
213baca6076SPierre Jolivet   /* nexn & nixn matrices for equally and inequalty constraints */
2148e58fa1dSresundermann   if (!user->noeqflag) {
2159566063dSJacob Faibussowitsch     PetscCall(MatCreate(PETSC_COMM_WORLD, &user->Ae));
2169566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(user->Ae, neloc, nloc, user->ne, user->n));
2179566063dSJacob Faibussowitsch     PetscCall(MatSetFromOptions(user->Ae));
2189566063dSJacob Faibussowitsch     PetscCall(MatSetUp(user->Ae));
2198e58fa1dSresundermann   }
2208e58fa1dSresundermann 
2219566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_WORLD, &user->Ai));
2229566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(user->Ai, niloc, nloc, user->ni, user->n));
2239566063dSJacob Faibussowitsch   PetscCall(MatSetFromOptions(user->Ai));
2249566063dSJacob Faibussowitsch   PetscCall(MatSetUp(user->Ai));
225628da978Sresundermann 
2269566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_WORLD, &user->H));
2279566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(user->H, nloc, nloc, user->n, user->n));
2289566063dSJacob Faibussowitsch   PetscCall(MatSetFromOptions(user->H));
2299566063dSJacob Faibussowitsch   PetscCall(MatSetUp(user->H));
2303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
231aad13602SShrirang Abhyankar }
232aad13602SShrirang Abhyankar 
DestroyProblem(AppCtx * user)233d71ae5a4SJacob Faibussowitsch PetscErrorCode DestroyProblem(AppCtx *user)
234d71ae5a4SJacob Faibussowitsch {
235aad13602SShrirang Abhyankar   PetscFunctionBegin;
23648a46eb9SPierre Jolivet   if (!user->noeqflag) PetscCall(MatDestroy(&user->Ae));
2379566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&user->Ai));
2389566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&user->H));
239aad13602SShrirang Abhyankar 
2409566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&user->x));
24148a46eb9SPierre Jolivet   if (!user->noeqflag) PetscCall(VecDestroy(&user->ce));
2429566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&user->ci));
2439566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&user->xl));
2449566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&user->xu));
2459566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&user->Xseq));
2469566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&user->scat));
2473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
248aad13602SShrirang Abhyankar }
249aad13602SShrirang Abhyankar 
250628da978Sresundermann /* Evaluate
251628da978Sresundermann    f(x) = (x0 - 2)^2 + (x1 - 2)^2 - 2*(x0 + x1)
25283f04556SHong Zhang    G = grad f = [2*(x0 - 2) - 2, 2*(x1 - 2) - 2] = 2*X - 6
253aad13602SShrirang Abhyankar */
FormFunctionGradient(Tao tao,Vec X,PetscReal * f,Vec G,PetscCtx ctx)254*2a8381b2SBarry Smith PetscErrorCode FormFunctionGradient(Tao tao, Vec X, PetscReal *f, Vec G, PetscCtx ctx)
255d71ae5a4SJacob Faibussowitsch {
256aad13602SShrirang Abhyankar   const PetscScalar *x;
257aad13602SShrirang Abhyankar   MPI_Comm           comm;
258aad13602SShrirang Abhyankar   PetscMPIInt        rank;
259aad13602SShrirang Abhyankar   PetscReal          fin;
260aad13602SShrirang Abhyankar   AppCtx            *user = (AppCtx *)ctx;
261aad13602SShrirang Abhyankar   Vec                Xseq = user->Xseq;
262aad13602SShrirang Abhyankar   VecScatter         scat = user->scat;
263aad13602SShrirang Abhyankar 
264aad13602SShrirang Abhyankar   PetscFunctionBegin;
26583f04556SHong Zhang   /* f = (x0 - 2)^2 + (x1 - 2)^2 - 2*(x0 + x1) */
2669566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
2679566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
268aad13602SShrirang Abhyankar 
2699566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(scat, X, Xseq, INSERT_VALUES, SCATTER_FORWARD));
2709566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(scat, X, Xseq, INSERT_VALUES, SCATTER_FORWARD));
271aad13602SShrirang Abhyankar 
272aad13602SShrirang Abhyankar   fin = 0.0;
273dd400576SPatrick Sanan   if (rank == 0) {
2749566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(Xseq, &x));
275aad13602SShrirang Abhyankar     fin = (x[0] - 2.0) * (x[0] - 2.0) + (x[1] - 2.0) * (x[1] - 2.0) - 2.0 * (x[0] + x[1]);
2769566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(Xseq, &x));
277aad13602SShrirang Abhyankar   }
278462c564dSBarry Smith   PetscCallMPI(MPIU_Allreduce(&fin, f, 1, MPIU_REAL, MPIU_SUM, comm));
27983f04556SHong Zhang 
28083f04556SHong Zhang   /* G = 2*X - 6 */
28183f04556SHong Zhang   PetscCall(VecSet(G, -6.0));
28283f04556SHong Zhang   PetscCall(VecAXPY(G, 2.0, X));
2833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
284aad13602SShrirang Abhyankar }
285aad13602SShrirang Abhyankar 
28683f04556SHong Zhang /* Evaluate PDIPM Hessian, see Eqn(22) in http://doi.org/10.1049/gtd2.12708
28783f04556SHong Zhang    H = Wxx = fxx        + Jacobian(grad g^T*DE)   - Jacobian(grad h^T*DI)]
28883f04556SHong Zhang            = fxx        + Jacobin([2*x0; 1]de[0]) - Jacobian([2*x0, -2*x0; -1, 1][di[0] di[1]]^T)
28983f04556SHong Zhang            = [2 0; 0 2] + [2*de[0]  0;      0  0] - [2*di[0]-2*di[1], 0; 0, 0]
290628da978Sresundermann            = [ 2*(1+de[0]-di[0]+di[1]), 0;
291628da978Sresundermann                           0,            2]
292628da978Sresundermann */
FormPDIPMHessian(Tao tao,Vec x,Mat H,Mat Hpre,PetscCtx ctx)293*2a8381b2SBarry Smith PetscErrorCode FormPDIPMHessian(Tao tao, Vec x, Mat H, Mat Hpre, PetscCtx ctx)
294d71ae5a4SJacob Faibussowitsch {
295aad13602SShrirang Abhyankar   AppCtx            *user = (AppCtx *)ctx;
296aad13602SShrirang Abhyankar   Vec                DE, DI;
297aad13602SShrirang Abhyankar   const PetscScalar *de, *di;
298aad13602SShrirang Abhyankar   PetscInt           zero = 0, one = 1;
299aad13602SShrirang Abhyankar   PetscScalar        two = 2.0;
300aad13602SShrirang Abhyankar   PetscScalar        val = 0.0;
301f560b561SHong Zhang   Vec                Deseq, Diseq;
302f560b561SHong Zhang   VecScatter         Descat, Discat;
303aad13602SShrirang Abhyankar   PetscMPIInt        rank;
304aad13602SShrirang Abhyankar   MPI_Comm           comm;
305aad13602SShrirang Abhyankar 
306aad13602SShrirang Abhyankar   PetscFunctionBegin;
3079566063dSJacob Faibussowitsch   PetscCall(TaoGetDualVariables(tao, &DE, &DI));
308aad13602SShrirang Abhyankar 
3099566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
3109566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
311aad13602SShrirang Abhyankar 
3128e58fa1dSresundermann   if (!user->noeqflag) {
3139566063dSJacob Faibussowitsch     PetscCall(VecScatterCreateToZero(DE, &Descat, &Deseq));
3149566063dSJacob Faibussowitsch     PetscCall(VecScatterBegin(Descat, DE, Deseq, INSERT_VALUES, SCATTER_FORWARD));
3159566063dSJacob Faibussowitsch     PetscCall(VecScatterEnd(Descat, DE, Deseq, INSERT_VALUES, SCATTER_FORWARD));
3168e58fa1dSresundermann   }
3179566063dSJacob Faibussowitsch   PetscCall(VecScatterCreateToZero(DI, &Discat, &Diseq));
3189566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(Discat, DI, Diseq, INSERT_VALUES, SCATTER_FORWARD));
3199566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(Discat, DI, Diseq, INSERT_VALUES, SCATTER_FORWARD));
320aad13602SShrirang Abhyankar 
321dd400576SPatrick Sanan   if (rank == 0) {
322ac530a7eSPierre Jolivet     if (!user->noeqflag) PetscCall(VecGetArrayRead(Deseq, &de)); /* places equality constraint dual into array */
3239566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(Diseq, &di));                      /* places inequality constraint dual into array */
324628da978Sresundermann 
3258e58fa1dSresundermann     if (!user->noeqflag) {
326628da978Sresundermann       val = 2.0 * (1 + de[0] - di[0] + di[1]);
3279566063dSJacob Faibussowitsch       PetscCall(VecRestoreArrayRead(Deseq, &de));
3289566063dSJacob Faibussowitsch       PetscCall(VecRestoreArrayRead(Diseq, &di));
3298e58fa1dSresundermann     } else {
330628da978Sresundermann       val = 2.0 * (1 - di[0] + di[1]);
3318e58fa1dSresundermann     }
3329566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(Diseq, &di));
3339566063dSJacob Faibussowitsch     PetscCall(MatSetValues(H, 1, &zero, 1, &zero, &val, INSERT_VALUES));
3349566063dSJacob Faibussowitsch     PetscCall(MatSetValues(H, 1, &one, 1, &one, &two, INSERT_VALUES));
335aad13602SShrirang Abhyankar   }
3369566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(H, MAT_FINAL_ASSEMBLY));
3379566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(H, MAT_FINAL_ASSEMBLY));
3388e58fa1dSresundermann   if (!user->noeqflag) {
3399566063dSJacob Faibussowitsch     PetscCall(VecScatterDestroy(&Descat));
3409566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&Deseq));
3418e58fa1dSresundermann   }
3429566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&Discat));
3439566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Diseq));
3443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
345aad13602SShrirang Abhyankar }
346aad13602SShrirang Abhyankar 
347628da978Sresundermann /* Evaluate
348628da978Sresundermann    h = [ x0^2 - x1;
349628da978Sresundermann          1 -(x0^2 - x1)]
350628da978Sresundermann */
FormInequalityConstraints(Tao tao,Vec X,Vec CI,PetscCtx ctx)351*2a8381b2SBarry Smith PetscErrorCode FormInequalityConstraints(Tao tao, Vec X, Vec CI, PetscCtx ctx)
352d71ae5a4SJacob Faibussowitsch {
353aad13602SShrirang Abhyankar   const PetscScalar *x;
354aad13602SShrirang Abhyankar   PetscScalar        ci;
355aad13602SShrirang Abhyankar   MPI_Comm           comm;
356aad13602SShrirang Abhyankar   PetscMPIInt        rank;
357aad13602SShrirang Abhyankar   AppCtx            *user = (AppCtx *)ctx;
358aad13602SShrirang Abhyankar   Vec                Xseq = user->Xseq;
359aad13602SShrirang Abhyankar   VecScatter         scat = user->scat;
360aad13602SShrirang Abhyankar 
361aad13602SShrirang Abhyankar   PetscFunctionBegin;
3629566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
3639566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
364aad13602SShrirang Abhyankar 
3659566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(scat, X, Xseq, INSERT_VALUES, SCATTER_FORWARD));
3669566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(scat, X, Xseq, INSERT_VALUES, SCATTER_FORWARD));
367aad13602SShrirang Abhyankar 
368dd400576SPatrick Sanan   if (rank == 0) {
3699566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(Xseq, &x));
370aad13602SShrirang Abhyankar     ci = x[0] * x[0] - x[1];
3719566063dSJacob Faibussowitsch     PetscCall(VecSetValue(CI, 0, ci, INSERT_VALUES));
372aad13602SShrirang Abhyankar     ci = -x[0] * x[0] + x[1] + 1.0;
3739566063dSJacob Faibussowitsch     PetscCall(VecSetValue(CI, 1, ci, INSERT_VALUES));
3749566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(Xseq, &x));
375aad13602SShrirang Abhyankar   }
3769566063dSJacob Faibussowitsch   PetscCall(VecAssemblyBegin(CI));
3779566063dSJacob Faibussowitsch   PetscCall(VecAssemblyEnd(CI));
3783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
379aad13602SShrirang Abhyankar }
380aad13602SShrirang Abhyankar 
381628da978Sresundermann /* Evaluate
382628da978Sresundermann    g = [ x0^2 + x1 - 2]
383628da978Sresundermann */
FormEqualityConstraints(Tao tao,Vec X,Vec CE,PetscCtx ctx)384*2a8381b2SBarry Smith PetscErrorCode FormEqualityConstraints(Tao tao, Vec X, Vec CE, PetscCtx ctx)
385d71ae5a4SJacob Faibussowitsch {
386aad13602SShrirang Abhyankar   const PetscScalar *x;
387aad13602SShrirang Abhyankar   PetscScalar        ce;
388aad13602SShrirang Abhyankar   MPI_Comm           comm;
389aad13602SShrirang Abhyankar   PetscMPIInt        rank;
390aad13602SShrirang Abhyankar   AppCtx            *user = (AppCtx *)ctx;
391aad13602SShrirang Abhyankar   Vec                Xseq = user->Xseq;
392aad13602SShrirang Abhyankar   VecScatter         scat = user->scat;
393aad13602SShrirang Abhyankar 
394aad13602SShrirang Abhyankar   PetscFunctionBegin;
3959566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
3969566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
397aad13602SShrirang Abhyankar 
3989566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(scat, X, Xseq, INSERT_VALUES, SCATTER_FORWARD));
3999566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(scat, X, Xseq, INSERT_VALUES, SCATTER_FORWARD));
400aad13602SShrirang Abhyankar 
401dd400576SPatrick Sanan   if (rank == 0) {
4029566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(Xseq, &x));
403aad13602SShrirang Abhyankar     ce = x[0] * x[0] + x[1] - 2.0;
4049566063dSJacob Faibussowitsch     PetscCall(VecSetValue(CE, 0, ce, INSERT_VALUES));
4059566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(Xseq, &x));
406aad13602SShrirang Abhyankar   }
4079566063dSJacob Faibussowitsch   PetscCall(VecAssemblyBegin(CE));
4089566063dSJacob Faibussowitsch   PetscCall(VecAssemblyEnd(CE));
4093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
410aad13602SShrirang Abhyankar }
411aad13602SShrirang Abhyankar 
412628da978Sresundermann /*
413628da978Sresundermann   grad h = [  2*x0, -1;
414628da978Sresundermann              -2*x0,  1]
415628da978Sresundermann */
FormInequalityJacobian(Tao tao,Vec X,Mat JI,Mat JIpre,PetscCtx ctx)416*2a8381b2SBarry Smith PetscErrorCode FormInequalityJacobian(Tao tao, Vec X, Mat JI, Mat JIpre, PetscCtx ctx)
417d71ae5a4SJacob Faibussowitsch {
418aad13602SShrirang Abhyankar   AppCtx            *user = (AppCtx *)ctx;
419f560b561SHong Zhang   PetscInt           zero = 0, one = 1, cols[2];
420aad13602SShrirang Abhyankar   PetscScalar        vals[2];
421aad13602SShrirang Abhyankar   const PetscScalar *x;
422aad13602SShrirang Abhyankar   Vec                Xseq = user->Xseq;
423aad13602SShrirang Abhyankar   VecScatter         scat = user->scat;
424aad13602SShrirang Abhyankar   MPI_Comm           comm;
425aad13602SShrirang Abhyankar   PetscMPIInt        rank;
426aad13602SShrirang Abhyankar 
427aad13602SShrirang Abhyankar   PetscFunctionBegin;
4289566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
4299566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
4309566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(scat, X, Xseq, INSERT_VALUES, SCATTER_FORWARD));
4319566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(scat, X, Xseq, INSERT_VALUES, SCATTER_FORWARD));
432aad13602SShrirang Abhyankar 
4339566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Xseq, &x));
434c5853193SPierre Jolivet   if (rank == 0) {
4359371c9d4SSatish Balay     cols[0] = 0;
4369371c9d4SSatish Balay     cols[1] = 1;
4379371c9d4SSatish Balay     vals[0] = 2 * x[0];
4389371c9d4SSatish Balay     vals[1] = -1.0;
4399566063dSJacob Faibussowitsch     PetscCall(MatSetValues(JI, 1, &zero, 2, cols, vals, INSERT_VALUES));
4409371c9d4SSatish Balay     vals[0] = -2 * x[0];
4419371c9d4SSatish Balay     vals[1] = 1.0;
4429566063dSJacob Faibussowitsch     PetscCall(MatSetValues(JI, 1, &one, 2, cols, vals, INSERT_VALUES));
443aad13602SShrirang Abhyankar   }
4449566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Xseq, &x));
4459566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(JI, MAT_FINAL_ASSEMBLY));
4469566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(JI, MAT_FINAL_ASSEMBLY));
4473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
448aad13602SShrirang Abhyankar }
449aad13602SShrirang Abhyankar 
450628da978Sresundermann /*
45183f04556SHong Zhang   grad g = [2*x0, 1.0]
452628da978Sresundermann */
FormEqualityJacobian(Tao tao,Vec X,Mat JE,Mat JEpre,PetscCtx ctx)453*2a8381b2SBarry Smith PetscErrorCode FormEqualityJacobian(Tao tao, Vec X, Mat JE, Mat JEpre, PetscCtx ctx)
454d71ae5a4SJacob Faibussowitsch {
455f560b561SHong Zhang   PetscInt           zero = 0, cols[2];
456aad13602SShrirang Abhyankar   PetscScalar        vals[2];
457aad13602SShrirang Abhyankar   const PetscScalar *x;
458aad13602SShrirang Abhyankar   PetscMPIInt        rank;
459aad13602SShrirang Abhyankar   MPI_Comm           comm;
460aad13602SShrirang Abhyankar 
461aad13602SShrirang Abhyankar   PetscFunctionBegin;
4629566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
4639566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
464aad13602SShrirang Abhyankar 
465dd400576SPatrick Sanan   if (rank == 0) {
4669566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(X, &x));
4679371c9d4SSatish Balay     cols[0] = 0;
4689371c9d4SSatish Balay     cols[1] = 1;
4699371c9d4SSatish Balay     vals[0] = 2 * x[0];
4709371c9d4SSatish Balay     vals[1] = 1.0;
4719566063dSJacob Faibussowitsch     PetscCall(MatSetValues(JE, 1, &zero, 2, cols, vals, INSERT_VALUES));
4729566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(X, &x));
473aad13602SShrirang Abhyankar   }
4749566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(JE, MAT_FINAL_ASSEMBLY));
4759566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(JE, MAT_FINAL_ASSEMBLY));
4763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
477aad13602SShrirang Abhyankar }
478aad13602SShrirang Abhyankar 
479aad13602SShrirang Abhyankar /*TEST
480aad13602SShrirang Abhyankar 
481aad13602SShrirang Abhyankar    build:
482f560b561SHong Zhang       requires: !complex !defined(PETSC_USE_CXX)
483aad13602SShrirang Abhyankar 
484aad13602SShrirang Abhyankar    test:
4859a09327dSAlp Dener       args: -tao_converged_reason -tao_gatol 1.e-6 -tao_type pdipm -tao_pdipm_kkt_shift_pd
486910b42cbSStefano Zampini       requires: mumps !single
4879a09327dSAlp Dener       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
488aad13602SShrirang Abhyankar 
489aad13602SShrirang Abhyankar    test:
49083f04556SHong Zhang       suffix: pdipm_2
49183f04556SHong Zhang       requires: mumps
49283f04556SHong Zhang       nsize: 2
49383f04556SHong Zhang       args: -tao_converged_reason -tao_gatol 1.e-6 -tao_type pdipm
49483f04556SHong Zhang       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
49583f04556SHong Zhang 
49683f04556SHong Zhang    test:
497aad13602SShrirang Abhyankar       suffix: 2
4989a09327dSAlp Dener       args: -tao_converged_reason
4999a09327dSAlp Dener       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
500aad13602SShrirang Abhyankar 
5018e58fa1dSresundermann    test:
5028e58fa1dSresundermann       suffix: 3
5038e58fa1dSresundermann       args: -tao_converged_reason -no_eq
5049a09327dSAlp Dener       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
5058e58fa1dSresundermann 
5068e58fa1dSresundermann    test:
5078e58fa1dSresundermann       suffix: 4
5089a09327dSAlp Dener       args: -tao_converged_reason -tao_almm_type classic
5099a09327dSAlp Dener       requires: !single
5109a09327dSAlp Dener       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
5118e58fa1dSresundermann 
512661095bbSAlp Dener    test:
513661095bbSAlp Dener       suffix: 5
514c8b0c2b5SHansol Suh       args: -tao_converged_reason -tao_almm_type classic -no_eq
515c8b0c2b5SHansol Suh       requires: !single
5169a09327dSAlp Dener       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
517661095bbSAlp Dener 
518661095bbSAlp Dener    test:
519661095bbSAlp Dener       suffix: 6
5209a09327dSAlp Dener       args: -tao_converged_reason -tao_almm_subsolver_tao_type bqnktr
5219a09327dSAlp Dener       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
522661095bbSAlp Dener 
523661095bbSAlp Dener    test:
524661095bbSAlp Dener       suffix: 7
5259a09327dSAlp Dener       args: -tao_converged_reason -tao_almm_subsolver_tao_type bncg
5269a09327dSAlp Dener       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
527661095bbSAlp Dener 
528661095bbSAlp Dener    test:
529661095bbSAlp Dener       suffix: 8
530661095bbSAlp Dener       nsize: 2
5319a09327dSAlp Dener       args: -tao_converged_reason
5329a09327dSAlp Dener       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
533661095bbSAlp Dener 
534661095bbSAlp Dener    test:
535661095bbSAlp Dener       suffix: 9
536661095bbSAlp Dener       nsize: 2
5379a09327dSAlp Dener       args: -tao_converged_reason -vec_type cuda -mat_type aijcusparse
5389a09327dSAlp Dener       requires: cuda
5399a09327dSAlp Dener       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
540661095bbSAlp Dener 
541c8b0c2b5SHansol Suh    test:
542c8b0c2b5SHansol Suh       suffix: 10
543c8b0c2b5SHansol Suh       args: -tao_converged_reason -tao_almm_type classic -no_eq -no_bound
544c8b0c2b5SHansol Suh       requires: !single
545c8b0c2b5SHansol Suh       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
546c8b0c2b5SHansol Suh 
547c8b0c2b5SHansol Suh    test:
548c8b0c2b5SHansol Suh       suffix: 11
549c8b0c2b5SHansol Suh       args: -tao_converged_reason -tao_almm_type classic -no_bound
550c8b0c2b5SHansol Suh       requires: !single
551c8b0c2b5SHansol Suh       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
552c8b0c2b5SHansol Suh 
553c8b0c2b5SHansol Suh    test:
554c8b0c2b5SHansol Suh       suffix: 12
555c8b0c2b5SHansol Suh       args: -tao_converged_reason -tao_almm_type phr -no_eq -no_bound
556c8b0c2b5SHansol Suh       requires: !single
557c8b0c2b5SHansol Suh       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
558c8b0c2b5SHansol Suh 
559c8b0c2b5SHansol Suh    test:
560c8b0c2b5SHansol Suh       suffix: 13
561c8b0c2b5SHansol Suh       args: -tao_converged_reason -tao_almm_type phr -no_bound
562c8b0c2b5SHansol Suh       requires: !single
563c8b0c2b5SHansol Suh       filter: sed  -e "s/CONVERGED_GATOL iterations *[0-9]\{1,\}/CONVERGED_GATOL/g"
564c8b0c2b5SHansol Suh 
565aad13602SShrirang Abhyankar TEST*/
566