1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
#!/usr/bin/env python3
import sys, petsc4py
petsc4py.init(sys.argv)
from petsc4py import PETSc
import numpy as np
try:
from matplotlib import pylab
except ImportError:
pylab = None
# this user class is an application
# context for the nonlinear problem
# at hand; it contains some parameters
# and knows how to compute residuals
class AppCtx:
def __init__(self, nx, ny, nz):
self.n = np.array([nx, ny, nz], dtype='i')
self.h = np.array([1.0/(n-1) for n in self.n], dtype='d')
from App import formFunction
from App import formInitial
self._formFunction = formFunction
self._formInitial = formInitial
def formInitial(self, t, X):
xx = X.getArray(readonly=0).reshape(self.n, order='f')
self._formInitial(self.h, t, xx)
def formFunction(self, ts, t, X, Xdot, F):
n = self.n
h = self.h
x = X.getArray(readonly=1).reshape(n, order='f')
xdot = Xdot.getArray(readonly=1).reshape(n, order='f')
f = F[...].reshape(n, order='f')
self._formFunction(h, t, x, xdot, f)
def plot(self, t, x):
nx, ny, nz = self.n
from numpy import mgrid
#
U = x.getArray(readonly=1).reshape(nx,ny,nz, order='f')
#
X, Y = mgrid[0:1:1j*nx,0:1:1j*ny]
Z = U[:,:,nz//2]
pylab.figure(0)
pylab.contourf(X,Y,Z)
pylab.colorbar()
pylab.plot(X.ravel(),Y.ravel(),'.k')
pylab.title('z=0.50')
pylab.xlabel('x')
pylab.ylabel('y')
pylab.axis('equal')
#
X, Y = mgrid[0:1:1j*nx,0:1:1j*nz]
Z = U[:,ny//4,:]
pylab.figure(1)
pylab.contourf(X,Y,Z)
pylab.colorbar()
pylab.plot(X.ravel(),Y.ravel(),'.k')
pylab.title('y=0.25')
pylab.xlabel('x')
pylab.ylabel('z')
pylab.axis('equal')
#
X, Y = mgrid[0:1:1j*ny,0:1:1j*nz]
Z = U[nx//2,:,:]
pylab.figure(2)
pylab.contourf(X,Y,Z)
pylab.colorbar()
pylab.plot(X.ravel(),Y.ravel(),'.k')
pylab.title('x=0.50')
pylab.xlabel('y')
pylab.ylabel('z')
pylab.axis('equal')
def run_test(nx,ny,nz,samples,plot=False):
ts = PETSc.TS().create()
ts.setType('theta')
ts.setTheta(1.0)
ts.setTimeStep(0.01)
ts.setTime(0.0)
ts.setMaxTime(1.0)
ts.setMaxSteps(10)
eft = PETSc.TS.ExactFinalTime.STEPOVER
ts.setExactFinalTime(eft)
x = PETSc.Vec().createSeq(nx*ny*nz)
ts.setSolution(x)
app = AppCtx(nx, ny, nz)
f = PETSc.Vec().createSeq(nx*ny*nz)
ts.setIFunction(app.formFunction, f)
ts.snes.setUseMF(1)
ts.snes.ksp.setType('cg')
ts.setFromOptions()
ts.setUp()
wt = 1e300
for i in range(samples):
app.formInitial(0, x)
t1 = PETSc.Log.getTime()
ts.solve(x)
t2 = PETSc.Log.getTime()
wt = min(wt,t2-t1)
if plot and pylab:
app.plot(ts.time, x)
return wt
OptDB = PETSc.Options()
start = OptDB.getInt('start', 12)
step = OptDB.getInt('step', 4)
stop = OptDB.getInt('stop', start)
samples = OptDB.getInt('samples', 1)
plot = OptDB.getBool('plot', False)
if plot and not pylab:
PETSc.Sys.Print("matplotlib not available")
for n in range(start, stop+step, step):
nx = ny = nz = n+1
wt = run_test(nx,ny,nz,samples,plot)
PETSc.Sys.Print("Grid %3d x %3d x %3d -> %f seconds (%2d samples)"
% (nx,ny,nz,wt,samples))
if plot and pylab:
pylab.show()
|