xref: /petsc/src/binding/petsc4py/demo/legacy/perftest/driver.py (revision f748bf6bfc83f133d5068e6a5445afd45844ada1)
1*1b37a2a7SPierre Jolivet#!/usr/bin/env python3
255a74a43SLisandro Dalcinimport sys, petsc4py
355a74a43SLisandro Dalcinpetsc4py.init(sys.argv)
455a74a43SLisandro Dalcinfrom petsc4py import PETSc
555a74a43SLisandro Dalcinimport numpy as np
655a74a43SLisandro Dalcin
755a74a43SLisandro Dalcintry:
855a74a43SLisandro Dalcin    from matplotlib import pylab
955a74a43SLisandro Dalcinexcept ImportError:
1055a74a43SLisandro Dalcin    pylab = None
1155a74a43SLisandro Dalcin
1255a74a43SLisandro Dalcin# this user class is an application
1355a74a43SLisandro Dalcin# context for the nonlinear problem
1455a74a43SLisandro Dalcin# at hand; it contains some parameters
1555a74a43SLisandro Dalcin# and knows how to compute residuals
1655a74a43SLisandro Dalcin
1755a74a43SLisandro Dalcinclass AppCtx:
1855a74a43SLisandro Dalcin
1955a74a43SLisandro Dalcin    def __init__(self, nx, ny, nz):
2055a74a43SLisandro Dalcin        self.n = np.array([nx, ny, nz], dtype='i')
2155a74a43SLisandro Dalcin        self.h = np.array([1.0/(n-1) for n in self.n], dtype='d')
2255a74a43SLisandro Dalcin        from App import formFunction
2355a74a43SLisandro Dalcin        from App import formInitial
2455a74a43SLisandro Dalcin        self._formFunction = formFunction
2555a74a43SLisandro Dalcin        self._formInitial = formInitial
2655a74a43SLisandro Dalcin
2755a74a43SLisandro Dalcin    def formInitial(self, t, X):
2855a74a43SLisandro Dalcin        xx = X.getArray(readonly=0).reshape(self.n, order='f')
2955a74a43SLisandro Dalcin        self._formInitial(self.h, t, xx)
3055a74a43SLisandro Dalcin
3155a74a43SLisandro Dalcin    def formFunction(self, ts, t, X, Xdot, F):
3255a74a43SLisandro Dalcin        n = self.n
3355a74a43SLisandro Dalcin        h = self.h
3455a74a43SLisandro Dalcin        x = X.getArray(readonly=1).reshape(n, order='f')
3555a74a43SLisandro Dalcin        xdot = Xdot.getArray(readonly=1).reshape(n, order='f')
3655a74a43SLisandro Dalcin        f = F[...].reshape(n, order='f')
3755a74a43SLisandro Dalcin        self._formFunction(h, t, x, xdot, f)
3855a74a43SLisandro Dalcin
3955a74a43SLisandro Dalcin    def plot(self, t, x):
4055a74a43SLisandro Dalcin        nx, ny, nz = self.n
4155a74a43SLisandro Dalcin        from numpy import mgrid
4255a74a43SLisandro Dalcin        #
4355a74a43SLisandro Dalcin        U = x.getArray(readonly=1).reshape(nx,ny,nz, order='f')
4455a74a43SLisandro Dalcin        #
4555a74a43SLisandro Dalcin        X, Y =  mgrid[0:1:1j*nx,0:1:1j*ny]
4655a74a43SLisandro Dalcin        Z = U[:,:,nz//2]
4755a74a43SLisandro Dalcin        pylab.figure(0)
4855a74a43SLisandro Dalcin        pylab.contourf(X,Y,Z)
4955a74a43SLisandro Dalcin        pylab.colorbar()
5055a74a43SLisandro Dalcin        pylab.plot(X.ravel(),Y.ravel(),'.k')
5155a74a43SLisandro Dalcin        pylab.title('z=0.50')
5255a74a43SLisandro Dalcin        pylab.xlabel('x')
5355a74a43SLisandro Dalcin        pylab.ylabel('y')
5455a74a43SLisandro Dalcin        pylab.axis('equal')
5555a74a43SLisandro Dalcin        #
5655a74a43SLisandro Dalcin        X, Y =  mgrid[0:1:1j*nx,0:1:1j*nz]
5755a74a43SLisandro Dalcin        Z = U[:,ny//4,:]
5855a74a43SLisandro Dalcin        pylab.figure(1)
5955a74a43SLisandro Dalcin        pylab.contourf(X,Y,Z)
6055a74a43SLisandro Dalcin        pylab.colorbar()
6155a74a43SLisandro Dalcin        pylab.plot(X.ravel(),Y.ravel(),'.k')
6255a74a43SLisandro Dalcin        pylab.title('y=0.25')
6355a74a43SLisandro Dalcin        pylab.xlabel('x')
6455a74a43SLisandro Dalcin        pylab.ylabel('z')
6555a74a43SLisandro Dalcin        pylab.axis('equal')
6655a74a43SLisandro Dalcin        #
6755a74a43SLisandro Dalcin        X, Y =  mgrid[0:1:1j*ny,0:1:1j*nz]
6855a74a43SLisandro Dalcin        Z = U[nx//2,:,:]
6955a74a43SLisandro Dalcin        pylab.figure(2)
7055a74a43SLisandro Dalcin        pylab.contourf(X,Y,Z)
7155a74a43SLisandro Dalcin        pylab.colorbar()
7255a74a43SLisandro Dalcin        pylab.plot(X.ravel(),Y.ravel(),'.k')
7355a74a43SLisandro Dalcin        pylab.title('x=0.50')
7455a74a43SLisandro Dalcin        pylab.xlabel('y')
7555a74a43SLisandro Dalcin        pylab.ylabel('z')
7655a74a43SLisandro Dalcin        pylab.axis('equal')
7755a74a43SLisandro Dalcin
7855a74a43SLisandro Dalcin
7955a74a43SLisandro Dalcindef run_test(nx,ny,nz,samples,plot=False):
8055a74a43SLisandro Dalcin    ts  = PETSc.TS().create()
8155a74a43SLisandro Dalcin    ts.setType('theta')
8255a74a43SLisandro Dalcin    ts.setTheta(1.0)
8355a74a43SLisandro Dalcin    ts.setTimeStep(0.01)
8455a74a43SLisandro Dalcin    ts.setTime(0.0)
8555a74a43SLisandro Dalcin    ts.setMaxTime(1.0)
8655a74a43SLisandro Dalcin    ts.setMaxSteps(10)
8755a74a43SLisandro Dalcin    eft = PETSc.TS.ExactFinalTime.STEPOVER
8855a74a43SLisandro Dalcin    ts.setExactFinalTime(eft)
8955a74a43SLisandro Dalcin
9055a74a43SLisandro Dalcin    x = PETSc.Vec().createSeq(nx*ny*nz)
9155a74a43SLisandro Dalcin    ts.setSolution(x)
9255a74a43SLisandro Dalcin    app = AppCtx(nx, ny, nz)
9355a74a43SLisandro Dalcin    f = PETSc.Vec().createSeq(nx*ny*nz)
9455a74a43SLisandro Dalcin    ts.setIFunction(app.formFunction, f)
9555a74a43SLisandro Dalcin    ts.snes.setUseMF(1)
9655a74a43SLisandro Dalcin    ts.snes.ksp.setType('cg')
9755a74a43SLisandro Dalcin    ts.setFromOptions()
9855a74a43SLisandro Dalcin    ts.setUp()
9955a74a43SLisandro Dalcin
10055a74a43SLisandro Dalcin    wt = 1e300
10155a74a43SLisandro Dalcin    for i in range(samples):
10255a74a43SLisandro Dalcin        app.formInitial(0, x)
10355a74a43SLisandro Dalcin        t1 = PETSc.Log.getTime()
10455a74a43SLisandro Dalcin        ts.solve(x)
10555a74a43SLisandro Dalcin        t2 = PETSc.Log.getTime()
10655a74a43SLisandro Dalcin        wt = min(wt,t2-t1)
10755a74a43SLisandro Dalcin
10855a74a43SLisandro Dalcin    if plot and pylab:
10955a74a43SLisandro Dalcin        app.plot(ts.time, x)
11055a74a43SLisandro Dalcin
11155a74a43SLisandro Dalcin    return wt
11255a74a43SLisandro Dalcin
11355a74a43SLisandro DalcinOptDB = PETSc.Options()
11455a74a43SLisandro Dalcin
11555a74a43SLisandro Dalcin
11655a74a43SLisandro Dalcinstart = OptDB.getInt('start', 12)
11755a74a43SLisandro Dalcinstep = OptDB.getInt('step', 4)
11855a74a43SLisandro Dalcinstop = OptDB.getInt('stop', start)
11955a74a43SLisandro Dalcinsamples = OptDB.getInt('samples', 1)
12055a74a43SLisandro Dalcin
12155a74a43SLisandro Dalcinplot = OptDB.getBool('plot', False)
12255a74a43SLisandro Dalcinif plot and not pylab:
12355a74a43SLisandro Dalcin    PETSc.Sys.Print("matplotlib not available")
12455a74a43SLisandro Dalcin
12555a74a43SLisandro Dalcinfor n in range(start, stop+step, step):
12655a74a43SLisandro Dalcin    nx = ny = nz = n+1
12755a74a43SLisandro Dalcin    wt = run_test(nx,ny,nz,samples,plot)
12855a74a43SLisandro Dalcin    PETSc.Sys.Print("Grid %3d x %3d x %3d -> %f  seconds (%2d samples)"
12955a74a43SLisandro Dalcin                    % (nx,ny,nz,wt,samples))
13055a74a43SLisandro Dalcin
13155a74a43SLisandro Dalcinif plot and pylab:
13255a74a43SLisandro Dalcin    pylab.show()
133