def initialize(self): """ Initialize the grid and variables for incompressible flow and set the initial conditions for the chosen problem. """ my_grid = grid_setup(self.rp, ng=4) # create the variables bc, bc_xodd, bc_yodd = bc_setup(self.rp) my_data = patch.CellCenterData2d(my_grid) # velocities my_data.register_var("x-velocity", bc_xodd) my_data.register_var("y-velocity", bc_yodd) # phi -- used for the projections my_data.register_var("phi-MAC", bc) my_data.register_var("phi", bc) my_data.register_var("gradp_x", bc) my_data.register_var("gradp_y", bc) my_data.create() self.cc_data = my_data if self.rp.get_param("particles.do_particles") == 1: n_particles = self.rp.get_param("particles.n_particles") particle_generator = self.rp.get_param("particles.particle_generator") self.particles = particles.Particles(self.cc_data, bc, n_particles, particle_generator) # now set the initial conditions for the problem problem = importlib.import_module("incompressible.problems.{}".format(self.problem_name)) problem.init_data(self.cc_data, self.rp)
def initialize(self): """ Initialize the grid and variables for advection and set the initial conditions for the chosen problem. """ my_grid = grid_setup(self.rp, ng=4) # create the variables my_data = patch.CellCenterData2d(my_grid) bc = bc_setup(self.rp)[0] my_data.register_var("density", bc) my_data.create() self.cc_data = my_data if self.rp.get_param("particles.do_particles") == 1: n_particles = self.rp.get_param("particles.n_particles") particle_generator = self.rp.get_param( "particles.particle_generator") self.particles = particles.Particles(self.cc_data, bc, n_particles, particle_generator) # now set the initial conditions for the problem problem = importlib.import_module("advection.problems.{}".format( self.problem_name)) problem.init_data(self.cc_data, self.rp)
def initialize(self, extra_vars=None, ng=4): """ Initialize the grid and variables for swe flow and set the initial conditions for the chosen problem. """ my_grid = grid_setup(self.rp, ng=ng) my_data = self.data_class(my_grid) bc, bc_xodd, bc_yodd = bc_setup(self.rp) # are we dealing with solid boundaries? we'll use these for # the Riemann solver self.solid = bnd.bc_is_solid(bc) # density and energy my_data.register_var("height", bc) my_data.register_var("x-momentum", bc_xodd) my_data.register_var("y-momentum", bc_yodd) my_data.register_var("fuel", bc) # any extras? if extra_vars is not None: for v in extra_vars: my_data.register_var(v, bc) # store the gravitational acceration g as an auxillary quantity # so we can have a # self-contained object stored in output files to make plots. # store grav because we'll need that in some BCs my_data.set_aux("g", self.rp.get_param("swe.grav")) my_data.create() self.cc_data = my_data if self.rp.get_param("particles.do_particles") == 1: n_particles = self.rp.get_param("particles.n_particles") particle_generator = self.rp.get_param("particles.particle_generator") self.particles = particles.Particles(self.cc_data, bc, n_particles, particle_generator) # some auxillary data that we'll need to fill GC in, but isn't # really part of the main solution aux_data = self.data_class(my_grid) aux_data.register_var("ymom_src", bc_yodd) aux_data.create() self.aux_data = aux_data self.ivars = Variables(my_data) # derived variables self.cc_data.add_derived(derives.derive_primitives) # initial conditions for the problem problem = importlib.import_module("{}.problems.{}".format( self.solver_name, self.problem_name)) problem.init_data(self.cc_data, self.rp) if self.verbose > 0: print(my_data)
def initialize(self): """ Initialize the grid and variables for advection and set the initial conditions for the chosen problem. """ def shift(velocity): """ Computes the direction of shift for each node for upwind discretization based on sign of veclocity """ shift_vel = np.sign(velocity) shift_vel[np.where(shift_vel <= 0)] = 0 shift_vel[np.where(shift_vel > 0)] = -1 return shift_vel my_grid = grid_setup(self.rp, ng=4) # create the variables bc, bc_xodd, bc_yodd = bc_setup(self.rp) my_data = patch.CellCenterData2d(my_grid) # velocities my_data.register_var("x-velocity", bc_xodd) my_data.register_var("y-velocity", bc_yodd) # shift my_data.register_var("x-shift", bc_xodd) my_data.register_var("y-shift", bc_yodd) # density my_data.register_var("density", bc) my_data.create() self.cc_data = my_data if self.rp.get_param("particles.do_particles") == 1: n_particles = self.rp.get_param("particles.n_particles") particle_generator = self.rp.get_param( "particles.particle_generator") self.particles = particles.Particles(self.cc_data, bc, n_particles, particle_generator) # now set the initial conditions for the problem problem = importlib.import_module( "advection_nonuniform.problems.{}".format(self.problem_name)) problem.init_data(self.cc_data, self.rp) # compute the required shift for each node using corresponding velocity at the node shx = self.cc_data.get_var("x-shift") shx[:, :] = shift(self.cc_data.get_var("x-velocity")) shy = self.cc_data.get_var("y-shift") shy[:, :] = shift(self.cc_data.get_var("y-velocity"))
def test_particles_array_gen(): """ Test Particles particle generator from input array. """ myd, bc, n_particles = setup_test() # generate random array of particles init_positions = np.random.rand(n_particles, 2) ps = particles.Particles(myd, bc, n_particles, "array", pos_array=init_positions) positions = set([(p.x, p.y) for p in ps.particles.values()]) correct_positions = set([(x, y) for (x, y) in init_positions]) assert positions == correct_positions, "sets are not the same"
def test_outflow_bcs(): """ Test particles correctly disappear when flow outside of boundaries with outflow boundary conditions. """ extra_rp_params = {"mesh.xlboundary": "outflow", "mesh.xrboundary": "outflow", "mesh.ylboundary": "outflow", "mesh.yrboundary": "outflow"} myd, bc, _ = setup_test(extra_rp_params=extra_rp_params) # create an array of particles with some at the edge of the domain. init_particle_positions = [[0.5, 0.03], [0.5, 0.96], [0.04, 0.5], [0.97, 0.5], [0.5, 0.2], [0.8, 0.5]] ps = particles.Particles(myd, bc, 4, "array", init_particle_positions) u = myd.grid.scratch_array() v = myd.grid.scratch_array() x = myd.grid.x2d y = myd.grid.y2d # setup up velocity so that some of the particles are lost. u[(x < y) & (x < (1-y))] = -1 v[(x < y) & (x > (1-y))] = 1 u[(x > y) & (x > (1-y))] = 1 v[(x > y) & (x < (1-y))] = -1 ps.update_particles(0.1, u, v) assert len(ps.particles) == 2, "All but two of the particles should have flowed out of the domain" # extract positions by their initial positions so they're in the right order # (as particles are stored in a dictionary they may not be returned in the # same order as we first inserted them.) positions = [ps.particles[(x, y)].pos() for (x, y) in init_particle_positions[4:]] correct_positions = [[0.5, 0.1], [0.9, 0.5]] np.testing.assert_array_almost_equal(positions, correct_positions)
def test_particles_grid_gen(): """ Test Particles grid generator. """ myd, bc, n_particles = setup_test() ps = particles.Particles(myd, bc, n_particles, "grid") assert len(ps.particles) == 49, "There should be 49 particles" positions = set([(p.x, p.y) for p in ps.particles.values()]) xs, step = np.linspace(0, 1, num=7, endpoint=False, retstep=True) xs += 0.5 * step correct_positions = set([(x, y) for x in xs for y in xs]) assert positions == correct_positions, "sets are not the same"
def test_reflect_bcs(): """ Test reflective boundary conditions. """ extra_rp_params = {"mesh.xlboundary": "reflect-even", "mesh.xrboundary": "reflect-even", "mesh.ylboundary": "reflect-even", "mesh.yrboundary": "reflect-even"} myd, bc, _ = setup_test(extra_rp_params=extra_rp_params) # create an array of particles at the edge of the domain. init_particle_positions = [[0.5, 0.03], [0.5, 0.96], [0.04, 0.5], [0.97, 0.5]] ps = particles.Particles(myd, bc, 4, "array", init_particle_positions) u = myd.grid.scratch_array() v = myd.grid.scratch_array() x = myd.grid.x2d y = myd.grid.y2d # setup up velocity so that each of the particles bounces off the walls. u[(x < y) & (x < (1-y))] = -1 v[(x < y) & (x > (1-y))] = 1 u[(x > y) & (x > (1-y))] = 1 v[(x > y) & (x < (1-y))] = -1 ps.update_particles(0.1, u, v) # extract positions by their initial positions so they're in the right order # (as particles are stored in a dictionary they may not be returned in the # same order as we first inserted them.) positions = [ps.particles[(x, y)].pos() for (x, y) in init_particle_positions] correct_positions = [[0.5, 0.07], [0.5, 0.94], [0.06, 0.5], [0.93, 0.5]] np.testing.assert_array_almost_equal(positions, correct_positions)
def test_particles_random_gen(): """ Test random particle generator. """ myd, bc, n_particles = setup_test() # seed random number generator np.random.seed(3287469) ps = particles.Particles(myd, bc, n_particles, "random") positions = set([(p.x, p.y) for p in ps.particles.values()]) assert len(ps.particles) == n_particles, "There should be {} particles".format(n_particles) # reseed random number generator np.random.seed(3287469) correct_positions = np.random.rand(n_particles, 2) correct_positions = set([(x, y) for (x, y) in correct_positions]) assert positions == correct_positions, "sets are not the same"
def initialize(self, extra_vars=None, ng=4): """ Initialize the grid and variables for compressible flow and set the initial conditions for the chosen problem. """ my_grid = grid_setup(self.rp, ng=ng) my_data = self.data_class(my_grid) # define solver specific boundary condition routines bnd.define_bc("hse", BC.user, is_solid=False) bnd.define_bc("ramp", BC.user, is_solid=False) # for double mach reflection problem bc, bc_xodd, bc_yodd = bc_setup(self.rp) # are we dealing with solid boundaries? we'll use these for # the Riemann solver self.solid = bnd.bc_is_solid(bc) # density and energy my_data.register_var("density", bc) my_data.register_var("energy", bc) my_data.register_var("x-momentum", bc_xodd) my_data.register_var("y-momentum", bc_yodd) # any extras? if extra_vars is not None: for v in extra_vars: my_data.register_var(v, bc) # store the EOS gamma as an auxillary quantity so we can have a # self-contained object stored in output files to make plots. # store grav because we'll need that in some BCs my_data.set_aux("gamma", self.rp.get_param("eos.gamma")) my_data.set_aux("grav", self.rp.get_param("compressible.grav")) my_data.create() self.cc_data = my_data if self.rp.get_param("particles.do_particles") == 1: self.particles = particles.Particles(self.cc_data, bc, self.rp) # some auxillary data that we'll need to fill GC in, but isn't # really part of the main solution aux_data = self.data_class(my_grid) aux_data.register_var("ymom_src", bc_yodd) aux_data.register_var("E_src", bc) aux_data.create() self.aux_data = aux_data self.ivars = Variables(my_data) # derived variables self.cc_data.add_derived(derives.derive_primitives) # initial conditions for the problem problem = importlib.import_module("{}.problems.{}".format( self.solver_name, self.problem_name)) problem.init_data(self.cc_data, self.rp) if self.verbose > 0: print(my_data)
def read(filename): """read an HDF5 file and recreate the simulation object that holds the data and state of the simulation. """ if not filename.endswith(".h5"): filename += ".h5" with h5py.File(filename, "r") as f: # read the simulation information -- this only exists if the # file was created as a simulation object try: solver_name = f.attrs["solver"] problem_name = f.attrs["problem"] t = f.attrs["time"] n = f.attrs["nsteps"] except KeyError: # this was just a patch written out solver_name = None # read in the grid info and create our grid grid = f["grid"].attrs myg = patch.Grid2d(grid["nx"], grid["ny"], ng=grid["ng"], xmin=grid["xmin"], xmax=grid["xmax"], ymin=grid["ymin"], ymax=grid["ymax"]) # sometimes problems define custom BCs -- at the moment, we # are going to assume that these always map to BC.user. We # need to read these in now, since the variable creation # requires it. custom_bcs = read_bcs(f) if custom_bcs is not None: if solver_name in [ "compressible_fv4", "compressible_rk", "compressible_sdc" ]: bc_solver = "compressible" else: bc_solver = solver_name bcmod = importlib.import_module("{}.{}".format(bc_solver, "BC")) for name in custom_bcs: bnd.define_bc(name, bcmod.user, is_solid=custom_bcs[name]) # read in the variable info -- start by getting the names gs = f["state"] names = [] for n in gs: names.append(n) # create the CellCenterData2d object myd = patch.CellCenterData2d(myg) for n in names: grp = gs[n] bc = bnd.BC(xlb=grp.attrs["xlb"], xrb=grp.attrs["xrb"], ylb=grp.attrs["ylb"], yrb=grp.attrs["yrb"]) myd.register_var(n, bc) myd.create() # auxillary data for k in f["aux"].attrs: myd.set_aux(k, f["aux"].attrs[k]) # restore the variable data for n in names: grp = gs[n] data = grp["data"] v = myd.get_var(n) v.v()[:, :] = data[:, :] # restore the particle data try: gparticles = f["particles"] particle_data = gparticles["particle_positions"] init_data = gparticles["init_particle_positions"] my_particles = particles.Particles(myd, None, len(particle_data), "array", particle_data, init_data) except KeyError: my_particles = None if solver_name is not None: solver = importlib.import_module(solver_name) sim = solver.Simulation(solver_name, problem_name, None) sim.n = n sim.cc_data = myd sim.cc_data.t = t sim.particles = my_particles sim.read_extras(f) if solver_name is not None: return sim return myd
def test_particles_advect(): """ Test particles are advected correctly and check periodic boundary conditions. """ extra_rp_params = {"mesh.xlboundary": "periodic", "mesh.xrboundary": "periodic", "mesh.ylboundary": "periodic", "mesh.yrboundary": "periodic"} myd, bc, n_particles = setup_test(extra_rp_params=extra_rp_params) ps = particles.Particles(myd, bc, n_particles, "grid") # advect with constant velocity # first try 0 velocity u = myd.grid.scratch_array() v = myd.grid.scratch_array() ps.update_particles(1, u, v) positions = set([(p.x, p.y) for p in ps.particles.values()]) xs, step = np.linspace(0, 1, num=7, endpoint=False, retstep=True) xs += 0.5 * step correct_positions = set([(x, y) for x in xs for y in xs]) assert positions == correct_positions, "sets are not the same" # now move constant speed to the right u[:, :] = 1 ps.update_particles(0.1, u, v) positions = set([(p.x, p.y) for p in ps.particles.values()]) correct_positions = set([((x+0.1) % 1, y) for x in xs for y in xs]) assert positions == correct_positions, "sets are not the same" # constant speed up u[:, :] = 0 v[:, :] = 1 ps = particles.Particles(myd, bc, n_particles, "grid") ps.update_particles(0.1, u, v) positions = set([(p.x, p.y) for p in ps.particles.values()]) correct_positions = set([(x, (y+0.1) % 1) for x in xs for y in xs]) assert positions == correct_positions, "sets are not the same" # constant speed right + up u[:, :] = 1 ps = particles.Particles(myd, bc, n_particles, "grid") ps.update_particles(0.1, u, v) positions = set([(p.x, p.y) for p in ps.particles.values()]) correct_positions = set([((x+0.1) % 1, (y+0.1) % 1) for x in xs for y in xs]) assert positions == correct_positions, "sets are not the same"