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