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 /*------------------------------------------------------------*/ 7e031d6f5SAlp Dener 8df278d8fSAlp Dener /* Routine for initializing the KSP solver, the BFGS preconditioner, and the initial trust radius estimation */ 9df278d8fSAlp Dener 10c0f10754SAlp Dener PetscErrorCode TaoBNKInitialize(Tao tao, PetscInt initType, PetscBool *needH) 11eb910715SAlp Dener { 12eb910715SAlp Dener PetscErrorCode ierr; 13eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 14eb910715SAlp Dener PC pc; 15eb910715SAlp Dener 1689da521bSAlp Dener PetscReal f_min, ftrial, prered, actred, kappa, sigma, resnorm; 17eb910715SAlp Dener PetscReal tau, tau_1, tau_2, tau_max, tau_min, max_radius; 180ad3a497SAlp Dener PetscBool is_bfgs, is_jacobi, is_symmetric, sym_set; 19c4b75bccSAlp Dener PetscInt n, N, nDiff; 20eb910715SAlp Dener PetscInt i_max = 5; 21eb910715SAlp Dener PetscInt j_max = 1; 22eb910715SAlp Dener PetscInt i, j; 23eb910715SAlp Dener 24eb910715SAlp Dener PetscFunctionBegin; 2528017e9fSAlp Dener /* Project the current point onto the feasible set */ 2628017e9fSAlp Dener ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); 27e031d6f5SAlp Dener ierr = TaoSetVariableBounds(bnk->bncg, tao->XL, tao->XU);CHKERRQ(ierr); 28b9ac7092SAlp Dener if (tao->bounded) { 2928017e9fSAlp Dener ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr); 30cd929ea3SAlp Dener } 3128017e9fSAlp Dener 3228017e9fSAlp Dener /* Project the initial point onto the feasible region */ 333b063059SAlp Dener ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 3428017e9fSAlp Dener 3528017e9fSAlp Dener /* Check convergence criteria */ 3628017e9fSAlp Dener ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &bnk->f, bnk->unprojected_gradient);CHKERRQ(ierr); 3761be54a6SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, bnk->as_type);CHKERRQ(ierr); 3861be54a6SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->gradient);CHKERRQ(ierr); 3961be54a6SAlp Dener ierr = VecISSet(tao->gradient, bnk->active_idx, 0.0);CHKERRQ(ierr); 4008752603SAlp Dener ierr = VecNorm(tao->gradient,NORM_2,&bnk->gnorm);CHKERRQ(ierr); 4128017e9fSAlp Dener 42c0f10754SAlp Dener /* Test the initial point for convergence */ 4389da521bSAlp Dener ierr = VecFischer(tao->solution, bnk->unprojected_gradient, tao->XL, tao->XU, bnk->W);CHKERRQ(ierr); 4489da521bSAlp Dener ierr = VecNorm(bnk->W, NORM_2, &resnorm);CHKERRQ(ierr); 45b4a30f08SAlp Dener if (PetscIsInfOrNanReal(bnk->f) || PetscIsInfOrNanReal(resnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 46e031d6f5SAlp Dener ierr = TaoLogConvergenceHistory(tao,bnk->f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 47e031d6f5SAlp Dener ierr = TaoMonitor(tao,tao->niter,bnk->f,resnorm,0.0,1.0);CHKERRQ(ierr); 48c0f10754SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 49c0f10754SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 50c0f10754SAlp Dener 51e031d6f5SAlp Dener /* Reset KSP stopping reason counters */ 52eb910715SAlp Dener bnk->ksp_atol = 0; 53eb910715SAlp Dener bnk->ksp_rtol = 0; 54eb910715SAlp Dener bnk->ksp_dtol = 0; 55eb910715SAlp Dener bnk->ksp_ctol = 0; 56eb910715SAlp Dener bnk->ksp_negc = 0; 57eb910715SAlp Dener bnk->ksp_iter = 0; 58eb910715SAlp Dener bnk->ksp_othr = 0; 59eb910715SAlp Dener 60e031d6f5SAlp Dener /* Reset accepted step type counters */ 61e031d6f5SAlp Dener bnk->tot_cg_its = 0; 62e031d6f5SAlp Dener bnk->newt = 0; 63e031d6f5SAlp Dener bnk->bfgs = 0; 64e031d6f5SAlp Dener bnk->sgrad = 0; 65e031d6f5SAlp Dener bnk->grad = 0; 66e031d6f5SAlp Dener 67fed79b8eSAlp Dener /* Initialize the Hessian perturbation */ 68fed79b8eSAlp Dener bnk->pert = bnk->sval; 69fed79b8eSAlp Dener 70937a31a1SAlp Dener /* Reset initial steplength to zero (this helps BNCG reset its direction internally) */ 71937a31a1SAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 72937a31a1SAlp Dener 73e031d6f5SAlp Dener /* Allocate the vectors needed for the BFGS approximation */ 74b9ac7092SAlp Dener ierr = KSPGetPC(tao->ksp, &pc);CHKERRQ(ierr); 75b9ac7092SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)pc, PCLMVM, &is_bfgs);CHKERRQ(ierr); 76b9ac7092SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)pc, PCJACOBI, &is_jacobi);CHKERRQ(ierr); 77b9ac7092SAlp Dener if (is_bfgs) { 78b9ac7092SAlp Dener bnk->bfgs_pre = pc; 79b9ac7092SAlp Dener ierr = PCLMVMGetMatLMVM(bnk->bfgs_pre, &bnk->M);CHKERRQ(ierr); 80eb910715SAlp Dener ierr = VecGetLocalSize(tao->solution, &n);CHKERRQ(ierr); 81eb910715SAlp Dener ierr = VecGetSize(tao->solution, &N);CHKERRQ(ierr); 82b9ac7092SAlp Dener ierr = MatSetSizes(bnk->M, n, n, N, N);CHKERRQ(ierr); 83cd929ea3SAlp Dener ierr = MatLMVMAllocate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 840ad3a497SAlp Dener ierr = MatIsSymmetricKnown(bnk->M, &sym_set, &is_symmetric);CHKERRQ(ierr); 850ad3a497SAlp Dener if (!sym_set || !is_symmetric) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix in the LMVM preconditioner must be symmetric."); 86b9ac7092SAlp Dener } else if (is_jacobi) { 87b9ac7092SAlp Dener ierr = PCJacobiSetUseAbs(pc,PETSC_TRUE);CHKERRQ(ierr); 88e031d6f5SAlp Dener } 89e031d6f5SAlp Dener 90e031d6f5SAlp Dener /* Prepare the min/max vectors for safeguarding diagonal scales */ 9162675beeSAlp Dener ierr = VecSet(bnk->Diag_min, bnk->dmin);CHKERRQ(ierr); 9262675beeSAlp Dener ierr = VecSet(bnk->Diag_max, bnk->dmax);CHKERRQ(ierr); 93eb910715SAlp Dener 94eb910715SAlp Dener /* Initialize trust-region radius. The initialization is only performed 95eb910715SAlp Dener when we are using Nash, Steihaug-Toint or the Generalized Lanczos method. */ 96c0f10754SAlp Dener *needH = PETSC_TRUE; 97eb910715SAlp Dener if (bnk->is_nash || bnk->is_stcg || bnk->is_gltr) { 9862675beeSAlp Dener switch(initType) { 99eb910715SAlp Dener case BNK_INIT_CONSTANT: 100eb910715SAlp Dener /* Use the initial radius specified */ 101c0f10754SAlp Dener tao->trust = tao->trust0; 102eb910715SAlp Dener break; 103eb910715SAlp Dener 104eb910715SAlp Dener case BNK_INIT_INTERPOLATION: 105c0f10754SAlp Dener /* Use interpolation based on the initial Hessian */ 106eb910715SAlp Dener max_radius = 0.0; 10708752603SAlp Dener tao->trust = tao->trust0; 108eb910715SAlp Dener for (j = 0; j < j_max; ++j) { 1090a4511e9SAlp Dener f_min = bnk->f; 110eb910715SAlp Dener sigma = 0.0; 111eb910715SAlp Dener 112c0f10754SAlp Dener if (*needH) { 11362602cfbSAlp Dener /* Compute the Hessian at the new step, and extract the inactive subsystem */ 114e0ed867bSAlp Dener ierr = bnk->computehessian(tao);CHKERRQ(ierr); 11508752603SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, BNK_AS_NONE);CHKERRQ(ierr); 11689da521bSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 11789da521bSAlp Dener if (bnk->active_idx) { 1182ab2a32cSAlp Dener ierr = MatCreateSubMatrix(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->H_inactive);CHKERRQ(ierr); 11928017e9fSAlp Dener } else { 12008752603SAlp Dener ierr = MatDuplicate(tao->hessian, MAT_COPY_VALUES, &bnk->H_inactive);CHKERRQ(ierr); 12128017e9fSAlp Dener } 122c0f10754SAlp Dener *needH = PETSC_FALSE; 123eb910715SAlp Dener } 124eb910715SAlp Dener 125eb910715SAlp Dener for (i = 0; i < i_max; ++i) { 12662602cfbSAlp Dener /* Take a steepest descent step and snap it to bounds */ 12762602cfbSAlp Dener ierr = VecCopy(tao->solution, bnk->Xold);CHKERRQ(ierr); 12862602cfbSAlp Dener ierr = VecAXPY(tao->solution, -tao->trust/bnk->gnorm, tao->gradient);CHKERRQ(ierr); 1293b063059SAlp Dener ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 13089da521bSAlp Dener /* Compute the step we actually accepted */ 131eb910715SAlp Dener ierr = VecCopy(tao->solution, bnk->W);CHKERRQ(ierr); 13262602cfbSAlp Dener ierr = VecAXPY(bnk->W, -1.0, bnk->Xold);CHKERRQ(ierr); 13362602cfbSAlp Dener /* Compute the objective at the trial */ 13462602cfbSAlp Dener ierr = TaoComputeObjective(tao, tao->solution, &ftrial);CHKERRQ(ierr); 135b4a30f08SAlp Dener if (PetscIsInfOrNanReal(bnk->f)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 13662602cfbSAlp Dener ierr = VecCopy(bnk->Xold, tao->solution);CHKERRQ(ierr); 137eb910715SAlp Dener if (PetscIsInfOrNanReal(ftrial)) { 138eb910715SAlp Dener tau = bnk->gamma1_i; 139eb910715SAlp Dener } else { 1400a4511e9SAlp Dener if (ftrial < f_min) { 1410a4511e9SAlp Dener f_min = ftrial; 142eb910715SAlp Dener sigma = -tao->trust / bnk->gnorm; 143eb910715SAlp Dener } 14408752603SAlp Dener 145770b7498SAlp Dener /* Compute the predicted and actual reduction */ 14689da521bSAlp Dener if (bnk->active_idx) { 14708752603SAlp Dener ierr = VecGetSubVector(bnk->W, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 14808752603SAlp Dener ierr = VecGetSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 1492ab2a32cSAlp Dener } else { 15008752603SAlp Dener bnk->X_inactive = bnk->W; 15108752603SAlp Dener bnk->inactive_work = bnk->Xwork; 1522ab2a32cSAlp Dener } 15308752603SAlp Dener ierr = MatMult(bnk->H_inactive, bnk->X_inactive, bnk->inactive_work);CHKERRQ(ierr); 15408752603SAlp Dener ierr = VecDot(bnk->X_inactive, bnk->inactive_work, &prered);CHKERRQ(ierr); 15589da521bSAlp Dener if (bnk->active_idx) { 15608752603SAlp Dener ierr = VecRestoreSubVector(bnk->W, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 15708752603SAlp Dener ierr = VecRestoreSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 1582ab2a32cSAlp Dener } 159eb910715SAlp Dener prered = tao->trust * (bnk->gnorm - 0.5 * tao->trust * prered / (bnk->gnorm * bnk->gnorm)); 160eb910715SAlp Dener actred = bnk->f - ftrial; 1613105154fSTodd Munson if ((PetscAbsScalar(actred) <= bnk->epsilon) && (PetscAbsScalar(prered) <= bnk->epsilon)) { 162eb910715SAlp Dener kappa = 1.0; 1633105154fSTodd Munson } else { 164eb910715SAlp Dener kappa = actred / prered; 165eb910715SAlp Dener } 166eb910715SAlp Dener 167eb910715SAlp Dener tau_1 = bnk->theta_i * bnk->gnorm * tao->trust / (bnk->theta_i * bnk->gnorm * tao->trust + (1.0 - bnk->theta_i) * prered - actred); 168eb910715SAlp Dener tau_2 = bnk->theta_i * bnk->gnorm * tao->trust / (bnk->theta_i * bnk->gnorm * tao->trust - (1.0 + bnk->theta_i) * prered + actred); 169eb910715SAlp Dener tau_min = PetscMin(tau_1, tau_2); 170eb910715SAlp Dener tau_max = PetscMax(tau_1, tau_2); 171eb910715SAlp Dener 172eb910715SAlp Dener if (PetscAbsScalar(kappa - 1.0) <= bnk->mu1_i) { 173eb910715SAlp Dener /* Great agreement */ 174eb910715SAlp Dener max_radius = PetscMax(max_radius, tao->trust); 175eb910715SAlp Dener 176eb910715SAlp Dener if (tau_max < 1.0) { 177eb910715SAlp Dener tau = bnk->gamma3_i; 1783105154fSTodd Munson } else if (tau_max > bnk->gamma4_i) { 179eb910715SAlp Dener tau = bnk->gamma4_i; 1803105154fSTodd Munson } else { 181eb910715SAlp Dener tau = tau_max; 182eb910715SAlp Dener } 1838f8a4e06SAlp Dener } else if (PetscAbsScalar(kappa - 1.0) <= bnk->mu2_i) { 184eb910715SAlp Dener /* Good agreement */ 185eb910715SAlp Dener max_radius = PetscMax(max_radius, tao->trust); 186eb910715SAlp Dener 187eb910715SAlp Dener if (tau_max < bnk->gamma2_i) { 188eb910715SAlp Dener tau = bnk->gamma2_i; 189eb910715SAlp Dener } else if (tau_max > bnk->gamma3_i) { 190eb910715SAlp Dener tau = bnk->gamma3_i; 191eb910715SAlp Dener } else { 192eb910715SAlp Dener tau = tau_max; 193eb910715SAlp Dener } 1948f8a4e06SAlp Dener } else { 195eb910715SAlp Dener /* Not good agreement */ 196eb910715SAlp Dener if (tau_min > 1.0) { 197eb910715SAlp Dener tau = bnk->gamma2_i; 198eb910715SAlp Dener } else if (tau_max < bnk->gamma1_i) { 199eb910715SAlp Dener tau = bnk->gamma1_i; 200eb910715SAlp Dener } else if ((tau_min < bnk->gamma1_i) && (tau_max >= 1.0)) { 201eb910715SAlp Dener tau = bnk->gamma1_i; 2023105154fSTodd Munson } else if ((tau_1 >= bnk->gamma1_i) && (tau_1 < 1.0) && ((tau_2 < bnk->gamma1_i) || (tau_2 >= 1.0))) { 203eb910715SAlp Dener tau = tau_1; 2043105154fSTodd Munson } else if ((tau_2 >= bnk->gamma1_i) && (tau_2 < 1.0) && ((tau_1 < bnk->gamma1_i) || (tau_2 >= 1.0))) { 205eb910715SAlp Dener tau = tau_2; 206eb910715SAlp Dener } else { 207eb910715SAlp Dener tau = tau_max; 208eb910715SAlp Dener } 209eb910715SAlp Dener } 210eb910715SAlp Dener } 211eb910715SAlp Dener tao->trust = tau * tao->trust; 212eb910715SAlp Dener } 213eb910715SAlp Dener 2140a4511e9SAlp Dener if (f_min < bnk->f) { 215937a31a1SAlp Dener /* We accidentally found a solution better than the initial, so accept it */ 2160a4511e9SAlp Dener bnk->f = f_min; 217937a31a1SAlp Dener ierr = VecCopy(tao->solution, bnk->Xold);CHKERRQ(ierr); 218eb910715SAlp Dener ierr = VecAXPY(tao->solution,sigma,tao->gradient);CHKERRQ(ierr); 2193b063059SAlp Dener ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 220937a31a1SAlp Dener ierr = VecCopy(tao->solution, tao->stepdirection);CHKERRQ(ierr); 221937a31a1SAlp Dener ierr = VecAXPY(tao->stepdirection, -1.0, bnk->Xold);CHKERRQ(ierr); 22209164190SAlp Dener ierr = TaoComputeGradient(tao,tao->solution,bnk->unprojected_gradient);CHKERRQ(ierr); 22361be54a6SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, bnk->as_type);CHKERRQ(ierr); 22461be54a6SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->gradient);CHKERRQ(ierr); 22561be54a6SAlp Dener ierr = VecISSet(tao->gradient, bnk->active_idx, 0.0);CHKERRQ(ierr); 226937a31a1SAlp Dener /* Compute gradient at the new iterate and flip switch to compute the Hessian later */ 227c4b75bccSAlp Dener ierr = VecNorm(tao->gradient, NORM_2, &bnk->gnorm);CHKERRQ(ierr); 228c0f10754SAlp Dener *needH = PETSC_TRUE; 229937a31a1SAlp Dener /* Test the new step for convergence */ 23089da521bSAlp Dener ierr = VecFischer(tao->solution, bnk->unprojected_gradient, tao->XL, tao->XU, bnk->W);CHKERRQ(ierr); 23189da521bSAlp Dener ierr = VecNorm(bnk->W, NORM_2, &resnorm);CHKERRQ(ierr); 232b4a30f08SAlp Dener if (PetscIsInfOrNanReal(resnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 233e031d6f5SAlp Dener ierr = TaoLogConvergenceHistory(tao,bnk->f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 234e031d6f5SAlp Dener ierr = TaoMonitor(tao,tao->niter,bnk->f,resnorm,0.0,1.0);CHKERRQ(ierr); 235eb910715SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 236eb910715SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 237937a31a1SAlp Dener /* active BNCG recycling early because we have a stepdirection computed */ 238937a31a1SAlp Dener ierr = TaoBNCGSetRecycleFlag(bnk->bncg, PETSC_TRUE);CHKERRQ(ierr); 239eb910715SAlp Dener } 240eb910715SAlp Dener } 241eb910715SAlp Dener tao->trust = PetscMax(tao->trust, max_radius); 242e031d6f5SAlp Dener 243e031d6f5SAlp Dener /* Ensure that the trust radius is within the limits */ 244e031d6f5SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 245e031d6f5SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 246eb910715SAlp Dener break; 247eb910715SAlp Dener 248eb910715SAlp Dener default: 249eb910715SAlp Dener /* Norm of the first direction will initialize radius */ 250eb910715SAlp Dener tao->trust = 0.0; 251eb910715SAlp Dener break; 252eb910715SAlp Dener } 253eb910715SAlp Dener } 254eb910715SAlp Dener PetscFunctionReturn(0); 255eb910715SAlp Dener } 256eb910715SAlp Dener 257df278d8fSAlp Dener /*------------------------------------------------------------*/ 258df278d8fSAlp Dener 259e0ed867bSAlp Dener /* Routine for computing the exact Hessian and preparing the preconditioner at the new iterate */ 26062675beeSAlp Dener 26162675beeSAlp Dener PetscErrorCode TaoBNKComputeHessian(Tao tao) 26262675beeSAlp Dener { 26362675beeSAlp Dener PetscErrorCode ierr; 26462675beeSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 26562675beeSAlp Dener 26662675beeSAlp Dener PetscFunctionBegin; 26762675beeSAlp Dener /* Compute the Hessian */ 26862675beeSAlp Dener ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 26962675beeSAlp Dener /* Add a correction to the BFGS preconditioner */ 270b9ac7092SAlp Dener if (bnk->M) { 27162675beeSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 27262675beeSAlp Dener } 273e0ed867bSAlp Dener /* Prepare the reduced sub-matrices for the inactive set */ 274e0ed867bSAlp Dener if (bnk->active_idx) { 275e0ed867bSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 276e0ed867bSAlp Dener ierr = MatCreateSubMatrix(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->H_inactive);CHKERRQ(ierr); 277e0ed867bSAlp Dener if (tao->hessian == tao->hessian_pre) { 278e0ed867bSAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 279e0ed867bSAlp Dener } else { 280e0ed867bSAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 281e0ed867bSAlp Dener ierr = MatCreateSubMatrix(tao->hessian_pre, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->Hpre_inactive);CHKERRQ(ierr); 282e0ed867bSAlp Dener } 283e0ed867bSAlp Dener if (bnk->bfgs_pre) { 284e0ed867bSAlp Dener ierr = PCLMVMSetIS(bnk->bfgs_pre, bnk->inactive_idx);CHKERRQ(ierr); 285e0ed867bSAlp Dener } 286e0ed867bSAlp Dener } else { 287e0ed867bSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 288e0ed867bSAlp Dener ierr = MatDuplicate(tao->hessian, MAT_COPY_VALUES, &bnk->H_inactive);CHKERRQ(ierr); 289e0ed867bSAlp Dener if (tao->hessian == tao->hessian_pre) { 290e0ed867bSAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 291e0ed867bSAlp Dener } else { 292e0ed867bSAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 293e0ed867bSAlp Dener ierr = MatDuplicate(tao->hessian_pre, MAT_COPY_VALUES, &bnk->Hpre_inactive);CHKERRQ(ierr); 294e0ed867bSAlp Dener } 295e0ed867bSAlp Dener if (bnk->bfgs_pre) { 296e0ed867bSAlp Dener ierr = PCLMVMClearIS(bnk->bfgs_pre);CHKERRQ(ierr); 297e0ed867bSAlp Dener } 298e0ed867bSAlp Dener } 29962675beeSAlp Dener PetscFunctionReturn(0); 30062675beeSAlp Dener } 30162675beeSAlp Dener 30262675beeSAlp Dener /*------------------------------------------------------------*/ 30362675beeSAlp Dener 3042f75a4aaSAlp Dener /* Routine for estimating the active set */ 3052f75a4aaSAlp Dener 30608752603SAlp Dener PetscErrorCode TaoBNKEstimateActiveSet(Tao tao, PetscInt asType) 3072f75a4aaSAlp Dener { 3082f75a4aaSAlp Dener PetscErrorCode ierr; 3092f75a4aaSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 310c4b75bccSAlp Dener PetscBool hessComputed, diagExists; 3112f75a4aaSAlp Dener 3122f75a4aaSAlp Dener PetscFunctionBegin; 31308752603SAlp Dener switch (asType) { 3142f75a4aaSAlp Dener case BNK_AS_NONE: 3152f75a4aaSAlp Dener ierr = ISDestroy(&bnk->inactive_idx);CHKERRQ(ierr); 3162f75a4aaSAlp Dener ierr = VecWhichInactive(tao->XL, tao->solution, bnk->unprojected_gradient, tao->XU, PETSC_TRUE, &bnk->inactive_idx);CHKERRQ(ierr); 3172f75a4aaSAlp Dener ierr = ISDestroy(&bnk->active_idx);CHKERRQ(ierr); 3182f75a4aaSAlp Dener ierr = ISComplementVec(bnk->inactive_idx, tao->solution, &bnk->active_idx);CHKERRQ(ierr); 3192f75a4aaSAlp Dener break; 3202f75a4aaSAlp Dener 3212f75a4aaSAlp Dener case BNK_AS_BERTSEKAS: 3222f75a4aaSAlp Dener /* Compute the trial step vector with which we will estimate the active set at the next iteration */ 323b9ac7092SAlp Dener if (bnk->M) { 3242f75a4aaSAlp Dener /* If the BFGS preconditioner matrix is available, we will construct a trial step with it */ 325cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, bnk->W);CHKERRQ(ierr); 3262f75a4aaSAlp Dener } else { 32761be54a6SAlp Dener ierr = MatAssembled(tao->hessian, &hessComputed);CHKERRQ(ierr); 328c4b75bccSAlp Dener ierr = MatHasOperation(tao->hessian, MATOP_GET_DIAGONAL, &diagExists);CHKERRQ(ierr); 329c4b75bccSAlp Dener if (hessComputed && diagExists) { 3309b6ef848SAlp Dener /* BFGS preconditioner doesn't exist so let's invert the absolute diagonal of the Hessian instead onto the gradient */ 3312f75a4aaSAlp Dener ierr = MatGetDiagonal(tao->hessian, bnk->Xwork);CHKERRQ(ierr); 3329b6ef848SAlp Dener ierr = VecAbs(bnk->Xwork);CHKERRQ(ierr); 3339b6ef848SAlp Dener ierr = VecMedian(bnk->Diag_min, bnk->Xwork, bnk->Diag_max, bnk->Xwork);CHKERRQ(ierr); 3342f75a4aaSAlp Dener ierr = VecReciprocal(bnk->Xwork);CHKERRQ(ierr);CHKERRQ(ierr); 3352f75a4aaSAlp Dener ierr = VecPointwiseMult(bnk->W, bnk->Xwork, bnk->unprojected_gradient);CHKERRQ(ierr); 33661be54a6SAlp Dener } else { 337c4b75bccSAlp Dener /* If the Hessian or its diagonal does not exist, we will simply use gradient step */ 33861be54a6SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, bnk->W);CHKERRQ(ierr); 33961be54a6SAlp Dener } 3402f75a4aaSAlp Dener } 3412f75a4aaSAlp Dener ierr = VecScale(bnk->W, -1.0);CHKERRQ(ierr); 34289da521bSAlp Dener ierr = TaoEstimateActiveBounds(tao->solution, tao->XL, tao->XU, bnk->unprojected_gradient, bnk->W, bnk->Xwork, bnk->as_step, &bnk->as_tol, 34389da521bSAlp Dener &bnk->active_lower, &bnk->active_upper, &bnk->active_fixed, &bnk->active_idx, &bnk->inactive_idx);CHKERRQ(ierr); 344c4b75bccSAlp Dener break; 3452f75a4aaSAlp Dener 3462f75a4aaSAlp Dener default: 3472f75a4aaSAlp Dener break; 3482f75a4aaSAlp Dener } 3492f75a4aaSAlp Dener PetscFunctionReturn(0); 3502f75a4aaSAlp Dener } 3512f75a4aaSAlp Dener 3522f75a4aaSAlp Dener /*------------------------------------------------------------*/ 3532f75a4aaSAlp Dener 3542f75a4aaSAlp Dener /* Routine for bounding the step direction */ 3552f75a4aaSAlp Dener 356a1318120SAlp Dener PetscErrorCode TaoBNKBoundStep(Tao tao, PetscInt asType, Vec step) 3572f75a4aaSAlp Dener { 3582f75a4aaSAlp Dener PetscErrorCode ierr; 3592f75a4aaSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 3602f75a4aaSAlp Dener 3612f75a4aaSAlp Dener PetscFunctionBegin; 362a1318120SAlp Dener switch (asType) { 3632f75a4aaSAlp Dener case BNK_AS_NONE: 364c4b75bccSAlp Dener ierr = VecISSet(step, bnk->active_idx, 0.0);CHKERRQ(ierr); 3652f75a4aaSAlp Dener break; 3662f75a4aaSAlp Dener 3672f75a4aaSAlp Dener case BNK_AS_BERTSEKAS: 368c4b75bccSAlp Dener ierr = TaoBoundStep(tao->solution, tao->XL, tao->XU, bnk->active_lower, bnk->active_upper, bnk->active_fixed, 1.0, step);CHKERRQ(ierr); 3692f75a4aaSAlp Dener break; 3702f75a4aaSAlp Dener 3712f75a4aaSAlp Dener default: 3722f75a4aaSAlp Dener break; 3732f75a4aaSAlp Dener } 3742f75a4aaSAlp Dener PetscFunctionReturn(0); 3752f75a4aaSAlp Dener } 3762f75a4aaSAlp Dener 377e031d6f5SAlp Dener /*------------------------------------------------------------*/ 378e031d6f5SAlp Dener 379e031d6f5SAlp Dener /* Routine for taking a finite number of BNCG iterations to 380e031d6f5SAlp Dener accelerate Newton convergence. 381e031d6f5SAlp Dener 382e031d6f5SAlp Dener In practice, this approach simply trades off Hessian evaluations 383e031d6f5SAlp Dener for more gradient evaluations. 384e031d6f5SAlp Dener */ 385e031d6f5SAlp Dener 386c0f10754SAlp Dener PetscErrorCode TaoBNKTakeCGSteps(Tao tao, PetscBool *terminate) 387c0f10754SAlp Dener { 388c0f10754SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 389c0f10754SAlp Dener PetscErrorCode ierr; 390c0f10754SAlp Dener 391c0f10754SAlp Dener PetscFunctionBegin; 392c0f10754SAlp Dener *terminate = PETSC_FALSE; 393c0f10754SAlp Dener if (bnk->max_cg_its > 0) { 394c4b75bccSAlp Dener /* Copy the current function value (important vectors are already shared) */ 395c0f10754SAlp Dener bnk->bncg_ctx->f = bnk->f; 396c0f10754SAlp Dener /* Take some small finite number of BNCG iterations */ 397c0f10754SAlp Dener ierr = TaoSolve(bnk->bncg);CHKERRQ(ierr); 398c0f10754SAlp Dener /* Add the number of gradient and function evaluations to the total */ 399c0f10754SAlp Dener tao->nfuncs += bnk->bncg->nfuncs; 400c0f10754SAlp Dener tao->nfuncgrads += bnk->bncg->nfuncgrads; 401c0f10754SAlp Dener tao->ngrads += bnk->bncg->ngrads; 402c0f10754SAlp Dener tao->nhess += bnk->bncg->nhess; 403e031d6f5SAlp Dener bnk->tot_cg_its += bnk->bncg->niter; 404c4b75bccSAlp Dener /* Extract the BNCG function value out and save it into BNK */ 405c0f10754SAlp Dener bnk->f = bnk->bncg_ctx->f; 406c0f10754SAlp 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) { 407c0f10754SAlp Dener *terminate = PETSC_TRUE; 40861be54a6SAlp Dener } else { 40933c78596SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, bnk->as_type);CHKERRQ(ierr); 410c0f10754SAlp Dener } 411c0f10754SAlp Dener } 412c0f10754SAlp Dener PetscFunctionReturn(0); 413c0f10754SAlp Dener } 414c0f10754SAlp Dener 4152f75a4aaSAlp Dener /*------------------------------------------------------------*/ 4162f75a4aaSAlp Dener 417c0f10754SAlp Dener /* Routine for computing the Newton step. */ 418df278d8fSAlp Dener 419*6b591159SAlp Dener PetscErrorCode TaoBNKComputeStep(Tao tao, PetscBool shift, KSPConvergedReason *ksp_reason, PetscInt *step_type) 420eb910715SAlp Dener { 421eb910715SAlp Dener PetscErrorCode ierr; 422eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 423eb910715SAlp Dener PetscInt bfgsUpdates = 0; 424eb910715SAlp Dener PetscInt kspits; 425eb910715SAlp Dener 426eb910715SAlp Dener PetscFunctionBegin; 42789da521bSAlp Dener /* If there are no inactive variables left, save some computation and return an adjusted zero step 42889da521bSAlp Dener that has (l-x) and (u-x) for lower and upper bounded variables. */ 42989da521bSAlp Dener if (!bnk->inactive_idx) { 43089da521bSAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 431a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 43289da521bSAlp Dener PetscFunctionReturn(0); 43389da521bSAlp Dener } 43489da521bSAlp Dener 43562675beeSAlp Dener /* Shift the reduced Hessian matrix */ 43662675beeSAlp Dener if ((shift) && (bnk->pert > 0)) { 43762675beeSAlp Dener ierr = MatShift(bnk->H_inactive, bnk->pert);CHKERRQ(ierr); 43862675beeSAlp Dener if (bnk->H_inactive != bnk->Hpre_inactive) { 43962675beeSAlp Dener ierr = MatShift(bnk->Hpre_inactive, bnk->pert);CHKERRQ(ierr); 44062675beeSAlp Dener } 44162675beeSAlp Dener } 44262675beeSAlp Dener 443eb910715SAlp Dener /* Solve the Newton system of equations */ 444937a31a1SAlp Dener tao->ksp_its = 0; 4452f75a4aaSAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 4465e9b73cbSAlp Dener ierr = KSPReset(tao->ksp);CHKERRQ(ierr); 44709164190SAlp Dener ierr = KSPSetOperators(tao->ksp,bnk->H_inactive,bnk->Hpre_inactive);CHKERRQ(ierr); 4485e9b73cbSAlp Dener ierr = VecCopy(bnk->unprojected_gradient, bnk->Gwork);CHKERRQ(ierr); 44989da521bSAlp Dener if (bnk->active_idx) { 4505e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 4515e9b73cbSAlp Dener ierr = VecGetSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 4525e9b73cbSAlp Dener } else { 4535e9b73cbSAlp Dener bnk->G_inactive = bnk->unprojected_gradient; 4545e9b73cbSAlp Dener bnk->X_inactive = tao->stepdirection; 45528017e9fSAlp Dener } 456eb910715SAlp Dener if (bnk->is_nash || bnk->is_stcg || bnk->is_gltr) { 457fed79b8eSAlp Dener ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 4585e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 459eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 460eb910715SAlp Dener tao->ksp_its+=kspits; 461eb910715SAlp Dener tao->ksp_tot_its+=kspits; 462080d2917SAlp Dener ierr = KSPCGGetNormD(tao->ksp,&bnk->dnorm);CHKERRQ(ierr); 463eb910715SAlp Dener 464eb910715SAlp Dener if (0.0 == tao->trust) { 465eb910715SAlp Dener /* Radius was uninitialized; use the norm of the direction */ 466080d2917SAlp Dener if (bnk->dnorm > 0.0) { 467080d2917SAlp Dener tao->trust = bnk->dnorm; 468eb910715SAlp Dener 469eb910715SAlp Dener /* Modify the radius if it is too large or small */ 470eb910715SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 471eb910715SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 472eb910715SAlp Dener } else { 473eb910715SAlp Dener /* The direction was bad; set radius to default value and re-solve 474eb910715SAlp Dener the trust-region subproblem to get a direction */ 475eb910715SAlp Dener tao->trust = tao->trust0; 476eb910715SAlp Dener 477eb910715SAlp Dener /* Modify the radius if it is too large or small */ 478eb910715SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 479eb910715SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 480eb910715SAlp Dener 481fed79b8eSAlp Dener ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 4825e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 483eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 484eb910715SAlp Dener tao->ksp_its+=kspits; 485eb910715SAlp Dener tao->ksp_tot_its+=kspits; 486080d2917SAlp Dener ierr = KSPCGGetNormD(tao->ksp,&bnk->dnorm);CHKERRQ(ierr); 487eb910715SAlp Dener 488080d2917SAlp Dener if (bnk->dnorm == 0.0) SETERRQ(PETSC_COMM_SELF,1, "Initial direction zero"); 489eb910715SAlp Dener } 490eb910715SAlp Dener } 491eb910715SAlp Dener } else { 4925e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 493eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp, &kspits);CHKERRQ(ierr); 494eb910715SAlp Dener tao->ksp_its += kspits; 495eb910715SAlp Dener tao->ksp_tot_its+=kspits; 496eb910715SAlp Dener } 4975e9b73cbSAlp Dener /* Restore sub vectors back */ 49889da521bSAlp Dener if (bnk->active_idx) { 4995e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5005e9b73cbSAlp Dener ierr = VecRestoreSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5015e9b73cbSAlp Dener } 502770b7498SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 503fed79b8eSAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 504a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 505770b7498SAlp Dener 506770b7498SAlp Dener /* Record convergence reasons */ 507e465cd6fSAlp Dener ierr = KSPGetConvergedReason(tao->ksp, ksp_reason);CHKERRQ(ierr); 508e465cd6fSAlp Dener if (KSP_CONVERGED_ATOL == *ksp_reason) { 509770b7498SAlp Dener ++bnk->ksp_atol; 510e465cd6fSAlp Dener } else if (KSP_CONVERGED_RTOL == *ksp_reason) { 511770b7498SAlp Dener ++bnk->ksp_rtol; 512e465cd6fSAlp Dener } else if (KSP_CONVERGED_CG_CONSTRAINED == *ksp_reason) { 513770b7498SAlp Dener ++bnk->ksp_ctol; 514e465cd6fSAlp Dener } else if (KSP_CONVERGED_CG_NEG_CURVE == *ksp_reason) { 515770b7498SAlp Dener ++bnk->ksp_negc; 516e465cd6fSAlp Dener } else if (KSP_DIVERGED_DTOL == *ksp_reason) { 517770b7498SAlp Dener ++bnk->ksp_dtol; 518e465cd6fSAlp Dener } else if (KSP_DIVERGED_ITS == *ksp_reason) { 519770b7498SAlp Dener ++bnk->ksp_iter; 520770b7498SAlp Dener } else { 521770b7498SAlp Dener ++bnk->ksp_othr; 522770b7498SAlp Dener } 523fed79b8eSAlp Dener 524fed79b8eSAlp Dener /* Make sure the BFGS preconditioner is healthy */ 525b9ac7092SAlp Dener if (bnk->M) { 526cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 527b2d8c577SAlp Dener if ((KSP_DIVERGED_INDEFINITE_PC == *ksp_reason) && (bfgsUpdates > 0)) { 528fed79b8eSAlp Dener /* Preconditioner is numerically indefinite; reset the approximation. */ 529cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 53009164190SAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 531eb910715SAlp Dener } 532fed79b8eSAlp Dener } 533*6b591159SAlp Dener *step_type = BNK_NEWTON; 534e465cd6fSAlp Dener PetscFunctionReturn(0); 535e465cd6fSAlp Dener } 536eb910715SAlp Dener 53762675beeSAlp Dener /*------------------------------------------------------------*/ 53862675beeSAlp Dener 5395e9b73cbSAlp Dener /* Routine for recomputing the predicted reduction for a given step vector */ 5405e9b73cbSAlp Dener 5415e9b73cbSAlp Dener PetscErrorCode TaoBNKRecomputePred(Tao tao, Vec S, PetscReal *prered) 5425e9b73cbSAlp Dener { 5435e9b73cbSAlp Dener PetscErrorCode ierr; 5445e9b73cbSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 5455e9b73cbSAlp Dener 5465e9b73cbSAlp Dener PetscFunctionBegin; 5475e9b73cbSAlp Dener /* Extract subvectors associated with the inactive set */ 54889da521bSAlp Dener if (bnk->active_idx){ 5495e9b73cbSAlp Dener ierr = VecGetSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5505e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 5515e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5525e9b73cbSAlp Dener } else { 5535e9b73cbSAlp Dener bnk->X_inactive = tao->stepdirection; 5545e9b73cbSAlp Dener bnk->inactive_work = bnk->Xwork; 5555e9b73cbSAlp Dener bnk->G_inactive = bnk->Gwork; 5565e9b73cbSAlp Dener } 5575e9b73cbSAlp Dener /* Recompute the predicted decrease based on the quadratic model */ 5585e9b73cbSAlp Dener ierr = MatMult(bnk->H_inactive, bnk->X_inactive, bnk->inactive_work);CHKERRQ(ierr); 5595e9b73cbSAlp Dener ierr = VecAYPX(bnk->inactive_work, -0.5, bnk->G_inactive);CHKERRQ(ierr); 56033c78596SAlp Dener ierr = VecDot(bnk->inactive_work, bnk->X_inactive, prered);CHKERRQ(ierr); 5615e9b73cbSAlp Dener /* Restore the sub vectors */ 56289da521bSAlp Dener if (bnk->active_idx){ 5635e9b73cbSAlp Dener ierr = VecRestoreSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5645e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 5655e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5665e9b73cbSAlp Dener } 5675e9b73cbSAlp Dener PetscFunctionReturn(0); 5685e9b73cbSAlp Dener } 5695e9b73cbSAlp Dener 5705e9b73cbSAlp Dener /*------------------------------------------------------------*/ 5715e9b73cbSAlp Dener 57262675beeSAlp Dener /* Routine for ensuring that the Newton step is a descent direction. 57362675beeSAlp Dener 57462675beeSAlp Dener The step direction falls back onto BFGS, scaled gradient and gradient steps 57562675beeSAlp Dener in the event that the Newton step fails the test. 57662675beeSAlp Dener */ 57762675beeSAlp Dener 578e465cd6fSAlp Dener PetscErrorCode TaoBNKSafeguardStep(Tao tao, KSPConvergedReason ksp_reason, PetscInt *stepType) 579e465cd6fSAlp Dener { 580e465cd6fSAlp Dener PetscErrorCode ierr; 581e465cd6fSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 582e465cd6fSAlp Dener 583b2d8c577SAlp Dener PetscReal gdx, e_min; 584e465cd6fSAlp Dener PetscInt bfgsUpdates; 585e465cd6fSAlp Dener 586e465cd6fSAlp Dener PetscFunctionBegin; 587*6b591159SAlp Dener switch (*stepType) { 588*6b591159SAlp Dener case BNK_NEWTON: 589080d2917SAlp Dener ierr = VecDot(tao->stepdirection, tao->gradient, &gdx);CHKERRQ(ierr); 590eb910715SAlp Dener if ((gdx >= 0.0) || PetscIsInfOrNanReal(gdx)) { 591eb910715SAlp Dener /* Newton step is not descent or direction produced Inf or NaN 592eb910715SAlp Dener Update the perturbation for next time */ 593eb910715SAlp Dener if (bnk->pert <= 0.0) { 594eb910715SAlp Dener /* Initialize the perturbation */ 595eb910715SAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 596eb910715SAlp Dener if (bnk->is_gltr) { 597eb910715SAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 598eb910715SAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 599eb910715SAlp Dener } 600eb910715SAlp Dener } else { 601eb910715SAlp Dener /* Increase the perturbation */ 602eb910715SAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 603eb910715SAlp Dener } 604eb910715SAlp Dener 6050ad3a497SAlp Dener if (!bnk->M) { 606eb910715SAlp Dener /* We don't have the bfgs matrix around and updated 607eb910715SAlp Dener Must use gradient direction in this case */ 608080d2917SAlp Dener ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr); 609eb910715SAlp Dener *stepType = BNK_GRADIENT; 610eb910715SAlp Dener } else { 611eb910715SAlp Dener /* Attempt to use the BFGS direction */ 612cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 613eb910715SAlp Dener 6148d5ead36SAlp Dener /* Check for success (descent direction) 6158d5ead36SAlp Dener NOTE: Negative gdx here means not a descent direction because 6168d5ead36SAlp Dener the fall-back step is missing a negative sign. */ 617080d2917SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 6183105154fSTodd Munson if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 619eb910715SAlp Dener /* BFGS direction is not descent or direction produced not a number 620eb910715SAlp Dener We can assert bfgsUpdates > 1 in this case because 621eb910715SAlp Dener the first solve produces the scaled gradient direction, 622eb910715SAlp Dener which is guaranteed to be descent */ 623eb910715SAlp Dener 624eb910715SAlp Dener /* Use steepest descent direction (scaled) */ 625cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 62609164190SAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 627cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 628eb910715SAlp Dener 629eb910715SAlp Dener *stepType = BNK_SCALED_GRADIENT; 630eb910715SAlp Dener } else { 631cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 632eb910715SAlp Dener if (1 == bfgsUpdates) { 633eb910715SAlp Dener /* The first BFGS direction is always the scaled gradient */ 634eb910715SAlp Dener *stepType = BNK_SCALED_GRADIENT; 635eb910715SAlp Dener } else { 636eb910715SAlp Dener *stepType = BNK_BFGS; 637eb910715SAlp Dener } 638eb910715SAlp Dener } 639eb910715SAlp Dener } 6408d5ead36SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 6418d5ead36SAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 642a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 643eb910715SAlp Dener } else { 644eb910715SAlp Dener /* Computed Newton step is descent */ 645eb910715SAlp Dener switch (ksp_reason) { 646eb910715SAlp Dener case KSP_DIVERGED_NANORINF: 647eb910715SAlp Dener case KSP_DIVERGED_BREAKDOWN: 648eb910715SAlp Dener case KSP_DIVERGED_INDEFINITE_MAT: 649eb910715SAlp Dener case KSP_DIVERGED_INDEFINITE_PC: 650eb910715SAlp Dener case KSP_CONVERGED_CG_NEG_CURVE: 651eb910715SAlp Dener /* Matrix or preconditioner is indefinite; increase perturbation */ 652eb910715SAlp Dener if (bnk->pert <= 0.0) { 653eb910715SAlp Dener /* Initialize the perturbation */ 654eb910715SAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 655eb910715SAlp Dener if (bnk->is_gltr) { 656eb910715SAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp, &e_min);CHKERRQ(ierr); 657eb910715SAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 658eb910715SAlp Dener } 659eb910715SAlp Dener } else { 660eb910715SAlp Dener /* Increase the perturbation */ 661eb910715SAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 662eb910715SAlp Dener } 663eb910715SAlp Dener break; 664eb910715SAlp Dener 665eb910715SAlp Dener default: 666eb910715SAlp Dener /* Newton step computation is good; decrease perturbation */ 667eb910715SAlp Dener bnk->pert = PetscMin(bnk->psfac * bnk->pert, bnk->pmsfac * bnk->gnorm); 668eb910715SAlp Dener if (bnk->pert < bnk->pmin) { 669eb910715SAlp Dener bnk->pert = 0.0; 670eb910715SAlp Dener } 671eb910715SAlp Dener break; 672eb910715SAlp Dener } 673fed79b8eSAlp Dener *stepType = BNK_NEWTON; 674eb910715SAlp Dener } 675*6b591159SAlp Dener break; 676*6b591159SAlp Dener 677*6b591159SAlp Dener case BNK_BFGS: 678*6b591159SAlp Dener /* Check for success (descent direction) */ 679*6b591159SAlp Dener ierr = VecDot(tao->stepdirection, tao->gradient, &gdx);CHKERRQ(ierr); 680*6b591159SAlp Dener if (gdx >= 0 || PetscIsInfOrNanReal(gdx)) { 681*6b591159SAlp Dener /* Step is not descent or solve was not successful 682*6b591159SAlp Dener Use steepest descent direction (scaled) */ 683*6b591159SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 684*6b591159SAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 685*6b591159SAlp Dener ierr = MatSolve(bnk->M, tao->gradient, tao->stepdirection);CHKERRQ(ierr); 686*6b591159SAlp Dener ierr = VecScale(tao->stepdirection,-1.0);CHKERRQ(ierr); 687*6b591159SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 688*6b591159SAlp Dener *stepType = BNK_SCALED_GRADIENT; 689*6b591159SAlp Dener } else { 690*6b591159SAlp Dener *stepType = BNK_BFGS; 691*6b591159SAlp Dener } 692*6b591159SAlp Dener break; 693*6b591159SAlp Dener 694*6b591159SAlp Dener case BNK_SCALED_GRADIENT: 695*6b591159SAlp Dener break; 696*6b591159SAlp Dener 697*6b591159SAlp Dener default: 698*6b591159SAlp Dener break; 699*6b591159SAlp Dener } 700*6b591159SAlp Dener 701eb910715SAlp Dener PetscFunctionReturn(0); 702eb910715SAlp Dener } 703eb910715SAlp Dener 704df278d8fSAlp Dener /*------------------------------------------------------------*/ 705df278d8fSAlp Dener 706df278d8fSAlp Dener /* Routine for performing a bound-projected More-Thuente line search. 707df278d8fSAlp Dener 708df278d8fSAlp Dener Includes fallbacks to BFGS, scaled gradient, and unscaled gradient steps if the 709df278d8fSAlp Dener Newton step does not produce a valid step length. 710df278d8fSAlp Dener */ 711df278d8fSAlp Dener 712937a31a1SAlp Dener PetscErrorCode TaoBNKPerformLineSearch(Tao tao, PetscInt *stepType, PetscReal *steplen, TaoLineSearchConvergedReason *reason) 713c14b763aSAlp Dener { 714c14b763aSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 715c14b763aSAlp Dener PetscErrorCode ierr; 716c14b763aSAlp Dener TaoLineSearchConvergedReason ls_reason; 717c14b763aSAlp Dener 718b2d8c577SAlp Dener PetscReal e_min, gdx; 719c14b763aSAlp Dener PetscInt bfgsUpdates; 720c14b763aSAlp Dener 721c14b763aSAlp Dener PetscFunctionBegin; 722c14b763aSAlp Dener /* Perform the linesearch */ 723c14b763aSAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &bnk->f, bnk->unprojected_gradient, tao->stepdirection, steplen, &ls_reason);CHKERRQ(ierr); 724c14b763aSAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 725c14b763aSAlp Dener 726b2d8c577SAlp Dener while (ls_reason != TAOLINESEARCH_SUCCESS && ls_reason != TAOLINESEARCH_SUCCESS_USER && *stepType != BNK_SCALED_GRADIENT && *stepType != BNK_GRADIENT) { 727c14b763aSAlp Dener /* Linesearch failed, revert solution */ 728c14b763aSAlp Dener bnk->f = bnk->fold; 729c14b763aSAlp Dener ierr = VecCopy(bnk->Xold, tao->solution);CHKERRQ(ierr); 730c14b763aSAlp Dener ierr = VecCopy(bnk->unprojected_gradient_old, bnk->unprojected_gradient);CHKERRQ(ierr); 731c14b763aSAlp Dener 732937a31a1SAlp Dener switch(*stepType) { 733c14b763aSAlp Dener case BNK_NEWTON: 7348d5ead36SAlp Dener /* Failed to obtain acceptable iterate with Newton step 735c14b763aSAlp Dener Update the perturbation for next time */ 736c14b763aSAlp Dener if (bnk->pert <= 0.0) { 737c14b763aSAlp Dener /* Initialize the perturbation */ 738c14b763aSAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 739c14b763aSAlp Dener if (bnk->is_gltr) { 740c14b763aSAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 741c14b763aSAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 742c14b763aSAlp Dener } 743c14b763aSAlp Dener } else { 744c14b763aSAlp Dener /* Increase the perturbation */ 745c14b763aSAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 746c14b763aSAlp Dener } 747c14b763aSAlp Dener 7480ad3a497SAlp Dener if (!bnk->M) { 749c14b763aSAlp Dener /* We don't have the bfgs matrix around and being updated 750c14b763aSAlp Dener Must use gradient direction in this case */ 751937a31a1SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 752937a31a1SAlp Dener *stepType = BNK_GRADIENT; 753c14b763aSAlp Dener } else { 754c14b763aSAlp Dener /* Attempt to use the BFGS direction */ 755cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 7568d5ead36SAlp Dener /* Check for success (descent direction) 7578d5ead36SAlp Dener NOTE: Negative gdx means not a descent direction because the step here is missing a negative sign. */ 758c14b763aSAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 7593105154fSTodd Munson if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 760c14b763aSAlp Dener /* BFGS direction is not descent or direction produced not a number 761c14b763aSAlp Dener We can assert bfgsUpdates > 1 in this case 762c14b763aSAlp Dener Use steepest descent direction (scaled) */ 763cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 764c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 765cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 766c14b763aSAlp Dener 767c14b763aSAlp Dener bfgsUpdates = 1; 768937a31a1SAlp Dener *stepType = BNK_SCALED_GRADIENT; 769c14b763aSAlp Dener } else { 770cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 771c14b763aSAlp Dener if (1 == bfgsUpdates) { 772c14b763aSAlp Dener /* The first BFGS direction is always the scaled gradient */ 773937a31a1SAlp Dener *stepType = BNK_SCALED_GRADIENT; 774c14b763aSAlp Dener } else { 775937a31a1SAlp Dener *stepType = BNK_BFGS; 776c14b763aSAlp Dener } 777c14b763aSAlp Dener } 778c14b763aSAlp Dener } 779c14b763aSAlp Dener break; 780c14b763aSAlp Dener 781c14b763aSAlp Dener case BNK_BFGS: 782c14b763aSAlp Dener /* Can only enter if pc_type == BNK_PC_BFGS 783c14b763aSAlp Dener Failed to obtain acceptable iterate with BFGS step 784c14b763aSAlp Dener Attempt to use the scaled gradient direction */ 785cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 786c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 787cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 788c14b763aSAlp Dener 789c14b763aSAlp Dener bfgsUpdates = 1; 790937a31a1SAlp Dener *stepType = BNK_SCALED_GRADIENT; 791c14b763aSAlp Dener break; 792c14b763aSAlp Dener } 7938d5ead36SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 7948d5ead36SAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 795a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 796c14b763aSAlp Dener 7978d5ead36SAlp Dener /* Perform one last line search with the fall-back step */ 798c14b763aSAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &bnk->f, bnk->unprojected_gradient, tao->stepdirection, steplen, &ls_reason);CHKERRQ(ierr); 799c14b763aSAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 800c14b763aSAlp Dener } 801c14b763aSAlp Dener *reason = ls_reason; 802c14b763aSAlp Dener PetscFunctionReturn(0); 803c14b763aSAlp Dener } 804c14b763aSAlp Dener 805df278d8fSAlp Dener /*------------------------------------------------------------*/ 806df278d8fSAlp Dener 807df278d8fSAlp Dener /* Routine for updating the trust radius. 808df278d8fSAlp Dener 809df278d8fSAlp Dener Function features three different update methods: 810df278d8fSAlp Dener 1) Line-search step length based 811df278d8fSAlp Dener 2) Predicted decrease on the CG quadratic model 812df278d8fSAlp Dener 3) Interpolation 813df278d8fSAlp Dener */ 814df278d8fSAlp Dener 81528017e9fSAlp Dener PetscErrorCode TaoBNKUpdateTrustRadius(Tao tao, PetscReal prered, PetscReal actred, PetscInt updateType, PetscInt stepType, PetscBool *accept) 816080d2917SAlp Dener { 817080d2917SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 818080d2917SAlp Dener PetscErrorCode ierr; 819080d2917SAlp Dener 820b1c2d0e3SAlp Dener PetscReal step, kappa; 821080d2917SAlp Dener PetscReal gdx, tau_1, tau_2, tau_min, tau_max; 822080d2917SAlp Dener 823080d2917SAlp Dener PetscFunctionBegin; 824080d2917SAlp Dener /* Update trust region radius */ 825080d2917SAlp Dener *accept = PETSC_FALSE; 82628017e9fSAlp Dener switch(updateType) { 827080d2917SAlp Dener case BNK_UPDATE_STEP: 828c14b763aSAlp Dener *accept = PETSC_TRUE; /* always accept here because line search succeeded */ 829080d2917SAlp Dener if (stepType == BNK_NEWTON) { 830080d2917SAlp Dener ierr = TaoLineSearchGetStepLength(tao->linesearch, &step);CHKERRQ(ierr); 831080d2917SAlp Dener if (step < bnk->nu1) { 832080d2917SAlp Dener /* Very bad step taken; reduce radius */ 833080d2917SAlp Dener tao->trust = bnk->omega1 * PetscMin(bnk->dnorm, tao->trust); 834080d2917SAlp Dener } else if (step < bnk->nu2) { 835080d2917SAlp Dener /* Reasonably bad step taken; reduce radius */ 836080d2917SAlp Dener tao->trust = bnk->omega2 * PetscMin(bnk->dnorm, tao->trust); 837080d2917SAlp Dener } else if (step < bnk->nu3) { 838080d2917SAlp Dener /* Reasonable step was taken; leave radius alone */ 839080d2917SAlp Dener if (bnk->omega3 < 1.0) { 840080d2917SAlp Dener tao->trust = bnk->omega3 * PetscMin(bnk->dnorm, tao->trust); 841080d2917SAlp Dener } else if (bnk->omega3 > 1.0) { 842080d2917SAlp Dener tao->trust = PetscMax(bnk->omega3 * bnk->dnorm, tao->trust); 843080d2917SAlp Dener } 844080d2917SAlp Dener } else if (step < bnk->nu4) { 845080d2917SAlp Dener /* Full step taken; increase the radius */ 846080d2917SAlp Dener tao->trust = PetscMax(bnk->omega4 * bnk->dnorm, tao->trust); 847080d2917SAlp Dener } else { 848080d2917SAlp Dener /* More than full step taken; increase the radius */ 849080d2917SAlp Dener tao->trust = PetscMax(bnk->omega5 * bnk->dnorm, tao->trust); 850080d2917SAlp Dener } 851080d2917SAlp Dener } else { 852080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 853080d2917SAlp Dener tao->trust = bnk->omega1 * PetscMin(bnk->dnorm, tao->trust); 854080d2917SAlp Dener } 855080d2917SAlp Dener break; 856080d2917SAlp Dener 857080d2917SAlp Dener case BNK_UPDATE_REDUCTION: 858080d2917SAlp Dener if (stepType == BNK_NEWTON) { 859e0ed867bSAlp Dener if ((prered < 0.0) || PetscIsInfOrNanReal(prered)) { 860fed79b8eSAlp Dener /* The predicted reduction has the wrong sign. This cannot 861fed79b8eSAlp Dener happen in infinite precision arithmetic. Step should 862fed79b8eSAlp Dener be rejected! */ 863080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 8643105154fSTodd Munson } else { 865b1c2d0e3SAlp Dener if (PetscIsInfOrNanReal(actred)) { 866080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 867080d2917SAlp Dener } else { 8683105154fSTodd Munson if ((PetscAbsScalar(actred) <= PetscMax(1.0, PetscAbsScalar(bnk->f))*bnk->epsilon) && (PetscAbsScalar(prered) <= PetscMax(1.0, PetscAbsScalar(bnk->f))*bnk->epsilon)) { 869080d2917SAlp Dener kappa = 1.0; 8703105154fSTodd Munson } else { 871080d2917SAlp Dener kappa = actred / prered; 872080d2917SAlp Dener } 873fed79b8eSAlp Dener /* Accept or reject the step and update radius */ 874080d2917SAlp Dener if (kappa < bnk->eta1) { 875fed79b8eSAlp Dener /* Reject the step */ 876080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 8773105154fSTodd Munson } else { 878fed79b8eSAlp Dener /* Accept the step */ 879c133c014SAlp Dener *accept = PETSC_TRUE; 880c133c014SAlp Dener /* Update the trust region radius only if the computed step is at the trust radius boundary */ 8818d5ead36SAlp Dener if (bnk->dnorm == tao->trust) { 882080d2917SAlp Dener if (kappa < bnk->eta2) { 883080d2917SAlp Dener /* Marginal bad step */ 884c133c014SAlp Dener tao->trust = bnk->alpha2 * tao->trust; 8853105154fSTodd Munson } else if (kappa < bnk->eta3) { 886fed79b8eSAlp Dener /* Reasonable step */ 887fed79b8eSAlp Dener tao->trust = bnk->alpha3 * tao->trust; 8883105154fSTodd Munson } else if (kappa < bnk->eta4) { 889080d2917SAlp Dener /* Good step */ 890c133c014SAlp Dener tao->trust = bnk->alpha4 * tao->trust; 8913105154fSTodd Munson } else { 892080d2917SAlp Dener /* Very good step */ 893c133c014SAlp Dener tao->trust = bnk->alpha5 * tao->trust; 894080d2917SAlp Dener } 895c133c014SAlp Dener } 896080d2917SAlp Dener } 897080d2917SAlp Dener } 898080d2917SAlp Dener } 899080d2917SAlp Dener } else { 900080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 901080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(bnk->dnorm, tao->trust); 902080d2917SAlp Dener } 903080d2917SAlp Dener break; 904080d2917SAlp Dener 905080d2917SAlp Dener default: 906080d2917SAlp Dener if (stepType == BNK_NEWTON) { 907b1c2d0e3SAlp Dener if (prered < 0.0) { 908080d2917SAlp Dener /* The predicted reduction has the wrong sign. This cannot */ 909080d2917SAlp Dener /* happen in infinite precision arithmetic. Step should */ 910080d2917SAlp Dener /* be rejected! */ 911080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 912080d2917SAlp Dener } else { 913b1c2d0e3SAlp Dener if (PetscIsInfOrNanReal(actred)) { 914080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 915080d2917SAlp Dener } else { 916080d2917SAlp Dener if ((PetscAbsScalar(actred) <= bnk->epsilon) && (PetscAbsScalar(prered) <= bnk->epsilon)) { 917080d2917SAlp Dener kappa = 1.0; 918080d2917SAlp Dener } else { 919080d2917SAlp Dener kappa = actred / prered; 920080d2917SAlp Dener } 921080d2917SAlp Dener 922080d2917SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 923080d2917SAlp Dener tau_1 = bnk->theta * gdx / (bnk->theta * gdx - (1.0 - bnk->theta) * prered + actred); 924080d2917SAlp Dener tau_2 = bnk->theta * gdx / (bnk->theta * gdx + (1.0 + bnk->theta) * prered - actred); 925080d2917SAlp Dener tau_min = PetscMin(tau_1, tau_2); 926080d2917SAlp Dener tau_max = PetscMax(tau_1, tau_2); 927080d2917SAlp Dener 928080d2917SAlp Dener if (kappa >= 1.0 - bnk->mu1) { 929080d2917SAlp Dener /* Great agreement */ 930080d2917SAlp Dener *accept = PETSC_TRUE; 931080d2917SAlp Dener if (tau_max < 1.0) { 932080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma3 * bnk->dnorm); 933080d2917SAlp Dener } else if (tau_max > bnk->gamma4) { 934080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma4 * bnk->dnorm); 935080d2917SAlp Dener } else { 936080d2917SAlp Dener tao->trust = PetscMax(tao->trust, tau_max * bnk->dnorm); 937080d2917SAlp Dener } 938080d2917SAlp Dener } else if (kappa >= 1.0 - bnk->mu2) { 939080d2917SAlp Dener /* Good agreement */ 940080d2917SAlp Dener *accept = PETSC_TRUE; 941080d2917SAlp Dener if (tau_max < bnk->gamma2) { 942080d2917SAlp Dener tao->trust = bnk->gamma2 * PetscMin(tao->trust, bnk->dnorm); 943080d2917SAlp Dener } else if (tau_max > bnk->gamma3) { 944080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma3 * bnk->dnorm); 945080d2917SAlp Dener } else if (tau_max < 1.0) { 946080d2917SAlp Dener tao->trust = tau_max * PetscMin(tao->trust, bnk->dnorm); 947080d2917SAlp Dener } else { 948080d2917SAlp Dener tao->trust = PetscMax(tao->trust, tau_max * bnk->dnorm); 949080d2917SAlp Dener } 950080d2917SAlp Dener } else { 951080d2917SAlp Dener /* Not good agreement */ 952080d2917SAlp Dener if (tau_min > 1.0) { 953080d2917SAlp Dener tao->trust = bnk->gamma2 * PetscMin(tao->trust, bnk->dnorm); 954080d2917SAlp Dener } else if (tau_max < bnk->gamma1) { 955080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 956080d2917SAlp Dener } else if ((tau_min < bnk->gamma1) && (tau_max >= 1.0)) { 957080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 958080d2917SAlp Dener } else if ((tau_1 >= bnk->gamma1) && (tau_1 < 1.0) && ((tau_2 < bnk->gamma1) || (tau_2 >= 1.0))) { 959080d2917SAlp Dener tao->trust = tau_1 * PetscMin(tao->trust, bnk->dnorm); 960080d2917SAlp Dener } else if ((tau_2 >= bnk->gamma1) && (tau_2 < 1.0) && ((tau_1 < bnk->gamma1) || (tau_2 >= 1.0))) { 961080d2917SAlp Dener tao->trust = tau_2 * PetscMin(tao->trust, bnk->dnorm); 962080d2917SAlp Dener } else { 963080d2917SAlp Dener tao->trust = tau_max * PetscMin(tao->trust, bnk->dnorm); 964080d2917SAlp Dener } 965080d2917SAlp Dener } 966080d2917SAlp Dener } 967080d2917SAlp Dener } 968080d2917SAlp Dener } else { 969080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 970080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(bnk->dnorm, tao->trust); 971080d2917SAlp Dener } 97228017e9fSAlp Dener break; 973080d2917SAlp Dener } 974c133c014SAlp Dener /* Make sure the radius does not violate min and max settings */ 975c133c014SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 976fed79b8eSAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 977080d2917SAlp Dener PetscFunctionReturn(0); 978080d2917SAlp Dener } 979080d2917SAlp Dener 980eb910715SAlp Dener /* ---------------------------------------------------------- */ 981df278d8fSAlp Dener 98262675beeSAlp Dener PetscErrorCode TaoBNKAddStepCounts(Tao tao, PetscInt stepType) 98362675beeSAlp Dener { 98462675beeSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 98562675beeSAlp Dener 98662675beeSAlp Dener PetscFunctionBegin; 98762675beeSAlp Dener switch (stepType) { 98862675beeSAlp Dener case BNK_NEWTON: 98962675beeSAlp Dener ++bnk->newt; 99062675beeSAlp Dener break; 99162675beeSAlp Dener case BNK_BFGS: 99262675beeSAlp Dener ++bnk->bfgs; 99362675beeSAlp Dener break; 99462675beeSAlp Dener case BNK_SCALED_GRADIENT: 99562675beeSAlp Dener ++bnk->sgrad; 99662675beeSAlp Dener break; 99762675beeSAlp Dener case BNK_GRADIENT: 99862675beeSAlp Dener ++bnk->grad; 99962675beeSAlp Dener break; 100062675beeSAlp Dener default: 100162675beeSAlp Dener break; 100262675beeSAlp Dener } 100362675beeSAlp Dener PetscFunctionReturn(0); 100462675beeSAlp Dener } 100562675beeSAlp Dener 100662675beeSAlp Dener /* ---------------------------------------------------------- */ 100762675beeSAlp Dener 10089b6ef848SAlp Dener PetscErrorCode TaoSetUp_BNK(Tao tao) 1009eb910715SAlp Dener { 1010eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1011eb910715SAlp Dener PetscErrorCode ierr; 1012e031d6f5SAlp Dener PetscInt i; 1013eb910715SAlp Dener 1014eb910715SAlp Dener PetscFunctionBegin; 1015c4b75bccSAlp Dener if (!tao->gradient) { 1016c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr); 1017c4b75bccSAlp Dener } 1018c4b75bccSAlp Dener if (!tao->stepdirection) { 1019c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr); 1020c4b75bccSAlp Dener } 1021c4b75bccSAlp Dener if (!bnk->W) { 1022c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->W);CHKERRQ(ierr); 1023c4b75bccSAlp Dener } 1024c4b75bccSAlp Dener if (!bnk->Xold) { 1025c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Xold);CHKERRQ(ierr); 1026c4b75bccSAlp Dener } 1027c4b75bccSAlp Dener if (!bnk->Gold) { 1028c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Gold);CHKERRQ(ierr); 1029c4b75bccSAlp Dener } 1030c4b75bccSAlp Dener if (!bnk->Xwork) { 1031c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Xwork);CHKERRQ(ierr); 1032c4b75bccSAlp Dener } 1033c4b75bccSAlp Dener if (!bnk->Gwork) { 1034c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Gwork);CHKERRQ(ierr); 1035c4b75bccSAlp Dener } 1036c4b75bccSAlp Dener if (!bnk->unprojected_gradient) { 1037c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->unprojected_gradient);CHKERRQ(ierr); 1038c4b75bccSAlp Dener } 1039c4b75bccSAlp Dener if (!bnk->unprojected_gradient_old) { 1040c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->unprojected_gradient_old);CHKERRQ(ierr); 1041c4b75bccSAlp Dener } 1042c4b75bccSAlp Dener if (!bnk->Diag_min) { 1043c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Diag_min);CHKERRQ(ierr); 1044c4b75bccSAlp Dener } 1045c4b75bccSAlp Dener if (!bnk->Diag_max) { 1046c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Diag_max);CHKERRQ(ierr); 1047c4b75bccSAlp Dener } 1048e031d6f5SAlp Dener if (bnk->max_cg_its > 0) { 1049c4b75bccSAlp Dener /* Ensure that the important common vectors are shared between BNK and embedded BNCG */ 1050c4b75bccSAlp Dener bnk->bncg_ctx = (TAO_BNCG *)bnk->bncg->data; 105189da521bSAlp Dener ierr = PetscObjectReference((PetscObject)(bnk->unprojected_gradient_old));CHKERRQ(ierr); 105289da521bSAlp Dener ierr = VecDestroy(&bnk->bncg_ctx->unprojected_gradient_old);CHKERRQ(ierr); 105389da521bSAlp Dener bnk->bncg_ctx->unprojected_gradient_old = bnk->unprojected_gradient_old; 1054c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(bnk->unprojected_gradient));CHKERRQ(ierr); 1055c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg_ctx->unprojected_gradient);CHKERRQ(ierr); 1056c4b75bccSAlp Dener bnk->bncg_ctx->unprojected_gradient = bnk->unprojected_gradient; 1057c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(bnk->Gold));CHKERRQ(ierr); 1058c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg_ctx->G_old);CHKERRQ(ierr); 1059c4b75bccSAlp Dener bnk->bncg_ctx->G_old = bnk->Gold; 1060c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(tao->gradient));CHKERRQ(ierr); 1061c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg->gradient);CHKERRQ(ierr); 1062c4b75bccSAlp Dener bnk->bncg->gradient = tao->gradient; 1063c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(tao->stepdirection));CHKERRQ(ierr); 1064c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg->stepdirection);CHKERRQ(ierr); 1065c4b75bccSAlp Dener bnk->bncg->stepdirection = tao->stepdirection; 1066c4b75bccSAlp Dener ierr = TaoSetInitialVector(bnk->bncg, tao->solution);CHKERRQ(ierr); 1067c4b75bccSAlp Dener /* Copy over some settings from BNK into BNCG */ 1068e031d6f5SAlp Dener ierr = TaoSetMaximumIterations(bnk->bncg, bnk->max_cg_its);CHKERRQ(ierr); 1069e031d6f5SAlp Dener ierr = TaoSetTolerances(bnk->bncg, tao->gatol, tao->grtol, tao->gttol);CHKERRQ(ierr); 1070e031d6f5SAlp Dener ierr = TaoSetFunctionLowerBound(bnk->bncg, tao->fmin);CHKERRQ(ierr); 1071937a31a1SAlp Dener ierr = TaoSetConvergenceTest(bnk->bncg, tao->ops->convergencetest, tao->cnvP);CHKERRQ(ierr); 1072e031d6f5SAlp Dener ierr = TaoSetObjectiveRoutine(bnk->bncg, tao->ops->computeobjective, tao->user_objP);CHKERRQ(ierr); 1073e031d6f5SAlp Dener ierr = TaoSetGradientRoutine(bnk->bncg, tao->ops->computegradient, tao->user_gradP);CHKERRQ(ierr); 1074e031d6f5SAlp Dener ierr = TaoSetObjectiveAndGradientRoutine(bnk->bncg, tao->ops->computeobjectiveandgradient, tao->user_objgradP);CHKERRQ(ierr); 1075e031d6f5SAlp Dener ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)tao, (PetscObject)(bnk->bncg));CHKERRQ(ierr); 1076c4b75bccSAlp Dener for (i=0; i<tao->numbermonitors; ++i) { 1077e031d6f5SAlp Dener ierr = TaoSetMonitor(bnk->bncg, tao->monitor[i], tao->monitorcontext[i], tao->monitordestroy[i]);CHKERRQ(ierr); 1078e031d6f5SAlp Dener ierr = PetscObjectReference((PetscObject)(tao->monitorcontext[i]));CHKERRQ(ierr); 1079e031d6f5SAlp Dener } 1080e031d6f5SAlp Dener } 1081c0f10754SAlp Dener bnk->X_inactive = 0; 1082c0f10754SAlp Dener bnk->G_inactive = 0; 108362675beeSAlp Dener bnk->inactive_work = 0; 108462675beeSAlp Dener bnk->active_work = 0; 108562675beeSAlp Dener bnk->inactive_idx = 0; 108662675beeSAlp Dener bnk->active_idx = 0; 108762675beeSAlp Dener bnk->active_lower = 0; 108862675beeSAlp Dener bnk->active_upper = 0; 108962675beeSAlp Dener bnk->active_fixed = 0; 1090eb910715SAlp Dener bnk->M = 0; 109109164190SAlp Dener bnk->H_inactive = 0; 109209164190SAlp Dener bnk->Hpre_inactive = 0; 1093eb910715SAlp Dener PetscFunctionReturn(0); 1094eb910715SAlp Dener } 1095eb910715SAlp Dener 1096eb910715SAlp Dener /*------------------------------------------------------------*/ 1097df278d8fSAlp Dener 1098e0ed867bSAlp Dener PetscErrorCode TaoDestroy_BNK(Tao tao) 1099eb910715SAlp Dener { 1100eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1101eb910715SAlp Dener PetscErrorCode ierr; 1102eb910715SAlp Dener 1103eb910715SAlp Dener PetscFunctionBegin; 1104eb910715SAlp Dener if (tao->setupcalled) { 1105eb910715SAlp Dener ierr = VecDestroy(&bnk->W);CHKERRQ(ierr); 1106eb910715SAlp Dener ierr = VecDestroy(&bnk->Xold);CHKERRQ(ierr); 1107eb910715SAlp Dener ierr = VecDestroy(&bnk->Gold);CHKERRQ(ierr); 110809164190SAlp Dener ierr = VecDestroy(&bnk->Xwork);CHKERRQ(ierr); 110909164190SAlp Dener ierr = VecDestroy(&bnk->Gwork);CHKERRQ(ierr); 111009164190SAlp Dener ierr = VecDestroy(&bnk->unprojected_gradient);CHKERRQ(ierr); 111109164190SAlp Dener ierr = VecDestroy(&bnk->unprojected_gradient_old);CHKERRQ(ierr); 111262675beeSAlp Dener ierr = VecDestroy(&bnk->Diag_min);CHKERRQ(ierr); 111362675beeSAlp Dener ierr = VecDestroy(&bnk->Diag_max);CHKERRQ(ierr); 1114c4b75bccSAlp Dener } 1115ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_lower);CHKERRQ(ierr); 1116ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_upper);CHKERRQ(ierr); 1117ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_fixed);CHKERRQ(ierr); 1118ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_idx);CHKERRQ(ierr); 1119ca964c49SAlp Dener ierr = ISDestroy(&bnk->inactive_idx);CHKERRQ(ierr); 1120c4b75bccSAlp Dener if (bnk->Hpre_inactive != tao->hessian_pre && bnk->Hpre_inactive != bnk->H_inactive) { 1121c4b75bccSAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 1122c4b75bccSAlp Dener } 1123c4b75bccSAlp Dener if (bnk->H_inactive != tao->hessian) { 1124c4b75bccSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 1125c4b75bccSAlp Dener } 1126ca964c49SAlp Dener ierr = TaoDestroy(&bnk->bncg);CHKERRQ(ierr); 1127eb910715SAlp Dener ierr = PetscFree(tao->data);CHKERRQ(ierr); 1128eb910715SAlp Dener PetscFunctionReturn(0); 1129eb910715SAlp Dener } 1130eb910715SAlp Dener 1131eb910715SAlp Dener /*------------------------------------------------------------*/ 1132df278d8fSAlp Dener 1133e0ed867bSAlp Dener PetscErrorCode TaoSetFromOptions_BNK(PetscOptionItems *PetscOptionsObject,Tao tao) 1134eb910715SAlp Dener { 1135eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1136eb910715SAlp Dener PetscErrorCode ierr; 1137e0ed867bSAlp Dener KSPType ksp_type; 1138eb910715SAlp Dener 1139eb910715SAlp Dener PetscFunctionBegin; 11404f4fdda4SAlp Dener ierr = PetscOptionsHead(PetscOptionsObject,"Newton-Krylov method for bound constrained optimization");CHKERRQ(ierr); 11418d5ead36SAlp 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); 11428d5ead36SAlp 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); 11432f75a4aaSAlp 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); 1144748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_sval", "(developer) Hessian perturbation starting value", "", bnk->sval, &bnk->sval,NULL);CHKERRQ(ierr); 1145748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imin", "(developer) minimum initial Hessian perturbation", "", bnk->imin, &bnk->imin,NULL);CHKERRQ(ierr); 1146748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imax", "(developer) maximum initial Hessian perturbation", "", bnk->imax, &bnk->imax,NULL);CHKERRQ(ierr); 1147748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imfac", "(developer) initial merit factor for Hessian perturbation", "", bnk->imfac, &bnk->imfac,NULL);CHKERRQ(ierr); 1148748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmin", "(developer) minimum Hessian perturbation", "", bnk->pmin, &bnk->pmin,NULL);CHKERRQ(ierr); 1149748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmax", "(developer) maximum Hessian perturbation", "", bnk->pmax, &bnk->pmax,NULL);CHKERRQ(ierr); 1150748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pgfac", "(developer) Hessian perturbation growth factor", "", bnk->pgfac, &bnk->pgfac,NULL);CHKERRQ(ierr); 1151748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_psfac", "(developer) Hessian perturbation shrink factor", "", bnk->psfac, &bnk->psfac,NULL);CHKERRQ(ierr); 1152748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmgfac", "(developer) merit growth factor for Hessian perturbation", "", bnk->pmgfac, &bnk->pmgfac,NULL);CHKERRQ(ierr); 1153748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmsfac", "(developer) merit shrink factor for Hessian perturbation", "", bnk->pmsfac, &bnk->pmsfac,NULL);CHKERRQ(ierr); 1154748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta1", "(developer) threshold for rejecting step (-tao_bnk_update_type reduction)", "", bnk->eta1, &bnk->eta1,NULL);CHKERRQ(ierr); 1155748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta2", "(developer) threshold for accepting marginal step (-tao_bnk_update_type reduction)", "", bnk->eta2, &bnk->eta2,NULL);CHKERRQ(ierr); 1156748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta3", "(developer) threshold for accepting reasonable step (-tao_bnk_update_type reduction)", "", bnk->eta3, &bnk->eta3,NULL);CHKERRQ(ierr); 1157748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta4", "(developer) threshold for accepting good step (-tao_bnk_update_type reduction)", "", bnk->eta4, &bnk->eta4,NULL);CHKERRQ(ierr); 1158748696b1SAlp 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); 1159748696b1SAlp 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); 1160748696b1SAlp 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); 1161748696b1SAlp 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); 1162748696b1SAlp 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); 1163748696b1SAlp 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); 1164748696b1SAlp 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); 1165748696b1SAlp 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); 1166748696b1SAlp 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); 1167748696b1SAlp 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); 1168748696b1SAlp 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); 1169748696b1SAlp 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); 1170748696b1SAlp 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); 1171748696b1SAlp 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); 1172748696b1SAlp 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); 1173748696b1SAlp 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); 1174748696b1SAlp 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); 1175748696b1SAlp 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); 1176748696b1SAlp 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); 1177748696b1SAlp 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); 1178748696b1SAlp 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); 1179748696b1SAlp 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); 1180748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu2", "(developer) threshold for accepting good step (-tao_bnk_update_type interpolation)", "", bnk->mu2, &bnk->mu2,NULL);CHKERRQ(ierr); 1181748696b1SAlp 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); 1182748696b1SAlp 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); 1183748696b1SAlp 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); 1184748696b1SAlp 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); 1185748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_theta", "(developer) trust region interpolation factor (-tao_bnk_update_type interpolation)", "", bnk->theta, &bnk->theta,NULL);CHKERRQ(ierr); 1186748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_min_radius", "(developer) lower bound on initial radius", "", bnk->min_radius, &bnk->min_radius,NULL);CHKERRQ(ierr); 1187748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_max_radius", "(developer) upper bound on radius", "", bnk->max_radius, &bnk->max_radius,NULL);CHKERRQ(ierr); 1188748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_epsilon", "(developer) tolerance used when computing actual and predicted reduction", "", bnk->epsilon, &bnk->epsilon,NULL);CHKERRQ(ierr); 1189748696b1SAlp 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); 1190748696b1SAlp 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); 1191c0f10754SAlp 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); 1192eb910715SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 119333c78596SAlp Dener ierr = TaoSetFromOptions(bnk->bncg);CHKERRQ(ierr); 1194eb910715SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 1195eb910715SAlp Dener ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 1196e0ed867bSAlp Dener ierr = KSPGetType(tao->ksp,&ksp_type);CHKERRQ(ierr); 1197e0ed867bSAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGNASH,&bnk->is_nash);CHKERRQ(ierr); 1198e0ed867bSAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGSTCG,&bnk->is_stcg);CHKERRQ(ierr); 1199e0ed867bSAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGGLTR,&bnk->is_gltr);CHKERRQ(ierr); 1200eb910715SAlp Dener PetscFunctionReturn(0); 1201eb910715SAlp Dener } 1202eb910715SAlp Dener 1203eb910715SAlp Dener /*------------------------------------------------------------*/ 1204df278d8fSAlp Dener 1205e0ed867bSAlp Dener PetscErrorCode TaoView_BNK(Tao tao, PetscViewer viewer) 1206eb910715SAlp Dener { 1207eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1208eb910715SAlp Dener PetscInt nrejects; 1209eb910715SAlp Dener PetscBool isascii; 1210eb910715SAlp Dener PetscErrorCode ierr; 1211eb910715SAlp Dener 1212eb910715SAlp Dener PetscFunctionBegin; 1213eb910715SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1214eb910715SAlp Dener if (isascii) { 1215eb910715SAlp Dener ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1216b9ac7092SAlp Dener if (bnk->M) { 1217cd929ea3SAlp Dener ierr = MatLMVMGetRejectCount(bnk->M,&nrejects);CHKERRQ(ierr); 1218b9ac7092SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Rejected BFGS updates: %D\n",nrejects);CHKERRQ(ierr); 1219eb910715SAlp Dener } 1220e031d6f5SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "CG steps: %D\n", bnk->tot_cg_its);CHKERRQ(ierr); 1221eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Newton steps: %D\n", bnk->newt);CHKERRQ(ierr); 1222b9ac7092SAlp Dener if (bnk->M) { 1223eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "BFGS steps: %D\n", bnk->bfgs);CHKERRQ(ierr); 1224b9ac7092SAlp Dener } 1225eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Scaled gradient steps: %D\n", bnk->sgrad);CHKERRQ(ierr); 1226eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", bnk->grad);CHKERRQ(ierr); 1227eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "KSP termination reasons:\n");CHKERRQ(ierr); 1228eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " atol: %D\n", bnk->ksp_atol);CHKERRQ(ierr); 1229eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " rtol: %D\n", bnk->ksp_rtol);CHKERRQ(ierr); 1230eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " ctol: %D\n", bnk->ksp_ctol);CHKERRQ(ierr); 1231eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " negc: %D\n", bnk->ksp_negc);CHKERRQ(ierr); 1232eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " dtol: %D\n", bnk->ksp_dtol);CHKERRQ(ierr); 1233eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " iter: %D\n", bnk->ksp_iter);CHKERRQ(ierr); 1234eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " othr: %D\n", bnk->ksp_othr);CHKERRQ(ierr); 1235eb910715SAlp Dener ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1236eb910715SAlp Dener } 1237eb910715SAlp Dener PetscFunctionReturn(0); 1238eb910715SAlp Dener } 1239eb910715SAlp Dener 1240eb910715SAlp Dener /* ---------------------------------------------------------- */ 1241df278d8fSAlp Dener 1242eb910715SAlp Dener /*MC 1243eb910715SAlp Dener TAOBNK - Shared base-type for Bounded Newton-Krylov type algorithms. 124466ed3702SAlp Dener At each iteration, the BNK methods solve the symmetric 1245eb910715SAlp Dener system of equations to obtain the step diretion dk: 1246eb910715SAlp Dener Hk dk = -gk 12472b97c8d8SAlp Dener for free variables only. The step can be globalized either through 12482b97c8d8SAlp Dener trust-region methods, or a line search, or a heuristic mixture of both. 1249eb910715SAlp Dener 1250eb910715SAlp Dener Options Database Keys: 1251e0ed867bSAlp Dener + -max_cg_its - maximum number of bounded conjugate-gradient iterations taken in each Newton loop 1252e0ed867bSAlp Dener . -init_type - trust radius initialization method ("constant", "direction", "interpolation") 1253e0ed867bSAlp Dener . -update_type - trust radius update method ("step", "direction", "interpolation") 1254e0ed867bSAlp Dener . -as_type - active-set estimation method ("none", "bertsekas") 1255e0ed867bSAlp Dener . -as_tol - (developer) initial tolerance used in estimating bounded active variables (-as_type bertsekas) 1256e0ed867bSAlp Dener . -as_step - (developer) trial step length used in estimating bounded active variables (-as_type bertsekas) 1257e0ed867bSAlp Dener . -sval - (developer) Hessian perturbation starting value 1258e0ed867bSAlp Dener . -imin - (developer) minimum initial Hessian perturbation 1259e0ed867bSAlp Dener . -imax - (developer) maximum initial Hessian perturbation 1260e0ed867bSAlp Dener . -pmin - (developer) minimum Hessian perturbation 1261e0ed867bSAlp Dener . -pmax - (developer) aximum Hessian perturbation 1262e0ed867bSAlp Dener . -pgfac - (developer) Hessian perturbation growth factor 1263e0ed867bSAlp Dener . -psfac - (developer) Hessian perturbation shrink factor 1264e0ed867bSAlp Dener . -imfac - (developer) initial merit factor for Hessian perturbation 1265e0ed867bSAlp Dener . -pmgfac - (developer) merit growth factor for Hessian perturbation 1266e0ed867bSAlp Dener . -pmsfac - (developer) merit shrink factor for Hessian perturbation 1267e0ed867bSAlp Dener . -eta1 - (developer) threshold for rejecting step (-update_type reduction) 1268e0ed867bSAlp Dener . -eta2 - (developer) threshold for accepting marginal step (-update_type reduction) 1269e0ed867bSAlp Dener . -eta3 - (developer) threshold for accepting reasonable step (-update_type reduction) 1270e0ed867bSAlp Dener . -eta4 - (developer) threshold for accepting good step (-update_type reduction) 1271e0ed867bSAlp Dener . -alpha1 - (developer) radius reduction factor for rejected step (-update_type reduction) 1272e0ed867bSAlp Dener . -alpha2 - (developer) radius reduction factor for marginally accepted bad step (-update_type reduction) 1273e0ed867bSAlp Dener . -alpha3 - (developer) radius increase factor for reasonable accepted step (-update_type reduction) 1274e0ed867bSAlp Dener . -alpha4 - (developer) radius increase factor for good accepted step (-update_type reduction) 1275e0ed867bSAlp Dener . -alpha5 - (developer) radius increase factor for very good accepted step (-update_type reduction) 1276e0ed867bSAlp Dener . -epsilon - (developer) tolerance for small pred/actual ratios that trigger automatic step acceptance (-update_type reduction) 1277e0ed867bSAlp Dener . -mu1 - (developer) threshold for accepting very good step (-update_type interpolation) 1278e0ed867bSAlp Dener . -mu2 - (developer) threshold for accepting good step (-update_type interpolation) 1279e0ed867bSAlp Dener . -gamma1 - (developer) radius reduction factor for rejected very bad step (-update_type interpolation) 1280e0ed867bSAlp Dener . -gamma2 - (developer) radius reduction factor for rejected bad step (-update_type interpolation) 1281e0ed867bSAlp Dener . -gamma3 - (developer) radius increase factor for accepted good step (-update_type interpolation) 1282e0ed867bSAlp Dener . -gamma4 - (developer) radius increase factor for accepted very good step (-update_type interpolation) 1283e0ed867bSAlp Dener . -theta - (developer) trust region interpolation factor (-update_type interpolation) 1284e0ed867bSAlp Dener . -nu1 - (developer) threshold for small line-search step length (-update_type step) 1285e0ed867bSAlp Dener . -nu2 - (developer) threshold for reasonable line-search step length (-update_type step) 1286e0ed867bSAlp Dener . -nu3 - (developer) threshold for large line-search step length (-update_type step) 1287e0ed867bSAlp Dener . -nu4 - (developer) threshold for very large line-search step length (-update_type step) 1288e0ed867bSAlp Dener . -omega1 - (developer) radius reduction factor for very small line-search step length (-update_type step) 1289e0ed867bSAlp Dener . -omega2 - (developer) radius reduction factor for small line-search step length (-update_type step) 1290e0ed867bSAlp Dener . -omega3 - (developer) radius factor for decent line-search step length (-update_type step) 1291e0ed867bSAlp Dener . -omega4 - (developer) radius increase factor for large line-search step length (-update_type step) 1292e0ed867bSAlp Dener . -omega5 - (developer) radius increase factor for very large line-search step length (-update_type step) 1293e0ed867bSAlp Dener . -mu1_i - (developer) threshold for accepting very good step (-init_type interpolation) 1294e0ed867bSAlp Dener . -mu2_i - (developer) threshold for accepting good step (-init_type interpolation) 1295e0ed867bSAlp Dener . -gamma1_i - (developer) radius reduction factor for rejected very bad step (-init_type interpolation) 1296e0ed867bSAlp Dener . -gamma2_i - (developer) radius reduction factor for rejected bad step (-init_type interpolation) 1297e0ed867bSAlp Dener . -gamma3_i - (developer) radius increase factor for accepted good step (-init_type interpolation) 1298e0ed867bSAlp Dener . -gamma4_i - (developer) radius increase factor for accepted very good step (-init_type interpolation) 1299e0ed867bSAlp Dener - -theta_i - (developer) trust region interpolation factor (-init_type interpolation) 1300eb910715SAlp Dener 1301eb910715SAlp Dener Level: beginner 1302eb910715SAlp Dener M*/ 1303eb910715SAlp Dener 1304eb910715SAlp Dener PetscErrorCode TaoCreate_BNK(Tao tao) 1305eb910715SAlp Dener { 1306eb910715SAlp Dener TAO_BNK *bnk; 1307eb910715SAlp Dener const char *morethuente_type = TAOLINESEARCHMT; 1308eb910715SAlp Dener PetscErrorCode ierr; 1309b9ac7092SAlp Dener PC pc; 1310eb910715SAlp Dener 1311eb910715SAlp Dener PetscFunctionBegin; 1312eb910715SAlp Dener ierr = PetscNewLog(tao,&bnk);CHKERRQ(ierr); 1313eb910715SAlp Dener 1314eb910715SAlp Dener tao->ops->setup = TaoSetUp_BNK; 1315eb910715SAlp Dener tao->ops->view = TaoView_BNK; 1316eb910715SAlp Dener tao->ops->setfromoptions = TaoSetFromOptions_BNK; 1317eb910715SAlp Dener tao->ops->destroy = TaoDestroy_BNK; 1318eb910715SAlp Dener 1319eb910715SAlp Dener /* Override default settings (unless already changed) */ 1320eb910715SAlp Dener if (!tao->max_it_changed) tao->max_it = 50; 1321eb910715SAlp Dener if (!tao->trust0_changed) tao->trust0 = 100.0; 1322eb910715SAlp Dener 1323eb910715SAlp Dener tao->data = (void*)bnk; 1324eb910715SAlp Dener 132566ed3702SAlp Dener /* Hessian shifting parameters */ 1326e0ed867bSAlp Dener bnk->computehessian = TaoBNKComputeHessian; 1327e0ed867bSAlp Dener bnk->computestep = TaoBNKComputeStep; 1328e0ed867bSAlp Dener 1329eb910715SAlp Dener bnk->sval = 0.0; 1330eb910715SAlp Dener bnk->imin = 1.0e-4; 1331eb910715SAlp Dener bnk->imax = 1.0e+2; 1332eb910715SAlp Dener bnk->imfac = 1.0e-1; 1333eb910715SAlp Dener 1334eb910715SAlp Dener bnk->pmin = 1.0e-12; 1335eb910715SAlp Dener bnk->pmax = 1.0e+2; 1336eb910715SAlp Dener bnk->pgfac = 1.0e+1; 1337eb910715SAlp Dener bnk->psfac = 4.0e-1; 1338eb910715SAlp Dener bnk->pmgfac = 1.0e-1; 1339eb910715SAlp Dener bnk->pmsfac = 1.0e-1; 1340eb910715SAlp Dener 1341eb910715SAlp Dener /* Default values for trust-region radius update based on steplength */ 1342eb910715SAlp Dener bnk->nu1 = 0.25; 1343eb910715SAlp Dener bnk->nu2 = 0.50; 1344eb910715SAlp Dener bnk->nu3 = 1.00; 1345eb910715SAlp Dener bnk->nu4 = 1.25; 1346eb910715SAlp Dener 1347eb910715SAlp Dener bnk->omega1 = 0.25; 1348eb910715SAlp Dener bnk->omega2 = 0.50; 1349eb910715SAlp Dener bnk->omega3 = 1.00; 1350eb910715SAlp Dener bnk->omega4 = 2.00; 1351eb910715SAlp Dener bnk->omega5 = 4.00; 1352eb910715SAlp Dener 1353eb910715SAlp Dener /* Default values for trust-region radius update based on reduction */ 1354eb910715SAlp Dener bnk->eta1 = 1.0e-4; 1355eb910715SAlp Dener bnk->eta2 = 0.25; 1356eb910715SAlp Dener bnk->eta3 = 0.50; 1357eb910715SAlp Dener bnk->eta4 = 0.90; 1358eb910715SAlp Dener 1359eb910715SAlp Dener bnk->alpha1 = 0.25; 1360eb910715SAlp Dener bnk->alpha2 = 0.50; 1361eb910715SAlp Dener bnk->alpha3 = 1.00; 1362eb910715SAlp Dener bnk->alpha4 = 2.00; 1363eb910715SAlp Dener bnk->alpha5 = 4.00; 1364eb910715SAlp Dener 1365eb910715SAlp Dener /* Default values for trust-region radius update based on interpolation */ 1366eb910715SAlp Dener bnk->mu1 = 0.10; 1367eb910715SAlp Dener bnk->mu2 = 0.50; 1368eb910715SAlp Dener 1369eb910715SAlp Dener bnk->gamma1 = 0.25; 1370eb910715SAlp Dener bnk->gamma2 = 0.50; 1371eb910715SAlp Dener bnk->gamma3 = 2.00; 1372eb910715SAlp Dener bnk->gamma4 = 4.00; 1373eb910715SAlp Dener 1374eb910715SAlp Dener bnk->theta = 0.05; 1375eb910715SAlp Dener 1376eb910715SAlp Dener /* Default values for trust region initialization based on interpolation */ 1377eb910715SAlp Dener bnk->mu1_i = 0.35; 1378eb910715SAlp Dener bnk->mu2_i = 0.50; 1379eb910715SAlp Dener 1380eb910715SAlp Dener bnk->gamma1_i = 0.0625; 1381eb910715SAlp Dener bnk->gamma2_i = 0.5; 1382eb910715SAlp Dener bnk->gamma3_i = 2.0; 1383eb910715SAlp Dener bnk->gamma4_i = 5.0; 1384eb910715SAlp Dener 1385eb910715SAlp Dener bnk->theta_i = 0.25; 1386eb910715SAlp Dener 1387eb910715SAlp Dener /* Remaining parameters */ 1388c0f10754SAlp Dener bnk->max_cg_its = 0; 1389eb910715SAlp Dener bnk->min_radius = 1.0e-10; 1390eb910715SAlp Dener bnk->max_radius = 1.0e10; 1391770b7498SAlp Dener bnk->epsilon = PetscPowReal(PETSC_MACHINE_EPSILON, 2.0/3.0); 13920a4511e9SAlp Dener bnk->as_tol = 1.0e-3; 13930a4511e9SAlp Dener bnk->as_step = 1.0e-3; 139462675beeSAlp Dener bnk->dmin = 1.0e-6; 139562675beeSAlp Dener bnk->dmax = 1.0e6; 1396eb910715SAlp Dener 1397b9ac7092SAlp Dener bnk->M = 0; 1398b9ac7092SAlp Dener bnk->bfgs_pre = 0; 1399eb910715SAlp Dener bnk->init_type = BNK_INIT_INTERPOLATION; 14007b1c7716SAlp Dener bnk->update_type = BNK_UPDATE_REDUCTION; 14012f75a4aaSAlp Dener bnk->as_type = BNK_AS_BERTSEKAS; 1402eb910715SAlp Dener 1403e031d6f5SAlp Dener /* Create the embedded BNCG solver */ 1404e031d6f5SAlp Dener ierr = TaoCreate(PetscObjectComm((PetscObject)tao), &bnk->bncg);CHKERRQ(ierr); 1405e031d6f5SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)bnk->bncg, (PetscObject)tao, 1);CHKERRQ(ierr); 1406e031d6f5SAlp Dener ierr = TaoSetOptionsPrefix(bnk->bncg, "tao_bnk_");CHKERRQ(ierr); 1407e031d6f5SAlp Dener ierr = TaoSetType(bnk->bncg, TAOBNCG);CHKERRQ(ierr); 1408e031d6f5SAlp Dener 1409c0f10754SAlp Dener /* Create the line search */ 1410eb910715SAlp Dener ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr); 1411eb910715SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 1412e031d6f5SAlp Dener ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 1413eb910715SAlp Dener ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr); 1414eb910715SAlp Dener ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr); 1415eb910715SAlp Dener 1416eb910715SAlp Dener /* Set linear solver to default for symmetric matrices */ 1417eb910715SAlp Dener ierr = KSPCreate(((PetscObject)tao)->comm,&tao->ksp);CHKERRQ(ierr); 1418eb910715SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1);CHKERRQ(ierr); 1419e0ed867bSAlp Dener ierr = KSPSetOptionsPrefix(tao->ksp,"tao_bnk_");CHKERRQ(ierr); 1420eb910715SAlp Dener ierr = KSPSetType(tao->ksp,KSPCGSTCG);CHKERRQ(ierr); 1421b9ac7092SAlp Dener ierr = KSPGetPC(tao->ksp, &pc); 1422b9ac7092SAlp Dener ierr = PCSetType(pc, PCLMVM);CHKERRQ(ierr); 1423eb910715SAlp Dener PetscFunctionReturn(0); 1424eb910715SAlp Dener } 1425