def test_coalescence_2_sd(backend_class): # Arrange s = Settings() s.kernel = Golovin(b=1.5e12) s.formulae.seed = 0 steps = [0, 200] s.n_sd = 2 builder = Builder(n_sd=s.n_sd, backend=backend_class(formulae=s.formulae)) builder.set_environment(Box(dt=s.dt, dv=s.dv)) attributes = {} attributes['volume'], attributes['n'] = ConstantMultiplicity( s.spectrum).sample(s.n_sd) builder.add_dynamic(Coalescence(s.kernel, adaptive=False)) particulator = builder.build(attributes) volumes = {} # Act for step in steps: particulator.run(step - particulator.n_steps) volumes[particulator. n_steps] = particulator.attributes['volume'].to_ndarray() # Assert x_max = 0 for volume in volumes.values(): assert x_max < np.amax(volume) x_max = np.amax(volume) assert particulator.attributes.super_droplet_count == 1
def run(settings, backend=CPU, observers=()): builder = Builder(n_sd=settings.n_sd, backend=backend(formulae=settings.formulae)) builder.set_environment(Box(dv=settings.dv, dt=settings.dt)) attributes = {} sampling = ConstantMultiplicity(settings.spectrum) attributes["volume"], attributes["n"] = sampling.sample(settings.n_sd) coalescence = Coalescence(collision_kernel=settings.kernel, adaptive=settings.adaptive) builder.add_dynamic(coalescence) products = ( ParticleVolumeVersusRadiusLogarithmSpectrum(settings.radius_bins_edges, name="dv/dlnr"), WallTime(), ) particulator = builder.build(attributes, products) if hasattr(settings, "u_term") and "terminal velocity" in particulator.attributes: particulator.attributes[ "terminal velocity"].approximation = settings.u_term(particulator) for observer in observers: particulator.observers.append(observer) vals = {} particulator.products["wall time"].reset() for step in settings.output_steps: particulator.run(step - particulator.n_steps) vals[step] = particulator.products["dv/dlnr"].get()[0] vals[step][:] *= settings.rho exec_time = particulator.products["wall time"].get() return vals, exec_time
def make_core(settings, coal_eff): backend = CPU builder = Builder(n_sd=settings.n_sd, backend=backend(settings.formulae)) env = Box(dv=settings.dv, dt=settings.dt) builder.set_environment(env) env["rhod"] = 1.0 attributes = {} attributes["volume"], attributes["n"] = ConstantMultiplicity( settings.spectrum).sample(settings.n_sd) collision = Collision( collision_kernel=settings.kernel, coalescence_efficiency=coal_eff, breakup_efficiency=settings.break_eff, fragmentation_function=settings.fragmentation, adaptive=settings.adaptive, ) builder.add_dynamic(collision) M0 = am.make_arbitrary_moment_product(rank=0, attr="volume", attr_unit="m^3") M1 = am.make_arbitrary_moment_product(rank=1, attr="volume", attr_unit="m^3") M2 = am.make_arbitrary_moment_product(rank=2, attr="volume", attr_unit="m^3") products = (M0(name="M0"), M1(name="M1"), M2(name="M2")) return builder.build(attributes, products)
def test_coalescence(backend, kernel, croupier, adaptive): if backend == ThrustRTC and croupier == 'local': # TODO #358 return if backend == ThrustRTC and adaptive and croupier == 'global': # TODO #329 return # Arrange s = Settings() s.formulae.seed = 0 steps = [0, 800] builder = Builder(n_sd=s.n_sd, backend=backend, formulae=s.formulae) builder.set_environment(Box(dt=s.dt, dv=s.dv)) attributes = {} attributes['volume'], attributes['n'] = ConstantMultiplicity(s.spectrum).sample(s.n_sd) builder.add_dynamic(Coalescence(kernel, croupier=croupier, adaptive=adaptive)) core = builder.build(attributes) volumes = {} # Act for step in steps: core.run(step - core.n_steps) volumes[core.n_steps] = core.particles['volume'].to_ndarray() # Assert x_max = 0 for volume in volumes.values(): assert x_max < np.amax(volume) x_max = np.amax(volume)
def run_box_NObreakup(settings, step): backend = CPU builder = Builder(n_sd=settings.n_sd, backend=backend(settings.formulae)) env = Box(dv=settings.dv, dt=settings.dt) builder.set_environment(env) env["rhod"] = 1.0 attributes = {} attributes["volume"], attributes["n"] = ConstantMultiplicity( settings.spectrum).sample(settings.n_sd) coal = Coalescence( collision_kernel=settings.kernel, coalescence_efficiency=settings.coal_eff, adaptive=settings.adaptive, ) builder.add_dynamic(coal) products = ( ParticleVolumeVersusRadiusLogarithmSpectrum( radius_bins_edges=settings.radius_bins_edges, name="dv/dlnr"), CollisionRatePerGridbox(name="cr"), CollisionRateDeficitPerGridbox(name="crd"), ) core = builder.build(attributes, products) # run core.run(step - core.n_steps) x = (settings.radius_bins_edges[:-1] / si.micrometres, ) y = core.products["dv/dlnr"].get() return (x, y)
def make_core(settings): backend = CPU builder = Builder(n_sd=settings.n_sd, backend=backend(settings.formulae)) env = Box(dv=settings.dv, dt=settings.dt) builder.set_environment(env) env["rhod"] = 1.0 attributes = {} attributes["volume"], attributes["n"] = ConstantMultiplicity( settings.spectrum).sample(settings.n_sd) collision = Collision( collision_kernel=settings.kernel, coalescence_efficiency=settings.coal_eff, breakup_efficiency=settings.break_eff, fragmentation_function=settings.fragmentation, adaptive=settings.adaptive, ) builder.add_dynamic(collision) products = ( ParticleSizeSpectrumPerVolume( radius_bins_edges=settings.radius_bins_edges, name="dv/dlnr"), CollisionRatePerGridbox(name="cr"), CollisionRateDeficitPerGridbox(name="crd"), ) return builder.build(attributes, products)
def test_coalescence_2_sd(backend): # Arrange s = Settings() s.kernel = Golovin(b=1.5e12) s.formulae.seed = 0 steps = [0, 200] s.n_sd = 2 builder = Builder(n_sd=s.n_sd, backend=backend, formulae=s.formulae) builder.set_environment(Box(dt=s.dt, dv=s.dv)) attributes = {} attributes['volume'], attributes['n'] = ConstantMultiplicity(s.spectrum).sample(s.n_sd) builder.add_dynamic(Coalescence(s.kernel)) core = builder.build(attributes) volumes = {} # Act for step in steps: core.run(step - core.n_steps) volumes[core.n_steps] = core.particles['volume'].to_ndarray() # Assert x_max = 0 for volume in volumes.values(): assert x_max < np.amax(volume) x_max = np.amax(volume) print(core.particles['n'].to_ndarray()) assert core.particles.SD_num == 1
def run(setup, observers=()): builder = Builder(n_sd=setup.n_sd, backend=setup.backend) builder.set_environment(Box(dv=setup.dv, dt=setup.dt)) attributes = {} attributes['volume'], attributes['n'] = constant_multiplicity( setup.n_sd, setup.spectrum, (setup.init_x_min, setup.init_x_max)) coalescence = Coalescence(setup.kernel) coalescence.adaptive = setup.adaptive builder.add_dynamic(coalescence) products = [ParticlesVolumeSpectrum()] particles = builder.build(attributes, products) if hasattr(setup, 'u_term') and 'terminal velocity' in particles.state.attributes: particles.state.attributes[ 'terminal velocity'].approximation = setup.u_term(particles) for observer in observers: particles.observers.append(observer) vals = {} for step in setup.steps: particles.run(step - particles.n_steps) vals[step] = particles.products['dv/dlnr'].get(setup.radius_bins_edges) vals[step][:] *= setup.rho return vals, particles.stats
def run(settings, backend=CPU, observers=()): builder = Builder(n_sd=settings.n_sd, backend=backend) builder.set_environment(Box(dv=settings.dv, dt=settings.dt)) attributes = {} attributes['volume'], attributes['n'] = ConstantMultiplicity( settings.spectrum).sample(settings.n_sd) coalescence = Coalescence(settings.kernel) coalescence.adaptive = settings.adaptive builder.add_dynamic(coalescence) products = [ParticlesVolumeSpectrum(), WallTime()] core = builder.build(attributes, products) if hasattr(settings, 'u_term') and 'terminal velocity' in core.particles.attributes: core.particles.attributes[ 'terminal velocity'].approximation = settings.u_term(core) for observer in observers: core.observers.append(observer) vals = {} core.products['wall_time'].reset() for step in settings.steps: core.run(step - core.n_steps) vals[step] = core.products['dv/dlnr'].get(settings.radius_bins_edges) vals[step][:] *= settings.rho exec_time = core.products['wall_time'].get() return vals, exec_time
def __init__(self, settings, backend=CPU): t_half = settings.z_half / settings.w_avg dt_output = (2 * t_half) / settings.n_output self.n_substeps = 1 while dt_output / self.n_substeps >= settings.dt_max: # TODO #334 dt_max self.n_substeps += 1 builder = Builder(backend=backend(formulae=settings.formulae), n_sd=1) builder.set_environment( Parcel( dt=dt_output / self.n_substeps, mass_of_dry_air=settings.mass_of_dry_air, p0=settings.p0, q0=settings.q0, T0=settings.T0, w=settings.w, )) builder.add_dynamic(AmbientThermodynamics()) builder.add_dynamic( Condensation( rtol_x=settings.rtol_x, rtol_thd=settings.rtol_thd, dt_cond_range=settings.dt_cond_range, )) attributes = {} r_dry = np.array([settings.r_dry]) attributes["dry volume"] = settings.formulae.trivia.volume( radius=r_dry) attributes["kappa times dry volume"] = attributes[ "dry volume"] * settings.kappa attributes["n"] = np.array([settings.n_in_dv], dtype=np.int64) environment = builder.particulator.environment r_wet = equilibrate_wet_radii( r_dry=r_dry, environment=environment, kappa_times_dry_volume=attributes["kappa times dry volume"], ) attributes["volume"] = settings.formulae.trivia.volume(radius=r_wet) products = [ PySDM_products.MeanRadius(name="radius_m1", unit="um"), PySDM_products.CondensationTimestepMin(name="dt_cond_min"), PySDM_products.ParcelDisplacement(name="z"), PySDM_products.AmbientRelativeHumidity(name="RH", unit="%"), PySDM_products.Time(name="t"), PySDM_products.ActivatingRate(unit="s^-1 mg^-1", name="activating_rate"), PySDM_products.DeactivatingRate(unit="s^-1 mg^-1", name="deactivating_rate"), PySDM_products.RipeningRate(unit="s^-1 mg^-1", name="ripening_rate"), PySDM_products.PeakSupersaturation(unit="%", name="S_max"), ] self.particulator = builder.build(attributes, products) self.n_output = settings.n_output
def run(settings): builder = Builder(n_sd=settings.n_sd, backend=settings.backend) builder.set_environment(Box(dv=settings.dv, dt=settings.dt)) attributes = {} attributes['volume'], attributes['n'] = ConstantMultiplicity( settings.spectrum).sample(settings.n_sd) builder.add_dynamic(Coalescence(settings.kernel)) particles = builder.build(attributes, products=[WallTime()]) states = {} for step in settings.steps: particles.run(step - particles.n_steps) last_wall_time = particles.products['wall_time'].get() return states, last_wall_time
def run(setup): builder = Builder(n_sd=setup.n_sd, backend=setup.backend) builder.set_environment(Box(dv=setup.dv, dt=setup.dt)) v, n = constant_multiplicity(setup.n_sd, setup.spectrum, (setup.init_x_min, setup.init_x_max)) attributes = {'n': n, 'volume': v} builder.add_dynamic(Coalescence(setup.kernel)) particles = builder.build(attributes) states = {} for step in setup.steps: particles.run(step - particles.n_steps) return states, particles.stats
def run(settings, backend): builder = Builder(n_sd=settings.n_sd, backend=backend) builder.set_environment(Box(dv=settings.dv, dt=settings.dt)) attributes = {} sampling = ConstantMultiplicity(settings.spectrum) attributes["volume"], attributes["n"] = sampling.sample(settings.n_sd) builder.add_dynamic(Coalescence(collision_kernel=settings.kernel)) particles = builder.build(attributes, products=(WallTime(), )) states = {} last_wall_time = None for step in settings.output_steps: particles.run(step - particles.n_steps) last_wall_time = particles.products["wall time"].get() return states, last_wall_time
def __init__(self, settings, backend=CPU): t_half = settings.z_half / settings.w_avg dt_output = (2 * t_half) / settings.n_output self.n_substeps = 1 while dt_output / self.n_substeps >= settings.dt_max: # TODO #334 dt_max self.n_substeps += 1 builder = Builder(backend=backend, n_sd=1, formulae=settings.formulae) builder.set_environment(Parcel( dt=dt_output / self.n_substeps, mass_of_dry_air=settings.mass_of_dry_air, p0=settings.p0, q0=settings.q0, T0=settings.T0, w=settings.w )) builder.add_dynamic(AmbientThermodynamics()) builder.add_dynamic(Condensation( kappa=settings.kappa, rtol_x=settings.rtol_x, rtol_thd=settings.rtol_thd, dt_cond_range=settings.dt_cond_range )) attributes = {} r_dry = np.array([settings.r_dry]) attributes['dry volume'] = settings.formulae.trivia.volume(radius=r_dry) attributes['n'] = np.array([settings.n_in_dv], dtype=np.int64) environment = builder.core.environment r_wet = r_wet_init(r_dry, environment, kappa=settings.kappa) attributes['volume'] = settings.formulae.trivia.volume(radius=r_wet) products = [ PySDM_products.ParticleMeanRadius(), PySDM_products.CondensationTimestepMin(), PySDM_products.ParcelDisplacement(), PySDM_products.RelativeHumidity(), PySDM_products.Time(), PySDM_products.ActivatingRate(), PySDM_products.DeactivatingRate(), PySDM_products.RipeningRate(), PySDM_products.PeakSupersaturation() ] self.core = builder.build(attributes, products) self.n_output = settings.n_output
def test_coalescence(croupier): # Arrange v_min = 4.186e-15 v_max = 4.186e-12 n_sd = 2**13 steps = [0, 30, 60] X0 = 4 / 3 * np.pi * 30.531e-6**3 n_part = 2**23 / si.metre**3 dv = 1e6 * si.metres**3 dt = 1 * si.seconds norm_factor = n_part * dv rho = 1000 * si.kilogram / si.metre**3 kernel = Golovin(b=1.5e3) # [s-1] spectrum = Exponential(norm_factor=norm_factor, scale=X0) particles_builder = Builder(n_sd=n_sd, backend=backend) particles_builder.set_environment(Box(dt=dt, dv=dv)) attributes = {} attributes['volume'], attributes['n'] = constant_multiplicity( n_sd, spectrum, (v_min, v_max)) particles_builder.add_dynamic(Coalescence(kernel, seed=256)) particles = particles_builder.build(attributes) particles.croupier = croupier class Seed: seed = 0 def __call__(self): Seed.seed += 1 return Seed.seed particles.dynamics[str(Coalescence)].seed = Seed() states = {} # Act for step in steps: particles.run(step - particles.n_steps) check(n_part, dv, n_sd, rho, particles.state, step) states[particles.n_steps] = copy.deepcopy(particles.state) # Assert x_max = 0 for state in states.values(): assert x_max < np.amax(state['volume'].to_ndarray()) x_max = np.amax(state['volume'].to_ndarray())
def __init__(self, settings, backend=CPU): dt_output = settings.total_time / settings.n_steps # TODO #334 overwritten in jupyter example self.n_substeps = 1 # TODO #334 use condensation substeps while (dt_output / self.n_substeps >= settings.dt_max): self.n_substeps += 1 self.formulae = Formulae(condensation_coordinate=settings.coord, saturation_vapour_pressure='AugustRocheMagnus') self.bins_edges = self.formulae.trivia.volume(settings.r_bins_edges) builder = Builder(backend=backend, n_sd=settings.n_sd, formulae=self.formulae) builder.set_environment(Parcel( dt=dt_output / self.n_substeps, mass_of_dry_air=settings.mass_of_dry_air, p0=settings.p0, q0=settings.q0, T0=settings.T0, w=settings.w, z0=settings.z0 )) environment = builder.core.environment builder.add_dynamic(AmbientThermodynamics()) condensation = Condensation( kappa=settings.kappa, adaptive=settings.adaptive, rtol_x=settings.rtol_x, rtol_thd=settings.rtol_thd, dt_cond_range=settings.dt_cond_range ) builder.add_dynamic(condensation) products = [ PySDM_products.ParticlesWetSizeSpectrum(v_bins=self.formulae.trivia.volume(settings.r_bins_edges)), PySDM_products.CondensationTimestepMin(), PySDM_products.CondensationTimestepMax(), PySDM_products.RipeningRate() ] attributes = environment.init_attributes( n_in_dv=settings.n, kappa=settings.kappa, r_dry=settings.r_dry ) self.core = builder.build(attributes, products) self.n_steps = settings.n_steps
def test_coalescence(backend, croupier, adaptive): if backend == ThrustRTC and croupier == 'local': # TODO #358 return if backend == ThrustRTC and adaptive and croupier == 'global': # TODO #329 return # Arrange formulae = Formulae(seed=256) n_sd = 2**14 steps = [0, 100, 200] X0 = formulae.trivia.volume(radius=30.531e-6) n_part = 2**23 / si.metre**3 dv = 1e6 * si.metres**3 dt = 1 * si.seconds norm_factor = n_part * dv rho = 1000 * si.kilogram / si.metre**3 kernel = Golovin(b=1.5e3) # [s-1] spectrum = Exponential(norm_factor=norm_factor, scale=X0) builder = Builder(n_sd=n_sd, backend=backend(formulae=formulae)) builder.set_environment(Box(dt=dt, dv=dv)) attributes = {} attributes['volume'], attributes['n'] = ConstantMultiplicity( spectrum).sample(n_sd) builder.add_dynamic( Coalescence(kernel, croupier=croupier, adaptive=adaptive)) particulator = builder.build(attributes) volumes = {} # Act for step in steps: particulator.run(step - particulator.n_steps) check(n_part, dv, n_sd, rho, particulator.attributes, step) volumes[particulator. n_steps] = particulator.attributes['volume'].to_ndarray() # Assert x_max = 0 for volume in volumes.values(): assert x_max < np.amax(volume) x_max = np.amax(volume)
def __init__(self, setup): dt_output = setup.total_time / setup.n_steps # TODO: overwritten in jupyter example self.n_substeps = 1 # TODO while (dt_output / self.n_substeps >= setup.dt_max): self.n_substeps += 1 self.bins_edges = phys.volume(setup.r_bins_edges) particles_builder = Builder(backend=setup.backend, n_sd=setup.n_sd) particles_builder.set_environment( MoistLagrangianParcelAdiabatic( dt=dt_output / self.n_substeps, mass_of_dry_air=setup.mass_of_dry_air, p0=setup.p0, q0=setup.q0, T0=setup.T0, w=setup.w, z0=setup.z0)) environment = particles_builder.core.environment r_wet = r_wet_init(setup.r_dry, environment, np.zeros_like(setup.n), setup.kappa) condensation = Condensation(kappa=setup.kappa, coord=setup.coord, adaptive=setup.adaptive, rtol_x=setup.rtol_x, rtol_thd=setup.rtol_thd) particles_builder.add_dynamic(condensation) attributes = { 'n': setup.n, 'dry volume': phys.volume(radius=setup.r_dry), 'volume': phys.volume(radius=r_wet) } products = [ ParticlesWetSizeSpectrum(v_bins=phys.volume(setup.r_bins_edges)), CondensationTimestep(), RipeningRate() ] self.particles = particles_builder.build(attributes, products) self.n_steps = setup.n_steps
def __init__(self, settings, backend=CPU): dt_output = settings.total_time / settings.n_steps # TODO: overwritten in jupyter example self.n_substeps = 1 # TODO while (dt_output / self.n_substeps >= settings.dt_max): self.n_substeps += 1 self.bins_edges = phys.volume(settings.r_bins_edges) builder = Builder(backend=backend, n_sd=settings.n_sd) builder.set_environment( Parcel(dt=dt_output / self.n_substeps, mass_of_dry_air=settings.mass_of_dry_air, p0=settings.p0, q0=settings.q0, T0=settings.T0, w=settings.w, z0=settings.z0)) environment = builder.core.environment builder.add_dynamic(AmbientThermodynamics()) condensation = Condensation(kappa=settings.kappa, coord=settings.coord, adaptive=settings.adaptive, rtol_x=settings.rtol_x, rtol_thd=settings.rtol_thd) builder.add_dynamic(condensation) products = [ ParticlesWetSizeSpectrum( v_bins=phys.volume(settings.r_bins_edges)), CondensationTimestep(), RipeningRate() ] attributes = environment.init_attributes(n_in_dv=settings.n, kappa=settings.kappa, r_dry=settings.r_dry) self.core = builder.build(attributes, products) self.n_steps = settings.n_steps
def __init__(self, setup): t_half = setup.z_half / setup.w_avg dt_output = (2 * t_half) / setup.n_output self.n_substeps = 1 while dt_output / self.n_substeps >= setup.dt_max: # TODO dt_max self.n_substeps += 1 builder = Builder(backend=setup.backend, n_sd=1) builder.set_environment( MoistLagrangianParcelAdiabatic( dt=dt_output / self.n_substeps, mass_of_dry_air=setup.mass_of_dry_air, p0=setup.p0, q0=setup.q0, T0=setup.T0, w=setup.w)) builder.add_dynamic( Condensation( kappa=setup.kappa, rtol_x=setup.rtol_x, rtol_thd=setup.rtol_thd, )) attributes = {} r_dry = np.array([setup.r_dry]) attributes['dry volume'] = phys.volume(radius=r_dry) attributes['n'] = np.array([setup.n_in_dv], dtype=np.int64) environment = builder.core.environment r_wet = r_wet_init(r_dry, environment, np.zeros_like(attributes['n']), setup.kappa) attributes['volume'] = phys.volume(radius=r_wet) products = [ParticleMeanRadius(), CondensationTimestep()] self.core = builder.build(attributes, products) self.n_output = setup.n_output
def reinit(self, products=None): formulae = self.settings.formulae backend = self.backend_class(formulae=formulae) builder = Builder(n_sd=self.settings.n_sd, backend=backend) environment = Kinematic2D( dt=self.settings.dt, grid=self.settings.grid, size=self.settings.size, rhod_of=self.settings.rhod_of_zZ, mixed_phase=self.settings.processes["freezing"], ) builder.set_environment(environment) if products is not None: products = list(products) else: products = make_default_product_collection(self.settings) if self.settings.processes["fluid advection"]: builder.add_dynamic(AmbientThermodynamics()) if self.settings.processes["condensation"]: condensation = Condensation( rtol_x=self.settings.condensation_rtol_x, rtol_thd=self.settings.condensation_rtol_thd, adaptive=self.settings.condensation_adaptive, substeps=self.settings.condensation_substeps, dt_cond_range=self.settings.condensation_dt_cond_range, schedule=self.settings.condensation_schedule, ) builder.add_dynamic(condensation) displacement = None if self.settings.processes["particle advection"]: displacement = Displacement( enable_sedimentation=self.settings.processes["sedimentation"], adaptive=self.settings.displacement_adaptive, rtol=self.settings.displacement_rtol, ) if self.settings.processes["fluid advection"]: initial_profiles = { "th": self.settings.initial_dry_potential_temperature_profile, "qv": self.settings.initial_vapour_mixing_ratio_profile, } advectees = dict(( key, np.repeat( profile.reshape(1, -1), environment.mesh.grid[0], axis=0), ) for key, profile in initial_profiles.items()) solver = MPDATA_2D( advectees=advectees, stream_function=self.settings.stream_function, rhod_of_zZ=self.settings.rhod_of_zZ, dt=self.settings.dt, grid=self.settings.grid, size=self.settings.size, displacement=displacement, n_iters=self.settings.mpdata_iters, infinite_gauge=self.settings.mpdata_iga, nonoscillatory=self.settings.mpdata_fct, third_order_terms=self.settings.mpdata_tot, ) builder.add_dynamic(EulerianAdvection(solver)) if self.settings.processes["particle advection"]: builder.add_dynamic(displacement) if self.settings.processes["coalescence"]: builder.add_dynamic( Coalescence( collision_kernel=self.settings.kernel, adaptive=self.settings.coalescence_adaptive, dt_coal_range=self.settings.coalescence_dt_coal_range, substeps=self.settings.coalescence_substeps, optimized_random=self.settings. coalescence_optimized_random, )) if self.settings.processes["freezing"]: builder.add_dynamic( Freezing(singular=self.settings.freezing_singular)) attributes = environment.init_attributes( spatial_discretisation=spatial_sampling.Pseudorandom(), dry_radius_spectrum=self.settings.spectrum_per_mass_of_dry_air, kappa=self.settings.kappa, ) if self.settings.processes["freezing"]: if self.settings.freezing_inp_spec is None: immersed_surface_area = formulae.trivia.sphere_surface( diameter=2 * formulae.trivia.radius(volume=attributes["dry volume"])) else: immersed_surface_area = self.settings.freezing_inp_spec.percentiles( np.random.random(self.settings.n_sd), # TODO #599: seed ) if self.settings.freezing_singular: attributes[ "freezing temperature"] = formulae.freezing_temperature_spectrum.invcdf( np.random.random( self.settings.n_sd), # TODO #599: seed immersed_surface_area, ) else: attributes["immersed surface area"] = immersed_surface_area self.particulator = builder.build(attributes, tuple(products)) if self.SpinUp is not None: self.SpinUp(self.particulator, self.settings.n_spin_up) if self.storage is not None: self.storage.init(self.settings)
def reinit(self): builder = Builder(n_sd=self.setup.n_sd, backend=self.setup.backend) builder.set_environment( MoistEulerian2DKinematic( dt=self.setup.dt, grid=self.setup.grid, size=self.setup.size, stream_function=self.setup.stream_function, field_values=self.setup.field_values, rhod_of=self.setup.rhod, mpdata_iga=self.setup.mpdata_iga, mpdata_tot=self.setup.mpdata_tot, mpdata_fct=self.setup.mpdata_fct, mpdata_iters=self.setup.mpdata_iters)) condensation = Condensation( kappa=self.setup.kappa, rtol_x=self.setup.condensation_rtol_x, rtol_thd=self.setup.condensation_rtol_thd, coord=self.setup.condensation_coord, adaptive=self.setup.adaptive, do_advection=self.setup. processes["fluid advection"], # TODO req. EulerianAdvection do_condensation=self.setup.processes["condensation"] ) # do somthing with that) builder.add_dynamic(condensation) builder.add_dynamic(EulerianAdvection()) if self.setup.processes["particle advection"]: displacement = Displacement( scheme='FTBS', sedimentation=self.setup.processes["sedimentation"]) builder.add_dynamic(displacement) if self.setup.processes["coalescence"]: builder.add_dynamic(Coalescence(kernel=self.setup.kernel)) attributes = {} moist_environment_init( attributes, builder.core.environment, spatial_discretisation=spatial_sampling.pseudorandom, spectral_discretisation=spectral_sampling.constant_multiplicity, spectrum_per_mass_of_dry_air=self.setup. spectrum_per_mass_of_dry_air, r_range=(self.setup.r_min, self.setup.r_max), kappa=self.setup.kappa) products = [ ParticlesWetSizeSpectrum(v_bins=self.setup.v_bins, normalise_by_dv=True), ParticlesDrySizeSpectrum( v_bins=self.setup.v_bins, normalise_by_dv=True), # Note: better v_bins TotalParticleConcentration(), TotalParticleSpecificConcentration(), AerosolConcentration( radius_threshold=self.setup.aerosol_radius_threshold), CloudConcentration( radius_range=(self.setup.aerosol_radius_threshold, self.setup.drizzle_radius_threshold)), DrizzleConcentration( radius_threshold=self.setup.drizzle_radius_threshold), AerosolSpecificConcentration( radius_threshold=self.setup.aerosol_radius_threshold), ParticleMeanRadius(), SuperDropletCount(), RelativeHumidity(), WaterVapourMixingRatio(), DryAirDensity(), DryAirPotentialTemperature(), CondensationTimestep(), # RipeningRate() ] self.core = builder.build(attributes, products) SpinUp(self.core, self.setup.n_spin_up) # TODO if self.storage is not None: self.storage.init(self.setup)
def reinit(self, products=None): builder = Builder(n_sd=self.settings.n_sd, backend=self.backend) environment = Kinematic2D(dt=self.settings.dt, grid=self.settings.grid, size=self.settings.size, rhod_of=self.settings.rhod, field_values=self.settings.field_values) builder.set_environment(environment) products = products or [ ParticlesWetSizeSpectrum(v_bins=self.settings.v_bins, normalise_by_dv=True), ParticlesDrySizeSpectrum( v_bins=self.settings.v_bins, normalise_by_dv=True), # Note: better v_bins TotalParticleConcentration(), TotalParticleSpecificConcentration(), AerosolConcentration( radius_threshold=self.settings.aerosol_radius_threshold), CloudConcentration( radius_range=(self.settings.aerosol_radius_threshold, self.settings.drizzle_radius_threshold)), DrizzleConcentration( radius_threshold=self.settings.drizzle_radius_threshold), AerosolSpecificConcentration( radius_threshold=self.settings.aerosol_radius_threshold), ParticleMeanRadius(), SuperDropletCount(), RelativeHumidity(), Pressure(), Temperature(), WaterVapourMixingRatio(), DryAirDensity(), DryAirPotentialTemperature(), CPUTime(), WallTime() ] fields = Fields(environment, self.settings.stream_function) if self.settings.processes[ 'fluid advection']: # TODO: ambient thermodynamics checkbox builder.add_dynamic(AmbientThermodynamics()) if self.settings.processes["condensation"]: condensation = Condensation( kappa=self.settings.kappa, rtol_x=self.settings.condensation_rtol_x, rtol_thd=self.settings.condensation_rtol_thd, coord=self.settings.condensation_coord, adaptive=self.settings.adaptive) builder.add_dynamic(condensation) products.append(CondensationTimestep() ) # TODO: and what if a user doesn't want it? if self.settings.processes['fluid advection']: solver = MPDATA(fields=fields, n_iters=self.settings.mpdata_iters, infinite_gauge=self.settings.mpdata_iga, flux_corrected_transport=self.settings.mpdata_fct, third_order_terms=self.settings.mpdata_tot) builder.add_dynamic(EulerianAdvection(solver)) if self.settings.processes["particle advection"]: displacement = Displacement( courant_field=fields.courant_field, scheme='FTBS', enable_sedimentation=self.settings.processes["sedimentation"]) builder.add_dynamic(displacement) products.append(SurfacePrecipitation()) # TODO: ditto if self.settings.processes["coalescence"]: builder.add_dynamic(Coalescence(kernel=self.settings.kernel)) attributes = environment.init_attributes( spatial_discretisation=spatial_sampling.Pseudorandom(), spectral_discretisation=spectral_sampling.ConstantMultiplicity( spectrum=self.settings.spectrum_per_mass_of_dry_air), kappa=self.settings.kappa) self.core = builder.build(attributes, products) SpinUp(self.core, self.settings.n_spin_up) # TODO if self.storage is not None: self.storage.init(self.settings)
def reinit(self, products=None): builder = Builder(n_sd=self.settings.n_sd, backend=self.backend, formulae=self.settings.formulae) environment = Kinematic2D(dt=self.settings.dt, grid=self.settings.grid, size=self.settings.size, rhod_of=self.settings.rhod, field_values=self.settings.field_values) builder.set_environment(environment) cloud_range = (self.settings.aerosol_radius_threshold, self.settings.drizzle_radius_threshold) if products is not None: products = list(products) products = products or [ PySDM_products.ParticlesWetSizeSpectrum( v_bins=self.settings.v_bins, normalise_by_dv=True), PySDM_products.ParticlesDrySizeSpectrum( v_bins=self.settings.v_bins, normalise_by_dv=True), # Note: better v_bins PySDM_products.TotalParticleConcentration(), PySDM_products.TotalParticleSpecificConcentration(), PySDM_products.AerosolConcentration( radius_threshold=self.settings.aerosol_radius_threshold), PySDM_products.CloudDropletConcentration(radius_range=cloud_range), PySDM_products.WaterMixingRatio(name='qc', description_prefix='Cloud', radius_range=cloud_range), PySDM_products.WaterMixingRatio( name='qr', description_prefix='Rain', radius_range=(self.settings.drizzle_radius_threshold, np.inf)), PySDM_products.DrizzleConcentration( radius_threshold=self.settings.drizzle_radius_threshold), PySDM_products.AerosolSpecificConcentration( radius_threshold=self.settings.aerosol_radius_threshold), PySDM_products.ParticleMeanRadius(), PySDM_products.SuperDropletCount(), PySDM_products.RelativeHumidity(), PySDM_products.Pressure(), PySDM_products.Temperature(), PySDM_products.WaterVapourMixingRatio(), PySDM_products.DryAirDensity(), PySDM_products.DryAirPotentialTemperature(), PySDM_products.CPUTime(), PySDM_products.WallTime(), PySDM_products.CloudDropletEffectiveRadius( radius_range=cloud_range), PySDM_products.PeakSupersaturation(), PySDM_products.ActivatingRate(), PySDM_products.DeactivatingRate(), PySDM_products.RipeningRate() ] fields = Fields(environment, self.settings.stream_function) if self.settings.processes[ 'fluid advection']: # TODO #37 ambient thermodynamics checkbox builder.add_dynamic(AmbientThermodynamics()) if self.settings.processes["condensation"]: condensation = Condensation( kappa=self.settings.kappa, rtol_x=self.settings.condensation_rtol_x, rtol_thd=self.settings.condensation_rtol_thd, adaptive=self.settings.condensation_adaptive, substeps=self.settings.condensation_substeps, dt_cond_range=self.settings.condensation_dt_cond_range, schedule=self.settings.condensation_schedule) builder.add_dynamic(condensation) products.append(PySDM_products.CondensationTimestepMin() ) # TODO #37 and what if a user doesn't want it? products.append(PySDM_products.CondensationTimestepMax()) if self.settings.processes['fluid advection']: solver = MPDATA(fields=fields, n_iters=self.settings.mpdata_iters, infinite_gauge=self.settings.mpdata_iga, flux_corrected_transport=self.settings.mpdata_fct, third_order_terms=self.settings.mpdata_tot) builder.add_dynamic(EulerianAdvection(solver)) if self.settings.processes["particle advection"]: displacement = Displacement( courant_field=fields.courant_field, enable_sedimentation=self.settings.processes["sedimentation"]) builder.add_dynamic(displacement) products.append( PySDM_products.SurfacePrecipitation()) # TODO #37 ditto if self.settings.processes["coalescence"]: builder.add_dynamic( Coalescence( kernel=self.settings.kernel, adaptive=self.settings.coalescence_adaptive, dt_coal_range=self.settings.coalescence_dt_coal_range, substeps=self.settings.coalescence_substeps, optimized_random=self.settings.coalescence_optimized_random )) products.append(PySDM_products.CoalescenceTimestepMean()) products.append(PySDM_products.CoalescenceTimestepMin()) products.append(PySDM_products.CollisionRate()) products.append(PySDM_products.CollisionRateDeficit()) attributes = environment.init_attributes( spatial_discretisation=spatial_sampling.Pseudorandom(), spectral_discretisation=spectral_sampling.ConstantMultiplicity( spectrum=self.settings.spectrum_per_mass_of_dry_air), kappa=self.settings.kappa) self.core = builder.build(attributes, products) SpinUp(self.core, self.settings.n_spin_up) if self.storage is not None: self.storage.init(self.settings)