1*55a74a43SLisandro Dalcin #include <petsc.h> 2*55a74a43SLisandro Dalcin 3*55a74a43SLisandro Dalcin EXTERN_C_BEGIN 4*55a74a43SLisandro Dalcin extern void formInitial(int*,int*,int*,double*, 5*55a74a43SLisandro Dalcin double*,double*); 6*55a74a43SLisandro Dalcin extern void formFunction(const int*,const int*,const int*,const double*, 7*55a74a43SLisandro Dalcin const double*,const double[],const double[],double[]); 8*55a74a43SLisandro Dalcin EXTERN_C_END 9*55a74a43SLisandro Dalcin 10*55a74a43SLisandro Dalcin typedef struct AppCtx { 11*55a74a43SLisandro Dalcin PetscInt nx,ny,nz; 12*55a74a43SLisandro Dalcin PetscScalar h[3]; 13*55a74a43SLisandro Dalcin } AppCtx; 14*55a74a43SLisandro Dalcin 15*55a74a43SLisandro Dalcin PetscErrorCode FormInitial(PetscReal t, Vec X, void *ctx) 16*55a74a43SLisandro Dalcin { 17*55a74a43SLisandro Dalcin PetscScalar *x; 18*55a74a43SLisandro Dalcin AppCtx *app = (AppCtx*) ctx; 19*55a74a43SLisandro Dalcin PetscFunctionBegin; 20*55a74a43SLisandro Dalcin PetscCall(VecGetArray(X,&x)); 21*55a74a43SLisandro Dalcin /**/ 22*55a74a43SLisandro Dalcin formInitial(&app->nx,&app->ny,&app->nz,app->h,&t,x); 23*55a74a43SLisandro Dalcin /**/ 24*55a74a43SLisandro Dalcin PetscCall(VecRestoreArray(X,&x)); 25*55a74a43SLisandro Dalcin PetscFunctionReturn(PETSC_SUCCESS); 26*55a74a43SLisandro Dalcin } 27*55a74a43SLisandro Dalcin 28*55a74a43SLisandro Dalcin PetscErrorCode FormFunction(TS ts, PetscReal t, Vec X, Vec Xdot,Vec F, void *ctx) 29*55a74a43SLisandro Dalcin { 30*55a74a43SLisandro Dalcin const PetscScalar *x; 31*55a74a43SLisandro Dalcin const PetscScalar *xdot; 32*55a74a43SLisandro Dalcin PetscScalar *f; 33*55a74a43SLisandro Dalcin AppCtx *app = (AppCtx*) ctx; 34*55a74a43SLisandro Dalcin PetscFunctionBegin; 35*55a74a43SLisandro Dalcin PetscCall(VecGetArrayRead(X,&x)); 36*55a74a43SLisandro Dalcin PetscCall(VecGetArrayRead(Xdot,&xdot)); 37*55a74a43SLisandro Dalcin PetscCall(VecGetArray(F,&f)); 38*55a74a43SLisandro Dalcin /**/ 39*55a74a43SLisandro Dalcin formFunction(&app->nx,&app->ny,&app->nz,app->h,&t,x,xdot,f); 40*55a74a43SLisandro Dalcin /**/ 41*55a74a43SLisandro Dalcin PetscCall(VecRestoreArrayRead(X,&x)); 42*55a74a43SLisandro Dalcin PetscCall(VecRestoreArrayRead(Xdot,&xdot)); 43*55a74a43SLisandro Dalcin PetscCall(VecRestoreArray(F,&f)); 44*55a74a43SLisandro Dalcin PetscFunctionReturn(PETSC_SUCCESS); 45*55a74a43SLisandro Dalcin } 46*55a74a43SLisandro Dalcin 47*55a74a43SLisandro Dalcin PetscErrorCode RunTest(int nx, int ny, int nz, int loops, double *wt) 48*55a74a43SLisandro Dalcin { 49*55a74a43SLisandro Dalcin Vec x,f; 50*55a74a43SLisandro Dalcin TS ts; 51*55a74a43SLisandro Dalcin AppCtx _app,*app=&_app; 52*55a74a43SLisandro Dalcin double t1,t2; 53*55a74a43SLisandro Dalcin PetscFunctionBegin; 54*55a74a43SLisandro Dalcin 55*55a74a43SLisandro Dalcin app->nx = nx; app->h[0] = 1./(nx-1); 56*55a74a43SLisandro Dalcin app->ny = ny; app->h[1] = 1./(ny-1); 57*55a74a43SLisandro Dalcin app->nz = nz; app->h[2] = 1./(nz-1); 58*55a74a43SLisandro Dalcin 59*55a74a43SLisandro Dalcin PetscCall(VecCreate(PETSC_COMM_SELF,&x)); 60*55a74a43SLisandro Dalcin PetscCall(VecSetSizes(x,nx*ny*nz,nx*ny*nz)); 61*55a74a43SLisandro Dalcin PetscCall(VecSetUp(x)); 62*55a74a43SLisandro Dalcin PetscCall(VecDuplicate(x,&f)); 63*55a74a43SLisandro Dalcin 64*55a74a43SLisandro Dalcin PetscCall(TSCreate(PETSC_COMM_SELF,&ts)); 65*55a74a43SLisandro Dalcin PetscCall(TSSetProblemType(ts,TS_NONLINEAR)); 66*55a74a43SLisandro Dalcin PetscCall(TSSetType(ts,TSTHETA)); 67*55a74a43SLisandro Dalcin PetscCall(TSThetaSetTheta(ts,1.0)); 68*55a74a43SLisandro Dalcin PetscCall(TSSetTimeStep(ts,0.01)); 69*55a74a43SLisandro Dalcin PetscCall(TSSetTime(ts,0.0)); 70*55a74a43SLisandro Dalcin PetscCall(TSSetMaxTime(ts,1.0)); 71*55a74a43SLisandro Dalcin PetscCall(TSSetMaxSteps(ts,10)); 72*55a74a43SLisandro Dalcin PetscCall(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER)); 73*55a74a43SLisandro Dalcin 74*55a74a43SLisandro Dalcin PetscCall(TSSetSolution(ts,x)); 75*55a74a43SLisandro Dalcin PetscCall(TSSetIFunction(ts,f,FormFunction,app)); 76*55a74a43SLisandro Dalcin PetscCall(PetscOptionsSetValue(NULL,"-snes_mf","1")); 77*55a74a43SLisandro Dalcin { 78*55a74a43SLisandro Dalcin SNES snes; 79*55a74a43SLisandro Dalcin KSP ksp; 80*55a74a43SLisandro Dalcin PetscCall(TSGetSNES(ts,&snes)); 81*55a74a43SLisandro Dalcin PetscCall(SNESGetKSP(snes,&ksp)); 82*55a74a43SLisandro Dalcin PetscCall(KSPSetType(ksp,KSPCG)); 83*55a74a43SLisandro Dalcin } 84*55a74a43SLisandro Dalcin PetscCall(TSSetFromOptions(ts)); 85*55a74a43SLisandro Dalcin PetscCall(TSSetUp(ts)); 86*55a74a43SLisandro Dalcin 87*55a74a43SLisandro Dalcin *wt = 1e300; 88*55a74a43SLisandro Dalcin while (loops-- > 0) { 89*55a74a43SLisandro Dalcin PetscCall(FormInitial(0.0,x,app)); 90*55a74a43SLisandro Dalcin PetscCall(PetscTime(&t1)); 91*55a74a43SLisandro Dalcin PetscCall(TSSolve(ts,x)); 92*55a74a43SLisandro Dalcin PetscCall(PetscTime(&t2)); 93*55a74a43SLisandro Dalcin *wt = PetscMin(*wt,t2-t1); 94*55a74a43SLisandro Dalcin } 95*55a74a43SLisandro Dalcin 96*55a74a43SLisandro Dalcin PetscCall(VecDestroy(&x)); 97*55a74a43SLisandro Dalcin PetscCall(VecDestroy(&f)); 98*55a74a43SLisandro Dalcin PetscCall(TSDestroy(&ts)); 99*55a74a43SLisandro Dalcin 100*55a74a43SLisandro Dalcin PetscFunctionReturn(PETSC_SUCCESS); 101*55a74a43SLisandro Dalcin } 102*55a74a43SLisandro Dalcin 103*55a74a43SLisandro Dalcin PetscErrorCode GetInt(const char* name, PetscInt *v, PetscInt defv) 104*55a74a43SLisandro Dalcin { 105*55a74a43SLisandro Dalcin PetscFunctionBegin; 106*55a74a43SLisandro Dalcin *v = defv; 107*55a74a43SLisandro Dalcin PetscCall(PetscOptionsGetInt(NULL,NULL,name,v,NULL)); 108*55a74a43SLisandro Dalcin PetscFunctionReturn(PETSC_SUCCESS); 109*55a74a43SLisandro Dalcin } 110*55a74a43SLisandro Dalcin 111*55a74a43SLisandro Dalcin int main(int argc, char *argv[]) 112*55a74a43SLisandro Dalcin { 113*55a74a43SLisandro Dalcin double wt; 114*55a74a43SLisandro Dalcin PetscInt n,start,step,stop,samples; 115*55a74a43SLisandro Dalcin 116*55a74a43SLisandro Dalcin PetscCall(PetscInitialize(&argc,&argv,NULL,NULL)); 117*55a74a43SLisandro Dalcin 118*55a74a43SLisandro Dalcin PetscCall(GetInt("-start", &start, 12)); 119*55a74a43SLisandro Dalcin PetscCall(GetInt("-step", &step, 4)); 120*55a74a43SLisandro Dalcin PetscCall(GetInt("-stop", &stop, start)); 121*55a74a43SLisandro Dalcin PetscCall(GetInt("-samples", &samples, 1)); 122*55a74a43SLisandro Dalcin 123*55a74a43SLisandro Dalcin for (n=start; n<=stop; n+=step) { 124*55a74a43SLisandro Dalcin int nx=n+1, ny=n+1, nz=n+1; 125*55a74a43SLisandro Dalcin PetscCall(RunTest(nx,ny,nz,samples,&wt)); 126*55a74a43SLisandro Dalcin PetscCall(PetscPrintf(PETSC_COMM_SELF,"Grid %3d x %3d x %3d -> %f seconds (%2d samples)\n",nx,ny,nz,wt,samples)); 127*55a74a43SLisandro Dalcin } 128*55a74a43SLisandro Dalcin PetscCall(PetscFinalize()); 129*55a74a43SLisandro Dalcin return 0; 130*55a74a43SLisandro Dalcin } 131