Пример #1
0
def data(request):
    # initial values                                        
    RH_init = .99999
    T_init  = 280.
    p_init  = 100000.
    r_init  = common.eps * RH_init * common.p_vs(T_init) / (p_init - RH_init * common.p_vs(T_init))
    # lists to store RH_max and N at the end of the simulation from each test run 
    RH_list = []
    N_list  = []

    for dt in Dt_list:
        print "\nt time step", dt
        outfile_nc = "timesteptest_dt=" + str(dt) + ".nc" 
        parcel(dt=dt, outfreq = int(100/dt),   outfile = outfile_nc,\
                w = 1., T_0 = T_init, p_0 = p_init, r_0 = r_init, z_max = 200, \
                mean_r = 5e-8, gstdev = 1.5, n_tot = 1e9, sd_conc = 1000, \
                out_bin = '{"radii": {"rght": 1, "moms": [0], "drwt": "wet", "nbin": 1, "lnli": "lin", "left": 1e-06}}'
              )

        f_out  = netcdf.netcdf_file(outfile_nc, "r")
        RH_max = f_out.RH_max
        N_end  = f_out.variables["radii_m0"][-1,0] # concentration of drops > 1e-6 m
    
        RH_list.append((RH_max - 1)*100)  # [%]                                      
        N_list.append(N_end / 1e6)        # [1/mg]           

    data = {"RH" : RH_list, "N" : N_list, "dt" : Dt_list}

    # removing all netcdf files after all tests
    def removing_files():
         for file in glob.glob("timesteptest_dt*"):
            subprocess.call(["rm", file])
    request.addfinalizer(removing_files)
    return data
Пример #2
0
def main(dt_list = [1e-3, 1.5e-3, 2e-3, 3e-3, 4e-3, 8e-3, 1e-2, 2e-2, 4e-2, 8e-2, 1e-1, 2e-1,  4e-1, 8e-1, 1.]):

    # initial values
    z_max  = 200.
    w       = 1.                                        
    RH_init = .99999
    T_init  = 280.
    p_init  = 100000.
    r_init  = common.eps * RH_init * common.p_vs(T_init) / (p_init - RH_init * common.p_vs(T_init))

    # lists to store RH_max and N at the end of the simulation from each test run 
    RH_list = []
    N_list  = []

    for dt in dt_list:
        print("\nt time step", dt)
        outfile_nc = "timesteptest_dt=" + str(dt) + ".nc"
        parcel(dt=dt, outfreq = int(z_max/w/dt),   outfile = outfile_nc,\
                w = w, T_0 = T_init, p_0 = p_init, r_0 = r_init, z_max = z_max, \
                mean_r = 5e-8, gstdev = 1.5, n_tot = 1e9, sd_conc = 1000, \
                radii = 1e-6 * pow(10, -3 + np.arange(26) * .2)
              )

        f_out  = netcdf.netcdf_file(outfile_nc, "r")
        RH_max = f_out.RH_max
        N_end  = sum(f_out.variables["conc"][-1, -9:]) # concentration of drops > 1e-6 m                                                                                  
        RH_list.append((RH_max - 1)*100)  # [%]                                      
        N_list.append(N_end / 1e6)        # [1/mg] 

        subprocess.call(["rm", outfile_nc])          

    data = {"RH" : RH_list, "N" : N_list, "dt" : dt_list}
    timestep_plot(data)
Пример #3
0
def data(request):
    # initial condition
    RH_init = .999999
    T_init  = 300.
    p_init  = 100000.
    r_init  = cm.eps * RH_init * cm.p_vs(T_init) / (p_init - RH_init * cm.p_vs(T_init))

    # calculate rhod for gas init cond
    th_0      = T_init * (cm.p_1000 / p_init)**(cm.R_d / cm.c_pd)
    rhod_init = cm.rhod(p_init, th_0, r_init)

    # init cond for trace gases
    SO2_g_init  = fn.mole_frac_to_mix_ratio(200e-12, p_init, cm.M_SO2,  T_init, rhod_init)
    O3_g_init   = fn.mole_frac_to_mix_ratio(50e-9,   p_init, cm.M_O3,   T_init, rhod_init)
    H2O2_g_init = fn.mole_frac_to_mix_ratio(500e-12, p_init, cm.M_H2O2, T_init, rhod_init)
    CO2_g_init  = fn.mole_frac_to_mix_ratio(360e-6,  p_init, cm.M_CO2,  T_init, rhod_init)
    NH3_g_init  = fn.mole_frac_to_mix_ratio(100e-12, p_init, cm.M_NH3,  T_init, rhod_init)
    HNO3_g_init = fn.mole_frac_to_mix_ratio(100e-12, p_init, cm.M_HNO3, T_init, rhod_init)

    # aerosol size distribution
    mean_r = .08e-6 / 2
    gstdev = 2.
    n_tot  = 566.e6

    # output
    sd_conc     = 1
    outfreq     = 50
    z_max       = 300.
    outfile     = "test_chem_henry.nc"
    dt          = 0.1
    wait        = 100

    parcel(dt = dt, z_max = z_max, outfreq = outfreq, wait=wait,\
          T_0 = T_init, p_0 = p_init, r_0 = r_init,\
          SO2_g = SO2_g_init, O3_g  = O3_g_init,  H2O2_g = H2O2_g_init,\
          CO2_g = CO2_g_init, NH3_g = NH3_g_init, HNO3_g = HNO3_g_init,\
          outfile = outfile,\
          chem_dsl = True, chem_dsc = True, chem_rct = False,\
          aerosol = \
            '{"test": {"kappa": 0.5, "mean_r": [' + str(mean_r) + '], "gstdev": [' + str(gstdev) + '], "n_tot": [' + str(n_tot) + ']}}',\
          sd_conc = sd_conc,\
          out_bin = \
            '{"radii": {"rght": 1.0, "left": 0.0, "drwt": "wet", "lnli": "lin", "nbin": 1, "moms": [0, 3]},\
              "chem" : {"rght": 1.0, "left": 0.0, "drwt": "wet", "lnli": "lin", "nbin": 1,\
               "moms": ["O3_a", "H2O2_a", "SO2_a", "CO2_a", "NH3_a", "HNO3_a", "H"]}}')

    data = netcdf.netcdf_file("test_chem_henry.nc", "r")

    # removing all netcdf files after all tests                                      
    def removing_files():
        subprocess.call(["rm", "test_chem_henry.nc"])

    request.addfinalizer(removing_files)
    return data
Пример #4
0
def main():
    RH_init = .99999
    T_init = 300.
    p_init = 100000.
    r_init = cm.eps * RH_init * cm.p_vs(T_init) / (p_init -
                                                   RH_init * cm.p_vs(T_init))

    # calculate rhod for initial gas mixing ratio
    th_0 = T_init * (cm.p_1000 / p_init)**(cm.R_d / cm.c_pd)
    rhod_init = cm.rhod(p_init, th_0, r_init)

    SO2_g_init = fn.mole_frac_to_mix_ratio(200e-12, p_init, cm.M_SO2, T_init,
                                           rhod_init)
    O3_g_init = fn.mole_frac_to_mix_ratio(50e-9, p_init, cm.M_O3, T_init,
                                          rhod_init)
    H2O2_g_init = fn.mole_frac_to_mix_ratio(500e-12, p_init, cm.M_H2O2, T_init,
                                            rhod_init)
    CO2_g_init = fn.mole_frac_to_mix_ratio(360e-6, p_init, cm.M_CO2, T_init,
                                           rhod_init)
    NH3_g_init = fn.mole_frac_to_mix_ratio(100e-12, p_init, cm.M_NH3, T_init,
                                           rhod_init)
    HNO3_g_init = fn.mole_frac_to_mix_ratio(100e-12, p_init, cm.M_HNO3, T_init,
                                            rhod_init)

    outfreq = 50
    z_max = 50.
    outfile = "test_chem_henry.nc"
    dt = 0.1
    wait = 1000
    sd_conc = 1

    # run parcel run!
    parcel(dt = dt, z_max = z_max, outfreq = outfreq, wait=wait,\
            T_0 = T_init, p_0 = p_init, r_0 = r_init, sd_conc=sd_conc,\
            SO2_g = SO2_g_init, O3_g  = O3_g_init,  H2O2_g = H2O2_g_init,\
            CO2_g = CO2_g_init, NH3_g = NH3_g_init, HNO3_g = HNO3_g_init,\
            outfile = outfile,\
            chem_dsl = True, chem_dsc = False, chem_rct = False,\
            out_bin = \
            '{"radii": {"rght": 1, "left": 0, "drwt": "wet", "lnli": "lin", "nbin": 1, "moms": [0, 3]},\
              "chem" : {"rght": 1, "left": 0, "drwt": "wet", "lnli": "lin", "nbin": 1,\
                  "moms": ["O3_a", "H2O2_a", "SO2_a", "CO2_a", "NH3_a", "HNO3_a", "H"]}}'                                                                                         )

    data = netcdf.netcdf_file(outfile, "r")

    #plot
    plot_henry(data, output_folder="../outputs")

    #cleanup
    data.close()
    subprocess.call(["rm", "test_chem_henry.nc"])
Пример #5
0
def main():
    RH_init = .99999
    T_init  = 300.
    p_init  = 100000.
    r_init  = cm.eps * RH_init * cm.p_vs(T_init) / (p_init - RH_init * cm.p_vs(T_init))

    # calculate rhod for initial gas mixing ratio
    th_0      = T_init * (cm.p_1000 / p_init)**(cm.R_d / cm.c_pd)
    rhod_init = cm.rhod(p_init, th_0, r_init)

    SO2_g_init  = fn.mole_frac_to_mix_ratio(200e-12, p_init, cm.M_SO2,  T_init, rhod_init)
    O3_g_init   = fn.mole_frac_to_mix_ratio(50e-9,   p_init, cm.M_O3,   T_init, rhod_init)
    H2O2_g_init = fn.mole_frac_to_mix_ratio(500e-12, p_init, cm.M_H2O2, T_init, rhod_init)
    CO2_g_init  = fn.mole_frac_to_mix_ratio(360e-6,  p_init, cm.M_CO2,  T_init, rhod_init)
    NH3_g_init  = fn.mole_frac_to_mix_ratio(100e-12, p_init, cm.M_NH3,  T_init, rhod_init)
    HNO3_g_init = fn.mole_frac_to_mix_ratio(100e-12, p_init, cm.M_HNO3, T_init, rhod_init)

    outfreq     = 50
    z_max       = 50.
    outfile     = "test_chem_henry.nc"
    dt          = 0.1
    wait        = 1000
    sd_conc     = 1

    # run parcel run!
    parcel(dt = dt, z_max = z_max, outfreq = outfreq, wait=wait,\
            T_0 = T_init, p_0 = p_init, r_0 = r_init, sd_conc=sd_conc,\
            SO2_g = SO2_g_init, O3_g  = O3_g_init,  H2O2_g = H2O2_g_init,\
            CO2_g = CO2_g_init, NH3_g = NH3_g_init, HNO3_g = HNO3_g_init,\
            outfile = outfile,\
            chem_dsl = True, chem_dsc = False, chem_rct = False,\
            out_bin = \
            '{"radii": {"rght": 1, "left": 0, "drwt": "wet", "lnli": "lin", "nbin": 1, "moms": [0, 3]},\
              "chem" : {"rght": 1, "left": 0, "drwt": "wet", "lnli": "lin", "nbin": 1,\
                  "moms": ["O3_a", "H2O2_a", "SO2_a", "CO2_a", "NH3_a", "HNO3_a", "H"]}}')

    data = netcdf.netcdf_file(outfile,"r")

    #plot
    plot_henry(data, output_folder = "../outputs")

    #cleanup
    data.close()
    subprocess.call(["rm", "test_chem_henry.nc"])
Пример #6
0
def main(dt_list=[1e-3, 1.5e-3, 2e-3, 3e-3, 4e-3, 8e-3, 1e-2, 2e-2, 4e-2, 8e-2, 1e-1, 2e-1, 4e-1, 8e-1, 1.0]):

    # initial values
    z_max = 200.0
    w = 1.0
    RH_init = 0.99999
    T_init = 280.0
    p_init = 100000.0
    r_init = common.eps * RH_init * common.p_vs(T_init) / (p_init - RH_init * common.p_vs(T_init))

    # lists to store RH_max and N at the end of the simulation from each test run
    RH_list = []
    N_list = []

    for dt in dt_list:
        print "\nt time step", dt
        outfile_nc = "timesteptest_dt=" + str(dt) + ".nc"
        parcel(
            dt=dt,
            outfreq=int(z_max / w / dt),
            outfile=outfile_nc,
            w=w,
            T_0=T_init,
            p_0=p_init,
            r_0=r_init,
            z_max=z_max,
            mean_r=5e-8,
            gstdev=1.5,
            n_tot=1e9,
            sd_conc=1000,
            radii=1e-6 * pow(10, -3 + np.arange(26) * 0.2),
        )

        f_out = netcdf.netcdf_file(outfile_nc, "r")
        RH_max = f_out.RH_max
        N_end = sum(f_out.variables["conc"][-1, -9:])  # concentration of drops > 1e-6 m
        RH_list.append((RH_max - 1) * 100)  # [%]
        N_list.append(N_end / 1e6)  # [1/mg]

        subprocess.call(["rm", outfile_nc])

    data = {"RH": RH_list, "N": N_list, "dt": dt_list}
    timestep_plot(data)
Пример #7
0
def data(request):
    # initial values
    RH_init = .99999
    T_init = 280.
    p_init = 100000.
    r_init = common.eps * RH_init * common.p_vs(T_init) / (
        p_init - RH_init * common.p_vs(T_init))
    # lists to store RH_max and N at the end of the simulation from each test run
    RH_list = []
    N_list = []

    for dt in Dt_list:
        print("\nt time step", dt)
        outfile_nc = "timesteptest_dt=" + str(dt) + ".nc"
        parcel(dt=dt, outfreq = int(100/dt),   outfile = outfile_nc,\
                w = 1., T_0 = T_init, p_0 = p_init, r_0 = r_init, z_max = 200, \
                sd_conc = 1000, \
                aerosol = '{"ammonium_sulfate": {"kappa": 0.61, "mean_r": [5e-8], "gstdev": [1.5], "n_tot": [1e9]}}',
                out_bin = '{"radii": {"rght": 1, "moms": [0], "drwt": "wet", "nbin": 1, "lnli": "lin", "left": 1e-06}}'
              )

        f_out = netcdf.netcdf_file(outfile_nc, "r")
        RH_max = f_out.RH_max
        N_end = f_out.variables["radii_m0"][
            -1, 0]  # concentration of drops > 1e-6 m

        RH_list.append((RH_max - 1) * 100)  # [%]
        N_list.append(N_end / 1e6)  # [1/mg]

    data = {"RH": RH_list, "N": N_list, "dt": Dt_list}

    # removing all netcdf files after all tests
    def removing_files():
        for file in glob.glob("timesteptest_dt*"):
            subprocess.call(["rm", file])

    request.addfinalizer(removing_files)
    return data
Пример #8
0
def rh_to_rv(RH, T, p):
    """
    convert relative humidity [%] to water vapor mixing ratio [kg/kg]
    """
    return cm.eps * RH * cm.p_vs(T) / (p - RH * cm.p_vs(T))
Пример #9
0
def test_pvs(arg, epsilon = 0.03):
    pvs_md = common.p_vs(arg["T"])
    pvs_anpy = anpy.press_sat(arg["T"])
    assert abs(pvs_anpy - pvs_md) <= epsilon * pvs_anpy
Пример #10
0
def rh_to_rv(RH, T, p):
    """
    convert relative humidity [%] to water vapor mixing ratio [kg/kg]
    """
    return cm.eps * RH * cm.p_vs(T) / (p - RH * cm.p_vs(T))
Пример #11
0
def data(request):
    # initial condition
    RH_init = .999999
    T_init = 300.
    p_init = 100000.
    r_init = cm.eps * RH_init * cm.p_vs(T_init) / (p_init -
                                                   RH_init * cm.p_vs(T_init))

    # calculate rhod for gas init cond
    th_0 = T_init * (cm.p_1000 / p_init)**(cm.R_d / cm.c_pd)
    rhod_init = cm.rhod(p_init, th_0, r_init)

    # init cond for trace gases
    SO2_g_init = fn.mole_frac_to_mix_ratio(200e-12, p_init, cm.M_SO2, T_init,
                                           rhod_init)
    O3_g_init = fn.mole_frac_to_mix_ratio(50e-9, p_init, cm.M_O3, T_init,
                                          rhod_init)
    H2O2_g_init = fn.mole_frac_to_mix_ratio(500e-12, p_init, cm.M_H2O2, T_init,
                                            rhod_init)
    CO2_g_init = fn.mole_frac_to_mix_ratio(360e-6, p_init, cm.M_CO2, T_init,
                                           rhod_init)
    NH3_g_init = fn.mole_frac_to_mix_ratio(100e-12, p_init, cm.M_NH3, T_init,
                                           rhod_init)
    HNO3_g_init = fn.mole_frac_to_mix_ratio(100e-12, p_init, cm.M_HNO3, T_init,
                                            rhod_init)

    # aerosol size distribution
    mean_r = .08e-6 / 2
    gstdev = 2.
    n_tot = 566.e6

    # output
    sd_conc = 1
    outfreq = 50
    z_max = 300.
    outfile = "test_chem_henry.nc"
    dt = 0.1
    wait = 100

    parcel(dt = dt, z_max = z_max, outfreq = outfreq, wait=wait,\
          T_0 = T_init, p_0 = p_init, r_0 = r_init,\
          SO2_g = SO2_g_init, O3_g  = O3_g_init,  H2O2_g = H2O2_g_init,\
          CO2_g = CO2_g_init, NH3_g = NH3_g_init, HNO3_g = HNO3_g_init,\
          outfile = outfile,\
          chem_dsl = True, chem_dsc = True, chem_rct = False,\
          aerosol = \
            '{"test": {"kappa": 0.5, "mean_r": [' + str(mean_r) + '], "gstdev": [' + str(gstdev) + '], "n_tot": [' + str(n_tot) + ']}}',\
          sd_conc = sd_conc,\
          out_bin = \
            '{"radii": {"rght": 1.0, "left": 0.0, "drwt": "wet", "lnli": "lin", "nbin": 1, "moms": [0, 3]},\
              "chem" : {"rght": 1.0, "left": 0.0, "drwt": "wet", "lnli": "lin", "nbin": 1,\
               "moms": ["O3_a", "H2O2_a", "SO2_a", "CO2_a", "NH3_a", "HNO3_a", "H"]}}'                                                                                      )

    data = netcdf.netcdf_file("test_chem_henry.nc", "r")

    # removing all netcdf files after all tests
    def removing_files():
        subprocess.call(["rm", "test_chem_henry.nc"])

    request.addfinalizer(removing_files)
    return data
Пример #12
0
from rhs_blk_2m import rhs_blk_2m
from rhs_lgrngn import rhs_lgrngn
from libcloudphxx.common import th_std2dry, th_dry2std
from libcloudphxx.common import p_vs
from libcloudphxx.common import eps, p_1000, R_d, c_pd

from libcloudphxx.lgrngn import chem_species_t

from numpy import array as arr_t
from math import exp, log, sqrt, pi


# initial parameters
T    = arr_t([282.2])
p    = arr_t([95000.]) 
p_v  = arr_t([0.95 * p_vs(T[0])])
p_d  = p - p_v 
r_v  = eps * p_v / p_d
#th_d = arr_t([th_std2dry(300., r_v[0])])
th_d = T * pow(p_1000 / p_d[0], R_d / c_pd) 
w    = 0.5
dt   = .1
nt   = int(600 / w / dt) # 600 metres

# blk_2m-specific parameter
# TODO: spectrum

# lgrngn-specific parameters
sd_conc = 44
def lognormal(lnr):
  mean_r = .08e-6 / 2
Пример #13
0
prsr_lgr.add_argument('--kappa',     type=float, required=True, help='aerosol hygroscopicity parameter [1]')
prsr_lgr.add_argument('--n_tot',     type=float, required=True, help='aerosol concentration @STP [m-3]')
prsr_lgr.add_argument('--meanr',     type=float, required=True, help='aerosol mean dry radius [m]')
prsr_lgr.add_argument('--gstdv',     type=float, required=True, help='aerosol geometric standard deviation [1]')
prsr_lgr.add_argument('--chem_SO2',  type=float, default=0,     help='SO2 volume concentration [1]')
prsr_lgr.add_argument('--chem_O3',   type=float, default=0,     help='O3 volume concentration [1]')
prsr_lgr.add_argument('--chem_H2O2', type=float, default=0,     help='H2O2 volume concentration [1]')

## blk_2m options
prsr_b2m = sprsr.add_parser('blk_2m')
#TODO...

args = prsr.parse_args()

# computing state variables
p_v = arr_t([args.RH * p_vs(args.T)])
p_d = args.p - p_v
r_v = eps * p_v / p_d
th_d = args.T * pow(p_1000 / p_d, R_d / c_pd)

class lognormal:
  def __init__(self, n_tot, meanr, gstdv):
    self.meanr = meanr
    self.stdev = gstdv
    self.n_tot = n_tot
 
  def __call__(self, lnr):
    return self.n_tot * exp(
      -pow((lnr - log(self.meanr)), 2) / 2 / pow(log(self.stdev),2)
    ) / log(self.stdev) / sqrt(2*pi);
Пример #14
0
prsr_lgr.add_argument('--gstdv',     type=float, required=(dflts.gstdv   is None), default=dflts.gstdv,   help='aerosol geometric standard deviation [1]', nargs='+')
prsr_lgr.add_argument('--cloud_r_min', type=float, required=(dflts.cloud_r_min is None), default=dflts.cloud_r_min, help='minimum radius of cloud droplet range [m]')
prsr_lgr.add_argument('--cloud_r_max', type=float, required=(dflts.cloud_r_max is None), default=dflts.cloud_r_max, help='maximum radius of cloud droplet range [m]')
prsr_lgr.add_argument('--cloud_n_bin', type=int, required=(dflts.cloud_n_bin is None), default=dflts.cloud_n_bin, help='number of bins in the cloud droplet range [1]')
prsr_lgr.add_argument('--chem_SO2',  type=float, default=dflts.chem_SO2,  help='SO2 volume concentration [1]')
prsr_lgr.add_argument('--chem_O3',   type=float, default=dflts.chem_O3,   help='O3 volume concentration [1]')
prsr_lgr.add_argument('--chem_H2O2', type=float, default=dflts.chem_H2O2, help='H2O2 volume concentration [1]')

## blk_2m options
prsr_b2m = sprsr.add_parser('blk_2m')
#TODO...

args = prsr.parse_args()

# computing state variables
p_v = np.array([args.RH * libcom.p_vs(args.T)])
p_d = args.p - p_v
r_v = libcom.eps * p_v / p_d
th_d = args.T * pow(libcom.p_1000 / p_d, libcom.R_d / libcom.c_pd)


chem_gas = None
if args.chem_SO2 + args.chem_O3 + args.chem_H2O2 > 0:
  chem_gas = {
    libcl.lgrngn.chem_species_t.SO2  : args.chem_SO2,
    libcl.lgrngn.chem_species_t.O3   : args.chem_O3,
    libcl.lgrngn.chem_species_t.H2O2 : args.chem_H2O2
  }

# performing the simulation
rhs = rhs_lgrngn.rhs_lgrngn(
Пример #15
0
def _stats(state, info):
    state["T"] = np.array([common.T(state["th_d"][0], state["rhod"][0])])
    state["RH"] = state["p"] * state["r_v"] / (
        state["r_v"] + common.eps) / common.p_vs(state["T"][0])
    info["RH_max"] = max(info["RH_max"], state["RH"])
Пример #16
0
from parcel import parcel
from rhs_blk_2m import rhs_blk_2m
from rhs_lgrngn import rhs_lgrngn
from libcloudphxx.common import th_std2dry, th_dry2std
from libcloudphxx.common import p_vs
from libcloudphxx.common import eps, p_1000, R_d, c_pd

from libcloudphxx.lgrngn import chem_species_t

from numpy import array as arr_t
from math import exp, log, sqrt, pi

# initial parameters
T = arr_t([282.2])
p = arr_t([95000.])
p_v = arr_t([0.95 * p_vs(T[0])])
p_d = p - p_v
r_v = eps * p_v / p_d
#th_d = arr_t([th_std2dry(300., r_v[0])])
th_d = T * pow(p_1000 / p_d[0], R_d / c_pd)
w = 0.5
dt = .1
nt = int(600 / w / dt)  # 600 metres

# blk_2m-specific parameter
# TODO: spectrum

# lgrngn-specific parameters
sd_conc = 44

Пример #17
0
import sys
sys.path.insert(0, "../../bindings/python/")

#<listing-1>
from libcloudphxx import common, git_revision

print(git_revision)

print("common.p_vs(273.16)=", common.p_vs(273.16))
assert abs(common.p_vs(273.16) - 611.73) < .001
#</listing-1>

print("R_d =", common.R_d)
print("c_pd =", common.c_pd)
print("g =", common.g)
print("p_1000 =", common.p_1000)
print("eps =", common.eps)
print("rho_w =", common.rho_w)

th = 300
rv = .01

print(common.th_dry2std(th, rv))
assert common.th_std2dry(common.th_dry2std(th, rv), rv) == th

rd3 = (.2e-6)**3
assert common.rw3_cr(rd3, .5, 300) > rd3
assert common.S_cr(rd3, .5, 300) > 1

# just testing if pressure at 200m is lower than at 100m
assert common.p_hydro(100, 300, .01, 0, 100000) > common.p_hydro(
Пример #18
0
def parcel(
        dt=.1,
        z_max=200.,
        w=1.,
        T_0=300.,
        p_0=101300.,
        r_0=-1.,
        RH_0=-1.,  #if none specified, the default will be r_0=.022, 
        outfile="test.nc",
        pprof="pprof_piecewise_const_rhod",
        outfreq=100,
        sd_conc=64,
        aerosol='{"ammonium_sulfate": {"kappa": 0.61, "mean_r": [0.02e-6], "gstdev": [1.4], "n_tot": [60.0e6]}}',
        out_bin='{"radii": {"rght": 0.0001, "moms": [0], "drwt": "wet", "nbin": 1, "lnli": "log", "left": 1e-09}}',
        SO2_g=0.,
        O3_g=0.,
        H2O2_g=0.,
        CO2_g=0.,
        HNO3_g=0.,
        NH3_g=0.,
        chem_dsl=False,
        chem_dsc=False,
        chem_rct=False,
        chem_rho=1.8e3,
        sstp_cond=1,
        sstp_chem=1,
        wait=0):
    """
  Args:
    dt      (Optional[float]):    timestep [s]
    z_max   (Optional[float]):    maximum vertical displacement [m]
    w       (Optional[float]):    updraft velocity [m/s]
    T_0     (Optional[float]):    initial temperature [K]
    p_0     (Optional[float]):    initial pressure [Pa]
    r_0     (Optional[float]):    initial water vapour mass mixing ratio [kg/kg]
    RH_0    (Optional[float]):    initial relative humidity
    outfile (Optional[string]):   output netCDF file name
    outfreq (Optional[int]):      output interval (in number of time steps)
    sd_conc (Optional[int]):      number of moving bins (super-droplets)
    aerosol (Optional[json str]): dict of dicts defining aerosol distribution, e.g.:
                                  
                                  {"ammonium_sulfate": {"kappa": 0.61, "mean_r": [0.02e-6, 0.07e-7], "gstdev": [1.4, 1.2], "n_tot": [120.0e6, 80.0e6]}
                                   "gccn" : {"kappa": 1.28, "mean_r": [2e-6], "gstdev": [1.6], "n_tot": [1e2]}}
              
                                  where kappa  - hygroscopicity parameter (see doi:10.5194/acp-7-1961-2007)
                                        mean_r - lognormal distribution mean radius [m]                    (list if multimodal distribution)
                                        gstdev - lognormal distribution geometric standard deviation       (list if multimodal distribution)
                                        n_tot  - lognormal distribution total concentration under standard 
                                                 conditions (T=20C, p=1013.25 hPa, rv=0) [m^-3]            (list if multimodal distribution)


    out_bin (Optional[json str]): dict of dicts defining spectrum diagnostics, e.g.:

                                  {"radii": {"rght": 0.0001,  "moms": [0],          "drwt": "wet", "nbin": 26, "lnli": "log", "left": 1e-09},
                                   "cloud": {"rght": 2.5e-05, "moms": [0, 1, 2, 3], "drwt": "wet", "nbin": 49, "lnli": "lin", "left": 5e-07}}
                                  will generate five output spectra:
                                  - 0-th spectrum moment for 26 bins spaced logarithmically between 0 and 1e-4 m for dry radius
                                  - 0,1,2 & 3-rd moments for 49 bins spaced linearly between .5e-6 and 25e-6 for wet radius
                                  
                                  It can also define spectrum diagnostics for chemical compounds, e.g.:

                                  {"chem" : {"rght": 1e-6, "left": 1e-10, "drwt": "dry", "lnli": "log", "nbin": 100, "moms": ["S_VI", "NH4_a"]}}
                                  will output the total mass of H2SO4  and NH4 ions in each sizedistribution bin
                                  
                                  Valid "moms" for chemistry are: 
                                    "O3_a",  "H2O2_a", "H", 
                                    "SO2_a",  "S_VI",
                                    "CO2_a",  
                                    "NH3_a", "HNO3_a",

    SO2_g    (Optional[float]):   initial SO2  gas mixing ratio [kg / kg dry air]
    O3_g     (Optional[float]):   initial O3   gas mixing ratio [kg / kg dry air]
    H2O2_g   (Optional[float]):   initial H2O2 gas mixing ratio [kg / kg dry air]
    CO2_g    (Optional[float]):   initial CO2  gas mixing ratio [kg / kg dry air]
    NH3_g     (Optional[float]):  initial NH3  gas mixing ratio [kg / kg dry air]
    HNO3_g   (Optional[float]):   initial HNO3 gas mixing ratio [kg / kg dry air]
    chem_dsl (Optional[bool]):    on/off for dissolving chem species into droplets
    chem_dsc (Optional[bool]):    on/off for dissociation of chem species in droplets
    chem_rct (Optional[bool]):    on/off for oxidation of S_IV to S_VI
    pprof   (Optional[string]):   method to calculate pressure profile used to calculate 
                                  dry air density that is used by the super-droplet scheme
                                  valid options are: pprof_const_th_rv, pprof_const_rhod, pprof_piecewise_const_rhod
    wait (Optional[float]):       number of timesteps to run parcel model with vertical velocity=0 at the end of simulation
                                  (added for testing)
   """
    # packing function arguments into "opts" dictionary
    args, _, _, _ = inspect.getargvalues(inspect.currentframe())
    opts = dict(zip(args, [locals()[k] for k in args]))

    # parsing json specification of output spectra
    spectra = json.loads(opts["out_bin"])

    # parsing json specification of init aerosol spectra
    aerosol = json.loads(opts["aerosol"])

    # default water content
    if ((opts["r_0"] < 0) and (opts["RH_0"] < 0)):
        print "both r_0 and RH_0 negative, using default r_0 = 0.022"
        r_0 = .022
    # water coontent specified with RH
    if ((opts["r_0"] < 0) and (opts["RH_0"] >= 0)):
        r_0 = common.eps * opts["RH_0"] * common.p_vs(T_0) / (
            p_0 - opts["RH_0"] * common.p_vs(T_0))

    # sanity checks for arguments
    _arguments_checking(opts, spectra, aerosol)

    th_0 = T_0 * (common.p_1000 / p_0)**(common.R_d / common.c_pd)
    nt = int(z_max / (w * dt))
    state = {
        "t": 0,
        "z": 0,
        "r_v": np.array([r_0]),
        "p": p_0,
        "th_d": np.array([common.th_std2dry(th_0, r_0)]),
        "rhod": np.array([common.rhod(p_0, th_0, r_0)]),
        "T": None,
        "RH": None
    }

    if opts["chem_dsl"] or opts["chem_dsc"] or opts["chem_rct"]:
        for key in _Chem_g_id.iterkeys():
            state.update({key: np.array([opts[key]])})

    info = {
        "RH_max": 0,
        "libcloud_Git_revision": libcloud_version,
        "parcel_Git_revision": parcel_version
    }

    micro = _micro_init(aerosol, opts, state, info)

    with _output_init(micro, opts, spectra) as fout:
        # adding chem state vars
        if micro.opts_init.chem_switch:
            state.update({
                "SO2_a": 0.,
                "O3_a": 0.,
                "H2O2_a": 0.,
            })
            state.update({"CO2_a": 0., "HNO3_a": 0.})

            micro.diag_all()  # selecting all particles
            micro.diag_chem(_Chem_a_id["NH3_a"])
            state.update({"NH3_a": np.frombuffer(micro.outbuf())[0]})

        # t=0 : init & save
        _output(fout, opts, micro, state, 0, spectra)

        # timestepping
        for it in range(1, nt + 1):
            # diagnostics
            # the reasons to use analytic solution:
            # - independent of dt
            # - same as in 2D kinematic model
            state["z"] += w * dt
            state["t"] = it * dt

            # pressure
            if pprof == "pprof_const_th_rv":
                # as in icicle model
                p_hydro = _p_hydro_const_th_rv(state["z"], p_0, th_0, r_0)
            elif pprof == "pprof_const_rhod":
                # as in Grabowski and Wang 2009
                rho = 1.13  # kg/m3  1.13
                state["p"] = _p_hydro_const_rho(state["z"], p_0, rho)

            elif pprof == "pprof_piecewise_const_rhod":
                # as in Grabowski and Wang 2009 but calculating pressure
                # for rho piecewise constant per each time step
                state["p"] = _p_hydro_const_rho(w * dt, state["p"],
                                                state["rhod"][0])

            else:
                raise Exception(
                    "pprof should be pprof_const_th_rv, pprof_const_rhod, or pprof_piecewise_const_rhod"
                )

            # dry air density
            if pprof == "pprof_const_th_rv":
                state["rhod"][0] = common.rhod(p_hydro, th_0, r_0)
                state["p"] = common.p(
                    state["rhod"][0], state["r_v"][0],
                    common.T(state["th_d"][0], state["rhod"][0]))

            else:
                state["rhod"][0] = common.rhod(
                    state["p"],
                    common.th_dry2std(state["th_d"][0], state["r_v"][0]),
                    state["r_v"][0])

            # microphysics
            _micro_step(micro, state, info, opts, it, fout)

            # TODO: only if user wants to stop @ RH_max
            #if (state["RH"] < info["RH_max"]): break

            # output
            if (it % outfreq == 0):
                print str(round(it / (nt * 1.) * 100, 2)) + " %"
                rec = it / outfreq
                _output(fout, opts, micro, state, rec, spectra)

        _save_attrs(fout, info)
        _save_attrs(fout, opts)

        if wait != 0:
            for it in range(nt + 1, nt + wait):
                state["t"] = it * dt
                _micro_step(micro, state, info, opts, it, fout)

                if (it % outfreq == 0):
                    rec = it / outfreq
                    _output(fout, opts, micro, state, rec, spectra)
Пример #19
0
def _stats(state, info):
  state["T"] = np.array([common.T(state["th_d"][0], state["rhod"][0])])
  state["RH"] = state["p"] * state["r_v"] / (state["r_v"] + common.eps) / common.p_vs(state["T"][0])
  info["RH_max"] = max(info["RH_max"], state["RH"])
Пример #20
0
def parcel(dt=.1, z_max=200., w=1., T_0=300., p_0=101300., 
  r_0=-1., RH_0=-1., #if none specified, the default will be r_0=.022, 
  outfile="test.nc", 
  pprof="pprof_piecewise_const_rhod",
  outfreq=100, sd_conc=64,
  aerosol = '{"ammonium_sulfate": {"kappa": 0.61, "mean_r": [0.02e-6], "gstdev": [1.4], "n_tot": [60.0e6]}}',
  out_bin = '{"radii": {"rght": 0.0001, "moms": [0], "drwt": "wet", "nbin": 1, "lnli": "log", "left": 1e-09}}',
  SO2_g = 0., O3_g = 0., H2O2_g = 0., CO2_g = 0., HNO3_g = 0., NH3_g = 0.,
  chem_dsl = False, chem_dsc = False, chem_rct = False, 
  chem_rho = 1.8e3,
  sstp_cond = 1,
  sstp_chem = 1,
  wait = 0
):
  """
  Args:
    dt      (Optional[float]):    timestep [s]
    z_max   (Optional[float]):    maximum vertical displacement [m]
    w       (Optional[float]):    updraft velocity [m/s]
    T_0     (Optional[float]):    initial temperature [K]
    p_0     (Optional[float]):    initial pressure [Pa]
    r_0     (Optional[float]):    initial water vapour mass mixing ratio [kg/kg]
    RH_0    (Optional[float]):    initial relative humidity
    outfile (Optional[string]):   output netCDF file name
    outfreq (Optional[int]):      output interval (in number of time steps)
    sd_conc (Optional[int]):      number of moving bins (super-droplets)
    aerosol (Optional[json str]): dict of dicts defining aerosol distribution, e.g.:
                                  
                                  {"ammonium_sulfate": {"kappa": 0.61, "mean_r": [0.02e-6, 0.07e-7], "gstdev": [1.4, 1.2], "n_tot": [120.0e6, 80.0e6]}
                                   "gccn" : {"kappa": 1.28, "mean_r": [2e-6], "gstdev": [1.6], "n_tot": [1e2]}}
              
                                  where kappa  - hygroscopicity parameter (see doi:10.5194/acp-7-1961-2007)
                                        mean_r - lognormal distribution mean radius [m]                    (list if multimodal distribution)
                                        gstdev - lognormal distribution geometric standard deviation       (list if multimodal distribution)
                                        n_tot  - lognormal distribution total concentration under standard 
                                                 conditions (T=20C, p=1013.25 hPa, rv=0) [m^-3]            (list if multimodal distribution)


    out_bin (Optional[json str]): dict of dicts defining spectrum diagnostics, e.g.:

                                  {"radii": {"rght": 0.0001,  "moms": [0],          "drwt": "wet", "nbin": 26, "lnli": "log", "left": 1e-09},
                                   "cloud": {"rght": 2.5e-05, "moms": [0, 1, 2, 3], "drwt": "wet", "nbin": 49, "lnli": "lin", "left": 5e-07}}
                                  will generate five output spectra:
                                  - 0-th spectrum moment for 26 bins spaced logarithmically between 0 and 1e-4 m for dry radius
                                  - 0,1,2 & 3-rd moments for 49 bins spaced linearly between .5e-6 and 25e-6 for wet radius
                                  
                                  It can also define spectrum diagnostics for chemical compounds, e.g.:

                                  {"chem" : {"rght": 1e-6, "left": 1e-10, "drwt": "dry", "lnli": "log", "nbin": 100, "moms": ["S_VI", "NH4_a"]}}
                                  will output the total mass of H2SO4  and NH4 ions in each sizedistribution bin
                                  
                                  Valid "moms" for chemistry are: 
                                    "O3_a",  "H2O2_a", "H", 
                                    "SO2_a",  "S_VI",
                                    "CO2_a",  
                                    "NH3_a", "HNO3_a",

    SO2_g    (Optional[float]):   initial SO2  gas mixing ratio [kg / kg dry air]
    O3_g     (Optional[float]):   initial O3   gas mixing ratio [kg / kg dry air]
    H2O2_g   (Optional[float]):   initial H2O2 gas mixing ratio [kg / kg dry air]
    CO2_g    (Optional[float]):   initial CO2  gas mixing ratio [kg / kg dry air]
    NH3_g     (Optional[float]):  initial NH3  gas mixing ratio [kg / kg dry air]
    HNO3_g   (Optional[float]):   initial HNO3 gas mixing ratio [kg / kg dry air]
    chem_dsl (Optional[bool]):    on/off for dissolving chem species into droplets
    chem_dsc (Optional[bool]):    on/off for dissociation of chem species in droplets
    chem_rct (Optional[bool]):    on/off for oxidation of S_IV to S_VI
    pprof   (Optional[string]):   method to calculate pressure profile used to calculate 
                                  dry air density that is used by the super-droplet scheme
                                  valid options are: pprof_const_th_rv, pprof_const_rhod, pprof_piecewise_const_rhod
    wait (Optional[float]):       number of timesteps to run parcel model with vertical velocity=0 at the end of simulation
                                  (added for testing)
   """
  # packing function arguments into "opts" dictionary
  args, _, _, _ = inspect.getargvalues(inspect.currentframe())
  opts = dict(zip(args, [locals()[k] for k in args]))

  # parsing json specification of output spectra
  spectra = json.loads(opts["out_bin"])

  # parsing json specification of init aerosol spectra
  aerosol = json.loads(opts["aerosol"])

  # default water content
  if ((opts["r_0"] < 0) and (opts["RH_0"] < 0)): 
    print "both r_0 and RH_0 negative, using default r_0 = 0.022"
    r_0 = .022
  # water coontent specified with RH
  if ((opts["r_0"] < 0) and (opts["RH_0"] >= 0)): 
    r_0 = common.eps * opts["RH_0"] * common.p_vs(T_0) / (p_0 - opts["RH_0"] * common.p_vs(T_0))

  # sanity checks for arguments
  _arguments_checking(opts, spectra, aerosol)

  th_0 = T_0 * (common.p_1000 / p_0)**(common.R_d / common.c_pd)
  nt = int(z_max / (w * dt))
  state = {
    "t" : 0, "z" : 0,
    "r_v" : np.array([r_0]), "p" : p_0,
    "th_d" : np.array([common.th_std2dry(th_0, r_0)]), 
    "rhod" : np.array([common.rhod(p_0, th_0, r_0)]),
    "T" : None, "RH" : None
  }

  if opts["chem_dsl"] or opts["chem_dsc"] or opts["chem_rct"]:
    for key in _Chem_g_id.iterkeys():
      state.update({ key : np.array([opts[key]])}) 

  info = { "RH_max" : 0, "libcloud_Git_revision" : libcloud_version, 
           "parcel_Git_revision" : parcel_version }

  micro = _micro_init(aerosol, opts, state, info)

  with _output_init(micro, opts, spectra) as fout:
    # adding chem state vars
    if micro.opts_init.chem_switch:
      state.update({ "SO2_a" : 0.,"O3_a" : 0.,"H2O2_a" : 0.,})
      state.update({ "CO2_a" : 0.,"HNO3_a" : 0.})

      micro.diag_all() # selecting all particles
      micro.diag_chem(_Chem_a_id["NH3_a"])
      state.update({"NH3_a": np.frombuffer(micro.outbuf())[0]})

    # t=0 : init & save
    _output(fout, opts, micro, state, 0, spectra)

    # timestepping
    for it in range(1,nt+1):
      # diagnostics
      # the reasons to use analytic solution:
      # - independent of dt
      # - same as in 2D kinematic model
      state["z"] += w * dt
      state["t"] = it * dt

      # pressure
      if pprof == "pprof_const_th_rv":
        # as in icicle model
        p_hydro = _p_hydro_const_th_rv(state["z"], p_0, th_0, r_0)
      elif pprof == "pprof_const_rhod":
        # as in Grabowski and Wang 2009
        rho = 1.13 # kg/m3  1.13 
        state["p"] = _p_hydro_const_rho(state["z"], p_0, rho) 

      elif pprof == "pprof_piecewise_const_rhod":
        # as in Grabowski and Wang 2009 but calculating pressure
        # for rho piecewise constant per each time step
        state["p"] = _p_hydro_const_rho(w*dt, state["p"], state["rhod"][0])

      else: raise Exception("pprof should be pprof_const_th_rv, pprof_const_rhod, or pprof_piecewise_const_rhod") 

      # dry air density
      if pprof == "pprof_const_th_rv":
        state["rhod"][0] = common.rhod(p_hydro, th_0, r_0)
        state["p"] = common.p(
          state["rhod"][0],
          state["r_v"][0],
          common.T(state["th_d"][0], state["rhod"][0])
        )

      else:
        state["rhod"][0] = common.rhod(
          state["p"], 
          common.th_dry2std(state["th_d"][0], state["r_v"][0]), 
          state["r_v"][0]
        )

      # microphysics
      _micro_step(micro, state, info, opts, it, fout)
 
      # TODO: only if user wants to stop @ RH_max
      #if (state["RH"] < info["RH_max"]): break
 
      # output
      if (it % outfreq == 0):
        print str(round(it / (nt * 1.) * 100, 2)) + " %"
        rec = it/outfreq
        _output(fout, opts, micro, state, rec, spectra)

    _save_attrs(fout, info)
    _save_attrs(fout, opts)

    if wait != 0:
      for it in range (nt+1, nt+wait):
        state["t"] = it * dt
        _micro_step(micro, state, info, opts, it, fout)

        if (it % outfreq == 0): 
          rec = it/outfreq
          _output(fout, opts, micro, state, rec, spectra)
Пример #21
0
import sys
sys.path.insert(0, "../../bindings/python/")

#<listing-1>
from libcloudphxx import common, git_revision

print git_revision

print "common.p_vs(273.16)=", common.p_vs(273.16)
assert abs(common.p_vs(273.16) - 611.73) < .001
#</listing-1>

print "R_d =", common.R_d
print "c_pd =", common.c_pd
print "g =", common.g
print "p_1000 =", common.p_1000
print "eps =", common.eps
print "rho_w =", common.rho_w

th = 300
rv = .01

print common.th_dry2std(th, rv)	
assert common.th_std2dry(common.th_dry2std(th, rv), rv) == th

rd3 = (.2e-6)**3
assert common.rw3_cr(rd3, .5, 300) > rd3
assert common.S_cr(rd3, .5, 300) > 1

# just testing if pressure at 200m is lower than at 100m
assert common.p_hydro(100, 300, .01, 0, 100000) > common.p_hydro(200, 300, .01, 0, 100000)