def _micro_init(opts, state, info): # sanity check _stats(state, info) if (state["RH"] > 1): raise Exception("Please supply initial T,p,r_v below supersaturation") # using nested function to get access to opts def lognormal(lnr): from math import exp, log, sqrt, pi return opts["n_tot"] * exp( -(lnr - log(opts["mean_r"]))**2 / 2 / log(opts["gstdev"])**2 ) / log(opts["gstdev"]) / sqrt(2*pi); # lagrangian scheme options opts_init = lgrngn.opts_init_t() for opt in ["dt",]: setattr(opts_init, opt, opts[opt]) opts_init.sd_conc = opts["sd_conc"] opts_init.dry_distros = {opts["kappa"]:lognormal} opts_init.kernel = lgrngn.kernel_t.geometric #TODO: will not be needed soon (libcloud PR #89) opts_init.chem_rho = opts["chem_rho"] # switch off sedimentation and collisions opts_init.sedi_switch = False opts_init.coal_switch = False # switching on chemistry if either dissolving, dissociation or reactions are chosen opts_init.chem_switch = False if opts["chem_dsl"] or opts["chem_dsc"] or opts["chem_rct"]: opts_init.chem_switch = True # initialisation micro = lgrngn.factory(lgrngn.backend_t.serial, opts_init) micro.init(state["th_d"], state["r_v"], state["rhod"]) return micro
def test(RH_formula, step_count, substep_count, exact_substep, constp): print "[RH_formula = ", RH_formula, "]" print "step_count = ", step_count, " substep_count = ", substep_count, "exact substepping = ", exact_substep, "constp = ", constp opts_init.sstp_cond = substep_count opts_init.exact_sstp_cond = exact_substep opts_init.RH_formula = RH_formula rhod, th, rv, p = initial_state() rv_init = rv.copy() # in constp mode, th_std is expected instead of th_dry if constp == True: # dry/std conversions assume p = rhod (Rd + rv * Rv) T # which in general is not true in constp, but is true at init so we use it here th[0] = common.th_dry2std(th[0], rv[0]) th_init = th.copy() prtcls = lgrngn.factory(backend, opts_init) if constp == False: prtcls.init(th, rv, rhod) else: prtcls.init(th, rv, rhod, p) ss = supersaturation(prtcls) print "initial supersaturation", ss exectime = 0 # first step without condesnation just to see diag output opts.cond = False for step in arange(step_count): wrapped = wrapper(prtcls.step_sync, opts, th, rv, rhod) exectime += timeit.timeit(wrapped, number=1) prtcls.step_async(opts) opts.cond = True # print step, supersaturation(prtcls), temperature(prtcls), pressure(prtcls), th[0], rv[0] ss_post_cond = supersaturation(prtcls) print "supersaturation after condensation", ss_post_cond, th[0], rv[0] assert (abs(th[0] - exp_th[constp]) < 1e-4 * exp_th[constp]) assert (abs(rv[0] - exp_rv[constp]) < 1e-3 * exp_rv[constp]) rv_diff = rv_init.copy() - rv[0].copy() # change to subsaturated air - test evaporation rv[0] = 0.002 rv_init = rv.copy() for step in arange(step_count): wrapped = wrapper(prtcls.step_sync, opts, th, rv, rhod) exectime += timeit.timeit(wrapped, number=1) prtcls.step_async(opts) # print step, supersaturation(prtcls), temperature(prtcls), pressure(prtcls), th[0], rv[0] ss_post_evap = supersaturation(prtcls) print "supersaturation after evaporation", ss_post_evap, th[0], rv[0] print 'execution time: ', exectime return ss_post_cond, th[0] - th_init[0], rv[0] - rv_init[0] - rv_diff[0]
def advection_1step(Cx_arg, Cz_arg, backend=Backend, opts_init=Opts_init, opts=Opts, rhod=Rhod, th=Th, rv=Rv): prtcls = lgrngn.factory(backend, opts_init) Cx = Cx_arg * np.ones((opts_init.nx + 1, opts_init.nz)) Cz = Cz_arg * np.ones((opts_init.nx, opts_init.nz + 1)) prtcls.init(th, rv, rhod, Cx=Cx, Cz=Cz) prtcls.step_sync(opts, th, rv, rhod) #prtcls.diag_wet_rng(0,1) prtcls.diag_all() prtcls.diag_sd_conc() tab_in = np.copy( np.frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) print("tab_in \n", tab_in) prtcls.step_async(opts) prtcls.step_sync(opts, th, rv, rhod) #prtcls.diag_wet_rng(0,1) prtcls.diag_all() prtcls.diag_sd_conc() tab_out = np.copy( np.frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) print("tab_out \n", tab_out, np.roll(tab_out, -1, 0)) return tab_in, tab_out
def test(RH_formula, step_count, substep_count, exact_substep, constp): print "[RH_formula = ", RH_formula,"]" print "step_count = ", step_count, " substep_count = ", substep_count, "exact substepping = ", exact_substep, "constp = ", constp opts_init.sstp_cond=substep_count opts_init.exact_sstp_cond=exact_substep opts_init.RH_formula = RH_formula rhod, th, rv, p = initial_state() rv_init = rv.copy() # in constp mode, th_std is expected instead of th_dry if constp == True: # dry/std conversions assume p = rhod (Rd + rv * Rv) T # which in general is not true in constp, but is true at init so we use it here th[0] = common.th_dry2std(th[0], rv[0]) th_init = th.copy() prtcls = lgrngn.factory(backend, opts_init) if constp == False: prtcls.init(th, rv, rhod) else: prtcls.init(th, rv, rhod, p) ss = supersaturation(prtcls) print "initial supersaturation", ss exectime = 0 # first step without condesnation just to see diag output opts.cond = False for step in arange(step_count): wrapped = wrapper(prtcls.step_sync, opts, th, rv, rhod) exectime += timeit.timeit(wrapped, number=1) prtcls.step_async(opts) opts.cond = True # print step, supersaturation(prtcls), temperature(prtcls), pressure(prtcls), th[0], rv[0] ss_post_cond = supersaturation(prtcls) print "supersaturation after condensation", ss_post_cond, th[0], rv[0] assert(abs(th[0] - exp_th[constp]) < 1e-4 * exp_th[constp]) assert(abs(rv[0] - exp_rv[constp]) < 1e-3 * exp_rv[constp]) rv_diff = rv_init.copy() - rv[0].copy() # change to subsaturated air - test evaporation rv[0] = 0.002 rv_init = rv.copy() for step in arange(step_count): wrapped = wrapper(prtcls.step_sync, opts, th, rv, rhod) exectime += timeit.timeit(wrapped, number=1) prtcls.step_async(opts) # print step, supersaturation(prtcls), temperature(prtcls), pressure(prtcls), th[0], rv[0] ss_post_evap = supersaturation(prtcls) print "supersaturation after evaporation", ss_post_evap, th[0], rv[0] print 'execution time: ', exectime return ss_post_cond, th[0] - th_init[0], rv[0] - rv_init[0] - rv_diff[0]
def _micro_init(aerosol, opts, state, info): # lagrangian scheme options opts_init = lgrngn.opts_init_t() for opt in ["dt", "sd_conc", "chem_rho", "sstp_cond"]: setattr(opts_init, opt, opts[opt]) opts_init.n_sd_max = opts_init.sd_conc # read in the initial aerosol size distribution dry_distros = {} for name, dct in aerosol.items(): # loop over kappas lognormals = [] for i in range(len(dct["mean_r"])): lognormals.append( lognormal(dct["mean_r"][i], dct["gstdev"][i], dct["n_tot"][i])) dry_distros[dct["kappa"]] = sum_of_lognormals(lognormals) opts_init.dry_distros = dry_distros # better resolution for the SD tail if opts["large_tail"]: opts_init.sd_conc_large_tail = 1 opts_init.n_sd_max = int(1e6) # some more space for the tail SDs # switch off sedimentation and collisions opts_init.sedi_switch = False opts_init.coal_switch = False # switching on chemistry if either dissolving, dissociation or reactions are chosen opts_init.chem_switch = False if opts["chem_dsl"] or opts["chem_dsc"] or opts["chem_rct"]: opts_init.chem_switch = True opts_init.sstp_chem = opts["sstp_chem"] # initialisation micro = lgrngn.factory(lgrngn.backend_t.serial, opts_init) ambient_chem = {} if micro.opts_init.chem_switch: ambient_chem = dict((v, state[k]) for k, v in _Chem_g_id.items()) micro.init(state["th_d"], state["r_v"], state["rhod"], ambient_chem=ambient_chem) # sanity check _stats(state, info) if (state["RH"] > 1): raise Exception("Please supply initial T,p,r_v below supersaturation") return micro
def _micro_init(aerosol, opts, state, info): # lagrangian scheme options opts_init = lgrngn.opts_init_t() for opt in ["dt", "sd_conc", "chem_rho", "sstp_cond"]: setattr(opts_init, opt, opts[opt]) opts_init.n_sd_max = opts_init.sd_conc # read in the initial aerosol size distribution dry_distros = {} for name, dct in aerosol.iteritems(): # loop over kappas lognormals = [] for i in range(len(dct["mean_r"])): lognormals.append(lognormal(dct["mean_r"][i], dct["gstdev"][i], dct["n_tot"][i])) dry_distros[dct["kappa"]] = sum_of_lognormals(lognormals) opts_init.dry_distros = dry_distros # better resolution for the SD tail if opts["large_tail"]: opts_init.sd_conc_large_tail = 1 opts_init.n_sd_max = int(1e6) # some more space for the tail SDs # switch off sedimentation and collisions opts_init.sedi_switch = False opts_init.coal_switch = False # switching on chemistry if either dissolving, dissociation or reactions are chosen opts_init.chem_switch = False if opts["chem_dsl"] or opts["chem_dsc"] or opts["chem_rct"]: opts_init.chem_switch = True opts_init.sstp_chem = opts["sstp_chem"] # initialisation micro = lgrngn.factory(lgrngn.backend_t.serial, opts_init) ambient_chem = {} if micro.opts_init.chem_switch: ambient_chem = dict((v, state[k]) for k,v in _Chem_g_id.iteritems()) micro.init(state["th_d"], state["r_v"], state["rhod"], ambient_chem=ambient_chem) # sanity check _stats(state, info) if (state["RH"] > 1): raise Exception("Please supply initial T,p,r_v below supersaturation") return micro
def advection_1step(Cx_arg, Cz_arg, backend=Backend, opts_init=Opts_init, opts=Opts, rhod=Rhod, th=Th, rv=Rv): prtcls = lgrngn.factory(backend, opts_init) Cx = Cx_arg * np.ones((opts_init.nx + 1, opts_init.nz)) Cz = Cz_arg * np.ones((opts_init.nx, opts_init.nz + 1)) prtcls.init(th, rv, rhod, Cx, Cz) prtcls.step_sync(opts, th, rv, rhod) #prtcls.diag_wet_rng(0,1) prtcls.diag_sd_conc() tab_in = np.copy(np.frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz)) print "tab_in \n", tab_in prtcls.step_async(opts) prtcls.step_sync(opts, th, rv, rhod) #prtcls.diag_wet_rng(0,1) prtcls.diag_sd_conc() tab_out = np.frombuffer(prtcls.outbuf()).reshape(opts_init.nx, opts_init.nz) print "tab_out \n", tab_out, np.roll(tab_out, -1, 0) return tab_in, tab_out
def _micro_init(opts, state, info): # sanity check _stats(state, info) if (state["RH"] > 1): raise Exception("Please supply initial T,p,r_v below supersaturation") # using nested function to get access to opts def lognormal(lnr): from math import exp, log, sqrt, pi return opts["n_tot"] * exp( -(lnr - log(opts["mean_r"]))**2 / 2 / log(opts["gstdev"])**2 ) / log(opts["gstdev"]) / sqrt(2*pi); # lagrangian scheme options opts_init = lgrngn.opts_init_t() for opt in ["dt", "sd_conc", "chem_rho", "sstp_cond"]: setattr(opts_init, opt, opts[opt]) opts_init.n_sd_max = opts_init.sd_conc opts_init.dry_distros = {opts["kappa"]:lognormal} # switch off sedimentation and collisions opts_init.sedi_switch = False opts_init.coal_switch = False # switching on chemistry if either dissolving, dissociation or reactions are chosen opts_init.chem_switch = False if opts["chem_dsl"] or opts["chem_dsc"] or opts["chem_rct"]: opts_init.chem_switch = True opts_init.sstp_chem = opts["sstp_chem"] # initialisation micro = lgrngn.factory(lgrngn.backend_t.serial, opts_init) ambient_chem = {} if micro.opts_init.chem_switch: ambient_chem = dict((v, state[k]) for k,v in _Chem_g_id.iteritems()) micro.init(state["th_d"], state["r_v"], state["rhod"], ambient_chem=ambient_chem) return micro
Backend = lgrngn.backend_t.serial Opts = lgrngn.opts_t() Opts.adve = False Opts.sedi = False Opts.subs = True Opts.cond = False Opts.coal = False Opts.chem = False Opts.rcyc = False Rhod = 1. * np.ones((Opts_init.nx, Opts_init.nz)) Th = 300. * np.ones((Opts_init.nx, Opts_init.nz)) Rv = 0.01 * np.ones((Opts_init.nx, Opts_init.nz)) prtcls = lgrngn.factory(Backend, Opts_init) prtcls.init(Th, Rv, Rhod) prtcls.diag_all() prtcls.diag_sd_conc() tab_in = np.copy( np.frombuffer(prtcls.outbuf()).reshape(Opts_init.nx, Opts_init.nz)) print("at init \n", tab_in) for it in range(100): prtcls.step_sync(Opts, Th, Rv, Rhod) prtcls.step_async(Opts) prtcls.diag_all() prtcls.diag_sd_conc() tab_out = np.copy(
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) prtcls.step_sync(Opts,th,rv,rhod) prtcls.step_async(Opts)
m1 = frombuffer(prtcls.outbuf())[0] prtcls.diag_incloud_time_mom(0) m0 = frombuffer(prtcls.outbuf())[0] return m1 / m0 def initial_state(): rhod = arr_t([1.]) th = arr_t([300.]) rv = arr_t([0.009 - 0.00005]) return rhod, th, rv rhod, th, rv = initial_state() prtcls = lgrngn.factory(backend, opts_init) prtcls.init(th, rv, rhod) #ss = supersaturation(prtcls) #print "initial supersaturation", ss # first step without condesnation just to see diag output opts.cond = True for step in arange(400): rv[0] += 0.00001 * opts_init.dt prtcls.sync_in(th, rv, rhod) # ss_post_add = supersaturation(prtcls) # print "supersaturation after increaseing rv", ss_post_add prtcls.step_cond(opts, th, rv)
opts.chem_gas = { lgrngn.chem_species_t.SO2 : 44, lgrngn.chem_species_t.O3 : 44, lgrngn.chem_species_t.H2O2 : 44 } print "chem_gas[SO2] = ", opts.chem_gas[lgrngn.chem_species_t.SO2] print "chem_gas = ", opts.chem_gas # 0D (parcel) print "0D" rhod = arr_t([ 1.]) th = arr_t([300.]) rv = arr_t([ 0.01]) prtcls = lgrngn.factory(backend, opts_init) prtcls.init(th, rv, rhod) try: prtcls.init(th, rv, rhod) raise Exception("multiple init call not reported!") except: pass prtcls.step_sync(opts, th, rv, rhod) try: prtcls.step_sync(opts, th, rv, rhod) raise Exception("sync/async order mismatch not reported!") except: pass rain = prtcls.step_async(opts) prtcls.step_sync(opts, th, rv) prtcls.diag_dry_rng(0.,1.)
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)
opts_init.dt = 1 def lognormal(lnr): mean_r = .04e-6 / 2 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 try: prtcls = lgrngn.factory( lgrngn.backend_t.OpenMP, opts_init ) # the segfault actually was detected on CUDA, but we don't have yet a mechanism do detect if CUDA hardware is present (e.g. on Travis) except: prtcls = lgrngn.factory(lgrngn.backend_t.serial, opts_init) rhod = 1. * np.ones((1, )) th = 300. * np.ones((1, )) rv = 0.01 * np.ones((1, )) prtcls.init(th, rv, rhod)
def test(RH_formula, step_count, substep_count, exact_substep, constp): print("[RH_formula = ", RH_formula, "]") print("step_count = ", step_count, " substep_count = ", substep_count, "exact substepping = ", exact_substep, "constp = ", constp) opts_init.sstp_cond = substep_count opts_init.exact_sstp_cond = exact_substep opts_init.RH_formula = RH_formula rhod, th, rv, p = initial_state() rhod_ss, th_ss, rv_ss, p_ss = supersat_state() # in constp mode, th_std is expected instead of th_dry if constp == True: # dry/std conversions assume p = rhod (Rd + rv * Rv) T # which in general is not true in constp, but is true at init so we use it here th[0] = common.th_dry2std(th[0], rv[0]) th_ss[0] = common.th_dry2std(th_ss[0], rv_ss[0]) prtcls = lgrngn.factory(backend, opts_init) if constp == False: prtcls.init(th, rv, rhod) else: prtcls.init(th, rv, rhod, p_ss) # go to supersaturated air, density changes to test density substepping too rhod[0] = rhod_ss th[0] = th_ss rv[0] = rv_ss rv_init = rv.copy() th_init = th.copy() exectime = 0 opts.cond = 0 for step in arange(step_count): wrapped = wrapper(prtcls.step_sync, opts, th, rv, rhod) exectime += timeit.timeit(wrapped, number=1) prtcls.step_async(opts) if step == 9: # some parameters are analyzed after 10 steps, before small CCNs evaporate act_conc_post_cond = act_conc(prtcls) mean_r_post_cond = mean_r(prtcls) second_r_post_cond = second_r(prtcls) third_r_post_cond = third_r(prtcls) if step == 0: print("initial supersaturation", supersaturation(prtcls)) opts.cond = 1 # print step, supersaturation(prtcls), th[0], rv[0], mean_r(prtcls), second_r(prtcls), third_r(prtcls), act_conc(prtcls) ss_post_cond = supersaturation(prtcls) print("supersaturation after condensation", ss_post_cond, th[0], rv[0], mean_r(prtcls), second_r(prtcls), third_r(prtcls), act_conc(prtcls)) assert (abs(th[0] - exp_th[constp]) < 1e-4 * exp_th[constp]) assert (abs(rv[0] - exp_rv[constp]) < 1e-3 * exp_rv[constp]) rv_diff = rv_init.copy() - rv[0].copy() th_diff = th_init.copy() - th[0].copy() # change to subsaturated air - test evaporation rhod[0] = 1.1 th[0] = 305 rv[0] = 0.0085 rv_init = rv.copy() th_init = th.copy() for step in arange(step_count): wrapped = wrapper(prtcls.step_sync, opts, th, rv, rhod) exectime += timeit.timeit(wrapped, number=1) prtcls.step_async(opts) # print step, supersaturation(prtcls), th[0], rv[0], mean_r(prtcls), second_r(prtcls), third_r(prtcls), act_conc(prtcls) ss_post_evap = supersaturation(prtcls) print("supersaturation after evaporation", ss_post_evap, th[0], rv[0], mean_r(prtcls), second_r(prtcls), third_r(prtcls), act_conc(prtcls), gccn_conc(prtcls)) # after evaporation, only larger mode particles should have r > 0.5 microns assert (act_conc(prtcls) == gccn_conc(prtcls)) print('execution time: ', exectime) return ss_post_cond, th[0] - th_init[0] - th_diff[0], rv[0] - rv_init[ 0] - rv_diff[ 0], act_conc_post_cond, mean_r_post_cond, second_r_post_cond, third_r_post_cond
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
Backend = lgrngn.backend_t.serial Opts = lgrngn.opts_t() Opts.adve = False Opts.sedi = True Opts.cond = False Opts.coal = False Opts.chem = False Opts.rcyc = False Rhod = 1. * np.ones((Opts_init.nx, Opts_init.nz)) Th = 300. * np.ones((Opts_init.nx, Opts_init.nz)) Rv = 0.01 * np.ones((Opts_init.nx, Opts_init.nz)) prtcls = lgrngn.factory(Backend, Opts_init) prtcls.init(Th, Rv, Rhod) prtcls.diag_all() prtcls.diag_sd_conc() tab_in = np.copy(np.frombuffer(prtcls.outbuf()).reshape(Opts_init.nx, Opts_init.nz)) print "at init \n", tab_in for it in range(100): prtcls.step_sync(Opts, Th, Rv, Rhod) prtcls.step_async(Opts) prtcls.diag_all() prtcls.diag_sd_conc() tab_out = np.copy(np.frombuffer(prtcls.outbuf()).reshape(Opts_init.nx, Opts_init.nz)) print "after 1s \n", tab_out
kappa = .61 opts_init.dry_distros = {kappa:lognormal} opts_init.sd_conc = 50 opts_init.n_sd_max = 50 opts_init.kernel = lgrngn.kernel_t.geometric Opts = lgrngn.opts_t() Opts.adve = False Opts.sedi = False Opts.cond = False Opts.coal = True Opts.chem = False for vt_eq in [lgrngn.vt_t.beard76, lgrngn.vt_t.beard77, lgrngn.vt_t.beard77fast, lgrngn.vt_t.khvorostyanov_spherical, lgrngn.vt_t.khvorostyanov_nonspherical]: opts_init.terminal_velocity = vt_eq 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) prtcls.step_sync(Opts,th,rv,rhod) prtcls.step_async(Opts)
Opts_init.dev_count = 2 Opts = lgrngn.opts_t() Opts.adve = False Opts.sedi = True Opts.cond = False Opts.coal = False Opts.chem = False Opts.rcyc = False Rhod = 1. * np.ones((Opts_init.nx, Opts_init.nz)) Th = 300. * np.ones((Opts_init.nx, Opts_init.nz)) Rv = 0.01 * np.ones((Opts_init.nx, Opts_init.nz)) try: prtcls = lgrngn.factory(lgrngn.backend_t.multi_CUDA, Opts_init) except: prtcls = lgrngn.factory(lgrngn.backend_t.serial, Opts_init) prtcls.init(Th, Rv, Rhod) for it in range(10): prtcls.step_sync(Opts, Th, Rv, Rhod) prtcls.step_async(Opts) puddle = prtcls.diag_puddle() prtcls.diag_all() prtcls.diag_sd_conc() tab_out = np.copy( np.frombuffer(prtcls.outbuf()).reshape(Opts_init.nx, Opts_init.nz))
def test(RH_formula, step_count, substep_count, exact_substep, constp): print "[RH_formula = ", RH_formula,"]" print "step_count = ", step_count, " substep_count = ", substep_count, "exact substepping = ", exact_substep, "constp = ", constp opts_init.sstp_cond=substep_count opts_init.exact_sstp_cond=exact_substep opts_init.RH_formula = RH_formula rhod, th, rv, p = initial_state() rhod_ss, th_ss, rv_ss, p_ss = supersat_state() # in constp mode, th_std is expected instead of th_dry if constp == True: # dry/std conversions assume p = rhod (Rd + rv * Rv) T # which in general is not true in constp, but is true at init so we use it here th[0] = common.th_dry2std(th[0], rv[0]) th_ss[0] = common.th_dry2std(th_ss[0], rv_ss[0]) prtcls = lgrngn.factory(backend, opts_init) if constp == False: prtcls.init(th, rv, rhod) else: prtcls.init(th, rv, rhod, p_ss) # go to supersaturated air, density changes to test density substepping too rhod[0] = rhod_ss th[0] = th_ss rv[0] = rv_ss rv_init = rv.copy() th_init = th.copy() exectime = 0 opts.cond = 0 for step in arange(step_count): wrapped = wrapper(prtcls.step_sync, opts, th, rv, rhod) exectime += timeit.timeit(wrapped, number=1) prtcls.step_async(opts) if step == 9: # some parameters are analyzed after 10 steps, before small CCNs evaporate act_conc_post_cond = act_conc(prtcls) mean_r_post_cond = mean_r(prtcls) second_r_post_cond = second_r(prtcls) third_r_post_cond = third_r(prtcls) if step == 0: print "initial supersaturation", supersaturation(prtcls) opts.cond = 1 # print step, supersaturation(prtcls), th[0], rv[0], mean_r(prtcls), second_r(prtcls), third_r(prtcls), act_conc(prtcls) ss_post_cond = supersaturation(prtcls) print "supersaturation after condensation", ss_post_cond, th[0], rv[0], mean_r(prtcls), second_r(prtcls), third_r(prtcls), act_conc(prtcls) assert(abs(th[0] - exp_th[constp]) < 1e-4 * exp_th[constp]) assert(abs(rv[0] - exp_rv[constp]) < 1e-3 * exp_rv[constp]) rv_diff = rv_init.copy() - rv[0].copy() th_diff = th_init.copy() - th[0].copy() # change to subsaturated air - test evaporation rhod[0] = 1.1 th[0] = 305 rv[0] = 0.0085 rv_init = rv.copy() th_init = th.copy() for step in arange(step_count): wrapped = wrapper(prtcls.step_sync, opts, th, rv, rhod) exectime += timeit.timeit(wrapped, number=1) prtcls.step_async(opts) # print step, supersaturation(prtcls), th[0], rv[0], mean_r(prtcls), second_r(prtcls), third_r(prtcls), act_conc(prtcls) ss_post_evap = supersaturation(prtcls) print "supersaturation after evaporation", ss_post_evap, th[0], rv[0], mean_r(prtcls), second_r(prtcls), third_r(prtcls), act_conc(prtcls), gccn_conc(prtcls) # after evaporation, only larger mode particles should have r > 0.5 microns assert(act_conc(prtcls) == gccn_conc(prtcls)) print 'execution time: ', exectime return ss_post_cond, th[0] - th_init[0] - th_diff[0], rv[0] - rv_init[0] - rv_diff[0], act_conc_post_cond, mean_r_post_cond, second_r_post_cond, third_r_post_cond
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
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)
opts_init = lgrngn.opts_init_t() opts_init.coal_switch = False opts_init.sedi_switch = False opts_init.dt = 1 def lognormal(lnr): mean_r = .04e-6 / 2 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 try: prtcls = lgrngn.factory(lgrngn.backend_t.OpenMP, opts_init) # the segfault actually was detected on CUDA, but we don't have yet a mechanism do detect if CUDA hardware is present (e.g. on Travis) except: prtcls = lgrngn.factory(lgrngn.backend_t.serial, opts_init) rhod = 1. * np.ones((1,)) th = 300. * np.ones((1,)) rv = 0.01 * np.ones((1,)) prtcls.init(th, rv, rhod)