def _micro_step(micro, state, info, opts, it, fout): libopts = lgrngn.opts_t() libopts.cond = True libopts.coal = False libopts.adve = False libopts.sedi = False # chemical options if micro.opts_init.chem_switch: # chem processes: dissolving, dissociation, reactions libopts.chem_dsl = opts["chem_dsl"] libopts.chem_dsc = opts["chem_dsc"] libopts.chem_rct = opts["chem_rct"] # get trace gases ambient_chem = {} if micro.opts_init.chem_switch: ambient_chem = dict((v, state[k]) for k,v in _Chem_g_id.iteritems()) # call libcloudphxx microphysics micro.step_sync(libopts, state["th_d"], state["r_v"], state["rhod"], ambient_chem=ambient_chem) micro.step_async(libopts) # update state after microphysics (needed for below update for chemistry) _stats(state, info) # update in state for aqueous chem (TODO do we still want to have aq chem in state?) if micro.opts_init.chem_switch: micro.diag_all() # selecting all particles for id_str, id_int in _Chem_g_id.iteritems(): # save changes due to chemistry micro.diag_chem(id_int) state[id_str.replace('_g', '_a')] = np.frombuffer(micro.outbuf())[0]
def _micro_step(micro, state, info, opts, it): libopts = lgrngn.opts_t() libopts.cond = True libopts.coal = False libopts.adve = False libopts.sedi = False if micro.opts_init.chem_switch: tmp = {} for id_str, id_int in _Chem_g_id.iteritems(): tmp[id_int] = state[id_str] libopts.chem_gas = tmp libopts.chem_dsl = opts["chem_dsl"] libopts.chem_dsc = opts["chem_dsc"] if it < opts["chem_spn"]: libopts.chem_rct = False else: libopts.chem_rct = opts["chem_rct"] micro.step_sync(libopts, state["th_d"], state["r_v"], state["rhod"]) micro.step_async(libopts) _stats(state, info) # give updated T needed for chemistry below if micro.opts_init.chem_switch: micro.diag_all() # selecting all particles for id_str, id_int in _Chem_g_id.iteritems(): if opts['chem_sys'] == 'closed': old = state[id_str.replace('_g', '_a')] micro.diag_chem(id_int) new = np.frombuffer(micro.outbuf()) # since p & rhod are the "new" ones, for consistency we also use new T (_stats called above) state[id_str] -= (new[0] - old) * state["rhod"][0] * common.R * state["T"][0] / _molar_mass[id_int] / state["p"] assert state[id_str] >= 0 state[id_str.replace('_g', '_a')] = new[0] elif opts['chem_sys'] == 'open': micro.diag_chem(id_int) state[id_str.replace('_g', '_a')] = np.frombuffer(micro.outbuf())[0] else: assert False
stdev = 1.4 n_tot = 60e6 return n_tot * exp( -pow((lnr - log(mean_r)), 2) / 2 / pow(log(stdev),2) ) / log(stdev) / sqrt(2*pi); kappa = .61 opts_init.dry_distros = {kappa:lognormal} opts_init.sd_conc = 50 opts_init.n_sd_max = 50 opts_init.coal_switch = False opts_init.sedi_switch = False Opts = lgrngn.opts_t() Opts.adve = True Opts.sedi = False Opts.cond = False Opts.coal = False Opts.chem = False for adve_scheme in [lgrngn.as_t.euler, lgrngn.as_t.implicit, lgrngn.as_t.pred_corr]: opts_init.adve_scheme = adve_scheme try: prtcls = lgrngn.factory(lgrngn.backend_t.OpenMP, opts_init) except: prtcls = lgrngn.factory(lgrngn.backend_t.serial, opts_init) prtcls.init(th, rv, rhod)
print "chem_switch = ", opts_init.chem_switch print "coal_switch = ", opts_init.coal_switch print "sedi_switch = ", opts_init.sedi_switch print "src_switch = ", opts_init.src_switch print "sstp_cond =", opts_init.sstp_cond print "sstp_coal =", opts_init.sstp_coal print "sstp_chem =", opts_init.sstp_chem print "n_sd_max =", opts_init.n_sd_max print lgrngn.backend_t.OpenMP print lgrngn.backend_t.CUDA backend = lgrngn.backend_t.serial opts = lgrngn.opts_t() opts.sedi=0 opts.coal=0 opts.cond=0 opts.adve=1 print "adve =", opts.adve print "sedi =", opts.sedi print "cond =", opts.cond print "coal =", opts.coal print "src =", opts.src print "chem_dsl =", opts.chem_dsl print "chem_dcs =", opts.chem_dsc print "chem_rct =", opts.chem_rct print "RH_max =", opts.RH_max opts.chem_gas = {
def test(turb_cond): print 'turb_cond = ', turb_cond opts_init = lgrngn.opts_init_t() kappa = .61 opts_init.dry_distros = {kappa:lognormal} opts_init.coal_switch=0 opts_init.sedi_switch=0 opts_init.dt = 1 opts_init.sd_conc = 64 opts_init.n_sd_max = 512 opts_init.rng_seed = 396 opts_init.exact_sstp_cond = True # test would fail with per-cell sstp logic opts_init.turb_cond_switch = turb_cond spinup = 20 backend = lgrngn.backend_t.serial opts = lgrngn.opts_t() opts.sedi=0 opts.coal=0 opts.cond=1 opts.turb_cond=turb_cond opts_init.nx = 2 opts_init.dx = 1 opts_init.x1 = opts_init.nx * opts_init.dx opts_init.nz = 1 opts_init.dz = 1 opts_init.z1 = opts_init.nz * opts_init.dz rhod = 1. * ones((opts_init.nx, opts_init.nz)) Cx = 1. * ones((opts_init.nx+1, opts_init.nz)) Cz = 0. * ones((opts_init.nx, opts_init.nz+1)) eps = 1e-4 * ones((opts_init.nx, opts_init.nz)) for sstp_cond in [1,2,5]: print 'sstp_cond = ' + str(sstp_cond) opts.adve=0 opts_init.sstp_cond = sstp_cond prtcls = lgrngn.factory(backend, opts_init) th = 300 * ones((opts_init.nx, opts_init.nz)) rv = .0025 * ones((opts_init.nx, opts_init.nz)) rv[1,0] = 0.0095 prtcls.init(th, rv, rhod, Cx=Cx, Cz=Cz) #equilibrium wet moment post spinup prtcls.diag_all() prtcls.diag_wet_mom(3); wet_post_init = copy(frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) water_post_init = 1000. * 4./3. * pi * wet_post_init + rv #spinup to get equilibrium if(turb_cond): prtcls.step_sync(opts, th, rv, diss_rate=eps) else: prtcls.step_sync(opts, th, rv) for it in range(spinup): prtcls.step_async(opts) if(turb_cond): prtcls.step_sync(opts, th, rv, diss_rate=eps) else: prtcls.step_sync(opts, th, rv) #equilibrium wet moment post spinup prtcls.diag_all() prtcls.diag_wet_mom(3); wet_post_spin = copy(frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) water_post_spin = 1000. * 4./3. * pi * wet_post_spin + rv assert allclose(water_post_spin, water_post_init, atol=0, rtol=1e-10) #some discrepancy due to water density #advect SDs opts.adve=1 prtcls.step_async(opts) #equilibrium wet moment post adve prtcls.diag_all() prtcls.diag_wet_mom(3); wet_post_adve = copy(frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) wet_post_adve_roll = roll(wet_post_adve,1).copy() assert all(wet_post_adve_roll == wet_post_spin) #advect rv tmp = rv.copy() rv[0,0] = tmp[1,0] rv[1,0] = tmp[0,0] #advect th tmp = th.copy() th[0,0] = tmp[1,0] th[1,0] = tmp[0,0] #condensation with advected SDs and rv if(turb_cond): prtcls.step_sync(opts, th, rv, diss_rate=eps) else: prtcls.step_sync(opts, th, rv) #wet mom post adve and cond prtcls.diag_all() prtcls.diag_wet_mom(3); wet_post_adve_cond = copy(frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) assert allclose(wet_post_adve, wet_post_adve_cond, atol=0, rtol=3e-2)
def test(opts_init): opts_init.supstp_src = 50 opts_init.rng_seed = int(time()) opts_init.dt = 1 opts_init.nx = 2 opts_init.nz = 2 opts_init.dx = 1. opts_init.dz = 1. opts_init.x0 = 0. opts_init.z0 = 0. opts_init.x1 = opts_init.nx * opts_init.dx opts_init.z1 = opts_init.nz * opts_init.dz opts_init.src_z0 = 0 opts_init.src_z1 = opts_init.dz #create aerosol only in the lower cells opts_init.src_x0 = 0 opts_init.src_x1 = opts_init.dx * opts_init.nx opts_init.chem_switch = 0 opts_init.coal_switch = 0 opts_init.adve_switch = 0 opts_init.cond_switch = 0 opts_init.sedi_switch = 0 opts = lgrngn.opts_t() opts.adve = 0 opts.chem = 0 opts.sedi = 0 opts.coal = 0 opts.cond = 0 rhod = arr_t([[1., 1.], [1., 1.]]) th = arr_t([[300., 300.], [300., 300.]]) rv = arr_t([[.01, .01], [.01, .01]]) try: prtcls = lgrngn.factory(lgrngn.backend_t.OpenMP, opts_init) except: prtcls = lgrngn.factory(lgrngn.backend_t.serial, opts_init) prtcls.init(th, rv, rhod) # 100 steps during which number of droplets should be doubled in two calls to src opts.src = 1 for i in range(100): prtcls.step_sync(opts, th, rv, rhod) prtcls.step_async(opts) prtcls.diag_all() prtcls.diag_sd_conc() sd_conc = frombuffer(prtcls.outbuf()).copy() prtcls.diag_all() prtcls.diag_wet_mom(0) wet_mom0 = frombuffer(prtcls.outbuf()).copy() prtcls.diag_all() prtcls.diag_wet_mom(1) wet_mom1 = frombuffer(prtcls.outbuf()).copy() return sd_conc, wet_mom0, wet_mom1
def test(turb_cond): print 'turb_cond = ', turb_cond opts_init = lgrngn.opts_init_t() kappa = .61 opts_init.dry_distros = {kappa: lognormal} opts_init.coal_switch = 0 opts_init.sedi_switch = 0 opts_init.dt = 1 opts_init.sd_conc = 64 opts_init.n_sd_max = 512 opts_init.rng_seed = 396 opts_init.exact_sstp_cond = True # test would fail with per-cell sstp logic opts_init.turb_cond_switch = turb_cond spinup = 20 backend = lgrngn.backend_t.serial opts = lgrngn.opts_t() opts.sedi = 0 opts.coal = 0 opts.cond = 1 opts.turb_cond = turb_cond opts_init.nx = 2 opts_init.dx = 1 opts_init.x1 = opts_init.nx * opts_init.dx opts_init.nz = 1 opts_init.dz = 1 opts_init.z1 = opts_init.nz * opts_init.dz rhod = 1. * ones((opts_init.nx, opts_init.nz)) Cx = 1. * ones((opts_init.nx + 1, opts_init.nz)) Cz = 0. * ones((opts_init.nx, opts_init.nz + 1)) eps = 1e-4 * ones((opts_init.nx, opts_init.nz)) for sstp_cond in [1, 2, 5]: print 'sstp_cond = ' + str(sstp_cond) opts.adve = 0 opts_init.sstp_cond = sstp_cond prtcls = lgrngn.factory(backend, opts_init) th = 300 * ones((opts_init.nx, opts_init.nz)) rv = .0025 * ones((opts_init.nx, opts_init.nz)) rv[1, 0] = 0.0095 prtcls.init(th, rv, rhod, Cx=Cx, Cz=Cz) #equilibrium wet moment post spinup prtcls.diag_all() prtcls.diag_wet_mom(3) wet_post_init = copy( frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) water_post_init = 1000. * 4. / 3. * pi * wet_post_init + rv #spinup to get equilibrium if (turb_cond): prtcls.step_sync(opts, th, rv, diss_rate=eps) else: prtcls.step_sync(opts, th, rv) for it in range(spinup): prtcls.step_async(opts) if (turb_cond): prtcls.step_sync(opts, th, rv, diss_rate=eps) else: prtcls.step_sync(opts, th, rv) #equilibrium wet moment post spinup prtcls.diag_all() prtcls.diag_wet_mom(3) wet_post_spin = copy( frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) water_post_spin = 1000. * 4. / 3. * pi * wet_post_spin + rv assert allclose(water_post_spin, water_post_init, atol=0, rtol=1e-10) #some discrepancy due to water density #advect SDs opts.adve = 1 prtcls.step_async(opts) #equilibrium wet moment post adve prtcls.diag_all() prtcls.diag_wet_mom(3) wet_post_adve = copy( frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) wet_post_adve_roll = roll(wet_post_adve, 1).copy() assert all(wet_post_adve_roll == wet_post_spin) #advect rv tmp = rv.copy() rv[0, 0] = tmp[1, 0] rv[1, 0] = tmp[0, 0] #advect th tmp = th.copy() th[0, 0] = tmp[1, 0] th[1, 0] = tmp[0, 0] #condensation with advected SDs and rv if (turb_cond): prtcls.step_sync(opts, th, rv, diss_rate=eps) else: prtcls.step_sync(opts, th, rv) #wet mom post adve and cond prtcls.diag_all() prtcls.diag_wet_mom(3) wet_post_adve_cond = copy( frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) assert allclose(wet_post_adve, wet_post_adve_cond, atol=0, rtol=3e-2)
def test(opts_init): opts_init.supstp_rlx = 2 opts_init.rng_seed = int(time()) opts_init.dt = 1 opts_init.nx = 2; opts_init.nz = 2; opts_init.dx=1.; opts_init.dz=1.; opts_init.x0=0.; opts_init.z0=0.; opts_init.x1=opts_init.nx * opts_init.dx; opts_init.z1=opts_init.nz * opts_init.dz; opts_init.aerosol_independent_of_rhod=1; opts_init.y0=0.; opts_init.y1=1.; opts_init.chem_switch = 0; opts_init.coal_switch = 0; opts_init.adve_switch = 0; opts_init.cond_switch = 0; opts_init.sedi_switch = 0; opts_init.rlx_switch = 1; opts = lgrngn.opts_t() opts.adve = 0; opts.chem = 0; opts.sedi = 0; opts.coal = 0; opts.cond = 0; rhod = arr_t([[ 1., 1. ],[ 1., 1. ]]) th = arr_t([[300., 300. ],[ 300., 300. ]]) rv = arr_t([[ .01, .01],[ .01, .01]]) try: prtcls = lgrngn.factory(lgrngn.backend_t.OpenMP, opts_init) except: prtcls = lgrngn.factory(lgrngn.backend_t.serial, opts_init) prtcls.init(th, rv, rhod) # 2 steps during which relaxation should be done once opts.rlx = 1 for i in range(2): prtcls.step_sync(opts,th,rv,rhod) prtcls.step_async(opts) prtcls.diag_all() prtcls.diag_sd_conc() sd_conc = frombuffer(prtcls.outbuf()).copy() prtcls.diag_all() prtcls.diag_wet_mom(0) wet_mom0 = frombuffer(prtcls.outbuf()).copy() prtcls.diag_all() prtcls.diag_wet_mom(1) wet_mom1 = frombuffer(prtcls.outbuf()).copy() return sd_conc, wet_mom0, wet_mom1