def setUp(self): # need to eliminate beta and U for tests self.m = pyqg.QGModel(beta=0., U1=0., U2=0., filterfac=0.) # the maximum wavelengths to use in tests # if we go to higher wavelengths, we don't get machine precision self.kwavemax = int(self.m.nx/8) self.lwavemax = int(self.m.ny/8)
def test_xarray(): m = pyqg.QGModel(1) ds = m.to_dataset() assert type(ds) == xr.Dataset expected_vars = ['q', 'u', 'v', 'ph', 'Qy'] for v in expected_vars: assert v in ds
def test_advect(rtol=1.e-13): """ Make sure advective term vanishes for plane wave It is an unpleasant fact that we cannot to get a double precision accuracy when the plane wave is slanted (kx != 0 and ky !=0 ) """ #m = bt_model.BTModel(L=2.*np.pi,nx=256) m = pyqg.QGModel(L=2.*np.pi,nx=256,U1=0) # there are some magic combinations that # fails the test...try kx=12,ky=24 # should investigate what's going on... kx = np.array([1.,5.,10.,0.,24.,2.]) ky = np.array([2.,0.,10.,21.,12.,49.]) for i in range(kx.size): # set plane wave PV #m.set_q( # np.cos( kx[i] * m.x + ky[i] * m.y )) m.set_q1q2( np.cos( kx[i] * m.x + ky[i] * m.y ), np.zeros_like(m.x) ) # compute psi m._invert() #m.ph1,m.ph2 = m.invph(m.qh1,m.qh2) # diagnose vel. #m.u1,m.v1 = m.caluv(m.ph1) # compute advection #jacobh = m.advect(m.q[0],m.u[0],m.v[0]) jacobh = m._advect(m.q,m.u,m.v) #jacobh = m.advect(m.q,m.u,m.v) jacob = m.ifft(jacobh) # residual -- the L2-norm of the jacobian res = np.abs(jacob).sum()*m.dx*m.dy/(m.L**2) print("residual = %1.5e" %res) assert res<rtol, " *** Jacobian residual is larger than %1.1e" %rtol
m = pyqg.QGModel( # grid size parameters nx=256, # grid resolution ny=256, L=16e6, # domain size is L [m] W=16e6, #72e6, # timestepping parameters dt=7200. / 50.0, # numerical timestep twrite=1000, # interval for cfl and ke writeout (in timesteps) tmax=10 * year, # total time of integration tavestart=1 * year, # start time for averaging taveint= 86400., # time interval used for summation in longterm average in seconds #useAB2=False, # use second order Adams Bashforth timestepping instead of 3rd # friction parameters rek=1.0 / (60.0 * 60.0 * 24.0 * 7.0), #5.787e-7, # linear drag in lower layer filterfac=23.6, # the factor for use in the exponential filter # constants #f = None, # coriolis parameter (not necessary for two-layer model # if deformation radius is provided) g=9.81, # acceleration due to gravity # diagnostics parameters diagnostics_list='all', # which diagnostics to output # fft parameters # removed because fftw is now manditory #use_fftw = False, # fftw flag #teststyle = False, # use fftw with "estimate" planner to get reproducibility ntd=int(ncors), # number of threads to use in fftw computations #log_level = 1, # logger level: from 0 for quiet (no log) to 4 for verbose # # logger (see https://docs.python.org/2/library/logging.html) logfile=None, # logfile; None prints to screen beta=1.7e-11, # gradient of coriolis parameter # in Naburos model: delta = 4.4e-18 !linear devrease in beta (1/(s*m*m)) #rek=5.787e-7, # linear drag in lower layer rd=800000.0, # deformation radius delta=.5, # layer thickness ratio (H1/H2) H1=5000, # depth of layer 1 (H1) in m (?) U1=20, # upper layer flow U2=0.0, # lower layer flow )
def test_two_layer(self): """ Tests against some statistics of a reference two-layer solution """ year = 360 * 86400. m = pyqg.QGModel(nx=32, L=1e6, beta=1.5e-11, rek=5.787e-7, rbg=0, rd=30000.0, delta=0.25, U1=0.05, U2=0.0, filterfac=18.4, dt=12800., tmax=3 * year, tavestart=1 * year, taveint=12800., useAB2=True, diagnostics_list='all') m.set_q1q2((1e-6 * np.cos(2 * 5 * np.pi * m.x / m.L) + 1e-7 * np.cos(2 * 5 * np.pi * m.y / m.W)), np.zeros_like(m.x)) m.run() q1 = m.q[0] q1norm = (q1**2).sum() assert m.t == 93312000.0 # machine + numpy.version fluctuations # appears to be less than 0.1% rtol, atol = 0.01, 0. # These numbers come from Malte's original 2-layer simulation np.testing.assert_allclose( q1norm, 9.561430503712755e-08, rtol=rtol, atol=atol, err_msg=' Inconsistent with reference solution') diagnostic_results = { 'APEgen': 2.5225558013107688e-07 / (m.nx**2), 'EKEdiss': 1.4806764171539711e-07 / (m.nx**2), } sum_diagnostic_results = { 'EKE': 0.00818377631732826 + 0.00015616609033468579, } # need to average these diagnostics avg_diagnostic_results = { 'entspec': 1.5015983257921716e-06, 'APEflux': 0.00017889483037254459, 'KEflux': 0.00037067750708912918, 'APEgenspec': 0.00025837684260178754, 'KEspec': 2 * (8581.3114357188006 + 163.75201433878425) / (m.M**2) } # first print all output for name, des in iteritems(diagnostic_results): res = np.mean(np.asarray(m.get_diagnostic(name))) print('%10s: %1.15e \n%10s %1.15e (desired)' % (name, res, '', des)) for name, des in iteritems(sum_diagnostic_results): res = m.get_diagnostic(name).sum() print('%10s: %1.15e \n%10s %1.15e (desired)' % (name, res, '', des)) for name, des in iteritems(avg_diagnostic_results): res = diag.spec_sum(np.abs(m.get_diagnostic(name))).sum() print('%10s: %1.15e \n%10s %1.15e (desired)' % (name, res, '', des)) # now do assertions for name, des in iteritems(diagnostic_results): res = m.get_diagnostic(name) np.testing.assert_allclose(res, des, rtol=rtol, atol=atol) for name, des in iteritems(sum_diagnostic_results): res = m.get_diagnostic(name).sum() np.testing.assert_allclose(res, des, rtol=rtol, atol=atol) for name, des in iteritems(avg_diagnostic_results): res = diag.spec_sum(np.abs(m.get_diagnostic(name))).sum() np.testing.assert_allclose(res, des, rtol=rtol, atol=atol)
def setUp(self): self.m = pyqg.QGModel(L=2. * np.pi, beta=0., U1=0., U2=0., filterfac=0.)
import numpy as np from matplotlib import pyplot as plt import pyqg m = pyqg.QGModel(tavestart=0, dt=8000) for snapshot in m.run_with_snapshots(tsnapstart=0, tsnapint=1000 * m.dt): plt.clf() plt.imshow(m.q[0] + m.Qy1 * m.y) plt.clim([0, m.Qy1 * m.W]) plt.pause(0.01) plt.draw() # now the model is done
res = np.zeros((len(mynx), 5)) print 'nx, threads, timesteps, time' for j, nx in enumerate(mynx): dt = dtfac / nx #for i, (use_fftw, nth) in enumerate([(False, 1), (True, 1), # (True, 2), (True, 4), (True, 8)]): for i, nth in enumerate(mynth): m = pyqg.QGModel( nx=nx, tmax=tmax, dt=dt, ntd=nth, # no output twrite=np.inf, # no time average taveint=np.inf, ) tic = time.time() m.run() toc = time.time() tottime = toc - tic #res[j,i] = tottime #print 'nx=%3d, fftw=%g, threads=%g: %g' % (nx, use_fftw, nth, tottime) print '%3d, %3d, %8d, %10.4f' % (nx, nth, m.tc, tottime) # # profiling # prof = cProfile.Profile()
def test_the_model(rtol=0.1): """Make sure the results are correct within relative tolerance rtol.""" year = 360*86400. m = pyqg.QGModel( nx=32, # grid resolution ny=None, L=1e6, # domain size W=None, # physical parameters beta=1.5e-11, # gradient of coriolis parameter rek=5.787e-7, # linear drag in lower layer rd=30000.0, # deformation radius delta=0.25, # layer thickness ratio (H1/H2) U1=0.05, # upper layer flow U2=0.0, # lower layer flow filterfac=18.4, # timestepping parameters dt=12800., # numerical timstep tmax=3*year, # total time of integration tavestart=1*year, # start time for averaging taveint=12800., useAB2=True, # diagnostics parameters diagnostics_list='all' # which diagnostics to output) ) # set initial conditions m.set_q1q2( (1e-6*np.cos(2*5*np.pi * m.x / m.L) + 1e-7*np.cos(2*5*np.pi * m.y / m.W)), np.zeros_like(m.x) ) m.run() try: q1 = m.q1 # old syntax except AttributeError: q1 = m.q[0] # new syntax q1norm = (q1**2).sum() print 'time: %g' % m.t assert m.t == 93312000.0 ## do we really need this if we have all the other diagnostics? #print 'q1norm: %.15e' % q1norm #np.testing.assert_allclose(q1norm, 9.723198783759038e-08, rtol) #old value np.testing.assert_allclose(q1norm, 9.561430503712755e-08, rtol) # just skip all the other tests for now return ## raw diagnostics (scalar output) diagnostic_results = { 'EKE1': 5.695448642915733e-03, 'EKE2': 1.088253274803528e-04, 'APEgen': 8.842056320175081e-08, 'EKEdiss': 6.368668363708053e-08, } ## old values #diagnostic_results = { # 'EKE1': 0.008183776317328265, # 'EKE2': 0.00015616609033468579, # 'APEgen': 2.5225558013107688e-07, # 'EKEdiss': 1.4806764171539711e-07, #} ## need to average these diagnostics avg_diagnostic_results = { 'entspec': 5.703438193477885e-07, 'APEflux': 9.192940039964286e-05, 'KEflux': 1.702621259427053e-04, 'APEgenspec': 9.058591846403974e-05, 'KE1spec': 3.338261440237941e+03, 'KE2spec': 7.043282793801889e+01 } ## old values #avg_diagnostic_results = { # 'entspec': 1.5015983257921716e-06,, # 'APEflux': 0.00017889483037254459, # 'KEflux': 0.00037067750708912918, # 'APEgenspec': 0.00025837684260178754, # 'KE1spec': 8581.3114357188006,, # 'KE2spec': 163.75201433878425 #} # first print all output for name, des in diagnostic_results.iteritems(): res = m.get_diagnostic(name) print '%10s: %1.15e \n%10s %1.15e (desired)' % (name, res, '', des) for name, des in avg_diagnostic_results.iteritems(): res = np.abs(m.get_diagnostic(name)).sum() print '%10s: %1.15e \n%10s %1.15e (desired)' % (name, res, '', des) # now do assertions for name, des in diagnostic_results.iteritems(): res = m.get_diagnostic(name) np.testing.assert_allclose(res, des, rtol) for name, des in avg_diagnostic_results.iteritems(): res = np.abs(m.get_diagnostic(name)).sum() np.testing.assert_allclose(res, des, rtol)
def test_describe_diagnostics(self): """ Test whether describe_diagnostics runs without error """ m = pyqg.QGModel(1) m.describe_diagnostics()