Development manual
Contributing
If you are interested in contributing to the model, please contact the developers using the information on the main page.
Coding style
- Indentation uses 4 spaces, no tabs.
- Function names should be lowercase, with words separated by underscores .
- Lines should aim to have a length of no more than 92 characters.
- All functions should have docstrings, ideally with Arguments and Returns listed.
- More comments are always better, even if they seem redundant.
- Use type hinting where possible.
- Print statements should be made through the logger where possible.
- The core package code should not contain global variables, except in the phys module.
Code reference
Atmosphere initialisation and variables
Functions from atmosphere.jl
.
AGNI.atmosphere.allocate!
— MethodAllocate atmosphere arrays, prepare spectral files, and final steps.
Will not modify spectral file if stellar_spectrum
` is an empty string.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.stellar_spectrum::String
path to stellar spectrum csv file
AGNI.atmosphere.calc_layer_props!
— MethodCalculate properties within each layer of the atmosphere (e.g. density, mmw).
Arguments: - atmos::Atmos_t
the atmosphere struct instance to be used. - ignore_errors::Bool
do not generate errors from hydrostatic integrator.
Returns: - ok::Bool
function result is ok
AGNI.atmosphere.calc_observed_rho!
— MethodCalculate observed radius and bulk density.
This is done at the layer probed in transmission, which is set to a fixed pressure.
Arguments: - atmos::Atmos_t
the atmosphere struct instance to be used.
Returns: - transspec_rho::Float64
the bulk density observed in transmission
AGNI.atmosphere.calc_profile_cpkc!
— MethodCalculate specific heat capacity and thermal conductivity for all layers.
Specific heat per unit mass: J K-1 kg-1. Thermal conductivity: W m-1 K-1.
Arguments: - atmos::Atmos_t
the atmosphere struct instance to be used.
AGNI.atmosphere.calc_profile_density!
— MethodCalculate the mass-density for all layers.
Requires temperature, pressure, mmw to be already have been set.
Arguments: - atmos::Atmos_t
the atmosphere struct instance to be used.
AGNI.atmosphere.calc_profile_mmw!
— MethodCalculate mean molecular weight for all layers.
MMW stored as kg/mol.
Arguments: - atmos::Atmos_t
the atmosphere struct instance to be used.
AGNI.atmosphere.calc_profile_radius!
— MethodCalculate radius and gravity for all layers.
Performs hydrostatic integration from the ground upwards. Requires density, temperature, pressure to have already been set.
Arguments: - atmos::Atmos_t
the atmosphere struct instance to be used. - ignore_errors::Bool
do not generate errors from hydrostatic integrator.
Returns: - ok::Bool
function result is ok
AGNI.atmosphere.calc_single_cpkc!
— MethodCalculate specific heat capacity and thermal conductivity of a single layer.
Specific heat per unit mass: J K-1 kg-1. Thermal conductivity: W m-1 K-1.
Arguments: - atmos::Atmos_t
the atmosphere struct instance to be used. - idx::Int
index of the layer
AGNI.atmosphere.calc_single_density!
— MethodCalculate the mass-density of a single layer.
Requires temperature, pressure, mmw to be already have been set.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.idx::Int
index of the layer
AGNI.atmosphere.estimate_photosphere!
— MethodEstimate photosphere.
Estimates the location of the photosphere by finding the median of the contribution function in each band (0.2 um to 150 um), and then finding the pressure level at which these median values are maximised.
Arguments: - atmos::Atmos_t
the atmosphere struct instance to be used.
Returns: - p_ref::Float64
pressure level of photosphere [Pa]
AGNI.atmosphere.generate_pgrid!
— MethodGenerate pressure grid.
Almost-equally log-spaced between pboa and pboa. The near-surface layers are smaller than they would be on an equally log-spaced grid, to avoid f numerical weirdness at the bottom boundary.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.
AGNI.atmosphere.integrate_hydrograv
— MethodIntegrate hydrostatic and gravity equations across a pressure interval.
Uses the classic fourth-order Runge-Kutta method.
Arguments: - r0::Float64
radius at start of interval [m] - g0::Float64
gravity at start of interval [m s-2] - p0::Float64
pressure at start of interval [Pa] - p1::Float64
pressure at end of interval [Pa] - rho::Float64
density throughout interval, constant [kg m-3]
Returns: - r1::Float64
radius at end of interval [m]
AGNI.atmosphere.set_tmpl_from_tmp!
— MethodSet cell-edge temperatures from cell-centre values.
Uses interpolation within the bulk of the column and extrapolation for the topmost edge.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.
AGNI.atmosphere.setup!
— MethodSet parameters of the atmosphere.
This is used to set up the struct immediately after creation. It must be done before allocate!()
is called, and before any RT calculcations are performed.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.ROOT_DIR::String
AGNI root directory.OUT_DIR::String
Output directory.spfile::String
path to spectral file.instellation::Float64
bolometric solar flux at the top of the atmosphere [W m-2]s0_fact::Float64
scale factor to account for planetary rotation (i.e. S0^*/S0 in Cronin+14)albedo_b::Float64
bond albedo scale factor applied to instellation in order to imitate shortwave reflectionzenith_degrees::Float64
angle of radiation from the star, relative to the zenith [degrees].tmp_surf::Float64
effective surface temperature to provide upward longwave flux at the bottom of the atmosphere [K].gravity::Float64
gravitational acceleration at the surface [m s-2].radius::Float64
planet radius at the surface [m].nlev_centre::Int
number of model levels.p_surf::Float64
total surface pressure [bar].p_top::Float64
total top of atmosphere pressure [bar].mf_dict::Dict
dictionary of VMRs in the format (key,value)=(gas,mf).mf_path::String
path to file containing VMRs at each level.
Optional arguments:
condensates
list of condensates (gas names).surface_material::String
surface material (default is "greybody", but can point to file instead).albedo_s::Float64
grey surface albedo used whensurface_material="greybody"
.tmp_floor::Float64
temperature floor [K].C_d::Float64
turbulent heat exchange coefficient [dimensionless].U::Float64
surface wind speed [m s-1].Kzz_floor::Float64
eddy diffusion coefficient, min value [cm2 s-1]tmp_magma::Float64
mantle temperature [K] for sol_type==2.skin_d::Float64
skin thickness [m].skin_k::Float64
skin thermal conductivity [W m-1 K-1].overlap_method::String
gaseous overlap scheme (ro: rand overlap, ee: equiv extinct, rorr: ro+resort+rebin).target_olr::Float64
target OLR [W m-2] for sol_type==4.flux_int::Float64
planet's internal flux for sol_type==3.all_channels::Bool
use all channels available for RT?flag_rayleigh::Bool
include rayleigh scattering?flag_gcontinuum::Bool
include generalised continuum absorption?flag_continuum::Bool
include continuum absorption?flag_aerosol::Bool
include aersols?flag_cloud::Bool
include clouds?real_gas::Bool
use real gas EOS where possiblethermo_functions::Bool
use temperature-dependent thermodynamic propertiesuse_all_gases::Bool
store information on all supported gases, incl those not provided in cfg
Returns: Nothing
AGNI.atmosphere.water_cloud!
— MethodManually set water cloud properties at saturated levels.
Uses the default mass mixing ratio, area fraction, and droplet sizes. This function is redundant if condensation is done via chemsitry.handle_saturation!()
.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.
Energy flux evaluation
Functions from energy.jl
.
AGNI.energy.calc_fluxes!
— MethodCalculate energy flux at each level.
Calculates flux components (radtrans, convection, etc.) and sums them to get total flux. Also updates thermodynamic properties (heat capacity, density, etc.) at each layer.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.latent::Bool
include condensation fluxconvect::Bool
include MLT convection fluxsens_heat::Bool
include TKE sensible heat transportconduct::Bool
include conductive heat transportconvect_sf::Float64
scale factor applied to convection fluxeslatent_sf::Float64
scale factor applied to phase change fluxescalc_cf::Bool
calculate LW contribution function?rainout::Bool
allow rainout ( do not reset VMRs to dry values )
AGNI.energy.calc_hrates!
— MethodCalculate heating rates at cell-centres from the total flux.
Requires the total flux to have already been set (atmos.flux_tot). Heating rates are calculated in units of kelvin per day.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.
AGNI.energy.condense_diffuse!
— MethodAnalytical diffusion scheme for condensation and evaporation energy.
Integrates from bottom of model upwards. Based on the amount of phase change at each level, a phase change flux is calculated by assuming a fixed condensation timescale.
Updates fluxes. Requires chemistry.handle_saturation
to be called first in the multi-component case.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.
AGNI.energy.convection!
— MethodCalculate dry convective fluxes using mixing length theory.
Uses the mixing length formulation outlined by Joyce & Tayar (2023), which was also implemented in Lee et al. (2024), and partially outlined in an earlier paper by Robinson & Marley (2014).
https://arxiv.org/abs/2303.09596 https://doi.org/10.1093/mnras/stae537 https://ui.adsabs.harvard.edu/abs/1962JGR....67.3095B/abstract
Convective energy transport fluxes are calculated at every level edge, just like the radiative fluxes. This is not compatible with moist convection. By using MLT to parameterise convection, we can also calculate Kzz directly.
The mixing length is set to asymptotically approach H (for z>>H) or z (for z<H) as per Blackadar (1962). Alternatively, it can be set equal to H.
The scale height is formulated as: Hp = P / (ρ g)
The adiabatic lapse rate is formulated as: ∇_ad = dln(T)/dln(P) = (P/T)*(dT/dP) = (P/T)*(1/[ρ c_p])
for an ideal gas, this becomes: ∇_ad = R / (μ c_p)
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.pmin::Float64
pressure [bar] below which convection is disabledmltype::Int
mixing length value (1: scale height, 2: asymptotic)
AGNI.energy.fill_Kzz!
— MethodFill Kzz values for the entire profile.
This function is called after the convection scheme has been run.
The Kzz value in the convective region (and below) are set equal to the maximum value in the convective region, as calculated by MLT. The value increases with power-law scaling with pressure in the stratosphere.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.
AGNI.energy.radtrans!
— MethodCalculate radiative fluxes using SOCRATES.
Uses the configuration inside the atmos struct. Can either do LW or SW calculation as required. Imports SOCRATES wrapper from the atmosphere module, rather than loading it twice.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.lw::Bool
longwave calculation? Else: shortwavecalc_cf::Bool=false
also calculate contribution function?
AGNI.energy.reset_fluxes!
— MethodReset energy fluxes to zero.
AGNI.energy.restore_composition!
— MethodReset mixing ratios to their original values
AGNI.energy.skin_flux
— MethodCalculate flux carried by conductive skin.
Numerical solver
Functions from solver.jl
.
AGNI.solver.gs_search
— MethodGolden section search algorithm
Minimises a function f
between the bounds a
and b
. The function f
must return a positive scalar.
Arguments:
f
Function to be minimiseda
Initial bracket, lower valueb
Initial bracket, upper valuiedxtol
Convergence: exit when bracket is smaller than this sizeatol
Convergence: absolute tolerance on minimumrtol
Convergence: relative tolerance on minimummax_steps
Maximum number of iterationswarnings
Print warning if search does not converge beforemax_steps
` are taken.
AGNI.solver.solve_energy!
— MethodObtain radiative-convective equilibrium using a matrix method.
Solves the non-linear system of equations defined by the flux field divergence, minimising flux loss across a cell by iterating the temperature profile.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.sol_type::Int
solution type, 1: tmpsurf | 2: skin | 3: fluxint | 4: tgt_olrchem_type::Int
chemistry type (see wiki)convect::Bool
include convectionsens_heat::Bool
include sensible heating at the surfaceconduct::Bool
include conductive heat transport within the atmospherelatent::Bool
include latent heat exchange (condensation/evaporation)rainout::Bool
allow rainout (phase change impacts mixing ratios, not just energy fluxes)dx_max::Float64
maximum step size [K]max_steps::Int
maximum number of solver stepsmax_runtime::Float64
maximum runtime in wall-clock secondsfdw::Float64
finite difference: relative width (dx/x) of the "difference"fdc::Bool
finite difference: ALWAYS use central difference?fdo::Int
finite difference: scheme order (2nd or 4th)method::Int
numerical method (1: Newton-Raphson, 2: Gauss-Newton, 3: Levenberg-Marquardt)ls_method::Int
linesearch algorithm (0: None, 1: golden, 2: backtracking)easy_start::Bool
improve convergence by introducing convection and phase change graduallyperturb_all::Bool
always recalculate entire Jacobian matrix? Otherwise updates columns only as requiredls_increase::Bool
factor by which the cost can increase from last step before triggering linesearchdetect_plateau::Bool
assist solver when it is stuck in a region of small dF/dTmodplot::Int
iteration frequency at which to make plotssave_frames::Bool
save plotting framesmodprint::Int
iteration frequency at which to print infoplot_jacobian::Bool
plot jacobian too?conv_atol::Float64
convergence: absolute tolerance on per-level flux deviation [W m-2]conv_rtol::Float64
convergence: relative tolerance on per-level flux deviation [dimensionless]
Returns: Nothing
Plotting functions and utilities
Functions from plotting.jl
.
AGNI.plotting.animate
— FunctionAnimate output frames from solver, using ffmpeg
AGNI.plotting.combined
— MethodCombined plot used for tracking behaviour of the solver
AGNI.plotting.jacobian
— MethodPlot jacobian matrix
AGNI.plotting.plot_albedo
— MethodPlot spectral albedo (ratio of SWUP to SWDN)
AGNI.plotting.plot_cloud
— MethodPlot the cloud mass mixing ratio and area fraction.
AGNI.plotting.plot_contfunc1
— MethodPlot contribution function at different bands.
AGNI.plotting.plot_contfunc2
— MethodPlot normalised contribution function (per band)
The data displayed in this plot are fine, but the x-axis ticks are labelled incorrectly by the plotting library. I don't know why this is.
AGNI.plotting.plot_emission
— MethodPlot emission spectrum at the TOA
AGNI.plotting.plot_fluxes
— MethodPlot the fluxes at each pressure level
AGNI.plotting.plot_pt
— MethodPlot the temperature-pressure profile.
AGNI.plotting.plot_radius
— MethodPlot the radius vs pressure profile.
AGNI.plotting.plot_vmr
— MethodPlot the VMRs of the atmosphere at each cell-centre location.
File I/O modules
Functions from save.jl
and load.jl
.
AGNI.save.write_fluxes
— MethodWrite cell-edge energy fluxes to a CSV file
Arguments
atmos::Atmos_t
Atmosphere objectfname::String
Filename to write to
AGNI.save.write_ncdf
— MethodWrite verbose atmosphere data to a NetCDF file
Arguments
atmos::Atmos_t
Atmosphere objectfname::String
Filename to write to
AGNI.save.write_profile
— MethodWrite {Pressure, Temperature, Radius} profile to a CSV file
Arguments
atmos::Atmos_t
Atmosphere objectfname::String
Filename to write to
AGNI.load.load_ncdf!
— MethodLoad atmosphere data from a NetCDF file.
This must be called after setup! and allocate! have been called on this atmos struct. Does not overwrite energy fluxes within the atmospherem, or other wavelength-dependent properties. Only composition, temperatures, layer properties, and boundary conditions are updated by this function.
Arguments:
atmos::Atmos_t
the atmosphere struct instance to be used.fname::String
path to the NetCDF file
Returns:
ok::Bool
loaded ok?