diff --git a/.github/workflows/cla-check.yaml b/.github/workflows/cla-check.yaml deleted file mode 100644 index 3d28d73..0000000 --- a/.github/workflows/cla-check.yaml +++ /dev/null @@ -1,10 +0,0 @@ -name: Legal - -on: - pull_request_target: - -jobs: - cla: - uses: MetOffice/growss/.github/workflows/cla-check.yaml@main - with: - runner: 'ubuntu-24.04' diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 0000000..18da917 --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,73 @@ +name: Documentation website + +on: + workflow_dispatch: + push: + branches: + - main + +permissions: + actions: read + contents: read + pages: write + id-token: write +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - uses: actions/configure-pages@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Find latest successful docs PDF build + id: latest-pdf-run + uses: actions/github-script@v7 + with: + script: | + const { data } = await github.rest.actions.listWorkflowRuns({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: "build-docs-pdf.yaml", + branch: "main", + status: "completed", + per_page: 50, + }); + + const latest = data.workflow_runs.find((run) => run.conclusion === "success"); + + if (!latest) { + core.setFailed("No successful build-docs-pdf.yaml runs found on branch main."); + return; + } + core.info(`Using build-docs-pdf run ${latest.id} from ${latest.created_at} on branch main.`); + core.setOutput("run_id", String(latest.id)); + - name: Download docs PDFs from latest successful build + uses: actions/download-artifact@v5 + with: + name: docs-pdf + path: docs + run-id: ${{ steps.latest-pdf-run.outputs.run_id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Place docs PDFs in MkDocs assets + run: | + set -euo pipefail + mkdir -p docs/assets/pdfs + USERGUIDE_PDF="$(find docs -type f -name 'socrates_userguide.pdf' | head -n 1)" + TECHGUIDE_PDF="$(find docs -type f -name 'socrates_techguide.pdf' | head -n 1)" + if [ -z "${USERGUIDE_PDF}" ] || [ -z "${TECHGUIDE_PDF}" ]; then + echo "Could not locate expected docs PDFs after artifact download." + exit 1 + fi + cp "${USERGUIDE_PDF}" docs/assets/pdfs/socrates_userguide.pdf + cp "${TECHGUIDE_PDF}" docs/assets/pdfs/socrates_techguide.pdf + - run: pip install zensical markdown-include pymdown-extensions mkdocstrings mkdocstrings-python + - run: zensical build --clean + - uses: actions/upload-pages-artifact@v4 + with: + path: site + - uses: actions/deploy-pages@v4 + id: deployment diff --git a/.gitignore b/.gitignore index 1747090..053751d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ __pycache__ *.pyc .pytest_cache bin/ + +# documentation site +site/ \ No newline at end of file diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index b01b911..72dc56b 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -6,4 +6,5 @@ | mo-jmanners | James Manners | Met Office | 2025-12-18 | | t00sa | Sam Clarke-Green | Met Office | 2026-03-02 | | Pierre-siddall | Pierre Siddall | Met Office | 2026-03-16 | -| nichollsh | Harrison Nicholls | University of Cambridge | 2026-03-24 | +| nichollsh | Harrison Nicholls | University of Cambridge | 2026-03-19 | +| stuitje | Karen Stuitje | University of Groningen | 2026-04-11 | diff --git a/docs/Community/CODE_OF_CONDUCT.md b/docs/Community/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..fed5081 --- /dev/null +++ b/docs/Community/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +contact@formingworlds.space. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/docs/Community/contact.md b/docs/Community/contact.md new file mode 100644 index 0000000..a8382b3 --- /dev/null +++ b/docs/Community/contact.md @@ -0,0 +1,9 @@ +# Contact + +We encourage you to reach out! Choose the most appropriate channel below. + +| Channel | Use for | +|---------|---------| +| [GitHub Discussions](https://github.com/orgs/FormingWorlds/discussions) | Questions, installation help, feature suggestions | +| [GitHub Issues](https://github.com/FormingWorlds/SOCRATES/issues) | Bug reports, specific feature requests | +| [proteus_dev@formingworlds.space](mailto:proteus_dev@formingworlds.space) | General enquiries | diff --git a/docs/Explanations/interface.md b/docs/Explanations/interface.md new file mode 100644 index 0000000..a9022b5 --- /dev/null +++ b/docs/Explanations/interface.md @@ -0,0 +1,86 @@ +# Interface to the calling model + +!!! note + This overview is adapted from the technical guide by James Manners, John M. Edwards, Peter Hill & Jean-Claude Thelen (Met Office, 2017), which can be found [here](../Reference/documentation_pdfs.md#technical-guide). It is under Crown Copyright. + +## Overview + +The SOCRATES interface is designed to present a **clear and logical structure** to the input and output fields required by the radiation code. All variables passed to the core routine are wrapped into well-defined Fortran derived types. + +--- + +## Input and output types + +All arguments to the core routine `radiance_calc` are contained within **eight derived types**: + +| Type | Intent | Description | +|---|---|---| +| `control` | `IN` | Control options, initially read via a namelist | +| `dimen` | `IN` | Array dimension sizes | +| `spectrum` | `IN` | Spectral discretisation and optical properties read from the spectral file | +| `atm` | `IN` | Grid discretisation and atmospheric profiles of thermodynamic quantities and gas amounts | +| `cld` | `IN` | Cloud fields: fractions, mixing ratios, and sub-grid structure | +| `aer` | `IN` | Aerosol fields: mixing ratios for CLASSIC aerosols, optical properties for GLOMAP-MODE aerosols | +| `bound` | `IN` | Boundary conditions at top-of-atmosphere and surface: input fluxes, albedo/emissivity | +| `radout` | `OUT` | All output variables: fluxes and other diagnostics | + +The first seven types are `INTENT(IN)` and `radout` is `INTENT(OUT)`. All variables required or produced by the code are contained within these types. Modules are used only to pass parameters, constants, and type definitions. + +--- + +## Call structure + +The recommended structure for a calling model (such as the Unified Model) is: + +```fortran +CALL read_control ! Sets up control (elements that are not time-step dependent) +CALL read_spectrum ! Sets up spectrum by reading from a standard spectral file + +! --- Begin loop over time-steps / calls to radiation --- + + CALL set_control ! Sets control options for this call + + ! --- Begin loop over OpenMP segments --- + + CALL set_dimen ! Sets dimen for this segment + CALL set_atm ! CALL allocate_atm(atm, dimen), set atm + CALL set_cld ! CALL allocate_cld(cld, dimen), set cld + CALL set_aer ! CALL allocate_aer(aer, dimen), set aer + CALL set_bound ! CALL allocate_bound(bound, dimen), set bound + + CALL radiance_calc(control, dimen, spectrum, atm, cld, aer, bound, radout) + ! --> CALL allocate_out(radout, dimen), calculate radout + ! --> Assign required variables from radout onto the full model grid + + DEALLOCATE(atm, cld, aer, bound, radout) + + ! <-- End loop over OpenMP segments --- + +! <-- End loop over time-steps / calls to radiation --- +``` + +This structure is repeated separately for the SW and LW radiation calls. + +--- + +## Core routines + +The core radiation code provides the following routines and modules: + +**`read_spectrum`** +: A standard routine to read in spectral files, which can then be used interchangeably between models. + +**Type definition modules** (`def_spectrum`, `def_control`, `def_dimen`, `def_atm`, `def_cld`, `def_aer`, `def_bound`, `def_out`) +: Type definitions including associated `allocate` and `deallocate` routines, and netCDF read/write routines in future. + +**`radiance_calc` and called routines** +: The core radiation code itself. + +--- + +## Routines provided by the calling model + +The calling model provides routines to set the input variables: + +**`set_control`, `set_dimen`, `set_atm`, `set_cld`, `set_aer`, `set_bound`** +: These routines USE the type-definition modules from the core code. diff --git a/docs/Explanations/overview.md b/docs/Explanations/overview.md new file mode 100644 index 0000000..be215d1 --- /dev/null +++ b/docs/Explanations/overview.md @@ -0,0 +1,73 @@ +# Physical model description + +!!! note + This overview is based on the SOCRATES technical guide by James Manners, John M. Edwards, Peter Hill & Jean-Claude Thelen (Met Office, 2017), which can be found [here](../Reference/documentation_pdfs.md#technical-guide). It is under Crown Copyright. + +## What is SOCRATES? + +SOCRATES (Suite Of Community RAdiative Transfer codes based on Edwards and Slingo) is a flexible radiative transfer code developed at the Met Office. It computes **radiative fluxes and heating rates** throughout an atmospheric column, and is designed to serve a wide range of applications; from weather prediction to climate modelling and exoplanet atmosphere research. + +The code is structured around two core radiation solvers, supported by spectral files that encode the frequency discretisation and optical property data, and a well-defined interface to any calling model. + +--- + +## Structure of the physical model + +### Radiation solvers + +SOCRATES provides two complementary approaches to solving the radiative transfer equation: + +#### [Two-stream radiation code](two_stream.md) + +The two-stream code is the primary solver for computing broad-band radiative fluxes and heating rates efficiently. It represents the angular dependence of the radiation field with just two streams — an upward and a downward diffuse flux — together with a direct solar beam in the shortwave. The key steps are: + +1. The spectrum is divided into **bands**, each further subdivided into quasi-monochromatic regions using a k-distribution method. +2. Within each region, layer **transmission and reflection coefficients** are derived from the single-scattering properties (optical depth $\tau$, single-scattering albedo $\omega$, asymmetry parameter $g$). +3. A **two-stream approximation** (Eddington, PIFM, discrete ordinates, or hemispheric mean) is selected to close the system. +4. **$\delta$-rescaling** corrects for strong forward scattering. +5. The resulting linear system is solved by an efficient recurrence based on Gaussian elimination. + +The code handles gaseous absorption (including overlapping gases and continua), aerosols, Rayleigh scattering, water droplets, and ice crystals. Cloud overlap is treated via random, maximum-random, or exponential-random schemes, with the Monte Carlo Independent Column Approximation (McICA) available for sub-grid cloud variability. + +#### [Spherical harmonic radiance code](spherical_harmonic.md) + +The spherical harmonic code solves for the full angular radiance field by expanding $I(\mathbf{x}, n)$ in spherical harmonics $Y_l^m(n)$. This provides greater angular resolution than the two-stream approach, at higher computational cost, and is suited to applications requiring accurate radiances (e.g. remote sensing simulations). Key features include: + +- A **complementary function** built from eigensolutions of a symmetric tridiagonal system, with careful numerical stabilisation for conservative scattering and large optical depths. +- **Particular integrals** for thermal emission (linear and quadratic Planckian variation) and the direct solar beam, with regularisation for small optical depths. +- **Marshak boundary conditions** at the top of atmosphere, and a full **BRDF surface boundary condition**, including an ocean surface model with Fresnel reflection, Snell's law refraction, and particulate/absorption parametrisations. +- The **TMS source function technique** [^cite-NT88] to accelerate convergence by separating single and multiple scattering. +- A fast block-recurrence linear solver that reduces the dominant operation count from $O(18N^3 L)$ to $O(6N^3 L)$. + +### [Spectral files](spectral_files.md) + +Both solvers rely on **spectral files**: external, user-supplied files that define the frequency discretisation and store all spectrally dependent optical property data. This includes: + +- Band limits and solar fractions +- k-distribution fits for gaseous absorption +- Rayleigh scattering coefficients +- Planck function polynomial fits +- Parametrisations for cloud droplets, ice crystals, and aerosols + +The separation of spectral data from the radiation code itself makes SOCRATES highly flexible: a spectral file generated for one version of the code remains compatible with future versions, and new gases, aerosols, or parametrisations can be added without modifying the solver. + +### [Interface to the calling model](interface.md) + +SOCRATES is designed to be embedded in any atmospheric model through a clean, well-defined interface. All inputs and outputs are wrapped into eight structured types, `control`, `dimen`, `spectrum`, `atm`, `cld`, `aer`, `bound`, and `radout`, passed to the core routine `radiance_calc`. This design keeps the radiation code self-contained and straightforward to couple to new models. + +--- + +## Choosing a solver + +| | Two-stream | Spherical harmonic | +|---|---|---| +| **Primary output** | Fluxes, heating rates | Radiances | +| **Angular resolution** | Low (2 streams) | High (up to order $L$) | +| **Computational cost** | Low | High | +| **Typical use** | GCMs, NWP, climate runs | Remote sensing, offline studies | +| **Cloud treatment** | Single column or McICA | Single column | +| **Surface BRDF** | Albedo ($\alpha_s$, $\alpha_d$) | Full BRDF expansion | + +For most atmospheric modelling applications the **two-stream code** is the appropriate choice. The **spherical harmonic code** is used where accurate radiance fields are needed. + +[^cite-NT88]: T. Nakajima and M. Tanaka, *Algorithms for radiative intensity calculations in moderately thick atmospheres using a truncation approximation*, J. Quant. Spectrosc. Radiat. Transfer, 40:51–69, 1988. diff --git a/docs/Explanations/spectral_files.md b/docs/Explanations/spectral_files.md new file mode 100644 index 0000000..4539e54 --- /dev/null +++ b/docs/Explanations/spectral_files.md @@ -0,0 +1,113 @@ +# Spectral files + +!!! note + This overview is based on the technical guide by James Manners, John M. Edwards, Peter Hill & Jean-Claude Thelen (Met Office, 2017), which can be found [here](../Reference/documentation_pdfs.md#technical-guide). It is under Crown Copyright. + +## Overview + +Atmospheric radiative transfer spans an enormous range of frequencies, across which gaseous absorption coefficients vary by many orders of magnitude. The approach adopted in SOCRATES, and in general circulation models (GCMs) broadly, is to divide the solar or infra-red spectral region into a number of **bands**, across which all radiative quantities except gaseous absorption coefficients may be treated as uniform. More bands give more accuracy, but at greater computational cost; the appropriate balance depends on the application. + +A key design choice in SOCRATES is that the frequency discretisation is not fixed in the code itself. Instead, it is set by an external file supplied at runtime: the **spectral file**. This separates the physical parametrisation data from the radiation solver, making the code flexible and easy to update. A spectral file generated for one version of SOCRATES remains compatible with future versions (though not necessarily the reverse, as new functionality may add new data blocks). + +--- + +## Role of the spectral file + +The spectral file serves as the single source of truth for all spectrally dependent data used by the radiation code. This includes: + +- The number and limits of spectral bands +- The gaseous absorbers active in each band and their absorption data +- Rayleigh scattering coefficients +- Planck function polynomial fits (longwave only) +- Parametrisations for the single-scattering properties of cloud droplets, ice crystals, and aerosols +- Continuum absorption coefficients + +Because parametrisations that require spectrally dependent data can only be selected if such data are present in the spectral file, **the choice of spectral file determines which physical parametrisations are available** at runtime. Spectral files should therefore be selected with care to match the intended configuration. + +!!! warning + Generating or modifying spectral files requires detailed knowledge of radiative transfer. Standard files are provided for common configurations; users should not modify these unless they have the necessary expertise. + +--- + +## Spectral bands + +The spectral region is divided into bands within which all radiative quantities — except gaseous absorption coefficients — are treated as frequency-independent. The total flux is the sum of partial fluxes over bands (see [Two-stream radiation code](two_stream.md#spectral-integration)). + +In some shortwave spectral files, certain bands share the same wavelength limits. These are **not true spectral bands** — they represent a computational splitting for efficiency, and only the sum of fluxes across such paired bands is physically meaningful. The excluded sub-ranges are specified in block 14 (see below). + +--- + +## Block structure + +The spectral file is organised into numbered **blocks**, each corresponding to a different category of physical data. The flag `l_present(i)` is set to `.TRUE.` if block `i` is present; not all blocks are required for all calculations. + +| Block | Contents | Notes | +|---|---|---| +| 0 | Number and identities of gaseous and aerosol species | Gases indexed by type number from `gas_list_pcf`; aerosols from `rad_pcf` | +| 1 | Spectral band limits (wavelengths in metres) | Some bands may share limits — see split bands below | +| 2 | Fraction of solar spectrum in each band | Shortwave only | +| 3 | Rayleigh scattering coefficients | Shortwave only | +| 4 | List of gaseous absorbers active in each band | First gas listed must be the primary absorber | +| 5 | k-distribution fits to gaseous transmissions | Includes scaling functions or look-up tables | +| 6 | Polynomial fit to the Planck function in each band | Longwave only | +| 7 | *(Obsolete — not present in current files)* | — | +| 8 | List of continuum absorbers in each band | Primarily self- and foreign-broadened water vapour continua | +| 9 | Continuum absorption coefficients | — | +| 10 | Single-scattering parametrisations for cloud droplets | May contain multiple types; valid size range recorded | +| 11 | Aerosol optical properties | Selection varies by file; hygroscopic aerosols include humidity dependence via look-up table | +| 12 | Single-scattering parametrisations for ice crystals | May contain multiple types; valid size range recorded | +| 13 | Heuristic Doppler broadening adjustments | Longwave only; obsolescent — will move to block 5 | +| 14 | Band exclusions (split bands) | Defines sub-ranges excluded from a band's limits | +| 15 | Monochromatic aerosol absorption/scattering coefficients | At specific wavelengths, for aerosol optical depth diagnostics | + +### Gaseous absorption (block 5) + +Gaseous absorption data are stored as **k-distribution** fits. For each active gas in each band, absorption coefficients are either: + +- **Scaled** from a reference value using a pressure- and temperature-dependent scaling function (two functional forms are supported; see [Two-stream radiation code](two_stream.md#gaseous-absorption)), or +- **Interpolated** directly from a look-up table of coefficients at a grid of pressures and temperatures — now the preferred approach. + +The first gas listed in block 4 for each band is the **primary absorber**; minor gases may be treated via the equivalent extinction approximation rather than full random overlap. + +### Cloud and ice parametrisations (blocks 10 and 12) + +Blocks 10 and 12 may contain data for **multiple types** of droplet or ice crystal parametrisation within a single file. The term *type* is deliberately flexible — different types may represent: + +- Different assumed size distributions +- Different spectral averaging methods (thin or thick averaging) +- Different crystal shapes (for ice) +- Different fitting functions (linear, Padé approximants, polynomial) + +Type numbers are supplied at runtime and must be chosen to match the spectral file in use. The minimum and maximum particle sizes for which each parametrisation is valid are recorded alongside the coefficients. + +### Split bands (block 14) + +In some files, a band's wavelength limits in block 1 encompass a wider range than is actually used, with a sub-range **excluded** by listing it in block 14. For example, if band 5 spans 8–12 µm but band 6 spans 10–11 µm and is excluded from band 5, then band 5 effectively covers 8–10 µm and 11–12 µm. Split bands are used purely for computational efficiency and are transparent to the solver. + +--- + +## Naming conventions + +Although not formally required, a consistent naming convention is used for standard files: + +| Prefix | Format | Description | +|---|---|---| +| `sp_sw_` | Text | Shortwave file, UM version ≥ 8.6 or offline code | +| `sp_lw_` | Text | Longwave file, UM version ≥ 8.6 or offline code | +| `spec3a_sw_` | Namelist | Shortwave file, UM version ≤ 8.5 | +| `spec3a_lw_` | Namelist | Longwave file, UM version ≤ 8.5 | + +When new functionality is added to a file without changing existing results, the **filename is unchanged**. When existing data are modified (changing results), a **new filename** is introduced so that older configurations remain reproducible. + +Two utility programs handle format conversion between namelist and text formats: `nml_spec` (text → namelist) and `spec_nml` (namelist → text). + +--- + +## Generating and modifying spectral files + +Spectral files are generated using the **pre-processing suite** of the offline Edwards–Slingo radiation code. Generation requires expertise in radiative transfer — most users will use standard provided files and should not modify them. + +When a new requirement arises (e.g. adding a new absorbing gas, updating continuum data, or incorporating a new aerosol type), users should contact the radiation group rather than modifying files independently. Aerosol optical property data in particular are generated in consultation with aerosol modelling specialists. + +!!! note + Standard spectral files for common configurations are provided in the SOCRATES repository. A reference description of these files is given in the [reference section](../Reference/spectral_file_reference.md). diff --git a/docs/Explanations/spherical_harmonic.md b/docs/Explanations/spherical_harmonic.md new file mode 100644 index 0000000..d4ea78f --- /dev/null +++ b/docs/Explanations/spherical_harmonic.md @@ -0,0 +1,283 @@ +# Spherical harmonic radiance code + +!!! note + This overview is based on the technical guide by James Manners, John M. Edwards, Peter Hill & Jean-Claude Thelen (Met Office, 2017), which can be found [here](../Reference/documentation_pdfs.md#technical-guide). It is under Crown Copyright. + +## Overview + +The spherical harmonic radiance code solves the monochromatic radiative transfer equation for **radiances** rather than integrated fluxes, expanding the angular dependence of the radiation field in spherical harmonics. This provides greater angular resolution than the two-stream approach, at higher computational cost, and is particularly suited to applications requiring accurate radiance fields (e.g. remote sensing simulations). + +The monochromatic equation of transfer is: + +$$(n \cdot \nabla) I(\mathbf{x}, n) = -(k^{(s)} + k^{(a)}) I(\mathbf{x}, n) + \frac{k^{(s)}}{4\pi} \int_\Omega I(\mathbf{x}, n') P(n', n)\, d\omega_{n'} + j(\mathbf{x}, n)$$ + +where $I$ is the radiance, $k^{(s)}$ and $k^{(a)}$ are the scattering and absorption coefficients, $P(n', n)$ is the phase function, and $j$ is the emission source term. + +The phase function is expanded in Legendre polynomials: + +$$P(n', n) = \sum_{l=0}^\infty (2l+1) g_l P_l(n' \cdot n)$$ + +and may be $\delta$-rescaled using the standard prescription $k^{(s)} \to (1-f)k^{(s)}$ before further treatment. + +--- + +## Fundamentals of solving for radiances + +Assuming a **plane-parallel atmosphere**, the radiance field is expanded in spherical harmonics $Y_l^m(n)$: + +$$I(\mathbf{x}, n) = \sum_{l=0}^\infty \sum_{m=-l}^{l} I_{lm}(\mathbf{x}) Y_l^m(n) + I_\odot \delta(n' - n_\odot)$$ + +where the direct solar beam $I_\odot$ is kept separate. Using the orthogonality of the $Y_l^m$ and introducing optical depth $\tau$ and single-scattering albedo $\omega = k^{(s)} / (k^{(s)} + k^{(a)})$, the equation of transfer reduces to a coupled system: + +$$c^+_{l-1,m} \frac{dI_{l-1,m}}{d\tau} + c^-_{l+1,m} \frac{dI_{l+1,m}}{d\tau} = s_l I_{lm}(\tau) - s_0 \sqrt{4\pi} B(\tau) \delta_{l0}\delta_{m0} - \omega g_l Y_l^{m*}(n_\odot) I_\odot(\tau)$$ + +where $s_l = 1 - \omega g_l$ and the Clebsch–Gordan coefficients are: + +$$c^+_{lm} = \sqrt{\frac{(l+1-m)(l+1+m)}{(2l+1)(2l+3)}}, \qquad c^-_{lm} = \sqrt{\frac{(l-m)(l+m)}{(2l-1)(2l+1)}}$$ + +The atmosphere is divided into $N$ homogeneous layers with optical thicknesses $\tau_i$, $i = 1, \ldots, N$. The full solution in each layer is the sum of a **complementary function** and a **particular integral**. + +--- + +## The complementary function + +The complementary function consists of exponentials $H_{lm}(\mu) e^{\tau/\mu}$ for $\mu \in \mathbb{R}$. For fixed azimuthal order $m$, the permissible values of $\mu$ are defined by an eigenvalue problem. Truncating the spherical harmonic expansion at odd order $L$, the recurrence relations: + +$$c^-_{m+1,m} H_{m+1,m} = s_m \mu H_{mm}$$ + +$$c^+_{l-1,m} H_{l-1,m} + c^-_{l+1,m} H_{l+1,m} = s_l \mu H_{lm}, \quad m < l < L'$$ + +$$c^+_{L'-1,m} H_{L'-1,m} = s_{L'} \mu H_{L'm}$$ + +where $L' = L$ if $m$ is even and $L' = L+1$ if $m$ is odd. Defining $K_{lm} = \sqrt{s_l} H_{lm}$, this becomes a symmetric tridiagonal eigenvalue problem: + +$$\sum_l C_{ql} K_{lm} = \mu K_{lm}$$ + +with non-zero entries $C_{l-1,l} = c^+_{l-1,m}/\sqrt{s_l s_{l-1}}$. + +**Numerical stability:** For $|\mu| > 1$ the recurrence has growing solutions triggered by rounding errors. The recurrence is therefore always applied in the direction of **decreasing** $l$. When scattering is nearly conservative, intermediate terms can overflow; the recurrence is recast in $H'_{lm} = \sigma^{-l} H_{lm}$ where $\sigma = 1/\max(1, 2\mu^{-1})$ to prevent this. + +**Halving the eigenproblem:** Since eigenvalues come in $\pm\mu_k$ pairs, the even and odd components of the eigenvector decouple, halving the size of the matrix to be diagonalised. The eigenvalues of the reduced matrix have diagonal elements $d_j = E^2_{2j-1} + E^2_{2j}$ and sub-diagonal elements $e_j = E_{2j-2} E_{2j-1}$. + +The complementary function in the $i$-th layer is written using only negative exponentials to avoid overflow: + +$$I_{lm}(\tau) = \sum_k H^-_{lmk} e^{-\tau/\mu_k} + \sum_k H^+_{lmk} e^{-(\tau_i - \tau)/\mu_k}$$ + +**Conservative scattering** ($\omega \to 1$) causes the matrix $C$ to become singular for $m = 0$. This is handled by artificially reducing $\omega$ slightly to avoid ill-conditioning. + +--- + +## Particular integrals + +### Thermal radiation + +In the infra-red, the equation of transfer is reformulated in terms of **differential radiances** $I' = I - B$. For a Planckian source varying **linearly** across a layer: + +$$I_{i,10} = \frac{1}{s_{1i}} \sqrt{\frac{4\pi}{3}} \frac{\Delta B_i}{\tau_i}$$ + +with $I_{i,lm} = 0$ otherwise, where $\Delta B_i$ is the difference in the Planck function across layer $i$. + +For **quadratic** variation of the Planckian: + +$$I_{i,10} = \frac{1}{s_{1i}} \sqrt{\frac{4\pi}{3}} \frac{\Delta B_i}{\tau_i} - \frac{2}{s_{1i}} \sqrt{\frac{4\pi}{3}} \frac{\Delta^2 B_i}{\tau_i^2} \tau$$ + +$$I_{i,00} = -\frac{2 c^-_{1,0}}{s_{0i} s_{1i}} \sqrt{\frac{4\pi}{3}} \frac{\Delta^2 B_i}{\tau_i^2}, \qquad I_{i,20} = -\frac{2 c^+_{1,0}}{s_{2i} s_{1i}} \sqrt{\frac{4\pi}{3}} \frac{\Delta^2 B_i}{\tau_i^2}$$ + +**Small optical depths** cause ill-conditioning. This is resolved by adding to the particular integral a solution of the homogeneous system that exhibits the same singularity as $\tau \to 0$: + +$$I_{l0} = q_0 s_1 \sum_k V_{kl} V_{k1} \left\{ (-1)^l e^{-\tau/\mu_k} - e^{-(\tau_i - \tau)/\mu_k} \right\}$$ + +where $V_{kl} = K_{klm}/\sqrt{s_l}$ and the coefficients $u^\pm_k = \mp q_0 s_1 V_{k1}$ are determined by matching the singularity structure. + +### Solar particular integral + +Using the convention $\mu_0 = -\cos\theta_\odot$, the direct solar beam in layer $i$ is: + +$$I_{\odot i}(\tau) = I_\odot(\Delta_{i-1}) e^{-\tau/\mu_0}$$ + +A particular integral of the form $I_{ilm}(\tau) = Z_{ilm} e^{-\tau/\mu_0}$ is sought, giving the recurrence: + +$$c^+_{l-1,m} Z_{i,l-1,m} + c^-_{l+1,m} Z_{i,l+1,m} = -\mu_0 s_{li} Z_{ilm} + \mu_0 I_\odot(\Delta_{i-1}) \omega_i g_{li} Y_l^{m*}(n_\odot)$$ + +with solution: + +$$Z_{ilm} = -I_\odot(\Delta_{i-1}) Y_l^{m*}(n_\odot) + \gamma V_{ilm}(\mu_0)$$ + +where $\gamma = I_\odot(\Delta_{i-1}) Y_{L'+1}^{m*}(n_\odot) / V_{i,L'+1,m}(\mu_0)$ enforces the truncation condition, and $V(\mu_0)$ satisfies the associated homogeneous recurrence. + +**Ill-conditioning** arises when $\mu_0$ approaches an eigenvalue $\mu_k$. This is removed by subtracting a weighted multiple of the corresponding eigensolution, applied smoothly via a weighting that depends on the separation $|\mu_0 - \mu_k|$ rather than an if-test. + +--- + +## Boundary conditions + +### Interior boundaries + +Continuity of the radiance field at each interior level requires: + +$$I_{i,lm}(\tau_i) = I_{i+1,lm}(0), \quad 1 \leq i \leq N, \quad \forall\, l, m$$ + +### Upper boundary + +At the top of the atmosphere, the downward radiance is specified as $I(n) = I^{(0)}(n)$ for $n \in \Omega^-$. Since the full boundary condition cannot be imposed in a truncated system, **Marshak's conditions** [^cite-Marshak] are used — the inner product of the residual with odd-parity harmonics is set to zero: + +$$\sum_l \kappa_{ll'm} (I_{lm} - I^{(0)}_{lm}) = 0$$ + +where: + +$$\kappa_{ll'm} = \int_{\Omega^-} Y_l^m(n) Y_l^{m*}(n)\, d\omega_n$$ + +For $l + l'$ even, $\kappa_{ll'm} = \frac{1}{2} \delta_{ll'}$. For $l + l'$ odd, $\kappa_{ll'm}$ is evaluated analytically using associated Legendre polynomial identities: + +$$\Upsilon^m_l(0) = -\sqrt{\frac{2l+1}{2l-3} \cdot \frac{l+m-1}{l+m} \cdot \frac{l-m-1}{l-m}}\, \Upsilon^m_{l-2}(0)$$ + +### Surface boundary conditions + +The surface is characterised by a **bidirectional reflectance distribution function (BRDF)** $\gamma_r(n, n')$, so that: + +$$I(n) = \int_{\Omega^-} \gamma_r(n, n') I(n') (n' \cdot {-\hat{e}_z})\, d\omega_{n'}, \quad n \in \Omega^+$$ + +For a Lambertian surface, $\gamma_r = \alpha/\pi$ where $\alpha$ is the albedo. + +The BRDF is expanded in a double spherical harmonic series: + +$$\gamma_r(n, n') = \sum_{l,m} \sum_{l',m'} \Gamma_{lml'm'} Y_l^m(n) Y_l^{m'*}(n')$$ + +Imposing rotational symmetry, reflectional symmetry, reciprocity ($\gamma_r(n,n') = \gamma_r(n',n)$), and the reality of $\gamma_r$ reduces the coefficients to real, symmetric quantities $\Psi_{ll'm}$ with $\Psi_{ll'-m} = \Psi_{ll'm}$. + +The full surface boundary condition including thermal emission is: + +$$I(n) = \int_{\Omega^-} \gamma_r(n, n') \left[ I(n') + I_\odot \delta(n' - n_\odot) - B^* \right] (n' \cdot {-\hat{e}_z})\, d\omega_{n'} + B^*$$ + +where $B^*$ is the isotropic Planckian radiance at the surface temperature, arising from Kirchhoff's law. + +After applying Marshak's procedure and expanding, the boundary condition becomes: + +$$\sum_\lambda I_{\lambda M} \left[ (-1)^\lambda \kappa_{L\lambda M} + \sum_j \rho_j \Phi_{jL\lambda M} \right] = I_\odot \mu_\odot \sum_j \rho_j \sum_{l'} Y_L^{M*}(n_\odot) \Xi_{jLl'M} + B^* \delta_{0M} \left[ \sqrt{4\pi} \kappa_{L00} + \sum_j \rho_j \Lambda_{jL} \right]$$ + +where $\Xi$, $\Phi$, and $\Lambda$ are precomputed geometric coupling matrices that depend only on the BRDF expansion coefficients $\rho_j$ and the $\kappa_{ll'm}$ integrals. + +#### The BRDF of the ocean surface + +The ocean surface BRDF is not available from a single direct reference [^cite-Mobley94]. The radiance code itself is used to compute the radiance within the ocean, with special upper boundary conditions to handle refraction. Key optical properties: + +**Rayleigh scattering in water:** + +$$k^{(s)}_w(\lambda) = K_R (\lambda_0/\lambda)^{4.32}$$ + +where $\lambda_0 = 550\,\text{nm}$, $K_R = 0.93$ (pure water) or $1.21$ (sea water). + +**Particulate scattering** [^cite-Petzold72] is related to chlorophyll concentration $C$ (mg m$^{-3}$): + +$$k^{(s)}_P = \left(\frac{550}{\lambda[\text{nm}]}\right)^{0.3} C^{0.62}$$ + +**Absorption** [^cite-Morel91] [^cite-PS81]: + +$$k^{(a)} = \left( k^{(a)}_w(\lambda) + 0.66\, a^{*\prime}_c(\lambda)\, C^{0.65} \right) \left[ 1 + 0.2 \exp(-0.014(\lambda[\text{nm}] - 440)) \right]$$ + +**Refraction at the surface** follows Snell's law ($\sin\theta_i = n\sin\theta_t$, $n \approx 1.34$), with the Fresnel reflection coefficient for unpolarised light: + +$$r_{aw} = \frac{1}{2} \left[ \left(\frac{\sin(\theta_i - \theta_t)}{\sin(\theta_i + \theta_t)}\right)^2 + \left(\frac{\tan(\theta_i - \theta_t)}{\tan(\theta_i + \theta_t)}\right)^2 \right]$$ + +Total internal reflection occurs for upward rays beyond the critical angle ($r_{wa} = 1$). The boundary condition in the ocean is: + +$$I(n) = r_{wa} I(n_r) + (1 - r_{aw}) n^2 I_a(n_a), \quad n \in \Omega^-$$ + +--- + +## Numerical implementation + +Since $I \in \mathbb{R}$, coefficients satisfy $I_{l,-m} = (-1)^m I_{lm}^*$, so only $m \geq 0$ need be stored. The complex $e^{im\phi}$ dependence factors out as $I_{lm} = C_{lm} e^{-im\phi_\odot}$, and the full radiance field reduces to: + +$$I_{lm} Y_l^m + I_{l,-m} Y_l^{-m} = 2 C_{lm} \Upsilon^m_l \cos m(\phi - \phi_\odot)$$ + +reducing storage requirements by roughly a factor of two compared to a naive complex implementation. + +--- + +## Increasing the speed of computation + +### The source function (TMS) technique + +Computing radiances by spherical harmonics alone converges slowly because high orders are needed to represent singly scattered radiation. The **TMS method** [^cite-NT88] separates single and multiple scattering: the full (unrescaled) phase function is used for single scattering, while the rescaled truncated phase function handles multiple scattering. + +The diffuse radiance equation under rescaling becomes: + +$$\mu \frac{dI}{d\hat{\tau}} = I - \frac{\hat{\omega}}{4\pi} \int_\Omega \hat{I}_T \hat{P}\, d\omega'_n - \frac{\hat{\omega}}{4\pi(1-f)} \int_\Omega I_\odot P\, d\omega'_n$$ + +The algorithm proceeds as follows: + +1. Solve the rescaled, truncated equation using spherical harmonics to obtain $\hat{I}_T$ and $\hat{I}_\odot$. +2. Integrate along a ray using $\hat{I}_T$ as the source function for multiply scattered radiation. +3. Compute the unrescaled single-scattering contribution from the true solar beam $I_\odot$ separately. + +The final integration along a ray between optical depths $\hat{\Delta}^-$ and $\hat{\Delta}^+$ gives: + +$$I(n, \hat{\Delta}^+) = I(n, \hat{\Delta}^-) e^{(\hat{\Delta}^+/\mu - \hat{\Delta}^-/\mu)} + \sum_{i \in \mathcal{I}} \sum_{(l,m) \in T} \hat{\omega}_i \hat{g}_{li} Y_l^m(n) A_{ilm} + \sum_{i \in \mathcal{I}} \sum_{l \in F_L} \frac{2l+1}{4\pi} \hat{\omega}_i \hat{g}_{li} P_l(n_\odot \cdot n) B_i$$ + +where $A_{ilm}$ and $B_i$ are layer contributions evaluated by integrating exponential terms analytically. + +### Ill-conditioning near eigenvalue crossings + +When $\mu \to \tilde{\mu}$ (an eigenvalue or $\mu_0$), geometric factors of the form $\tilde{\mu}/(\tilde{\mu} - \mu)$ become ill-conditioned. This is regularised using a perturbation $\eta$: + +$$\eta = \frac{\varepsilon}{(\tilde{\mu} - \mu) + \text{sgn}(\tilde{\mu} - \mu)\sqrt{\varepsilon}}$$ + +where $\varepsilon$ is machine epsilon, so that: + +$$G \approx \tilde{\mu} \left(1 - \frac{\eta\hat{\tau}}{\mu\tilde{\mu}}\right) \frac{e^{-s_n + \hat{\tau}/\tilde{\mu}} - e^{-s_f}}{\tilde{\mu} - \mu + \eta}$$ + +This introduces errors of $O(\sqrt{\varepsilon})$ only in a neighbourhood of the singularity. + +--- + +## Fast solution of the linear equations + +A more efficient algorithm for the core linear system — not yet fully implemented — reduces the dominant operation count from $O(18N^3 L)$ (banded solver with partial pivoting) to $O(6N^3 L)$. + +### Block structure + +For fixed azimuthal order $m$, retaining $2N$ polar orders, the amplitudes at the top and bottom of each layer are assembled into a block matrix system. Collecting alternate (even/odd) eigenvector components as $W_{sk}$ and $U_{sk}$ respectively, the orthogonality relations give: + +$$\sum_s \rho_s W_{sk} W_{sk'} = \delta_{kk'}, \qquad \sum_s \sigma_s U_{sk} U_{sk'} = \delta_{kk'}$$ + +Marshak's condition at the top boundary becomes a block equation involving the matrix $M_{sp} = \tilde{M}_{2s+1-m,\, 2p-m}$. + +### Forward recurrence + +After block Gaussian elimination, the system reduces to a recurrence of the form: + +$$Z_n = C_n - D_n X_{n-1}$$ + +$$Y_n = (Z_n^{-1} - A_n)^{-1}$$ + +$$X_n = -Y_n B_n$$ + +where the matrices $A_n$, $B_n$, $C_n$, $D_n$ are related to the eigenvector blocks and layer transmission factors $\theta_k = e^{-\bar{\tau}/\mu_k}$. + +Key simplifications arise from the relations $R = P^{-1}$, $S = Q^{-1}$, and: + +$$P = \text{diag}(\mu_{11}^{-1}, \ldots, \mu_{N1}^{-1})\, S^T\, \text{diag}(\mu_{12}, \ldots, \mu_{N2})$$ + +which reduce the cost of computing $P$ and $R$ from $O(4N^3)$ to $O(4N^2)$ multiplications. + +### Back substitution + +After forward elimination, back substitution proceeds as: + +$$u^+_n = x_n - A_n u^-_{n+1} - B_n u^+_{n+1}$$ + +$$u^-_n = z_n - X_n x_n$$ + +Only matrices $A$, $B$, $X$ need be retained at each level, reducing memory by a factor of three relative to the banded solver. + +--- + +[^cite-Marshak]: R. E. Marshak, *Note on the spherical harmonic method as applied to the Milne problem for a sphere*, Phys. Rev., 71:443–446, 1947. +[^cite-Mobley94]: C. D. Mobley, *Light and Water*, Academic Press, first edition, 1994. +[^cite-Petzold72]: T. J. Petzold, *Volume scattering functions for selected ocean waters*, Technical Report SIO Ref. 72-78, Scripps Institution of Oceanography, La Jolla, 1972. +[^cite-Morel91]: A. Morel, *Light and marine photosynthesis: a spectral model with geochemical and climatological implications*, Prog. Oceanogr., 26:263, 1991. +[^cite-PS81]: L. Prieur and S. Sathyendranath, *An optical classification of coastal and oceanic waters based on the specific spectral absorption curves of phytoplankton pigments, dissolved organic matter, and other particulate materials*, Limnol. Oceanogr., 26(4):671–689, 1981. +[^cite-NT88]: T. Nakajima and M. Tanaka, *Algorithms for radiative intensity calculations in moderately thick atmospheres using a truncation approximation*, J. Quant. Spectrosc. Radiat. Transfer, 40:51–69, 1988. +[^cite-Roujean92]: J.-L. Roujean, M. Leroy, and P.-Y. Deschamps, *A bidirectional reflectance model of the Earth's surface for the correction of remote sensing data*, J. Geophys. Res., 97:20455–20468, 1992. +[^cite-Benassi84]: M. Benassi, R. D. M. Garcia, A. H. Karp, and C. E. Siewert, *A high-order spherical harmonics solution to the standard problem in radiative transfer*, Astrophys. J., 280:853–864, 1984. diff --git a/docs/Explanations/two_stream.md b/docs/Explanations/two_stream.md new file mode 100644 index 0000000..8656a7d --- /dev/null +++ b/docs/Explanations/two_stream.md @@ -0,0 +1,309 @@ +# Two-stream radiation code + +!!! note + This overview is adapted from the technical guide by James Manners, John M. Edwards, Peter Hill & Jean-Claude Thelen (Met Office, 2017), which can be found [here](../Reference/documentation_pdfs.md#technical-guide). It is under Crown Copyright. + +## Overview + +The two-stream radiation code computes radiative fluxes throughout an atmospheric column, from which heating rates and related diagnostics are derived. The approach proceeds as follows: + +1. The spectral region is divided into bands, each handled by a **spectral file** that encodes parametrizations and discretisation data. +2. Each band is subdivided into quasi-monochromatic regions, within which gaseous absorption coefficients are treated as fixed. +3. A **two-stream approximation** is applied in each quasi-monochromatic region, representing the radiance field with an upward diffuse flux, a downward diffuse flux, and (in the shortwave) a direct solar flux. +4. Partial fluxes are assembled into broad-band totals via weighted sums. + +The spectral file is external and user-supplied, making the frequency discretisation flexible and decoupled from the radiation code itself. A spectral file generated for one version of the code remains compatible with future versions. + +--- + +## Spectral integration + +Let $F$ denote any flux (direct, diffuse, or net). The total flux is the sum over spectral bands: + +$$F = \sum_j F_j^{(b)}$$ + +The flux in band $j$ is a weighted sum over quasi-monochromatic regions indexed $k$: + +$$F_j^{(b)} = \sum_k w_k F_k^{(qm)}$$ + +where $w_k$ is the weight of the $k$-th region and $F_k^{(qm)}$ is the flux calculated for that region. The number of quasi-monochromatic calculations and their weights are determined by the **overlap treatment** for gaseous absorption and the data in the spectral file. + +--- + +## Monochromatic flux calculation + +The atmosphere is divided into **N homogeneous layers**, numbered 1 to N from the top. Boundaries (levels) are numbered 0 to N. The primary variables are: + +| Region | Variables | +|---|---| +| Solar (shortwave) | Upward flux $U$, total downward flux $V$, direct solar flux $Z$ | +| Infra-red (longwave) | Upward and downward **differential** fluxes (actual flux minus $\pi B$), denoted $U$ and $V$ | + +The net flux is $N = V - U$. Fluxes in a homogeneous-layer column obey the recurrence: + +$$U_{i-1} = T_i U_i + R_i V_{i-1} + S_i^+$$ + +$$V_i = T_i V_{i-1} + R_i U_i + S_i^-$$ + +$$Z_i = T_{0i} Z_{i-1}$$ + +where $T$, $R$, and $T_0$ are the diffuse transmission, diffuse reflection, and direct transmission coefficients respectively. + +**Boundary conditions:** + +- *Top of atmosphere (solar):* $V_0 = Z_0 = \Phi_0 / \chi_0$, where $\Phi_0$ is the solar irradiance and $\chi_0$ is the secant of the solar zenith angle. +- *Top of atmosphere (IR):* $V_0 = 0$. +- *Surface (solar):* $U_N = \alpha_s Z_N + \alpha_d (V_N - Z_N)$, where $\alpha_s$ and $\alpha_d$ are the direct and diffuse surface albedos. +- *Surface (IR):* $U_N = \alpha_d V_N + \varepsilon^* \pi B^*$, where $\varepsilon^*$ is surface emissivity and $B^*$ is the Planckian function at the surface temperature. + +**Source terms** $S^\pm$ arise from: + +- *Solar:* Scattering of the direct beam into diffuse radiation. +- *IR:* Variations in the Planckian source function across the layer (linear or quadratic in the Unified Model to suppress grid-scale waves). + +The Planckian function is fitted by a polynomial in temperature: + +$$B = \sum_{k=0}^n \beta_k (\theta / \theta_R)^k$$ + +--- + +## Flux calculation: transmission and reflection coefficients + +For a single layer (subscript $i$ dropped), the fundamental single-scattering properties are the **optical depth** $\tau$, **single-scattering albedo** $\omega$, and **asymmetry parameter** $g$. + +These determine intermediate quantities $s$ and $d$ (see [Two-Stream Approximations](#two-stream-approximations) below), from which the layer coefficients are derived: + +$$\lambda = \sqrt{sd}, \quad p = e^{-\lambda\tau}, \quad \Gamma = \frac{s - \lambda}{s + \lambda}$$ + +$$T = \frac{p(1 - \Gamma^2)}{1 - p^2\Gamma^2}, \quad R = \Gamma(1 - p^2) / (1 - p^2\Gamma^2)$$ + +Numerical care is required as these expressions become **indeterminate as $\tau \to 0$**: a small tolerance (square root of machine precision) is added to relevant terms, and asymptotic forms are used where appropriate. + +--- + +## Two-stream approximations + +The two-stream equations express diffuse fluxes $F^\pm$ in terms of two parameters $s$ and $d$ (where $s = \alpha_1 + \alpha_2$, $d = \alpha_1 - \alpha_2$). Several approximations are available: + +| Approximation | $s$ | $d$ | +|---|---|---| +| **Eddington** | $\tfrac{3}{2}(1 - \omega g)$ | $2(1 - \omega)$ | +| **PIFM85** [^cite-ZK85] | $D - \tfrac{3}{2}\omega g$ | $D(1 - \omega)$, $D = 2$ (or $1.66$ in IR) | +| **Zdunkowski et al. 1980** [^cite-ZWK80] | $2 - \tfrac{3}{2}\omega g - \tfrac{1}{2}\omega$ | $2(1 - \omega)$ | +| **Discrete ordinates** | $\sqrt{3}(1 - \omega g)$ | $\sqrt{3}(1 - \omega)$ | +| **Hemispheric mean** | $2(1 - \omega g)$ | $2(1 - \omega)$ | + +--- + +## Delta-rescaling of single scattering properties + +The crude angular representation in the two-stream equations introduces errors for strongly forward-scattering particles. The **$\delta$-rescaling** [^cite-JWW76] corrects this. A forward-scattering fraction $f = g^2$ is defined and the properties are transformed: + +$$\tau \to \tau(1 - \omega f)$$ + +$$\omega \to \frac{\omega(1 - f)}{1 - \omega f}$$ + +$$g \to \frac{g - f}{1 - f}$$ + +--- + +## Single scattering properties by process + +When multiple optical processes are active, their mass extinction and scattering coefficients are combined additively, with the asymmetry weighted by scattering coefficients: + +$$k^{(e)} = \sum_j k_j^{(e)}, \quad k^{(s)} = \sum_j k_j^{(s)}, \quad g = \sum_j k_j^{(s)} g_j \Big/ \sum_j k_j^{(s)}$$ + +The optical depth and single-scattering albedo for a layer follow from: + +$$\tau = k^{(e)} \Delta m, \quad \omega = k^{(s)} / k^{(e)}$$ + +where $\Delta m$ is the column mass. + +### Gaseous absorption + +For $M$ active gases in a band, the total gaseous mass extinction is: + +$$k^{(e,g)} = \sum_j K_j^{(g)} q_j f_j(p, \theta)$$ + +where $K_j^{(g)}$ is a reference mass extinction coefficient, $q_j$ is the mixing ratio, and $f_j$ is a scaling function accounting for pressure and temperature variations. + +**Scaling functions**: two forms are supported. The preferred form is: + +$$f = \left(\frac{p + \Delta}{p_0 + \Delta}\right)^\alpha \left[1 + A\left(\frac{\theta - \theta_0}{\theta_0}\right) + B\left(\frac{\theta - \theta_0}{\theta_0}\right)^2\right]$$ + +where $\alpha$, $\Delta$, $A$, $B$ are fitted parameters ($\Delta$ represents Doppler broadening). Alternatively, coefficients may be interpolated directly from a **look-up table** in the spectral file (now the preferred method). + +### Self-broadening of gases + +When a gas has a volume mixing ratio close to unity, **self-broadening** from same-species collisions becomes important. The gas fraction (volume mixing ratio) is derived from mass mixing ratios, accounting for whether water vapour is included in the total density. + +### Continuum absorption + +Discrepancies far from line centres are represented by a **smoothly varying continuum**. The main continua are the **self-broadened** and **foreign-broadened** continua of water vapour: + +$$k^{(e,c)} = K_f^{(c)} q_w f_f n_{b,f} + K_s^{(c)} q_w f_s n_{b,s}$$ + +where $q_w$ is the water vapour mixing ratio, $n_b$ is the molar density of the broadening species, and subscripts $f$ and $s$ denote foreign and self-broadened components. The implementation is based on the **CKD continuum model** [^cite-CKD89]. A more general continuum parametrisation also supports **collision-induced absorption (CIA)**. + +### Aerosols + +For each aerosol species in each band, extinctions are proportional to mass mixing ratio: + +$$k^{(e,a)} = \sum_j K_j^{(e,a)} q_j, \quad k^{(s,a)} = \sum_j K_j^{(s,a)} q_j, \quad g^{(a)} = \sum_j K_j^{(s,a)} q_j g_j \Big/ k^{(s,a)}$$ + +There is no representation of size-distribution variation within the model. The **humidity dependence** of hygroscopic aerosol optical properties is handled via a look-up table in the spectral file. + +### Rayleigh scattering + +Represented by adding a **band-constant value** to the scattering and total extinctions. The asymmetry parameter for Rayleigh scattering is zero. + +### Water droplets + +Droplet properties depend on both mass mixing ratio $L$ and **effective radius** $r_e$. Three parametrisation forms are available: + +**Slingo & Schrecker (1982)** [^cite-SS82]: + +$$k^{(e)} = L(a + b/r_e), \quad k^{(s)} = k^{(e)}(1 - c - dr_e), \quad g = e + fr_e$$ + +**Ackerman & Stephens / Hu & Stamnes** [^cite-AS87] [^cite-HS93]: + +$$k^{(e)} = L(a_1 r_e^{b_2} + c_1), \quad \ldots$$ + +*(More flexible but computationally expensive due to exponentials; rarely used in practice.)* + +**Padé approximants** (recommended for wide size ranges): + +$$k^{(e)} = L \cdot \frac{p_1 + p_2 r_e + p_3 r_e^2}{1 + p_4 r_e + p_5 r_e^2 + p_6 r_e^3}, \quad \ldots$$ + +### Ice crystals + +Ice crystal parametrisation is more complex due to **irregular crystal shapes**. Several schemes are available: + +| Scheme | Size Measure | Notes | +|---|---|---| +| Slingo & Schrecker analogy [^cite-SS82] | Effective radius $r_e$ | Simplest; used in HadAM3 | +| Modified anomalous diffraction [^cite-M96] | Mean max dimension $\bar{D}_l$ | Two quartic polynomials for small/large ranges | +| Fu (1996) / Fu et al. (1998) [^cite-Fu96] [^cite-Fu98] | Effective dimension $D_e$ | Proportional to volume/projected-area ratio | +| Baran et al. (2013) [^cite-B13] | Ice water content + temperature | Linked directly to GCM prognostic variables | +| Baran et al. (2014) [^cite-B14] | Ice water content only | No intermediate size variable | + +The spectral file may contain data for multiple ice crystal types, selectable at runtime. + +--- + +## Overlapping gaseous absorption + +When multiple gases absorb in a band, their spectral lines may overlap. Full **random overlap** treatment is available but expensive. Faster approximations are provided: + +### Equivalent extinction + +An extension of the FESFT method [^cite-RG92]. For minor gases, a single band-representative extinction coefficient is derived from a subsidiary calculation: + +$$\bar{K} = \frac{\sum_r w_r K_r N_r}{\sum_r w_r N_r}$$ + +where $N_r$ is the net flux for the $r$-th k-term and $w_r$ is the corresponding weight. Variants using the **modulus of layer incident fluxes** are available for improved accuracy near temperature inversions. + +In the solar region, minor gas direct transmissions are multiplicative and computed exactly; diffuse flux corrections use a grey equivalent extinction weighted by direct surface fluxes. + +--- + +## Treatment of clouds + +### Single column approach + +A fractional cloud cover $W_i$ may be specified within each layer $i$, divided into $N_T$ types (stratiform water, stratiform ice, convective water, convective ice). Clouds are treated as **plane-parallel** with no three-dimensional effects. + +The vertical overlapping of clouds is handled by coupling coefficients $u_{i,j,k}$ and $v_{i,j,k}$ that transfer fluxes between regions at layer boundaries, following a generalisation of Geleyn & Hollingsworth (1979) [^cite-GH79]. + +Layers are decomposed into **regions** (clear, stratiform cloud, convective cloud), and fluxes within each region are assumed horizontally uniform. + +### Cloud overlap schemes + +Three assumptions are supported for computing the overlap area $Y_{i,j,k}$: + +| Scheme | Description | +|---|---| +| **Random overlap** | $Y_{i,j,k} = X_{i,j} X_{i+1,k}$ | +| **Maximum-random overlap** | Similar regions are maximally overlapped; dissimilar ones randomly overlapped | +| **Exponential-random overlap** [^cite-HI00] | Combines random and maximum-random linearly via overlap coefficient $\alpha = \exp(-\delta p / p_0)$, where $\delta p$ is layer separation and $p_0$ is the decorrelation length | + +Sub-grid scale cloud water content variability can be included by multiplying cloud water content by a **scaling factor**. + +### Monte Carlo Independent Column Approximation (McICA) + +McICA [^cite-P03] efficiently represents sub-grid cloud variability by sampling a different randomly chosen sub-column for each spectral integration point. Properties: + +- Each sub-column layer is either overcast or cloud-free (no partial cloud). +- The resulting radiative profile is **unbiased** relative to a full ICA calculation but introduces **noise**. +- Sub-columns are generated by a stochastic cloud generator [^cite-R04] using a **gamma distribution** for in-cloud water content. +- Fractional standard deviation may be set globally or parametrised from resolution and cloud properties [^cite-H12] [^cite-Boutle13]. +- McICA is currently available only when cloud is segregated by **phase** (not by type; no convection separation). + +--- + +## Algorithmic details + +### Algorithm overview + +On entry to the radiation code: + +1. Spectrally independent operations (cloud overlap, moist aerosol properties) are performed first. +2. Fluxes are computed band by band; broad-band fluxes are accumulated. +3. Within each band, single-scattering properties of non-gaseous species are computed (uniform across the band). +4. Gaseous overlap treatments generate sets of **pseudo-monochromatic calculations**. +5. In each pseudo-monochromatic calculation, the **linear two-stream equations are assembled and solved**. + +### Solving the two-stream equations + +The two-stream equations generate a banded linear system. Rather than applying a standard banded-matrix algorithm directly, a **set of algebraic recurrences** is constructed that follows Gaussian elimination while exploiting the pattern of zero entries. This minimises the operation count. + +The algorithm proceeds in two stages: + +**Forward sweep:** Relations of the form +$$U_{ij} = \sum_k \alpha_{i+1,jk} V_{ik} + G^+_{i+1,j}$$ +are assembled upward from the surface boundary condition, progressively eliminating unknowns. + +**Back substitution:** Once downward fluxes at each level are known, upward fluxes are recovered from the recurrence. + +!!! note "Technical note" + No pivoting is performed. Given that the single-scattering albedo $\omega$ is perturbed away from 1 to avoid rescaling singularities and that elimination begins at the surface with an albedo less than 1, pivoting is not required. + +### Approximate scattering in the longwave + +Full scattering is less critical in the longwave. An **iterative approximation** is used: + +1. Assume the upward flux at each level is Planckian at the local temperature; set upward differential flux to zero and transmit downward from the top. +2. Knowing downward differential fluxes, compute upward fluxes working upward through the atmosphere. + +This captures scattering effects on cloud emissivity but not the direct reflection of radiation from below a cloud. It significantly reduces execution time. + +### Other fast algorithms + +- **Ignoring LW scattering entirely:** Fastest option; flux equations reduce to pure transmission problems. Not recommended where clouds or dust cause significant LW scattering. +- **Hybrid scattering:** Different scattering treatments per k-term, specified in the spectral file. Restricts expensive full-scattering calculations to optically thin, scattering-important wavelengths. Gives significant speed improvements for small accuracy cost. + +### The magnification factor + +At grazing solar zenith angles, Earth's curvature causes the local zenith angle to increase along a ray path toward the Sun. A magnification factor could correct surface flux calculations, but would be inconsistent with column heating rate profiles (where the local zenith angle does not change with altitude). The code **omits the magnification factor**, prioritising accuracy of atmospheric heating rate profiles over surface flux accuracy at high zenith angles. + +--- + +[^cite-ZK85]: W. G. Zdunkowski and G. J. Korb, *Numerische Methoden zur Lösung der Strahlungsübertragungsgleichung*, Promet, 2/3:26–39, 1985. +[^cite-ZWK80]: W. G. Zdunkowski, R. M. Welch, and G. Korb, *An investigation of the structure of typical two-stream methods for the calculation of solar fluxes and heating rates in clouds*, Beiträge Phys. Atmosph., 53:147–166, 1980. +[^cite-JWW76]: J. H. Joseph, W. J. Wiscombe, and J. A. Weinman, *The delta-Eddington approximation for radiative flux transfer*, J. Atm. Sci., 33:2452–2459, 1976. +[^cite-CKD89]: S. A. Clough, F. X. Kneizys, and R. W. Davies, *Line shape and the water vapor continuum*, Atmos. Res., 23:229–241, 1989. +[^cite-SS82]: A. Slingo and H. M. Schrecker, *On the shortwave radiative properties of stratiform water clouds*, Q. J. R. Meteorol. Soc., 108:407–426, 1982. +[^cite-AS87]: S. A. Ackerman and G. L. Stephens, *The absorption of solar radiation by cloud droplets: An application of anomalous diffraction theory*, J. Atm. Sci., 44:1574–1588, 1987. +[^cite-HS93]: Y. X. Hu and K. Stamnes, *An accurate parametrization of the radiative properties of water clouds suitable for use in climate models*, J. Climate, 6:728–742, 1993. +[^cite-M96]: D. L. Mitchell, A. Macke, and Y. Liu, *Modeling cirrus clouds. Part II: Treatment of radiative properties*, J. Atm. Sci., 53:2967–2988, 1996. +[^cite-Fu96]: Q. Fu, *An accurate parametrization of the solar radiative properties of cirrus clouds for climate models*, J. Clim., 9:2058–2082, 1996. +[^cite-Fu98]: Q. Fu, P. Yang, and W. B. Sun, *An accurate parametrization of the infrared radiative properties of cirrus clouds for climate models*, J. Clim., 11:2223–2237, 1998. +[^cite-B13]: A. J. Baran, P. J. Connolly, and C. Lee, *Testing an ensemble model of cirrus ice crystals using midlatitude in situ estimates of ice water content, volume extinction coefficient and the total solar optical depth*, J. Quant. Spectrosc. Radiat. Transfer, 110:1579–1598, 2009; Baran et al., AIP Conf. Proc., 1531:716–719, 2013. +[^cite-B14]: A. J. Baran, P. Hill, K. Furtado, P. Field, and J. Manners, *A Coupled Cloud Physics–Radiation Parameterization of the Bulk Optical Properties of Cirrus and its Impact on the Met Office Unified Model Global Atmosphere 5.0 Configuration*, J. Climate, 27:7725–7752, 2014. +[^cite-RG92]: B. Ritter and J.-F. Geleyn, *A comprehensive radiation scheme for numerical weather prediction models with potential applications in climate simulations*, Mon. Wea. Rev., 120:303–325, 1992. +[^cite-GH79]: J. F. Geleyn and A. Hollingsworth, *An economical analytical method for the computation of the interaction between scattering and line absorption of radiation*, Beiträge Phys. Atmosph., 52:1–16, 1979. +[^cite-HI00]: R. J. Hogan and A. J. Illingworth, *Deriving cloud overlap statistics from radar*, Q. J. Roy. Meteorol. Soc., 126:1–7, 2000. +[^cite-P03]: R. Pincus, H. W. Barker, and J.-J. Morcrette, *A fast, flexible, approximate technique for computing radiative transfer in inhomogeneous cloud fields*, J. Geophys. Res., 108(D13):4376, 2003. +[^cite-R04]: P. Räisänen, H. W. Barker, M. F. Khairoutdinov, J. Li, and D. A. Randall, *Stochastic generation of subgrid-scale cloudy columns for large-scale models*, Q. J. Roy. Meteorol. Soc., 130:2047–2067, 2004. +[^cite-H12]: P. G. Hill, R. J. Hogan, J. Manners, and J. C. Petch, *Parametrizing the horizontal inhomogeneity of ice water content using CloudSat data products*, Q. J. Roy. Meteorol. Soc., 138:1784–1793, 2012. +[^cite-Boutle13]: I. A. Boutle, S. J. Abel, P. G. Hill, and C. J. Morcrette, *Spatial variability of liquid cloud and rain: observations and microphysical effects*, Q. J. Roy. Meteorol. Soc., 2013. diff --git a/docs/How-to/installation.md b/docs/How-to/installation.md new file mode 100644 index 0000000..37338bf --- /dev/null +++ b/docs/How-to/installation.md @@ -0,0 +1,7 @@ +# Installation + +This page is still under construction. As SOCRATES is most commonly used and installed within the [PROTEUS framework](https://proteus-framework.org/PROTEUS/), or within the atmosphere models [AGNI](https://www.h-nicholls.space/AGNI/dev/) or [JANUS](https://proteus-framework.org/JANUS), please find the relevant installation instructions there: + +- [Installation within PROTEUS framework](https://proteus-framework.org/PROTEUS/How-to/installation.html#7-install-socrates-radiative-transfer) +- [Installation within AGNI](https://www.h-nicholls.space/AGNI/dev/tutorials/getting_started/) +- [Installation within JANUS](https://proteus-framework.org/JANUS/How-to/installation.html) \ No newline at end of file diff --git a/docs/Reference/documentation_pdfs.md b/docs/Reference/documentation_pdfs.md new file mode 100644 index 0000000..1ddff55 --- /dev/null +++ b/docs/Reference/documentation_pdfs.md @@ -0,0 +1,19 @@ +# Documentation PDFs + +This page embeds the latest SOCRATES documentation PDFs built by GitHub Actions. + +## User guide + +[Open/download user guide PDF](../assets/pdfs/socrates_userguide.pdf) + + +

Unable to display the PDF in this browser. Download the user guide PDF.

+
+ +## Technical guide + +[Open/download technical guide PDF](../assets/pdfs/socrates_techguide.pdf) + + +

Unable to display the PDF in this browser. Download the technical guide PDF.

+
diff --git a/docs/Reference/proteus_spectral_file_reference.md b/docs/Reference/proteus_spectral_file_reference.md new file mode 100644 index 0000000..71862cc --- /dev/null +++ b/docs/Reference/proteus_spectral_file_reference.md @@ -0,0 +1,244 @@ +# PROTEUS spectral files + +!!! note + The spectral files described here have been generated specifically for use within the PROTEUS framework, covering atmospheric compositions relevant to exoplanet and planetary science applications. They are distinct from the [standard Met Office spectral files](spectral_file_reference.md) distributed with SOCRATES for Earth atmosphere modelling. + +--- + +## Overview + +Each spectral file is identified by a codename and a band count; several codenames are available at multiple resolutions. All files are in the standard SOCRATES spectral file format. + +Spectroscopic data sources are abbreviated as follows: **HITRAN** – [HITRAN database](https://hitran.org/); **EXOMOL** — [ExoMol database](https://www.exomol.com/); **DACE** — [DACE opacity database](https://dace.unige.ch/opacityDatabase/). + +--- + +## Spectral file summary table + +| Codename | Bands | Absorbers | Source | Notes | +|---|---|---|---|---| +| Legacy | 318 | CO₂, CH₄, O₂, N₂, H₂, He | HITRAN | Legacy file used in Lichtenberg et al. (2021) | +| Oak | 318 | H₂O | HITRAN | Water-only file from HITRAN; intended for benchmarking | +| Idwal | 318 | H₂O | HITRAN | Made redundant by Oak | +| Balmora | 318 | H₂O | HITRAN | Made redundant by Oak | +| Triangle | 318 | H₂O, H₂, CO₂ | HITRAN | Test file | +| Mallard | 318 | H₂O, H₂, CO₂, CO, CH₄, O₂, N₂, He | HITRAN | HITRAN file with useful opacities | +| Reach | 318 | H₂O, CO₂, O₃, N₂O, CO, CH₄, O₂, NO, SO₂, NO₂, NH₃, HNO₃, N₂, H₂, He, OCS | HITRAN | Same as Mallard but with more opacities | +| Vivec | 318 | H₂O, CO₂, O₃, N₂O, CO, CH₄, O₂, NO, SO₂, NO₂, NH₃, HNO₃, N₂, H₂, He, OCS | HITRAN | Same as Reach, compiled on macOS | +| Alduin | 432 | H₂O | EXOMOL | | +| Kynesgrove | 318 | O₂ | DACE | Validation of DACE cross-section data against SOCRATES line-by-line calculations | +| Frostflow | 16 / 48 / 256 / 4096 | H₂O | DACE | Multi-resolution; 4096 intended for benchmarking, 16 for debugging | +| Dayspring | 16 / 48 / 256 / 4096 | H₂O, H₂, CO₂, CO, CH₄, N₂ | DACE | Multi-resolution; 4096 intended for benchmarking, 16 for debugging | +| Honeyside | 16 / 48 / 256 / 4096 | H₂O, H₂, CO₂, CO, CH₄, N₂, NH₃, SO₂, N₂O, O₃, HCN, H₂S | DACE | Multi-resolution; 4096 intended for benchmarking, 16 for debugging | +| Rocks | 64 / 128 / 256 | H₂, H₂O, O₂, SiO, SiO₂ | DACE | Rock vapours and key volatiles; 128-band file for JWST comparison | + +--- + +## Full metadata + +??? info "Honeyside" + | Bands | Tolerance | NaN-clean | SOCRATES | Date | Platform | Creator | Notes | + |---|---|---|---|---|---|---|---| + | 4096 | 1.00E-02 | Yes | 2403 | 2024-07-07 | Linux Intel | Harrison Nicholls | Very high resolution; intended for benchmarking | + | 256 | ^ | ^ | ^ | ^ | ^ | ^ | High resolution | + | 48 | ^ | ^ | ^ | ^ | ^ | ^ | Medium resolution | + | 16 | ^ | ^ | ^ | ^ | ^ | ^ | Low resolution; intended for debugging | + + **Absorbers:** H₂O, H₂, CO₂, CO, CH₄, N₂, NH₃, SO₂, N₂O, O₃, HCN, H₂S + **Continua:** H₂O-H₂O, H₂-CH₄, H₂-H₂, H₂-N₂, N₂-N₂, N₂-H₂O, CO₂-CO₂, CO₂-H₂, CO₂-CH₄ + **Source:** DACE + +??? info "Rocks" + | Bands | Absorbers | Continua | NaN-clean | SOCRATES | Date | Platform | Creator | Notes | + |---|---|---|---|---|---|---|---|---| + | 256 | O₂, SiO, SiO₂ | O₂-O₂ | Yes | 2407.2 | 2025-05-15 | Linux Intel | Alex McGinty | — | + | 128 | H₂, H₂O, O₂, SiO, SiO₂ | H₂O-H₂O, H₂-H₂, O₂-O₂ | Yes | 2407.02 | 2025-05-15 | Linux Intel | Alex McGinty | Rock vapours and key volatiles. High resolution file for comparison with JWST observations of rock-vapour atmospheres | + | 64 | H₂, H₂O, O₂, SiO, SiO₂ | H₂O-H₂O, H₂-H₂, O₂-O₂ | Yes | 2407.02 | 2025-05-15 | Linux Intel | Alex McGinty | Rock vapours and key volatiles (low resolution) | + + **Source:** DACE + +??? info "Dayspring" + | Bands | Tolerance | NaN-clean | SOCRATES | Date | Platform | Creator | Notes | + |---|---|---|---|---|---|---|---| + | 4096 | 1.00E-02 | Yes | 2403 | 2024-04-30 | Linux Intel | Harrison Nicholls | Very high resolution; intended for benchmarking | + | 256 | ^ | ^ | ^ | ^ | ^ | ^ | High resolution | + | 48 | ^ | ^ | ^ | ^ | ^ | ^ | Medium resolution | + | 16 | ^ | ^ | ^ | ^ | ^ | ^ | Low resolution; intended for debugging | + + **Absorbers:** H₂O, H₂, CO₂, CO, CH₄, N₂ + **Continua:** H₂O-H₂O, H₂-CH₄, H₂-H₂, H₂-N₂, N₂-N₂, N₂-H₂O, CO₂-CO₂, CO₂-H₂, CO₂-CH₄ + **Source:** DACE + +??? info "Frostflow" + | Bands | Tolerance | NaN-clean | SOCRATES | Date | Platform | Creator | Notes | + |---|---|---|---|---|---|---|---| + | 4096 | 5.00E-03 | Yes | 2403 | 2024-03-20 | Linux Intel | Harrison Nicholls | Very high resolution; intended for benchmarking | + | 256 | ^ | ^ | ^ | ^ | ^ | ^ | High resolution | + | 48 | ^ | ^ | ^ | ^ | ^ | ^ | Medium resolution | + | 16 | ^ | ^ | ^ | ^ | ^ | ^ | Low resolution; intended for debugging | + + **Absorbers:** H₂O + **Continua:** H₂O + **Source:** DACE + +??? info "Kynesgrove" + | Field | Value | + |---|---| + | Bands | 318 | + | Absorbers | O₂ | + | Continua | O₂-O₂ | + | Tolerance | 5.00E-04 | + | Source | DACE | + | NaN-clean | Yes | + | SOCRATES version | 2403 | + | Date | 2024-03-14 | + | Platform | Linux Intel | + | Creator | Harrison Nicholls | + | Notes | Created for validation of DACE cross-section data against SOCRATES' own line-by-line calculations used in Mallard | + +??? info "Reach" + | Field | Value | + |---|---| + | Bands | 318 | + | Absorbers | H₂O, CO₂, O₃, N₂O, CO, CH₄, O₂, NO, SO₂, NO₂, NH₃, HNO₃, N₂, H₂, He, OCS | + | Continua | H₂O, CO₂, CH₄, O₂, N₂, H₂, He | + | Tolerance | 1.00E-02 | + | Source | HITRAN | + | NaN-clean | Yes | + | SOCRATES version | 2306 | + | Date | 2023-07-19 | + | Platform | Linux Intel | + | Creator | Harrison Nicholls | + | Notes | Same as Mallard but with more opacities. Script exists to generate this file, but it is not currently available. | + +??? info "Mallard" + | Field | Value | + |---|---| + | Bands | 318 | + | Absorbers | H₂O, H₂, CO₂, CO, CH₄, O₂, N₂, He | + | Continua | H₂O, CO₂, CH₄, O₂, N₂, H₂, He | + | Tolerance | 1.00E-02 | + | Source | HITRAN | + | NaN-clean | Yes | + | SOCRATES version | 2306 | + | Date | 2023-07-13 | + | Platform | Linux Intel | + | Creator | Harrison Nicholls | + | Notes | HITRAN file with useful opacities | + +??? info "Alduin" + | Field | Value | + |---|---| + | Bands | 432 | + | Absorbers | H₂O | + | Continua | H₂O | + | Tolerance | 1.00E-02 | + | Source | EXOMOL | + | NaN-clean | Yes | + | SOCRATES version | 2306 | + | Date | — | + | Platform | Linux Intel | + | Creator | Ryan Boukrouche | + | Notes | — | + +??? info "Oak" + | Field | Value | + |---|---| + | Bands | 318 | + | Absorbers | H₂O | + | Continua | H₂O | + | Tolerance | 1.00E-02 | + | Source | HITRAN | + | NaN-clean | Yes | + | SOCRATES version | 2306 | + | Date | 2023-07-10 | + | Platform | Linux Intel | + | Creator | Harrison Nicholls | + | Notes | Water-only spectral file from HITRAN. To be used for benchmarking. | + +??? info "Legacy" + | Field | Value | + |---|---| + | Bands | 318 | + | Absorbers | CO₂, CH₄, O₂, N₂, H₂, He | + | Continua | — | + | Tolerance | 1.00E-02 | + | Source | HITRAN | + | NaN-clean | Yes | + | SOCRATES version | 2002 | + | Date | 2021 | + | Platform | Linux Intel | + | Creator | Tim Lichtenberg | + | Notes | Legacy spectral file used in Lichtenberg et al. (2021) | + +??? info "Vivec" + | Field | Value | + |---|---| + | Bands | 318 | + | Absorbers | H₂O, CO₂, O₃, N₂O, CO, CH₄, O₂, NO, SO₂, NO₂, NH₃, HNO₃, N₂, H₂, He, OCS | + | Continua | H₂O, CO₂, CH₄, O₂, N₂, H₂, He | + | Tolerance | 1.00E-02 | + | Source | HITRAN | + | NaN-clean | No | + | SOCRATES version | 2306 | + | Date | 2023-07-25 | + | Platform | Mac Intel | + | Creator | Tim Lichtenberg | + | Notes | Same as Reach, but compiled on macOS | + +??? info "Triangle" + | Field | Value | + |---|---| + | Bands | 318 | + | Absorbers | H₂O, H₂, CO₂ | + | Continua | H₂O, H₂, CO₂ | + | Tolerance | 1.00E-02 | + | Source | HITRAN | + | NaN-clean | Yes | + | SOCRATES version | 2306 | + | Date | 2023-07-11 | + | Platform | Linux Intel | + | Creator | Harrison Nicholls | + | Notes | Test | + +??? info "Idwal" + | Field | Value | + |---|---| + | Bands | 318 | + | Absorbers | H₂O | + | Continua | H₂O | + | Tolerance | 1.00E-02 | + | Source | HITRAN | + | NaN-clean | No | + | SOCRATES version | 2211 | + | Date | 2023-07-11 | + | Platform | Linux Intel | + | Creator | Harrison Nicholls | + | Notes | Made redundant by Oak. They only differ by SOCRATES version. | + +??? info "Balmora" + | Field | Value | + |---|---| + | Bands | 318 | + | Absorbers | H₂O | + | Continua | H₂O | + | Tolerance | 1.00E-02 | + | Source | HITRAN | + | NaN-clean | No | + | SOCRATES version | 2306 | + | Date | 2023-07-19 | + | Platform | Mac ARM | + | Creator | Tim Lichtenberg | + | Notes | Made redundant by Oak. They only differ by creation platform. | + +--- + +## Choosing a spectral file + +The appropriate spectral file depends on the atmospheric composition being modelled and the required spectral resolution: + +- For **benchmarking or comparison with observations**, use a high- or very-high-resolution configuration (256–4096 bands). +- For **debugging**, use a low resolution spectral file with 16 bands. +- For **water-dominated atmospheres**, Frostflow or Oak are appropriate depending on the required resolution and data source. +- For **mixed volatile atmospheres** (H₂O, CO₂, CH₄, H₂, N₂ and more), Honeyside is the most complete option. +- For **rock-vapour atmospheres** (relevant to magma ocean planets), use the Rocks files which include SiO and SiO₂ opacity. \ No newline at end of file diff --git a/docs/Reference/spectral_file_reference.md b/docs/Reference/spectral_file_reference.md new file mode 100644 index 0000000..d627168 --- /dev/null +++ b/docs/Reference/spectral_file_reference.md @@ -0,0 +1,191 @@ +# Standard spectral files + +!!! note + The spectral files described here are the **standard Met Office files** distributed with SOCRATES, originally developed for use in the Unified Model (UM) and associated climate configurations. They are described in detail in the technical guide by James Manners, John M. Edwards, Peter Hill & Jean-Claude Thelen (Met Office, 2017), found [here](documentation_pdfs.md#technical-guide). + +--- + +## Overview + +Standard spectral files are provided for four major model configurations, each with separate shortwave (SW) and longwave (LW) files. Files with names beginning `sp_` are readable text format for use with UM version ≥ 8.6 or the offline code; files beginning `spec3a_` are namelist format for UM version ≤ 8.5. + +| Configuration | SW file | LW file(s) | +|---|---|---| +| Global Atmosphere 7 | `sp_sw_ga7` | `sp_lw_ga7` | +| Global Atmosphere 3 | `sp_sw_ga3_0` | `sp_lw_ga3_0`, `sp_lw_ga3_1` | +| HadGEM2 | `spec3a_sw_hadgem1_5o_rlfx` | `spec3a_lw_hadgem1_5C` | +| HadGEM1 | `spec3a_sw_hadgem1_3` | `spec3a_lw_hadgem1_3` | + +Older files for HadCM3, HadAM4, and the mesoscale model are also distributed; see the technical guide for their full descriptions. + +--- + +## Global Atmosphere Configuration 7 + +### `sp_sw_ga7` + +Sections are identical to `sp_sw_ga3_0` except for changes to the spectral bands, solar spectrum (including Rayleigh coefficients), and gaseous absorption. + +**Spectral bands:** + +| Band | Wavelength (nm) | +|---|---| +| 1 | 200 – 320 | +| 2 | 320 – 505 | +| 3 | 505 – 690 | +| 4 | 690 – 1190 | +| 5 | 1190 – 2380 | +| 6 | 2380 – 10000 | + +The six bands are identical to `sp_sw_ga3_0` except that the combined bands 2 and 3 are now properly split into two true bands at 505 nm. + +**Solar spectrum:** "Lean 12" — a mean over 2000–2011 from the SPARC/SOLARIS group recommendation [^cite-Lean00], with associated updates to Rayleigh scattering coefficients. + +**Gaseous absorption:** Newly derived for all gases using HITRAN 2012 [^cite-HITRAN] and the CAVIAR water vapour continuum. Absorption coefficients are scaled via a look-up table of 59 pressures × 5 temperatures, based on a mid-latitude summer profile. Total of **41 major gas k-terms**. + +Gases included: H₂O, O₃, CO₂, O₂, N₂O, CH₄, SO₂ (experimental), OCS (experimental). + +Ozone cross-sections from Serdyuchenko et al. [^cite-Serd14] and Gorshelev et al. [^cite-Gors14] for UV/visible; Brion–Daumont–Malicet for the far UV. In band 1, one k-term per 20 nm sub-interval (200–320 nm); in band 2, sub-intervals at 320–400 nm and 400–505 nm to allow the incoming solar flux to be supplied on finer wavelength bands for solar spectral variability experiments. + +--- + +### `sp_lw_ga7` + +Sections are identical to `sp_lw_ga3_0` except for changes to gaseous absorption and thermal emission. + +**Spectral bands:** + +| Band | Wavenumber (cm⁻¹) | Wavelength (µm) | +|---|---|---| +| 1 | 1 – 400 | 25 – 10000 | +| 2 | 400 – 550 | 18.18 – 25 | +| 3 | 550 – 590 and 750 – 800 | 12.5 – 13.33 and 16.95 – 18.18 | +| 4 | 590 – 750 | 13.33 – 16.95 | +| 5 | 800 – 990 and 1120 – 1200 | 8.33 – 8.93 and 10.10 – 12.5 | +| 6 | 990 – 1120 | 8.93 – 10.10 | +| 7 | 1200 – 1330 | 7.52 – 8.33 | +| 8 | 1330 – 1500 | 6.67 – 7.52 | +| 9 | 1500 – 2995 | 3.34 – 6.67 | + +Bands 3 and 5 are split bands (see [Spectral files: split bands](../Explanations/spectral_files.md#split-bands-block-14)). + +**Gaseous absorption:** Newly derived for all gases (except CO₂ in band 4) using HITRAN 2012 and CAVIAR. Total of **81 major gas k-terms**. + +Greenhouse gases included: H₂O, CO₂, O₃, N₂O, CH₄, CFC-11, CFC-12, CFC-113, HCFC-22, HFC-134a, SO₂ (experimental), OCS (experimental). + +The improved representation of CO₂ in the window region (more minor gas k-terms in bands 5 and 6) provides a better forcing response to increases in CO₂ (tested up to ×32 present-day). The new method of hybrid scattering may be used with this spectral file: 27 of the major gas k-terms (where their nominal optical depth is less than 10 in a mid-latitude summer atmosphere) use the full scattering solver; the remaining 54 (optical depth > 10) use a cheaper non-scattering solver. + +**Thermal emission:** Planck function fitted by a quartic polynomial over 160–330 K. This increases the lower bound of the fit from 150 K used with `sp_lw_ga3_0` and slightly improves the fit over the important temperature range for the Earth's atmosphere. + +--- + +## Global Atmosphere Configuration 3 + +### `sp_sw_ga3_0` + +Sections are identical to `spec3a_sw_hadgem1_5o_rlfx` except for changes to the solar spectrum (including Rayleigh coefficients), gaseous absorption, aerosols, and ice crystals. + +**Spectral bands:** Identical to `sp_sw_ga7` except bands 2 and 3 are not true spectral bands — they share the combined range 320–690 nm and only the sum of fluxes in these two bands is physically meaningful. + +**Solar spectrum:** Lean (2000, updated) [^cite-Lean00] — based on satellite observations at wavelengths shorter than 735 nm with the Kurucz spectrum [^cite-Kurucz95] at longer wavelengths, meaned over the last two solar cycles (1983–2004). + +**Gaseous absorption:** Revised O₃ k-terms in bands 1–3 for improved ozone heating rate calculations and to better incorporate solar variability [^cite-Zhong08]. The UV band is divided into six narrow sub-bands, each with a single ozone k-term. + +Gases included: H₂O, O₃, CO₂, O₂. + +**Aerosols:** Addition of four aerosol species: fresh and aged OCFF (organic carbon fossil fuel), delta aerosol, and nitrate aerosol. The optical properties of the six divisions of mineral dust have been revised using refractive indices from Balkanski et al. [^cite-Balk07], making mineral dust less absorbing in the SW and more absorbing in the LW. + +**Ice crystals:** A new parametrisation (type 9) based on observed particle size distributions and an ensemble model of ice crystal type and orientation. Optical properties are linked directly to temperature and ice water content with no intermediate dependence on ice crystal size. + +--- + +### `sp_lw_ga3_0` + +Used for climate configurations where a more accurate treatment of the stratosphere is required. Sections are identical to `spec3a_lw_hadgem1_5C` except for changes to gaseous absorption, thermal emission, aerosols, and ice crystals. + +**Spectral bands:** Identical to `sp_lw_ga7` (nine bands; bands 3 and 5 split). + +**Gaseous absorption:** New k-terms for CO₂ (band 4) and O₃ (band 6) [^cite-ZhongH00], increasing the total number of k-terms by 14 relative to `spec3a_lw_hadgem1_5C` to allow a more accurate treatment of stratospheric absorption. + +Greenhouse gases: H₂O, CO₂, O₃, N₂O, CH₄, CFC-11, CFC-12, CFC-113, HCFC-22, HFC-134a. + +**Thermal emission:** Quartic fit over 150–330 K. The previous fit (180–330 K in `spec3a_lw_hadgem1_5C`) could give negative emission at very cold temperatures sometimes seen at the top of the model. + +**Aerosols and ice crystals:** Same additions as `sp_sw_ga3_0`. + +--- + +### `sp_lw_ga3_1` + +Used for forecast configurations where speed of computation and a more accurate treatment of the troposphere are required. Sections are identical to `spec3a_lw_hadgem1_5C` except for changes to aerosols and ice crystals — the same additions as `sp_sw_ga3_0` — with the extra CO₂ and O₃ k-terms of `sp_lw_ga3_0` not included. + +--- + +## HadGEM2 + +### `spec3a_sw_hadgem1_5o_rlfx` + +Used in the HadGEM2-A model and the global forecast model from PS20. All sections are identical to `spec3a_sw_hadgem1_3` except for changes to aerosols and Rayleigh scattering. + +**Rayleigh scattering:** Rayleigh scattering coefficients in `spec3a_sw_hadgem1_3` were found to be in error by approximately 20% due to a bug in the generating code [^cite-Haywood08]. These are corrected here. + +**Aerosols:** Mie scattering calculations have provided optical properties for seven additional aerosols: six size bins of mineral dust and one mode of biogenic aerosol from terpene emissions. Parametrisations of Aitken sulphate, fresh biomass (mode 1), and aged biomass (mode 2) have also been updated. Biogenic aerosols are hygroscopic. + +--- + +### `spec3a_lw_hadgem1_5C` + +Used in the HadGEM2-A model and the global forecast model from PS20. All sections are identical to `spec3a_lw_hadgem1_3` except for changes to aerosols. + +**Aerosols:** Same additions as `spec3a_sw_hadgem1_5o_rlfx`. + +**Block 15 (new):** Contains specific absorption and scattering coefficients of each aerosol mode at six wavelengths (0.38, 0.44, 0.55, 0.67, 0.87, 1.02 µm), used by the model to compute aerosol optical depth. In contrast to block 11, these coefficients are monochromatic. Hygroscopic aerosols have relative-humidity-dependent coefficients. + +--- + +## HadGEM1 + +### `spec3a_sw_hadgem1_3` + +**Spectral bands:** Six bands; bands 2 and 3 share the range 320–690 nm (not true bands). + +**Solar spectrum:** Kurucz (1995) [^cite-Kurucz95]. + +**Gaseous absorption:** H₂O (with CKD 2.4 continuum [^cite-CKD]), O₃, CO₂, O₂. Foreign continuum combined with line data and fitted as one entity; self-broadened continuum represented explicitly. Spectroscopic data from HITRAN 2000 [^cite-HITRAN] with published corrections, augmented by theoretical weak lines. + +**Aerosols:** Five standard climatological aerosols [^cite-Cusack98], plus two sulphate modes (Aitken and accumulation), two black carbon modes (fresh and aged), two sea-salt modes (film and jet), two biomass smoke modes (fresh and aged), and six mineral dust size bins. + +**Cloud droplets:** Four types available (2, 3, 4, 5), based on size distributions from Rockel et al. [^cite-Rockel91] with effective radii 1.5–50 µm. Types 2 and 3 use linear fits (Slingo & Schrecker [^cite-SS82]); types 4 and 5 use Padé approximants. Type 4 corresponds to thin averaging and type 5 to thick averaging; **type 5 preferred** for both convective and large-scale clouds. + +**Ice crystals:** Types 2 and 3 (spherical analogy, thin/thick averaging); type 7 (planar polycrystals, anomalous diffraction approximation [^cite-Krist99] [^cite-Krist00], fit in terms of mean maximum dimension $\bar{D}_l$); type 8 (ice aggregates [^cite-Edwards07], fit in terms of effective dimension $D_e$). **Type 2 recommended** for large-scale cloud; **type 3 for convective cloud**. + +--- + +### `spec3a_lw_hadgem1_3` + +**Spectral bands:** Nine bands; bands 3 and 5 are split. + +**Thermal emission:** Quartic fit over 180–330 K. + +**Gaseous absorption:** H₂O, O₃, CO₂, N₂O, CH₄, CFC-11, CFC-12, CFC-113, HCFC-22, HFC-125, HFC-134a. Spectroscopic data from HITRAN 92 for most gases; CKD 2.4 continuum for water vapour [^cite-CKD]. Halocarbon cross-sections from K. Shine (pers. comm.). + +**Cloud droplets and ice crystals:** As per `spec3a_sw_hadgem1_3`. Only type 1 droplet data initially available for LW; types 4 and 5 (Padé fits) now recommended. + +--- + +[^cite-Lean00]: J. Lean, *Evolution of the sun's spectral irradiance since the Maunder minimum*, Geophys. Res. Lett., 27:2425–2428, 2000. +[^cite-Kurucz95]: R. L. Kurucz, CD-ROM 23, Harvard Smithsonian Center for Astrophysics, 1995. +[^cite-HITRAN]: L. S. Rothman et al., *The HITRAN molecular spectroscopic database*, J. Quant. Spectrosc. Radiat. Transfer, various editions (2000, 2012). +[^cite-Serd14]: A. Serdyuchenko, V. Gorshelev, M. Weber, W. Chehade, and J. P. Burrows, *High spectral resolution ozone absorption cross-sections — Part 2: Temperature dependence*, Atmos. Meas. Tech., 7:625–636, 2014. +[^cite-Gors14]: V. Gorshelev, A. Serdyuchenko, M. Weber, W. Chehade, and J. P. Burrows, *High spectral resolution ozone absorption cross-sections — Part 1: Measurements, data analysis and comparison with previous measurements around 293 K*, Atmos. Meas. Tech., 7:609–624, 2014. +[^cite-Zhong08]: W. Zhong, S. M. Osprey, L. J. Gray, and J. D. Haigh, *Influence of the prescribed solar spectrum on calculations of atmospheric temperature*, Geophys. Res. Lett., 35(L22813), 2008. +[^cite-ZhongH00]: W. Zhong and J. D. Haigh, *An efficient and accurate correlated-k parametrization of infrared radiative transfer for troposphere–stratosphere–mesosphere GCMs*, Atmos. Sci. Lett., 1(2):125–135, 2000. +[^cite-Balk07]: Y. Balkanski, M. Schulz, T. Claquin, and S. Guibert, *Reevaluation of mineral aerosol radiative forcings suggests a better agreement with satellite and AERONET data*, Atmos. Chem. Phys., 7:81–95, 2007. +[^cite-Haywood08]: J. Haywood et al., *Identification/impact/rectification of a bug in radiation code preprocessing and spectral files*, Met Office Technical Report, 2008. +[^cite-CKD]: S. A. Clough, F. X. Kneizys, and R. W. Davies, *Line shape and the water vapor continuum*, Atmos. Res., 23:229–241, 1989. +[^cite-Cusack98]: S. Cusack, A. Slingo, J. M. Edwards, and M. Wild, *The radiative impact of a simple aerosol climatology on the Hadley Centre atmospheric GCM*, Q. J. Roy. Meteorol. Soc., 124:2517–2526, 1998. +[^cite-Rockel91]: B. Rockel, E. Raschke, and B. Weyres, *A parametrization of broad band radiative transfer properties of water, ice and mixed clouds*, Beiträge Phys. Atmosph., 64:1–12, 1991. +[^cite-SS82]: A. Slingo and H. M. Schrecker, *On the shortwave radiative properties of stratiform water clouds*, Q. J. R. Meteorol. Soc., 108:407–426, 1982. +[^cite-Krist99]: J. E. Kristjánsson, J. M. Edwards, and D. L. Mitchell, *A new parameterization scheme for the optical properties of ice crystals for use in general circulation models*, Phys. Chem. Earth (B), 24:231–236, 1999. +[^cite-Krist00]: J. E. Kristjánsson, J. M. Edwards, and D. L. Mitchell, *The impact of a new scheme for the optical properties of ice crystals on the climates of two GCMs*, J. Geophys. Res., 105:10063–10079, 2000. +[^cite-Edwards07]: J. M. Edwards, S. Havemann, J.-C. Thelen, and A. J. Baran, *A new parametrization for the radiative properties of ice crystals: Comparison with existing schemes and impact in a GCM*, J. Atmos. Res., 83:19–35, 2007. diff --git a/docs/assets/PROTEUS_black.png b/docs/assets/PROTEUS_black.png new file mode 100644 index 0000000..742eaa8 Binary files /dev/null and b/docs/assets/PROTEUS_black.png differ diff --git a/docs/assets/PROTEUS_black_nobkg.png b/docs/assets/PROTEUS_black_nobkg.png new file mode 100644 index 0000000..ddcc24e Binary files /dev/null and b/docs/assets/PROTEUS_black_nobkg.png differ diff --git a/docs/assets/PROTEUS_black_on_white_logo_only.png b/docs/assets/PROTEUS_black_on_white_logo_only.png new file mode 100644 index 0000000..fe49048 Binary files /dev/null and b/docs/assets/PROTEUS_black_on_white_logo_only.png differ diff --git a/docs/assets/PROTEUS_white.png b/docs/assets/PROTEUS_white.png new file mode 100644 index 0000000..290ff61 Binary files /dev/null and b/docs/assets/PROTEUS_white.png differ diff --git a/docs/assets/PROTEUS_white_on_black.png b/docs/assets/PROTEUS_white_on_black.png new file mode 100644 index 0000000..14e5d75 Binary files /dev/null and b/docs/assets/PROTEUS_white_on_black.png differ diff --git a/docs/assets/PROTEUS_white_on_black_logo_only.png b/docs/assets/PROTEUS_white_on_black_logo_only.png new file mode 100644 index 0000000..fbd6d48 Binary files /dev/null and b/docs/assets/PROTEUS_white_on_black_logo_only.png differ diff --git a/docs/assets/schematic.odg b/docs/assets/schematic.odg new file mode 100644 index 0000000..282848c Binary files /dev/null and b/docs/assets/schematic.odg differ diff --git a/docs/assets/schematic.png b/docs/assets/schematic.png new file mode 100644 index 0000000..35f4a1a Binary files /dev/null and b/docs/assets/schematic.png differ diff --git a/docs/assets/schematic_round.png b/docs/assets/schematic_round.png new file mode 100644 index 0000000..f503338 Binary files /dev/null and b/docs/assets/schematic_round.png differ diff --git a/docs/getting_started.md b/docs/getting_started.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..d501f76 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,26 @@ +# SOCRATES + +

Suite Of Community RAdiative Transfer codes based on Edwards and Slingo

+ +SOCRATES is a high-performance radiative transfer code for computing fluxes, heating rates, and radiances in planetary atmospheres. Its primary development and maintenance is lead by the UK Met Office. SOCRATES is applied as the radiative transfer core of the [PROTEUS framework](https://proteus-framework.org/PROTEUS/), called by the radiative-convective atmosphere model [AGNI](https://www.h-nicholls.space/AGNI/). + +!!! info "PROTEUS framework" + This documentation describes SOCRATES as integrated into the PROTEUS framework for exoplanet atmosphere modelling. The original Met Office repository can be found [here](https://github.com/MetOffice/socrates). + +--- +## Overview + +SOCRATES solves the radiative transfer equation in a plane-parallel atmosphere, computing monochromatic and broad-band radiative quantities across the shortwave and longwave spectral regions. Its primary solver is the two-stream radiation code, driven by **spectral files**: pre-computed data files that encode absorption data, optical properties for gases, clouds, aerosols, and scattering. In PROTEUS, there are spectral files available created specifically for exoplanet applications, covering a wide range of atmospheric compositions. + + + + +--- + +## Citation + +If you use SOCRATES as part of PROTEUS, please cite the original code description: + +- Edwards, J. M. and Slingo, A. (1996): [10.1002/qj.49712253107](https://doi.org/10.1002/qj.49712253107) +- Manners, J. (2024): [10.1063/5.0185476](https://doi.org/10.1063/5.0185476) + diff --git a/docs/javascripts/header-links.js b/docs/javascripts/header-links.js new file mode 100644 index 0000000..d664949 --- /dev/null +++ b/docs/javascripts/header-links.js @@ -0,0 +1,26 @@ +function wire() { + const homepage = "https://proteus-framework.org/"; + + const logo = document.querySelector(".md-header__button.md-logo"); + if (logo) logo.href = homepage; + + const title = document.querySelector(".md-header__title[data-md-component='header-title']"); + if (title && !title.dataset.spiderWired) { + title.dataset.spiderWired = "1"; + title.style.cursor = "pointer"; + + // always go to /SOCRATES/ when hosted there, else "/" (mkdocs serve) + const href = location.href; + const docsHome = href.includes("/SOCRATES/") + ? href.split("/SOCRATES/")[0] + "/SOCRATES/" + : location.origin + "/"; + + title.addEventListener("click", (e) => { + if (e.target.closest("a, button, input, label")) return; + window.location.assign(docsHome); + }, true); + } +} + +document.addEventListener("DOMContentLoaded", wire); +if (window.document$?.subscribe) window.document$.subscribe(wire); diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 0000000..be8f24d --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,54 @@ +{% extends "base.html" %} + +{% block extrahead %} + {{ super() }} + + + + + + + +{% endblock %} diff --git a/docs/proteus_framework.md b/docs/proteus_framework.md new file mode 100644 index 0000000..ba522aa --- /dev/null +++ b/docs/proteus_framework.md @@ -0,0 +1,20 @@ +

+ +
+ + +
+
+

+ +SOCRATES is the radiative transfer code of PROTEUS (/ˈproʊtiəs, PROH-tee-əs), a modular Python framework that simulates the coupled evolution of the atmospheres and interiors of rocky planets and exoplanets. A schematic of PROTEUS components and corresponding modules can be found below. +
+
+You can find the documentation of each PROTEUS module in the sidebar. +
+
+ +

+
+ Schematic of PROTEUS components and corresponding modules.
+

\ No newline at end of file diff --git a/docs/stylesheets/footnotes.css b/docs/stylesheets/footnotes.css new file mode 100644 index 0000000..f3729cf --- /dev/null +++ b/docs/stylesheets/footnotes.css @@ -0,0 +1,29 @@ +/* ---- Footnote/citation markers: render as inline [1] instead of superscript ---- */ +.md-typeset sup[id^="fnref"] { + vertical-align: baseline !important; + font-size: 1em !important; + line-height: inherit !important; +} + +.md-typeset sup[id^="fnref"] > a.footnote-ref { + text-decoration: none; +} + +.md-typeset sup[id^="fnref"] > a.footnote-ref::before { content: "["; } +.md-typeset sup[id^="fnref"] > a.footnote-ref::after { content: "]"; } + +/* fallback (some versions/themes) */ +.md-typeset a.footnote-ref { + vertical-align: baseline !important; + font-size: 1em !important; +} + +/* reduce space under the page title */ +.md-typeset h1 { + margin-bottom: 0.2rem; /* try 0, 0.2rem, 0.5rem */ +} + +/* optionally reduce any top margin on the first image */ +.md-typeset h1 + p img { + margin-top: 0; +} diff --git a/docs/stylesheets/proteus_theme.css b/docs/stylesheets/proteus_theme.css new file mode 100644 index 0000000..83c5b8f --- /dev/null +++ b/docs/stylesheets/proteus_theme.css @@ -0,0 +1,250 @@ +/* ========================================================= + PROTEUS theme variables + ========================================================= */ + +/* Be careful when changing these, as they affect multiple elements across the site. */ + +[data-md-color-scheme="default"], +[data-md-color-scheme="slate"] { + --md-primary-fg-color: #1c2b4b; + --md-primary-fg-color--light: #2a3d69; + --md-primary-fg-color--dark: #14203a; + + --proteus-highlight-color: #ff6e40; + --proteus-highlight-bg-soft: rgba(255, 109, 64, 0.093); + + --md-accent-fg-color: var(--proteus-highlight-color); + + --md-typeset-a-color: #3b6193; +} + +/* Softer slate background + more muted link color */ +[data-md-color-scheme="slate"] { + --md-default-bg-color: #0f172ad2; + --md-default-bg-color--light: #1e293b; + --md-default-bg-color--lighter: #334155; + --md-default-bg-color--lightest: #475569; + + --md-typeset-a-color: #8fa8c9; +} + +/* ========================================================= + Header + tabs + ========================================================= */ + +[data-md-color-scheme="default"] .md-header, +[data-md-color-scheme="default"] .md-tabs, +[data-md-color-scheme="slate"] .md-header, +[data-md-color-scheme="slate"] .md-tabs { + background-color: var(--md-primary-fg-color); +} + +[data-md-color-scheme="default"] .md-header *, +[data-md-color-scheme="default"] .md-tabs *, +[data-md-color-scheme="slate"] .md-header *, +[data-md-color-scheme="slate"] .md-tabs * { + color: #fff !important; + fill: #fff !important; +} + +/* ========================================================= + Expanded search + ========================================================= */ + +[data-md-color-scheme="default"] .md-search__form, +[data-md-color-scheme="slate"] .md-search__form { + background-color: rgba(255, 255, 255, 0.12) !important; + border-radius: 0.2rem !important; + box-shadow: none !important; +} + +[data-md-color-scheme="default"] .md-search__form:hover, +[data-md-color-scheme="default"] .md-search__form:focus-within, +[data-md-color-scheme="slate"] .md-search__form:hover, +[data-md-color-scheme="slate"] .md-search__form:focus-within { + background-color: rgba(255, 255, 255, 0.16) !important; +} + +[data-md-color-scheme="default"] .md-search__input, +[data-md-color-scheme="slate"] .md-search__input { + color: #fff !important; + -webkit-text-fill-color: #fff !important; + caret-color: #fff !important; + background: transparent !important; + -webkit-appearance: none; + appearance: none; +} + +[data-md-color-scheme="default"] .md-search__input::placeholder, +[data-md-color-scheme="slate"] .md-search__input::placeholder { + color: rgba(255, 255, 255, 0.75) !important; + -webkit-text-fill-color: rgba(255, 255, 255, 0.75) !important; + opacity: 1 !important; +} + +/* Hide browser-native search decorations */ +.md-search__input::-webkit-search-decoration, +.md-search__input::-webkit-search-cancel-button, +.md-search__input::-webkit-search-results-button, +.md-search__input::-webkit-search-results-decoration { + -webkit-appearance: none; + appearance: none; + display: none; +} + +/* Expanded search icons */ +[data-md-color-scheme="default"] .md-search__icon, +[data-md-color-scheme="default"] .md-search__icon svg, +[data-md-color-scheme="default"] .md-search__icon svg *, +[data-md-color-scheme="default"] .md-search__label, +[data-md-color-scheme="default"] .md-search__label svg, +[data-md-color-scheme="default"] .md-search__label svg *, +[data-md-color-scheme="slate"] .md-search__icon, +[data-md-color-scheme="slate"] .md-search__icon svg, +[data-md-color-scheme="slate"] .md-search__icon svg *, +[data-md-color-scheme="slate"] .md-search__label, +[data-md-color-scheme="slate"] .md-search__label svg, +[data-md-color-scheme="slate"] .md-search__label svg * { + color: #fff !important; + fill: #fff !important; + stroke: #fff !important; + opacity: 1 !important; +} + +/* ========================================================= + Collapsed search trigger in header + ========================================================= */ + +[data-md-color-scheme="default"] .md-search__button, +[data-md-color-scheme="slate"] .md-search__button { + color: #fff !important; + background-color: rgba(255, 255, 255, 0.12) !important; + border-radius: 0.6rem !important; +} + +[data-md-color-scheme="default"] .md-search__button:hover, +[data-md-color-scheme="default"] .md-search__button:focus, +[data-md-color-scheme="slate"] .md-search__button:hover, +[data-md-color-scheme="slate"] .md-search__button:focus { + background-color: rgba(255, 255, 255, 0.16) !important; +} + +/* Collapsed magnifier */ +[data-md-color-scheme="default"] .md-search__button::before, +[data-md-color-scheme="slate"] .md-search__button::before { + color: #fff !important; + -webkit-text-fill-color: #fff !important; + filter: brightness(0) invert(1) !important; + opacity: 1 !important; +} + +/* If an inner SVG is used in some states */ +[data-md-color-scheme="default"] .md-search__button svg, +[data-md-color-scheme="default"] .md-search__button svg *, +[data-md-color-scheme="slate"] .md-search__button svg, +[data-md-color-scheme="slate"] .md-search__button svg * { + fill: #fff !important; + stroke: #fff !important; + color: #fff !important; +} + +/* Shortcut badge */ +[data-md-color-scheme="default"] .md-search__button kbd, +[data-md-color-scheme="default"] .md-search__button .md-search__kbd, +[data-md-color-scheme="slate"] .md-search__button kbd, +[data-md-color-scheme="slate"] .md-search__button .md-search__kbd { + color: rgba(255, 255, 255, 0.9) !important; + background-color: rgba(255, 255, 255, 0.18) !important; + border: none !important; + box-shadow: none !important; +} + +/* Badge drawn as pseudo-element in some versions */ +[data-md-color-scheme="default"] .md-search__button::after, +[data-md-color-scheme="slate"] .md-search__button::after { + background-color: rgba(255, 255, 255, 0.12) !important; + border: none !important; + box-shadow: none !important; + color: rgba(255, 255, 255, 0.9) !important; +} + +/* ========================================================= + Top tabs + ========================================================= */ + +/* All tab labels white by default */ +[data-md-color-scheme="default"] .md-tabs__link, +[data-md-color-scheme="slate"] .md-tabs__link { + color: #fff !important; + opacity: 0.9 !important; + transition: color 0.15s ease, opacity 0.15s ease !important; +} + +/* Hover state */ +[data-md-color-scheme="default"] .md-tabs__link:hover, +[data-md-color-scheme="slate"] .md-tabs__link:hover { + color: var(--proteus-highlight-color) !important; + opacity: 0.8 !important; +} + +/* Active tab text only, no underline */ +[data-md-color-scheme="default"] .md-tabs__item--active, +[data-md-color-scheme="default"] .md-tabs__link--active, +[data-md-color-scheme="default"] .md-tabs__item--active .md-tabs__link, +[data-md-color-scheme="slate"] .md-tabs__item--active, +[data-md-color-scheme="slate"] .md-tabs__link--active, +[data-md-color-scheme="slate"] .md-tabs__item--active .md-tabs__link { + color: var(--proteus-highlight-color) !important; + box-shadow: none !important; + border-bottom: none !important; + text-decoration: none !important; +} + +/* Remove any underline/pseudo-element indicator */ +[data-md-color-scheme="default"] .md-tabs__item--active::after, +[data-md-color-scheme="default"] .md-tabs__link--active::after, +[data-md-color-scheme="default"] .md-tabs__item--active .md-tabs__link::after, +[data-md-color-scheme="slate"] .md-tabs__item--active::after, +[data-md-color-scheme="slate"] .md-tabs__link--active::after, +[data-md-color-scheme="slate"] .md-tabs__item--active .md-tabs__link::after { + content: none !important; + display: none !important; + background: none !important; +} + +/* ========================================================= + Sidebar navigation + ========================================================= */ + +/* Style only active leaf page links */ +[data-md-color-scheme="default"] .md-nav__item .md-nav__link--active:not(.md-nav__link--passed), +[data-md-color-scheme="slate"] .md-nav__item .md-nav__link--active:not(.md-nav__link--passed) { + background-color: var(--proteus-highlight-bg-soft) !important; + border-radius: 1rem !important; + color: var(--proteus-highlight-color) !important; + padding-left: 1rem; + padding-right: 1rem; +} + +/* ========================================================= + Footer + ========================================================= */ + +/* Remove underline from footer copyright link */ +.md-footer-copyright a, +.md-footer-meta a { + text-decoration: none !important; +} + +/* ========================================================= + Make header title look clickable and add hover effect + ========================================================= */ + +.md-header__title[data-md-component="header-title"] { + cursor: pointer; + transition: opacity 0.15s ease !important; +} + +.md-header__title[data-md-component="header-title"]:hover { + opacity: 0.7 !important; +} diff --git a/docs/stylesheets/subtitle.css b/docs/stylesheets/subtitle.css new file mode 100644 index 0000000..82b7f0f --- /dev/null +++ b/docs/stylesheets/subtitle.css @@ -0,0 +1,5 @@ +.subtitle { + font-size: 1.0rem; + color: var(--md-default-fg-color--light); + margin-top: -0.1rem; +} \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..f5dd01d --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,141 @@ +site_name: SOCRATES +site_url: https://proteus-framework.org/SOCRATES/ +repo_url: https://github.com/FormingWorlds/SOCRATES +repo_name: GitHub + +copyright: '© 2023-2026 Forming Worlds Lab' + +nav: + - Home: + - About: index.md + + - How-to guides: + - Installation: How-to/installation.md + + - Explanations: + - Physical model description: + - Overview: Explanations/overview.md + - Two-stream radiation code: Explanations/two_stream.md + - Spherical harmonic code: Explanations/spherical_harmonic.md + - Spectral files: Explanations/spectral_files.md + - Interface to the calling model: Explanations/interface.md + + - Reference: + - Spectral files: + - MET Office spectral files: Reference/spectral_file_reference.md + - PROTEUS spectral files: Reference/proteus_spectral_file_reference.md + - Documentation PDFs: Reference/documentation_pdfs.md + + + - Community: + - Contact: Community/contact.md + - Code of Conduct: Community/CODE_OF_CONDUCT.md + - Developers: https://proteus-framework.org/people + - Issues: https://github.com/FormingWorlds/SOCRATES/issues + + - Source code: https://github.com/FormingWorlds/SOCRATES + + - Other PROTEUS modules: + - PROTEUS framework: proteus_framework.md + - PROTEUS: https://proteus-framework.org/PROTEUS/ + - MORS: https://proteus-framework.org/MORS/ + - JANUS: https://proteus-framework.org/JANUS/ + - ZEPHYRUS: https://proteus-framework.org/ZEPHYRUS/ + - CALLIOPE: https://proteus-framework.org/CALLIOPE/ + - AGNI: https://www.h-nicholls.space/AGNI/ + - Obliqua: https://proteus-framework.org/Obliqua/ + - VULCAN: https://proteus-framework.org/VULCAN/ + - Zalmoxis: https://proteus-framework.org/Zalmoxis/ + - Aragog: https://proteus-framework.org/aragog/ + - SPIDER: https://proteus-framework.org/SPIDER/ + - Atmodeller: https://atmodeller.readthedocs.io/en/latest/ + - FastChem: https://newstrangeworlds.github.io/FastChem/ + - PLATON: https://platon.readthedocs.io/en/latest/ + +theme: + name: material + custom_dir: docs/overrides + features: + - navigation.tabs + - navigation.tabs.sticky + - navigation.expand + - content.code.copy + - content.tabs.link + + + # Default assets (used unless overridden per palette below) + favicon: assets/PROTEUS_black_on_white_logo_only.png + logo: assets/PROTEUS_white_on_black.png + + palette: + - media: "(prefers-color-scheme: light)" + scheme: default + primary: custom + accent: custom + favicon: assets/PROTEUS_black_on_white_logo_only.png + logo: assets/PROTEUS_white_on_black.png + toggle: + icon: lucide/moon + name: Switch to dark mode + + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: custom + accent: custom + favicon: assets/PROTEUS_white_on_black_logo_only.png + logo: assets/PROTEUS_white_on_black.png + toggle: + icon: lucide/sun + name: Switch to light mode + +markdown_extensions: + - admonition + - attr_list + - markdown_include.include: + base_path: docs + - pymdownx.extra + - pymdownx.arithmatex: + generic: true + - pymdownx.tabbed: + alternate_style: true + - pymdownx.details + - md_in_html + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + +# footer: +extra: + generator: false + social: + - icon: material/web + link: https://proteus-framework.org/ + name: PROTEUS website + - icon: material/email + link: mailto:proteus_dev@formingworlds.space + name: Mail PROTEUS developers + - icon: fontawesome/brands/python + link: https://pypi.org/project/fwl-proteus/ + name: PROTEUS on PyPI + - icon: fontawesome/brands/github + link: https://github.com/FormingWorlds/SOCRATES + name: SOCRATES on GitHub + +extra_javascript: + - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js + - javascripts/header-links.js + +extra_css: + - stylesheets/proteus_theme.css + - stylesheets/subtitle.css + - stylesheets/footnotes.css + +plugins: + - search + +use_directory_urls: false + +watch: + - src/ + - docs/ + - README.md