xref: /petsc/src/binding/petsc4py/demo/legacy/perftest/driver.c (revision 55a74a43bb44613d95e937906bec3b8c3581b432)
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