xref: /petsc/src/tao/complementarity/impls/asls/asfls.c (revision 7d3de750dec08ee2edc7d15bcef3046c0443ab7d)
1aaa7dc30SBarry Smith #include <../src/tao/complementarity/impls/ssls/ssls.h>
2a7e14dcfSSatish Balay /*
3a7e14dcfSSatish Balay    Context for ASXLS
4a7e14dcfSSatish Balay      -- active-set      - reduced matrices formed
5a7e14dcfSSatish Balay                           - inherit properties of original system
6a7e14dcfSSatish Balay      -- semismooth (S)  - function not differentiable
7a7e14dcfSSatish Balay                         - merit function continuously differentiable
8a7e14dcfSSatish Balay                         - Fischer-Burmeister reformulation of complementarity
9a7e14dcfSSatish Balay                           - Billups composition for two finite bounds
10a7e14dcfSSatish Balay      -- infeasible (I)  - iterates not guaranteed to remain within bounds
11a7e14dcfSSatish Balay      -- feasible (F)    - iterates guaranteed to remain within bounds
12a7e14dcfSSatish Balay      -- linesearch (LS) - Armijo rule on direction
13a7e14dcfSSatish Balay 
14a7e14dcfSSatish Balay    Many other reformulations are possible and combinations of
15a7e14dcfSSatish Balay    feasible/infeasible and linesearch/trust region are possible.
16a7e14dcfSSatish Balay 
17a7e14dcfSSatish Balay    Basic theory
18a7e14dcfSSatish Balay      Fischer-Burmeister reformulation is semismooth with a continuously
19a7e14dcfSSatish Balay      differentiable merit function and strongly semismooth if the F has
20a7e14dcfSSatish Balay      lipschitz continuous derivatives.
21a7e14dcfSSatish Balay 
22a7e14dcfSSatish Balay      Every accumulation point generated by the algorithm is a stationary
23a7e14dcfSSatish Balay      point for the merit function.  Stationary points of the merit function
24a7e14dcfSSatish Balay      are solutions of the complementarity problem if
25a7e14dcfSSatish Balay        a.  the stationary point has a BD-regular subdifferential, or
26a7e14dcfSSatish Balay        b.  the Schur complement F'/F'_ff is a P_0-matrix where ff is the
27a7e14dcfSSatish Balay            index set corresponding to the free variables.
28a7e14dcfSSatish Balay 
29a7e14dcfSSatish Balay      If one of the accumulation points has a BD-regular subdifferential then
30a7e14dcfSSatish Balay        a.  the entire sequence converges to this accumulation point at
31a7e14dcfSSatish Balay            a local q-superlinear rate
32a7e14dcfSSatish Balay        b.  if in addition the reformulation is strongly semismooth near
33a7e14dcfSSatish Balay            this accumulation point, then the algorithm converges at a
34a7e14dcfSSatish Balay            local q-quadratic rate.
35a7e14dcfSSatish Balay 
36a7e14dcfSSatish Balay    The theory for the feasible version follows from the feasible descent
37a7e14dcfSSatish Balay    algorithm framework.
38a7e14dcfSSatish Balay 
39a7e14dcfSSatish Balay    References:
40a7e14dcfSSatish Balay      Billups, "Algorithms for Complementarity Problems and Generalized
4196a0c994SBarry Smith        Equations," Ph.D thesis, University of Wisconsin  Madison, 1995.
42a7e14dcfSSatish Balay      De Luca, Facchinei, Kanzow, "A Semismooth Equation Approach to the
43a7e14dcfSSatish Balay        Solution of Nonlinear Complementarity Problems," Mathematical
4496a0c994SBarry Smith        Programming, 75, pages 407439, 1996.
45a7e14dcfSSatish Balay      Ferris, Kanzow, Munson, "Feasible Descent Algorithms for Mixed
46a7e14dcfSSatish Balay        Complementarity Problems," Mathematical Programming, 86,
4796a0c994SBarry Smith        pages 475497, 1999.
4896a0c994SBarry Smith      Fischer, "A Special Newton type Optimization Method," Optimization,
4996a0c994SBarry Smith        24, 1992
50a7e14dcfSSatish Balay      Munson, Facchinei, Ferris, Fischer, Kanzow, "The Semismooth Algorithm
5196a0c994SBarry Smith        for Large Scale Complementarity Problems," Technical Report,
5296a0c994SBarry Smith        University of Wisconsin  Madison, 1999.
53a7e14dcfSSatish Balay */
54a7e14dcfSSatish Balay 
55e0877f53SBarry Smith static PetscErrorCode TaoSetUp_ASFLS(Tao tao)
56a7e14dcfSSatish Balay {
57a7e14dcfSSatish Balay   TAO_SSLS       *asls = (TAO_SSLS *)tao->data;
58a7e14dcfSSatish Balay   PetscErrorCode ierr;
59a7e14dcfSSatish Balay 
60a7e14dcfSSatish Balay   PetscFunctionBegin;
61a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr);
62a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr);
63a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&asls->ff);CHKERRQ(ierr);
64a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&asls->dpsi);CHKERRQ(ierr);
65a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&asls->da);CHKERRQ(ierr);
66a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&asls->db);CHKERRQ(ierr);
67a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&asls->t1);CHKERRQ(ierr);
68a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&asls->t2);CHKERRQ(ierr);
69a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &asls->w);CHKERRQ(ierr);
706c23d075SBarry Smith   asls->fixed = NULL;
716c23d075SBarry Smith   asls->free = NULL;
726c23d075SBarry Smith   asls->J_sub = NULL;
736c23d075SBarry Smith   asls->Jpre_sub = NULL;
746c23d075SBarry Smith   asls->r1 = NULL;
756c23d075SBarry Smith   asls->r2 = NULL;
766c23d075SBarry Smith   asls->r3 = NULL;
776c23d075SBarry Smith   asls->dxfree = NULL;
78a7e14dcfSSatish Balay   PetscFunctionReturn(0);
79a7e14dcfSSatish Balay }
80a7e14dcfSSatish Balay 
81a7e14dcfSSatish Balay static PetscErrorCode Tao_ASLS_FunctionGradient(TaoLineSearch ls, Vec X, PetscReal *fcn,  Vec G, void *ptr)
82a7e14dcfSSatish Balay {
83441846f8SBarry Smith   Tao            tao = (Tao)ptr;
84a7e14dcfSSatish Balay   TAO_SSLS       *asls = (TAO_SSLS *)tao->data;
85a7e14dcfSSatish Balay   PetscErrorCode ierr;
86a7e14dcfSSatish Balay 
87a7e14dcfSSatish Balay   PetscFunctionBegin;
88a7e14dcfSSatish Balay   ierr = TaoComputeConstraints(tao, X, tao->constraints);CHKERRQ(ierr);
89a7e14dcfSSatish Balay   ierr = VecFischer(X,tao->constraints,tao->XL,tao->XU,asls->ff);CHKERRQ(ierr);
90a7e14dcfSSatish Balay   ierr = VecNorm(asls->ff,NORM_2,&asls->merit);CHKERRQ(ierr);
91a7e14dcfSSatish Balay   *fcn = 0.5*asls->merit*asls->merit;
92ffad9901SBarry Smith   ierr = TaoComputeJacobian(tao,tao->solution,tao->jacobian,tao->jacobian_pre);CHKERRQ(ierr);
93a7e14dcfSSatish Balay 
94235fd6e6SBarry Smith   ierr = MatDFischer(tao->jacobian, tao->solution, tao->constraints,tao->XL, tao->XU, asls->t1, asls->t2,asls->da, asls->db);CHKERRQ(ierr);
95a7e14dcfSSatish Balay   ierr = VecPointwiseMult(asls->t1, asls->ff, asls->db);CHKERRQ(ierr);
96a7e14dcfSSatish Balay   ierr = MatMultTranspose(tao->jacobian,asls->t1,G);CHKERRQ(ierr);
97a7e14dcfSSatish Balay   ierr = VecPointwiseMult(asls->t1, asls->ff, asls->da);CHKERRQ(ierr);
98a7e14dcfSSatish Balay   ierr = VecAXPY(G,1.0,asls->t1);CHKERRQ(ierr);
99a7e14dcfSSatish Balay   PetscFunctionReturn(0);
100a7e14dcfSSatish Balay }
101a7e14dcfSSatish Balay 
102441846f8SBarry Smith static PetscErrorCode TaoDestroy_ASFLS(Tao tao)
103a7e14dcfSSatish Balay {
104a7e14dcfSSatish Balay   TAO_SSLS       *ssls = (TAO_SSLS *)tao->data;
105a7e14dcfSSatish Balay   PetscErrorCode ierr;
106a7e14dcfSSatish Balay 
107a7e14dcfSSatish Balay   PetscFunctionBegin;
108a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->ff);CHKERRQ(ierr);
109a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->dpsi);CHKERRQ(ierr);
110a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->da);CHKERRQ(ierr);
111a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->db);CHKERRQ(ierr);
112a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->w);CHKERRQ(ierr);
113a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->t1);CHKERRQ(ierr);
114a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->t2);CHKERRQ(ierr);
115a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->r1);CHKERRQ(ierr);
116a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->r2);CHKERRQ(ierr);
117a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->r3);CHKERRQ(ierr);
118a7e14dcfSSatish Balay   ierr = VecDestroy(&ssls->dxfree);CHKERRQ(ierr);
119a7e14dcfSSatish Balay   ierr = MatDestroy(&ssls->J_sub);CHKERRQ(ierr);
120a7e14dcfSSatish Balay   ierr = MatDestroy(&ssls->Jpre_sub);CHKERRQ(ierr);
121a7e14dcfSSatish Balay   ierr = ISDestroy(&ssls->fixed);CHKERRQ(ierr);
122a7e14dcfSSatish Balay   ierr = ISDestroy(&ssls->free);CHKERRQ(ierr);
123a7e14dcfSSatish Balay   ierr = PetscFree(tao->data);CHKERRQ(ierr);
1246c23d075SBarry Smith   tao->data = NULL;
125a7e14dcfSSatish Balay   PetscFunctionReturn(0);
126a7e14dcfSSatish Balay }
12747a47007SBarry Smith 
128441846f8SBarry Smith static PetscErrorCode TaoSolve_ASFLS(Tao tao)
129a7e14dcfSSatish Balay {
130a7e14dcfSSatish Balay   TAO_SSLS                     *asls = (TAO_SSLS *)tao->data;
131a7e14dcfSSatish Balay   PetscReal                    psi,ndpsi, normd, innerd, t=0;
1328931d482SJason Sarich   PetscInt                     nf;
133a7e14dcfSSatish Balay   PetscErrorCode               ierr;
134e4cb33bbSBarry Smith   TaoLineSearchConvergedReason ls_reason;
135a7e14dcfSSatish Balay 
136a7e14dcfSSatish Balay   PetscFunctionBegin;
137a7e14dcfSSatish Balay   /* Assume that Setup has been called!
138a7e14dcfSSatish Balay      Set the structure for the Jacobian and create a linear solver. */
139a7e14dcfSSatish Balay 
140a7e14dcfSSatish Balay   ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr);
141a7e14dcfSSatish Balay   ierr = TaoLineSearchSetObjectiveAndGradientRoutine(tao->linesearch,Tao_ASLS_FunctionGradient,tao);CHKERRQ(ierr);
142a7e14dcfSSatish Balay   ierr = TaoLineSearchSetObjectiveRoutine(tao->linesearch,Tao_SSLS_Function,tao);CHKERRQ(ierr);
143a7e14dcfSSatish Balay   ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr);
144a7e14dcfSSatish Balay 
145a7e14dcfSSatish Balay   ierr = VecMedian(tao->XL, tao->solution, tao->XU, tao->solution);CHKERRQ(ierr);
146a7e14dcfSSatish Balay 
147a7e14dcfSSatish Balay   /* Calculate the function value and fischer function value at the
148a7e14dcfSSatish Balay      current iterate */
149a7e14dcfSSatish Balay   ierr = TaoLineSearchComputeObjectiveAndGradient(tao->linesearch,tao->solution,&psi,asls->dpsi);CHKERRQ(ierr);
150a7e14dcfSSatish Balay   ierr = VecNorm(asls->dpsi,NORM_2,&ndpsi);CHKERRQ(ierr);
151a7e14dcfSSatish Balay 
152763847b4SAlp Dener   tao->reason = TAO_CONTINUE_ITERATING;
153a7e14dcfSSatish Balay   while (1) {
154e4cb33bbSBarry Smith     /* Check the converged criteria */
155*7d3de750SJacob Faibussowitsch     ierr = PetscInfo(tao,"iter %D, merit: %g, ||dpsi||: %g\n",tao->niter,(double)asls->merit,(double)ndpsi);CHKERRQ(ierr);
156763847b4SAlp Dener     ierr = TaoLogConvergenceHistory(tao,asls->merit,ndpsi,0.0,tao->ksp_its);CHKERRQ(ierr);
157763847b4SAlp Dener     ierr = TaoMonitor(tao,tao->niter,asls->merit,ndpsi,0.0,t);CHKERRQ(ierr);
158763847b4SAlp Dener     ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr);
159763847b4SAlp Dener     if (TAO_CONTINUE_ITERATING != tao->reason) break;
160e1e80dc8SAlp Dener 
161e1e80dc8SAlp Dener     /* Call general purpose update function */
162e1e80dc8SAlp Dener     if (tao->ops->update) {
1638fcddce6SStefano Zampini       ierr = (*tao->ops->update)(tao, tao->niter, tao->user_update);CHKERRQ(ierr);
164e1e80dc8SAlp Dener     }
165e6d4cb7fSJason Sarich     tao->niter++;
166a7e14dcfSSatish Balay 
167a7e14dcfSSatish Balay     /* We are going to solve a linear system of equations.  We need to
168a7e14dcfSSatish Balay        set the tolerances for the solve so that we maintain an asymptotic
169a7e14dcfSSatish Balay        rate of convergence that is superlinear.
170a7e14dcfSSatish Balay        Note: these tolerances are for the reduced system.  We really need
171a7e14dcfSSatish Balay        to make sure that the full system satisfies the full-space conditions.
172a7e14dcfSSatish Balay 
173a7e14dcfSSatish Balay        This rule gives superlinear asymptotic convergence
174a7e14dcfSSatish Balay        asls->atol = min(0.5, asls->merit*sqrt(asls->merit));
175a7e14dcfSSatish Balay        asls->rtol = 0.0;
176a7e14dcfSSatish Balay 
177a7e14dcfSSatish Balay        This rule gives quadratic asymptotic convergence
178a7e14dcfSSatish Balay        asls->atol = min(0.5, asls->merit*asls->merit);
179a7e14dcfSSatish Balay        asls->rtol = 0.0;
180a7e14dcfSSatish Balay 
181a7e14dcfSSatish Balay        Calculate a free and fixed set of variables.  The fixed set of
182a7e14dcfSSatish Balay        variables are those for the d_b is approximately equal to zero.
183a7e14dcfSSatish Balay        The definition of approximately changes as we approach the solution
184a7e14dcfSSatish Balay        to the problem.
185a7e14dcfSSatish Balay 
186a7e14dcfSSatish Balay        No one rule is guaranteed to work in all cases.  The following
187a7e14dcfSSatish Balay        definition is based on the norm of the Jacobian matrix.  If the
188a7e14dcfSSatish Balay        norm is large, the tolerance becomes smaller. */
189a7e14dcfSSatish Balay     ierr = MatNorm(tao->jacobian,NORM_1,&asls->identifier);CHKERRQ(ierr);
190a7e14dcfSSatish Balay     asls->identifier = PetscMin(asls->merit, 1e-2) / (1 + asls->identifier);
191a7e14dcfSSatish Balay 
192a7e14dcfSSatish Balay     ierr = VecSet(asls->t1,-asls->identifier);CHKERRQ(ierr);
193a7e14dcfSSatish Balay     ierr = VecSet(asls->t2, asls->identifier);CHKERRQ(ierr);
194a7e14dcfSSatish Balay 
195a7e14dcfSSatish Balay     ierr = ISDestroy(&asls->fixed);CHKERRQ(ierr);
196a7e14dcfSSatish Balay     ierr = ISDestroy(&asls->free);CHKERRQ(ierr);
197a7e14dcfSSatish Balay     ierr = VecWhichBetweenOrEqual(asls->t1, asls->db, asls->t2, &asls->fixed);CHKERRQ(ierr);
1984473680cSBarry Smith     ierr = ISComplementVec(asls->fixed,asls->t1, &asls->free);CHKERRQ(ierr);
199a7e14dcfSSatish Balay 
200a7e14dcfSSatish Balay     ierr = ISGetSize(asls->fixed,&nf);CHKERRQ(ierr);
201*7d3de750SJacob Faibussowitsch     ierr = PetscInfo(tao,"Number of fixed variables: %D\n", nf);CHKERRQ(ierr);
202a7e14dcfSSatish Balay 
203a7e14dcfSSatish Balay     /* We now have our partition.  Now calculate the direction in the
204a7e14dcfSSatish Balay        fixed variable space. */
205302440fdSBarry Smith     ierr = TaoVecGetSubVec(asls->ff, asls->fixed, tao->subset_type, 0.0, &asls->r1);CHKERRQ(ierr);
206302440fdSBarry Smith     ierr = TaoVecGetSubVec(asls->da, asls->fixed, tao->subset_type, 1.0, &asls->r2);CHKERRQ(ierr);
207a7e14dcfSSatish Balay     ierr = VecPointwiseDivide(asls->r1,asls->r1,asls->r2);CHKERRQ(ierr);
208a7e14dcfSSatish Balay     ierr = VecSet(tao->stepdirection,0.0);CHKERRQ(ierr);
2094473680cSBarry Smith     ierr = VecISAXPY(tao->stepdirection, asls->fixed, 1.0,asls->r1);CHKERRQ(ierr);
210a7e14dcfSSatish Balay 
211a7e14dcfSSatish Balay     /* Our direction in the Fixed Variable Set is fixed.  Calculate the
212a7e14dcfSSatish Balay        information needed for the step in the Free Variable Set.  To
213a7e14dcfSSatish Balay        do this, we need to know the diagonal perturbation and the
214a7e14dcfSSatish Balay        right hand side. */
215a7e14dcfSSatish Balay 
216b98f30f2SJason Sarich     ierr = TaoVecGetSubVec(asls->da, asls->free, tao->subset_type, 0.0, &asls->r1);CHKERRQ(ierr);
217b98f30f2SJason Sarich     ierr = TaoVecGetSubVec(asls->ff, asls->free, tao->subset_type, 0.0, &asls->r2);CHKERRQ(ierr);
218b98f30f2SJason Sarich     ierr = TaoVecGetSubVec(asls->db, asls->free, tao->subset_type, 1.0, &asls->r3);CHKERRQ(ierr);
219a7e14dcfSSatish Balay     ierr = VecPointwiseDivide(asls->r1,asls->r1, asls->r3);CHKERRQ(ierr);
220a7e14dcfSSatish Balay     ierr = VecPointwiseDivide(asls->r2,asls->r2, asls->r3);CHKERRQ(ierr);
221a7e14dcfSSatish Balay 
222a7e14dcfSSatish Balay     /* r1 is the diagonal perturbation
223a7e14dcfSSatish Balay        r2 is the right hand side
224a7e14dcfSSatish Balay        r3 is no longer needed
225a7e14dcfSSatish Balay 
226a7e14dcfSSatish Balay        Now need to modify r2 for our direction choice in the fixed
227a7e14dcfSSatish Balay        variable set:  calculate t1 = J*d, take the reduced vector
228a7e14dcfSSatish Balay        of t1 and modify r2. */
229a7e14dcfSSatish Balay 
230a7e14dcfSSatish Balay     ierr = MatMult(tao->jacobian, tao->stepdirection, asls->t1);CHKERRQ(ierr);
231b98f30f2SJason Sarich     ierr = TaoVecGetSubVec(asls->t1,asls->free,tao->subset_type,0.0,&asls->r3);CHKERRQ(ierr);
232a7e14dcfSSatish Balay     ierr = VecAXPY(asls->r2, -1.0, asls->r3);CHKERRQ(ierr);
233a7e14dcfSSatish Balay 
234a7e14dcfSSatish Balay     /* Calculate the reduced problem matrix and the direction */
235b98f30f2SJason Sarich     ierr = TaoMatGetSubMat(tao->jacobian, asls->free, asls->w, tao->subset_type,&asls->J_sub);CHKERRQ(ierr);
236a7e14dcfSSatish Balay     if (tao->jacobian != tao->jacobian_pre) {
237b98f30f2SJason Sarich       ierr = TaoMatGetSubMat(tao->jacobian_pre, asls->free, asls->w, tao->subset_type, &asls->Jpre_sub);CHKERRQ(ierr);
238a7e14dcfSSatish Balay     } else {
239a7e14dcfSSatish Balay       ierr = MatDestroy(&asls->Jpre_sub);CHKERRQ(ierr);
240a7e14dcfSSatish Balay       asls->Jpre_sub = asls->J_sub;
241a7e14dcfSSatish Balay       ierr = PetscObjectReference((PetscObject)(asls->Jpre_sub));CHKERRQ(ierr);
242a7e14dcfSSatish Balay     }
243a7e14dcfSSatish Balay     ierr = MatDiagonalSet(asls->J_sub, asls->r1,ADD_VALUES);CHKERRQ(ierr);
244b98f30f2SJason Sarich     ierr = TaoVecGetSubVec(tao->stepdirection, asls->free, tao->subset_type, 0.0, &asls->dxfree);CHKERRQ(ierr);
245a7e14dcfSSatish Balay     ierr = VecSet(asls->dxfree, 0.0);CHKERRQ(ierr);
246a7e14dcfSSatish Balay 
247a7e14dcfSSatish Balay     /* Calculate the reduced direction.  (Really negative of Newton
248a7e14dcfSSatish Balay        direction.  Therefore, rest of the code uses -d.) */
249a7e14dcfSSatish Balay     ierr = KSPReset(tao->ksp);CHKERRQ(ierr);
25023ee1639SBarry Smith     ierr = KSPSetOperators(tao->ksp, asls->J_sub, asls->Jpre_sub);CHKERRQ(ierr);
251a7e14dcfSSatish Balay     ierr = KSPSolve(tao->ksp, asls->r2, asls->dxfree);CHKERRQ(ierr);
252b0026674SJason Sarich     ierr = KSPGetIterationNumber(tao->ksp,&tao->ksp_its);CHKERRQ(ierr);
253b0026674SJason Sarich     tao->ksp_tot_its+=tao->ksp_its;
254a7e14dcfSSatish Balay 
255a7e14dcfSSatish Balay     /* Add the direction in the free variables back into the real direction. */
2564473680cSBarry Smith     ierr = VecISAXPY(tao->stepdirection, asls->free, 1.0,asls->dxfree);CHKERRQ(ierr);
257a7e14dcfSSatish Balay 
258a7e14dcfSSatish Balay     /* Check the projected real direction for descent and if not, use the negative
259a7e14dcfSSatish Balay        gradient direction. */
260a7e14dcfSSatish Balay     ierr = VecCopy(tao->stepdirection, asls->w);CHKERRQ(ierr);
261a7e14dcfSSatish Balay     ierr = VecScale(asls->w, -1.0);CHKERRQ(ierr);
262a7e14dcfSSatish Balay     ierr = VecBoundGradientProjection(asls->w, tao->solution, tao->XL, tao->XU, asls->w);CHKERRQ(ierr);
263a7e14dcfSSatish Balay     ierr = VecNorm(asls->w, NORM_2, &normd);CHKERRQ(ierr);
264a7e14dcfSSatish Balay     ierr = VecDot(asls->w, asls->dpsi, &innerd);CHKERRQ(ierr);
265a7e14dcfSSatish Balay 
266d90ca52eSBarry Smith     if (innerd >= -asls->delta*PetscPowReal(normd, asls->rho)) {
267*7d3de750SJacob Faibussowitsch       ierr = PetscInfo(tao,"Gradient direction: %5.4e.\n", (double)innerd);CHKERRQ(ierr);
268*7d3de750SJacob Faibussowitsch       ierr = PetscInfo(tao, "Iteration %D: newton direction not descent\n", tao->niter);CHKERRQ(ierr);
269a7e14dcfSSatish Balay       ierr = VecCopy(asls->dpsi, tao->stepdirection);CHKERRQ(ierr);
270a7e14dcfSSatish Balay       ierr = VecDot(asls->dpsi, tao->stepdirection, &innerd);CHKERRQ(ierr);
271a7e14dcfSSatish Balay     }
272a7e14dcfSSatish Balay 
273a7e14dcfSSatish Balay     ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr);
274a7e14dcfSSatish Balay     innerd = -innerd;
275a7e14dcfSSatish Balay 
276a7e14dcfSSatish Balay     /* We now have a correct descent direction.  Apply a linesearch to
277a7e14dcfSSatish Balay        find the new iterate. */
278a7e14dcfSSatish Balay     ierr = TaoLineSearchSetInitialStepLength(tao->linesearch, 1.0);CHKERRQ(ierr);
279d90ca52eSBarry Smith     ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &psi,asls->dpsi, tao->stepdirection, &t, &ls_reason);CHKERRQ(ierr);
280a7e14dcfSSatish Balay     ierr = VecNorm(asls->dpsi, NORM_2, &ndpsi);CHKERRQ(ierr);
281a7e14dcfSSatish Balay   }
282a7e14dcfSSatish Balay   PetscFunctionReturn(0);
283a7e14dcfSSatish Balay }
284a7e14dcfSSatish Balay 
285a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
2861522df2eSJason Sarich /*MC
2871522df2eSJason Sarich    TAOASFLS - Active-set feasible linesearch algorithm for solving
2881522df2eSJason Sarich        complementarity constraints
2891522df2eSJason Sarich 
2901522df2eSJason Sarich    Options Database Keys:
2911522df2eSJason Sarich + -tao_ssls_delta - descent test fraction
2921522df2eSJason Sarich - -tao_ssls_rho - descent test power
2931522df2eSJason Sarich 
2941eb8069cSJason Sarich    Level: beginner
2951522df2eSJason Sarich M*/
296728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_ASFLS(Tao tao)
297a7e14dcfSSatish Balay {
298a7e14dcfSSatish Balay   TAO_SSLS       *asls;
299a7e14dcfSSatish Balay   PetscErrorCode ierr;
3008caf6e8cSBarry Smith   const char     *armijo_type = TAOLINESEARCHARMIJO;
301a7e14dcfSSatish Balay 
302a7e14dcfSSatish Balay   PetscFunctionBegin;
3033c9e27cfSGeoffrey Irving   ierr = PetscNewLog(tao,&asls);CHKERRQ(ierr);
304a7e14dcfSSatish Balay   tao->data = (void*)asls;
305a7e14dcfSSatish Balay   tao->ops->solve = TaoSolve_ASFLS;
306a7e14dcfSSatish Balay   tao->ops->setup = TaoSetUp_ASFLS;
307a7e14dcfSSatish Balay   tao->ops->view = TaoView_SSLS;
308a7e14dcfSSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_SSLS;
309a7e14dcfSSatish Balay   tao->ops->destroy = TaoDestroy_ASFLS;
310a7e14dcfSSatish Balay   tao->subset_type = TAO_SUBSET_SUBVEC;
311a7e14dcfSSatish Balay   asls->delta = 1e-10;
312a7e14dcfSSatish Balay   asls->rho = 2.1;
3136c23d075SBarry Smith   asls->fixed = NULL;
3146c23d075SBarry Smith   asls->free = NULL;
3156c23d075SBarry Smith   asls->J_sub = NULL;
3166c23d075SBarry Smith   asls->Jpre_sub = NULL;
3176c23d075SBarry Smith   asls->w = NULL;
3186c23d075SBarry Smith   asls->r1 = NULL;
3196c23d075SBarry Smith   asls->r2 = NULL;
3206c23d075SBarry Smith   asls->r3 = NULL;
3216c23d075SBarry Smith   asls->t1 = NULL;
3226c23d075SBarry Smith   asls->t2 = NULL;
3236c23d075SBarry Smith   asls->dxfree = NULL;
324a7e14dcfSSatish Balay   asls->identifier = 1e-5;
325a7e14dcfSSatish Balay 
326a7e14dcfSSatish Balay   ierr = TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch);CHKERRQ(ierr);
32763b15415SAlp Dener   ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr);
328a7e14dcfSSatish Balay   ierr = TaoLineSearchSetType(tao->linesearch, armijo_type);CHKERRQ(ierr);
3295d527766SPatrick Farrell   ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr);
330a7e14dcfSSatish Balay   ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr);
331a7e14dcfSSatish Balay 
332a7e14dcfSSatish Balay   ierr = KSPCreate(((PetscObject)tao)->comm, &tao->ksp);CHKERRQ(ierr);
33363b15415SAlp Dener   ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1);CHKERRQ(ierr);
3345d527766SPatrick Farrell   ierr = KSPSetOptionsPrefix(tao->ksp,tao->hdr.prefix);CHKERRQ(ierr);
335a7e14dcfSSatish Balay   ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr);
3366552cf8aSJason Sarich 
3376552cf8aSJason Sarich   /* Override default settings (unless already changed) */
3386552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 2000;
3396552cf8aSJason Sarich   if (!tao->max_funcs_changed) tao->max_funcs = 4000;
3406552cf8aSJason Sarich   if (!tao->gttol_changed) tao->gttol = 0;
3416552cf8aSJason Sarich   if (!tao->grtol_changed) tao->grtol = 0;
3426f4723b1SBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
3436552cf8aSJason Sarich   if (!tao->gatol_changed) tao->gatol = 1.0e-6;
3446552cf8aSJason Sarich   if (!tao->fmin_changed)  tao->fmin = 1.0e-4;
3456f4723b1SBarry Smith #else
3466552cf8aSJason Sarich   if (!tao->gatol_changed) tao->gatol = 1.0e-16;
3476552cf8aSJason Sarich   if (!tao->fmin_changed)  tao->fmin = 1.0e-8;
3486f4723b1SBarry Smith #endif
349a7e14dcfSSatish Balay   PetscFunctionReturn(0);
350a7e14dcfSSatish Balay }
351