adding_doubling_solver module
Here the ice/impurity optical properties and illumination conditions are used to calculate energy fluxes between the ice, atmosphere and underlying substrate.
Typically this function would be called from main.py
because it takes as inputs intermediates that are calculated elsewhere.
Specifically, the functions setup_snicar()
, get_layer_OPs()
and mix_in_impurities()
are called to generate tau
, ssa
, g
and L_snw
,
which are then passed as inputs to adding_doubling_solver()
.
The adding-doubling routine implemented here originates in Brieglib and Light (2007) and was coded up in Matlab by Chloe Whicker and Mark Flanner to be published in Whicker (2022: The Cryosphere). Their scripts were the jumping off point for this script and their code is still used to benchmark this script against.
The adding-doubling solver implemented here has been shown to do an excellent job at simulating solid glacier ice. This solver can either treat ice as a "granular" material with a bulk medium of air with discrete ice grains, or as a bulk medium of ice with air inclusions. In the latter case, the upper boundary is a Fresnel reflecting surface. Total internal reflection is accounted for if the irradiance angles exceed the critical angle.
This is always the appropriate solver to use in any model configuration where solid ice layers and fresnel reflection are included.
adding_doubling_solver:
Control function for the adding-doubling solver.
Makes function calls in sequence to generate, then return, an instance of Outputs
.
Args:
tau
: optical thickness of ice column in m/mssa
: single scattering albedo of ice column (dimensionless)g
: asymmetry parameter for ice columnL_snw
: mass of ice in lgice
: instance of Ice classillumination
: instance of Illumination classmodel_config
: instance of ModelConfig class
Returns:
outputs
: Instance of Outputs class
Raises:
ValueError
if violation of conservation of energy detected
calc_reflectivity_transmittivity
Calculates reflectivity and transmissivity. Sets up new variables, applies delta transformation and makes initial calculations of reflectivity and transmissivity in each layer.
Args:
tau0
: initial optical thicknessssa0
: initial single scattering albedog0
: initial asymmetry parameterlyr
: index of current layermodel_config
: instance of ModelConfig classexp_min
: small number to avoid /zero errorrdif_a
: reflectivity to diffuse irradiance at polarization angle == perpendiculartdif_a
: transmissivity to diffuse irradiance at polarization angle == perpendiculartrnlay
: transmission through layermu0n
: incident beam angle adjusted for refractionepsilon
: small number to avoid singularityrdir
: reflectivity to direct beamtdir
: transmissivity to direct beam
Returns:
rdir
:tdir
:ts
:ws
:gs
:lm
:
define_constants_arrays
Defines and instantiates all variables required for calculating energy fluxes using the adding-doubling method.
Args:
tau
: optical thickness of ice column in m/mg
:asymmetry parameter for ice columnssa
: single scattering albedo of ice column (dimensionless)ice
: instance of Ice classillumination
: instance of Illumination classmodel_config
: instance of ModelConfig class
Returns:
tau0
: initial optical thickness (m/m)g0
: initial asymmetry parameter (dimensionless)ssa0
: initial single scatterign albedo (dimensionless)epsilon
: small number to avoid singularityexp_min
: small number to avoid zero calcsnr
: real part of refractive indexmu0
: cosine of direct beam zenith anglemu0n
: adjusted cosine of direct beam zenith angle after refractiontrnlay
: transmission through layerrdif_a
: reflectivity to diffuse irradiance at polarization angle == perpendicularrdif_b
: reflectivity to diffuse irradiance at polarization angle == paralleltdif_a
: transmissivity to diffuse irradiance at polarization angle == perpendiculartdif_b
: transmissivity to diffuse irradiance at polarization angle == parallelrdir
: reflectivity to direct beamtdir
: transmissivity to direct beamlyrfrsnl
: index of uppermost fresnel reflecting layer in ice columntrnlay
:rdif_a
:rdif_b
:tdif_a
:tdif_b
:rdir
:tdir
:rdndif
:trntdr
:trndir
:trndif
:fdirup
:fdifup
:fdirdn
:fdifdn
:dfdir
:dfdif
:F_up
:F_dwn
:F_abs
:F_abs_vis
:F_abs_nir
:rupdif
:rupdir
:
calc_reflection_transmission_from_top
Calculates the reflection and transmission of energy at top surfaces.
Args:
lyr
: integer representing the index of the current layer (0 at top)trnlay
: transmissivity of current layerrdif_a
: reflectivity to diffuse irradiance at polarization state == perpendicularrdir
: reflectivity to direct beamtdif_a
: transmissivity to diffuse irradiance at polarization state == perpendicularrdif_b
: reflectivity to diffuse irradiance at polarization state == paralleltdir
: transmissivity to direct beamtdif_b
: transmissivity to diffuse irradiance at polarization state == parallelmodel_config
: instance of ModelConfig classice
: instance of Ice classtrndir
:rdndif
:trntdr
:trndif
:
Returns:
trndir
: transmission of direct beamtrntdr
: total transmission of direct beam for all layers above current layerrdndif
: downwards diffuse reflectancetrndif
: diffuse transmission
apply_gaussian_integral
Applies gaussian integral to integrate over angles. Uses Gaussian integration to integrate fluxes hemispherically from N reference angles where N = len(gauspt) (default is 8).
Args:
model_config
: instance of ModelConfig classexp_min
: small number for avoiding div/0 errorts
: delta-scaled extinction optical depth for lyrws
: delta-scaled single scattering albedo for lyrgs
: delta-scaled asymmetry parameter for lyrepsilon
: small number to avoid singularitylm
: lamda for use in delta scalinglyr
: integer representing index of current layer (0==top)rdif_a
: reflectance to diffuse energy w polarization state == perpendiculartdif_a
: transmittance to diffuse energy w polarization state == perpendicular
Returns:
smt
: accumulator for tdif gaussian integrationsmr
: accumulator for rdif gaussian integrationswt
: sum of gaussian weights
update_transmittivity_reflectivity
Updates transmissivity and reflectivity values after iterations.
Args:
swt
: sum of gaussian weights (for integrating over angle)smr
: accumulator for rdif gaussian integrationsmt
: accumulator for tdif gaussian integrationlyr
: integer representign index of current layer (0 == top)rdif_a
: reflectance to diffuse energy w polarization state == perpendicularrdif_b
: reflectance to diffuse energy w polarization state == paralleltdif_a
: transmittance to diffuse energy w polarization state == perpendiculartdif_b
: transmittance to diffuse energy w polarization state == parallel
Returns:
rdif_a
: updated reflectance to diffuse energy w polarization state == perpendicularrdif_b
: updated reflectance to diffuse energy w polarization state == paralleltdif_a
: updated transmittance to diffuse energy w polarization state == perpendiculartdif_b
: updated transmittance to diffuse energy w polarization state == parallel
calc_correction_fresnel_layer
Calculates correction for Fresnel reflection and total internal reflection. Corrects fluxes for Fresnel reflection in cases where total internal reflection does and does not occur (angle > critical_angle). In TIR case fluxes are precalculated because ~256 gaussian points required for convergence.
Args:
model_config
: instance of ModelConfig classice
: instance of Ice classillumination
: instance of Illumination classmu0n
: incidence angle for direct beam adjusted for refractionmu0
: incidence angle of direct beam at upper surfacenr
: real part of refractive indexrdif_a
: reflectance to diffuse energy w polarization state == perpendicularrdif_b
: reflectance to diffuse energy w polarization state == paralleltdif_a
: transmittance to diffuse energy w polarization state == perpendiculartdif_b
: transmittance to diffuse energy w polarization state == paralleltrnlay
: transmission of layer == lyrlyr
: current layer (0 ==top)rdir
: reflectance to direct beamtdir
: transmission of direct beam
Returns:
rdif_a
: updated reflectance to diffuse energy w polarization state == perpendicularrdif_b
: updated reflectance to diffuse energy w polarization state == paralleltdif_a
: updated transmittance to diffuse energy w polarization state == perpendiculartdif_b
: updated transmittance to diffuse energy w polarization state == paralleltrnlay
: updated transmission of layer == lyrrdir
:updated reflectance to direct beamtdir
: updated transmission of direct beam
calc_reflection_below
Calculates dir/diff reflectyivity for layers below surface. Computes reflectivity to direct (rupdir) and diffuse (rupdif) radiation for layers below by adding succesive layers starting from the underlying ice and working upwards.
Args:
model_config
: instance of ModelConfig classice
: instance of Ice classrdif_a
: reflectance to diffuse energy w polarization state == perpendicularrdif_b
: reflectance to diffuse energy w polarization state == paralleltdif_a
: transmittance to diffuse energy w polarization state == perpendiculartdif_b
: transmittance to diffuse energy w polarization state == paralleltrnlay
: transmission of layer == lyrrdir
: reflectance to direct beamtdir
: transmission of direct beamrupdif
: upwards flux directrupdir
: upwards flux diffuse
Returns:
rupdir
: upwards flux directrupdif
: upwards flux diffuse
trans_refl_at_interfaces
Calculates transmission and reflection at layer interfaces.
Args:
model_config
: instance of ModelConfig classice
: instance of Ice classrupdif
: total diffuse radiation reflected upwardsrupdir
: total direct radiation reflected upwardsrdndif
: downwards reflection of diffuse radiationtrndir
: transmission of direct radiationtrndif
: transmission of diffuse radiationtrntdr
: total transmissionfdirup
:fdirdn
:fdifup
:fdifdn
:dfdir
:dfdif
:
Returns:
fdirup
: upwards flux of direct radiationfdifup
: upwards flux of diffuse radiationfdirdn
: downwards flux of direct radiationfdifdn
: downwards flux of diffuse radiation
calculate_fluxes
Calculates total fluxes in each layer and for entire column.
Args:
model_config
: instance ofModelConfig
classice
: instance ofIce
classillumination
: instance ofIllumination
classfdirup
: upwards flux of direct radiationfdifup
: upwards flux od diffuse radiationfdirdn
: downwards flux of direct radiationfdifdn
: downwards flux of diffuse radiationF_up
:F_dwn
:F_abs
:F_abs_vis
:F_abs_nir
:
Returns:
albedo
: ratio of upwards fluxes to incoming irradianceF_abs
: absorbed flux in each layerF_btm_net
: net fluxes at bottom surfaceF_top_pls
: upwards flux from upper surface
conservation_of_energy_check
Checks there is no conservation of energy violation.
Args:
illumination
: instance of Illumination classF_abs
: absorbed flux in each layerF_btm_net
: net flux at bottom surfaceF_top_pls
: upwards flux from upper boundary
Returns:
None
Raises:
ValueError
is conservation of energy error is detected
get_outputs
Assimilates useful data into instance of Outputs class.
Args:
illumination
: instance of Illumination classalbedo
: ratio of upwwards fluxes and irradiancemodel_config
: instance of ModelConfig classL_snw
: mass of ice in each layerF_abs
: absorbed flux in each layerF_btm_net
: net flux at bottom surface
Returns:
outputs
: instance of Outputs class