1c4762a1bSJed Brown #include <petsc/private/taoimpl.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(); 7a82e8c82SStefano Zampini Routines: TaoSetSolution(); 8a82e8c82SStefano Zampini Routines: TaoSetObjective(); 9a82e8c82SStefano 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: n 18c4762a1bSJed Brown T*/ 19c4762a1bSJed Brown 20c4762a1bSJed Brown typedef struct { 21c4762a1bSJed Brown PetscInt n; /* Number of variables */ 22c4762a1bSJed Brown PetscInt m; /* Number of constraints per time step */ 23c4762a1bSJed Brown PetscInt mx; /* grid points in each direction */ 24c4762a1bSJed Brown PetscInt nt; /* Number of time steps; as of now, must be divisible by 8 */ 25c4762a1bSJed Brown PetscInt ndata; /* Number of data points per sample */ 26c4762a1bSJed Brown PetscInt ns; /* Number of samples */ 27c4762a1bSJed Brown PetscInt *sample_times; /* Times of samples */ 28c4762a1bSJed Brown IS s_is; 29c4762a1bSJed Brown IS d_is; 30c4762a1bSJed Brown 31c4762a1bSJed Brown VecScatter state_scatter; 32c4762a1bSJed Brown VecScatter design_scatter; 33c4762a1bSJed Brown VecScatter *yi_scatter; 34c4762a1bSJed Brown VecScatter *di_scatter; 35c4762a1bSJed Brown 36c4762a1bSJed Brown Mat Js,Jd,JsBlockPrec,JsInv,JsBlock; 37c4762a1bSJed Brown PetscBool jformed,dsg_formed; 38c4762a1bSJed Brown 39c4762a1bSJed Brown PetscReal alpha; /* Regularization parameter */ 40c4762a1bSJed Brown PetscReal beta; /* Weight attributed to ||u||^2 in regularization functional */ 41c4762a1bSJed Brown PetscReal noise; /* Amount of noise to add to data */ 42c4762a1bSJed Brown PetscReal ht; /* Time step */ 43c4762a1bSJed Brown 44c4762a1bSJed Brown Mat Qblock,QblockT; 45c4762a1bSJed Brown Mat L,LT; 46c4762a1bSJed Brown Mat Div,Divwork; 47c4762a1bSJed Brown Mat Grad; 48c4762a1bSJed Brown Mat Av,Avwork,AvT; 49c4762a1bSJed Brown Mat DSG; 50c4762a1bSJed Brown Vec q; 51c4762a1bSJed Brown Vec ur; /* reference */ 52c4762a1bSJed Brown 53c4762a1bSJed Brown Vec d; 54c4762a1bSJed Brown Vec dwork; 55c4762a1bSJed Brown Vec *di; 56c4762a1bSJed Brown 57c4762a1bSJed Brown Vec y; /* state variables */ 58c4762a1bSJed Brown Vec ywork; 59c4762a1bSJed Brown 60c4762a1bSJed Brown Vec ytrue; 61c4762a1bSJed Brown Vec *yi,*yiwork; 62c4762a1bSJed Brown 63c4762a1bSJed Brown Vec u; /* design variables */ 64c4762a1bSJed Brown Vec uwork; 65c4762a1bSJed Brown 66c4762a1bSJed Brown Vec utrue; 67c4762a1bSJed Brown Vec js_diag; 68c4762a1bSJed Brown Vec c; /* constraint vector */ 69c4762a1bSJed Brown Vec cwork; 70c4762a1bSJed Brown 71c4762a1bSJed Brown Vec lwork; 72c4762a1bSJed Brown Vec S; 73c4762a1bSJed Brown Vec Rwork,Swork,Twork; 74c4762a1bSJed Brown Vec Av_u; 75c4762a1bSJed Brown 76c4762a1bSJed Brown KSP solver; 77c4762a1bSJed Brown PC prec; 78c4762a1bSJed Brown 79c4762a1bSJed Brown PetscInt ksp_its; 80c4762a1bSJed Brown PetscInt ksp_its_initial; 81c4762a1bSJed Brown } AppCtx; 82c4762a1bSJed Brown 83c4762a1bSJed Brown PetscErrorCode FormFunction(Tao, Vec, PetscReal*, void*); 84c4762a1bSJed Brown PetscErrorCode FormGradient(Tao, Vec, Vec, void*); 85c4762a1bSJed Brown PetscErrorCode FormFunctionGradient(Tao, Vec, PetscReal*, Vec, void*); 86c4762a1bSJed Brown PetscErrorCode FormJacobianState(Tao, Vec, Mat, Mat, Mat, void*); 87c4762a1bSJed Brown PetscErrorCode FormJacobianDesign(Tao, Vec, Mat, void*); 88c4762a1bSJed Brown PetscErrorCode FormConstraints(Tao, Vec, Vec, void*); 89c4762a1bSJed Brown PetscErrorCode FormHessian(Tao, Vec, Mat, Mat, void*); 90c4762a1bSJed Brown PetscErrorCode Gather(Vec x, Vec state, VecScatter s_scat, Vec design, VecScatter d_scat); 91c4762a1bSJed Brown PetscErrorCode Scatter(Vec x, Vec state, VecScatter s_scat, Vec design, VecScatter d_scat); 92c4762a1bSJed Brown PetscErrorCode ParabolicInitialize(AppCtx *user); 93c4762a1bSJed Brown PetscErrorCode ParabolicDestroy(AppCtx *user); 94c4762a1bSJed Brown PetscErrorCode ParabolicMonitor(Tao, void*); 95c4762a1bSJed Brown 96c4762a1bSJed Brown PetscErrorCode StateMatMult(Mat,Vec,Vec); 97c4762a1bSJed Brown PetscErrorCode StateMatBlockMult(Mat,Vec,Vec); 98c4762a1bSJed Brown PetscErrorCode StateMatMultTranspose(Mat,Vec,Vec); 99c4762a1bSJed Brown PetscErrorCode StateMatGetDiagonal(Mat,Vec); 100c4762a1bSJed Brown PetscErrorCode StateMatDuplicate(Mat,MatDuplicateOption,Mat*); 101c4762a1bSJed Brown PetscErrorCode StateMatInvMult(Mat,Vec,Vec); 102c4762a1bSJed Brown PetscErrorCode StateMatInvTransposeMult(Mat,Vec,Vec); 103c4762a1bSJed Brown PetscErrorCode StateMatBlockPrecMult(PC,Vec,Vec); 104c4762a1bSJed Brown 105c4762a1bSJed Brown PetscErrorCode DesignMatMult(Mat,Vec,Vec); 106c4762a1bSJed Brown PetscErrorCode DesignMatMultTranspose(Mat,Vec,Vec); 107c4762a1bSJed Brown 108c4762a1bSJed Brown PetscErrorCode Gather_i(Vec,Vec*,VecScatter*,PetscInt); 109c4762a1bSJed Brown PetscErrorCode Scatter_i(Vec,Vec*,VecScatter*,PetscInt); 110c4762a1bSJed Brown 111c4762a1bSJed Brown static char help[]=""; 112c4762a1bSJed Brown 113c4762a1bSJed Brown int main(int argc, char **argv) 114c4762a1bSJed Brown { 115c4762a1bSJed Brown PetscErrorCode ierr; 116c4762a1bSJed Brown Vec x,x0; 117c4762a1bSJed Brown Tao tao; 118c4762a1bSJed Brown AppCtx user; 119c4762a1bSJed Brown IS is_allstate,is_alldesign; 120c4762a1bSJed Brown PetscInt lo,hi,hi2,lo2,ksp_old; 121c4762a1bSJed Brown PetscInt ntests = 1; 122c4762a1bSJed Brown PetscInt i; 123c4762a1bSJed Brown #if defined(PETSC_USE_LOG) 124c4762a1bSJed Brown PetscLogStage stages[1]; 125c4762a1bSJed Brown #endif 126c4762a1bSJed Brown 127*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscInitialize(&argc, &argv, (char*)0,help)); 128c4762a1bSJed Brown user.mx = 8; 12976280437SVaclav Hapla ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"parabolic example",NULL);CHKERRQ(ierr); 1305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsInt("-mx","Number of grid points in each direction","",user.mx,&user.mx,NULL)); 131c4762a1bSJed Brown user.nt = 8; 1325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsInt("-nt","Number of time steps","",user.nt,&user.nt,NULL)); 133c4762a1bSJed Brown user.ndata = 64; 1345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsInt("-ndata","Numbers of data points per sample","",user.ndata,&user.ndata,NULL)); 135c4762a1bSJed Brown user.ns = 8; 1365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsInt("-ns","Number of samples","",user.ns,&user.ns,NULL)); 137c4762a1bSJed Brown user.alpha = 1.0; 1385f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsReal("-alpha","Regularization parameter","",user.alpha,&user.alpha,NULL)); 139c4762a1bSJed Brown user.beta = 0.01; 1405f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsReal("-beta","Weight attributed to ||u||^2 in regularization functional","",user.beta,&user.beta,NULL)); 141c4762a1bSJed Brown user.noise = 0.01; 1425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsReal("-noise","Amount of noise to add to data","",user.noise,&user.noise,NULL)); 1435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsInt("-ntests","Number of times to repeat TaoSolve","",ntests,&ntests,NULL)); 14476280437SVaclav Hapla ierr = PetscOptionsEnd();CHKERRQ(ierr); 145c4762a1bSJed Brown 146c4762a1bSJed Brown user.m = user.mx*user.mx*user.mx; /* number of constraints per time step */ 147c4762a1bSJed Brown user.n = user.m*(user.nt+1); /* number of variables */ 148c4762a1bSJed Brown user.ht = (PetscReal)1/user.nt; 149c4762a1bSJed Brown 1505f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&user.u)); 1515f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&user.y)); 1525f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&user.c)); 1535f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(user.u,PETSC_DECIDE,user.n-user.m*user.nt)); 1545f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(user.y,PETSC_DECIDE,user.m*user.nt)); 1555f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(user.c,PETSC_DECIDE,user.m*user.nt)); 1565f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(user.u)); 1575f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(user.y)); 1585f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(user.c)); 159c4762a1bSJed Brown 160c4762a1bSJed Brown /* Create scatters for reduced spaces. 161c4762a1bSJed Brown If the state vector y and design vector u are partitioned as 162c4762a1bSJed Brown [y_1; y_2; ...; y_np] and [u_1; u_2; ...; u_np] (with np = # of processors), 163c4762a1bSJed Brown then the solution vector x is organized as 164c4762a1bSJed Brown [y_1; u_1; y_2; u_2; ...; y_np; u_np]. 165c4762a1bSJed Brown The index sets user.s_is and user.d_is correspond to the indices of the 166c4762a1bSJed Brown state and design variables owned by the current processor. 167c4762a1bSJed Brown */ 1685f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&x)); 169c4762a1bSJed Brown 1705f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetOwnershipRange(user.y,&lo,&hi)); 1715f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetOwnershipRange(user.u,&lo2,&hi2)); 172c4762a1bSJed Brown 1735f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_allstate)); 1745f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateStride(PETSC_COMM_SELF,hi-lo,lo+lo2,1,&user.s_is)); 175c4762a1bSJed Brown 1765f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateStride(PETSC_COMM_SELF,hi2-lo2,lo2,1,&is_alldesign)); 1775f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateStride(PETSC_COMM_SELF,hi2-lo2,hi+lo2,1,&user.d_is)); 178c4762a1bSJed Brown 1795f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(x,hi-lo+hi2-lo2,user.n)); 1805f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(x)); 181c4762a1bSJed Brown 1825f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterCreate(x,user.s_is,user.y,is_allstate,&user.state_scatter)); 1835f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterCreate(x,user.d_is,user.u,is_alldesign,&user.design_scatter)); 1845f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&is_alldesign)); 1855f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&is_allstate)); 186c4762a1bSJed Brown 187c4762a1bSJed Brown /* Create TAO solver and set desired solution method */ 1885f80ce2aSJacob Faibussowitsch CHKERRQ(TaoCreate(PETSC_COMM_WORLD,&tao)); 1895f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetType(tao,TAOLCL)); 190c4762a1bSJed Brown 191c4762a1bSJed Brown /* Set up initial vectors and matrices */ 1925f80ce2aSJacob Faibussowitsch CHKERRQ(ParabolicInitialize(&user)); 193c4762a1bSJed Brown 1945f80ce2aSJacob Faibussowitsch CHKERRQ(Gather(x,user.y,user.state_scatter,user.u,user.design_scatter)); 1955f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(x,&x0)); 1965f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(x,x0)); 197c4762a1bSJed Brown 198c4762a1bSJed Brown /* Set solution vector with an initial guess */ 1995f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetSolution(tao,x)); 2005f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetObjective(tao, FormFunction, &user)); 2015f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetGradient(tao, NULL, FormGradient, &user)); 2025f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetConstraintsRoutine(tao, user.c, FormConstraints, &user)); 203c4762a1bSJed Brown 2045f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetJacobianStateRoutine(tao, user.Js, user.JsBlockPrec, user.JsInv, FormJacobianState, &user)); 2055f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetJacobianDesignRoutine(tao, user.Jd, FormJacobianDesign, &user)); 206c4762a1bSJed Brown 2075f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetFromOptions(tao)); 2085f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetStateDesignIS(tao,user.s_is,user.d_is)); 209c4762a1bSJed Brown 210c4762a1bSJed Brown /* SOLVE THE APPLICATION */ 2115f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogStageRegister("Trials",&stages[0])); 2125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogStagePush(stages[0])); 213c4762a1bSJed Brown user.ksp_its_initial = user.ksp_its; 214c4762a1bSJed Brown ksp_old = user.ksp_its; 215c4762a1bSJed Brown for (i=0; i<ntests; i++) { 2165f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSolve(tao)); 2175f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"KSP Iterations = %D\n",user.ksp_its-ksp_old)); 2185f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(x0,x)); 2195f80ce2aSJacob Faibussowitsch CHKERRQ(TaoSetSolution(tao,x)); 220c4762a1bSJed Brown } 2215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogStagePop()); 2225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBarrier((PetscObject)x)); 2235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"KSP iterations within initialization: ")); 2245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"%D\n",user.ksp_its_initial)); 2255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Total KSP iterations over %D trial(s): ",ntests)); 2265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"%D\n",user.ksp_its)); 2275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"KSP iterations per trial: ")); 2285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"%D\n",(user.ksp_its-user.ksp_its_initial)/ntests)); 229c4762a1bSJed Brown 2305f80ce2aSJacob Faibussowitsch CHKERRQ(TaoDestroy(&tao)); 2315f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&x)); 2325f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&x0)); 2335f80ce2aSJacob Faibussowitsch CHKERRQ(ParabolicDestroy(&user)); 234c4762a1bSJed Brown 235*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscFinalize()); 236*b122ec5aSJacob Faibussowitsch return 0; 237c4762a1bSJed Brown } 238c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 239c4762a1bSJed Brown /* 240c4762a1bSJed Brown dwork = Qy - d 241c4762a1bSJed Brown lwork = L*(u-ur) 242c4762a1bSJed Brown f = 1/2 * (dwork.dork + alpha*lwork.lwork) 243c4762a1bSJed Brown */ 244c4762a1bSJed Brown PetscErrorCode FormFunction(Tao tao,Vec X,PetscReal *f,void *ptr) 245c4762a1bSJed Brown { 246c4762a1bSJed Brown PetscReal d1=0,d2=0; 247c4762a1bSJed Brown PetscInt i,j; 248c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 249c4762a1bSJed Brown 250c4762a1bSJed Brown PetscFunctionBegin; 2515f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter)); 2525f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->y,user->yi,user->yi_scatter,user->nt)); 253c4762a1bSJed Brown for (j=0; j<user->ns; j++) { 254c4762a1bSJed Brown i = user->sample_times[j]; 2555f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Qblock,user->yi[i],user->di[j])); 256c4762a1bSJed Brown } 2575f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(user->dwork,user->di,user->di_scatter,user->ns)); 2585f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->dwork,-1.0,user->d)); 2595f80ce2aSJacob Faibussowitsch CHKERRQ(VecDot(user->dwork,user->dwork,&d1)); 260c4762a1bSJed Brown 2615f80ce2aSJacob Faibussowitsch CHKERRQ(VecWAXPY(user->uwork,-1.0,user->ur,user->u)); 2625f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->L,user->uwork,user->lwork)); 2635f80ce2aSJacob Faibussowitsch CHKERRQ(VecDot(user->lwork,user->lwork,&d2)); 264c4762a1bSJed Brown 265c4762a1bSJed Brown *f = 0.5 * (d1 + user->alpha*d2); 266c4762a1bSJed Brown PetscFunctionReturn(0); 267c4762a1bSJed Brown } 268c4762a1bSJed Brown 269c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 270c4762a1bSJed Brown /* 271c4762a1bSJed Brown state: g_s = Q' *(Qy - d) 272c4762a1bSJed Brown design: g_d = alpha*L'*L*(u-ur) 273c4762a1bSJed Brown */ 274c4762a1bSJed Brown PetscErrorCode FormGradient(Tao tao,Vec X,Vec G,void *ptr) 275c4762a1bSJed Brown { 276c4762a1bSJed Brown PetscInt i,j; 277c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 278c4762a1bSJed Brown 279c4762a1bSJed Brown PetscFunctionBegin; 2805f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter)); 2815f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->y,user->yi,user->yi_scatter,user->nt)); 282c4762a1bSJed Brown for (j=0; j<user->ns; j++) { 283c4762a1bSJed Brown i = user->sample_times[j]; 2845f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Qblock,user->yi[i],user->di[j])); 285c4762a1bSJed Brown } 2865f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(user->dwork,user->di,user->di_scatter,user->ns)); 2875f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->dwork,-1.0,user->d)); 2885f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->dwork,user->di,user->di_scatter,user->ns)); 2895f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->ywork,0.0)); 2905f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->ywork,user->yiwork,user->yi_scatter,user->nt)); 291c4762a1bSJed Brown for (j=0; j<user->ns; j++) { 292c4762a1bSJed Brown i = user->sample_times[j]; 2935f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->QblockT,user->di[j],user->yiwork[i])); 294c4762a1bSJed Brown } 2955f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(user->ywork,user->yiwork,user->yi_scatter,user->nt)); 296c4762a1bSJed Brown 2975f80ce2aSJacob Faibussowitsch CHKERRQ(VecWAXPY(user->uwork,-1.0,user->ur,user->u)); 2985f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->L,user->uwork,user->lwork)); 2995f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->LT,user->lwork,user->uwork)); 3005f80ce2aSJacob Faibussowitsch CHKERRQ(VecScale(user->uwork, user->alpha)); 3015f80ce2aSJacob Faibussowitsch CHKERRQ(Gather(G,user->ywork,user->state_scatter,user->uwork,user->design_scatter)); 302c4762a1bSJed Brown PetscFunctionReturn(0); 303c4762a1bSJed Brown } 304c4762a1bSJed Brown 305c4762a1bSJed Brown PetscErrorCode FormFunctionGradient(Tao tao, Vec X, PetscReal *f, Vec G, void *ptr) 306c4762a1bSJed Brown { 307c4762a1bSJed Brown PetscReal d1,d2; 308c4762a1bSJed Brown PetscInt i,j; 309c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 310c4762a1bSJed Brown 311c4762a1bSJed Brown PetscFunctionBegin; 3125f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter)); 3135f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->y,user->yi,user->yi_scatter,user->nt)); 314c4762a1bSJed Brown for (j=0; j<user->ns; j++) { 315c4762a1bSJed Brown i = user->sample_times[j]; 3165f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Qblock,user->yi[i],user->di[j])); 317c4762a1bSJed Brown } 3185f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(user->dwork,user->di,user->di_scatter,user->ns)); 3195f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->dwork,-1.0,user->d)); 3205f80ce2aSJacob Faibussowitsch CHKERRQ(VecDot(user->dwork,user->dwork,&d1)); 3215f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->dwork,user->di,user->di_scatter,user->ns)); 3225f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->ywork,0.0)); 3235f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->ywork,user->yiwork,user->yi_scatter,user->nt)); 324c4762a1bSJed Brown for (j=0; j<user->ns; j++) { 325c4762a1bSJed Brown i = user->sample_times[j]; 3265f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->QblockT,user->di[j],user->yiwork[i])); 327c4762a1bSJed Brown } 3285f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(user->ywork,user->yiwork,user->yi_scatter,user->nt)); 329c4762a1bSJed Brown 3305f80ce2aSJacob Faibussowitsch CHKERRQ(VecWAXPY(user->uwork,-1.0,user->ur,user->u)); 3315f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->L,user->uwork,user->lwork)); 3325f80ce2aSJacob Faibussowitsch CHKERRQ(VecDot(user->lwork,user->lwork,&d2)); 3335f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->LT,user->lwork,user->uwork)); 3345f80ce2aSJacob Faibussowitsch CHKERRQ(VecScale(user->uwork, user->alpha)); 335c4762a1bSJed Brown *f = 0.5 * (d1 + user->alpha*d2); 336c4762a1bSJed Brown 3375f80ce2aSJacob Faibussowitsch CHKERRQ(Gather(G,user->ywork,user->state_scatter,user->uwork,user->design_scatter)); 338c4762a1bSJed Brown PetscFunctionReturn(0); 339c4762a1bSJed Brown } 340c4762a1bSJed Brown 341c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 342c4762a1bSJed Brown /* A 343c4762a1bSJed Brown MatShell object 344c4762a1bSJed Brown */ 345c4762a1bSJed Brown PetscErrorCode FormJacobianState(Tao tao, Vec X, Mat J, Mat JPre, Mat JInv, void *ptr) 346c4762a1bSJed Brown { 347c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 348c4762a1bSJed Brown 349c4762a1bSJed Brown PetscFunctionBegin; 3505f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter)); 3515f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->uwork,0)); 3525f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->uwork,-1.0,user->u)); 3535f80ce2aSJacob Faibussowitsch CHKERRQ(VecExp(user->uwork)); 3545f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Av,user->uwork,user->Av_u)); 3555f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(user->Av_u,user->Swork)); 3565f80ce2aSJacob Faibussowitsch CHKERRQ(VecReciprocal(user->Swork)); 3575f80ce2aSJacob Faibussowitsch CHKERRQ(MatCopy(user->Div,user->Divwork,SAME_NONZERO_PATTERN)); 3585f80ce2aSJacob Faibussowitsch CHKERRQ(MatDiagonalScale(user->Divwork,NULL,user->Swork)); 359c4762a1bSJed Brown if (user->dsg_formed) { 3605f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductNumeric(user->DSG)); 361c4762a1bSJed Brown } else { 3625f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMult(user->Divwork,user->Grad,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&user->DSG)); 363c4762a1bSJed Brown user->dsg_formed = PETSC_TRUE; 364c4762a1bSJed Brown } 365c4762a1bSJed Brown 366c4762a1bSJed Brown /* B = speye(nx^3) + ht*DSG; */ 3675f80ce2aSJacob Faibussowitsch CHKERRQ(MatScale(user->DSG,user->ht)); 3685f80ce2aSJacob Faibussowitsch CHKERRQ(MatShift(user->DSG,1.0)); 369c4762a1bSJed Brown PetscFunctionReturn(0); 370c4762a1bSJed Brown } 371c4762a1bSJed Brown 372c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 373c4762a1bSJed Brown /* B */ 374c4762a1bSJed Brown PetscErrorCode FormJacobianDesign(Tao tao, Vec X, Mat J, void *ptr) 375c4762a1bSJed Brown { 376c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 377c4762a1bSJed Brown 378c4762a1bSJed Brown PetscFunctionBegin; 3795f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter)); 380c4762a1bSJed Brown PetscFunctionReturn(0); 381c4762a1bSJed Brown } 382c4762a1bSJed Brown 383c4762a1bSJed Brown PetscErrorCode StateMatMult(Mat J_shell, Vec X, Vec Y) 384c4762a1bSJed Brown { 385c4762a1bSJed Brown PetscInt i; 386c4762a1bSJed Brown AppCtx *user; 387c4762a1bSJed Brown 388c4762a1bSJed Brown PetscFunctionBegin; 3895f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellGetContext(J_shell,&user)); 3905f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(X,user->yi,user->yi_scatter,user->nt)); 3915f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->JsBlock,user->yi[0],user->yiwork[0])); 392c4762a1bSJed Brown for (i=1; i<user->nt; i++) { 3935f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->JsBlock,user->yi[i],user->yiwork[i])); 3945f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->yiwork[i],-1.0,user->yi[i-1])); 395c4762a1bSJed Brown } 3965f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(Y,user->yiwork,user->yi_scatter,user->nt)); 397c4762a1bSJed Brown PetscFunctionReturn(0); 398c4762a1bSJed Brown } 399c4762a1bSJed Brown 400c4762a1bSJed Brown PetscErrorCode StateMatMultTranspose(Mat J_shell, Vec X, Vec Y) 401c4762a1bSJed Brown { 402c4762a1bSJed Brown PetscInt i; 403c4762a1bSJed Brown AppCtx *user; 404c4762a1bSJed Brown 405c4762a1bSJed Brown PetscFunctionBegin; 4065f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellGetContext(J_shell,&user)); 4075f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(X,user->yi,user->yi_scatter,user->nt)); 408c4762a1bSJed Brown for (i=0; i<user->nt-1; i++) { 4095f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->JsBlock,user->yi[i],user->yiwork[i])); 4105f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->yiwork[i],-1.0,user->yi[i+1])); 411c4762a1bSJed Brown } 412c4762a1bSJed Brown i = user->nt-1; 4135f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->JsBlock,user->yi[i],user->yiwork[i])); 4145f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(Y,user->yiwork,user->yi_scatter,user->nt)); 415c4762a1bSJed Brown PetscFunctionReturn(0); 416c4762a1bSJed Brown } 417c4762a1bSJed Brown 418c4762a1bSJed Brown PetscErrorCode StateMatBlockMult(Mat J_shell, Vec X, Vec Y) 419c4762a1bSJed Brown { 420c4762a1bSJed Brown AppCtx *user; 421c4762a1bSJed Brown 422c4762a1bSJed Brown PetscFunctionBegin; 4235f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellGetContext(J_shell,&user)); 4245f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Grad,X,user->Swork)); 4255f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseDivide(user->Swork,user->Swork,user->Av_u)); 4265f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Div,user->Swork,Y)); 4275f80ce2aSJacob Faibussowitsch CHKERRQ(VecAYPX(Y,user->ht,X)); 428c4762a1bSJed Brown PetscFunctionReturn(0); 429c4762a1bSJed Brown } 430c4762a1bSJed Brown 431c4762a1bSJed Brown PetscErrorCode DesignMatMult(Mat J_shell, Vec X, Vec Y) 432c4762a1bSJed Brown { 433c4762a1bSJed Brown PetscInt i; 434c4762a1bSJed Brown AppCtx *user; 435c4762a1bSJed Brown 436c4762a1bSJed Brown PetscFunctionBegin; 4375f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellGetContext(J_shell,&user)); 438c4762a1bSJed Brown 439c4762a1bSJed Brown /* sdiag(1./v) */ 4405f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->uwork,0)); 4415f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->uwork,-1.0,user->u)); 4425f80ce2aSJacob Faibussowitsch CHKERRQ(VecExp(user->uwork)); 443c4762a1bSJed Brown 444c4762a1bSJed Brown /* sdiag(1./((Av*(1./v)).^2)) */ 4455f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Av,user->uwork,user->Swork)); 4465f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(user->Swork,user->Swork,user->Swork)); 4475f80ce2aSJacob Faibussowitsch CHKERRQ(VecReciprocal(user->Swork)); 448c4762a1bSJed Brown 449c4762a1bSJed Brown /* (Av * (sdiag(1./v) * b)) */ 4505f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(user->uwork,user->uwork,X)); 4515f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Av,user->uwork,user->Twork)); 452c4762a1bSJed Brown 453c4762a1bSJed Brown /* (sdiag(1./((Av*(1./v)).^2)) * (Av * (sdiag(1./v) * b))) */ 4545f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(user->Swork,user->Twork,user->Swork)); 455c4762a1bSJed Brown 4565f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->y,user->yi,user->yi_scatter,user->nt)); 457c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 458c4762a1bSJed Brown /* (sdiag(Grad*y(:,i)) */ 4595f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Grad,user->yi[i],user->Twork)); 460c4762a1bSJed Brown 461c4762a1bSJed Brown /* ht * Div * (sdiag(Grad*y(:,i)) * (sdiag(1./((Av*(1./v)).^2)) * (Av * (sdiag(1./v) * b)))) */ 4625f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(user->Twork,user->Twork,user->Swork)); 4635f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Div,user->Twork,user->yiwork[i])); 4645f80ce2aSJacob Faibussowitsch CHKERRQ(VecScale(user->yiwork[i],user->ht)); 465c4762a1bSJed Brown } 4665f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(Y,user->yiwork,user->yi_scatter,user->nt)); 467c4762a1bSJed Brown 468c4762a1bSJed Brown PetscFunctionReturn(0); 469c4762a1bSJed Brown } 470c4762a1bSJed Brown 471c4762a1bSJed Brown PetscErrorCode DesignMatMultTranspose(Mat J_shell, Vec X, Vec Y) 472c4762a1bSJed Brown { 473c4762a1bSJed Brown PetscInt i; 474c4762a1bSJed Brown AppCtx *user; 475c4762a1bSJed Brown 476c4762a1bSJed Brown PetscFunctionBegin; 4775f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellGetContext(J_shell,&user)); 478c4762a1bSJed Brown 479c4762a1bSJed Brown /* sdiag(1./((Av*(1./v)).^2)) */ 4805f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->uwork,0)); 4815f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->uwork,-1.0,user->u)); 4825f80ce2aSJacob Faibussowitsch CHKERRQ(VecExp(user->uwork)); 4835f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Av,user->uwork,user->Rwork)); 4845f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(user->Rwork,user->Rwork,user->Rwork)); 4855f80ce2aSJacob Faibussowitsch CHKERRQ(VecReciprocal(user->Rwork)); 486c4762a1bSJed Brown 4875f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(Y,0.0)); 4885f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->y,user->yi,user->yi_scatter,user->nt)); 4895f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(X,user->yiwork,user->yi_scatter,user->nt)); 490c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 491c4762a1bSJed Brown /* (Div' * b(:,i)) */ 4925f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Grad,user->yiwork[i],user->Swork)); 493c4762a1bSJed Brown 494c4762a1bSJed Brown /* sdiag(Grad*y(:,i)) */ 4955f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Grad,user->yi[i],user->Twork)); 496c4762a1bSJed Brown 497c4762a1bSJed Brown /* (sdiag(Grad*y(:,i)) * (Div' * b(:,i))) */ 4985f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(user->Twork,user->Swork,user->Twork)); 499c4762a1bSJed Brown 500c4762a1bSJed Brown /* (sdiag(1./((Av*(1./v)).^2)) * (sdiag(Grad*y(:,i)) * (Div' * b(:,i)))) */ 5015f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(user->Twork,user->Rwork,user->Twork)); 502c4762a1bSJed Brown 503c4762a1bSJed Brown /* (Av' * (sdiag(1./((Av*(1./v)).^2)) * (sdiag(Grad*y(:,i)) * (Div' * b(:,i))))) */ 5045f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->AvT,user->Twork,user->yiwork[i])); 505c4762a1bSJed Brown 506c4762a1bSJed Brown /* sdiag(1./v) * (Av' * (sdiag(1./((Av*(1./v)).^2)) * (sdiag(Grad*y(:,i)) * (Div' * b(:,i))))) */ 5075f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(user->yiwork[i],user->uwork,user->yiwork[i])); 5085f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(Y,user->ht,user->yiwork[i])); 509c4762a1bSJed Brown } 510c4762a1bSJed Brown PetscFunctionReturn(0); 511c4762a1bSJed Brown } 512c4762a1bSJed Brown 513c4762a1bSJed Brown PetscErrorCode StateMatBlockPrecMult(PC PC_shell, Vec X, Vec Y) 514c4762a1bSJed Brown { 515c4762a1bSJed Brown AppCtx *user; 516c4762a1bSJed Brown 517c4762a1bSJed Brown PetscFunctionBegin; 5185f80ce2aSJacob Faibussowitsch CHKERRQ(PCShellGetContext(PC_shell,&user)); 519c4762a1bSJed Brown 520c4762a1bSJed Brown if (user->dsg_formed) { 5215f80ce2aSJacob Faibussowitsch CHKERRQ(MatSOR(user->DSG,X,1.0,(MatSORType)(SOR_ZERO_INITIAL_GUESS | SOR_LOCAL_SYMMETRIC_SWEEP),0.0,1,1,Y)); 522c4762a1bSJed Brown } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"DSG not formed"); 523c4762a1bSJed Brown PetscFunctionReturn(0); 524c4762a1bSJed Brown } 525c4762a1bSJed Brown 526c4762a1bSJed Brown PetscErrorCode StateMatInvMult(Mat J_shell, Vec X, Vec Y) 527c4762a1bSJed Brown { 528c4762a1bSJed Brown AppCtx *user; 529c4762a1bSJed Brown PetscInt its,i; 530c4762a1bSJed Brown 531c4762a1bSJed Brown PetscFunctionBegin; 5325f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellGetContext(J_shell,&user)); 533c4762a1bSJed Brown 534c4762a1bSJed Brown if (Y == user->ytrue) { 535c4762a1bSJed Brown /* First solve is done with true solution to set up problem */ 5365f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetTolerances(user->solver,1e-8,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT)); 537c4762a1bSJed Brown } else { 5385f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetTolerances(user->solver,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT)); 539c4762a1bSJed Brown } 540c4762a1bSJed Brown 5415f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(X,user->yi,user->yi_scatter,user->nt)); 5425f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSolve(user->solver,user->yi[0],user->yiwork[0])); 5435f80ce2aSJacob Faibussowitsch CHKERRQ(KSPGetIterationNumber(user->solver,&its)); 544c4762a1bSJed Brown user->ksp_its = user->ksp_its + its; 545c4762a1bSJed Brown 546c4762a1bSJed Brown for (i=1; i<user->nt; i++) { 5475f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->yi[i],1.0,user->yiwork[i-1])); 5485f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSolve(user->solver,user->yi[i],user->yiwork[i])); 5495f80ce2aSJacob Faibussowitsch CHKERRQ(KSPGetIterationNumber(user->solver,&its)); 550c4762a1bSJed Brown user->ksp_its = user->ksp_its + its; 551c4762a1bSJed Brown } 5525f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(Y,user->yiwork,user->yi_scatter,user->nt)); 553c4762a1bSJed Brown PetscFunctionReturn(0); 554c4762a1bSJed Brown } 555c4762a1bSJed Brown 556c4762a1bSJed Brown PetscErrorCode StateMatInvTransposeMult(Mat J_shell, Vec X, Vec Y) 557c4762a1bSJed Brown { 558c4762a1bSJed Brown AppCtx *user; 559c4762a1bSJed Brown PetscInt its,i; 560c4762a1bSJed Brown 561c4762a1bSJed Brown PetscFunctionBegin; 5625f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellGetContext(J_shell,&user)); 563c4762a1bSJed Brown 5645f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(X,user->yi,user->yi_scatter,user->nt)); 565c4762a1bSJed Brown 566c4762a1bSJed Brown i = user->nt - 1; 5675f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSolve(user->solver,user->yi[i],user->yiwork[i])); 568c4762a1bSJed Brown 5695f80ce2aSJacob Faibussowitsch CHKERRQ(KSPGetIterationNumber(user->solver,&its)); 570c4762a1bSJed Brown user->ksp_its = user->ksp_its + its; 571c4762a1bSJed Brown 572c4762a1bSJed Brown for (i=user->nt-2; i>=0; i--) { 5735f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->yi[i],1.0,user->yiwork[i+1])); 5745f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSolve(user->solver,user->yi[i],user->yiwork[i])); 575c4762a1bSJed Brown 5765f80ce2aSJacob Faibussowitsch CHKERRQ(KSPGetIterationNumber(user->solver,&its)); 577c4762a1bSJed Brown user->ksp_its = user->ksp_its + its; 578c4762a1bSJed Brown 579c4762a1bSJed Brown } 580c4762a1bSJed Brown 5815f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(Y,user->yiwork,user->yi_scatter,user->nt)); 582c4762a1bSJed Brown PetscFunctionReturn(0); 583c4762a1bSJed Brown } 584c4762a1bSJed Brown 585c4762a1bSJed Brown PetscErrorCode StateMatDuplicate(Mat J_shell, MatDuplicateOption opt, Mat *new_shell) 586c4762a1bSJed Brown { 587c4762a1bSJed Brown AppCtx *user; 588c4762a1bSJed Brown 589c4762a1bSJed Brown PetscFunctionBegin; 5905f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellGetContext(J_shell,&user)); 591c4762a1bSJed Brown 5925f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m,user->m,user,new_shell)); 5935f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(*new_shell,MATOP_MULT,(void(*)(void))StateMatMult)); 5945f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(*new_shell,MATOP_DUPLICATE,(void(*)(void))StateMatDuplicate)); 5955f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(*new_shell,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatMultTranspose)); 5965f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(*new_shell,MATOP_GET_DIAGONAL,(void(*)(void))StateMatGetDiagonal)); 597c4762a1bSJed Brown PetscFunctionReturn(0); 598c4762a1bSJed Brown } 599c4762a1bSJed Brown 600c4762a1bSJed Brown PetscErrorCode StateMatGetDiagonal(Mat J_shell, Vec X) 601c4762a1bSJed Brown { 602c4762a1bSJed Brown AppCtx *user; 603c4762a1bSJed Brown 604c4762a1bSJed Brown PetscFunctionBegin; 6055f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellGetContext(J_shell,&user)); 6065f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(user->js_diag,X)); 607c4762a1bSJed Brown PetscFunctionReturn(0); 608c4762a1bSJed Brown 609c4762a1bSJed Brown } 610c4762a1bSJed Brown 611c4762a1bSJed Brown PetscErrorCode FormConstraints(Tao tao, Vec X, Vec C, void *ptr) 612c4762a1bSJed Brown { 613c4762a1bSJed Brown /* con = Ay - q, A = [B 0 0 ... 0; 614c4762a1bSJed Brown -I B 0 ... 0; 615c4762a1bSJed Brown 0 -I B ... 0; 616c4762a1bSJed Brown ... ; 617c4762a1bSJed Brown 0 ... -I B] 618c4762a1bSJed Brown B = ht * Div * Sigma * Grad + eye */ 619c4762a1bSJed Brown PetscInt i; 620c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 621c4762a1bSJed Brown 622c4762a1bSJed Brown PetscFunctionBegin; 6235f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter(X,user->y,user->state_scatter,user->u,user->design_scatter)); 6245f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->y,user->yi,user->yi_scatter,user->nt)); 6255f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->JsBlock,user->yi[0],user->yiwork[0])); 626c4762a1bSJed Brown for (i=1; i<user->nt; i++) { 6275f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->JsBlock,user->yi[i],user->yiwork[i])); 6285f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->yiwork[i],-1.0,user->yi[i-1])); 629c4762a1bSJed Brown } 6305f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(C,user->yiwork,user->yi_scatter,user->nt)); 6315f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(C,-1.0,user->q)); 632c4762a1bSJed Brown PetscFunctionReturn(0); 633c4762a1bSJed Brown } 634c4762a1bSJed Brown 635c4762a1bSJed Brown PetscErrorCode Scatter(Vec x, Vec state, VecScatter s_scat, Vec design, VecScatter d_scat) 636c4762a1bSJed Brown { 637c4762a1bSJed Brown PetscFunctionBegin; 6385f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(s_scat,x,state,INSERT_VALUES,SCATTER_FORWARD)); 6395f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd(s_scat,x,state,INSERT_VALUES,SCATTER_FORWARD)); 6405f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(d_scat,x,design,INSERT_VALUES,SCATTER_FORWARD)); 6415f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd(d_scat,x,design,INSERT_VALUES,SCATTER_FORWARD)); 642c4762a1bSJed Brown PetscFunctionReturn(0); 643c4762a1bSJed Brown } 644c4762a1bSJed Brown 645c4762a1bSJed Brown PetscErrorCode Scatter_i(Vec y, Vec *yi, VecScatter *scat, PetscInt nt) 646c4762a1bSJed Brown { 647c4762a1bSJed Brown PetscInt i; 648c4762a1bSJed Brown 649c4762a1bSJed Brown PetscFunctionBegin; 650c4762a1bSJed Brown for (i=0; i<nt; i++) { 6515f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(scat[i],y,yi[i],INSERT_VALUES,SCATTER_FORWARD)); 6525f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd(scat[i],y,yi[i],INSERT_VALUES,SCATTER_FORWARD)); 653c4762a1bSJed Brown } 654c4762a1bSJed Brown PetscFunctionReturn(0); 655c4762a1bSJed Brown } 656c4762a1bSJed Brown 657c4762a1bSJed Brown PetscErrorCode Gather(Vec x, Vec state, VecScatter s_scat, Vec design, VecScatter d_scat) 658c4762a1bSJed Brown { 659c4762a1bSJed Brown PetscFunctionBegin; 6605f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(s_scat,state,x,INSERT_VALUES,SCATTER_REVERSE)); 6615f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd(s_scat,state,x,INSERT_VALUES,SCATTER_REVERSE)); 6625f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(d_scat,design,x,INSERT_VALUES,SCATTER_REVERSE)); 6635f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd(d_scat,design,x,INSERT_VALUES,SCATTER_REVERSE)); 664c4762a1bSJed Brown PetscFunctionReturn(0); 665c4762a1bSJed Brown } 666c4762a1bSJed Brown 667c4762a1bSJed Brown PetscErrorCode Gather_i(Vec y, Vec *yi, VecScatter *scat, PetscInt nt) 668c4762a1bSJed Brown { 669c4762a1bSJed Brown PetscInt i; 670c4762a1bSJed Brown 671c4762a1bSJed Brown PetscFunctionBegin; 672c4762a1bSJed Brown for (i=0; i<nt; i++) { 6735f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(scat[i],yi[i],y,INSERT_VALUES,SCATTER_REVERSE)); 6745f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd(scat[i],yi[i],y,INSERT_VALUES,SCATTER_REVERSE)); 675c4762a1bSJed Brown } 676c4762a1bSJed Brown PetscFunctionReturn(0); 677c4762a1bSJed Brown } 678c4762a1bSJed Brown 679c4762a1bSJed Brown PetscErrorCode ParabolicInitialize(AppCtx *user) 680c4762a1bSJed Brown { 681c4762a1bSJed Brown PetscInt m,n,i,j,k,linear_index,istart,iend,iblock,lo,hi,lo2,hi2; 682c4762a1bSJed Brown Vec XX,YY,ZZ,XXwork,YYwork,ZZwork,UTwork,yi,di,bc; 683c4762a1bSJed Brown PetscReal *x, *y, *z; 684c4762a1bSJed Brown PetscReal h,stime; 685c4762a1bSJed Brown PetscScalar hinv,neg_hinv,half = 0.5,sqrt_beta; 686c4762a1bSJed Brown PetscInt im,indx1,indx2,indy1,indy2,indz1,indz2,nx,ny,nz; 687c4762a1bSJed Brown PetscReal xri,yri,zri,xim,yim,zim,dx1,dx2,dy1,dy2,dz1,dz2,Dx,Dy,Dz; 688c4762a1bSJed Brown PetscScalar v,vx,vy,vz; 689c4762a1bSJed Brown IS is_from_y,is_to_yi,is_from_d,is_to_di; 690c4762a1bSJed Brown /* Data locations */ 691c4762a1bSJed Brown PetscScalar xr[64] = {0.4970, 0.8498, 0.7814, 0.6268, 0.7782, 0.6402, 0.3617, 0.3160, 692c4762a1bSJed Brown 0.3610, 0.5298, 0.6987, 0.3331, 0.7962, 0.5596, 0.3866, 0.6774, 693c4762a1bSJed Brown 0.5407, 0.4518, 0.6702, 0.6061, 0.7580, 0.8997, 0.5198, 0.8326, 694c4762a1bSJed Brown 0.2138, 0.9198, 0.3000, 0.2833, 0.8288, 0.7076, 0.1820, 0.0728, 695c4762a1bSJed Brown 0.8447, 0.2367, 0.3239, 0.6413, 0.3114, 0.4731, 0.1192, 0.9273, 696c4762a1bSJed Brown 0.5724, 0.4331, 0.5136, 0.3547, 0.4413, 0.2602, 0.5698, 0.7278, 697c4762a1bSJed Brown 0.5261, 0.6230, 0.2454, 0.3948, 0.7479, 0.6582, 0.4660, 0.5594, 698c4762a1bSJed Brown 0.7574, 0.1143, 0.5900, 0.1065, 0.4260, 0.3294, 0.8276, 0.0756}; 699c4762a1bSJed Brown 700c4762a1bSJed Brown PetscScalar yr[64] = {0.7345, 0.9120, 0.9288, 0.7528, 0.4463, 0.4985, 0.2497, 0.6256, 701c4762a1bSJed Brown 0.3425, 0.9026, 0.6983, 0.4230, 0.7140, 0.2970, 0.4474, 0.8792, 702c4762a1bSJed Brown 0.6604, 0.2485, 0.7968, 0.6127, 0.1796, 0.2437, 0.5938, 0.6137, 703c4762a1bSJed Brown 0.3867, 0.5658, 0.4575, 0.1009, 0.0863, 0.3361, 0.0738, 0.3985, 704c4762a1bSJed Brown 0.6602, 0.1437, 0.0934, 0.5983, 0.5950, 0.0763, 0.0768, 0.2288, 705c4762a1bSJed Brown 0.5761, 0.1129, 0.3841, 0.6150, 0.6904, 0.6686, 0.1361, 0.4601, 706c4762a1bSJed Brown 0.4491, 0.3716, 0.1969, 0.6537, 0.6743, 0.6991, 0.4811, 0.5480, 707c4762a1bSJed Brown 0.1684, 0.4569, 0.6889, 0.8437, 0.3015, 0.2854, 0.8199, 0.2658}; 708c4762a1bSJed Brown 709c4762a1bSJed Brown PetscScalar zr[64] = {0.7668, 0.8573, 0.2654, 0.2719, 0.1060, 0.1311, 0.6232, 0.2295, 710c4762a1bSJed Brown 0.8009, 0.2147, 0.2119, 0.9325, 0.4473, 0.3600, 0.3374, 0.3819, 711c4762a1bSJed Brown 0.4066, 0.5801, 0.1673, 0.0959, 0.4638, 0.8236, 0.8800, 0.2939, 712c4762a1bSJed Brown 0.2028, 0.8262, 0.2706, 0.6276, 0.9085, 0.6443, 0.8241, 0.0712, 713c4762a1bSJed Brown 0.1824, 0.7789, 0.4389, 0.8415, 0.7055, 0.6639, 0.3653, 0.2078, 714c4762a1bSJed Brown 0.1987, 0.2297, 0.4321, 0.8115, 0.4915, 0.7764, 0.4657, 0.4627, 715c4762a1bSJed Brown 0.4569, 0.4232, 0.8514, 0.0674, 0.3227, 0.1055, 0.6690, 0.6313, 716c4762a1bSJed Brown 0.9226, 0.5461, 0.4126, 0.2364, 0.6096, 0.7042, 0.3914, 0.0711}; 717c4762a1bSJed Brown 718c4762a1bSJed Brown PetscFunctionBegin; 7195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(user->mx,&x)); 7205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(user->mx,&y)); 7215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(user->mx,&z)); 722c4762a1bSJed Brown user->jformed = PETSC_FALSE; 723c4762a1bSJed Brown user->dsg_formed = PETSC_FALSE; 724c4762a1bSJed Brown 725c4762a1bSJed Brown n = user->mx * user->mx * user->mx; 726c4762a1bSJed Brown m = 3 * user->mx * user->mx * (user->mx-1); 727c4762a1bSJed Brown sqrt_beta = PetscSqrtScalar(user->beta); 728c4762a1bSJed Brown 729c4762a1bSJed Brown user->ksp_its = 0; 730c4762a1bSJed Brown user->ksp_its_initial = 0; 731c4762a1bSJed Brown 732c4762a1bSJed Brown stime = (PetscReal)user->nt/user->ns; 7335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(user->ns,&user->sample_times)); 734c4762a1bSJed Brown for (i=0; i<user->ns; i++) { 735c4762a1bSJed Brown user->sample_times[i] = (PetscInt)(stime*((PetscReal)i+1.0)-0.5); 736c4762a1bSJed Brown } 737c4762a1bSJed Brown 7385f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&XX)); 7395f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&user->q)); 7405f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(XX,PETSC_DECIDE,n)); 7415f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(user->q,PETSC_DECIDE,n*user->nt)); 7425f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(XX)); 7435f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(user->q)); 744c4762a1bSJed Brown 7455f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(XX,&YY)); 7465f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(XX,&ZZ)); 7475f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(XX,&XXwork)); 7485f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(XX,&YYwork)); 7495f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(XX,&ZZwork)); 7505f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(XX,&UTwork)); 7515f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(XX,&user->utrue)); 7525f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(XX,&bc)); 753c4762a1bSJed Brown 754c4762a1bSJed Brown /* Generate 3D grid, and collect ns (1<=ns<=8) right-hand-side vectors into user->q */ 755c4762a1bSJed Brown h = 1.0/user->mx; 756c4762a1bSJed Brown hinv = user->mx; 757c4762a1bSJed Brown neg_hinv = -hinv; 758c4762a1bSJed Brown 7595f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetOwnershipRange(XX,&istart,&iend)); 760c4762a1bSJed Brown for (linear_index=istart; linear_index<iend; linear_index++) { 761c4762a1bSJed Brown i = linear_index % user->mx; 762c4762a1bSJed Brown j = ((linear_index-i)/user->mx) % user->mx; 763c4762a1bSJed Brown k = ((linear_index-i)/user->mx-j) / user->mx; 764c4762a1bSJed Brown vx = h*(i+0.5); 765c4762a1bSJed Brown vy = h*(j+0.5); 766c4762a1bSJed Brown vz = h*(k+0.5); 7675f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetValues(XX,1,&linear_index,&vx,INSERT_VALUES)); 7685f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetValues(YY,1,&linear_index,&vy,INSERT_VALUES)); 7695f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetValues(ZZ,1,&linear_index,&vz,INSERT_VALUES)); 770c4762a1bSJed Brown if ((vx<0.6) && (vx>0.4) && (vy<0.6) && (vy>0.4) && (vy<0.6) && (vz<0.6) && (vz>0.4)) { 771c4762a1bSJed Brown v = 1000.0; 7725f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetValues(bc,1,&linear_index,&v,INSERT_VALUES)); 773c4762a1bSJed Brown } 774c4762a1bSJed Brown } 775c4762a1bSJed Brown 7765f80ce2aSJacob Faibussowitsch CHKERRQ(VecAssemblyBegin(XX)); 7775f80ce2aSJacob Faibussowitsch CHKERRQ(VecAssemblyEnd(XX)); 7785f80ce2aSJacob Faibussowitsch CHKERRQ(VecAssemblyBegin(YY)); 7795f80ce2aSJacob Faibussowitsch CHKERRQ(VecAssemblyEnd(YY)); 7805f80ce2aSJacob Faibussowitsch CHKERRQ(VecAssemblyBegin(ZZ)); 7815f80ce2aSJacob Faibussowitsch CHKERRQ(VecAssemblyEnd(ZZ)); 7825f80ce2aSJacob Faibussowitsch CHKERRQ(VecAssemblyBegin(bc)); 7835f80ce2aSJacob Faibussowitsch CHKERRQ(VecAssemblyEnd(bc)); 784c4762a1bSJed Brown 785c4762a1bSJed Brown /* Compute true parameter function 786c4762a1bSJed Brown ut = 0.5 + exp(-10*((x-0.5)^2+(y-0.5)^2+(z-0.5)^2)) */ 7875f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(XX,XXwork)); 7885f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(YY,YYwork)); 7895f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(ZZ,ZZwork)); 790c4762a1bSJed Brown 7915f80ce2aSJacob Faibussowitsch CHKERRQ(VecShift(XXwork,-0.5)); 7925f80ce2aSJacob Faibussowitsch CHKERRQ(VecShift(YYwork,-0.5)); 7935f80ce2aSJacob Faibussowitsch CHKERRQ(VecShift(ZZwork,-0.5)); 794c4762a1bSJed Brown 7955f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(XXwork,XXwork,XXwork)); 7965f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(YYwork,YYwork,YYwork)); 7975f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(ZZwork,ZZwork,ZZwork)); 798c4762a1bSJed Brown 7995f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(XXwork,user->utrue)); 8005f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->utrue,1.0,YYwork)); 8015f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->utrue,1.0,ZZwork)); 8025f80ce2aSJacob Faibussowitsch CHKERRQ(VecScale(user->utrue,-10.0)); 8035f80ce2aSJacob Faibussowitsch CHKERRQ(VecExp(user->utrue)); 8045f80ce2aSJacob Faibussowitsch CHKERRQ(VecShift(user->utrue,0.5)); 805c4762a1bSJed Brown 8065f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&XX)); 8075f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&YY)); 8085f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&ZZ)); 8095f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&XXwork)); 8105f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&YYwork)); 8115f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&ZZwork)); 8125f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&UTwork)); 813c4762a1bSJed Brown 814c4762a1bSJed Brown /* Initial guess and reference model */ 8155f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->utrue,&user->ur)); 8165f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->ur,0.0)); 817c4762a1bSJed Brown 818c4762a1bSJed Brown /* Generate Grad matrix */ 8195f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PETSC_COMM_WORLD,&user->Grad)); 8205f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(user->Grad,PETSC_DECIDE,PETSC_DECIDE,m,n)); 8215f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetFromOptions(user->Grad)); 8225f80ce2aSJacob Faibussowitsch CHKERRQ(MatMPIAIJSetPreallocation(user->Grad,2,NULL,2,NULL)); 8235f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation(user->Grad,2,NULL)); 8245f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetOwnershipRange(user->Grad,&istart,&iend)); 825c4762a1bSJed Brown 826c4762a1bSJed Brown for (i=istart; i<iend; i++) { 827c4762a1bSJed Brown if (i<m/3) { 828c4762a1bSJed Brown iblock = i / (user->mx-1); 829c4762a1bSJed Brown j = iblock*user->mx + (i % (user->mx-1)); 8305f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Grad,1,&i,1,&j,&neg_hinv,INSERT_VALUES)); 831c4762a1bSJed Brown j = j+1; 8325f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Grad,1,&i,1,&j,&hinv,INSERT_VALUES)); 833c4762a1bSJed Brown } 834c4762a1bSJed Brown if (i>=m/3 && i<2*m/3) { 835c4762a1bSJed Brown iblock = (i-m/3) / (user->mx*(user->mx-1)); 836c4762a1bSJed Brown j = iblock*user->mx*user->mx + ((i-m/3) % (user->mx*(user->mx-1))); 8375f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Grad,1,&i,1,&j,&neg_hinv,INSERT_VALUES)); 838c4762a1bSJed Brown j = j + user->mx; 8395f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Grad,1,&i,1,&j,&hinv,INSERT_VALUES)); 840c4762a1bSJed Brown } 841c4762a1bSJed Brown if (i>=2*m/3) { 842c4762a1bSJed Brown j = i-2*m/3; 8435f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Grad,1,&i,1,&j,&neg_hinv,INSERT_VALUES)); 844c4762a1bSJed Brown j = j + user->mx*user->mx; 8455f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Grad,1,&i,1,&j,&hinv,INSERT_VALUES)); 846c4762a1bSJed Brown } 847c4762a1bSJed Brown } 848c4762a1bSJed Brown 8495f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(user->Grad,MAT_FINAL_ASSEMBLY)); 8505f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(user->Grad,MAT_FINAL_ASSEMBLY)); 851c4762a1bSJed Brown 852c4762a1bSJed Brown /* Generate arithmetic averaging matrix Av */ 8535f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PETSC_COMM_WORLD,&user->Av)); 8545f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(user->Av,PETSC_DECIDE,PETSC_DECIDE,m,n)); 8555f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetFromOptions(user->Av)); 8565f80ce2aSJacob Faibussowitsch CHKERRQ(MatMPIAIJSetPreallocation(user->Av,2,NULL,2,NULL)); 8575f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation(user->Av,2,NULL)); 8585f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetOwnershipRange(user->Av,&istart,&iend)); 859c4762a1bSJed Brown 860c4762a1bSJed Brown for (i=istart; i<iend; i++) { 861c4762a1bSJed Brown if (i<m/3) { 862c4762a1bSJed Brown iblock = i / (user->mx-1); 863c4762a1bSJed Brown j = iblock*user->mx + (i % (user->mx-1)); 8645f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Av,1,&i,1,&j,&half,INSERT_VALUES)); 865c4762a1bSJed Brown j = j+1; 8665f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Av,1,&i,1,&j,&half,INSERT_VALUES)); 867c4762a1bSJed Brown } 868c4762a1bSJed Brown if (i>=m/3 && i<2*m/3) { 869c4762a1bSJed Brown iblock = (i-m/3) / (user->mx*(user->mx-1)); 870c4762a1bSJed Brown j = iblock*user->mx*user->mx + ((i-m/3) % (user->mx*(user->mx-1))); 8715f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Av,1,&i,1,&j,&half,INSERT_VALUES)); 872c4762a1bSJed Brown j = j + user->mx; 8735f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Av,1,&i,1,&j,&half,INSERT_VALUES)); 874c4762a1bSJed Brown } 875c4762a1bSJed Brown if (i>=2*m/3) { 876c4762a1bSJed Brown j = i-2*m/3; 8775f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Av,1,&i,1,&j,&half,INSERT_VALUES)); 878c4762a1bSJed Brown j = j + user->mx*user->mx; 8795f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Av,1,&i,1,&j,&half,INSERT_VALUES)); 880c4762a1bSJed Brown } 881c4762a1bSJed Brown } 882c4762a1bSJed Brown 8835f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(user->Av,MAT_FINAL_ASSEMBLY)); 8845f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(user->Av,MAT_FINAL_ASSEMBLY)); 885c4762a1bSJed Brown 886c4762a1bSJed Brown /* Generate transpose of averaging matrix Av */ 8875f80ce2aSJacob Faibussowitsch CHKERRQ(MatTranspose(user->Av,MAT_INITIAL_MATRIX,&user->AvT)); 888c4762a1bSJed Brown 8895f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PETSC_COMM_WORLD,&user->L)); 8905f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(user->L,PETSC_DECIDE,PETSC_DECIDE,m+n,n)); 8915f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetFromOptions(user->L)); 8925f80ce2aSJacob Faibussowitsch CHKERRQ(MatMPIAIJSetPreallocation(user->L,2,NULL,2,NULL)); 8935f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation(user->L,2,NULL)); 8945f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetOwnershipRange(user->L,&istart,&iend)); 895c4762a1bSJed Brown 896c4762a1bSJed Brown for (i=istart; i<iend; i++) { 897c4762a1bSJed Brown if (i<m/3) { 898c4762a1bSJed Brown iblock = i / (user->mx-1); 899c4762a1bSJed Brown j = iblock*user->mx + (i % (user->mx-1)); 9005f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->L,1,&i,1,&j,&neg_hinv,INSERT_VALUES)); 901c4762a1bSJed Brown j = j+1; 9025f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->L,1,&i,1,&j,&hinv,INSERT_VALUES)); 903c4762a1bSJed Brown } 904c4762a1bSJed Brown if (i>=m/3 && i<2*m/3) { 905c4762a1bSJed Brown iblock = (i-m/3) / (user->mx*(user->mx-1)); 906c4762a1bSJed Brown j = iblock*user->mx*user->mx + ((i-m/3) % (user->mx*(user->mx-1))); 9075f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->L,1,&i,1,&j,&neg_hinv,INSERT_VALUES)); 908c4762a1bSJed Brown j = j + user->mx; 9095f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->L,1,&i,1,&j,&hinv,INSERT_VALUES)); 910c4762a1bSJed Brown } 911c4762a1bSJed Brown if (i>=2*m/3 && i<m) { 912c4762a1bSJed Brown j = i-2*m/3; 9135f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->L,1,&i,1,&j,&neg_hinv,INSERT_VALUES)); 914c4762a1bSJed Brown j = j + user->mx*user->mx; 9155f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->L,1,&i,1,&j,&hinv,INSERT_VALUES)); 916c4762a1bSJed Brown } 917c4762a1bSJed Brown if (i>=m) { 918c4762a1bSJed Brown j = i - m; 9195f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->L,1,&i,1,&j,&sqrt_beta,INSERT_VALUES)); 920c4762a1bSJed Brown } 921c4762a1bSJed Brown } 922c4762a1bSJed Brown 9235f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(user->L,MAT_FINAL_ASSEMBLY)); 9245f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(user->L,MAT_FINAL_ASSEMBLY)); 925c4762a1bSJed Brown 9265f80ce2aSJacob Faibussowitsch CHKERRQ(MatScale(user->L,PetscPowScalar(h,1.5))); 927c4762a1bSJed Brown 928c4762a1bSJed Brown /* Generate Div matrix */ 9295f80ce2aSJacob Faibussowitsch CHKERRQ(MatTranspose(user->Grad,MAT_INITIAL_MATRIX,&user->Div)); 930c4762a1bSJed Brown 931c4762a1bSJed Brown /* Build work vectors and matrices */ 9325f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&user->S)); 9335f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(user->S, PETSC_DECIDE, user->mx*user->mx*(user->mx-1)*3)); 9345f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(user->S)); 935c4762a1bSJed Brown 9365f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&user->lwork)); 9375f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(user->lwork,PETSC_DECIDE,m+user->mx*user->mx*user->mx)); 9385f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(user->lwork)); 939c4762a1bSJed Brown 9405f80ce2aSJacob Faibussowitsch CHKERRQ(MatDuplicate(user->Div,MAT_SHARE_NONZERO_PATTERN,&user->Divwork)); 9415f80ce2aSJacob Faibussowitsch CHKERRQ(MatDuplicate(user->Av,MAT_SHARE_NONZERO_PATTERN,&user->Avwork)); 942c4762a1bSJed Brown 9435f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&user->d)); 9445f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(user->d,PETSC_DECIDE,user->ndata*user->nt)); 9455f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(user->d)); 946c4762a1bSJed Brown 9475f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->S,&user->Swork)); 9485f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->S,&user->Av_u)); 9495f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->S,&user->Twork)); 9505f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->S,&user->Rwork)); 9515f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->y,&user->ywork)); 9525f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->u,&user->uwork)); 9535f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->u,&user->js_diag)); 9545f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->c,&user->cwork)); 9555f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(user->d,&user->dwork)); 956c4762a1bSJed Brown 957c4762a1bSJed Brown /* Create matrix-free shell user->Js for computing A*x */ 9585f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m*user->nt,user->m*user->nt,user,&user->Js)); 9595f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->Js,MATOP_MULT,(void(*)(void))StateMatMult)); 9605f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->Js,MATOP_DUPLICATE,(void(*)(void))StateMatDuplicate)); 9615f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->Js,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatMultTranspose)); 9625f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->Js,MATOP_GET_DIAGONAL,(void(*)(void))StateMatGetDiagonal)); 963c4762a1bSJed Brown 964c4762a1bSJed Brown /* Diagonal blocks of user->Js */ 9655f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m,user->m,user,&user->JsBlock)); 9665f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->JsBlock,MATOP_MULT,(void(*)(void))StateMatBlockMult)); 967c4762a1bSJed Brown /* Blocks are symmetric */ 9685f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->JsBlock,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatBlockMult)); 969c4762a1bSJed Brown 970c4762a1bSJed Brown /* Create a matrix-free shell user->JsBlockPrec for computing (U+D)\D*(L+D)\x, where JsBlock = L+D+U, 971c4762a1bSJed Brown D is diagonal, L is strictly lower triangular, and U is strictly upper triangular. 972c4762a1bSJed Brown This is an SSOR preconditioner for user->JsBlock. */ 9735f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m,user->m,user,&user->JsBlockPrec)); 9745f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->JsBlockPrec,MATOP_MULT,(void(*)(void))StateMatBlockPrecMult)); 975c4762a1bSJed Brown /* JsBlockPrec is symmetric */ 9765f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->JsBlockPrec,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatBlockPrecMult)); 9775f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetOption(user->JsBlockPrec,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 978c4762a1bSJed Brown 979c4762a1bSJed Brown /* Create a matrix-free shell user->Jd for computing B*x */ 9805f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m*user->nt,user->m,user,&user->Jd)); 9815f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->Jd,MATOP_MULT,(void(*)(void))DesignMatMult)); 9825f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->Jd,MATOP_MULT_TRANSPOSE,(void(*)(void))DesignMatMultTranspose)); 983c4762a1bSJed Brown 984c4762a1bSJed Brown /* User-defined routines for computing user->Js\x and user->Js^T\x*/ 9855f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateShell(PETSC_COMM_WORLD,PETSC_DETERMINE,PETSC_DETERMINE,user->m*user->nt,user->m*user->nt,user,&user->JsInv)); 9865f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->JsInv,MATOP_MULT,(void(*)(void))StateMatInvMult)); 9875f80ce2aSJacob Faibussowitsch CHKERRQ(MatShellSetOperation(user->JsInv,MATOP_MULT_TRANSPOSE,(void(*)(void))StateMatInvTransposeMult)); 988c4762a1bSJed Brown 989c4762a1bSJed Brown /* Solver options and tolerances */ 9905f80ce2aSJacob Faibussowitsch CHKERRQ(KSPCreate(PETSC_COMM_WORLD,&user->solver)); 9915f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetType(user->solver,KSPCG)); 9925f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetOperators(user->solver,user->JsBlock,user->JsBlockPrec)); 9935f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetInitialGuessNonzero(user->solver,PETSC_FALSE)); 9945f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetTolerances(user->solver,1e-4,1e-20,1e3,500)); 9955f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetFromOptions(user->solver)); 9965f80ce2aSJacob Faibussowitsch CHKERRQ(KSPGetPC(user->solver,&user->prec)); 9975f80ce2aSJacob Faibussowitsch CHKERRQ(PCSetType(user->prec,PCSHELL)); 998c4762a1bSJed Brown 9995f80ce2aSJacob Faibussowitsch CHKERRQ(PCShellSetApply(user->prec,StateMatBlockPrecMult)); 10005f80ce2aSJacob Faibussowitsch CHKERRQ(PCShellSetApplyTranspose(user->prec,StateMatBlockPrecMult)); 10015f80ce2aSJacob Faibussowitsch CHKERRQ(PCShellSetContext(user->prec,user)); 1002c4762a1bSJed Brown 1003c4762a1bSJed Brown /* Create scatter from y to y_1,y_2,...,y_nt */ 10045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(user->nt*user->m,&user->yi_scatter)); 10055f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&yi)); 10065f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(yi,PETSC_DECIDE,user->mx*user->mx*user->mx)); 10075f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(yi)); 10085f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicateVecs(yi,user->nt,&user->yi)); 10095f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicateVecs(yi,user->nt,&user->yiwork)); 1010c4762a1bSJed Brown 10115f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetOwnershipRange(user->y,&lo2,&hi2)); 1012c4762a1bSJed Brown istart = 0; 1013c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 10145f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetOwnershipRange(user->yi[i],&lo,&hi)); 10155f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_to_yi)); 10165f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateStride(PETSC_COMM_SELF,hi-lo,lo2+istart,1,&is_from_y)); 10175f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterCreate(user->y,is_from_y,user->yi[i],is_to_yi,&user->yi_scatter[i])); 1018c4762a1bSJed Brown istart = istart + hi-lo; 10195f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&is_to_yi)); 10205f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&is_from_y)); 1021c4762a1bSJed Brown } 10225f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&yi)); 1023c4762a1bSJed Brown 1024c4762a1bSJed Brown /* Create scatter from d to d_1,d_2,...,d_ns */ 10255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(user->ns*user->ndata,&user->di_scatter)); 10265f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&di)); 10275f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(di,PETSC_DECIDE,user->ndata)); 10285f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(di)); 10295f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicateVecs(di,user->ns,&user->di)); 10305f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetOwnershipRange(user->d,&lo2,&hi2)); 1031c4762a1bSJed Brown istart = 0; 1032c4762a1bSJed Brown for (i=0; i<user->ns; i++) { 10335f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetOwnershipRange(user->di[i],&lo,&hi)); 10345f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateStride(PETSC_COMM_SELF,hi-lo,lo,1,&is_to_di)); 10355f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateStride(PETSC_COMM_SELF,hi-lo,lo2+istart,1,&is_from_d)); 10365f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterCreate(user->d,is_from_d,user->di[i],is_to_di,&user->di_scatter[i])); 1037c4762a1bSJed Brown istart = istart + hi-lo; 10385f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&is_to_di)); 10395f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&is_from_d)); 1040c4762a1bSJed Brown } 10415f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&di)); 1042c4762a1bSJed Brown 1043c4762a1bSJed Brown /* Assemble RHS of forward problem */ 10445f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(bc,user->yiwork[0])); 1045c4762a1bSJed Brown for (i=1; i<user->nt; i++) { 10465f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->yiwork[i],0.0)); 1047c4762a1bSJed Brown } 10485f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(user->q,user->yiwork,user->yi_scatter,user->nt)); 10495f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&bc)); 1050c4762a1bSJed Brown 1051c4762a1bSJed Brown /* Compute true state function yt given ut */ 10525f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&user->ytrue)); 10535f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(user->ytrue,PETSC_DECIDE,n*user->nt)); 10545f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(user->ytrue)); 1055c4762a1bSJed Brown 1056c4762a1bSJed Brown /* First compute Av_u = Av*exp(-u) */ 10575f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->uwork,0)); 10585f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->uwork,-1.0,user->utrue)); /* Note: user->utrue */ 10595f80ce2aSJacob Faibussowitsch CHKERRQ(VecExp(user->uwork)); 10605f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Av,user->uwork,user->Av_u)); 1061c4762a1bSJed Brown 1062c20d7725SJed Brown /* Symbolic DSG = Div * Grad */ 10635f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductCreate(user->Div,user->Grad,NULL,&user->DSG)); 10645f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductSetType(user->DSG,MATPRODUCT_AB)); 10655f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductSetAlgorithm(user->DSG,"default")); 10665f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductSetFill(user->DSG,PETSC_DEFAULT)); 10675f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductSetFromOptions(user->DSG)); 10685f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductSymbolic(user->DSG)); 1069c20d7725SJed Brown 1070c4762a1bSJed Brown user->dsg_formed = PETSC_TRUE; 1071c4762a1bSJed Brown 1072c20d7725SJed Brown /* Next form DSG = Div*Grad */ 10735f80ce2aSJacob Faibussowitsch CHKERRQ(MatCopy(user->Div,user->Divwork,SAME_NONZERO_PATTERN)); 10745f80ce2aSJacob Faibussowitsch CHKERRQ(MatDiagonalScale(user->Divwork,NULL,user->Av_u)); 1075c4762a1bSJed Brown if (user->dsg_formed) { 10765f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductNumeric(user->DSG)); 1077c4762a1bSJed Brown } else { 10785f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMult(user->Div,user->Grad,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&user->DSG)); 1079c4762a1bSJed Brown user->dsg_formed = PETSC_TRUE; 1080c4762a1bSJed Brown } 1081c4762a1bSJed Brown /* B = speye(nx^3) + ht*DSG; */ 10825f80ce2aSJacob Faibussowitsch CHKERRQ(MatScale(user->DSG,user->ht)); 10835f80ce2aSJacob Faibussowitsch CHKERRQ(MatShift(user->DSG,1.0)); 1084c4762a1bSJed Brown 1085c4762a1bSJed Brown /* Now solve for ytrue */ 10865f80ce2aSJacob Faibussowitsch CHKERRQ(StateMatInvMult(user->Js,user->q,user->ytrue)); 1087c4762a1bSJed Brown 1088c4762a1bSJed Brown /* Initial guess y0 for state given u0 */ 1089c4762a1bSJed Brown 1090c4762a1bSJed Brown /* First compute Av_u = Av*exp(-u) */ 10915f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->uwork,0)); 10925f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->uwork,-1.0,user->u)); /* Note: user->u */ 10935f80ce2aSJacob Faibussowitsch CHKERRQ(VecExp(user->uwork)); 10945f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Av,user->uwork,user->Av_u)); 1095c4762a1bSJed Brown 1096c4762a1bSJed Brown /* Next form DSG = Div*S*Grad */ 10975f80ce2aSJacob Faibussowitsch CHKERRQ(MatCopy(user->Div,user->Divwork,SAME_NONZERO_PATTERN)); 10985f80ce2aSJacob Faibussowitsch CHKERRQ(MatDiagonalScale(user->Divwork,NULL,user->Av_u)); 1099c4762a1bSJed Brown if (user->dsg_formed) { 11005f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductNumeric(user->DSG)); 1101c4762a1bSJed Brown } else { 11025f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMult(user->Div,user->Grad,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&user->DSG)); 1103c20d7725SJed Brown 1104c4762a1bSJed Brown user->dsg_formed = PETSC_TRUE; 1105c4762a1bSJed Brown } 1106c4762a1bSJed Brown /* B = speye(nx^3) + ht*DSG; */ 11075f80ce2aSJacob Faibussowitsch CHKERRQ(MatScale(user->DSG,user->ht)); 11085f80ce2aSJacob Faibussowitsch CHKERRQ(MatShift(user->DSG,1.0)); 1109c4762a1bSJed Brown 1110c4762a1bSJed Brown /* Now solve for y */ 11115f80ce2aSJacob Faibussowitsch CHKERRQ(StateMatInvMult(user->Js,user->q,user->y)); 1112c4762a1bSJed Brown 1113c4762a1bSJed Brown /* Construct projection matrix Q, a block diagonal matrix consisting of nt copies of Qblock along the diagonal */ 11145f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PETSC_COMM_WORLD,&user->Qblock)); 11155f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(user->Qblock,PETSC_DECIDE,PETSC_DECIDE,user->ndata,n)); 11165f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetFromOptions(user->Qblock)); 11175f80ce2aSJacob Faibussowitsch CHKERRQ(MatMPIAIJSetPreallocation(user->Qblock,8,NULL,8,NULL)); 11185f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation(user->Qblock,8,NULL)); 1119c4762a1bSJed Brown 1120c4762a1bSJed Brown for (i=0; i<user->mx; i++) { 1121c4762a1bSJed Brown x[i] = h*(i+0.5); 1122c4762a1bSJed Brown y[i] = h*(i+0.5); 1123c4762a1bSJed Brown z[i] = h*(i+0.5); 1124c4762a1bSJed Brown } 1125c4762a1bSJed Brown 11265f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetOwnershipRange(user->Qblock,&istart,&iend)); 1127c4762a1bSJed Brown nx = user->mx; ny = user->mx; nz = user->mx; 1128c4762a1bSJed Brown for (i=istart; i<iend; i++) { 1129c4762a1bSJed Brown xri = xr[i]; 1130c4762a1bSJed Brown im = 0; 1131c4762a1bSJed Brown xim = x[im]; 1132c4762a1bSJed Brown while (xri>xim && im<nx) { 1133c4762a1bSJed Brown im = im+1; 1134c4762a1bSJed Brown xim = x[im]; 1135c4762a1bSJed Brown } 1136c4762a1bSJed Brown indx1 = im-1; 1137c4762a1bSJed Brown indx2 = im; 1138c4762a1bSJed Brown dx1 = xri - x[indx1]; 1139c4762a1bSJed Brown dx2 = x[indx2] - xri; 1140c4762a1bSJed Brown 1141c4762a1bSJed Brown yri = yr[i]; 1142c4762a1bSJed Brown im = 0; 1143c4762a1bSJed Brown yim = y[im]; 1144c4762a1bSJed Brown while (yri>yim && im<ny) { 1145c4762a1bSJed Brown im = im+1; 1146c4762a1bSJed Brown yim = y[im]; 1147c4762a1bSJed Brown } 1148c4762a1bSJed Brown indy1 = im-1; 1149c4762a1bSJed Brown indy2 = im; 1150c4762a1bSJed Brown dy1 = yri - y[indy1]; 1151c4762a1bSJed Brown dy2 = y[indy2] - yri; 1152c4762a1bSJed Brown 1153c4762a1bSJed Brown zri = zr[i]; 1154c4762a1bSJed Brown im = 0; 1155c4762a1bSJed Brown zim = z[im]; 1156c4762a1bSJed Brown while (zri>zim && im<nz) { 1157c4762a1bSJed Brown im = im+1; 1158c4762a1bSJed Brown zim = z[im]; 1159c4762a1bSJed Brown } 1160c4762a1bSJed Brown indz1 = im-1; 1161c4762a1bSJed Brown indz2 = im; 1162c4762a1bSJed Brown dz1 = zri - z[indz1]; 1163c4762a1bSJed Brown dz2 = z[indz2] - zri; 1164c4762a1bSJed Brown 1165c4762a1bSJed Brown Dx = x[indx2] - x[indx1]; 1166c4762a1bSJed Brown Dy = y[indy2] - y[indy1]; 1167c4762a1bSJed Brown Dz = z[indz2] - z[indz1]; 1168c4762a1bSJed Brown 1169c4762a1bSJed Brown j = indx1 + indy1*nx + indz1*nx*ny; 1170c4762a1bSJed Brown v = (1-dx1/Dx)*(1-dy1/Dy)*(1-dz1/Dz); 11715f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Qblock,1,&i,1,&j,&v,INSERT_VALUES)); 1172c4762a1bSJed Brown 1173c4762a1bSJed Brown j = indx1 + indy1*nx + indz2*nx*ny; 1174c4762a1bSJed Brown v = (1-dx1/Dx)*(1-dy1/Dy)*(1-dz2/Dz); 11755f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Qblock,1,&i,1,&j,&v,INSERT_VALUES)); 1176c4762a1bSJed Brown 1177c4762a1bSJed Brown j = indx1 + indy2*nx + indz1*nx*ny; 1178c4762a1bSJed Brown v = (1-dx1/Dx)*(1-dy2/Dy)*(1-dz1/Dz); 11795f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Qblock,1,&i,1,&j,&v,INSERT_VALUES)); 1180c4762a1bSJed Brown 1181c4762a1bSJed Brown j = indx1 + indy2*nx + indz2*nx*ny; 1182c4762a1bSJed Brown v = (1-dx1/Dx)*(1-dy2/Dy)*(1-dz2/Dz); 11835f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Qblock,1,&i,1,&j,&v,INSERT_VALUES)); 1184c4762a1bSJed Brown 1185c4762a1bSJed Brown j = indx2 + indy1*nx + indz1*nx*ny; 1186c4762a1bSJed Brown v = (1-dx2/Dx)*(1-dy1/Dy)*(1-dz1/Dz); 11875f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Qblock,1,&i,1,&j,&v,INSERT_VALUES)); 1188c4762a1bSJed Brown 1189c4762a1bSJed Brown j = indx2 + indy1*nx + indz2*nx*ny; 1190c4762a1bSJed Brown v = (1-dx2/Dx)*(1-dy1/Dy)*(1-dz2/Dz); 11915f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Qblock,1,&i,1,&j,&v,INSERT_VALUES)); 1192c4762a1bSJed Brown 1193c4762a1bSJed Brown j = indx2 + indy2*nx + indz1*nx*ny; 1194c4762a1bSJed Brown v = (1-dx2/Dx)*(1-dy2/Dy)*(1-dz1/Dz); 11955f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Qblock,1,&i,1,&j,&v,INSERT_VALUES)); 1196c4762a1bSJed Brown 1197c4762a1bSJed Brown j = indx2 + indy2*nx + indz2*nx*ny; 1198c4762a1bSJed Brown v = (1-dx2/Dx)*(1-dy2/Dy)*(1-dz2/Dz); 11995f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(user->Qblock,1,&i,1,&j,&v,INSERT_VALUES)); 1200c4762a1bSJed Brown } 12015f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(user->Qblock,MAT_FINAL_ASSEMBLY)); 12025f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(user->Qblock,MAT_FINAL_ASSEMBLY)); 1203c4762a1bSJed Brown 12045f80ce2aSJacob Faibussowitsch CHKERRQ(MatTranspose(user->Qblock,MAT_INITIAL_MATRIX,&user->QblockT)); 12055f80ce2aSJacob Faibussowitsch CHKERRQ(MatTranspose(user->L,MAT_INITIAL_MATRIX,&user->LT)); 1206c4762a1bSJed Brown 1207c4762a1bSJed Brown /* Add noise to the measurement data */ 12085f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(user->ywork,1.0)); 12095f80ce2aSJacob Faibussowitsch CHKERRQ(VecAYPX(user->ywork,user->noise,user->ytrue)); 12105f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter_i(user->ywork,user->yiwork,user->yi_scatter,user->nt)); 1211c4762a1bSJed Brown for (j=0; j<user->ns; j++) { 1212c4762a1bSJed Brown i = user->sample_times[j]; 12135f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(user->Qblock,user->yiwork[i],user->di[j])); 1214c4762a1bSJed Brown } 12155f80ce2aSJacob Faibussowitsch CHKERRQ(Gather_i(user->d,user->di,user->di_scatter,user->ns)); 1216c4762a1bSJed Brown 1217c4762a1bSJed Brown /* Now that initial conditions have been set, let the user pass tolerance options to the KSP solver */ 12185f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetFromOptions(user->solver)); 12195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(x)); 12205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(y)); 12215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(z)); 1222c4762a1bSJed Brown PetscFunctionReturn(0); 1223c4762a1bSJed Brown } 1224c4762a1bSJed Brown 1225c4762a1bSJed Brown PetscErrorCode ParabolicDestroy(AppCtx *user) 1226c4762a1bSJed Brown { 1227c4762a1bSJed Brown PetscInt i; 1228c4762a1bSJed Brown 1229c4762a1bSJed Brown PetscFunctionBegin; 12305f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->Qblock)); 12315f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->QblockT)); 12325f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->Div)); 12335f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->Divwork)); 12345f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->Grad)); 12355f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->Av)); 12365f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->Avwork)); 12375f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->AvT)); 12385f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->DSG)); 12395f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->L)); 12405f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->LT)); 12415f80ce2aSJacob Faibussowitsch CHKERRQ(KSPDestroy(&user->solver)); 12425f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->Js)); 12435f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->Jd)); 12445f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->JsInv)); 12455f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->JsBlock)); 12465f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&user->JsBlockPrec)); 12475f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->u)); 12485f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->uwork)); 12495f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->utrue)); 12505f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->y)); 12515f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->ywork)); 12525f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->ytrue)); 12535f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroyVecs(user->nt,&user->yi)); 12545f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroyVecs(user->nt,&user->yiwork)); 12555f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroyVecs(user->ns,&user->di)); 12565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(user->yi)); 12575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(user->yiwork)); 12585f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(user->di)); 12595f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->c)); 12605f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->cwork)); 12615f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->ur)); 12625f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->q)); 12635f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->d)); 12645f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->dwork)); 12655f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->lwork)); 12665f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->S)); 12675f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->Swork)); 12685f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->Av_u)); 12695f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->Twork)); 12705f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->Rwork)); 12715f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&user->js_diag)); 12725f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&user->s_is)); 12735f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&user->d_is)); 12745f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterDestroy(&user->state_scatter)); 12755f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterDestroy(&user->design_scatter)); 1276c4762a1bSJed Brown for (i=0; i<user->nt; i++) { 12775f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterDestroy(&user->yi_scatter[i])); 1278c4762a1bSJed Brown } 1279c4762a1bSJed Brown for (i=0; i<user->ns; i++) { 12805f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterDestroy(&user->di_scatter[i])); 1281c4762a1bSJed Brown } 12825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(user->yi_scatter)); 12835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(user->di_scatter)); 12845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(user->sample_times)); 1285c4762a1bSJed Brown PetscFunctionReturn(0); 1286c4762a1bSJed Brown } 1287c4762a1bSJed Brown 1288c4762a1bSJed Brown PetscErrorCode ParabolicMonitor(Tao tao, void *ptr) 1289c4762a1bSJed Brown { 1290c4762a1bSJed Brown Vec X; 1291c4762a1bSJed Brown PetscReal unorm,ynorm; 1292c4762a1bSJed Brown AppCtx *user = (AppCtx*)ptr; 1293c4762a1bSJed Brown 1294c4762a1bSJed Brown PetscFunctionBegin; 12955f80ce2aSJacob Faibussowitsch CHKERRQ(TaoGetSolution(tao,&X)); 12965f80ce2aSJacob Faibussowitsch CHKERRQ(Scatter(X,user->ywork,user->state_scatter,user->uwork,user->design_scatter)); 12975f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->ywork,-1.0,user->ytrue)); 12985f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(user->uwork,-1.0,user->utrue)); 12995f80ce2aSJacob Faibussowitsch CHKERRQ(VecNorm(user->uwork,NORM_2,&unorm)); 13005f80ce2aSJacob Faibussowitsch CHKERRQ(VecNorm(user->ywork,NORM_2,&ynorm)); 13015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(MPI_COMM_WORLD, "||u-ut||=%g ||y-yt||=%g\n",(double)unorm,(double)ynorm)); 1302c4762a1bSJed Brown PetscFunctionReturn(0); 1303c4762a1bSJed Brown } 1304c4762a1bSJed Brown 1305c4762a1bSJed Brown /*TEST 1306c4762a1bSJed Brown 1307c4762a1bSJed Brown build: 1308c4762a1bSJed Brown requires: !complex 1309c4762a1bSJed Brown 1310c4762a1bSJed Brown test: 1311c4762a1bSJed Brown args: -tao_cmonitor -tao_type lcl -ns 1 -tao_gatol 1.e-4 -ksp_max_it 30 1312c4762a1bSJed Brown requires: !single 1313c4762a1bSJed Brown 1314c4762a1bSJed Brown TEST*/ 1315