1eb910715SAlp Dener #include <petsctaolinesearch.h> 2eb910715SAlp Dener #include <../src/tao/bound/impls/bnk/bnk.h> 3eb910715SAlp Dener 4eb910715SAlp Dener #include <petscksp.h> 5eb910715SAlp Dener 6e031d6f5SAlp Dener static const char *BNK_INIT[64] = {"constant", "direction", "interpolation"}; 7e031d6f5SAlp Dener static const char *BNK_UPDATE[64] = {"step", "reduction", "interpolation"}; 8e031d6f5SAlp Dener static const char *BNK_AS[64] = {"none", "bertsekas"}; 9e031d6f5SAlp Dener 10e031d6f5SAlp Dener /*------------------------------------------------------------*/ 11e031d6f5SAlp Dener 12cd929ea3SAlp Dener PetscErrorCode TaoBNKPreconBFGS(PC BFGSpc, Vec X, Vec Y) 13eb910715SAlp Dener { 14eb910715SAlp Dener PetscErrorCode ierr; 15cd929ea3SAlp Dener Mat *M; 16eb910715SAlp Dener 17eb910715SAlp Dener PetscFunctionBegin; 18cd929ea3SAlp Dener ierr = PCShellGetContext(BFGSpc, (void**)&M);CHKERRQ(ierr); 19cd929ea3SAlp Dener ierr = MatSolve(*M, X, Y);CHKERRQ(ierr); 20eb910715SAlp Dener PetscFunctionReturn(0); 21eb910715SAlp Dener } 22eb910715SAlp Dener 23df278d8fSAlp Dener /*------------------------------------------------------------*/ 24df278d8fSAlp Dener 25df278d8fSAlp Dener /* Routine for initializing the KSP solver, the BFGS preconditioner, and the initial trust radius estimation */ 26df278d8fSAlp Dener 27c0f10754SAlp Dener PetscErrorCode TaoBNKInitialize(Tao tao, PetscInt initType, PetscBool *needH) 28eb910715SAlp Dener { 29eb910715SAlp Dener PetscErrorCode ierr; 30eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 31eb910715SAlp Dener PC pc; 32eb910715SAlp Dener 3389da521bSAlp Dener PetscReal f_min, ftrial, prered, actred, kappa, sigma, resnorm; 34eb910715SAlp Dener PetscReal tau, tau_1, tau_2, tau_max, tau_min, max_radius; 35*0ad3a497SAlp Dener PetscBool is_bfgs, is_jacobi, is_symmetric, sym_set; 36c4b75bccSAlp Dener PetscInt n, N, nDiff; 37eb910715SAlp Dener PetscInt i_max = 5; 38eb910715SAlp Dener PetscInt j_max = 1; 39eb910715SAlp Dener PetscInt i, j; 40eb910715SAlp Dener 41eb910715SAlp Dener PetscFunctionBegin; 4228017e9fSAlp Dener /* Project the current point onto the feasible set */ 4328017e9fSAlp Dener ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); 44e031d6f5SAlp Dener ierr = TaoSetVariableBounds(bnk->bncg, tao->XL, tao->XU);CHKERRQ(ierr); 45b9ac7092SAlp Dener if (tao->bounded) { 4628017e9fSAlp Dener ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr); 47cd929ea3SAlp Dener } 4828017e9fSAlp Dener 4928017e9fSAlp Dener /* Project the initial point onto the feasible region */ 503b063059SAlp Dener ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 5128017e9fSAlp Dener 5228017e9fSAlp Dener /* Check convergence criteria */ 5328017e9fSAlp Dener ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &bnk->f, bnk->unprojected_gradient);CHKERRQ(ierr); 5461be54a6SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, bnk->as_type);CHKERRQ(ierr); 5561be54a6SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->gradient);CHKERRQ(ierr); 5661be54a6SAlp Dener ierr = VecISSet(tao->gradient, bnk->active_idx, 0.0);CHKERRQ(ierr); 5708752603SAlp Dener ierr = VecNorm(tao->gradient,NORM_2,&bnk->gnorm);CHKERRQ(ierr); 5828017e9fSAlp Dener 59c0f10754SAlp Dener /* Test the initial point for convergence */ 6089da521bSAlp Dener ierr = VecFischer(tao->solution, bnk->unprojected_gradient, tao->XL, tao->XU, bnk->W);CHKERRQ(ierr); 6189da521bSAlp Dener ierr = VecNorm(bnk->W, NORM_2, &resnorm);CHKERRQ(ierr); 62b4a30f08SAlp Dener if (PetscIsInfOrNanReal(bnk->f) || PetscIsInfOrNanReal(resnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 63e031d6f5SAlp Dener ierr = TaoLogConvergenceHistory(tao,bnk->f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 64e031d6f5SAlp Dener ierr = TaoMonitor(tao,tao->niter,bnk->f,resnorm,0.0,1.0);CHKERRQ(ierr); 65c0f10754SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 66c0f10754SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 67c0f10754SAlp Dener 68e031d6f5SAlp Dener /* Reset KSP stopping reason counters */ 69eb910715SAlp Dener bnk->ksp_atol = 0; 70eb910715SAlp Dener bnk->ksp_rtol = 0; 71eb910715SAlp Dener bnk->ksp_dtol = 0; 72eb910715SAlp Dener bnk->ksp_ctol = 0; 73eb910715SAlp Dener bnk->ksp_negc = 0; 74eb910715SAlp Dener bnk->ksp_iter = 0; 75eb910715SAlp Dener bnk->ksp_othr = 0; 76eb910715SAlp Dener 77e031d6f5SAlp Dener /* Reset accepted step type counters */ 78e031d6f5SAlp Dener bnk->tot_cg_its = 0; 79e031d6f5SAlp Dener bnk->newt = 0; 80e031d6f5SAlp Dener bnk->bfgs = 0; 81e031d6f5SAlp Dener bnk->sgrad = 0; 82e031d6f5SAlp Dener bnk->grad = 0; 83e031d6f5SAlp Dener 84fed79b8eSAlp Dener /* Initialize the Hessian perturbation */ 85fed79b8eSAlp Dener bnk->pert = bnk->sval; 86fed79b8eSAlp Dener 87937a31a1SAlp Dener /* Reset initial steplength to zero (this helps BNCG reset its direction internally) */ 88937a31a1SAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 89937a31a1SAlp Dener 90e031d6f5SAlp Dener /* Allocate the vectors needed for the BFGS approximation */ 91b9ac7092SAlp Dener ierr = KSPGetPC(tao->ksp, &pc);CHKERRQ(ierr); 92b9ac7092SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)pc, PCLMVM, &is_bfgs);CHKERRQ(ierr); 93b9ac7092SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)pc, PCJACOBI, &is_jacobi);CHKERRQ(ierr); 94b9ac7092SAlp Dener if (is_bfgs) { 95b9ac7092SAlp Dener bnk->bfgs_pre = pc; 96b9ac7092SAlp Dener ierr = PCLMVMGetMatLMVM(bnk->bfgs_pre, &bnk->M);CHKERRQ(ierr); 97eb910715SAlp Dener ierr = VecGetLocalSize(tao->solution, &n);CHKERRQ(ierr); 98eb910715SAlp Dener ierr = VecGetSize(tao->solution, &N);CHKERRQ(ierr); 99b9ac7092SAlp Dener ierr = MatSetSizes(bnk->M, n, n, N, N);CHKERRQ(ierr); 100cd929ea3SAlp Dener ierr = MatLMVMAllocate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 101*0ad3a497SAlp Dener ierr = MatIsSymmetricKnown(bnk->M, &sym_set, &is_symmetric);CHKERRQ(ierr); 102*0ad3a497SAlp Dener if (!sym_set || !is_symmetric) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix in the LMVM preconditioner must be symmetric."); 103b9ac7092SAlp Dener } else if (is_jacobi) { 104b9ac7092SAlp Dener ierr = PCJacobiSetUseAbs(pc,PETSC_TRUE);CHKERRQ(ierr); 105e031d6f5SAlp Dener } 106e031d6f5SAlp Dener 107e031d6f5SAlp Dener /* Prepare the min/max vectors for safeguarding diagonal scales */ 10862675beeSAlp Dener ierr = VecSet(bnk->Diag_min, bnk->dmin);CHKERRQ(ierr); 10962675beeSAlp Dener ierr = VecSet(bnk->Diag_max, bnk->dmax);CHKERRQ(ierr); 110eb910715SAlp Dener 111eb910715SAlp Dener /* Initialize trust-region radius. The initialization is only performed 112eb910715SAlp Dener when we are using Nash, Steihaug-Toint or the Generalized Lanczos method. */ 113c0f10754SAlp Dener *needH = PETSC_TRUE; 114eb910715SAlp Dener if (bnk->is_nash || bnk->is_stcg || bnk->is_gltr) { 11562675beeSAlp Dener switch(initType) { 116eb910715SAlp Dener case BNK_INIT_CONSTANT: 117eb910715SAlp Dener /* Use the initial radius specified */ 118c0f10754SAlp Dener tao->trust = tao->trust0; 119eb910715SAlp Dener break; 120eb910715SAlp Dener 121eb910715SAlp Dener case BNK_INIT_INTERPOLATION: 122c0f10754SAlp Dener /* Use interpolation based on the initial Hessian */ 123eb910715SAlp Dener max_radius = 0.0; 12408752603SAlp Dener tao->trust = tao->trust0; 125eb910715SAlp Dener for (j = 0; j < j_max; ++j) { 1260a4511e9SAlp Dener f_min = bnk->f; 127eb910715SAlp Dener sigma = 0.0; 128eb910715SAlp Dener 129c0f10754SAlp Dener if (*needH) { 13062602cfbSAlp Dener /* Compute the Hessian at the new step, and extract the inactive subsystem */ 131e031d6f5SAlp Dener ierr = TaoBNKComputeHessian(tao);CHKERRQ(ierr); 13208752603SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, BNK_AS_NONE);CHKERRQ(ierr); 13389da521bSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 13489da521bSAlp Dener if (bnk->active_idx) { 1352ab2a32cSAlp Dener ierr = MatCreateSubMatrix(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->H_inactive);CHKERRQ(ierr); 13628017e9fSAlp Dener } else { 13708752603SAlp Dener ierr = MatDuplicate(tao->hessian, MAT_COPY_VALUES, &bnk->H_inactive);CHKERRQ(ierr); 13828017e9fSAlp Dener } 139c0f10754SAlp Dener *needH = PETSC_FALSE; 140eb910715SAlp Dener } 141eb910715SAlp Dener 142eb910715SAlp Dener for (i = 0; i < i_max; ++i) { 14362602cfbSAlp Dener /* Take a steepest descent step and snap it to bounds */ 14462602cfbSAlp Dener ierr = VecCopy(tao->solution, bnk->Xold);CHKERRQ(ierr); 14562602cfbSAlp Dener ierr = VecAXPY(tao->solution, -tao->trust/bnk->gnorm, tao->gradient);CHKERRQ(ierr); 1463b063059SAlp Dener ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 14789da521bSAlp Dener /* Compute the step we actually accepted */ 148eb910715SAlp Dener ierr = VecCopy(tao->solution, bnk->W);CHKERRQ(ierr); 14962602cfbSAlp Dener ierr = VecAXPY(bnk->W, -1.0, bnk->Xold);CHKERRQ(ierr); 15062602cfbSAlp Dener /* Compute the objective at the trial */ 15162602cfbSAlp Dener ierr = TaoComputeObjective(tao, tao->solution, &ftrial);CHKERRQ(ierr); 152b4a30f08SAlp Dener if (PetscIsInfOrNanReal(bnk->f)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 15362602cfbSAlp Dener ierr = VecCopy(bnk->Xold, tao->solution);CHKERRQ(ierr); 154eb910715SAlp Dener if (PetscIsInfOrNanReal(ftrial)) { 155eb910715SAlp Dener tau = bnk->gamma1_i; 156eb910715SAlp Dener } else { 1570a4511e9SAlp Dener if (ftrial < f_min) { 1580a4511e9SAlp Dener f_min = ftrial; 159eb910715SAlp Dener sigma = -tao->trust / bnk->gnorm; 160eb910715SAlp Dener } 16108752603SAlp Dener 162770b7498SAlp Dener /* Compute the predicted and actual reduction */ 16389da521bSAlp Dener if (bnk->active_idx) { 16408752603SAlp Dener ierr = VecGetSubVector(bnk->W, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 16508752603SAlp Dener ierr = VecGetSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 1662ab2a32cSAlp Dener } else { 16708752603SAlp Dener bnk->X_inactive = bnk->W; 16808752603SAlp Dener bnk->inactive_work = bnk->Xwork; 1692ab2a32cSAlp Dener } 17008752603SAlp Dener ierr = MatMult(bnk->H_inactive, bnk->X_inactive, bnk->inactive_work);CHKERRQ(ierr); 17108752603SAlp Dener ierr = VecDot(bnk->X_inactive, bnk->inactive_work, &prered);CHKERRQ(ierr); 17289da521bSAlp Dener if (bnk->active_idx) { 17308752603SAlp Dener ierr = VecRestoreSubVector(bnk->W, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 17408752603SAlp Dener ierr = VecRestoreSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 1752ab2a32cSAlp Dener } 176eb910715SAlp Dener prered = tao->trust * (bnk->gnorm - 0.5 * tao->trust * prered / (bnk->gnorm * bnk->gnorm)); 177eb910715SAlp Dener actred = bnk->f - ftrial; 1783105154fSTodd Munson if ((PetscAbsScalar(actred) <= bnk->epsilon) && (PetscAbsScalar(prered) <= bnk->epsilon)) { 179eb910715SAlp Dener kappa = 1.0; 1803105154fSTodd Munson } else { 181eb910715SAlp Dener kappa = actred / prered; 182eb910715SAlp Dener } 183eb910715SAlp Dener 184eb910715SAlp Dener tau_1 = bnk->theta_i * bnk->gnorm * tao->trust / (bnk->theta_i * bnk->gnorm * tao->trust + (1.0 - bnk->theta_i) * prered - actred); 185eb910715SAlp Dener tau_2 = bnk->theta_i * bnk->gnorm * tao->trust / (bnk->theta_i * bnk->gnorm * tao->trust - (1.0 + bnk->theta_i) * prered + actred); 186eb910715SAlp Dener tau_min = PetscMin(tau_1, tau_2); 187eb910715SAlp Dener tau_max = PetscMax(tau_1, tau_2); 188eb910715SAlp Dener 189eb910715SAlp Dener if (PetscAbsScalar(kappa - 1.0) <= bnk->mu1_i) { 190eb910715SAlp Dener /* Great agreement */ 191eb910715SAlp Dener max_radius = PetscMax(max_radius, tao->trust); 192eb910715SAlp Dener 193eb910715SAlp Dener if (tau_max < 1.0) { 194eb910715SAlp Dener tau = bnk->gamma3_i; 1953105154fSTodd Munson } else if (tau_max > bnk->gamma4_i) { 196eb910715SAlp Dener tau = bnk->gamma4_i; 1973105154fSTodd Munson } else { 198eb910715SAlp Dener tau = tau_max; 199eb910715SAlp Dener } 2008f8a4e06SAlp Dener } else if (PetscAbsScalar(kappa - 1.0) <= bnk->mu2_i) { 201eb910715SAlp Dener /* Good agreement */ 202eb910715SAlp Dener max_radius = PetscMax(max_radius, tao->trust); 203eb910715SAlp Dener 204eb910715SAlp Dener if (tau_max < bnk->gamma2_i) { 205eb910715SAlp Dener tau = bnk->gamma2_i; 206eb910715SAlp Dener } else if (tau_max > bnk->gamma3_i) { 207eb910715SAlp Dener tau = bnk->gamma3_i; 208eb910715SAlp Dener } else { 209eb910715SAlp Dener tau = tau_max; 210eb910715SAlp Dener } 2118f8a4e06SAlp Dener } else { 212eb910715SAlp Dener /* Not good agreement */ 213eb910715SAlp Dener if (tau_min > 1.0) { 214eb910715SAlp Dener tau = bnk->gamma2_i; 215eb910715SAlp Dener } else if (tau_max < bnk->gamma1_i) { 216eb910715SAlp Dener tau = bnk->gamma1_i; 217eb910715SAlp Dener } else if ((tau_min < bnk->gamma1_i) && (tau_max >= 1.0)) { 218eb910715SAlp Dener tau = bnk->gamma1_i; 2193105154fSTodd Munson } else if ((tau_1 >= bnk->gamma1_i) && (tau_1 < 1.0) && ((tau_2 < bnk->gamma1_i) || (tau_2 >= 1.0))) { 220eb910715SAlp Dener tau = tau_1; 2213105154fSTodd Munson } else if ((tau_2 >= bnk->gamma1_i) && (tau_2 < 1.0) && ((tau_1 < bnk->gamma1_i) || (tau_2 >= 1.0))) { 222eb910715SAlp Dener tau = tau_2; 223eb910715SAlp Dener } else { 224eb910715SAlp Dener tau = tau_max; 225eb910715SAlp Dener } 226eb910715SAlp Dener } 227eb910715SAlp Dener } 228eb910715SAlp Dener tao->trust = tau * tao->trust; 229eb910715SAlp Dener } 230eb910715SAlp Dener 2310a4511e9SAlp Dener if (f_min < bnk->f) { 232937a31a1SAlp Dener /* We accidentally found a solution better than the initial, so accept it */ 2330a4511e9SAlp Dener bnk->f = f_min; 234937a31a1SAlp Dener ierr = VecCopy(tao->solution, bnk->Xold);CHKERRQ(ierr); 235eb910715SAlp Dener ierr = VecAXPY(tao->solution,sigma,tao->gradient);CHKERRQ(ierr); 2363b063059SAlp Dener ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 237937a31a1SAlp Dener ierr = VecCopy(tao->solution, tao->stepdirection);CHKERRQ(ierr); 238937a31a1SAlp Dener ierr = VecAXPY(tao->stepdirection, -1.0, bnk->Xold);CHKERRQ(ierr); 23909164190SAlp Dener ierr = TaoComputeGradient(tao,tao->solution,bnk->unprojected_gradient);CHKERRQ(ierr); 24061be54a6SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, bnk->as_type);CHKERRQ(ierr); 24161be54a6SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->gradient);CHKERRQ(ierr); 24261be54a6SAlp Dener ierr = VecISSet(tao->gradient, bnk->active_idx, 0.0);CHKERRQ(ierr); 243937a31a1SAlp Dener /* Compute gradient at the new iterate and flip switch to compute the Hessian later */ 244c4b75bccSAlp Dener ierr = VecNorm(tao->gradient, NORM_2, &bnk->gnorm);CHKERRQ(ierr); 245c0f10754SAlp Dener *needH = PETSC_TRUE; 246937a31a1SAlp Dener /* Test the new step for convergence */ 24789da521bSAlp Dener ierr = VecFischer(tao->solution, bnk->unprojected_gradient, tao->XL, tao->XU, bnk->W);CHKERRQ(ierr); 24889da521bSAlp Dener ierr = VecNorm(bnk->W, NORM_2, &resnorm);CHKERRQ(ierr); 249b4a30f08SAlp Dener if (PetscIsInfOrNanReal(resnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 250e031d6f5SAlp Dener ierr = TaoLogConvergenceHistory(tao,bnk->f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 251e031d6f5SAlp Dener ierr = TaoMonitor(tao,tao->niter,bnk->f,resnorm,0.0,1.0);CHKERRQ(ierr); 252eb910715SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 253eb910715SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 254937a31a1SAlp Dener /* active BNCG recycling early because we have a stepdirection computed */ 255937a31a1SAlp Dener ierr = TaoBNCGSetRecycleFlag(bnk->bncg, PETSC_TRUE);CHKERRQ(ierr); 256eb910715SAlp Dener } 257eb910715SAlp Dener } 258eb910715SAlp Dener tao->trust = PetscMax(tao->trust, max_radius); 259e031d6f5SAlp Dener 260e031d6f5SAlp Dener /* Ensure that the trust radius is within the limits */ 261e031d6f5SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 262e031d6f5SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 263eb910715SAlp Dener break; 264eb910715SAlp Dener 265eb910715SAlp Dener default: 266eb910715SAlp Dener /* Norm of the first direction will initialize radius */ 267eb910715SAlp Dener tao->trust = 0.0; 268eb910715SAlp Dener break; 269eb910715SAlp Dener } 270eb910715SAlp Dener } 271eb910715SAlp Dener PetscFunctionReturn(0); 272eb910715SAlp Dener } 273eb910715SAlp Dener 274df278d8fSAlp Dener /*------------------------------------------------------------*/ 275df278d8fSAlp Dener 27662675beeSAlp Dener /* Routine for computing the Hessian and preparing the preconditioner at the new iterate */ 27762675beeSAlp Dener 27862675beeSAlp Dener PetscErrorCode TaoBNKComputeHessian(Tao tao) 27962675beeSAlp Dener { 28062675beeSAlp Dener PetscErrorCode ierr; 28162675beeSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 28262675beeSAlp Dener 28362675beeSAlp Dener PetscFunctionBegin; 28462675beeSAlp Dener /* Compute the Hessian */ 28562675beeSAlp Dener ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 28662675beeSAlp Dener /* Add a correction to the BFGS preconditioner */ 287b9ac7092SAlp Dener if (bnk->M) { 28862675beeSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 28962675beeSAlp Dener } 29062675beeSAlp Dener PetscFunctionReturn(0); 29162675beeSAlp Dener } 29262675beeSAlp Dener 29362675beeSAlp Dener /*------------------------------------------------------------*/ 29462675beeSAlp Dener 2952f75a4aaSAlp Dener /* Routine for estimating the active set */ 2962f75a4aaSAlp Dener 29708752603SAlp Dener PetscErrorCode TaoBNKEstimateActiveSet(Tao tao, PetscInt asType) 2982f75a4aaSAlp Dener { 2992f75a4aaSAlp Dener PetscErrorCode ierr; 3002f75a4aaSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 301c4b75bccSAlp Dener PetscBool hessComputed, diagExists; 3022f75a4aaSAlp Dener 3032f75a4aaSAlp Dener PetscFunctionBegin; 30408752603SAlp Dener switch (asType) { 3052f75a4aaSAlp Dener case BNK_AS_NONE: 3062f75a4aaSAlp Dener ierr = ISDestroy(&bnk->inactive_idx);CHKERRQ(ierr); 3072f75a4aaSAlp Dener ierr = VecWhichInactive(tao->XL, tao->solution, bnk->unprojected_gradient, tao->XU, PETSC_TRUE, &bnk->inactive_idx);CHKERRQ(ierr); 3082f75a4aaSAlp Dener ierr = ISDestroy(&bnk->active_idx);CHKERRQ(ierr); 3092f75a4aaSAlp Dener ierr = ISComplementVec(bnk->inactive_idx, tao->solution, &bnk->active_idx);CHKERRQ(ierr); 3102f75a4aaSAlp Dener break; 3112f75a4aaSAlp Dener 3122f75a4aaSAlp Dener case BNK_AS_BERTSEKAS: 3132f75a4aaSAlp Dener /* Compute the trial step vector with which we will estimate the active set at the next iteration */ 314b9ac7092SAlp Dener if (bnk->M) { 3152f75a4aaSAlp Dener /* If the BFGS preconditioner matrix is available, we will construct a trial step with it */ 316cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, bnk->W);CHKERRQ(ierr); 3172f75a4aaSAlp Dener } else { 31861be54a6SAlp Dener ierr = MatAssembled(tao->hessian, &hessComputed);CHKERRQ(ierr); 319c4b75bccSAlp Dener ierr = MatHasOperation(tao->hessian, MATOP_GET_DIAGONAL, &diagExists);CHKERRQ(ierr); 320c4b75bccSAlp Dener if (hessComputed && diagExists) { 3219b6ef848SAlp Dener /* BFGS preconditioner doesn't exist so let's invert the absolute diagonal of the Hessian instead onto the gradient */ 3222f75a4aaSAlp Dener ierr = MatGetDiagonal(tao->hessian, bnk->Xwork);CHKERRQ(ierr); 3239b6ef848SAlp Dener ierr = VecAbs(bnk->Xwork);CHKERRQ(ierr); 3249b6ef848SAlp Dener ierr = VecMedian(bnk->Diag_min, bnk->Xwork, bnk->Diag_max, bnk->Xwork);CHKERRQ(ierr); 3252f75a4aaSAlp Dener ierr = VecReciprocal(bnk->Xwork);CHKERRQ(ierr);CHKERRQ(ierr); 3262f75a4aaSAlp Dener ierr = VecPointwiseMult(bnk->W, bnk->Xwork, bnk->unprojected_gradient);CHKERRQ(ierr); 32761be54a6SAlp Dener } else { 328c4b75bccSAlp Dener /* If the Hessian or its diagonal does not exist, we will simply use gradient step */ 32961be54a6SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, bnk->W);CHKERRQ(ierr); 33061be54a6SAlp Dener } 3312f75a4aaSAlp Dener } 3322f75a4aaSAlp Dener ierr = VecScale(bnk->W, -1.0);CHKERRQ(ierr); 33389da521bSAlp Dener ierr = TaoEstimateActiveBounds(tao->solution, tao->XL, tao->XU, bnk->unprojected_gradient, bnk->W, bnk->Xwork, bnk->as_step, &bnk->as_tol, 33489da521bSAlp Dener &bnk->active_lower, &bnk->active_upper, &bnk->active_fixed, &bnk->active_idx, &bnk->inactive_idx);CHKERRQ(ierr); 335c4b75bccSAlp Dener break; 3362f75a4aaSAlp Dener 3372f75a4aaSAlp Dener default: 3382f75a4aaSAlp Dener break; 3392f75a4aaSAlp Dener } 3402f75a4aaSAlp Dener PetscFunctionReturn(0); 3412f75a4aaSAlp Dener } 3422f75a4aaSAlp Dener 3432f75a4aaSAlp Dener /*------------------------------------------------------------*/ 3442f75a4aaSAlp Dener 3452f75a4aaSAlp Dener /* Routine for bounding the step direction */ 3462f75a4aaSAlp Dener 347a1318120SAlp Dener PetscErrorCode TaoBNKBoundStep(Tao tao, PetscInt asType, Vec step) 3482f75a4aaSAlp Dener { 3492f75a4aaSAlp Dener PetscErrorCode ierr; 3502f75a4aaSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 3512f75a4aaSAlp Dener 3522f75a4aaSAlp Dener PetscFunctionBegin; 353a1318120SAlp Dener switch (asType) { 3542f75a4aaSAlp Dener case BNK_AS_NONE: 355c4b75bccSAlp Dener ierr = VecISSet(step, bnk->active_idx, 0.0);CHKERRQ(ierr); 3562f75a4aaSAlp Dener break; 3572f75a4aaSAlp Dener 3582f75a4aaSAlp Dener case BNK_AS_BERTSEKAS: 359c4b75bccSAlp Dener ierr = TaoBoundStep(tao->solution, tao->XL, tao->XU, bnk->active_lower, bnk->active_upper, bnk->active_fixed, 1.0, step);CHKERRQ(ierr); 3602f75a4aaSAlp Dener break; 3612f75a4aaSAlp Dener 3622f75a4aaSAlp Dener default: 3632f75a4aaSAlp Dener break; 3642f75a4aaSAlp Dener } 3652f75a4aaSAlp Dener PetscFunctionReturn(0); 3662f75a4aaSAlp Dener } 3672f75a4aaSAlp Dener 368e031d6f5SAlp Dener /*------------------------------------------------------------*/ 369e031d6f5SAlp Dener 370e031d6f5SAlp Dener /* Routine for taking a finite number of BNCG iterations to 371e031d6f5SAlp Dener accelerate Newton convergence. 372e031d6f5SAlp Dener 373e031d6f5SAlp Dener In practice, this approach simply trades off Hessian evaluations 374e031d6f5SAlp Dener for more gradient evaluations. 375e031d6f5SAlp Dener */ 376e031d6f5SAlp Dener 377c0f10754SAlp Dener PetscErrorCode TaoBNKTakeCGSteps(Tao tao, PetscBool *terminate) 378c0f10754SAlp Dener { 379c0f10754SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 380c0f10754SAlp Dener PetscErrorCode ierr; 381c0f10754SAlp Dener 382c0f10754SAlp Dener PetscFunctionBegin; 383c0f10754SAlp Dener *terminate = PETSC_FALSE; 384c0f10754SAlp Dener if (bnk->max_cg_its > 0) { 385c4b75bccSAlp Dener /* Copy the current function value (important vectors are already shared) */ 386c0f10754SAlp Dener bnk->bncg_ctx->f = bnk->f; 387c0f10754SAlp Dener /* Take some small finite number of BNCG iterations */ 388c0f10754SAlp Dener ierr = TaoSolve(bnk->bncg);CHKERRQ(ierr); 389c0f10754SAlp Dener /* Add the number of gradient and function evaluations to the total */ 390c0f10754SAlp Dener tao->nfuncs += bnk->bncg->nfuncs; 391c0f10754SAlp Dener tao->nfuncgrads += bnk->bncg->nfuncgrads; 392c0f10754SAlp Dener tao->ngrads += bnk->bncg->ngrads; 393c0f10754SAlp Dener tao->nhess += bnk->bncg->nhess; 394e031d6f5SAlp Dener bnk->tot_cg_its += bnk->bncg->niter; 395c4b75bccSAlp Dener /* Extract the BNCG function value out and save it into BNK */ 396c0f10754SAlp Dener bnk->f = bnk->bncg_ctx->f; 397c0f10754SAlp Dener if (bnk->bncg->reason == TAO_CONVERGED_GATOL || bnk->bncg->reason == TAO_CONVERGED_GRTOL || bnk->bncg->reason == TAO_CONVERGED_GTTOL || bnk->bncg->reason == TAO_CONVERGED_MINF) { 398c0f10754SAlp Dener *terminate = PETSC_TRUE; 39961be54a6SAlp Dener } else { 40033c78596SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, bnk->as_type);CHKERRQ(ierr); 401c0f10754SAlp Dener } 402c0f10754SAlp Dener } 403c0f10754SAlp Dener PetscFunctionReturn(0); 404c0f10754SAlp Dener } 405c0f10754SAlp Dener 4062f75a4aaSAlp Dener /*------------------------------------------------------------*/ 4072f75a4aaSAlp Dener 408c0f10754SAlp Dener /* Routine for computing the Newton step. */ 409df278d8fSAlp Dener 41062675beeSAlp Dener PetscErrorCode TaoBNKComputeStep(Tao tao, PetscBool shift, KSPConvergedReason *ksp_reason) 411eb910715SAlp Dener { 412eb910715SAlp Dener PetscErrorCode ierr; 413eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 414eb910715SAlp Dener PetscInt bfgsUpdates = 0; 415eb910715SAlp Dener PetscInt kspits; 416eb910715SAlp Dener 417eb910715SAlp Dener PetscFunctionBegin; 41889da521bSAlp Dener /* If there are no inactive variables left, save some computation and return an adjusted zero step 41989da521bSAlp Dener that has (l-x) and (u-x) for lower and upper bounded variables. */ 42089da521bSAlp Dener if (!bnk->inactive_idx) { 42189da521bSAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 422a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 42389da521bSAlp Dener PetscFunctionReturn(0); 42489da521bSAlp Dener } 42589da521bSAlp Dener 4265e9b73cbSAlp Dener /* Prepare the reduced sub-matrices for the inactive set */ 42789da521bSAlp Dener if (bnk->active_idx) { 42833c78596SAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 4295e9b73cbSAlp Dener ierr = MatCreateSubMatrix(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->H_inactive);CHKERRQ(ierr); 430eb3ba6a7SAlp Dener if (tao->hessian == tao->hessian_pre) { 431eb3ba6a7SAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 432eb3ba6a7SAlp Dener } else { 43333c78596SAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 4345e9b73cbSAlp Dener ierr = MatCreateSubMatrix(tao->hessian_pre, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->Hpre_inactive);CHKERRQ(ierr); 435eb3ba6a7SAlp Dener } 436b9ac7092SAlp Dener if (bnk->bfgs_pre) { 437b9ac7092SAlp Dener ierr = PCLMVMSetIS(bnk->bfgs_pre, bnk->inactive_idx);CHKERRQ(ierr); 438b9ac7092SAlp Dener } 4392f75a4aaSAlp Dener } else { 44033c78596SAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 44133c78596SAlp Dener ierr = MatDuplicate(tao->hessian, MAT_COPY_VALUES, &bnk->H_inactive);CHKERRQ(ierr); 44262675beeSAlp Dener if (tao->hessian == tao->hessian_pre) { 44362675beeSAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 44462675beeSAlp Dener } else { 44533c78596SAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 44633c78596SAlp Dener ierr = MatDuplicate(tao->hessian_pre, MAT_COPY_VALUES, &bnk->Hpre_inactive);CHKERRQ(ierr); 44762675beeSAlp Dener } 448b9ac7092SAlp Dener if (bnk->bfgs_pre) { 449b9ac7092SAlp Dener ierr = PCLMVMClearIS(bnk->bfgs_pre);CHKERRQ(ierr); 450b9ac7092SAlp Dener } 45162675beeSAlp Dener } 45262675beeSAlp Dener 45362675beeSAlp Dener /* Shift the reduced Hessian matrix */ 45462675beeSAlp Dener if ((shift) && (bnk->pert > 0)) { 45562675beeSAlp Dener ierr = MatShift(bnk->H_inactive, bnk->pert);CHKERRQ(ierr); 45662675beeSAlp Dener if (bnk->H_inactive != bnk->Hpre_inactive) { 45762675beeSAlp Dener ierr = MatShift(bnk->Hpre_inactive, bnk->pert);CHKERRQ(ierr); 45862675beeSAlp Dener } 45962675beeSAlp Dener } 46062675beeSAlp Dener 461eb910715SAlp Dener /* Solve the Newton system of equations */ 462937a31a1SAlp Dener tao->ksp_its = 0; 4632f75a4aaSAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 4645e9b73cbSAlp Dener ierr = KSPReset(tao->ksp);CHKERRQ(ierr); 46509164190SAlp Dener ierr = KSPSetOperators(tao->ksp,bnk->H_inactive,bnk->Hpre_inactive);CHKERRQ(ierr); 4665e9b73cbSAlp Dener ierr = VecCopy(bnk->unprojected_gradient, bnk->Gwork);CHKERRQ(ierr); 46789da521bSAlp Dener if (bnk->active_idx) { 4685e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 4695e9b73cbSAlp Dener ierr = VecGetSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 4705e9b73cbSAlp Dener } else { 4715e9b73cbSAlp Dener bnk->G_inactive = bnk->unprojected_gradient; 4725e9b73cbSAlp Dener bnk->X_inactive = tao->stepdirection; 47328017e9fSAlp Dener } 474eb910715SAlp Dener if (bnk->is_nash || bnk->is_stcg || bnk->is_gltr) { 475fed79b8eSAlp Dener ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 4765e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 477eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 478eb910715SAlp Dener tao->ksp_its+=kspits; 479eb910715SAlp Dener tao->ksp_tot_its+=kspits; 480080d2917SAlp Dener ierr = KSPCGGetNormD(tao->ksp,&bnk->dnorm);CHKERRQ(ierr); 481eb910715SAlp Dener 482eb910715SAlp Dener if (0.0 == tao->trust) { 483eb910715SAlp Dener /* Radius was uninitialized; use the norm of the direction */ 484080d2917SAlp Dener if (bnk->dnorm > 0.0) { 485080d2917SAlp Dener tao->trust = bnk->dnorm; 486eb910715SAlp Dener 487eb910715SAlp Dener /* Modify the radius if it is too large or small */ 488eb910715SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 489eb910715SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 490eb910715SAlp Dener } else { 491eb910715SAlp Dener /* The direction was bad; set radius to default value and re-solve 492eb910715SAlp Dener the trust-region subproblem to get a direction */ 493eb910715SAlp Dener tao->trust = tao->trust0; 494eb910715SAlp Dener 495eb910715SAlp Dener /* Modify the radius if it is too large or small */ 496eb910715SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 497eb910715SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 498eb910715SAlp Dener 499fed79b8eSAlp Dener ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 5005e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 501eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 502eb910715SAlp Dener tao->ksp_its+=kspits; 503eb910715SAlp Dener tao->ksp_tot_its+=kspits; 504080d2917SAlp Dener ierr = KSPCGGetNormD(tao->ksp,&bnk->dnorm);CHKERRQ(ierr); 505eb910715SAlp Dener 506080d2917SAlp Dener if (bnk->dnorm == 0.0) SETERRQ(PETSC_COMM_SELF,1, "Initial direction zero"); 507eb910715SAlp Dener } 508eb910715SAlp Dener } 509eb910715SAlp Dener } else { 5105e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 511eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp, &kspits);CHKERRQ(ierr); 512eb910715SAlp Dener tao->ksp_its += kspits; 513eb910715SAlp Dener tao->ksp_tot_its+=kspits; 514eb910715SAlp Dener } 5155e9b73cbSAlp Dener /* Restore sub vectors back */ 51689da521bSAlp Dener if (bnk->active_idx) { 5175e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5185e9b73cbSAlp Dener ierr = VecRestoreSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5195e9b73cbSAlp Dener } 520770b7498SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 521fed79b8eSAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 522a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 523770b7498SAlp Dener 524770b7498SAlp Dener /* Record convergence reasons */ 525e465cd6fSAlp Dener ierr = KSPGetConvergedReason(tao->ksp, ksp_reason);CHKERRQ(ierr); 526e465cd6fSAlp Dener if (KSP_CONVERGED_ATOL == *ksp_reason) { 527770b7498SAlp Dener ++bnk->ksp_atol; 528e465cd6fSAlp Dener } else if (KSP_CONVERGED_RTOL == *ksp_reason) { 529770b7498SAlp Dener ++bnk->ksp_rtol; 530e465cd6fSAlp Dener } else if (KSP_CONVERGED_CG_CONSTRAINED == *ksp_reason) { 531770b7498SAlp Dener ++bnk->ksp_ctol; 532e465cd6fSAlp Dener } else if (KSP_CONVERGED_CG_NEG_CURVE == *ksp_reason) { 533770b7498SAlp Dener ++bnk->ksp_negc; 534e465cd6fSAlp Dener } else if (KSP_DIVERGED_DTOL == *ksp_reason) { 535770b7498SAlp Dener ++bnk->ksp_dtol; 536e465cd6fSAlp Dener } else if (KSP_DIVERGED_ITS == *ksp_reason) { 537770b7498SAlp Dener ++bnk->ksp_iter; 538770b7498SAlp Dener } else { 539770b7498SAlp Dener ++bnk->ksp_othr; 540770b7498SAlp Dener } 541fed79b8eSAlp Dener 542fed79b8eSAlp Dener /* Make sure the BFGS preconditioner is healthy */ 543b9ac7092SAlp Dener if (bnk->M) { 544cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 545b2d8c577SAlp Dener if ((KSP_DIVERGED_INDEFINITE_PC == *ksp_reason) && (bfgsUpdates > 0)) { 546fed79b8eSAlp Dener /* Preconditioner is numerically indefinite; reset the approximation. */ 547cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 54809164190SAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 549eb910715SAlp Dener } 550fed79b8eSAlp Dener } 551e465cd6fSAlp Dener PetscFunctionReturn(0); 552e465cd6fSAlp Dener } 553eb910715SAlp Dener 55462675beeSAlp Dener /*------------------------------------------------------------*/ 55562675beeSAlp Dener 5565e9b73cbSAlp Dener /* Routine for recomputing the predicted reduction for a given step vector */ 5575e9b73cbSAlp Dener 5585e9b73cbSAlp Dener PetscErrorCode TaoBNKRecomputePred(Tao tao, Vec S, PetscReal *prered) 5595e9b73cbSAlp Dener { 5605e9b73cbSAlp Dener PetscErrorCode ierr; 5615e9b73cbSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 5625e9b73cbSAlp Dener 5635e9b73cbSAlp Dener PetscFunctionBegin; 5645e9b73cbSAlp Dener /* Extract subvectors associated with the inactive set */ 56589da521bSAlp Dener if (bnk->active_idx){ 5665e9b73cbSAlp Dener ierr = VecGetSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5675e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 5685e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5695e9b73cbSAlp Dener } else { 5705e9b73cbSAlp Dener bnk->X_inactive = tao->stepdirection; 5715e9b73cbSAlp Dener bnk->inactive_work = bnk->Xwork; 5725e9b73cbSAlp Dener bnk->G_inactive = bnk->Gwork; 5735e9b73cbSAlp Dener } 5745e9b73cbSAlp Dener /* Recompute the predicted decrease based on the quadratic model */ 5755e9b73cbSAlp Dener ierr = MatMult(bnk->H_inactive, bnk->X_inactive, bnk->inactive_work);CHKERRQ(ierr); 5765e9b73cbSAlp Dener ierr = VecAYPX(bnk->inactive_work, -0.5, bnk->G_inactive);CHKERRQ(ierr); 57733c78596SAlp Dener ierr = VecDot(bnk->inactive_work, bnk->X_inactive, prered);CHKERRQ(ierr); 5785e9b73cbSAlp Dener /* Restore the sub vectors */ 57989da521bSAlp Dener if (bnk->active_idx){ 5805e9b73cbSAlp Dener ierr = VecRestoreSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5815e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 5825e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5835e9b73cbSAlp Dener } 5845e9b73cbSAlp Dener PetscFunctionReturn(0); 5855e9b73cbSAlp Dener } 5865e9b73cbSAlp Dener 5875e9b73cbSAlp Dener /*------------------------------------------------------------*/ 5885e9b73cbSAlp Dener 58962675beeSAlp Dener /* Routine for ensuring that the Newton step is a descent direction. 59062675beeSAlp Dener 59162675beeSAlp Dener The step direction falls back onto BFGS, scaled gradient and gradient steps 59262675beeSAlp Dener in the event that the Newton step fails the test. 59362675beeSAlp Dener */ 59462675beeSAlp Dener 595e465cd6fSAlp Dener PetscErrorCode TaoBNKSafeguardStep(Tao tao, KSPConvergedReason ksp_reason, PetscInt *stepType) 596e465cd6fSAlp Dener { 597e465cd6fSAlp Dener PetscErrorCode ierr; 598e465cd6fSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 599e465cd6fSAlp Dener 600b2d8c577SAlp Dener PetscReal gdx, e_min; 601e465cd6fSAlp Dener PetscInt bfgsUpdates; 602e465cd6fSAlp Dener 603e465cd6fSAlp Dener PetscFunctionBegin; 604080d2917SAlp Dener ierr = VecDot(tao->stepdirection, tao->gradient, &gdx);CHKERRQ(ierr); 605eb910715SAlp Dener if ((gdx >= 0.0) || PetscIsInfOrNanReal(gdx)) { 606eb910715SAlp Dener /* Newton step is not descent or direction produced Inf or NaN 607eb910715SAlp Dener Update the perturbation for next time */ 608eb910715SAlp Dener if (bnk->pert <= 0.0) { 609eb910715SAlp Dener /* Initialize the perturbation */ 610eb910715SAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 611eb910715SAlp Dener if (bnk->is_gltr) { 612eb910715SAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 613eb910715SAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 614eb910715SAlp Dener } 615eb910715SAlp Dener } else { 616eb910715SAlp Dener /* Increase the perturbation */ 617eb910715SAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 618eb910715SAlp Dener } 619eb910715SAlp Dener 620*0ad3a497SAlp Dener if (!bnk->M) { 621eb910715SAlp Dener /* We don't have the bfgs matrix around and updated 622eb910715SAlp Dener Must use gradient direction in this case */ 623080d2917SAlp Dener ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr); 624eb910715SAlp Dener *stepType = BNK_GRADIENT; 625eb910715SAlp Dener } else { 626eb910715SAlp Dener /* Attempt to use the BFGS direction */ 627cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 628eb910715SAlp Dener 6298d5ead36SAlp Dener /* Check for success (descent direction) 6308d5ead36SAlp Dener NOTE: Negative gdx here means not a descent direction because 6318d5ead36SAlp Dener the fall-back step is missing a negative sign. */ 632080d2917SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 6333105154fSTodd Munson if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 634eb910715SAlp Dener /* BFGS direction is not descent or direction produced not a number 635eb910715SAlp Dener We can assert bfgsUpdates > 1 in this case because 636eb910715SAlp Dener the first solve produces the scaled gradient direction, 637eb910715SAlp Dener which is guaranteed to be descent */ 638eb910715SAlp Dener 639eb910715SAlp Dener /* Use steepest descent direction (scaled) */ 640cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 64109164190SAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 642cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 643eb910715SAlp Dener 644eb910715SAlp Dener *stepType = BNK_SCALED_GRADIENT; 645eb910715SAlp Dener } else { 646cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 647eb910715SAlp Dener if (1 == bfgsUpdates) { 648eb910715SAlp Dener /* The first BFGS direction is always the scaled gradient */ 649eb910715SAlp Dener *stepType = BNK_SCALED_GRADIENT; 650eb910715SAlp Dener } else { 651eb910715SAlp Dener *stepType = BNK_BFGS; 652eb910715SAlp Dener } 653eb910715SAlp Dener } 654eb910715SAlp Dener } 6558d5ead36SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 6568d5ead36SAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 657a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 658eb910715SAlp Dener } else { 659eb910715SAlp Dener /* Computed Newton step is descent */ 660eb910715SAlp Dener switch (ksp_reason) { 661eb910715SAlp Dener case KSP_DIVERGED_NANORINF: 662eb910715SAlp Dener case KSP_DIVERGED_BREAKDOWN: 663eb910715SAlp Dener case KSP_DIVERGED_INDEFINITE_MAT: 664eb910715SAlp Dener case KSP_DIVERGED_INDEFINITE_PC: 665eb910715SAlp Dener case KSP_CONVERGED_CG_NEG_CURVE: 666eb910715SAlp Dener /* Matrix or preconditioner is indefinite; increase perturbation */ 667eb910715SAlp Dener if (bnk->pert <= 0.0) { 668eb910715SAlp Dener /* Initialize the perturbation */ 669eb910715SAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 670eb910715SAlp Dener if (bnk->is_gltr) { 671eb910715SAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp, &e_min);CHKERRQ(ierr); 672eb910715SAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 673eb910715SAlp Dener } 674eb910715SAlp Dener } else { 675eb910715SAlp Dener /* Increase the perturbation */ 676eb910715SAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 677eb910715SAlp Dener } 678eb910715SAlp Dener break; 679eb910715SAlp Dener 680eb910715SAlp Dener default: 681eb910715SAlp Dener /* Newton step computation is good; decrease perturbation */ 682eb910715SAlp Dener bnk->pert = PetscMin(bnk->psfac * bnk->pert, bnk->pmsfac * bnk->gnorm); 683eb910715SAlp Dener if (bnk->pert < bnk->pmin) { 684eb910715SAlp Dener bnk->pert = 0.0; 685eb910715SAlp Dener } 686eb910715SAlp Dener break; 687eb910715SAlp Dener } 688fed79b8eSAlp Dener *stepType = BNK_NEWTON; 689eb910715SAlp Dener } 690eb910715SAlp Dener PetscFunctionReturn(0); 691eb910715SAlp Dener } 692eb910715SAlp Dener 693df278d8fSAlp Dener /*------------------------------------------------------------*/ 694df278d8fSAlp Dener 695df278d8fSAlp Dener /* Routine for performing a bound-projected More-Thuente line search. 696df278d8fSAlp Dener 697df278d8fSAlp Dener Includes fallbacks to BFGS, scaled gradient, and unscaled gradient steps if the 698df278d8fSAlp Dener Newton step does not produce a valid step length. 699df278d8fSAlp Dener */ 700df278d8fSAlp Dener 701937a31a1SAlp Dener PetscErrorCode TaoBNKPerformLineSearch(Tao tao, PetscInt *stepType, PetscReal *steplen, TaoLineSearchConvergedReason *reason) 702c14b763aSAlp Dener { 703c14b763aSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 704c14b763aSAlp Dener PetscErrorCode ierr; 705c14b763aSAlp Dener TaoLineSearchConvergedReason ls_reason; 706c14b763aSAlp Dener 707b2d8c577SAlp Dener PetscReal e_min, gdx; 708c14b763aSAlp Dener PetscInt bfgsUpdates; 709c14b763aSAlp Dener 710c14b763aSAlp Dener PetscFunctionBegin; 711c14b763aSAlp Dener /* Perform the linesearch */ 712c14b763aSAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &bnk->f, bnk->unprojected_gradient, tao->stepdirection, steplen, &ls_reason);CHKERRQ(ierr); 713c14b763aSAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 714c14b763aSAlp Dener 715b2d8c577SAlp Dener while (ls_reason != TAOLINESEARCH_SUCCESS && ls_reason != TAOLINESEARCH_SUCCESS_USER && *stepType != BNK_SCALED_GRADIENT && *stepType != BNK_GRADIENT) { 716c14b763aSAlp Dener /* Linesearch failed, revert solution */ 717c14b763aSAlp Dener bnk->f = bnk->fold; 718c14b763aSAlp Dener ierr = VecCopy(bnk->Xold, tao->solution);CHKERRQ(ierr); 719c14b763aSAlp Dener ierr = VecCopy(bnk->unprojected_gradient_old, bnk->unprojected_gradient);CHKERRQ(ierr); 720c14b763aSAlp Dener 721937a31a1SAlp Dener switch(*stepType) { 722c14b763aSAlp Dener case BNK_NEWTON: 7238d5ead36SAlp Dener /* Failed to obtain acceptable iterate with Newton step 724c14b763aSAlp Dener Update the perturbation for next time */ 725c14b763aSAlp Dener if (bnk->pert <= 0.0) { 726c14b763aSAlp Dener /* Initialize the perturbation */ 727c14b763aSAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 728c14b763aSAlp Dener if (bnk->is_gltr) { 729c14b763aSAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 730c14b763aSAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 731c14b763aSAlp Dener } 732c14b763aSAlp Dener } else { 733c14b763aSAlp Dener /* Increase the perturbation */ 734c14b763aSAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 735c14b763aSAlp Dener } 736c14b763aSAlp Dener 737*0ad3a497SAlp Dener if (!bnk->M) { 738c14b763aSAlp Dener /* We don't have the bfgs matrix around and being updated 739c14b763aSAlp Dener Must use gradient direction in this case */ 740937a31a1SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 741937a31a1SAlp Dener *stepType = BNK_GRADIENT; 742c14b763aSAlp Dener } else { 743c14b763aSAlp Dener /* Attempt to use the BFGS direction */ 744cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 7458d5ead36SAlp Dener /* Check for success (descent direction) 7468d5ead36SAlp Dener NOTE: Negative gdx means not a descent direction because the step here is missing a negative sign. */ 747c14b763aSAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 7483105154fSTodd Munson if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 749c14b763aSAlp Dener /* BFGS direction is not descent or direction produced not a number 750c14b763aSAlp Dener We can assert bfgsUpdates > 1 in this case 751c14b763aSAlp Dener Use steepest descent direction (scaled) */ 752cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 753c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 754cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 755c14b763aSAlp Dener 756c14b763aSAlp Dener bfgsUpdates = 1; 757937a31a1SAlp Dener *stepType = BNK_SCALED_GRADIENT; 758c14b763aSAlp Dener } else { 759cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 760c14b763aSAlp Dener if (1 == bfgsUpdates) { 761c14b763aSAlp Dener /* The first BFGS direction is always the scaled gradient */ 762937a31a1SAlp Dener *stepType = BNK_SCALED_GRADIENT; 763c14b763aSAlp Dener } else { 764937a31a1SAlp Dener *stepType = BNK_BFGS; 765c14b763aSAlp Dener } 766c14b763aSAlp Dener } 767c14b763aSAlp Dener } 768c14b763aSAlp Dener break; 769c14b763aSAlp Dener 770c14b763aSAlp Dener case BNK_BFGS: 771c14b763aSAlp Dener /* Can only enter if pc_type == BNK_PC_BFGS 772c14b763aSAlp Dener Failed to obtain acceptable iterate with BFGS step 773c14b763aSAlp Dener Attempt to use the scaled gradient direction */ 774cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 775c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 776cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 777c14b763aSAlp Dener 778c14b763aSAlp Dener bfgsUpdates = 1; 779937a31a1SAlp Dener *stepType = BNK_SCALED_GRADIENT; 780c14b763aSAlp Dener break; 781c14b763aSAlp Dener } 7828d5ead36SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 7838d5ead36SAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 784a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 785c14b763aSAlp Dener 7868d5ead36SAlp Dener /* Perform one last line search with the fall-back step */ 787c14b763aSAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &bnk->f, bnk->unprojected_gradient, tao->stepdirection, steplen, &ls_reason);CHKERRQ(ierr); 788c14b763aSAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 789c14b763aSAlp Dener } 790c14b763aSAlp Dener *reason = ls_reason; 791c14b763aSAlp Dener PetscFunctionReturn(0); 792c14b763aSAlp Dener } 793c14b763aSAlp Dener 794df278d8fSAlp Dener /*------------------------------------------------------------*/ 795df278d8fSAlp Dener 796df278d8fSAlp Dener /* Routine for updating the trust radius. 797df278d8fSAlp Dener 798df278d8fSAlp Dener Function features three different update methods: 799df278d8fSAlp Dener 1) Line-search step length based 800df278d8fSAlp Dener 2) Predicted decrease on the CG quadratic model 801df278d8fSAlp Dener 3) Interpolation 802df278d8fSAlp Dener */ 803df278d8fSAlp Dener 80428017e9fSAlp Dener PetscErrorCode TaoBNKUpdateTrustRadius(Tao tao, PetscReal prered, PetscReal actred, PetscInt updateType, PetscInt stepType, PetscBool *accept) 805080d2917SAlp Dener { 806080d2917SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 807080d2917SAlp Dener PetscErrorCode ierr; 808080d2917SAlp Dener 809b1c2d0e3SAlp Dener PetscReal step, kappa; 810080d2917SAlp Dener PetscReal gdx, tau_1, tau_2, tau_min, tau_max; 811080d2917SAlp Dener 812080d2917SAlp Dener PetscFunctionBegin; 813080d2917SAlp Dener /* Update trust region radius */ 814080d2917SAlp Dener *accept = PETSC_FALSE; 81528017e9fSAlp Dener switch(updateType) { 816080d2917SAlp Dener case BNK_UPDATE_STEP: 817c14b763aSAlp Dener *accept = PETSC_TRUE; /* always accept here because line search succeeded */ 818080d2917SAlp Dener if (stepType == BNK_NEWTON) { 819080d2917SAlp Dener ierr = TaoLineSearchGetStepLength(tao->linesearch, &step);CHKERRQ(ierr); 820080d2917SAlp Dener if (step < bnk->nu1) { 821080d2917SAlp Dener /* Very bad step taken; reduce radius */ 822080d2917SAlp Dener tao->trust = bnk->omega1 * PetscMin(bnk->dnorm, tao->trust); 823080d2917SAlp Dener } else if (step < bnk->nu2) { 824080d2917SAlp Dener /* Reasonably bad step taken; reduce radius */ 825080d2917SAlp Dener tao->trust = bnk->omega2 * PetscMin(bnk->dnorm, tao->trust); 826080d2917SAlp Dener } else if (step < bnk->nu3) { 827080d2917SAlp Dener /* Reasonable step was taken; leave radius alone */ 828080d2917SAlp Dener if (bnk->omega3 < 1.0) { 829080d2917SAlp Dener tao->trust = bnk->omega3 * PetscMin(bnk->dnorm, tao->trust); 830080d2917SAlp Dener } else if (bnk->omega3 > 1.0) { 831080d2917SAlp Dener tao->trust = PetscMax(bnk->omega3 * bnk->dnorm, tao->trust); 832080d2917SAlp Dener } 833080d2917SAlp Dener } else if (step < bnk->nu4) { 834080d2917SAlp Dener /* Full step taken; increase the radius */ 835080d2917SAlp Dener tao->trust = PetscMax(bnk->omega4 * bnk->dnorm, tao->trust); 836080d2917SAlp Dener } else { 837080d2917SAlp Dener /* More than full step taken; increase the radius */ 838080d2917SAlp Dener tao->trust = PetscMax(bnk->omega5 * bnk->dnorm, tao->trust); 839080d2917SAlp Dener } 840080d2917SAlp Dener } else { 841080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 842080d2917SAlp Dener tao->trust = bnk->omega1 * PetscMin(bnk->dnorm, tao->trust); 843080d2917SAlp Dener } 844080d2917SAlp Dener break; 845080d2917SAlp Dener 846080d2917SAlp Dener case BNK_UPDATE_REDUCTION: 847080d2917SAlp Dener if (stepType == BNK_NEWTON) { 848b1c2d0e3SAlp Dener if (prered < 0.0) { 849fed79b8eSAlp Dener /* The predicted reduction has the wrong sign. This cannot 850fed79b8eSAlp Dener happen in infinite precision arithmetic. Step should 851fed79b8eSAlp Dener be rejected! */ 852080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 8533105154fSTodd Munson } else { 854b1c2d0e3SAlp Dener if (PetscIsInfOrNanReal(actred)) { 855080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 856080d2917SAlp Dener } else { 8573105154fSTodd Munson if ((PetscAbsScalar(actred) <= PetscMax(1.0, PetscAbsScalar(bnk->f))*bnk->epsilon) && (PetscAbsScalar(prered) <= PetscMax(1.0, PetscAbsScalar(bnk->f))*bnk->epsilon)) { 858080d2917SAlp Dener kappa = 1.0; 8593105154fSTodd Munson } else { 860080d2917SAlp Dener kappa = actred / prered; 861080d2917SAlp Dener } 862fed79b8eSAlp Dener 863fed79b8eSAlp Dener /* Accept or reject the step and update radius */ 864080d2917SAlp Dener if (kappa < bnk->eta1) { 865fed79b8eSAlp Dener /* Reject the step */ 866080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 8673105154fSTodd Munson } else { 868fed79b8eSAlp Dener /* Accept the step */ 869c133c014SAlp Dener *accept = PETSC_TRUE; 870c133c014SAlp Dener /* Update the trust region radius only if the computed step is at the trust radius boundary */ 8718d5ead36SAlp Dener if (bnk->dnorm == tao->trust) { 872080d2917SAlp Dener if (kappa < bnk->eta2) { 873080d2917SAlp Dener /* Marginal bad step */ 874c133c014SAlp Dener tao->trust = bnk->alpha2 * tao->trust; 8753105154fSTodd Munson } else if (kappa < bnk->eta3) { 876fed79b8eSAlp Dener /* Reasonable step */ 877fed79b8eSAlp Dener tao->trust = bnk->alpha3 * tao->trust; 8783105154fSTodd Munson } else if (kappa < bnk->eta4) { 879080d2917SAlp Dener /* Good step */ 880c133c014SAlp Dener tao->trust = bnk->alpha4 * tao->trust; 8813105154fSTodd Munson } else { 882080d2917SAlp Dener /* Very good step */ 883c133c014SAlp Dener tao->trust = bnk->alpha5 * tao->trust; 884080d2917SAlp Dener } 885c133c014SAlp Dener } 886080d2917SAlp Dener } 887080d2917SAlp Dener } 888080d2917SAlp Dener } 889080d2917SAlp Dener } else { 890080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 891080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(bnk->dnorm, tao->trust); 892080d2917SAlp Dener } 893080d2917SAlp Dener break; 894080d2917SAlp Dener 895080d2917SAlp Dener default: 896080d2917SAlp Dener if (stepType == BNK_NEWTON) { 897b1c2d0e3SAlp Dener if (prered < 0.0) { 898080d2917SAlp Dener /* The predicted reduction has the wrong sign. This cannot */ 899080d2917SAlp Dener /* happen in infinite precision arithmetic. Step should */ 900080d2917SAlp Dener /* be rejected! */ 901080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 902080d2917SAlp Dener } else { 903b1c2d0e3SAlp Dener if (PetscIsInfOrNanReal(actred)) { 904080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 905080d2917SAlp Dener } else { 906080d2917SAlp Dener if ((PetscAbsScalar(actred) <= bnk->epsilon) && (PetscAbsScalar(prered) <= bnk->epsilon)) { 907080d2917SAlp Dener kappa = 1.0; 908080d2917SAlp Dener } else { 909080d2917SAlp Dener kappa = actred / prered; 910080d2917SAlp Dener } 911080d2917SAlp Dener 912080d2917SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 913080d2917SAlp Dener tau_1 = bnk->theta * gdx / (bnk->theta * gdx - (1.0 - bnk->theta) * prered + actred); 914080d2917SAlp Dener tau_2 = bnk->theta * gdx / (bnk->theta * gdx + (1.0 + bnk->theta) * prered - actred); 915080d2917SAlp Dener tau_min = PetscMin(tau_1, tau_2); 916080d2917SAlp Dener tau_max = PetscMax(tau_1, tau_2); 917080d2917SAlp Dener 918080d2917SAlp Dener if (kappa >= 1.0 - bnk->mu1) { 919080d2917SAlp Dener /* Great agreement */ 920080d2917SAlp Dener *accept = PETSC_TRUE; 921080d2917SAlp Dener if (tau_max < 1.0) { 922080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma3 * bnk->dnorm); 923080d2917SAlp Dener } else if (tau_max > bnk->gamma4) { 924080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma4 * bnk->dnorm); 925080d2917SAlp Dener } else { 926080d2917SAlp Dener tao->trust = PetscMax(tao->trust, tau_max * bnk->dnorm); 927080d2917SAlp Dener } 928080d2917SAlp Dener } else if (kappa >= 1.0 - bnk->mu2) { 929080d2917SAlp Dener /* Good agreement */ 930080d2917SAlp Dener *accept = PETSC_TRUE; 931080d2917SAlp Dener if (tau_max < bnk->gamma2) { 932080d2917SAlp Dener tao->trust = bnk->gamma2 * PetscMin(tao->trust, bnk->dnorm); 933080d2917SAlp Dener } else if (tau_max > bnk->gamma3) { 934080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma3 * bnk->dnorm); 935080d2917SAlp Dener } else if (tau_max < 1.0) { 936080d2917SAlp Dener tao->trust = tau_max * PetscMin(tao->trust, bnk->dnorm); 937080d2917SAlp Dener } else { 938080d2917SAlp Dener tao->trust = PetscMax(tao->trust, tau_max * bnk->dnorm); 939080d2917SAlp Dener } 940080d2917SAlp Dener } else { 941080d2917SAlp Dener /* Not good agreement */ 942080d2917SAlp Dener if (tau_min > 1.0) { 943080d2917SAlp Dener tao->trust = bnk->gamma2 * PetscMin(tao->trust, bnk->dnorm); 944080d2917SAlp Dener } else if (tau_max < bnk->gamma1) { 945080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 946080d2917SAlp Dener } else if ((tau_min < bnk->gamma1) && (tau_max >= 1.0)) { 947080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 948080d2917SAlp Dener } else if ((tau_1 >= bnk->gamma1) && (tau_1 < 1.0) && ((tau_2 < bnk->gamma1) || (tau_2 >= 1.0))) { 949080d2917SAlp Dener tao->trust = tau_1 * PetscMin(tao->trust, bnk->dnorm); 950080d2917SAlp Dener } else if ((tau_2 >= bnk->gamma1) && (tau_2 < 1.0) && ((tau_1 < bnk->gamma1) || (tau_2 >= 1.0))) { 951080d2917SAlp Dener tao->trust = tau_2 * PetscMin(tao->trust, bnk->dnorm); 952080d2917SAlp Dener } else { 953080d2917SAlp Dener tao->trust = tau_max * PetscMin(tao->trust, bnk->dnorm); 954080d2917SAlp Dener } 955080d2917SAlp Dener } 956080d2917SAlp Dener } 957080d2917SAlp Dener } 958080d2917SAlp Dener } else { 959080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 960080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(bnk->dnorm, tao->trust); 961080d2917SAlp Dener } 96228017e9fSAlp Dener break; 963080d2917SAlp Dener } 964c133c014SAlp Dener /* Make sure the radius does not violate min and max settings */ 965c133c014SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 966fed79b8eSAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 967080d2917SAlp Dener PetscFunctionReturn(0); 968080d2917SAlp Dener } 969080d2917SAlp Dener 970eb910715SAlp Dener /* ---------------------------------------------------------- */ 971df278d8fSAlp Dener 97262675beeSAlp Dener PetscErrorCode TaoBNKAddStepCounts(Tao tao, PetscInt stepType) 97362675beeSAlp Dener { 97462675beeSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 97562675beeSAlp Dener 97662675beeSAlp Dener PetscFunctionBegin; 97762675beeSAlp Dener switch (stepType) { 97862675beeSAlp Dener case BNK_NEWTON: 97962675beeSAlp Dener ++bnk->newt; 98062675beeSAlp Dener break; 98162675beeSAlp Dener case BNK_BFGS: 98262675beeSAlp Dener ++bnk->bfgs; 98362675beeSAlp Dener break; 98462675beeSAlp Dener case BNK_SCALED_GRADIENT: 98562675beeSAlp Dener ++bnk->sgrad; 98662675beeSAlp Dener break; 98762675beeSAlp Dener case BNK_GRADIENT: 98862675beeSAlp Dener ++bnk->grad; 98962675beeSAlp Dener break; 99062675beeSAlp Dener default: 99162675beeSAlp Dener break; 99262675beeSAlp Dener } 99362675beeSAlp Dener PetscFunctionReturn(0); 99462675beeSAlp Dener } 99562675beeSAlp Dener 99662675beeSAlp Dener /* ---------------------------------------------------------- */ 99762675beeSAlp Dener 9989b6ef848SAlp Dener PetscErrorCode TaoSetUp_BNK(Tao tao) 999eb910715SAlp Dener { 1000eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1001eb910715SAlp Dener PetscErrorCode ierr; 10029b6ef848SAlp Dener KSPType ksp_type; 1003e031d6f5SAlp Dener PetscInt i; 1004eb910715SAlp Dener 1005eb910715SAlp Dener PetscFunctionBegin; 1006c4b75bccSAlp Dener if (!tao->gradient) { 1007c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr); 1008c4b75bccSAlp Dener } 1009c4b75bccSAlp Dener if (!tao->stepdirection) { 1010c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr); 1011c4b75bccSAlp Dener } 1012c4b75bccSAlp Dener if (!bnk->W) { 1013c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->W);CHKERRQ(ierr); 1014c4b75bccSAlp Dener } 1015c4b75bccSAlp Dener if (!bnk->Xold) { 1016c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Xold);CHKERRQ(ierr); 1017c4b75bccSAlp Dener } 1018c4b75bccSAlp Dener if (!bnk->Gold) { 1019c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Gold);CHKERRQ(ierr); 1020c4b75bccSAlp Dener } 1021c4b75bccSAlp Dener if (!bnk->Xwork) { 1022c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Xwork);CHKERRQ(ierr); 1023c4b75bccSAlp Dener } 1024c4b75bccSAlp Dener if (!bnk->Gwork) { 1025c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Gwork);CHKERRQ(ierr); 1026c4b75bccSAlp Dener } 1027c4b75bccSAlp Dener if (!bnk->unprojected_gradient) { 1028c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->unprojected_gradient);CHKERRQ(ierr); 1029c4b75bccSAlp Dener } 1030c4b75bccSAlp Dener if (!bnk->unprojected_gradient_old) { 1031c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->unprojected_gradient_old);CHKERRQ(ierr); 1032c4b75bccSAlp Dener } 1033c4b75bccSAlp Dener if (!bnk->Diag_min) { 1034c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Diag_min);CHKERRQ(ierr); 1035c4b75bccSAlp Dener } 1036c4b75bccSAlp Dener if (!bnk->Diag_max) { 1037c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Diag_max);CHKERRQ(ierr); 1038c4b75bccSAlp Dener } 1039e031d6f5SAlp Dener if (bnk->max_cg_its > 0) { 1040c4b75bccSAlp Dener /* Ensure that the important common vectors are shared between BNK and embedded BNCG */ 1041c4b75bccSAlp Dener bnk->bncg_ctx = (TAO_BNCG *)bnk->bncg->data; 104289da521bSAlp Dener ierr = PetscObjectReference((PetscObject)(bnk->unprojected_gradient_old));CHKERRQ(ierr); 104389da521bSAlp Dener ierr = VecDestroy(&bnk->bncg_ctx->unprojected_gradient_old);CHKERRQ(ierr); 104489da521bSAlp Dener bnk->bncg_ctx->unprojected_gradient_old = bnk->unprojected_gradient_old; 1045c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(bnk->unprojected_gradient));CHKERRQ(ierr); 1046c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg_ctx->unprojected_gradient);CHKERRQ(ierr); 1047c4b75bccSAlp Dener bnk->bncg_ctx->unprojected_gradient = bnk->unprojected_gradient; 1048c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(bnk->Gold));CHKERRQ(ierr); 1049c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg_ctx->G_old);CHKERRQ(ierr); 1050c4b75bccSAlp Dener bnk->bncg_ctx->G_old = bnk->Gold; 1051c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(tao->gradient));CHKERRQ(ierr); 1052c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg->gradient);CHKERRQ(ierr); 1053c4b75bccSAlp Dener bnk->bncg->gradient = tao->gradient; 1054c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(tao->stepdirection));CHKERRQ(ierr); 1055c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg->stepdirection);CHKERRQ(ierr); 1056c4b75bccSAlp Dener bnk->bncg->stepdirection = tao->stepdirection; 1057c4b75bccSAlp Dener ierr = TaoSetInitialVector(bnk->bncg, tao->solution);CHKERRQ(ierr); 1058c4b75bccSAlp Dener /* Copy over some settings from BNK into BNCG */ 1059e031d6f5SAlp Dener ierr = TaoSetMaximumIterations(bnk->bncg, bnk->max_cg_its);CHKERRQ(ierr); 1060e031d6f5SAlp Dener ierr = TaoSetTolerances(bnk->bncg, tao->gatol, tao->grtol, tao->gttol);CHKERRQ(ierr); 1061e031d6f5SAlp Dener ierr = TaoSetFunctionLowerBound(bnk->bncg, tao->fmin);CHKERRQ(ierr); 1062937a31a1SAlp Dener ierr = TaoSetConvergenceTest(bnk->bncg, tao->ops->convergencetest, tao->cnvP);CHKERRQ(ierr); 1063e031d6f5SAlp Dener ierr = TaoSetObjectiveRoutine(bnk->bncg, tao->ops->computeobjective, tao->user_objP);CHKERRQ(ierr); 1064e031d6f5SAlp Dener ierr = TaoSetGradientRoutine(bnk->bncg, tao->ops->computegradient, tao->user_gradP);CHKERRQ(ierr); 1065e031d6f5SAlp Dener ierr = TaoSetObjectiveAndGradientRoutine(bnk->bncg, tao->ops->computeobjectiveandgradient, tao->user_objgradP);CHKERRQ(ierr); 1066e031d6f5SAlp Dener ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)tao, (PetscObject)(bnk->bncg));CHKERRQ(ierr); 1067c4b75bccSAlp Dener for (i=0; i<tao->numbermonitors; ++i) { 1068e031d6f5SAlp Dener ierr = TaoSetMonitor(bnk->bncg, tao->monitor[i], tao->monitorcontext[i], tao->monitordestroy[i]);CHKERRQ(ierr); 1069e031d6f5SAlp Dener ierr = PetscObjectReference((PetscObject)(tao->monitorcontext[i]));CHKERRQ(ierr); 1070e031d6f5SAlp Dener } 1071e031d6f5SAlp Dener } 1072c0f10754SAlp Dener bnk->X_inactive = 0; 1073c0f10754SAlp Dener bnk->G_inactive = 0; 107462675beeSAlp Dener bnk->inactive_work = 0; 107562675beeSAlp Dener bnk->active_work = 0; 107662675beeSAlp Dener bnk->inactive_idx = 0; 107762675beeSAlp Dener bnk->active_idx = 0; 107862675beeSAlp Dener bnk->active_lower = 0; 107962675beeSAlp Dener bnk->active_upper = 0; 108062675beeSAlp Dener bnk->active_fixed = 0; 1081eb910715SAlp Dener bnk->M = 0; 108209164190SAlp Dener bnk->H_inactive = 0; 108309164190SAlp Dener bnk->Hpre_inactive = 0; 10849b6ef848SAlp Dener ierr = KSPGetType(tao->ksp,&ksp_type);CHKERRQ(ierr); 10859b6ef848SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGNASH,&bnk->is_nash);CHKERRQ(ierr); 10869b6ef848SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGSTCG,&bnk->is_stcg);CHKERRQ(ierr); 10879b6ef848SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGGLTR,&bnk->is_gltr);CHKERRQ(ierr); 1088eb910715SAlp Dener PetscFunctionReturn(0); 1089eb910715SAlp Dener } 1090eb910715SAlp Dener 1091eb910715SAlp Dener /*------------------------------------------------------------*/ 1092df278d8fSAlp Dener 1093eb910715SAlp Dener static PetscErrorCode TaoDestroy_BNK(Tao tao) 1094eb910715SAlp Dener { 1095eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1096eb910715SAlp Dener PetscErrorCode ierr; 1097eb910715SAlp Dener 1098eb910715SAlp Dener PetscFunctionBegin; 1099eb910715SAlp Dener if (tao->setupcalled) { 1100eb910715SAlp Dener ierr = VecDestroy(&bnk->W);CHKERRQ(ierr); 1101eb910715SAlp Dener ierr = VecDestroy(&bnk->Xold);CHKERRQ(ierr); 1102eb910715SAlp Dener ierr = VecDestroy(&bnk->Gold);CHKERRQ(ierr); 110309164190SAlp Dener ierr = VecDestroy(&bnk->Xwork);CHKERRQ(ierr); 110409164190SAlp Dener ierr = VecDestroy(&bnk->Gwork);CHKERRQ(ierr); 110509164190SAlp Dener ierr = VecDestroy(&bnk->unprojected_gradient);CHKERRQ(ierr); 110609164190SAlp Dener ierr = VecDestroy(&bnk->unprojected_gradient_old);CHKERRQ(ierr); 110762675beeSAlp Dener ierr = VecDestroy(&bnk->Diag_min);CHKERRQ(ierr); 110862675beeSAlp Dener ierr = VecDestroy(&bnk->Diag_max);CHKERRQ(ierr); 1109c4b75bccSAlp Dener } 1110ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_lower);CHKERRQ(ierr); 1111ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_upper);CHKERRQ(ierr); 1112ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_fixed);CHKERRQ(ierr); 1113ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_idx);CHKERRQ(ierr); 1114ca964c49SAlp Dener ierr = ISDestroy(&bnk->inactive_idx);CHKERRQ(ierr); 1115c4b75bccSAlp Dener if (bnk->Hpre_inactive != tao->hessian_pre && bnk->Hpre_inactive != bnk->H_inactive) { 1116c4b75bccSAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 1117c4b75bccSAlp Dener } 1118c4b75bccSAlp Dener if (bnk->H_inactive != tao->hessian) { 1119c4b75bccSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 1120c4b75bccSAlp Dener } 1121ca964c49SAlp Dener ierr = TaoDestroy(&bnk->bncg);CHKERRQ(ierr); 1122eb910715SAlp Dener ierr = PetscFree(tao->data);CHKERRQ(ierr); 1123eb910715SAlp Dener PetscFunctionReturn(0); 1124eb910715SAlp Dener } 1125eb910715SAlp Dener 1126eb910715SAlp Dener /*------------------------------------------------------------*/ 1127df278d8fSAlp Dener 1128eb910715SAlp Dener static PetscErrorCode TaoSetFromOptions_BNK(PetscOptionItems *PetscOptionsObject,Tao tao) 1129eb910715SAlp Dener { 1130eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1131eb910715SAlp Dener PetscErrorCode ierr; 1132eb910715SAlp Dener 1133eb910715SAlp Dener PetscFunctionBegin; 1134eb910715SAlp Dener ierr = PetscOptionsHead(PetscOptionsObject,"Newton line search method for unconstrained optimization");CHKERRQ(ierr); 11358d5ead36SAlp Dener ierr = PetscOptionsEList("-tao_bnk_init_type", "radius initialization type", "", BNK_INIT, BNK_INIT_TYPES, BNK_INIT[bnk->init_type], &bnk->init_type, 0);CHKERRQ(ierr); 11368d5ead36SAlp Dener ierr = PetscOptionsEList("-tao_bnk_update_type", "radius update type", "", BNK_UPDATE, BNK_UPDATE_TYPES, BNK_UPDATE[bnk->update_type], &bnk->update_type, 0);CHKERRQ(ierr); 11372f75a4aaSAlp Dener ierr = PetscOptionsEList("-tao_bnk_as_type", "active set estimation method", "", BNK_AS, BNK_AS_TYPES, BNK_AS[bnk->as_type], &bnk->as_type, 0);CHKERRQ(ierr); 1138748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_sval", "(developer) Hessian perturbation starting value", "", bnk->sval, &bnk->sval,NULL);CHKERRQ(ierr); 1139748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imin", "(developer) minimum initial Hessian perturbation", "", bnk->imin, &bnk->imin,NULL);CHKERRQ(ierr); 1140748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imax", "(developer) maximum initial Hessian perturbation", "", bnk->imax, &bnk->imax,NULL);CHKERRQ(ierr); 1141748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imfac", "(developer) initial merit factor for Hessian perturbation", "", bnk->imfac, &bnk->imfac,NULL);CHKERRQ(ierr); 1142748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmin", "(developer) minimum Hessian perturbation", "", bnk->pmin, &bnk->pmin,NULL);CHKERRQ(ierr); 1143748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmax", "(developer) maximum Hessian perturbation", "", bnk->pmax, &bnk->pmax,NULL);CHKERRQ(ierr); 1144748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pgfac", "(developer) Hessian perturbation growth factor", "", bnk->pgfac, &bnk->pgfac,NULL);CHKERRQ(ierr); 1145748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_psfac", "(developer) Hessian perturbation shrink factor", "", bnk->psfac, &bnk->psfac,NULL);CHKERRQ(ierr); 1146748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmgfac", "(developer) merit growth factor for Hessian perturbation", "", bnk->pmgfac, &bnk->pmgfac,NULL);CHKERRQ(ierr); 1147748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmsfac", "(developer) merit shrink factor for Hessian perturbation", "", bnk->pmsfac, &bnk->pmsfac,NULL);CHKERRQ(ierr); 1148748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta1", "(developer) threshold for rejecting step (-tao_bnk_update_type reduction)", "", bnk->eta1, &bnk->eta1,NULL);CHKERRQ(ierr); 1149748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta2", "(developer) threshold for accepting marginal step (-tao_bnk_update_type reduction)", "", bnk->eta2, &bnk->eta2,NULL);CHKERRQ(ierr); 1150748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta3", "(developer) threshold for accepting reasonable step (-tao_bnk_update_type reduction)", "", bnk->eta3, &bnk->eta3,NULL);CHKERRQ(ierr); 1151748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta4", "(developer) threshold for accepting good step (-tao_bnk_update_type reduction)", "", bnk->eta4, &bnk->eta4,NULL);CHKERRQ(ierr); 1152748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha1", "(developer) radius reduction factor for rejected step (-tao_bnk_update_type reduction)", "", bnk->alpha1, &bnk->alpha1,NULL);CHKERRQ(ierr); 1153748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha2", "(developer) radius reduction factor for marginally accepted bad step (-tao_bnk_update_type reduction)", "", bnk->alpha2, &bnk->alpha2,NULL);CHKERRQ(ierr); 1154748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha3", "(developer) radius increase factor for reasonable accepted step (-tao_bnk_update_type reduction)", "", bnk->alpha3, &bnk->alpha3,NULL);CHKERRQ(ierr); 1155748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha4", "(developer) radius increase factor for good accepted step (-tao_bnk_update_type reduction)", "", bnk->alpha4, &bnk->alpha4,NULL);CHKERRQ(ierr); 1156748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha5", "(developer) radius increase factor for very good accepted step (-tao_bnk_update_type reduction)", "", bnk->alpha5, &bnk->alpha5,NULL);CHKERRQ(ierr); 1157748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_nu1", "(developer) threshold for small line-search step length (-tao_bnk_update_type step)", "", bnk->nu1, &bnk->nu1,NULL);CHKERRQ(ierr); 1158748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_nu2", "(developer) threshold for reasonable line-search step length (-tao_bnk_update_type step)", "", bnk->nu2, &bnk->nu2,NULL);CHKERRQ(ierr); 1159748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_nu3", "(developer) threshold for large line-search step length (-tao_bnk_update_type step)", "", bnk->nu3, &bnk->nu3,NULL);CHKERRQ(ierr); 1160748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_nu4", "(developer) threshold for very large line-search step length (-tao_bnk_update_type step)", "", bnk->nu4, &bnk->nu4,NULL);CHKERRQ(ierr); 1161748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega1", "(developer) radius reduction factor for very small line-search step length (-tao_bnk_update_type step)", "", bnk->omega1, &bnk->omega1,NULL);CHKERRQ(ierr); 1162748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega2", "(developer) radius reduction factor for small line-search step length (-tao_bnk_update_type step)", "", bnk->omega2, &bnk->omega2,NULL);CHKERRQ(ierr); 1163748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega3", "(developer) radius factor for decent line-search step length (-tao_bnk_update_type step)", "", bnk->omega3, &bnk->omega3,NULL);CHKERRQ(ierr); 1164748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega4", "(developer) radius increase factor for large line-search step length (-tao_bnk_update_type step)", "", bnk->omega4, &bnk->omega4,NULL);CHKERRQ(ierr); 1165748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega5", "(developer) radius increase factor for very large line-search step length (-tao_bnk_update_type step)", "", bnk->omega5, &bnk->omega5,NULL);CHKERRQ(ierr); 1166748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu1_i", "(developer) threshold for accepting very good step (-tao_bnk_init_type interpolation)", "", bnk->mu1_i, &bnk->mu1_i,NULL);CHKERRQ(ierr); 1167748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu2_i", "(developer) threshold for accepting good step (-tao_bnk_init_type interpolation)", "", bnk->mu2_i, &bnk->mu2_i,NULL);CHKERRQ(ierr); 1168748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma1_i", "(developer) radius reduction factor for rejected very bad step (-tao_bnk_init_type interpolation)", "", bnk->gamma1_i, &bnk->gamma1_i,NULL);CHKERRQ(ierr); 1169748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma2_i", "(developer) radius reduction factor for rejected bad step (-tao_bnk_init_type interpolation)", "", bnk->gamma2_i, &bnk->gamma2_i,NULL);CHKERRQ(ierr); 1170748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma3_i", "(developer) radius increase factor for accepted good step (-tao_bnk_init_type interpolation)", "", bnk->gamma3_i, &bnk->gamma3_i,NULL);CHKERRQ(ierr); 1171748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma4_i", "(developer) radius increase factor for accepted very good step (-tao_bnk_init_type interpolation)", "", bnk->gamma4_i, &bnk->gamma4_i,NULL);CHKERRQ(ierr); 1172748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_theta_i", "(developer) trust region interpolation factor (-tao_bnk_init_type interpolation)", "", bnk->theta_i, &bnk->theta_i,NULL);CHKERRQ(ierr); 1173748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu1", "(developer) threshold for accepting very good step (-tao_bnk_update_type interpolation)", "", bnk->mu1, &bnk->mu1,NULL);CHKERRQ(ierr); 1174748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu2", "(developer) threshold for accepting good step (-tao_bnk_update_type interpolation)", "", bnk->mu2, &bnk->mu2,NULL);CHKERRQ(ierr); 1175748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma1", "(developer) radius reduction factor for rejected very bad step (-tao_bnk_update_type interpolation)", "", bnk->gamma1, &bnk->gamma1,NULL);CHKERRQ(ierr); 1176748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma2", "(developer) radius reduction factor for rejected bad step (-tao_bnk_update_type interpolation)", "", bnk->gamma2, &bnk->gamma2,NULL);CHKERRQ(ierr); 1177748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma3", "(developer) radius increase factor for accepted good step (-tao_bnk_update_type interpolation)", "", bnk->gamma3, &bnk->gamma3,NULL);CHKERRQ(ierr); 1178748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma4", "(developer) radius increase factor for accepted very good step (-tao_bnk_update_type interpolation)", "", bnk->gamma4, &bnk->gamma4,NULL);CHKERRQ(ierr); 1179748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_theta", "(developer) trust region interpolation factor (-tao_bnk_update_type interpolation)", "", bnk->theta, &bnk->theta,NULL);CHKERRQ(ierr); 1180748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_min_radius", "(developer) lower bound on initial radius", "", bnk->min_radius, &bnk->min_radius,NULL);CHKERRQ(ierr); 1181748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_max_radius", "(developer) upper bound on radius", "", bnk->max_radius, &bnk->max_radius,NULL);CHKERRQ(ierr); 1182748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_epsilon", "(developer) tolerance used when computing actual and predicted reduction", "", bnk->epsilon, &bnk->epsilon,NULL);CHKERRQ(ierr); 1183748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_as_tol", "(developer) initial tolerance used when estimating actively bounded variables", "", bnk->as_tol, &bnk->as_tol,NULL);CHKERRQ(ierr); 1184748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_as_step", "(developer) step length used when estimating actively bounded variables", "", bnk->as_step, &bnk->as_step,NULL);CHKERRQ(ierr); 1185c0f10754SAlp Dener ierr = PetscOptionsInt("-tao_bnk_max_cg_its", "number of BNCG iterations to take for each Newton step", "", bnk->max_cg_its, &bnk->max_cg_its,NULL);CHKERRQ(ierr); 1186eb910715SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 118733c78596SAlp Dener ierr = TaoSetFromOptions(bnk->bncg);CHKERRQ(ierr); 1188eb910715SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 1189eb910715SAlp Dener ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 1190eb910715SAlp Dener PetscFunctionReturn(0); 1191eb910715SAlp Dener } 1192eb910715SAlp Dener 1193eb910715SAlp Dener /*------------------------------------------------------------*/ 1194df278d8fSAlp Dener 1195eb910715SAlp Dener static PetscErrorCode TaoView_BNK(Tao tao, PetscViewer viewer) 1196eb910715SAlp Dener { 1197eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1198eb910715SAlp Dener PetscInt nrejects; 1199eb910715SAlp Dener PetscBool isascii; 1200eb910715SAlp Dener PetscErrorCode ierr; 1201eb910715SAlp Dener 1202eb910715SAlp Dener PetscFunctionBegin; 1203eb910715SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1204eb910715SAlp Dener if (isascii) { 1205eb910715SAlp Dener ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1206b9ac7092SAlp Dener if (bnk->M) { 1207cd929ea3SAlp Dener ierr = MatLMVMGetRejectCount(bnk->M,&nrejects);CHKERRQ(ierr); 1208b9ac7092SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Rejected BFGS updates: %D\n",nrejects);CHKERRQ(ierr); 1209eb910715SAlp Dener } 1210e031d6f5SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "CG steps: %D\n", bnk->tot_cg_its);CHKERRQ(ierr); 1211eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Newton steps: %D\n", bnk->newt);CHKERRQ(ierr); 1212b9ac7092SAlp Dener if (bnk->M) { 1213eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "BFGS steps: %D\n", bnk->bfgs);CHKERRQ(ierr); 1214b9ac7092SAlp Dener } 1215eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Scaled gradient steps: %D\n", bnk->sgrad);CHKERRQ(ierr); 1216eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", bnk->grad);CHKERRQ(ierr); 1217eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "KSP termination reasons:\n");CHKERRQ(ierr); 1218eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " atol: %D\n", bnk->ksp_atol);CHKERRQ(ierr); 1219eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " rtol: %D\n", bnk->ksp_rtol);CHKERRQ(ierr); 1220eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " ctol: %D\n", bnk->ksp_ctol);CHKERRQ(ierr); 1221eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " negc: %D\n", bnk->ksp_negc);CHKERRQ(ierr); 1222eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " dtol: %D\n", bnk->ksp_dtol);CHKERRQ(ierr); 1223eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " iter: %D\n", bnk->ksp_iter);CHKERRQ(ierr); 1224eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " othr: %D\n", bnk->ksp_othr);CHKERRQ(ierr); 1225eb910715SAlp Dener ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1226eb910715SAlp Dener } 1227eb910715SAlp Dener PetscFunctionReturn(0); 1228eb910715SAlp Dener } 1229eb910715SAlp Dener 1230eb910715SAlp Dener /* ---------------------------------------------------------- */ 1231df278d8fSAlp Dener 1232eb910715SAlp Dener /*MC 1233eb910715SAlp Dener TAOBNK - Shared base-type for Bounded Newton-Krylov type algorithms. 123466ed3702SAlp Dener At each iteration, the BNK methods solve the symmetric 1235eb910715SAlp Dener system of equations to obtain the step diretion dk: 1236eb910715SAlp Dener Hk dk = -gk 12372b97c8d8SAlp Dener for free variables only. The step can be globalized either through 12382b97c8d8SAlp Dener trust-region methods, or a line search, or a heuristic mixture of both. 1239eb910715SAlp Dener 1240eb910715SAlp Dener Options Database Keys: 1241b2d8c577SAlp Dener + -tao_bnk_max_cg_its - maximum number of bounded conjugate-gradient iterations taken in each Newton loop 12423cb832f1SAlp Dener . -tao_bnk_init_type - trust radius initialization method ("constant", "direction", "interpolation") 12433cb832f1SAlp Dener . -tao_bnk_update_type - trust radius update method ("step", "direction", "interpolation") 12443cb832f1SAlp Dener . -tao_bnk_as_type - active-set estimation method ("none", "bertsekas") 1245748696b1SAlp Dener . -tao_bnk_as_tol - (developer) initial tolerance used in estimating bounded active variables (-tao_bnk_as_type bertsekas) 1246748696b1SAlp Dener . -tao_bnk_as_step - (developer) trial step length used in estimating bounded active variables (-tao_bnk_as_type bertsekas) 1247748696b1SAlp Dener . -tao_bnk_sval - (developer) Hessian perturbation starting value 1248748696b1SAlp Dener . -tao_bnk_imin - (developer) minimum initial Hessian perturbation 1249748696b1SAlp Dener . -tao_bnk_imax - (developer) maximum initial Hessian perturbation 1250748696b1SAlp Dener . -tao_bnk_pmin - (developer) minimum Hessian perturbation 1251748696b1SAlp Dener . -tao_bnk_pmax - (developer) aximum Hessian perturbation 1252748696b1SAlp Dener . -tao_bnk_pgfac - (developer) Hessian perturbation growth factor 1253748696b1SAlp Dener . -tao_bnk_psfac - (developer) Hessian perturbation shrink factor 1254748696b1SAlp Dener . -tao_bnk_imfac - (developer) initial merit factor for Hessian perturbation 1255748696b1SAlp Dener . -tao_bnk_pmgfac - (developer) merit growth factor for Hessian perturbation 1256748696b1SAlp Dener . -tao_bnk_pmsfac - (developer) merit shrink factor for Hessian perturbation 1257748696b1SAlp Dener . -tao_bnk_eta1 - (developer) threshold for rejecting step (-tao_bnk_update_type reduction) 1258748696b1SAlp Dener . -tao_bnk_eta2 - (developer) threshold for accepting marginal step (-tao_bnk_update_type reduction) 1259748696b1SAlp Dener . -tao_bnk_eta3 - (developer) threshold for accepting reasonable step (-tao_bnk_update_type reduction) 1260748696b1SAlp Dener . -tao_bnk_eta4 - (developer) threshold for accepting good step (-tao_bnk_update_type reduction) 1261748696b1SAlp Dener . -tao_bnk_alpha1 - (developer) radius reduction factor for rejected step (-tao_bnk_update_type reduction) 1262748696b1SAlp Dener . -tao_bnk_alpha2 - (developer) radius reduction factor for marginally accepted bad step (-tao_bnk_update_type reduction) 1263748696b1SAlp Dener . -tao_bnk_alpha3 - (developer) radius increase factor for reasonable accepted step (-tao_bnk_update_type reduction) 1264748696b1SAlp Dener . -tao_bnk_alpha4 - (developer) radius increase factor for good accepted step (-tao_bnk_update_type reduction) 1265748696b1SAlp Dener . -tao_bnk_alpha5 - (developer) radius increase factor for very good accepted step (-tao_bnk_update_type reduction) 1266748696b1SAlp Dener . -tao_bnk_epsilon - (developer) tolerance for small pred/actual ratios that trigger automatic step acceptance (-tao_bnk_update_type reduction) 1267748696b1SAlp Dener . -tao_bnk_mu1 - (developer) threshold for accepting very good step (-tao_bnk_update_type interpolation) 1268748696b1SAlp Dener . -tao_bnk_mu2 - (developer) threshold for accepting good step (-tao_bnk_update_type interpolation) 1269748696b1SAlp Dener . -tao_bnk_gamma1 - (developer) radius reduction factor for rejected very bad step (-tao_bnk_update_type interpolation) 1270748696b1SAlp Dener . -tao_bnk_gamma2 - (developer) radius reduction factor for rejected bad step (-tao_bnk_update_type interpolation) 1271748696b1SAlp Dener . -tao_bnk_gamma3 - (developer) radius increase factor for accepted good step (-tao_bnk_update_type interpolation) 1272748696b1SAlp Dener . -tao_bnk_gamma4 - (developer) radius increase factor for accepted very good step (-tao_bnk_update_type interpolation) 1273748696b1SAlp Dener . -tao_bnk_theta - (developer) trust region interpolation factor (-tao_bnk_update_type interpolation) 1274748696b1SAlp Dener . -tao_bnk_nu1 - (developer) threshold for small line-search step length (-tao_bnk_update_type step) 1275748696b1SAlp Dener . -tao_bnk_nu2 - (developer) threshold for reasonable line-search step length (-tao_bnk_update_type step) 1276748696b1SAlp Dener . -tao_bnk_nu3 - (developer) threshold for large line-search step length (-tao_bnk_update_type step) 1277748696b1SAlp Dener . -tao_bnk_nu4 - (developer) threshold for very large line-search step length (-tao_bnk_update_type step) 1278748696b1SAlp Dener . -tao_bnk_omega1 - (developer) radius reduction factor for very small line-search step length (-tao_bnk_update_type step) 1279748696b1SAlp Dener . -tao_bnk_omega2 - (developer) radius reduction factor for small line-search step length (-tao_bnk_update_type step) 1280748696b1SAlp Dener . -tao_bnk_omega3 - (developer) radius factor for decent line-search step length (-tao_bnk_update_type step) 1281748696b1SAlp Dener . -tao_bnk_omega4 - (developer) radius increase factor for large line-search step length (-tao_bnk_update_type step) 1282748696b1SAlp Dener . -tao_bnk_omega5 - (developer) radius increase factor for very large line-search step length (-tao_bnk_update_type step) 1283748696b1SAlp Dener . -tao_bnk_mu1_i - (developer) threshold for accepting very good step (-tao_bnk_init_type interpolation) 1284748696b1SAlp Dener . -tao_bnk_mu2_i - (developer) threshold for accepting good step (-tao_bnk_init_type interpolation) 1285748696b1SAlp Dener . -tao_bnk_gamma1_i - (developer) radius reduction factor for rejected very bad step (-tao_bnk_init_type interpolation) 1286748696b1SAlp Dener . -tao_bnk_gamma2_i - (developer) radius reduction factor for rejected bad step (-tao_bnk_init_type interpolation) 1287748696b1SAlp Dener . -tao_bnk_gamma3_i - (developer) radius increase factor for accepted good step (-tao_bnk_init_type interpolation) 1288748696b1SAlp Dener . -tao_bnk_gamma4_i - (developer) radius increase factor for accepted very good step (-tao_bnk_init_type interpolation) 1289748696b1SAlp Dener - -tao_bnk_theta_i - (developer) trust region interpolation factor (-tao_bnk_init_type interpolation) 1290eb910715SAlp Dener 1291eb910715SAlp Dener Level: beginner 1292eb910715SAlp Dener M*/ 1293eb910715SAlp Dener 1294eb910715SAlp Dener PetscErrorCode TaoCreate_BNK(Tao tao) 1295eb910715SAlp Dener { 1296eb910715SAlp Dener TAO_BNK *bnk; 1297eb910715SAlp Dener const char *morethuente_type = TAOLINESEARCHMT; 1298eb910715SAlp Dener PetscErrorCode ierr; 1299b9ac7092SAlp Dener PC pc; 1300eb910715SAlp Dener 1301eb910715SAlp Dener PetscFunctionBegin; 1302eb910715SAlp Dener ierr = PetscNewLog(tao,&bnk);CHKERRQ(ierr); 1303eb910715SAlp Dener 1304eb910715SAlp Dener tao->ops->setup = TaoSetUp_BNK; 1305eb910715SAlp Dener tao->ops->view = TaoView_BNK; 1306eb910715SAlp Dener tao->ops->setfromoptions = TaoSetFromOptions_BNK; 1307eb910715SAlp Dener tao->ops->destroy = TaoDestroy_BNK; 1308eb910715SAlp Dener 1309eb910715SAlp Dener /* Override default settings (unless already changed) */ 1310eb910715SAlp Dener if (!tao->max_it_changed) tao->max_it = 50; 1311eb910715SAlp Dener if (!tao->trust0_changed) tao->trust0 = 100.0; 1312eb910715SAlp Dener 1313eb910715SAlp Dener tao->data = (void*)bnk; 1314eb910715SAlp Dener 131566ed3702SAlp Dener /* Hessian shifting parameters */ 1316eb910715SAlp Dener bnk->sval = 0.0; 1317eb910715SAlp Dener bnk->imin = 1.0e-4; 1318eb910715SAlp Dener bnk->imax = 1.0e+2; 1319eb910715SAlp Dener bnk->imfac = 1.0e-1; 1320eb910715SAlp Dener 1321eb910715SAlp Dener bnk->pmin = 1.0e-12; 1322eb910715SAlp Dener bnk->pmax = 1.0e+2; 1323eb910715SAlp Dener bnk->pgfac = 1.0e+1; 1324eb910715SAlp Dener bnk->psfac = 4.0e-1; 1325eb910715SAlp Dener bnk->pmgfac = 1.0e-1; 1326eb910715SAlp Dener bnk->pmsfac = 1.0e-1; 1327eb910715SAlp Dener 1328eb910715SAlp Dener /* Default values for trust-region radius update based on steplength */ 1329eb910715SAlp Dener bnk->nu1 = 0.25; 1330eb910715SAlp Dener bnk->nu2 = 0.50; 1331eb910715SAlp Dener bnk->nu3 = 1.00; 1332eb910715SAlp Dener bnk->nu4 = 1.25; 1333eb910715SAlp Dener 1334eb910715SAlp Dener bnk->omega1 = 0.25; 1335eb910715SAlp Dener bnk->omega2 = 0.50; 1336eb910715SAlp Dener bnk->omega3 = 1.00; 1337eb910715SAlp Dener bnk->omega4 = 2.00; 1338eb910715SAlp Dener bnk->omega5 = 4.00; 1339eb910715SAlp Dener 1340eb910715SAlp Dener /* Default values for trust-region radius update based on reduction */ 1341eb910715SAlp Dener bnk->eta1 = 1.0e-4; 1342eb910715SAlp Dener bnk->eta2 = 0.25; 1343eb910715SAlp Dener bnk->eta3 = 0.50; 1344eb910715SAlp Dener bnk->eta4 = 0.90; 1345eb910715SAlp Dener 1346eb910715SAlp Dener bnk->alpha1 = 0.25; 1347eb910715SAlp Dener bnk->alpha2 = 0.50; 1348eb910715SAlp Dener bnk->alpha3 = 1.00; 1349eb910715SAlp Dener bnk->alpha4 = 2.00; 1350eb910715SAlp Dener bnk->alpha5 = 4.00; 1351eb910715SAlp Dener 1352eb910715SAlp Dener /* Default values for trust-region radius update based on interpolation */ 1353eb910715SAlp Dener bnk->mu1 = 0.10; 1354eb910715SAlp Dener bnk->mu2 = 0.50; 1355eb910715SAlp Dener 1356eb910715SAlp Dener bnk->gamma1 = 0.25; 1357eb910715SAlp Dener bnk->gamma2 = 0.50; 1358eb910715SAlp Dener bnk->gamma3 = 2.00; 1359eb910715SAlp Dener bnk->gamma4 = 4.00; 1360eb910715SAlp Dener 1361eb910715SAlp Dener bnk->theta = 0.05; 1362eb910715SAlp Dener 1363eb910715SAlp Dener /* Default values for trust region initialization based on interpolation */ 1364eb910715SAlp Dener bnk->mu1_i = 0.35; 1365eb910715SAlp Dener bnk->mu2_i = 0.50; 1366eb910715SAlp Dener 1367eb910715SAlp Dener bnk->gamma1_i = 0.0625; 1368eb910715SAlp Dener bnk->gamma2_i = 0.5; 1369eb910715SAlp Dener bnk->gamma3_i = 2.0; 1370eb910715SAlp Dener bnk->gamma4_i = 5.0; 1371eb910715SAlp Dener 1372eb910715SAlp Dener bnk->theta_i = 0.25; 1373eb910715SAlp Dener 1374eb910715SAlp Dener /* Remaining parameters */ 1375c0f10754SAlp Dener bnk->max_cg_its = 0; 1376eb910715SAlp Dener bnk->min_radius = 1.0e-10; 1377eb910715SAlp Dener bnk->max_radius = 1.0e10; 1378770b7498SAlp Dener bnk->epsilon = PetscPowReal(PETSC_MACHINE_EPSILON, 2.0/3.0); 13790a4511e9SAlp Dener bnk->as_tol = 1.0e-3; 13800a4511e9SAlp Dener bnk->as_step = 1.0e-3; 138162675beeSAlp Dener bnk->dmin = 1.0e-6; 138262675beeSAlp Dener bnk->dmax = 1.0e6; 1383eb910715SAlp Dener 1384b9ac7092SAlp Dener bnk->M = 0; 1385b9ac7092SAlp Dener bnk->bfgs_pre = 0; 1386eb910715SAlp Dener bnk->init_type = BNK_INIT_INTERPOLATION; 1387fed79b8eSAlp Dener bnk->update_type = BNK_UPDATE_INTERPOLATION; 13882f75a4aaSAlp Dener bnk->as_type = BNK_AS_BERTSEKAS; 1389eb910715SAlp Dener 1390e031d6f5SAlp Dener /* Create the embedded BNCG solver */ 1391e031d6f5SAlp Dener ierr = TaoCreate(PetscObjectComm((PetscObject)tao), &bnk->bncg);CHKERRQ(ierr); 1392e031d6f5SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)bnk->bncg, (PetscObject)tao, 1);CHKERRQ(ierr); 1393e031d6f5SAlp Dener ierr = TaoSetOptionsPrefix(bnk->bncg, "tao_bnk_");CHKERRQ(ierr); 1394e031d6f5SAlp Dener ierr = TaoSetType(bnk->bncg, TAOBNCG);CHKERRQ(ierr); 1395e031d6f5SAlp Dener 1396c0f10754SAlp Dener /* Create the line search */ 1397eb910715SAlp Dener ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr); 1398eb910715SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 1399e031d6f5SAlp Dener ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 1400eb910715SAlp Dener ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr); 1401eb910715SAlp Dener ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr); 1402eb910715SAlp Dener 1403eb910715SAlp Dener /* Set linear solver to default for symmetric matrices */ 1404eb910715SAlp Dener ierr = KSPCreate(((PetscObject)tao)->comm,&tao->ksp);CHKERRQ(ierr); 1405eb910715SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1);CHKERRQ(ierr); 1406eb910715SAlp Dener ierr = KSPSetOptionsPrefix(tao->ksp,tao->hdr.prefix);CHKERRQ(ierr); 1407eb910715SAlp Dener ierr = KSPSetType(tao->ksp,KSPCGSTCG);CHKERRQ(ierr); 1408b9ac7092SAlp Dener ierr = KSPGetPC(tao->ksp, &pc); 1409b9ac7092SAlp Dener ierr = PCSetType(pc, PCLMVM);CHKERRQ(ierr); 1410eb910715SAlp Dener PetscFunctionReturn(0); 1411eb910715SAlp Dener } 1412