1 #include <../src/tao/pde_constrained/impls/lcl/lcl.h> 2 static PetscErrorCode LCLComputeLagrangianAndGradient(TaoLineSearch,Vec,PetscReal*,Vec,void*); 3 static PetscErrorCode LCLComputeAugmentedLagrangianAndGradient(TaoLineSearch,Vec,PetscReal*,Vec,void*); 4 static PetscErrorCode LCLScatter(TAO_LCL*,Vec,Vec,Vec); 5 static PetscErrorCode LCLGather(TAO_LCL*,Vec,Vec,Vec); 6 7 static PetscErrorCode TaoDestroy_LCL(Tao tao) 8 { 9 TAO_LCL *lclP = (TAO_LCL*)tao->data; 10 PetscErrorCode ierr; 11 12 PetscFunctionBegin; 13 if (tao->setupcalled) { 14 ierr = MatDestroy(&lclP->R);CHKERRQ(ierr); 15 ierr = VecDestroy(&lclP->lamda);CHKERRQ(ierr); 16 ierr = VecDestroy(&lclP->lamda0);CHKERRQ(ierr); 17 ierr = VecDestroy(&lclP->WL);CHKERRQ(ierr); 18 ierr = VecDestroy(&lclP->W);CHKERRQ(ierr); 19 ierr = VecDestroy(&lclP->X0);CHKERRQ(ierr); 20 ierr = VecDestroy(&lclP->G0);CHKERRQ(ierr); 21 ierr = VecDestroy(&lclP->GL);CHKERRQ(ierr); 22 ierr = VecDestroy(&lclP->GAugL);CHKERRQ(ierr); 23 ierr = VecDestroy(&lclP->dbar);CHKERRQ(ierr); 24 ierr = VecDestroy(&lclP->U);CHKERRQ(ierr); 25 ierr = VecDestroy(&lclP->U0);CHKERRQ(ierr); 26 ierr = VecDestroy(&lclP->V);CHKERRQ(ierr); 27 ierr = VecDestroy(&lclP->V0);CHKERRQ(ierr); 28 ierr = VecDestroy(&lclP->V1);CHKERRQ(ierr); 29 ierr = VecDestroy(&lclP->GU);CHKERRQ(ierr); 30 ierr = VecDestroy(&lclP->GV);CHKERRQ(ierr); 31 ierr = VecDestroy(&lclP->GU0);CHKERRQ(ierr); 32 ierr = VecDestroy(&lclP->GV0);CHKERRQ(ierr); 33 ierr = VecDestroy(&lclP->GL_U);CHKERRQ(ierr); 34 ierr = VecDestroy(&lclP->GL_V);CHKERRQ(ierr); 35 ierr = VecDestroy(&lclP->GAugL_U);CHKERRQ(ierr); 36 ierr = VecDestroy(&lclP->GAugL_V);CHKERRQ(ierr); 37 ierr = VecDestroy(&lclP->GL_U0);CHKERRQ(ierr); 38 ierr = VecDestroy(&lclP->GL_V0);CHKERRQ(ierr); 39 ierr = VecDestroy(&lclP->GAugL_U0);CHKERRQ(ierr); 40 ierr = VecDestroy(&lclP->GAugL_V0);CHKERRQ(ierr); 41 ierr = VecDestroy(&lclP->DU);CHKERRQ(ierr); 42 ierr = VecDestroy(&lclP->DV);CHKERRQ(ierr); 43 ierr = VecDestroy(&lclP->WU);CHKERRQ(ierr); 44 ierr = VecDestroy(&lclP->WV);CHKERRQ(ierr); 45 ierr = VecDestroy(&lclP->g1);CHKERRQ(ierr); 46 ierr = VecDestroy(&lclP->g2);CHKERRQ(ierr); 47 ierr = VecDestroy(&lclP->con1);CHKERRQ(ierr); 48 49 ierr = VecDestroy(&lclP->r);CHKERRQ(ierr); 50 ierr = VecDestroy(&lclP->s);CHKERRQ(ierr); 51 52 ierr = ISDestroy(&tao->state_is);CHKERRQ(ierr); 53 ierr = ISDestroy(&tao->design_is);CHKERRQ(ierr); 54 55 ierr = VecScatterDestroy(&lclP->state_scatter);CHKERRQ(ierr); 56 ierr = VecScatterDestroy(&lclP->design_scatter);CHKERRQ(ierr); 57 } 58 ierr = MatDestroy(&lclP->R);CHKERRQ(ierr); 59 ierr = PetscFree(tao->data);CHKERRQ(ierr); 60 PetscFunctionReturn(0); 61 } 62 63 static PetscErrorCode TaoSetFromOptions_LCL(PetscOptionItems *PetscOptionsObject,Tao tao) 64 { 65 TAO_LCL *lclP = (TAO_LCL*)tao->data; 66 PetscErrorCode ierr; 67 68 PetscFunctionBegin; 69 ierr = PetscOptionsHead(PetscOptionsObject,"Linearly-Constrained Augmented Lagrangian Method for PDE-constrained optimization");CHKERRQ(ierr); 70 ierr = PetscOptionsReal("-tao_lcl_eps1","epsilon 1 tolerance","",lclP->eps1,&lclP->eps1,NULL);CHKERRQ(ierr); 71 ierr = PetscOptionsReal("-tao_lcl_eps2","epsilon 2 tolerance","",lclP->eps2,&lclP->eps2,NULL);CHKERRQ(ierr); 72 ierr = PetscOptionsReal("-tao_lcl_rho0","init value for rho","",lclP->rho0,&lclP->rho0,NULL);CHKERRQ(ierr); 73 ierr = PetscOptionsReal("-tao_lcl_rhomax","max value for rho","",lclP->rhomax,&lclP->rhomax,NULL);CHKERRQ(ierr); 74 lclP->phase2_niter = 1; 75 ierr = PetscOptionsInt("-tao_lcl_phase2_niter","Number of phase 2 iterations in LCL algorithm","",lclP->phase2_niter,&lclP->phase2_niter,NULL);CHKERRQ(ierr); 76 lclP->verbose = PETSC_FALSE; 77 ierr = PetscOptionsBool("-tao_lcl_verbose","Print verbose output","",lclP->verbose,&lclP->verbose,NULL);CHKERRQ(ierr); 78 lclP->tau[0] = lclP->tau[1] = lclP->tau[2] = lclP->tau[3] = 1.0e-4; 79 ierr = PetscOptionsReal("-tao_lcl_tola","Tolerance for first forward solve","",lclP->tau[0],&lclP->tau[0],NULL);CHKERRQ(ierr); 80 ierr = PetscOptionsReal("-tao_lcl_tolb","Tolerance for first adjoint solve","",lclP->tau[1],&lclP->tau[1],NULL);CHKERRQ(ierr); 81 ierr = PetscOptionsReal("-tao_lcl_tolc","Tolerance for second forward solve","",lclP->tau[2],&lclP->tau[2],NULL);CHKERRQ(ierr); 82 ierr = PetscOptionsReal("-tao_lcl_told","Tolerance for second adjoint solve","",lclP->tau[3],&lclP->tau[3],NULL);CHKERRQ(ierr); 83 ierr = PetscOptionsTail();CHKERRQ(ierr); 84 ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 85 ierr = MatSetFromOptions(lclP->R);CHKERRQ(ierr); 86 PetscFunctionReturn(0); 87 } 88 89 static PetscErrorCode TaoView_LCL(Tao tao, PetscViewer viewer) 90 { 91 return 0; 92 } 93 94 static PetscErrorCode TaoSetup_LCL(Tao tao) 95 { 96 TAO_LCL *lclP = (TAO_LCL*)tao->data; 97 PetscInt lo, hi, nlocalstate, nlocaldesign; 98 PetscErrorCode ierr; 99 IS is_state, is_design; 100 101 PetscFunctionBegin; 102 if (!tao->state_is) SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"LCL Solver requires an initial state index set -- use TaoSetStateIS()"); 103 ierr = VecDuplicate(tao->solution, &tao->gradient);CHKERRQ(ierr); 104 ierr = VecDuplicate(tao->solution, &tao->stepdirection);CHKERRQ(ierr); 105 ierr = VecDuplicate(tao->solution, &lclP->W);CHKERRQ(ierr); 106 ierr = VecDuplicate(tao->solution, &lclP->X0);CHKERRQ(ierr); 107 ierr = VecDuplicate(tao->solution, &lclP->G0);CHKERRQ(ierr); 108 ierr = VecDuplicate(tao->solution, &lclP->GL);CHKERRQ(ierr); 109 ierr = VecDuplicate(tao->solution, &lclP->GAugL);CHKERRQ(ierr); 110 111 ierr = VecDuplicate(tao->constraints, &lclP->lamda);CHKERRQ(ierr); 112 ierr = VecDuplicate(tao->constraints, &lclP->WL);CHKERRQ(ierr); 113 ierr = VecDuplicate(tao->constraints, &lclP->lamda0);CHKERRQ(ierr); 114 ierr = VecDuplicate(tao->constraints, &lclP->con1);CHKERRQ(ierr); 115 116 ierr = VecSet(lclP->lamda,0.0);CHKERRQ(ierr); 117 118 ierr = VecGetSize(tao->solution, &lclP->n);CHKERRQ(ierr); 119 ierr = VecGetSize(tao->constraints, &lclP->m);CHKERRQ(ierr); 120 121 ierr = VecCreate(((PetscObject)tao)->comm,&lclP->U);CHKERRQ(ierr); 122 ierr = VecCreate(((PetscObject)tao)->comm,&lclP->V);CHKERRQ(ierr); 123 ierr = ISGetLocalSize(tao->state_is,&nlocalstate);CHKERRQ(ierr); 124 ierr = ISGetLocalSize(tao->design_is,&nlocaldesign);CHKERRQ(ierr); 125 ierr = VecSetSizes(lclP->U,nlocalstate,lclP->m);CHKERRQ(ierr); 126 ierr = VecSetSizes(lclP->V,nlocaldesign,lclP->n-lclP->m);CHKERRQ(ierr); 127 ierr = VecSetType(lclP->U,((PetscObject)(tao->solution))->type_name);CHKERRQ(ierr); 128 ierr = VecSetType(lclP->V,((PetscObject)(tao->solution))->type_name);CHKERRQ(ierr); 129 ierr = VecSetFromOptions(lclP->U);CHKERRQ(ierr); 130 ierr = VecSetFromOptions(lclP->V);CHKERRQ(ierr); 131 ierr = VecDuplicate(lclP->U,&lclP->DU);CHKERRQ(ierr); 132 ierr = VecDuplicate(lclP->U,&lclP->U0);CHKERRQ(ierr); 133 ierr = VecDuplicate(lclP->U,&lclP->GU);CHKERRQ(ierr); 134 ierr = VecDuplicate(lclP->U,&lclP->GU0);CHKERRQ(ierr); 135 ierr = VecDuplicate(lclP->U,&lclP->GAugL_U);CHKERRQ(ierr); 136 ierr = VecDuplicate(lclP->U,&lclP->GL_U);CHKERRQ(ierr); 137 ierr = VecDuplicate(lclP->U,&lclP->GAugL_U0);CHKERRQ(ierr); 138 ierr = VecDuplicate(lclP->U,&lclP->GL_U0);CHKERRQ(ierr); 139 ierr = VecDuplicate(lclP->U,&lclP->WU);CHKERRQ(ierr); 140 ierr = VecDuplicate(lclP->U,&lclP->r);CHKERRQ(ierr); 141 ierr = VecDuplicate(lclP->V,&lclP->V0);CHKERRQ(ierr); 142 ierr = VecDuplicate(lclP->V,&lclP->V1);CHKERRQ(ierr); 143 ierr = VecDuplicate(lclP->V,&lclP->DV);CHKERRQ(ierr); 144 ierr = VecDuplicate(lclP->V,&lclP->s);CHKERRQ(ierr); 145 ierr = VecDuplicate(lclP->V,&lclP->GV);CHKERRQ(ierr); 146 ierr = VecDuplicate(lclP->V,&lclP->GV0);CHKERRQ(ierr); 147 ierr = VecDuplicate(lclP->V,&lclP->dbar);CHKERRQ(ierr); 148 ierr = VecDuplicate(lclP->V,&lclP->GAugL_V);CHKERRQ(ierr); 149 ierr = VecDuplicate(lclP->V,&lclP->GL_V);CHKERRQ(ierr); 150 ierr = VecDuplicate(lclP->V,&lclP->GAugL_V0);CHKERRQ(ierr); 151 ierr = VecDuplicate(lclP->V,&lclP->GL_V0);CHKERRQ(ierr); 152 ierr = VecDuplicate(lclP->V,&lclP->WV);CHKERRQ(ierr); 153 ierr = VecDuplicate(lclP->V,&lclP->g1);CHKERRQ(ierr); 154 ierr = VecDuplicate(lclP->V,&lclP->g2);CHKERRQ(ierr); 155 156 /* create scatters for state, design subvecs */ 157 ierr = VecGetOwnershipRange(lclP->U,&lo,&hi);CHKERRQ(ierr); 158 ierr = ISCreateStride(((PetscObject)lclP->U)->comm,hi-lo,lo,1,&is_state);CHKERRQ(ierr); 159 ierr = VecGetOwnershipRange(lclP->V,&lo,&hi);CHKERRQ(ierr); 160 if (0) { 161 PetscInt sizeU,sizeV; 162 ierr = VecGetSize(lclP->U,&sizeU);CHKERRQ(ierr); 163 ierr = VecGetSize(lclP->V,&sizeV);CHKERRQ(ierr); 164 ierr = PetscPrintf(PETSC_COMM_WORLD,"size(U)=%D, size(V)=%D\n",sizeU,sizeV);CHKERRQ(ierr); 165 } 166 ierr = ISCreateStride(((PetscObject)lclP->V)->comm,hi-lo,lo,1,&is_design);CHKERRQ(ierr); 167 ierr = VecScatterCreate(tao->solution,tao->state_is,lclP->U,is_state,&lclP->state_scatter);CHKERRQ(ierr); 168 ierr = VecScatterCreate(tao->solution,tao->design_is,lclP->V,is_design,&lclP->design_scatter);CHKERRQ(ierr); 169 ierr = ISDestroy(&is_state);CHKERRQ(ierr); 170 ierr = ISDestroy(&is_design);CHKERRQ(ierr); 171 PetscFunctionReturn(0); 172 } 173 174 static PetscErrorCode TaoSolve_LCL(Tao tao) 175 { 176 TAO_LCL *lclP = (TAO_LCL*)tao->data; 177 PetscInt phase2_iter,nlocal,its; 178 TaoLineSearchConvergedReason ls_reason = TAOLINESEARCH_CONTINUE_ITERATING; 179 PetscReal step=1.0,f, descent, aldescent; 180 PetscReal cnorm, mnorm; 181 PetscReal adec,r2,rGL_U,rWU; 182 PetscBool set,pset,flag,pflag,symmetric; 183 PetscErrorCode ierr; 184 185 PetscFunctionBegin; 186 lclP->rho = lclP->rho0; 187 ierr = VecGetLocalSize(lclP->U,&nlocal);CHKERRQ(ierr); 188 ierr = VecGetLocalSize(lclP->V,&nlocal);CHKERRQ(ierr); 189 ierr = MatSetSizes(lclP->R, nlocal, nlocal, lclP->n-lclP->m, lclP->n-lclP->m);CHKERRQ(ierr); 190 ierr = MatLMVMAllocate(lclP->R,lclP->V,lclP->V);CHKERRQ(ierr); 191 lclP->recompute_jacobian_flag = PETSC_TRUE; 192 193 /* Scatter to U,V */ 194 ierr = LCLScatter(lclP,tao->solution,lclP->U,lclP->V);CHKERRQ(ierr); 195 196 /* Evaluate Function, Gradient, Constraints, and Jacobian */ 197 ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&f,tao->gradient);CHKERRQ(ierr); 198 ierr = TaoComputeJacobianState(tao,tao->solution,tao->jacobian_state,tao->jacobian_state_pre,tao->jacobian_state_inv);CHKERRQ(ierr); 199 ierr = TaoComputeJacobianDesign(tao,tao->solution,tao->jacobian_design);CHKERRQ(ierr); 200 ierr = TaoComputeConstraints(tao,tao->solution, tao->constraints);CHKERRQ(ierr); 201 202 /* Scatter gradient to GU,GV */ 203 ierr = LCLScatter(lclP,tao->gradient,lclP->GU,lclP->GV);CHKERRQ(ierr); 204 205 /* Evaluate Lagrangian function and gradient */ 206 /* p0 */ 207 ierr = VecSet(lclP->lamda,0.0);CHKERRQ(ierr); /* Initial guess in CG */ 208 ierr = MatIsSymmetricKnown(tao->jacobian_state,&set,&flag);CHKERRQ(ierr); 209 if (tao->jacobian_state_pre) { 210 ierr = MatIsSymmetricKnown(tao->jacobian_state_pre,&pset,&pflag);CHKERRQ(ierr); 211 } else { 212 pset = pflag = PETSC_TRUE; 213 } 214 if (set && pset && flag && pflag) symmetric = PETSC_TRUE; 215 else symmetric = PETSC_FALSE; 216 217 lclP->solve_type = LCL_ADJOINT2; 218 if (tao->jacobian_state_inv) { 219 if (symmetric) { 220 ierr = MatMult(tao->jacobian_state_inv, lclP->GU, lclP->lamda);CHKERRQ(ierr); } else { 221 ierr = MatMultTranspose(tao->jacobian_state_inv, lclP->GU, lclP->lamda);CHKERRQ(ierr); 222 } 223 } else { 224 ierr = KSPSetOperators(tao->ksp, tao->jacobian_state, tao->jacobian_state_pre);CHKERRQ(ierr); 225 if (symmetric) { 226 ierr = KSPSolve(tao->ksp, lclP->GU, lclP->lamda);CHKERRQ(ierr); 227 } else { 228 ierr = KSPSolveTranspose(tao->ksp, lclP->GU, lclP->lamda);CHKERRQ(ierr); 229 } 230 ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 231 tao->ksp_its+=its; 232 tao->ksp_tot_its+=its; 233 } 234 ierr = VecCopy(lclP->lamda,lclP->lamda0);CHKERRQ(ierr); 235 ierr = LCLComputeAugmentedLagrangianAndGradient(tao->linesearch,tao->solution,&lclP->aug,lclP->GAugL,tao);CHKERRQ(ierr); 236 237 ierr = LCLScatter(lclP,lclP->GL,lclP->GL_U,lclP->GL_V);CHKERRQ(ierr); 238 ierr = LCLScatter(lclP,lclP->GAugL,lclP->GAugL_U,lclP->GAugL_V);CHKERRQ(ierr); 239 240 /* Evaluate constraint norm */ 241 ierr = VecNorm(tao->constraints, NORM_2, &cnorm);CHKERRQ(ierr); 242 ierr = VecNorm(lclP->GAugL, NORM_2, &mnorm);CHKERRQ(ierr); 243 244 /* Monitor convergence */ 245 tao->reason = TAO_CONTINUE_ITERATING; 246 ierr = TaoLogConvergenceHistory(tao,f,mnorm,cnorm,tao->ksp_its);CHKERRQ(ierr); 247 ierr = TaoMonitor(tao,tao->niter,f,mnorm,cnorm,step);CHKERRQ(ierr); 248 ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 249 250 while (tao->reason == TAO_CONTINUE_ITERATING) { 251 /* Call general purpose update function */ 252 if (tao->ops->update) { 253 ierr = (*tao->ops->update)(tao, tao->niter, tao->user_update);CHKERRQ(ierr); 254 } 255 tao->ksp_its=0; 256 /* Compute a descent direction for the linearly constrained subproblem 257 minimize f(u+du, v+dv) 258 s.t. A(u0,v0)du + B(u0,v0)dv = -g(u0,v0) */ 259 260 /* Store the points around the linearization */ 261 ierr = VecCopy(lclP->U, lclP->U0);CHKERRQ(ierr); 262 ierr = VecCopy(lclP->V, lclP->V0);CHKERRQ(ierr); 263 ierr = VecCopy(lclP->GU,lclP->GU0);CHKERRQ(ierr); 264 ierr = VecCopy(lclP->GV,lclP->GV0);CHKERRQ(ierr); 265 ierr = VecCopy(lclP->GAugL_U,lclP->GAugL_U0);CHKERRQ(ierr); 266 ierr = VecCopy(lclP->GAugL_V,lclP->GAugL_V0);CHKERRQ(ierr); 267 ierr = VecCopy(lclP->GL_U,lclP->GL_U0);CHKERRQ(ierr); 268 ierr = VecCopy(lclP->GL_V,lclP->GL_V0);CHKERRQ(ierr); 269 270 lclP->aug0 = lclP->aug; 271 lclP->lgn0 = lclP->lgn; 272 273 /* Given the design variables, we need to project the current iterate 274 onto the linearized constraint. We choose to fix the design variables 275 and solve the linear system for the state variables. The resulting 276 point is the Newton direction */ 277 278 /* Solve r = A\con */ 279 lclP->solve_type = LCL_FORWARD1; 280 ierr = VecSet(lclP->r,0.0);CHKERRQ(ierr); /* Initial guess in CG */ 281 282 if (tao->jacobian_state_inv) { 283 ierr = MatMult(tao->jacobian_state_inv, tao->constraints, lclP->r);CHKERRQ(ierr); 284 } else { 285 ierr = KSPSetOperators(tao->ksp, tao->jacobian_state, tao->jacobian_state_pre);CHKERRQ(ierr); 286 ierr = KSPSolve(tao->ksp, tao->constraints, lclP->r);CHKERRQ(ierr); 287 ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 288 tao->ksp_its+=its; 289 tao->ksp_tot_its+=tao->ksp_its; 290 } 291 292 /* Set design step direction dv to zero */ 293 ierr = VecSet(lclP->s, 0.0);CHKERRQ(ierr); 294 295 /* 296 Check sufficient descent for constraint merit function .5*||con||^2 297 con' Ak r >= eps1 ||r||^(2+eps2) 298 */ 299 300 /* Compute WU= Ak' * con */ 301 if (symmetric) { 302 ierr = MatMult(tao->jacobian_state,tao->constraints,lclP->WU);CHKERRQ(ierr); 303 } else { 304 ierr = MatMultTranspose(tao->jacobian_state,tao->constraints,lclP->WU);CHKERRQ(ierr); 305 } 306 /* Compute r * Ak' * con */ 307 ierr = VecDot(lclP->r,lclP->WU,&rWU);CHKERRQ(ierr); 308 309 /* compute ||r||^(2+eps2) */ 310 ierr = VecNorm(lclP->r,NORM_2,&r2);CHKERRQ(ierr); 311 r2 = PetscPowScalar(r2,2.0+lclP->eps2); 312 adec = lclP->eps1 * r2; 313 314 if (rWU < adec) { 315 ierr = PetscInfo(tao,"Newton direction not descent for constraint, feasibility phase required\n");CHKERRQ(ierr); 316 if (lclP->verbose) { 317 ierr = PetscPrintf(PETSC_COMM_WORLD,"Newton direction not descent for constraint: %g -- using steepest descent\n",(double)descent);CHKERRQ(ierr); 318 } 319 320 ierr = PetscInfo(tao,"Using steepest descent direction instead.\n");CHKERRQ(ierr); 321 ierr = VecSet(lclP->r,0.0);CHKERRQ(ierr); 322 ierr = VecAXPY(lclP->r,-1.0,lclP->WU);CHKERRQ(ierr); 323 ierr = VecDot(lclP->r,lclP->r,&rWU);CHKERRQ(ierr); 324 ierr = VecNorm(lclP->r,NORM_2,&r2);CHKERRQ(ierr); 325 r2 = PetscPowScalar(r2,2.0+lclP->eps2); 326 ierr = VecDot(lclP->r,lclP->GAugL_U,&descent);CHKERRQ(ierr); 327 adec = lclP->eps1 * r2; 328 } 329 330 /* 331 Check descent for aug. lagrangian 332 r' (GUk - Ak'*yk - rho*Ak'*con) <= -eps1 ||r||^(2+eps2) 333 GL_U = GUk - Ak'*yk 334 WU = Ak'*con 335 adec=eps1||r||^(2+eps2) 336 337 ==> 338 Check r'GL_U - rho*r'WU <= adec 339 */ 340 341 ierr = VecDot(lclP->r,lclP->GL_U,&rGL_U);CHKERRQ(ierr); 342 aldescent = rGL_U - lclP->rho*rWU; 343 if (aldescent > -adec) { 344 if (lclP->verbose) { 345 ierr = PetscPrintf(PETSC_COMM_WORLD," Newton direction not descent for augmented Lagrangian: %g",(double)aldescent);CHKERRQ(ierr); 346 } 347 ierr = PetscInfo1(tao,"Newton direction not descent for augmented Lagrangian: %g\n",(double)aldescent);CHKERRQ(ierr); 348 lclP->rho = (rGL_U - adec)/rWU; 349 if (lclP->rho > lclP->rhomax) { 350 lclP->rho = lclP->rhomax; 351 SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_SUP,"rho=%g > rhomax, case not implemented. Increase rhomax (-tao_lcl_rhomax)",(double)lclP->rho); 352 } 353 if (lclP->verbose) { 354 ierr = PetscPrintf(PETSC_COMM_WORLD," Increasing penalty parameter to %g\n",(double)lclP->rho);CHKERRQ(ierr); 355 } 356 ierr = PetscInfo1(tao," Increasing penalty parameter to %g\n",(double)lclP->rho);CHKERRQ(ierr); 357 } 358 359 ierr = LCLComputeAugmentedLagrangianAndGradient(tao->linesearch,tao->solution,&lclP->aug,lclP->GAugL,tao);CHKERRQ(ierr); 360 ierr = LCLScatter(lclP,lclP->GL,lclP->GL_U,lclP->GL_V);CHKERRQ(ierr); 361 ierr = LCLScatter(lclP,lclP->GAugL,lclP->GAugL_U,lclP->GAugL_V);CHKERRQ(ierr); 362 363 /* We now minimize the augmented Lagrangian along the Newton direction */ 364 ierr = VecScale(lclP->r,-1.0);CHKERRQ(ierr); 365 ierr = LCLGather(lclP, lclP->r,lclP->s,tao->stepdirection);CHKERRQ(ierr); 366 ierr = VecScale(lclP->r,-1.0);CHKERRQ(ierr); 367 ierr = LCLGather(lclP, lclP->GAugL_U0, lclP->GAugL_V0, lclP->GAugL);CHKERRQ(ierr); 368 ierr = LCLGather(lclP, lclP->U0,lclP->V0,lclP->X0);CHKERRQ(ierr); 369 370 lclP->recompute_jacobian_flag = PETSC_TRUE; 371 372 ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0);CHKERRQ(ierr); 373 ierr = TaoLineSearchSetType(tao->linesearch, TAOLINESEARCHMT);CHKERRQ(ierr); 374 ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 375 ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &lclP->aug, lclP->GAugL, tao->stepdirection, &step, &ls_reason);CHKERRQ(ierr); 376 if (lclP->verbose) { 377 ierr = PetscPrintf(PETSC_COMM_WORLD,"Steplength = %g\n",(double)step);CHKERRQ(ierr); 378 } 379 380 ierr = LCLScatter(lclP,tao->solution,lclP->U,lclP->V);CHKERRQ(ierr); 381 ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&f,tao->gradient);CHKERRQ(ierr); 382 ierr = LCLScatter(lclP,tao->gradient,lclP->GU,lclP->GV);CHKERRQ(ierr); 383 384 ierr = LCLScatter(lclP,lclP->GAugL,lclP->GAugL_U,lclP->GAugL_V);CHKERRQ(ierr); 385 386 /* Check convergence */ 387 ierr = VecNorm(lclP->GAugL, NORM_2, &mnorm);CHKERRQ(ierr); 388 ierr = VecNorm(tao->constraints, NORM_2, &cnorm);CHKERRQ(ierr); 389 ierr = TaoLogConvergenceHistory(tao,f,mnorm,cnorm,tao->ksp_its);CHKERRQ(ierr); 390 ierr = TaoMonitor(tao,tao->niter,f,mnorm,cnorm,step);CHKERRQ(ierr); 391 ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 392 if (tao->reason != TAO_CONTINUE_ITERATING) { 393 break; 394 } 395 396 /* TODO: use a heuristic to choose how many iterations should be performed within phase 2 */ 397 for (phase2_iter=0; phase2_iter<lclP->phase2_niter; phase2_iter++) { 398 /* We now minimize the objective function starting from the fraction of 399 the Newton point accepted by applying one step of a reduced-space 400 method. The optimization problem is: 401 402 minimize f(u+du, v+dv) 403 s. t. A(u0,v0)du + B(u0,v0)du = -alpha g(u0,v0) 404 405 In particular, we have that 406 du = -inv(A)*(Bdv + alpha g) */ 407 408 ierr = TaoComputeJacobianState(tao,lclP->X0,tao->jacobian_state,tao->jacobian_state_pre,tao->jacobian_state_inv);CHKERRQ(ierr); 409 ierr = TaoComputeJacobianDesign(tao,lclP->X0,tao->jacobian_design);CHKERRQ(ierr); 410 411 /* Store V and constraints */ 412 ierr = VecCopy(lclP->V, lclP->V1);CHKERRQ(ierr); 413 ierr = VecCopy(tao->constraints,lclP->con1);CHKERRQ(ierr); 414 415 /* Compute multipliers */ 416 /* p1 */ 417 ierr = VecSet(lclP->lamda,0.0);CHKERRQ(ierr); /* Initial guess in CG */ 418 lclP->solve_type = LCL_ADJOINT1; 419 ierr = MatIsSymmetricKnown(tao->jacobian_state,&set,&flag);CHKERRQ(ierr); 420 if (tao->jacobian_state_pre) { 421 ierr = MatIsSymmetricKnown(tao->jacobian_state_pre,&pset,&pflag);CHKERRQ(ierr); 422 } else { 423 pset = pflag = PETSC_TRUE; 424 } 425 if (set && pset && flag && pflag) symmetric = PETSC_TRUE; 426 else symmetric = PETSC_FALSE; 427 428 if (tao->jacobian_state_inv) { 429 if (symmetric) { 430 ierr = MatMult(tao->jacobian_state_inv, lclP->GAugL_U, lclP->lamda);CHKERRQ(ierr); 431 } else { 432 ierr = MatMultTranspose(tao->jacobian_state_inv, lclP->GAugL_U, lclP->lamda);CHKERRQ(ierr); 433 } 434 } else { 435 if (symmetric) { 436 ierr = KSPSolve(tao->ksp, lclP->GAugL_U, lclP->lamda);CHKERRQ(ierr); 437 } else { 438 ierr = KSPSolveTranspose(tao->ksp, lclP->GAugL_U, lclP->lamda);CHKERRQ(ierr); 439 } 440 ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 441 tao->ksp_its+=its; 442 tao->ksp_tot_its+=its; 443 } 444 ierr = MatMultTranspose(tao->jacobian_design,lclP->lamda,lclP->g1);CHKERRQ(ierr); 445 ierr = VecAXPY(lclP->g1,-1.0,lclP->GAugL_V);CHKERRQ(ierr); 446 447 /* Compute the limited-memory quasi-newton direction */ 448 if (tao->niter > 0) { 449 ierr = MatSolve(lclP->R,lclP->g1,lclP->s);CHKERRQ(ierr); 450 ierr = VecDot(lclP->s,lclP->g1,&descent);CHKERRQ(ierr); 451 if (descent <= 0) { 452 if (lclP->verbose) { 453 ierr = PetscPrintf(PETSC_COMM_WORLD,"Reduced-space direction not descent: %g\n",(double)descent);CHKERRQ(ierr); 454 } 455 ierr = VecCopy(lclP->g1,lclP->s);CHKERRQ(ierr); 456 } 457 } else { 458 ierr = VecCopy(lclP->g1,lclP->s);CHKERRQ(ierr); 459 } 460 ierr = VecScale(lclP->g1,-1.0);CHKERRQ(ierr); 461 462 /* Recover the full space direction */ 463 ierr = MatMult(tao->jacobian_design,lclP->s,lclP->WU);CHKERRQ(ierr); 464 /* ierr = VecSet(lclP->r,0.0);CHKERRQ(ierr); */ /* Initial guess in CG */ 465 lclP->solve_type = LCL_FORWARD2; 466 if (tao->jacobian_state_inv) { 467 ierr = MatMult(tao->jacobian_state_inv,lclP->WU,lclP->r);CHKERRQ(ierr); 468 } else { 469 ierr = KSPSolve(tao->ksp, lclP->WU, lclP->r);CHKERRQ(ierr); 470 ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 471 tao->ksp_its += its; 472 tao->ksp_tot_its+=its; 473 } 474 475 /* We now minimize the augmented Lagrangian along the direction -r,s */ 476 ierr = VecScale(lclP->r, -1.0);CHKERRQ(ierr); 477 ierr = LCLGather(lclP,lclP->r,lclP->s,tao->stepdirection);CHKERRQ(ierr); 478 ierr = VecScale(lclP->r, -1.0);CHKERRQ(ierr); 479 lclP->recompute_jacobian_flag = PETSC_TRUE; 480 481 ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0);CHKERRQ(ierr); 482 ierr = TaoLineSearchSetType(tao->linesearch,TAOLINESEARCHMT);CHKERRQ(ierr); 483 ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 484 ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &lclP->aug, lclP->GAugL, tao->stepdirection,&step,&ls_reason);CHKERRQ(ierr); 485 if (lclP->verbose) { 486 ierr = PetscPrintf(PETSC_COMM_WORLD,"Reduced-space steplength = %g\n",(double)step);CHKERRQ(ierr); 487 } 488 489 ierr = LCLScatter(lclP,tao->solution,lclP->U,lclP->V);CHKERRQ(ierr); 490 ierr = LCLScatter(lclP,lclP->GL,lclP->GL_U,lclP->GL_V);CHKERRQ(ierr); 491 ierr = LCLScatter(lclP,lclP->GAugL,lclP->GAugL_U,lclP->GAugL_V);CHKERRQ(ierr); 492 ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&f,tao->gradient);CHKERRQ(ierr); 493 ierr = LCLScatter(lclP,tao->gradient,lclP->GU,lclP->GV);CHKERRQ(ierr); 494 495 /* Compute the reduced gradient at the new point */ 496 497 ierr = TaoComputeJacobianState(tao,lclP->X0,tao->jacobian_state,tao->jacobian_state_pre,tao->jacobian_state_inv);CHKERRQ(ierr); 498 ierr = TaoComputeJacobianDesign(tao,lclP->X0,tao->jacobian_design);CHKERRQ(ierr); 499 500 /* p2 */ 501 /* Compute multipliers, using lamda-rho*con as an initial guess in PCG */ 502 if (phase2_iter==0) { 503 ierr = VecWAXPY(lclP->lamda,-lclP->rho,lclP->con1,lclP->lamda0);CHKERRQ(ierr); 504 } else { 505 ierr = VecAXPY(lclP->lamda,-lclP->rho,tao->constraints);CHKERRQ(ierr); 506 } 507 508 ierr = MatIsSymmetricKnown(tao->jacobian_state,&set,&flag);CHKERRQ(ierr); 509 if (tao->jacobian_state_pre) { 510 ierr = MatIsSymmetricKnown(tao->jacobian_state_pre,&pset,&pflag);CHKERRQ(ierr); 511 } else { 512 pset = pflag = PETSC_TRUE; 513 } 514 if (set && pset && flag && pflag) symmetric = PETSC_TRUE; 515 else symmetric = PETSC_FALSE; 516 517 lclP->solve_type = LCL_ADJOINT2; 518 if (tao->jacobian_state_inv) { 519 if (symmetric) { 520 ierr = MatMult(tao->jacobian_state_inv, lclP->GU, lclP->lamda);CHKERRQ(ierr); 521 } else { 522 ierr = MatMultTranspose(tao->jacobian_state_inv, lclP->GU, lclP->lamda);CHKERRQ(ierr); 523 } 524 } else { 525 if (symmetric) { 526 ierr = KSPSolve(tao->ksp, lclP->GU, lclP->lamda);CHKERRQ(ierr); 527 } else { 528 ierr = KSPSolveTranspose(tao->ksp, lclP->GU, lclP->lamda);CHKERRQ(ierr); 529 } 530 ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 531 tao->ksp_its += its; 532 tao->ksp_tot_its += its; 533 } 534 535 ierr = MatMultTranspose(tao->jacobian_design,lclP->lamda,lclP->g2);CHKERRQ(ierr); 536 ierr = VecAXPY(lclP->g2,-1.0,lclP->GV);CHKERRQ(ierr); 537 538 ierr = VecScale(lclP->g2,-1.0);CHKERRQ(ierr); 539 540 /* Update the quasi-newton approximation */ 541 ierr = MatLMVMUpdate(lclP->R,lclP->V,lclP->g2);CHKERRQ(ierr); 542 /* Use "-tao_ls_type gpcg -tao_ls_ftol 0 -tao_lmm_broyden_phi 0.0 -tao_lmm_scale_type scalar" to obtain agreement with Matlab code */ 543 544 } 545 546 ierr = VecCopy(lclP->lamda,lclP->lamda0);CHKERRQ(ierr); 547 548 /* Evaluate Function, Gradient, Constraints, and Jacobian */ 549 ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&f,tao->gradient);CHKERRQ(ierr); 550 ierr = LCLScatter(lclP,tao->solution,lclP->U,lclP->V);CHKERRQ(ierr); 551 ierr = LCLScatter(lclP,tao->gradient,lclP->GU,lclP->GV);CHKERRQ(ierr); 552 553 ierr = TaoComputeJacobianState(tao,tao->solution,tao->jacobian_state,tao->jacobian_state_pre,tao->jacobian_state_inv);CHKERRQ(ierr); 554 ierr = TaoComputeJacobianDesign(tao,tao->solution,tao->jacobian_design);CHKERRQ(ierr); 555 ierr = TaoComputeConstraints(tao,tao->solution, tao->constraints);CHKERRQ(ierr); 556 557 ierr = LCLComputeAugmentedLagrangianAndGradient(tao->linesearch,tao->solution,&lclP->aug,lclP->GAugL,tao);CHKERRQ(ierr); 558 559 ierr = VecNorm(lclP->GAugL, NORM_2, &mnorm);CHKERRQ(ierr); 560 561 /* Evaluate constraint norm */ 562 ierr = VecNorm(tao->constraints, NORM_2, &cnorm);CHKERRQ(ierr); 563 564 /* Monitor convergence */ 565 tao->niter++; 566 ierr = TaoLogConvergenceHistory(tao,f,mnorm,cnorm,tao->ksp_its);CHKERRQ(ierr); 567 ierr = TaoMonitor(tao,tao->niter,f,mnorm,cnorm,step);CHKERRQ(ierr); 568 ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 569 } 570 PetscFunctionReturn(0); 571 } 572 573 /*MC 574 TAOLCL - linearly constrained lagrangian method for pde-constrained optimization 575 576 + -tao_lcl_eps1 - epsilon 1 tolerance 577 . -tao_lcl_eps2","epsilon 2 tolerance","",lclP->eps2,&lclP->eps2,NULL);CHKERRQ(ierr); 578 . -tao_lcl_rho0","init value for rho","",lclP->rho0,&lclP->rho0,NULL);CHKERRQ(ierr); 579 . -tao_lcl_rhomax","max value for rho","",lclP->rhomax,&lclP->rhomax,NULL);CHKERRQ(ierr); 580 . -tao_lcl_phase2_niter - Number of phase 2 iterations in LCL algorithm 581 . -tao_lcl_verbose - Print verbose output if True 582 . -tao_lcl_tola - Tolerance for first forward solve 583 . -tao_lcl_tolb - Tolerance for first adjoint solve 584 . -tao_lcl_tolc - Tolerance for second forward solve 585 - -tao_lcl_told - Tolerance for second adjoint solve 586 587 Level: beginner 588 M*/ 589 PETSC_EXTERN PetscErrorCode TaoCreate_LCL(Tao tao) 590 { 591 TAO_LCL *lclP; 592 PetscErrorCode ierr; 593 const char *morethuente_type = TAOLINESEARCHMT; 594 595 PetscFunctionBegin; 596 tao->ops->setup = TaoSetup_LCL; 597 tao->ops->solve = TaoSolve_LCL; 598 tao->ops->view = TaoView_LCL; 599 tao->ops->setfromoptions = TaoSetFromOptions_LCL; 600 tao->ops->destroy = TaoDestroy_LCL; 601 ierr = PetscNewLog(tao,&lclP);CHKERRQ(ierr); 602 tao->data = (void*)lclP; 603 604 /* Override default settings (unless already changed) */ 605 if (!tao->max_it_changed) tao->max_it = 200; 606 if (!tao->catol_changed) tao->catol = 1.0e-4; 607 if (!tao->gatol_changed) tao->gttol = 1.0e-4; 608 if (!tao->grtol_changed) tao->gttol = 1.0e-4; 609 if (!tao->gttol_changed) tao->gttol = 1.0e-4; 610 lclP->rho0 = 1.0e-4; 611 lclP->rhomax=1e5; 612 lclP->eps1 = 1.0e-8; 613 lclP->eps2 = 0.0; 614 lclP->solve_type=2; 615 lclP->tau[0] = lclP->tau[1] = lclP->tau[2] = lclP->tau[3] = 1.0e-4; 616 ierr = TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch);CHKERRQ(ierr); 617 ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 618 ierr = TaoLineSearchSetType(tao->linesearch, morethuente_type);CHKERRQ(ierr); 619 ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 620 621 ierr = TaoLineSearchSetObjectiveAndGradientRoutine(tao->linesearch,LCLComputeAugmentedLagrangianAndGradient, tao);CHKERRQ(ierr); 622 ierr = KSPCreate(((PetscObject)tao)->comm,&tao->ksp);CHKERRQ(ierr); 623 ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1);CHKERRQ(ierr); 624 ierr = KSPSetOptionsPrefix(tao->ksp, tao->hdr.prefix);CHKERRQ(ierr); 625 ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 626 627 ierr = MatCreate(((PetscObject)tao)->comm, &lclP->R);CHKERRQ(ierr); 628 ierr = MatSetType(lclP->R, MATLMVMBFGS);CHKERRQ(ierr); 629 PetscFunctionReturn(0); 630 } 631 632 static PetscErrorCode LCLComputeLagrangianAndGradient(TaoLineSearch ls, Vec X, PetscReal *f, Vec G, void *ptr) 633 { 634 Tao tao = (Tao)ptr; 635 TAO_LCL *lclP = (TAO_LCL*)tao->data; 636 PetscBool set,pset,flag,pflag,symmetric; 637 PetscReal cdotl; 638 PetscErrorCode ierr; 639 640 PetscFunctionBegin; 641 ierr = TaoComputeObjectiveAndGradient(tao,X,f,G);CHKERRQ(ierr); 642 ierr = LCLScatter(lclP,G,lclP->GU,lclP->GV);CHKERRQ(ierr); 643 if (lclP->recompute_jacobian_flag) { 644 ierr = TaoComputeJacobianState(tao,X,tao->jacobian_state,tao->jacobian_state_pre,tao->jacobian_state_inv);CHKERRQ(ierr); 645 ierr = TaoComputeJacobianDesign(tao,X,tao->jacobian_design);CHKERRQ(ierr); 646 } 647 ierr = TaoComputeConstraints(tao,X, tao->constraints);CHKERRQ(ierr); 648 ierr = MatIsSymmetricKnown(tao->jacobian_state,&set,&flag);CHKERRQ(ierr); 649 if (tao->jacobian_state_pre) { 650 ierr = MatIsSymmetricKnown(tao->jacobian_state_pre,&pset,&pflag);CHKERRQ(ierr); 651 } else { 652 pset = pflag = PETSC_TRUE; 653 } 654 if (set && pset && flag && pflag) symmetric = PETSC_TRUE; 655 else symmetric = PETSC_FALSE; 656 657 ierr = VecDot(lclP->lamda0, tao->constraints, &cdotl);CHKERRQ(ierr); 658 lclP->lgn = *f - cdotl; 659 660 /* Gradient of Lagrangian GL = G - J' * lamda */ 661 /* WU = A' * WL 662 WV = B' * WL */ 663 if (symmetric) { 664 ierr = MatMult(tao->jacobian_state,lclP->lamda0,lclP->GL_U);CHKERRQ(ierr); 665 } else { 666 ierr = MatMultTranspose(tao->jacobian_state,lclP->lamda0,lclP->GL_U);CHKERRQ(ierr); 667 } 668 ierr = MatMultTranspose(tao->jacobian_design,lclP->lamda0,lclP->GL_V);CHKERRQ(ierr); 669 ierr = VecScale(lclP->GL_U,-1.0);CHKERRQ(ierr); 670 ierr = VecScale(lclP->GL_V,-1.0);CHKERRQ(ierr); 671 ierr = VecAXPY(lclP->GL_U,1.0,lclP->GU);CHKERRQ(ierr); 672 ierr = VecAXPY(lclP->GL_V,1.0,lclP->GV);CHKERRQ(ierr); 673 ierr = LCLGather(lclP,lclP->GL_U,lclP->GL_V,lclP->GL);CHKERRQ(ierr); 674 675 f[0] = lclP->lgn; 676 ierr = VecCopy(lclP->GL,G);CHKERRQ(ierr); 677 PetscFunctionReturn(0); 678 } 679 680 static PetscErrorCode LCLComputeAugmentedLagrangianAndGradient(TaoLineSearch ls, Vec X, PetscReal *f, Vec G, void *ptr) 681 { 682 Tao tao = (Tao)ptr; 683 TAO_LCL *lclP = (TAO_LCL*)tao->data; 684 PetscReal con2; 685 PetscBool flag,pflag,set,pset,symmetric; 686 PetscErrorCode ierr; 687 688 PetscFunctionBegin; 689 ierr = LCLComputeLagrangianAndGradient(tao->linesearch,X,f,G,tao);CHKERRQ(ierr); 690 ierr = LCLScatter(lclP,G,lclP->GL_U,lclP->GL_V);CHKERRQ(ierr); 691 ierr = VecDot(tao->constraints,tao->constraints,&con2);CHKERRQ(ierr); 692 lclP->aug = lclP->lgn + 0.5*lclP->rho*con2; 693 694 /* Gradient of Aug. Lagrangian GAugL = GL + rho * J' c */ 695 /* WU = A' * c 696 WV = B' * c */ 697 ierr = MatIsSymmetricKnown(tao->jacobian_state,&set,&flag);CHKERRQ(ierr); 698 if (tao->jacobian_state_pre) { 699 ierr = MatIsSymmetricKnown(tao->jacobian_state_pre,&pset,&pflag);CHKERRQ(ierr); 700 } else { 701 pset = pflag = PETSC_TRUE; 702 } 703 if (set && pset && flag && pflag) symmetric = PETSC_TRUE; 704 else symmetric = PETSC_FALSE; 705 706 if (symmetric) { 707 ierr = MatMult(tao->jacobian_state,tao->constraints,lclP->GAugL_U);CHKERRQ(ierr); 708 } else { 709 ierr = MatMultTranspose(tao->jacobian_state,tao->constraints,lclP->GAugL_U);CHKERRQ(ierr); 710 } 711 712 ierr = MatMultTranspose(tao->jacobian_design,tao->constraints,lclP->GAugL_V);CHKERRQ(ierr); 713 ierr = VecAYPX(lclP->GAugL_U,lclP->rho,lclP->GL_U);CHKERRQ(ierr); 714 ierr = VecAYPX(lclP->GAugL_V,lclP->rho,lclP->GL_V);CHKERRQ(ierr); 715 ierr = LCLGather(lclP,lclP->GAugL_U,lclP->GAugL_V,lclP->GAugL);CHKERRQ(ierr); 716 717 f[0] = lclP->aug; 718 ierr = VecCopy(lclP->GAugL,G);CHKERRQ(ierr); 719 PetscFunctionReturn(0); 720 } 721 722 PetscErrorCode LCLGather(TAO_LCL *lclP, Vec u, Vec v, Vec x) 723 { 724 PetscErrorCode ierr; 725 PetscFunctionBegin; 726 ierr = VecScatterBegin(lclP->state_scatter, u, x, INSERT_VALUES, SCATTER_REVERSE);CHKERRQ(ierr); 727 ierr = VecScatterEnd(lclP->state_scatter, u, x, INSERT_VALUES, SCATTER_REVERSE);CHKERRQ(ierr); 728 ierr = VecScatterBegin(lclP->design_scatter, v, x, INSERT_VALUES, SCATTER_REVERSE);CHKERRQ(ierr); 729 ierr = VecScatterEnd(lclP->design_scatter, v, x, INSERT_VALUES, SCATTER_REVERSE);CHKERRQ(ierr); 730 PetscFunctionReturn(0); 731 732 } 733 PetscErrorCode LCLScatter(TAO_LCL *lclP, Vec x, Vec u, Vec v) 734 { 735 PetscErrorCode ierr; 736 PetscFunctionBegin; 737 ierr = VecScatterBegin(lclP->state_scatter, x, u, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); 738 ierr = VecScatterEnd(lclP->state_scatter, x, u, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); 739 ierr = VecScatterBegin(lclP->design_scatter, x, v, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); 740 ierr = VecScatterEnd(lclP->design_scatter, x, v, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); 741 PetscFunctionReturn(0); 742 743 } 744