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