PETSC_EXTERN void PETSC_STDCALL vecstepboundinfo_(Vec X,Vec DX,Vec XL,Vec XU,PetscReal *boundmin,PetscReal *wolfemin,PetscReal *boundmax, int *__ierr ){ *__ierr = VecStepBoundInfo( (Vec)PetscToPointer((X) ), (Vec)PetscToPointer((DX) ), (Vec)PetscToPointer((XL) ), (Vec)PetscToPointer((XU) ),boundmin,wolfemin,boundmax); }
static PetscErrorCode TaoLineSearchApply_MT(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s) { PetscErrorCode ierr; TaoLineSearch_MT *mt; PetscReal xtrapf = 4.0; PetscReal finit, width, width1, dginit, fm, fxm, fym, dgm, dgxm, dgym; PetscReal dgx, dgy, dg, dg2, fx, fy, stx, sty, dgtest; PetscReal ftest1=0.0, ftest2=0.0; PetscInt i, stage1,n1,n2,nn1,nn2; PetscReal bstepmin1, bstepmin2, bstepmax; PetscBool g_computed=PETSC_FALSE; /* to prevent extra gradient computation */ PetscFunctionBegin; PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); PetscValidHeaderSpecific(x,VEC_CLASSID,2); PetscValidScalarPointer(f,3); PetscValidHeaderSpecific(g,VEC_CLASSID,4); PetscValidHeaderSpecific(s,VEC_CLASSID,5); /* comm,type,size checks are done in interface TaoLineSearchApply */ mt = (TaoLineSearch_MT*)(ls->data); ls->reason = TAOLINESEARCH_CONTINUE_ITERATING; /* Check work vector */ if (!mt->work) { ierr = VecDuplicate(x,&mt->work);CHKERRQ(ierr); mt->x = x; ierr = PetscObjectReference((PetscObject)mt->x);CHKERRQ(ierr); } else if (x != mt->x) { ierr = VecDestroy(&mt->work);CHKERRQ(ierr); ierr = VecDuplicate(x,&mt->work);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject)mt->x);CHKERRQ(ierr); mt->x = x; ierr = PetscObjectReference((PetscObject)mt->x);CHKERRQ(ierr); } if (ls->bounded) { /* Compute step length needed to make all variables equal a bound */ /* Compute the smallest steplength that will make one nonbinding variable equal the bound */ ierr = VecGetLocalSize(ls->upper,&n1);CHKERRQ(ierr); ierr = VecGetLocalSize(mt->x, &n2);CHKERRQ(ierr); ierr = VecGetSize(ls->upper,&nn1);CHKERRQ(ierr); ierr = VecGetSize(mt->x,&nn2);CHKERRQ(ierr); if (n1 != n2 || nn1 != nn2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Variable vector not compatible with bounds vector"); ierr = VecScale(s,-1.0);CHKERRQ(ierr); ierr = VecBoundGradientProjection(s,x,ls->lower,ls->upper,s);CHKERRQ(ierr); ierr = VecScale(s,-1.0);CHKERRQ(ierr); ierr = VecStepBoundInfo(x,s,ls->lower,ls->upper,&bstepmin1,&bstepmin2,&bstepmax);CHKERRQ(ierr); ls->stepmax = PetscMin(bstepmax,1.0e15); } ierr = VecDot(g,s,&dginit);CHKERRQ(ierr); if (PetscIsInfOrNanReal(dginit)) { ierr = PetscInfo1(ls,"Initial Line Search step * g is Inf or Nan (%g)\n",(double)dginit);CHKERRQ(ierr); ls->reason=TAOLINESEARCH_FAILED_INFORNAN; PetscFunctionReturn(0); } if (dginit >= 0.0) { ierr = PetscInfo1(ls,"Initial Line Search step * g is not descent direction (%g)\n",(double)dginit);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_FAILED_ASCENT; PetscFunctionReturn(0); } /* Initialization */ mt->bracket = 0; stage1 = 1; finit = *f; dgtest = ls->ftol * dginit; width = ls->stepmax - ls->stepmin; width1 = width * 2.0; ierr = VecCopy(x,mt->work);CHKERRQ(ierr); /* Variable dictionary: stx, fx, dgx - the step, function, and derivative at the best step sty, fy, dgy - the step, function, and derivative at the other endpoint of the interval of uncertainty step, f, dg - the step, function, and derivative at the current step */ stx = 0.0; fx = finit; dgx = dginit; sty = 0.0; fy = finit; dgy = dginit; ls->step=ls->initstep; for (i=0; i< ls->max_funcs; i++) { /* Set min and max steps to correspond to the interval of uncertainty */ if (mt->bracket) { ls->stepmin = PetscMin(stx,sty); ls->stepmax = PetscMax(stx,sty); } else { ls->stepmin = stx; ls->stepmax = ls->step + xtrapf * (ls->step - stx); } /* Force the step to be within the bounds */ ls->step = PetscMax(ls->step,ls->stepmin); ls->step = PetscMin(ls->step,ls->stepmax); /* If an unusual termination is to occur, then let step be the lowest point obtained thus far */ if ((stx!=0) && (((mt->bracket) && (ls->step <= ls->stepmin || ls->step >= ls->stepmax)) || ((mt->bracket) && (ls->stepmax - ls->stepmin <= ls->rtol * ls->stepmax)) || ((ls->nfeval+ls->nfgeval) >= ls->max_funcs - 1) || (mt->infoc == 0))) { ls->step = stx; } ierr = VecCopy(x,mt->work);CHKERRQ(ierr); ierr = VecAXPY(mt->work,ls->step,s);CHKERRQ(ierr); /* W = X + step*S */ if (ls->bounded) { ierr = VecMedian(ls->lower, mt->work, ls->upper, mt->work);CHKERRQ(ierr); } if (ls->usegts) { ierr = TaoLineSearchComputeObjectiveAndGTS(ls,mt->work,f,&dg);CHKERRQ(ierr); g_computed=PETSC_FALSE; } else { ierr = TaoLineSearchComputeObjectiveAndGradient(ls,mt->work,f,g);CHKERRQ(ierr); g_computed=PETSC_TRUE; if (ls->bounded) { ierr = VecDot(g,x,&dg);CHKERRQ(ierr); ierr = VecDot(g,mt->work,&dg2);CHKERRQ(ierr); dg = (dg2 - dg)/ls->step; } else { ierr = VecDot(g,s,&dg);CHKERRQ(ierr); } } if (0 == i) { ls->f_fullstep=*f; } if (PetscIsInfOrNanReal(*f) || PetscIsInfOrNanReal(dg)) { /* User provided compute function generated Not-a-Number, assume domain violation and set function value and directional derivative to infinity. */ *f = PETSC_INFINITY; dg = PETSC_INFINITY; } ftest1 = finit + ls->step * dgtest; if (ls->bounded) { ftest2 = finit + ls->step * dgtest * ls->ftol; } /* Convergence testing */ if (((*f - ftest1 <= 1.0e-10 * PetscAbsReal(finit)) && (PetscAbsReal(dg) + ls->gtol*dginit <= 0.0))) { ierr = PetscInfo(ls, "Line search success: Sufficient decrease and directional deriv conditions hold\n");CHKERRQ(ierr); ls->reason = TAOLINESEARCH_SUCCESS; break; } /* Check Armijo if beyond the first breakpoint */ if (ls->bounded && (*f <= ftest2) && (ls->step >= bstepmin2)) { ierr = PetscInfo(ls,"Line search success: Sufficient decrease.\n");CHKERRQ(ierr); ls->reason = TAOLINESEARCH_SUCCESS; break; } /* Checks for bad cases */ if (((mt->bracket) && (ls->step <= ls->stepmin||ls->step >= ls->stepmax)) || (!mt->infoc)) { ierr = PetscInfo(ls,"Rounding errors may prevent further progress. May not be a step satisfying\n");CHKERRQ(ierr); ierr = PetscInfo(ls,"sufficient decrease and curvature conditions. Tolerances may be too small.\n");CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_OTHER; break; } if ((ls->step == ls->stepmax) && (*f <= ftest1) && (dg <= dgtest)) { ierr = PetscInfo1(ls,"Step is at the upper bound, stepmax (%g)\n",(double)ls->stepmax);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_UPPERBOUND; break; } if ((ls->step == ls->stepmin) && (*f >= ftest1) && (dg >= dgtest)) { ierr = PetscInfo1(ls,"Step is at the lower bound, stepmin (%g)\n",(double)ls->stepmin);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_LOWERBOUND; break; } if ((mt->bracket) && (ls->stepmax - ls->stepmin <= ls->rtol*ls->stepmax)){ ierr = PetscInfo1(ls,"Relative width of interval of uncertainty is at most rtol (%g)\n",(double)ls->rtol);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_RTOL; break; } /* In the first stage, we seek a step for which the modified function has a nonpositive value and nonnegative derivative */ if ((stage1) && (*f <= ftest1) && (dg >= dginit * PetscMin(ls->ftol, ls->gtol))) { stage1 = 0; } /* A modified function is used to predict the step only if we have not obtained a step for which the modified function has a nonpositive function value and nonnegative derivative, and if a lower function value has been obtained but the decrease is not sufficient */ if ((stage1) && (*f <= fx) && (*f > ftest1)) { fm = *f - ls->step * dgtest; /* Define modified function */ fxm = fx - stx * dgtest; /* and derivatives */ fym = fy - sty * dgtest; dgm = dg - dgtest; dgxm = dgx - dgtest; dgym = dgy - dgtest; /* if (dgxm * (ls->step - stx) >= 0.0) */ /* Update the interval of uncertainty and compute the new step */ ierr = Tao_mcstep(ls,&stx,&fxm,&dgxm,&sty,&fym,&dgym,&ls->step,&fm,&dgm);CHKERRQ(ierr); fx = fxm + stx * dgtest; /* Reset the function and */ fy = fym + sty * dgtest; /* gradient values */ dgx = dgxm + dgtest; dgy = dgym + dgtest; } else { /* Update the interval of uncertainty and compute the new step */ ierr = Tao_mcstep(ls,&stx,&fx,&dgx,&sty,&fy,&dgy,&ls->step,f,&dg);CHKERRQ(ierr); } /* Force a sufficient decrease in the interval of uncertainty */ if (mt->bracket) { if (PetscAbsReal(sty - stx) >= 0.66 * width1) ls->step = stx + 0.5*(sty - stx); width1 = width; width = PetscAbsReal(sty - stx); } } if ((ls->nfeval+ls->nfgeval) > ls->max_funcs) { ierr = PetscInfo2(ls,"Number of line search function evals (%D) > maximum (%D)\n",(ls->nfeval+ls->nfgeval),ls->max_funcs);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_MAXFCN; } /* Finish computations */ ierr = PetscInfo2(ls,"%D function evals in line search, step = %g\n",(ls->nfeval+ls->nfgeval),(double)ls->step);CHKERRQ(ierr); /* Set new solution vector and compute gradient if needed */ ierr = VecCopy(mt->work,x);CHKERRQ(ierr); if (!g_computed) { ierr = TaoLineSearchComputeGradient(ls,mt->work,g);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode TaoLineSearchApply_GPCG(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s) { TaoLineSearch_GPCG *neP = (TaoLineSearch_GPCG *)ls->data; PetscErrorCode ierr; PetscInt i; PetscBool g_computed=PETSC_FALSE; /* to prevent extra gradient computation */ PetscReal d1,finit,actred,prered,rho, gdx; PetscFunctionBegin; /* ls->stepmin - lower bound for step */ /* ls->stepmax - upper bound for step */ /* ls->rtol - relative tolerance for an acceptable step */ /* ls->ftol - tolerance for sufficient decrease condition */ /* ls->gtol - tolerance for curvature condition */ /* ls->nfeval - number of function evaluations */ /* ls->nfeval - number of function/gradient evaluations */ /* ls->max_funcs - maximum number of function evaluations */ ls->reason = TAOLINESEARCH_CONTINUE_ITERATING; ls->step = ls->initstep; if (!neP->W2) { ierr = VecDuplicate(x,&neP->W2);CHKERRQ(ierr); ierr = VecDuplicate(x,&neP->W1);CHKERRQ(ierr); ierr = VecDuplicate(x,&neP->Gold);CHKERRQ(ierr); neP->x = x; ierr = PetscObjectReference((PetscObject)neP->x);CHKERRQ(ierr); } else if (x != neP->x) { ierr = VecDestroy(&neP->x);CHKERRQ(ierr); ierr = VecDestroy(&neP->W1);CHKERRQ(ierr); ierr = VecDestroy(&neP->W2);CHKERRQ(ierr); ierr = VecDestroy(&neP->Gold);CHKERRQ(ierr); ierr = VecDuplicate(x,&neP->W1);CHKERRQ(ierr); ierr = VecDuplicate(x,&neP->W2);CHKERRQ(ierr); ierr = VecDuplicate(x,&neP->Gold);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject)neP->x);CHKERRQ(ierr); neP->x = x; ierr = PetscObjectReference((PetscObject)neP->x);CHKERRQ(ierr); } ierr = VecDot(g,s,&gdx);CHKERRQ(ierr); if (gdx > 0) { ierr = PetscInfo1(ls,"Line search error: search direction is not descent direction. dot(g,s) = %g\n",(double)gdx);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_FAILED_ASCENT; PetscFunctionReturn(0); } ierr = VecCopy(x,neP->W2);CHKERRQ(ierr); ierr = VecCopy(g,neP->Gold);CHKERRQ(ierr); if (ls->bounded) { /* Compute the smallest steplength that will make one nonbinding variable equal the bound */ ierr = VecStepBoundInfo(x,s,ls->lower,ls->upper,&rho,&actred,&d1);CHKERRQ(ierr); ls->step = PetscMin(ls->step,d1); } rho=0; actred=0; if (ls->step < 0) { ierr = PetscInfo1(ls,"Line search error: initial step parameter %g< 0\n",(double)ls->step);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_OTHER; PetscFunctionReturn(0); } /* Initialization */ finit = *f; for (i=0; i< ls->max_funcs; i++) { /* Force the step to be within the bounds */ ls->step = PetscMax(ls->step,ls->stepmin); ls->step = PetscMin(ls->step,ls->stepmax); ierr = VecCopy(x,neP->W2);CHKERRQ(ierr); ierr = VecAXPY(neP->W2,ls->step,s);CHKERRQ(ierr); if (ls->bounded) { /* Make sure new vector is numerically within bounds */ ierr = VecMedian(neP->W2,ls->lower,ls->upper,neP->W2);CHKERRQ(ierr); } /* Gradient is not needed here. Unless there is a separate gradient routine, compute it here anyway to prevent recomputing at the end of the line search */ if (ls->hasobjective) { ierr = TaoLineSearchComputeObjective(ls,neP->W2,f);CHKERRQ(ierr); g_computed=PETSC_FALSE; } else if (ls->usegts){ ierr = TaoLineSearchComputeObjectiveAndGTS(ls,neP->W2,f,&gdx);CHKERRQ(ierr); g_computed=PETSC_FALSE; } else { ierr = TaoLineSearchComputeObjectiveAndGradient(ls,neP->W2,f,g);CHKERRQ(ierr); g_computed=PETSC_TRUE; } if (0 == i) { ls->f_fullstep = *f; } actred = *f - finit; ierr = VecCopy(neP->W2,neP->W1);CHKERRQ(ierr); ierr = VecAXPY(neP->W1,-1.0,x);CHKERRQ(ierr); /* W1 = W2 - X */ ierr = VecDot(neP->W1,neP->Gold,&prered);CHKERRQ(ierr); if (fabs(prered)<1.0e-100) prered=1.0e-12; rho = actred/prered; /* If sufficient progress has been obtained, accept the point. Otherwise, backtrack. */ if (actred > 0) { ierr = PetscInfo(ls,"Step resulted in ascent, rejecting.\n");CHKERRQ(ierr); ls->step = (ls->step)/2; } else if (rho > ls->ftol){ break; } else{ ls->step = (ls->step)/2; } /* Convergence testing */ if (ls->step <= ls->stepmin || ls->step >= ls->stepmax) { ls->reason = TAOLINESEARCH_HALTED_OTHER; ierr = PetscInfo(ls,"Rounding errors may prevent further progress. May not be a step satisfying\n");CHKERRQ(ierr); ierr = PetscInfo(ls,"sufficient decrease and curvature conditions. Tolerances may be too small.\n");CHKERRQ(ierr); break; } if (ls->step == ls->stepmax) { ierr = PetscInfo1(ls,"Step is at the upper bound, stepmax (%g)\n",(double)ls->stepmax);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_UPPERBOUND; break; } if (ls->step == ls->stepmin) { ierr = PetscInfo1(ls,"Step is at the lower bound, stepmin (%g)\n",(double)ls->stepmin);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_LOWERBOUND; break; } if ((ls->nfeval+ls->nfgeval) >= ls->max_funcs) { ierr = PetscInfo2(ls,"Number of line search function evals (%D) > maximum (%D)\n",ls->nfeval+ls->nfgeval,ls->max_funcs);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_MAXFCN; break; } if ((neP->bracket) && (ls->stepmax - ls->stepmin <= ls->rtol*ls->stepmax)){ ierr = PetscInfo1(ls,"Relative width of interval of uncertainty is at most rtol (%g)\n",(double)ls->rtol);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_RTOL; break; } } ierr = PetscInfo2(ls,"%D function evals in line search, step = %g\n",ls->nfeval+ls->nfgeval,(double)ls->step);CHKERRQ(ierr); /* set new solution vector and compute gradient if necessary */ ierr = VecCopy(neP->W2, x);CHKERRQ(ierr); if (ls->reason == TAOLINESEARCH_CONTINUE_ITERATING) { ls->reason = TAOLINESEARCH_SUCCESS; } if (!g_computed) { ierr = TaoLineSearchComputeGradient(ls,x,g);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode TaoSolve_IPM(Tao tao) { PetscErrorCode ierr; TAO_IPM *ipmP = (TAO_IPM*)tao->data; TaoConvergedReason reason = TAO_CONTINUE_ITERATING; PetscInt its,i; PetscScalar stepsize=1.0; PetscScalar step_s,step_l,alpha,tau,sigma,phi_target; PetscFunctionBegin; /* Push initial point away from bounds */ ierr = IPMInitializeBounds(tao);CHKERRQ(ierr); ierr = IPMPushInitialPoint(tao);CHKERRQ(ierr); ierr = VecCopy(tao->solution,ipmP->rhs_x);CHKERRQ(ierr); ierr = IPMEvaluate(tao);CHKERRQ(ierr); ierr = IPMComputeKKT(tao);CHKERRQ(ierr); ierr = TaoMonitor(tao,tao->niter++,ipmP->kkt_f,ipmP->phi,0.0,1.0,&reason);CHKERRQ(ierr); while (reason == TAO_CONTINUE_ITERATING) { tao->ksp_its=0; ierr = IPMUpdateK(tao);CHKERRQ(ierr); /* rhs.x = -rd rhs.lame = -rpe rhs.lami = -rpi rhs.com = -com */ ierr = VecCopy(ipmP->rd,ipmP->rhs_x);CHKERRQ(ierr); if (ipmP->me > 0) { ierr = VecCopy(ipmP->rpe,ipmP->rhs_lamdae);CHKERRQ(ierr); } if (ipmP->nb > 0) { ierr = VecCopy(ipmP->rpi,ipmP->rhs_lamdai);CHKERRQ(ierr); ierr = VecCopy(ipmP->complementarity,ipmP->rhs_s);CHKERRQ(ierr); } ierr = IPMGatherRHS(tao,ipmP->bigrhs,ipmP->rhs_x,ipmP->rhs_lamdae,ipmP->rhs_lamdai,ipmP->rhs_s);CHKERRQ(ierr); ierr = VecScale(ipmP->bigrhs,-1.0);CHKERRQ(ierr); /* solve K * step = rhs */ ierr = KSPSetOperators(tao->ksp,ipmP->K,ipmP->K);CHKERRQ(ierr); ierr = KSPSolve(tao->ksp,ipmP->bigrhs,ipmP->bigstep);CHKERRQ(ierr); ierr = IPMScatterStep(tao,ipmP->bigstep,tao->stepdirection,ipmP->ds,ipmP->dlamdae,ipmP->dlamdai);CHKERRQ(ierr); ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); tao->ksp_its += its; tao->ksp_tot_its+=its; /* Find distance along step direction to closest bound */ if (ipmP->nb > 0) { ierr = VecStepBoundInfo(ipmP->s,ipmP->ds,ipmP->Zero_nb,ipmP->Inf_nb,&step_s,NULL,NULL);CHKERRQ(ierr); ierr = VecStepBoundInfo(ipmP->lamdai,ipmP->dlamdai,ipmP->Zero_nb,ipmP->Inf_nb,&step_l,NULL,NULL);CHKERRQ(ierr); alpha = PetscMin(step_s,step_l); alpha = PetscMin(alpha,1.0); ipmP->alpha1 = alpha; } else { ipmP->alpha1 = alpha = 1.0; } /* x_aff = x + alpha*d */ ierr = VecCopy(tao->solution,ipmP->save_x);CHKERRQ(ierr); if (ipmP->me > 0) { ierr = VecCopy(ipmP->lamdae,ipmP->save_lamdae);CHKERRQ(ierr); } if (ipmP->nb > 0) { ierr = VecCopy(ipmP->lamdai,ipmP->save_lamdai);CHKERRQ(ierr); ierr = VecCopy(ipmP->s,ipmP->save_s);CHKERRQ(ierr); } ierr = VecAXPY(tao->solution,alpha,tao->stepdirection);CHKERRQ(ierr); if (ipmP->me > 0) { ierr = VecAXPY(ipmP->lamdae,alpha,ipmP->dlamdae);CHKERRQ(ierr); } if (ipmP->nb > 0) { ierr = VecAXPY(ipmP->lamdai,alpha,ipmP->dlamdai);CHKERRQ(ierr); ierr = VecAXPY(ipmP->s,alpha,ipmP->ds);CHKERRQ(ierr); } /* Recompute kkt to find centering parameter sigma = (new_mu/old_mu)^3 */ if (ipmP->mu == 0.0) { sigma = 0.0; } else { sigma = 1.0/ipmP->mu; } ierr = IPMComputeKKT(tao);CHKERRQ(ierr); sigma *= ipmP->mu; sigma*=sigma*sigma; /* revert kkt info */ ierr = VecCopy(ipmP->save_x,tao->solution);CHKERRQ(ierr); if (ipmP->me > 0) { ierr = VecCopy(ipmP->save_lamdae,ipmP->lamdae);CHKERRQ(ierr); } if (ipmP->nb > 0) { ierr = VecCopy(ipmP->save_lamdai,ipmP->lamdai);CHKERRQ(ierr); ierr = VecCopy(ipmP->save_s,ipmP->s);CHKERRQ(ierr); } ierr = IPMComputeKKT(tao);CHKERRQ(ierr); /* update rhs with new complementarity vector */ if (ipmP->nb > 0) { ierr = VecCopy(ipmP->complementarity,ipmP->rhs_s);CHKERRQ(ierr); ierr = VecScale(ipmP->rhs_s,-1.0);CHKERRQ(ierr); ierr = VecShift(ipmP->rhs_s,sigma*ipmP->mu);CHKERRQ(ierr); } ierr = IPMGatherRHS(tao,ipmP->bigrhs,NULL,NULL,NULL,ipmP->rhs_s);CHKERRQ(ierr); /* solve K * step = rhs */ ierr = KSPSetOperators(tao->ksp,ipmP->K,ipmP->K);CHKERRQ(ierr); ierr = KSPSolve(tao->ksp,ipmP->bigrhs,ipmP->bigstep);CHKERRQ(ierr); ierr = IPMScatterStep(tao,ipmP->bigstep,tao->stepdirection,ipmP->ds,ipmP->dlamdae,ipmP->dlamdai);CHKERRQ(ierr); ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); tao->ksp_its += its; tao->ksp_tot_its+=its; if (ipmP->nb > 0) { /* Get max step size and apply frac-to-boundary */ tau = PetscMax(ipmP->taumin,1.0-ipmP->mu); tau = PetscMin(tau,1.0); if (tau != 1.0) { ierr = VecScale(ipmP->s,tau);CHKERRQ(ierr); ierr = VecScale(ipmP->lamdai,tau);CHKERRQ(ierr); } ierr = VecStepBoundInfo(ipmP->s,ipmP->ds,ipmP->Zero_nb,ipmP->Inf_nb,&step_s,NULL,NULL);CHKERRQ(ierr); ierr = VecStepBoundInfo(ipmP->lamdai,ipmP->dlamdai,ipmP->Zero_nb,ipmP->Inf_nb,&step_l,NULL,NULL);CHKERRQ(ierr); if (tau != 1.0) { ierr = VecCopy(ipmP->save_s,ipmP->s);CHKERRQ(ierr); ierr = VecCopy(ipmP->save_lamdai,ipmP->lamdai);CHKERRQ(ierr); } alpha = PetscMin(step_s,step_l); alpha = PetscMin(alpha,1.0); } else { alpha = 1.0; } ipmP->alpha2 = alpha; /* TODO make phi_target meaningful */ phi_target = ipmP->dec * ipmP->phi; for (i=0; i<11;i++) { ierr = VecAXPY(tao->solution,alpha,tao->stepdirection);CHKERRQ(ierr); if (ipmP->nb > 0) { ierr = VecAXPY(ipmP->s,alpha,ipmP->ds);CHKERRQ(ierr); ierr = VecAXPY(ipmP->lamdai,alpha,ipmP->dlamdai);CHKERRQ(ierr); } if (ipmP->me > 0) { ierr = VecAXPY(ipmP->lamdae,alpha,ipmP->dlamdae);CHKERRQ(ierr); } /* update dual variables */ if (ipmP->me > 0) { ierr = VecCopy(ipmP->lamdae,tao->DE);CHKERRQ(ierr); } ierr = IPMEvaluate(tao);CHKERRQ(ierr); ierr = IPMComputeKKT(tao);CHKERRQ(ierr); if (ipmP->phi <= phi_target) break; alpha /= 2.0; } ierr = TaoMonitor(tao,tao->niter,ipmP->kkt_f,ipmP->phi,0.0,stepsize,&reason);CHKERRQ(ierr); tao->niter++; } PetscFunctionReturn(0); }