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 _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 _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
import sys sys.path.insert(0, "../../bindings/python/") from libcloudphxx import lgrngn from math import exp, log, sqrt, pi import numpy as np opts_init = lgrngn.opts_init_t() opts_init.dt = 1 rhod = 1. * np.ones((1,)) th = 300. * np.ones((1,)) rv = 0.01 * np.ones((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 opts_init.coal_switch = False opts_init.sedi_switch = False
from libcloudphxx import lgrngn from numpy import array as arr_t, frombuffer, repeat, zeros, float64, ones from math import exp, log, sqrt, pi 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); opts_init = lgrngn.opts_init_t() kappa = .61 opts_init.dry_distros = {kappa:lognormal} opts_init.kernel = lgrngn.kernel_t.geometric opts_init.terminal_velocity = lgrngn.vt_t.beard76 opts_init.dt = 1 opts_init.sd_conc = 64 opts_init.n_sd_max = 512 opts_init.rng_seed = 396 opts_init.src_dry_distros = {kappa:lognormal} opts_init.src_sd_conc = 64 opts_init.src_z1 = opts_init.dz print "nx = ", opts_init.nx print "ny = ", opts_init.ny print "nz = ", opts_init.nz
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(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)