xref: /petsc/src/tao/unconstrained/impls/nls/nls.c (revision 0c51296cc97b5c762f2b5f128b2aab8171ac0691)
1ba92ff59SBarry Smith #include <petsctaolinesearch.h>
21daac38eSTodd Munson #include <../src/tao/unconstrained/impls/nls/nlsimpl.h>
3a7e14dcfSSatish Balay 
4aaa7dc30SBarry Smith #include <petscksp.h>
5a7e14dcfSSatish Balay 
6a7e14dcfSSatish Balay #define NLS_INIT_CONSTANT         0
7a7e14dcfSSatish Balay #define NLS_INIT_DIRECTION        1
8a7e14dcfSSatish Balay #define NLS_INIT_INTERPOLATION    2
9a7e14dcfSSatish Balay #define NLS_INIT_TYPES            3
10a7e14dcfSSatish Balay 
11a7e14dcfSSatish Balay #define NLS_UPDATE_STEP           0
12a7e14dcfSSatish Balay #define NLS_UPDATE_REDUCTION      1
13a7e14dcfSSatish Balay #define NLS_UPDATE_INTERPOLATION  2
14a7e14dcfSSatish Balay #define NLS_UPDATE_TYPES          3
15a7e14dcfSSatish Balay 
1687f595a5SBarry Smith static const char *NLS_INIT[64] = {"constant", "direction", "interpolation"};
17a7e14dcfSSatish Balay 
1887f595a5SBarry Smith static const char *NLS_UPDATE[64] = {"step", "reduction", "interpolation"};
19a7e14dcfSSatish Balay 
201daac38eSTodd Munson /*
21a7e14dcfSSatish Balay  Implements Newton's Method with a line search approach for solving
22a7e14dcfSSatish Balay  unconstrained minimization problems.  A More'-Thuente line search
23a7e14dcfSSatish Balay  is used to guarantee that the bfgs preconditioner remains positive
24a7e14dcfSSatish Balay  definite.
25a7e14dcfSSatish Balay 
26a7e14dcfSSatish Balay  The method can shift the Hessian matrix.  The shifting procedure is
27a7e14dcfSSatish Balay  adapted from the PATH algorithm for solving complementarity
28a7e14dcfSSatish Balay  problems.
29a7e14dcfSSatish Balay 
30a7e14dcfSSatish Balay  The linear system solve should be done with a conjugate gradient
311daac38eSTodd Munson  method, although any method can be used.
321daac38eSTodd Munson */
33a7e14dcfSSatish Balay 
34a7e14dcfSSatish Balay #define NLS_NEWTON              0
35a7e14dcfSSatish Balay #define NLS_BFGS                1
36*0c51296cSAlp Dener #define NLS_GRADIENT            2
37a7e14dcfSSatish Balay 
38441846f8SBarry Smith static PetscErrorCode TaoSolve_NLS(Tao tao)
39a7e14dcfSSatish Balay {
40a7e14dcfSSatish Balay   PetscErrorCode               ierr;
41a7e14dcfSSatish Balay   TAO_NLS                      *nlsP = (TAO_NLS *)tao->data;
421daac38eSTodd Munson   KSPType                      ksp_type;
43*0c51296cSAlp Dener   PetscBool                    is_nash,is_stcg,is_gltr,is_bfgs,is_jacobi;
44a7e14dcfSSatish Balay   KSPConvergedReason           ksp_reason;
451daac38eSTodd Munson   PC                           pc;
461daac38eSTodd Munson   TaoLineSearchConvergedReason ls_reason;
47a7e14dcfSSatish Balay 
48a7e14dcfSSatish Balay   PetscReal                    fmin, ftrial, f_full, prered, actred, kappa, sigma;
49a7e14dcfSSatish Balay   PetscReal                    tau, tau_1, tau_2, tau_max, tau_min, max_radius;
50a7e14dcfSSatish Balay   PetscReal                    f, fold, gdx, gnorm, pert;
51a7e14dcfSSatish Balay   PetscReal                    step = 1.0;
52a7e14dcfSSatish Balay   PetscReal                    norm_d = 0.0, e_min;
53a7e14dcfSSatish Balay 
54a7e14dcfSSatish Balay   PetscInt                     stepType;
55a7e14dcfSSatish Balay   PetscInt                     bfgsUpdates = 0;
56a7e14dcfSSatish Balay   PetscInt                     n,N,kspits;
57b4690188SBarry Smith   PetscInt                     needH = 1;
58a7e14dcfSSatish Balay 
59a7e14dcfSSatish Balay   PetscInt                     i_max = 5;
60a7e14dcfSSatish Balay   PetscInt                     j_max = 1;
61a7e14dcfSSatish Balay   PetscInt                     i, j;
62a7e14dcfSSatish Balay 
63a7e14dcfSSatish Balay   PetscFunctionBegin;
64a7e14dcfSSatish Balay   if (tao->XL || tao->XU || tao->ops->computebounds) {
65a7e14dcfSSatish Balay     ierr = PetscPrintf(((PetscObject)tao)->comm,"WARNING: Variable bounds have been set but will be ignored by nls algorithm\n");CHKERRQ(ierr);
66a7e14dcfSSatish Balay   }
67a7e14dcfSSatish Balay 
68a7e14dcfSSatish Balay   /* Initialized variables */
69a7e14dcfSSatish Balay   pert = nlsP->sval;
70a7e14dcfSSatish Balay 
712d9aa51bSJason Sarich   /* Number of times ksp stopped because of these reasons */
72a7e14dcfSSatish Balay   nlsP->ksp_atol = 0;
73a7e14dcfSSatish Balay   nlsP->ksp_rtol = 0;
74a7e14dcfSSatish Balay   nlsP->ksp_dtol = 0;
75a7e14dcfSSatish Balay   nlsP->ksp_ctol = 0;
76a7e14dcfSSatish Balay   nlsP->ksp_negc = 0;
77a7e14dcfSSatish Balay   nlsP->ksp_iter = 0;
78a7e14dcfSSatish Balay   nlsP->ksp_othr = 0;
79a7e14dcfSSatish Balay 
80a7e14dcfSSatish Balay   /* Initialize trust-region radius when using nash, stcg, or gltr
81ba7fe8fbSTodd Munson      Command automatically ignored for other methods
82ba7fe8fbSTodd Munson      Will be reset during the first iteration
83ba7fe8fbSTodd Munson   */
841daac38eSTodd Munson   ierr = KSPGetType(tao->ksp,&ksp_type);CHKERRQ(ierr);
851daac38eSTodd Munson   ierr = PetscStrcmp(ksp_type,KSPCGNASH,&is_nash);CHKERRQ(ierr);
861daac38eSTodd Munson   ierr = PetscStrcmp(ksp_type,KSPCGSTCG,&is_stcg);CHKERRQ(ierr);
871daac38eSTodd Munson   ierr = PetscStrcmp(ksp_type,KSPCGGLTR,&is_gltr);CHKERRQ(ierr);
881daac38eSTodd Munson 
89ba7fe8fbSTodd Munson   ierr = KSPCGSetRadius(tao->ksp,nlsP->max_radius);CHKERRQ(ierr);
90a7e14dcfSSatish Balay 
911daac38eSTodd Munson   if (is_nash || is_stcg || is_gltr) {
921daac38eSTodd Munson     if (tao->trust0 < 0.0) SETERRQ(PETSC_COMM_SELF,1,"Initial radius negative");
93a7e14dcfSSatish Balay     tao->trust = tao->trust0;
94a7e14dcfSSatish Balay     tao->trust = PetscMax(tao->trust, nlsP->min_radius);
95a7e14dcfSSatish Balay     tao->trust = PetscMin(tao->trust, nlsP->max_radius);
96a7e14dcfSSatish Balay   }
97a7e14dcfSSatish Balay 
98a7e14dcfSSatish Balay   /* Check convergence criteria */
99a7e14dcfSSatish Balay   ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient);CHKERRQ(ierr);
100a9603a14SPatrick Farrell   ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr);
10187f595a5SBarry Smith   if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN");
102a7e14dcfSSatish Balay 
1033ecd9318SAlp Dener   tao->reason = TAO_CONTINUE_ITERATING;
1043ecd9318SAlp Dener   ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr);
1053ecd9318SAlp Dener   ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr);
1063ecd9318SAlp Dener   ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr);
1073ecd9318SAlp Dener   if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
108a7e14dcfSSatish Balay 
109*0c51296cSAlp Dener   /* Allocate the vectors needed for the BFGS approximation */
110a7e14dcfSSatish Balay   ierr = KSPGetPC(tao->ksp, &pc);CHKERRQ(ierr);
111*0c51296cSAlp Dener   ierr = PetscObjectTypeCompare((PetscObject)pc, PCLMVM, &is_bfgs);CHKERRQ(ierr);
112*0c51296cSAlp Dener   ierr = PetscObjectTypeCompare((PetscObject)pc, PCJACOBI, &is_jacobi);CHKERRQ(ierr);
113*0c51296cSAlp Dener   if (is_bfgs) {
114*0c51296cSAlp Dener     nlsP->bfgs_pre = pc;
115*0c51296cSAlp Dener     ierr = PCLMVMGetMatLMVM(nlsP->bfgs_pre, &nlsP->M);CHKERRQ(ierr);
116*0c51296cSAlp Dener     ierr = VecGetLocalSize(tao->solution, &n);CHKERRQ(ierr);
117*0c51296cSAlp Dener     ierr = VecGetSize(tao->solution, &N);CHKERRQ(ierr);
118*0c51296cSAlp Dener     ierr = MatSetSizes(nlsP->M, n, n, N, N);CHKERRQ(ierr);
119*0c51296cSAlp Dener     ierr = MatLMVMAllocate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr);
120*0c51296cSAlp Dener   } else if (is_jacobi) {
121baa89ecbSBarry Smith     ierr = PCJacobiSetUseAbs(pc,PETSC_TRUE);CHKERRQ(ierr);
122a7e14dcfSSatish Balay   }
123a7e14dcfSSatish Balay 
124a7e14dcfSSatish Balay   /* Initialize trust-region radius.  The initialization is only performed
125a7e14dcfSSatish Balay      when we are using Nash, Steihaug-Toint or the Generalized Lanczos method. */
1261daac38eSTodd Munson   if (is_nash || is_stcg || is_gltr) {
127a7e14dcfSSatish Balay     switch(nlsP->init_type) {
128a7e14dcfSSatish Balay     case NLS_INIT_CONSTANT:
129a7e14dcfSSatish Balay       /* Use the initial radius specified */
130a7e14dcfSSatish Balay       break;
131a7e14dcfSSatish Balay 
132a7e14dcfSSatish Balay     case NLS_INIT_INTERPOLATION:
133a7e14dcfSSatish Balay       /* Use the initial radius specified */
134a7e14dcfSSatish Balay       max_radius = 0.0;
135a7e14dcfSSatish Balay 
136a7e14dcfSSatish Balay       for (j = 0; j < j_max; ++j) {
137a7e14dcfSSatish Balay         fmin = f;
138a7e14dcfSSatish Balay         sigma = 0.0;
139a7e14dcfSSatish Balay 
140a7e14dcfSSatish Balay         if (needH) {
141ffad9901SBarry Smith           ierr  = TaoComputeHessian(tao, tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr);
142a7e14dcfSSatish Balay           needH = 0;
143a7e14dcfSSatish Balay         }
144a7e14dcfSSatish Balay 
145a7e14dcfSSatish Balay         for (i = 0; i < i_max; ++i) {
146a7e14dcfSSatish Balay           ierr = VecCopy(tao->solution,nlsP->W);CHKERRQ(ierr);
147a7e14dcfSSatish Balay           ierr = VecAXPY(nlsP->W,-tao->trust/gnorm,tao->gradient);CHKERRQ(ierr);
148a7e14dcfSSatish Balay           ierr = TaoComputeObjective(tao, nlsP->W, &ftrial);CHKERRQ(ierr);
149a7e14dcfSSatish Balay           if (PetscIsInfOrNanReal(ftrial)) {
150a7e14dcfSSatish Balay             tau = nlsP->gamma1_i;
15187f595a5SBarry Smith           } else {
152a7e14dcfSSatish Balay             if (ftrial < fmin) {
153a7e14dcfSSatish Balay               fmin = ftrial;
154a7e14dcfSSatish Balay               sigma = -tao->trust / gnorm;
155a7e14dcfSSatish Balay             }
156a7e14dcfSSatish Balay 
157a7e14dcfSSatish Balay             ierr = MatMult(tao->hessian, tao->gradient, nlsP->D);CHKERRQ(ierr);
158a7e14dcfSSatish Balay             ierr = VecDot(tao->gradient, nlsP->D, &prered);CHKERRQ(ierr);
159a7e14dcfSSatish Balay 
160a7e14dcfSSatish Balay             prered = tao->trust * (gnorm - 0.5 * tao->trust * prered / (gnorm * gnorm));
161a7e14dcfSSatish Balay             actred = f - ftrial;
16287f595a5SBarry Smith             if ((PetscAbsScalar(actred) <= nlsP->epsilon) && (PetscAbsScalar(prered) <= nlsP->epsilon)) {
163a7e14dcfSSatish Balay               kappa = 1.0;
16487f595a5SBarry Smith             } else {
165a7e14dcfSSatish Balay               kappa = actred / prered;
166a7e14dcfSSatish Balay             }
167a7e14dcfSSatish Balay 
168a7e14dcfSSatish Balay             tau_1 = nlsP->theta_i * gnorm * tao->trust / (nlsP->theta_i * gnorm * tao->trust + (1.0 - nlsP->theta_i) * prered - actred);
169a7e14dcfSSatish Balay             tau_2 = nlsP->theta_i * gnorm * tao->trust / (nlsP->theta_i * gnorm * tao->trust - (1.0 + nlsP->theta_i) * prered + actred);
170a7e14dcfSSatish Balay             tau_min = PetscMin(tau_1, tau_2);
171a7e14dcfSSatish Balay             tau_max = PetscMax(tau_1, tau_2);
172a7e14dcfSSatish Balay 
173a7e14dcfSSatish Balay             if (PetscAbsScalar(kappa - 1.0) <= nlsP->mu1_i) {
174a7e14dcfSSatish Balay               /* Great agreement */
175a7e14dcfSSatish Balay               max_radius = PetscMax(max_radius, tao->trust);
176a7e14dcfSSatish Balay 
177a7e14dcfSSatish Balay               if (tau_max < 1.0) {
178a7e14dcfSSatish Balay                 tau = nlsP->gamma3_i;
17987f595a5SBarry Smith               } else if (tau_max > nlsP->gamma4_i) {
180a7e14dcfSSatish Balay                 tau = nlsP->gamma4_i;
18187f595a5SBarry Smith               } else if (tau_1 >= 1.0 && tau_1 <= nlsP->gamma4_i && tau_2 < 1.0) {
182a7e14dcfSSatish Balay                 tau = tau_1;
18387f595a5SBarry Smith               } else if (tau_2 >= 1.0 && tau_2 <= nlsP->gamma4_i && tau_1 < 1.0) {
184a7e14dcfSSatish Balay                 tau = tau_2;
18587f595a5SBarry Smith               } else {
186a7e14dcfSSatish Balay                 tau = tau_max;
187a7e14dcfSSatish Balay               }
18887f595a5SBarry Smith             } else if (PetscAbsScalar(kappa - 1.0) <= nlsP->mu2_i) {
189a7e14dcfSSatish Balay               /* Good agreement */
190a7e14dcfSSatish Balay               max_radius = PetscMax(max_radius, tao->trust);
191a7e14dcfSSatish Balay 
192a7e14dcfSSatish Balay               if (tau_max < nlsP->gamma2_i) {
193a7e14dcfSSatish Balay                 tau = nlsP->gamma2_i;
19487f595a5SBarry Smith               } else if (tau_max > nlsP->gamma3_i) {
195a7e14dcfSSatish Balay                 tau = nlsP->gamma3_i;
19687f595a5SBarry Smith               } else {
197a7e14dcfSSatish Balay                 tau = tau_max;
198a7e14dcfSSatish Balay               }
19987f595a5SBarry Smith             } else {
200a7e14dcfSSatish Balay               /* Not good agreement */
201a7e14dcfSSatish Balay               if (tau_min > 1.0) {
202a7e14dcfSSatish Balay                 tau = nlsP->gamma2_i;
20387f595a5SBarry Smith               } else if (tau_max < nlsP->gamma1_i) {
204a7e14dcfSSatish Balay                 tau = nlsP->gamma1_i;
20587f595a5SBarry Smith               } else if ((tau_min < nlsP->gamma1_i) && (tau_max >= 1.0)) {
206a7e14dcfSSatish Balay                 tau = nlsP->gamma1_i;
20787f595a5SBarry Smith               } else if ((tau_1 >= nlsP->gamma1_i) && (tau_1 < 1.0) && ((tau_2 < nlsP->gamma1_i) || (tau_2 >= 1.0))) {
208a7e14dcfSSatish Balay                 tau = tau_1;
20987f595a5SBarry Smith               } else if ((tau_2 >= nlsP->gamma1_i) && (tau_2 < 1.0) && ((tau_1 < nlsP->gamma1_i) || (tau_2 >= 1.0))) {
210a7e14dcfSSatish Balay                 tau = tau_2;
21187f595a5SBarry Smith               } else {
212a7e14dcfSSatish Balay                 tau = tau_max;
213a7e14dcfSSatish Balay               }
214a7e14dcfSSatish Balay             }
215a7e14dcfSSatish Balay           }
216a7e14dcfSSatish Balay           tao->trust = tau * tao->trust;
217a7e14dcfSSatish Balay         }
218a7e14dcfSSatish Balay 
219a7e14dcfSSatish Balay         if (fmin < f) {
220a7e14dcfSSatish Balay           f = fmin;
221a7e14dcfSSatish Balay           ierr = VecAXPY(tao->solution,sigma,tao->gradient);CHKERRQ(ierr);
222a7e14dcfSSatish Balay           ierr = TaoComputeGradient(tao,tao->solution,tao->gradient);CHKERRQ(ierr);
223a7e14dcfSSatish Balay 
224a9603a14SPatrick Farrell           ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr);
22587f595a5SBarry Smith           if (PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute gradient generated Inf or NaN");
226a7e14dcfSSatish Balay           needH = 1;
227a7e14dcfSSatish Balay 
2283ecd9318SAlp Dener           ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr);
2293ecd9318SAlp Dener           ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr);
2303ecd9318SAlp Dener           ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr);
2313ecd9318SAlp Dener           if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
232a7e14dcfSSatish Balay         }
233a7e14dcfSSatish Balay       }
234a7e14dcfSSatish Balay       tao->trust = PetscMax(tao->trust, max_radius);
235a7e14dcfSSatish Balay 
236a7e14dcfSSatish Balay       /* Modify the radius if it is too large or small */
237a7e14dcfSSatish Balay       tao->trust = PetscMax(tao->trust, nlsP->min_radius);
238a7e14dcfSSatish Balay       tao->trust = PetscMin(tao->trust, nlsP->max_radius);
239a7e14dcfSSatish Balay       break;
240a7e14dcfSSatish Balay 
241a7e14dcfSSatish Balay     default:
242a7e14dcfSSatish Balay       /* Norm of the first direction will initialize radius */
243a7e14dcfSSatish Balay       tao->trust = 0.0;
244a7e14dcfSSatish Balay       break;
245a7e14dcfSSatish Balay     }
246a7e14dcfSSatish Balay   }
247a7e14dcfSSatish Balay 
248a7e14dcfSSatish Balay   /* Set counter for gradient/reset steps*/
249a7e14dcfSSatish Balay   nlsP->newt = 0;
250a7e14dcfSSatish Balay   nlsP->bfgs = 0;
251a7e14dcfSSatish Balay   nlsP->grad = 0;
252a7e14dcfSSatish Balay 
253a7e14dcfSSatish Balay   /* Have not converged; continue with Newton method */
2543ecd9318SAlp Dener   while (tao->reason == TAO_CONTINUE_ITERATING) {
2558931d482SJason Sarich     ++tao->niter;
256ae93cb3cSJason Sarich     tao->ksp_its=0;
257a7e14dcfSSatish Balay 
258a7e14dcfSSatish Balay     /* Compute the Hessian */
259a7e14dcfSSatish Balay     if (needH) {
260ffad9901SBarry Smith       ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr);
261a7e14dcfSSatish Balay     }
262a7e14dcfSSatish Balay 
263a7e14dcfSSatish Balay     /* Shift the Hessian matrix */
264a7e14dcfSSatish Balay     if (pert > 0) {
265302440fdSBarry Smith       ierr = MatShift(tao->hessian, pert);CHKERRQ(ierr);
266a7e14dcfSSatish Balay       if (tao->hessian != tao->hessian_pre) {
267a7e14dcfSSatish Balay         ierr = MatShift(tao->hessian_pre, pert);CHKERRQ(ierr);
268a7e14dcfSSatish Balay       }
269a7e14dcfSSatish Balay     }
270a7e14dcfSSatish Balay 
271*0c51296cSAlp Dener     if (nlsP->bfgs_pre) {
272a7e14dcfSSatish Balay       ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr);
273a7e14dcfSSatish Balay       ++bfgsUpdates;
274a7e14dcfSSatish Balay     }
275a7e14dcfSSatish Balay 
276a7e14dcfSSatish Balay     /* Solve the Newton system of equations */
27723ee1639SBarry Smith     ierr = KSPSetOperators(tao->ksp,tao->hessian,tao->hessian_pre);CHKERRQ(ierr);
2781daac38eSTodd Munson     if (is_nash || is_stcg || is_gltr) {
279ba7fe8fbSTodd Munson       ierr = KSPCGSetRadius(tao->ksp,nlsP->max_radius);CHKERRQ(ierr);
280a7e14dcfSSatish Balay       ierr = KSPSolve(tao->ksp, tao->gradient, nlsP->D);CHKERRQ(ierr);
281a7e14dcfSSatish Balay       ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr);
282a7e14dcfSSatish Balay       tao->ksp_its+=kspits;
283ae93cb3cSJason Sarich       tao->ksp_tot_its+=kspits;
284ba7fe8fbSTodd Munson       ierr = KSPCGGetNormD(tao->ksp,&norm_d);CHKERRQ(ierr);
285a7e14dcfSSatish Balay 
286a7e14dcfSSatish Balay       if (0.0 == tao->trust) {
287a7e14dcfSSatish Balay         /* Radius was uninitialized; use the norm of the direction */
288a7e14dcfSSatish Balay         if (norm_d > 0.0) {
289a7e14dcfSSatish Balay           tao->trust = norm_d;
290a7e14dcfSSatish Balay 
291a7e14dcfSSatish Balay           /* Modify the radius if it is too large or small */
292a7e14dcfSSatish Balay           tao->trust = PetscMax(tao->trust, nlsP->min_radius);
293a7e14dcfSSatish Balay           tao->trust = PetscMin(tao->trust, nlsP->max_radius);
29487f595a5SBarry Smith         } else {
295a7e14dcfSSatish Balay           /* The direction was bad; set radius to default value and re-solve
296a7e14dcfSSatish Balay              the trust-region subproblem to get a direction */
297a7e14dcfSSatish Balay           tao->trust = tao->trust0;
298a7e14dcfSSatish Balay 
299a7e14dcfSSatish Balay           /* Modify the radius if it is too large or small */
300a7e14dcfSSatish Balay           tao->trust = PetscMax(tao->trust, nlsP->min_radius);
301a7e14dcfSSatish Balay           tao->trust = PetscMin(tao->trust, nlsP->max_radius);
302a7e14dcfSSatish Balay 
303ba7fe8fbSTodd Munson           ierr = KSPCGSetRadius(tao->ksp,nlsP->max_radius);CHKERRQ(ierr);
304a7e14dcfSSatish Balay           ierr = KSPSolve(tao->ksp, tao->gradient, nlsP->D);CHKERRQ(ierr);
305a7e14dcfSSatish Balay           ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr);
306a7e14dcfSSatish Balay           tao->ksp_its+=kspits;
307ae93cb3cSJason Sarich           tao->ksp_tot_its+=kspits;
308ba7fe8fbSTodd Munson           ierr = KSPCGGetNormD(tao->ksp,&norm_d);CHKERRQ(ierr);
309a7e14dcfSSatish Balay 
31087f595a5SBarry Smith           if (norm_d == 0.0) SETERRQ(PETSC_COMM_SELF,1, "Initial direction zero");
311a7e14dcfSSatish Balay         }
312a7e14dcfSSatish Balay       }
31387f595a5SBarry Smith     } else {
314a7e14dcfSSatish Balay       ierr = KSPSolve(tao->ksp, tao->gradient, nlsP->D);CHKERRQ(ierr);
315a7e14dcfSSatish Balay       ierr = KSPGetIterationNumber(tao->ksp, &kspits);CHKERRQ(ierr);
316a7e14dcfSSatish Balay       tao->ksp_its += kspits;
317ae93cb3cSJason Sarich       tao->ksp_tot_its+=kspits;
318a7e14dcfSSatish Balay     }
319a7e14dcfSSatish Balay     ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr);
320a7e14dcfSSatish Balay     ierr = KSPGetConvergedReason(tao->ksp, &ksp_reason);CHKERRQ(ierr);
321*0c51296cSAlp Dener     if ((KSP_DIVERGED_INDEFINITE_PC == ksp_reason) &&  (nlsP->bfgs_pre)) {
322a7e14dcfSSatish Balay       /* Preconditioner is numerically indefinite; reset the
323a7e14dcfSSatish Balay          approximate if using BFGS preconditioning. */
324cd929ea3SAlp Dener       ierr = MatLMVMReset(nlsP->M, PETSC_FALSE);CHKERRQ(ierr);
325a7e14dcfSSatish Balay       ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr);
326a7e14dcfSSatish Balay       bfgsUpdates = 1;
327a7e14dcfSSatish Balay     }
328a7e14dcfSSatish Balay 
329a7e14dcfSSatish Balay     if (KSP_CONVERGED_ATOL == ksp_reason) {
330a7e14dcfSSatish Balay       ++nlsP->ksp_atol;
33187f595a5SBarry Smith     } else if (KSP_CONVERGED_RTOL == ksp_reason) {
332a7e14dcfSSatish Balay       ++nlsP->ksp_rtol;
33387f595a5SBarry Smith     } else if (KSP_CONVERGED_CG_CONSTRAINED == ksp_reason) {
334a7e14dcfSSatish Balay       ++nlsP->ksp_ctol;
33587f595a5SBarry Smith     } else if (KSP_CONVERGED_CG_NEG_CURVE == ksp_reason) {
336a7e14dcfSSatish Balay       ++nlsP->ksp_negc;
33787f595a5SBarry Smith     } else if (KSP_DIVERGED_DTOL == ksp_reason) {
338a7e14dcfSSatish Balay       ++nlsP->ksp_dtol;
33987f595a5SBarry Smith     } else if (KSP_DIVERGED_ITS == ksp_reason) {
340a7e14dcfSSatish Balay       ++nlsP->ksp_iter;
34187f595a5SBarry Smith     } else {
342a7e14dcfSSatish Balay       ++nlsP->ksp_othr;
343a7e14dcfSSatish Balay     }
344a7e14dcfSSatish Balay 
345a7e14dcfSSatish Balay     /* Check for success (descent direction) */
346a7e14dcfSSatish Balay     ierr = VecDot(nlsP->D, tao->gradient, &gdx);CHKERRQ(ierr);
347a7e14dcfSSatish Balay     if ((gdx >= 0.0) || PetscIsInfOrNanReal(gdx)) {
348a7e14dcfSSatish Balay       /* Newton step is not descent or direction produced Inf or NaN
349a7e14dcfSSatish Balay          Update the perturbation for next time */
350a7e14dcfSSatish Balay       if (pert <= 0.0) {
351a7e14dcfSSatish Balay         /* Initialize the perturbation */
352a7e14dcfSSatish Balay         pert = PetscMin(nlsP->imax, PetscMax(nlsP->imin, nlsP->imfac * gnorm));
3531daac38eSTodd Munson         if (is_gltr) {
354ba7fe8fbSTodd Munson           ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr);
355a7e14dcfSSatish Balay           pert = PetscMax(pert, -e_min);
356a7e14dcfSSatish Balay         }
35787f595a5SBarry Smith       } else {
358a7e14dcfSSatish Balay         /* Increase the perturbation */
359a7e14dcfSSatish Balay         pert = PetscMin(nlsP->pmax, PetscMax(nlsP->pgfac * pert, nlsP->pmgfac * gnorm));
360a7e14dcfSSatish Balay       }
361a7e14dcfSSatish Balay 
362*0c51296cSAlp Dener       if (!nlsP->bfgs_pre) {
363a7e14dcfSSatish Balay         /* We don't have the bfgs matrix around and updated
364a7e14dcfSSatish Balay            Must use gradient direction in this case */
365a7e14dcfSSatish Balay         ierr = VecCopy(tao->gradient, nlsP->D);CHKERRQ(ierr);
366a7e14dcfSSatish Balay         ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr);
367a7e14dcfSSatish Balay         ++nlsP->grad;
368a7e14dcfSSatish Balay         stepType = NLS_GRADIENT;
36987f595a5SBarry Smith       } else {
370a7e14dcfSSatish Balay         /* Attempt to use the BFGS direction */
371cd929ea3SAlp Dener         ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr);
372a7e14dcfSSatish Balay         ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr);
373a7e14dcfSSatish Balay 
374a7e14dcfSSatish Balay         /* Check for success (descent direction) */
375a7e14dcfSSatish Balay         ierr = VecDot(tao->gradient, nlsP->D, &gdx);CHKERRQ(ierr);
376a7e14dcfSSatish Balay         if ((gdx >= 0) || PetscIsInfOrNanReal(gdx)) {
377a7e14dcfSSatish Balay           /* BFGS direction is not descent or direction produced not a number
378a7e14dcfSSatish Balay              We can assert bfgsUpdates > 1 in this case because
379a7e14dcfSSatish Balay              the first solve produces the scaled gradient direction,
380a7e14dcfSSatish Balay              which is guaranteed to be descent */
381a7e14dcfSSatish Balay 
382a7e14dcfSSatish Balay           /* Use steepest descent direction (scaled) */
383cd929ea3SAlp Dener           ierr = MatLMVMReset(nlsP->M, PETSC_FALSE);CHKERRQ(ierr);
384a7e14dcfSSatish Balay           ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr);
385cd929ea3SAlp Dener           ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr);
386a7e14dcfSSatish Balay           ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr);
387a7e14dcfSSatish Balay 
388a7e14dcfSSatish Balay           bfgsUpdates = 1;
389*0c51296cSAlp Dener           ++nlsP->grad;
390*0c51296cSAlp Dener           stepType = NLS_GRADIENT;
39187f595a5SBarry Smith         } else {
392*0c51296cSAlp Dener           ierr = MatLMVMGetUpdateCount(nlsP->M, &bfgsUpdates);CHKERRQ(ierr);
393a7e14dcfSSatish Balay           if (1 == bfgsUpdates) {
394a7e14dcfSSatish Balay             /* The first BFGS direction is always the scaled gradient */
395*0c51296cSAlp Dener             ++nlsP->grad;
396*0c51296cSAlp Dener             stepType = NLS_GRADIENT;
39787f595a5SBarry Smith           } else {
398a7e14dcfSSatish Balay             ++nlsP->bfgs;
399a7e14dcfSSatish Balay             stepType = NLS_BFGS;
400a7e14dcfSSatish Balay           }
401a7e14dcfSSatish Balay         }
402a7e14dcfSSatish Balay       }
40387f595a5SBarry Smith     } else {
404a7e14dcfSSatish Balay       /* Computed Newton step is descent */
405a7e14dcfSSatish Balay       switch (ksp_reason) {
406a7e14dcfSSatish Balay       case KSP_DIVERGED_NANORINF:
407a7e14dcfSSatish Balay       case KSP_DIVERGED_BREAKDOWN:
408a7e14dcfSSatish Balay       case KSP_DIVERGED_INDEFINITE_MAT:
409a7e14dcfSSatish Balay       case KSP_DIVERGED_INDEFINITE_PC:
410a7e14dcfSSatish Balay       case KSP_CONVERGED_CG_NEG_CURVE:
411a7e14dcfSSatish Balay         /* Matrix or preconditioner is indefinite; increase perturbation */
412a7e14dcfSSatish Balay         if (pert <= 0.0) {
413a7e14dcfSSatish Balay           /* Initialize the perturbation */
414a7e14dcfSSatish Balay           pert = PetscMin(nlsP->imax, PetscMax(nlsP->imin, nlsP->imfac * gnorm));
4151daac38eSTodd Munson           if (is_gltr) {
416ba7fe8fbSTodd Munson             ierr = KSPCGGLTRGetMinEig(tao->ksp, &e_min);CHKERRQ(ierr);
417a7e14dcfSSatish Balay             pert = PetscMax(pert, -e_min);
418a7e14dcfSSatish Balay           }
41987f595a5SBarry Smith         } else {
420a7e14dcfSSatish Balay           /* Increase the perturbation */
421a7e14dcfSSatish Balay           pert = PetscMin(nlsP->pmax, PetscMax(nlsP->pgfac * pert, nlsP->pmgfac * gnorm));
422a7e14dcfSSatish Balay         }
423a7e14dcfSSatish Balay         break;
424a7e14dcfSSatish Balay 
425a7e14dcfSSatish Balay       default:
426a7e14dcfSSatish Balay         /* Newton step computation is good; decrease perturbation */
427a7e14dcfSSatish Balay         pert = PetscMin(nlsP->psfac * pert, nlsP->pmsfac * gnorm);
428a7e14dcfSSatish Balay         if (pert < nlsP->pmin) {
429a7e14dcfSSatish Balay           pert = 0.0;
430a7e14dcfSSatish Balay         }
431a7e14dcfSSatish Balay         break;
432a7e14dcfSSatish Balay       }
433a7e14dcfSSatish Balay 
434a7e14dcfSSatish Balay       ++nlsP->newt;
435a7e14dcfSSatish Balay       stepType = NLS_NEWTON;
436a7e14dcfSSatish Balay     }
437a7e14dcfSSatish Balay 
438a7e14dcfSSatish Balay     /* Perform the linesearch */
439a7e14dcfSSatish Balay     fold = f;
440a7e14dcfSSatish Balay     ierr = VecCopy(tao->solution, nlsP->Xold);CHKERRQ(ierr);
441a7e14dcfSSatish Balay     ierr = VecCopy(tao->gradient, nlsP->Gold);CHKERRQ(ierr);
442a7e14dcfSSatish Balay 
443a7e14dcfSSatish Balay     ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, nlsP->D, &step, &ls_reason);CHKERRQ(ierr);
444a7e14dcfSSatish Balay     ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr);
445a7e14dcfSSatish Balay 
44687f595a5SBarry Smith     while (ls_reason != TAOLINESEARCH_SUCCESS && ls_reason != TAOLINESEARCH_SUCCESS_USER && stepType != NLS_GRADIENT) {      /* Linesearch failed */
447a7e14dcfSSatish Balay       f = fold;
448a7e14dcfSSatish Balay       ierr = VecCopy(nlsP->Xold, tao->solution);CHKERRQ(ierr);
449a7e14dcfSSatish Balay       ierr = VecCopy(nlsP->Gold, tao->gradient);CHKERRQ(ierr);
450a7e14dcfSSatish Balay 
451a7e14dcfSSatish Balay       switch(stepType) {
452a7e14dcfSSatish Balay       case NLS_NEWTON:
453a7e14dcfSSatish Balay         /* Failed to obtain acceptable iterate with Newton 1step
454a7e14dcfSSatish Balay            Update the perturbation for next time */
455a7e14dcfSSatish Balay         if (pert <= 0.0) {
456a7e14dcfSSatish Balay           /* Initialize the perturbation */
457a7e14dcfSSatish Balay           pert = PetscMin(nlsP->imax, PetscMax(nlsP->imin, nlsP->imfac * gnorm));
4581daac38eSTodd Munson           if (is_gltr) {
459ba7fe8fbSTodd Munson             ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr);
460a7e14dcfSSatish Balay             pert = PetscMax(pert, -e_min);
461a7e14dcfSSatish Balay           }
46287f595a5SBarry Smith         } else {
463a7e14dcfSSatish Balay           /* Increase the perturbation */
464a7e14dcfSSatish Balay           pert = PetscMin(nlsP->pmax, PetscMax(nlsP->pgfac * pert, nlsP->pmgfac * gnorm));
465a7e14dcfSSatish Balay         }
466a7e14dcfSSatish Balay 
467*0c51296cSAlp Dener         if (!nlsP->bfgs_pre) {
468a7e14dcfSSatish Balay           /* We don't have the bfgs matrix around and being updated
469a7e14dcfSSatish Balay              Must use gradient direction in this case */
470a7e14dcfSSatish Balay           ierr = VecCopy(tao->gradient, nlsP->D);CHKERRQ(ierr);
471a7e14dcfSSatish Balay           ++nlsP->grad;
472a7e14dcfSSatish Balay           stepType = NLS_GRADIENT;
47387f595a5SBarry Smith         } else {
474a7e14dcfSSatish Balay           /* Attempt to use the BFGS direction */
475cd929ea3SAlp Dener           ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr);
476a7e14dcfSSatish Balay           /* Check for success (descent direction) */
477a7e14dcfSSatish Balay           ierr = VecDot(tao->solution, nlsP->D, &gdx);CHKERRQ(ierr);
478a7e14dcfSSatish Balay           if ((gdx <= 0) || PetscIsInfOrNanReal(gdx)) {
479a7e14dcfSSatish Balay             /* BFGS direction is not descent or direction produced not a number
480a7e14dcfSSatish Balay                We can assert bfgsUpdates > 1 in this case
481a7e14dcfSSatish Balay                Use steepest descent direction (scaled) */
482cd929ea3SAlp Dener             ierr = MatLMVMReset(nlsP->M, PETSC_FALSE);CHKERRQ(ierr);
483a7e14dcfSSatish Balay             ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr);
484cd929ea3SAlp Dener             ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr);
485a7e14dcfSSatish Balay 
486a7e14dcfSSatish Balay             bfgsUpdates = 1;
487*0c51296cSAlp Dener             ++nlsP->grad;
488*0c51296cSAlp Dener             stepType = NLS_GRADIENT;
48987f595a5SBarry Smith           } else {
490a7e14dcfSSatish Balay             if (1 == bfgsUpdates) {
491a7e14dcfSSatish Balay               /* The first BFGS direction is always the scaled gradient */
492*0c51296cSAlp Dener               ++nlsP->grad;
493*0c51296cSAlp Dener               stepType = NLS_GRADIENT;
49487f595a5SBarry Smith             } else {
495a7e14dcfSSatish Balay               ++nlsP->bfgs;
496a7e14dcfSSatish Balay               stepType = NLS_BFGS;
497a7e14dcfSSatish Balay             }
498a7e14dcfSSatish Balay           }
499a7e14dcfSSatish Balay         }
500a7e14dcfSSatish Balay         break;
501a7e14dcfSSatish Balay 
502a7e14dcfSSatish Balay       case NLS_BFGS:
503a7e14dcfSSatish Balay         /* Can only enter if pc_type == NLS_PC_BFGS
504a7e14dcfSSatish Balay            Failed to obtain acceptable iterate with BFGS step
505a7e14dcfSSatish Balay            Attempt to use the scaled gradient direction */
506cd929ea3SAlp Dener         ierr = MatLMVMReset(nlsP->M, PETSC_FALSE);CHKERRQ(ierr);
507a7e14dcfSSatish Balay         ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr);
508cd929ea3SAlp Dener         ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr);
509a7e14dcfSSatish Balay 
510a7e14dcfSSatish Balay         bfgsUpdates = 1;
511a7e14dcfSSatish Balay         ++nlsP->grad;
512a7e14dcfSSatish Balay         stepType = NLS_GRADIENT;
513a7e14dcfSSatish Balay         break;
514a7e14dcfSSatish Balay       }
515a7e14dcfSSatish Balay       ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr);
516a7e14dcfSSatish Balay 
517a7e14dcfSSatish Balay       ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, nlsP->D, &step, &ls_reason);CHKERRQ(ierr);
518a7e14dcfSSatish Balay       ierr = TaoLineSearchGetFullStepObjective(tao->linesearch, &f_full);CHKERRQ(ierr);
519a7e14dcfSSatish Balay       ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr);
520a7e14dcfSSatish Balay     }
521a7e14dcfSSatish Balay 
52287f595a5SBarry Smith     if (ls_reason != TAOLINESEARCH_SUCCESS && ls_reason != TAOLINESEARCH_SUCCESS_USER) {
523a7e14dcfSSatish Balay       /* Failed to find an improving point */
524a7e14dcfSSatish Balay       f = fold;
525a7e14dcfSSatish Balay       ierr = VecCopy(nlsP->Xold, tao->solution);CHKERRQ(ierr);
526a7e14dcfSSatish Balay       ierr = VecCopy(nlsP->Gold, tao->gradient);CHKERRQ(ierr);
527a7e14dcfSSatish Balay       step = 0.0;
528a7e14dcfSSatish Balay       tao->reason = TAO_DIVERGED_LS_FAILURE;
529a7e14dcfSSatish Balay       break;
530a7e14dcfSSatish Balay     }
531a7e14dcfSSatish Balay 
532a7e14dcfSSatish Balay     /* Update trust region radius */
5331daac38eSTodd Munson     if (is_nash || is_stcg || is_gltr) {
534a7e14dcfSSatish Balay       switch(nlsP->update_type) {
535a7e14dcfSSatish Balay       case NLS_UPDATE_STEP:
536a7e14dcfSSatish Balay         if (stepType == NLS_NEWTON) {
537a7e14dcfSSatish Balay           if (step < nlsP->nu1) {
538a7e14dcfSSatish Balay             /* Very bad step taken; reduce radius */
539a7e14dcfSSatish Balay             tao->trust = nlsP->omega1 * PetscMin(norm_d, tao->trust);
54087f595a5SBarry Smith           } else if (step < nlsP->nu2) {
541a7e14dcfSSatish Balay             /* Reasonably bad step taken; reduce radius */
542a7e14dcfSSatish Balay             tao->trust = nlsP->omega2 * PetscMin(norm_d, tao->trust);
54387f595a5SBarry Smith           } else if (step < nlsP->nu3) {
544a7e14dcfSSatish Balay             /*  Reasonable step was taken; leave radius alone */
545a7e14dcfSSatish Balay             if (nlsP->omega3 < 1.0) {
546a7e14dcfSSatish Balay               tao->trust = nlsP->omega3 * PetscMin(norm_d, tao->trust);
54787f595a5SBarry Smith             } else if (nlsP->omega3 > 1.0) {
548a7e14dcfSSatish Balay               tao->trust = PetscMax(nlsP->omega3 * norm_d, tao->trust);
549a7e14dcfSSatish Balay             }
55087f595a5SBarry Smith           } else if (step < nlsP->nu4) {
551a7e14dcfSSatish Balay             /*  Full step taken; increase the radius */
552a7e14dcfSSatish Balay             tao->trust = PetscMax(nlsP->omega4 * norm_d, tao->trust);
55387f595a5SBarry Smith           } else {
554a7e14dcfSSatish Balay             /*  More than full step taken; increase the radius */
555a7e14dcfSSatish Balay             tao->trust = PetscMax(nlsP->omega5 * norm_d, tao->trust);
556a7e14dcfSSatish Balay           }
55787f595a5SBarry Smith         } else {
558a7e14dcfSSatish Balay           /*  Newton step was not good; reduce the radius */
559a7e14dcfSSatish Balay           tao->trust = nlsP->omega1 * PetscMin(norm_d, tao->trust);
560a7e14dcfSSatish Balay         }
561a7e14dcfSSatish Balay         break;
562a7e14dcfSSatish Balay 
563a7e14dcfSSatish Balay       case NLS_UPDATE_REDUCTION:
564a7e14dcfSSatish Balay         if (stepType == NLS_NEWTON) {
565a7e14dcfSSatish Balay           /*  Get predicted reduction */
566a7e14dcfSSatish Balay 
567ba7fe8fbSTodd Munson           ierr = KSPCGGetObjFcn(tao->ksp,&prered);CHKERRQ(ierr);
568a7e14dcfSSatish Balay           if (prered >= 0.0) {
569a7e14dcfSSatish Balay             /*  The predicted reduction has the wrong sign.  This cannot */
570a7e14dcfSSatish Balay             /*  happen in infinite precision arithmetic.  Step should */
571a7e14dcfSSatish Balay             /*  be rejected! */
572a7e14dcfSSatish Balay             tao->trust = nlsP->alpha1 * PetscMin(tao->trust, norm_d);
57387f595a5SBarry Smith           } else {
574a7e14dcfSSatish Balay             if (PetscIsInfOrNanReal(f_full)) {
575a7e14dcfSSatish Balay               tao->trust = nlsP->alpha1 * PetscMin(tao->trust, norm_d);
57687f595a5SBarry Smith             } else {
577a7e14dcfSSatish Balay               /*  Compute and actual reduction */
578a7e14dcfSSatish Balay               actred = fold - f_full;
579a7e14dcfSSatish Balay               prered = -prered;
580a7e14dcfSSatish Balay               if ((PetscAbsScalar(actred) <= nlsP->epsilon) &&
581a7e14dcfSSatish Balay                   (PetscAbsScalar(prered) <= nlsP->epsilon)) {
582a7e14dcfSSatish Balay                 kappa = 1.0;
58387f595a5SBarry Smith               } else {
584a7e14dcfSSatish Balay                 kappa = actred / prered;
585a7e14dcfSSatish Balay               }
586a7e14dcfSSatish Balay 
587a7e14dcfSSatish Balay               /*  Accept of reject the step and update radius */
588a7e14dcfSSatish Balay               if (kappa < nlsP->eta1) {
589a7e14dcfSSatish Balay                 /*  Very bad step */
590a7e14dcfSSatish Balay                 tao->trust = nlsP->alpha1 * PetscMin(tao->trust, norm_d);
59187f595a5SBarry Smith               } else if (kappa < nlsP->eta2) {
592a7e14dcfSSatish Balay                 /*  Marginal bad step */
593a7e14dcfSSatish Balay                 tao->trust = nlsP->alpha2 * PetscMin(tao->trust, norm_d);
59487f595a5SBarry Smith               } else if (kappa < nlsP->eta3) {
595a7e14dcfSSatish Balay                 /*  Reasonable step */
596a7e14dcfSSatish Balay                 if (nlsP->alpha3 < 1.0) {
597a7e14dcfSSatish Balay                   tao->trust = nlsP->alpha3 * PetscMin(norm_d, tao->trust);
59887f595a5SBarry Smith                 } else if (nlsP->alpha3 > 1.0) {
599a7e14dcfSSatish Balay                   tao->trust = PetscMax(nlsP->alpha3 * norm_d, tao->trust);
600a7e14dcfSSatish Balay                 }
60187f595a5SBarry Smith               } else if (kappa < nlsP->eta4) {
602a7e14dcfSSatish Balay                 /*  Good step */
603a7e14dcfSSatish Balay                 tao->trust = PetscMax(nlsP->alpha4 * norm_d, tao->trust);
60487f595a5SBarry Smith               } else {
605a7e14dcfSSatish Balay                 /*  Very good step */
606a7e14dcfSSatish Balay                 tao->trust = PetscMax(nlsP->alpha5 * norm_d, tao->trust);
607a7e14dcfSSatish Balay               }
608a7e14dcfSSatish Balay             }
609a7e14dcfSSatish Balay           }
61087f595a5SBarry Smith         } else {
611a7e14dcfSSatish Balay           /*  Newton step was not good; reduce the radius */
612a7e14dcfSSatish Balay           tao->trust = nlsP->alpha1 * PetscMin(norm_d, tao->trust);
613a7e14dcfSSatish Balay         }
614a7e14dcfSSatish Balay         break;
615a7e14dcfSSatish Balay 
616a7e14dcfSSatish Balay       default:
617a7e14dcfSSatish Balay         if (stepType == NLS_NEWTON) {
618ba7fe8fbSTodd Munson           ierr = KSPCGGetObjFcn(tao->ksp,&prered);CHKERRQ(ierr);
619a7e14dcfSSatish Balay           if (prered >= 0.0) {
620a7e14dcfSSatish Balay             /*  The predicted reduction has the wrong sign.  This cannot */
621a7e14dcfSSatish Balay             /*  happen in infinite precision arithmetic.  Step should */
622a7e14dcfSSatish Balay             /*  be rejected! */
623a7e14dcfSSatish Balay             tao->trust = nlsP->gamma1 * PetscMin(tao->trust, norm_d);
62487f595a5SBarry Smith           } else {
625a7e14dcfSSatish Balay             if (PetscIsInfOrNanReal(f_full)) {
626a7e14dcfSSatish Balay               tao->trust = nlsP->gamma1 * PetscMin(tao->trust, norm_d);
62787f595a5SBarry Smith             } else {
628a7e14dcfSSatish Balay               actred = fold - f_full;
629a7e14dcfSSatish Balay               prered = -prered;
63087f595a5SBarry Smith               if ((PetscAbsScalar(actred) <= nlsP->epsilon) && (PetscAbsScalar(prered) <= nlsP->epsilon)) {
631a7e14dcfSSatish Balay                 kappa = 1.0;
63287f595a5SBarry Smith               } else {
633a7e14dcfSSatish Balay                 kappa = actred / prered;
634a7e14dcfSSatish Balay               }
635a7e14dcfSSatish Balay 
636a7e14dcfSSatish Balay               tau_1 = nlsP->theta * gdx / (nlsP->theta * gdx - (1.0 - nlsP->theta) * prered + actred);
637a7e14dcfSSatish Balay               tau_2 = nlsP->theta * gdx / (nlsP->theta * gdx + (1.0 + nlsP->theta) * prered - actred);
638a7e14dcfSSatish Balay               tau_min = PetscMin(tau_1, tau_2);
639a7e14dcfSSatish Balay               tau_max = PetscMax(tau_1, tau_2);
640a7e14dcfSSatish Balay 
641a7e14dcfSSatish Balay               if (kappa >= 1.0 - nlsP->mu1) {
642a7e14dcfSSatish Balay                 /*  Great agreement */
643a7e14dcfSSatish Balay                 if (tau_max < 1.0) {
644a7e14dcfSSatish Balay                   tao->trust = PetscMax(tao->trust, nlsP->gamma3 * norm_d);
64587f595a5SBarry Smith                 } else if (tau_max > nlsP->gamma4) {
646a7e14dcfSSatish Balay                   tao->trust = PetscMax(tao->trust, nlsP->gamma4 * norm_d);
64787f595a5SBarry Smith                 } else {
648a7e14dcfSSatish Balay                   tao->trust = PetscMax(tao->trust, tau_max * norm_d);
649a7e14dcfSSatish Balay                 }
65087f595a5SBarry Smith               } else if (kappa >= 1.0 - nlsP->mu2) {
651a7e14dcfSSatish Balay                 /*  Good agreement */
652a7e14dcfSSatish Balay 
653a7e14dcfSSatish Balay                 if (tau_max < nlsP->gamma2) {
654a7e14dcfSSatish Balay                   tao->trust = nlsP->gamma2 * PetscMin(tao->trust, norm_d);
65587f595a5SBarry Smith                 } else if (tau_max > nlsP->gamma3) {
656a7e14dcfSSatish Balay                   tao->trust = PetscMax(tao->trust, nlsP->gamma3 * norm_d);
65787f595a5SBarry Smith                 } else if (tau_max < 1.0) {
658a7e14dcfSSatish Balay                   tao->trust = tau_max * PetscMin(tao->trust, norm_d);
65987f595a5SBarry Smith                 } else {
660a7e14dcfSSatish Balay                   tao->trust = PetscMax(tao->trust, tau_max * norm_d);
661a7e14dcfSSatish Balay                 }
66287f595a5SBarry Smith               } else {
663a7e14dcfSSatish Balay                 /*  Not good agreement */
664a7e14dcfSSatish Balay                 if (tau_min > 1.0) {
665a7e14dcfSSatish Balay                   tao->trust = nlsP->gamma2 * PetscMin(tao->trust, norm_d);
66687f595a5SBarry Smith                 } else if (tau_max < nlsP->gamma1) {
667a7e14dcfSSatish Balay                   tao->trust = nlsP->gamma1 * PetscMin(tao->trust, norm_d);
66887f595a5SBarry Smith                 } else if ((tau_min < nlsP->gamma1) && (tau_max >= 1.0)) {
669a7e14dcfSSatish Balay                   tao->trust = nlsP->gamma1 * PetscMin(tao->trust, norm_d);
67087f595a5SBarry Smith                 } else if ((tau_1 >= nlsP->gamma1) && (tau_1 < 1.0) && ((tau_2 < nlsP->gamma1) || (tau_2 >= 1.0))) {
671a7e14dcfSSatish Balay                   tao->trust = tau_1 * PetscMin(tao->trust, norm_d);
67287f595a5SBarry Smith                 } else if ((tau_2 >= nlsP->gamma1) && (tau_2 < 1.0) && ((tau_1 < nlsP->gamma1) || (tau_2 >= 1.0))) {
673a7e14dcfSSatish Balay                   tao->trust = tau_2 * PetscMin(tao->trust, norm_d);
67487f595a5SBarry Smith                 } else {
675a7e14dcfSSatish Balay                   tao->trust = tau_max * PetscMin(tao->trust, norm_d);
676a7e14dcfSSatish Balay                 }
677a7e14dcfSSatish Balay               }
678a7e14dcfSSatish Balay             }
679a7e14dcfSSatish Balay           }
68087f595a5SBarry Smith         } else {
681a7e14dcfSSatish Balay           /*  Newton step was not good; reduce the radius */
682a7e14dcfSSatish Balay           tao->trust = nlsP->gamma1 * PetscMin(norm_d, tao->trust);
683a7e14dcfSSatish Balay         }
684a7e14dcfSSatish Balay         break;
685a7e14dcfSSatish Balay       }
686a7e14dcfSSatish Balay 
687a7e14dcfSSatish Balay       /*  The radius may have been increased; modify if it is too large */
688a7e14dcfSSatish Balay       tao->trust = PetscMin(tao->trust, nlsP->max_radius);
689a7e14dcfSSatish Balay     }
690a7e14dcfSSatish Balay 
691a7e14dcfSSatish Balay     /*  Check for termination */
692a9603a14SPatrick Farrell     ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr);
69387f595a5SBarry Smith     if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1,"User provided compute function generated Not-a-Number");
694a7e14dcfSSatish Balay     needH = 1;
6953ecd9318SAlp Dener     ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr);
6963ecd9318SAlp Dener     ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr);
6973ecd9318SAlp Dener     ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr);
698a7e14dcfSSatish Balay   }
699a7e14dcfSSatish Balay   PetscFunctionReturn(0);
700a7e14dcfSSatish Balay }
701a7e14dcfSSatish Balay 
702a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
703441846f8SBarry Smith static PetscErrorCode TaoSetUp_NLS(Tao tao)
704a7e14dcfSSatish Balay {
705a7e14dcfSSatish Balay   TAO_NLS        *nlsP = (TAO_NLS *)tao->data;
706a7e14dcfSSatish Balay   PetscErrorCode ierr;
707a7e14dcfSSatish Balay 
708a7e14dcfSSatish Balay   PetscFunctionBegin;
709a7e14dcfSSatish Balay   if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr);}
710a7e14dcfSSatish Balay   if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr);}
711a7e14dcfSSatish Balay   if (!nlsP->W) {ierr = VecDuplicate(tao->solution,&nlsP->W);CHKERRQ(ierr);}
712a7e14dcfSSatish Balay   if (!nlsP->D) {ierr = VecDuplicate(tao->solution,&nlsP->D);CHKERRQ(ierr);}
713a7e14dcfSSatish Balay   if (!nlsP->Xold) {ierr = VecDuplicate(tao->solution,&nlsP->Xold);CHKERRQ(ierr);}
714a7e14dcfSSatish Balay   if (!nlsP->Gold) {ierr = VecDuplicate(tao->solution,&nlsP->Gold);CHKERRQ(ierr);}
715a7e14dcfSSatish Balay   nlsP->M = 0;
716*0c51296cSAlp Dener   nlsP->bfgs_pre = 0;
717a7e14dcfSSatish Balay   PetscFunctionReturn(0);
718a7e14dcfSSatish Balay }
719a7e14dcfSSatish Balay 
720a7e14dcfSSatish Balay /*------------------------------------------------------------*/
721441846f8SBarry Smith static PetscErrorCode TaoDestroy_NLS(Tao tao)
722a7e14dcfSSatish Balay {
723a7e14dcfSSatish Balay   TAO_NLS        *nlsP = (TAO_NLS *)tao->data;
724a7e14dcfSSatish Balay   PetscErrorCode ierr;
725a7e14dcfSSatish Balay 
726a7e14dcfSSatish Balay   PetscFunctionBegin;
727a7e14dcfSSatish Balay   if (tao->setupcalled) {
728a7e14dcfSSatish Balay     ierr = VecDestroy(&nlsP->D);CHKERRQ(ierr);
729a7e14dcfSSatish Balay     ierr = VecDestroy(&nlsP->W);CHKERRQ(ierr);
730a7e14dcfSSatish Balay     ierr = VecDestroy(&nlsP->Xold);CHKERRQ(ierr);
731a7e14dcfSSatish Balay     ierr = VecDestroy(&nlsP->Gold);CHKERRQ(ierr);
732a7e14dcfSSatish Balay   }
733a7e14dcfSSatish Balay   ierr = PetscFree(tao->data);CHKERRQ(ierr);
734a7e14dcfSSatish Balay   PetscFunctionReturn(0);
735a7e14dcfSSatish Balay }
736a7e14dcfSSatish Balay 
737a7e14dcfSSatish Balay /*------------------------------------------------------------*/
7384416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_NLS(PetscOptionItems *PetscOptionsObject,Tao tao)
739a7e14dcfSSatish Balay {
740a7e14dcfSSatish Balay   TAO_NLS        *nlsP = (TAO_NLS *)tao->data;
741a7e14dcfSSatish Balay   PetscErrorCode ierr;
742a7e14dcfSSatish Balay 
743a7e14dcfSSatish Balay   PetscFunctionBegin;
7441a1499c8SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Newton line search method for unconstrained optimization");CHKERRQ(ierr);
745a7e14dcfSSatish Balay   ierr = PetscOptionsEList("-tao_nls_init_type", "radius initialization type", "", NLS_INIT, NLS_INIT_TYPES, NLS_INIT[nlsP->init_type], &nlsP->init_type, 0);CHKERRQ(ierr);
746a7e14dcfSSatish Balay   ierr = PetscOptionsEList("-tao_nls_update_type", "radius update type", "", NLS_UPDATE, NLS_UPDATE_TYPES, NLS_UPDATE[nlsP->update_type], &nlsP->update_type, 0);CHKERRQ(ierr);
74794ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_sval", "perturbation starting value", "", nlsP->sval, &nlsP->sval,NULL);CHKERRQ(ierr);
74894ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_imin", "minimum initial perturbation", "", nlsP->imin, &nlsP->imin,NULL);CHKERRQ(ierr);
74994ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_imax", "maximum initial perturbation", "", nlsP->imax, &nlsP->imax,NULL);CHKERRQ(ierr);
75094ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_imfac", "initial merit factor", "", nlsP->imfac, &nlsP->imfac,NULL);CHKERRQ(ierr);
75194ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_pmin", "minimum perturbation", "", nlsP->pmin, &nlsP->pmin,NULL);CHKERRQ(ierr);
75294ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_pmax", "maximum perturbation", "", nlsP->pmax, &nlsP->pmax,NULL);CHKERRQ(ierr);
75394ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_pgfac", "growth factor", "", nlsP->pgfac, &nlsP->pgfac,NULL);CHKERRQ(ierr);
75494ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_psfac", "shrink factor", "", nlsP->psfac, &nlsP->psfac,NULL);CHKERRQ(ierr);
75594ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_pmgfac", "merit growth factor", "", nlsP->pmgfac, &nlsP->pmgfac,NULL);CHKERRQ(ierr);
75694ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_pmsfac", "merit shrink factor", "", nlsP->pmsfac, &nlsP->pmsfac,NULL);CHKERRQ(ierr);
75794ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_eta1", "poor steplength; reduce radius", "", nlsP->eta1, &nlsP->eta1,NULL);CHKERRQ(ierr);
75894ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_eta2", "reasonable steplength; leave radius alone", "", nlsP->eta2, &nlsP->eta2,NULL);CHKERRQ(ierr);
75994ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_eta3", "good steplength; increase radius", "", nlsP->eta3, &nlsP->eta3,NULL);CHKERRQ(ierr);
76094ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_eta4", "excellent steplength; greatly increase radius", "", nlsP->eta4, &nlsP->eta4,NULL);CHKERRQ(ierr);
76194ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_alpha1", "", "", nlsP->alpha1, &nlsP->alpha1,NULL);CHKERRQ(ierr);
76294ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_alpha2", "", "", nlsP->alpha2, &nlsP->alpha2,NULL);CHKERRQ(ierr);
76394ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_alpha3", "", "", nlsP->alpha3, &nlsP->alpha3,NULL);CHKERRQ(ierr);
76494ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_alpha4", "", "", nlsP->alpha4, &nlsP->alpha4,NULL);CHKERRQ(ierr);
76594ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_alpha5", "", "", nlsP->alpha5, &nlsP->alpha5,NULL);CHKERRQ(ierr);
76694ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_nu1", "poor steplength; reduce radius", "", nlsP->nu1, &nlsP->nu1,NULL);CHKERRQ(ierr);
76794ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_nu2", "reasonable steplength; leave radius alone", "", nlsP->nu2, &nlsP->nu2,NULL);CHKERRQ(ierr);
76894ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_nu3", "good steplength; increase radius", "", nlsP->nu3, &nlsP->nu3,NULL);CHKERRQ(ierr);
76994ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_nu4", "excellent steplength; greatly increase radius", "", nlsP->nu4, &nlsP->nu4,NULL);CHKERRQ(ierr);
77094ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_omega1", "", "", nlsP->omega1, &nlsP->omega1,NULL);CHKERRQ(ierr);
77194ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_omega2", "", "", nlsP->omega2, &nlsP->omega2,NULL);CHKERRQ(ierr);
77294ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_omega3", "", "", nlsP->omega3, &nlsP->omega3,NULL);CHKERRQ(ierr);
77394ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_omega4", "", "", nlsP->omega4, &nlsP->omega4,NULL);CHKERRQ(ierr);
77494ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_omega5", "", "", nlsP->omega5, &nlsP->omega5,NULL);CHKERRQ(ierr);
77594ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_mu1_i", "", "", nlsP->mu1_i, &nlsP->mu1_i,NULL);CHKERRQ(ierr);
77694ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_mu2_i", "", "", nlsP->mu2_i, &nlsP->mu2_i,NULL);CHKERRQ(ierr);
77794ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_gamma1_i", "", "", nlsP->gamma1_i, &nlsP->gamma1_i,NULL);CHKERRQ(ierr);
77894ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_gamma2_i", "", "", nlsP->gamma2_i, &nlsP->gamma2_i,NULL);CHKERRQ(ierr);
77994ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_gamma3_i", "", "", nlsP->gamma3_i, &nlsP->gamma3_i,NULL);CHKERRQ(ierr);
78094ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_gamma4_i", "", "", nlsP->gamma4_i, &nlsP->gamma4_i,NULL);CHKERRQ(ierr);
78194ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_theta_i", "", "", nlsP->theta_i, &nlsP->theta_i,NULL);CHKERRQ(ierr);
78294ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_mu1", "", "", nlsP->mu1, &nlsP->mu1,NULL);CHKERRQ(ierr);
78394ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_mu2", "", "", nlsP->mu2, &nlsP->mu2,NULL);CHKERRQ(ierr);
78494ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_gamma1", "", "", nlsP->gamma1, &nlsP->gamma1,NULL);CHKERRQ(ierr);
78594ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_gamma2", "", "", nlsP->gamma2, &nlsP->gamma2,NULL);CHKERRQ(ierr);
78694ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_gamma3", "", "", nlsP->gamma3, &nlsP->gamma3,NULL);CHKERRQ(ierr);
78794ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_gamma4", "", "", nlsP->gamma4, &nlsP->gamma4,NULL);CHKERRQ(ierr);
78894ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_theta", "", "", nlsP->theta, &nlsP->theta,NULL);CHKERRQ(ierr);
78994ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_min_radius", "lower bound on initial radius", "", nlsP->min_radius, &nlsP->min_radius,NULL);CHKERRQ(ierr);
79094ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_max_radius", "upper bound on radius", "", nlsP->max_radius, &nlsP->max_radius,NULL);CHKERRQ(ierr);
79194ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_nls_epsilon", "tolerance used when computing actual and predicted reduction", "", nlsP->epsilon, &nlsP->epsilon,NULL);CHKERRQ(ierr);
792a7e14dcfSSatish Balay   ierr = PetscOptionsTail();CHKERRQ(ierr);
793a7e14dcfSSatish Balay   ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr);
794a7e14dcfSSatish Balay   ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr);
795a7e14dcfSSatish Balay   PetscFunctionReturn(0);
796a7e14dcfSSatish Balay }
797a7e14dcfSSatish Balay 
798a7e14dcfSSatish Balay 
799a7e14dcfSSatish Balay /*------------------------------------------------------------*/
800441846f8SBarry Smith static PetscErrorCode TaoView_NLS(Tao tao, PetscViewer viewer)
801a7e14dcfSSatish Balay {
802a7e14dcfSSatish Balay   TAO_NLS        *nlsP = (TAO_NLS *)tao->data;
803a7e14dcfSSatish Balay   PetscBool      isascii;
804a7e14dcfSSatish Balay   PetscErrorCode ierr;
805a7e14dcfSSatish Balay 
806a7e14dcfSSatish Balay   PetscFunctionBegin;
807a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
808a7e14dcfSSatish Balay   if (isascii) {
809a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
810a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "Newton steps: %D\n", nlsP->newt);CHKERRQ(ierr);
811a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "BFGS steps: %D\n", nlsP->bfgs);CHKERRQ(ierr);
812a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", nlsP->grad);CHKERRQ(ierr);
813a7e14dcfSSatish Balay 
814a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "nls ksp atol: %D\n", nlsP->ksp_atol);CHKERRQ(ierr);
815a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "nls ksp rtol: %D\n", nlsP->ksp_rtol);CHKERRQ(ierr);
816a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "nls ksp ctol: %D\n", nlsP->ksp_ctol);CHKERRQ(ierr);
817a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "nls ksp negc: %D\n", nlsP->ksp_negc);CHKERRQ(ierr);
818a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "nls ksp dtol: %D\n", nlsP->ksp_dtol);CHKERRQ(ierr);
819a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "nls ksp iter: %D\n", nlsP->ksp_iter);CHKERRQ(ierr);
820a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "nls ksp othr: %D\n", nlsP->ksp_othr);CHKERRQ(ierr);
821a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
822a7e14dcfSSatish Balay   }
823a7e14dcfSSatish Balay   PetscFunctionReturn(0);
824a7e14dcfSSatish Balay }
825a7e14dcfSSatish Balay 
826a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
8274aa34175SJason Sarich /*MC
8284aa34175SJason Sarich   TAONLS - Newton's method with linesearch for unconstrained minimization.
8294aa34175SJason Sarich   At each iteration, the Newton line search method solves the symmetric
8304aa34175SJason Sarich   system of equations to obtain the step diretion dk:
8314aa34175SJason Sarich               Hk dk = -gk
8324aa34175SJason Sarich   a More-Thuente line search is applied on the direction dk to approximately
8334aa34175SJason Sarich   solve
8344aa34175SJason Sarich               min_t f(xk + t d_k)
8354aa34175SJason Sarich 
8364aa34175SJason Sarich     Options Database Keys:
8371daac38eSTodd Munson + -tao_nls_pc_type - "none","ahess","bfgs","petsc"
8384aa34175SJason Sarich . -tao_nls_bfgs_scale_type - "ahess","phess","bfgs"
8394aa34175SJason Sarich . -tao_nls_init_type - "constant","direction","interpolation"
8404aa34175SJason Sarich . -tao_nls_update_type - "step","direction","interpolation"
8414aa34175SJason Sarich . -tao_nls_sval - perturbation starting value
8424aa34175SJason Sarich . -tao_nls_imin - minimum initial perturbation
8434aa34175SJason Sarich . -tao_nls_imax - maximum initial perturbation
8444aa34175SJason Sarich . -tao_nls_pmin - minimum perturbation
8454aa34175SJason Sarich . -tao_nls_pmax - maximum perturbation
8464aa34175SJason Sarich . -tao_nls_pgfac - growth factor
8474aa34175SJason Sarich . -tao_nls_psfac - shrink factor
8484aa34175SJason Sarich . -tao_nls_imfac - initial merit factor
8494aa34175SJason Sarich . -tao_nls_pmgfac - merit growth factor
8504aa34175SJason Sarich . -tao_nls_pmsfac - merit shrink factor
8514aa34175SJason Sarich . -tao_nls_eta1 - poor steplength; reduce radius
8524aa34175SJason Sarich . -tao_nls_eta2 - reasonable steplength; leave radius
8534aa34175SJason Sarich . -tao_nls_eta3 - good steplength; increase readius
8544aa34175SJason Sarich . -tao_nls_eta4 - excellent steplength; greatly increase radius
8554aa34175SJason Sarich . -tao_nls_alpha1 - alpha1 reduction
8564aa34175SJason Sarich . -tao_nls_alpha2 - alpha2 reduction
8574aa34175SJason Sarich . -tao_nls_alpha3 - alpha3 reduction
8584aa34175SJason Sarich . -tao_nls_alpha4 - alpha4 reduction
8594aa34175SJason Sarich . -tao_nls_alpha - alpha5 reduction
8604aa34175SJason Sarich . -tao_nls_mu1 - mu1 interpolation update
8614aa34175SJason Sarich . -tao_nls_mu2 - mu2 interpolation update
8624aa34175SJason Sarich . -tao_nls_gamma1 - gamma1 interpolation update
8634aa34175SJason Sarich . -tao_nls_gamma2 - gamma2 interpolation update
8644aa34175SJason Sarich . -tao_nls_gamma3 - gamma3 interpolation update
8654aa34175SJason Sarich . -tao_nls_gamma4 - gamma4 interpolation update
8664aa34175SJason Sarich . -tao_nls_theta - theta interpolation update
8674aa34175SJason Sarich . -tao_nls_omega1 - omega1 step update
8684aa34175SJason Sarich . -tao_nls_omega2 - omega2 step update
8694aa34175SJason Sarich . -tao_nls_omega3 - omega3 step update
8704aa34175SJason Sarich . -tao_nls_omega4 - omega4 step update
8714aa34175SJason Sarich . -tao_nls_omega5 - omega5 step update
8721522df2eSJason Sarich . -tao_nls_mu1_i -  mu1 interpolation init factor
8731522df2eSJason Sarich . -tao_nls_mu2_i -  mu2 interpolation init factor
8741522df2eSJason Sarich . -tao_nls_gamma1_i -  gamma1 interpolation init factor
8751522df2eSJason Sarich . -tao_nls_gamma2_i -  gamma2 interpolation init factor
8761522df2eSJason Sarich . -tao_nls_gamma3_i -  gamma3 interpolation init factor
8771522df2eSJason Sarich . -tao_nls_gamma4_i -  gamma4 interpolation init factor
8781522df2eSJason Sarich - -tao_nls_theta_i -  theta interpolation init factor
8791eb8069cSJason Sarich 
8801eb8069cSJason Sarich   Level: beginner
8811522df2eSJason Sarich M*/
8824aa34175SJason Sarich 
883728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_NLS(Tao tao)
884a7e14dcfSSatish Balay {
885a7e14dcfSSatish Balay   TAO_NLS        *nlsP;
8868caf6e8cSBarry Smith   const char     *morethuente_type = TAOLINESEARCHMT;
887a7e14dcfSSatish Balay   PetscErrorCode ierr;
888a7e14dcfSSatish Balay 
889a7e14dcfSSatish Balay   PetscFunctionBegin;
8903c9e27cfSGeoffrey Irving   ierr = PetscNewLog(tao,&nlsP);CHKERRQ(ierr);
891a7e14dcfSSatish Balay 
892a7e14dcfSSatish Balay   tao->ops->setup = TaoSetUp_NLS;
893a7e14dcfSSatish Balay   tao->ops->solve = TaoSolve_NLS;
894a7e14dcfSSatish Balay   tao->ops->view = TaoView_NLS;
895a7e14dcfSSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_NLS;
896a7e14dcfSSatish Balay   tao->ops->destroy = TaoDestroy_NLS;
897a7e14dcfSSatish Balay 
8986552cf8aSJason Sarich   /* Override default settings (unless already changed) */
8996552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 50;
9006552cf8aSJason Sarich   if (!tao->trust0_changed) tao->trust0 = 100.0;
9016552cf8aSJason Sarich 
902a7e14dcfSSatish Balay   tao->data = (void*)nlsP;
903a7e14dcfSSatish Balay 
904a7e14dcfSSatish Balay   nlsP->sval   = 0.0;
905a7e14dcfSSatish Balay   nlsP->imin   = 1.0e-4;
906a7e14dcfSSatish Balay   nlsP->imax   = 1.0e+2;
907a7e14dcfSSatish Balay   nlsP->imfac  = 1.0e-1;
908a7e14dcfSSatish Balay 
909a7e14dcfSSatish Balay   nlsP->pmin   = 1.0e-12;
910a7e14dcfSSatish Balay   nlsP->pmax   = 1.0e+2;
911a7e14dcfSSatish Balay   nlsP->pgfac  = 1.0e+1;
912a7e14dcfSSatish Balay   nlsP->psfac  = 4.0e-1;
913a7e14dcfSSatish Balay   nlsP->pmgfac = 1.0e-1;
914a7e14dcfSSatish Balay   nlsP->pmsfac = 1.0e-1;
915a7e14dcfSSatish Balay 
916a7e14dcfSSatish Balay   /*  Default values for trust-region radius update based on steplength */
917a7e14dcfSSatish Balay   nlsP->nu1 = 0.25;
918a7e14dcfSSatish Balay   nlsP->nu2 = 0.50;
919a7e14dcfSSatish Balay   nlsP->nu3 = 1.00;
920a7e14dcfSSatish Balay   nlsP->nu4 = 1.25;
921a7e14dcfSSatish Balay 
922a7e14dcfSSatish Balay   nlsP->omega1 = 0.25;
923a7e14dcfSSatish Balay   nlsP->omega2 = 0.50;
924a7e14dcfSSatish Balay   nlsP->omega3 = 1.00;
925a7e14dcfSSatish Balay   nlsP->omega4 = 2.00;
926a7e14dcfSSatish Balay   nlsP->omega5 = 4.00;
927a7e14dcfSSatish Balay 
928a7e14dcfSSatish Balay   /*  Default values for trust-region radius update based on reduction */
929a7e14dcfSSatish Balay   nlsP->eta1 = 1.0e-4;
930a7e14dcfSSatish Balay   nlsP->eta2 = 0.25;
931a7e14dcfSSatish Balay   nlsP->eta3 = 0.50;
932a7e14dcfSSatish Balay   nlsP->eta4 = 0.90;
933a7e14dcfSSatish Balay 
934a7e14dcfSSatish Balay   nlsP->alpha1 = 0.25;
935a7e14dcfSSatish Balay   nlsP->alpha2 = 0.50;
936a7e14dcfSSatish Balay   nlsP->alpha3 = 1.00;
937a7e14dcfSSatish Balay   nlsP->alpha4 = 2.00;
938a7e14dcfSSatish Balay   nlsP->alpha5 = 4.00;
939a7e14dcfSSatish Balay 
940a7e14dcfSSatish Balay   /*  Default values for trust-region radius update based on interpolation */
941a7e14dcfSSatish Balay   nlsP->mu1 = 0.10;
942a7e14dcfSSatish Balay   nlsP->mu2 = 0.50;
943a7e14dcfSSatish Balay 
944a7e14dcfSSatish Balay   nlsP->gamma1 = 0.25;
945a7e14dcfSSatish Balay   nlsP->gamma2 = 0.50;
946a7e14dcfSSatish Balay   nlsP->gamma3 = 2.00;
947a7e14dcfSSatish Balay   nlsP->gamma4 = 4.00;
948a7e14dcfSSatish Balay 
949a7e14dcfSSatish Balay   nlsP->theta = 0.05;
950a7e14dcfSSatish Balay 
951a7e14dcfSSatish Balay   /*  Default values for trust region initialization based on interpolation */
952a7e14dcfSSatish Balay   nlsP->mu1_i = 0.35;
953a7e14dcfSSatish Balay   nlsP->mu2_i = 0.50;
954a7e14dcfSSatish Balay 
955a7e14dcfSSatish Balay   nlsP->gamma1_i = 0.0625;
956a7e14dcfSSatish Balay   nlsP->gamma2_i = 0.5;
957a7e14dcfSSatish Balay   nlsP->gamma3_i = 2.0;
958a7e14dcfSSatish Balay   nlsP->gamma4_i = 5.0;
959a7e14dcfSSatish Balay 
960a7e14dcfSSatish Balay   nlsP->theta_i = 0.25;
961a7e14dcfSSatish Balay 
962a7e14dcfSSatish Balay   /*  Remaining parameters */
963a7e14dcfSSatish Balay   nlsP->min_radius = 1.0e-10;
964a7e14dcfSSatish Balay   nlsP->max_radius = 1.0e10;
965a7e14dcfSSatish Balay   nlsP->epsilon = 1.0e-6;
966a7e14dcfSSatish Balay 
967a7e14dcfSSatish Balay   nlsP->init_type       = NLS_INIT_INTERPOLATION;
968a7e14dcfSSatish Balay   nlsP->update_type     = NLS_UPDATE_STEP;
969a7e14dcfSSatish Balay 
970a7e14dcfSSatish Balay   ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr);
97163b15415SAlp Dener   ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr);
972a7e14dcfSSatish Balay   ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr);
973441846f8SBarry Smith   ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr);
9745d527766SPatrick Farrell   ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr);
975a7e14dcfSSatish Balay 
976a7e14dcfSSatish Balay   /*  Set linear solver to default for symmetric matrices */
977a7e14dcfSSatish Balay   ierr = KSPCreate(((PetscObject)tao)->comm,&tao->ksp);CHKERRQ(ierr);
97863b15415SAlp Dener   ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1);CHKERRQ(ierr);
9795d527766SPatrick Farrell   ierr = KSPSetOptionsPrefix(tao->ksp,tao->hdr.prefix);CHKERRQ(ierr);
9801daac38eSTodd Munson   ierr = KSPSetType(tao->ksp,KSPCGSTCG);CHKERRQ(ierr);
981a7e14dcfSSatish Balay   PetscFunctionReturn(0);
982a7e14dcfSSatish Balay }
983