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