1eb910715SAlp Dener #include <petsctaolinesearch.h> 2eb910715SAlp Dener #include <../src/tao/bound/impls/bnk/bnk.h> 3eb910715SAlp Dener 4eb910715SAlp Dener #include <petscksp.h> 5eb910715SAlp Dener 6e031d6f5SAlp Dener static const char *BNK_INIT[64] = {"constant", "direction", "interpolation"}; 7e031d6f5SAlp Dener static const char *BNK_UPDATE[64] = {"step", "reduction", "interpolation"}; 8e031d6f5SAlp Dener static const char *BNK_AS[64] = {"none", "bertsekas"}; 9e031d6f5SAlp Dener 10e031d6f5SAlp Dener /*------------------------------------------------------------*/ 11e031d6f5SAlp Dener 12cd929ea3SAlp Dener PetscErrorCode TaoBNKPreconBFGS(PC BFGSpc, Vec X, Vec Y) 13eb910715SAlp Dener { 14eb910715SAlp Dener PetscErrorCode ierr; 15cd929ea3SAlp Dener Mat *M; 16eb910715SAlp Dener 17eb910715SAlp Dener PetscFunctionBegin; 18cd929ea3SAlp Dener ierr = PCShellGetContext(BFGSpc, (void**)&M);CHKERRQ(ierr); 19cd929ea3SAlp Dener ierr = MatSolve(*M, X, Y);CHKERRQ(ierr); 20eb910715SAlp Dener PetscFunctionReturn(0); 21eb910715SAlp Dener } 22eb910715SAlp Dener 23df278d8fSAlp Dener /*------------------------------------------------------------*/ 24df278d8fSAlp Dener 25df278d8fSAlp Dener /* Routine for initializing the KSP solver, the BFGS preconditioner, and the initial trust radius estimation */ 26df278d8fSAlp Dener 27c0f10754SAlp Dener PetscErrorCode TaoBNKInitialize(Tao tao, PetscInt initType, PetscBool *needH) 28eb910715SAlp Dener { 29eb910715SAlp Dener PetscErrorCode ierr; 30eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 31eb910715SAlp Dener PC pc; 32eb910715SAlp Dener 3389da521bSAlp Dener PetscReal f_min, ftrial, prered, actred, kappa, sigma, resnorm; 34eb910715SAlp Dener PetscReal tau, tau_1, tau_2, tau_max, tau_min, max_radius; 3589da521bSAlp Dener PetscReal delta; 36*b9ac7092SAlp Dener PetscBool is_bfgs, is_jacobi; 37c4b75bccSAlp Dener PetscInt n, N, nDiff; 38eb910715SAlp Dener PetscInt i_max = 5; 39eb910715SAlp Dener PetscInt j_max = 1; 40eb910715SAlp Dener PetscInt i, j; 41eb910715SAlp Dener 42eb910715SAlp Dener PetscFunctionBegin; 4328017e9fSAlp Dener /* Project the current point onto the feasible set */ 4428017e9fSAlp Dener ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); 45e031d6f5SAlp Dener ierr = TaoSetVariableBounds(bnk->bncg, tao->XL, tao->XU);CHKERRQ(ierr); 46*b9ac7092SAlp Dener if (tao->bounded) { 4728017e9fSAlp Dener ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr); 48cd929ea3SAlp Dener } 4928017e9fSAlp Dener 5028017e9fSAlp Dener /* Project the initial point onto the feasible region */ 513b063059SAlp Dener ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 5228017e9fSAlp Dener 5328017e9fSAlp Dener /* Check convergence criteria */ 5428017e9fSAlp Dener ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &bnk->f, bnk->unprojected_gradient);CHKERRQ(ierr); 5561be54a6SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, bnk->as_type);CHKERRQ(ierr); 5661be54a6SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->gradient);CHKERRQ(ierr); 5761be54a6SAlp Dener ierr = VecISSet(tao->gradient, bnk->active_idx, 0.0);CHKERRQ(ierr); 5808752603SAlp Dener ierr = VecNorm(tao->gradient,NORM_2,&bnk->gnorm);CHKERRQ(ierr); 5928017e9fSAlp Dener 60c0f10754SAlp Dener /* Test the initial point for convergence */ 6189da521bSAlp Dener ierr = VecFischer(tao->solution, bnk->unprojected_gradient, tao->XL, tao->XU, bnk->W);CHKERRQ(ierr); 6289da521bSAlp Dener ierr = VecNorm(bnk->W, NORM_2, &resnorm);CHKERRQ(ierr); 63b4a30f08SAlp Dener if (PetscIsInfOrNanReal(bnk->f) || PetscIsInfOrNanReal(resnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 64e031d6f5SAlp Dener ierr = TaoLogConvergenceHistory(tao,bnk->f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 65e031d6f5SAlp Dener ierr = TaoMonitor(tao,tao->niter,bnk->f,resnorm,0.0,1.0);CHKERRQ(ierr); 66c0f10754SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 67c0f10754SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 68c0f10754SAlp Dener 69e031d6f5SAlp Dener /* Reset KSP stopping reason counters */ 70eb910715SAlp Dener bnk->ksp_atol = 0; 71eb910715SAlp Dener bnk->ksp_rtol = 0; 72eb910715SAlp Dener bnk->ksp_dtol = 0; 73eb910715SAlp Dener bnk->ksp_ctol = 0; 74eb910715SAlp Dener bnk->ksp_negc = 0; 75eb910715SAlp Dener bnk->ksp_iter = 0; 76eb910715SAlp Dener bnk->ksp_othr = 0; 77eb910715SAlp Dener 78e031d6f5SAlp Dener /* Reset accepted step type counters */ 79e031d6f5SAlp Dener bnk->tot_cg_its = 0; 80e031d6f5SAlp Dener bnk->newt = 0; 81e031d6f5SAlp Dener bnk->bfgs = 0; 82e031d6f5SAlp Dener bnk->sgrad = 0; 83e031d6f5SAlp Dener bnk->grad = 0; 84e031d6f5SAlp Dener 85fed79b8eSAlp Dener /* Initialize the Hessian perturbation */ 86fed79b8eSAlp Dener bnk->pert = bnk->sval; 87fed79b8eSAlp Dener 88937a31a1SAlp Dener /* Reset initial steplength to zero (this helps BNCG reset its direction internally) */ 89937a31a1SAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 90937a31a1SAlp Dener 91e031d6f5SAlp Dener /* Allocate the vectors needed for the BFGS approximation */ 92*b9ac7092SAlp Dener ierr = KSPGetPC(tao->ksp, &pc);CHKERRQ(ierr); 93*b9ac7092SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)pc, PCLMVM, &is_bfgs);CHKERRQ(ierr); 94*b9ac7092SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)pc, PCJACOBI, &is_jacobi);CHKERRQ(ierr); 95*b9ac7092SAlp Dener if (is_bfgs) { 96*b9ac7092SAlp Dener bnk->bfgs_pre = pc; 97*b9ac7092SAlp Dener ierr = PCLMVMGetMatLMVM(bnk->bfgs_pre, &bnk->M);CHKERRQ(ierr); 98eb910715SAlp Dener ierr = VecGetLocalSize(tao->solution, &n);CHKERRQ(ierr); 99eb910715SAlp Dener ierr = VecGetSize(tao->solution, &N);CHKERRQ(ierr); 100*b9ac7092SAlp Dener ierr = MatSetSizes(bnk->M, n, n, N, N);CHKERRQ(ierr); 101cd929ea3SAlp Dener ierr = MatLMVMAllocate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 102*b9ac7092SAlp Dener } else if (is_jacobi) { 103*b9ac7092SAlp Dener ierr = PCJacobiSetUseAbs(pc,PETSC_TRUE);CHKERRQ(ierr); 104e031d6f5SAlp Dener } 105e031d6f5SAlp Dener 106e031d6f5SAlp Dener /* Prepare the min/max vectors for safeguarding diagonal scales */ 10762675beeSAlp Dener ierr = VecSet(bnk->Diag_min, bnk->dmin);CHKERRQ(ierr); 10862675beeSAlp Dener ierr = VecSet(bnk->Diag_max, bnk->dmax);CHKERRQ(ierr); 109eb910715SAlp Dener 110eb910715SAlp Dener /* Initialize trust-region radius. The initialization is only performed 111eb910715SAlp Dener when we are using Nash, Steihaug-Toint or the Generalized Lanczos method. */ 112c0f10754SAlp Dener *needH = PETSC_TRUE; 113eb910715SAlp Dener if (bnk->is_nash || bnk->is_stcg || bnk->is_gltr) { 11462675beeSAlp Dener switch(initType) { 115eb910715SAlp Dener case BNK_INIT_CONSTANT: 116eb910715SAlp Dener /* Use the initial radius specified */ 117c0f10754SAlp Dener tao->trust = tao->trust0; 118eb910715SAlp Dener break; 119eb910715SAlp Dener 120eb910715SAlp Dener case BNK_INIT_INTERPOLATION: 121c0f10754SAlp Dener /* Use interpolation based on the initial Hessian */ 122eb910715SAlp Dener max_radius = 0.0; 12308752603SAlp Dener tao->trust = tao->trust0; 124eb910715SAlp Dener for (j = 0; j < j_max; ++j) { 1250a4511e9SAlp Dener f_min = bnk->f; 126eb910715SAlp Dener sigma = 0.0; 127eb910715SAlp Dener 128c0f10754SAlp Dener if (*needH) { 12962602cfbSAlp Dener /* Compute the Hessian at the new step, and extract the inactive subsystem */ 130e031d6f5SAlp Dener ierr = TaoBNKComputeHessian(tao);CHKERRQ(ierr); 13108752603SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, BNK_AS_NONE);CHKERRQ(ierr); 13289da521bSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 13389da521bSAlp Dener if (bnk->active_idx) { 1342ab2a32cSAlp Dener ierr = MatCreateSubMatrix(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->H_inactive);CHKERRQ(ierr); 13528017e9fSAlp Dener } else { 13608752603SAlp Dener ierr = MatDuplicate(tao->hessian, MAT_COPY_VALUES, &bnk->H_inactive);CHKERRQ(ierr); 13728017e9fSAlp Dener } 138c0f10754SAlp Dener *needH = PETSC_FALSE; 139eb910715SAlp Dener } 140eb910715SAlp Dener 141eb910715SAlp Dener for (i = 0; i < i_max; ++i) { 14262602cfbSAlp Dener /* Take a steepest descent step and snap it to bounds */ 14362602cfbSAlp Dener ierr = VecCopy(tao->solution, bnk->Xold);CHKERRQ(ierr); 14462602cfbSAlp Dener ierr = VecAXPY(tao->solution, -tao->trust/bnk->gnorm, tao->gradient);CHKERRQ(ierr); 1453b063059SAlp Dener ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 14689da521bSAlp Dener /* Compute the step we actually accepted */ 147eb910715SAlp Dener ierr = VecCopy(tao->solution, bnk->W);CHKERRQ(ierr); 14862602cfbSAlp Dener ierr = VecAXPY(bnk->W, -1.0, bnk->Xold);CHKERRQ(ierr); 14962602cfbSAlp Dener /* Compute the objective at the trial */ 15062602cfbSAlp Dener ierr = TaoComputeObjective(tao, tao->solution, &ftrial);CHKERRQ(ierr); 151b4a30f08SAlp Dener if (PetscIsInfOrNanReal(bnk->f)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 15262602cfbSAlp Dener ierr = VecCopy(bnk->Xold, tao->solution);CHKERRQ(ierr); 153eb910715SAlp Dener if (PetscIsInfOrNanReal(ftrial)) { 154eb910715SAlp Dener tau = bnk->gamma1_i; 155eb910715SAlp Dener } else { 1560a4511e9SAlp Dener if (ftrial < f_min) { 1570a4511e9SAlp Dener f_min = ftrial; 158eb910715SAlp Dener sigma = -tao->trust / bnk->gnorm; 159eb910715SAlp Dener } 16008752603SAlp Dener 161770b7498SAlp Dener /* Compute the predicted and actual reduction */ 16289da521bSAlp Dener if (bnk->active_idx) { 16308752603SAlp Dener ierr = VecGetSubVector(bnk->W, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 16408752603SAlp Dener ierr = VecGetSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 1652ab2a32cSAlp Dener } else { 16608752603SAlp Dener bnk->X_inactive = bnk->W; 16708752603SAlp Dener bnk->inactive_work = bnk->Xwork; 1682ab2a32cSAlp Dener } 16908752603SAlp Dener ierr = MatMult(bnk->H_inactive, bnk->X_inactive, bnk->inactive_work);CHKERRQ(ierr); 17008752603SAlp Dener ierr = VecDot(bnk->X_inactive, bnk->inactive_work, &prered);CHKERRQ(ierr); 17189da521bSAlp Dener if (bnk->active_idx) { 17208752603SAlp Dener ierr = VecRestoreSubVector(bnk->W, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 17308752603SAlp Dener ierr = VecRestoreSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 1742ab2a32cSAlp Dener } 175eb910715SAlp Dener prered = tao->trust * (bnk->gnorm - 0.5 * tao->trust * prered / (bnk->gnorm * bnk->gnorm)); 176eb910715SAlp Dener actred = bnk->f - ftrial; 1773105154fSTodd Munson if ((PetscAbsScalar(actred) <= bnk->epsilon) && (PetscAbsScalar(prered) <= bnk->epsilon)) { 178eb910715SAlp Dener kappa = 1.0; 1793105154fSTodd Munson } else { 180eb910715SAlp Dener kappa = actred / prered; 181eb910715SAlp Dener } 182eb910715SAlp Dener 183eb910715SAlp Dener tau_1 = bnk->theta_i * bnk->gnorm * tao->trust / (bnk->theta_i * bnk->gnorm * tao->trust + (1.0 - bnk->theta_i) * prered - actred); 184eb910715SAlp Dener tau_2 = bnk->theta_i * bnk->gnorm * tao->trust / (bnk->theta_i * bnk->gnorm * tao->trust - (1.0 + bnk->theta_i) * prered + actred); 185eb910715SAlp Dener tau_min = PetscMin(tau_1, tau_2); 186eb910715SAlp Dener tau_max = PetscMax(tau_1, tau_2); 187eb910715SAlp Dener 188eb910715SAlp Dener if (PetscAbsScalar(kappa - 1.0) <= bnk->mu1_i) { 189eb910715SAlp Dener /* Great agreement */ 190eb910715SAlp Dener max_radius = PetscMax(max_radius, tao->trust); 191eb910715SAlp Dener 192eb910715SAlp Dener if (tau_max < 1.0) { 193eb910715SAlp Dener tau = bnk->gamma3_i; 1943105154fSTodd Munson } else if (tau_max > bnk->gamma4_i) { 195eb910715SAlp Dener tau = bnk->gamma4_i; 1963105154fSTodd Munson } else { 197eb910715SAlp Dener tau = tau_max; 198eb910715SAlp Dener } 1998f8a4e06SAlp Dener } else if (PetscAbsScalar(kappa - 1.0) <= bnk->mu2_i) { 200eb910715SAlp Dener /* Good agreement */ 201eb910715SAlp Dener max_radius = PetscMax(max_radius, tao->trust); 202eb910715SAlp Dener 203eb910715SAlp Dener if (tau_max < bnk->gamma2_i) { 204eb910715SAlp Dener tau = bnk->gamma2_i; 205eb910715SAlp Dener } else if (tau_max > bnk->gamma3_i) { 206eb910715SAlp Dener tau = bnk->gamma3_i; 207eb910715SAlp Dener } else { 208eb910715SAlp Dener tau = tau_max; 209eb910715SAlp Dener } 2108f8a4e06SAlp Dener } else { 211eb910715SAlp Dener /* Not good agreement */ 212eb910715SAlp Dener if (tau_min > 1.0) { 213eb910715SAlp Dener tau = bnk->gamma2_i; 214eb910715SAlp Dener } else if (tau_max < bnk->gamma1_i) { 215eb910715SAlp Dener tau = bnk->gamma1_i; 216eb910715SAlp Dener } else if ((tau_min < bnk->gamma1_i) && (tau_max >= 1.0)) { 217eb910715SAlp Dener tau = bnk->gamma1_i; 2183105154fSTodd Munson } else if ((tau_1 >= bnk->gamma1_i) && (tau_1 < 1.0) && ((tau_2 < bnk->gamma1_i) || (tau_2 >= 1.0))) { 219eb910715SAlp Dener tau = tau_1; 2203105154fSTodd Munson } else if ((tau_2 >= bnk->gamma1_i) && (tau_2 < 1.0) && ((tau_1 < bnk->gamma1_i) || (tau_2 >= 1.0))) { 221eb910715SAlp Dener tau = tau_2; 222eb910715SAlp Dener } else { 223eb910715SAlp Dener tau = tau_max; 224eb910715SAlp Dener } 225eb910715SAlp Dener } 226eb910715SAlp Dener } 227eb910715SAlp Dener tao->trust = tau * tao->trust; 228eb910715SAlp Dener } 229eb910715SAlp Dener 2300a4511e9SAlp Dener if (f_min < bnk->f) { 231937a31a1SAlp Dener /* We accidentally found a solution better than the initial, so accept it */ 2320a4511e9SAlp Dener bnk->f = f_min; 233937a31a1SAlp Dener ierr = VecCopy(tao->solution, bnk->Xold);CHKERRQ(ierr); 234eb910715SAlp Dener ierr = VecAXPY(tao->solution,sigma,tao->gradient);CHKERRQ(ierr); 2353b063059SAlp Dener ierr = TaoBoundSolution(tao->solution, tao->XL,tao->XU, 0.0, &nDiff, tao->solution);CHKERRQ(ierr); 236937a31a1SAlp Dener ierr = VecCopy(tao->solution, tao->stepdirection);CHKERRQ(ierr); 237937a31a1SAlp Dener ierr = VecAXPY(tao->stepdirection, -1.0, bnk->Xold);CHKERRQ(ierr); 23809164190SAlp Dener ierr = TaoComputeGradient(tao,tao->solution,bnk->unprojected_gradient);CHKERRQ(ierr); 23961be54a6SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, bnk->as_type);CHKERRQ(ierr); 24061be54a6SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->gradient);CHKERRQ(ierr); 24161be54a6SAlp Dener ierr = VecISSet(tao->gradient, bnk->active_idx, 0.0);CHKERRQ(ierr); 242937a31a1SAlp Dener /* Compute gradient at the new iterate and flip switch to compute the Hessian later */ 243c4b75bccSAlp Dener ierr = VecNorm(tao->gradient, NORM_2, &bnk->gnorm);CHKERRQ(ierr); 244c0f10754SAlp Dener *needH = PETSC_TRUE; 245937a31a1SAlp Dener /* Test the new step for convergence */ 24689da521bSAlp Dener ierr = VecFischer(tao->solution, bnk->unprojected_gradient, tao->XL, tao->XU, bnk->W);CHKERRQ(ierr); 24789da521bSAlp Dener ierr = VecNorm(bnk->W, NORM_2, &resnorm);CHKERRQ(ierr); 248b4a30f08SAlp Dener if (PetscIsInfOrNanReal(resnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 249e031d6f5SAlp Dener ierr = TaoLogConvergenceHistory(tao,bnk->f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 250e031d6f5SAlp Dener ierr = TaoMonitor(tao,tao->niter,bnk->f,resnorm,0.0,1.0);CHKERRQ(ierr); 251eb910715SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 252eb910715SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 253937a31a1SAlp Dener /* active BNCG recycling early because we have a stepdirection computed */ 254937a31a1SAlp Dener ierr = TaoBNCGSetRecycleFlag(bnk->bncg, PETSC_TRUE);CHKERRQ(ierr); 255eb910715SAlp Dener } 256eb910715SAlp Dener } 257eb910715SAlp Dener tao->trust = PetscMax(tao->trust, max_radius); 258e031d6f5SAlp Dener 259e031d6f5SAlp Dener /* Ensure that the trust radius is within the limits */ 260e031d6f5SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 261e031d6f5SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 262eb910715SAlp Dener break; 263eb910715SAlp Dener 264eb910715SAlp Dener default: 265eb910715SAlp Dener /* Norm of the first direction will initialize radius */ 266eb910715SAlp Dener tao->trust = 0.0; 267eb910715SAlp Dener break; 268eb910715SAlp Dener } 269eb910715SAlp Dener } 270e031d6f5SAlp Dener 271eb910715SAlp Dener /* Set initial scaling for the BFGS preconditioner 272eb910715SAlp Dener This step is done after computing the initial trust-region radius 273eb910715SAlp Dener since the function value may have decreased */ 274*b9ac7092SAlp Dener if (bnk->M) { 2759b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 276cd929ea3SAlp Dener ierr = MatLMVMSetJ0Scale(bnk->M, delta);CHKERRQ(ierr); 277eb910715SAlp Dener } 278eb910715SAlp Dener PetscFunctionReturn(0); 279eb910715SAlp Dener } 280eb910715SAlp Dener 281df278d8fSAlp Dener /*------------------------------------------------------------*/ 282df278d8fSAlp Dener 28362675beeSAlp Dener /* Routine for computing the Hessian and preparing the preconditioner at the new iterate */ 28462675beeSAlp Dener 28562675beeSAlp Dener PetscErrorCode TaoBNKComputeHessian(Tao tao) 28662675beeSAlp Dener { 28762675beeSAlp Dener PetscErrorCode ierr; 28862675beeSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 289c4b75bccSAlp Dener PetscReal delta; 29062675beeSAlp Dener 29162675beeSAlp Dener PetscFunctionBegin; 29262675beeSAlp Dener /* Compute the Hessian */ 29362675beeSAlp Dener ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 29462675beeSAlp Dener /* Add a correction to the BFGS preconditioner */ 295*b9ac7092SAlp Dener if (bnk->M) { 29662675beeSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 29762675beeSAlp Dener /* Update the BFGS diagonal scaling */ 298c4b75bccSAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 299cd929ea3SAlp Dener ierr = MatLMVMSetJ0Scale(bnk->M,delta);CHKERRQ(ierr); 30062675beeSAlp Dener } 30162675beeSAlp Dener PetscFunctionReturn(0); 30262675beeSAlp Dener } 30362675beeSAlp Dener 30462675beeSAlp Dener /*------------------------------------------------------------*/ 30562675beeSAlp Dener 3062f75a4aaSAlp Dener /* Routine for estimating the active set */ 3072f75a4aaSAlp Dener 30808752603SAlp Dener PetscErrorCode TaoBNKEstimateActiveSet(Tao tao, PetscInt asType) 3092f75a4aaSAlp Dener { 3102f75a4aaSAlp Dener PetscErrorCode ierr; 3112f75a4aaSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 312c4b75bccSAlp Dener PetscBool hessComputed, diagExists; 3132f75a4aaSAlp Dener 3142f75a4aaSAlp Dener PetscFunctionBegin; 31508752603SAlp Dener switch (asType) { 3162f75a4aaSAlp Dener case BNK_AS_NONE: 3172f75a4aaSAlp Dener ierr = ISDestroy(&bnk->inactive_idx);CHKERRQ(ierr); 3182f75a4aaSAlp Dener ierr = VecWhichInactive(tao->XL, tao->solution, bnk->unprojected_gradient, tao->XU, PETSC_TRUE, &bnk->inactive_idx);CHKERRQ(ierr); 3192f75a4aaSAlp Dener ierr = ISDestroy(&bnk->active_idx);CHKERRQ(ierr); 3202f75a4aaSAlp Dener ierr = ISComplementVec(bnk->inactive_idx, tao->solution, &bnk->active_idx);CHKERRQ(ierr); 3212f75a4aaSAlp Dener break; 3222f75a4aaSAlp Dener 3232f75a4aaSAlp Dener case BNK_AS_BERTSEKAS: 3242f75a4aaSAlp Dener /* Compute the trial step vector with which we will estimate the active set at the next iteration */ 325*b9ac7092SAlp Dener if (bnk->M) { 3262f75a4aaSAlp Dener /* If the BFGS preconditioner matrix is available, we will construct a trial step with it */ 327cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, bnk->W);CHKERRQ(ierr); 3282f75a4aaSAlp Dener } else { 32961be54a6SAlp Dener ierr = MatAssembled(tao->hessian, &hessComputed);CHKERRQ(ierr); 330c4b75bccSAlp Dener ierr = MatHasOperation(tao->hessian, MATOP_GET_DIAGONAL, &diagExists);CHKERRQ(ierr); 331c4b75bccSAlp Dener if (hessComputed && diagExists) { 3329b6ef848SAlp Dener /* BFGS preconditioner doesn't exist so let's invert the absolute diagonal of the Hessian instead onto the gradient */ 3332f75a4aaSAlp Dener ierr = MatGetDiagonal(tao->hessian, bnk->Xwork);CHKERRQ(ierr); 3349b6ef848SAlp Dener ierr = VecAbs(bnk->Xwork);CHKERRQ(ierr); 3359b6ef848SAlp Dener ierr = VecMedian(bnk->Diag_min, bnk->Xwork, bnk->Diag_max, bnk->Xwork);CHKERRQ(ierr); 3362f75a4aaSAlp Dener ierr = VecReciprocal(bnk->Xwork);CHKERRQ(ierr);CHKERRQ(ierr); 3372f75a4aaSAlp Dener ierr = VecPointwiseMult(bnk->W, bnk->Xwork, bnk->unprojected_gradient);CHKERRQ(ierr); 33861be54a6SAlp Dener } else { 339c4b75bccSAlp Dener /* If the Hessian or its diagonal does not exist, we will simply use gradient step */ 34061be54a6SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, bnk->W);CHKERRQ(ierr); 34161be54a6SAlp Dener } 3422f75a4aaSAlp Dener } 3432f75a4aaSAlp Dener ierr = VecScale(bnk->W, -1.0);CHKERRQ(ierr); 34489da521bSAlp Dener ierr = TaoEstimateActiveBounds(tao->solution, tao->XL, tao->XU, bnk->unprojected_gradient, bnk->W, bnk->Xwork, bnk->as_step, &bnk->as_tol, 34589da521bSAlp Dener &bnk->active_lower, &bnk->active_upper, &bnk->active_fixed, &bnk->active_idx, &bnk->inactive_idx);CHKERRQ(ierr); 346c4b75bccSAlp Dener break; 3472f75a4aaSAlp Dener 3482f75a4aaSAlp Dener default: 3492f75a4aaSAlp Dener break; 3502f75a4aaSAlp Dener } 3512f75a4aaSAlp Dener PetscFunctionReturn(0); 3522f75a4aaSAlp Dener } 3532f75a4aaSAlp Dener 3542f75a4aaSAlp Dener /*------------------------------------------------------------*/ 3552f75a4aaSAlp Dener 3562f75a4aaSAlp Dener /* Routine for bounding the step direction */ 3572f75a4aaSAlp Dener 358a1318120SAlp Dener PetscErrorCode TaoBNKBoundStep(Tao tao, PetscInt asType, Vec step) 3592f75a4aaSAlp Dener { 3602f75a4aaSAlp Dener PetscErrorCode ierr; 3612f75a4aaSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 3622f75a4aaSAlp Dener 3632f75a4aaSAlp Dener PetscFunctionBegin; 364a1318120SAlp Dener switch (asType) { 3652f75a4aaSAlp Dener case BNK_AS_NONE: 366c4b75bccSAlp Dener ierr = VecISSet(step, bnk->active_idx, 0.0);CHKERRQ(ierr); 3672f75a4aaSAlp Dener break; 3682f75a4aaSAlp Dener 3692f75a4aaSAlp Dener case BNK_AS_BERTSEKAS: 370c4b75bccSAlp Dener ierr = TaoBoundStep(tao->solution, tao->XL, tao->XU, bnk->active_lower, bnk->active_upper, bnk->active_fixed, 1.0, step);CHKERRQ(ierr); 3712f75a4aaSAlp Dener break; 3722f75a4aaSAlp Dener 3732f75a4aaSAlp Dener default: 3742f75a4aaSAlp Dener break; 3752f75a4aaSAlp Dener } 3762f75a4aaSAlp Dener PetscFunctionReturn(0); 3772f75a4aaSAlp Dener } 3782f75a4aaSAlp Dener 379e031d6f5SAlp Dener /*------------------------------------------------------------*/ 380e031d6f5SAlp Dener 381e031d6f5SAlp Dener /* Routine for taking a finite number of BNCG iterations to 382e031d6f5SAlp Dener accelerate Newton convergence. 383e031d6f5SAlp Dener 384e031d6f5SAlp Dener In practice, this approach simply trades off Hessian evaluations 385e031d6f5SAlp Dener for more gradient evaluations. 386e031d6f5SAlp Dener */ 387e031d6f5SAlp Dener 388c0f10754SAlp Dener PetscErrorCode TaoBNKTakeCGSteps(Tao tao, PetscBool *terminate) 389c0f10754SAlp Dener { 390c0f10754SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 391c0f10754SAlp Dener PetscErrorCode ierr; 392c0f10754SAlp Dener 393c0f10754SAlp Dener PetscFunctionBegin; 394c0f10754SAlp Dener *terminate = PETSC_FALSE; 395c0f10754SAlp Dener if (bnk->max_cg_its > 0) { 396c4b75bccSAlp Dener /* Copy the current function value (important vectors are already shared) */ 397c0f10754SAlp Dener bnk->bncg_ctx->f = bnk->f; 398c0f10754SAlp Dener /* Take some small finite number of BNCG iterations */ 399c0f10754SAlp Dener ierr = TaoSolve(bnk->bncg);CHKERRQ(ierr); 400c0f10754SAlp Dener /* Add the number of gradient and function evaluations to the total */ 401c0f10754SAlp Dener tao->nfuncs += bnk->bncg->nfuncs; 402c0f10754SAlp Dener tao->nfuncgrads += bnk->bncg->nfuncgrads; 403c0f10754SAlp Dener tao->ngrads += bnk->bncg->ngrads; 404c0f10754SAlp Dener tao->nhess += bnk->bncg->nhess; 405e031d6f5SAlp Dener bnk->tot_cg_its += bnk->bncg->niter; 406c4b75bccSAlp Dener /* Extract the BNCG function value out and save it into BNK */ 407c0f10754SAlp Dener bnk->f = bnk->bncg_ctx->f; 408c0f10754SAlp 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) { 409c0f10754SAlp Dener *terminate = PETSC_TRUE; 41061be54a6SAlp Dener } else { 41133c78596SAlp Dener ierr = TaoBNKEstimateActiveSet(tao, bnk->as_type);CHKERRQ(ierr); 412c0f10754SAlp Dener } 413c0f10754SAlp Dener } 414c0f10754SAlp Dener PetscFunctionReturn(0); 415c0f10754SAlp Dener } 416c0f10754SAlp Dener 4172f75a4aaSAlp Dener /*------------------------------------------------------------*/ 4182f75a4aaSAlp Dener 419c0f10754SAlp Dener /* Routine for computing the Newton step. */ 420df278d8fSAlp Dener 42162675beeSAlp Dener PetscErrorCode TaoBNKComputeStep(Tao tao, PetscBool shift, KSPConvergedReason *ksp_reason) 422eb910715SAlp Dener { 423eb910715SAlp Dener PetscErrorCode ierr; 424eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 425e465cd6fSAlp Dener PetscReal delta; 426eb910715SAlp Dener PetscInt bfgsUpdates = 0; 427eb910715SAlp Dener PetscInt kspits; 428eb910715SAlp Dener 429eb910715SAlp Dener PetscFunctionBegin; 43089da521bSAlp Dener /* If there are no inactive variables left, save some computation and return an adjusted zero step 43189da521bSAlp Dener that has (l-x) and (u-x) for lower and upper bounded variables. */ 43289da521bSAlp Dener if (!bnk->inactive_idx) { 43389da521bSAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 434a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 43589da521bSAlp Dener PetscFunctionReturn(0); 43689da521bSAlp Dener } 43789da521bSAlp Dener 4385e9b73cbSAlp Dener /* Prepare the reduced sub-matrices for the inactive set */ 43989da521bSAlp Dener if (bnk->active_idx) { 44033c78596SAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 4415e9b73cbSAlp Dener ierr = MatCreateSubMatrix(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->H_inactive);CHKERRQ(ierr); 442eb3ba6a7SAlp Dener if (tao->hessian == tao->hessian_pre) { 443eb3ba6a7SAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 444eb3ba6a7SAlp Dener } else { 44533c78596SAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 4465e9b73cbSAlp Dener ierr = MatCreateSubMatrix(tao->hessian_pre, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->Hpre_inactive);CHKERRQ(ierr); 447eb3ba6a7SAlp Dener } 448*b9ac7092SAlp Dener if (bnk->bfgs_pre) { 449*b9ac7092SAlp Dener ierr = PCLMVMSetIS(bnk->bfgs_pre, bnk->inactive_idx);CHKERRQ(ierr); 450*b9ac7092SAlp Dener } 4512f75a4aaSAlp Dener } else { 45233c78596SAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 45333c78596SAlp Dener ierr = MatDuplicate(tao->hessian, MAT_COPY_VALUES, &bnk->H_inactive);CHKERRQ(ierr); 45462675beeSAlp Dener if (tao->hessian == tao->hessian_pre) { 45562675beeSAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 45662675beeSAlp Dener } else { 45733c78596SAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 45833c78596SAlp Dener ierr = MatDuplicate(tao->hessian_pre, MAT_COPY_VALUES, &bnk->Hpre_inactive);CHKERRQ(ierr); 45962675beeSAlp Dener } 460*b9ac7092SAlp Dener if (bnk->bfgs_pre) { 461*b9ac7092SAlp Dener ierr = PCLMVMClearIS(bnk->bfgs_pre);CHKERRQ(ierr); 462*b9ac7092SAlp Dener } 46362675beeSAlp Dener } 46462675beeSAlp Dener 46562675beeSAlp Dener /* Shift the reduced Hessian matrix */ 46662675beeSAlp Dener if ((shift) && (bnk->pert > 0)) { 46762675beeSAlp Dener ierr = MatShift(bnk->H_inactive, bnk->pert);CHKERRQ(ierr); 46862675beeSAlp Dener if (bnk->H_inactive != bnk->Hpre_inactive) { 46962675beeSAlp Dener ierr = MatShift(bnk->Hpre_inactive, bnk->pert);CHKERRQ(ierr); 47062675beeSAlp Dener } 47162675beeSAlp Dener } 47262675beeSAlp Dener 473eb910715SAlp Dener /* Solve the Newton system of equations */ 474937a31a1SAlp Dener tao->ksp_its = 0; 4752f75a4aaSAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 4765e9b73cbSAlp Dener ierr = KSPReset(tao->ksp);CHKERRQ(ierr); 47709164190SAlp Dener ierr = KSPSetOperators(tao->ksp,bnk->H_inactive,bnk->Hpre_inactive);CHKERRQ(ierr); 4785e9b73cbSAlp Dener ierr = VecCopy(bnk->unprojected_gradient, bnk->Gwork);CHKERRQ(ierr); 47989da521bSAlp Dener if (bnk->active_idx) { 4805e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 4815e9b73cbSAlp Dener ierr = VecGetSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 4825e9b73cbSAlp Dener } else { 4835e9b73cbSAlp Dener bnk->G_inactive = bnk->unprojected_gradient; 4845e9b73cbSAlp Dener bnk->X_inactive = tao->stepdirection; 48528017e9fSAlp Dener } 486eb910715SAlp Dener if (bnk->is_nash || bnk->is_stcg || bnk->is_gltr) { 487fed79b8eSAlp Dener ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 4885e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 489eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 490eb910715SAlp Dener tao->ksp_its+=kspits; 491eb910715SAlp Dener tao->ksp_tot_its+=kspits; 492080d2917SAlp Dener ierr = KSPCGGetNormD(tao->ksp,&bnk->dnorm);CHKERRQ(ierr); 493eb910715SAlp Dener 494eb910715SAlp Dener if (0.0 == tao->trust) { 495eb910715SAlp Dener /* Radius was uninitialized; use the norm of the direction */ 496080d2917SAlp Dener if (bnk->dnorm > 0.0) { 497080d2917SAlp Dener tao->trust = bnk->dnorm; 498eb910715SAlp Dener 499eb910715SAlp Dener /* Modify the radius if it is too large or small */ 500eb910715SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 501eb910715SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 502eb910715SAlp Dener } else { 503eb910715SAlp Dener /* The direction was bad; set radius to default value and re-solve 504eb910715SAlp Dener the trust-region subproblem to get a direction */ 505eb910715SAlp Dener tao->trust = tao->trust0; 506eb910715SAlp Dener 507eb910715SAlp Dener /* Modify the radius if it is too large or small */ 508eb910715SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 509eb910715SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 510eb910715SAlp Dener 511fed79b8eSAlp Dener ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 5125e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 513eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 514eb910715SAlp Dener tao->ksp_its+=kspits; 515eb910715SAlp Dener tao->ksp_tot_its+=kspits; 516080d2917SAlp Dener ierr = KSPCGGetNormD(tao->ksp,&bnk->dnorm);CHKERRQ(ierr); 517eb910715SAlp Dener 518080d2917SAlp Dener if (bnk->dnorm == 0.0) SETERRQ(PETSC_COMM_SELF,1, "Initial direction zero"); 519eb910715SAlp Dener } 520eb910715SAlp Dener } 521eb910715SAlp Dener } else { 5225e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 523eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp, &kspits);CHKERRQ(ierr); 524eb910715SAlp Dener tao->ksp_its += kspits; 525eb910715SAlp Dener tao->ksp_tot_its+=kspits; 526eb910715SAlp Dener } 5275e9b73cbSAlp Dener /* Restore sub vectors back */ 52889da521bSAlp Dener if (bnk->active_idx) { 5295e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5305e9b73cbSAlp Dener ierr = VecRestoreSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5315e9b73cbSAlp Dener } 532770b7498SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 533fed79b8eSAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 534a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 535770b7498SAlp Dener 536770b7498SAlp Dener /* Record convergence reasons */ 537e465cd6fSAlp Dener ierr = KSPGetConvergedReason(tao->ksp, ksp_reason);CHKERRQ(ierr); 538e465cd6fSAlp Dener if (KSP_CONVERGED_ATOL == *ksp_reason) { 539770b7498SAlp Dener ++bnk->ksp_atol; 540e465cd6fSAlp Dener } else if (KSP_CONVERGED_RTOL == *ksp_reason) { 541770b7498SAlp Dener ++bnk->ksp_rtol; 542e465cd6fSAlp Dener } else if (KSP_CONVERGED_CG_CONSTRAINED == *ksp_reason) { 543770b7498SAlp Dener ++bnk->ksp_ctol; 544e465cd6fSAlp Dener } else if (KSP_CONVERGED_CG_NEG_CURVE == *ksp_reason) { 545770b7498SAlp Dener ++bnk->ksp_negc; 546e465cd6fSAlp Dener } else if (KSP_DIVERGED_DTOL == *ksp_reason) { 547770b7498SAlp Dener ++bnk->ksp_dtol; 548e465cd6fSAlp Dener } else if (KSP_DIVERGED_ITS == *ksp_reason) { 549770b7498SAlp Dener ++bnk->ksp_iter; 550770b7498SAlp Dener } else { 551770b7498SAlp Dener ++bnk->ksp_othr; 552770b7498SAlp Dener } 553fed79b8eSAlp Dener 554fed79b8eSAlp Dener /* Make sure the BFGS preconditioner is healthy */ 555*b9ac7092SAlp Dener if (bnk->M) { 556cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 557e465cd6fSAlp Dener if ((KSP_DIVERGED_INDEFINITE_PC == *ksp_reason) && (bfgsUpdates > 1)) { 558fed79b8eSAlp Dener /* Preconditioner is numerically indefinite; reset the approximation. */ 5599b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 560cd929ea3SAlp Dener ierr = MatLMVMSetJ0Scale(bnk->M,delta);CHKERRQ(ierr); 561cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 56209164190SAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 563eb910715SAlp Dener } 564fed79b8eSAlp Dener } 565e465cd6fSAlp Dener PetscFunctionReturn(0); 566e465cd6fSAlp Dener } 567eb910715SAlp Dener 56862675beeSAlp Dener /*------------------------------------------------------------*/ 56962675beeSAlp Dener 5705e9b73cbSAlp Dener /* Routine for recomputing the predicted reduction for a given step vector */ 5715e9b73cbSAlp Dener 5725e9b73cbSAlp Dener PetscErrorCode TaoBNKRecomputePred(Tao tao, Vec S, PetscReal *prered) 5735e9b73cbSAlp Dener { 5745e9b73cbSAlp Dener PetscErrorCode ierr; 5755e9b73cbSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 5765e9b73cbSAlp Dener 5775e9b73cbSAlp Dener PetscFunctionBegin; 5785e9b73cbSAlp Dener /* Extract subvectors associated with the inactive set */ 57989da521bSAlp Dener if (bnk->active_idx){ 5805e9b73cbSAlp Dener ierr = VecGetSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5815e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 5825e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5835e9b73cbSAlp Dener } else { 5845e9b73cbSAlp Dener bnk->X_inactive = tao->stepdirection; 5855e9b73cbSAlp Dener bnk->inactive_work = bnk->Xwork; 5865e9b73cbSAlp Dener bnk->G_inactive = bnk->Gwork; 5875e9b73cbSAlp Dener } 5885e9b73cbSAlp Dener /* Recompute the predicted decrease based on the quadratic model */ 5895e9b73cbSAlp Dener ierr = MatMult(bnk->H_inactive, bnk->X_inactive, bnk->inactive_work);CHKERRQ(ierr); 5905e9b73cbSAlp Dener ierr = VecAYPX(bnk->inactive_work, -0.5, bnk->G_inactive);CHKERRQ(ierr); 59133c78596SAlp Dener ierr = VecDot(bnk->inactive_work, bnk->X_inactive, prered);CHKERRQ(ierr); 5925e9b73cbSAlp Dener /* Restore the sub vectors */ 59389da521bSAlp Dener if (bnk->active_idx){ 5945e9b73cbSAlp Dener ierr = VecRestoreSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5955e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 5965e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5975e9b73cbSAlp Dener } 5985e9b73cbSAlp Dener PetscFunctionReturn(0); 5995e9b73cbSAlp Dener } 6005e9b73cbSAlp Dener 6015e9b73cbSAlp Dener /*------------------------------------------------------------*/ 6025e9b73cbSAlp Dener 60362675beeSAlp Dener /* Routine for ensuring that the Newton step is a descent direction. 60462675beeSAlp Dener 60562675beeSAlp Dener The step direction falls back onto BFGS, scaled gradient and gradient steps 60662675beeSAlp Dener in the event that the Newton step fails the test. 60762675beeSAlp Dener */ 60862675beeSAlp Dener 609e465cd6fSAlp Dener PetscErrorCode TaoBNKSafeguardStep(Tao tao, KSPConvergedReason ksp_reason, PetscInt *stepType) 610e465cd6fSAlp Dener { 611e465cd6fSAlp Dener PetscErrorCode ierr; 612e465cd6fSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 613e465cd6fSAlp Dener 614e465cd6fSAlp Dener PetscReal gdx, delta, e_min; 615e465cd6fSAlp Dener PetscInt bfgsUpdates; 616e465cd6fSAlp Dener 617e465cd6fSAlp Dener PetscFunctionBegin; 618080d2917SAlp Dener ierr = VecDot(tao->stepdirection, tao->gradient, &gdx);CHKERRQ(ierr); 619eb910715SAlp Dener if ((gdx >= 0.0) || PetscIsInfOrNanReal(gdx)) { 620eb910715SAlp Dener /* Newton step is not descent or direction produced Inf or NaN 621eb910715SAlp Dener Update the perturbation for next time */ 622eb910715SAlp Dener if (bnk->pert <= 0.0) { 623eb910715SAlp Dener /* Initialize the perturbation */ 624eb910715SAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 625eb910715SAlp Dener if (bnk->is_gltr) { 626eb910715SAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 627eb910715SAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 628eb910715SAlp Dener } 629eb910715SAlp Dener } else { 630eb910715SAlp Dener /* Increase the perturbation */ 631eb910715SAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 632eb910715SAlp Dener } 633eb910715SAlp Dener 634*b9ac7092SAlp Dener if (bnk->M) { 635eb910715SAlp Dener /* We don't have the bfgs matrix around and updated 636eb910715SAlp Dener Must use gradient direction in this case */ 637080d2917SAlp Dener ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr); 638eb910715SAlp Dener *stepType = BNK_GRADIENT; 639eb910715SAlp Dener } else { 640eb910715SAlp Dener /* Attempt to use the BFGS direction */ 641cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 642eb910715SAlp Dener 6438d5ead36SAlp Dener /* Check for success (descent direction) 6448d5ead36SAlp Dener NOTE: Negative gdx here means not a descent direction because 6458d5ead36SAlp Dener the fall-back step is missing a negative sign. */ 646080d2917SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 6473105154fSTodd Munson if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 648eb910715SAlp Dener /* BFGS direction is not descent or direction produced not a number 649eb910715SAlp Dener We can assert bfgsUpdates > 1 in this case because 650eb910715SAlp Dener the first solve produces the scaled gradient direction, 651eb910715SAlp Dener which is guaranteed to be descent */ 652eb910715SAlp Dener 653eb910715SAlp Dener /* Use steepest descent direction (scaled) */ 6549b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 655cd929ea3SAlp Dener ierr = MatLMVMSetJ0Scale(bnk->M, delta);CHKERRQ(ierr); 656cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 65709164190SAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 658cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 659eb910715SAlp Dener 660eb910715SAlp Dener *stepType = BNK_SCALED_GRADIENT; 661eb910715SAlp Dener } else { 662cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 663eb910715SAlp Dener if (1 == bfgsUpdates) { 664eb910715SAlp Dener /* The first BFGS direction is always the scaled gradient */ 665eb910715SAlp Dener *stepType = BNK_SCALED_GRADIENT; 666eb910715SAlp Dener } else { 667eb910715SAlp Dener *stepType = BNK_BFGS; 668eb910715SAlp Dener } 669eb910715SAlp Dener } 670eb910715SAlp Dener } 6718d5ead36SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 6728d5ead36SAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 673a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 674eb910715SAlp Dener } else { 675eb910715SAlp Dener /* Computed Newton step is descent */ 676eb910715SAlp Dener switch (ksp_reason) { 677eb910715SAlp Dener case KSP_DIVERGED_NANORINF: 678eb910715SAlp Dener case KSP_DIVERGED_BREAKDOWN: 679eb910715SAlp Dener case KSP_DIVERGED_INDEFINITE_MAT: 680eb910715SAlp Dener case KSP_DIVERGED_INDEFINITE_PC: 681eb910715SAlp Dener case KSP_CONVERGED_CG_NEG_CURVE: 682eb910715SAlp Dener /* Matrix or preconditioner is indefinite; increase perturbation */ 683eb910715SAlp Dener if (bnk->pert <= 0.0) { 684eb910715SAlp Dener /* Initialize the perturbation */ 685eb910715SAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 686eb910715SAlp Dener if (bnk->is_gltr) { 687eb910715SAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp, &e_min);CHKERRQ(ierr); 688eb910715SAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 689eb910715SAlp Dener } 690eb910715SAlp Dener } else { 691eb910715SAlp Dener /* Increase the perturbation */ 692eb910715SAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 693eb910715SAlp Dener } 694eb910715SAlp Dener break; 695eb910715SAlp Dener 696eb910715SAlp Dener default: 697eb910715SAlp Dener /* Newton step computation is good; decrease perturbation */ 698eb910715SAlp Dener bnk->pert = PetscMin(bnk->psfac * bnk->pert, bnk->pmsfac * bnk->gnorm); 699eb910715SAlp Dener if (bnk->pert < bnk->pmin) { 700eb910715SAlp Dener bnk->pert = 0.0; 701eb910715SAlp Dener } 702eb910715SAlp Dener break; 703eb910715SAlp Dener } 704fed79b8eSAlp Dener *stepType = BNK_NEWTON; 705eb910715SAlp Dener } 706eb910715SAlp Dener PetscFunctionReturn(0); 707eb910715SAlp Dener } 708eb910715SAlp Dener 709df278d8fSAlp Dener /*------------------------------------------------------------*/ 710df278d8fSAlp Dener 711df278d8fSAlp Dener /* Routine for performing a bound-projected More-Thuente line search. 712df278d8fSAlp Dener 713df278d8fSAlp Dener Includes fallbacks to BFGS, scaled gradient, and unscaled gradient steps if the 714df278d8fSAlp Dener Newton step does not produce a valid step length. 715df278d8fSAlp Dener */ 716df278d8fSAlp Dener 717937a31a1SAlp Dener PetscErrorCode TaoBNKPerformLineSearch(Tao tao, PetscInt *stepType, PetscReal *steplen, TaoLineSearchConvergedReason *reason) 718c14b763aSAlp Dener { 719c14b763aSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 720c14b763aSAlp Dener PetscErrorCode ierr; 721c14b763aSAlp Dener TaoLineSearchConvergedReason ls_reason; 722c14b763aSAlp Dener 723c14b763aSAlp Dener PetscReal e_min, gdx, delta; 724c14b763aSAlp Dener PetscInt bfgsUpdates; 725c14b763aSAlp Dener 726c14b763aSAlp Dener PetscFunctionBegin; 727c14b763aSAlp Dener /* Perform the linesearch */ 728c14b763aSAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &bnk->f, bnk->unprojected_gradient, tao->stepdirection, steplen, &ls_reason);CHKERRQ(ierr); 729c14b763aSAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 730c14b763aSAlp Dener 731937a31a1SAlp Dener while (ls_reason != TAOLINESEARCH_SUCCESS && ls_reason != TAOLINESEARCH_SUCCESS_USER && *stepType != BNK_GRADIENT) { 732c14b763aSAlp Dener /* Linesearch failed, revert solution */ 733c14b763aSAlp Dener bnk->f = bnk->fold; 734c14b763aSAlp Dener ierr = VecCopy(bnk->Xold, tao->solution);CHKERRQ(ierr); 735c14b763aSAlp Dener ierr = VecCopy(bnk->unprojected_gradient_old, bnk->unprojected_gradient);CHKERRQ(ierr); 736c14b763aSAlp Dener 737937a31a1SAlp Dener switch(*stepType) { 738c14b763aSAlp Dener case BNK_NEWTON: 7398d5ead36SAlp Dener /* Failed to obtain acceptable iterate with Newton step 740c14b763aSAlp Dener Update the perturbation for next time */ 741c14b763aSAlp Dener if (bnk->pert <= 0.0) { 742c14b763aSAlp Dener /* Initialize the perturbation */ 743c14b763aSAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 744c14b763aSAlp Dener if (bnk->is_gltr) { 745c14b763aSAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 746c14b763aSAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 747c14b763aSAlp Dener } 748c14b763aSAlp Dener } else { 749c14b763aSAlp Dener /* Increase the perturbation */ 750c14b763aSAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 751c14b763aSAlp Dener } 752c14b763aSAlp Dener 753*b9ac7092SAlp Dener if (bnk->M) { 754c14b763aSAlp Dener /* We don't have the bfgs matrix around and being updated 755c14b763aSAlp Dener Must use gradient direction in this case */ 756937a31a1SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 757937a31a1SAlp Dener *stepType = BNK_GRADIENT; 758c14b763aSAlp Dener } else { 759c14b763aSAlp Dener /* Attempt to use the BFGS direction */ 760cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 7618d5ead36SAlp Dener /* Check for success (descent direction) 7628d5ead36SAlp Dener NOTE: Negative gdx means not a descent direction because the step here is missing a negative sign. */ 763c14b763aSAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 7643105154fSTodd Munson if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { 765c14b763aSAlp Dener /* BFGS direction is not descent or direction produced not a number 766c14b763aSAlp Dener We can assert bfgsUpdates > 1 in this case 767c14b763aSAlp Dener Use steepest descent direction (scaled) */ 7689b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 769cd929ea3SAlp Dener ierr = MatLMVMSetJ0Scale(bnk->M, delta);CHKERRQ(ierr); 770cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 771c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 772cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 773c14b763aSAlp Dener 774c14b763aSAlp Dener bfgsUpdates = 1; 775937a31a1SAlp Dener *stepType = BNK_SCALED_GRADIENT; 776c14b763aSAlp Dener } else { 777cd929ea3SAlp Dener ierr = MatLMVMGetUpdateCount(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 778c14b763aSAlp Dener if (1 == bfgsUpdates) { 779c14b763aSAlp Dener /* The first BFGS direction is always the scaled gradient */ 780937a31a1SAlp Dener *stepType = BNK_SCALED_GRADIENT; 781c14b763aSAlp Dener } else { 782937a31a1SAlp Dener *stepType = BNK_BFGS; 783c14b763aSAlp Dener } 784c14b763aSAlp Dener } 785c14b763aSAlp Dener } 786c14b763aSAlp Dener break; 787c14b763aSAlp Dener 788c14b763aSAlp Dener case BNK_BFGS: 789c14b763aSAlp Dener /* Can only enter if pc_type == BNK_PC_BFGS 790c14b763aSAlp Dener Failed to obtain acceptable iterate with BFGS step 791c14b763aSAlp Dener Attempt to use the scaled gradient direction */ 7929b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 793cd929ea3SAlp Dener ierr = MatLMVMSetJ0Scale(bnk->M, delta);CHKERRQ(ierr); 794cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 795c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 796cd929ea3SAlp Dener ierr = MatSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 797c14b763aSAlp Dener 798c14b763aSAlp Dener bfgsUpdates = 1; 799937a31a1SAlp Dener *stepType = BNK_SCALED_GRADIENT; 800c14b763aSAlp Dener break; 801c14b763aSAlp Dener 802c14b763aSAlp Dener case BNK_SCALED_GRADIENT: 803c14b763aSAlp Dener /* Can only enter if pc_type == BNK_PC_BFGS 804c14b763aSAlp Dener The scaled gradient step did not produce a new iterate; 805937a31a1SAlp Dener reset the BFGS matrix and attemp to use the gradient direction. */ 806cd929ea3SAlp Dener ierr = MatLMVMSetJ0Scale(bnk->M,1.0);CHKERRQ(ierr); 807cd929ea3SAlp Dener ierr = MatLMVMReset(bnk->M, PETSC_FALSE);CHKERRQ(ierr); 808c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 809937a31a1SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 810c14b763aSAlp Dener 811c14b763aSAlp Dener bfgsUpdates = 1; 812937a31a1SAlp Dener *stepType = BNK_GRADIENT; 813c14b763aSAlp Dener break; 814c14b763aSAlp Dener } 8158d5ead36SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 8168d5ead36SAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 817a1318120SAlp Dener ierr = TaoBNKBoundStep(tao, bnk->as_type, tao->stepdirection);CHKERRQ(ierr); 818c14b763aSAlp Dener 8198d5ead36SAlp Dener /* Perform one last line search with the fall-back step */ 820c14b763aSAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &bnk->f, bnk->unprojected_gradient, tao->stepdirection, steplen, &ls_reason);CHKERRQ(ierr); 821c14b763aSAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 822c14b763aSAlp Dener } 823c14b763aSAlp Dener *reason = ls_reason; 824c14b763aSAlp Dener PetscFunctionReturn(0); 825c14b763aSAlp Dener } 826c14b763aSAlp Dener 827df278d8fSAlp Dener /*------------------------------------------------------------*/ 828df278d8fSAlp Dener 829df278d8fSAlp Dener /* Routine for updating the trust radius. 830df278d8fSAlp Dener 831df278d8fSAlp Dener Function features three different update methods: 832df278d8fSAlp Dener 1) Line-search step length based 833df278d8fSAlp Dener 2) Predicted decrease on the CG quadratic model 834df278d8fSAlp Dener 3) Interpolation 835df278d8fSAlp Dener */ 836df278d8fSAlp Dener 83728017e9fSAlp Dener PetscErrorCode TaoBNKUpdateTrustRadius(Tao tao, PetscReal prered, PetscReal actred, PetscInt updateType, PetscInt stepType, PetscBool *accept) 838080d2917SAlp Dener { 839080d2917SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 840080d2917SAlp Dener PetscErrorCode ierr; 841080d2917SAlp Dener 842b1c2d0e3SAlp Dener PetscReal step, kappa; 843080d2917SAlp Dener PetscReal gdx, tau_1, tau_2, tau_min, tau_max; 844080d2917SAlp Dener 845080d2917SAlp Dener PetscFunctionBegin; 846080d2917SAlp Dener /* Update trust region radius */ 847080d2917SAlp Dener *accept = PETSC_FALSE; 84828017e9fSAlp Dener switch(updateType) { 849080d2917SAlp Dener case BNK_UPDATE_STEP: 850c14b763aSAlp Dener *accept = PETSC_TRUE; /* always accept here because line search succeeded */ 851080d2917SAlp Dener if (stepType == BNK_NEWTON) { 852080d2917SAlp Dener ierr = TaoLineSearchGetStepLength(tao->linesearch, &step);CHKERRQ(ierr); 853080d2917SAlp Dener if (step < bnk->nu1) { 854080d2917SAlp Dener /* Very bad step taken; reduce radius */ 855080d2917SAlp Dener tao->trust = bnk->omega1 * PetscMin(bnk->dnorm, tao->trust); 856080d2917SAlp Dener } else if (step < bnk->nu2) { 857080d2917SAlp Dener /* Reasonably bad step taken; reduce radius */ 858080d2917SAlp Dener tao->trust = bnk->omega2 * PetscMin(bnk->dnorm, tao->trust); 859080d2917SAlp Dener } else if (step < bnk->nu3) { 860080d2917SAlp Dener /* Reasonable step was taken; leave radius alone */ 861080d2917SAlp Dener if (bnk->omega3 < 1.0) { 862080d2917SAlp Dener tao->trust = bnk->omega3 * PetscMin(bnk->dnorm, tao->trust); 863080d2917SAlp Dener } else if (bnk->omega3 > 1.0) { 864080d2917SAlp Dener tao->trust = PetscMax(bnk->omega3 * bnk->dnorm, tao->trust); 865080d2917SAlp Dener } 866080d2917SAlp Dener } else if (step < bnk->nu4) { 867080d2917SAlp Dener /* Full step taken; increase the radius */ 868080d2917SAlp Dener tao->trust = PetscMax(bnk->omega4 * bnk->dnorm, tao->trust); 869080d2917SAlp Dener } else { 870080d2917SAlp Dener /* More than full step taken; increase the radius */ 871080d2917SAlp Dener tao->trust = PetscMax(bnk->omega5 * bnk->dnorm, tao->trust); 872080d2917SAlp Dener } 873080d2917SAlp Dener } else { 874080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 875080d2917SAlp Dener tao->trust = bnk->omega1 * PetscMin(bnk->dnorm, tao->trust); 876080d2917SAlp Dener } 877080d2917SAlp Dener break; 878080d2917SAlp Dener 879080d2917SAlp Dener case BNK_UPDATE_REDUCTION: 880080d2917SAlp Dener if (stepType == BNK_NEWTON) { 881b1c2d0e3SAlp Dener if (prered < 0.0) { 882fed79b8eSAlp Dener /* The predicted reduction has the wrong sign. This cannot 883fed79b8eSAlp Dener happen in infinite precision arithmetic. Step should 884fed79b8eSAlp Dener be rejected! */ 885080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 8863105154fSTodd Munson } else { 887b1c2d0e3SAlp Dener if (PetscIsInfOrNanReal(actred)) { 888080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 889080d2917SAlp Dener } else { 8903105154fSTodd Munson if ((PetscAbsScalar(actred) <= PetscMax(1.0, PetscAbsScalar(bnk->f))*bnk->epsilon) && (PetscAbsScalar(prered) <= PetscMax(1.0, PetscAbsScalar(bnk->f))*bnk->epsilon)) { 891080d2917SAlp Dener kappa = 1.0; 8923105154fSTodd Munson } else { 893080d2917SAlp Dener kappa = actred / prered; 894080d2917SAlp Dener } 895fed79b8eSAlp Dener 896fed79b8eSAlp Dener /* Accept or reject the step and update radius */ 897080d2917SAlp Dener if (kappa < bnk->eta1) { 898fed79b8eSAlp Dener /* Reject the step */ 899080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 9003105154fSTodd Munson } else { 901fed79b8eSAlp Dener /* Accept the step */ 902c133c014SAlp Dener *accept = PETSC_TRUE; 903c133c014SAlp Dener /* Update the trust region radius only if the computed step is at the trust radius boundary */ 9048d5ead36SAlp Dener if (bnk->dnorm == tao->trust) { 905080d2917SAlp Dener if (kappa < bnk->eta2) { 906080d2917SAlp Dener /* Marginal bad step */ 907c133c014SAlp Dener tao->trust = bnk->alpha2 * tao->trust; 9083105154fSTodd Munson } else if (kappa < bnk->eta3) { 909fed79b8eSAlp Dener /* Reasonable step */ 910fed79b8eSAlp Dener tao->trust = bnk->alpha3 * tao->trust; 9113105154fSTodd Munson } else if (kappa < bnk->eta4) { 912080d2917SAlp Dener /* Good step */ 913c133c014SAlp Dener tao->trust = bnk->alpha4 * tao->trust; 9143105154fSTodd Munson } else { 915080d2917SAlp Dener /* Very good step */ 916c133c014SAlp Dener tao->trust = bnk->alpha5 * tao->trust; 917080d2917SAlp Dener } 918c133c014SAlp Dener } 919080d2917SAlp Dener } 920080d2917SAlp Dener } 921080d2917SAlp Dener } 922080d2917SAlp Dener } else { 923080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 924080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(bnk->dnorm, tao->trust); 925080d2917SAlp Dener } 926080d2917SAlp Dener break; 927080d2917SAlp Dener 928080d2917SAlp Dener default: 929080d2917SAlp Dener if (stepType == BNK_NEWTON) { 930b1c2d0e3SAlp Dener if (prered < 0.0) { 931080d2917SAlp Dener /* The predicted reduction has the wrong sign. This cannot */ 932080d2917SAlp Dener /* happen in infinite precision arithmetic. Step should */ 933080d2917SAlp Dener /* be rejected! */ 934080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 935080d2917SAlp Dener } else { 936b1c2d0e3SAlp Dener if (PetscIsInfOrNanReal(actred)) { 937080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 938080d2917SAlp Dener } else { 939080d2917SAlp Dener if ((PetscAbsScalar(actred) <= bnk->epsilon) && (PetscAbsScalar(prered) <= bnk->epsilon)) { 940080d2917SAlp Dener kappa = 1.0; 941080d2917SAlp Dener } else { 942080d2917SAlp Dener kappa = actred / prered; 943080d2917SAlp Dener } 944080d2917SAlp Dener 945080d2917SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 946080d2917SAlp Dener tau_1 = bnk->theta * gdx / (bnk->theta * gdx - (1.0 - bnk->theta) * prered + actred); 947080d2917SAlp Dener tau_2 = bnk->theta * gdx / (bnk->theta * gdx + (1.0 + bnk->theta) * prered - actred); 948080d2917SAlp Dener tau_min = PetscMin(tau_1, tau_2); 949080d2917SAlp Dener tau_max = PetscMax(tau_1, tau_2); 950080d2917SAlp Dener 951080d2917SAlp Dener if (kappa >= 1.0 - bnk->mu1) { 952080d2917SAlp Dener /* Great agreement */ 953080d2917SAlp Dener *accept = PETSC_TRUE; 954080d2917SAlp Dener if (tau_max < 1.0) { 955080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma3 * bnk->dnorm); 956080d2917SAlp Dener } else if (tau_max > bnk->gamma4) { 957080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma4 * bnk->dnorm); 958080d2917SAlp Dener } else { 959080d2917SAlp Dener tao->trust = PetscMax(tao->trust, tau_max * bnk->dnorm); 960080d2917SAlp Dener } 961080d2917SAlp Dener } else if (kappa >= 1.0 - bnk->mu2) { 962080d2917SAlp Dener /* Good agreement */ 963080d2917SAlp Dener *accept = PETSC_TRUE; 964080d2917SAlp Dener if (tau_max < bnk->gamma2) { 965080d2917SAlp Dener tao->trust = bnk->gamma2 * PetscMin(tao->trust, bnk->dnorm); 966080d2917SAlp Dener } else if (tau_max > bnk->gamma3) { 967080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma3 * bnk->dnorm); 968080d2917SAlp Dener } else if (tau_max < 1.0) { 969080d2917SAlp Dener tao->trust = tau_max * PetscMin(tao->trust, bnk->dnorm); 970080d2917SAlp Dener } else { 971080d2917SAlp Dener tao->trust = PetscMax(tao->trust, tau_max * bnk->dnorm); 972080d2917SAlp Dener } 973080d2917SAlp Dener } else { 974080d2917SAlp Dener /* Not good agreement */ 975080d2917SAlp Dener if (tau_min > 1.0) { 976080d2917SAlp Dener tao->trust = bnk->gamma2 * PetscMin(tao->trust, bnk->dnorm); 977080d2917SAlp Dener } else if (tau_max < bnk->gamma1) { 978080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 979080d2917SAlp Dener } else if ((tau_min < bnk->gamma1) && (tau_max >= 1.0)) { 980080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 981080d2917SAlp Dener } else if ((tau_1 >= bnk->gamma1) && (tau_1 < 1.0) && ((tau_2 < bnk->gamma1) || (tau_2 >= 1.0))) { 982080d2917SAlp Dener tao->trust = tau_1 * PetscMin(tao->trust, bnk->dnorm); 983080d2917SAlp Dener } else if ((tau_2 >= bnk->gamma1) && (tau_2 < 1.0) && ((tau_1 < bnk->gamma1) || (tau_2 >= 1.0))) { 984080d2917SAlp Dener tao->trust = tau_2 * PetscMin(tao->trust, bnk->dnorm); 985080d2917SAlp Dener } else { 986080d2917SAlp Dener tao->trust = tau_max * PetscMin(tao->trust, bnk->dnorm); 987080d2917SAlp Dener } 988080d2917SAlp Dener } 989080d2917SAlp Dener } 990080d2917SAlp Dener } 991080d2917SAlp Dener } else { 992080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 993080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(bnk->dnorm, tao->trust); 994080d2917SAlp Dener } 99528017e9fSAlp Dener break; 996080d2917SAlp Dener } 997c133c014SAlp Dener /* Make sure the radius does not violate min and max settings */ 998c133c014SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 999fed79b8eSAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 1000080d2917SAlp Dener PetscFunctionReturn(0); 1001080d2917SAlp Dener } 1002080d2917SAlp Dener 1003eb910715SAlp Dener /* ---------------------------------------------------------- */ 1004df278d8fSAlp Dener 100562675beeSAlp Dener PetscErrorCode TaoBNKAddStepCounts(Tao tao, PetscInt stepType) 100662675beeSAlp Dener { 100762675beeSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 100862675beeSAlp Dener 100962675beeSAlp Dener PetscFunctionBegin; 101062675beeSAlp Dener switch (stepType) { 101162675beeSAlp Dener case BNK_NEWTON: 101262675beeSAlp Dener ++bnk->newt; 101362675beeSAlp Dener break; 101462675beeSAlp Dener case BNK_BFGS: 101562675beeSAlp Dener ++bnk->bfgs; 101662675beeSAlp Dener break; 101762675beeSAlp Dener case BNK_SCALED_GRADIENT: 101862675beeSAlp Dener ++bnk->sgrad; 101962675beeSAlp Dener break; 102062675beeSAlp Dener case BNK_GRADIENT: 102162675beeSAlp Dener ++bnk->grad; 102262675beeSAlp Dener break; 102362675beeSAlp Dener default: 102462675beeSAlp Dener break; 102562675beeSAlp Dener } 102662675beeSAlp Dener PetscFunctionReturn(0); 102762675beeSAlp Dener } 102862675beeSAlp Dener 102962675beeSAlp Dener /* ---------------------------------------------------------- */ 103062675beeSAlp Dener 10319b6ef848SAlp Dener PetscErrorCode TaoSetUp_BNK(Tao tao) 1032eb910715SAlp Dener { 1033eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1034eb910715SAlp Dener PetscErrorCode ierr; 10359b6ef848SAlp Dener KSPType ksp_type; 1036e031d6f5SAlp Dener PetscInt i; 1037eb910715SAlp Dener 1038eb910715SAlp Dener PetscFunctionBegin; 1039c4b75bccSAlp Dener if (!tao->gradient) { 1040c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr); 1041c4b75bccSAlp Dener } 1042c4b75bccSAlp Dener if (!tao->stepdirection) { 1043c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr); 1044c4b75bccSAlp Dener } 1045c4b75bccSAlp Dener if (!bnk->W) { 1046c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->W);CHKERRQ(ierr); 1047c4b75bccSAlp Dener } 1048c4b75bccSAlp Dener if (!bnk->Xold) { 1049c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Xold);CHKERRQ(ierr); 1050c4b75bccSAlp Dener } 1051c4b75bccSAlp Dener if (!bnk->Gold) { 1052c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Gold);CHKERRQ(ierr); 1053c4b75bccSAlp Dener } 1054c4b75bccSAlp Dener if (!bnk->Xwork) { 1055c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Xwork);CHKERRQ(ierr); 1056c4b75bccSAlp Dener } 1057c4b75bccSAlp Dener if (!bnk->Gwork) { 1058c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Gwork);CHKERRQ(ierr); 1059c4b75bccSAlp Dener } 1060c4b75bccSAlp Dener if (!bnk->unprojected_gradient) { 1061c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->unprojected_gradient);CHKERRQ(ierr); 1062c4b75bccSAlp Dener } 1063c4b75bccSAlp Dener if (!bnk->unprojected_gradient_old) { 1064c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->unprojected_gradient_old);CHKERRQ(ierr); 1065c4b75bccSAlp Dener } 1066c4b75bccSAlp Dener if (!bnk->Diag_min) { 1067c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Diag_min);CHKERRQ(ierr); 1068c4b75bccSAlp Dener } 1069c4b75bccSAlp Dener if (!bnk->Diag_max) { 1070c4b75bccSAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Diag_max);CHKERRQ(ierr); 1071c4b75bccSAlp Dener } 1072e031d6f5SAlp Dener if (bnk->max_cg_its > 0) { 1073c4b75bccSAlp Dener /* Ensure that the important common vectors are shared between BNK and embedded BNCG */ 1074c4b75bccSAlp Dener bnk->bncg_ctx = (TAO_BNCG *)bnk->bncg->data; 107589da521bSAlp Dener ierr = PetscObjectReference((PetscObject)(bnk->unprojected_gradient_old));CHKERRQ(ierr); 107689da521bSAlp Dener ierr = VecDestroy(&bnk->bncg_ctx->unprojected_gradient_old);CHKERRQ(ierr); 107789da521bSAlp Dener bnk->bncg_ctx->unprojected_gradient_old = bnk->unprojected_gradient_old; 1078c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(bnk->unprojected_gradient));CHKERRQ(ierr); 1079c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg_ctx->unprojected_gradient);CHKERRQ(ierr); 1080c4b75bccSAlp Dener bnk->bncg_ctx->unprojected_gradient = bnk->unprojected_gradient; 1081c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(bnk->Gold));CHKERRQ(ierr); 1082c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg_ctx->G_old);CHKERRQ(ierr); 1083c4b75bccSAlp Dener bnk->bncg_ctx->G_old = bnk->Gold; 1084c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(tao->gradient));CHKERRQ(ierr); 1085c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg->gradient);CHKERRQ(ierr); 1086c4b75bccSAlp Dener bnk->bncg->gradient = tao->gradient; 1087c4b75bccSAlp Dener ierr = PetscObjectReference((PetscObject)(tao->stepdirection));CHKERRQ(ierr); 1088c4b75bccSAlp Dener ierr = VecDestroy(&bnk->bncg->stepdirection);CHKERRQ(ierr); 1089c4b75bccSAlp Dener bnk->bncg->stepdirection = tao->stepdirection; 1090c4b75bccSAlp Dener ierr = TaoSetInitialVector(bnk->bncg, tao->solution);CHKERRQ(ierr); 1091c4b75bccSAlp Dener /* Copy over some settings from BNK into BNCG */ 1092e031d6f5SAlp Dener ierr = TaoSetMaximumIterations(bnk->bncg, bnk->max_cg_its);CHKERRQ(ierr); 1093e031d6f5SAlp Dener ierr = TaoSetTolerances(bnk->bncg, tao->gatol, tao->grtol, tao->gttol);CHKERRQ(ierr); 1094e031d6f5SAlp Dener ierr = TaoSetFunctionLowerBound(bnk->bncg, tao->fmin);CHKERRQ(ierr); 1095937a31a1SAlp Dener ierr = TaoSetConvergenceTest(bnk->bncg, tao->ops->convergencetest, tao->cnvP);CHKERRQ(ierr); 1096e031d6f5SAlp Dener ierr = TaoSetObjectiveRoutine(bnk->bncg, tao->ops->computeobjective, tao->user_objP);CHKERRQ(ierr); 1097e031d6f5SAlp Dener ierr = TaoSetGradientRoutine(bnk->bncg, tao->ops->computegradient, tao->user_gradP);CHKERRQ(ierr); 1098e031d6f5SAlp Dener ierr = TaoSetObjectiveAndGradientRoutine(bnk->bncg, tao->ops->computeobjectiveandgradient, tao->user_objgradP);CHKERRQ(ierr); 1099e031d6f5SAlp Dener ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)tao, (PetscObject)(bnk->bncg));CHKERRQ(ierr); 1100c4b75bccSAlp Dener for (i=0; i<tao->numbermonitors; ++i) { 1101e031d6f5SAlp Dener ierr = TaoSetMonitor(bnk->bncg, tao->monitor[i], tao->monitorcontext[i], tao->monitordestroy[i]);CHKERRQ(ierr); 1102e031d6f5SAlp Dener ierr = PetscObjectReference((PetscObject)(tao->monitorcontext[i]));CHKERRQ(ierr); 1103e031d6f5SAlp Dener } 1104e031d6f5SAlp Dener } 1105c0f10754SAlp Dener bnk->X_inactive = 0; 1106c0f10754SAlp Dener bnk->G_inactive = 0; 110762675beeSAlp Dener bnk->inactive_work = 0; 110862675beeSAlp Dener bnk->active_work = 0; 110962675beeSAlp Dener bnk->inactive_idx = 0; 111062675beeSAlp Dener bnk->active_idx = 0; 111162675beeSAlp Dener bnk->active_lower = 0; 111262675beeSAlp Dener bnk->active_upper = 0; 111362675beeSAlp Dener bnk->active_fixed = 0; 1114eb910715SAlp Dener bnk->M = 0; 111509164190SAlp Dener bnk->H_inactive = 0; 111609164190SAlp Dener bnk->Hpre_inactive = 0; 11179b6ef848SAlp Dener ierr = KSPGetType(tao->ksp,&ksp_type);CHKERRQ(ierr); 11189b6ef848SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGNASH,&bnk->is_nash);CHKERRQ(ierr); 11199b6ef848SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGSTCG,&bnk->is_stcg);CHKERRQ(ierr); 11209b6ef848SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGGLTR,&bnk->is_gltr);CHKERRQ(ierr); 1121eb910715SAlp Dener PetscFunctionReturn(0); 1122eb910715SAlp Dener } 1123eb910715SAlp Dener 1124eb910715SAlp Dener /*------------------------------------------------------------*/ 1125df278d8fSAlp Dener 1126eb910715SAlp Dener static PetscErrorCode TaoDestroy_BNK(Tao tao) 1127eb910715SAlp Dener { 1128eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1129eb910715SAlp Dener PetscErrorCode ierr; 1130eb910715SAlp Dener 1131eb910715SAlp Dener PetscFunctionBegin; 1132eb910715SAlp Dener if (tao->setupcalled) { 1133eb910715SAlp Dener ierr = VecDestroy(&bnk->W);CHKERRQ(ierr); 1134eb910715SAlp Dener ierr = VecDestroy(&bnk->Xold);CHKERRQ(ierr); 1135eb910715SAlp Dener ierr = VecDestroy(&bnk->Gold);CHKERRQ(ierr); 113609164190SAlp Dener ierr = VecDestroy(&bnk->Xwork);CHKERRQ(ierr); 113709164190SAlp Dener ierr = VecDestroy(&bnk->Gwork);CHKERRQ(ierr); 113809164190SAlp Dener ierr = VecDestroy(&bnk->unprojected_gradient);CHKERRQ(ierr); 113909164190SAlp Dener ierr = VecDestroy(&bnk->unprojected_gradient_old);CHKERRQ(ierr); 114062675beeSAlp Dener ierr = VecDestroy(&bnk->Diag_min);CHKERRQ(ierr); 114162675beeSAlp Dener ierr = VecDestroy(&bnk->Diag_max);CHKERRQ(ierr); 1142c4b75bccSAlp Dener } 1143ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_lower);CHKERRQ(ierr); 1144ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_upper);CHKERRQ(ierr); 1145ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_fixed);CHKERRQ(ierr); 1146ca964c49SAlp Dener ierr = ISDestroy(&bnk->active_idx);CHKERRQ(ierr); 1147ca964c49SAlp Dener ierr = ISDestroy(&bnk->inactive_idx);CHKERRQ(ierr); 1148c4b75bccSAlp Dener if (bnk->Hpre_inactive != tao->hessian_pre && bnk->Hpre_inactive != bnk->H_inactive) { 1149c4b75bccSAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr); 1150c4b75bccSAlp Dener } 1151c4b75bccSAlp Dener if (bnk->H_inactive != tao->hessian) { 1152c4b75bccSAlp Dener ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr); 1153c4b75bccSAlp Dener } 1154ca964c49SAlp Dener ierr = TaoDestroy(&bnk->bncg);CHKERRQ(ierr); 1155eb910715SAlp Dener ierr = PetscFree(tao->data);CHKERRQ(ierr); 1156eb910715SAlp Dener PetscFunctionReturn(0); 1157eb910715SAlp Dener } 1158eb910715SAlp Dener 1159eb910715SAlp Dener /*------------------------------------------------------------*/ 1160df278d8fSAlp Dener 1161eb910715SAlp Dener static PetscErrorCode TaoSetFromOptions_BNK(PetscOptionItems *PetscOptionsObject,Tao tao) 1162eb910715SAlp Dener { 1163eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1164eb910715SAlp Dener PetscErrorCode ierr; 1165eb910715SAlp Dener 1166eb910715SAlp Dener PetscFunctionBegin; 1167eb910715SAlp Dener ierr = PetscOptionsHead(PetscOptionsObject,"Newton line search method for unconstrained optimization");CHKERRQ(ierr); 11688d5ead36SAlp 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); 11698d5ead36SAlp 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); 11702f75a4aaSAlp 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); 1171748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_sval", "(developer) Hessian perturbation starting value", "", bnk->sval, &bnk->sval,NULL);CHKERRQ(ierr); 1172748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imin", "(developer) minimum initial Hessian perturbation", "", bnk->imin, &bnk->imin,NULL);CHKERRQ(ierr); 1173748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imax", "(developer) maximum initial Hessian perturbation", "", bnk->imax, &bnk->imax,NULL);CHKERRQ(ierr); 1174748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imfac", "(developer) initial merit factor for Hessian perturbation", "", bnk->imfac, &bnk->imfac,NULL);CHKERRQ(ierr); 1175748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmin", "(developer) minimum Hessian perturbation", "", bnk->pmin, &bnk->pmin,NULL);CHKERRQ(ierr); 1176748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmax", "(developer) maximum Hessian perturbation", "", bnk->pmax, &bnk->pmax,NULL);CHKERRQ(ierr); 1177748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pgfac", "(developer) Hessian perturbation growth factor", "", bnk->pgfac, &bnk->pgfac,NULL);CHKERRQ(ierr); 1178748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_psfac", "(developer) Hessian perturbation shrink factor", "", bnk->psfac, &bnk->psfac,NULL);CHKERRQ(ierr); 1179748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmgfac", "(developer) merit growth factor for Hessian perturbation", "", bnk->pmgfac, &bnk->pmgfac,NULL);CHKERRQ(ierr); 1180748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmsfac", "(developer) merit shrink factor for Hessian perturbation", "", bnk->pmsfac, &bnk->pmsfac,NULL);CHKERRQ(ierr); 1181748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta1", "(developer) threshold for rejecting step (-tao_bnk_update_type reduction)", "", bnk->eta1, &bnk->eta1,NULL);CHKERRQ(ierr); 1182748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta2", "(developer) threshold for accepting marginal step (-tao_bnk_update_type reduction)", "", bnk->eta2, &bnk->eta2,NULL);CHKERRQ(ierr); 1183748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta3", "(developer) threshold for accepting reasonable step (-tao_bnk_update_type reduction)", "", bnk->eta3, &bnk->eta3,NULL);CHKERRQ(ierr); 1184748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta4", "(developer) threshold for accepting good step (-tao_bnk_update_type reduction)", "", bnk->eta4, &bnk->eta4,NULL);CHKERRQ(ierr); 1185748696b1SAlp 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); 1186748696b1SAlp 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); 1187748696b1SAlp 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); 1188748696b1SAlp 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); 1189748696b1SAlp 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); 1190748696b1SAlp 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); 1191748696b1SAlp 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); 1192748696b1SAlp 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); 1193748696b1SAlp 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); 1194748696b1SAlp 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); 1195748696b1SAlp 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); 1196748696b1SAlp 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); 1197748696b1SAlp 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); 1198748696b1SAlp 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); 1199748696b1SAlp 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); 1200748696b1SAlp 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); 1201748696b1SAlp 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); 1202748696b1SAlp 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); 1203748696b1SAlp 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); 1204748696b1SAlp 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); 1205748696b1SAlp 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); 1206748696b1SAlp 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); 1207748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu2", "(developer) threshold for accepting good step (-tao_bnk_update_type interpolation)", "", bnk->mu2, &bnk->mu2,NULL);CHKERRQ(ierr); 1208748696b1SAlp 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); 1209748696b1SAlp 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); 1210748696b1SAlp 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); 1211748696b1SAlp 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); 1212748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_theta", "(developer) trust region interpolation factor (-tao_bnk_update_type interpolation)", "", bnk->theta, &bnk->theta,NULL);CHKERRQ(ierr); 1213748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_min_radius", "(developer) lower bound on initial radius", "", bnk->min_radius, &bnk->min_radius,NULL);CHKERRQ(ierr); 1214748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_max_radius", "(developer) upper bound on radius", "", bnk->max_radius, &bnk->max_radius,NULL);CHKERRQ(ierr); 1215748696b1SAlp Dener ierr = PetscOptionsReal("-tao_bnk_epsilon", "(developer) tolerance used when computing actual and predicted reduction", "", bnk->epsilon, &bnk->epsilon,NULL);CHKERRQ(ierr); 1216748696b1SAlp 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); 1217748696b1SAlp 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); 1218c0f10754SAlp 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); 1219eb910715SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 122033c78596SAlp Dener ierr = TaoSetFromOptions(bnk->bncg);CHKERRQ(ierr); 1221eb910715SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 1222eb910715SAlp Dener ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 1223eb910715SAlp Dener PetscFunctionReturn(0); 1224eb910715SAlp Dener } 1225eb910715SAlp Dener 1226eb910715SAlp Dener /*------------------------------------------------------------*/ 1227df278d8fSAlp Dener 1228eb910715SAlp Dener static PetscErrorCode TaoView_BNK(Tao tao, PetscViewer viewer) 1229eb910715SAlp Dener { 1230eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1231eb910715SAlp Dener PetscInt nrejects; 1232eb910715SAlp Dener PetscBool isascii; 1233eb910715SAlp Dener PetscErrorCode ierr; 1234eb910715SAlp Dener 1235eb910715SAlp Dener PetscFunctionBegin; 1236eb910715SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1237eb910715SAlp Dener if (isascii) { 1238eb910715SAlp Dener ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1239*b9ac7092SAlp Dener if (bnk->M) { 1240cd929ea3SAlp Dener ierr = MatLMVMGetRejectCount(bnk->M,&nrejects);CHKERRQ(ierr); 1241*b9ac7092SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Rejected BFGS updates: %D\n",nrejects);CHKERRQ(ierr); 1242eb910715SAlp Dener } 1243e031d6f5SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "CG steps: %D\n", bnk->tot_cg_its);CHKERRQ(ierr); 1244eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Newton steps: %D\n", bnk->newt);CHKERRQ(ierr); 1245*b9ac7092SAlp Dener if (bnk->M) { 1246eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "BFGS steps: %D\n", bnk->bfgs);CHKERRQ(ierr); 1247*b9ac7092SAlp Dener } 1248eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Scaled gradient steps: %D\n", bnk->sgrad);CHKERRQ(ierr); 1249eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", bnk->grad);CHKERRQ(ierr); 1250eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "KSP termination reasons:\n");CHKERRQ(ierr); 1251eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " atol: %D\n", bnk->ksp_atol);CHKERRQ(ierr); 1252eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " rtol: %D\n", bnk->ksp_rtol);CHKERRQ(ierr); 1253eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " ctol: %D\n", bnk->ksp_ctol);CHKERRQ(ierr); 1254eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " negc: %D\n", bnk->ksp_negc);CHKERRQ(ierr); 1255eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " dtol: %D\n", bnk->ksp_dtol);CHKERRQ(ierr); 1256eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " iter: %D\n", bnk->ksp_iter);CHKERRQ(ierr); 1257eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " othr: %D\n", bnk->ksp_othr);CHKERRQ(ierr); 1258eb910715SAlp Dener ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1259eb910715SAlp Dener } 1260eb910715SAlp Dener PetscFunctionReturn(0); 1261eb910715SAlp Dener } 1262eb910715SAlp Dener 1263eb910715SAlp Dener /* ---------------------------------------------------------- */ 1264df278d8fSAlp Dener 1265eb910715SAlp Dener /*MC 1266eb910715SAlp Dener TAOBNK - Shared base-type for Bounded Newton-Krylov type algorithms. 126766ed3702SAlp Dener At each iteration, the BNK methods solve the symmetric 1268eb910715SAlp Dener system of equations to obtain the step diretion dk: 1269eb910715SAlp Dener Hk dk = -gk 12702b97c8d8SAlp Dener for free variables only. The step can be globalized either through 12712b97c8d8SAlp Dener trust-region methods, or a line search, or a heuristic mixture of both. 1272eb910715SAlp Dener 1273eb910715SAlp Dener Options Database Keys: 1274748696b1SAlp Dener + -tao_max_cg_its - maximum number of bounded conjugate-gradient iterations taken in each Newton loop 1275748696b1SAlp Dener . -tao_bnk_pc_type - preconditioner type ("none", "ahess", "bfgs", "petsc") 12763cb832f1SAlp Dener . -tao_bnk_bfgs_scale_type - BFGS preconditioner diagonal scaling type ("ahess", "phess", "bfgs") 12773cb832f1SAlp Dener . -tao_bnk_init_type - trust radius initialization method ("constant", "direction", "interpolation") 12783cb832f1SAlp Dener . -tao_bnk_update_type - trust radius update method ("step", "direction", "interpolation") 12793cb832f1SAlp Dener . -tao_bnk_as_type - active-set estimation method ("none", "bertsekas") 1280748696b1SAlp Dener . -tao_bnk_as_tol - (developer) initial tolerance used in estimating bounded active variables (-tao_bnk_as_type bertsekas) 1281748696b1SAlp Dener . -tao_bnk_as_step - (developer) trial step length used in estimating bounded active variables (-tao_bnk_as_type bertsekas) 1282748696b1SAlp Dener . -tao_bnk_sval - (developer) Hessian perturbation starting value 1283748696b1SAlp Dener . -tao_bnk_imin - (developer) minimum initial Hessian perturbation 1284748696b1SAlp Dener . -tao_bnk_imax - (developer) maximum initial Hessian perturbation 1285748696b1SAlp Dener . -tao_bnk_pmin - (developer) minimum Hessian perturbation 1286748696b1SAlp Dener . -tao_bnk_pmax - (developer) aximum Hessian perturbation 1287748696b1SAlp Dener . -tao_bnk_pgfac - (developer) Hessian perturbation growth factor 1288748696b1SAlp Dener . -tao_bnk_psfac - (developer) Hessian perturbation shrink factor 1289748696b1SAlp Dener . -tao_bnk_imfac - (developer) initial merit factor for Hessian perturbation 1290748696b1SAlp Dener . -tao_bnk_pmgfac - (developer) merit growth factor for Hessian perturbation 1291748696b1SAlp Dener . -tao_bnk_pmsfac - (developer) merit shrink factor for Hessian perturbation 1292748696b1SAlp Dener . -tao_bnk_eta1 - (developer) threshold for rejecting step (-tao_bnk_update_type reduction) 1293748696b1SAlp Dener . -tao_bnk_eta2 - (developer) threshold for accepting marginal step (-tao_bnk_update_type reduction) 1294748696b1SAlp Dener . -tao_bnk_eta3 - (developer) threshold for accepting reasonable step (-tao_bnk_update_type reduction) 1295748696b1SAlp Dener . -tao_bnk_eta4 - (developer) threshold for accepting good step (-tao_bnk_update_type reduction) 1296748696b1SAlp Dener . -tao_bnk_alpha1 - (developer) radius reduction factor for rejected step (-tao_bnk_update_type reduction) 1297748696b1SAlp Dener . -tao_bnk_alpha2 - (developer) radius reduction factor for marginally accepted bad step (-tao_bnk_update_type reduction) 1298748696b1SAlp Dener . -tao_bnk_alpha3 - (developer) radius increase factor for reasonable accepted step (-tao_bnk_update_type reduction) 1299748696b1SAlp Dener . -tao_bnk_alpha4 - (developer) radius increase factor for good accepted step (-tao_bnk_update_type reduction) 1300748696b1SAlp Dener . -tao_bnk_alpha5 - (developer) radius increase factor for very good accepted step (-tao_bnk_update_type reduction) 1301748696b1SAlp Dener . -tao_bnk_epsilon - (developer) tolerance for small pred/actual ratios that trigger automatic step acceptance (-tao_bnk_update_type reduction) 1302748696b1SAlp Dener . -tao_bnk_mu1 - (developer) threshold for accepting very good step (-tao_bnk_update_type interpolation) 1303748696b1SAlp Dener . -tao_bnk_mu2 - (developer) threshold for accepting good step (-tao_bnk_update_type interpolation) 1304748696b1SAlp Dener . -tao_bnk_gamma1 - (developer) radius reduction factor for rejected very bad step (-tao_bnk_update_type interpolation) 1305748696b1SAlp Dener . -tao_bnk_gamma2 - (developer) radius reduction factor for rejected bad step (-tao_bnk_update_type interpolation) 1306748696b1SAlp Dener . -tao_bnk_gamma3 - (developer) radius increase factor for accepted good step (-tao_bnk_update_type interpolation) 1307748696b1SAlp Dener . -tao_bnk_gamma4 - (developer) radius increase factor for accepted very good step (-tao_bnk_update_type interpolation) 1308748696b1SAlp Dener . -tao_bnk_theta - (developer) trust region interpolation factor (-tao_bnk_update_type interpolation) 1309748696b1SAlp Dener . -tao_bnk_nu1 - (developer) threshold for small line-search step length (-tao_bnk_update_type step) 1310748696b1SAlp Dener . -tao_bnk_nu2 - (developer) threshold for reasonable line-search step length (-tao_bnk_update_type step) 1311748696b1SAlp Dener . -tao_bnk_nu3 - (developer) threshold for large line-search step length (-tao_bnk_update_type step) 1312748696b1SAlp Dener . -tao_bnk_nu4 - (developer) threshold for very large line-search step length (-tao_bnk_update_type step) 1313748696b1SAlp Dener . -tao_bnk_omega1 - (developer) radius reduction factor for very small line-search step length (-tao_bnk_update_type step) 1314748696b1SAlp Dener . -tao_bnk_omega2 - (developer) radius reduction factor for small line-search step length (-tao_bnk_update_type step) 1315748696b1SAlp Dener . -tao_bnk_omega3 - (developer) radius factor for decent line-search step length (-tao_bnk_update_type step) 1316748696b1SAlp Dener . -tao_bnk_omega4 - (developer) radius increase factor for large line-search step length (-tao_bnk_update_type step) 1317748696b1SAlp Dener . -tao_bnk_omega5 - (developer) radius increase factor for very large line-search step length (-tao_bnk_update_type step) 1318748696b1SAlp Dener . -tao_bnk_mu1_i - (developer) threshold for accepting very good step (-tao_bnk_init_type interpolation) 1319748696b1SAlp Dener . -tao_bnk_mu2_i - (developer) threshold for accepting good step (-tao_bnk_init_type interpolation) 1320748696b1SAlp Dener . -tao_bnk_gamma1_i - (developer) radius reduction factor for rejected very bad step (-tao_bnk_init_type interpolation) 1321748696b1SAlp Dener . -tao_bnk_gamma2_i - (developer) radius reduction factor for rejected bad step (-tao_bnk_init_type interpolation) 1322748696b1SAlp Dener . -tao_bnk_gamma3_i - (developer) radius increase factor for accepted good step (-tao_bnk_init_type interpolation) 1323748696b1SAlp Dener . -tao_bnk_gamma4_i - (developer) radius increase factor for accepted very good step (-tao_bnk_init_type interpolation) 1324748696b1SAlp Dener - -tao_bnk_theta_i - (developer) trust region interpolation factor (-tao_bnk_init_type interpolation) 1325eb910715SAlp Dener 1326eb910715SAlp Dener Level: beginner 1327eb910715SAlp Dener M*/ 1328eb910715SAlp Dener 1329eb910715SAlp Dener PetscErrorCode TaoCreate_BNK(Tao tao) 1330eb910715SAlp Dener { 1331eb910715SAlp Dener TAO_BNK *bnk; 1332eb910715SAlp Dener const char *morethuente_type = TAOLINESEARCHMT; 1333eb910715SAlp Dener PetscErrorCode ierr; 1334*b9ac7092SAlp Dener PC pc; 1335eb910715SAlp Dener 1336eb910715SAlp Dener PetscFunctionBegin; 1337eb910715SAlp Dener ierr = PetscNewLog(tao,&bnk);CHKERRQ(ierr); 1338eb910715SAlp Dener 1339eb910715SAlp Dener tao->ops->setup = TaoSetUp_BNK; 1340eb910715SAlp Dener tao->ops->view = TaoView_BNK; 1341eb910715SAlp Dener tao->ops->setfromoptions = TaoSetFromOptions_BNK; 1342eb910715SAlp Dener tao->ops->destroy = TaoDestroy_BNK; 1343eb910715SAlp Dener 1344eb910715SAlp Dener /* Override default settings (unless already changed) */ 1345eb910715SAlp Dener if (!tao->max_it_changed) tao->max_it = 50; 1346eb910715SAlp Dener if (!tao->trust0_changed) tao->trust0 = 100.0; 1347eb910715SAlp Dener 1348eb910715SAlp Dener tao->data = (void*)bnk; 1349eb910715SAlp Dener 135066ed3702SAlp Dener /* Hessian shifting parameters */ 1351eb910715SAlp Dener bnk->sval = 0.0; 1352eb910715SAlp Dener bnk->imin = 1.0e-4; 1353eb910715SAlp Dener bnk->imax = 1.0e+2; 1354eb910715SAlp Dener bnk->imfac = 1.0e-1; 1355eb910715SAlp Dener 1356eb910715SAlp Dener bnk->pmin = 1.0e-12; 1357eb910715SAlp Dener bnk->pmax = 1.0e+2; 1358eb910715SAlp Dener bnk->pgfac = 1.0e+1; 1359eb910715SAlp Dener bnk->psfac = 4.0e-1; 1360eb910715SAlp Dener bnk->pmgfac = 1.0e-1; 1361eb910715SAlp Dener bnk->pmsfac = 1.0e-1; 1362eb910715SAlp Dener 1363eb910715SAlp Dener /* Default values for trust-region radius update based on steplength */ 1364eb910715SAlp Dener bnk->nu1 = 0.25; 1365eb910715SAlp Dener bnk->nu2 = 0.50; 1366eb910715SAlp Dener bnk->nu3 = 1.00; 1367eb910715SAlp Dener bnk->nu4 = 1.25; 1368eb910715SAlp Dener 1369eb910715SAlp Dener bnk->omega1 = 0.25; 1370eb910715SAlp Dener bnk->omega2 = 0.50; 1371eb910715SAlp Dener bnk->omega3 = 1.00; 1372eb910715SAlp Dener bnk->omega4 = 2.00; 1373eb910715SAlp Dener bnk->omega5 = 4.00; 1374eb910715SAlp Dener 1375eb910715SAlp Dener /* Default values for trust-region radius update based on reduction */ 1376eb910715SAlp Dener bnk->eta1 = 1.0e-4; 1377eb910715SAlp Dener bnk->eta2 = 0.25; 1378eb910715SAlp Dener bnk->eta3 = 0.50; 1379eb910715SAlp Dener bnk->eta4 = 0.90; 1380eb910715SAlp Dener 1381eb910715SAlp Dener bnk->alpha1 = 0.25; 1382eb910715SAlp Dener bnk->alpha2 = 0.50; 1383eb910715SAlp Dener bnk->alpha3 = 1.00; 1384eb910715SAlp Dener bnk->alpha4 = 2.00; 1385eb910715SAlp Dener bnk->alpha5 = 4.00; 1386eb910715SAlp Dener 1387eb910715SAlp Dener /* Default values for trust-region radius update based on interpolation */ 1388eb910715SAlp Dener bnk->mu1 = 0.10; 1389eb910715SAlp Dener bnk->mu2 = 0.50; 1390eb910715SAlp Dener 1391eb910715SAlp Dener bnk->gamma1 = 0.25; 1392eb910715SAlp Dener bnk->gamma2 = 0.50; 1393eb910715SAlp Dener bnk->gamma3 = 2.00; 1394eb910715SAlp Dener bnk->gamma4 = 4.00; 1395eb910715SAlp Dener 1396eb910715SAlp Dener bnk->theta = 0.05; 1397eb910715SAlp Dener 1398eb910715SAlp Dener /* Default values for trust region initialization based on interpolation */ 1399eb910715SAlp Dener bnk->mu1_i = 0.35; 1400eb910715SAlp Dener bnk->mu2_i = 0.50; 1401eb910715SAlp Dener 1402eb910715SAlp Dener bnk->gamma1_i = 0.0625; 1403eb910715SAlp Dener bnk->gamma2_i = 0.5; 1404eb910715SAlp Dener bnk->gamma3_i = 2.0; 1405eb910715SAlp Dener bnk->gamma4_i = 5.0; 1406eb910715SAlp Dener 1407eb910715SAlp Dener bnk->theta_i = 0.25; 1408eb910715SAlp Dener 1409eb910715SAlp Dener /* Remaining parameters */ 1410c0f10754SAlp Dener bnk->max_cg_its = 0; 1411eb910715SAlp Dener bnk->min_radius = 1.0e-10; 1412eb910715SAlp Dener bnk->max_radius = 1.0e10; 1413770b7498SAlp Dener bnk->epsilon = PetscPowReal(PETSC_MACHINE_EPSILON, 2.0/3.0); 14140a4511e9SAlp Dener bnk->as_tol = 1.0e-3; 14150a4511e9SAlp Dener bnk->as_step = 1.0e-3; 141662675beeSAlp Dener bnk->dmin = 1.0e-6; 141762675beeSAlp Dener bnk->dmax = 1.0e6; 1418eb910715SAlp Dener 1419*b9ac7092SAlp Dener bnk->M = 0; 1420*b9ac7092SAlp Dener bnk->bfgs_pre = 0; 1421cd929ea3SAlp Dener bnk->bfgs_scale_type = BFGS_SCALE_AHESS; 1422eb910715SAlp Dener bnk->init_type = BNK_INIT_INTERPOLATION; 1423fed79b8eSAlp Dener bnk->update_type = BNK_UPDATE_INTERPOLATION; 14242f75a4aaSAlp Dener bnk->as_type = BNK_AS_BERTSEKAS; 1425eb910715SAlp Dener 1426e031d6f5SAlp Dener /* Create the embedded BNCG solver */ 1427e031d6f5SAlp Dener ierr = TaoCreate(PetscObjectComm((PetscObject)tao), &bnk->bncg);CHKERRQ(ierr); 1428e031d6f5SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)bnk->bncg, (PetscObject)tao, 1);CHKERRQ(ierr); 1429e031d6f5SAlp Dener ierr = TaoSetOptionsPrefix(bnk->bncg, "tao_bnk_");CHKERRQ(ierr); 1430e031d6f5SAlp Dener ierr = TaoSetType(bnk->bncg, TAOBNCG);CHKERRQ(ierr); 1431e031d6f5SAlp Dener 1432c0f10754SAlp Dener /* Create the line search */ 1433eb910715SAlp Dener ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr); 1434eb910715SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 1435e031d6f5SAlp Dener ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 1436eb910715SAlp Dener ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr); 1437eb910715SAlp Dener ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr); 1438eb910715SAlp Dener 1439eb910715SAlp Dener /* Set linear solver to default for symmetric matrices */ 1440eb910715SAlp Dener ierr = KSPCreate(((PetscObject)tao)->comm,&tao->ksp);CHKERRQ(ierr); 1441eb910715SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1);CHKERRQ(ierr); 1442eb910715SAlp Dener ierr = KSPSetOptionsPrefix(tao->ksp,tao->hdr.prefix);CHKERRQ(ierr); 1443eb910715SAlp Dener ierr = KSPSetType(tao->ksp,KSPCGSTCG);CHKERRQ(ierr); 1444*b9ac7092SAlp Dener ierr = KSPGetPC(tao->ksp, &pc); 1445*b9ac7092SAlp Dener ierr = PCSetType(pc, PCLMVM);CHKERRQ(ierr); 1446eb910715SAlp Dener PetscFunctionReturn(0); 1447eb910715SAlp Dener } 1448