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