diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 13c44a57..c5f643f2 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-09-13T13:31:37","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-09-17T08:25:36","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/dev/assets/refs.bib b/dev/assets/refs.bib index 416481cb..6cc115c8 100644 --- a/dev/assets/refs.bib +++ b/dev/assets/refs.bib @@ -649,3 +649,25 @@ @techreport{manners_socrates_2017 institution={Met Office, Exeter, UK} } +@misc{nicholls_socrates_2024, + author = {Nicholls, Harrison}, + title = {SOCRATES and other tools}, + month = jun, + year = 2024, + publisher = {Zenodo}, + version = {v24.03.01}, + doi = {10.5281/zenodo.12190852}, + url = {https://doi.org/10.5281/zenodo.12190852} +} + +@article{amundsen_treatment_2017, + author = {{Amundsen, David S.} and {Tremblin, Pascal} and {Manners, James} and {Baraffe, Isabelle} and {Mayne, Nathan J.}}, + title = {Treatment of overlapping gaseous absorption with the correlated-k method in hot Jupiter and brown dwarf atmosphere models}, + DOI= "10.1051/0004-6361/201629322", + url= "https://doi.org/10.1051/0004-6361/201629322", + journal = {A&A}, + year = 2017, + volume = 598, + pages = "A97", +} + diff --git a/dev/examples/index.html b/dev/examples/index.html index 74f4aa36..4f09ecb8 100644 --- a/dev/examples/index.html +++ b/dev/examples/index.html @@ -3,4 +3,4 @@

We can also plot the outgoing emission spectrum and normalised longwave contribution function (CF). The spectrum clearly demonstrates complex water absorption features, and exceeds blackbody emission at shorter wavelengths due to Rayleigh scattering. The CF quantifies how much each pressure level contributes to the outgoing emission spectrum at a given wavelength – this is then plotted versus wavelength and pressure.


- + diff --git a/dev/index.html b/dev/index.html index decf8b9e..16faddcf 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · AGNI

AGNI

A numerical model for the atmospheres of hot terrestrial (exo)planets. AGNI's primary purpose is to simulate the evolving atmospheres of magma ocean planets, while ensuring that radiative-convective equilibrium is sufficiently maintained.

Follow Getting started for information on installing the code and obtaining results.

Contact: harrison[dot]nicholls[at]physics.ox.ac.uk

GitHub: https://github.com/nichollsh/AGNI

Pronounced: ag-nee. Named after the fire deity of Hinduism.

This software is available under the GPLv3. Copyright (C) 2024 Harrison Nicholls.

+Home · AGNI

AGNI

A numerical model for the atmospheres of hot rocky (exo)planets. AGNI's primary purpose is to simulate the evolving atmospheres of magma ocean planets, while ensuring that radiative-convective equilibrium is sufficiently maintained.

Follow Getting started for information on installing the code and obtaining results.

Contact: harrison[dot]nicholls[at]physics.ox.ac.uk

GitHub: https://github.com/nichollsh/AGNI

Pronounced: ag-nee. Named after the fire deity of Hinduism.

This software is available under the GPLv3. Copyright (C) 2024 Harrison Nicholls.

diff --git a/dev/manual/index.html b/dev/manual/index.html index 4019a04e..a5a6b0cc 100644 --- a/dev/manual/index.html +++ b/dev/manual/index.html @@ -1,2 +1,2 @@ -Development · AGNI

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

To be completed.

+Development · AGNI

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

To be completed.

diff --git a/dev/model/index.html b/dev/model/index.html index 6037944e..e8e410ad 100644 --- a/dev/model/index.html +++ b/dev/model/index.html @@ -1,5 +1,5 @@ -Model description · AGNI

Model description

AGNI models a planetary atmosphere by treating it as a single column (1D) and splitting it up into levels of finite thickness. These levels are defined in pressure-space, and are arranged logarithmically between the surface and the top of the atmosphere. The atmosphere is assumed to be plane-parallel. Quantities such as pressure and temperature are calculated at level-centres and level-edges, while energy fluxes are calculated only at the edges, and thermodynamic properties (e.g. heat capacity) are calculated only at their centres.

Radiative transfer

Radiative transfer (RT) refers to the transport of radiation energy through a medium subject to the characteristics of the medium. Radiation passing through an atmosphere is absorbed, emitted, scattered, and reflected. In the context of planetary atmospheres, we also have to handle their surfaces, cloud formation, and radiation from the host star.

AGNI simulates RT using SOCRATES, a numerical code written by the UK Met Office which solves the RT equation using a two-stream solution. SOCRATES is accessed using a Julia interface originally written by Stuart Daines. The atmosphere is assumed to be hydrostatically supported and to behave as an ideal gas. Opacity is handle using the correlated-k approximation, with either random overlap or equivalent extinction used to account for overlapping absorption in mixtures of gases.

The model uses k-terms fitted to spectral absorption cross-section data from DACE. The MT_CKD model is used to estimate water continuum absorption cross-sections. Other continuua are derived from the HITRAN tables. Rayleigh scattering and water cloud radiative properties are also included. You can find tools for fitting k-terms and processing line absorption data in my redistribution of SOCRATES on GitHub. The flowchart below outlines how these absorption data are converted into a 'spectral file'.

Surface reflectivity can be modelled as a greybody with an albedo from 0 to 1. Alternatively, it can be modelled from empirical single-scattering data which varies with zenith angle and wavelength.

Convection

Convection is a turbulent process which occurs across more than one spatial dimension, so it must be parameterised within 1D models like AGNI. In fact, it is typically parameterised inside 3D global circulation models as resolving convection is numerically expensive. AGNI uses mixing length theory (MLT) to parameterise convection. This is in contrast to convective adjustment, which forcibly adjusts a convectively unstable region of the atmosphere to the corresponding adiabat while ensuring that enthalpy is conserved.

MLT directly calculates the energy flux associated with convective heat transport, and thus is the preferred parameterisation within the model. It assumes that parcels of gas are diffused over a characteristic mixing length, transporting energy in the process. This requires choosing a scale for this mixing length, but in practice this has very little impact on the results from the model.

Heat capacities are temperature-dependent, using values derived from the JANAF database.

Phase change

Gases release energy ("latent heat" or "enthalpy") into their surroundings when condensing into a liquid or solid. This is included in the model through a diffusive condensation scheme, which assumes a fixed condensation timescale. This takes place as follows... firstly, the mixing ratios of the gases are updated according to the temperature profile, where rainout occurs until all condensibles are saturated or sub-saturated. The mixing ratios of dry species are increased in order to satisfy the total pressure at condensing levels. The heat released associated with the change in partial pressure of condensible gases is used to calculate a latent heating rate. This is then integrated (from the TOA downwards) to provide a latent heat transport flux at cell-edges.

Latent heats are temperature-dependent, using values derived from Coker (2007) and Wagner & Pruß (2001).

Solar flux

A key input to the radiation model is the shortwave downward-directed flux from the star at the top of the atmosphere. This is quantified by the bolometric instellation flux, a scale factor, an artificial additional albedo factor, and a zenith angle. All of these may be provided to the model through the configuration file. The model also requires a stellar spectrum scaled to the top of the atmosphere.

Obtaining a solution

Summary

AGNI is designed for modelling planetary atmospheres with high surface pressures and temperatures. This means that the radiative timescale differs by several orders of magnitude across the column, which makes obtaining a solution difficult. To obtain a temperature structure solution that conserves energy more precisely than a time-stepping method, AGNI solves for the temperature structure of the atmosphere as an optimisation problem. This finds the state which conserves energy across all levels and satisfies the required configuration from the user.

Solution types

It is necessary to tell AGNI what kind of atmospheric solution to solve for. There are currently a few options available set by the solution_type variable in the configuration file.

  • (1) Aim to conserve energy fluxes throughout the column. The surface temperature is fixed.
  • (2) Aim to conserve energy fluxes throughout the column. The surface temperature is set by energy transport through a solid conductive boundary layer of thickness $d$ such that $T_s = T_m - \frac{Fd}{k}$, where $T_m$ is the mantle temperature and $k$ is the thermal conductivity.
  • (3) Solve for a state such that the flux carried at each level is equal to $F_{\text{eff}} = \sigma T_{\text{eff}}^4$, representing the rate at which a planet is losing energy into space.

Construction

The atmosphere is constructed of $N$ levels (cell-centres), corresponding to $N+1$ interfaces (cell-edges). The RT model takes cell-centre temperatures $T_i$, pressures $p_i$, geometric heights, and mixing ratios as input variables at each level $i$. As well as the surface temperature and incoming stellar flux. In return, it provides cell-edges spectral fluxes $F_i$ at all $N+1$ interfaces for LW & SW components and upward & downward streams. Convective fluxes can be estimated using the MLT scheme, condensation fluxes from the condensation scheme, and sensible heat from a simple TKE approximation.

The total upward-directed energy flux $F_{i}$ describes the total upward-directed energy transport (units of $\text{W m}^{-2}$) from cell $i$ into cell $i-1$ above (or into space for $i=1$). For energy to be conserved throughout the column, it must be true that $F_i = F_t \text{ } \forall \text{ } i$ where $F_t$ is the total amount of energy being transported out of the planet. In global radiative equilibrium, $F_t = 0$.

Definition of residuals

We can use this construction to solve for the temperature profile of the atmosphere as an $N+1$-dimensional optimisation problem. This directly solves for $T(p)$ at radiative-convective equilibrium without having to invoke heating rate calculations, thereby avoiding slow convergence in regions of the atmosphere with long radiative timescales. The residuals vector (length $N+1$)

\[ +Model description · AGNI

Model description

AGNI models a planetary atmosphere by treating it as a single column (1D) and splitting it up into levels of finite thickness. These levels are defined in pressure-space, and are arranged logarithmically between the surface and the top of the atmosphere. The atmosphere is assumed to be plane-parallel. Quantities such as pressure and temperature are calculated at level-centres and level-edges, while energy fluxes are calculated only at the edges, and thermodynamic properties (e.g. heat capacity) are calculated only at their centres.

Radiative transfer

Radiative transfer (RT) refers to the transport of radiation energy through a medium subject to the characteristics of the medium. Radiation passing through an atmosphere is absorbed, emitted, scattered, and reflected. In the context of planetary atmospheres, we also have to handle their surfaces, cloud formation, and radiation from the host star.

AGNI simulates RT using SOCRATES, a numerical code written by the UK Met Office which solves the RT equation using a two-stream solution. SOCRATES is accessed using a Julia interface originally written by Stuart Daines. The atmosphere is assumed to be hydrostatically supported and to behave as an ideal gas. Opacity is handle using the correlated-k approximation, with either random overlap or equivalent extinction used to account for overlapping absorption in mixtures of gases.

The model uses k-terms fitted to spectral absorption cross-section data from DACE. The MT_CKD model is used to estimate water continuum absorption cross-sections. Other continuua are derived from the HITRAN tables. Rayleigh scattering and water cloud radiative properties are also included. You can find tools for fitting k-terms and processing line absorption data in my redistribution of SOCRATES on GitHub. The flowchart below outlines how these absorption data are converted into a 'spectral file'.

Surface reflectivity can be modelled as a greybody with an albedo from 0 to 1. Alternatively, it can be modelled from empirical single-scattering data which varies with zenith angle and wavelength.

Convection

Convection is a turbulent process which occurs across more than one spatial dimension, so it must be parameterised within 1D models like AGNI. In fact, it is typically parameterised inside 3D global circulation models as resolving convection is numerically expensive. AGNI uses mixing length theory (MLT) to parameterise convection. This is in contrast to convective adjustment, which forcibly adjusts a convectively unstable region of the atmosphere to the corresponding adiabat while ensuring that enthalpy is conserved.

MLT directly calculates the energy flux associated with convective heat transport, and thus is the preferred parameterisation within the model. It assumes that parcels of gas are diffused over a characteristic mixing length, transporting energy in the process. This requires choosing a scale for this mixing length, but in practice this has very little impact on the results from the model.

Phase change

Gases release energy ("latent heat" or "enthalpy") into their surroundings when condensing into a liquid or solid. This is included in the model through a diffusive condensation scheme, which assumes a fixed condensation timescale. This takes place as follows... firstly, the mixing ratios of the gases are updated according to the temperature profile, where rainout occurs until all condensibles are saturated or sub-saturated. The mixing ratios of dry species are increased in order to satisfy the total pressure at condensing levels. The heat released associated with the change in partial pressure of condensible gases is used to calculate a latent heating rate. This is then integrated (from the TOA downwards) to provide a latent heat transport flux at cell-edges. The integrate condensible heat flux is balanced by evaporation at deeper layers.

Latent heats are temperature-dependent, using values derived from Coker (2007) and Wagner & Pruß (2001). Heat capacities are also temperature-dependent, using values derived from the JANAF database. See the ThermoTools repo for scripts.

Solar flux

A key input to the radiation model is the shortwave downward-directed flux from the star at the top of the atmosphere. This is quantified by the bolometric instellation flux, a scale factor, an artificial additional albedo factor, and a zenith angle. All of these may be provided to the model through the configuration file. The model also requires a stellar spectrum scaled to the top of the atmosphere.

Obtaining a solution

Summary

AGNI is designed for modelling planetary atmospheres with high surface pressures and temperatures. This means that the radiative timescale differs by several orders of magnitude across the column, which makes obtaining a solution difficult. To obtain a temperature structure solution that conserves energy more precisely than a time-stepping method, AGNI solves for the temperature structure of the atmosphere as an optimisation problem. This finds the state which conserves energy across all levels and satisfies the required configuration from the user.

Solution types

It is necessary to tell AGNI what kind of atmospheric solution to solve for. There are currently a few options available set by the solution_type variable in the configuration file.

  • (1) Aim to conserve energy fluxes throughout the column. The surface temperature is fixed.
  • (2) Aim to conserve energy fluxes throughout the column. The surface temperature is set by energy transport through a solid conductive boundary layer of thickness $d$ such that $T_s = T_m - \frac{Fd}{k}$, where $T_m$ is the mantle temperature and $k$ is the thermal conductivity.
  • (3) Solve for a state such that the flux carried at each level is equal to $F_{\text{eff}} = \sigma T_{\text{eff}}^4$, representing the rate at which a planet is losing energy into space.

Construction

The atmosphere is constructed of $N$ levels (cell-centres), corresponding to $N+1$ interfaces (cell-edges). The RT model takes cell-centre temperatures $T_i$, pressures $p_i$, geometric heights, and mixing ratios as input variables at each level $i$. As well as the surface temperature and incoming stellar flux. In return, it provides cell-edges spectral fluxes $F_i$ at all $N+1$ interfaces for LW & SW components and upward & downward streams. Convective fluxes can be estimated using the MLT scheme, condensation fluxes from the condensation scheme, and sensible heat from a simple TKE approximation.

The total upward-directed energy flux $F_{i}$ describes the total upward-directed energy transport (units of $\text{W m}^{-2}$) from cell $i$ into cell $i-1$ above (or into space for $i=1$). For energy to be conserved throughout the column, it must be true that $F_i = F_t \text{ } \forall \text{ } i$ where $F_t$ is the total amount of energy being transported out of the planet. In global radiative equilibrium, $F_t = 0$.

Definition of residuals

We can use this construction to solve for the temperature profile of the atmosphere as an $N+1$-dimensional optimisation problem. This directly solves for $T(p)$ at radiative-convective equilibrium without having to invoke heating rate calculations, thereby avoiding slow convergence in regions of the atmosphere with long radiative timescales. The residuals vector (length $N+1$)

\[ \bm{r} = \begin{pmatrix} @@ -26,4 +26,4 @@ ... \\ T_N \\ T_s -\end{pmatrix}\]

where $T_s$ is the surface temperature. Cell-edge temperatures in the bulk atmosphere are interpolated using the PCHIP algorithm, which avoids Runge's phenomenon and overshooting. The bottom- and top-most cell edge temperatures are extrapolated by estimation of $dT/d \log p$. Cell properties (heat capacity, gravity, density, average molecular weight, etc.) are consistently updated at each evaluation of $\bm{r}$. Condensation/rainout are also handled at each evaluation of $\bm{r}$ in order to avoid supersaturation.

The model converges when the cost function $c(\bm{x}) = \sqrt{\sum_i |r_i|}$ satisfies the condition

\[c(\bm{x}) < c_a + c_r \cdot \underset{i}{\max} \text{ } |F_i|\]

which represents a state where the fluxes are sufficiently conserved.

Iterative steps

The model solves for $\bm{x}$ iteratively, starting from some initial guess. The initial guess should be any reasonable temperature profile which is not significantly cooler than the expected solution. The flowchart below broadly outlines the solution process.

The Jacobian matrix $\bm{J}$ represents the directional gradient of the residuals with respect to the solution vector. It is a square matrix with elements set according to

\[J_{uv} = \frac{\partial r_u}{\partial x_v}\]

AGNI estimates $\bm{J}$ using finite-differences, requiring $N+1$ evalulations of $\bm{r}$ in order to fill the matrix. This corresponds to $2(N+1)+1$ objective function calculations under a 2nd order central-difference scheme. Each level $v$ with temperature $x_v$ is perturbed by an amount $\pm \varepsilon x_v$ in order to fill a single column of $\bm{J}$. As such, it can be expensive to construct a full Jacobian, especially when it is discarded at the end of each iteration. To reduce the total number of calculations AGNI retains some of the columns in $\bm{J}$ between model iterations. This assumes that the second derivative of the residuals is small. A column $v$ is retained only when

\[\max |r_i| \lt 0.7 \text{ for } i \in \{v-1, v, v+1\}\]

and when $c(\bm{x})/10$ does not satisfy the convergence criteria.

With a Jacobian constructed, we can calculate an update $\bm{d}$ to the solution vector $\bm{x} \rightarrow \bm{x} + \bm{d}$. This is primarily done via the Newton-Raphson method

\[\bm{d} = -\bm{J}^{-1} \bm{r}\]

but can alternatively be performed via the Gauss-Newton and Levenberg–Marquardt methods.

It is possible for the model to become stuck in a local minimum, leading to very small values of $|\bm{d}|$. This is identified when $c(\bm{x})$ has seen little change over the last few iterations. When this occurs, the model is 'nudged' by scaling the update via

\[\bm{d} \rightarrow 3 \bm{d}\]

In many cases $\bm{d}$ is too large, leading to instabilities. This is due to the non-convexity of the solution space, and the somewhat discontinuous nature of the physics involved (particularly in its temperature derivatives). When $|\bm{d}|>d_{\text{max}}$, the update is crudely scaled via

\[\bm{d} \rightarrow d_{\text{max}} \hat{\bm{d}}\]

The update may also be scaled by a linesearch

\[\bm{d} \rightarrow \alpha \bm{d}\]

on $\alpha$. This is applied if the full step $\bm{d}$ would increase the cost by an unacceptable amount. If the model is close to convergence then a golden-section search method is used to determine the optimal $\alpha$, otherwise a backtracking method is used. This means that the model is (mostly) able to avoid oscillating around a solution. All three of these scalings to $\bm{d}$ preserve its direction.

Other features

AGNI can calculate emission spectra, provided with T(p) and the volume mixing ratios of the gases. This is performed using the same RT as the RCE calculations, so is limited in resolution by the choice of correlated-k bands. Similarly, the longwave contribution function can also be calculated.

Julia and Fortran

AGNI is primarily written in Julia, while SOCRATES itself is written in Fortran. Julia was chosen because it allows the SOCRATES binaries to be included in the precompiled code, which significantly improves performance.

+\end{pmatrix}\]

where $T_s$ is the surface temperature. Cell-edge temperatures in the bulk atmosphere are interpolated using the PCHIP algorithm, which avoids Runge's phenomenon and overshooting. The bottom- and top-most cell edge temperatures are extrapolated by estimation of $dT/d \log p$. Cell properties (heat capacity, gravity, density, average molecular weight, etc.) are consistently updated at each evaluation of $\bm{r}$. Condensation/rainout are also handled at each evaluation of $\bm{r}$ in order to avoid supersaturation.

The model converges when the cost function $c(\bm{x}) = \sqrt{\sum_i |r_i|}$ satisfies the condition

\[c(\bm{x}) < c_a + c_r \cdot \underset{i}{\max} \text{ } |F_i|\]

which represents a state where the fluxes are sufficiently conserved.

Iterative steps

The model solves for $\bm{x}$ iteratively, starting from some initial guess. The initial guess should be any reasonable temperature profile which is not significantly cooler than the expected solution. The flowchart below broadly outlines the solution process.

The Jacobian matrix $\bm{J}$ represents the directional gradient of the residuals with respect to the solution vector. It is a square matrix with elements set according to

\[J_{uv} = \frac{\partial r_u}{\partial x_v}\]

AGNI estimates $\bm{J}$ using finite-differences, requiring $N+1$ evalulations of $\bm{r}$ in order to fill the matrix. This corresponds to $2(N+1)+1$ objective function calculations under a 2nd order central-difference scheme. Each level $v$ with temperature $x_v$ is perturbed by an amount $\pm \varepsilon x_v$ in order to fill a single column of $\bm{J}$. As such, it can be expensive to construct a full Jacobian, especially when it is discarded at the end of each iteration. To reduce the total number of calculations AGNI retains some of the columns in $\bm{J}$ between model iterations. This assumes that the second derivative of the residuals is small. A column $v$ is retained only when

\[\max |r_i| \lt 0.7 \text{ for } i \in \{v-1, v, v+1\}\]

and when $c(\bm{x})/10$ does not satisfy the convergence criteria.

With a Jacobian constructed, we can calculate an update $\bm{d}$ to the solution vector $\bm{x} \rightarrow \bm{x} + \bm{d}$. This is primarily done via the Newton-Raphson method

\[\bm{d} = -\bm{J}^{-1} \bm{r}\]

but can alternatively be performed via the Gauss-Newton and Levenberg–Marquardt methods.

It is possible for the model to become stuck in a local minimum, leading to very small values of $|\bm{d}|$. This is identified when $c(\bm{x})$ has seen little change over the last few iterations. When this occurs, the model is 'nudged' by scaling the update via

\[\bm{d} \rightarrow 3 \bm{d}\]

In many cases $\bm{d}$ is too large, leading to instabilities. This is due to the non-convexity of the solution space, and the somewhat discontinuous nature of the physics involved (particularly in its temperature derivatives). When $|\bm{d}|>d_{\text{max}}$, the update is crudely scaled via

\[\bm{d} \rightarrow d_{\text{max}} \hat{\bm{d}}\]

The update may also be scaled by a linesearch

\[\bm{d} \rightarrow \alpha \bm{d}\]

on $\alpha$. This is applied if the full step $\bm{d}$ would increase the cost by an unacceptable amount. If the model is close to convergence then a golden-section search method is used to determine the optimal $\alpha$, otherwise a backtracking method is used. This means that the model is (mostly) able to avoid oscillating around a solution. All three of these scalings to $\bm{d}$ preserve its direction.

Other features

AGNI can calculate emission spectra, provided with T(p) and the volume mixing ratios of the gases. This is performed using the same RT as the RCE calculations, so is limited in resolution by the choice of correlated-k bands. Similarly, the longwave contribution function can also be calculated.

Julia and Fortran

AGNI is primarily written in Julia, while SOCRATES itself is written in Fortran. Julia was chosen because it allows the SOCRATES binaries to be included in the precompiled code, which significantly improves performance.

diff --git a/dev/objects.inv b/dev/objects.inv index 7ecd5825..8a5b3fc7 100644 Binary files a/dev/objects.inv and b/dev/objects.inv differ diff --git a/dev/search_index.js b/dev/search_index.js index a188c7bb..cb6c8636 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"model/#Model-description","page":"Model description","title":"Model description","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI models a planetary atmosphere by treating it as a single column (1D) and splitting it up into levels of finite thickness. These levels are defined in pressure-space, and are arranged logarithmically between the surface and the top of the atmosphere. The atmosphere is assumed to be plane-parallel. Quantities such as pressure and temperature are calculated at level-centres and level-edges, while energy fluxes are calculated only at the edges, and thermodynamic properties (e.g. heat capacity) are calculated only at their centres.","category":"page"},{"location":"model/#Radiative-transfer","page":"Model description","title":"Radiative transfer","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"Radiative transfer (RT) refers to the transport of radiation energy through a medium subject to the characteristics of the medium. Radiation passing through an atmosphere is absorbed, emitted, scattered, and reflected. In the context of planetary atmospheres, we also have to handle their surfaces, cloud formation, and radiation from the host star.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI simulates RT using SOCRATES, a numerical code written by the UK Met Office which solves the RT equation using a two-stream solution. SOCRATES is accessed using a Julia interface originally written by Stuart Daines. The atmosphere is assumed to be hydrostatically supported and to behave as an ideal gas. Opacity is handle using the correlated-k approximation, with either random overlap or equivalent extinction used to account for overlapping absorption in mixtures of gases.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The model uses k-terms fitted to spectral absorption cross-section data from DACE. The MT_CKD model is used to estimate water continuum absorption cross-sections. Other continuua are derived from the HITRAN tables. Rayleigh scattering and water cloud radiative properties are also included. You can find tools for fitting k-terms and processing line absorption data in my redistribution of SOCRATES on GitHub. The flowchart below outlines how these absorption data are converted into a 'spectral file'.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":" ","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"Surface reflectivity can be modelled as a greybody with an albedo from 0 to 1. Alternatively, it can be modelled from empirical single-scattering data which varies with zenith angle and wavelength.","category":"page"},{"location":"model/#Convection","page":"Model description","title":"Convection","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"Convection is a turbulent process which occurs across more than one spatial dimension, so it must be parameterised within 1D models like AGNI. In fact, it is typically parameterised inside 3D global circulation models as resolving convection is numerically expensive. AGNI uses mixing length theory (MLT) to parameterise convection. This is in contrast to convective adjustment, which forcibly adjusts a convectively unstable region of the atmosphere to the corresponding adiabat while ensuring that enthalpy is conserved.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"MLT directly calculates the energy flux associated with convective heat transport, and thus is the preferred parameterisation within the model. It assumes that parcels of gas are diffused over a characteristic mixing length, transporting energy in the process. This requires choosing a scale for this mixing length, but in practice this has very little impact on the results from the model.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"Heat capacities are temperature-dependent, using values derived from the JANAF database.","category":"page"},{"location":"model/#Phase-change","page":"Model description","title":"Phase change","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"Gases release energy (\"latent heat\" or \"enthalpy\") into their surroundings when condensing into a liquid or solid. This is included in the model through a diffusive condensation scheme, which assumes a fixed condensation timescale. This takes place as follows... firstly, the mixing ratios of the gases are updated according to the temperature profile, where rainout occurs until all condensibles are saturated or sub-saturated. The mixing ratios of dry species are increased in order to satisfy the total pressure at condensing levels. The heat released associated with the change in partial pressure of condensible gases is used to calculate a latent heating rate. This is then integrated (from the TOA downwards) to provide a latent heat transport flux at cell-edges.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"Latent heats are temperature-dependent, using values derived from Coker (2007) and Wagner & Pruß (2001).","category":"page"},{"location":"model/#Solar-flux","page":"Model description","title":"Solar flux","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"A key input to the radiation model is the shortwave downward-directed flux from the star at the top of the atmosphere. This is quantified by the bolometric instellation flux, a scale factor, an artificial additional albedo factor, and a zenith angle. All of these may be provided to the model through the configuration file. The model also requires a stellar spectrum scaled to the top of the atmosphere.","category":"page"},{"location":"model/#Obtaining-a-solution","page":"Model description","title":"Obtaining a solution","text":"","category":"section"},{"location":"model/#Summary","page":"Model description","title":"Summary","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI is designed for modelling planetary atmospheres with high surface pressures and temperatures. This means that the radiative timescale differs by several orders of magnitude across the column, which makes obtaining a solution difficult. To obtain a temperature structure solution that conserves energy more precisely than a time-stepping method, AGNI solves for the temperature structure of the atmosphere as an optimisation problem. This finds the state which conserves energy across all levels and satisfies the required configuration from the user.","category":"page"},{"location":"model/#Solution-types","page":"Model description","title":"Solution types","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"It is necessary to tell AGNI what kind of atmospheric solution to solve for. There are currently a few options available set by the solution_type variable in the configuration file.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"(1) Aim to conserve energy fluxes throughout the column. The surface temperature is fixed.\n(2) Aim to conserve energy fluxes throughout the column. The surface temperature is set by energy transport through a solid conductive boundary layer of thickness d such that T_s = T_m - fracFdk, where T_m is the mantle temperature and k is the thermal conductivity.\n(3) Solve for a state such that the flux carried at each level is equal to F_texteff = sigma T_texteff^4, representing the rate at which a planet is losing energy into space.","category":"page"},{"location":"model/#Construction","page":"Model description","title":"Construction","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"The atmosphere is constructed of N levels (cell-centres), corresponding to N+1 interfaces (cell-edges). The RT model takes cell-centre temperatures T_i, pressures p_i, geometric heights, and mixing ratios as input variables at each level i. As well as the surface temperature and incoming stellar flux. In return, it provides cell-edges spectral fluxes F_i at all N+1 interfaces for LW & SW components and upward & downward streams. Convective fluxes can be estimated using the MLT scheme, condensation fluxes from the condensation scheme, and sensible heat from a simple TKE approximation.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The total upward-directed energy flux F_i describes the total upward-directed energy transport (units of textW m^-2) from cell i into cell i-1 above (or into space for i=1). For energy to be conserved throughout the column, it must be true that F_i = F_t text forall text i where F_t is the total amount of energy being transported out of the planet. In global radiative equilibrium, F_t = 0.","category":"page"},{"location":"model/#Definition-of-residuals","page":"Model description","title":"Definition of residuals","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"We can use this construction to solve for the temperature profile of the atmosphere as an N+1-dimensional optimisation problem. This directly solves for T(p) at radiative-convective equilibrium without having to invoke heating rate calculations, thereby avoiding slow convergence in regions of the atmosphere with long radiative timescales. The residuals vector (length N+1)","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"\nbmr =\n\nbeginpmatrix\nr_i \nr_i+1 \n \nr_N \nr_N+1\nendpmatrix\n\n=\n\nbeginpmatrix\nF_i+1 - F_i \nF_i+2 - F_i+1 \n \nF_N+1 - F_N \nF_N+1 - F_t\nendpmatrix","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"is what we aim to minimise as our 'objective function', subject to the solution vector of cell-centre temperatures","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmx =\n\nbeginpmatrix\nT_i \nT_i+1 \n \nT_N \nT_s\nendpmatrix","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"where T_s is the surface temperature. Cell-edge temperatures in the bulk atmosphere are interpolated using the PCHIP algorithm, which avoids Runge's phenomenon and overshooting. The bottom- and top-most cell edge temperatures are extrapolated by estimation of dTd log p. Cell properties (heat capacity, gravity, density, average molecular weight, etc.) are consistently updated at each evaluation of bmr. Condensation/rainout are also handled at each evaluation of bmr in order to avoid supersaturation.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The model converges when the cost function c(bmx) = sqrtsum_i r_i satisfies the condition","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"c(bmx) c_a + c_r cdot undersetimax text F_i","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"which represents a state where the fluxes are sufficiently conserved.","category":"page"},{"location":"model/#Iterative-steps","page":"Model description","title":"Iterative steps","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"The model solves for bmx iteratively, starting from some initial guess. The initial guess should be any reasonable temperature profile which is not significantly cooler than the expected solution. The flowchart below broadly outlines the solution process.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":" ","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The Jacobian matrix bmJ represents the directional gradient of the residuals with respect to the solution vector. It is a square matrix with elements set according to","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"J_uv = fracpartial r_upartial x_v","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI estimates bmJ using finite-differences, requiring N+1 evalulations of bmr in order to fill the matrix. This corresponds to 2(N+1)+1 objective function calculations under a 2nd order central-difference scheme. Each level v with temperature x_v is perturbed by an amount pm varepsilon x_v in order to fill a single column of bmJ. As such, it can be expensive to construct a full Jacobian, especially when it is discarded at the end of each iteration. To reduce the total number of calculations AGNI retains some of the columns in bmJ between model iterations. This assumes that the second derivative of the residuals is small. A column v is retained only when","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"max r_i lt 07 text for i in v-1 v v+1","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"and when c(bmx)10 does not satisfy the convergence criteria.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"With a Jacobian constructed, we can calculate an update bmd to the solution vector bmx rightarrow bmx + bmd. This is primarily done via the Newton-Raphson method","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmd = -bmJ^-1 bmr","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"but can alternatively be performed via the Gauss-Newton and Levenberg–Marquardt methods.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"It is possible for the model to become stuck in a local minimum, leading to very small values of bmd. This is identified when c(bmx) has seen little change over the last few iterations. When this occurs, the model is 'nudged' by scaling the update via","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmd rightarrow 3 bmd","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"In many cases bmd is too large, leading to instabilities. This is due to the non-convexity of the solution space, and the somewhat discontinuous nature of the physics involved (particularly in its temperature derivatives). When bmdd_textmax, the update is crudely scaled via","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmd rightarrow d_textmax hatbmd","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The update may also be scaled by a linesearch","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmd rightarrow alpha bmd","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"on alpha. This is applied if the full step bmd would increase the cost by an unacceptable amount. If the model is close to convergence then a golden-section search method is used to determine the optimal alpha, otherwise a backtracking method is used. This means that the model is (mostly) able to avoid oscillating around a solution. All three of these scalings to bmd preserve its direction.","category":"page"},{"location":"model/#Other-features","page":"Model description","title":"Other features","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI can calculate emission spectra, provided with T(p) and the volume mixing ratios of the gases. This is performed using the same RT as the RCE calculations, so is limited in resolution by the choice of correlated-k bands. Similarly, the longwave contribution function can also be calculated.","category":"page"},{"location":"model/#Julia-and-Fortran","page":"Model description","title":"Julia and Fortran","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI is primarily written in Julia, while SOCRATES itself is written in Fortran. Julia was chosen because it allows the SOCRATES binaries to be included in the precompiled code, which significantly improves performance.","category":"page"},{"location":"usage/#Running-the-model","page":"Running the model","title":"Running the model","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"First, follow the Getting started instructions. Only read-on once you have confirmed that the code is working.","category":"page"},{"location":"usage/#Input-data-files","page":"Running the model","title":"Input data files","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"The minimal input data required to run the model will have been downloaded automatically. If you require more data, such as additional stellar spectra or opacities, then these can also be easily obtained using the get_data script in the AGNI root directory. To see how to use this script, run it without arguments like so:","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"./get_data.sh","category":"page"},{"location":"usage/#Tutorials","page":"Running the model","title":"Tutorials","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"There are Jupyter notebooks containing tutorials in the tutorials/ directory of the repository.","category":"page"},{"location":"usage/#General-execution","page":"Running the model","title":"General execution","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"The environment variable RAD_DIR must point to the SOCRATES installation directory. This is required for AGNI to find the SOCRATES libraries, and can be done by running source path/to/socrates/set_rad_env in your terminal.","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"Then to use the model, simply run ./agni.jl [cfg] where [cfg] is the path to the required configuration file. If [cfg] is not passed, then the default configuration will be used.","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"To calculate equilibrium chemistry self-consistently with the climate, FastChem is coupled to AGNI. For AGNI to find FastChem, the environment variable FC_DIR must point to the FastChem installation directory.","category":"page"},{"location":"usage/#Configuration","page":"Running the model","title":"Configuration","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"AGNI configuration files are formatted using TOML. There are examples in res/config/. The default configuration file contains comments explaining the purpose of each parameter, although some are explained in greater detail below. Take care to format the variables in the TOML file correctly. There are no 'default values'. Not all parameters are required in all cases, but the model will return an error naming any parameters which are both necessary and absent.","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"Broadly, the configuration files are broken up into four sections:","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"[planet] - general characteristics of the planet\n[files] - input/output files and other paths\n[composition] - atmospheric composition and chemistry\n[execution] - what the model should do\n[plots] - which plots should be produced","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"Some parameters:","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"files.input_sf is the file path to the \"spectral file\" containing opacity data. Several spectral files are packged with AGNI, but you can find more online via the Open Science Framework.\nexecution.solution_type tells the model which state to solve for. The allowed values (integers) are...\n1 : zero flux divergence at fixed tmp_surf\n2 : zero flux divergence, with tmp_surf set such that the conductive skin (CBL) conserves energy flux\n3 : the net upward flux at each layer is equal to flux_int = sigma * tmp_int^4\nexecution.solvers tells the model which solvers to use. This is a list of strings, so multiple solvers can be applied sequentially. An empty string is always appended to the end of this list. Allowed solvers are...\n[empty string] : no solving takes place, so the model just calculates fluxes using the initial state\nnewton : the Newton-Raphson algorithm is used\ngauss : the Gauss-Newton algorithm is used\nlevenberg : the Levenberg–Marquardt algorithm is used\nexecution.initial_state describes the initial temperature profile applied to the atmosphere. This is a list of strings which are applied in the given order, which allows the user to describe a specific state as required. The descriptors are listed below, some of which take a single argument that needs to immediately follow the descriptor in the list order.\ndry : integrate the dry adiabatic lapse rate from the surface upwards\nstr, arg : apply an isothermal stratosphere at arg kelvin\niso, arg : set the whole atmosphere to be isothermal at arg kelvin\ncsv, arg : set the temperature profile using the CSV file at the file path arg\nsat, arg : apply Clausius-Clapeyron saturation curve for the gas arg\nncdf, arg : load profile from the NetCDF file located at arg\nloglin, arg : log-linear profile between tmp_surf at the bottom and arg at the top\nFor example, setting initial_state = [\"dry\", \"sat\", \"H2O\", \"str\", \"180\"] will set T(p) to follow the dry adiabat from the surface, the water condensation curve above that, and then to be isothermal at 180 K until the top of the model.\ncomposition.chem_type describes the type of chemistry to implement within the model. This is handled externally by FastChem, so you must set the environment variable FC_DIR to point to the FastChem directory. The allowed values (integers) are...\n0 : Disabled\n1 : Equilibrium, gas phase only\n2 : Equilibrium, with condensation (condensates retained)\n3 : Equilibrium, with condensation (condensates rained out)","category":"page"},{"location":"usage/#Outputs","page":"Running the model","title":"Outputs","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"Results are optionally plotted and animated, and data will be saved as NetCDF or CSV files.","category":"page"},{"location":"usage/#Python","page":"Running the model","title":"Python","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"It is possible to interact with the model using Python. This is best done with the juliacall package from PythonCall.jl, and is implemented this way in the PROTEUS framework.","category":"page"},{"location":"troubleshooting/#Troubleshooting","page":"Troubleshooting","title":"Troubleshooting","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"This page may be useful if you are having problems. However, I would suggest that you also double check the Getting started instructions.","category":"page"},{"location":"troubleshooting/#Julia-errors-on-start,-potentially-referencing-the-CURL-library","page":"Troubleshooting","title":"Julia errors on start, potentially referencing the CURL library","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"It is important that the shell environment variable LD_LIBRARY_PATH is not set when running AGNI. This will cause Julia to use the wrong libraries, which will causes problems. You can unset this variable or reset using either of the following commands ","category":"page"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"unset LD_LIBRARY_PATH\nexport LD_LIBRARY_PATH=\"\"","category":"page"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"If this does not help, it's possible that you are using a Julia distribution provided by your system package manager. It's important that you only use Julia distributed from the official website.","category":"page"},{"location":"troubleshooting/#Cannot-find-SOCRATES","page":"Troubleshooting","title":"Cannot find SOCRATES","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"Check the installation instructions. Have you set RAD_DIR? Try running l_run_cdf in the terminal; if this fails, then SOCRATES has not compiled or you haven't added it to your PATH.","category":"page"},{"location":"troubleshooting/#Spectral-file-does-not-exist","page":"Troubleshooting","title":"Spectral file does not exist","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"Check the path in the configuration file. Download additional spectral files using the get_data script in the AGNI root directory. For example, for additional pure-steam spectral files you would run","category":"page"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"./get_data.sh steam","category":"page"},{"location":"troubleshooting/#Finally...","page":"Troubleshooting","title":"Finally...","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"If you are still stuck, or feel that there is a problem with the code, then you can contact the authors using the information on the main page.","category":"page"},{"location":"manual/#Development-manual","page":"Development","title":"Development manual","text":"","category":"section"},{"location":"manual/#Contributing","page":"Development","title":"Contributing","text":"","category":"section"},{"location":"manual/","page":"Development","title":"Development","text":"If you are interested in contributing to the model, please contact the developers using the information on the main page.","category":"page"},{"location":"manual/#Coding-style","page":"Development","title":"Coding style","text":"","category":"section"},{"location":"manual/","page":"Development","title":"Development","text":"Indentation uses 4 spaces, no tabs.\nFunction names should be lowercase, with words separated by underscores .\nLines should aim to have a length of no more than 92 characters.\nAll functions should have docstrings, ideally with Arguments and Returns listed.\nMore comments are always better, even if they seem redundant.\nUse type hinting where possible.\nPrint statements should be made through the logger where possible.\nThe core package code should not contain global variables, except in the phys module.","category":"page"},{"location":"manual/#Code-reference","page":"Development","title":"Code reference","text":"","category":"section"},{"location":"manual/","page":"Development","title":"Development","text":"To be completed.","category":"page"},{"location":"examples/#Example-outputs","page":"Example outputs","title":"Example outputs","text":"","category":"section"},{"location":"examples/#Pure-steam-runaway-greenhouse-effect","page":"Example outputs","title":"Pure steam runaway greenhouse effect","text":"","category":"section"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"By assuming the atmosphere temperature profile follows a dry adiabat and the water vapour-condensate coexistance curve defined by the Clausius-Claperyron relation, we see a characteristic relationship between the outgoing longwave radiation (OLR) and the surface temperature (T_s). Initially OLR increases with T_s, but as the condensing layer (which is independent of T_s) overlaps with the photosphere, OLR and T_s decouple. Eventually the atmosphere reaches a dry post-runaway state, and OLR increases rapidly with T_s.","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"You can find a Jupyter notebook which reproduces this result in the tutorials directory of the repository.","category":"page"},{"location":"examples/#Prescribed-convective-case","page":"Example outputs","title":"Prescribed convective case","text":"","category":"section"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"In this case, a temperature profile is prescribed to follow a dry adiabat from the surface to a moist region, and then a pseudoadiabat to the top of the atmosphere. This is in line with previous works and the OLR curve above. ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"Radiative fluxes are then calculated according to this temperature profile. Because the profile is prescribed, the fluxes are not balanced locally or globally across the column.","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" ","category":"page"},{"location":"examples/#Radiative-convective-solution","page":"Example outputs","title":"Radiative-convective solution","text":"","category":"section"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"Instead, we can model an atmosphere such that that energy is globally and locally conserved. Convection is parameterised using mixing length theory in this case, allowing the system to be solved using a Newton-Raphson method. In the convective region at ~0.1 bar, we can see that the radiative fluxes and convective fluxes entirely cancel, because AGNI was asked to solve for a case with zero total flux transport. ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" \n
\n ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"We can also plot the outgoing emission spectrum and normalised longwave contribution function (CF). The spectrum clearly demonstrates complex water absorption features, and exceeds blackbody emission at shorter wavelengths due to Rayleigh scattering. The CF quantifies how much each pressure level contributes to the outgoing emission spectrum at a given wavelength – this is then plotted versus wavelength and pressure. ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" \n
\n ","category":"page"},{"location":"#AGNI","page":"Home","title":"AGNI","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"A numerical model for the atmospheres of hot terrestrial (exo)planets. AGNI's primary purpose is to simulate the evolving atmospheres of magma ocean planets, while ensuring that radiative-convective equilibrium is sufficiently maintained.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Follow Getting started for information on installing the code and obtaining results.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Contact: harrison[dot]nicholls[at]physics.ox.ac.uk","category":"page"},{"location":"","page":"Home","title":"Home","text":"GitHub: https://github.com/nichollsh/AGNI","category":"page"},{"location":"","page":"Home","title":"Home","text":"Pronounced: ag-nee. Named after the fire deity of Hinduism.","category":"page"},{"location":"","page":"Home","title":"Home","text":"This software is available under the GPLv3. Copyright (C) 2024 Harrison Nicholls.","category":"page"},{"location":"setup/#Getting-started","page":"Getting started","title":"Getting started","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"This page outlines requirements and installation steps for the code. Currently, GNU/Linux and MacOS (including ARM) are supported.","category":"page"},{"location":"setup/#Requirements","page":"Getting started","title":"Requirements","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"gfortran\nNetCDF library for FORTRAN\nmake\ncurl","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"warning: Warning\nDo not install Julia using your system package manager. Install only from julialang.org","category":"page"},{"location":"setup/#Installation","page":"Getting started","title":"Installation","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"Follow the steps below in order to setup the code.","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"Install Julia: curl -fsSL https://install.julialang.org | sh\nDownload AGNI: git clone https://github.com/nichollsh/AGNI.git\nChange directory: cd AGNI\nSetup SOCRATES by doing either ONE of the following...\nFollow the instructions on the SOCRATES GitHub page\nRun source get_socrates.sh\njulia -e 'using Pkg; Pkg.activate(\".\"); Pkg.build()'","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"AGNI is now installed as a package into a Julia environment in the AGNI directory. This will also have downloaded some basic input data. You should run the tests next.","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"tip: Tip\nThe get_socrates.sh script automatically adds the radiation code to your environment with the variable RAD_DIR, which points to the SOCRATES installation. This variable must be set whenever AGNI is being used.","category":"page"},{"location":"setup/#Testing","page":"Getting started","title":"Testing","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"Now try running the tests in your terminal.","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"julia ./test/runtests.jl","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"This will print information on whether tests passed or failed.","category":"page"},{"location":"setup/#Using-the-code","page":"Getting started","title":"Using the code","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"See Running the model for information on using the code. See Troubleshooting for troubleshooting advice.","category":"page"}] +[{"location":"model/#Model-description","page":"Model description","title":"Model description","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI models a planetary atmosphere by treating it as a single column (1D) and splitting it up into levels of finite thickness. These levels are defined in pressure-space, and are arranged logarithmically between the surface and the top of the atmosphere. The atmosphere is assumed to be plane-parallel. Quantities such as pressure and temperature are calculated at level-centres and level-edges, while energy fluxes are calculated only at the edges, and thermodynamic properties (e.g. heat capacity) are calculated only at their centres.","category":"page"},{"location":"model/#Radiative-transfer","page":"Model description","title":"Radiative transfer","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"Radiative transfer (RT) refers to the transport of radiation energy through a medium subject to the characteristics of the medium. Radiation passing through an atmosphere is absorbed, emitted, scattered, and reflected. In the context of planetary atmospheres, we also have to handle their surfaces, cloud formation, and radiation from the host star.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI simulates RT using SOCRATES, a numerical code written by the UK Met Office which solves the RT equation using a two-stream solution. SOCRATES is accessed using a Julia interface originally written by Stuart Daines. The atmosphere is assumed to be hydrostatically supported and to behave as an ideal gas. Opacity is handle using the correlated-k approximation, with either random overlap or equivalent extinction used to account for overlapping absorption in mixtures of gases.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The model uses k-terms fitted to spectral absorption cross-section data from DACE. The MT_CKD model is used to estimate water continuum absorption cross-sections. Other continuua are derived from the HITRAN tables. Rayleigh scattering and water cloud radiative properties are also included. You can find tools for fitting k-terms and processing line absorption data in my redistribution of SOCRATES on GitHub. The flowchart below outlines how these absorption data are converted into a 'spectral file'.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":" ","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"Surface reflectivity can be modelled as a greybody with an albedo from 0 to 1. Alternatively, it can be modelled from empirical single-scattering data which varies with zenith angle and wavelength.","category":"page"},{"location":"model/#Convection","page":"Model description","title":"Convection","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"Convection is a turbulent process which occurs across more than one spatial dimension, so it must be parameterised within 1D models like AGNI. In fact, it is typically parameterised inside 3D global circulation models as resolving convection is numerically expensive. AGNI uses mixing length theory (MLT) to parameterise convection. This is in contrast to convective adjustment, which forcibly adjusts a convectively unstable region of the atmosphere to the corresponding adiabat while ensuring that enthalpy is conserved.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"MLT directly calculates the energy flux associated with convective heat transport, and thus is the preferred parameterisation within the model. It assumes that parcels of gas are diffused over a characteristic mixing length, transporting energy in the process. This requires choosing a scale for this mixing length, but in practice this has very little impact on the results from the model.","category":"page"},{"location":"model/#Phase-change","page":"Model description","title":"Phase change","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"Gases release energy (\"latent heat\" or \"enthalpy\") into their surroundings when condensing into a liquid or solid. This is included in the model through a diffusive condensation scheme, which assumes a fixed condensation timescale. This takes place as follows... firstly, the mixing ratios of the gases are updated according to the temperature profile, where rainout occurs until all condensibles are saturated or sub-saturated. The mixing ratios of dry species are increased in order to satisfy the total pressure at condensing levels. The heat released associated with the change in partial pressure of condensible gases is used to calculate a latent heating rate. This is then integrated (from the TOA downwards) to provide a latent heat transport flux at cell-edges. The integrate condensible heat flux is balanced by evaporation at deeper layers.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"Latent heats are temperature-dependent, using values derived from Coker (2007) and Wagner & Pruß (2001). Heat capacities are also temperature-dependent, using values derived from the JANAF database. See the ThermoTools repo for scripts.","category":"page"},{"location":"model/#Solar-flux","page":"Model description","title":"Solar flux","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"A key input to the radiation model is the shortwave downward-directed flux from the star at the top of the atmosphere. This is quantified by the bolometric instellation flux, a scale factor, an artificial additional albedo factor, and a zenith angle. All of these may be provided to the model through the configuration file. The model also requires a stellar spectrum scaled to the top of the atmosphere.","category":"page"},{"location":"model/#Obtaining-a-solution","page":"Model description","title":"Obtaining a solution","text":"","category":"section"},{"location":"model/#Summary","page":"Model description","title":"Summary","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI is designed for modelling planetary atmospheres with high surface pressures and temperatures. This means that the radiative timescale differs by several orders of magnitude across the column, which makes obtaining a solution difficult. To obtain a temperature structure solution that conserves energy more precisely than a time-stepping method, AGNI solves for the temperature structure of the atmosphere as an optimisation problem. This finds the state which conserves energy across all levels and satisfies the required configuration from the user.","category":"page"},{"location":"model/#Solution-types","page":"Model description","title":"Solution types","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"It is necessary to tell AGNI what kind of atmospheric solution to solve for. There are currently a few options available set by the solution_type variable in the configuration file.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"(1) Aim to conserve energy fluxes throughout the column. The surface temperature is fixed.\n(2) Aim to conserve energy fluxes throughout the column. The surface temperature is set by energy transport through a solid conductive boundary layer of thickness d such that T_s = T_m - fracFdk, where T_m is the mantle temperature and k is the thermal conductivity.\n(3) Solve for a state such that the flux carried at each level is equal to F_texteff = sigma T_texteff^4, representing the rate at which a planet is losing energy into space.","category":"page"},{"location":"model/#Construction","page":"Model description","title":"Construction","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"The atmosphere is constructed of N levels (cell-centres), corresponding to N+1 interfaces (cell-edges). The RT model takes cell-centre temperatures T_i, pressures p_i, geometric heights, and mixing ratios as input variables at each level i. As well as the surface temperature and incoming stellar flux. In return, it provides cell-edges spectral fluxes F_i at all N+1 interfaces for LW & SW components and upward & downward streams. Convective fluxes can be estimated using the MLT scheme, condensation fluxes from the condensation scheme, and sensible heat from a simple TKE approximation.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The total upward-directed energy flux F_i describes the total upward-directed energy transport (units of textW m^-2) from cell i into cell i-1 above (or into space for i=1). For energy to be conserved throughout the column, it must be true that F_i = F_t text forall text i where F_t is the total amount of energy being transported out of the planet. In global radiative equilibrium, F_t = 0.","category":"page"},{"location":"model/#Definition-of-residuals","page":"Model description","title":"Definition of residuals","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"We can use this construction to solve for the temperature profile of the atmosphere as an N+1-dimensional optimisation problem. This directly solves for T(p) at radiative-convective equilibrium without having to invoke heating rate calculations, thereby avoiding slow convergence in regions of the atmosphere with long radiative timescales. The residuals vector (length N+1)","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"\nbmr =\n\nbeginpmatrix\nr_i \nr_i+1 \n \nr_N \nr_N+1\nendpmatrix\n\n=\n\nbeginpmatrix\nF_i+1 - F_i \nF_i+2 - F_i+1 \n \nF_N+1 - F_N \nF_N+1 - F_t\nendpmatrix","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"is what we aim to minimise as our 'objective function', subject to the solution vector of cell-centre temperatures","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmx =\n\nbeginpmatrix\nT_i \nT_i+1 \n \nT_N \nT_s\nendpmatrix","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"where T_s is the surface temperature. Cell-edge temperatures in the bulk atmosphere are interpolated using the PCHIP algorithm, which avoids Runge's phenomenon and overshooting. The bottom- and top-most cell edge temperatures are extrapolated by estimation of dTd log p. Cell properties (heat capacity, gravity, density, average molecular weight, etc.) are consistently updated at each evaluation of bmr. Condensation/rainout are also handled at each evaluation of bmr in order to avoid supersaturation.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The model converges when the cost function c(bmx) = sqrtsum_i r_i satisfies the condition","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"c(bmx) c_a + c_r cdot undersetimax text F_i","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"which represents a state where the fluxes are sufficiently conserved.","category":"page"},{"location":"model/#Iterative-steps","page":"Model description","title":"Iterative steps","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"The model solves for bmx iteratively, starting from some initial guess. The initial guess should be any reasonable temperature profile which is not significantly cooler than the expected solution. The flowchart below broadly outlines the solution process.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":" ","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The Jacobian matrix bmJ represents the directional gradient of the residuals with respect to the solution vector. It is a square matrix with elements set according to","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"J_uv = fracpartial r_upartial x_v","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI estimates bmJ using finite-differences, requiring N+1 evalulations of bmr in order to fill the matrix. This corresponds to 2(N+1)+1 objective function calculations under a 2nd order central-difference scheme. Each level v with temperature x_v is perturbed by an amount pm varepsilon x_v in order to fill a single column of bmJ. As such, it can be expensive to construct a full Jacobian, especially when it is discarded at the end of each iteration. To reduce the total number of calculations AGNI retains some of the columns in bmJ between model iterations. This assumes that the second derivative of the residuals is small. A column v is retained only when","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"max r_i lt 07 text for i in v-1 v v+1","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"and when c(bmx)10 does not satisfy the convergence criteria.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"With a Jacobian constructed, we can calculate an update bmd to the solution vector bmx rightarrow bmx + bmd. This is primarily done via the Newton-Raphson method","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmd = -bmJ^-1 bmr","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"but can alternatively be performed via the Gauss-Newton and Levenberg–Marquardt methods.","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"It is possible for the model to become stuck in a local minimum, leading to very small values of bmd. This is identified when c(bmx) has seen little change over the last few iterations. When this occurs, the model is 'nudged' by scaling the update via","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmd rightarrow 3 bmd","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"In many cases bmd is too large, leading to instabilities. This is due to the non-convexity of the solution space, and the somewhat discontinuous nature of the physics involved (particularly in its temperature derivatives). When bmdd_textmax, the update is crudely scaled via","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmd rightarrow d_textmax hatbmd","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"The update may also be scaled by a linesearch","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"bmd rightarrow alpha bmd","category":"page"},{"location":"model/","page":"Model description","title":"Model description","text":"on alpha. This is applied if the full step bmd would increase the cost by an unacceptable amount. If the model is close to convergence then a golden-section search method is used to determine the optimal alpha, otherwise a backtracking method is used. This means that the model is (mostly) able to avoid oscillating around a solution. All three of these scalings to bmd preserve its direction.","category":"page"},{"location":"model/#Other-features","page":"Model description","title":"Other features","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI can calculate emission spectra, provided with T(p) and the volume mixing ratios of the gases. This is performed using the same RT as the RCE calculations, so is limited in resolution by the choice of correlated-k bands. Similarly, the longwave contribution function can also be calculated.","category":"page"},{"location":"model/#Julia-and-Fortran","page":"Model description","title":"Julia and Fortran","text":"","category":"section"},{"location":"model/","page":"Model description","title":"Model description","text":"AGNI is primarily written in Julia, while SOCRATES itself is written in Fortran. Julia was chosen because it allows the SOCRATES binaries to be included in the precompiled code, which significantly improves performance.","category":"page"},{"location":"usage/#Running-the-model","page":"Running the model","title":"Running the model","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"First, follow the Getting started instructions. Only read-on once you have confirmed that the code is working.","category":"page"},{"location":"usage/#Input-data-files","page":"Running the model","title":"Input data files","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"The minimal input data required to run the model will have been downloaded automatically. If you require more data, such as additional stellar spectra or opacities, then these can also be easily obtained using the get_data script in the AGNI root directory. To see how to use this script, run it without arguments like so:","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"./get_data.sh","category":"page"},{"location":"usage/#Tutorials","page":"Running the model","title":"Tutorials","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"There are Jupyter notebooks containing tutorials in the tutorials/ directory of the repository.","category":"page"},{"location":"usage/#General-execution","page":"Running the model","title":"General execution","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"The environment variable RAD_DIR must point to the SOCRATES installation directory. This is required for AGNI to find the SOCRATES libraries, and can be done by running source path/to/socrates/set_rad_env in your terminal.","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"Then to use the model, simply run ./agni.jl [cfg] where [cfg] is the path to the required configuration file. If [cfg] is not passed, then the default configuration will be used.","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"To calculate equilibrium chemistry self-consistently with the climate, FastChem is coupled to AGNI. For AGNI to find FastChem, the environment variable FC_DIR must point to the FastChem installation directory.","category":"page"},{"location":"usage/#Configuration","page":"Running the model","title":"Configuration","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"AGNI configuration files are formatted using TOML. There are examples in res/config/. The default configuration file contains comments explaining the purpose of each parameter, although some are explained in greater detail below. Take care to format the variables in the TOML file correctly. There are no 'default values'. Not all parameters are required in all cases, but the model will return an error naming any parameters which are both necessary and absent.","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"Broadly, the configuration files are broken up into four sections:","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"[planet] - general characteristics of the planet\n[files] - input/output files and other paths\n[composition] - atmospheric composition and chemistry\n[execution] - what the model should do\n[plots] - which plots should be produced","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"Some parameters:","category":"page"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"files.input_sf is the file path to the \"spectral file\" containing opacity data. Several spectral files are packged with AGNI, but you can find more online via the Open Science Framework.\nexecution.solution_type tells the model which state to solve for. The allowed values (integers) are...\n1 : zero flux divergence at fixed tmp_surf\n2 : zero flux divergence, with tmp_surf set such that the conductive skin (CBL) conserves energy flux\n3 : the net upward flux at each layer is equal to flux_int = sigma * tmp_int^4\nexecution.solvers tells the model which solvers to use. This is a list of strings, so multiple solvers can be applied sequentially. An empty string is always appended to the end of this list. Allowed solvers are...\n[empty string] : no solving takes place, so the model just calculates fluxes using the initial state\nnewton : the Newton-Raphson algorithm is used\ngauss : the Gauss-Newton algorithm is used\nlevenberg : the Levenberg–Marquardt algorithm is used\nexecution.initial_state describes the initial temperature profile applied to the atmosphere. This is a list of strings which are applied in the given order, which allows the user to describe a specific state as required. The descriptors are listed below, some of which take a single argument that needs to immediately follow the descriptor in the list order.\ndry : integrate the dry adiabatic lapse rate from the surface upwards\nstr, arg : apply an isothermal stratosphere at arg kelvin\niso, arg : set the whole atmosphere to be isothermal at arg kelvin\ncsv, arg : set the temperature profile using the CSV file at the file path arg\nsat, arg : apply Clausius-Clapeyron saturation curve for the gas arg\nncdf, arg : load profile from the NetCDF file located at arg\nloglin, arg : log-linear profile between tmp_surf at the bottom and arg at the top\nFor example, setting initial_state = [\"dry\", \"sat\", \"H2O\", \"str\", \"180\"] will set T(p) to follow the dry adiabat from the surface, the water condensation curve above that, and then to be isothermal at 180 K until the top of the model.\ncomposition.chem_type describes the type of chemistry to implement within the model. This is handled externally by FastChem, so you must set the environment variable FC_DIR to point to the FastChem directory. The allowed values (integers) are...\n0 : Disabled\n1 : Equilibrium, gas phase only\n2 : Equilibrium, with condensation (condensates retained)\n3 : Equilibrium, with condensation (condensates rained out)","category":"page"},{"location":"usage/#Outputs","page":"Running the model","title":"Outputs","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"Results are optionally plotted and animated, and data will be saved as NetCDF or CSV files.","category":"page"},{"location":"usage/#Python","page":"Running the model","title":"Python","text":"","category":"section"},{"location":"usage/","page":"Running the model","title":"Running the model","text":"It is possible to interact with the model using Python. This is best done with the juliacall package from PythonCall.jl, and is implemented this way in the PROTEUS framework.","category":"page"},{"location":"troubleshooting/#Troubleshooting","page":"Troubleshooting","title":"Troubleshooting","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"This page may be useful if you are having problems. However, I would suggest that you also double check the Getting started instructions.","category":"page"},{"location":"troubleshooting/#Julia-errors-on-start,-potentially-referencing-the-CURL-library","page":"Troubleshooting","title":"Julia errors on start, potentially referencing the CURL library","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"It is important that the shell environment variable LD_LIBRARY_PATH is not set when running AGNI. This will cause Julia to use the wrong libraries, which will causes problems. You can unset this variable or reset using either of the following commands ","category":"page"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"unset LD_LIBRARY_PATH\nexport LD_LIBRARY_PATH=\"\"","category":"page"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"If this does not help, it's possible that you are using a Julia distribution provided by your system package manager. It's important that you only use Julia distributed from the official website.","category":"page"},{"location":"troubleshooting/#Cannot-find-SOCRATES","page":"Troubleshooting","title":"Cannot find SOCRATES","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"Check the installation instructions. Have you set RAD_DIR? Try running l_run_cdf in the terminal; if this fails, then SOCRATES has not compiled or you haven't added it to your PATH.","category":"page"},{"location":"troubleshooting/#Spectral-file-does-not-exist","page":"Troubleshooting","title":"Spectral file does not exist","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"Check the path in the configuration file. Download additional spectral files using the get_data script in the AGNI root directory. For example, for additional pure-steam spectral files you would run","category":"page"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"./get_data.sh steam","category":"page"},{"location":"troubleshooting/#Finally...","page":"Troubleshooting","title":"Finally...","text":"","category":"section"},{"location":"troubleshooting/","page":"Troubleshooting","title":"Troubleshooting","text":"If you are still stuck, or feel that there is a problem with the code, then you can contact the authors using the information on the main page.","category":"page"},{"location":"manual/#Development-manual","page":"Development","title":"Development manual","text":"","category":"section"},{"location":"manual/#Contributing","page":"Development","title":"Contributing","text":"","category":"section"},{"location":"manual/","page":"Development","title":"Development","text":"If you are interested in contributing to the model, please contact the developers using the information on the main page.","category":"page"},{"location":"manual/#Coding-style","page":"Development","title":"Coding style","text":"","category":"section"},{"location":"manual/","page":"Development","title":"Development","text":"Indentation uses 4 spaces, no tabs.\nFunction names should be lowercase, with words separated by underscores .\nLines should aim to have a length of no more than 92 characters.\nAll functions should have docstrings, ideally with Arguments and Returns listed.\nMore comments are always better, even if they seem redundant.\nUse type hinting where possible.\nPrint statements should be made through the logger where possible.\nThe core package code should not contain global variables, except in the phys module.","category":"page"},{"location":"manual/#Code-reference","page":"Development","title":"Code reference","text":"","category":"section"},{"location":"manual/","page":"Development","title":"Development","text":"To be completed.","category":"page"},{"location":"examples/#Example-outputs","page":"Example outputs","title":"Example outputs","text":"","category":"section"},{"location":"examples/#Pure-steam-runaway-greenhouse-effect","page":"Example outputs","title":"Pure steam runaway greenhouse effect","text":"","category":"section"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"By assuming the atmosphere temperature profile follows a dry adiabat and the water vapour-condensate coexistance curve defined by the Clausius-Claperyron relation, we see a characteristic relationship between the outgoing longwave radiation (OLR) and the surface temperature (T_s). Initially OLR increases with T_s, but as the condensing layer (which is independent of T_s) overlaps with the photosphere, OLR and T_s decouple. Eventually the atmosphere reaches a dry post-runaway state, and OLR increases rapidly with T_s.","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"You can find a Jupyter notebook which reproduces this result in the tutorials directory of the repository.","category":"page"},{"location":"examples/#Prescribed-convective-case","page":"Example outputs","title":"Prescribed convective case","text":"","category":"section"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"In this case, a temperature profile is prescribed to follow a dry adiabat from the surface to a moist region, and then a pseudoadiabat to the top of the atmosphere. This is in line with previous works and the OLR curve above. ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"Radiative fluxes are then calculated according to this temperature profile. Because the profile is prescribed, the fluxes are not balanced locally or globally across the column.","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" ","category":"page"},{"location":"examples/#Radiative-convective-solution","page":"Example outputs","title":"Radiative-convective solution","text":"","category":"section"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"Instead, we can model an atmosphere such that that energy is globally and locally conserved. Convection is parameterised using mixing length theory in this case, allowing the system to be solved using a Newton-Raphson method. In the convective region at ~0.1 bar, we can see that the radiative fluxes and convective fluxes entirely cancel, because AGNI was asked to solve for a case with zero total flux transport. ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" \n
\n ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":"We can also plot the outgoing emission spectrum and normalised longwave contribution function (CF). The spectrum clearly demonstrates complex water absorption features, and exceeds blackbody emission at shorter wavelengths due to Rayleigh scattering. The CF quantifies how much each pressure level contributes to the outgoing emission spectrum at a given wavelength – this is then plotted versus wavelength and pressure. ","category":"page"},{"location":"examples/","page":"Example outputs","title":"Example outputs","text":" \n
\n ","category":"page"},{"location":"#AGNI","page":"Home","title":"AGNI","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"A numerical model for the atmospheres of hot rocky (exo)planets. AGNI's primary purpose is to simulate the evolving atmospheres of magma ocean planets, while ensuring that radiative-convective equilibrium is sufficiently maintained.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Follow Getting started for information on installing the code and obtaining results.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Contact: harrison[dot]nicholls[at]physics.ox.ac.uk","category":"page"},{"location":"","page":"Home","title":"Home","text":"GitHub: https://github.com/nichollsh/AGNI","category":"page"},{"location":"","page":"Home","title":"Home","text":"Pronounced: ag-nee. Named after the fire deity of Hinduism.","category":"page"},{"location":"","page":"Home","title":"Home","text":"This software is available under the GPLv3. Copyright (C) 2024 Harrison Nicholls.","category":"page"},{"location":"setup/#Getting-started","page":"Getting started","title":"Getting started","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"This page outlines requirements and installation steps for the code. Currently, GNU/Linux and MacOS (including ARM) are supported.","category":"page"},{"location":"setup/#Requirements","page":"Getting started","title":"Requirements","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"gfortran\nNetCDF library for FORTRAN\nmake\ncurl","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"warning: Warning\nDo not install Julia using your system package manager. Install only from julialang.org","category":"page"},{"location":"setup/#Installation","page":"Getting started","title":"Installation","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"Follow the steps below in order to setup the code.","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"Install Julia: curl -fsSL https://install.julialang.org | sh\nDownload AGNI: git clone https://github.com/nichollsh/AGNI.git\nChange directory: cd AGNI\nSetup SOCRATES by doing either ONE of the following...\nFollow the instructions on the SOCRATES GitHub page\nRun source get_socrates.sh\njulia -e 'using Pkg; Pkg.activate(\".\"); Pkg.build()'","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"AGNI is now installed as a package into a Julia environment in the AGNI directory. This will also have downloaded some basic input data. You should run the tests next.","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"tip: Tip\nThe get_socrates.sh script automatically adds the radiation code to your environment with the variable RAD_DIR, which points to the SOCRATES installation. This variable must be set whenever AGNI is being used.","category":"page"},{"location":"setup/#Testing","page":"Getting started","title":"Testing","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"Now try running the tests in your terminal.","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"julia ./test/runtests.jl","category":"page"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"This will print information on whether tests passed or failed.","category":"page"},{"location":"setup/#Using-the-code","page":"Getting started","title":"Using the code","text":"","category":"section"},{"location":"setup/","page":"Getting started","title":"Getting started","text":"See Running the model for information on using the code. See Troubleshooting for troubleshooting advice.","category":"page"}] } diff --git a/dev/setup/index.html b/dev/setup/index.html index e597745d..2205c81d 100644 --- a/dev/setup/index.html +++ b/dev/setup/index.html @@ -1,2 +1,2 @@ -Getting started · AGNI

Getting started

This page outlines requirements and installation steps for the code. Currently, GNU/Linux and MacOS (including ARM) are supported.

Requirements

  • gfortran
  • NetCDF library for FORTRAN
  • make
  • curl
Warning

Do not install Julia using your system package manager. Install only from julialang.org

Installation

Follow the steps below in order to setup the code.

  1. Install Julia: curl -fsSL https://install.julialang.org | sh
  2. Download AGNI: git clone https://github.com/nichollsh/AGNI.git
  3. Change directory: cd AGNI
  4. Setup SOCRATES by doing either ONE of the following...
    • Follow the instructions on the SOCRATES GitHub page
    • Run source get_socrates.sh
  5. julia -e 'using Pkg; Pkg.activate("."); Pkg.build()'

AGNI is now installed as a package into a Julia environment in the AGNI directory. This will also have downloaded some basic input data. You should run the tests next.

Tip

The get_socrates.sh script automatically adds the radiation code to your environment with the variable RAD_DIR, which points to the SOCRATES installation. This variable must be set whenever AGNI is being used.

Testing

Now try running the tests in your terminal.

julia ./test/runtests.jl

This will print information on whether tests passed or failed.

Using the code

See Running the model for information on using the code. See Troubleshooting for troubleshooting advice.

+Getting started · AGNI

Getting started

This page outlines requirements and installation steps for the code. Currently, GNU/Linux and MacOS (including ARM) are supported.

Requirements

  • gfortran
  • NetCDF library for FORTRAN
  • make
  • curl
Warning

Do not install Julia using your system package manager. Install only from julialang.org

Installation

Follow the steps below in order to setup the code.

  1. Install Julia: curl -fsSL https://install.julialang.org | sh
  2. Download AGNI: git clone https://github.com/nichollsh/AGNI.git
  3. Change directory: cd AGNI
  4. Setup SOCRATES by doing either ONE of the following...
    • Follow the instructions on the SOCRATES GitHub page
    • Run source get_socrates.sh
  5. julia -e 'using Pkg; Pkg.activate("."); Pkg.build()'

AGNI is now installed as a package into a Julia environment in the AGNI directory. This will also have downloaded some basic input data. You should run the tests next.

Tip

The get_socrates.sh script automatically adds the radiation code to your environment with the variable RAD_DIR, which points to the SOCRATES installation. This variable must be set whenever AGNI is being used.

Testing

Now try running the tests in your terminal.

julia ./test/runtests.jl

This will print information on whether tests passed or failed.

Using the code

See Running the model for information on using the code. See Troubleshooting for troubleshooting advice.

diff --git a/dev/troubleshooting/index.html b/dev/troubleshooting/index.html index 6c9648ea..0d83273a 100644 --- a/dev/troubleshooting/index.html +++ b/dev/troubleshooting/index.html @@ -1,3 +1,3 @@ Troubleshooting · AGNI

Troubleshooting

This page may be useful if you are having problems. However, I would suggest that you also double check the Getting started instructions.

Julia errors on start, potentially referencing the CURL library

It is important that the shell environment variable LD_LIBRARY_PATH is not set when running AGNI. This will cause Julia to use the wrong libraries, which will causes problems. You can unset this variable or reset using either of the following commands

unset LD_LIBRARY_PATH
-export LD_LIBRARY_PATH=""

If this does not help, it's possible that you are using a Julia distribution provided by your system package manager. It's important that you only use Julia distributed from the official website.

Cannot find SOCRATES

Check the installation instructions. Have you set RAD_DIR? Try running l_run_cdf in the terminal; if this fails, then SOCRATES has not compiled or you haven't added it to your PATH.

Spectral file does not exist

Check the path in the configuration file. Download additional spectral files using the get_data script in the AGNI root directory. For example, for additional pure-steam spectral files you would run

./get_data.sh steam

Finally...

If you are still stuck, or feel that there is a problem with the code, then you can contact the authors using the information on the main page.

+export LD_LIBRARY_PATH=""

If this does not help, it's possible that you are using a Julia distribution provided by your system package manager. It's important that you only use Julia distributed from the official website.

Cannot find SOCRATES

Check the installation instructions. Have you set RAD_DIR? Try running l_run_cdf in the terminal; if this fails, then SOCRATES has not compiled or you haven't added it to your PATH.

Spectral file does not exist

Check the path in the configuration file. Download additional spectral files using the get_data script in the AGNI root directory. For example, for additional pure-steam spectral files you would run

./get_data.sh steam

Finally...

If you are still stuck, or feel that there is a problem with the code, then you can contact the authors using the information on the main page.

diff --git a/dev/usage/index.html b/dev/usage/index.html index 750e1f0f..51141f2a 100644 --- a/dev/usage/index.html +++ b/dev/usage/index.html @@ -1,2 +1,2 @@ -Running the model · AGNI

Running the model

First, follow the Getting started instructions. Only read-on once you have confirmed that the code is working.

Input data files

The minimal input data required to run the model will have been downloaded automatically. If you require more data, such as additional stellar spectra or opacities, then these can also be easily obtained using the get_data script in the AGNI root directory. To see how to use this script, run it without arguments like so:

./get_data.sh

Tutorials

There are Jupyter notebooks containing tutorials in the tutorials/ directory of the repository.

General execution

The environment variable RAD_DIR must point to the SOCRATES installation directory. This is required for AGNI to find the SOCRATES libraries, and can be done by running source path/to/socrates/set_rad_env in your terminal.

Then to use the model, simply run ./agni.jl [cfg] where [cfg] is the path to the required configuration file. If [cfg] is not passed, then the default configuration will be used.

To calculate equilibrium chemistry self-consistently with the climate, FastChem is coupled to AGNI. For AGNI to find FastChem, the environment variable FC_DIR must point to the FastChem installation directory.

Configuration

AGNI configuration files are formatted using TOML. There are examples in res/config/. The default configuration file contains comments explaining the purpose of each parameter, although some are explained in greater detail below. Take care to format the variables in the TOML file correctly. There are no 'default values'. Not all parameters are required in all cases, but the model will return an error naming any parameters which are both necessary and absent.

Broadly, the configuration files are broken up into four sections:

  • [planet] - general characteristics of the planet
  • [files] - input/output files and other paths
  • [composition] - atmospheric composition and chemistry
  • [execution] - what the model should do
  • [plots] - which plots should be produced

Some parameters:

  • files.input_sf is the file path to the "spectral file" containing opacity data. Several spectral files are packged with AGNI, but you can find more online via the Open Science Framework.

  • execution.solution_type tells the model which state to solve for. The allowed values (integers) are...

    • 1 : zero flux divergence at fixed tmp_surf
    • 2 : zero flux divergence, with tmp_surf set such that the conductive skin (CBL) conserves energy flux
    • 3 : the net upward flux at each layer is equal to flux_int = sigma * tmp_int^4
  • execution.solvers tells the model which solvers to use. This is a list of strings, so multiple solvers can be applied sequentially. An empty string is always appended to the end of this list. Allowed solvers are...

    • [empty string] : no solving takes place, so the model just calculates fluxes using the initial state
    • newton : the Newton-Raphson algorithm is used
    • gauss : the Gauss-Newton algorithm is used
    • levenberg : the Levenberg–Marquardt algorithm is used
  • execution.initial_state describes the initial temperature profile applied to the atmosphere. This is a list of strings which are applied in the given order, which allows the user to describe a specific state as required. The descriptors are listed below, some of which take a single argument that needs to immediately follow the descriptor in the list order.

    • dry : integrate the dry adiabatic lapse rate from the surface upwards
    • str, arg : apply an isothermal stratosphere at arg kelvin
    • iso, arg : set the whole atmosphere to be isothermal at arg kelvin
    • csv, arg : set the temperature profile using the CSV file at the file path arg
    • sat, arg : apply Clausius-Clapeyron saturation curve for the gas arg
    • ncdf, arg : load profile from the NetCDF file located at arg
    • loglin, arg : log-linear profile between tmp_surf at the bottom and arg at the top

    For example, setting initial_state = ["dry", "sat", "H2O", "str", "180"] will set T(p) to follow the dry adiabat from the surface, the water condensation curve above that, and then to be isothermal at 180 K until the top of the model.

  • composition.chem_type describes the type of chemistry to implement within the model. This is handled externally by FastChem, so you must set the environment variable FC_DIR to point to the FastChem directory. The allowed values (integers) are...

    • 0 : Disabled
    • 1 : Equilibrium, gas phase only
    • 2 : Equilibrium, with condensation (condensates retained)
    • 3 : Equilibrium, with condensation (condensates rained out)

Outputs

Results are optionally plotted and animated, and data will be saved as NetCDF or CSV files.

Python

It is possible to interact with the model using Python. This is best done with the juliacall package from PythonCall.jl, and is implemented this way in the PROTEUS framework.

+Running the model · AGNI

Running the model

First, follow the Getting started instructions. Only read-on once you have confirmed that the code is working.

Input data files

The minimal input data required to run the model will have been downloaded automatically. If you require more data, such as additional stellar spectra or opacities, then these can also be easily obtained using the get_data script in the AGNI root directory. To see how to use this script, run it without arguments like so:

./get_data.sh

Tutorials

There are Jupyter notebooks containing tutorials in the tutorials/ directory of the repository.

General execution

The environment variable RAD_DIR must point to the SOCRATES installation directory. This is required for AGNI to find the SOCRATES libraries, and can be done by running source path/to/socrates/set_rad_env in your terminal.

Then to use the model, simply run ./agni.jl [cfg] where [cfg] is the path to the required configuration file. If [cfg] is not passed, then the default configuration will be used.

To calculate equilibrium chemistry self-consistently with the climate, FastChem is coupled to AGNI. For AGNI to find FastChem, the environment variable FC_DIR must point to the FastChem installation directory.

Configuration

AGNI configuration files are formatted using TOML. There are examples in res/config/. The default configuration file contains comments explaining the purpose of each parameter, although some are explained in greater detail below. Take care to format the variables in the TOML file correctly. There are no 'default values'. Not all parameters are required in all cases, but the model will return an error naming any parameters which are both necessary and absent.

Broadly, the configuration files are broken up into four sections:

  • [planet] - general characteristics of the planet
  • [files] - input/output files and other paths
  • [composition] - atmospheric composition and chemistry
  • [execution] - what the model should do
  • [plots] - which plots should be produced

Some parameters:

  • files.input_sf is the file path to the "spectral file" containing opacity data. Several spectral files are packged with AGNI, but you can find more online via the Open Science Framework.

  • execution.solution_type tells the model which state to solve for. The allowed values (integers) are...

    • 1 : zero flux divergence at fixed tmp_surf
    • 2 : zero flux divergence, with tmp_surf set such that the conductive skin (CBL) conserves energy flux
    • 3 : the net upward flux at each layer is equal to flux_int = sigma * tmp_int^4
  • execution.solvers tells the model which solvers to use. This is a list of strings, so multiple solvers can be applied sequentially. An empty string is always appended to the end of this list. Allowed solvers are...

    • [empty string] : no solving takes place, so the model just calculates fluxes using the initial state
    • newton : the Newton-Raphson algorithm is used
    • gauss : the Gauss-Newton algorithm is used
    • levenberg : the Levenberg–Marquardt algorithm is used
  • execution.initial_state describes the initial temperature profile applied to the atmosphere. This is a list of strings which are applied in the given order, which allows the user to describe a specific state as required. The descriptors are listed below, some of which take a single argument that needs to immediately follow the descriptor in the list order.

    • dry : integrate the dry adiabatic lapse rate from the surface upwards
    • str, arg : apply an isothermal stratosphere at arg kelvin
    • iso, arg : set the whole atmosphere to be isothermal at arg kelvin
    • csv, arg : set the temperature profile using the CSV file at the file path arg
    • sat, arg : apply Clausius-Clapeyron saturation curve for the gas arg
    • ncdf, arg : load profile from the NetCDF file located at arg
    • loglin, arg : log-linear profile between tmp_surf at the bottom and arg at the top

    For example, setting initial_state = ["dry", "sat", "H2O", "str", "180"] will set T(p) to follow the dry adiabat from the surface, the water condensation curve above that, and then to be isothermal at 180 K until the top of the model.

  • composition.chem_type describes the type of chemistry to implement within the model. This is handled externally by FastChem, so you must set the environment variable FC_DIR to point to the FastChem directory. The allowed values (integers) are...

    • 0 : Disabled
    • 1 : Equilibrium, gas phase only
    • 2 : Equilibrium, with condensation (condensates retained)
    • 3 : Equilibrium, with condensation (condensates rained out)

Outputs

Results are optionally plotted and animated, and data will be saved as NetCDF or CSV files.

Python

It is possible to interact with the model using Python. This is best done with the juliacall package from PythonCall.jl, and is implemented this way in the PROTEUS framework.