1eb910715SAlp Dener #include <petsctaolinesearch.h> 2eb910715SAlp Dener #include <../src/tao/bound/impls/bnk/bnk.h> 3eb910715SAlp Dener 4eb910715SAlp Dener #include <petscksp.h> 5eb910715SAlp Dener 6*e031d6f5SAlp Dener static const char *BNK_PC[64] = {"none", "ahess", "bfgs", "petsc"}; 7*e031d6f5SAlp Dener static const char *BFGS_SCALE[64] = {"ahess", "phess", "bfgs"}; 8*e031d6f5SAlp Dener static const char *BNK_INIT[64] = {"constant", "direction", "interpolation"}; 9*e031d6f5SAlp Dener static const char *BNK_UPDATE[64] = {"step", "reduction", "interpolation"}; 10*e031d6f5SAlp Dener static const char *BNK_AS[64] = {"none", "bertsekas"}; 11*e031d6f5SAlp Dener 12*e031d6f5SAlp Dener /*------------------------------------------------------------*/ 13*e031d6f5SAlp Dener 14eb910715SAlp Dener /* Routine for BFGS preconditioner */ 15eb910715SAlp Dener 16eb910715SAlp Dener PetscErrorCode MatLMVMSolveShell(PC pc, Vec b, Vec x) 17eb910715SAlp Dener { 18eb910715SAlp Dener PetscErrorCode ierr; 19eb910715SAlp Dener Mat M; 20eb910715SAlp Dener 21eb910715SAlp Dener PetscFunctionBegin; 22eb910715SAlp Dener PetscValidHeaderSpecific(pc,PC_CLASSID,1); 23eb910715SAlp Dener PetscValidHeaderSpecific(b,VEC_CLASSID,2); 24eb910715SAlp Dener PetscValidHeaderSpecific(x,VEC_CLASSID,3); 25eb910715SAlp Dener ierr = PCShellGetContext(pc,(void**)&M);CHKERRQ(ierr); 265e9b73cbSAlp Dener ierr = MatLMVMSolve(M, b, x);CHKERRQ(ierr); 27eb910715SAlp Dener PetscFunctionReturn(0); 28eb910715SAlp Dener } 29eb910715SAlp Dener 30df278d8fSAlp Dener /*------------------------------------------------------------*/ 31df278d8fSAlp Dener 32df278d8fSAlp Dener /* Routine for initializing the KSP solver, the BFGS preconditioner, and the initial trust radius estimation */ 33df278d8fSAlp Dener 34c0f10754SAlp Dener PetscErrorCode TaoBNKInitialize(Tao tao, PetscInt initType, PetscBool *needH) 35eb910715SAlp Dener { 36eb910715SAlp Dener PetscErrorCode ierr; 37eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 38eb910715SAlp Dener PC pc; 39eb910715SAlp Dener 400a4511e9SAlp Dener PetscReal f_min, ftrial, prered, actred, kappa, sigma; 41eb910715SAlp Dener PetscReal tau, tau_1, tau_2, tau_max, tau_min, max_radius; 42*e031d6f5SAlp Dener PetscReal resnorm, delta; 43eb910715SAlp Dener 44c0f10754SAlp Dener PetscInt n,N; 45eb910715SAlp Dener 46eb910715SAlp Dener PetscInt i_max = 5; 47eb910715SAlp Dener PetscInt j_max = 1; 48eb910715SAlp Dener PetscInt i, j; 49eb910715SAlp Dener 50eb910715SAlp Dener PetscFunctionBegin; 5128017e9fSAlp Dener /* Project the current point onto the feasible set */ 5228017e9fSAlp Dener ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); 53*e031d6f5SAlp Dener ierr = TaoSetVariableBounds(bnk->bncg, tao->XL, tao->XU);CHKERRQ(ierr); 5428017e9fSAlp Dener ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr); 5528017e9fSAlp Dener 5628017e9fSAlp Dener /* Project the initial point onto the feasible region */ 5728017e9fSAlp Dener ierr = VecMedian(tao->XL,tao->solution,tao->XU,tao->solution);CHKERRQ(ierr); 5828017e9fSAlp Dener 5928017e9fSAlp Dener /* Check convergence criteria */ 6028017e9fSAlp Dener ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &bnk->f, bnk->unprojected_gradient);CHKERRQ(ierr); 6128017e9fSAlp Dener ierr = VecBoundGradientProjection(bnk->unprojected_gradient,tao->solution,tao->XL,tao->XU,tao->gradient);CHKERRQ(ierr); 6228017e9fSAlp Dener ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&bnk->gnorm);CHKERRQ(ierr); 6328017e9fSAlp Dener if (PetscIsInfOrNanReal(bnk->f) || PetscIsInfOrNanReal(bnk->gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 6428017e9fSAlp Dener 65c0f10754SAlp Dener /* Test the initial point for convergence */ 66*e031d6f5SAlp Dener ierr = VecFischer(tao->solution, bnk->unprojected_gradient, tao->XL, tao->XU, bnk->Gwork);CHKERRQ(ierr); 67*e031d6f5SAlp Dener ierr = VecNorm(bnk->Gwork, NORM_2, &resnorm);CHKERRQ(ierr); 68*e031d6f5SAlp Dener ierr = TaoLogConvergenceHistory(tao,bnk->f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 69*e031d6f5SAlp Dener ierr = TaoMonitor(tao,tao->niter,bnk->f,resnorm,0.0,1.0);CHKERRQ(ierr); 70c0f10754SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 71c0f10754SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 72c0f10754SAlp Dener 73*e031d6f5SAlp Dener /* Reset KSP stopping reason counters */ 74eb910715SAlp Dener bnk->ksp_atol = 0; 75eb910715SAlp Dener bnk->ksp_rtol = 0; 76eb910715SAlp Dener bnk->ksp_dtol = 0; 77eb910715SAlp Dener bnk->ksp_ctol = 0; 78eb910715SAlp Dener bnk->ksp_negc = 0; 79eb910715SAlp Dener bnk->ksp_iter = 0; 80eb910715SAlp Dener bnk->ksp_othr = 0; 81eb910715SAlp Dener 82*e031d6f5SAlp Dener /* Reset accepted step type counters */ 83*e031d6f5SAlp Dener bnk->tot_cg_its = 0; 84*e031d6f5SAlp Dener bnk->newt = 0; 85*e031d6f5SAlp Dener bnk->bfgs = 0; 86*e031d6f5SAlp Dener bnk->sgrad = 0; 87*e031d6f5SAlp Dener bnk->grad = 0; 88*e031d6f5SAlp Dener 89fed79b8eSAlp Dener /* Initialize the Hessian perturbation */ 90fed79b8eSAlp Dener bnk->pert = bnk->sval; 91fed79b8eSAlp Dener 92*e031d6f5SAlp Dener /* Allocate the vectors needed for the BFGS approximation */ 93*e031d6f5SAlp Dener if (BNK_PC_BFGS == bnk->pc_type) { 94*e031d6f5SAlp Dener if (!bnk->M) { 95eb910715SAlp Dener ierr = VecGetLocalSize(tao->solution,&n);CHKERRQ(ierr); 96eb910715SAlp Dener ierr = VecGetSize(tao->solution,&N);CHKERRQ(ierr); 97eb910715SAlp Dener ierr = MatCreateLMVM(((PetscObject)tao)->comm,n,N,&bnk->M);CHKERRQ(ierr); 98eb910715SAlp Dener ierr = MatLMVMAllocateVectors(bnk->M,tao->solution);CHKERRQ(ierr); 99eb910715SAlp Dener } 100*e031d6f5SAlp Dener if (bnk->bfgs_scale_type != BFGS_SCALE_BFGS && !bnk->Diag) { 101*e031d6f5SAlp Dener ierr = VecDuplicate(tao->solution,&bnk->Diag);CHKERRQ(ierr); 1025e9b73cbSAlp Dener } 103*e031d6f5SAlp Dener } 104*e031d6f5SAlp Dener 105*e031d6f5SAlp Dener /* Prepare the min/max vectors for safeguarding diagonal scales */ 10662675beeSAlp Dener ierr = VecSet(bnk->Diag_min, bnk->dmin);CHKERRQ(ierr); 10762675beeSAlp Dener ierr = VecSet(bnk->Diag_max, bnk->dmax);CHKERRQ(ierr); 108eb910715SAlp Dener 109eb910715SAlp Dener /* Modify the preconditioner to use the bfgs approximation */ 110eb910715SAlp Dener ierr = KSPGetPC(tao->ksp, &pc);CHKERRQ(ierr); 111eb910715SAlp Dener switch(bnk->pc_type) { 112eb910715SAlp Dener case BNK_PC_NONE: 113eb910715SAlp Dener ierr = PCSetType(pc, PCNONE);CHKERRQ(ierr); 114eb910715SAlp Dener ierr = PCSetFromOptions(pc);CHKERRQ(ierr); 115eb910715SAlp Dener break; 116eb910715SAlp Dener 117eb910715SAlp Dener case BNK_PC_AHESS: 118eb910715SAlp Dener ierr = PCSetType(pc, PCJACOBI);CHKERRQ(ierr); 119eb910715SAlp Dener ierr = PCSetFromOptions(pc);CHKERRQ(ierr); 120eb910715SAlp Dener ierr = PCJacobiSetUseAbs(pc,PETSC_TRUE);CHKERRQ(ierr); 121eb910715SAlp Dener break; 122eb910715SAlp Dener 123eb910715SAlp Dener case BNK_PC_BFGS: 124eb910715SAlp Dener ierr = PCSetType(pc, PCSHELL);CHKERRQ(ierr); 125eb910715SAlp Dener ierr = PCSetFromOptions(pc);CHKERRQ(ierr); 126eb910715SAlp Dener ierr = PCShellSetName(pc, "bfgs");CHKERRQ(ierr); 127eb910715SAlp Dener ierr = PCShellSetContext(pc, bnk->M);CHKERRQ(ierr); 128eb910715SAlp Dener ierr = PCShellSetApply(pc, MatLMVMSolveShell);CHKERRQ(ierr); 129eb910715SAlp Dener break; 130eb910715SAlp Dener 131eb910715SAlp Dener default: 132eb910715SAlp Dener /* Use the pc method set by pc_type */ 133eb910715SAlp Dener break; 134eb910715SAlp Dener } 135eb910715SAlp Dener 136eb910715SAlp Dener /* Initialize trust-region radius. The initialization is only performed 137eb910715SAlp Dener when we are using Nash, Steihaug-Toint or the Generalized Lanczos method. */ 138c0f10754SAlp Dener *needH = PETSC_TRUE; 139eb910715SAlp Dener if (bnk->is_nash || bnk->is_stcg || bnk->is_gltr) { 14062675beeSAlp Dener switch(initType) { 141eb910715SAlp Dener case BNK_INIT_CONSTANT: 142eb910715SAlp Dener /* Use the initial radius specified */ 143c0f10754SAlp Dener tao->trust = tao->trust0; 144eb910715SAlp Dener break; 145eb910715SAlp Dener 146eb910715SAlp Dener case BNK_INIT_INTERPOLATION: 147c0f10754SAlp Dener /* Use interpolation based on the initial Hessian */ 148eb910715SAlp Dener max_radius = 0.0; 149eb910715SAlp Dener for (j = 0; j < j_max; ++j) { 1500a4511e9SAlp Dener f_min = bnk->f; 151eb910715SAlp Dener sigma = 0.0; 152eb910715SAlp Dener 153c0f10754SAlp Dener if (*needH) { 15462602cfbSAlp Dener /* Compute the Hessian at the new step, and extract the inactive subsystem */ 155*e031d6f5SAlp Dener ierr = TaoBNKComputeHessian(tao);CHKERRQ(ierr); 156*e031d6f5SAlp Dener ierr = TaoBNKEstimateActiveSet(tao);CHKERRQ(ierr); 15728017e9fSAlp Dener if (bnk->inactive_idx) { 158*e031d6f5SAlp Dener ierr = MatDestroy(&bnk->H_inactive); 1592ab2a32cSAlp Dener ierr = MatCreateSubMatrix(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->H_inactive);CHKERRQ(ierr); 16028017e9fSAlp Dener } else { 161*e031d6f5SAlp Dener ierr = MatDestroy(&bnk->H_inactive); 16262675beeSAlp Dener ierr = MatDuplicate(tao->hessian, MAT_COPY_VALUES, &bnk->H_inactive); 16328017e9fSAlp Dener } 164c0f10754SAlp Dener *needH = PETSC_FALSE; 165eb910715SAlp Dener } 166eb910715SAlp Dener 167eb910715SAlp Dener for (i = 0; i < i_max; ++i) { 16862602cfbSAlp Dener /* Take a steepest descent step and snap it to bounds */ 16962602cfbSAlp Dener ierr = VecCopy(tao->solution, bnk->Xold);CHKERRQ(ierr); 17062602cfbSAlp Dener ierr = VecAXPY(tao->solution, -tao->trust/bnk->gnorm, tao->gradient);CHKERRQ(ierr); 17162602cfbSAlp Dener ierr = VecMedian(tao->XL, tao->solution, tao->XU, tao->solution);CHKERRQ(ierr); 172770b7498SAlp Dener /* Recompute the step after bound snapping so that it can be used in predicted decrease calculation later */ 173eb910715SAlp Dener ierr = VecCopy(tao->solution, bnk->W);CHKERRQ(ierr); 17462602cfbSAlp Dener ierr = VecAXPY(bnk->W, -1.0, bnk->Xold);CHKERRQ(ierr); 17562602cfbSAlp Dener /* Compute the objective at the trial */ 17662602cfbSAlp Dener ierr = TaoComputeObjective(tao, tao->solution, &ftrial);CHKERRQ(ierr); 17762602cfbSAlp Dener ierr = VecCopy(bnk->Xold, tao->solution);CHKERRQ(ierr); 178eb910715SAlp Dener if (PetscIsInfOrNanReal(ftrial)) { 179eb910715SAlp Dener tau = bnk->gamma1_i; 180eb910715SAlp Dener } else { 1810a4511e9SAlp Dener if (ftrial < f_min) { 1820a4511e9SAlp Dener f_min = ftrial; 183eb910715SAlp Dener sigma = -tao->trust / bnk->gnorm; 184eb910715SAlp Dener } 185770b7498SAlp Dener /* Compute the predicted and actual reduction */ 1862ab2a32cSAlp Dener if (bnk->inactive_idx) { 1872ab2a32cSAlp Dener ierr = VecGetSubVector(bnk->W, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 188*e031d6f5SAlp Dener ierr = VecGetSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 1892ab2a32cSAlp Dener } else { 1902ab2a32cSAlp Dener bnk->G_inactive = bnk->unprojected_gradient; 1912ab2a32cSAlp Dener bnk->inactive_work = bnk->W; 1922ab2a32cSAlp Dener } 193*e031d6f5SAlp Dener ierr = MatMult(bnk->H_inactive, bnk->inactive_work, bnk->G_inactive);CHKERRQ(ierr); 1942ab2a32cSAlp Dener ierr = VecDot(bnk->G_inactive, bnk->inactive_work, &prered);CHKERRQ(ierr); 1952ab2a32cSAlp Dener if (bnk->inactive_idx) { 1962ab2a32cSAlp Dener ierr = VecRestoreSubVector(bnk->W, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 197*e031d6f5SAlp Dener ierr = VecRestoreSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 1982ab2a32cSAlp Dener } 199eb910715SAlp Dener prered = tao->trust * (bnk->gnorm - 0.5 * tao->trust * prered / (bnk->gnorm * bnk->gnorm)); 200eb910715SAlp Dener actred = bnk->f - ftrial; 201eb910715SAlp Dener if ((PetscAbsScalar(actred) <= bnk->epsilon) && (PetscAbsScalar(prered) <= bnk->epsilon)) { 202eb910715SAlp Dener kappa = 1.0; 203eb910715SAlp Dener } else { 204eb910715SAlp Dener kappa = actred / prered; 205eb910715SAlp Dener } 206eb910715SAlp Dener 207eb910715SAlp Dener tau_1 = bnk->theta_i * bnk->gnorm * tao->trust / (bnk->theta_i * bnk->gnorm * tao->trust + (1.0 - bnk->theta_i) * prered - actred); 208eb910715SAlp Dener tau_2 = bnk->theta_i * bnk->gnorm * tao->trust / (bnk->theta_i * bnk->gnorm * tao->trust - (1.0 + bnk->theta_i) * prered + actred); 209eb910715SAlp Dener tau_min = PetscMin(tau_1, tau_2); 210eb910715SAlp Dener tau_max = PetscMax(tau_1, tau_2); 211eb910715SAlp Dener 212eb910715SAlp Dener if (PetscAbsScalar(kappa - 1.0) <= bnk->mu1_i) { 213eb910715SAlp Dener /* Great agreement */ 214eb910715SAlp Dener max_radius = PetscMax(max_radius, tao->trust); 215eb910715SAlp Dener 216eb910715SAlp Dener if (tau_max < 1.0) { 217eb910715SAlp Dener tau = bnk->gamma3_i; 218eb910715SAlp Dener } else if (tau_max > bnk->gamma4_i) { 219eb910715SAlp Dener tau = bnk->gamma4_i; 220eb910715SAlp Dener } else if (tau_1 >= 1.0 && tau_1 <= bnk->gamma4_i && tau_2 < 1.0) { 221eb910715SAlp Dener tau = tau_1; 222eb910715SAlp Dener } else if (tau_2 >= 1.0 && tau_2 <= bnk->gamma4_i && tau_1 < 1.0) { 223eb910715SAlp Dener tau = tau_2; 224eb910715SAlp Dener } else { 225eb910715SAlp Dener tau = tau_max; 226eb910715SAlp Dener } 227eb910715SAlp Dener } else if (PetscAbsScalar(kappa - 1.0) <= bnk->mu2_i) { 228eb910715SAlp Dener /* Good agreement */ 229eb910715SAlp Dener max_radius = PetscMax(max_radius, tao->trust); 230eb910715SAlp Dener 231eb910715SAlp Dener if (tau_max < bnk->gamma2_i) { 232eb910715SAlp Dener tau = bnk->gamma2_i; 233eb910715SAlp Dener } else if (tau_max > bnk->gamma3_i) { 234eb910715SAlp Dener tau = bnk->gamma3_i; 235eb910715SAlp Dener } else { 236eb910715SAlp Dener tau = tau_max; 237eb910715SAlp Dener } 238eb910715SAlp Dener } else { 239eb910715SAlp Dener /* Not good agreement */ 240eb910715SAlp Dener if (tau_min > 1.0) { 241eb910715SAlp Dener tau = bnk->gamma2_i; 242eb910715SAlp Dener } else if (tau_max < bnk->gamma1_i) { 243eb910715SAlp Dener tau = bnk->gamma1_i; 244eb910715SAlp Dener } else if ((tau_min < bnk->gamma1_i) && (tau_max >= 1.0)) { 245eb910715SAlp Dener tau = bnk->gamma1_i; 246eb910715SAlp Dener } else if ((tau_1 >= bnk->gamma1_i) && (tau_1 < 1.0) && ((tau_2 < bnk->gamma1_i) || (tau_2 >= 1.0))) { 247eb910715SAlp Dener tau = tau_1; 248eb910715SAlp Dener } else if ((tau_2 >= bnk->gamma1_i) && (tau_2 < 1.0) && ((tau_1 < bnk->gamma1_i) || (tau_2 >= 1.0))) { 249eb910715SAlp Dener tau = tau_2; 250eb910715SAlp Dener } else { 251eb910715SAlp Dener tau = tau_max; 252eb910715SAlp Dener } 253eb910715SAlp Dener } 254eb910715SAlp Dener } 255eb910715SAlp Dener tao->trust = tau * tao->trust; 256eb910715SAlp Dener } 257eb910715SAlp Dener 2580a4511e9SAlp Dener if (f_min < bnk->f) { 259*e031d6f5SAlp Dener /* We found a solution better than the initial, so let's test and accept it */ 2600a4511e9SAlp Dener bnk->f = f_min; 261eb910715SAlp Dener ierr = VecAXPY(tao->solution,sigma,tao->gradient);CHKERRQ(ierr); 26287602d1eSAlp Dener ierr = VecMedian(tao->XL, tao->solution, tao->XU, tao->solution);CHKERRQ(ierr); 26309164190SAlp Dener ierr = TaoComputeGradient(tao,tao->solution,bnk->unprojected_gradient);CHKERRQ(ierr); 26409164190SAlp Dener ierr = VecBoundGradientProjection(bnk->unprojected_gradient,tao->solution,tao->XL,tao->XU,tao->gradient);CHKERRQ(ierr); 265eb910715SAlp Dener 266eb910715SAlp Dener ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&bnk->gnorm);CHKERRQ(ierr); 267eb910715SAlp Dener if (PetscIsInfOrNanReal(bnk->gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute gradient generated Inf or NaN"); 268c0f10754SAlp Dener *needH = PETSC_TRUE; 269eb910715SAlp Dener 270*e031d6f5SAlp Dener ierr = VecFischer(tao->solution, bnk->unprojected_gradient, tao->XL, tao->XU, bnk->Gwork);CHKERRQ(ierr); 271*e031d6f5SAlp Dener ierr = VecNorm(bnk->Gwork, NORM_2, &resnorm);CHKERRQ(ierr); 272*e031d6f5SAlp Dener ierr = TaoLogConvergenceHistory(tao,bnk->f,resnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 273*e031d6f5SAlp Dener ierr = TaoMonitor(tao,tao->niter,bnk->f,resnorm,0.0,1.0);CHKERRQ(ierr); 274eb910715SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 275eb910715SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 276eb910715SAlp Dener } 277eb910715SAlp Dener } 278eb910715SAlp Dener tao->trust = PetscMax(tao->trust, max_radius); 279*e031d6f5SAlp Dener 280*e031d6f5SAlp Dener /* Ensure that the trust radius is within the limits */ 281*e031d6f5SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 282*e031d6f5SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 283eb910715SAlp Dener break; 284eb910715SAlp Dener 285eb910715SAlp Dener default: 286eb910715SAlp Dener /* Norm of the first direction will initialize radius */ 287eb910715SAlp Dener tao->trust = 0.0; 288eb910715SAlp Dener break; 289eb910715SAlp Dener } 290eb910715SAlp Dener } 291*e031d6f5SAlp Dener 292eb910715SAlp Dener /* Set initial scaling for the BFGS preconditioner 293eb910715SAlp Dener This step is done after computing the initial trust-region radius 294eb910715SAlp Dener since the function value may have decreased */ 295eb910715SAlp Dener if (BNK_PC_BFGS == bnk->pc_type) { 2969b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 297eb910715SAlp Dener ierr = MatLMVMSetDelta(bnk->M,delta);CHKERRQ(ierr); 298eb910715SAlp Dener } 299eb910715SAlp Dener PetscFunctionReturn(0); 300eb910715SAlp Dener } 301eb910715SAlp Dener 302df278d8fSAlp Dener /*------------------------------------------------------------*/ 303df278d8fSAlp Dener 30462675beeSAlp Dener /* Routine for computing the Hessian and preparing the preconditioner at the new iterate */ 30562675beeSAlp Dener 30662675beeSAlp Dener PetscErrorCode TaoBNKComputeHessian(Tao tao) 30762675beeSAlp Dener { 30862675beeSAlp Dener PetscErrorCode ierr; 30962675beeSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 31062675beeSAlp Dener 31162675beeSAlp Dener PetscFunctionBegin; 31262675beeSAlp Dener /* Compute the Hessian */ 31362675beeSAlp Dener ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 31462675beeSAlp Dener /* Add a correction to the BFGS preconditioner */ 31562675beeSAlp Dener if (BNK_PC_BFGS == bnk->pc_type) { 31662675beeSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 31762675beeSAlp Dener /* Update the BFGS diagonal scaling */ 31862675beeSAlp Dener if (BFGS_SCALE_AHESS == bnk->bfgs_scale_type) { 31962675beeSAlp Dener ierr = MatGetDiagonal(tao->hessian, bnk->Diag);CHKERRQ(ierr); 32062675beeSAlp Dener ierr = VecAbs(bnk->Diag);CHKERRQ(ierr); 32162675beeSAlp Dener ierr = VecMedian(bnk->Diag_min, bnk->Diag, bnk->Diag_max, bnk->Diag);CHKERRQ(ierr); 32262675beeSAlp Dener ierr = VecReciprocal(bnk->Diag);CHKERRQ(ierr); 32362675beeSAlp Dener ierr = MatLMVMSetScale(bnk->M,bnk->Diag);CHKERRQ(ierr); 32462675beeSAlp Dener } 32562675beeSAlp Dener } 32662675beeSAlp Dener PetscFunctionReturn(0); 32762675beeSAlp Dener } 32862675beeSAlp Dener 32962675beeSAlp Dener /*------------------------------------------------------------*/ 33062675beeSAlp Dener 3312f75a4aaSAlp Dener /* Routine for estimating the active set */ 3322f75a4aaSAlp Dener 3332f75a4aaSAlp Dener PetscErrorCode TaoBNKEstimateActiveSet(Tao tao) 3342f75a4aaSAlp Dener { 3352f75a4aaSAlp Dener PetscErrorCode ierr; 3362f75a4aaSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 3372f75a4aaSAlp Dener 3382f75a4aaSAlp Dener PetscFunctionBegin; 3392f75a4aaSAlp Dener switch (bnk->as_type) { 3402f75a4aaSAlp Dener case BNK_AS_NONE: 3412f75a4aaSAlp Dener ierr = ISDestroy(&bnk->inactive_idx);CHKERRQ(ierr); 3422f75a4aaSAlp Dener ierr = VecWhichInactive(tao->XL, tao->solution, bnk->unprojected_gradient, tao->XU, PETSC_TRUE, &bnk->inactive_idx);CHKERRQ(ierr); 3432f75a4aaSAlp Dener ierr = ISDestroy(&bnk->active_idx);CHKERRQ(ierr); 3442f75a4aaSAlp Dener ierr = ISComplementVec(bnk->inactive_idx, tao->solution, &bnk->active_idx);CHKERRQ(ierr); 3452f75a4aaSAlp Dener break; 3462f75a4aaSAlp Dener 3472f75a4aaSAlp Dener case BNK_AS_BERTSEKAS: 3482f75a4aaSAlp Dener /* Compute the trial step vector with which we will estimate the active set at the next iteration */ 3492f75a4aaSAlp Dener if (BNK_PC_BFGS == bnk->pc_type) { 3502f75a4aaSAlp Dener /* If the BFGS preconditioner matrix is available, we will construct a trial step with it */ 3515e9b73cbSAlp Dener ierr = MatLMVMSetInactive(bnk->M, NULL);CHKERRQ(ierr); 3522f75a4aaSAlp Dener ierr = MatLMVMSolve(bnk->M, bnk->unprojected_gradient, bnk->W);CHKERRQ(ierr); 3532f75a4aaSAlp Dener } else { 3549b6ef848SAlp Dener /* BFGS preconditioner doesn't exist so let's invert the absolute diagonal of the Hessian instead onto the gradient */ 3552f75a4aaSAlp Dener ierr = MatGetDiagonal(tao->hessian, bnk->Xwork);CHKERRQ(ierr); 3569b6ef848SAlp Dener ierr = VecAbs(bnk->Xwork);CHKERRQ(ierr); 3579b6ef848SAlp Dener ierr = VecMedian(bnk->Diag_min, bnk->Xwork, bnk->Diag_max, bnk->Xwork);CHKERRQ(ierr); 3582f75a4aaSAlp Dener ierr = VecReciprocal(bnk->Xwork);CHKERRQ(ierr);CHKERRQ(ierr); 3592f75a4aaSAlp Dener ierr = VecPointwiseMult(bnk->W, bnk->Xwork, bnk->unprojected_gradient);CHKERRQ(ierr); 3602f75a4aaSAlp Dener } 3612f75a4aaSAlp Dener ierr = VecScale(bnk->W, -1.0);CHKERRQ(ierr); 3620a4511e9SAlp Dener ierr = TaoEstimateActiveBounds(tao->solution, tao->XL, tao->XU, bnk->unprojected_gradient, bnk->W, bnk->as_step, &bnk->as_tol, &bnk->active_lower, &bnk->active_upper, &bnk->active_fixed, &bnk->active_idx, &bnk->inactive_idx);CHKERRQ(ierr); 3632f75a4aaSAlp Dener 3642f75a4aaSAlp Dener default: 3652f75a4aaSAlp Dener break; 3662f75a4aaSAlp Dener } 3672f75a4aaSAlp Dener PetscFunctionReturn(0); 3682f75a4aaSAlp Dener } 3692f75a4aaSAlp Dener 3702f75a4aaSAlp Dener /*------------------------------------------------------------*/ 3712f75a4aaSAlp Dener 3722f75a4aaSAlp Dener /* Routine for bounding the step direction */ 3732f75a4aaSAlp Dener 3742f75a4aaSAlp Dener PetscErrorCode TaoBNKBoundStep(Tao tao, Vec step) 3752f75a4aaSAlp Dener { 3762f75a4aaSAlp Dener PetscErrorCode ierr; 3772f75a4aaSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 3782f75a4aaSAlp Dener 3792f75a4aaSAlp Dener PetscFunctionBegin; 38028017e9fSAlp Dener if (bnk->active_idx) { 3812f75a4aaSAlp Dener switch (bnk->as_type) { 3822f75a4aaSAlp Dener case BNK_AS_NONE: 3832f75a4aaSAlp Dener if (bnk->active_idx) { 3842f75a4aaSAlp Dener ierr = VecGetSubVector(step, bnk->active_idx, &bnk->active_work);CHKERRQ(ierr); 3852f75a4aaSAlp Dener ierr = VecSet(bnk->active_work, 0.0);CHKERRQ(ierr); 3862f75a4aaSAlp Dener ierr = VecRestoreSubVector(step, bnk->active_idx, &bnk->active_work);CHKERRQ(ierr); 3872f75a4aaSAlp Dener } 3882f75a4aaSAlp Dener break; 3892f75a4aaSAlp Dener 3902f75a4aaSAlp Dener case BNK_AS_BERTSEKAS: 3912f75a4aaSAlp Dener ierr = TaoBoundStep(tao->solution, tao->XL, tao->XU, bnk->active_lower, bnk->active_upper, bnk->active_fixed, step);CHKERRQ(ierr); 3922f75a4aaSAlp Dener break; 3932f75a4aaSAlp Dener 3942f75a4aaSAlp Dener default: 3952f75a4aaSAlp Dener break; 3962f75a4aaSAlp Dener } 397e465cd6fSAlp Dener } 3982f75a4aaSAlp Dener PetscFunctionReturn(0); 3992f75a4aaSAlp Dener } 4002f75a4aaSAlp Dener 401*e031d6f5SAlp Dener /*------------------------------------------------------------*/ 402*e031d6f5SAlp Dener 403*e031d6f5SAlp Dener /* Routine for taking a finite number of BNCG iterations to 404*e031d6f5SAlp Dener accelerate Newton convergence. 405*e031d6f5SAlp Dener 406*e031d6f5SAlp Dener In practice, this approach simply trades off Hessian evaluations 407*e031d6f5SAlp Dener for more gradient evaluations. 408*e031d6f5SAlp Dener */ 409*e031d6f5SAlp Dener 410c0f10754SAlp Dener PetscErrorCode TaoBNKTakeCGSteps(Tao tao, PetscBool *terminate) 411c0f10754SAlp Dener { 412c0f10754SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 413c0f10754SAlp Dener PetscErrorCode ierr; 414c0f10754SAlp Dener 415c0f10754SAlp Dener PetscFunctionBegin; 416c0f10754SAlp Dener *terminate = PETSC_FALSE; 417c0f10754SAlp Dener if (bnk->max_cg_its > 0) { 418c0f10754SAlp Dener /* Copy the current solution, unprojected gradient and step info into BNCG */ 419c0f10754SAlp Dener ierr = VecCopy(tao->solution, bnk->bncg->solution);CHKERRQ(ierr); 420c0f10754SAlp Dener if (tao->niter > 1) { 421c0f10754SAlp Dener bnk->bncg_ctx->f = bnk->f; 422c0f10754SAlp Dener ierr = VecCopy(bnk->unprojected_gradient, bnk->bncg_ctx->unprojected_gradient);CHKERRQ(ierr); 423c0f10754SAlp Dener ierr = VecCopy(tao->stepdirection, bnk->bncg->stepdirection);CHKERRQ(ierr); 424c0f10754SAlp Dener ierr = TaoBNCGSetRecycleFlag(bnk->bncg, PETSC_TRUE);CHKERRQ(ierr); 425c0f10754SAlp Dener } 426c0f10754SAlp Dener /* Take some small finite number of BNCG iterations */ 427c0f10754SAlp Dener ierr = TaoSolve(bnk->bncg);CHKERRQ(ierr); 428c0f10754SAlp Dener /* Add the number of gradient and function evaluations to the total */ 429c0f10754SAlp Dener tao->nfuncs += bnk->bncg->nfuncs; 430c0f10754SAlp Dener tao->nfuncgrads += bnk->bncg->nfuncgrads; 431c0f10754SAlp Dener tao->ngrads += bnk->bncg->ngrads; 432c0f10754SAlp Dener tao->nhess += bnk->bncg->nhess; 433*e031d6f5SAlp Dener bnk->tot_cg_its += bnk->bncg->niter; 434c0f10754SAlp Dener /* Extract the BNCG solution out and save it into BNK */ 435c0f10754SAlp Dener bnk->f = bnk->bncg_ctx->f; 436c0f10754SAlp Dener ierr = VecCopy(bnk->bncg->solution, tao->solution); 437c0f10754SAlp Dener ierr = VecCopy(bnk->bncg_ctx->unprojected_gradient, bnk->unprojected_gradient); 438c0f10754SAlp Dener ierr = VecCopy(bnk->bncg->gradient, tao->gradient); 439c0f10754SAlp Dener /* Check to see if BNCG converged the problem */ 440c0f10754SAlp 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) { 441c0f10754SAlp Dener *terminate = PETSC_TRUE; 442c0f10754SAlp Dener } 443c0f10754SAlp Dener } 444c0f10754SAlp Dener PetscFunctionReturn(0); 445c0f10754SAlp Dener } 446c0f10754SAlp Dener 4472f75a4aaSAlp Dener /*------------------------------------------------------------*/ 4482f75a4aaSAlp Dener 449c0f10754SAlp Dener /* Routine for computing the Newton step. */ 450df278d8fSAlp Dener 45162675beeSAlp Dener PetscErrorCode TaoBNKComputeStep(Tao tao, PetscBool shift, KSPConvergedReason *ksp_reason) 452eb910715SAlp Dener { 453eb910715SAlp Dener PetscErrorCode ierr; 454eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 455eb910715SAlp Dener 456e465cd6fSAlp Dener PetscReal delta; 457eb910715SAlp Dener PetscInt bfgsUpdates = 0; 458eb910715SAlp Dener PetscInt kspits; 459eb910715SAlp Dener 460eb910715SAlp Dener PetscFunctionBegin; 4615e9b73cbSAlp Dener /* Prepare the reduced sub-matrices for the inactive set */ 4622f75a4aaSAlp Dener if (BNK_PC_BFGS == bnk->pc_type) { ierr = MatLMVMSetInactive(bnk->M, bnk->inactive_idx);CHKERRQ(ierr); } 4632f75a4aaSAlp Dener if (bnk->inactive_idx) { 4645e9b73cbSAlp Dener ierr = MatDestroy(&bnk->H_inactive); 4655e9b73cbSAlp Dener ierr = MatCreateSubMatrix(tao->hessian, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->H_inactive);CHKERRQ(ierr); 466eb3ba6a7SAlp Dener if (tao->hessian == tao->hessian_pre) { 467eb3ba6a7SAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 468eb3ba6a7SAlp Dener } else { 4695e9b73cbSAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive); 4705e9b73cbSAlp Dener ierr = MatCreateSubMatrix(tao->hessian_pre, bnk->inactive_idx, bnk->inactive_idx, MAT_INITIAL_MATRIX, &bnk->Hpre_inactive);CHKERRQ(ierr); 471eb3ba6a7SAlp Dener } 4722f75a4aaSAlp Dener } else { 47362675beeSAlp Dener ierr = MatDestroy(&bnk->H_inactive); 47462675beeSAlp Dener ierr = MatDuplicate(tao->hessian, MAT_COPY_VALUES, &bnk->H_inactive); 47562675beeSAlp Dener if (tao->hessian == tao->hessian_pre) { 47662675beeSAlp Dener bnk->Hpre_inactive = bnk->H_inactive; 47762675beeSAlp Dener } else { 47862675beeSAlp Dener ierr = MatDestroy(&bnk->Hpre_inactive); 47962675beeSAlp Dener ierr = MatDuplicate(tao->hessian_pre, MAT_COPY_VALUES, &bnk->Hpre_inactive); 48062675beeSAlp Dener } 48162675beeSAlp Dener } 48262675beeSAlp Dener 48362675beeSAlp Dener /* Shift the reduced Hessian matrix */ 48462675beeSAlp Dener if ((shift) && (bnk->pert > 0)) { 48562675beeSAlp Dener ierr = MatShift(bnk->H_inactive, bnk->pert);CHKERRQ(ierr); 48662675beeSAlp Dener if (bnk->H_inactive != bnk->Hpre_inactive) { 48762675beeSAlp Dener ierr = MatShift(bnk->Hpre_inactive, bnk->pert);CHKERRQ(ierr); 48862675beeSAlp Dener } 48962675beeSAlp Dener } 49062675beeSAlp Dener 49162675beeSAlp Dener /* Update the diagonal scaling for the BFGS preconditioner, this time with the Hessian perturbation */ 49262675beeSAlp Dener if ((BNK_PC_BFGS == bnk->pc_type) && (BFGS_SCALE_PHESS == bnk->bfgs_scale_type)) { 49362675beeSAlp Dener /* Obtain diagonal for the bfgs preconditioner */ 4945e9b73cbSAlp Dener ierr = VecSet(bnk->Diag, 1.0);CHKERRQ(ierr); 4955e9b73cbSAlp Dener if (bnk->inactive_idx) { 4965e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Diag, bnk->inactive_idx, &bnk->Diag_red);CHKERRQ(ierr); 4975e9b73cbSAlp Dener } else { 4985e9b73cbSAlp Dener bnk->Diag_red = bnk->Diag; 4995e9b73cbSAlp Dener } 5005e9b73cbSAlp Dener ierr = MatGetDiagonal(bnk->H_inactive, bnk->Diag_red);CHKERRQ(ierr); 5015e9b73cbSAlp Dener if (bnk->inactive_idx) { 5025e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Diag, bnk->inactive_idx, &bnk->Diag_red);CHKERRQ(ierr); 5035e9b73cbSAlp Dener } 50462675beeSAlp Dener ierr = VecAbs(bnk->Diag);CHKERRQ(ierr); 50562675beeSAlp Dener ierr = VecMedian(bnk->Diag_min, bnk->Diag, bnk->Diag_max, bnk->Diag);CHKERRQ(ierr); 50662675beeSAlp Dener ierr = VecReciprocal(bnk->Diag);CHKERRQ(ierr); 50762675beeSAlp Dener ierr = MatLMVMSetScale(bnk->M,bnk->Diag);CHKERRQ(ierr); 5082f75a4aaSAlp Dener } 50909164190SAlp Dener 510eb910715SAlp Dener /* Solve the Newton system of equations */ 5112f75a4aaSAlp Dener ierr = VecSet(tao->stepdirection, 0.0);CHKERRQ(ierr); 5125e9b73cbSAlp Dener ierr = KSPReset(tao->ksp);CHKERRQ(ierr); 51309164190SAlp Dener ierr = KSPSetOperators(tao->ksp,bnk->H_inactive,bnk->Hpre_inactive);CHKERRQ(ierr); 5145e9b73cbSAlp Dener ierr = VecCopy(bnk->unprojected_gradient, bnk->Gwork);CHKERRQ(ierr); 5155e9b73cbSAlp Dener if (bnk->inactive_idx) { 5165e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5175e9b73cbSAlp Dener ierr = VecGetSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5185e9b73cbSAlp Dener } else { 5195e9b73cbSAlp Dener bnk->G_inactive = bnk->unprojected_gradient; 5205e9b73cbSAlp Dener bnk->X_inactive = tao->stepdirection; 52128017e9fSAlp Dener } 522eb910715SAlp Dener if (bnk->is_nash || bnk->is_stcg || bnk->is_gltr) { 523fed79b8eSAlp Dener ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 5245e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 525eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 526eb910715SAlp Dener tao->ksp_its+=kspits; 527eb910715SAlp Dener tao->ksp_tot_its+=kspits; 528080d2917SAlp Dener ierr = KSPCGGetNormD(tao->ksp,&bnk->dnorm);CHKERRQ(ierr); 529eb910715SAlp Dener 530eb910715SAlp Dener if (0.0 == tao->trust) { 531eb910715SAlp Dener /* Radius was uninitialized; use the norm of the direction */ 532080d2917SAlp Dener if (bnk->dnorm > 0.0) { 533080d2917SAlp Dener tao->trust = bnk->dnorm; 534eb910715SAlp Dener 535eb910715SAlp Dener /* Modify the radius if it is too large or small */ 536eb910715SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 537eb910715SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 538eb910715SAlp Dener } else { 539eb910715SAlp Dener /* The direction was bad; set radius to default value and re-solve 540eb910715SAlp Dener the trust-region subproblem to get a direction */ 541eb910715SAlp Dener tao->trust = tao->trust0; 542eb910715SAlp Dener 543eb910715SAlp Dener /* Modify the radius if it is too large or small */ 544eb910715SAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 545eb910715SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 546eb910715SAlp Dener 547fed79b8eSAlp Dener ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 5485e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 549eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 550eb910715SAlp Dener tao->ksp_its+=kspits; 551eb910715SAlp Dener tao->ksp_tot_its+=kspits; 552080d2917SAlp Dener ierr = KSPCGGetNormD(tao->ksp,&bnk->dnorm);CHKERRQ(ierr); 553eb910715SAlp Dener 554080d2917SAlp Dener if (bnk->dnorm == 0.0) SETERRQ(PETSC_COMM_SELF,1, "Initial direction zero"); 555eb910715SAlp Dener } 556eb910715SAlp Dener } 557eb910715SAlp Dener } else { 5585e9b73cbSAlp Dener ierr = KSPSolve(tao->ksp, bnk->G_inactive, bnk->X_inactive);CHKERRQ(ierr); 559eb910715SAlp Dener ierr = KSPGetIterationNumber(tao->ksp, &kspits);CHKERRQ(ierr); 560eb910715SAlp Dener tao->ksp_its += kspits; 561eb910715SAlp Dener tao->ksp_tot_its+=kspits; 562eb910715SAlp Dener } 5635e9b73cbSAlp Dener /* Restore sub vectors back */ 5645e9b73cbSAlp Dener if (bnk->inactive_idx) { 5655e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 5665e9b73cbSAlp Dener ierr = VecRestoreSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 5675e9b73cbSAlp Dener } 568770b7498SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 569fed79b8eSAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 5702f75a4aaSAlp Dener ierr = TaoBNKBoundStep(tao, tao->stepdirection);CHKERRQ(ierr); 571770b7498SAlp Dener 572770b7498SAlp Dener /* Record convergence reasons */ 573e465cd6fSAlp Dener ierr = KSPGetConvergedReason(tao->ksp, ksp_reason);CHKERRQ(ierr); 574e465cd6fSAlp Dener if (KSP_CONVERGED_ATOL == *ksp_reason) { 575770b7498SAlp Dener ++bnk->ksp_atol; 576e465cd6fSAlp Dener } else if (KSP_CONVERGED_RTOL == *ksp_reason) { 577770b7498SAlp Dener ++bnk->ksp_rtol; 578e465cd6fSAlp Dener } else if (KSP_CONVERGED_CG_CONSTRAINED == *ksp_reason) { 579770b7498SAlp Dener ++bnk->ksp_ctol; 580e465cd6fSAlp Dener } else if (KSP_CONVERGED_CG_NEG_CURVE == *ksp_reason) { 581770b7498SAlp Dener ++bnk->ksp_negc; 582e465cd6fSAlp Dener } else if (KSP_DIVERGED_DTOL == *ksp_reason) { 583770b7498SAlp Dener ++bnk->ksp_dtol; 584e465cd6fSAlp Dener } else if (KSP_DIVERGED_ITS == *ksp_reason) { 585770b7498SAlp Dener ++bnk->ksp_iter; 586770b7498SAlp Dener } else { 587770b7498SAlp Dener ++bnk->ksp_othr; 588770b7498SAlp Dener } 589fed79b8eSAlp Dener 590fed79b8eSAlp Dener /* Make sure the BFGS preconditioner is healthy */ 591fed79b8eSAlp Dener if (bnk->pc_type == BNK_PC_BFGS) { 592fed79b8eSAlp Dener ierr = MatLMVMGetUpdates(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 593e465cd6fSAlp Dener if ((KSP_DIVERGED_INDEFINITE_PC == *ksp_reason) && (bfgsUpdates > 1)) { 594fed79b8eSAlp Dener /* Preconditioner is numerically indefinite; reset the approximation. */ 5959b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 596eb910715SAlp Dener ierr = MatLMVMSetDelta(bnk->M,delta);CHKERRQ(ierr); 597eb910715SAlp Dener ierr = MatLMVMReset(bnk->M);CHKERRQ(ierr); 59809164190SAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 599eb910715SAlp Dener } 600fed79b8eSAlp Dener } 601e465cd6fSAlp Dener PetscFunctionReturn(0); 602e465cd6fSAlp Dener } 603eb910715SAlp Dener 60462675beeSAlp Dener /*------------------------------------------------------------*/ 60562675beeSAlp Dener 6065e9b73cbSAlp Dener /* Routine for recomputing the predicted reduction for a given step vector */ 6075e9b73cbSAlp Dener 6085e9b73cbSAlp Dener PetscErrorCode TaoBNKRecomputePred(Tao tao, Vec S, PetscReal *prered) 6095e9b73cbSAlp Dener { 6105e9b73cbSAlp Dener PetscErrorCode ierr; 6115e9b73cbSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 6125e9b73cbSAlp Dener 6135e9b73cbSAlp Dener PetscFunctionBegin; 6145e9b73cbSAlp Dener /* Extract subvectors associated with the inactive set */ 6155e9b73cbSAlp Dener if (bnk->inactive_idx){ 6165e9b73cbSAlp Dener ierr = VecGetSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 6175e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 6185e9b73cbSAlp Dener ierr = VecGetSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 6195e9b73cbSAlp Dener } else { 6205e9b73cbSAlp Dener bnk->X_inactive = tao->stepdirection; 6215e9b73cbSAlp Dener bnk->inactive_work = bnk->Xwork; 6225e9b73cbSAlp Dener bnk->G_inactive = bnk->Gwork; 6235e9b73cbSAlp Dener } 6245e9b73cbSAlp Dener /* Recompute the predicted decrease based on the quadratic model */ 6255e9b73cbSAlp Dener ierr = MatMult(bnk->H_inactive, bnk->X_inactive, bnk->inactive_work);CHKERRQ(ierr); 6265e9b73cbSAlp Dener ierr = VecAYPX(bnk->inactive_work, -0.5, bnk->G_inactive);CHKERRQ(ierr); 6275e9b73cbSAlp Dener ierr = VecDot(bnk->inactive_work, bnk->X_inactive, prered); 6285e9b73cbSAlp Dener /* Restore the sub vectors */ 6295e9b73cbSAlp Dener if (bnk->inactive_idx){ 6305e9b73cbSAlp Dener ierr = VecRestoreSubVector(tao->stepdirection, bnk->inactive_idx, &bnk->X_inactive);CHKERRQ(ierr); 6315e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Xwork, bnk->inactive_idx, &bnk->inactive_work);CHKERRQ(ierr); 6325e9b73cbSAlp Dener ierr = VecRestoreSubVector(bnk->Gwork, bnk->inactive_idx, &bnk->G_inactive);CHKERRQ(ierr); 6335e9b73cbSAlp Dener } 6345e9b73cbSAlp Dener PetscFunctionReturn(0); 6355e9b73cbSAlp Dener } 6365e9b73cbSAlp Dener 6375e9b73cbSAlp Dener /*------------------------------------------------------------*/ 6385e9b73cbSAlp Dener 63962675beeSAlp Dener /* Routine for ensuring that the Newton step is a descent direction. 64062675beeSAlp Dener 64162675beeSAlp Dener The step direction falls back onto BFGS, scaled gradient and gradient steps 64262675beeSAlp Dener in the event that the Newton step fails the test. 64362675beeSAlp Dener */ 64462675beeSAlp Dener 645e465cd6fSAlp Dener PetscErrorCode TaoBNKSafeguardStep(Tao tao, KSPConvergedReason ksp_reason, PetscInt *stepType) 646e465cd6fSAlp Dener { 647e465cd6fSAlp Dener PetscErrorCode ierr; 648e465cd6fSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 649e465cd6fSAlp Dener 650e465cd6fSAlp Dener PetscReal gdx, delta, e_min; 651e465cd6fSAlp Dener PetscInt bfgsUpdates; 652e465cd6fSAlp Dener 653e465cd6fSAlp Dener PetscFunctionBegin; 654080d2917SAlp Dener ierr = VecDot(tao->stepdirection, tao->gradient, &gdx);CHKERRQ(ierr); 655eb910715SAlp Dener if ((gdx >= 0.0) || PetscIsInfOrNanReal(gdx)) { 656eb910715SAlp Dener /* Newton step is not descent or direction produced Inf or NaN 657eb910715SAlp Dener Update the perturbation for next time */ 658eb910715SAlp Dener if (bnk->pert <= 0.0) { 659eb910715SAlp Dener /* Initialize the perturbation */ 660eb910715SAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 661eb910715SAlp Dener if (bnk->is_gltr) { 662eb910715SAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 663eb910715SAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 664eb910715SAlp Dener } 665eb910715SAlp Dener } else { 666eb910715SAlp Dener /* Increase the perturbation */ 667eb910715SAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 668eb910715SAlp Dener } 669eb910715SAlp Dener 670eb910715SAlp Dener if (BNK_PC_BFGS != bnk->pc_type) { 671eb910715SAlp Dener /* We don't have the bfgs matrix around and updated 672eb910715SAlp Dener Must use gradient direction in this case */ 673080d2917SAlp Dener ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr); 674eb910715SAlp Dener *stepType = BNK_GRADIENT; 675eb910715SAlp Dener } else { 676eb910715SAlp Dener /* Attempt to use the BFGS direction */ 6772ab2a32cSAlp Dener ierr = MatLMVMSetInactive(bnk->M, NULL);CHKERRQ(ierr); 67809164190SAlp Dener ierr = MatLMVMSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 679eb910715SAlp Dener 6808d5ead36SAlp Dener /* Check for success (descent direction) 6818d5ead36SAlp Dener NOTE: Negative gdx here means not a descent direction because 6828d5ead36SAlp Dener the fall-back step is missing a negative sign. */ 683080d2917SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 6848d5ead36SAlp Dener if ((gdx <= 0) || PetscIsInfOrNanReal(gdx)) { 685eb910715SAlp Dener /* BFGS direction is not descent or direction produced not a number 686eb910715SAlp Dener We can assert bfgsUpdates > 1 in this case because 687eb910715SAlp Dener the first solve produces the scaled gradient direction, 688eb910715SAlp Dener which is guaranteed to be descent */ 689eb910715SAlp Dener 690eb910715SAlp Dener /* Use steepest descent direction (scaled) */ 6919b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 692eb910715SAlp Dener ierr = MatLMVMSetDelta(bnk->M, delta);CHKERRQ(ierr); 693eb910715SAlp Dener ierr = MatLMVMReset(bnk->M);CHKERRQ(ierr); 69409164190SAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 69509164190SAlp Dener ierr = MatLMVMSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 696eb910715SAlp Dener 697eb910715SAlp Dener *stepType = BNK_SCALED_GRADIENT; 698eb910715SAlp Dener } else { 699770b7498SAlp Dener ierr = MatLMVMGetUpdates(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 700eb910715SAlp Dener if (1 == bfgsUpdates) { 701eb910715SAlp Dener /* The first BFGS direction is always the scaled gradient */ 702eb910715SAlp Dener *stepType = BNK_SCALED_GRADIENT; 703eb910715SAlp Dener } else { 704eb910715SAlp Dener *stepType = BNK_BFGS; 705eb910715SAlp Dener } 706eb910715SAlp Dener } 707eb910715SAlp Dener } 7088d5ead36SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 7098d5ead36SAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 7102f75a4aaSAlp Dener ierr = TaoBNKBoundStep(tao, tao->stepdirection);CHKERRQ(ierr); 711eb910715SAlp Dener } else { 712eb910715SAlp Dener /* Computed Newton step is descent */ 713eb910715SAlp Dener switch (ksp_reason) { 714eb910715SAlp Dener case KSP_DIVERGED_NANORINF: 715eb910715SAlp Dener case KSP_DIVERGED_BREAKDOWN: 716eb910715SAlp Dener case KSP_DIVERGED_INDEFINITE_MAT: 717eb910715SAlp Dener case KSP_DIVERGED_INDEFINITE_PC: 718eb910715SAlp Dener case KSP_CONVERGED_CG_NEG_CURVE: 719eb910715SAlp Dener /* Matrix or preconditioner is indefinite; increase perturbation */ 720eb910715SAlp Dener if (bnk->pert <= 0.0) { 721eb910715SAlp Dener /* Initialize the perturbation */ 722eb910715SAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 723eb910715SAlp Dener if (bnk->is_gltr) { 724eb910715SAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp, &e_min);CHKERRQ(ierr); 725eb910715SAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 726eb910715SAlp Dener } 727eb910715SAlp Dener } else { 728eb910715SAlp Dener /* Increase the perturbation */ 729eb910715SAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 730eb910715SAlp Dener } 731eb910715SAlp Dener break; 732eb910715SAlp Dener 733eb910715SAlp Dener default: 734eb910715SAlp Dener /* Newton step computation is good; decrease perturbation */ 735eb910715SAlp Dener bnk->pert = PetscMin(bnk->psfac * bnk->pert, bnk->pmsfac * bnk->gnorm); 736eb910715SAlp Dener if (bnk->pert < bnk->pmin) { 737eb910715SAlp Dener bnk->pert = 0.0; 738eb910715SAlp Dener } 739eb910715SAlp Dener break; 740eb910715SAlp Dener } 741fed79b8eSAlp Dener *stepType = BNK_NEWTON; 742eb910715SAlp Dener } 743eb910715SAlp Dener PetscFunctionReturn(0); 744eb910715SAlp Dener } 745eb910715SAlp Dener 746df278d8fSAlp Dener /*------------------------------------------------------------*/ 747df278d8fSAlp Dener 748df278d8fSAlp Dener /* Routine for performing a bound-projected More-Thuente line search. 749df278d8fSAlp Dener 750df278d8fSAlp Dener Includes fallbacks to BFGS, scaled gradient, and unscaled gradient steps if the 751df278d8fSAlp Dener Newton step does not produce a valid step length. 752df278d8fSAlp Dener */ 753df278d8fSAlp Dener 754c14b763aSAlp Dener PetscErrorCode TaoBNKPerformLineSearch(Tao tao, PetscInt stepType, PetscReal *steplen, TaoLineSearchConvergedReason *reason) 755c14b763aSAlp Dener { 756c14b763aSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 757c14b763aSAlp Dener PetscErrorCode ierr; 758c14b763aSAlp Dener TaoLineSearchConvergedReason ls_reason; 759c14b763aSAlp Dener 760c14b763aSAlp Dener PetscReal e_min, gdx, delta; 761c14b763aSAlp Dener PetscInt bfgsUpdates; 762c14b763aSAlp Dener 763c14b763aSAlp Dener PetscFunctionBegin; 764c14b763aSAlp Dener /* Perform the linesearch */ 765c14b763aSAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &bnk->f, bnk->unprojected_gradient, tao->stepdirection, steplen, &ls_reason);CHKERRQ(ierr); 766c14b763aSAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 767c14b763aSAlp Dener 7689b6ef848SAlp Dener while (ls_reason != TAOLINESEARCH_SUCCESS && ls_reason != TAOLINESEARCH_SUCCESS_USER && (stepType != BNK_GRADIENT || stepType !=BNK_SCALED_GRADIENT)) { 769c14b763aSAlp Dener /* Linesearch failed, revert solution */ 770c14b763aSAlp Dener bnk->f = bnk->fold; 771c14b763aSAlp Dener ierr = VecCopy(bnk->Xold, tao->solution);CHKERRQ(ierr); 772c14b763aSAlp Dener ierr = VecCopy(bnk->unprojected_gradient_old, bnk->unprojected_gradient);CHKERRQ(ierr); 773c14b763aSAlp Dener 774c14b763aSAlp Dener switch(stepType) { 775c14b763aSAlp Dener case BNK_NEWTON: 7768d5ead36SAlp Dener /* Failed to obtain acceptable iterate with Newton step 777c14b763aSAlp Dener Update the perturbation for next time */ 778c14b763aSAlp Dener if (bnk->pert <= 0.0) { 779c14b763aSAlp Dener /* Initialize the perturbation */ 780c14b763aSAlp Dener bnk->pert = PetscMin(bnk->imax, PetscMax(bnk->imin, bnk->imfac * bnk->gnorm)); 781c14b763aSAlp Dener if (bnk->is_gltr) { 782c14b763aSAlp Dener ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 783c14b763aSAlp Dener bnk->pert = PetscMax(bnk->pert, -e_min); 784c14b763aSAlp Dener } 785c14b763aSAlp Dener } else { 786c14b763aSAlp Dener /* Increase the perturbation */ 787c14b763aSAlp Dener bnk->pert = PetscMin(bnk->pmax, PetscMax(bnk->pgfac * bnk->pert, bnk->pmgfac * bnk->gnorm)); 788c14b763aSAlp Dener } 789c14b763aSAlp Dener 790c14b763aSAlp Dener if (BNK_PC_BFGS != bnk->pc_type) { 791c14b763aSAlp Dener /* We don't have the bfgs matrix around and being updated 792c14b763aSAlp Dener Must use gradient direction in this case */ 793c14b763aSAlp Dener ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr); 794c14b763aSAlp Dener stepType = BNK_GRADIENT; 795c14b763aSAlp Dener } else { 796c14b763aSAlp Dener /* Attempt to use the BFGS direction */ 797c14b763aSAlp Dener ierr = MatLMVMSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 7988d5ead36SAlp Dener /* Check for success (descent direction) 7998d5ead36SAlp Dener NOTE: Negative gdx means not a descent direction because the step here is missing a negative sign. */ 800c14b763aSAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 801c14b763aSAlp Dener if ((gdx <= 0) || PetscIsInfOrNanReal(gdx)) { 802c14b763aSAlp Dener /* BFGS direction is not descent or direction produced not a number 803c14b763aSAlp Dener We can assert bfgsUpdates > 1 in this case 804c14b763aSAlp Dener Use steepest descent direction (scaled) */ 8059b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 806c14b763aSAlp Dener ierr = MatLMVMSetDelta(bnk->M, delta);CHKERRQ(ierr); 807c14b763aSAlp Dener ierr = MatLMVMReset(bnk->M);CHKERRQ(ierr); 808c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 809c14b763aSAlp Dener ierr = MatLMVMSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 810c14b763aSAlp Dener 811c14b763aSAlp Dener bfgsUpdates = 1; 812c14b763aSAlp Dener stepType = BNK_SCALED_GRADIENT; 813c14b763aSAlp Dener } else { 814c14b763aSAlp Dener ierr = MatLMVMGetUpdates(bnk->M, &bfgsUpdates);CHKERRQ(ierr); 815c14b763aSAlp Dener if (1 == bfgsUpdates) { 816c14b763aSAlp Dener /* The first BFGS direction is always the scaled gradient */ 817c14b763aSAlp Dener stepType = BNK_SCALED_GRADIENT; 818c14b763aSAlp Dener } else { 819c14b763aSAlp Dener stepType = BNK_BFGS; 820c14b763aSAlp Dener } 821c14b763aSAlp Dener } 822c14b763aSAlp Dener } 823c14b763aSAlp Dener break; 824c14b763aSAlp Dener 825c14b763aSAlp Dener case BNK_BFGS: 826c14b763aSAlp Dener /* Can only enter if pc_type == BNK_PC_BFGS 827c14b763aSAlp Dener Failed to obtain acceptable iterate with BFGS step 828c14b763aSAlp Dener Attempt to use the scaled gradient direction */ 8299b6ef848SAlp Dener delta = 2.0 * PetscMax(1.0, PetscAbsScalar(bnk->f)) / (bnk->gnorm*bnk->gnorm); 830c14b763aSAlp Dener ierr = MatLMVMSetDelta(bnk->M, delta);CHKERRQ(ierr); 831c14b763aSAlp Dener ierr = MatLMVMReset(bnk->M);CHKERRQ(ierr); 832c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 833c14b763aSAlp Dener ierr = MatLMVMSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 834c14b763aSAlp Dener 835c14b763aSAlp Dener bfgsUpdates = 1; 836c14b763aSAlp Dener stepType = BNK_SCALED_GRADIENT; 837c14b763aSAlp Dener break; 838c14b763aSAlp Dener 839c14b763aSAlp Dener case BNK_SCALED_GRADIENT: 840c14b763aSAlp Dener /* Can only enter if pc_type == BNK_PC_BFGS 841c14b763aSAlp Dener The scaled gradient step did not produce a new iterate; 842c14b763aSAlp Dener attemp to use the gradient direction. 843c14b763aSAlp Dener Need to make sure we are not using a different diagonal scaling */ 844c14b763aSAlp Dener ierr = MatLMVMSetScale(bnk->M,0);CHKERRQ(ierr); 845c14b763aSAlp Dener ierr = MatLMVMSetDelta(bnk->M,1.0);CHKERRQ(ierr); 846c14b763aSAlp Dener ierr = MatLMVMReset(bnk->M);CHKERRQ(ierr); 847c14b763aSAlp Dener ierr = MatLMVMUpdate(bnk->M, tao->solution, bnk->unprojected_gradient);CHKERRQ(ierr); 848c14b763aSAlp Dener ierr = MatLMVMSolve(bnk->M, bnk->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); 849c14b763aSAlp Dener 850c14b763aSAlp Dener bfgsUpdates = 1; 851c14b763aSAlp Dener stepType = BNK_GRADIENT; 852c14b763aSAlp Dener break; 853c14b763aSAlp Dener } 8548d5ead36SAlp Dener /* Make sure the safeguarded fall-back step is zero for actively bounded variables */ 8558d5ead36SAlp Dener ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 8562f75a4aaSAlp Dener ierr = TaoBNKBoundStep(tao, tao->stepdirection);CHKERRQ(ierr); 857c14b763aSAlp Dener 8588d5ead36SAlp Dener /* Perform one last line search with the fall-back step */ 859c14b763aSAlp Dener ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &bnk->f, bnk->unprojected_gradient, tao->stepdirection, steplen, &ls_reason);CHKERRQ(ierr); 860c14b763aSAlp Dener ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 861c14b763aSAlp Dener } 862c14b763aSAlp Dener *reason = ls_reason; 863c14b763aSAlp Dener PetscFunctionReturn(0); 864c14b763aSAlp Dener } 865c14b763aSAlp Dener 866df278d8fSAlp Dener /*------------------------------------------------------------*/ 867df278d8fSAlp Dener 868df278d8fSAlp Dener /* Routine for updating the trust radius. 869df278d8fSAlp Dener 870df278d8fSAlp Dener Function features three different update methods: 871df278d8fSAlp Dener 1) Line-search step length based 872df278d8fSAlp Dener 2) Predicted decrease on the CG quadratic model 873df278d8fSAlp Dener 3) Interpolation 874df278d8fSAlp Dener */ 875df278d8fSAlp Dener 87628017e9fSAlp Dener PetscErrorCode TaoBNKUpdateTrustRadius(Tao tao, PetscReal prered, PetscReal actred, PetscInt updateType, PetscInt stepType, PetscBool *accept) 877080d2917SAlp Dener { 878080d2917SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 879080d2917SAlp Dener PetscErrorCode ierr; 880080d2917SAlp Dener 881b1c2d0e3SAlp Dener PetscReal step, kappa; 882080d2917SAlp Dener PetscReal gdx, tau_1, tau_2, tau_min, tau_max; 883080d2917SAlp Dener 884080d2917SAlp Dener PetscFunctionBegin; 885080d2917SAlp Dener /* Update trust region radius */ 886080d2917SAlp Dener *accept = PETSC_FALSE; 88728017e9fSAlp Dener switch(updateType) { 888080d2917SAlp Dener case BNK_UPDATE_STEP: 889c14b763aSAlp Dener *accept = PETSC_TRUE; /* always accept here because line search succeeded */ 890080d2917SAlp Dener if (stepType == BNK_NEWTON) { 891080d2917SAlp Dener ierr = TaoLineSearchGetStepLength(tao->linesearch, &step);CHKERRQ(ierr); 892080d2917SAlp Dener if (step < bnk->nu1) { 893080d2917SAlp Dener /* Very bad step taken; reduce radius */ 894080d2917SAlp Dener tao->trust = bnk->omega1 * PetscMin(bnk->dnorm, tao->trust); 895080d2917SAlp Dener } else if (step < bnk->nu2) { 896080d2917SAlp Dener /* Reasonably bad step taken; reduce radius */ 897080d2917SAlp Dener tao->trust = bnk->omega2 * PetscMin(bnk->dnorm, tao->trust); 898080d2917SAlp Dener } else if (step < bnk->nu3) { 899080d2917SAlp Dener /* Reasonable step was taken; leave radius alone */ 900080d2917SAlp Dener if (bnk->omega3 < 1.0) { 901080d2917SAlp Dener tao->trust = bnk->omega3 * PetscMin(bnk->dnorm, tao->trust); 902080d2917SAlp Dener } else if (bnk->omega3 > 1.0) { 903080d2917SAlp Dener tao->trust = PetscMax(bnk->omega3 * bnk->dnorm, tao->trust); 904080d2917SAlp Dener } 905080d2917SAlp Dener } else if (step < bnk->nu4) { 906080d2917SAlp Dener /* Full step taken; increase the radius */ 907080d2917SAlp Dener tao->trust = PetscMax(bnk->omega4 * bnk->dnorm, tao->trust); 908080d2917SAlp Dener } else { 909080d2917SAlp Dener /* More than full step taken; increase the radius */ 910080d2917SAlp Dener tao->trust = PetscMax(bnk->omega5 * bnk->dnorm, tao->trust); 911080d2917SAlp Dener } 912080d2917SAlp Dener } else { 913080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 914080d2917SAlp Dener tao->trust = bnk->omega1 * PetscMin(bnk->dnorm, tao->trust); 915080d2917SAlp Dener } 916080d2917SAlp Dener break; 917080d2917SAlp Dener 918080d2917SAlp Dener case BNK_UPDATE_REDUCTION: 919080d2917SAlp Dener if (stepType == BNK_NEWTON) { 920b1c2d0e3SAlp Dener if (prered < 0.0) { 921fed79b8eSAlp Dener /* The predicted reduction has the wrong sign. This cannot 922fed79b8eSAlp Dener happen in infinite precision arithmetic. Step should 923fed79b8eSAlp Dener be rejected! */ 924080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 925fed79b8eSAlp Dener } 926fed79b8eSAlp Dener else { 927b1c2d0e3SAlp Dener if (PetscIsInfOrNanReal(actred)) { 928080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 929080d2917SAlp Dener } else { 9300a4511e9SAlp Dener if ((PetscAbsScalar(actred) <= PetscMax(1.0, PetscAbsScalar(bnk->f))*bnk->epsilon) && 9310a4511e9SAlp Dener (PetscAbsScalar(prered) <= PetscMax(1.0, PetscAbsScalar(bnk->f))*bnk->epsilon)) { 932080d2917SAlp Dener kappa = 1.0; 933fed79b8eSAlp Dener } 934fed79b8eSAlp Dener else { 935080d2917SAlp Dener kappa = actred / prered; 936080d2917SAlp Dener } 937fed79b8eSAlp Dener 938fed79b8eSAlp Dener /* Accept or reject the step and update radius */ 939080d2917SAlp Dener if (kappa < bnk->eta1) { 940fed79b8eSAlp Dener /* Reject the step */ 941080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(tao->trust, bnk->dnorm); 942fed79b8eSAlp Dener } 943fed79b8eSAlp Dener else { 944fed79b8eSAlp Dener /* Accept the step */ 945c133c014SAlp Dener *accept = PETSC_TRUE; 946c133c014SAlp Dener /* Update the trust region radius only if the computed step is at the trust radius boundary */ 9478d5ead36SAlp Dener if (bnk->dnorm == tao->trust) { 948080d2917SAlp Dener if (kappa < bnk->eta2) { 949080d2917SAlp Dener /* Marginal bad step */ 950c133c014SAlp Dener tao->trust = bnk->alpha2 * tao->trust; 951080d2917SAlp Dener } 952fed79b8eSAlp Dener else if (kappa < bnk->eta3) { 953fed79b8eSAlp Dener /* Reasonable step */ 954fed79b8eSAlp Dener tao->trust = bnk->alpha3 * tao->trust; 955fed79b8eSAlp Dener } 956fed79b8eSAlp Dener else if (kappa < bnk->eta4) { 957080d2917SAlp Dener /* Good step */ 958c133c014SAlp Dener tao->trust = bnk->alpha4 * tao->trust; 959fed79b8eSAlp Dener } 960fed79b8eSAlp Dener else { 961080d2917SAlp Dener /* Very good step */ 962c133c014SAlp Dener tao->trust = bnk->alpha5 * tao->trust; 963080d2917SAlp Dener } 964c133c014SAlp Dener } 965080d2917SAlp Dener } 966080d2917SAlp Dener } 967080d2917SAlp Dener } 968080d2917SAlp Dener } else { 969080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 970080d2917SAlp Dener tao->trust = bnk->alpha1 * PetscMin(bnk->dnorm, tao->trust); 971080d2917SAlp Dener } 972080d2917SAlp Dener break; 973080d2917SAlp Dener 974080d2917SAlp Dener default: 975080d2917SAlp Dener if (stepType == BNK_NEWTON) { 976b1c2d0e3SAlp Dener if (prered < 0.0) { 977080d2917SAlp Dener /* The predicted reduction has the wrong sign. This cannot */ 978080d2917SAlp Dener /* happen in infinite precision arithmetic. Step should */ 979080d2917SAlp Dener /* be rejected! */ 980080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 981080d2917SAlp Dener } else { 982b1c2d0e3SAlp Dener if (PetscIsInfOrNanReal(actred)) { 983080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 984080d2917SAlp Dener } else { 985080d2917SAlp Dener if ((PetscAbsScalar(actred) <= bnk->epsilon) && (PetscAbsScalar(prered) <= bnk->epsilon)) { 986080d2917SAlp Dener kappa = 1.0; 987080d2917SAlp Dener } else { 988080d2917SAlp Dener kappa = actred / prered; 989080d2917SAlp Dener } 990080d2917SAlp Dener 991080d2917SAlp Dener ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); 992080d2917SAlp Dener tau_1 = bnk->theta * gdx / (bnk->theta * gdx - (1.0 - bnk->theta) * prered + actred); 993080d2917SAlp Dener tau_2 = bnk->theta * gdx / (bnk->theta * gdx + (1.0 + bnk->theta) * prered - actred); 994080d2917SAlp Dener tau_min = PetscMin(tau_1, tau_2); 995080d2917SAlp Dener tau_max = PetscMax(tau_1, tau_2); 996080d2917SAlp Dener 997080d2917SAlp Dener if (kappa >= 1.0 - bnk->mu1) { 998080d2917SAlp Dener /* Great agreement */ 999080d2917SAlp Dener *accept = PETSC_TRUE; 1000080d2917SAlp Dener if (tau_max < 1.0) { 1001080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma3 * bnk->dnorm); 1002080d2917SAlp Dener } else if (tau_max > bnk->gamma4) { 1003080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma4 * bnk->dnorm); 1004080d2917SAlp Dener } else { 1005080d2917SAlp Dener tao->trust = PetscMax(tao->trust, tau_max * bnk->dnorm); 1006080d2917SAlp Dener } 1007080d2917SAlp Dener } else if (kappa >= 1.0 - bnk->mu2) { 1008080d2917SAlp Dener /* Good agreement */ 1009080d2917SAlp Dener *accept = PETSC_TRUE; 1010080d2917SAlp Dener if (tau_max < bnk->gamma2) { 1011080d2917SAlp Dener tao->trust = bnk->gamma2 * PetscMin(tao->trust, bnk->dnorm); 1012080d2917SAlp Dener } else if (tau_max > bnk->gamma3) { 1013080d2917SAlp Dener tao->trust = PetscMax(tao->trust, bnk->gamma3 * bnk->dnorm); 1014080d2917SAlp Dener } else if (tau_max < 1.0) { 1015080d2917SAlp Dener tao->trust = tau_max * PetscMin(tao->trust, bnk->dnorm); 1016080d2917SAlp Dener } else { 1017080d2917SAlp Dener tao->trust = PetscMax(tao->trust, tau_max * bnk->dnorm); 1018080d2917SAlp Dener } 1019080d2917SAlp Dener } else { 1020080d2917SAlp Dener /* Not good agreement */ 1021080d2917SAlp Dener if (tau_min > 1.0) { 1022080d2917SAlp Dener tao->trust = bnk->gamma2 * PetscMin(tao->trust, bnk->dnorm); 1023080d2917SAlp Dener } else if (tau_max < bnk->gamma1) { 1024080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 1025080d2917SAlp Dener } else if ((tau_min < bnk->gamma1) && (tau_max >= 1.0)) { 1026080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(tao->trust, bnk->dnorm); 1027080d2917SAlp Dener } else if ((tau_1 >= bnk->gamma1) && (tau_1 < 1.0) && ((tau_2 < bnk->gamma1) || (tau_2 >= 1.0))) { 1028080d2917SAlp Dener tao->trust = tau_1 * PetscMin(tao->trust, bnk->dnorm); 1029080d2917SAlp Dener } else if ((tau_2 >= bnk->gamma1) && (tau_2 < 1.0) && ((tau_1 < bnk->gamma1) || (tau_2 >= 1.0))) { 1030080d2917SAlp Dener tao->trust = tau_2 * PetscMin(tao->trust, bnk->dnorm); 1031080d2917SAlp Dener } else { 1032080d2917SAlp Dener tao->trust = tau_max * PetscMin(tao->trust, bnk->dnorm); 1033080d2917SAlp Dener } 1034080d2917SAlp Dener } 1035080d2917SAlp Dener } 1036080d2917SAlp Dener } 1037080d2917SAlp Dener } else { 1038080d2917SAlp Dener /* Newton step was not good; reduce the radius */ 1039080d2917SAlp Dener tao->trust = bnk->gamma1 * PetscMin(bnk->dnorm, tao->trust); 1040080d2917SAlp Dener } 104128017e9fSAlp Dener break; 1042080d2917SAlp Dener } 1043c133c014SAlp Dener /* Make sure the radius does not violate min and max settings */ 1044c133c014SAlp Dener tao->trust = PetscMin(tao->trust, bnk->max_radius); 1045fed79b8eSAlp Dener tao->trust = PetscMax(tao->trust, bnk->min_radius); 1046080d2917SAlp Dener PetscFunctionReturn(0); 1047080d2917SAlp Dener } 1048080d2917SAlp Dener 1049eb910715SAlp Dener /* ---------------------------------------------------------- */ 1050df278d8fSAlp Dener 105162675beeSAlp Dener PetscErrorCode TaoBNKAddStepCounts(Tao tao, PetscInt stepType) 105262675beeSAlp Dener { 105362675beeSAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 105462675beeSAlp Dener 105562675beeSAlp Dener PetscFunctionBegin; 105662675beeSAlp Dener switch (stepType) { 105762675beeSAlp Dener case BNK_NEWTON: 105862675beeSAlp Dener ++bnk->newt; 105962675beeSAlp Dener break; 106062675beeSAlp Dener case BNK_BFGS: 106162675beeSAlp Dener ++bnk->bfgs; 106262675beeSAlp Dener break; 106362675beeSAlp Dener case BNK_SCALED_GRADIENT: 106462675beeSAlp Dener ++bnk->sgrad; 106562675beeSAlp Dener break; 106662675beeSAlp Dener case BNK_GRADIENT: 106762675beeSAlp Dener ++bnk->grad; 106862675beeSAlp Dener break; 106962675beeSAlp Dener default: 107062675beeSAlp Dener break; 107162675beeSAlp Dener } 107262675beeSAlp Dener PetscFunctionReturn(0); 107362675beeSAlp Dener } 107462675beeSAlp Dener 107562675beeSAlp Dener /* ---------------------------------------------------------- */ 107662675beeSAlp Dener 10779b6ef848SAlp Dener PetscErrorCode TaoSetUp_BNK(Tao tao) 1078eb910715SAlp Dener { 1079eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1080eb910715SAlp Dener PetscErrorCode ierr; 10819b6ef848SAlp Dener KSPType ksp_type; 1082*e031d6f5SAlp Dener PetscInt i; 1083eb910715SAlp Dener 1084eb910715SAlp Dener PetscFunctionBegin; 1085eb910715SAlp Dener if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr);} 1086eb910715SAlp Dener if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr);} 1087eb910715SAlp Dener if (!bnk->W) {ierr = VecDuplicate(tao->solution,&bnk->W);CHKERRQ(ierr);} 1088eb910715SAlp Dener if (!bnk->Xold) {ierr = VecDuplicate(tao->solution,&bnk->Xold);CHKERRQ(ierr);} 1089eb910715SAlp Dener if (!bnk->Gold) {ierr = VecDuplicate(tao->solution,&bnk->Gold);CHKERRQ(ierr);} 109009164190SAlp Dener if (!bnk->Xwork) {ierr = VecDuplicate(tao->solution,&bnk->Xwork);CHKERRQ(ierr);} 109109164190SAlp Dener if (!bnk->Gwork) {ierr = VecDuplicate(tao->solution,&bnk->Gwork);CHKERRQ(ierr);} 109209164190SAlp Dener if (!bnk->unprojected_gradient) {ierr = VecDuplicate(tao->solution,&bnk->unprojected_gradient);CHKERRQ(ierr);} 109309164190SAlp Dener if (!bnk->unprojected_gradient_old) {ierr = VecDuplicate(tao->solution,&bnk->unprojected_gradient_old);CHKERRQ(ierr);} 10945e9b73cbSAlp Dener if (!bnk->Diag_min) {ierr = VecDuplicate(tao->solution,&bnk->Diag_min);CHKERRQ(ierr);} 10955e9b73cbSAlp Dener if (!bnk->Diag_max) {ierr = VecDuplicate(tao->solution,&bnk->Diag_max);CHKERRQ(ierr);} 1096*e031d6f5SAlp Dener if (bnk->max_cg_its > 0) { 1097*e031d6f5SAlp Dener if (!bnk->bncg_sol) {ierr = VecDuplicate(tao->solution,&bnk->bncg_sol);CHKERRQ(ierr);} 1098*e031d6f5SAlp Dener ierr = TaoSetInitialVector(bnk->bncg, bnk->bncg_sol);CHKERRQ(ierr); 1099*e031d6f5SAlp Dener ierr = TaoSetMaximumIterations(bnk->bncg, bnk->max_cg_its);CHKERRQ(ierr); 1100*e031d6f5SAlp Dener ierr = TaoSetTolerances(bnk->bncg, tao->gatol, tao->grtol, tao->gttol);CHKERRQ(ierr); 1101*e031d6f5SAlp Dener ierr = TaoSetFunctionLowerBound(bnk->bncg, tao->fmin);CHKERRQ(ierr); 1102*e031d6f5SAlp Dener 1103*e031d6f5SAlp Dener ierr = TaoSetObjectiveRoutine(bnk->bncg, tao->ops->computeobjective, tao->user_objP);CHKERRQ(ierr); 1104*e031d6f5SAlp Dener ierr = TaoSetGradientRoutine(bnk->bncg, tao->ops->computegradient, tao->user_gradP);CHKERRQ(ierr); 1105*e031d6f5SAlp Dener ierr = TaoSetObjectiveAndGradientRoutine(bnk->bncg, tao->ops->computeobjectiveandgradient, tao->user_objgradP);CHKERRQ(ierr); 1106*e031d6f5SAlp Dener ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)tao, (PetscObject)(bnk->bncg));CHKERRQ(ierr); 1107*e031d6f5SAlp Dener for (i=0; i<tao->numbermonitors; i++) { 1108*e031d6f5SAlp Dener ierr = TaoSetMonitor(bnk->bncg, tao->monitor[i], tao->monitorcontext[i], tao->monitordestroy[i]);CHKERRQ(ierr); 1109*e031d6f5SAlp Dener ierr = PetscObjectReference((PetscObject)(tao->monitorcontext[i]));CHKERRQ(ierr); 1110*e031d6f5SAlp Dener } 1111*e031d6f5SAlp Dener bnk->bncg_ctx = (TAO_BNCG *)bnk->bncg->data; 1112*e031d6f5SAlp Dener } 1113eb910715SAlp Dener bnk->Diag = 0; 1114c0f10754SAlp Dener bnk->Diag_red = 0; 1115c0f10754SAlp Dener bnk->X_inactive = 0; 1116c0f10754SAlp Dener bnk->G_inactive = 0; 111762675beeSAlp Dener bnk->inactive_work = 0; 111862675beeSAlp Dener bnk->active_work = 0; 111962675beeSAlp Dener bnk->inactive_idx = 0; 112062675beeSAlp Dener bnk->active_idx = 0; 112162675beeSAlp Dener bnk->active_lower = 0; 112262675beeSAlp Dener bnk->active_upper = 0; 112362675beeSAlp Dener bnk->active_fixed = 0; 1124eb910715SAlp Dener bnk->M = 0; 112509164190SAlp Dener bnk->H_inactive = 0; 112609164190SAlp Dener bnk->Hpre_inactive = 0; 11279b6ef848SAlp Dener ierr = KSPGetType(tao->ksp,&ksp_type);CHKERRQ(ierr); 11289b6ef848SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGNASH,&bnk->is_nash);CHKERRQ(ierr); 11299b6ef848SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGSTCG,&bnk->is_stcg);CHKERRQ(ierr); 11309b6ef848SAlp Dener ierr = PetscStrcmp(ksp_type,KSPCGGLTR,&bnk->is_gltr);CHKERRQ(ierr); 1131eb910715SAlp Dener PetscFunctionReturn(0); 1132eb910715SAlp Dener } 1133eb910715SAlp Dener 1134eb910715SAlp Dener /*------------------------------------------------------------*/ 1135df278d8fSAlp Dener 1136eb910715SAlp Dener static PetscErrorCode TaoDestroy_BNK(Tao tao) 1137eb910715SAlp Dener { 1138eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1139eb910715SAlp Dener PetscErrorCode ierr; 1140eb910715SAlp Dener 1141eb910715SAlp Dener PetscFunctionBegin; 1142eb910715SAlp Dener if (tao->setupcalled) { 1143eb910715SAlp Dener ierr = VecDestroy(&bnk->W);CHKERRQ(ierr); 1144eb910715SAlp Dener ierr = VecDestroy(&bnk->Xold);CHKERRQ(ierr); 1145eb910715SAlp Dener ierr = VecDestroy(&bnk->Gold);CHKERRQ(ierr); 114609164190SAlp Dener ierr = VecDestroy(&bnk->Xwork);CHKERRQ(ierr); 114709164190SAlp Dener ierr = VecDestroy(&bnk->Gwork);CHKERRQ(ierr); 114809164190SAlp Dener ierr = VecDestroy(&bnk->unprojected_gradient);CHKERRQ(ierr); 114909164190SAlp Dener ierr = VecDestroy(&bnk->unprojected_gradient_old);CHKERRQ(ierr); 115062675beeSAlp Dener ierr = VecDestroy(&bnk->Diag_min);CHKERRQ(ierr); 115162675beeSAlp Dener ierr = VecDestroy(&bnk->Diag_max);CHKERRQ(ierr); 1152c0f10754SAlp Dener if (bnk->max_cg_its > 0) { 1153c0f10754SAlp Dener ierr = TaoDestroy(&bnk->bncg);CHKERRQ(ierr); 1154c0f10754SAlp Dener ierr = VecDestroy(&bnk->bncg_sol);CHKERRQ(ierr); 1155c0f10754SAlp Dener } 11565e9b73cbSAlp Dener } 11575e9b73cbSAlp Dener ierr = VecDestroy(&bnk->Diag);CHKERRQ(ierr); 1158eb910715SAlp Dener ierr = MatDestroy(&bnk->M);CHKERRQ(ierr); 1159c0f10754SAlp Dener if (bnk->Hpre_inactive != tao->hessian_pre && bnk->Hpre_inactive != bnk->H_inactive) {ierr = MatDestroy(&bnk->Hpre_inactive);CHKERRQ(ierr);} 1160c0f10754SAlp Dener if (bnk->H_inactive != tao->hessian) {ierr = MatDestroy(&bnk->H_inactive);CHKERRQ(ierr);} 1161eb910715SAlp Dener ierr = PetscFree(tao->data);CHKERRQ(ierr); 1162eb910715SAlp Dener PetscFunctionReturn(0); 1163eb910715SAlp Dener } 1164eb910715SAlp Dener 1165eb910715SAlp Dener /*------------------------------------------------------------*/ 1166df278d8fSAlp Dener 1167eb910715SAlp Dener static PetscErrorCode TaoSetFromOptions_BNK(PetscOptionItems *PetscOptionsObject,Tao tao) 1168eb910715SAlp Dener { 1169eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1170eb910715SAlp Dener PetscErrorCode ierr; 1171eb910715SAlp Dener 1172eb910715SAlp Dener PetscFunctionBegin; 1173eb910715SAlp Dener ierr = PetscOptionsHead(PetscOptionsObject,"Newton line search method for unconstrained optimization");CHKERRQ(ierr); 11748d5ead36SAlp Dener ierr = PetscOptionsEList("-tao_bnk_pc_type", "pc type", "", BNK_PC, BNK_PC_TYPES, BNK_PC[bnk->pc_type], &bnk->pc_type, 0);CHKERRQ(ierr); 11758d5ead36SAlp Dener ierr = PetscOptionsEList("-tao_bnk_bfgs_scale_type", "bfgs scale type", "", BFGS_SCALE, BFGS_SCALE_TYPES, BFGS_SCALE[bnk->bfgs_scale_type], &bnk->bfgs_scale_type, 0);CHKERRQ(ierr); 11768d5ead36SAlp 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); 11778d5ead36SAlp 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); 11782f75a4aaSAlp 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); 11798d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_sval", "perturbation starting value", "", bnk->sval, &bnk->sval,NULL);CHKERRQ(ierr); 11808d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imin", "minimum initial perturbation", "", bnk->imin, &bnk->imin,NULL);CHKERRQ(ierr); 11818d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imax", "maximum initial perturbation", "", bnk->imax, &bnk->imax,NULL);CHKERRQ(ierr); 11828d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_imfac", "initial merit factor", "", bnk->imfac, &bnk->imfac,NULL);CHKERRQ(ierr); 11838d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmin", "minimum perturbation", "", bnk->pmin, &bnk->pmin,NULL);CHKERRQ(ierr); 11848d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmax", "maximum perturbation", "", bnk->pmax, &bnk->pmax,NULL);CHKERRQ(ierr); 11858d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pgfac", "growth factor", "", bnk->pgfac, &bnk->pgfac,NULL);CHKERRQ(ierr); 11868d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_psfac", "shrink factor", "", bnk->psfac, &bnk->psfac,NULL);CHKERRQ(ierr); 11878d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmgfac", "merit growth factor", "", bnk->pmgfac, &bnk->pmgfac,NULL);CHKERRQ(ierr); 11888d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_pmsfac", "merit shrink factor", "", bnk->pmsfac, &bnk->pmsfac,NULL);CHKERRQ(ierr); 11898d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta1", "poor steplength; reduce radius", "", bnk->eta1, &bnk->eta1,NULL);CHKERRQ(ierr); 11908d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta2", "reasonable steplength; leave radius alone", "", bnk->eta2, &bnk->eta2,NULL);CHKERRQ(ierr); 11918d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta3", "good steplength; increase radius", "", bnk->eta3, &bnk->eta3,NULL);CHKERRQ(ierr); 11928d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_eta4", "excellent steplength; greatly increase radius", "", bnk->eta4, &bnk->eta4,NULL);CHKERRQ(ierr); 11938d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha1", "", "", bnk->alpha1, &bnk->alpha1,NULL);CHKERRQ(ierr); 11948d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha2", "", "", bnk->alpha2, &bnk->alpha2,NULL);CHKERRQ(ierr); 11958d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha3", "", "", bnk->alpha3, &bnk->alpha3,NULL);CHKERRQ(ierr); 11968d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha4", "", "", bnk->alpha4, &bnk->alpha4,NULL);CHKERRQ(ierr); 11978d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_alpha5", "", "", bnk->alpha5, &bnk->alpha5,NULL);CHKERRQ(ierr); 11988d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_nu1", "poor steplength; reduce radius", "", bnk->nu1, &bnk->nu1,NULL);CHKERRQ(ierr); 11998d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_nu2", "reasonable steplength; leave radius alone", "", bnk->nu2, &bnk->nu2,NULL);CHKERRQ(ierr); 12008d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_nu3", "good steplength; increase radius", "", bnk->nu3, &bnk->nu3,NULL);CHKERRQ(ierr); 12018d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_nu4", "excellent steplength; greatly increase radius", "", bnk->nu4, &bnk->nu4,NULL);CHKERRQ(ierr); 12028d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega1", "", "", bnk->omega1, &bnk->omega1,NULL);CHKERRQ(ierr); 12038d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega2", "", "", bnk->omega2, &bnk->omega2,NULL);CHKERRQ(ierr); 12048d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega3", "", "", bnk->omega3, &bnk->omega3,NULL);CHKERRQ(ierr); 12058d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega4", "", "", bnk->omega4, &bnk->omega4,NULL);CHKERRQ(ierr); 12068d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_omega5", "", "", bnk->omega5, &bnk->omega5,NULL);CHKERRQ(ierr); 12078d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu1_i", "", "", bnk->mu1_i, &bnk->mu1_i,NULL);CHKERRQ(ierr); 12088d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu2_i", "", "", bnk->mu2_i, &bnk->mu2_i,NULL);CHKERRQ(ierr); 12098d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma1_i", "", "", bnk->gamma1_i, &bnk->gamma1_i,NULL);CHKERRQ(ierr); 12108d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma2_i", "", "", bnk->gamma2_i, &bnk->gamma2_i,NULL);CHKERRQ(ierr); 12118d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma3_i", "", "", bnk->gamma3_i, &bnk->gamma3_i,NULL);CHKERRQ(ierr); 12128d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma4_i", "", "", bnk->gamma4_i, &bnk->gamma4_i,NULL);CHKERRQ(ierr); 12138d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_theta_i", "", "", bnk->theta_i, &bnk->theta_i,NULL);CHKERRQ(ierr); 12148d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu1", "", "", bnk->mu1, &bnk->mu1,NULL);CHKERRQ(ierr); 12158d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_mu2", "", "", bnk->mu2, &bnk->mu2,NULL);CHKERRQ(ierr); 12168d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma1", "", "", bnk->gamma1, &bnk->gamma1,NULL);CHKERRQ(ierr); 12178d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma2", "", "", bnk->gamma2, &bnk->gamma2,NULL);CHKERRQ(ierr); 12188d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma3", "", "", bnk->gamma3, &bnk->gamma3,NULL);CHKERRQ(ierr); 12198d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_gamma4", "", "", bnk->gamma4, &bnk->gamma4,NULL);CHKERRQ(ierr); 12208d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_theta", "", "", bnk->theta, &bnk->theta,NULL);CHKERRQ(ierr); 12218d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_min_radius", "lower bound on initial radius", "", bnk->min_radius, &bnk->min_radius,NULL);CHKERRQ(ierr); 12228d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_max_radius", "upper bound on radius", "", bnk->max_radius, &bnk->max_radius,NULL);CHKERRQ(ierr); 12238d5ead36SAlp Dener ierr = PetscOptionsReal("-tao_bnk_epsilon", "tolerance used when computing actual and predicted reduction", "", bnk->epsilon, &bnk->epsilon,NULL);CHKERRQ(ierr); 12240a4511e9SAlp Dener ierr = PetscOptionsReal("-tao_bnk_as_tol", "initial tolerance used when estimating actively bounded variables", "", bnk->as_tol, &bnk->as_tol,NULL);CHKERRQ(ierr); 12250a4511e9SAlp Dener ierr = PetscOptionsReal("-tao_bnk_as_step", "step length used when estimating actively bounded variables", "", bnk->as_step, &bnk->as_step,NULL);CHKERRQ(ierr); 1226c0f10754SAlp 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); 1227eb910715SAlp Dener ierr = PetscOptionsTail();CHKERRQ(ierr); 1228*e031d6f5SAlp Dener ierr = TaoSetFromOptions(bnk->bncg); 1229eb910715SAlp Dener ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 1230eb910715SAlp Dener ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 1231eb910715SAlp Dener PetscFunctionReturn(0); 1232eb910715SAlp Dener } 1233eb910715SAlp Dener 1234eb910715SAlp Dener /*------------------------------------------------------------*/ 1235df278d8fSAlp Dener 1236eb910715SAlp Dener static PetscErrorCode TaoView_BNK(Tao tao, PetscViewer viewer) 1237eb910715SAlp Dener { 1238eb910715SAlp Dener TAO_BNK *bnk = (TAO_BNK *)tao->data; 1239eb910715SAlp Dener PetscInt nrejects; 1240eb910715SAlp Dener PetscBool isascii; 1241eb910715SAlp Dener PetscErrorCode ierr; 1242eb910715SAlp Dener 1243eb910715SAlp Dener PetscFunctionBegin; 1244eb910715SAlp Dener ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1245eb910715SAlp Dener if (isascii) { 1246eb910715SAlp Dener ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1247eb910715SAlp Dener if (BNK_PC_BFGS == bnk->pc_type && bnk->M) { 1248eb910715SAlp Dener ierr = MatLMVMGetRejects(bnk->M,&nrejects);CHKERRQ(ierr); 1249eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Rejected matrix updates: %D\n",nrejects);CHKERRQ(ierr); 1250eb910715SAlp Dener } 1251*e031d6f5SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "CG steps: %D\n", bnk->tot_cg_its);CHKERRQ(ierr); 1252eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Newton steps: %D\n", bnk->newt);CHKERRQ(ierr); 1253eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "BFGS steps: %D\n", bnk->bfgs);CHKERRQ(ierr); 1254eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Scaled gradient steps: %D\n", bnk->sgrad);CHKERRQ(ierr); 1255eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", bnk->grad);CHKERRQ(ierr); 1256eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, "KSP termination reasons:\n");CHKERRQ(ierr); 1257eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " atol: %D\n", bnk->ksp_atol);CHKERRQ(ierr); 1258eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " rtol: %D\n", bnk->ksp_rtol);CHKERRQ(ierr); 1259eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " ctol: %D\n", bnk->ksp_ctol);CHKERRQ(ierr); 1260eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " negc: %D\n", bnk->ksp_negc);CHKERRQ(ierr); 1261eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " dtol: %D\n", bnk->ksp_dtol);CHKERRQ(ierr); 1262eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " iter: %D\n", bnk->ksp_iter);CHKERRQ(ierr); 1263eb910715SAlp Dener ierr = PetscViewerASCIIPrintf(viewer, " othr: %D\n", bnk->ksp_othr);CHKERRQ(ierr); 1264eb910715SAlp Dener ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1265eb910715SAlp Dener } 1266eb910715SAlp Dener PetscFunctionReturn(0); 1267eb910715SAlp Dener } 1268eb910715SAlp Dener 1269eb910715SAlp Dener /* ---------------------------------------------------------- */ 1270df278d8fSAlp Dener 1271eb910715SAlp Dener /*MC 1272eb910715SAlp Dener TAOBNK - Shared base-type for Bounded Newton-Krylov type algorithms. 127366ed3702SAlp Dener At each iteration, the BNK methods solve the symmetric 1274eb910715SAlp Dener system of equations to obtain the step diretion dk: 1275eb910715SAlp Dener Hk dk = -gk 12762b97c8d8SAlp Dener for free variables only. The step can be globalized either through 12772b97c8d8SAlp Dener trust-region methods, or a line search, or a heuristic mixture of both. 1278eb910715SAlp Dener 1279eb910715SAlp Dener Options Database Keys: 12808d5ead36SAlp Dener + -tao_bnk_pc_type - "none","ahess","bfgs","petsc" 12818d5ead36SAlp Dener . -tao_bnk_bfgs_scale_type - "ahess","phess","bfgs" 12828d5ead36SAlp Dener . -tao_bnk_init_type - "constant","direction","interpolation" 12838d5ead36SAlp Dener . -tao_bnk_update_type - "step","direction","interpolation" 12842f75a4aaSAlp Dener . -tao_bnk_as_type - "none","bertsekas" 12858d5ead36SAlp Dener . -tao_bnk_sval - perturbation starting value 12868d5ead36SAlp Dener . -tao_bnk_imin - minimum initial perturbation 12878d5ead36SAlp Dener . -tao_bnk_imax - maximum initial perturbation 12888d5ead36SAlp Dener . -tao_bnk_pmin - minimum perturbation 12898d5ead36SAlp Dener . -tao_bnk_pmax - maximum perturbation 12908d5ead36SAlp Dener . -tao_bnk_pgfac - growth factor 12918d5ead36SAlp Dener . -tao_bnk_psfac - shrink factor 12928d5ead36SAlp Dener . -tao_bnk_imfac - initial merit factor 12938d5ead36SAlp Dener . -tao_bnk_pmgfac - merit growth factor 12948d5ead36SAlp Dener . -tao_bnk_pmsfac - merit shrink factor 12958d5ead36SAlp Dener . -tao_bnk_eta1 - poor steplength; reduce radius 12968d5ead36SAlp Dener . -tao_bnk_eta2 - reasonable steplength; leave radius 12978d5ead36SAlp Dener . -tao_bnk_eta3 - good steplength; increase readius 12988d5ead36SAlp Dener . -tao_bnk_eta4 - excellent steplength; greatly increase radius 12998d5ead36SAlp Dener . -tao_bnk_alpha1 - alpha1 reduction 13008d5ead36SAlp Dener . -tao_bnk_alpha2 - alpha2 reduction 13018d5ead36SAlp Dener . -tao_bnk_alpha3 - alpha3 reduction 13028d5ead36SAlp Dener . -tao_bnk_alpha4 - alpha4 reduction 13038d5ead36SAlp Dener . -tao_bnk_alpha - alpha5 reduction 13048d5ead36SAlp Dener . -tao_bnk_mu1 - mu1 interpolation update 13058d5ead36SAlp Dener . -tao_bnk_mu2 - mu2 interpolation update 13068d5ead36SAlp Dener . -tao_bnk_gamma1 - gamma1 interpolation update 13078d5ead36SAlp Dener . -tao_bnk_gamma2 - gamma2 interpolation update 13088d5ead36SAlp Dener . -tao_bnk_gamma3 - gamma3 interpolation update 13098d5ead36SAlp Dener . -tao_bnk_gamma4 - gamma4 interpolation update 13108d5ead36SAlp Dener . -tao_bnk_theta - theta interpolation update 13118d5ead36SAlp Dener . -tao_bnk_omega1 - omega1 step update 13128d5ead36SAlp Dener . -tao_bnk_omega2 - omega2 step update 13138d5ead36SAlp Dener . -tao_bnk_omega3 - omega3 step update 13148d5ead36SAlp Dener . -tao_bnk_omega4 - omega4 step update 13158d5ead36SAlp Dener . -tao_bnk_omega5 - omega5 step update 13168d5ead36SAlp Dener . -tao_bnk_mu1_i - mu1 interpolation init factor 13178d5ead36SAlp Dener . -tao_bnk_mu2_i - mu2 interpolation init factor 13188d5ead36SAlp Dener . -tao_bnk_gamma1_i - gamma1 interpolation init factor 13198d5ead36SAlp Dener . -tao_bnk_gamma2_i - gamma2 interpolation init factor 13208d5ead36SAlp Dener . -tao_bnk_gamma3_i - gamma3 interpolation init factor 13218d5ead36SAlp Dener . -tao_bnk_gamma4_i - gamma4 interpolation init factor 13222f75a4aaSAlp Dener . -tao_bnk_theta_i - theta interpolation init factor 13232f75a4aaSAlp Dener - -tao_bnk_bound_tol - initial tolerance used in estimating bounded active variables 1324eb910715SAlp Dener 1325eb910715SAlp Dener Level: beginner 1326eb910715SAlp Dener M*/ 1327eb910715SAlp Dener 1328eb910715SAlp Dener PetscErrorCode TaoCreate_BNK(Tao tao) 1329eb910715SAlp Dener { 1330eb910715SAlp Dener TAO_BNK *bnk; 1331eb910715SAlp Dener const char *morethuente_type = TAOLINESEARCHMT; 1332eb910715SAlp Dener PetscErrorCode ierr; 1333eb910715SAlp Dener 1334eb910715SAlp Dener PetscFunctionBegin; 1335eb910715SAlp Dener ierr = PetscNewLog(tao,&bnk);CHKERRQ(ierr); 1336eb910715SAlp Dener 1337eb910715SAlp Dener tao->ops->setup = TaoSetUp_BNK; 1338eb910715SAlp Dener tao->ops->view = TaoView_BNK; 1339eb910715SAlp Dener tao->ops->setfromoptions = TaoSetFromOptions_BNK; 1340eb910715SAlp Dener tao->ops->destroy = TaoDestroy_BNK; 1341eb910715SAlp Dener 1342eb910715SAlp Dener /* Override default settings (unless already changed) */ 1343eb910715SAlp Dener if (!tao->max_it_changed) tao->max_it = 50; 1344eb910715SAlp Dener if (!tao->trust0_changed) tao->trust0 = 100.0; 1345eb910715SAlp Dener 1346eb910715SAlp Dener tao->data = (void*)bnk; 1347eb910715SAlp Dener 134866ed3702SAlp Dener /* Hessian shifting parameters */ 1349eb910715SAlp Dener bnk->sval = 0.0; 1350eb910715SAlp Dener bnk->imin = 1.0e-4; 1351eb910715SAlp Dener bnk->imax = 1.0e+2; 1352eb910715SAlp Dener bnk->imfac = 1.0e-1; 1353eb910715SAlp Dener 1354eb910715SAlp Dener bnk->pmin = 1.0e-12; 1355eb910715SAlp Dener bnk->pmax = 1.0e+2; 1356eb910715SAlp Dener bnk->pgfac = 1.0e+1; 1357eb910715SAlp Dener bnk->psfac = 4.0e-1; 1358eb910715SAlp Dener bnk->pmgfac = 1.0e-1; 1359eb910715SAlp Dener bnk->pmsfac = 1.0e-1; 1360eb910715SAlp Dener 1361eb910715SAlp Dener /* Default values for trust-region radius update based on steplength */ 1362eb910715SAlp Dener bnk->nu1 = 0.25; 1363eb910715SAlp Dener bnk->nu2 = 0.50; 1364eb910715SAlp Dener bnk->nu3 = 1.00; 1365eb910715SAlp Dener bnk->nu4 = 1.25; 1366eb910715SAlp Dener 1367eb910715SAlp Dener bnk->omega1 = 0.25; 1368eb910715SAlp Dener bnk->omega2 = 0.50; 1369eb910715SAlp Dener bnk->omega3 = 1.00; 1370eb910715SAlp Dener bnk->omega4 = 2.00; 1371eb910715SAlp Dener bnk->omega5 = 4.00; 1372eb910715SAlp Dener 1373eb910715SAlp Dener /* Default values for trust-region radius update based on reduction */ 1374eb910715SAlp Dener bnk->eta1 = 1.0e-4; 1375eb910715SAlp Dener bnk->eta2 = 0.25; 1376eb910715SAlp Dener bnk->eta3 = 0.50; 1377eb910715SAlp Dener bnk->eta4 = 0.90; 1378eb910715SAlp Dener 1379eb910715SAlp Dener bnk->alpha1 = 0.25; 1380eb910715SAlp Dener bnk->alpha2 = 0.50; 1381eb910715SAlp Dener bnk->alpha3 = 1.00; 1382eb910715SAlp Dener bnk->alpha4 = 2.00; 1383eb910715SAlp Dener bnk->alpha5 = 4.00; 1384eb910715SAlp Dener 1385eb910715SAlp Dener /* Default values for trust-region radius update based on interpolation */ 1386eb910715SAlp Dener bnk->mu1 = 0.10; 1387eb910715SAlp Dener bnk->mu2 = 0.50; 1388eb910715SAlp Dener 1389eb910715SAlp Dener bnk->gamma1 = 0.25; 1390eb910715SAlp Dener bnk->gamma2 = 0.50; 1391eb910715SAlp Dener bnk->gamma3 = 2.00; 1392eb910715SAlp Dener bnk->gamma4 = 4.00; 1393eb910715SAlp Dener 1394eb910715SAlp Dener bnk->theta = 0.05; 1395eb910715SAlp Dener 1396eb910715SAlp Dener /* Default values for trust region initialization based on interpolation */ 1397eb910715SAlp Dener bnk->mu1_i = 0.35; 1398eb910715SAlp Dener bnk->mu2_i = 0.50; 1399eb910715SAlp Dener 1400eb910715SAlp Dener bnk->gamma1_i = 0.0625; 1401eb910715SAlp Dener bnk->gamma2_i = 0.5; 1402eb910715SAlp Dener bnk->gamma3_i = 2.0; 1403eb910715SAlp Dener bnk->gamma4_i = 5.0; 1404eb910715SAlp Dener 1405eb910715SAlp Dener bnk->theta_i = 0.25; 1406eb910715SAlp Dener 1407eb910715SAlp Dener /* Remaining parameters */ 1408c0f10754SAlp Dener bnk->max_cg_its = 0; 1409eb910715SAlp Dener bnk->min_radius = 1.0e-10; 1410eb910715SAlp Dener bnk->max_radius = 1.0e10; 1411770b7498SAlp Dener bnk->epsilon = PetscPowReal(PETSC_MACHINE_EPSILON, 2.0/3.0); 14120a4511e9SAlp Dener bnk->as_tol = 1.0e-3; 14130a4511e9SAlp Dener bnk->as_step = 1.0e-3; 141462675beeSAlp Dener bnk->dmin = 1.0e-6; 141562675beeSAlp Dener bnk->dmax = 1.0e6; 1416eb910715SAlp Dener 1417*e031d6f5SAlp Dener bnk->pc_type = BNK_PC_AHESS; 1418eb910715SAlp Dener bnk->bfgs_scale_type = BFGS_SCALE_PHESS; 1419eb910715SAlp Dener bnk->init_type = BNK_INIT_INTERPOLATION; 1420fed79b8eSAlp Dener bnk->update_type = BNK_UPDATE_INTERPOLATION; 14212f75a4aaSAlp Dener bnk->as_type = BNK_AS_BERTSEKAS; 1422eb910715SAlp Dener 1423*e031d6f5SAlp Dener /* Create the embedded BNCG solver */ 1424*e031d6f5SAlp Dener ierr = TaoCreate(PetscObjectComm((PetscObject)tao), &bnk->bncg);CHKERRQ(ierr); 1425*e031d6f5SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)bnk->bncg, (PetscObject)tao, 1);CHKERRQ(ierr); 1426*e031d6f5SAlp Dener ierr = TaoSetOptionsPrefix(bnk->bncg, "tao_bnk_");CHKERRQ(ierr); 1427*e031d6f5SAlp Dener ierr = TaoSetType(bnk->bncg, TAOBNCG);CHKERRQ(ierr); 1428*e031d6f5SAlp Dener 1429c0f10754SAlp Dener /* Create the line search */ 1430eb910715SAlp Dener ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr); 1431eb910715SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 1432*e031d6f5SAlp Dener ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 1433eb910715SAlp Dener ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr); 1434eb910715SAlp Dener ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr); 1435eb910715SAlp Dener 1436eb910715SAlp Dener /* Set linear solver to default for symmetric matrices */ 1437eb910715SAlp Dener ierr = KSPCreate(((PetscObject)tao)->comm,&tao->ksp);CHKERRQ(ierr); 1438eb910715SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1);CHKERRQ(ierr); 1439eb910715SAlp Dener ierr = KSPSetOptionsPrefix(tao->ksp,tao->hdr.prefix);CHKERRQ(ierr); 1440eb910715SAlp Dener ierr = KSPSetType(tao->ksp,KSPCGSTCG);CHKERRQ(ierr); 1441eb910715SAlp Dener PetscFunctionReturn(0); 1442eb910715SAlp Dener } 1443