1 #include <petsctaolinesearch.h> 2 #include <../src/tao/constrained/impls/ipm/ipm.h> /*I "ipm.h" I*/ 3 4 /* 5 x,d in R^n 6 f in R 7 nb = mi + nlb+nub 8 s in R^nb is slack vector CI(x) / x-XL / -x+XU 9 bin in R^mi (tao->constraints_inequality) 10 beq in R^me (tao->constraints_equality) 11 lamdai in R^nb (ipmP->lamdai) 12 lamdae in R^me (ipmP->lamdae) 13 Jeq in R^(me x n) (tao->jacobian_equality) 14 Jin in R^(mi x n) (tao->jacobian_inequality) 15 Ai in R^(nb x n) (ipmP->Ai) 16 H in R^(n x n) (tao->hessian) 17 min f=(1/2)*x'*H*x + d'*x 18 s.t. CE(x) == 0 19 CI(x) >= 0 20 x >= tao->XL 21 -x >= -tao->XU 22 */ 23 24 static PetscErrorCode IPMComputeKKT(Tao tao); 25 static PetscErrorCode IPMPushInitialPoint(Tao tao); 26 static PetscErrorCode IPMEvaluate(Tao tao); 27 static PetscErrorCode IPMUpdateK(Tao tao); 28 static PetscErrorCode IPMUpdateAi(Tao tao); 29 static PetscErrorCode IPMGatherRHS(Tao tao,Vec,Vec,Vec,Vec,Vec); 30 static PetscErrorCode IPMScatterStep(Tao tao,Vec,Vec,Vec,Vec,Vec); 31 static PetscErrorCode IPMInitializeBounds(Tao tao); 32 33 static PetscErrorCode TaoSolve_IPM(Tao tao) 34 { 35 PetscErrorCode ierr; 36 TAO_IPM *ipmP = (TAO_IPM*)tao->data; 37 TaoConvergedReason reason = TAO_CONTINUE_ITERATING; 38 PetscInt its,i; 39 PetscScalar stepsize=1.0; 40 PetscScalar step_s,step_l,alpha,tau,sigma,phi_target; 41 42 PetscFunctionBegin; 43 /* Push initial point away from bounds */ 44 ierr = IPMInitializeBounds(tao);CHKERRQ(ierr); 45 ierr = IPMPushInitialPoint(tao);CHKERRQ(ierr); 46 ierr = VecCopy(tao->solution,ipmP->rhs_x);CHKERRQ(ierr); 47 ierr = IPMEvaluate(tao);CHKERRQ(ierr); 48 ierr = IPMComputeKKT(tao);CHKERRQ(ierr); 49 ierr = TaoMonitor(tao,tao->niter++,ipmP->kkt_f,ipmP->phi,0.0,1.0,&reason);CHKERRQ(ierr); 50 51 while (reason == TAO_CONTINUE_ITERATING) { 52 tao->ksp_its=0; 53 ierr = IPMUpdateK(tao);CHKERRQ(ierr); 54 /* 55 rhs.x = -rd 56 rhs.lame = -rpe 57 rhs.lami = -rpi 58 rhs.com = -com 59 */ 60 61 ierr = VecCopy(ipmP->rd,ipmP->rhs_x);CHKERRQ(ierr); 62 if (ipmP->me > 0) { 63 ierr = VecCopy(ipmP->rpe,ipmP->rhs_lamdae);CHKERRQ(ierr); 64 } 65 if (ipmP->nb > 0) { 66 ierr = VecCopy(ipmP->rpi,ipmP->rhs_lamdai);CHKERRQ(ierr); 67 ierr = VecCopy(ipmP->complementarity,ipmP->rhs_s);CHKERRQ(ierr); 68 } 69 ierr = IPMGatherRHS(tao,ipmP->bigrhs,ipmP->rhs_x,ipmP->rhs_lamdae,ipmP->rhs_lamdai,ipmP->rhs_s);CHKERRQ(ierr); 70 ierr = VecScale(ipmP->bigrhs,-1.0);CHKERRQ(ierr); 71 72 /* solve K * step = rhs */ 73 ierr = KSPSetOperators(tao->ksp,ipmP->K,ipmP->K);CHKERRQ(ierr); 74 ierr = KSPSolve(tao->ksp,ipmP->bigrhs,ipmP->bigstep);CHKERRQ(ierr); 75 76 ierr = IPMScatterStep(tao,ipmP->bigstep,tao->stepdirection,ipmP->ds,ipmP->dlamdae,ipmP->dlamdai);CHKERRQ(ierr); 77 ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 78 tao->ksp_its += its; 79 tao->ksp_tot_its+=its; 80 /* Find distance along step direction to closest bound */ 81 if (ipmP->nb > 0) { 82 ierr = VecStepBoundInfo(ipmP->s,ipmP->ds,ipmP->Zero_nb,ipmP->Inf_nb,&step_s,NULL,NULL);CHKERRQ(ierr); 83 ierr = VecStepBoundInfo(ipmP->lamdai,ipmP->dlamdai,ipmP->Zero_nb,ipmP->Inf_nb,&step_l,NULL,NULL);CHKERRQ(ierr); 84 alpha = PetscMin(step_s,step_l); 85 alpha = PetscMin(alpha,1.0); 86 ipmP->alpha1 = alpha; 87 } else { 88 ipmP->alpha1 = alpha = 1.0; 89 } 90 91 /* x_aff = x + alpha*d */ 92 ierr = VecCopy(tao->solution,ipmP->save_x);CHKERRQ(ierr); 93 if (ipmP->me > 0) { 94 ierr = VecCopy(ipmP->lamdae,ipmP->save_lamdae);CHKERRQ(ierr); 95 } 96 if (ipmP->nb > 0) { 97 ierr = VecCopy(ipmP->lamdai,ipmP->save_lamdai);CHKERRQ(ierr); 98 ierr = VecCopy(ipmP->s,ipmP->save_s);CHKERRQ(ierr); 99 } 100 101 ierr = VecAXPY(tao->solution,alpha,tao->stepdirection);CHKERRQ(ierr); 102 if (ipmP->me > 0) { 103 ierr = VecAXPY(ipmP->lamdae,alpha,ipmP->dlamdae);CHKERRQ(ierr); 104 } 105 if (ipmP->nb > 0) { 106 ierr = VecAXPY(ipmP->lamdai,alpha,ipmP->dlamdai);CHKERRQ(ierr); 107 ierr = VecAXPY(ipmP->s,alpha,ipmP->ds);CHKERRQ(ierr); 108 } 109 110 /* Recompute kkt to find centering parameter sigma = (new_mu/old_mu)^3 */ 111 if (ipmP->mu == 0.0) { 112 sigma = 0.0; 113 } else { 114 sigma = 1.0/ipmP->mu; 115 } 116 ierr = IPMComputeKKT(tao);CHKERRQ(ierr); 117 sigma *= ipmP->mu; 118 sigma*=sigma*sigma; 119 120 /* revert kkt info */ 121 ierr = VecCopy(ipmP->save_x,tao->solution);CHKERRQ(ierr); 122 if (ipmP->me > 0) { 123 ierr = VecCopy(ipmP->save_lamdae,ipmP->lamdae);CHKERRQ(ierr); 124 } 125 if (ipmP->nb > 0) { 126 ierr = VecCopy(ipmP->save_lamdai,ipmP->lamdai);CHKERRQ(ierr); 127 ierr = VecCopy(ipmP->save_s,ipmP->s);CHKERRQ(ierr); 128 } 129 ierr = IPMComputeKKT(tao);CHKERRQ(ierr); 130 131 /* update rhs with new complementarity vector */ 132 if (ipmP->nb > 0) { 133 ierr = VecCopy(ipmP->complementarity,ipmP->rhs_s);CHKERRQ(ierr); 134 ierr = VecScale(ipmP->rhs_s,-1.0);CHKERRQ(ierr); 135 ierr = VecShift(ipmP->rhs_s,sigma*ipmP->mu);CHKERRQ(ierr); 136 } 137 ierr = IPMGatherRHS(tao,ipmP->bigrhs,NULL,NULL,NULL,ipmP->rhs_s);CHKERRQ(ierr); 138 139 /* solve K * step = rhs */ 140 ierr = KSPSetOperators(tao->ksp,ipmP->K,ipmP->K);CHKERRQ(ierr); 141 ierr = KSPSolve(tao->ksp,ipmP->bigrhs,ipmP->bigstep);CHKERRQ(ierr); 142 143 ierr = IPMScatterStep(tao,ipmP->bigstep,tao->stepdirection,ipmP->ds,ipmP->dlamdae,ipmP->dlamdai);CHKERRQ(ierr); 144 ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 145 tao->ksp_its += its; 146 tao->ksp_tot_its+=its; 147 if (ipmP->nb > 0) { 148 /* Get max step size and apply frac-to-boundary */ 149 tau = PetscMax(ipmP->taumin,1.0-ipmP->mu); 150 tau = PetscMin(tau,1.0); 151 if (tau != 1.0) { 152 ierr = VecScale(ipmP->s,tau);CHKERRQ(ierr); 153 ierr = VecScale(ipmP->lamdai,tau);CHKERRQ(ierr); 154 } 155 ierr = VecStepBoundInfo(ipmP->s,ipmP->ds,ipmP->Zero_nb,ipmP->Inf_nb,&step_s,NULL,NULL);CHKERRQ(ierr); 156 ierr = VecStepBoundInfo(ipmP->lamdai,ipmP->dlamdai,ipmP->Zero_nb,ipmP->Inf_nb,&step_l,NULL,NULL);CHKERRQ(ierr); 157 if (tau != 1.0) { 158 ierr = VecCopy(ipmP->save_s,ipmP->s);CHKERRQ(ierr); 159 ierr = VecCopy(ipmP->save_lamdai,ipmP->lamdai);CHKERRQ(ierr); 160 } 161 alpha = PetscMin(step_s,step_l); 162 alpha = PetscMin(alpha,1.0); 163 } else { 164 alpha = 1.0; 165 } 166 ipmP->alpha2 = alpha; 167 /* TODO make phi_target meaningful */ 168 phi_target = ipmP->dec * ipmP->phi; 169 for (i=0; i<11;i++) { 170 ierr = VecAXPY(tao->solution,alpha,tao->stepdirection);CHKERRQ(ierr); 171 if (ipmP->nb > 0) { 172 ierr = VecAXPY(ipmP->s,alpha,ipmP->ds);CHKERRQ(ierr); 173 ierr = VecAXPY(ipmP->lamdai,alpha,ipmP->dlamdai);CHKERRQ(ierr); 174 } 175 if (ipmP->me > 0) { 176 ierr = VecAXPY(ipmP->lamdae,alpha,ipmP->dlamdae);CHKERRQ(ierr); 177 } 178 179 /* update dual variables */ 180 if (ipmP->me > 0) { 181 ierr = VecCopy(ipmP->lamdae,tao->DE);CHKERRQ(ierr); 182 } 183 184 ierr = IPMEvaluate(tao);CHKERRQ(ierr); 185 ierr = IPMComputeKKT(tao);CHKERRQ(ierr); 186 if (ipmP->phi <= phi_target) break; 187 alpha /= 2.0; 188 } 189 190 ierr = TaoMonitor(tao,tao->niter,ipmP->kkt_f,ipmP->phi,0.0,stepsize,&reason);CHKERRQ(ierr); 191 tao->niter++; 192 } 193 PetscFunctionReturn(0); 194 } 195 196 static PetscErrorCode TaoSetup_IPM(Tao tao) 197 { 198 TAO_IPM *ipmP = (TAO_IPM*)tao->data; 199 PetscErrorCode ierr; 200 201 PetscFunctionBegin; 202 ipmP->nb = ipmP->mi = ipmP->me = 0; 203 ipmP->K=0; 204 ierr = VecGetSize(tao->solution,&ipmP->n);CHKERRQ(ierr); 205 if (!tao->gradient) { 206 ierr = VecDuplicate(tao->solution, &tao->gradient);CHKERRQ(ierr); 207 ierr = VecDuplicate(tao->solution, &tao->stepdirection);CHKERRQ(ierr); 208 ierr = VecDuplicate(tao->solution, &ipmP->rd);CHKERRQ(ierr); 209 ierr = VecDuplicate(tao->solution, &ipmP->rhs_x);CHKERRQ(ierr); 210 ierr = VecDuplicate(tao->solution, &ipmP->work);CHKERRQ(ierr); 211 ierr = VecDuplicate(tao->solution, &ipmP->save_x);CHKERRQ(ierr); 212 } 213 if (tao->constraints_equality) { 214 ierr = VecGetSize(tao->constraints_equality,&ipmP->me);CHKERRQ(ierr); 215 ierr = VecDuplicate(tao->constraints_equality,&ipmP->lamdae);CHKERRQ(ierr); 216 ierr = VecDuplicate(tao->constraints_equality,&ipmP->dlamdae);CHKERRQ(ierr); 217 ierr = VecDuplicate(tao->constraints_equality,&ipmP->rhs_lamdae);CHKERRQ(ierr); 218 ierr = VecDuplicate(tao->constraints_equality,&ipmP->save_lamdae);CHKERRQ(ierr); 219 ierr = VecDuplicate(tao->constraints_equality,&ipmP->rpe);CHKERRQ(ierr); 220 ierr = VecDuplicate(tao->constraints_equality,&tao->DE);CHKERRQ(ierr); 221 } 222 if (tao->constraints_inequality) { 223 ierr = VecDuplicate(tao->constraints_inequality,&tao->DI);CHKERRQ(ierr); 224 } 225 PetscFunctionReturn(0); 226 } 227 228 static PetscErrorCode IPMInitializeBounds(Tao tao) 229 { 230 TAO_IPM *ipmP = (TAO_IPM*)tao->data; 231 Vec xtmp; 232 PetscInt xstart,xend; 233 PetscInt ucstart,ucend; /* user ci */ 234 PetscInt ucestart,uceend; /* user ce */ 235 PetscInt sstart,send; 236 PetscInt bigsize; 237 PetscInt i,counter,nloc; 238 PetscInt *cind,*xind,*ucind,*uceind,*stepind; 239 VecType vtype; 240 const PetscInt *xli,*xui; 241 PetscInt xl_offset,xu_offset; 242 IS bigxl,bigxu,isuc,isc,isx,sis,is1; 243 PetscErrorCode ierr; 244 MPI_Comm comm; 245 246 PetscFunctionBegin; 247 cind=xind=ucind=uceind=stepind=0; 248 ipmP->mi=0; 249 ipmP->nxlb=0; 250 ipmP->nxub=0; 251 ipmP->nb=0; 252 ipmP->nslack=0; 253 254 ierr = VecDuplicate(tao->solution,&xtmp);CHKERRQ(ierr); 255 if (!tao->XL && !tao->XU && tao->ops->computebounds) { 256 ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); 257 } 258 if (tao->XL) { 259 ierr = VecSet(xtmp,PETSC_NINFINITY);CHKERRQ(ierr); 260 ierr = VecWhichGreaterThan(tao->XL,xtmp,&ipmP->isxl);CHKERRQ(ierr); 261 ierr = ISGetSize(ipmP->isxl,&ipmP->nxlb);CHKERRQ(ierr); 262 } else { 263 ipmP->nxlb=0; 264 } 265 if (tao->XU) { 266 ierr = VecSet(xtmp,PETSC_INFINITY);CHKERRQ(ierr); 267 ierr = VecWhichLessThan(tao->XU,xtmp,&ipmP->isxu);CHKERRQ(ierr); 268 ierr = ISGetSize(ipmP->isxu,&ipmP->nxub);CHKERRQ(ierr); 269 } else { 270 ipmP->nxub=0; 271 } 272 ierr = VecDestroy(&xtmp);CHKERRQ(ierr); 273 if (tao->constraints_inequality) { 274 ierr = VecGetSize(tao->constraints_inequality,&ipmP->mi);CHKERRQ(ierr); 275 } else { 276 ipmP->mi = 0; 277 } 278 ipmP->nb = ipmP->nxlb + ipmP->nxub + ipmP->mi; 279 280 ierr = PetscObjectGetComm((PetscObject)tao->solution,&comm);CHKERRQ(ierr); 281 282 bigsize = ipmP->n+2*ipmP->nb+ipmP->me; 283 ierr = PetscMalloc1(bigsize,&stepind);CHKERRQ(ierr); 284 ierr = PetscMalloc1(ipmP->n,&xind);CHKERRQ(ierr); 285 ierr = PetscMalloc1(ipmP->me,&uceind);CHKERRQ(ierr); 286 ierr = VecGetOwnershipRange(tao->solution,&xstart,&xend);CHKERRQ(ierr); 287 288 if (ipmP->nb > 0) { 289 ierr = VecCreate(comm,&ipmP->s);CHKERRQ(ierr); 290 ierr = VecSetSizes(ipmP->s,PETSC_DECIDE,ipmP->nb);CHKERRQ(ierr); 291 ierr = VecSetFromOptions(ipmP->s);CHKERRQ(ierr); 292 ierr = VecDuplicate(ipmP->s,&ipmP->ds);CHKERRQ(ierr); 293 ierr = VecDuplicate(ipmP->s,&ipmP->rhs_s);CHKERRQ(ierr); 294 ierr = VecDuplicate(ipmP->s,&ipmP->complementarity);CHKERRQ(ierr); 295 ierr = VecDuplicate(ipmP->s,&ipmP->ci);CHKERRQ(ierr); 296 297 ierr = VecDuplicate(ipmP->s,&ipmP->lamdai);CHKERRQ(ierr); 298 ierr = VecDuplicate(ipmP->s,&ipmP->dlamdai);CHKERRQ(ierr); 299 ierr = VecDuplicate(ipmP->s,&ipmP->rhs_lamdai);CHKERRQ(ierr); 300 ierr = VecDuplicate(ipmP->s,&ipmP->save_lamdai);CHKERRQ(ierr); 301 302 ierr = VecDuplicate(ipmP->s,&ipmP->save_s);CHKERRQ(ierr); 303 ierr = VecDuplicate(ipmP->s,&ipmP->rpi);CHKERRQ(ierr); 304 ierr = VecDuplicate(ipmP->s,&ipmP->Zero_nb);CHKERRQ(ierr); 305 ierr = VecSet(ipmP->Zero_nb,0.0);CHKERRQ(ierr); 306 ierr = VecDuplicate(ipmP->s,&ipmP->One_nb);CHKERRQ(ierr); 307 ierr = VecSet(ipmP->One_nb,1.0);CHKERRQ(ierr); 308 ierr = VecDuplicate(ipmP->s,&ipmP->Inf_nb);CHKERRQ(ierr); 309 ierr = VecSet(ipmP->Inf_nb,PETSC_INFINITY);CHKERRQ(ierr); 310 311 ierr = PetscMalloc1(ipmP->nb,&cind);CHKERRQ(ierr); 312 ierr = PetscMalloc1(ipmP->mi,&ucind);CHKERRQ(ierr); 313 ierr = VecGetOwnershipRange(ipmP->s,&sstart,&send);CHKERRQ(ierr); 314 315 if (ipmP->mi > 0) { 316 ierr = VecGetOwnershipRange(tao->constraints_inequality,&ucstart,&ucend);CHKERRQ(ierr); 317 counter=0; 318 for (i=ucstart;i<ucend;i++) { 319 cind[counter++] = i; 320 } 321 ierr = ISCreateGeneral(comm,counter,cind,PETSC_COPY_VALUES,&isuc);CHKERRQ(ierr); 322 ierr = ISCreateGeneral(comm,counter,cind,PETSC_COPY_VALUES,&isc);CHKERRQ(ierr); 323 ierr = VecScatterCreate(tao->constraints_inequality,isuc,ipmP->ci,isc,&ipmP->ci_scat);CHKERRQ(ierr); 324 325 ierr = ISDestroy(&isuc);CHKERRQ(ierr); 326 ierr = ISDestroy(&isc);CHKERRQ(ierr); 327 } 328 /* need to know how may xbound indices are on each process */ 329 /* TODO better way */ 330 if (ipmP->nxlb) { 331 ierr = ISAllGather(ipmP->isxl,&bigxl);CHKERRQ(ierr); 332 ierr = ISGetIndices(bigxl,&xli);CHKERRQ(ierr); 333 /* find offsets for this processor */ 334 xl_offset = ipmP->mi; 335 for (i=0;i<ipmP->nxlb;i++) { 336 if (xli[i] < xstart) { 337 xl_offset++; 338 } else break; 339 } 340 ierr = ISRestoreIndices(bigxl,&xli);CHKERRQ(ierr); 341 342 ierr = ISGetIndices(ipmP->isxl,&xli);CHKERRQ(ierr); 343 ierr = ISGetLocalSize(ipmP->isxl,&nloc);CHKERRQ(ierr); 344 for (i=0;i<nloc;i++) { 345 xind[i] = xli[i]; 346 cind[i] = xl_offset+i; 347 } 348 349 ierr = ISCreateGeneral(comm,nloc,xind,PETSC_COPY_VALUES,&isx);CHKERRQ(ierr); 350 ierr = ISCreateGeneral(comm,nloc,cind,PETSC_COPY_VALUES,&isc);CHKERRQ(ierr); 351 ierr = VecScatterCreate(tao->XL,isx,ipmP->ci,isc,&ipmP->xl_scat);CHKERRQ(ierr); 352 ierr = ISDestroy(&isx);CHKERRQ(ierr); 353 ierr = ISDestroy(&isc);CHKERRQ(ierr); 354 ierr = ISDestroy(&bigxl);CHKERRQ(ierr); 355 } 356 357 if (ipmP->nxub) { 358 ierr = ISAllGather(ipmP->isxu,&bigxu);CHKERRQ(ierr); 359 ierr = ISGetIndices(bigxu,&xui);CHKERRQ(ierr); 360 /* find offsets for this processor */ 361 xu_offset = ipmP->mi + ipmP->nxlb; 362 for (i=0;i<ipmP->nxub;i++) { 363 if (xui[i] < xstart) { 364 xu_offset++; 365 } else break; 366 } 367 ierr = ISRestoreIndices(bigxu,&xui);CHKERRQ(ierr); 368 369 ierr = ISGetIndices(ipmP->isxu,&xui);CHKERRQ(ierr); 370 ierr = ISGetLocalSize(ipmP->isxu,&nloc);CHKERRQ(ierr); 371 for (i=0;i<nloc;i++) { 372 xind[i] = xui[i]; 373 cind[i] = xu_offset+i; 374 } 375 376 ierr = ISCreateGeneral(comm,nloc,xind,PETSC_COPY_VALUES,&isx);CHKERRQ(ierr); 377 ierr = ISCreateGeneral(comm,nloc,cind,PETSC_COPY_VALUES,&isc);CHKERRQ(ierr); 378 ierr = VecScatterCreate(tao->XU,isx,ipmP->ci,isc,&ipmP->xu_scat);CHKERRQ(ierr); 379 ierr = ISDestroy(&isx);CHKERRQ(ierr); 380 ierr = ISDestroy(&isc);CHKERRQ(ierr); 381 ierr = ISDestroy(&bigxu);CHKERRQ(ierr); 382 } 383 } 384 ierr = VecCreate(comm,&ipmP->bigrhs);CHKERRQ(ierr); 385 ierr = VecGetType(tao->solution,&vtype);CHKERRQ(ierr); 386 ierr = VecSetType(ipmP->bigrhs,vtype);CHKERRQ(ierr); 387 ierr = VecSetSizes(ipmP->bigrhs,PETSC_DECIDE,bigsize);CHKERRQ(ierr); 388 ierr = VecSetFromOptions(ipmP->bigrhs);CHKERRQ(ierr); 389 ierr = VecDuplicate(ipmP->bigrhs,&ipmP->bigstep);CHKERRQ(ierr); 390 391 /* create scatters for step->x and x->rhs */ 392 for (i=xstart;i<xend;i++) { 393 stepind[i-xstart] = i; 394 xind[i-xstart] = i; 395 } 396 ierr = ISCreateGeneral(comm,xend-xstart,stepind,PETSC_COPY_VALUES,&sis);CHKERRQ(ierr); 397 ierr = ISCreateGeneral(comm,xend-xstart,xind,PETSC_COPY_VALUES,&is1);CHKERRQ(ierr); 398 ierr = VecScatterCreate(ipmP->bigstep,sis,tao->solution,is1,&ipmP->step1);CHKERRQ(ierr); 399 ierr = VecScatterCreate(tao->solution,is1,ipmP->bigrhs,sis,&ipmP->rhs1);CHKERRQ(ierr); 400 ierr = ISDestroy(&sis);CHKERRQ(ierr); 401 ierr = ISDestroy(&is1);CHKERRQ(ierr); 402 403 if (ipmP->nb > 0) { 404 for (i=sstart;i<send;i++) { 405 stepind[i-sstart] = i+ipmP->n; 406 cind[i-sstart] = i; 407 } 408 ierr = ISCreateGeneral(comm,send-sstart,stepind,PETSC_COPY_VALUES,&sis);CHKERRQ(ierr); 409 ierr = ISCreateGeneral(comm,send-sstart,cind,PETSC_COPY_VALUES,&is1);CHKERRQ(ierr); 410 ierr = VecScatterCreate(ipmP->bigstep,sis,ipmP->s,is1,&ipmP->step2);CHKERRQ(ierr); 411 ierr = ISDestroy(&sis);CHKERRQ(ierr); 412 413 for (i=sstart;i<send;i++) { 414 stepind[i-sstart] = i+ipmP->n+ipmP->me; 415 cind[i-sstart] = i; 416 } 417 ierr = ISCreateGeneral(comm,send-sstart,stepind,PETSC_COPY_VALUES,&sis);CHKERRQ(ierr); 418 ierr = VecScatterCreate(ipmP->s,is1,ipmP->bigrhs,sis,&ipmP->rhs3);CHKERRQ(ierr); 419 ierr = ISDestroy(&sis);CHKERRQ(ierr); 420 ierr = ISDestroy(&is1);CHKERRQ(ierr); 421 } 422 423 if (ipmP->me > 0) { 424 ierr = VecGetOwnershipRange(tao->constraints_equality,&ucestart,&uceend);CHKERRQ(ierr); 425 for (i=ucestart;i<uceend;i++) { 426 stepind[i-ucestart] = i + ipmP->n+ipmP->nb; 427 uceind[i-ucestart] = i; 428 } 429 430 ierr = ISCreateGeneral(comm,uceend-ucestart,stepind,PETSC_COPY_VALUES,&sis);CHKERRQ(ierr); 431 ierr = ISCreateGeneral(comm,uceend-ucestart,uceind,PETSC_COPY_VALUES,&is1);CHKERRQ(ierr); 432 ierr = VecScatterCreate(ipmP->bigstep,sis,tao->constraints_equality,is1,&ipmP->step3);CHKERRQ(ierr); 433 ierr = ISDestroy(&sis);CHKERRQ(ierr); 434 435 for (i=ucestart;i<uceend;i++) { 436 stepind[i-ucestart] = i + ipmP->n; 437 } 438 439 ierr = ISCreateGeneral(comm,uceend-ucestart,stepind,PETSC_COPY_VALUES,&sis);CHKERRQ(ierr); 440 ierr = VecScatterCreate(tao->constraints_equality,is1,ipmP->bigrhs,sis,&ipmP->rhs2);CHKERRQ(ierr); 441 ierr = ISDestroy(&sis);CHKERRQ(ierr); 442 ierr = ISDestroy(&is1);CHKERRQ(ierr); 443 } 444 445 if (ipmP->nb > 0) { 446 for (i=sstart;i<send;i++) { 447 stepind[i-sstart] = i + ipmP->n + ipmP->nb + ipmP->me; 448 cind[i-sstart] = i; 449 } 450 ierr = ISCreateGeneral(comm,send-sstart,cind,PETSC_COPY_VALUES,&is1);CHKERRQ(ierr); 451 ierr = ISCreateGeneral(comm,send-sstart,stepind,PETSC_COPY_VALUES,&sis);CHKERRQ(ierr); 452 ierr = VecScatterCreate(ipmP->bigstep,sis,ipmP->s,is1,&ipmP->step4);CHKERRQ(ierr); 453 ierr = VecScatterCreate(ipmP->s,is1,ipmP->bigrhs,sis,&ipmP->rhs4);CHKERRQ(ierr); 454 ierr = ISDestroy(&sis);CHKERRQ(ierr); 455 ierr = ISDestroy(&is1);CHKERRQ(ierr); 456 } 457 458 ierr = PetscFree(stepind);CHKERRQ(ierr); 459 ierr = PetscFree(cind);CHKERRQ(ierr); 460 ierr = PetscFree(ucind);CHKERRQ(ierr); 461 ierr = PetscFree(uceind);CHKERRQ(ierr); 462 ierr = PetscFree(xind);CHKERRQ(ierr); 463 PetscFunctionReturn(0); 464 } 465 466 static PetscErrorCode TaoDestroy_IPM(Tao tao) 467 { 468 TAO_IPM *ipmP = (TAO_IPM*)tao->data; 469 PetscErrorCode ierr; 470 471 PetscFunctionBegin; 472 ierr = VecDestroy(&ipmP->rd);CHKERRQ(ierr); 473 ierr = VecDestroy(&ipmP->rpe);CHKERRQ(ierr); 474 ierr = VecDestroy(&ipmP->rpi);CHKERRQ(ierr); 475 ierr = VecDestroy(&ipmP->work);CHKERRQ(ierr); 476 ierr = VecDestroy(&ipmP->lamdae);CHKERRQ(ierr); 477 ierr = VecDestroy(&ipmP->lamdai);CHKERRQ(ierr); 478 ierr = VecDestroy(&ipmP->s);CHKERRQ(ierr); 479 ierr = VecDestroy(&ipmP->ds);CHKERRQ(ierr); 480 ierr = VecDestroy(&ipmP->ci);CHKERRQ(ierr); 481 482 ierr = VecDestroy(&ipmP->rhs_x);CHKERRQ(ierr); 483 ierr = VecDestroy(&ipmP->rhs_lamdae);CHKERRQ(ierr); 484 ierr = VecDestroy(&ipmP->rhs_lamdai);CHKERRQ(ierr); 485 ierr = VecDestroy(&ipmP->rhs_s);CHKERRQ(ierr); 486 487 ierr = VecDestroy(&ipmP->save_x);CHKERRQ(ierr); 488 ierr = VecDestroy(&ipmP->save_lamdae);CHKERRQ(ierr); 489 ierr = VecDestroy(&ipmP->save_lamdai);CHKERRQ(ierr); 490 ierr = VecDestroy(&ipmP->save_s);CHKERRQ(ierr); 491 492 ierr = VecScatterDestroy(&ipmP->step1);CHKERRQ(ierr); 493 ierr = VecScatterDestroy(&ipmP->step2);CHKERRQ(ierr); 494 ierr = VecScatterDestroy(&ipmP->step3);CHKERRQ(ierr); 495 ierr = VecScatterDestroy(&ipmP->step4);CHKERRQ(ierr); 496 497 ierr = VecScatterDestroy(&ipmP->rhs1);CHKERRQ(ierr); 498 ierr = VecScatterDestroy(&ipmP->rhs2);CHKERRQ(ierr); 499 ierr = VecScatterDestroy(&ipmP->rhs3);CHKERRQ(ierr); 500 ierr = VecScatterDestroy(&ipmP->rhs4);CHKERRQ(ierr); 501 502 ierr = VecScatterDestroy(&ipmP->ci_scat);CHKERRQ(ierr); 503 ierr = VecScatterDestroy(&ipmP->xl_scat);CHKERRQ(ierr); 504 ierr = VecScatterDestroy(&ipmP->xu_scat);CHKERRQ(ierr); 505 506 ierr = VecDestroy(&ipmP->dlamdai);CHKERRQ(ierr); 507 ierr = VecDestroy(&ipmP->dlamdae);CHKERRQ(ierr); 508 ierr = VecDestroy(&ipmP->Zero_nb);CHKERRQ(ierr); 509 ierr = VecDestroy(&ipmP->One_nb);CHKERRQ(ierr); 510 ierr = VecDestroy(&ipmP->Inf_nb);CHKERRQ(ierr); 511 ierr = VecDestroy(&ipmP->complementarity);CHKERRQ(ierr); 512 513 ierr = VecDestroy(&ipmP->bigrhs);CHKERRQ(ierr); 514 ierr = VecDestroy(&ipmP->bigstep);CHKERRQ(ierr); 515 ierr = MatDestroy(&ipmP->Ai);CHKERRQ(ierr); 516 ierr = MatDestroy(&ipmP->K);CHKERRQ(ierr); 517 ierr = ISDestroy(&ipmP->isxu);CHKERRQ(ierr); 518 ierr = ISDestroy(&ipmP->isxl);CHKERRQ(ierr); 519 ierr = PetscFree(tao->data);CHKERRQ(ierr); 520 PetscFunctionReturn(0); 521 } 522 523 static PetscErrorCode TaoSetFromOptions_IPM(PetscOptionItems *PetscOptionsObject,Tao tao) 524 { 525 TAO_IPM *ipmP = (TAO_IPM*)tao->data; 526 PetscErrorCode ierr; 527 528 PetscFunctionBegin; 529 ierr = PetscOptionsHead(PetscOptionsObject,"IPM method for constrained optimization");CHKERRQ(ierr); 530 ierr = PetscOptionsBool("-tao_ipm_monitorkkt","monitor kkt status",NULL,ipmP->monitorkkt,&ipmP->monitorkkt,NULL);CHKERRQ(ierr); 531 ierr = PetscOptionsReal("-tao_ipm_pushs","parameter to push initial slack variables away from bounds",NULL,ipmP->pushs,&ipmP->pushs,NULL);CHKERRQ(ierr); 532 ierr = PetscOptionsReal("-tao_ipm_pushnu","parameter to push initial (inequality) dual variables away from bounds",NULL,ipmP->pushnu,&ipmP->pushnu,NULL);CHKERRQ(ierr); 533 ierr = PetscOptionsTail();CHKERRQ(ierr); 534 ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 535 PetscFunctionReturn(0); 536 } 537 538 static PetscErrorCode TaoView_IPM(Tao tao, PetscViewer viewer) 539 { 540 return 0; 541 } 542 543 /* IPMObjectiveAndGradient() 544 f = d'x + 0.5 * x' * H * x 545 rd = H*x + d + Ae'*lame - Ai'*lami 546 rpe = Ae*x - be 547 rpi = Ai*x - yi - bi 548 mu = yi' * lami/mi; 549 com = yi.*lami 550 551 phi = ||rd|| + ||rpe|| + ||rpi|| + ||com|| 552 */ 553 /* 554 static PetscErrorCode IPMObjective(TaoLineSearch ls, Vec X, PetscReal *f, void *tptr) 555 { 556 Tao tao = (Tao)tptr; 557 TAO_IPM *ipmP = (TAO_IPM*)tao->data; 558 PetscErrorCode ierr; 559 PetscFunctionBegin; 560 ierr = IPMComputeKKT(tao);CHKERRQ(ierr); 561 *f = ipmP->phi; 562 PetscFunctionReturn(0); 563 } 564 */ 565 566 /* 567 f = d'x + 0.5 * x' * H * x 568 rd = H*x + d + Ae'*lame - Ai'*lami 569 Ai = jac_ineq 570 I (w/lb) 571 -I (w/ub) 572 573 rpe = ce 574 rpi = ci - s; 575 com = s.*lami 576 mu = yi' * lami/mi; 577 578 phi = ||rd|| + ||rpe|| + ||rpi|| + ||com|| 579 */ 580 static PetscErrorCode IPMComputeKKT(Tao tao) 581 { 582 TAO_IPM *ipmP = (TAO_IPM *)tao->data; 583 PetscScalar norm; 584 PetscErrorCode ierr; 585 586 PetscFunctionBegin; 587 ierr = VecCopy(tao->gradient,ipmP->rd);CHKERRQ(ierr); 588 589 if (ipmP->me > 0) { 590 /* rd = gradient + Ae'*lamdae */ 591 ierr = MatMultTranspose(tao->jacobian_equality,ipmP->lamdae,ipmP->work);CHKERRQ(ierr); 592 ierr = VecAXPY(ipmP->rd, 1.0, ipmP->work);CHKERRQ(ierr); 593 594 /* rpe = ce(x) */ 595 ierr = VecCopy(tao->constraints_equality,ipmP->rpe);CHKERRQ(ierr); 596 } 597 if (ipmP->nb > 0) { 598 /* rd = rd - Ai'*lamdai */ 599 ierr = MatMultTranspose(ipmP->Ai,ipmP->lamdai,ipmP->work);CHKERRQ(ierr); 600 ierr = VecAXPY(ipmP->rd, -1.0, ipmP->work);CHKERRQ(ierr); 601 602 /* rpi = cin - s */ 603 ierr = VecCopy(ipmP->ci,ipmP->rpi);CHKERRQ(ierr); 604 ierr = VecAXPY(ipmP->rpi, -1.0, ipmP->s);CHKERRQ(ierr); 605 606 /* com = s .* lami */ 607 ierr = VecPointwiseMult(ipmP->complementarity, ipmP->s,ipmP->lamdai);CHKERRQ(ierr); 608 } 609 /* phi = ||rd; rpe; rpi; com|| */ 610 ierr = VecDot(ipmP->rd,ipmP->rd,&norm);CHKERRQ(ierr); 611 ipmP->phi = norm; 612 if (ipmP->me > 0 ) { 613 ierr = VecDot(ipmP->rpe,ipmP->rpe,&norm);CHKERRQ(ierr); 614 ipmP->phi += norm; 615 } 616 if (ipmP->nb > 0) { 617 ierr = VecDot(ipmP->rpi,ipmP->rpi,&norm);CHKERRQ(ierr); 618 ipmP->phi += norm; 619 ierr = VecDot(ipmP->complementarity,ipmP->complementarity,&norm);CHKERRQ(ierr); 620 ipmP->phi += norm; 621 /* mu = s'*lami/nb */ 622 ierr = VecDot(ipmP->s,ipmP->lamdai,&ipmP->mu);CHKERRQ(ierr); 623 ipmP->mu /= ipmP->nb; 624 } else { 625 ipmP->mu = 1.0; 626 } 627 628 ipmP->phi = PetscSqrtScalar(ipmP->phi); 629 PetscFunctionReturn(0); 630 } 631 632 /* evaluate user info at current point */ 633 PetscErrorCode IPMEvaluate(Tao tao) 634 { 635 TAO_IPM *ipmP = (TAO_IPM *)tao->data; 636 PetscErrorCode ierr; 637 638 PetscFunctionBegin; 639 ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&ipmP->kkt_f,tao->gradient);CHKERRQ(ierr); 640 ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 641 if (ipmP->me > 0) { 642 ierr = TaoComputeEqualityConstraints(tao,tao->solution,tao->constraints_equality);CHKERRQ(ierr); 643 ierr = TaoComputeJacobianEquality(tao,tao->solution,tao->jacobian_equality,tao->jacobian_equality_pre);CHKERRQ(ierr); 644 } 645 if (ipmP->mi > 0) { 646 ierr = TaoComputeInequalityConstraints(tao,tao->solution,tao->constraints_inequality);CHKERRQ(ierr); 647 ierr = TaoComputeJacobianInequality(tao,tao->solution,tao->jacobian_inequality,tao->jacobian_inequality_pre);CHKERRQ(ierr); 648 } 649 if (ipmP->nb > 0) { 650 /* Ai' = jac_ineq | I (w/lb) | -I (w/ub) */ 651 ierr = IPMUpdateAi(tao);CHKERRQ(ierr); 652 } 653 PetscFunctionReturn(0); 654 } 655 656 /* Push initial point away from bounds */ 657 PetscErrorCode IPMPushInitialPoint(Tao tao) 658 { 659 TAO_IPM *ipmP = (TAO_IPM *)tao->data; 660 PetscErrorCode ierr; 661 662 PetscFunctionBegin; 663 ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); 664 if (tao->XL && tao->XU) { 665 ierr = VecMedian(tao->XL, tao->solution, tao->XU, tao->solution);CHKERRQ(ierr); 666 } 667 if (ipmP->nb > 0) { 668 ierr = VecSet(ipmP->s,ipmP->pushs);CHKERRQ(ierr); 669 ierr = VecSet(ipmP->lamdai,ipmP->pushnu);CHKERRQ(ierr); 670 if (ipmP->mi > 0) { 671 ierr = VecSet(tao->DI,ipmP->pushnu);CHKERRQ(ierr); 672 } 673 } 674 if (ipmP->me > 0) { 675 ierr = VecSet(tao->DE,1.0);CHKERRQ(ierr); 676 ierr = VecSet(ipmP->lamdae,1.0);CHKERRQ(ierr); 677 } 678 PetscFunctionReturn(0); 679 } 680 681 PetscErrorCode IPMUpdateAi(Tao tao) 682 { 683 /* Ai = Ji 684 I (w/lb) 685 -I (w/ub) */ 686 687 /* Ci = user->ci 688 Xi - lb (w/lb) 689 -Xi + ub (w/ub) */ 690 691 TAO_IPM *ipmP = (TAO_IPM *)tao->data; 692 MPI_Comm comm; 693 PetscInt i; 694 PetscScalar newval; 695 PetscInt newrow,newcol,ncols; 696 const PetscScalar *vals; 697 const PetscInt *cols; 698 PetscInt astart,aend,jstart,jend; 699 PetscInt *nonzeros; 700 PetscInt r2,r3,r4; 701 PetscMPIInt size; 702 PetscErrorCode ierr; 703 704 PetscFunctionBegin; 705 r2 = ipmP->mi; 706 r3 = r2 + ipmP->nxlb; 707 r4 = r3 + ipmP->nxub; 708 709 if (!ipmP->nb) PetscFunctionReturn(0); 710 711 /* Create Ai matrix if it doesn't exist yet */ 712 if (!ipmP->Ai) { 713 comm = ((PetscObject)(tao->solution))->comm; 714 ierr = PetscMalloc1(ipmP->nb,&nonzeros);CHKERRQ(ierr); 715 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 716 if (size == 1) { 717 for (i=0;i<ipmP->mi;i++) { 718 ierr = MatGetRow(tao->jacobian_inequality,i,&ncols,NULL,NULL);CHKERRQ(ierr); 719 nonzeros[i] = ncols; 720 ierr = MatRestoreRow(tao->jacobian_inequality,i,&ncols,NULL,NULL);CHKERRQ(ierr); 721 } 722 for (i=r2;i<r4;i++) { 723 nonzeros[i] = 1; 724 } 725 } 726 ierr = MatCreate(comm,&ipmP->Ai);CHKERRQ(ierr); 727 ierr = MatSetType(ipmP->Ai,MATAIJ);CHKERRQ(ierr); 728 ierr = MatSetSizes(ipmP->Ai,PETSC_DECIDE,PETSC_DECIDE,ipmP->nb,ipmP->n);CHKERRQ(ierr); 729 ierr = MatSetFromOptions(ipmP->Ai);CHKERRQ(ierr); 730 ierr = MatMPIAIJSetPreallocation(ipmP->Ai,ipmP->nb,NULL,ipmP->nb,NULL);CHKERRQ(ierr); 731 ierr = MatSeqAIJSetPreallocation(ipmP->Ai,PETSC_DEFAULT,nonzeros);CHKERRQ(ierr); 732 if (size ==1) { 733 ierr = PetscFree(nonzeros);CHKERRQ(ierr); 734 } 735 } 736 737 /* Copy values from user jacobian to Ai */ 738 ierr = MatGetOwnershipRange(ipmP->Ai,&astart,&aend);CHKERRQ(ierr); 739 740 /* Ai w/lb */ 741 if (ipmP->mi) { 742 ierr = MatZeroEntries(ipmP->Ai);CHKERRQ(ierr); 743 ierr = MatGetOwnershipRange(tao->jacobian_inequality,&jstart,&jend);CHKERRQ(ierr); 744 for (i=jstart;i<jend;i++) { 745 ierr = MatGetRow(tao->jacobian_inequality,i,&ncols,&cols,&vals);CHKERRQ(ierr); 746 newrow = i; 747 ierr = MatSetValues(ipmP->Ai,1,&newrow,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 748 ierr = MatRestoreRow(tao->jacobian_inequality,i,&ncols,&cols,&vals);CHKERRQ(ierr); 749 } 750 } 751 752 /* I w/ xlb */ 753 if (ipmP->nxlb) { 754 for (i=0;i<ipmP->nxlb;i++) { 755 if (i>=astart && i<aend) { 756 newrow = i+r2; 757 newcol = i; 758 newval = 1.0; 759 ierr = MatSetValues(ipmP->Ai,1,&newrow,1,&newcol,&newval,INSERT_VALUES);CHKERRQ(ierr); 760 } 761 } 762 } 763 if (ipmP->nxub) { 764 /* I w/ xub */ 765 for (i=0;i<ipmP->nxub;i++) { 766 if (i>=astart && i<aend) { 767 newrow = i+r3; 768 newcol = i; 769 newval = -1.0; 770 ierr = MatSetValues(ipmP->Ai,1,&newrow,1,&newcol,&newval,INSERT_VALUES);CHKERRQ(ierr); 771 } 772 } 773 } 774 775 ierr = MatAssemblyBegin(ipmP->Ai,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 776 ierr = MatAssemblyEnd(ipmP->Ai,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 777 CHKMEMQ; 778 779 ierr = VecSet(ipmP->ci,0.0);CHKERRQ(ierr); 780 781 /* user ci */ 782 if (ipmP->mi > 0) { 783 ierr = VecScatterBegin(ipmP->ci_scat,tao->constraints_inequality,ipmP->ci,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 784 ierr = VecScatterEnd(ipmP->ci_scat,tao->constraints_inequality,ipmP->ci,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 785 } 786 if (!ipmP->work){ 787 VecDuplicate(tao->solution,&ipmP->work); 788 } 789 ierr = VecCopy(tao->solution,ipmP->work);CHKERRQ(ierr); 790 if (tao->XL) { 791 ierr = VecAXPY(ipmP->work,-1.0,tao->XL);CHKERRQ(ierr); 792 793 /* lower bounds on variables */ 794 if (ipmP->nxlb > 0) { 795 ierr = VecScatterBegin(ipmP->xl_scat,ipmP->work,ipmP->ci,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 796 ierr = VecScatterEnd(ipmP->xl_scat,ipmP->work,ipmP->ci,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 797 } 798 } 799 if (tao->XU) { 800 /* upper bounds on variables */ 801 ierr = VecCopy(tao->solution,ipmP->work);CHKERRQ(ierr); 802 ierr = VecScale(ipmP->work,-1.0);CHKERRQ(ierr); 803 ierr = VecAXPY(ipmP->work,1.0,tao->XU);CHKERRQ(ierr); 804 if (ipmP->nxub > 0) { 805 ierr = VecScatterBegin(ipmP->xu_scat,ipmP->work,ipmP->ci,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 806 ierr = VecScatterEnd(ipmP->xu_scat,ipmP->work,ipmP->ci,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 807 } 808 } 809 PetscFunctionReturn(0); 810 } 811 812 /* create K = [ Hlag , 0 , Ae', -Ai']; 813 [Ae , 0, 0 , 0]; 814 [Ai ,-I, 0 , 0]; 815 [ 0 , S , 0, Y ]; */ 816 PetscErrorCode IPMUpdateK(Tao tao) 817 { 818 TAO_IPM *ipmP = (TAO_IPM *)tao->data; 819 MPI_Comm comm; 820 PetscMPIInt size; 821 PetscErrorCode ierr; 822 PetscInt i,j,row; 823 PetscInt ncols,newcol,newcols[2],newrow; 824 const PetscInt *cols; 825 const PetscReal *vals; 826 const PetscReal *l,*y; 827 PetscReal *newvals; 828 PetscReal newval; 829 PetscInt subsize; 830 const PetscInt *indices; 831 PetscInt *nonzeros,*d_nonzeros,*o_nonzeros; 832 PetscInt bigsize; 833 PetscInt r1,r2,r3; 834 PetscInt c1,c2,c3; 835 PetscInt klocalsize; 836 PetscInt hstart,hend,kstart,kend; 837 PetscInt aistart,aiend,aestart,aeend; 838 PetscInt sstart,send; 839 840 PetscFunctionBegin; 841 comm = ((PetscObject)(tao->solution))->comm; 842 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 843 ierr = IPMUpdateAi(tao);CHKERRQ(ierr); 844 845 /* allocate workspace */ 846 subsize = PetscMax(ipmP->n,ipmP->nb); 847 subsize = PetscMax(ipmP->me,subsize); 848 subsize = PetscMax(2,subsize); 849 ierr = PetscMalloc1(subsize,&indices);CHKERRQ(ierr); 850 ierr = PetscMalloc1(subsize,&newvals);CHKERRQ(ierr); 851 852 r1 = c1 = ipmP->n; 853 r2 = r1 + ipmP->me; c2 = c1 + ipmP->nb; 854 r3 = c3 = r2 + ipmP->nb; 855 856 bigsize = ipmP->n+2*ipmP->nb+ipmP->me; 857 ierr = VecGetOwnershipRange(ipmP->bigrhs,&kstart,&kend);CHKERRQ(ierr); 858 ierr = MatGetOwnershipRange(tao->hessian,&hstart,&hend);CHKERRQ(ierr); 859 klocalsize = kend-kstart; 860 if (!ipmP->K) { 861 if (size == 1) { 862 ierr = PetscMalloc1(kend-kstart,&nonzeros);CHKERRQ(ierr); 863 for (i=0;i<bigsize;i++) { 864 if (i<r1) { 865 ierr = MatGetRow(tao->hessian,i,&ncols,NULL,NULL);CHKERRQ(ierr); 866 nonzeros[i] = ncols; 867 ierr = MatRestoreRow(tao->hessian,i,&ncols,NULL,NULL);CHKERRQ(ierr); 868 nonzeros[i] += ipmP->me+ipmP->nb; 869 } else if (i<r2) { 870 nonzeros[i-kstart] = ipmP->n; 871 } else if (i<r3) { 872 nonzeros[i-kstart] = ipmP->n+1; 873 } else if (i<bigsize) { 874 nonzeros[i-kstart] = 2; 875 } 876 } 877 ierr = MatCreate(comm,&ipmP->K);CHKERRQ(ierr); 878 ierr = MatSetType(ipmP->K,MATSEQAIJ);CHKERRQ(ierr); 879 ierr = MatSetSizes(ipmP->K,klocalsize,klocalsize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 880 ierr = MatSeqAIJSetPreallocation(ipmP->K,0,nonzeros);CHKERRQ(ierr); 881 ierr = MatSetFromOptions(ipmP->K);CHKERRQ(ierr); 882 ierr = PetscFree(nonzeros);CHKERRQ(ierr); 883 } else { 884 ierr = PetscMalloc1(kend-kstart,&d_nonzeros);CHKERRQ(ierr); 885 ierr = PetscMalloc1(kend-kstart,&o_nonzeros);CHKERRQ(ierr); 886 for (i=kstart;i<kend;i++) { 887 if (i<r1) { 888 /* TODO fix preallocation for mpi mats */ 889 d_nonzeros[i-kstart] = PetscMin(ipmP->n+ipmP->me+ipmP->nb,kend-kstart); 890 o_nonzeros[i-kstart] = PetscMin(ipmP->n+ipmP->me+ipmP->nb,bigsize-(kend-kstart)); 891 } else if (i<r2) { 892 d_nonzeros[i-kstart] = PetscMin(ipmP->n,kend-kstart); 893 o_nonzeros[i-kstart] = PetscMin(ipmP->n,bigsize-(kend-kstart)); 894 } else if (i<r3) { 895 d_nonzeros[i-kstart] = PetscMin(ipmP->n+2,kend-kstart); 896 o_nonzeros[i-kstart] = PetscMin(ipmP->n+2,bigsize-(kend-kstart)); 897 } else { 898 d_nonzeros[i-kstart] = PetscMin(2,kend-kstart); 899 o_nonzeros[i-kstart] = PetscMin(2,bigsize-(kend-kstart)); 900 } 901 } 902 ierr = MatCreate(comm,&ipmP->K);CHKERRQ(ierr); 903 ierr = MatSetType(ipmP->K,MATMPIAIJ);CHKERRQ(ierr); 904 ierr = MatSetSizes(ipmP->K,klocalsize,klocalsize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 905 ierr = MatMPIAIJSetPreallocation(ipmP->K,0,d_nonzeros,0,o_nonzeros);CHKERRQ(ierr); 906 ierr = PetscFree(d_nonzeros);CHKERRQ(ierr); 907 ierr = PetscFree(o_nonzeros);CHKERRQ(ierr); 908 ierr = MatSetFromOptions(ipmP->K);CHKERRQ(ierr); 909 } 910 } 911 912 ierr = MatZeroEntries(ipmP->K);CHKERRQ(ierr); 913 /* Copy H */ 914 for (i=hstart;i<hend;i++) { 915 ierr = MatGetRow(tao->hessian,i,&ncols,&cols,&vals);CHKERRQ(ierr); 916 if (ncols > 0) { 917 ierr = MatSetValues(ipmP->K,1,&i,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 918 } 919 ierr = MatRestoreRow(tao->hessian,i,&ncols,&cols,&vals);CHKERRQ(ierr); 920 } 921 922 /* Copy Ae and Ae' */ 923 if (ipmP->me > 0) { 924 ierr = MatGetOwnershipRange(tao->jacobian_equality,&aestart,&aeend);CHKERRQ(ierr); 925 for (i=aestart;i<aeend;i++) { 926 ierr = MatGetRow(tao->jacobian_equality,i,&ncols,&cols,&vals);CHKERRQ(ierr); 927 if (ncols > 0) { 928 /*Ae*/ 929 row = i+r1; 930 ierr = MatSetValues(ipmP->K,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 931 /*Ae'*/ 932 for (j=0;j<ncols;j++) { 933 newcol = i + c2; 934 newrow = cols[j]; 935 newval = vals[j]; 936 ierr = MatSetValues(ipmP->K,1,&newrow,1,&newcol,&newval,INSERT_VALUES);CHKERRQ(ierr); 937 } 938 } 939 ierr = MatRestoreRow(tao->jacobian_equality,i,&ncols,&cols,&vals);CHKERRQ(ierr); 940 } 941 } 942 943 if (ipmP->nb > 0) { 944 ierr = MatGetOwnershipRange(ipmP->Ai,&aistart,&aiend);CHKERRQ(ierr); 945 /* Copy Ai,and Ai' */ 946 for (i=aistart;i<aiend;i++) { 947 row = i+r2; 948 ierr = MatGetRow(ipmP->Ai,i,&ncols,&cols,&vals);CHKERRQ(ierr); 949 if (ncols > 0) { 950 /*Ai*/ 951 ierr = MatSetValues(ipmP->K,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 952 /*-Ai'*/ 953 for (j=0;j<ncols;j++) { 954 newcol = i + c3; 955 newrow = cols[j]; 956 newval = -vals[j]; 957 ierr = MatSetValues(ipmP->K,1,&newrow,1,&newcol,&newval,INSERT_VALUES);CHKERRQ(ierr); 958 } 959 } 960 ierr = MatRestoreRow(ipmP->Ai,i,&ncols,&cols,&vals);CHKERRQ(ierr); 961 } 962 963 /* -I */ 964 for (i=kstart;i<kend;i++) { 965 if (i>=r2 && i<r3) { 966 newrow = i; 967 newcol = i-r2+c1; 968 newval = -1.0; 969 MatSetValues(ipmP->K,1,&newrow,1,&newcol,&newval,INSERT_VALUES);CHKERRQ(ierr); 970 } 971 } 972 973 /* Copy L,Y */ 974 ierr = VecGetOwnershipRange(ipmP->s,&sstart,&send);CHKERRQ(ierr); 975 ierr = VecGetArrayRead(ipmP->lamdai,&l);CHKERRQ(ierr); 976 ierr = VecGetArrayRead(ipmP->s,&y);CHKERRQ(ierr); 977 978 for (i=sstart;i<send;i++) { 979 newcols[0] = c1+i; 980 newcols[1] = c3+i; 981 newvals[0] = l[i-sstart]; 982 newvals[1] = y[i-sstart]; 983 newrow = r3+i; 984 ierr = MatSetValues(ipmP->K,1,&newrow,2,newcols,newvals,INSERT_VALUES);CHKERRQ(ierr); 985 } 986 987 ierr = VecRestoreArrayRead(ipmP->lamdai,&l);CHKERRQ(ierr); 988 ierr = VecRestoreArrayRead(ipmP->s,&y);CHKERRQ(ierr); 989 } 990 991 ierr = PetscFree(indices);CHKERRQ(ierr); 992 ierr = PetscFree(newvals);CHKERRQ(ierr); 993 ierr = MatAssemblyBegin(ipmP->K,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 994 ierr = MatAssemblyEnd(ipmP->K,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 995 PetscFunctionReturn(0); 996 } 997 998 PetscErrorCode IPMGatherRHS(Tao tao,Vec RHS,Vec X1,Vec X2,Vec X3,Vec X4) 999 { 1000 TAO_IPM *ipmP = (TAO_IPM *)tao->data; 1001 PetscErrorCode ierr; 1002 1003 PetscFunctionBegin; 1004 /* rhs = [x1 (n) 1005 x2 (me) 1006 x3 (nb) 1007 x4 (nb)] */ 1008 if (X1) { 1009 ierr = VecScatterBegin(ipmP->rhs1,X1,RHS,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1010 ierr = VecScatterEnd(ipmP->rhs1,X1,RHS,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1011 } 1012 if (ipmP->me > 0 && X2) { 1013 ierr = VecScatterBegin(ipmP->rhs2,X2,RHS,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1014 ierr = VecScatterEnd(ipmP->rhs2,X2,RHS,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1015 } 1016 if (ipmP->nb > 0) { 1017 if (X3) { 1018 ierr = VecScatterBegin(ipmP->rhs3,X3,RHS,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1019 ierr = VecScatterEnd(ipmP->rhs3,X3,RHS,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1020 } 1021 if (X4) { 1022 ierr = VecScatterBegin(ipmP->rhs4,X4,RHS,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1023 ierr = VecScatterEnd(ipmP->rhs4,X4,RHS,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1024 } 1025 } 1026 PetscFunctionReturn(0); 1027 } 1028 1029 PetscErrorCode IPMScatterStep(Tao tao, Vec STEP, Vec X1, Vec X2, Vec X3, Vec X4) 1030 { 1031 TAO_IPM *ipmP = (TAO_IPM *)tao->data; 1032 PetscErrorCode ierr; 1033 1034 PetscFunctionBegin; 1035 CHKMEMQ; 1036 /* [x1 (n) 1037 x2 (nb) may be 0 1038 x3 (me) may be 0 1039 x4 (nb) may be 0 */ 1040 if (X1) { 1041 ierr = VecScatterBegin(ipmP->step1,STEP,X1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1042 ierr = VecScatterEnd(ipmP->step1,STEP,X1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1043 } 1044 if (X2 && ipmP->nb > 0) { 1045 ierr = VecScatterBegin(ipmP->step2,STEP,X2,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1046 ierr = VecScatterEnd(ipmP->step2,STEP,X2,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1047 } 1048 if (X3 && ipmP->me > 0) { 1049 ierr = VecScatterBegin(ipmP->step3,STEP,X3,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1050 ierr = VecScatterEnd(ipmP->step3,STEP,X3,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1051 } 1052 if (X4 && ipmP->nb > 0) { 1053 ierr = VecScatterBegin(ipmP->step4,STEP,X4,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1054 ierr = VecScatterEnd(ipmP->step4,STEP,X4,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1055 } 1056 CHKMEMQ; 1057 PetscFunctionReturn(0); 1058 } 1059 1060 /*MC 1061 TAOIPM - Interior point algorithm for generally constrained optimization. 1062 1063 Option Database Keys: 1064 + -tao_ipm_pushnu - parameter to push initial dual variables away from bounds 1065 . -tao_ipm_pushs - parameter to push initial slack variables away from bounds 1066 1067 Notes: 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. 1068 Level: beginner 1069 1070 M*/ 1071 1072 PETSC_EXTERN PetscErrorCode TaoCreate_IPM(Tao tao) 1073 { 1074 TAO_IPM *ipmP; 1075 PetscErrorCode ierr; 1076 1077 PetscFunctionBegin; 1078 tao->ops->setup = TaoSetup_IPM; 1079 tao->ops->solve = TaoSolve_IPM; 1080 tao->ops->view = TaoView_IPM; 1081 tao->ops->setfromoptions = TaoSetFromOptions_IPM; 1082 tao->ops->destroy = TaoDestroy_IPM; 1083 /* tao->ops->computedual = TaoComputeDual_IPM; */ 1084 1085 ierr = PetscNewLog(tao,&ipmP);CHKERRQ(ierr); 1086 tao->data = (void*)ipmP; 1087 1088 /* Override default settings (unless already changed) */ 1089 if (!tao->max_it_changed) tao->max_it = 200; 1090 if (!tao->max_funcs_changed) tao->max_funcs = 500; 1091 1092 ipmP->dec = 10000; /* line search critera */ 1093 ipmP->taumin = 0.995; 1094 ipmP->monitorkkt = PETSC_FALSE; 1095 ipmP->pushs = 100; 1096 ipmP->pushnu = 100; 1097 ierr = KSPCreate(((PetscObject)tao)->comm, &tao->ksp);CHKERRQ(ierr); 1098 ierr = KSPSetOptionsPrefix(tao->ksp, tao->hdr.prefix);CHKERRQ(ierr); 1099 PetscFunctionReturn(0); 1100 } 1101 1102 1103