1ba92ff59SBarry Smith #include <petsctaolinesearch.h> 2aaa7dc30SBarry Smith #include <../src/tao/constrained/impls/ipm/ipm.h> /*I "ipm.h" I*/ 31522df2eSJason Sarich 4a7e14dcfSSatish Balay /* 5a7e14dcfSSatish Balay x,d in R^n 6a7e14dcfSSatish Balay f in R 7a7e14dcfSSatish Balay nb = mi + nlb+nub 8a7e14dcfSSatish Balay s in R^nb is slack vector CI(x) / x-XL / -x+XU 9a7e14dcfSSatish Balay bin in R^mi (tao->constraints_inequality) 10a7e14dcfSSatish Balay beq in R^me (tao->constraints_equality) 11*a8d3b578SPierre Jolivet lambdai in R^nb (ipmP->lambdai) 12*a8d3b578SPierre Jolivet lambdae in R^me (ipmP->lambdae) 13a7e14dcfSSatish Balay Jeq in R^(me x n) (tao->jacobian_equality) 14a7e14dcfSSatish Balay Jin in R^(mi x n) (tao->jacobian_inequality) 15a7e14dcfSSatish Balay Ai in R^(nb x n) (ipmP->Ai) 16a7e14dcfSSatish Balay H in R^(n x n) (tao->hessian) 17a7e14dcfSSatish Balay min f=(1/2)*x'*H*x + d'*x 18a7e14dcfSSatish Balay s.t. CE(x) == 0 19a7e14dcfSSatish Balay CI(x) >= 0 20a7e14dcfSSatish Balay x >= tao->XL 21a7e14dcfSSatish Balay -x >= -tao->XU 22a7e14dcfSSatish Balay */ 23a7e14dcfSSatish Balay 24441846f8SBarry Smith static PetscErrorCode IPMComputeKKT(Tao tao); 25441846f8SBarry Smith static PetscErrorCode IPMPushInitialPoint(Tao tao); 26441846f8SBarry Smith static PetscErrorCode IPMEvaluate(Tao tao); 27441846f8SBarry Smith static PetscErrorCode IPMUpdateK(Tao tao); 28441846f8SBarry Smith static PetscErrorCode IPMUpdateAi(Tao tao); 29441846f8SBarry Smith static PetscErrorCode IPMGatherRHS(Tao tao, Vec, Vec, Vec, Vec, Vec); 30441846f8SBarry Smith static PetscErrorCode IPMScatterStep(Tao tao, Vec, Vec, Vec, Vec, Vec); 31441846f8SBarry Smith static PetscErrorCode IPMInitializeBounds(Tao tao); 32a7e14dcfSSatish Balay 33d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSolve_IPM(Tao tao) 34d71ae5a4SJacob Faibussowitsch { 35a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 368931d482SJason Sarich PetscInt its, i; 37a7e14dcfSSatish Balay PetscScalar stepsize = 1.0; 38a7e14dcfSSatish Balay PetscScalar step_s, step_l, alpha, tau, sigma, phi_target; 39a7e14dcfSSatish Balay 4047a47007SBarry Smith PetscFunctionBegin; 41a7e14dcfSSatish Balay /* Push initial point away from bounds */ 429566063dSJacob Faibussowitsch PetscCall(IPMInitializeBounds(tao)); 439566063dSJacob Faibussowitsch PetscCall(IPMPushInitialPoint(tao)); 449566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, ipmP->rhs_x)); 459566063dSJacob Faibussowitsch PetscCall(IPMEvaluate(tao)); 469566063dSJacob Faibussowitsch PetscCall(IPMComputeKKT(tao)); 47a7e14dcfSSatish Balay 48763847b4SAlp Dener tao->reason = TAO_CONTINUE_ITERATING; 499566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao, ipmP->kkt_f, ipmP->phi, 0.0, tao->ksp_its)); 509566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao, tao->niter, ipmP->kkt_f, ipmP->phi, 0.0, 1.0)); 51dbbe0bcdSBarry Smith PetscUseTypeMethod(tao, convergencetest, tao->cnvP); 52763847b4SAlp Dener 53763847b4SAlp Dener while (tao->reason == TAO_CONTINUE_ITERATING) { 54e1e80dc8SAlp Dener /* Call general purpose update function */ 55dbbe0bcdSBarry Smith PetscTryTypeMethod(tao, update, tao->niter, tao->user_update); 56e1e80dc8SAlp Dener 57b0026674SJason Sarich tao->ksp_its = 0; 589566063dSJacob Faibussowitsch PetscCall(IPMUpdateK(tao)); 59a7e14dcfSSatish Balay /* 60a7e14dcfSSatish Balay rhs.x = -rd 61a7e14dcfSSatish Balay rhs.lame = -rpe 62a7e14dcfSSatish Balay rhs.lami = -rpi 63a7e14dcfSSatish Balay rhs.com = -com 64a7e14dcfSSatish Balay */ 65a7e14dcfSSatish Balay 669566063dSJacob Faibussowitsch PetscCall(VecCopy(ipmP->rd, ipmP->rhs_x)); 67*a8d3b578SPierre Jolivet if (ipmP->me > 0) PetscCall(VecCopy(ipmP->rpe, ipmP->rhs_lambdae)); 68a7e14dcfSSatish Balay if (ipmP->nb > 0) { 69*a8d3b578SPierre Jolivet PetscCall(VecCopy(ipmP->rpi, ipmP->rhs_lambdai)); 709566063dSJacob Faibussowitsch PetscCall(VecCopy(ipmP->complementarity, ipmP->rhs_s)); 71a7e14dcfSSatish Balay } 72*a8d3b578SPierre Jolivet PetscCall(IPMGatherRHS(tao, ipmP->bigrhs, ipmP->rhs_x, ipmP->rhs_lambdae, ipmP->rhs_lambdai, ipmP->rhs_s)); 739566063dSJacob Faibussowitsch PetscCall(VecScale(ipmP->bigrhs, -1.0)); 74a7e14dcfSSatish Balay 75a7e14dcfSSatish Balay /* solve K * step = rhs */ 769566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(tao->ksp, ipmP->K, ipmP->K)); 779566063dSJacob Faibussowitsch PetscCall(KSPSolve(tao->ksp, ipmP->bigrhs, ipmP->bigstep)); 78a7e14dcfSSatish Balay 79*a8d3b578SPierre Jolivet PetscCall(IPMScatterStep(tao, ipmP->bigstep, tao->stepdirection, ipmP->ds, ipmP->dlambdae, ipmP->dlambdai)); 809566063dSJacob Faibussowitsch PetscCall(KSPGetIterationNumber(tao->ksp, &its)); 81a7e14dcfSSatish Balay tao->ksp_its += its; 82b0026674SJason Sarich tao->ksp_tot_its += its; 83a7e14dcfSSatish Balay /* Find distance along step direction to closest bound */ 84a7e14dcfSSatish Balay if (ipmP->nb > 0) { 859566063dSJacob Faibussowitsch PetscCall(VecStepBoundInfo(ipmP->s, ipmP->ds, ipmP->Zero_nb, ipmP->Inf_nb, &step_s, NULL, NULL)); 86*a8d3b578SPierre Jolivet PetscCall(VecStepBoundInfo(ipmP->lambdai, ipmP->dlambdai, ipmP->Zero_nb, ipmP->Inf_nb, &step_l, NULL, NULL)); 87a7e14dcfSSatish Balay alpha = PetscMin(step_s, step_l); 88a7e14dcfSSatish Balay alpha = PetscMin(alpha, 1.0); 89a7e14dcfSSatish Balay ipmP->alpha1 = alpha; 90a7e14dcfSSatish Balay } else { 91a7e14dcfSSatish Balay ipmP->alpha1 = alpha = 1.0; 92a7e14dcfSSatish Balay } 93a7e14dcfSSatish Balay 94a7e14dcfSSatish Balay /* x_aff = x + alpha*d */ 959566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, ipmP->save_x)); 96*a8d3b578SPierre Jolivet if (ipmP->me > 0) PetscCall(VecCopy(ipmP->lambdae, ipmP->save_lambdae)); 97a7e14dcfSSatish Balay if (ipmP->nb > 0) { 98*a8d3b578SPierre Jolivet PetscCall(VecCopy(ipmP->lambdai, ipmP->save_lambdai)); 999566063dSJacob Faibussowitsch PetscCall(VecCopy(ipmP->s, ipmP->save_s)); 100a7e14dcfSSatish Balay } 101a7e14dcfSSatish Balay 1029566063dSJacob Faibussowitsch PetscCall(VecAXPY(tao->solution, alpha, tao->stepdirection)); 103*a8d3b578SPierre Jolivet if (ipmP->me > 0) PetscCall(VecAXPY(ipmP->lambdae, alpha, ipmP->dlambdae)); 104a7e14dcfSSatish Balay if (ipmP->nb > 0) { 105*a8d3b578SPierre Jolivet PetscCall(VecAXPY(ipmP->lambdai, alpha, ipmP->dlambdai)); 1069566063dSJacob Faibussowitsch PetscCall(VecAXPY(ipmP->s, alpha, ipmP->ds)); 107a7e14dcfSSatish Balay } 108a7e14dcfSSatish Balay 109a7e14dcfSSatish Balay /* Recompute kkt to find centering parameter sigma = (new_mu/old_mu)^3 */ 110a7e14dcfSSatish Balay if (ipmP->mu == 0.0) { 111a7e14dcfSSatish Balay sigma = 0.0; 112a7e14dcfSSatish Balay } else { 113a7e14dcfSSatish Balay sigma = 1.0 / ipmP->mu; 114a7e14dcfSSatish Balay } 1159566063dSJacob Faibussowitsch PetscCall(IPMComputeKKT(tao)); 116a7e14dcfSSatish Balay sigma *= ipmP->mu; 117a7e14dcfSSatish Balay sigma *= sigma * sigma; 118a7e14dcfSSatish Balay 119a7e14dcfSSatish Balay /* revert kkt info */ 1209566063dSJacob Faibussowitsch PetscCall(VecCopy(ipmP->save_x, tao->solution)); 121*a8d3b578SPierre Jolivet if (ipmP->me > 0) PetscCall(VecCopy(ipmP->save_lambdae, ipmP->lambdae)); 122a7e14dcfSSatish Balay if (ipmP->nb > 0) { 123*a8d3b578SPierre Jolivet PetscCall(VecCopy(ipmP->save_lambdai, ipmP->lambdai)); 1249566063dSJacob Faibussowitsch PetscCall(VecCopy(ipmP->save_s, ipmP->s)); 125a7e14dcfSSatish Balay } 1269566063dSJacob Faibussowitsch PetscCall(IPMComputeKKT(tao)); 127a7e14dcfSSatish Balay 128a7e14dcfSSatish Balay /* update rhs with new complementarity vector */ 129a7e14dcfSSatish Balay if (ipmP->nb > 0) { 1309566063dSJacob Faibussowitsch PetscCall(VecCopy(ipmP->complementarity, ipmP->rhs_s)); 1319566063dSJacob Faibussowitsch PetscCall(VecScale(ipmP->rhs_s, -1.0)); 1329566063dSJacob Faibussowitsch PetscCall(VecShift(ipmP->rhs_s, sigma * ipmP->mu)); 133a7e14dcfSSatish Balay } 1349566063dSJacob Faibussowitsch PetscCall(IPMGatherRHS(tao, ipmP->bigrhs, NULL, NULL, NULL, ipmP->rhs_s)); 135a7e14dcfSSatish Balay 136a7e14dcfSSatish Balay /* solve K * step = rhs */ 1379566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(tao->ksp, ipmP->K, ipmP->K)); 1389566063dSJacob Faibussowitsch PetscCall(KSPSolve(tao->ksp, ipmP->bigrhs, ipmP->bigstep)); 139a7e14dcfSSatish Balay 140*a8d3b578SPierre Jolivet PetscCall(IPMScatterStep(tao, ipmP->bigstep, tao->stepdirection, ipmP->ds, ipmP->dlambdae, ipmP->dlambdai)); 1419566063dSJacob Faibussowitsch PetscCall(KSPGetIterationNumber(tao->ksp, &its)); 142a7e14dcfSSatish Balay tao->ksp_its += its; 143b0026674SJason Sarich tao->ksp_tot_its += its; 144a7e14dcfSSatish Balay if (ipmP->nb > 0) { 145a7e14dcfSSatish Balay /* Get max step size and apply frac-to-boundary */ 146a7e14dcfSSatish Balay tau = PetscMax(ipmP->taumin, 1.0 - ipmP->mu); 147a7e14dcfSSatish Balay tau = PetscMin(tau, 1.0); 148a7e14dcfSSatish Balay if (tau != 1.0) { 1499566063dSJacob Faibussowitsch PetscCall(VecScale(ipmP->s, tau)); 150*a8d3b578SPierre Jolivet PetscCall(VecScale(ipmP->lambdai, tau)); 151a7e14dcfSSatish Balay } 1529566063dSJacob Faibussowitsch PetscCall(VecStepBoundInfo(ipmP->s, ipmP->ds, ipmP->Zero_nb, ipmP->Inf_nb, &step_s, NULL, NULL)); 153*a8d3b578SPierre Jolivet PetscCall(VecStepBoundInfo(ipmP->lambdai, ipmP->dlambdai, ipmP->Zero_nb, ipmP->Inf_nb, &step_l, NULL, NULL)); 154a7e14dcfSSatish Balay if (tau != 1.0) { 1559566063dSJacob Faibussowitsch PetscCall(VecCopy(ipmP->save_s, ipmP->s)); 156*a8d3b578SPierre Jolivet PetscCall(VecCopy(ipmP->save_lambdai, ipmP->lambdai)); 157a7e14dcfSSatish Balay } 158a7e14dcfSSatish Balay alpha = PetscMin(step_s, step_l); 159a7e14dcfSSatish Balay alpha = PetscMin(alpha, 1.0); 160a7e14dcfSSatish Balay } else { 161a7e14dcfSSatish Balay alpha = 1.0; 162a7e14dcfSSatish Balay } 163a7e14dcfSSatish Balay ipmP->alpha2 = alpha; 164a7e14dcfSSatish Balay /* TODO make phi_target meaningful */ 165a7e14dcfSSatish Balay phi_target = ipmP->dec * ipmP->phi; 166a7e14dcfSSatish Balay for (i = 0; i < 11; i++) { 1679566063dSJacob Faibussowitsch PetscCall(VecAXPY(tao->solution, alpha, tao->stepdirection)); 168a7e14dcfSSatish Balay if (ipmP->nb > 0) { 1699566063dSJacob Faibussowitsch PetscCall(VecAXPY(ipmP->s, alpha, ipmP->ds)); 170*a8d3b578SPierre Jolivet PetscCall(VecAXPY(ipmP->lambdai, alpha, ipmP->dlambdai)); 171a7e14dcfSSatish Balay } 172*a8d3b578SPierre Jolivet if (ipmP->me > 0) PetscCall(VecAXPY(ipmP->lambdae, alpha, ipmP->dlambdae)); 173a7e14dcfSSatish Balay 174a7e14dcfSSatish Balay /* update dual variables */ 175*a8d3b578SPierre Jolivet if (ipmP->me > 0) PetscCall(VecCopy(ipmP->lambdae, tao->DE)); 176a7e14dcfSSatish Balay 1779566063dSJacob Faibussowitsch PetscCall(IPMEvaluate(tao)); 1789566063dSJacob Faibussowitsch PetscCall(IPMComputeKKT(tao)); 179a7e14dcfSSatish Balay if (ipmP->phi <= phi_target) break; 180a7e14dcfSSatish Balay alpha /= 2.0; 181a7e14dcfSSatish Balay } 182a7e14dcfSSatish Balay 1839566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao, ipmP->kkt_f, ipmP->phi, 0.0, tao->ksp_its)); 1849566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao, tao->niter, ipmP->kkt_f, ipmP->phi, 0.0, stepsize)); 185dbbe0bcdSBarry Smith PetscUseTypeMethod(tao, convergencetest, tao->cnvP); 1868931d482SJason Sarich tao->niter++; 187a7e14dcfSSatish Balay } 188a7e14dcfSSatish Balay PetscFunctionReturn(0); 189a7e14dcfSSatish Balay } 190a7e14dcfSSatish Balay 191d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSetup_IPM(Tao tao) 192d71ae5a4SJacob Faibussowitsch { 193a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 194a7e14dcfSSatish Balay 195a7e14dcfSSatish Balay PetscFunctionBegin; 196a7e14dcfSSatish Balay ipmP->nb = ipmP->mi = ipmP->me = 0; 19783c8fe1dSLisandro Dalcin ipmP->K = NULL; 1989566063dSJacob Faibussowitsch PetscCall(VecGetSize(tao->solution, &ipmP->n)); 199a7e14dcfSSatish Balay if (!tao->gradient) { 2009566063dSJacob Faibussowitsch PetscCall(VecDuplicate(tao->solution, &tao->gradient)); 2019566063dSJacob Faibussowitsch PetscCall(VecDuplicate(tao->solution, &tao->stepdirection)); 2029566063dSJacob Faibussowitsch PetscCall(VecDuplicate(tao->solution, &ipmP->rd)); 2039566063dSJacob Faibussowitsch PetscCall(VecDuplicate(tao->solution, &ipmP->rhs_x)); 2049566063dSJacob Faibussowitsch PetscCall(VecDuplicate(tao->solution, &ipmP->work)); 2059566063dSJacob Faibussowitsch PetscCall(VecDuplicate(tao->solution, &ipmP->save_x)); 206a7e14dcfSSatish Balay } 207a7e14dcfSSatish Balay if (tao->constraints_equality) { 2089566063dSJacob Faibussowitsch PetscCall(VecGetSize(tao->constraints_equality, &ipmP->me)); 209*a8d3b578SPierre Jolivet PetscCall(VecDuplicate(tao->constraints_equality, &ipmP->lambdae)); 210*a8d3b578SPierre Jolivet PetscCall(VecDuplicate(tao->constraints_equality, &ipmP->dlambdae)); 211*a8d3b578SPierre Jolivet PetscCall(VecDuplicate(tao->constraints_equality, &ipmP->rhs_lambdae)); 212*a8d3b578SPierre Jolivet PetscCall(VecDuplicate(tao->constraints_equality, &ipmP->save_lambdae)); 2139566063dSJacob Faibussowitsch PetscCall(VecDuplicate(tao->constraints_equality, &ipmP->rpe)); 2149566063dSJacob Faibussowitsch PetscCall(VecDuplicate(tao->constraints_equality, &tao->DE)); 215a7e14dcfSSatish Balay } 21648a46eb9SPierre Jolivet if (tao->constraints_inequality) PetscCall(VecDuplicate(tao->constraints_inequality, &tao->DI)); 217a7e14dcfSSatish Balay PetscFunctionReturn(0); 218a7e14dcfSSatish Balay } 219a7e14dcfSSatish Balay 220d71ae5a4SJacob Faibussowitsch static PetscErrorCode IPMInitializeBounds(Tao tao) 221d71ae5a4SJacob Faibussowitsch { 222a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 223a7e14dcfSSatish Balay Vec xtmp; 224a7e14dcfSSatish Balay PetscInt xstart, xend; 225a7e14dcfSSatish Balay PetscInt ucstart, ucend; /* user ci */ 226a7e14dcfSSatish Balay PetscInt ucestart, uceend; /* user ce */ 227b99af1fdSBarry Smith PetscInt sstart = 0, send = 0; 228a7e14dcfSSatish Balay PetscInt bigsize; 229a7e14dcfSSatish Balay PetscInt i, counter, nloc; 230a7e14dcfSSatish Balay PetscInt *cind, *xind, *ucind, *uceind, *stepind; 231a7e14dcfSSatish Balay VecType vtype; 232a7e14dcfSSatish Balay const PetscInt *xli, *xui; 233a7e14dcfSSatish Balay PetscInt xl_offset, xu_offset; 234a7e14dcfSSatish Balay IS bigxl, bigxu, isuc, isc, isx, sis, is1; 235a7e14dcfSSatish Balay MPI_Comm comm; 23647a47007SBarry Smith 237a7e14dcfSSatish Balay PetscFunctionBegin; 23883c8fe1dSLisandro Dalcin cind = xind = ucind = uceind = stepind = NULL; 239a7e14dcfSSatish Balay ipmP->mi = 0; 240a7e14dcfSSatish Balay ipmP->nxlb = 0; 241a7e14dcfSSatish Balay ipmP->nxub = 0; 242a7e14dcfSSatish Balay ipmP->nb = 0; 243a7e14dcfSSatish Balay ipmP->nslack = 0; 244a7e14dcfSSatish Balay 2459566063dSJacob Faibussowitsch PetscCall(VecDuplicate(tao->solution, &xtmp)); 2469566063dSJacob Faibussowitsch PetscCall(TaoComputeVariableBounds(tao)); 247a7e14dcfSSatish Balay if (tao->XL) { 2489566063dSJacob Faibussowitsch PetscCall(VecSet(xtmp, PETSC_NINFINITY)); 2499566063dSJacob Faibussowitsch PetscCall(VecWhichGreaterThan(tao->XL, xtmp, &ipmP->isxl)); 2509566063dSJacob Faibussowitsch PetscCall(ISGetSize(ipmP->isxl, &ipmP->nxlb)); 251a7e14dcfSSatish Balay } else { 252a7e14dcfSSatish Balay ipmP->nxlb = 0; 253a7e14dcfSSatish Balay } 254a7e14dcfSSatish Balay if (tao->XU) { 2559566063dSJacob Faibussowitsch PetscCall(VecSet(xtmp, PETSC_INFINITY)); 2569566063dSJacob Faibussowitsch PetscCall(VecWhichLessThan(tao->XU, xtmp, &ipmP->isxu)); 2579566063dSJacob Faibussowitsch PetscCall(ISGetSize(ipmP->isxu, &ipmP->nxub)); 258a7e14dcfSSatish Balay } else { 259a7e14dcfSSatish Balay ipmP->nxub = 0; 260a7e14dcfSSatish Balay } 2619566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xtmp)); 262a7e14dcfSSatish Balay if (tao->constraints_inequality) { 2639566063dSJacob Faibussowitsch PetscCall(VecGetSize(tao->constraints_inequality, &ipmP->mi)); 264a7e14dcfSSatish Balay } else { 265a7e14dcfSSatish Balay ipmP->mi = 0; 266a7e14dcfSSatish Balay } 267a7e14dcfSSatish Balay ipmP->nb = ipmP->nxlb + ipmP->nxub + ipmP->mi; 268a7e14dcfSSatish Balay 2699566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)tao->solution, &comm)); 270a7e14dcfSSatish Balay 271a7e14dcfSSatish Balay bigsize = ipmP->n + 2 * ipmP->nb + ipmP->me; 2729566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bigsize, &stepind)); 2739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ipmP->n, &xind)); 2749566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ipmP->me, &uceind)); 2759566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(tao->solution, &xstart, &xend)); 276a7e14dcfSSatish Balay 277a7e14dcfSSatish Balay if (ipmP->nb > 0) { 2789566063dSJacob Faibussowitsch PetscCall(VecCreate(comm, &ipmP->s)); 2799566063dSJacob Faibussowitsch PetscCall(VecSetSizes(ipmP->s, PETSC_DECIDE, ipmP->nb)); 2809566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(ipmP->s)); 2819566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->s, &ipmP->ds)); 2829566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->s, &ipmP->rhs_s)); 2839566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->s, &ipmP->complementarity)); 2849566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->s, &ipmP->ci)); 285a7e14dcfSSatish Balay 286*a8d3b578SPierre Jolivet PetscCall(VecDuplicate(ipmP->s, &ipmP->lambdai)); 287*a8d3b578SPierre Jolivet PetscCall(VecDuplicate(ipmP->s, &ipmP->dlambdai)); 288*a8d3b578SPierre Jolivet PetscCall(VecDuplicate(ipmP->s, &ipmP->rhs_lambdai)); 289*a8d3b578SPierre Jolivet PetscCall(VecDuplicate(ipmP->s, &ipmP->save_lambdai)); 290a7e14dcfSSatish Balay 2919566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->s, &ipmP->save_s)); 2929566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->s, &ipmP->rpi)); 2939566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->s, &ipmP->Zero_nb)); 2949566063dSJacob Faibussowitsch PetscCall(VecSet(ipmP->Zero_nb, 0.0)); 2959566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->s, &ipmP->One_nb)); 2969566063dSJacob Faibussowitsch PetscCall(VecSet(ipmP->One_nb, 1.0)); 2979566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->s, &ipmP->Inf_nb)); 2989566063dSJacob Faibussowitsch PetscCall(VecSet(ipmP->Inf_nb, PETSC_INFINITY)); 299a7e14dcfSSatish Balay 3009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ipmP->nb, &cind)); 3019566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ipmP->mi, &ucind)); 3029566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(ipmP->s, &sstart, &send)); 303a7e14dcfSSatish Balay 304a7e14dcfSSatish Balay if (ipmP->mi > 0) { 3059566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(tao->constraints_inequality, &ucstart, &ucend)); 306a7e14dcfSSatish Balay counter = 0; 307ad540459SPierre Jolivet for (i = ucstart; i < ucend; i++) cind[counter++] = i; 3089566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, counter, cind, PETSC_COPY_VALUES, &isuc)); 3099566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, counter, cind, PETSC_COPY_VALUES, &isc)); 3109566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(tao->constraints_inequality, isuc, ipmP->ci, isc, &ipmP->ci_scat)); 311a7e14dcfSSatish Balay 3129566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isuc)); 3139566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isc)); 314a7e14dcfSSatish Balay } 315a7e14dcfSSatish Balay /* need to know how may xbound indices are on each process */ 316a7e14dcfSSatish Balay /* TODO better way */ 317a7e14dcfSSatish Balay if (ipmP->nxlb) { 3189566063dSJacob Faibussowitsch PetscCall(ISAllGather(ipmP->isxl, &bigxl)); 3199566063dSJacob Faibussowitsch PetscCall(ISGetIndices(bigxl, &xli)); 320a7e14dcfSSatish Balay /* find offsets for this processor */ 321a7e14dcfSSatish Balay xl_offset = ipmP->mi; 322a7e14dcfSSatish Balay for (i = 0; i < ipmP->nxlb; i++) { 323a7e14dcfSSatish Balay if (xli[i] < xstart) { 324a7e14dcfSSatish Balay xl_offset++; 325a7e14dcfSSatish Balay } else break; 326a7e14dcfSSatish Balay } 3279566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(bigxl, &xli)); 328a7e14dcfSSatish Balay 3299566063dSJacob Faibussowitsch PetscCall(ISGetIndices(ipmP->isxl, &xli)); 3309566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(ipmP->isxl, &nloc)); 331a7e14dcfSSatish Balay for (i = 0; i < nloc; i++) { 332a7e14dcfSSatish Balay xind[i] = xli[i]; 333a7e14dcfSSatish Balay cind[i] = xl_offset + i; 334a7e14dcfSSatish Balay } 335a7e14dcfSSatish Balay 3369566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, nloc, xind, PETSC_COPY_VALUES, &isx)); 3379566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, nloc, cind, PETSC_COPY_VALUES, &isc)); 3389566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(tao->XL, isx, ipmP->ci, isc, &ipmP->xl_scat)); 3399566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isx)); 3409566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isc)); 3419566063dSJacob Faibussowitsch PetscCall(ISDestroy(&bigxl)); 342a7e14dcfSSatish Balay } 343a7e14dcfSSatish Balay 344a7e14dcfSSatish Balay if (ipmP->nxub) { 3459566063dSJacob Faibussowitsch PetscCall(ISAllGather(ipmP->isxu, &bigxu)); 3469566063dSJacob Faibussowitsch PetscCall(ISGetIndices(bigxu, &xui)); 347a7e14dcfSSatish Balay /* find offsets for this processor */ 348a7e14dcfSSatish Balay xu_offset = ipmP->mi + ipmP->nxlb; 349a7e14dcfSSatish Balay for (i = 0; i < ipmP->nxub; i++) { 350a7e14dcfSSatish Balay if (xui[i] < xstart) { 351a7e14dcfSSatish Balay xu_offset++; 352a7e14dcfSSatish Balay } else break; 353a7e14dcfSSatish Balay } 3549566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(bigxu, &xui)); 355a7e14dcfSSatish Balay 3569566063dSJacob Faibussowitsch PetscCall(ISGetIndices(ipmP->isxu, &xui)); 3579566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(ipmP->isxu, &nloc)); 358a7e14dcfSSatish Balay for (i = 0; i < nloc; i++) { 359a7e14dcfSSatish Balay xind[i] = xui[i]; 360a7e14dcfSSatish Balay cind[i] = xu_offset + i; 361a7e14dcfSSatish Balay } 362a7e14dcfSSatish Balay 3639566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, nloc, xind, PETSC_COPY_VALUES, &isx)); 3649566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, nloc, cind, PETSC_COPY_VALUES, &isc)); 3659566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(tao->XU, isx, ipmP->ci, isc, &ipmP->xu_scat)); 3669566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isx)); 3679566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isc)); 3689566063dSJacob Faibussowitsch PetscCall(ISDestroy(&bigxu)); 369a7e14dcfSSatish Balay } 370a7e14dcfSSatish Balay } 3719566063dSJacob Faibussowitsch PetscCall(VecCreate(comm, &ipmP->bigrhs)); 3729566063dSJacob Faibussowitsch PetscCall(VecGetType(tao->solution, &vtype)); 3739566063dSJacob Faibussowitsch PetscCall(VecSetType(ipmP->bigrhs, vtype)); 3749566063dSJacob Faibussowitsch PetscCall(VecSetSizes(ipmP->bigrhs, PETSC_DECIDE, bigsize)); 3759566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(ipmP->bigrhs)); 3769566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ipmP->bigrhs, &ipmP->bigstep)); 377a7e14dcfSSatish Balay 378a7e14dcfSSatish Balay /* create scatters for step->x and x->rhs */ 379a7e14dcfSSatish Balay for (i = xstart; i < xend; i++) { 380a7e14dcfSSatish Balay stepind[i - xstart] = i; 381a7e14dcfSSatish Balay xind[i - xstart] = i; 382a7e14dcfSSatish Balay } 3839566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, xend - xstart, stepind, PETSC_COPY_VALUES, &sis)); 3849566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, xend - xstart, xind, PETSC_COPY_VALUES, &is1)); 3859566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(ipmP->bigstep, sis, tao->solution, is1, &ipmP->step1)); 3869566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(tao->solution, is1, ipmP->bigrhs, sis, &ipmP->rhs1)); 3879566063dSJacob Faibussowitsch PetscCall(ISDestroy(&sis)); 3889566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 389a7e14dcfSSatish Balay 390a7e14dcfSSatish Balay if (ipmP->nb > 0) { 391a7e14dcfSSatish Balay for (i = sstart; i < send; i++) { 392a7e14dcfSSatish Balay stepind[i - sstart] = i + ipmP->n; 393a7e14dcfSSatish Balay cind[i - sstart] = i; 394a7e14dcfSSatish Balay } 3959566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, send - sstart, stepind, PETSC_COPY_VALUES, &sis)); 3969566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, send - sstart, cind, PETSC_COPY_VALUES, &is1)); 3979566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(ipmP->bigstep, sis, ipmP->s, is1, &ipmP->step2)); 3989566063dSJacob Faibussowitsch PetscCall(ISDestroy(&sis)); 399a7e14dcfSSatish Balay 400a7e14dcfSSatish Balay for (i = sstart; i < send; i++) { 401a7e14dcfSSatish Balay stepind[i - sstart] = i + ipmP->n + ipmP->me; 402a7e14dcfSSatish Balay cind[i - sstart] = i; 403a7e14dcfSSatish Balay } 4049566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, send - sstart, stepind, PETSC_COPY_VALUES, &sis)); 4059566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(ipmP->s, is1, ipmP->bigrhs, sis, &ipmP->rhs3)); 4069566063dSJacob Faibussowitsch PetscCall(ISDestroy(&sis)); 4079566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 408a7e14dcfSSatish Balay } 409a7e14dcfSSatish Balay 410a7e14dcfSSatish Balay if (ipmP->me > 0) { 4119566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(tao->constraints_equality, &ucestart, &uceend)); 412a7e14dcfSSatish Balay for (i = ucestart; i < uceend; i++) { 413a7e14dcfSSatish Balay stepind[i - ucestart] = i + ipmP->n + ipmP->nb; 414a7e14dcfSSatish Balay uceind[i - ucestart] = i; 415a7e14dcfSSatish Balay } 416a7e14dcfSSatish Balay 4179566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, uceend - ucestart, stepind, PETSC_COPY_VALUES, &sis)); 4189566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, uceend - ucestart, uceind, PETSC_COPY_VALUES, &is1)); 4199566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(ipmP->bigstep, sis, tao->constraints_equality, is1, &ipmP->step3)); 4209566063dSJacob Faibussowitsch PetscCall(ISDestroy(&sis)); 421a7e14dcfSSatish Balay 422ad540459SPierre Jolivet for (i = ucestart; i < uceend; i++) stepind[i - ucestart] = i + ipmP->n; 423a7e14dcfSSatish Balay 4249566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, uceend - ucestart, stepind, PETSC_COPY_VALUES, &sis)); 4259566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(tao->constraints_equality, is1, ipmP->bigrhs, sis, &ipmP->rhs2)); 4269566063dSJacob Faibussowitsch PetscCall(ISDestroy(&sis)); 4279566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 428a7e14dcfSSatish Balay } 429a7e14dcfSSatish Balay 430a7e14dcfSSatish Balay if (ipmP->nb > 0) { 431a7e14dcfSSatish Balay for (i = sstart; i < send; i++) { 432a7e14dcfSSatish Balay stepind[i - sstart] = i + ipmP->n + ipmP->nb + ipmP->me; 433a7e14dcfSSatish Balay cind[i - sstart] = i; 434a7e14dcfSSatish Balay } 4359566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, send - sstart, cind, PETSC_COPY_VALUES, &is1)); 4369566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, send - sstart, stepind, PETSC_COPY_VALUES, &sis)); 4379566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(ipmP->bigstep, sis, ipmP->s, is1, &ipmP->step4)); 4389566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(ipmP->s, is1, ipmP->bigrhs, sis, &ipmP->rhs4)); 4399566063dSJacob Faibussowitsch PetscCall(ISDestroy(&sis)); 4409566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 441a7e14dcfSSatish Balay } 442a7e14dcfSSatish Balay 4439566063dSJacob Faibussowitsch PetscCall(PetscFree(stepind)); 4449566063dSJacob Faibussowitsch PetscCall(PetscFree(cind)); 4459566063dSJacob Faibussowitsch PetscCall(PetscFree(ucind)); 4469566063dSJacob Faibussowitsch PetscCall(PetscFree(uceind)); 4479566063dSJacob Faibussowitsch PetscCall(PetscFree(xind)); 448a7e14dcfSSatish Balay PetscFunctionReturn(0); 449a7e14dcfSSatish Balay } 450a7e14dcfSSatish Balay 451d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoDestroy_IPM(Tao tao) 452d71ae5a4SJacob Faibussowitsch { 453a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 45447a47007SBarry Smith 455a7e14dcfSSatish Balay PetscFunctionBegin; 4569566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->rd)); 4579566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->rpe)); 4589566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->rpi)); 4599566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->work)); 460*a8d3b578SPierre Jolivet PetscCall(VecDestroy(&ipmP->lambdae)); 461*a8d3b578SPierre Jolivet PetscCall(VecDestroy(&ipmP->lambdai)); 4629566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->s)); 4639566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->ds)); 4649566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->ci)); 465a7e14dcfSSatish Balay 4669566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->rhs_x)); 467*a8d3b578SPierre Jolivet PetscCall(VecDestroy(&ipmP->rhs_lambdae)); 468*a8d3b578SPierre Jolivet PetscCall(VecDestroy(&ipmP->rhs_lambdai)); 4699566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->rhs_s)); 470a7e14dcfSSatish Balay 4719566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->save_x)); 472*a8d3b578SPierre Jolivet PetscCall(VecDestroy(&ipmP->save_lambdae)); 473*a8d3b578SPierre Jolivet PetscCall(VecDestroy(&ipmP->save_lambdai)); 4749566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->save_s)); 475a7e14dcfSSatish Balay 4769566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->step1)); 4779566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->step2)); 4789566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->step3)); 4799566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->step4)); 480a7e14dcfSSatish Balay 4819566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->rhs1)); 4829566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->rhs2)); 4839566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->rhs3)); 4849566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->rhs4)); 485a7e14dcfSSatish Balay 4869566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->ci_scat)); 4879566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->xl_scat)); 4889566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&ipmP->xu_scat)); 489a7e14dcfSSatish Balay 490*a8d3b578SPierre Jolivet PetscCall(VecDestroy(&ipmP->dlambdai)); 491*a8d3b578SPierre Jolivet PetscCall(VecDestroy(&ipmP->dlambdae)); 4929566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->Zero_nb)); 4939566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->One_nb)); 4949566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->Inf_nb)); 4959566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->complementarity)); 496a7e14dcfSSatish Balay 4979566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->bigrhs)); 4989566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ipmP->bigstep)); 4999566063dSJacob Faibussowitsch PetscCall(MatDestroy(&ipmP->Ai)); 5009566063dSJacob Faibussowitsch PetscCall(MatDestroy(&ipmP->K)); 5019566063dSJacob Faibussowitsch PetscCall(ISDestroy(&ipmP->isxu)); 5029566063dSJacob Faibussowitsch PetscCall(ISDestroy(&ipmP->isxl)); 503a958fbfcSStefano Zampini PetscCall(KSPDestroy(&tao->ksp)); 5049566063dSJacob Faibussowitsch PetscCall(PetscFree(tao->data)); 505a7e14dcfSSatish Balay PetscFunctionReturn(0); 506a7e14dcfSSatish Balay } 507a7e14dcfSSatish Balay 508d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSetFromOptions_IPM(Tao tao, PetscOptionItems *PetscOptionsObject) 509d71ae5a4SJacob Faibussowitsch { 510a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 51147a47007SBarry Smith 512a7e14dcfSSatish Balay PetscFunctionBegin; 513d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "IPM method for constrained optimization"); 5149566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-tao_ipm_monitorkkt", "monitor kkt status", NULL, ipmP->monitorkkt, &ipmP->monitorkkt, NULL)); 5159566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-tao_ipm_pushs", "parameter to push initial slack variables away from bounds", NULL, ipmP->pushs, &ipmP->pushs, NULL)); 5169566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-tao_ipm_pushnu", "parameter to push initial (inequality) dual variables away from bounds", NULL, ipmP->pushnu, &ipmP->pushnu, NULL)); 517d0609cedSBarry Smith PetscOptionsHeadEnd(); 5189566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(tao->ksp)); 519a7e14dcfSSatish Balay PetscFunctionReturn(0); 520a7e14dcfSSatish Balay } 521a7e14dcfSSatish Balay 522d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoView_IPM(Tao tao, PetscViewer viewer) 523d71ae5a4SJacob Faibussowitsch { 524a7e14dcfSSatish Balay return 0; 525a7e14dcfSSatish Balay } 526a7e14dcfSSatish Balay 527a7e14dcfSSatish Balay /* IPMObjectiveAndGradient() 528a7e14dcfSSatish Balay f = d'x + 0.5 * x' * H * x 529a7e14dcfSSatish Balay rd = H*x + d + Ae'*lame - Ai'*lami 530a7e14dcfSSatish Balay rpe = Ae*x - be 531a7e14dcfSSatish Balay rpi = Ai*x - yi - bi 532a7e14dcfSSatish Balay mu = yi' * lami/mi; 533a7e14dcfSSatish Balay com = yi.*lami 534a7e14dcfSSatish Balay 535a7e14dcfSSatish Balay phi = ||rd|| + ||rpe|| + ||rpi|| + ||com|| 536a7e14dcfSSatish Balay */ 537a7e14dcfSSatish Balay /* 538a7e14dcfSSatish Balay static PetscErrorCode IPMObjective(TaoLineSearch ls, Vec X, PetscReal *f, void *tptr) 539a7e14dcfSSatish Balay { 540441846f8SBarry Smith Tao tao = (Tao)tptr; 541a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM*)tao->data; 542a7e14dcfSSatish Balay PetscFunctionBegin; 5439566063dSJacob Faibussowitsch PetscCall(IPMComputeKKT(tao)); 544a7e14dcfSSatish Balay *f = ipmP->phi; 545a7e14dcfSSatish Balay PetscFunctionReturn(0); 546a7e14dcfSSatish Balay } 547a7e14dcfSSatish Balay */ 548a7e14dcfSSatish Balay 549a7e14dcfSSatish Balay /* 550a7e14dcfSSatish Balay f = d'x + 0.5 * x' * H * x 551a7e14dcfSSatish Balay rd = H*x + d + Ae'*lame - Ai'*lami 552a7e14dcfSSatish Balay Ai = jac_ineq 553a7e14dcfSSatish Balay I (w/lb) 554a7e14dcfSSatish Balay -I (w/ub) 555a7e14dcfSSatish Balay 556a7e14dcfSSatish Balay rpe = ce 557a7e14dcfSSatish Balay rpi = ci - s; 558a7e14dcfSSatish Balay com = s.*lami 559a7e14dcfSSatish Balay mu = yi' * lami/mi; 560a7e14dcfSSatish Balay 561a7e14dcfSSatish Balay phi = ||rd|| + ||rpe|| + ||rpi|| + ||com|| 562a7e14dcfSSatish Balay */ 563d71ae5a4SJacob Faibussowitsch static PetscErrorCode IPMComputeKKT(Tao tao) 564d71ae5a4SJacob Faibussowitsch { 565a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 566a7e14dcfSSatish Balay PetscScalar norm; 56747a47007SBarry Smith 56847a47007SBarry Smith PetscFunctionBegin; 5699566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, ipmP->rd)); 570a7e14dcfSSatish Balay 571a7e14dcfSSatish Balay if (ipmP->me > 0) { 572*a8d3b578SPierre Jolivet /* rd = gradient + Ae'*lambdae */ 573*a8d3b578SPierre Jolivet PetscCall(MatMultTranspose(tao->jacobian_equality, ipmP->lambdae, ipmP->work)); 5749566063dSJacob Faibussowitsch PetscCall(VecAXPY(ipmP->rd, 1.0, ipmP->work)); 575a7e14dcfSSatish Balay 576a7e14dcfSSatish Balay /* rpe = ce(x) */ 5779566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->constraints_equality, ipmP->rpe)); 578a7e14dcfSSatish Balay } 579a7e14dcfSSatish Balay if (ipmP->nb > 0) { 580*a8d3b578SPierre Jolivet /* rd = rd - Ai'*lambdai */ 581*a8d3b578SPierre Jolivet PetscCall(MatMultTranspose(ipmP->Ai, ipmP->lambdai, ipmP->work)); 5829566063dSJacob Faibussowitsch PetscCall(VecAXPY(ipmP->rd, -1.0, ipmP->work)); 5831522df2eSJason Sarich 584a7e14dcfSSatish Balay /* rpi = cin - s */ 5859566063dSJacob Faibussowitsch PetscCall(VecCopy(ipmP->ci, ipmP->rpi)); 5869566063dSJacob Faibussowitsch PetscCall(VecAXPY(ipmP->rpi, -1.0, ipmP->s)); 587a7e14dcfSSatish Balay 588a7e14dcfSSatish Balay /* com = s .* lami */ 589*a8d3b578SPierre Jolivet PetscCall(VecPointwiseMult(ipmP->complementarity, ipmP->s, ipmP->lambdai)); 590a7e14dcfSSatish Balay } 591a7e14dcfSSatish Balay /* phi = ||rd; rpe; rpi; com|| */ 5929566063dSJacob Faibussowitsch PetscCall(VecDot(ipmP->rd, ipmP->rd, &norm)); 593a7e14dcfSSatish Balay ipmP->phi = norm; 594a7e14dcfSSatish Balay if (ipmP->me > 0) { 5959566063dSJacob Faibussowitsch PetscCall(VecDot(ipmP->rpe, ipmP->rpe, &norm)); 596a7e14dcfSSatish Balay ipmP->phi += norm; 597a7e14dcfSSatish Balay } 598a7e14dcfSSatish Balay if (ipmP->nb > 0) { 5999566063dSJacob Faibussowitsch PetscCall(VecDot(ipmP->rpi, ipmP->rpi, &norm)); 600a7e14dcfSSatish Balay ipmP->phi += norm; 6019566063dSJacob Faibussowitsch PetscCall(VecDot(ipmP->complementarity, ipmP->complementarity, &norm)); 602a7e14dcfSSatish Balay ipmP->phi += norm; 603a7e14dcfSSatish Balay /* mu = s'*lami/nb */ 604*a8d3b578SPierre Jolivet PetscCall(VecDot(ipmP->s, ipmP->lambdai, &ipmP->mu)); 605a7e14dcfSSatish Balay ipmP->mu /= ipmP->nb; 606a7e14dcfSSatish Balay } else { 607a7e14dcfSSatish Balay ipmP->mu = 1.0; 608a7e14dcfSSatish Balay } 609a7e14dcfSSatish Balay 610a7e14dcfSSatish Balay ipmP->phi = PetscSqrtScalar(ipmP->phi); 611a7e14dcfSSatish Balay PetscFunctionReturn(0); 612a7e14dcfSSatish Balay } 613a7e14dcfSSatish Balay 614a7e14dcfSSatish Balay /* evaluate user info at current point */ 615d71ae5a4SJacob Faibussowitsch PetscErrorCode IPMEvaluate(Tao tao) 616d71ae5a4SJacob Faibussowitsch { 617a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 61847a47007SBarry Smith 619a7e14dcfSSatish Balay PetscFunctionBegin; 6209566063dSJacob Faibussowitsch PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &ipmP->kkt_f, tao->gradient)); 6219566063dSJacob Faibussowitsch PetscCall(TaoComputeHessian(tao, tao->solution, tao->hessian, tao->hessian_pre)); 622a7e14dcfSSatish Balay if (ipmP->me > 0) { 6239566063dSJacob Faibussowitsch PetscCall(TaoComputeEqualityConstraints(tao, tao->solution, tao->constraints_equality)); 6249566063dSJacob Faibussowitsch PetscCall(TaoComputeJacobianEquality(tao, tao->solution, tao->jacobian_equality, tao->jacobian_equality_pre)); 625a7e14dcfSSatish Balay } 626a7e14dcfSSatish Balay if (ipmP->mi > 0) { 6279566063dSJacob Faibussowitsch PetscCall(TaoComputeInequalityConstraints(tao, tao->solution, tao->constraints_inequality)); 6289566063dSJacob Faibussowitsch PetscCall(TaoComputeJacobianInequality(tao, tao->solution, tao->jacobian_inequality, tao->jacobian_inequality_pre)); 629a7e14dcfSSatish Balay } 630a7e14dcfSSatish Balay if (ipmP->nb > 0) { 631a7e14dcfSSatish Balay /* Ai' = jac_ineq | I (w/lb) | -I (w/ub) */ 6329566063dSJacob Faibussowitsch PetscCall(IPMUpdateAi(tao)); 633a7e14dcfSSatish Balay } 634a7e14dcfSSatish Balay PetscFunctionReturn(0); 635a7e14dcfSSatish Balay } 636a7e14dcfSSatish Balay 637a7e14dcfSSatish Balay /* Push initial point away from bounds */ 638d71ae5a4SJacob Faibussowitsch PetscErrorCode IPMPushInitialPoint(Tao tao) 639d71ae5a4SJacob Faibussowitsch { 640a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 641a7e14dcfSSatish Balay 64247a47007SBarry Smith PetscFunctionBegin; 6439566063dSJacob Faibussowitsch PetscCall(TaoComputeVariableBounds(tao)); 6449566063dSJacob Faibussowitsch PetscCall(VecMedian(tao->XL, tao->solution, tao->XU, tao->solution)); 645a7e14dcfSSatish Balay if (ipmP->nb > 0) { 6469566063dSJacob Faibussowitsch PetscCall(VecSet(ipmP->s, ipmP->pushs)); 647*a8d3b578SPierre Jolivet PetscCall(VecSet(ipmP->lambdai, ipmP->pushnu)); 64848a46eb9SPierre Jolivet if (ipmP->mi > 0) PetscCall(VecSet(tao->DI, ipmP->pushnu)); 649a7e14dcfSSatish Balay } 650a7e14dcfSSatish Balay if (ipmP->me > 0) { 6519566063dSJacob Faibussowitsch PetscCall(VecSet(tao->DE, 1.0)); 652*a8d3b578SPierre Jolivet PetscCall(VecSet(ipmP->lambdae, 1.0)); 653a7e14dcfSSatish Balay } 654a7e14dcfSSatish Balay PetscFunctionReturn(0); 655a7e14dcfSSatish Balay } 656a7e14dcfSSatish Balay 657d71ae5a4SJacob Faibussowitsch PetscErrorCode IPMUpdateAi(Tao tao) 658d71ae5a4SJacob Faibussowitsch { 659a7e14dcfSSatish Balay /* Ai = Ji 660a7e14dcfSSatish Balay I (w/lb) 661a7e14dcfSSatish Balay -I (w/ub) */ 662a7e14dcfSSatish Balay 663a7e14dcfSSatish Balay /* Ci = user->ci 664a7e14dcfSSatish Balay Xi - lb (w/lb) 665a7e14dcfSSatish Balay -Xi + ub (w/ub) */ 666a7e14dcfSSatish Balay 667a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 668a7e14dcfSSatish Balay MPI_Comm comm; 669a7e14dcfSSatish Balay PetscInt i; 670a7e14dcfSSatish Balay PetscScalar newval; 671a7e14dcfSSatish Balay PetscInt newrow, newcol, ncols; 672a7e14dcfSSatish Balay const PetscScalar *vals; 673a7e14dcfSSatish Balay const PetscInt *cols; 674a7e14dcfSSatish Balay PetscInt astart, aend, jstart, jend; 675a7e14dcfSSatish Balay PetscInt *nonzeros; 676a7e14dcfSSatish Balay PetscInt r2, r3, r4; 67747a47007SBarry Smith PetscMPIInt size; 678f86eb7e8SHong Zhang Vec solu; 679f86eb7e8SHong Zhang PetscInt nloc; 680a7e14dcfSSatish Balay 681a7e14dcfSSatish Balay PetscFunctionBegin; 682a7e14dcfSSatish Balay r2 = ipmP->mi; 683a7e14dcfSSatish Balay r3 = r2 + ipmP->nxlb; 684a7e14dcfSSatish Balay r4 = r3 + ipmP->nxub; 685a7e14dcfSSatish Balay 686050fc7a3SBarry Smith if (!ipmP->nb) PetscFunctionReturn(0); 687a7e14dcfSSatish Balay 688a7e14dcfSSatish Balay /* Create Ai matrix if it doesn't exist yet */ 689a7e14dcfSSatish Balay if (!ipmP->Ai) { 690a7e14dcfSSatish Balay comm = ((PetscObject)(tao->solution))->comm; 6919566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 69247a47007SBarry Smith if (size == 1) { 6939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ipmP->nb, &nonzeros)); 694a7e14dcfSSatish Balay for (i = 0; i < ipmP->mi; i++) { 6959566063dSJacob Faibussowitsch PetscCall(MatGetRow(tao->jacobian_inequality, i, &ncols, NULL, NULL)); 696a7e14dcfSSatish Balay nonzeros[i] = ncols; 6979566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(tao->jacobian_inequality, i, &ncols, NULL, NULL)); 698a7e14dcfSSatish Balay } 699ad540459SPierre Jolivet for (i = r2; i < r4; i++) nonzeros[i] = 1; 700a7e14dcfSSatish Balay } 7019566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &ipmP->Ai)); 7029566063dSJacob Faibussowitsch PetscCall(MatSetType(ipmP->Ai, MATAIJ)); 703f86eb7e8SHong Zhang 7049566063dSJacob Faibussowitsch PetscCall(TaoGetSolution(tao, &solu)); 7059566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(solu, &nloc)); 7069566063dSJacob Faibussowitsch PetscCall(MatSetSizes(ipmP->Ai, PETSC_DECIDE, nloc, ipmP->nb, PETSC_DECIDE)); 7079566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(ipmP->Ai)); 7089566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(ipmP->Ai, ipmP->nb, NULL, ipmP->nb, NULL)); 7099566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(ipmP->Ai, PETSC_DEFAULT, nonzeros)); 71048a46eb9SPierre Jolivet if (size == 1) PetscCall(PetscFree(nonzeros)); 711a7e14dcfSSatish Balay } 712a7e14dcfSSatish Balay 713a7e14dcfSSatish Balay /* Copy values from user jacobian to Ai */ 7149566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(ipmP->Ai, &astart, &aend)); 715a7e14dcfSSatish Balay 716a7e14dcfSSatish Balay /* Ai w/lb */ 717a7e14dcfSSatish Balay if (ipmP->mi) { 7189566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(ipmP->Ai)); 7199566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(tao->jacobian_inequality, &jstart, &jend)); 720a7e14dcfSSatish Balay for (i = jstart; i < jend; i++) { 7219566063dSJacob Faibussowitsch PetscCall(MatGetRow(tao->jacobian_inequality, i, &ncols, &cols, &vals)); 722a7e14dcfSSatish Balay newrow = i; 7239566063dSJacob Faibussowitsch PetscCall(MatSetValues(ipmP->Ai, 1, &newrow, ncols, cols, vals, INSERT_VALUES)); 7249566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(tao->jacobian_inequality, i, &ncols, &cols, &vals)); 725a7e14dcfSSatish Balay } 726a7e14dcfSSatish Balay } 727a7e14dcfSSatish Balay 728a7e14dcfSSatish Balay /* I w/ xlb */ 729a7e14dcfSSatish Balay if (ipmP->nxlb) { 730a7e14dcfSSatish Balay for (i = 0; i < ipmP->nxlb; i++) { 731a7e14dcfSSatish Balay if (i >= astart && i < aend) { 732a7e14dcfSSatish Balay newrow = i + r2; 733a7e14dcfSSatish Balay newcol = i; 734a7e14dcfSSatish Balay newval = 1.0; 7359566063dSJacob Faibussowitsch PetscCall(MatSetValues(ipmP->Ai, 1, &newrow, 1, &newcol, &newval, INSERT_VALUES)); 736a7e14dcfSSatish Balay } 737a7e14dcfSSatish Balay } 738a7e14dcfSSatish Balay } 739a7e14dcfSSatish Balay if (ipmP->nxub) { 740a7e14dcfSSatish Balay /* I w/ xub */ 741a7e14dcfSSatish Balay for (i = 0; i < ipmP->nxub; i++) { 742a7e14dcfSSatish Balay if (i >= astart && i < aend) { 743a7e14dcfSSatish Balay newrow = i + r3; 744a7e14dcfSSatish Balay newcol = i; 745a7e14dcfSSatish Balay newval = -1.0; 7469566063dSJacob Faibussowitsch PetscCall(MatSetValues(ipmP->Ai, 1, &newrow, 1, &newcol, &newval, INSERT_VALUES)); 747a7e14dcfSSatish Balay } 748a7e14dcfSSatish Balay } 749a7e14dcfSSatish Balay } 750a7e14dcfSSatish Balay 7519566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(ipmP->Ai, MAT_FINAL_ASSEMBLY)); 7529566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(ipmP->Ai, MAT_FINAL_ASSEMBLY)); 753a7e14dcfSSatish Balay CHKMEMQ; 754a7e14dcfSSatish Balay 7559566063dSJacob Faibussowitsch PetscCall(VecSet(ipmP->ci, 0.0)); 756a7e14dcfSSatish Balay 757a7e14dcfSSatish Balay /* user ci */ 758a7e14dcfSSatish Balay if (ipmP->mi > 0) { 7599566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->ci_scat, tao->constraints_inequality, ipmP->ci, INSERT_VALUES, SCATTER_FORWARD)); 7609566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->ci_scat, tao->constraints_inequality, ipmP->ci, INSERT_VALUES, SCATTER_FORWARD)); 761a7e14dcfSSatish Balay } 762ad540459SPierre Jolivet if (!ipmP->work) VecDuplicate(tao->solution, &ipmP->work); 7639566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, ipmP->work)); 764a7e14dcfSSatish Balay if (tao->XL) { 7659566063dSJacob Faibussowitsch PetscCall(VecAXPY(ipmP->work, -1.0, tao->XL)); 766a7e14dcfSSatish Balay 767a7e14dcfSSatish Balay /* lower bounds on variables */ 768a7e14dcfSSatish Balay if (ipmP->nxlb > 0) { 7699566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->xl_scat, ipmP->work, ipmP->ci, INSERT_VALUES, SCATTER_FORWARD)); 7709566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->xl_scat, ipmP->work, ipmP->ci, INSERT_VALUES, SCATTER_FORWARD)); 771a7e14dcfSSatish Balay } 772a7e14dcfSSatish Balay } 773a7e14dcfSSatish Balay if (tao->XU) { 774a7e14dcfSSatish Balay /* upper bounds on variables */ 7759566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, ipmP->work)); 7769566063dSJacob Faibussowitsch PetscCall(VecScale(ipmP->work, -1.0)); 7779566063dSJacob Faibussowitsch PetscCall(VecAXPY(ipmP->work, 1.0, tao->XU)); 778a7e14dcfSSatish Balay if (ipmP->nxub > 0) { 7799566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->xu_scat, ipmP->work, ipmP->ci, INSERT_VALUES, SCATTER_FORWARD)); 7809566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->xu_scat, ipmP->work, ipmP->ci, INSERT_VALUES, SCATTER_FORWARD)); 781a7e14dcfSSatish Balay } 782a7e14dcfSSatish Balay } 783a7e14dcfSSatish Balay PetscFunctionReturn(0); 784a7e14dcfSSatish Balay } 785a7e14dcfSSatish Balay 786a7e14dcfSSatish Balay /* create K = [ Hlag , 0 , Ae', -Ai']; 787a7e14dcfSSatish Balay [Ae , 0, 0 , 0]; 788a7e14dcfSSatish Balay [Ai ,-I, 0 , 0]; 789a7e14dcfSSatish Balay [ 0 , S , 0, Y ]; */ 790d71ae5a4SJacob Faibussowitsch PetscErrorCode IPMUpdateK(Tao tao) 791d71ae5a4SJacob Faibussowitsch { 792a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 793a7e14dcfSSatish Balay MPI_Comm comm; 79447a47007SBarry Smith PetscMPIInt size; 795a7e14dcfSSatish Balay PetscInt i, j, row; 796a7e14dcfSSatish Balay PetscInt ncols, newcol, newcols[2], newrow; 797a7e14dcfSSatish Balay const PetscInt *cols; 798a7e14dcfSSatish Balay const PetscReal *vals; 7995e081366SBarry Smith const PetscReal *l, *y; 800a7e14dcfSSatish Balay PetscReal *newvals; 801a7e14dcfSSatish Balay PetscReal newval; 802a7e14dcfSSatish Balay PetscInt subsize; 803a7e14dcfSSatish Balay const PetscInt *indices; 804a7e14dcfSSatish Balay PetscInt *nonzeros, *d_nonzeros, *o_nonzeros; 805a7e14dcfSSatish Balay PetscInt bigsize; 806a7e14dcfSSatish Balay PetscInt r1, r2, r3; 807a7e14dcfSSatish Balay PetscInt c1, c2, c3; 808a7e14dcfSSatish Balay PetscInt klocalsize; 809a7e14dcfSSatish Balay PetscInt hstart, hend, kstart, kend; 810a7e14dcfSSatish Balay PetscInt aistart, aiend, aestart, aeend; 811a7e14dcfSSatish Balay PetscInt sstart, send; 812a7e14dcfSSatish Balay 81347a47007SBarry Smith PetscFunctionBegin; 814a7e14dcfSSatish Balay comm = ((PetscObject)(tao->solution))->comm; 8159566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 8169566063dSJacob Faibussowitsch PetscCall(IPMUpdateAi(tao)); 8171522df2eSJason Sarich 818a7e14dcfSSatish Balay /* allocate workspace */ 819a7e14dcfSSatish Balay subsize = PetscMax(ipmP->n, ipmP->nb); 820a7e14dcfSSatish Balay subsize = PetscMax(ipmP->me, subsize); 821a7e14dcfSSatish Balay subsize = PetscMax(2, subsize); 8229566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(subsize, (PetscInt **)&indices)); 8239566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(subsize, &newvals)); 824a7e14dcfSSatish Balay 825a7e14dcfSSatish Balay r1 = c1 = ipmP->n; 8269371c9d4SSatish Balay r2 = r1 + ipmP->me; 8279371c9d4SSatish Balay c2 = c1 + ipmP->nb; 828a7e14dcfSSatish Balay r3 = c3 = r2 + ipmP->nb; 829a7e14dcfSSatish Balay 830a7e14dcfSSatish Balay bigsize = ipmP->n + 2 * ipmP->nb + ipmP->me; 8319566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(ipmP->bigrhs, &kstart, &kend)); 8329566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(tao->hessian, &hstart, &hend)); 833a7e14dcfSSatish Balay klocalsize = kend - kstart; 834a7e14dcfSSatish Balay if (!ipmP->K) { 83547a47007SBarry Smith if (size == 1) { 8369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(kend - kstart, &nonzeros)); 837a7e14dcfSSatish Balay for (i = 0; i < bigsize; i++) { 838a7e14dcfSSatish Balay if (i < r1) { 8399566063dSJacob Faibussowitsch PetscCall(MatGetRow(tao->hessian, i, &ncols, NULL, NULL)); 840a7e14dcfSSatish Balay nonzeros[i] = ncols; 8419566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(tao->hessian, i, &ncols, NULL, NULL)); 842a7e14dcfSSatish Balay nonzeros[i] += ipmP->me + ipmP->nb; 843a7e14dcfSSatish Balay } else if (i < r2) { 844a7e14dcfSSatish Balay nonzeros[i - kstart] = ipmP->n; 845a7e14dcfSSatish Balay } else if (i < r3) { 846a7e14dcfSSatish Balay nonzeros[i - kstart] = ipmP->n + 1; 847a7e14dcfSSatish Balay } else if (i < bigsize) { 848a7e14dcfSSatish Balay nonzeros[i - kstart] = 2; 849a7e14dcfSSatish Balay } 850a7e14dcfSSatish Balay } 8519566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &ipmP->K)); 8529566063dSJacob Faibussowitsch PetscCall(MatSetType(ipmP->K, MATSEQAIJ)); 8539566063dSJacob Faibussowitsch PetscCall(MatSetSizes(ipmP->K, klocalsize, klocalsize, PETSC_DETERMINE, PETSC_DETERMINE)); 8549566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(ipmP->K, 0, nonzeros)); 8559566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(ipmP->K)); 8569566063dSJacob Faibussowitsch PetscCall(PetscFree(nonzeros)); 857a7e14dcfSSatish Balay } else { 8589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(kend - kstart, &d_nonzeros)); 8599566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(kend - kstart, &o_nonzeros)); 860a7e14dcfSSatish Balay for (i = kstart; i < kend; i++) { 861a7e14dcfSSatish Balay if (i < r1) { 862a7e14dcfSSatish Balay /* TODO fix preallocation for mpi mats */ 863a7e14dcfSSatish Balay d_nonzeros[i - kstart] = PetscMin(ipmP->n + ipmP->me + ipmP->nb, kend - kstart); 864a7e14dcfSSatish Balay o_nonzeros[i - kstart] = PetscMin(ipmP->n + ipmP->me + ipmP->nb, bigsize - (kend - kstart)); 865a7e14dcfSSatish Balay } else if (i < r2) { 866a7e14dcfSSatish Balay d_nonzeros[i - kstart] = PetscMin(ipmP->n, kend - kstart); 867a7e14dcfSSatish Balay o_nonzeros[i - kstart] = PetscMin(ipmP->n, bigsize - (kend - kstart)); 868a7e14dcfSSatish Balay } else if (i < r3) { 869a7e14dcfSSatish Balay d_nonzeros[i - kstart] = PetscMin(ipmP->n + 2, kend - kstart); 870a7e14dcfSSatish Balay o_nonzeros[i - kstart] = PetscMin(ipmP->n + 2, bigsize - (kend - kstart)); 871a7e14dcfSSatish Balay } else { 872a7e14dcfSSatish Balay d_nonzeros[i - kstart] = PetscMin(2, kend - kstart); 873a7e14dcfSSatish Balay o_nonzeros[i - kstart] = PetscMin(2, bigsize - (kend - kstart)); 874a7e14dcfSSatish Balay } 875a7e14dcfSSatish Balay } 8769566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &ipmP->K)); 8779566063dSJacob Faibussowitsch PetscCall(MatSetType(ipmP->K, MATMPIAIJ)); 8789566063dSJacob Faibussowitsch PetscCall(MatSetSizes(ipmP->K, klocalsize, klocalsize, PETSC_DETERMINE, PETSC_DETERMINE)); 8799566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(ipmP->K, 0, d_nonzeros, 0, o_nonzeros)); 8809566063dSJacob Faibussowitsch PetscCall(PetscFree(d_nonzeros)); 8819566063dSJacob Faibussowitsch PetscCall(PetscFree(o_nonzeros)); 8829566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(ipmP->K)); 883a7e14dcfSSatish Balay } 884a7e14dcfSSatish Balay } 885a7e14dcfSSatish Balay 8869566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(ipmP->K)); 887a7e14dcfSSatish Balay /* Copy H */ 888a7e14dcfSSatish Balay for (i = hstart; i < hend; i++) { 8899566063dSJacob Faibussowitsch PetscCall(MatGetRow(tao->hessian, i, &ncols, &cols, &vals)); 89048a46eb9SPierre Jolivet if (ncols > 0) PetscCall(MatSetValues(ipmP->K, 1, &i, ncols, cols, vals, INSERT_VALUES)); 8919566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(tao->hessian, i, &ncols, &cols, &vals)); 892a7e14dcfSSatish Balay } 893a7e14dcfSSatish Balay 894a7e14dcfSSatish Balay /* Copy Ae and Ae' */ 895a7e14dcfSSatish Balay if (ipmP->me > 0) { 8969566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(tao->jacobian_equality, &aestart, &aeend)); 897a7e14dcfSSatish Balay for (i = aestart; i < aeend; i++) { 8989566063dSJacob Faibussowitsch PetscCall(MatGetRow(tao->jacobian_equality, i, &ncols, &cols, &vals)); 899a7e14dcfSSatish Balay if (ncols > 0) { 900a7e14dcfSSatish Balay /*Ae*/ 901a7e14dcfSSatish Balay row = i + r1; 9029566063dSJacob Faibussowitsch PetscCall(MatSetValues(ipmP->K, 1, &row, ncols, cols, vals, INSERT_VALUES)); 903a7e14dcfSSatish Balay /*Ae'*/ 904a7e14dcfSSatish Balay for (j = 0; j < ncols; j++) { 905a7e14dcfSSatish Balay newcol = i + c2; 906a7e14dcfSSatish Balay newrow = cols[j]; 907a7e14dcfSSatish Balay newval = vals[j]; 9089566063dSJacob Faibussowitsch PetscCall(MatSetValues(ipmP->K, 1, &newrow, 1, &newcol, &newval, INSERT_VALUES)); 909a7e14dcfSSatish Balay } 910a7e14dcfSSatish Balay } 9119566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(tao->jacobian_equality, i, &ncols, &cols, &vals)); 912a7e14dcfSSatish Balay } 913a7e14dcfSSatish Balay } 914a7e14dcfSSatish Balay 915a7e14dcfSSatish Balay if (ipmP->nb > 0) { 9169566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(ipmP->Ai, &aistart, &aiend)); 917a7e14dcfSSatish Balay /* Copy Ai,and Ai' */ 918a7e14dcfSSatish Balay for (i = aistart; i < aiend; i++) { 919a7e14dcfSSatish Balay row = i + r2; 9209566063dSJacob Faibussowitsch PetscCall(MatGetRow(ipmP->Ai, i, &ncols, &cols, &vals)); 921a7e14dcfSSatish Balay if (ncols > 0) { 922a7e14dcfSSatish Balay /*Ai*/ 9239566063dSJacob Faibussowitsch PetscCall(MatSetValues(ipmP->K, 1, &row, ncols, cols, vals, INSERT_VALUES)); 924a7e14dcfSSatish Balay /*-Ai'*/ 925a7e14dcfSSatish Balay for (j = 0; j < ncols; j++) { 926a7e14dcfSSatish Balay newcol = i + c3; 927a7e14dcfSSatish Balay newrow = cols[j]; 928a7e14dcfSSatish Balay newval = -vals[j]; 9299566063dSJacob Faibussowitsch PetscCall(MatSetValues(ipmP->K, 1, &newrow, 1, &newcol, &newval, INSERT_VALUES)); 930a7e14dcfSSatish Balay } 931a7e14dcfSSatish Balay } 9329566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(ipmP->Ai, i, &ncols, &cols, &vals)); 933a7e14dcfSSatish Balay } 934a7e14dcfSSatish Balay 935a7e14dcfSSatish Balay /* -I */ 936a7e14dcfSSatish Balay for (i = kstart; i < kend; i++) { 937a7e14dcfSSatish Balay if (i >= r2 && i < r3) { 938a7e14dcfSSatish Balay newrow = i; 939a7e14dcfSSatish Balay newcol = i - r2 + c1; 940a7e14dcfSSatish Balay newval = -1.0; 9419566063dSJacob Faibussowitsch PetscCall(MatSetValues(ipmP->K, 1, &newrow, 1, &newcol, &newval, INSERT_VALUES)); 942a7e14dcfSSatish Balay } 943a7e14dcfSSatish Balay } 944a7e14dcfSSatish Balay 945a7e14dcfSSatish Balay /* Copy L,Y */ 9469566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(ipmP->s, &sstart, &send)); 947*a8d3b578SPierre Jolivet PetscCall(VecGetArrayRead(ipmP->lambdai, &l)); 9489566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ipmP->s, &y)); 949a7e14dcfSSatish Balay 950a7e14dcfSSatish Balay for (i = sstart; i < send; i++) { 951a7e14dcfSSatish Balay newcols[0] = c1 + i; 952a7e14dcfSSatish Balay newcols[1] = c3 + i; 953a7e14dcfSSatish Balay newvals[0] = l[i - sstart]; 954a7e14dcfSSatish Balay newvals[1] = y[i - sstart]; 955a7e14dcfSSatish Balay newrow = r3 + i; 9569566063dSJacob Faibussowitsch PetscCall(MatSetValues(ipmP->K, 1, &newrow, 2, newcols, newvals, INSERT_VALUES)); 957a7e14dcfSSatish Balay } 958a7e14dcfSSatish Balay 959*a8d3b578SPierre Jolivet PetscCall(VecRestoreArrayRead(ipmP->lambdai, &l)); 9609566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ipmP->s, &y)); 961a7e14dcfSSatish Balay } 962a7e14dcfSSatish Balay 9639566063dSJacob Faibussowitsch PetscCall(PetscFree(indices)); 9649566063dSJacob Faibussowitsch PetscCall(PetscFree(newvals)); 9659566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(ipmP->K, MAT_FINAL_ASSEMBLY)); 9669566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(ipmP->K, MAT_FINAL_ASSEMBLY)); 967a7e14dcfSSatish Balay PetscFunctionReturn(0); 968a7e14dcfSSatish Balay } 969a7e14dcfSSatish Balay 970d71ae5a4SJacob Faibussowitsch PetscErrorCode IPMGatherRHS(Tao tao, Vec RHS, Vec X1, Vec X2, Vec X3, Vec X4) 971d71ae5a4SJacob Faibussowitsch { 972a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 973a7e14dcfSSatish Balay 97447a47007SBarry Smith PetscFunctionBegin; 975a7e14dcfSSatish Balay /* rhs = [x1 (n) 976a7e14dcfSSatish Balay x2 (me) 977a7e14dcfSSatish Balay x3 (nb) 978a7e14dcfSSatish Balay x4 (nb)] */ 979a7e14dcfSSatish Balay if (X1) { 9809566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->rhs1, X1, RHS, INSERT_VALUES, SCATTER_FORWARD)); 9819566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->rhs1, X1, RHS, INSERT_VALUES, SCATTER_FORWARD)); 982a7e14dcfSSatish Balay } 983a7e14dcfSSatish Balay if (ipmP->me > 0 && X2) { 9849566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->rhs2, X2, RHS, INSERT_VALUES, SCATTER_FORWARD)); 9859566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->rhs2, X2, RHS, INSERT_VALUES, SCATTER_FORWARD)); 986a7e14dcfSSatish Balay } 987a7e14dcfSSatish Balay if (ipmP->nb > 0) { 988a7e14dcfSSatish Balay if (X3) { 9899566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->rhs3, X3, RHS, INSERT_VALUES, SCATTER_FORWARD)); 9909566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->rhs3, X3, RHS, INSERT_VALUES, SCATTER_FORWARD)); 991a7e14dcfSSatish Balay } 992a7e14dcfSSatish Balay if (X4) { 9939566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->rhs4, X4, RHS, INSERT_VALUES, SCATTER_FORWARD)); 9949566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->rhs4, X4, RHS, INSERT_VALUES, SCATTER_FORWARD)); 995a7e14dcfSSatish Balay } 996a7e14dcfSSatish Balay } 997a7e14dcfSSatish Balay PetscFunctionReturn(0); 998a7e14dcfSSatish Balay } 999a7e14dcfSSatish Balay 1000d71ae5a4SJacob Faibussowitsch PetscErrorCode IPMScatterStep(Tao tao, Vec STEP, Vec X1, Vec X2, Vec X3, Vec X4) 1001d71ae5a4SJacob Faibussowitsch { 1002a7e14dcfSSatish Balay TAO_IPM *ipmP = (TAO_IPM *)tao->data; 100347a47007SBarry Smith 1004a7e14dcfSSatish Balay PetscFunctionBegin; 1005a7e14dcfSSatish Balay CHKMEMQ; 1006a7e14dcfSSatish Balay /* [x1 (n) 1007a7e14dcfSSatish Balay x2 (nb) may be 0 1008a7e14dcfSSatish Balay x3 (me) may be 0 1009a7e14dcfSSatish Balay x4 (nb) may be 0 */ 1010a7e14dcfSSatish Balay if (X1) { 10119566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->step1, STEP, X1, INSERT_VALUES, SCATTER_FORWARD)); 10129566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->step1, STEP, X1, INSERT_VALUES, SCATTER_FORWARD)); 1013a7e14dcfSSatish Balay } 1014a7e14dcfSSatish Balay if (X2 && ipmP->nb > 0) { 10159566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->step2, STEP, X2, INSERT_VALUES, SCATTER_FORWARD)); 10169566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->step2, STEP, X2, INSERT_VALUES, SCATTER_FORWARD)); 1017a7e14dcfSSatish Balay } 1018a7e14dcfSSatish Balay if (X3 && ipmP->me > 0) { 10199566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->step3, STEP, X3, INSERT_VALUES, SCATTER_FORWARD)); 10209566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->step3, STEP, X3, INSERT_VALUES, SCATTER_FORWARD)); 1021a7e14dcfSSatish Balay } 1022a7e14dcfSSatish Balay if (X4 && ipmP->nb > 0) { 10239566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(ipmP->step4, STEP, X4, INSERT_VALUES, SCATTER_FORWARD)); 10249566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(ipmP->step4, STEP, X4, INSERT_VALUES, SCATTER_FORWARD)); 1025a7e14dcfSSatish Balay } 1026a7e14dcfSSatish Balay CHKMEMQ; 1027a7e14dcfSSatish Balay PetscFunctionReturn(0); 1028a7e14dcfSSatish Balay } 1029a7e14dcfSSatish Balay 10301522df2eSJason Sarich /*MC 10311522df2eSJason Sarich TAOIPM - Interior point algorithm for generally constrained optimization. 10321522df2eSJason Sarich 10331522df2eSJason Sarich Option Database Keys: 10341522df2eSJason Sarich + -tao_ipm_pushnu - parameter to push initial dual variables away from bounds 1035a2b725a8SWilliam Gropp - -tao_ipm_pushs - parameter to push initial slack variables away from bounds 10361522df2eSJason Sarich 103795452b02SPatrick Sanan Notes: 103895452b02SPatrick Sanan This algorithm is more of a place-holder for future constrained optimization algorithms and should not yet be used for large problems or production code. 10391eb8069cSJason Sarich Level: beginner 10401eb8069cSJason Sarich 10411522df2eSJason Sarich M*/ 10421522df2eSJason Sarich 1043d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TaoCreate_IPM(Tao tao) 1044d71ae5a4SJacob Faibussowitsch { 1045a7e14dcfSSatish Balay TAO_IPM *ipmP; 1046a7e14dcfSSatish Balay 1047a7e14dcfSSatish Balay PetscFunctionBegin; 1048a7e14dcfSSatish Balay tao->ops->setup = TaoSetup_IPM; 1049a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_IPM; 1050a7e14dcfSSatish Balay tao->ops->view = TaoView_IPM; 1051a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_IPM; 1052a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_IPM; 1053e9f9aeaeSSatish Balay /* tao->ops->computedual = TaoComputeDual_IPM; */ 1054a7e14dcfSSatish Balay 10554dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&ipmP)); 1056a7e14dcfSSatish Balay tao->data = (void *)ipmP; 10576552cf8aSJason Sarich 10586552cf8aSJason Sarich /* Override default settings (unless already changed) */ 10596552cf8aSJason Sarich if (!tao->max_it_changed) tao->max_it = 200; 10606552cf8aSJason Sarich if (!tao->max_funcs_changed) tao->max_funcs = 500; 10616552cf8aSJason Sarich 106235cb6cd3SPierre Jolivet ipmP->dec = 10000; /* line search criteria */ 1063a7e14dcfSSatish Balay ipmP->taumin = 0.995; 1064a7e14dcfSSatish Balay ipmP->monitorkkt = PETSC_FALSE; 1065a7e14dcfSSatish Balay ipmP->pushs = 100; 1066a7e14dcfSSatish Balay ipmP->pushnu = 100; 10679566063dSJacob Faibussowitsch PetscCall(KSPCreate(((PetscObject)tao)->comm, &tao->ksp)); 10689566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1)); 10699566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(tao->ksp, tao->hdr.prefix)); 1070a7e14dcfSSatish Balay PetscFunctionReturn(0); 1071a7e14dcfSSatish Balay } 1072