def test_S2_AdvectiveCFL(Lmax, timestepper, dtype, dealias): radius = 1 # Bases c, d, sb, phi, theta = build_S2(2 * (Lmax + 1), (Lmax + 1), dealias, dtype=dtype, grid_scale=1) x = radius * np.sin(theta) * np.cos(phi) y = radius * np.sin(theta) * np.sin(phi) z = radius * np.cos(theta) # Fields u = field.Field(name='u', dist=d, tensorsig=(c, ), bases=(sb, ), dtype=dtype) # For a scalar field f = x*z, set velocity as u = grad(f). (S2 grad currently not implemened) u['g'][0] = -radius * np.cos(theta) * np.sin(phi) u['g'][1] = radius * (np.cos(theta)**2 - np.sin(theta)**2) * np.cos(phi) # AdvectiveCFL initialization cfl = operators.AdvectiveCFL(u, c) cfl_freq = cfl.evaluate()['g'] comparison_freq = np.sqrt(u['g'][0]**2 + u['g'][1]**2) / cfl.cfl_spacing()[0] assert np.allclose(cfl_freq, comparison_freq)
def test_box_AdvectiveCFL(x_basis_class, Nx, Nz, timestepper, dtype, z_velocity_mag, dealias): # Bases Lx = 2 Lz = 1 c = coords.CartesianCoordinates('x', 'z') d = distributor.Distributor((c, )) xb = x_basis_class(c.coords[0], size=Nx, bounds=(0, Lx), dealias=dealias) x = xb.local_grid(1) zb = basis.ChebyshevT(c.coords[1], size=Nz, bounds=(0, Lz), dealias=dealias) z = zb.local_grid(1) b = (xb, zb) # Fields u = field.Field(name='u', dist=d, tensorsig=(c, ), bases=b, dtype=dtype) print(u.domain.get_basis(c)) # Test Fourier CFL fourier_velocity = lambda x: np.sin(4 * np.pi * x / Lx) chebyshev_velocity = lambda z: -z_velocity_mag * z u['g'][0] = fourier_velocity(x) u['g'][1] = chebyshev_velocity(z) # AdvectiveCFL initialization cfl = operators.AdvectiveCFL(u, c) cfl_freq = cfl.evaluate()['g'] comparison_freq = np.abs(u['g'][0]) / cfl.cfl_spacing(u)[0] comparison_freq += np.abs(u['g'][1]) / cfl.cfl_spacing(u)[1] assert np.allclose(cfl_freq, comparison_freq)
def add_velocity(self, velocity): """ Add grid-crossing frequency from a velocity vector. Parameters --------- velocity : field object The velocity; must be a vector with a tensorsig of length 1 """ coords = velocity.tensorsig if len(coords) != 1: raise ValueError("Velocity must be a vector") cfl_operator = operators.AdvectiveCFL(velocity, coords[0]) self.add_frequency(cfl_operator)
def test_flow_tools_cfl(x_basis_class, Nx, Nz, timestepper, dtype, safety, z_velocity_mag, dealias): # Bases Lx = 2 Lz = 1 c = coords.CartesianCoordinates('x', 'z') d = distributor.Distributor((c, )) xb = x_basis_class(c.coords[0], size=Nx, bounds=(0, Lx), dealias=dealias) x = xb.local_grid(1) zb = basis.ChebyshevT(c.coords[1], size=Nz, bounds=(0, Lz), dealias=dealias) z = zb.local_grid(1) b = (xb, zb) # Fields u = field.Field(name='u', dist=d, tensorsig=(c, ), bases=b, dtype=dtype) # Problem ddt = operators.TimeDerivative problem = problems.IVP([u]) problem.add_equation((ddt(u), 0)) # Solver solver = solvers.InitialValueSolver(problem, timestepper) # cfl initialization dt = 1 cfl = flow_tools.CFL(solver, dt, safety=safety, cadence=1) cfl.add_velocity(u) # Test Fourier CFL fourier_velocity = lambda x: np.sin(4 * np.pi * x / Lx) chebyshev_velocity = lambda z: -z_velocity_mag * z u['g'][0] = fourier_velocity(x) u['g'][1] = chebyshev_velocity(z) solver.step(dt) solver.step( dt ) #need two timesteps to get past stored_dt per compute_timestep logic dt = cfl.compute_timestep() op = operators.AdvectiveCFL(u, c) cfl_freq = np.abs(u['g'][0] / op.cfl_spacing(u)[0]) cfl_freq += np.abs(u['g'][1] / op.cfl_spacing(u)[1]) cfl_freq = np.max(cfl_freq) dt_comparison = safety * (cfl_freq)**(-1) assert np.allclose(dt, dt_comparison)
def test_disk_AdvectiveCFL(Nr, Nphi, timestepper, dtype, dealias): radius = 2 # Bases c, d, db, phi, r, x, y = build_disk(Nphi, Nr, radius, dealias, dtype=dtype, grid_scale=1) # Fields f = field.Field(name='f', dist=d, bases=(db, ), dtype=dtype) f['g'] = x * y u = operators.Gradient(f, c).evaluate() # AdvectiveCFL initialization cfl = operators.AdvectiveCFL(u, c) cfl_freq = cfl.evaluate()['g'] comparison_freq = np.abs(u['g'][0]) / cfl.cfl_spacing()[0] comparison_freq += np.abs(u['g'][1]) / cfl.cfl_spacing()[1] assert np.allclose(cfl_freq, comparison_freq)
def test_spherical_shell_AdvectiveCFL(Lmax, Nmax, timestepper, dtype, dealias): radii = (0.5, 2) # Bases c, d, b, phi, theta, r, x, y, z = build_shell(2 * (Lmax + 1), (Lmax + 1), (Nmax + 1), radii, dealias, dtype=dtype, grid_scale=1) # Fields f = field.Field(name='f', dist=d, bases=(b, ), dtype=dtype) f['g'] = x * y * z u = operators.Gradient(f, c).evaluate() # AdvectiveCFL initialization cfl = operators.AdvectiveCFL(u, c) cfl_freq = cfl.evaluate()['g'] comparison_freq = np.sqrt(u['g'][0]**2 + u['g'][1]**2) / cfl.cfl_spacing()[0] comparison_freq += np.abs(u['g'][2]) / cfl.cfl_spacing()[1] assert np.allclose(cfl_freq, comparison_freq)
def test_fourier_AdvectiveCFL(x_basis_class, Nx, timestepper, dtype, dealias): Lx = 1 # Bases c = coords.CartesianCoordinates('x') d = distributor.Distributor((c, )) xb = x_basis_class(c.coords[0], size=Nx, bounds=(0, Lx), dealias=dealias) x = xb.local_grid(1) # Fields u = field.Field(name='u', dist=d, tensorsig=(c, ), bases=(xb, ), dtype=dtype) velocity = lambda x: np.sin(2 * np.pi * x / Lx) u['g'][0] = velocity(x) # AdvectiveCFL initialization cfl = operators.AdvectiveCFL(u, c) cfl_freq = cfl.evaluate()['g'] comparison_freq = np.abs(u['g']) / cfl.cfl_spacing(u)[0] assert np.allclose(cfl_freq, comparison_freq)