def test_initialize_fneq(Case, dtype_device): dtype, device = dtype_device lattice = Lattice(D2Q9, device, dtype) if Case == TaylorGreenVortex3D: lattice = Lattice(D3Q27, dtype=dtype, device=device) flow = Case(resolution=16, reynolds_number=1000, mach_number=0.01, lattice=lattice) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation_neq = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) pre_rho = lattice.rho(simulation_neq.f) pre_u = lattice.u(simulation_neq.f) simulation_neq.initialize_f_neq() post_rho = lattice.rho(simulation_neq.f) post_u = lattice.u(simulation_neq.f) assert(torch.allclose(pre_rho,post_rho,1e-6)) assert(torch.allclose(pre_u,post_u)) if Case == TaylorGreenVortex2D: error_reporter_neq = ErrorReporter(lattice, flow, interval=1, out=None) error_reporter_eq = ErrorReporter(lattice, flow, interval=1, out=None) simulation_eq = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) simulation_neq.reporters.append(error_reporter_neq) simulation_eq.reporters.append(error_reporter_eq) simulation_neq.step(10) simulation_eq.step(10) error_u, error_p = np.mean(np.abs(error_reporter_neq.out), axis=0).tolist() error_u_eq, error_p_eq = np.mean(np.abs(error_reporter_eq.out), axis=0).tolist() assert(error_u < error_u_eq)
def test_grid_fine_to_coarse_3d(): lattice = Lattice(D3Q27, 'cpu', dtype=torch.double) flow_f = TaylorGreenVortex3D(40, 1600, 0.15, lattice) collision_f = BGKCollision(lattice, tau=flow_f.units.relaxation_parameter_lu) sim_f = Simulation(flow_f, lattice, collision_f, streaming=None) flow_c = TaylorGreenVortex3D(20, 1600, 0.15, lattice) collision_c = BGKCollision(lattice, tau=flow_c.units.relaxation_parameter_lu) sim_c = Simulation(flow_c, lattice, collision_c, streaming=None) f_c = grid_fine_to_coarse(lattice, sim_f.f, flow_f.units.relaxation_parameter_lu, flow_c.units.relaxation_parameter_lu) p_c_init, u_c_init = flow_c.initial_solution(flow_c.grid) rho_c_init = flow_c.units.convert_pressure_pu_to_density_lu(p_c_init) u_c_init = flow_c.units.convert_velocity_to_lu(u_c_init) shear_c_init = lattice.shear_tensor(sim_c.f) shear_c = lattice.shear_tensor(f_c) assert np.isclose(lattice.u(f_c).cpu().numpy(), u_c_init).all() assert np.isclose(lattice.rho(f_c).cpu().numpy(), rho_c_init).all() assert torch.isclose(f_c, sim_c.f).all() assert torch.isclose(shear_c_init, shear_c).all()
def test_HDF5Reporter(tmpdir): lattice = Lattice(D2Q9, "cpu") flow = TaylorGreenVortex2D(resolution=16, reynolds_number=10, mach_number=0.05, lattice=lattice) collision = BGKCollision(lattice=lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice=lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) hdf5_reporter = HDF5Reporter(flow=flow, collision=collision, interval=1, filebase=tmpdir / "output") simulation.reporters.append(hdf5_reporter) simulation.step(3) assert os.path.isfile(tmpdir / "output.h5") dataset_train = LettuceDataset(filebase=tmpdir / "output.h5", target=True) train_loader = torch.utils.data.DataLoader(dataset_train, shuffle=False) print(dataset_train) for (f, target, idx) in train_loader: assert idx in (0, 1, 2) assert f.shape == (1, 9, 16, 16) assert target.shape == (1, 9, 16, 16)
def test_initialization(dtype_device): dtype, device = dtype_device lattice = Lattice(D2Q9, device, dtype) flow = TaylorGreenVortex2D(resolution=16, reynolds_number=10, mach_number=0.05, lattice=lattice) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) # set initial pressure to 0 everywhere p, u = flow.initial_solution(flow.grid) u0 = lattice.convert_to_tensor(flow.units.convert_velocity_to_lu(u)) rho0 = lattice.convert_to_tensor(np.ones_like(u0[0, ...])) simulation.f = lattice.equilibrium(rho0, u0) num_iterations = simulation.initialize(500, 0.001) piter = lattice.convert_to_numpy( flow.units.convert_density_lu_to_pressure_pu(lattice.rho( simulation.f))) # assert that pressure is converged up to 0.05 (max p assert piter == pytest.approx(p, abs=5e-2) assert num_iterations < 500
def test_force_guo(ForceType, device): dtype = torch.double lattice = Lattice(D2Q9, dtype=dtype, device=device) flow = PoiseuilleFlow2D(resolution=10, reynolds_number=1, mach_number=0.02, lattice=lattice, initialize_with_zeros=True) force = ForceType(lattice, tau=flow.units.relaxation_parameter_lu, acceleration=flow.units.convert_acceleration_to_lu( flow.acceleration)) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu, force=force) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) simulation.step(500) # compare with reference solution u_sim = flow.units.convert_velocity_to_pu( lattice.convert_to_numpy(lattice.u(simulation.f))) _, u_ref = flow.analytic_solution(flow.grid) fluidnodes = np.where(np.logical_not(flow.boundaries[0].mask.cpu())) assert u_ref[0].max() == pytest.approx(u_sim[0].max(), rel=0.005) assert u_ref[0][fluidnodes] == pytest.approx(u_sim[0][fluidnodes], rel=None, abs=0.005 * u_ref[0].max())
def test_readme(): """Whenever you have to change this test, the example in README.rst has to change, too. Note differences in the device + number of steps. """ import torch from lettuce import BGKCollision, StandardStreaming, Lattice, D2Q9, TaylorGreenVortex2D, Simulation device = "cpu" dtype = torch.float32 lattice = Lattice(D2Q9, device, dtype) flow = TaylorGreenVortex2D(resolution=256, reynolds_number=10, mach_number=0.05, lattice=lattice) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) mlups = simulation.step(num_steps=1) print("Performance in MLUPS:", mlups)
def test_obstacle(stencil, dtype_device): dtype, device = dtype_device lattice = Lattice(stencil, dtype=dtype, device=device) if stencil is D2Q9: mask = np.zeros([20, 10]) mask[3:6, 3:6] = 1 flow = Obstacle2D(20, 10, 100, 0.1, lattice=lattice, char_length_lu=3) if stencil is D3Q27: mask = np.zeros([20, 10, 5]) mask[3:6, 3:6, :] = 1 flow = Obstacle3D(20, 10, 5, 100, 0.1, lattice=lattice, char_length_lu=3) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) flow.mask = mask != 0 streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) simulation.step(2)
def test_flow_3d(IncompressibleFlow, dtype_device): dtype, device = dtype_device lattice = Lattice(D3Q27, dtype=dtype, device=device) flow = IncompressibleFlow(16, 1, 0.05, lattice=lattice) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) simulation.step(1)
def test_save_and_load(dtype_device, tmpdir): dtype, device = dtype_device lattice = Lattice(D2Q9, device, dtype) flow = TaylorGreenVortex2D(resolution=16, reynolds_number=10, mach_number=0.05, lattice=lattice) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) simulation.step(10) simulation.save_checkpoint(tmpdir / "checkpoint.pic") simulation2 = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) simulation2.load_checkpoint(tmpdir / "checkpoint.pic") assert lattice.convert_to_numpy(simulation2.f) == pytest.approx(lattice.convert_to_numpy(simulation.f))
def test_divergence(stencil, dtype_device): dtype, device = dtype_device lattice = Lattice(stencil, dtype=dtype, device=device) flow = DecayingTurbulence(50, 1, 0.05, lattice=lattice, ic_energy=0.5) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) ekin = flow.units.convert_incompressible_energy_to_pu( torch.sum(lattice.incompressible_energy( simulation.f))) * flow.units.convert_length_to_pu(1.0)**lattice.D u0 = flow.units.convert_velocity_to_pu(lattice.u(simulation.f)[0]) u1 = flow.units.convert_velocity_to_pu(lattice.u(simulation.f)[1]) dx = flow.units.convert_length_to_pu(1.0) grad_u0 = torch_gradient(u0, dx=dx, order=6).cpu().numpy() grad_u1 = torch_gradient(u1, dx=dx, order=6).cpu().numpy() divergence = np.sum(grad_u0[0] + grad_u1[1]) if lattice.D == 3: u2 = flow.units.convert_velocity_to_pu(lattice.u(simulation.f)[2]) grad_u2 = torch_gradient(u2, dx=dx, order=6).cpu().numpy() divergence += np.sum(grad_u2[2]) assert (flow.ic_energy == pytest.approx(lattice.convert_to_numpy(ekin), rel=1)) assert (0 == pytest.approx(divergence, abs=2e-3))
def test_energy_spectrum(tmpdir, Flow): lattice = Lattice(D2Q9, device='cpu') if Flow == TaylorGreenVortex3D or Flow == 'DecayingTurbulence3D': lattice = Lattice(D3Q27, device='cpu') if Flow == 'DecayingTurbulence2D' or Flow == 'DecayingTurbulence3D': Flow = DecayingTurbulence flow = Flow(resolution=20, reynolds_number=1600, mach_number=0.01, lattice=lattice) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) spectrum = lattice.convert_to_numpy( EnergySpectrum(lattice, flow)(simulation.f)) energy = IncompressibleKineticEnergy(lattice, flow)(simulation.f).item() if Flow == DecayingTurbulence: # check that the reported spectrum agrees with the spectrum used for initialization ek_ref, _ = flow.energy_spectrum assert (spectrum == pytest.approx(ek_ref, rel=0.0, abs=0.1)) if Flow == TaylorGreenVortex2D or Flow == TaylorGreenVortex3D: # check that flow has only one mode ek_max = sorted(spectrum, reverse=True) assert ek_max[0] * 1e-5 > ek_max[1] assert (energy == pytest.approx(np.sum(spectrum), rel=0.1, abs=0.0))
def benchmark(ctx, steps, resolution, profile_out, flow, vtk_out): """Run a short simulation and print performance in MLUPS. """ # start profiling if profile_out: profile = cProfile.Profile() profile.enable() # setup and run simulation device, dtype = ctx.obj['device'], ctx.obj['dtype'] flow_class, stencil = flow_by_name[flow] lattice = Lattice(stencil, device, dtype) flow = flow_class(resolution=resolution, reynolds_number=1, mach_number=0.05, lattice=lattice) force = Guo(lattice, tau=flow.units.relaxation_parameter_lu, acceleration=flow.units.convert_acceleration_to_lu( flow.force)) if hasattr(flow, "acceleration") else None collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu, force=force) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) if vtk_out: simulation.reporters.append(VTKReporter(lattice, flow, interval=10)) mlups = simulation.step(num_steps=steps) # write profiling output if profile_out: profile.disable() stats = pstats.Stats(profile) stats.sort_stats('cumulative') stats.print_stats() profile.dump_stats(profile_out) click.echo(f"Saved profiling information to {profile_out}.") click.echo("Finished {} steps in {} bit precision. MLUPS: {:10.2f}".format( steps, str(dtype).replace("torch.float", ""), mlups)) return 0
def test_generic_reporters(Reporter, Case, dtype_device): dtype, device = dtype_device lattice = Lattice(D2Q9, dtype=dtype, device=device) flow = Case(64, 10000, 0.05, lattice=lattice) if Case == TaylorGreenVortex3D: lattice = Lattice(D3Q27, dtype=dtype, device=device) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) kinE_reporter = Reporter(lattice, flow, interval=1, out=None) simulation.reporters.append(kinE_reporter) simulation.step(2) assert (np.asarray(kinE_reporter.out)[1, 1] == pytest.approx(np.asarray( kinE_reporter.out)[0, 1], rel=0.05))
def test_masks(dtype_device): """test if masks are applied from boundary conditions""" dtype, device = dtype_device lattice = Lattice(D2Q9, dtype=dtype, device=device) flow = Obstacle((10, 5), 100, 0.1, lattice, 2) flow.mask[1, 1] = 1 streaming = StandardStreaming(lattice) simulation = Simulation(flow, lattice, None, streaming) assert simulation.streaming.no_stream_mask.any() assert simulation.no_collision_mask.any()
def test_vtk_reporter_no_mask(tmpdir): lattice = Lattice(D2Q9, "cpu") flow = TaylorGreenVortex2D(resolution=16, reynolds_number=10, mach_number=0.05, lattice=lattice) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) vtk_reporter = VTKReporter(lattice, flow, interval=1, filename_base=tmpdir / "output") simulation.reporters.append(vtk_reporter) simulation.step(2) assert os.path.isfile(tmpdir / "output_00000000.vtr") assert os.path.isfile(tmpdir / "output_00000001.vtr")
def test_equilibrium_pressure_outlet(dtype_device): dtype, device = dtype_device lattice = Lattice(D2Q9, dtype=dtype, device=device) class MyObstacle(Obstacle2D): @property def boundaries(self, *args): x, y = self.grid return [ EquilibriumBoundaryPU( np.abs(x) < 1e-6, self.units.lattice, self.units, np.array([self.units.characteristic_velocity_pu, 0])), EquilibriumOutletP(self.units.lattice, [0, -1]), EquilibriumOutletP(self.units.lattice, [0, 1]), EquilibriumOutletP(self.units.lattice, [1, 0]), BounceBackBoundary(self.mask, self.units.lattice) ] flow = MyObstacle(30, 30, reynolds_number=10, mach_number=0.1, lattice=lattice, char_length_lu=10) mask = np.zeros_like(flow.grid[0], dtype=np.bool) mask[10:20, 10:20] = 1 flow.mask = mask simulation = Simulation( flow, lattice, RegularizedCollision(lattice, flow.units.relaxation_parameter_lu), StandardStreaming(lattice)) simulation.step(20) rho = lattice.rho(simulation.f) u = lattice.u(simulation.f) feq = lattice.equilibrium(torch.ones_like(rho), u) p = flow.units.convert_density_lu_to_pressure_pu(rho) zeros = torch.zeros_like(p[0, -1, :]) assert torch.allclose(zeros, p[:, -1, :], rtol=0, atol=1e-4) assert torch.allclose(zeros, p[:, :, 0], rtol=0, atol=1e-4) assert torch.allclose(zeros, p[:, :, -1], rtol=0, atol=1e-4) assert torch.allclose(feq[:, -1, 1:-1], feq[:, -2, 1:-1])
def test_generic_reporters(Observable, Case, dtype_device): dtype, device = dtype_device lattice = Lattice(D2Q9, dtype=dtype, device=device) flow = Case(32, 10000, 0.05, lattice=lattice) if Case == TaylorGreenVortex3D: lattice = Lattice(D3Q27, dtype=dtype, device=device) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) reporter = ObservableReporter(Observable(lattice, flow), interval=1, out=None) simulation.reporters.append(reporter) simulation.step(2) values = np.asarray(reporter.out) if Observable is EnergySpectrum: assert values[1, 2:] == pytest.approx(values[0, 2:], rel=0.0, abs=values[0, 2:].sum() / 10) else: assert values[1, 2] == pytest.approx(values[0, 2], rel=0.05)
def convergence(ctx, init_f_neq): """Use Taylor Green 2D for convergence test in diffusive scaling.""" device, dtype = ctx.obj['device'], ctx.obj['dtype'] lattice = Lattice(D2Q9, device, dtype) error_u_old = None error_p_old = None print(("{:>15} " * 5).format("resolution", "error (u)", "order (u)", "error (p)", "order (p)")) for i in range(4, 9): resolution = 2**i mach_number = 8 / resolution # Simulation flow = TaylorGreenVortex2D(resolution=resolution, reynolds_number=10000, mach_number=mach_number, lattice=lattice) collision = BGKCollision(lattice, tau=flow.units.relaxation_parameter_lu) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow, lattice=lattice, collision=collision, streaming=streaming) if (init_f_neq): simulation.initialize_f_neq() error_reporter = ErrorReporter(lattice, flow, interval=1, out=None) simulation.reporters.append(error_reporter) for _ in range(10 * resolution): simulation.step(1) error_u, error_p = np.mean(np.abs(error_reporter.out), axis=0).tolist() factor_u = 0 if error_u_old is None else error_u_old / error_u factor_p = 0 if error_p_old is None else error_p_old / error_p error_u_old = error_u error_p_old = error_p print("{:15} {:15.2e} {:15.1f} {:15.2e} {:15.1f}".format( resolution, error_u, factor_u / 2, error_p, factor_p / 2)) if factor_u / 2 < 1.9: print("Velocity convergence order < 2.") if factor_p / 2 < 0.9: print("Velocity convergence order < 1.") if factor_u / 2 < 1.9 or factor_p / 2 < 0.9: sys.exit(1) else: return 0
reynolds_number=reynolds, mach_number=mach, lattice=lattice, ) tau_fine = flow_fine.units.relaxation_parameter_lu flow_coarse = flowclass( resolution=resolution, reynolds_number=reynolds, mach_number=mach, lattice=lattice, ) collision = BGKCollision(lattice, tau=tau_fine) streaming = StandardStreaming(lattice) simulation = Simulation(flow=flow_fine, lattice=lattice, collision=collision, streaming=streaming) flow_coarse.units.characteristic_velocity_pu = flow_fine.units.characteristic_velocity_pu tau_coarse = flow_coarse.units.relaxation_parameter_lu ### Reporter spectrum = EnergySpectrum(lattice, flow_fine) enstrophy_f = ObservableReporter(Enstrophy(lattice, flow_fine), interval=postplotinterval * 2, out=None) energy_f = ObservableReporter(IncompressibleKineticEnergy(lattice, flow_fine), interval=postplotinterval * 2, out=None) spectrum_f = ObservableReporter(EnergySpectrum(lattice, flow_fine), interval=postplotinterval * 2,