1c4762a1bSJed Brown #include <petsctao.h> 2c4762a1bSJed Brown 3c4762a1bSJed Brown /*T 4c4762a1bSJed Brown Concepts: TAO^Solving a system of nonlinear equations, nonlinear least squares 5c4762a1bSJed Brown Routines: TaoCreate(); 6c4762a1bSJed Brown Routines: TaoSetType(); 7*a82e8c82SStefano Zampini Routines: TaoSetSolution(); 8*a82e8c82SStefano Zampini Routines: TaoSetObjective(); 9*a82e8c82SStefano Zampini Routines: TaoSetGradient(); 10c4762a1bSJed Brown Routines: TaoSetConstraintsRoutine(); 11c4762a1bSJed Brown Routines: TaoSetJacobianStateRoutine(); 12c4762a1bSJed Brown Routines: TaoSetJacobianDesignRoutine(); 13c4762a1bSJed Brown Routines: TaoSetStateDesignIS(); 14c4762a1bSJed Brown Routines: TaoSetFromOptions(); 15c4762a1bSJed Brown Routines: TaoSolve(); 16c4762a1bSJed Brown Routines: TaoDestroy(); 17c4762a1bSJed Brown Processors: 1 18c4762a1bSJed Brown T*/ 19c4762a1bSJed Brown 20c4762a1bSJed Brown typedef struct { 21c4762a1bSJed Brown PetscInt n; /* Number of variables */ 22c4762a1bSJed Brown PetscInt m; /* Number of constraints */ 23c4762a1bSJed Brown PetscInt mx; /* grid points in each direction */ 24c4762a1bSJed Brown PetscInt nt; /* Number of time steps */ 25c4762a1bSJed Brown PetscInt ndata; /* Number of data points per sample */ 26c4762a1bSJed Brown IS s_is; 27c4762a1bSJed Brown IS d_is; 28c4762a1bSJed Brown VecScatter state_scatter; 29c4762a1bSJed Brown VecScatter design_scatter; 30c4762a1bSJed Brown VecScatter *uxi_scatter,*uyi_scatter,*ux_scatter,*uy_scatter,*ui_scatter; 31c4762a1bSJed Brown VecScatter *yi_scatter; 32c4762a1bSJed Brown 33c4762a1bSJed Brown Mat Js,Jd,JsBlockPrec,JsInv,JsBlock; 34c4762a1bSJed Brown PetscBool jformed,c_formed; 35c4762a1bSJed Brown 36c4762a1bSJed Brown PetscReal alpha; /* Regularization parameter */ 37c4762a1bSJed Brown PetscReal gamma; 38c4762a1bSJed Brown PetscReal ht; /* Time step */ 39c4762a1bSJed Brown PetscReal T; /* Final time */ 40c4762a1bSJed Brown Mat Q,QT; 41c4762a1bSJed Brown Mat L,LT; 42c4762a1bSJed Brown Mat Div,Divwork,Divxy[2]; 43c4762a1bSJed Brown Mat Grad,Gradxy[2]; 44c4762a1bSJed Brown Mat M; 45c4762a1bSJed Brown Mat *C,*Cwork; 46c4762a1bSJed Brown /* Mat Hs,Hd,Hsd; */ 47c4762a1bSJed Brown Vec q; 48c4762a1bSJed Brown Vec ur; /* reference */ 49c4762a1bSJed Brown 50c4762a1bSJed Brown Vec d; 51c4762a1bSJed Brown Vec dwork; 52c4762a1bSJed Brown 53c4762a1bSJed Brown Vec y; /* state variables */ 54c4762a1bSJed Brown Vec ywork; 55c4762a1bSJed Brown Vec ytrue; 56c4762a1bSJed Brown Vec *yi,*yiwork,*ziwork; 57c4762a1bSJed Brown Vec *uxi,*uyi,*uxiwork,*uyiwork,*ui,*uiwork; 58c4762a1bSJed Brown 59c4762a1bSJed Brown Vec u; /* design variables */ 60c4762a1bSJed Brown Vec uwork,vwork; 61c4762a1bSJed Brown Vec utrue; 62c4762a1bSJed Brown 63c4762a1bSJed Brown Vec js_diag; 64c4762a1bSJed Brown 65c4762a1bSJed Brown Vec c; /* constraint vector */ 66c4762a1bSJed Brown Vec cwork; 67c4762a1bSJed Brown 68c4762a1bSJed Brown Vec lwork; 69c4762a1bSJed Brown 70c4762a1bSJed Brown KSP solver; 71c4762a1bSJed Brown PC prec; 72c4762a1bSJed Brown PetscInt block_index; 73c4762a1bSJed Brown 74c4762a1bSJed Brown PetscInt ksp_its; 75c4762a1bSJed Brown PetscInt ksp_its_initial; 76c4762a1bSJed Brown } AppCtx; 77c4762a1bSJed Brown 78c4762a1bSJed Brown PetscErrorCode FormFunction(Tao, Vec, PetscReal*, void*); 79c4762a1bSJed Brown PetscErrorCode FormGradient(Tao, Vec, Vec, void*); 80c4762a1bSJed Brown PetscErrorCode FormFunctionGradient(Tao, Vec, PetscReal*, Vec, void*); 81c4762a1bSJed Brown PetscErrorCode FormJacobianState(Tao, Vec, Mat, Mat, Mat, void*); 82c4762a1bSJed Brown PetscErrorCode FormJacobianDesign(Tao, Vec, Mat,void*); 83c4762a1bSJed Brown PetscErrorCode FormConstraints(Tao, Vec, Vec, void*); 84c4762a1bSJed Brown PetscErrorCode FormHessian(Tao, Vec, Mat, Mat, void*); 85c4762a1bSJed Brown PetscErrorCode Gather(Vec x, Vec state, VecScatter s_scat, Vec design, VecScatter d_scat); 86c4762a1bSJed Brown PetscErrorCode Scatter(Vec x, Vec state, VecScatter s_scat, Vec design, VecScatter d_scat); 87c4762a1bSJed Brown PetscErrorCode HyperbolicInitialize(AppCtx *user); 88c4762a1bSJed Brown PetscErrorCode HyperbolicDestroy(AppCtx *user); 89c4762a1bSJed Brown PetscErrorCode HyperbolicMonitor(Tao, void*); 90c4762a1bSJed Brown 91c4762a1bSJed Brown PetscErrorCode StateMatMult(Mat,Vec,Vec); 92c4762a1bSJed Brown PetscErrorCode StateMatBlockMult(Mat,Vec,Vec); 93c4762a1bSJed Brown PetscErrorCode StateMatBlockMultTranspose(Mat,Vec,Vec); 94c4762a1bSJed Brown PetscErrorCode StateMatMultTranspose(Mat,Vec,Vec); 95c4762a1bSJed Brown PetscErrorCode StateMatGetDiagonal(Mat,Vec); 96c4762a1bSJed Brown PetscErrorCode StateMatDuplicate(Mat,MatDuplicateOption,Mat*); 97c4762a1bSJed Brown PetscErrorCode StateMatInvMult(Mat,Vec,Vec); 98c4762a1bSJed Brown PetscErrorCode StateMatInvTransposeMult(Mat,Vec,Vec); 99c4762a1bSJed Brown PetscErrorCode StateMatBlockPrecMult(PC,Vec,Vec); 100c4762a1bSJed Brown 101c4762a1bSJed Brown PetscErrorCode DesignMatMult(Mat,Vec,Vec); 102c4762a1bSJed Brown PetscErrorCode DesignMatMultTranspose(Mat,Vec,Vec); 103c4762a1bSJed Brown 104c4762a1bSJed Brown PetscErrorCode Scatter_yi(Vec,Vec*,VecScatter*,PetscInt); /* y to y1,y2,...,y_nt */ 105c4762a1bSJed Brown PetscErrorCode Gather_yi(Vec,Vec*,VecScatter*,PetscInt); 106c4762a1bSJed Brown PetscErrorCode Scatter_uxi_uyi(Vec,Vec*,VecScatter*,Vec*,VecScatter*,PetscInt); /* u to ux_1,uy_1,ux_2,uy_2,...,u */ 107c4762a1bSJed Brown PetscErrorCode Gather_uxi_uyi(Vec,Vec*,VecScatter*,Vec*,VecScatter*,PetscInt); 108c4762a1bSJed Brown 109c4762a1bSJed Brown static char help[]=""; 110c4762a1bSJed Brown 111c4762a1bSJed Brown int main(int argc, char **argv) 112c4762a1bSJed Brown { 113c4762a1bSJed Brown PetscErrorCode ierr; 114c4762a1bSJed Brown Vec x,x0; 115c4762a1bSJed Brown Tao tao; 116c4762a1bSJed Brown AppCtx user; 117c4762a1bSJed Brown IS is_allstate,is_alldesign; 118c4762a1bSJed Brown PetscInt lo,hi,hi2,lo2,ksp_old; 119c4762a1bSJed Brown PetscInt ntests = 1; 120c4762a1bSJed Brown PetscInt i; 121c4762a1bSJed Brown #if defined(PETSC_USE_LOG) 122c4762a1bSJed Brown PetscLogStage stages[1]; 123c4762a1bSJed Brown #endif 124c4762a1bSJed Brown 125c4762a1bSJed Brown ierr = PetscInitialize(&argc, &argv, (char*)0,help);if (ierr) return ierr; 126c4762a1bSJed Brown user.mx = 32; 12776280437SVaclav Hapla ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"hyperbolic example",NULL);CHKERRQ(ierr); 128c4762a1bSJed Brown ierr = PetscOptionsInt("-mx","Number of grid points in each direction","",user.mx,&user.mx,NULL);CHKERRQ(ierr); 129c4762a1bSJed Brown user.nt = 16; 130c4762a1bSJed Brown ierr = PetscOptionsInt("-nt","Number of time steps","",user.nt,&user.nt,NULL);CHKERRQ(ierr); 131c4762a1bSJed Brown user.ndata = 64; 132c4762a1bSJed Brown ierr = PetscOptionsInt("-ndata","Numbers of data points per sample","",user.ndata,&user.ndata,NULL);CHKERRQ(ierr); 133c4762a1bSJed Brown user.alpha = 10.0; 134c4762a1bSJed Brown ierr = PetscOptionsReal("-alpha","Regularization parameter","",user.alpha,&user.alpha,NULL);CHKERRQ(ierr); 135c4762a1bSJed Brown user.T = 1.0/32.0; 136c4762a1bSJed Brown ierr = PetscOptionsReal("-Tfinal","Final time","",user.T,&user.T,NULL);CHKERRQ(ierr); 13776280437SVaclav Hapla ierr = PetscOptionsInt("-ntests","Number of times to repeat TaoSolve","",ntests,&ntests,NULL);CHKERRQ(ierr); 13876280437SVaclav Hapla ierr = PetscOptionsEnd();CHKERRQ(ierr); 139c4762a1bSJed Brown 140c4762a1bSJed Brown user.m = user.mx*user.mx*user.nt; /* number of constraints */ 141c4762a1bSJed Brown user.n = user.mx*user.mx*3*user.nt; /* number of variables */ 142c4762a1bSJed Brown user.ht = user.T/user.nt; /* Time step */ 143c4762a1bSJed Brown user.gamma = user.T*user.ht / (user.mx*user.mx); 144c4762a1bSJed Brown 145c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&user.u);CHKERRQ(ierr); 146c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&user.y);CHKERRQ(ierr); 147c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&user.c);CHKERRQ(ierr); 148c4762a1bSJed Brown ierr = VecSetSizes(user.u,PETSC_DECIDE,user.n-user.m);CHKERRQ(ierr); 149c4762a1bSJed Brown ierr = VecSetSizes(user.y,PETSC_DECIDE,user.m);CHKERRQ(ierr); 150c4762a1bSJed Brown ierr = VecSetSizes(user.c,PETSC_DECIDE,user.m);CHKERRQ(ierr); 151c4762a1bSJed Brown ierr = VecSetFromOptions(user.u);CHKERRQ(ierr); 152c4762a1bSJed Brown ierr = VecSetFromOptions(user.y);CHKERRQ(ierr); 153c4762a1bSJed Brown ierr = VecSetFromOptions(user.c);CHKERRQ(ierr); 154c4762a1bSJed Brown 155c4762a1bSJed Brown /* Create scatters for reduced spaces. 156c4762a1bSJed Brown If the state vector y and design vector u are partitioned as 157c4762a1bSJed Brown [y_1; y_2; ...; y_np] and [u_1; u_2; ...; u_np] (with np = # of processors), 158c4762a1bSJed Brown then the solution vector x is organized as 159c4762a1bSJed Brown [y_1; u_1; y_2; u_2; ...; y_np; u_np]. 160c4762a1bSJed Brown The index sets user.s_is and user.d_is correspond to the indices of the 161c4762a1bSJed Brown state and design variables owned by the current processor. 162c4762a1bSJed Brown */ 163c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); 164c4762a1bSJed Brown 165c4762a1bSJed Brown ierr = VecGetOwnershipRange(user.y,&lo,&hi);CHKERRQ(ierr); 166c4762a1bSJed Brown ierr = VecGetOwnershipRange(user.u,&lo2,&hi2);CHKERRQ(ierr); 167c4762a1bSJed Brown 168c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_allstate);CHKERRQ(ierr); 169c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo+lo2,1,&user.s_is);CHKERRQ(ierr); 170c4762a1bSJed Brown 171c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi2-lo2,lo2,1,&is_alldesign);CHKERRQ(ierr); 172c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi2-lo2,hi+lo2,1,&user.d_is);CHKERRQ(ierr); 173c4762a1bSJed Brown 174c4762a1bSJed Brown ierr = VecSetSizes(x,hi-lo+hi2-lo2,user.n);CHKERRQ(ierr); 175c4762a1bSJed Brown ierr = VecSetFromOptions(x);CHKERRQ(ierr); 176c4762a1bSJed Brown 177c4762a1bSJed Brown ierr = VecScatterCreate(x,user.s_is,user.y,is_allstate,&user.state_scatter);CHKERRQ(ierr); 178c4762a1bSJed Brown ierr = VecScatterCreate(x,user.d_is,user.u,is_alldesign,&user.design_scatter);CHKERRQ(ierr); 179c4762a1bSJed Brown ierr = ISDestroy(&is_alldesign);CHKERRQ(ierr); 180c4762a1bSJed Brown ierr = ISDestroy(&is_allstate);CHKERRQ(ierr); 181c4762a1bSJed Brown 182c4762a1bSJed Brown /* Create TAO solver and set desired solution method */ 183c4762a1bSJed Brown ierr = TaoCreate(PETSC_COMM_WORLD,&tao);CHKERRQ(ierr); 184c4762a1bSJed Brown ierr = TaoSetType(tao,TAOLCL);CHKERRQ(ierr); 185c4762a1bSJed Brown 186c4762a1bSJed Brown /* Set up initial vectors and matrices */ 187c4762a1bSJed Brown ierr = HyperbolicInitialize(&user);CHKERRQ(ierr); 188c4762a1bSJed Brown 189c4762a1bSJed Brown ierr = Gather(x,user.y,user.state_scatter,user.u,user.design_scatter);CHKERRQ(ierr); 190c4762a1bSJed Brown ierr = VecDuplicate(x,&x0);CHKERRQ(ierr); 191c4762a1bSJed Brown ierr = VecCopy(x,x0);CHKERRQ(ierr); 192c4762a1bSJed Brown 193c4762a1bSJed Brown /* Set solution vector with an initial guess */ 194*a82e8c82SStefano Zampini ierr = TaoSetSolution(tao,x);CHKERRQ(ierr); 195*a82e8c82SStefano Zampini ierr = TaoSetObjective(tao, FormFunction, &user);CHKERRQ(ierr); 196*a82e8c82SStefano Zampini ierr = TaoSetGradient(tao, NULL, FormGradient, &user);CHKERRQ(ierr); 1973ec1f749SStefano Zampini ierr = TaoSetConstraintsRoutine(tao, user.c, FormConstraints, &user);CHKERRQ(ierr); 1983ec1f749SStefano Zampini ierr = TaoSetJacobianStateRoutine(tao, user.Js, user.Js, user.JsInv, FormJacobianState, &user);CHKERRQ(ierr); 1993ec1f749SStefano Zampini ierr = TaoSetJacobianDesignRoutine(tao, user.Jd, FormJacobianDesign, &user);CHKERRQ(ierr); 200c4762a1bSJed Brown ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); 201c4762a1bSJed Brown ierr = TaoSetStateDesignIS(tao,user.s_is,user.d_is);CHKERRQ(ierr); 202c4762a1bSJed Brown 203c4762a1bSJed Brown /* SOLVE THE APPLICATION */ 204c4762a1bSJed Brown ierr = PetscLogStageRegister("Trials",&stages[0]);CHKERRQ(ierr); 205c4762a1bSJed Brown ierr = PetscLogStagePush(stages[0]);CHKERRQ(ierr); 206c4762a1bSJed Brown user.ksp_its_initial = user.ksp_its; 207c4762a1bSJed Brown ksp_old = user.ksp_its; 208c4762a1bSJed Brown for (i=0; i<ntests; i++) { 209c4762a1bSJed Brown ierr = TaoSolve(tao);CHKERRQ(ierr); 210c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"KSP Iterations = %D\n",user.ksp_its-ksp_old);CHKERRQ(ierr); 211c4762a1bSJed Brown ierr = VecCopy(x0,x);CHKERRQ(ierr); 212*a82e8c82SStefano Zampini ierr = TaoSetSolution(tao,x);CHKERRQ(ierr); 213c4762a1bSJed Brown } 214c4762a1bSJed Brown ierr = PetscLogStagePop();CHKERRQ(ierr); 215c4762a1bSJed Brown ierr = PetscBarrier((PetscObject)x);CHKERRQ(ierr); 216c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"KSP iterations within initialization: ");CHKERRQ(ierr); 217c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"%D\n",user.ksp_its_initial);CHKERRQ(ierr); 218c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"Total KSP iterations over %D trial(s): ",ntests);CHKERRQ(ierr); 219c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"%D\n",user.ksp_its);CHKERRQ(ierr); 220c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"KSP iterations per trial: ");CHKERRQ(ierr); 221c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"%D\n",(user.ksp_its-user.ksp_its_initial)/ntests);CHKERRQ(ierr); 222c4762a1bSJed Brown 223c4762a1bSJed Brown ierr = TaoDestroy(&tao);CHKERRQ(ierr); 224c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); 225c4762a1bSJed Brown ierr = VecDestroy(&x0);CHKERRQ(ierr); 226c4762a1bSJed Brown ierr = HyperbolicDestroy(&user);CHKERRQ(ierr); 227c4762a1bSJed Brown ierr = PetscFinalize(); 228c4762a1bSJed Brown return ierr; 229c4762a1bSJed Brown } 230c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 231c4762a1bSJed Brown /* 232c4762a1bSJed Brown dwork = Qy - d 233c4762a1bSJed Brown lwork = L*(u-ur).^2 234c4762a1bSJed Brown f = 1/2 * (dwork.dork + alpha*y.lwork) 235c4762a1bSJed Brown */ 236c4762a1bSJed Brown PetscErrorCode FormFunction(Tao tao,Vec X,PetscReal *f,void *ptr) 237c4762a1bSJed Brown { 238c4762a1bSJed Brown PetscErrorCode ierr; 239c4762a1bSJed Brown PetscReal d1=0,d2=0; 240c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 241c4762a1bSJed Brown 242c4762a1bSJed Brown PetscFunctionBegin; 243c4762a1bSJed Brown ierr = Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter);CHKERRQ(ierr); 244c4762a1bSJed Brown ierr = MatMult(user->Q,user->y,user->dwork);CHKERRQ(ierr); 245c4762a1bSJed Brown ierr = VecAXPY(user->dwork,-1.0,user->d);CHKERRQ(ierr); 246c4762a1bSJed Brown ierr = VecDot(user->dwork,user->dwork,&d1);CHKERRQ(ierr); 247c4762a1bSJed Brown 248c4762a1bSJed Brown ierr = VecWAXPY(user->uwork,-1.0,user->ur,user->u);CHKERRQ(ierr); 249c4762a1bSJed Brown ierr = VecPointwiseMult(user->uwork,user->uwork,user->uwork);CHKERRQ(ierr); 250c4762a1bSJed Brown ierr = MatMult(user->L,user->uwork,user->lwork);CHKERRQ(ierr); 251c4762a1bSJed Brown ierr = VecDot(user->y,user->lwork,&d2);CHKERRQ(ierr); 252c4762a1bSJed Brown *f = 0.5 * (d1 + user->alpha*d2); 253c4762a1bSJed Brown PetscFunctionReturn(0); 254c4762a1bSJed Brown } 255c4762a1bSJed Brown 256c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 257c4762a1bSJed Brown /* 258c4762a1bSJed Brown state: g_s = Q' *(Qy - d) + 0.5*alpha*L*(u-ur).^2 259c4762a1bSJed Brown design: g_d = alpha*(L'y).*(u-ur) 260c4762a1bSJed Brown */ 261c4762a1bSJed Brown PetscErrorCode FormGradient(Tao tao,Vec X,Vec G,void *ptr) 262c4762a1bSJed Brown { 263c4762a1bSJed Brown PetscErrorCode ierr; 264c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 265c4762a1bSJed Brown 266c4762a1bSJed Brown PetscFunctionBegin; 267c4762a1bSJed Brown ierr = Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter);CHKERRQ(ierr); 268c4762a1bSJed Brown ierr = MatMult(user->Q,user->y,user->dwork);CHKERRQ(ierr); 269c4762a1bSJed Brown ierr = VecAXPY(user->dwork,-1.0,user->d);CHKERRQ(ierr); 270c4762a1bSJed Brown 271c4762a1bSJed Brown ierr = MatMult(user->QT,user->dwork,user->ywork);CHKERRQ(ierr); 272c4762a1bSJed Brown 273c4762a1bSJed Brown ierr = MatMult(user->LT,user->y,user->uwork);CHKERRQ(ierr); 274c4762a1bSJed Brown ierr = VecWAXPY(user->vwork,-1.0,user->ur,user->u);CHKERRQ(ierr); 275c4762a1bSJed Brown ierr = VecPointwiseMult(user->uwork,user->vwork,user->uwork);CHKERRQ(ierr); 276c4762a1bSJed Brown ierr = VecScale(user->uwork,user->alpha);CHKERRQ(ierr); 277c4762a1bSJed Brown 278c4762a1bSJed Brown ierr = VecPointwiseMult(user->vwork,user->vwork,user->vwork);CHKERRQ(ierr); 279c4762a1bSJed Brown ierr = MatMult(user->L,user->vwork,user->lwork);CHKERRQ(ierr); 280c4762a1bSJed Brown ierr = VecAXPY(user->ywork,0.5*user->alpha,user->lwork);CHKERRQ(ierr); 281c4762a1bSJed Brown 282c4762a1bSJed Brown ierr = Gather(G,user->ywork,user->state_scatter,user->uwork,user->design_scatter);CHKERRQ(ierr); 283c4762a1bSJed Brown PetscFunctionReturn(0); 284c4762a1bSJed Brown } 285c4762a1bSJed Brown 286c4762a1bSJed Brown PetscErrorCode FormFunctionGradient(Tao tao, Vec X, PetscReal *f, Vec G, void *ptr) 287c4762a1bSJed Brown { 288c4762a1bSJed Brown PetscErrorCode ierr; 289c4762a1bSJed Brown PetscReal d1,d2; 290c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 291c4762a1bSJed Brown 292c4762a1bSJed Brown PetscFunctionBegin; 293c4762a1bSJed Brown ierr = Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter);CHKERRQ(ierr); 294c4762a1bSJed Brown ierr = MatMult(user->Q,user->y,user->dwork);CHKERRQ(ierr); 295c4762a1bSJed Brown ierr = VecAXPY(user->dwork,-1.0,user->d);CHKERRQ(ierr); 296c4762a1bSJed Brown 297c4762a1bSJed Brown ierr = MatMult(user->QT,user->dwork,user->ywork);CHKERRQ(ierr); 298c4762a1bSJed Brown 299c4762a1bSJed Brown ierr = VecDot(user->dwork,user->dwork,&d1);CHKERRQ(ierr); 300c4762a1bSJed Brown 301c4762a1bSJed Brown ierr = MatMult(user->LT,user->y,user->uwork);CHKERRQ(ierr); 302c4762a1bSJed Brown ierr = VecWAXPY(user->vwork,-1.0,user->ur,user->u);CHKERRQ(ierr); 303c4762a1bSJed Brown ierr = VecPointwiseMult(user->uwork,user->vwork,user->uwork);CHKERRQ(ierr); 304c4762a1bSJed Brown ierr = VecScale(user->uwork,user->alpha);CHKERRQ(ierr); 305c4762a1bSJed Brown 306c4762a1bSJed Brown ierr = VecPointwiseMult(user->vwork,user->vwork,user->vwork);CHKERRQ(ierr); 307c4762a1bSJed Brown ierr = MatMult(user->L,user->vwork,user->lwork);CHKERRQ(ierr); 308c4762a1bSJed Brown ierr = VecAXPY(user->ywork,0.5*user->alpha,user->lwork);CHKERRQ(ierr); 309c4762a1bSJed Brown 310c4762a1bSJed Brown ierr = VecDot(user->y,user->lwork,&d2);CHKERRQ(ierr); 311c4762a1bSJed Brown 312c4762a1bSJed Brown *f = 0.5 * (d1 + user->alpha*d2); 313c4762a1bSJed Brown ierr = Gather(G,user->ywork,user->state_scatter,user->uwork,user->design_scatter);CHKERRQ(ierr); 314c4762a1bSJed Brown PetscFunctionReturn(0); 315c4762a1bSJed Brown } 316c4762a1bSJed Brown 317c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 318c4762a1bSJed Brown /* A 319c4762a1bSJed Brown MatShell object 320c4762a1bSJed Brown */ 321c4762a1bSJed Brown PetscErrorCode FormJacobianState(Tao tao, Vec X, Mat J, Mat JPre, Mat JInv, void *ptr) 322c4762a1bSJed Brown { 323c4762a1bSJed Brown PetscErrorCode ierr; 324c4762a1bSJed Brown PetscInt i; 325c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 326c4762a1bSJed Brown 327c4762a1bSJed Brown PetscFunctionBegin; 328c4762a1bSJed Brown ierr = Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter);CHKERRQ(ierr); 329c4762a1bSJed Brown ierr = Scatter_yi(user->u,user->ui,user->ui_scatter,user->nt);CHKERRQ(ierr); 330c4762a1bSJed Brown ierr = Scatter_uxi_uyi(user->u,user->uxi,user->uxi_scatter,user->uyi,user->uyi_scatter,user->nt);CHKERRQ(ierr); 331c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 332c4762a1bSJed Brown ierr = MatCopy(user->Divxy[0],user->C[i],SUBSET_NONZERO_PATTERN);CHKERRQ(ierr); 333c4762a1bSJed Brown ierr = MatCopy(user->Divxy[1],user->Cwork[i],SAME_NONZERO_PATTERN);CHKERRQ(ierr); 334c4762a1bSJed Brown 335c4762a1bSJed Brown ierr = MatDiagonalScale(user->C[i],NULL,user->uxi[i]);CHKERRQ(ierr); 336c4762a1bSJed Brown ierr = MatDiagonalScale(user->Cwork[i],NULL,user->uyi[i]);CHKERRQ(ierr); 337c4762a1bSJed Brown ierr = MatAXPY(user->C[i],1.0,user->Cwork[i],SUBSET_NONZERO_PATTERN);CHKERRQ(ierr); 338c4762a1bSJed Brown ierr = MatScale(user->C[i],user->ht);CHKERRQ(ierr); 339c4762a1bSJed Brown ierr = MatShift(user->C[i],1.0);CHKERRQ(ierr); 340c4762a1bSJed Brown } 341c4762a1bSJed Brown PetscFunctionReturn(0); 342c4762a1bSJed Brown } 343c4762a1bSJed Brown 344c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 345c4762a1bSJed Brown /* B */ 346c4762a1bSJed Brown PetscErrorCode FormJacobianDesign(Tao tao, Vec X, Mat J, void *ptr) 347c4762a1bSJed Brown { 348c4762a1bSJed Brown PetscErrorCode ierr; 349c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 350c4762a1bSJed Brown 351c4762a1bSJed Brown PetscFunctionBegin; 352c4762a1bSJed Brown ierr = Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter);CHKERRQ(ierr); 353c4762a1bSJed Brown PetscFunctionReturn(0); 354c4762a1bSJed Brown } 355c4762a1bSJed Brown 356c4762a1bSJed Brown PetscErrorCode StateMatMult(Mat J_shell, Vec X, Vec Y) 357c4762a1bSJed Brown { 358c4762a1bSJed Brown PetscErrorCode ierr; 359c4762a1bSJed Brown PetscInt i; 360c4762a1bSJed Brown AppCtx *user; 361c4762a1bSJed Brown 362c4762a1bSJed Brown PetscFunctionBegin; 3633ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 364c4762a1bSJed Brown ierr = Scatter_yi(X,user->yi,user->yi_scatter,user->nt);CHKERRQ(ierr); 365c4762a1bSJed Brown user->block_index = 0; 366c4762a1bSJed Brown ierr = MatMult(user->JsBlock,user->yi[0],user->yiwork[0]);CHKERRQ(ierr); 367c4762a1bSJed Brown 368c4762a1bSJed Brown for (i=1; i<user->nt; i++) { 369c4762a1bSJed Brown user->block_index = i; 370c4762a1bSJed Brown ierr = MatMult(user->JsBlock,user->yi[i],user->yiwork[i]);CHKERRQ(ierr); 371c4762a1bSJed Brown ierr = MatMult(user->M,user->yi[i-1],user->ziwork[i-1]);CHKERRQ(ierr); 372c4762a1bSJed Brown ierr = VecAXPY(user->yiwork[i],-1.0,user->ziwork[i-1]);CHKERRQ(ierr); 373c4762a1bSJed Brown } 374c4762a1bSJed Brown ierr = Gather_yi(Y,user->yiwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 375c4762a1bSJed Brown PetscFunctionReturn(0); 376c4762a1bSJed Brown } 377c4762a1bSJed Brown 378c4762a1bSJed Brown PetscErrorCode StateMatMultTranspose(Mat J_shell, Vec X, Vec Y) 379c4762a1bSJed Brown { 380c4762a1bSJed Brown PetscErrorCode ierr; 381c4762a1bSJed Brown PetscInt i; 382c4762a1bSJed Brown AppCtx *user; 383c4762a1bSJed Brown 384c4762a1bSJed Brown PetscFunctionBegin; 3853ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 386c4762a1bSJed Brown ierr = Scatter_yi(X,user->yi,user->yi_scatter,user->nt);CHKERRQ(ierr); 387c4762a1bSJed Brown 388c4762a1bSJed Brown for (i=0; i<user->nt-1; i++) { 389c4762a1bSJed Brown user->block_index = i; 390c4762a1bSJed Brown ierr = MatMultTranspose(user->JsBlock,user->yi[i],user->yiwork[i]);CHKERRQ(ierr); 391c4762a1bSJed Brown ierr = MatMult(user->M,user->yi[i+1],user->ziwork[i+1]);CHKERRQ(ierr); 392c4762a1bSJed Brown ierr = VecAXPY(user->yiwork[i],-1.0,user->ziwork[i+1]);CHKERRQ(ierr); 393c4762a1bSJed Brown } 394c4762a1bSJed Brown 395c4762a1bSJed Brown i = user->nt-1; 396c4762a1bSJed Brown user->block_index = i; 397c4762a1bSJed Brown ierr = MatMultTranspose(user->JsBlock,user->yi[i],user->yiwork[i]);CHKERRQ(ierr); 398c4762a1bSJed Brown ierr = Gather_yi(Y,user->yiwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 399c4762a1bSJed Brown PetscFunctionReturn(0); 400c4762a1bSJed Brown } 401c4762a1bSJed Brown 402c4762a1bSJed Brown PetscErrorCode StateMatBlockMult(Mat J_shell, Vec X, Vec Y) 403c4762a1bSJed Brown { 404c4762a1bSJed Brown PetscErrorCode ierr; 405c4762a1bSJed Brown PetscInt i; 406c4762a1bSJed Brown AppCtx *user; 407c4762a1bSJed Brown 408c4762a1bSJed Brown PetscFunctionBegin; 4093ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 410c4762a1bSJed Brown i = user->block_index; 411c4762a1bSJed Brown ierr = VecPointwiseMult(user->uxiwork[i],X,user->uxi[i]);CHKERRQ(ierr); 412c4762a1bSJed Brown ierr = VecPointwiseMult(user->uyiwork[i],X,user->uyi[i]);CHKERRQ(ierr); 413c4762a1bSJed Brown ierr = Gather(user->uiwork[i],user->uxiwork[i],user->ux_scatter[i],user->uyiwork[i],user->uy_scatter[i]);CHKERRQ(ierr); 414c4762a1bSJed Brown ierr = MatMult(user->Div,user->uiwork[i],Y);CHKERRQ(ierr); 415c4762a1bSJed Brown ierr = VecAYPX(Y,user->ht,X);CHKERRQ(ierr); 416c4762a1bSJed Brown PetscFunctionReturn(0); 417c4762a1bSJed Brown } 418c4762a1bSJed Brown 419c4762a1bSJed Brown PetscErrorCode StateMatBlockMultTranspose(Mat J_shell, Vec X, Vec Y) 420c4762a1bSJed Brown { 421c4762a1bSJed Brown PetscErrorCode ierr; 422c4762a1bSJed Brown PetscInt i; 423c4762a1bSJed Brown AppCtx *user; 424c4762a1bSJed Brown 425c4762a1bSJed Brown PetscFunctionBegin; 4263ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 427c4762a1bSJed Brown i = user->block_index; 428c4762a1bSJed Brown ierr = MatMult(user->Grad,X,user->uiwork[i]);CHKERRQ(ierr); 429c4762a1bSJed Brown ierr = Scatter(user->uiwork[i],user->uxiwork[i],user->ux_scatter[i],user->uyiwork[i],user->uy_scatter[i]);CHKERRQ(ierr); 430c4762a1bSJed Brown ierr = VecPointwiseMult(user->uxiwork[i],user->uxi[i],user->uxiwork[i]);CHKERRQ(ierr); 431c4762a1bSJed Brown ierr = VecPointwiseMult(user->uyiwork[i],user->uyi[i],user->uyiwork[i]);CHKERRQ(ierr); 432c4762a1bSJed Brown ierr = VecWAXPY(Y,1.0,user->uxiwork[i],user->uyiwork[i]);CHKERRQ(ierr); 433c4762a1bSJed Brown ierr = VecAYPX(Y,user->ht,X);CHKERRQ(ierr); 434c4762a1bSJed Brown PetscFunctionReturn(0); 435c4762a1bSJed Brown } 436c4762a1bSJed Brown 437c4762a1bSJed Brown PetscErrorCode DesignMatMult(Mat J_shell, Vec X, Vec Y) 438c4762a1bSJed Brown { 439c4762a1bSJed Brown PetscErrorCode ierr; 440c4762a1bSJed Brown PetscInt i; 441c4762a1bSJed Brown AppCtx *user; 442c4762a1bSJed Brown 443c4762a1bSJed Brown PetscFunctionBegin; 4443ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 445c4762a1bSJed Brown ierr = Scatter_yi(user->y,user->yi,user->yi_scatter,user->nt);CHKERRQ(ierr); 446c4762a1bSJed Brown ierr = Scatter_uxi_uyi(X,user->uxiwork,user->uxi_scatter,user->uyiwork,user->uyi_scatter,user->nt);CHKERRQ(ierr); 447c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 448c4762a1bSJed Brown ierr = VecPointwiseMult(user->uxiwork[i],user->yi[i],user->uxiwork[i]);CHKERRQ(ierr); 449c4762a1bSJed Brown ierr = VecPointwiseMult(user->uyiwork[i],user->yi[i],user->uyiwork[i]);CHKERRQ(ierr); 450c4762a1bSJed Brown ierr = Gather(user->uiwork[i],user->uxiwork[i],user->ux_scatter[i],user->uyiwork[i],user->uy_scatter[i]);CHKERRQ(ierr); 451c4762a1bSJed Brown ierr = MatMult(user->Div,user->uiwork[i],user->ziwork[i]);CHKERRQ(ierr); 452c4762a1bSJed Brown ierr = VecScale(user->ziwork[i],user->ht);CHKERRQ(ierr); 453c4762a1bSJed Brown } 454c4762a1bSJed Brown ierr = Gather_yi(Y,user->ziwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 455c4762a1bSJed Brown PetscFunctionReturn(0); 456c4762a1bSJed Brown } 457c4762a1bSJed Brown 458c4762a1bSJed Brown PetscErrorCode DesignMatMultTranspose(Mat J_shell, Vec X, Vec Y) 459c4762a1bSJed Brown { 460c4762a1bSJed Brown PetscErrorCode ierr; 461c4762a1bSJed Brown PetscInt i; 462c4762a1bSJed Brown AppCtx *user; 463c4762a1bSJed Brown 464c4762a1bSJed Brown PetscFunctionBegin; 4653ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 466c4762a1bSJed Brown ierr = Scatter_yi(user->y,user->yi,user->yi_scatter,user->nt);CHKERRQ(ierr); 467c4762a1bSJed Brown ierr = Scatter_yi(X,user->yiwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 468c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 469c4762a1bSJed Brown ierr = MatMult(user->Grad,user->yiwork[i],user->uiwork[i]);CHKERRQ(ierr); 470c4762a1bSJed Brown ierr = Scatter(user->uiwork[i],user->uxiwork[i],user->ux_scatter[i],user->uyiwork[i],user->uy_scatter[i]);CHKERRQ(ierr); 471c4762a1bSJed Brown ierr = VecPointwiseMult(user->uxiwork[i],user->yi[i],user->uxiwork[i]);CHKERRQ(ierr); 472c4762a1bSJed Brown ierr = VecPointwiseMult(user->uyiwork[i],user->yi[i],user->uyiwork[i]);CHKERRQ(ierr); 473c4762a1bSJed Brown ierr = Gather(user->uiwork[i],user->uxiwork[i],user->ux_scatter[i],user->uyiwork[i],user->uy_scatter[i]);CHKERRQ(ierr); 474c4762a1bSJed Brown ierr = VecScale(user->uiwork[i],user->ht);CHKERRQ(ierr); 475c4762a1bSJed Brown } 476c4762a1bSJed Brown ierr = Gather_yi(Y,user->uiwork,user->ui_scatter,user->nt);CHKERRQ(ierr); 477c4762a1bSJed Brown PetscFunctionReturn(0); 478c4762a1bSJed Brown } 479c4762a1bSJed Brown 480c4762a1bSJed Brown PetscErrorCode StateMatBlockPrecMult(PC PC_shell, Vec X, Vec Y) 481c4762a1bSJed Brown { 482c4762a1bSJed Brown PetscErrorCode ierr; 483c4762a1bSJed Brown PetscInt i; 484c4762a1bSJed Brown AppCtx *user; 485c4762a1bSJed Brown 486c4762a1bSJed Brown PetscFunctionBegin; 4873ec1f749SStefano Zampini ierr = PCShellGetContext(PC_shell,&user);CHKERRQ(ierr); 488c4762a1bSJed Brown i = user->block_index; 489c4762a1bSJed Brown if (user->c_formed) { 490c4762a1bSJed Brown ierr = MatSOR(user->C[i],X,1.0,(MatSORType)(SOR_ZERO_INITIAL_GUESS | SOR_LOCAL_SYMMETRIC_SWEEP),0.0,1,1,Y);CHKERRQ(ierr); 491c4762a1bSJed Brown } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not formed"); 492c4762a1bSJed Brown PetscFunctionReturn(0); 493c4762a1bSJed Brown } 494c4762a1bSJed Brown 495c4762a1bSJed Brown PetscErrorCode StateMatBlockPrecMultTranspose(PC PC_shell, Vec X, Vec Y) 496c4762a1bSJed Brown { 497c4762a1bSJed Brown PetscErrorCode ierr; 498c4762a1bSJed Brown PetscInt i; 499c4762a1bSJed Brown AppCtx *user; 500c4762a1bSJed Brown 501c4762a1bSJed Brown PetscFunctionBegin; 5023ec1f749SStefano Zampini ierr = PCShellGetContext(PC_shell,&user);CHKERRQ(ierr); 503c4762a1bSJed Brown 504c4762a1bSJed Brown i = user->block_index; 505c4762a1bSJed Brown if (user->c_formed) { 506c4762a1bSJed Brown ierr = MatSOR(user->C[i],X,1.0,(MatSORType)(SOR_ZERO_INITIAL_GUESS | SOR_LOCAL_SYMMETRIC_SWEEP),0.0,1,1,Y);CHKERRQ(ierr); 507c4762a1bSJed Brown } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not formed"); 508c4762a1bSJed Brown PetscFunctionReturn(0); 509c4762a1bSJed Brown } 510c4762a1bSJed Brown 511c4762a1bSJed Brown PetscErrorCode StateMatInvMult(Mat J_shell, Vec X, Vec Y) 512c4762a1bSJed Brown { 513c4762a1bSJed Brown PetscErrorCode ierr; 514c4762a1bSJed Brown AppCtx *user; 515c4762a1bSJed Brown PetscInt its,i; 516c4762a1bSJed Brown 517c4762a1bSJed Brown PetscFunctionBegin; 5183ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 519c4762a1bSJed Brown 520c4762a1bSJed Brown if (Y == user->ytrue) { 521c4762a1bSJed Brown /* First solve is done using true solution to set up problem */ 522c4762a1bSJed Brown ierr = KSPSetTolerances(user->solver,1e-4,1e-20,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 523c4762a1bSJed Brown } else { 524c4762a1bSJed Brown ierr = KSPSetTolerances(user->solver,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 525c4762a1bSJed Brown } 526c4762a1bSJed Brown ierr = Scatter_yi(X,user->yi,user->yi_scatter,user->nt);CHKERRQ(ierr); 527c4762a1bSJed Brown ierr = Scatter_yi(Y,user->yiwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 528c4762a1bSJed Brown ierr = Scatter_uxi_uyi(user->u,user->uxi,user->uxi_scatter,user->uyi,user->uyi_scatter,user->nt);CHKERRQ(ierr); 529c4762a1bSJed Brown 530c4762a1bSJed Brown user->block_index = 0; 531c4762a1bSJed Brown ierr = KSPSolve(user->solver,user->yi[0],user->yiwork[0]);CHKERRQ(ierr); 532c4762a1bSJed Brown 533c4762a1bSJed Brown ierr = KSPGetIterationNumber(user->solver,&its);CHKERRQ(ierr); 534c4762a1bSJed Brown user->ksp_its = user->ksp_its + its; 535c4762a1bSJed Brown for (i=1; i<user->nt; i++) { 536c4762a1bSJed Brown ierr = MatMult(user->M,user->yiwork[i-1],user->ziwork[i-1]);CHKERRQ(ierr); 537c4762a1bSJed Brown ierr = VecAXPY(user->yi[i],1.0,user->ziwork[i-1]);CHKERRQ(ierr); 538c4762a1bSJed Brown user->block_index = i; 539c4762a1bSJed Brown ierr = KSPSolve(user->solver,user->yi[i],user->yiwork[i]);CHKERRQ(ierr); 540c4762a1bSJed Brown 541c4762a1bSJed Brown ierr = KSPGetIterationNumber(user->solver,&its);CHKERRQ(ierr); 542c4762a1bSJed Brown user->ksp_its = user->ksp_its + its; 543c4762a1bSJed Brown } 544c4762a1bSJed Brown ierr = Gather_yi(Y,user->yiwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 545c4762a1bSJed Brown PetscFunctionReturn(0); 546c4762a1bSJed Brown } 547c4762a1bSJed Brown 548c4762a1bSJed Brown PetscErrorCode StateMatInvTransposeMult(Mat J_shell, Vec X, Vec Y) 549c4762a1bSJed Brown { 550c4762a1bSJed Brown PetscErrorCode ierr; 551c4762a1bSJed Brown AppCtx *user; 552c4762a1bSJed Brown PetscInt its,i; 553c4762a1bSJed Brown 554c4762a1bSJed Brown PetscFunctionBegin; 5553ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 556c4762a1bSJed Brown 557c4762a1bSJed Brown ierr = Scatter_yi(X,user->yi,user->yi_scatter,user->nt);CHKERRQ(ierr); 558c4762a1bSJed Brown ierr = Scatter_yi(Y,user->yiwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 559c4762a1bSJed Brown ierr = Scatter_uxi_uyi(user->u,user->uxi,user->uxi_scatter,user->uyi,user->uyi_scatter,user->nt);CHKERRQ(ierr); 560c4762a1bSJed Brown 561c4762a1bSJed Brown i = user->nt - 1; 562c4762a1bSJed Brown user->block_index = i; 563c4762a1bSJed Brown ierr = KSPSolveTranspose(user->solver,user->yi[i],user->yiwork[i]);CHKERRQ(ierr); 564c4762a1bSJed Brown 565c4762a1bSJed Brown ierr = KSPGetIterationNumber(user->solver,&its);CHKERRQ(ierr); 566c4762a1bSJed Brown user->ksp_its = user->ksp_its + its; 567c4762a1bSJed Brown 568c4762a1bSJed Brown for (i=user->nt-2; i>=0; i--) { 569c4762a1bSJed Brown ierr = MatMult(user->M,user->yiwork[i+1],user->ziwork[i+1]);CHKERRQ(ierr); 570c4762a1bSJed Brown ierr = VecAXPY(user->yi[i],1.0,user->ziwork[i+1]);CHKERRQ(ierr); 571c4762a1bSJed Brown user->block_index = i; 572c4762a1bSJed Brown ierr = KSPSolveTranspose(user->solver,user->yi[i],user->yiwork[i]);CHKERRQ(ierr); 573c4762a1bSJed Brown 574c4762a1bSJed Brown ierr = KSPGetIterationNumber(user->solver,&its);CHKERRQ(ierr); 575c4762a1bSJed Brown user->ksp_its = user->ksp_its + its; 576c4762a1bSJed Brown } 577c4762a1bSJed Brown ierr = Gather_yi(Y,user->yiwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 578c4762a1bSJed Brown PetscFunctionReturn(0); 579c4762a1bSJed Brown } 580c4762a1bSJed Brown 581c4762a1bSJed Brown PetscErrorCode StateMatDuplicate(Mat J_shell, MatDuplicateOption opt, Mat *new_shell) 582c4762a1bSJed Brown { 583c4762a1bSJed Brown PetscErrorCode ierr; 584c4762a1bSJed Brown AppCtx *user; 585c4762a1bSJed Brown 586c4762a1bSJed Brown PetscFunctionBegin; 5873ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 588c4762a1bSJed Brown 589c4762a1bSJed Brown ierr = MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m,user->m,user,new_shell);CHKERRQ(ierr); 590c4762a1bSJed Brown ierr = MatShellSetOperation(*new_shell,MATOP_MULT,(void(*)(void))StateMatMult);CHKERRQ(ierr); 591c4762a1bSJed Brown ierr = MatShellSetOperation(*new_shell,MATOP_DUPLICATE,(void(*)(void))StateMatDuplicate);CHKERRQ(ierr); 592c4762a1bSJed Brown ierr = MatShellSetOperation(*new_shell,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatMultTranspose);CHKERRQ(ierr); 593c4762a1bSJed Brown ierr = MatShellSetOperation(*new_shell,MATOP_GET_DIAGONAL,(void(*)(void))StateMatGetDiagonal);CHKERRQ(ierr); 594c4762a1bSJed Brown PetscFunctionReturn(0); 595c4762a1bSJed Brown } 596c4762a1bSJed Brown 597c4762a1bSJed Brown PetscErrorCode StateMatGetDiagonal(Mat J_shell, Vec X) 598c4762a1bSJed Brown { 599c4762a1bSJed Brown PetscErrorCode ierr; 600c4762a1bSJed Brown AppCtx *user; 601c4762a1bSJed Brown 602c4762a1bSJed Brown PetscFunctionBegin; 6033ec1f749SStefano Zampini ierr = MatShellGetContext(J_shell,&user);CHKERRQ(ierr); 604c4762a1bSJed Brown ierr = VecCopy(user->js_diag,X);CHKERRQ(ierr); 605c4762a1bSJed Brown PetscFunctionReturn(0); 606c4762a1bSJed Brown } 607c4762a1bSJed Brown 608c4762a1bSJed Brown PetscErrorCode FormConstraints(Tao tao, Vec X, Vec C, void *ptr) 609c4762a1bSJed Brown { 610c4762a1bSJed Brown /* con = Ay - q, A = [C(u1) 0 0 ... 0; 611c4762a1bSJed Brown -M C(u2) 0 ... 0; 612c4762a1bSJed Brown 0 -M C(u3) ... 0; 613c4762a1bSJed Brown ... ; 614c4762a1bSJed Brown 0 ... -M C(u_nt)] 615c4762a1bSJed Brown C(u) = eye + ht*Div*[diag(u1); diag(u2)] */ 616c4762a1bSJed Brown PetscErrorCode ierr; 617c4762a1bSJed Brown PetscInt i; 618c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 619c4762a1bSJed Brown 620c4762a1bSJed Brown PetscFunctionBegin; 621c4762a1bSJed Brown ierr = Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter);CHKERRQ(ierr); 622c4762a1bSJed Brown ierr = Scatter_yi(user->y,user->yi,user->yi_scatter,user->nt);CHKERRQ(ierr); 623c4762a1bSJed Brown ierr = Scatter_uxi_uyi(user->u,user->uxi,user->uxi_scatter,user->uyi,user->uyi_scatter,user->nt);CHKERRQ(ierr); 624c4762a1bSJed Brown 625c4762a1bSJed Brown user->block_index = 0; 626c4762a1bSJed Brown ierr = MatMult(user->JsBlock,user->yi[0],user->yiwork[0]);CHKERRQ(ierr); 627c4762a1bSJed Brown 628c4762a1bSJed Brown for (i=1; i<user->nt; i++) { 629c4762a1bSJed Brown user->block_index = i; 630c4762a1bSJed Brown ierr = MatMult(user->JsBlock,user->yi[i],user->yiwork[i]);CHKERRQ(ierr); 631c4762a1bSJed Brown ierr = MatMult(user->M,user->yi[i-1],user->ziwork[i-1]);CHKERRQ(ierr); 632c4762a1bSJed Brown ierr = VecAXPY(user->yiwork[i],-1.0,user->ziwork[i-1]);CHKERRQ(ierr); 633c4762a1bSJed Brown } 634c4762a1bSJed Brown 635c4762a1bSJed Brown ierr = Gather_yi(C,user->yiwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 636c4762a1bSJed Brown ierr = VecAXPY(C,-1.0,user->q);CHKERRQ(ierr); 637c4762a1bSJed Brown 638c4762a1bSJed Brown PetscFunctionReturn(0); 639c4762a1bSJed Brown } 640c4762a1bSJed Brown 641c4762a1bSJed Brown PetscErrorCode Scatter(Vec x, Vec state, VecScatter s_scat, Vec design, VecScatter d_scat) 642c4762a1bSJed Brown { 643c4762a1bSJed Brown PetscErrorCode ierr; 644c4762a1bSJed Brown 645c4762a1bSJed Brown PetscFunctionBegin; 646c4762a1bSJed Brown ierr = VecScatterBegin(s_scat,x,state,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 647c4762a1bSJed Brown ierr = VecScatterEnd(s_scat,x,state,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 648c4762a1bSJed Brown ierr = VecScatterBegin(d_scat,x,design,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 649c4762a1bSJed Brown ierr = VecScatterEnd(d_scat,x,design,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 650c4762a1bSJed Brown PetscFunctionReturn(0); 651c4762a1bSJed Brown } 652c4762a1bSJed Brown 653c4762a1bSJed Brown PetscErrorCode Scatter_uxi_uyi(Vec u, Vec *uxi, VecScatter *scatx, Vec *uyi, VecScatter *scaty, PetscInt nt) 654c4762a1bSJed Brown { 655c4762a1bSJed Brown PetscErrorCode ierr; 656c4762a1bSJed Brown PetscInt i; 657c4762a1bSJed Brown 658c4762a1bSJed Brown PetscFunctionBegin; 659c4762a1bSJed Brown for (i=0; i<nt; i++) { 660c4762a1bSJed Brown ierr = VecScatterBegin(scatx[i],u,uxi[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 661c4762a1bSJed Brown ierr = VecScatterEnd(scatx[i],u,uxi[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 662c4762a1bSJed Brown ierr = VecScatterBegin(scaty[i],u,uyi[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 663c4762a1bSJed Brown ierr = VecScatterEnd(scaty[i],u,uyi[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 664c4762a1bSJed Brown } 665c4762a1bSJed Brown PetscFunctionReturn(0); 666c4762a1bSJed Brown } 667c4762a1bSJed Brown 668c4762a1bSJed Brown PetscErrorCode Gather(Vec x, Vec state, VecScatter s_scat, Vec design, VecScatter d_scat) 669c4762a1bSJed Brown { 670c4762a1bSJed Brown PetscErrorCode ierr; 671c4762a1bSJed Brown 672c4762a1bSJed Brown PetscFunctionBegin; 673c4762a1bSJed Brown ierr = VecScatterBegin(s_scat,state,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 674c4762a1bSJed Brown ierr = VecScatterEnd(s_scat,state,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 675c4762a1bSJed Brown ierr = VecScatterBegin(d_scat,design,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 676c4762a1bSJed Brown ierr = VecScatterEnd(d_scat,design,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 677c4762a1bSJed Brown PetscFunctionReturn(0); 678c4762a1bSJed Brown } 679c4762a1bSJed Brown 680c4762a1bSJed Brown PetscErrorCode Gather_uxi_uyi(Vec u, Vec *uxi, VecScatter *scatx, Vec *uyi, VecScatter *scaty, PetscInt nt) 681c4762a1bSJed Brown { 682c4762a1bSJed Brown PetscErrorCode ierr; 683c4762a1bSJed Brown PetscInt i; 684c4762a1bSJed Brown 685c4762a1bSJed Brown PetscFunctionBegin; 686c4762a1bSJed Brown for (i=0; i<nt; i++) { 687c4762a1bSJed Brown ierr = VecScatterBegin(scatx[i],uxi[i],u,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 688c4762a1bSJed Brown ierr = VecScatterEnd(scatx[i],uxi[i],u,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 689c4762a1bSJed Brown ierr = VecScatterBegin(scaty[i],uyi[i],u,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 690c4762a1bSJed Brown ierr = VecScatterEnd(scaty[i],uyi[i],u,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 691c4762a1bSJed Brown } 692c4762a1bSJed Brown PetscFunctionReturn(0); 693c4762a1bSJed Brown } 694c4762a1bSJed Brown 695c4762a1bSJed Brown PetscErrorCode Scatter_yi(Vec y, Vec *yi, VecScatter *scat, PetscInt nt) 696c4762a1bSJed Brown { 697c4762a1bSJed Brown PetscErrorCode ierr; 698c4762a1bSJed Brown PetscInt i; 699c4762a1bSJed Brown 700c4762a1bSJed Brown PetscFunctionBegin; 701c4762a1bSJed Brown for (i=0; i<nt; i++) { 702c4762a1bSJed Brown ierr = VecScatterBegin(scat[i],y,yi[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 703c4762a1bSJed Brown ierr = VecScatterEnd(scat[i],y,yi[i],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 704c4762a1bSJed Brown } 705c4762a1bSJed Brown PetscFunctionReturn(0); 706c4762a1bSJed Brown } 707c4762a1bSJed Brown 708c4762a1bSJed Brown PetscErrorCode Gather_yi(Vec y, Vec *yi, VecScatter *scat, PetscInt nt) 709c4762a1bSJed Brown { 710c4762a1bSJed Brown PetscErrorCode ierr; 711c4762a1bSJed Brown PetscInt i; 712c4762a1bSJed Brown 713c4762a1bSJed Brown PetscFunctionBegin; 714c4762a1bSJed Brown for (i=0; i<nt; i++) { 715c4762a1bSJed Brown ierr = VecScatterBegin(scat[i],yi[i],y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 716c4762a1bSJed Brown ierr = VecScatterEnd(scat[i],yi[i],y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 717c4762a1bSJed Brown } 718c4762a1bSJed Brown PetscFunctionReturn(0); 719c4762a1bSJed Brown } 720c4762a1bSJed Brown 721c4762a1bSJed Brown PetscErrorCode HyperbolicInitialize(AppCtx *user) 722c4762a1bSJed Brown { 723c4762a1bSJed Brown PetscErrorCode ierr; 724c4762a1bSJed Brown PetscInt n,i,j,linear_index,istart,iend,iblock,lo,hi; 725c4762a1bSJed Brown Vec XX,YY,XXwork,YYwork,yi,uxi,ui,bc; 726c4762a1bSJed Brown PetscReal h,sum; 727c4762a1bSJed Brown PetscScalar hinv,neg_hinv,quarter=0.25,one=1.0,half_hinv,neg_half_hinv; 728c4762a1bSJed Brown PetscScalar vx,vy,zero=0.0; 729c4762a1bSJed Brown IS is_from_y,is_to_yi,is_from_u,is_to_uxi,is_to_uyi; 730c4762a1bSJed Brown 731c4762a1bSJed Brown PetscFunctionBegin; 732c4762a1bSJed Brown user->jformed = PETSC_FALSE; 733c4762a1bSJed Brown user->c_formed = PETSC_FALSE; 734c4762a1bSJed Brown 735c4762a1bSJed Brown user->ksp_its = 0; 736c4762a1bSJed Brown user->ksp_its_initial = 0; 737c4762a1bSJed Brown 738c4762a1bSJed Brown n = user->mx * user->mx; 739c4762a1bSJed Brown 740c4762a1bSJed Brown h = 1.0/user->mx; 741c4762a1bSJed Brown hinv = user->mx; 742c4762a1bSJed Brown neg_hinv = -hinv; 743c4762a1bSJed Brown half_hinv = hinv / 2.0; 744c4762a1bSJed Brown neg_half_hinv = neg_hinv / 2.0; 745c4762a1bSJed Brown 746c4762a1bSJed Brown /* Generate Grad matrix */ 747c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD,&user->Grad);CHKERRQ(ierr); 748c4762a1bSJed Brown ierr = MatSetSizes(user->Grad,PETSC_DECIDE,PETSC_DECIDE,2*n,n);CHKERRQ(ierr); 749c4762a1bSJed Brown ierr = MatSetFromOptions(user->Grad);CHKERRQ(ierr); 750c4762a1bSJed Brown ierr = MatMPIAIJSetPreallocation(user->Grad,3,NULL,3,NULL);CHKERRQ(ierr); 751c4762a1bSJed Brown ierr = MatSeqAIJSetPreallocation(user->Grad,3,NULL);CHKERRQ(ierr); 752c4762a1bSJed Brown ierr = MatGetOwnershipRange(user->Grad,&istart,&iend);CHKERRQ(ierr); 753c4762a1bSJed Brown 754c4762a1bSJed Brown for (i=istart; i<iend; i++) { 755c4762a1bSJed Brown if (i<n) { 756c4762a1bSJed Brown iblock = i / user->mx; 757c4762a1bSJed Brown j = iblock*user->mx + ((i+user->mx-1) % user->mx); 758c4762a1bSJed Brown ierr = MatSetValues(user->Grad,1,&i,1,&j,&half_hinv,INSERT_VALUES);CHKERRQ(ierr); 759c4762a1bSJed Brown j = iblock*user->mx + ((i+1) % user->mx); 760c4762a1bSJed Brown ierr = MatSetValues(user->Grad,1,&i,1,&j,&neg_half_hinv,INSERT_VALUES);CHKERRQ(ierr); 761c4762a1bSJed Brown } 762c4762a1bSJed Brown if (i>=n) { 763c4762a1bSJed Brown j = (i - user->mx) % n; 764c4762a1bSJed Brown ierr = MatSetValues(user->Grad,1,&i,1,&j,&half_hinv,INSERT_VALUES);CHKERRQ(ierr); 765c4762a1bSJed Brown j = (j + 2*user->mx) % n; 766c4762a1bSJed Brown ierr = MatSetValues(user->Grad,1,&i,1,&j,&neg_half_hinv,INSERT_VALUES);CHKERRQ(ierr); 767c4762a1bSJed Brown } 768c4762a1bSJed Brown } 769c4762a1bSJed Brown 770c4762a1bSJed Brown ierr = MatAssemblyBegin(user->Grad,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 771c4762a1bSJed Brown ierr = MatAssemblyEnd(user->Grad,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 772c4762a1bSJed Brown 773c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD,&user->Gradxy[0]);CHKERRQ(ierr); 774c4762a1bSJed Brown ierr = MatSetSizes(user->Gradxy[0],PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); 775c4762a1bSJed Brown ierr = MatSetFromOptions(user->Gradxy[0]);CHKERRQ(ierr); 776c4762a1bSJed Brown ierr = MatMPIAIJSetPreallocation(user->Gradxy[0],3,NULL,3,NULL);CHKERRQ(ierr); 777c4762a1bSJed Brown ierr = MatSeqAIJSetPreallocation(user->Gradxy[0],3,NULL);CHKERRQ(ierr); 778c4762a1bSJed Brown ierr = MatGetOwnershipRange(user->Gradxy[0],&istart,&iend);CHKERRQ(ierr); 779c4762a1bSJed Brown 780c4762a1bSJed Brown for (i=istart; i<iend; i++) { 781c4762a1bSJed Brown iblock = i / user->mx; 782c4762a1bSJed Brown j = iblock*user->mx + ((i+user->mx-1) % user->mx); 783c4762a1bSJed Brown ierr = MatSetValues(user->Gradxy[0],1,&i,1,&j,&half_hinv,INSERT_VALUES);CHKERRQ(ierr); 784c4762a1bSJed Brown j = iblock*user->mx + ((i+1) % user->mx); 785c4762a1bSJed Brown ierr = MatSetValues(user->Gradxy[0],1,&i,1,&j,&neg_half_hinv,INSERT_VALUES);CHKERRQ(ierr); 786c4762a1bSJed Brown ierr = MatSetValues(user->Gradxy[0],1,&i,1,&i,&zero,INSERT_VALUES);CHKERRQ(ierr); 787c4762a1bSJed Brown } 788c4762a1bSJed Brown ierr = MatAssemblyBegin(user->Gradxy[0],MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 789c4762a1bSJed Brown ierr = MatAssemblyEnd(user->Gradxy[0],MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 790c4762a1bSJed Brown 791c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD,&user->Gradxy[1]);CHKERRQ(ierr); 792c4762a1bSJed Brown ierr = MatSetSizes(user->Gradxy[1],PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); 793c4762a1bSJed Brown ierr = MatSetFromOptions(user->Gradxy[1]);CHKERRQ(ierr); 794c4762a1bSJed Brown ierr = MatMPIAIJSetPreallocation(user->Gradxy[1],3,NULL,3,NULL);CHKERRQ(ierr); 795c4762a1bSJed Brown ierr = MatSeqAIJSetPreallocation(user->Gradxy[1],3,NULL);CHKERRQ(ierr); 796c4762a1bSJed Brown ierr = MatGetOwnershipRange(user->Gradxy[1],&istart,&iend);CHKERRQ(ierr); 797c4762a1bSJed Brown 798c4762a1bSJed Brown for (i=istart; i<iend; i++) { 799c4762a1bSJed Brown j = (i + n - user->mx) % n; 800c4762a1bSJed Brown ierr = MatSetValues(user->Gradxy[1],1,&i,1,&j,&half_hinv,INSERT_VALUES);CHKERRQ(ierr); 801c4762a1bSJed Brown j = (j + 2*user->mx) % n; 802c4762a1bSJed Brown ierr = MatSetValues(user->Gradxy[1],1,&i,1,&j,&neg_half_hinv,INSERT_VALUES);CHKERRQ(ierr); 803c4762a1bSJed Brown ierr = MatSetValues(user->Gradxy[1],1,&i,1,&i,&zero,INSERT_VALUES);CHKERRQ(ierr); 804c4762a1bSJed Brown } 805c4762a1bSJed Brown ierr = MatAssemblyBegin(user->Gradxy[1],MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 806c4762a1bSJed Brown ierr = MatAssemblyEnd(user->Gradxy[1],MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 807c4762a1bSJed Brown 808c4762a1bSJed Brown /* Generate Div matrix */ 809c4762a1bSJed Brown ierr = MatTranspose(user->Grad,MAT_INITIAL_MATRIX,&user->Div);CHKERRQ(ierr); 810c4762a1bSJed Brown ierr = MatTranspose(user->Gradxy[0],MAT_INITIAL_MATRIX,&user->Divxy[0]);CHKERRQ(ierr); 811c4762a1bSJed Brown ierr = MatTranspose(user->Gradxy[1],MAT_INITIAL_MATRIX,&user->Divxy[1]);CHKERRQ(ierr); 812c4762a1bSJed Brown 813c4762a1bSJed Brown /* Off-diagonal averaging matrix */ 814c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD,&user->M);CHKERRQ(ierr); 815c4762a1bSJed Brown ierr = MatSetSizes(user->M,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); 816c4762a1bSJed Brown ierr = MatSetFromOptions(user->M);CHKERRQ(ierr); 817c4762a1bSJed Brown ierr = MatMPIAIJSetPreallocation(user->M,4,NULL,4,NULL);CHKERRQ(ierr); 818c4762a1bSJed Brown ierr = MatSeqAIJSetPreallocation(user->M,4,NULL);CHKERRQ(ierr); 819c4762a1bSJed Brown ierr = MatGetOwnershipRange(user->M,&istart,&iend);CHKERRQ(ierr); 820c4762a1bSJed Brown 821c4762a1bSJed Brown for (i=istart; i<iend; i++) { 822c4762a1bSJed Brown /* kron(Id,Av) */ 823c4762a1bSJed Brown iblock = i / user->mx; 824c4762a1bSJed Brown j = iblock*user->mx + ((i+user->mx-1) % user->mx); 825c4762a1bSJed Brown ierr = MatSetValues(user->M,1,&i,1,&j,&quarter,INSERT_VALUES);CHKERRQ(ierr); 826c4762a1bSJed Brown j = iblock*user->mx + ((i+1) % user->mx); 827c4762a1bSJed Brown ierr = MatSetValues(user->M,1,&i,1,&j,&quarter,INSERT_VALUES);CHKERRQ(ierr); 828c4762a1bSJed Brown 829c4762a1bSJed Brown /* kron(Av,Id) */ 830c4762a1bSJed Brown j = (i + user->mx) % n; 831c4762a1bSJed Brown ierr = MatSetValues(user->M,1,&i,1,&j,&quarter,INSERT_VALUES);CHKERRQ(ierr); 832c4762a1bSJed Brown j = (i + n - user->mx) % n; 833c4762a1bSJed Brown ierr = MatSetValues(user->M,1,&i,1,&j,&quarter,INSERT_VALUES);CHKERRQ(ierr); 834c4762a1bSJed Brown } 835c4762a1bSJed Brown ierr = MatAssemblyBegin(user->M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 836c4762a1bSJed Brown ierr = MatAssemblyEnd(user->M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 837c4762a1bSJed Brown 838c4762a1bSJed Brown /* Generate 2D grid */ 839c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&XX);CHKERRQ(ierr); 840c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&user->q);CHKERRQ(ierr); 841c4762a1bSJed Brown ierr = VecSetSizes(XX,PETSC_DECIDE,n);CHKERRQ(ierr); 842c4762a1bSJed Brown ierr = VecSetSizes(user->q,PETSC_DECIDE,n*user->nt);CHKERRQ(ierr); 843c4762a1bSJed Brown ierr = VecSetFromOptions(XX);CHKERRQ(ierr); 844c4762a1bSJed Brown ierr = VecSetFromOptions(user->q);CHKERRQ(ierr); 845c4762a1bSJed Brown 846c4762a1bSJed Brown ierr = VecDuplicate(XX,&YY);CHKERRQ(ierr); 847c4762a1bSJed Brown ierr = VecDuplicate(XX,&XXwork);CHKERRQ(ierr); 848c4762a1bSJed Brown ierr = VecDuplicate(XX,&YYwork);CHKERRQ(ierr); 849c4762a1bSJed Brown ierr = VecDuplicate(XX,&user->d);CHKERRQ(ierr); 850c4762a1bSJed Brown ierr = VecDuplicate(XX,&user->dwork);CHKERRQ(ierr); 851c4762a1bSJed Brown 852c4762a1bSJed Brown ierr = VecGetOwnershipRange(XX,&istart,&iend);CHKERRQ(ierr); 853c4762a1bSJed Brown for (linear_index=istart; linear_index<iend; linear_index++) { 854c4762a1bSJed Brown i = linear_index % user->mx; 855c4762a1bSJed Brown j = (linear_index-i)/user->mx; 856c4762a1bSJed Brown vx = h*(i+0.5); 857c4762a1bSJed Brown vy = h*(j+0.5); 858c4762a1bSJed Brown ierr = VecSetValues(XX,1,&linear_index,&vx,INSERT_VALUES);CHKERRQ(ierr); 859c4762a1bSJed Brown ierr = VecSetValues(YY,1,&linear_index,&vy,INSERT_VALUES);CHKERRQ(ierr); 860c4762a1bSJed Brown } 861c4762a1bSJed Brown 862c4762a1bSJed Brown ierr = VecAssemblyBegin(XX);CHKERRQ(ierr); 863c4762a1bSJed Brown ierr = VecAssemblyEnd(XX);CHKERRQ(ierr); 864c4762a1bSJed Brown ierr = VecAssemblyBegin(YY);CHKERRQ(ierr); 865c4762a1bSJed Brown ierr = VecAssemblyEnd(YY);CHKERRQ(ierr); 866c4762a1bSJed Brown 867c4762a1bSJed Brown /* Compute final density function yT 868c4762a1bSJed Brown yT = 1.0 + exp(-30*((x-0.25)^2+(y-0.25)^2)) + exp(-30*((x-0.75)^2+(y-0.75)^2)) 869c4762a1bSJed Brown yT = yT / (h^2*sum(yT)) */ 870c4762a1bSJed Brown ierr = VecCopy(XX,XXwork);CHKERRQ(ierr); 871c4762a1bSJed Brown ierr = VecCopy(YY,YYwork);CHKERRQ(ierr); 872c4762a1bSJed Brown 873c4762a1bSJed Brown ierr = VecShift(XXwork,-0.25);CHKERRQ(ierr); 874c4762a1bSJed Brown ierr = VecShift(YYwork,-0.25);CHKERRQ(ierr); 875c4762a1bSJed Brown 876c4762a1bSJed Brown ierr = VecPointwiseMult(XXwork,XXwork,XXwork);CHKERRQ(ierr); 877c4762a1bSJed Brown ierr = VecPointwiseMult(YYwork,YYwork,YYwork);CHKERRQ(ierr); 878c4762a1bSJed Brown 879c4762a1bSJed Brown ierr = VecCopy(XXwork,user->dwork);CHKERRQ(ierr); 880c4762a1bSJed Brown ierr = VecAXPY(user->dwork,1.0,YYwork);CHKERRQ(ierr); 881c4762a1bSJed Brown ierr = VecScale(user->dwork,-30.0);CHKERRQ(ierr); 882c4762a1bSJed Brown ierr = VecExp(user->dwork);CHKERRQ(ierr); 883c4762a1bSJed Brown ierr = VecCopy(user->dwork,user->d);CHKERRQ(ierr); 884c4762a1bSJed Brown 885c4762a1bSJed Brown ierr = VecCopy(XX,XXwork);CHKERRQ(ierr); 886c4762a1bSJed Brown ierr = VecCopy(YY,YYwork);CHKERRQ(ierr); 887c4762a1bSJed Brown 888c4762a1bSJed Brown ierr = VecShift(XXwork,-0.75);CHKERRQ(ierr); 889c4762a1bSJed Brown ierr = VecShift(YYwork,-0.75);CHKERRQ(ierr); 890c4762a1bSJed Brown 891c4762a1bSJed Brown ierr = VecPointwiseMult(XXwork,XXwork,XXwork);CHKERRQ(ierr); 892c4762a1bSJed Brown ierr = VecPointwiseMult(YYwork,YYwork,YYwork);CHKERRQ(ierr); 893c4762a1bSJed Brown 894c4762a1bSJed Brown ierr = VecCopy(XXwork,user->dwork);CHKERRQ(ierr); 895c4762a1bSJed Brown ierr = VecAXPY(user->dwork,1.0,YYwork);CHKERRQ(ierr); 896c4762a1bSJed Brown ierr = VecScale(user->dwork,-30.0);CHKERRQ(ierr); 897c4762a1bSJed Brown ierr = VecExp(user->dwork);CHKERRQ(ierr); 898c4762a1bSJed Brown 899c4762a1bSJed Brown ierr = VecAXPY(user->d,1.0,user->dwork);CHKERRQ(ierr); 900c4762a1bSJed Brown ierr = VecShift(user->d,1.0);CHKERRQ(ierr); 901c4762a1bSJed Brown ierr = VecSum(user->d,&sum);CHKERRQ(ierr); 902c4762a1bSJed Brown ierr = VecScale(user->d,1.0/(h*h*sum));CHKERRQ(ierr); 903c4762a1bSJed Brown 904c4762a1bSJed Brown /* Initial conditions of forward problem */ 905c4762a1bSJed Brown ierr = VecDuplicate(XX,&bc);CHKERRQ(ierr); 906c4762a1bSJed Brown ierr = VecCopy(XX,XXwork);CHKERRQ(ierr); 907c4762a1bSJed Brown ierr = VecCopy(YY,YYwork);CHKERRQ(ierr); 908c4762a1bSJed Brown 909c4762a1bSJed Brown ierr = VecShift(XXwork,-0.5);CHKERRQ(ierr); 910c4762a1bSJed Brown ierr = VecShift(YYwork,-0.5);CHKERRQ(ierr); 911c4762a1bSJed Brown 912c4762a1bSJed Brown ierr = VecPointwiseMult(XXwork,XXwork,XXwork);CHKERRQ(ierr); 913c4762a1bSJed Brown ierr = VecPointwiseMult(YYwork,YYwork,YYwork);CHKERRQ(ierr); 914c4762a1bSJed Brown 915c4762a1bSJed Brown ierr = VecWAXPY(bc,1.0,XXwork,YYwork);CHKERRQ(ierr); 916c4762a1bSJed Brown ierr = VecScale(bc,-50.0);CHKERRQ(ierr); 917c4762a1bSJed Brown ierr = VecExp(bc);CHKERRQ(ierr); 918c4762a1bSJed Brown ierr = VecShift(bc,1.0);CHKERRQ(ierr); 919c4762a1bSJed Brown ierr = VecSum(bc,&sum);CHKERRQ(ierr); 920c4762a1bSJed Brown ierr = VecScale(bc,1.0/(h*h*sum));CHKERRQ(ierr); 921c4762a1bSJed Brown 922c4762a1bSJed Brown /* Create scatter from y to y_1,y_2,...,y_nt */ 923c4762a1bSJed Brown /* TODO: Reorder for better parallelism. (This will require reordering Q and L as well.) */ 924c4762a1bSJed Brown ierr = PetscMalloc1(user->nt*user->mx*user->mx,&user->yi_scatter);CHKERRQ(ierr); 925c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&yi);CHKERRQ(ierr); 926c4762a1bSJed Brown ierr = VecSetSizes(yi,PETSC_DECIDE,user->mx*user->mx);CHKERRQ(ierr); 927c4762a1bSJed Brown ierr = VecSetFromOptions(yi);CHKERRQ(ierr); 928c4762a1bSJed Brown ierr = VecDuplicateVecs(yi,user->nt,&user->yi);CHKERRQ(ierr); 929c4762a1bSJed Brown ierr = VecDuplicateVecs(yi,user->nt,&user->yiwork);CHKERRQ(ierr); 930c4762a1bSJed Brown ierr = VecDuplicateVecs(yi,user->nt,&user->ziwork);CHKERRQ(ierr); 931c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 932c4762a1bSJed Brown ierr = VecGetOwnershipRange(user->yi[i],&lo,&hi);CHKERRQ(ierr); 933c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_to_yi);CHKERRQ(ierr); 934c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo+i*user->mx*user->mx,1,&is_from_y);CHKERRQ(ierr); 935c4762a1bSJed Brown ierr = VecScatterCreate(user->y,is_from_y,user->yi[i],is_to_yi,&user->yi_scatter[i]);CHKERRQ(ierr); 936c4762a1bSJed Brown ierr = ISDestroy(&is_to_yi);CHKERRQ(ierr); 937c4762a1bSJed Brown ierr = ISDestroy(&is_from_y);CHKERRQ(ierr); 938c4762a1bSJed Brown } 939c4762a1bSJed Brown 940c4762a1bSJed Brown /* Create scatter from u to ux_1,uy_1,ux_2,uy_2,...,ux_nt,uy_nt */ 941c4762a1bSJed Brown /* TODO: reorder for better parallelism */ 942c4762a1bSJed Brown ierr = PetscMalloc1(user->nt*user->mx*user->mx,&user->uxi_scatter);CHKERRQ(ierr); 943c4762a1bSJed Brown ierr = PetscMalloc1(user->nt*user->mx*user->mx,&user->uyi_scatter);CHKERRQ(ierr); 944c4762a1bSJed Brown ierr = PetscMalloc1(user->nt*user->mx*user->mx,&user->ux_scatter);CHKERRQ(ierr); 945c4762a1bSJed Brown ierr = PetscMalloc1(user->nt*user->mx*user->mx,&user->uy_scatter);CHKERRQ(ierr); 946c4762a1bSJed Brown ierr = PetscMalloc1(2*user->nt*user->mx*user->mx,&user->ui_scatter);CHKERRQ(ierr); 947c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&uxi);CHKERRQ(ierr); 948c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&ui);CHKERRQ(ierr); 949c4762a1bSJed Brown ierr = VecSetSizes(uxi,PETSC_DECIDE,user->mx*user->mx);CHKERRQ(ierr); 950c4762a1bSJed Brown ierr = VecSetSizes(ui,PETSC_DECIDE,2*user->mx*user->mx);CHKERRQ(ierr); 951c4762a1bSJed Brown ierr = VecSetFromOptions(uxi);CHKERRQ(ierr); 952c4762a1bSJed Brown ierr = VecSetFromOptions(ui);CHKERRQ(ierr); 953c4762a1bSJed Brown ierr = VecDuplicateVecs(uxi,user->nt,&user->uxi);CHKERRQ(ierr); 954c4762a1bSJed Brown ierr = VecDuplicateVecs(uxi,user->nt,&user->uyi);CHKERRQ(ierr); 955c4762a1bSJed Brown ierr = VecDuplicateVecs(uxi,user->nt,&user->uxiwork);CHKERRQ(ierr); 956c4762a1bSJed Brown ierr = VecDuplicateVecs(uxi,user->nt,&user->uyiwork);CHKERRQ(ierr); 957c4762a1bSJed Brown ierr = VecDuplicateVecs(ui,user->nt,&user->ui);CHKERRQ(ierr); 958c4762a1bSJed Brown ierr = VecDuplicateVecs(ui,user->nt,&user->uiwork);CHKERRQ(ierr); 959c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 960c4762a1bSJed Brown ierr = VecGetOwnershipRange(user->uxi[i],&lo,&hi);CHKERRQ(ierr); 961c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_to_uxi);CHKERRQ(ierr); 962c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo+2*i*user->mx*user->mx,1,&is_from_u);CHKERRQ(ierr); 963c4762a1bSJed Brown ierr = VecScatterCreate(user->u,is_from_u,user->uxi[i],is_to_uxi,&user->uxi_scatter[i]);CHKERRQ(ierr); 964c4762a1bSJed Brown 965c4762a1bSJed Brown ierr = ISDestroy(&is_to_uxi);CHKERRQ(ierr); 966c4762a1bSJed Brown ierr = ISDestroy(&is_from_u);CHKERRQ(ierr); 967c4762a1bSJed Brown 968c4762a1bSJed Brown ierr = VecGetOwnershipRange(user->uyi[i],&lo,&hi);CHKERRQ(ierr); 969c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_to_uyi);CHKERRQ(ierr); 970c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo+(2*i+1)*user->mx*user->mx,1,&is_from_u);CHKERRQ(ierr); 971c4762a1bSJed Brown ierr = VecScatterCreate(user->u,is_from_u,user->uyi[i],is_to_uyi,&user->uyi_scatter[i]);CHKERRQ(ierr); 972c4762a1bSJed Brown 973c4762a1bSJed Brown ierr = ISDestroy(&is_to_uyi);CHKERRQ(ierr); 974c4762a1bSJed Brown ierr = ISDestroy(&is_from_u);CHKERRQ(ierr); 975c4762a1bSJed Brown 976c4762a1bSJed Brown ierr = VecGetOwnershipRange(user->uxi[i],&lo,&hi);CHKERRQ(ierr); 977c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_to_uxi);CHKERRQ(ierr); 978c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_from_u);CHKERRQ(ierr); 979c4762a1bSJed Brown ierr = VecScatterCreate(user->ui[i],is_from_u,user->uxi[i],is_to_uxi,&user->ux_scatter[i]);CHKERRQ(ierr); 980c4762a1bSJed Brown 981c4762a1bSJed Brown ierr = ISDestroy(&is_to_uxi);CHKERRQ(ierr); 982c4762a1bSJed Brown ierr = ISDestroy(&is_from_u);CHKERRQ(ierr); 983c4762a1bSJed Brown 984c4762a1bSJed Brown ierr = VecGetOwnershipRange(user->uyi[i],&lo,&hi);CHKERRQ(ierr); 985c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_to_uyi);CHKERRQ(ierr); 986c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo+user->mx*user->mx,1,&is_from_u);CHKERRQ(ierr); 987c4762a1bSJed Brown ierr = VecScatterCreate(user->ui[i],is_from_u,user->uyi[i],is_to_uyi,&user->uy_scatter[i]);CHKERRQ(ierr); 988c4762a1bSJed Brown 989c4762a1bSJed Brown ierr = ISDestroy(&is_to_uyi);CHKERRQ(ierr); 990c4762a1bSJed Brown ierr = ISDestroy(&is_from_u);CHKERRQ(ierr); 991c4762a1bSJed Brown 992c4762a1bSJed Brown ierr = VecGetOwnershipRange(user->ui[i],&lo,&hi);CHKERRQ(ierr); 993c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_to_uxi);CHKERRQ(ierr); 994c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,hi-lo,lo+2*i*user->mx*user->mx,1,&is_from_u);CHKERRQ(ierr); 995c4762a1bSJed Brown ierr = VecScatterCreate(user->u,is_from_u,user->ui[i],is_to_uxi,&user->ui_scatter[i]);CHKERRQ(ierr); 996c4762a1bSJed Brown 997c4762a1bSJed Brown ierr = ISDestroy(&is_to_uxi);CHKERRQ(ierr); 998c4762a1bSJed Brown ierr = ISDestroy(&is_from_u);CHKERRQ(ierr); 999c4762a1bSJed Brown } 1000c4762a1bSJed Brown 1001c4762a1bSJed Brown /* RHS of forward problem */ 1002c4762a1bSJed Brown ierr = MatMult(user->M,bc,user->yiwork[0]);CHKERRQ(ierr); 1003c4762a1bSJed Brown for (i=1; i<user->nt; i++) { 1004c4762a1bSJed Brown ierr = VecSet(user->yiwork[i],0.0);CHKERRQ(ierr); 1005c4762a1bSJed Brown } 1006c4762a1bSJed Brown ierr = Gather_yi(user->q,user->yiwork,user->yi_scatter,user->nt);CHKERRQ(ierr); 1007c4762a1bSJed Brown 1008c4762a1bSJed Brown /* Compute true velocity field utrue */ 1009c4762a1bSJed Brown ierr = VecDuplicate(user->u,&user->utrue);CHKERRQ(ierr); 1010c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 1011c4762a1bSJed Brown ierr = VecCopy(YY,user->uxi[i]);CHKERRQ(ierr); 1012c4762a1bSJed Brown ierr = VecScale(user->uxi[i],150.0*i*user->ht);CHKERRQ(ierr); 1013c4762a1bSJed Brown ierr = VecCopy(XX,user->uyi[i]);CHKERRQ(ierr); 1014c4762a1bSJed Brown ierr = VecShift(user->uyi[i],-10.0);CHKERRQ(ierr); 1015c4762a1bSJed Brown ierr = VecScale(user->uyi[i],15.0*i*user->ht);CHKERRQ(ierr); 1016c4762a1bSJed Brown } 1017c4762a1bSJed Brown ierr = Gather_uxi_uyi(user->utrue,user->uxi,user->uxi_scatter,user->uyi,user->uyi_scatter,user->nt);CHKERRQ(ierr); 1018c4762a1bSJed Brown 1019c4762a1bSJed Brown /* Initial guess and reference model */ 1020c4762a1bSJed Brown ierr = VecDuplicate(user->utrue,&user->ur);CHKERRQ(ierr); 1021c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 1022c4762a1bSJed Brown ierr = VecCopy(XX,user->uxi[i]);CHKERRQ(ierr); 1023c4762a1bSJed Brown ierr = VecShift(user->uxi[i],i*user->ht);CHKERRQ(ierr); 1024c4762a1bSJed Brown ierr = VecCopy(YY,user->uyi[i]);CHKERRQ(ierr); 1025c4762a1bSJed Brown ierr = VecShift(user->uyi[i],-i*user->ht);CHKERRQ(ierr); 1026c4762a1bSJed Brown } 1027c4762a1bSJed Brown ierr = Gather_uxi_uyi(user->ur,user->uxi,user->uxi_scatter,user->uyi,user->uyi_scatter,user->nt);CHKERRQ(ierr); 1028c4762a1bSJed Brown 1029c4762a1bSJed Brown /* Generate regularization matrix L */ 1030c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD,&user->LT);CHKERRQ(ierr); 1031c4762a1bSJed Brown ierr = MatSetSizes(user->LT,PETSC_DECIDE,PETSC_DECIDE,2*n*user->nt,n*user->nt);CHKERRQ(ierr); 1032c4762a1bSJed Brown ierr = MatSetFromOptions(user->LT);CHKERRQ(ierr); 1033c4762a1bSJed Brown ierr = MatMPIAIJSetPreallocation(user->LT,1,NULL,1,NULL);CHKERRQ(ierr); 1034c4762a1bSJed Brown ierr = MatSeqAIJSetPreallocation(user->LT,1,NULL);CHKERRQ(ierr); 1035c4762a1bSJed Brown ierr = MatGetOwnershipRange(user->LT,&istart,&iend);CHKERRQ(ierr); 1036c4762a1bSJed Brown 1037c4762a1bSJed Brown for (i=istart; i<iend; i++) { 1038c4762a1bSJed Brown iblock = (i+n) / (2*n); 1039c4762a1bSJed Brown j = i - iblock*n; 1040c4762a1bSJed Brown ierr = MatSetValues(user->LT,1,&i,1,&j,&user->gamma,INSERT_VALUES);CHKERRQ(ierr); 1041c4762a1bSJed Brown } 1042c4762a1bSJed Brown 1043c4762a1bSJed Brown ierr = MatAssemblyBegin(user->LT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1044c4762a1bSJed Brown ierr = MatAssemblyEnd(user->LT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1045c4762a1bSJed Brown 1046c4762a1bSJed Brown ierr = MatTranspose(user->LT,MAT_INITIAL_MATRIX,&user->L);CHKERRQ(ierr); 1047c4762a1bSJed Brown 1048c4762a1bSJed Brown /* Build work vectors and matrices */ 1049c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&user->lwork);CHKERRQ(ierr); 1050c4762a1bSJed Brown ierr = VecSetType(user->lwork,VECMPI);CHKERRQ(ierr); 1051c4762a1bSJed Brown ierr = VecSetSizes(user->lwork,PETSC_DECIDE,user->m);CHKERRQ(ierr); 1052c4762a1bSJed Brown ierr = VecSetFromOptions(user->lwork);CHKERRQ(ierr); 1053c4762a1bSJed Brown 1054c4762a1bSJed Brown ierr = MatDuplicate(user->Div,MAT_SHARE_NONZERO_PATTERN,&user->Divwork);CHKERRQ(ierr); 1055c4762a1bSJed Brown 1056c4762a1bSJed Brown ierr = VecDuplicate(user->y,&user->ywork);CHKERRQ(ierr); 1057c4762a1bSJed Brown ierr = VecDuplicate(user->u,&user->uwork);CHKERRQ(ierr); 1058c4762a1bSJed Brown ierr = VecDuplicate(user->u,&user->vwork);CHKERRQ(ierr); 1059c4762a1bSJed Brown ierr = VecDuplicate(user->u,&user->js_diag);CHKERRQ(ierr); 1060c4762a1bSJed Brown ierr = VecDuplicate(user->c,&user->cwork);CHKERRQ(ierr); 1061c4762a1bSJed Brown 1062c4762a1bSJed Brown /* Create matrix-free shell user->Js for computing A*x */ 1063c4762a1bSJed Brown ierr = MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m,user->m,user,&user->Js);CHKERRQ(ierr); 1064c4762a1bSJed Brown ierr = MatShellSetOperation(user->Js,MATOP_MULT,(void(*)(void))StateMatMult);CHKERRQ(ierr); 1065c4762a1bSJed Brown ierr = MatShellSetOperation(user->Js,MATOP_DUPLICATE,(void(*)(void))StateMatDuplicate);CHKERRQ(ierr); 1066c4762a1bSJed Brown ierr = MatShellSetOperation(user->Js,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatMultTranspose);CHKERRQ(ierr); 1067c4762a1bSJed Brown ierr = MatShellSetOperation(user->Js,MATOP_GET_DIAGONAL,(void(*)(void))StateMatGetDiagonal);CHKERRQ(ierr); 1068c4762a1bSJed Brown 1069c4762a1bSJed Brown /* Diagonal blocks of user->Js */ 1070c4762a1bSJed Brown ierr = MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,n,n,user,&user->JsBlock);CHKERRQ(ierr); 1071c4762a1bSJed Brown ierr = MatShellSetOperation(user->JsBlock,MATOP_MULT,(void(*)(void))StateMatBlockMult);CHKERRQ(ierr); 1072c4762a1bSJed Brown ierr = MatShellSetOperation(user->JsBlock,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatBlockMultTranspose);CHKERRQ(ierr); 1073c4762a1bSJed Brown 1074c4762a1bSJed Brown /* Create a matrix-free shell user->JsBlockPrec for computing (U+D)\D*(L+D)\x, where JsBlock = L+D+U, 1075c4762a1bSJed Brown D is diagonal, L is strictly lower triangular, and U is strictly upper triangular. 1076c4762a1bSJed Brown This is an SOR preconditioner for user->JsBlock. */ 1077c4762a1bSJed Brown ierr = MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,n,n,user,&user->JsBlockPrec);CHKERRQ(ierr); 1078c4762a1bSJed Brown ierr = MatShellSetOperation(user->JsBlockPrec,MATOP_MULT,(void(*)(void))StateMatBlockPrecMult);CHKERRQ(ierr); 1079c4762a1bSJed Brown ierr = MatShellSetOperation(user->JsBlockPrec,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatBlockPrecMultTranspose);CHKERRQ(ierr); 1080c4762a1bSJed Brown 1081c4762a1bSJed Brown /* Create a matrix-free shell user->Jd for computing B*x */ 1082c4762a1bSJed Brown ierr = MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m,user->n-user->m,user,&user->Jd);CHKERRQ(ierr); 1083c4762a1bSJed Brown ierr = MatShellSetOperation(user->Jd,MATOP_MULT,(void(*)(void))DesignMatMult);CHKERRQ(ierr); 1084c4762a1bSJed Brown ierr = MatShellSetOperation(user->Jd,MATOP_MULT_TRANSPOSE,(void(*)(void))DesignMatMultTranspose);CHKERRQ(ierr); 1085c4762a1bSJed Brown 1086c4762a1bSJed Brown /* User-defined routines for computing user->Js\x and user->Js^T\x*/ 1087c4762a1bSJed Brown ierr = MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m,user->m,user,&user->JsInv);CHKERRQ(ierr); 1088c4762a1bSJed Brown ierr = MatShellSetOperation(user->JsInv,MATOP_MULT,(void(*)(void))StateMatInvMult);CHKERRQ(ierr); 1089c4762a1bSJed Brown ierr = MatShellSetOperation(user->JsInv,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatInvTransposeMult);CHKERRQ(ierr); 1090c4762a1bSJed Brown 1091c4762a1bSJed Brown /* Build matrices for SOR preconditioner */ 1092c4762a1bSJed Brown ierr = Scatter_uxi_uyi(user->u,user->uxi,user->uxi_scatter,user->uyi,user->uyi_scatter,user->nt);CHKERRQ(ierr); 1093c4762a1bSJed Brown ierr = PetscMalloc1(5*n,&user->C);CHKERRQ(ierr); 1094c4762a1bSJed Brown ierr = PetscMalloc1(2*n,&user->Cwork);CHKERRQ(ierr); 1095c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 1096c4762a1bSJed Brown ierr = MatDuplicate(user->Divxy[0],MAT_COPY_VALUES,&user->C[i]);CHKERRQ(ierr); 1097c4762a1bSJed Brown ierr = MatDuplicate(user->Divxy[1],MAT_COPY_VALUES,&user->Cwork[i]);CHKERRQ(ierr); 1098c4762a1bSJed Brown 1099c4762a1bSJed Brown ierr = MatDiagonalScale(user->C[i],NULL,user->uxi[i]);CHKERRQ(ierr); 1100c4762a1bSJed Brown ierr = MatDiagonalScale(user->Cwork[i],NULL,user->uyi[i]);CHKERRQ(ierr); 1101c4762a1bSJed Brown ierr = MatAXPY(user->C[i],1.0,user->Cwork[i],DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 1102c4762a1bSJed Brown ierr = MatScale(user->C[i],user->ht);CHKERRQ(ierr); 1103c4762a1bSJed Brown ierr = MatShift(user->C[i],1.0);CHKERRQ(ierr); 1104c4762a1bSJed Brown } 1105c4762a1bSJed Brown 1106c4762a1bSJed Brown /* Solver options and tolerances */ 1107c4762a1bSJed Brown ierr = KSPCreate(PETSC_COMM_WORLD,&user->solver);CHKERRQ(ierr); 1108c4762a1bSJed Brown ierr = KSPSetType(user->solver,KSPGMRES);CHKERRQ(ierr); 1109c4762a1bSJed Brown ierr = KSPSetOperators(user->solver,user->JsBlock,user->JsBlockPrec);CHKERRQ(ierr); 1110c4762a1bSJed Brown ierr = KSPSetTolerances(user->solver,1e-4,1e-20,1e3,500);CHKERRQ(ierr); 1111c4762a1bSJed Brown /* ierr = KSPSetTolerances(user->solver,1e-8,1e-16,1e3,500);CHKERRQ(ierr); */ 1112c4762a1bSJed Brown ierr = KSPGetPC(user->solver,&user->prec);CHKERRQ(ierr); 1113c4762a1bSJed Brown ierr = PCSetType(user->prec,PCSHELL);CHKERRQ(ierr); 1114c4762a1bSJed Brown 1115c4762a1bSJed Brown ierr = PCShellSetApply(user->prec,StateMatBlockPrecMult);CHKERRQ(ierr); 1116c4762a1bSJed Brown ierr = PCShellSetApplyTranspose(user->prec,StateMatBlockPrecMultTranspose);CHKERRQ(ierr); 1117c4762a1bSJed Brown ierr = PCShellSetContext(user->prec,user);CHKERRQ(ierr); 1118c4762a1bSJed Brown 1119c4762a1bSJed Brown /* Compute true state function yt given ut */ 1120c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&user->ytrue);CHKERRQ(ierr); 1121c4762a1bSJed Brown ierr = VecSetSizes(user->ytrue,PETSC_DECIDE,n*user->nt);CHKERRQ(ierr); 1122c4762a1bSJed Brown ierr = VecSetFromOptions(user->ytrue);CHKERRQ(ierr); 1123c4762a1bSJed Brown user->c_formed = PETSC_TRUE; 1124c4762a1bSJed Brown ierr = VecCopy(user->utrue,user->u);CHKERRQ(ierr); /* Set u=utrue temporarily for StateMatInv */ 1125c4762a1bSJed Brown ierr = VecSet(user->ytrue,0.0);CHKERRQ(ierr); /* Initial guess */ 1126c4762a1bSJed Brown ierr = StateMatInvMult(user->Js,user->q,user->ytrue);CHKERRQ(ierr); 1127c4762a1bSJed Brown ierr = VecCopy(user->ur,user->u);CHKERRQ(ierr); /* Reset u=ur */ 1128c4762a1bSJed Brown 1129c4762a1bSJed Brown /* Initial guess y0 for state given u0 */ 1130c4762a1bSJed Brown ierr = StateMatInvMult(user->Js,user->q,user->y);CHKERRQ(ierr); 1131c4762a1bSJed Brown 1132c4762a1bSJed Brown /* Data discretization */ 1133c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD,&user->Q);CHKERRQ(ierr); 1134c4762a1bSJed Brown ierr = MatSetSizes(user->Q,PETSC_DECIDE,PETSC_DECIDE,user->mx*user->mx,user->m);CHKERRQ(ierr); 1135c4762a1bSJed Brown ierr = MatSetFromOptions(user->Q);CHKERRQ(ierr); 1136c4762a1bSJed Brown ierr = MatMPIAIJSetPreallocation(user->Q,0,NULL,1,NULL);CHKERRQ(ierr); 1137c4762a1bSJed Brown ierr = MatSeqAIJSetPreallocation(user->Q,1,NULL);CHKERRQ(ierr); 1138c4762a1bSJed Brown 1139c4762a1bSJed Brown ierr = MatGetOwnershipRange(user->Q,&istart,&iend);CHKERRQ(ierr); 1140c4762a1bSJed Brown 1141c4762a1bSJed Brown for (i=istart; i<iend; i++) { 1142c4762a1bSJed Brown j = i + user->m - user->mx*user->mx; 1143c4762a1bSJed Brown ierr = MatSetValues(user->Q,1,&i,1,&j,&one,INSERT_VALUES);CHKERRQ(ierr); 1144c4762a1bSJed Brown } 1145c4762a1bSJed Brown 1146c4762a1bSJed Brown ierr = MatAssemblyBegin(user->Q,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1147c4762a1bSJed Brown ierr = MatAssemblyEnd(user->Q,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1148c4762a1bSJed Brown 1149c4762a1bSJed Brown ierr = MatTranspose(user->Q,MAT_INITIAL_MATRIX,&user->QT);CHKERRQ(ierr); 1150c4762a1bSJed Brown 1151c4762a1bSJed Brown ierr = VecDestroy(&XX);CHKERRQ(ierr); 1152c4762a1bSJed Brown ierr = VecDestroy(&YY);CHKERRQ(ierr); 1153c4762a1bSJed Brown ierr = VecDestroy(&XXwork);CHKERRQ(ierr); 1154c4762a1bSJed Brown ierr = VecDestroy(&YYwork);CHKERRQ(ierr); 1155c4762a1bSJed Brown ierr = VecDestroy(&yi);CHKERRQ(ierr); 1156c4762a1bSJed Brown ierr = VecDestroy(&uxi);CHKERRQ(ierr); 1157c4762a1bSJed Brown ierr = VecDestroy(&ui);CHKERRQ(ierr); 1158c4762a1bSJed Brown ierr = VecDestroy(&bc);CHKERRQ(ierr); 1159c4762a1bSJed Brown 1160c4762a1bSJed Brown /* Now that initial conditions have been set, let the user pass tolerance options to the KSP solver */ 1161c4762a1bSJed Brown ierr = KSPSetFromOptions(user->solver);CHKERRQ(ierr); 1162c4762a1bSJed Brown PetscFunctionReturn(0); 1163c4762a1bSJed Brown } 1164c4762a1bSJed Brown 1165c4762a1bSJed Brown PetscErrorCode HyperbolicDestroy(AppCtx *user) 1166c4762a1bSJed Brown { 1167c4762a1bSJed Brown PetscErrorCode ierr; 1168c4762a1bSJed Brown PetscInt i; 1169c4762a1bSJed Brown 1170c4762a1bSJed Brown PetscFunctionBegin; 1171c4762a1bSJed Brown ierr = MatDestroy(&user->Q);CHKERRQ(ierr); 1172c4762a1bSJed Brown ierr = MatDestroy(&user->QT);CHKERRQ(ierr); 1173c4762a1bSJed Brown ierr = MatDestroy(&user->Div);CHKERRQ(ierr); 1174c4762a1bSJed Brown ierr = MatDestroy(&user->Divwork);CHKERRQ(ierr); 1175c4762a1bSJed Brown ierr = MatDestroy(&user->Grad);CHKERRQ(ierr); 1176c4762a1bSJed Brown ierr = MatDestroy(&user->L);CHKERRQ(ierr); 1177c4762a1bSJed Brown ierr = MatDestroy(&user->LT);CHKERRQ(ierr); 1178c4762a1bSJed Brown ierr = KSPDestroy(&user->solver);CHKERRQ(ierr); 1179c4762a1bSJed Brown ierr = MatDestroy(&user->Js);CHKERRQ(ierr); 1180c4762a1bSJed Brown ierr = MatDestroy(&user->Jd);CHKERRQ(ierr); 1181c4762a1bSJed Brown ierr = MatDestroy(&user->JsBlockPrec);CHKERRQ(ierr); 1182c4762a1bSJed Brown ierr = MatDestroy(&user->JsInv);CHKERRQ(ierr); 1183c4762a1bSJed Brown ierr = MatDestroy(&user->JsBlock);CHKERRQ(ierr); 1184c4762a1bSJed Brown ierr = MatDestroy(&user->Divxy[0]);CHKERRQ(ierr); 1185c4762a1bSJed Brown ierr = MatDestroy(&user->Divxy[1]);CHKERRQ(ierr); 1186c4762a1bSJed Brown ierr = MatDestroy(&user->Gradxy[0]);CHKERRQ(ierr); 1187c4762a1bSJed Brown ierr = MatDestroy(&user->Gradxy[1]);CHKERRQ(ierr); 1188c4762a1bSJed Brown ierr = MatDestroy(&user->M);CHKERRQ(ierr); 1189c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 1190c4762a1bSJed Brown ierr = MatDestroy(&user->C[i]);CHKERRQ(ierr); 1191c4762a1bSJed Brown ierr = MatDestroy(&user->Cwork[i]);CHKERRQ(ierr); 1192c4762a1bSJed Brown } 1193c4762a1bSJed Brown ierr = PetscFree(user->C);CHKERRQ(ierr); 1194c4762a1bSJed Brown ierr = PetscFree(user->Cwork);CHKERRQ(ierr); 1195c4762a1bSJed Brown ierr = VecDestroy(&user->u);CHKERRQ(ierr); 1196c4762a1bSJed Brown ierr = VecDestroy(&user->uwork);CHKERRQ(ierr); 1197c4762a1bSJed Brown ierr = VecDestroy(&user->vwork);CHKERRQ(ierr); 1198c4762a1bSJed Brown ierr = VecDestroy(&user->utrue);CHKERRQ(ierr); 1199c4762a1bSJed Brown ierr = VecDestroy(&user->y);CHKERRQ(ierr); 1200c4762a1bSJed Brown ierr = VecDestroy(&user->ywork);CHKERRQ(ierr); 1201c4762a1bSJed Brown ierr = VecDestroy(&user->ytrue);CHKERRQ(ierr); 1202c4762a1bSJed Brown ierr = VecDestroyVecs(user->nt,&user->yi);CHKERRQ(ierr); 1203c4762a1bSJed Brown ierr = VecDestroyVecs(user->nt,&user->yiwork);CHKERRQ(ierr); 1204c4762a1bSJed Brown ierr = VecDestroyVecs(user->nt,&user->ziwork);CHKERRQ(ierr); 1205c4762a1bSJed Brown ierr = VecDestroyVecs(user->nt,&user->uxi);CHKERRQ(ierr); 1206c4762a1bSJed Brown ierr = VecDestroyVecs(user->nt,&user->uyi);CHKERRQ(ierr); 1207c4762a1bSJed Brown ierr = VecDestroyVecs(user->nt,&user->uxiwork);CHKERRQ(ierr); 1208c4762a1bSJed Brown ierr = VecDestroyVecs(user->nt,&user->uyiwork);CHKERRQ(ierr); 1209c4762a1bSJed Brown ierr = VecDestroyVecs(user->nt,&user->ui);CHKERRQ(ierr); 1210c4762a1bSJed Brown ierr = VecDestroyVecs(user->nt,&user->uiwork);CHKERRQ(ierr); 1211c4762a1bSJed Brown ierr = VecDestroy(&user->c);CHKERRQ(ierr); 1212c4762a1bSJed Brown ierr = VecDestroy(&user->cwork);CHKERRQ(ierr); 1213c4762a1bSJed Brown ierr = VecDestroy(&user->ur);CHKERRQ(ierr); 1214c4762a1bSJed Brown ierr = VecDestroy(&user->q);CHKERRQ(ierr); 1215c4762a1bSJed Brown ierr = VecDestroy(&user->d);CHKERRQ(ierr); 1216c4762a1bSJed Brown ierr = VecDestroy(&user->dwork);CHKERRQ(ierr); 1217c4762a1bSJed Brown ierr = VecDestroy(&user->lwork);CHKERRQ(ierr); 1218c4762a1bSJed Brown ierr = VecDestroy(&user->js_diag);CHKERRQ(ierr); 1219c4762a1bSJed Brown ierr = ISDestroy(&user->s_is);CHKERRQ(ierr); 1220c4762a1bSJed Brown ierr = ISDestroy(&user->d_is);CHKERRQ(ierr); 1221c4762a1bSJed Brown ierr = VecScatterDestroy(&user->state_scatter);CHKERRQ(ierr); 1222c4762a1bSJed Brown ierr = VecScatterDestroy(&user->design_scatter);CHKERRQ(ierr); 1223c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 1224c4762a1bSJed Brown ierr = VecScatterDestroy(&user->uxi_scatter[i]);CHKERRQ(ierr); 1225c4762a1bSJed Brown ierr = VecScatterDestroy(&user->uyi_scatter[i]);CHKERRQ(ierr); 1226c4762a1bSJed Brown ierr = VecScatterDestroy(&user->ux_scatter[i]);CHKERRQ(ierr); 1227c4762a1bSJed Brown ierr = VecScatterDestroy(&user->uy_scatter[i]);CHKERRQ(ierr); 1228c4762a1bSJed Brown ierr = VecScatterDestroy(&user->ui_scatter[i]);CHKERRQ(ierr); 1229c4762a1bSJed Brown ierr = VecScatterDestroy(&user->yi_scatter[i]);CHKERRQ(ierr); 1230c4762a1bSJed Brown } 1231c4762a1bSJed Brown ierr = PetscFree(user->uxi_scatter);CHKERRQ(ierr); 1232c4762a1bSJed Brown ierr = PetscFree(user->uyi_scatter);CHKERRQ(ierr); 1233c4762a1bSJed Brown ierr = PetscFree(user->ux_scatter);CHKERRQ(ierr); 1234c4762a1bSJed Brown ierr = PetscFree(user->uy_scatter);CHKERRQ(ierr); 1235c4762a1bSJed Brown ierr = PetscFree(user->ui_scatter);CHKERRQ(ierr); 1236c4762a1bSJed Brown ierr = PetscFree(user->yi_scatter);CHKERRQ(ierr); 1237c4762a1bSJed Brown PetscFunctionReturn(0); 1238c4762a1bSJed Brown } 1239c4762a1bSJed Brown 1240c4762a1bSJed Brown PetscErrorCode HyperbolicMonitor(Tao tao, void *ptr) 1241c4762a1bSJed Brown { 1242c4762a1bSJed Brown PetscErrorCode ierr; 1243c4762a1bSJed Brown Vec X; 1244c4762a1bSJed Brown PetscReal unorm,ynorm; 1245c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 1246c4762a1bSJed Brown 1247c4762a1bSJed Brown PetscFunctionBegin; 1248*a82e8c82SStefano Zampini ierr = TaoGetSolution(tao,&X);CHKERRQ(ierr); 1249c4762a1bSJed Brown ierr = Scatter(X,user->ywork,user->state_scatter,user->uwork,user->design_scatter);CHKERRQ(ierr); 1250c4762a1bSJed Brown ierr = VecAXPY(user->ywork,-1.0,user->ytrue);CHKERRQ(ierr); 1251c4762a1bSJed Brown ierr = VecAXPY(user->uwork,-1.0,user->utrue);CHKERRQ(ierr); 1252c4762a1bSJed Brown ierr = VecNorm(user->uwork,NORM_2,&unorm);CHKERRQ(ierr); 1253c4762a1bSJed Brown ierr = VecNorm(user->ywork,NORM_2,&ynorm);CHKERRQ(ierr); 1254c4762a1bSJed Brown ierr = PetscPrintf(MPI_COMM_WORLD, "||u-ut||=%g ||y-yt||=%g\n",(double)unorm,(double)ynorm);CHKERRQ(ierr); 1255c4762a1bSJed Brown PetscFunctionReturn(0); 1256c4762a1bSJed Brown } 1257c4762a1bSJed Brown 1258c4762a1bSJed Brown /*TEST 1259c4762a1bSJed Brown 1260c4762a1bSJed Brown build: 1261c4762a1bSJed Brown requires: !complex 1262c4762a1bSJed Brown 1263c4762a1bSJed Brown test: 1264c4762a1bSJed Brown requires: !single 1265c4762a1bSJed Brown args: -tao_cmonitor -tao_max_funcs 10 -tao_type lcl -tao_gatol 1.e-5 1266c4762a1bSJed Brown 1267c4762a1bSJed Brown test: 1268c4762a1bSJed Brown suffix: guess_pod 1269c4762a1bSJed Brown requires: !single 1270c4762a1bSJed Brown args: -tao_cmonitor -tao_max_funcs 10 -tao_type lcl -ksp_guess_type pod -tao_gatol 1.e-5 1271c4762a1bSJed Brown 1272c4762a1bSJed Brown TEST*/ 1273