binmod1d package

Submodules

binmod1d.analytical_solutions module

These are analytical solutions to the SCE, SBE, and SCE-SBE steady-state solution following Scott (1964) and Feingold et al. (1988). For more information, see:

Scott, W. T.: Analytical studies of cloud droplet coalesence I, J. Atmos. Sci., 25, 54–65, https://doi.org/10.1175/1520- 0469(1968)025<0054:ASOCDC>2.0.CO;2, 1968.

Feingold, G., Tzivion, S., and Levin, Z.: Evolution of raindrop spectra. Part I: Solution to the Stochastic Collection/Breakup equation using the method of moments, J. Atmos. Sci., 45, 3387–3399, https://doi.org/10.1175/1520-0469(1988)045<3387:EORSPI>2.0.CO;2, 1988.

binmod1d.analytical_solutions.Feingold_dists(xbins, t, nu, E, B, gam, kernel_type='SBE')

Calculates Feingold’s analytical number distribution function solution to the SBE/SCE-SBE steady-state solution for Constant kernel.

Parameters:
  • xbins (TYPE) – DESCRIPTION.

  • t (TYPE) – DESCRIPTION.

  • nu (TYPE) – DESCRIPTION.

  • E (TYPE) – DESCRIPTION.

  • B (TYPE) – DESCRIPTION.

  • gam (TYPE) – DESCRIPTION.

  • kernel_type (TYPE, optional) – DESCRIPTION. The default is β€˜SBE’.

Returns:

npbins – DESCRIPTION.

Return type:

TYPE

binmod1d.analytical_solutions.Feingold_moments(r, t, nu, B, gam, kernel_type='SBE')

Calculate moments for Feingold’s analytical solutions to the SBE/SCE-SBE Steady state solution for Constant kernel.

Parameters:
  • r (TYPE) – DESCRIPTION.

  • t (TYPE) – DESCRIPTION.

  • nu (TYPE) – DESCRIPTION.

  • B (TYPE) – DESCRIPTION.

  • gam (TYPE) – DESCRIPTION.

  • kernel_type (TYPE, optional) – DESCRIPTION. The default is β€˜SBE’.

Returns:

M_rt – DESCRIPTION.

Return type:

TYPE

binmod1d.analytical_solutions.Scott_dists(xbins, Eagg, nu, t, kernel_type='Golovin', max_k=100)

Calculates Scott’s analytical number distribution function solution to the SCE for Golovin, Product, and Constant kernels.

Parameters:
  • xbins (TYPE) – DESCRIPTION.

  • Eagg (TYPE) – DESCRIPTION.

  • nu (TYPE) – DESCRIPTION.

  • t (TYPE) – DESCRIPTION.

  • kernel_type (TYPE, optional) – DESCRIPTION. The default is β€˜Golovin’.

  • max_k (TYPE, optional) – DESCRIPTION. The default is 100.

Returns:

npbins – DESCRIPTION.

Return type:

TYPE

binmod1d.analytical_solutions.Scott_moments(r, t, nu, E, B, kernel_type='Golovin')

Calculate moments for Scott’s analytical solutions to the SCE for Golovin, Product, and Constant kernels.

Parameters:
  • r (TYPE) – DESCRIPTION.

  • t (TYPE) – DESCRIPTION.

  • nu (TYPE) – DESCRIPTION.

  • E (TYPE) – DESCRIPTION.

  • B (TYPE) – DESCRIPTION.

  • kernel_type (TYPE, optional) – DESCRIPTION. The default is β€˜Golovin’.

Returns:

M_rt – DESCRIPTION.

Return type:

TYPE

binmod1d.bin_integrals module

Created on Wed Sep 24 08:17:50 2025

@author: edwin.dunnavan

binmod1d.bin_integrals.GAU_int(n, mu, sig2, x1, x2)

Integrates x^n * Normal(mu, sigma^2) from x1 to x2. Uses a 3rd-order central moment expansion that is EXACT for integer moments (n=0, 1, 2, 3) and highly accurate for fractional moments.

binmod1d.bin_integrals.In_int(n, c, x1, x2)
binmod1d.bin_integrals.LGN_int(n, mu, sig2, x1, x2)

High-Precision Log-Normal integral. Handles both Left Tail (z < -26) and Right Tail (z > 26) using erfcx scaling. Calculates Integral(x^n * PDF(x) dx) from x1 to x2.

binmod1d.bin_integrals.Pn(n, x1, x2)
binmod1d.bin_integrals.breakup_1mom_kernel(M_gain, M_loss, dMb_kernel, i_idx, j_idx, h_idx, k_limit_idx, indb, Ebr)

2-moment breakup calculations using numba

binmod1d.bin_integrals.breakup_kernel(M_gain, N_gain, M_loss, dMb_kernel, dNb_kernel, Ebr, p_idx, i_idx, j_idx, h_idx, k_limit_idx, indb)

2-moment breakup calculations using numba

binmod1d.bin_integrals.calculate_rates(Hlen, bins, region_inds, x_bottom_edge, x_top_edge, y_left_edge, y_right_edge, kr, ir, jr, x11, x21, ak1, ck1, x12, x22, ak2, ck2, PK, kmin, kmid, dMb_gain_frac, dNb_gain_frac, w, L, breakup=False)

Description: Calcualates Wang et al. (2007) integrals using numpy functions.

# kr = Height index (batch,) # ir = collectee index (batch,) # jr = collector index (batch,)

Vectorized Integration Regions: cond_1 : All rectangular bin-pair interactions used cond_2 : k bin: Lower triangle region. Just clips BR corner.

Triangle = ((xi1,xj1),(xi1,y_left_edge),(xi2,xj1))

cond_3k bin: Lower triangle region. Just clips UL corner.

Triangle = ((xi1,xj1),(xi1,xj2),(x_bottom_edge,xj1))

cond_2bk+1 bins: Upper triangle region. Just clips BR corner.

Triangle = ((xi1,xj1),(x_top_edge,xj2),(xi2,xj2))

cond_3bk+1 bin: Upper triangle region. Just clips UL corner.

Triangle = ((xi1,xj2),(xi2,xj2),(xi2,y_right_edge)

cond_4 : Full Rectangular source region based on self collection: ii == jj –> ii+sbin or jj+sbin cond_5 : k bin: Top/Bottom clip: Rectangle on left, triangle on right

Rectangle = ((xi1,xj1),(xi1,xj2),(x_top_edge,xj2),(x_top_edge,xj1)) Triangle = ((x_top_edge,xj1),(x_top_edge,xj2),(x_bottom_edge,xj1))

cond_6k bin: Left/Right clip: Rectangle on bottom, triangle on top

Rectangle = ((xi1,xj1),(xi1,y_right_edge),(xi2,y_right_edge),(xi2,xj1)) Triangle = ((xi1,y_right_edge),(xi1,y_left_edge),(xi2,y_right_edge))

cond_7k+1 bin: Triangle in top right corner

Triangle = ((x_top_edge,xj2),(xi2,xj2),(xi2,y_right_edge))

cond_8k bin: Triangle in lower left corner

Triangle = ((xi1,xj1),(xi1,y_left_edge),(x_bottom_edge,xj1))

cond_9: k bin: Rectangle collection within k bin. All Mass/Number goes into kbin cond_10: k+1 bin: Rectangle collection within k+1 bin. All Mass/Number goes into kbin

binmod1d.bin_integrals.calculate_regions_batch(Hlen, bins, kr, ir, jr, x11, x21, ak1, ck1, x12, x22, ak2, ck2, PK, region_inds, x_bottom_edge, x_top_edge, y_left_edge, y_right_edge, w, L)

Vectorized Integration Regions: cond_1 : All rectangular bin-pair interactions used cond_2 : k bin: Lower triangle region. Just clips BR corner.

Triangle = ((xi1,xj1),(xi1,y_left_edge),(xi2,xj1))

cond_3k bin: Lower triangle region. Just clips UL corner.

Triangle = ((xi1,xj1),(xi1,xj2),(x_bottom_edge,xj1))

cond_2bk+1 bins: Upper triangle region. Just clips BR corner.

Triangle = ((xi1,xj1),(x_top_edge,xj2),(xi2,xj2))

cond_3bk+1 bin: Upper triangle region. Just clips UL corner.

Triangle = ((xi1,xj2),(xi2,xj2),(xi2,y_right_edge)

cond_4 : Full Rectangular source region based on self collection: ii == jj –> ii+sbin or jj+sbin cond_5 : k bin: Top/Bottom clip: Rectangle on left, triangle on right

Rectangle = ((xi1,xj1),(xi1,xj2),(x_top_edge,xj2),(x_top_edge,xj1)) Triangle = ((x_top_edge,xj1),(x_top_edge,xj2),(x_bottom_edge,xj1))

cond_6k bin: Left/Right clip: Rectangle on bottom, triangle on top

Rectangle = ((xi1,xj1),(xi1,y_right_edge),(xi2,y_right_edge),(xi2,xj1)) Triangle = ((xi1,y_right_edge),(xi1,y_left_edge),(xi2,y_right_edge))

cond_7k+1 bin: Triangle in top right corner

Triangle = ((x_top_edge,xj2),(xi2,xj2),(xi2,y_right_edge))

cond_8k bin: Triangle in lower left corner

Triangle = ((xi1,xj1),(xi1,y_left_edge),(x_bottom_edge,xj1))

cond_9: k bin: Rectangle collection within k bin. All Mass/Number goes into kbin cond_10: k+1 bin: Rectangle collection within k+1 bin. All Mass/Number goes into kbin

binmod1d.bin_integrals.combined_coeffs_array(f, ax, cx, ay, cy)

Returns C00,C10,C01,C20,C11,C02,C21,C12 such that: P(x,y) = sum Cij * x^i y^j

binmod1d.bin_integrals.combined_coeffs_tensor(f, params)

Expands: (a + bx + cy + dxy) * (aki1*x + cki1) * (aki2*y + cki2) f: (4, pnum, 1, bins, bins) | aki, cki: (pnum, H, bins, 1) or (pnum, H, 1, bins)

binmod1d.bin_integrals.gam_int(n, mu, Dm, x1, x2)
binmod1d.bin_integrals.init_rk(rk_order)
Parameters:

rk_order (int) – Runge-Kutta order.

Returns:

RK – Dictionary of Runge-Kutta Butcher table parameters.

Return type:

dict

binmod1d.bin_integrals.kernel_1mom(M_loss, M_gain, Eagg, Ebr, rate, h_idx, s1_idx, s2_idx, i_idx, j_idx, p_idx, dMi, dMj, k0_map, k1_map, dMg, dMb_kernel, indc, indb)

1 moment Numba kernel calculations

binmod1d.bin_integrals.loss_kernel_numba(dN_out, dMi_out, dMj_out, C, x1, x2, y1, y2)

2-moment loss term numba calculation

binmod1d.bin_integrals.moments(r, aki, cki, x1, x2)
binmod1d.bin_integrals.rect_gain_integrals(C, x1, x2, y1, y2)

Tensor-based rectangular integration for N rectangles. Calculates Int(P), Int(xP), Int(yP), and Int((x+y)P).

binmod1d.bin_integrals.rect_integrals(C00, C10, C01, C20, C11, C02, C21, C12, C22, x1, x2, y1, y2)

Tensor-based rectangular integration for N rectangles. Calculates Int(P), Int(xP), Int(yP), and Int((x+y)P).

binmod1d.bin_integrals.setup_regions(bins, kr, ir, jr, x11, x21, x12, x22, xk_min)
binmod1d.bin_integrals.source_integrals(C, x1, x2, y1, y2)

Tensor-based rectangular integration for N rectangles. Calculates Int(P), Int(xP), Int(yP), and Int((x+y)P).

binmod1d.bin_integrals.transfer_1mom_bins(Hlen, bins, kr, ir, jr, n12, dMi_loss, dMj_loss, dM_loss, dM_gain, kmin, kmid, dMb_gain_frac, breakup)
binmod1d.bin_integrals.transfer_bins(Hlen, bins, kr, ir, jr, kmin, kmid, dMi_loss, dMj_loss, dM_loss, dM_gain, dNi_loss, dN_gain, dMb_gain_frac, dNb_gain_frac, breakup=False)

Performs bin transfer of mass and number

binmod1d.bin_integrals.tri_gain_integrals(C, xt1, yt1, xt2, yt2, xt3, yt3, w, L)

Direct contraction of a (3, 3, N) coefficient tensor. i: x-power (0,1,2), j: y-power (0,1,2), n: triangle index

binmod1d.bin_integrals.tri_kernel_numba(dN_out, dM_out, C, x1, y1, x2, y2, x3, y3, w, L)

2-moment triangular gain region calculations using numba

binmod1d.bin_integrals.vectorized_1mom(cki, params, dMi, dMj, dMg, kmin, kmid, dMb_kernel, indc, indb, dnum, Hlen, bins)

Numba-optimized 1-moment gain and loss bin integral calculations

binmod1d.bin_integrals.vectorized_2mom(params, w, L, dMb_kernel, dNb_kernel, indc, indb, dnum, Hlen, bins)

Numba-optimized 2-moment gain and loss bin integral calculations

binmod1d.collection_kernels module

Created on Wed Sep 24 08:16:15 2025

@author: edwin.dunnavan

binmod1d.collection_kernels.CKE(di1d, dj1d, vi1d, vj1d)

Collisional Kinetic Energy as defined by Low and List and others.

Parameters:
  • di1d (array (bins,)) – i bin midpoint diameter.

  • dj1d (array (,bins)) – j bin midpoint diameter.

  • vi1d (array (bins,)) – i bin midpoint fall speed.

  • vj1d (array (,bins)) – i bin midpoint diameter.

Returns:

CKE values broadcasted for each i,j bin combination.

Return type:

array (bins,bins)

binmod1d.collection_kernels.Constant_kernel(xi, xj)

Constant kernel

Parameters:
  • xi (array (bins,)) – Bin mass edges for i distribution

  • xj (array (,bins)) – Bin mass edges for j distribution

Returns:

Constant kernel evaluated at bin edge combination.

Return type:

array (bins,bins)

binmod1d.collection_kernels.Golovin_kernel(xi, xj)

Golovin (summation) kernel

Parameters:
  • xi (array (bins,)) – Bin mass edges for i distribution

  • xj (array (,bins)) – Bin mass edges for j distribution

Returns:

Golovin (summation) kernel evaluated at bin edge combination.

Return type:

array (bins,bins)

binmod1d.collection_kernels.Prod_kernel(xi, xj)

Product kernel

Parameters:
  • xi (array (bins,)) – Bin mass edges for i distribution

  • xj (array (,bins)) – Bin mass edges for j distribution

Returns:

Product kernel evaluated at bin edge combination.

Return type:

array (bins,bins)

binmod1d.collection_kernels.Straub_params(di1d, dj1d, vi1d, vj1d)

Straub et al. (2010) fragment distribution parameters

Parameters:
  • di1d (array (bins,)) – i bin midpoint diameter.

  • dj1d (array (,bins)) – j bin midpoint diameter.

  • vi1d (array (bins,)) – i bin midpoint fall speed.

  • vj1d (array (,bins)) – i bin midpoint diameter.

Returns:

Straub_dict – Dictionary of Straub’s parameters for lognormal, two Gaussians, and dirac distributions.

Return type:

dict

binmod1d.collection_kernels.Weber_number(di1d, dj1d, vi1d, vj1d)

Weber number as defined by Low and List and others.

Parameters:
  • di1d (array (bins,)) – i bin midpoint diameter.

  • dj1d (array (,bins)) – j bin midpoint diameter.

  • vi1d (array (bins,)) – i bin midpoint fall speed.

  • vj1d (array (,bins)) – i bin midpoint diameter.

Returns:

We values broadcasted for each i,j bin combination.

Return type:

array (bins,bins)

binmod1d.collection_kernels.hall_kernel(di, dj, vi, vj, Ai, Aj)

Hall (1980) collection kernel.

Parameters:
  • di (array (bins,)) – Bin diameter edges for i distribution

  • dj (array (,bins)) – Bin diameter edges for j distribution

  • vti (array (bins,)) – Bin fall speed edges for i distribution

  • vtj (array (,bins)) – Bin fall speed edges for j distribution

  • Ai (array (bins,)) – Bin collection surface area for i distribution

  • Aj (array (,bins)) – Bin collection surface area for j distribution

Returns:

Kxy – Collection kernel evaluated at bin edges

Return type:

array (bins,bins)

binmod1d.collection_kernels.hydro_kernel(vtx, vty, Ax, Ay)

Hydrodynamic kernel

Parameters:
  • vtx (array (bins,)) – Bin fall speed edges for i distribution

  • vty (array (,bins)) – Bin fall speed edges for j distribution

  • Ax (array (bins,)) – Bin collection surface area for i distribution

  • Ay (array (,bins)) – Bin collection surface area for j distribution

Returns:

Kxy – Hydrodynamic collection kernel evaluated at bin edges

Return type:

array (bins,bins)

binmod1d.collection_kernels.long_kernel(di, dj, vi, vj, Ai, Aj)

Long (1974) kernel as formulated by Simmel et al. (2000)

Parameters:
  • di (array (bins,)) – Bin diameter edges for i distribution

  • dj (array (,bins)) – Bin diameter edges for j distribution

  • vti (array (bins,)) – Bin fall speed edges for i distribution

  • vtj (array (,bins)) – Bin fall speed edges for j distribution

  • Ai (array (bins,)) – Bin collection surface area for i distribution

  • Aj (array (,bins)) – Bin collection surface area for j distribution

Returns:

Kxy – Collection kernel evaluated at bin edges

Return type:

array (bins,bins)

binmod1d.collection_kernels.straub_efficiency(di, dj, vi, vj, Ai, Aj)

Calculates Coalescence Efficiency (E_coal) based on Straub et al. (2010). Equation: Ec = exp(-1.15 * We)

Note: The parameterization is based on CGS units. We must ensure the Weber number calculation uses consistent units.

ALSO, BinMod1D currently does not handle non-constant Es parameterizations! Future versions will incorporate this.

Parameters:
  • di (array (bins,)) – Bin diameter edges for i distribution

  • dj (array (,bins)) – Bin diameter edges for j distribution

  • vti (array (bins,)) – Bin fall speed edges for i distribution

  • vtj (array (,bins)) – Bin fall speed edges for j distribution

  • Ai (array (bins,)) – Bin collection surface area for i distribution

  • Aj (array (,bins)) – Bin collection surface area for j distribution

Returns:

Kxy – Collection kernel evaluated at bin edges

Return type:

array (bins,bins)

binmod1d.distribution module

Created on Wed Sep 24 08:35:18 2025

@author: edwin.dunnavan

binmod1d.distribution.angular_moments(sigma)

Calculates angular moments from Ryzhkov et al. (2011)

Parameters:

sigma (TYPE) – DESCRIPTION.

Returns:

angs – DESCRIPTION.

Return type:

TYPE

binmod1d.distribution.dielectric_ice(lamda, TK)
binmod1d.distribution.dielectric_water(t, eps_0, t0=273.15, wave=110.0)

Calculate dielectric constant for fresh water at temperature T based on Ray (1972).

Input:

Temperature [K]

Output:

Dielectric constant

class binmod1d.distribution.dist(sbin=4, bins=80, D1=0.01, dist_var='mass', kernel='Hydro', habit_dict=None, ptype='rain', Tc=10.0, x0=None, mom_num=2)

Bases: object

A class for initializing a spectral bin distribution

bin_analytical_dist(func_nD, var='size')

Populates bins using user-defined analytical functions. func_N: A lambda returning number concentration (dN/dD or dN/dm) func_M: (Optional) A lambda returning mass concentration var: β€˜diameter’ or β€˜mass’ indicating what the lambda expects.

bin_direct_dist(edges, Nbins, Mbins=None, var='size')

Conservatively regrids discrete user arrays onto the model’s native grid.

Parameters:

edgesarray

Array of length (K+1) defining the user’s bin boundaries.

Nbinsarray

Array of length K defining the absolute total number in each user bin.

Mbinsarray (Optional)

Array of length K defining the absolute total mass in each user bin.

varstr

β€˜diameter’ or β€˜mass’, indicating what physical property edges represents.

bin_empirical_counts(user_edges, user_N, user_M=None)

Conservatively regrids external binned data to the model’s native grid. user_edges: Array of length (N+1) defining the user’s bin boundaries. user_N: Array of length N defining total number in each bin.

bin_empirical_dist(user_edges, user_nD)

Conservatively regrids external PSD data (density n(D)) to the model’s grid.

Parameters:

user_edgesarray

Array of length (K+1) defining the user’s bin boundaries (diameter). Must be in the same units as the model’s internal self.d1 / self.d2

user_nDarray

Array of length K defining the number density n(D). Assumed to be piecewise-constant across the bin.

bin_gamma_dist(Nt0=1.0, Mt0=1.0, mbar=None, mu0=3, Dm0=2, normalize=False)

Description: Set up bins and integrals if using only mass moment

diagnose()

Function for diagnosing uniform distribution function following Wang et al. (2008)

diagnose_1mom()

Function for diagnosing uniform distribution function

init_dist(sbin, bins, D1, kernel='Hydro', habit_dict=None, ptype='rain', Tc=10.0, dist_var='mass', x0=None, mom_num=2)
Parameters:
  • sbin (int) – Spectral bin mass grid resolution. The default is 4.

  • bins (int) – Number of bins used for each distribution. The default is 80

  • D1 (float, optional) – Left-hand edge of first bin in mm if dist_var=’size’. The default is 0.01.

  • kernel (str, optional) –

    Name of collection kernel used. Option must be either:

    kernel=’Golovin’ kernel=’Product’ kernel=’Constant’ kernel=’Hydro’ (Hydrodynamic kernel) kernel=’Long’ (see Long (1974)) kernel=’Hall’ (see Hall (1980)) The default is β€˜Hydro’.

  • habit_dict (dict, optional) – Dictionary with habit parameters. If None, then dictionary will default to β€˜rain’ (see habits.py). The default is None.

  • ptype (str, optional) –

    Type of precipitation. Either, ptype = β€˜rain’

    or

    ptype = β€˜snow’ The default is β€˜rain’.

  • Tc (float, optional) – Assumed mean temperature of layer in degrees Celsius. Currently only used for dielectric constant calculation but eventually will be used for collection kernels and potentially other microphysical processes. The default is 10..

  • dist_var (str, optional) – The independent variable chosen for specifying initial distribution function. dist_var = β€˜size’ (if particle size distribution n(D)) dist_var = β€˜mass’ (if particle mass distribution n(m)) The default is β€˜mass’.

  • x0 (float, optional) – Left-hand edge of first bin in g if dist_var=’mass’. If None, then defaults to 0.01.

  • mom_num (int, optional) – Number of bin moments used to specify subgrid linear distribution (either mom_num=2 or mom_num=1). The default is 2.

moments(r)

Integrates to find arbitrary moments of subgrid distribution Mn = Int x^n *[n(x)=ak*x+ck]*dx

plot(log_switch=True, x_axis='mass', ax=None)

Plots number and mass distributions for distribution object.

Parameters:
  • log_switch (Bool, optional) – Whether distribution scaling is log or linear. The default is True.

  • x_axis (string, optional) – Whether x axis is β€˜mass’ or β€˜size’. The default is β€˜mass’.

  • ax (matplotlib.pyplot axes() object, optional) – Plots number/mass distributions in existing pyplot axes. The default is None.

Returns:

  • fig (matplotlib figure object)

  • ax (matplotlib axes object)

radar_bins()

Calculate radar variables for each bin of distribution.

binmod1d.distribution.extended_brandes(d)

Brandes et al. (2002): https://doi.org/10.1175/1520-0450(2002)041<0674:EIREWA>2.0.CO;2 their equation 2

Modified Brandes AR fit function: - Unity (1.0) at d=0 - Matches original poly between ~0.3743 and 10 - Levels off to 0.4 for d > 10

binmod1d.distribution.rain_terminal_velocity(d_mm)

Calculates terminal velocity (m/s) from diameter (mm) using a Weibull-like fit to the Gunn & Kinzer (1949) measurements according to Equation 5 from Best (1950).

binmod1d.distribution.spheroid_factors(ar)

Calculates spheroid factors for Rayleigh scattering calculations.

Parameters:

ar (TYPE) – DESCRIPTION.

Returns:

  • La (TYPE) – DESCRIPTION.

  • Lc (TYPE) – DESCRIPTION.

binmod1d.distribution.update_1mom(Mbins, dxi)

Updates 1 moment distribution uniform subgrid parameters.

Parameters:
  • Mbins (TYPE) – DESCRIPTION.

  • dxi (TYPE) – DESCRIPTION.

Returns:

DESCRIPTION.

Return type:

TYPE

binmod1d.distribution.update_2mom(Mbins, Nbins, rhobins, bound_low, bound_high, dx, xi1, xi2)

Google Gemini enhanced version of 2 moment subgrid linear distribution diagnosis from Mbins and Nbins. Needed to bug fix. (see original commented).

Parameters:
  • Mbins (TYPE) – DESCRIPTION.

  • Nbins (TYPE) – DESCRIPTION.

  • rhobins (TYPE) – DESCRIPTION.

  • bound_low (TYPE) – DESCRIPTION.

  • bound_high (TYPE) – DESCRIPTION.

  • dx (TYPE) – DESCRIPTION.

  • xi1 (TYPE) – DESCRIPTION.

  • xi2 (TYPE) – DESCRIPTION.

Returns:

  • aki (TYPE) – DESCRIPTION.

  • cki (TYPE) – DESCRIPTION.

  • x1i (TYPE) – DESCRIPTION.

  • x2i (TYPE) – DESCRIPTION.

binmod1d.habits module

Created on Tue Oct 7 09:06:50 2025

@author: edwin.dunnavan

binmod1d.habits.fragments(dist='exp', **kwargs)

This function can be used to generate example fragment distribution functions that spectral_1d() can use based on the desired dist input parameter string. The format of each output dictionary has the same structure. For example, the lognormal fragment distribution has the following default dictionary:

{β€˜dist’: β€˜LGN’,

β€˜var’: β€˜size’, β€˜Df_med’: 0.25, β€˜Df_mode’: 0.2, β€˜cdf_bounds’: (0.5, 0.95), β€˜d_start’: np.float64(0.25), β€˜d_end’: np.float64(0.5437328654539426), β€˜func’: <function binmod1d.habits.fragments.<locals>.<lambda>(n, c, pi, pj)>}

Here, β€˜dist’ is the name of the distribution, β€˜var’ is whether the fragment distribution is defined in terms of mass (β€˜mass’) or size (β€˜size’), β€˜Df_med’ and β€˜Df_mode’ are the lognormal distribution parameters, cdf_bounds are the requested percentile bounds of the lognormal distribution where the distribution will become active. The d_start and d_end parameters correspond to the 50% and 95% percentiles where d<d_start will not be active d_start<d<d_end will ramp from 0 to Eb and d>d_end will have Eb. The lambda function β€˜func’ is the output conditional fragment distribution BIN-WISE MOMENT FUNCTION:

(mass) int_xi1^xi2 m^n P(m|x,y) dm

or

(size) int_d1^d2 d_m^n P(d_m|d_x,d_y) dd_m

that Interaction() will use. Users who want to create their own fragment distributions simply need to structure their lambda function as follows:

FOR β€˜var’ = β€˜size’

func = lambda n, c, pi, pj: dist_int(*params,n,c.d1,c.d2)

FOR β€˜var’ = β€˜mass’

func = lambda n, c, pi, pj: dist_int(*params,n,c.xi1,c.xi2),

where c corresponds to the fragment distribution (i.e., dists[indb]) whereas pi and pj correspond to the i and j distributions (i.e., dists[d1_indices] and dists[d2_indices]).

Note, for marginal distributions which use a static (yet truncated) distribution (as with the examples shown here), pi and pj do not need to be used in the lambda function but still need to be inputs. For conditional fragment distributions of the form p(m|x,y), users can use the pi and pj object inputs to structure the conditional nature of the multivariate distribution function. For example, if the conditional distribution depends upon the i and j bin midpoint fall speeds, then the lambda function structure might be something like:

func = lambda n, c, pi, pj: dist_int(n,c.d1,c.d2,pi.vt,pj.vt).

Parameters:
  • dist (str, optional) – Name of default distribution. The default is β€˜exp’.

  • **kwargs (dict) – Extra parameters.

Returns:

fragments – Dictionary of fragment parameters and lambda function.

Return type:

dict

binmod1d.habits.habits()

Sample habit dictionary parameters that can be used in β€˜habit_params’ input for spectral_1d class.

Returns:

habits – Dictionary of habit parameters.

Return type:

Dict

binmod1d.habits.straub_wrapper(n, c, pi, pj, cdf_bounds=None, state=None)

Evaluates the full 4-part Straub distribution efficiently in 4D.

binmod1d.interaction module

Created on Thu Oct 2 11:31:38 2025

@author: edwin.dunnavan

class binmod1d.interaction.BroadcastNode4D(dist_list, indices, target_axes)

Bases: object

Wraps an array of distributions. Intercepts property requests, stacks them across the pnum axis, and broadcasts them into 4D space: (pnum, fragment_bins, i_bins, j_bins).

class binmod1d.interaction.Interaction(dists, Hlen, cc_dest, br_dest, Eagg, Ecb, Ebr, frag_dict=None, kernel='Golovin', mom_num=2, gpu=False)

Bases: object

Interaction class initializes Interaction objects that contain arrays in the form (Ndists x M x N) which specifies the interactions among all Ndists distributions.

calc_smootherstep(d_array, d_start, d_end)

Calculates the quintic smootherstep function over an array. Mathematically guarantees 1st and 2nd derivatives are zero at the boundaries.

Parameters:
  • d_array (np.ndarray) – Array of diameters to evaluate.

  • d_start (float) – Diameter where efficiency starts to rise above 0.

  • d_end (float) – Diameter where efficiency reaches 1.0.

Returns:

Scale factors from 0.0 to 1.0 matching the shape of d_array.

Return type:

np.ndarray

create_kernels(dists)

Creates collection kernel bilinear coefficients for requested kernel type.

Parameters:

dists (TYPE) – DESCRIPTION.

Returns:

DESCRIPTION.

Return type:

TYPE

get_dynamic_params()

Synchronizes moving grid edges and evolving distributions into a single parameter dictionary.

get_dynamic_params_1mom()

Flattens everything into 1D vectors. This removes all 3D/4D indexing from the Numba kernel.

interact_1mom(dt)

Interaction kernel calculation for 1 moment scheme.

interact_2mom(dt)

Interaction kernel calculation for 2 moment scheme.

setup_1mom()

Sets up 1 moment calculations

setup_fragments()

Sets up conditional fragment distribution based on self.kernel.

update_1mom_subgrid()

Updates 1 moment subgrid uniform distribution parameters from Mbins

update_2mom_subgrid()

Updates 2 moment subgrid linear distribution from Mbins and Nbins

binmod1d.plotting_functions module

Created on Mon Oct 13 10:50:41 2025

@author: edwin.dunnavan

binmod1d.plotting_functions.get_cm_cmaps()

Generate colormap lists of NWS colormaps from cmweather python package

Returns:

  • NWS_REF_COLORS (List) – NWS Ref colormap list.

  • THEODORE16_COLORS (List) – THEODORE16 colormap list.

  • NWS_CC_COLORS (TYPE) – NWS CC colormap list.

  • RRATE11_COLORS (TYPE) – RRATE11 colormap list.

binmod1d.plotting_functions.get_cmap_vars(varname)
Parameters:

varname (str) – Variable name.

Returns:

  • cmap (matplotlib.color colorbar) – colorbar handle.

  • levels (array or list) – Array or list of levels for contours.

  • levels_ticks (array or list) – Array or list of ticks for levels.

  • clabel (str) – Colorbar label.

  • labelpad (int) – matplotlib colorbar labelpad parameter.

  • fontsize (int) – fontsize for colorbar title.

  • slabel (str) – Shorthand label for colorbar.

binmod1d.radar module

Created on Thu Jan 29 08:23:48 2026

@author: edwin.dunnavan

binmod1d.radar.angular_moments(sigma)

Calculate angular moments following Ryzhkov et al. (2011)

Parameters:

sigma (float) – Axisymmteric Gaussian angle standard deviation (generally between 0 and 40 deg) from Ryzhkov et al. (2011).

Returns:

angs – Angular moments in order: [Ang1,Ang2,Ang3,Ang4,Ang5,Ang6,Ang7].

Return type:

array

binmod1d.radar.dielectric_ice(lamda, TK)

Ray (1972) dielectric constant calculation for ice.

Parameters:
  • lamda (froat) – Radar wavelength in mm.

  • TK (float) – Air temperature in Kelvin.

Returns:

ei – Dielectric constant of ice for wavelength and temperature.

Return type:

complex

binmod1d.radar.dielectric_water(t, eps_0, t0=273.15, wave=110.0)

Calculate dielectric constant for fresh water at temperature T based on Ray (1972).

Parameters:
  • t (float) – Air temperature in Kelvins.

  • eps_0 (Dielectric constant for liquid water at 0 C.) – DESCRIPTION.

  • t0 (float, optional) – 0 degrees Celsisus in Kelvins. The default is 273.15.

  • wave (float, optional) – Radar wavelength in mm. The default is 110..

Returns:

ew – Dielectric constant for liquid water at temperature and radar wavlength.

Return type:

complex

binmod1d.radar.spheroid_factors(ar)

Calculate spheroid factors

Parameters:

ar (array) – Particle aspect ratios.

Returns:

  • La (array) – Geometric shape factor along a axis.

  • Lc (array) – Geometric shape factor along c axis

binmod1d.spectral_model module

Created on Thu Sep 4 11:51:00 2025

@author: Edwin L. Dunnavan, RSII Cooperative Institute for Severe and High-Impact

Weather Research and Operations (CIWRO)

Description:

This code can be used to generate model objects representing collision-coalescence and collisional breakup based on the Wang et al. (2007) source-based solution to the Kinetic Collection Equation (KCE).

Version 1.0.10

binmod1d.spectral_model.get_kwargs(kwargs)

Get kwargs for figure, axis, and plot.

binmod1d.spectral_model.latex_check()

Verifies that all executables required by Matplotlib’s usetex engine are in the system PATH.

class binmod1d.spectral_model.spectral_1d(sbin=2, bins=60, dt=1, tmax=800.0, output_freq=1, dz=10.0, ztop=0.0, zbot=0.0, D1=0.1, x0=0.05, Ecol=1.0, Es=1.0, Eb=0.0, moments=2, dist_var='size', kernel='Hydro', frag_dist='LGN', habit_params='rain', ptype='rain', Tc=10.0, boundary=None, cc_dest=1, br_dest=1, radar=False, wavl=110.0, rk_order=1, adv_order=1, gpu=False, load=None, progress=True, **kwargs)

Bases: object

calc_micro()

Calculate microphysical variables

calc_moments(r, moments=2)

Calculates bin-wise moments using subgrid distributions.

Parameters:
  • r (int) – Moment order.

  • moments (int, optional) – Whether 2-moment or 1-moment subgrid distribution. The default is 2.

Returns:

Bin-wise moments.

Return type:

float array

calc_radar()

Calculates radar variables from Mbins and Nbins.

clean_up()

Method for cleaning up spectral_1d object after model runs.

diagnose_subgrid()

Diagnoses 2-moment and 1-moment subgrid distribution parameters.

get_sed_rate_2mom_only(M_curr, N_curr)

Calculates pure sedimentation rate (dM/dt, dN/dt) for 2-moment. Does NOT apply boundary clamping (allows flux to flow).

get_sed_rate_only(M_curr)

Calculates pure sedimentation rate (dM/dt). Does NOT apply boundary clamping (allows flux to flow).

get_steady_rate_1mom(M_curr)

Helper function to calculate derivatives for the Steady State RK scheme. Updates the kernel state and returns the rate of change.

get_steady_rates(M_curr, N_curr)

Helper function to calculate derivatives for the Steady State RK scheme. Equivalent to β€˜advance_2mom’ but for the steady-state loop.

load_case(filename)

Loads netcdf file variables and attributes into spectral_1d object.

Parameters:

filename (str) – Filename of netcdf file.

plot_dists(tind=-1, hind=-1, x_axis='mass', xscale='log', yscale='linear', distscale='log', normbin=False, scott_solution=False, feingold_solution=False, plot_habits=False, plot_init=True, ax=None, **kwargs)
Parameters:
  • tind (int, optional) – Time index for plotting moments if steady-state or full 1D model run. The default is -1.

  • hind (int, optional) – Height index for plotting moments if steady-state or full 1D model run. The default is -1 (i.e., bottom level).

  • x_axis (str, optional) – x axis variable. Either β€˜size’ or β€˜mass’. The default is β€˜mass’.

  • xscale (TYPE, optional) – Whether to plot x axis with linear (β€˜linear’) or log (β€˜log’) scaling. The default is β€˜log’.

  • yscale (str, optional) – Whether to plot y axis with linear (β€˜linear’) or log (β€˜log’) scaling. The default is β€˜linear’.

  • distscale (str, optional) – Whether to plot distribution functions in a log-scaled way (e.g., dN/dlog(m)). The default is β€˜log’.

  • normbin (bool, optional) – Normalize number (mass) distribution function by total number (mass). The default is False.

  • scott_solution (bool, optional) – Plots Scott (1968) analytical solutions for Golovin, Product, or Constant kernels. The default is False.

  • feingold_solution (bool, optional) – Whether to plot Feingold et al. (1988) analytical solutions to SBE or SCE/SBE steady-state. The default is False.

  • plot_habits (bool, optional) – Plots individual habit variables. The default is False.

  • plot_init (bool, optional) – Whether to plot initial distribution functions. The default is True.

  • ax (array of objects, optional) – Array of Matplotlib pyplot axes objects for each subplot. If None, then create new figure and axes. The default is None.

  • **kwargs (dict) – Keyword arguments to be passed into axes and/or plots.

Returns:

  • fig (object) – Matplotlib pyplot figure object.

  • ax (objects) – Numpy array of Matplotlib pyplot axes objects.

plot_dists_height(tind=-1, dz=1.0, plot_habits=False, **kwargs)

Plots number distribution function at various height levels. Note, only works for steady-state or full 1D time/height modes.

Parameters:
  • tind (int, optional) – Time index for plotting moments if steady-state or full 1D model run. The default is -1.

  • dz (float, optional) – Height difference (in km) between each subplot (starting with topmost height level, ztop). The default is 1..

  • plot_habits (bool, optional) – Plots individual habit variables. The default is False.

  • **kwargs (dict) – Keyword arguments to be passed into axes and/or plots.

Returns:

  • fig (object) – Matplotlib pyplot figure object.

  • ax (objects) – Numpy array of Matplotlib pyplot axes objects.

plot_init(x_axis='mass', xscale='log', yscale='linear', distscale='log', normbin=False, plot_habits=False, **kwargs)
Parameters:
  • x_axis (str, optional) – x axis variable. Either β€˜size’ or β€˜mass’. The default is β€˜mass’.

  • xscale (TYPE, optional) – Whether to plot x axis with linear (β€˜linear’) or log (β€˜log’) scaling. The default is β€˜log’.

  • yscale (str, optional) – Whether to plot y axis with linear (β€˜linear’) or log (β€˜log’) scaling. The default is β€˜linear’.

  • distscale (str, optional) – Whether to plot distribution functions in a log-scaled way (e.g., dN/dlog(m)). The default is β€˜log’.

  • normbin (bool, optional) – Normalize number (mass) distribution function by total number (mass). The default is False.

  • plot_habits (bool, optional) – Plots individual habit variables. The default is False.

  • **kwargs (dict) – Keyword arguments to be passed into axes and/or plots.

Returns:

  • fig (object) – Matplotlib pyplot figure object.

  • ax (objects) – Numpy array of Matplotlib pyplot axes objects.

plot_moments_radar(ax=None, tind=-1, plot_habits=False, **kwargs)

Plots timeseries or height profiles of bulk microphysical parameters and radar parameters from spectral_1d model run.

Parameters:
  • ax (object, optional) – Matplotlib pyplot axes object. If none, then create new figure and axes. The default is None.

  • tind (int, optional) – Time index for plotting moments if steady-state or full 1D model run. The default is -1.

  • plot_habits (bool, optional) – Plots individual habit variables. The default is False.

  • **kwargs (dict) – Keyword arguments to be passed into axes and/or plots.

Returns:

  • fig (object) – Matplotlib pyplot figure object.

  • ax (objects) – Numpy array of Matplotlib pyplot axes objects.

plot_time_height(var='Z', ax=None, **kwargs)

Plots time/height profile of microphysical or radar variables from full 1D column model spectral_1d run.

Parameters:

var (TYPE, optional) – DESCRIPTION. The default is β€˜Z’.

Returns:

  • fig (object) – Matplotlib pyplot figure object.

  • ax (objects) – Matplotlib pyplot axes object.

run()

Runs bin model for user-prescribed parameters.

run_full_1mom(pbar=None)

Run full 1D bin model using Adaptive Sub-stepping RK4. Matches original BC logic and optimizes CFL calculation.

run_full_2mom(pbar=None)

Run full 1D bin model (2-Moment) using Adaptive Sub-stepping RK4.

  1. Physics: Calculated ONCE over full dt (Linearized Source).

  2. Transport: Calculated iteratively using update_2mom_subgrid (Accuracy).

  3. Stability: Adaptive sub-stepping handles CFL and Depletion (M & N).

run_steady_state_1mom(pbar=None)

Run steady-state bin model (1-Moment) using Explicit Runge-Kutta integration. Uses ADAPTIVE SUB-STEPPING based on β€œFraction of Residence Time”.

run_steady_state_2mom(pbar=None)

Run steady-state bin model using Explicit Runge-Kutta integration. Uses ADAPTIVE SUB-STEPPING based on β€œFraction of Residence Time”.

setup_case(sbin=4, bins=160, D1=0.001, x0=0.01, dist_var='mass', kernel='Golovin', Ecol=1.53, Es=0.001, Eb=0.0, moments=2, ztop=3000.0, zbot=0.0, zout=None, tout=None, tmax=800.0, output_freq=1, dt=10.0, dz=10.0, frag_dist='exp', habit_dict=None, ptype='rain', Tc=10.0, radar=False, wavl=110.0, boundary=None, cc_dest=1, br_dest=1, rk_order=1, adv_order=1, gpu=False, progress=True, **kwargs)

Set’s up BinMod1D model for solving the SCE/SBE equation for user-prescribed parameters.

Parameters:
  • sbin (int) – Spectral bin mass grid resolution. The default is 4.

  • bins (int) – Number of bins used for each distribution. The default is 56.

  • D1 (float, optional) – Minimum equivolume diameter bin size in mm when the β€˜dist_var’ parameter is β€˜size’. The default is 0.25.

  • x0 (float, optional) – Minimum bin mass in grams when the β€˜dist_var’ parameter is β€˜mass’.. The default is 0.05.

  • dist_var (str, optional) – Whether to use mass or size to specify initial gamma distribution. The default is β€˜mass’.

  • kernel (str, optional) – Type of collision kernel in collection_kernels.py to use for coalescence/breakup. The default is β€˜Golovin’.

  • Ecol (float, optional) – Collision efficiency. The default is 1.0.

  • Es (float, optional) – Sticking efficiency. The default is 1.0.

  • Eb (float, optional) – Breakup efficiency. The default is 0..

  • moments (int, optional) – Number of moments to use for spectral bin model (either 1 (mass) or 2 (mass and number)). The default is 2.

  • ztop (float, optional) – Top height of steady-state/1D model domain in meters. The default is 0..

  • zbot (float, optional) – Bottom height of steady-state/1D model domain in meters. The default is 0..

  • tmax (float, optional) – Maximum time in seconds the model is run. The default is 800.

  • output_freq (int, optional) – Frequency in time with which the Full 1D column model is output. The default is 60..

  • dt (float, optional) – Model time step in seconds. The default is 1.

  • dz (float, optional) – Height grid spacing in meters. The default is 10..

  • frag_dist (str, optional) – Type of fragment distribution. The default is β€˜exp’.

  • habit_params (list, optional) – List of distribution parameters for each category (total distribution number determined by len(habit_lists)). elements of list can be either strings where each string defines a default habit type from the habits() function in the habits module or a dictionary with the necessary parameters. The default is [β€˜rain’].

  • ptype (str, optional) – Whether particles are rain or snow. NOTE: currently not considering mixed phase or mixture of rain/show. The default is β€˜rain’.

  • Tc (float, optional) – Layer-averaged temperature in degrees Celsius. Used in radar calculations. The default is 10..

  • boundary (Nonetype or str, optional) –

    Upper boundary conditions for full 1D model: None = fallout mode for 1D model

    ’fixed’ = fixed upper boundary condition. The default is None.

  • cc_dest (int, optional) – Distribution destination of coalesced particles. Index (1 = first distribution) corresponds to the distribution in habit_list. The default is 1.

  • br_dest (int, optional) – Distribution destination of breakup (fragment) particles. Index (1 = first distribution) corresponds to the distribution in habit_list. DESCRIPTION. The default is 1.

  • radar (bool, optional) – Whether to calculate radar variables for each bin. The default is False.

  • wavl (float, optional) – Radar wavelength in mm.

  • rk_order (int, optional) – Runge-Kutta time stepping order. The default is 1.

  • adv_order (int, optional) – Upwind advection scheme order (CURRENTLY NOT IMPLMENTED YET). The default is 1.

  • gpu (bool, optional) – Whether to use GPU (if available) (CURRENTLY NOT IMPLEMENTED YET). The default is False.

  • load (str, optional) – If loading spectral_1d() object from netcdf file, this is the path string to the netcdf file. None means no loading. The default is None.

  • progress (bool, optional) – If using a progressbar when using run() method. The default is None.

  • **kwargs (TYPE) – DESCRIPTION.

setup_habits(habit_params, psd_params=None)

Set’s up habits based on habit_params list.

Parameters:
  • habit_params (list or str or dict) – Habit parameters for each desired distribution.

  • psd_params (dict, optional) – PSD parameters. The default is None.

setup_radar()
write_netcdf(filename, save_radar=False)

Writes netcdf file for spectral_1d object.

Parameters:
  • filename (str) – Path and filename of netcdf file.

  • save_radar (bool, optional) – Whether to save total radar variables to netcdf file. The default is False.

Module contents