def test_skew_explicit(basis, N, dealias, dtype, layout): c, d, b, r = basis(N, dealias, dtype) # Random vector field f = d.VectorField(c, bases=b) f.fill_random(layout='g') # Evaluate skew f.change_layout(layout) g = d3.skew(f).evaluate() assert np.allclose(g[layout][0], -f[layout][1]) assert np.allclose(g[layout][1], f[layout][0])
def test_curl_explicit_2d_scalar(basis, N, dealias, dtype): c, d, b, r = basis(N, dealias, dtype) x, y = r kx, ky = 2 * np.pi / Lx, 2 * np.pi / Ly f = d.Field(bases=b) f.preset_scales(dealias) f['g'] = (np.sin(2 * kx * x) + np.sin(kx * x)) * np.cos(ky * y) g_op = -d3.skew(d3.grad(f)) # curl(f*ez) g = d.VectorField(c, bases=b) g.preset_scales(dealias) g['g'][0] = -ky * (np.sin(2 * kx * x) + np.sin(kx * x)) * np.sin(ky * y) g['g'][1] = -(2 * kx * np.cos(2 * kx * x) + kx * np.cos(kx * x)) * np.cos( ky * y) assert np.allclose(g_op.evaluate()['g'], g['g'])
# Solver solver = problem.build_solver(timestepper) solver.stop_sim_time = stop_sim_time # Initial conditions b.fill_random('g', seed=42, distribution='normal', scale=1e-3) # Random noise b['g'] *= z * (Lz - z) # Damp noise at walls b['g'] += Lz - z # Add linear background # Analysis snapshots = solver.evaluator.add_file_handler('snapshots', sim_dt=0.25, max_writes=50) snapshots.add_task(b, name='buoyancy') snapshots.add_task(-d3.div(d3.skew(u)), name='vorticity') # CFL CFL = d3.CFL(solver, initial_dt=max_timestep, cadence=10, safety=0.5, threshold=0.05, max_change=1.5, min_change=0.5, max_dt=max_timestep) CFL.add_velocity(u) # Flow properties flow = d3.GlobalFlowProperty(solver, cadence=10) flow.add_property(np.sqrt(u @ u) / nu, name='Re')
dtype = np.float64 # Bases coords = d3.S2Coordinates('phi', 'theta') dist = d3.Distributor(coords, dtype=dtype) basis = d3.SphereBasis(coords, (Nphi, Ntheta), radius=R, dealias=dealias, dtype=dtype) # Fields u = dist.VectorField(coords, name='u', bases=basis) h = dist.Field(name='h', bases=basis) # Substitutions zcross = lambda A: d3.MulCosine(d3.skew(A)) # Initial conditions: zonal jet phi, theta = dist.local_grids(basis) lat = np.pi / 2 - theta + 0 * phi umax = 80 * meter / second lat0 = np.pi / 7 lat1 = np.pi / 2 - lat0 en = np.exp(-4 / (lat1 - lat0)**2) jet = (lat0 <= lat) * (lat <= lat1) u_jet = umax / en * np.exp(1 / (lat[jet] - lat0) / (lat[jet] - lat1)) u['g'][0][jet] = u_jet # Initial conditions: balanced height c = dist.Field(name='c') problem = d3.LBVP([h, c], namespace=locals())
#[beta] = 1 / T / L # Bases coords = d3.S2Coordinates('phi', 'theta') dist = d3.Distributor(coords, dtype=dtype) basis = d3.SphereBasis(coords, (Nphi, Ntheta), radius=1, dealias=dealias, dtype=dtype) phi, theta = basis.local_grids((1, 1)) # Fields u = dist.VectorField(coords, name='u', bases=basis) f = dist.VectorField(coords, name='f', bases=basis) p = dist.Field(name='p', bases=basis) g = dist.Field(name='g') # Substitutions zcross = lambda A: d3.MulCosine(d3.skew(A)) curl_vec = lambda A: - d3.div(d3.skew(A)) # Problem problem = d3.IVP([u, p, g], namespace=locals()) problem.add_equation("dt(u) + grad(p) + kappa*u - nu*lap(u) + (2*Omega)*zcross(u) = - dot(u,grad(u)) + f") problem.add_equation("div(u) + g = 0") problem.add_equation("ave(p) = 0") # Solver solver = problem.build_solver(d3.RK222) solver.stop_iteration = stop_iteration # Analysis snapshots = solver.evaluator.add_file_handler('snapshots', iter=10, max_writes=10) snapshots.add_task(curl_vec(u), name='vorticity')