diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 7b7d495..b925da4 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -5,25 +5,25 @@ on: - master - main permissions: - contents: write + 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/checkout@v4 - - name: Configure Git Credentials - run: | - git config user.name github-actions[bot] - git config user.email 41898282+github-actions[bot]@users.noreply.github.com + - uses: actions/configure-pages@v5 + - uses: actions/checkout@v5 - uses: actions/setup-python@v5 with: python-version: 3.x - - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - - uses: actions/cache@v4 + - run: pip install zensical markdown-include pymdown-extensions mkdocstrings mkdocstrings-python + - run: zensical build --clean + - uses: actions/upload-pages-artifact@v4 with: - key: mkdocs-material-${{ env.cache_id }} - path: ~/.cache - restore-keys: | - mkdocs-material- - - run: pip install mkdocs-material markdown-include pymdown-extensions mkdocstrings mkdocstrings-python - - run: mkdocs gh-deploy --force + path: site + - uses: actions/deploy-pages@v4 + id: deployment \ No newline at end of file diff --git a/README.md b/README.md index 911e17a..e532de2 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,16 @@ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/release/python-3100/) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) -[![Documentation Status](https://readthedocs.org/projects/aragog/badge/?version=latest)](https://aragog.readthedocs.io/en/latest/?badge=latest) -[![Python package](https://github.com/ExPlanetology/aragog/actions/workflows/python-package.yml/badge.svg)](https://github.com/ExPlanetology/aragog/actions/workflows/python-package.yml) - -## Under development - -This code remains under active development, hence the interface is not stable and should not be relied upon. +[![Documentation](https://github.com/FormingWorlds/aragog/actions/workflows/docs.yaml/badge.svg)](https://proteus-framework.org/aragog) +[![Tests](https://github.com/FormingWorlds/aragog/actions/workflows/ci_tests.yml/badge.svg)](https://github.com/FormingWorlds/aragog/actions/workflows/ci_tests.yml) ## About -Aragog is a Python package that computes the 1-D interior dynamics of rocky mantles that are solid, liquid, or mixed phase. It is mostly a pure Python version of the [SPIDER code](https://github.com/djbower/spider) originally written in C albeit with some differences. Note that the atmosphere module in the original SPIDER code is now supported by a separate and more comprehensive Python package Atmodeller (release forthcoming). +Aragog is a Python package that computes the 1-D interior dynamics of rocky mantles that are solid, liquid, or mixed phase. It is mostly a pure Python version of the [SPIDER code](https://github.com/FormingWorlds/SPIDER) originally written in C albeit with some differences. Note that the atmosphere module in the original SPIDER code is now supported by a separate and more comprehensive Python package Atmodeller. -Documentation: +Documentation: -Source code: +Source code: ## Citation @@ -30,37 +26,67 @@ Open access versions of the publication are available: ## Installation +> **Note:** The standard way of installing this version of Aragog is within the PROTEUS Framework, as described in the [PROTEUS installation guide](https://proteus-framework.org/PROTEUS/installation.html#9-install-submodules-as-editable). + ### Quick install The basic procedure is to install Aragog into a Python environment. For example, if you are using a Conda distribution to create and manage Python environments (e.g. [Anaconda](https://www.anaconda.com/download)), create a new environment noting that Aragog requires Python >= 3.10. Once created, make sure to activate the environment. To achieve this, terminal commands are given below, but you can also use the Anaconda Navigator (or similar GUI) to create and activate environments: - conda create -n aragog python - conda activate aragog +```sh +conda create -n aragog python +conda activate aragog +``` Alternatively, you can create and activate a [virtual environment](https://docs.python.org/3/library/venv.html). Finally, install Aragog into the activated environment: - pip install aragog +```sh +pip install fwl-aragog +``` ### Developer install -> - See this [guide](https://gist.github.com/djbower/c66474000029730ac9f8b73b96071db3) to develop Aragog using [VS Code](https://code.visualstudio.com) and [Poetry](https://python-poetry.org). -> - See this [guide](https://gist.github.com/djbower/c82b4a70a3c3c74ad26dc572edefdd34) to develop Aragog if you are a Windows or Spyder user. - Navigate to a location on your computer and obtain the source code using git: - git clone git@github.com:ExPlanetology/aragog.git aragog - cd aragog +```sh +git clone git@github.com:FormingWorlds/aragog.git aragog +cd aragog +``` + +Install Aragog into the environment using either: (a) [Poetry](https://python-poetry.org), or (b) [pip](https://pip.pypa.io/en/stable/getting-started/). + +There are some subtle differences between Poetry and pip, but in general Aragog is configured to be interoperable for most common operations (e.g. see this [Gist](https://gist.github.com/djbower/e9538e7eb5ed3deaf3c4de9dea41ebcd)). + +(a) Poetry option, which requires that [Poetry](https://python-poetry.org) is installed: + +```sh +poetry install --with docs +``` + +(b) pip option, where the ``-e`` option is for an [editable install](https://setuptools.pypa.io/en/latest/userguide/development_mode.html): + +```sh +pip install -e ".[docs]" +``` + +If desired, you will need to manually install the dependencies for the tests, which are automatically installed by Poetry but not by pip. See the additional dependencies to install in `pyproject.toml`. + +More comprehensive set up guides are available here: -Install Aragog into the environment using either (a) [Poetry](https://python-poetry.org) or (b) [pip](https://pip.pypa.io/en/stable/getting-started/). There are some subtle differences between Poetry and pip, but in general Aragog is configured to be interoperable for most common operations (e.g. see this [Gist](https://gist.github.com/djbower/e9538e7eb5ed3deaf3c4de9dea41ebcd)). +- [VS Code and Poetry guide](https://gist.github.com/djbower/c66474000029730ac9f8b73b96071db3) +- [Windows and Spyder guide](https://gist.github.com/djbower/c82b4a70a3c3c74ad26dc572edefdd34) -- (a) Poetry option, which requires that [Poetry](https://python-poetry.org) is installed: +### Download data from the OSF repository - poetry install --all-extras +Aragog requires lookup table data storing thermophysics properties of the liquid and solid matter. These data are stored in an [OSF repository](https://osf.io/phsxf/) and on a [Zenodo record](https://zenodo.org/records/15728072). You can download it with the command: -- (b) pip option, where the `-e` option is for an [editable install](https://setuptools.pypa.io/en/latest/userguide/development_mode.html): +```sh +aragog download all +``` - pip install -e ".[docs]" +The command `aragog env` will give you the path where the data have been downloaded. If you want to set up your own path, setup the environment variable `FWL_DATA` before running the download command: - If desired, you will need to manually install the dependencies for the tests, which are automatically installed by Poetry but not by `pip`. See the additional dependencies to install in `pyproject.toml`. \ No newline at end of file +```sh +export FWL_DATA=your_absolute_path/ +``` diff --git a/docs/CODE_OF_CONDUCT.md b/docs/Community/CODE_OF_CONDUCT.md similarity index 100% rename from docs/CODE_OF_CONDUCT.md rename to docs/Community/CODE_OF_CONDUCT.md diff --git a/docs/Community/contact.md b/docs/Community/contact.md new file mode 100644 index 0000000..e71bf68 --- /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/aragog/issues) | Bug reports, specific feature requests | +| [proteus_dev@formingworlds.space](mailto:proteus_dev@formingworlds.space) | General enquiries | diff --git a/docs/Explanations/enthalpy_balance.md b/docs/Explanations/enthalpy_balance.md new file mode 100644 index 0000000..d595984 --- /dev/null +++ b/docs/Explanations/enthalpy_balance.md @@ -0,0 +1,110 @@ +# Aragog: model overview + +## Enthalpy balance + +We start with the enthalpy balance in integral form: + +$$\int_V \rho c_p \left.\frac{\partial T}{\partial t}\right|_\xi \, dV = -\oint_S \mathbf{q} \cdot \mathbf{n} \, dS + \int_V \Phi \, dV \tag{1}$$ + +where $T$ is the effective temperature of the melting medium, assuming thermal equilibrium between solid and melt phases. Mass coordinates $\xi$ are used (see Sec. 1.3), but integration is performed over a physical domain of volume $V$ and surface boundary $S$. Any control volume $V$ is assumed to coincide with a material volume that does not evolve in time — the mass of each volume is constant and there is no mass flux at the interfaces. + +Spherical symmetry is assumed and only spatial variations along the radial direction are considered. In what follows, only the radial component of vector quantities is retained. The enthalpy balance, heat fluxes, and heat sources are implemented in Aragog in [`solver.py`](https://github.com/FormingWorlds/aragog/blob/main/aragog/solver.py). + +--- + +## 1.1 Heat fluxes + +The total heat flux is defined as the sum of the conductive ($q_{cd}$), convective ($q_{cv}$), convective mixing ($q_{cm}$), and gravitational separation ($q_{gm}$) contributions: + +$$q_{tot} = q_{cd} + q_{cv} + q_{cm} + q_{gm} \tag{2}$$ + +The **conductive flux** is: + +$$q_{cd} = -\lambda \frac{\partial T}{\partial r} \tag{3}$$ + +The **convective flux** is modelled as: + +$$q_{cv} = -\rho c_p \kappa_h \left(\frac{\partial T}{\partial r} - \left.\frac{\partial T}{\partial r}\right|_S\right) \tag{4}$$ + +where the adiabatic temperature gradient (temperature gradient at constant entropy $S$) is: + +$$\left.\frac{\partial T}{\partial r}\right|_S = -\frac{g \alpha T}{c_p} \tag{5}$$ + +The **convective mixing flux** and the **gravitational separation flux** are enthalpy fluxes associated with corresponding mass fluxes: + +$$q_{cm} + q_{gm} = \Delta h \left(j_{cm} + j_{gm}\right) \tag{6}$$ + +where $j_{cm}$ and $j_{gm}$ are mass fluxes associated with the melt (the corresponding fluxes for the solid are $-j_{cm}$ and $-j_{gm}$, such that the sum of species mass fluxes is zero). + +The **mass diffusion flux of melt** is: + +$$j_{cm} = -\rho \kappa_h \frac{\partial \phi}{\partial r} \tag{7}$$ + +where $\phi$ is the mass fraction of melt (defined in Sec. 2.1). The mass diffusivity is assumed equal to the eddy diffusivity $\kappa_h$. + +The **melt mass flux associated with gravitational separation** is: + +$$j_{gm} = \rho \phi (1 - \phi) v_{rel} \tag{8}$$ + +where $v_{rel}$ is the relative velocity between melt and solid: + +$$v_{rel} = \frac{(\rho_m - \rho_s) g K}{\eta_m} \tag{9}$$ + +Both mass fluxes $j_{cm}$ and $j_{gm}$ are zero outside the mixed-phase region. + +--- + +## 1.2 Heat sources + +The volumetric heat sources considered are: + +$$\Phi = \Phi_{tidal} + \Phi_{radio} + \Phi_{vol} \tag{10}$$ + +associated with tidal heating, radiogenic heating, and volumetric dilatation or compression, respectively. + +The **volumetric dilatation/compression** source is expressed as a function of the mass fluxes: + +$$\Phi_{vol} = \rho g \left(\frac{1}{\rho_m} - \frac{1}{\rho_s}\right)(j_{cm} + j_{gm}) \tag{11}$$ + +The **radiogenic heating** is defined as: + +$$\Phi_{radio} = \sum_i \rho \phi_i \chi_i \exp\left(-\frac{t - t_0}{\tau^{1/2}_i}\right) \tag{12}$$ + +where $\phi_i$, $\chi_i$, and $\tau^{1/2}_i$ are the power generation per unit mass, the mass fraction, and the half-life associated with radioisotope $i$, respectively. The radiogenic heating is time-dependent but spatially uniform. + +The **tidal heating** volume source must be provided by the user. It can be spatially dependent but is constant in time. + +--- + +## 1.3 Mass coordinates + +Mass coordinates $\xi$ (in unit length) correspond to a change of variable from the spatial coordinate $r$, such that the mass contained in an element $\Delta\xi$ is constant regardless of depth. + +The transformation from spatial to mass coordinates is: + +$$\xi(r) = \left[3\int_{r_{cmb}}^{r} \frac{\rho^*(r')}{\rho^*_{planet}} r'^2 \, dr' + \xi_{cmb}^3\right]^{1/3} \tag{13}$$ + +where $\rho^*_{planet}$ is the volume-averaged density of the planet and $\rho^*$ is the local mantle density. The mass coordinate at the core-mantle boundary (CMB) is defined as: + +$$\xi_{cmb} = \left(\frac{\rho^*_{core}}{\rho^*_{planet}}\right)^{1/3} r_{cmb} \tag{14}$$ + +where $\rho^*_{core}$ is the volume-averaged density of the core. Using the volume-averaged planetary density as a scaling quantity ensures that the spatial coordinate and the mass coordinate coincide at the surface: + +$$\xi_{top} = r_{top} \tag{15}$$ + +which equals the planetary radius. The reverse transformation from mass coordinates back to spatial coordinates is: + +$$r(\xi) = \left[3\int_{\xi_{cmb}}^{\xi} \frac{\rho^*_{planet}}{\rho^*(\xi')} \xi'^2 \, d\xi' + r_{cmb}^3\right]^{1/3} \tag{16}$$ + +The spatial gradient of any quantity $\psi$ is computed according to: + +$$\frac{\partial \psi}{\partial r} = \frac{\rho^*(r)}{\rho^*_{planet}} \left(\frac{r}{\xi}\right)^2 \frac{\partial \psi}{\partial \xi} \tag{17}$$ + +!!! note + If the spatial mesh is uniform, the mass coordinate mesh will generally not be uniform. The notation $\rho^*$ for density will be clarified in the [next section](thermodynamics.md). + +If this transformation is ignored and spatial coordinates are used directly, the convective derivative term in the enthalpy balance is neglected, i.e.: + +$$\left.\frac{\partial T}{\partial t}\right|_\xi \simeq \left.\frac{\partial T}{\partial t}\right|_r \tag{18}$$ + +Mass coordinates are implemented in Aragog in [`mesh.py`](https://github.com/FormingWorlds/aragog/blob/main/aragog/mesh.py). \ No newline at end of file diff --git a/docs/Explanations/numerical_methods.md b/docs/Explanations/numerical_methods.md new file mode 100644 index 0000000..bc28290 --- /dev/null +++ b/docs/Explanations/numerical_methods.md @@ -0,0 +1,109 @@ +# Aragog: model overview + +## Numerical methods + +The solver for the enthalpy balance is implemented in [`solver.py`](https://github.com/FormingWorlds/aragog/blob/main/aragog/solver.py). Spatial approximation routines (gradients, interpolations) are found in [`mesh.py`](https://github.com/FormingWorlds/aragog/blob/main/aragog/mesh.py). Boundary conditions and the initial condition are implemented in [`core.py`](https://github.com/FormingWorlds/aragog/blob/main/aragog/core.py). + +--- + +## 4.1 Finite-volume method + +Spatial integration of Eq. (1) in a finite-volume fashion, over a spherical layer $i$ bounded by radii $r_{i-1/2}$ and $r_{i+1/2}$, gives: + +$$(\rho c_p V)_i \left.\frac{\partial T}{\partial t}\right|_i = -q_{i+1/2} S_{i+1/2} + q_{i-1/2} S_{i-1/2} + \Phi_i V_i \tag{47}$$ + +with $S_{i+1/2} = 4\pi r_{i+1/2}^2$ and $V_i = \frac{4}{3}\pi\left(r_{i+1/2}^3 - r_{i-1/2}^3\right)$. + +Volume terms are evaluated at cell centers of the mass coordinate mesh, while surface terms are evaluated at cell boundaries. A **dual mesh** approach maps quantities between staggered nodes (cell centers) and basic nodes (boundaries). + +A uniform spatial mesh of constant spacing $\Delta r$ is used between the surface $r_{top}$ and the core-mantle boundary $r_{cmb}$. This mesh is then mapped into mass coordinates as described in Sec. 1.3. The mesh is defined in terms of basic nodes such that the spatial and mass coordinate meshes overlap at cell boundaries ($\xi_{i+1/2} = \xi(r_{i+1/2})$) but not at cell centers ($\xi_i \neq \xi(r_i)$). + +Physical quantities at basic nodes (cell boundaries) are approximated from quantities at staggered nodes (cell centers) via simple **linear interpolation**: + +$$\psi(\xi_{i+1/2}) = \frac{\Delta\xi_i\, \psi(\xi_{i+1}) + \Delta\xi_{i+1}\, \psi(\xi_i)}{\Delta\xi_i + \Delta\xi_{i+1}} \tag{48}$$ + +where $\Delta\xi_i = \xi_{i+1/2} - \xi_{i-1/2}$ is the cell width. + +**Spatial gradients** at basic nodes are approximated as: + +$$\left.\frac{\partial \psi}{\partial \xi}\right|_{\xi_{i+1/2}} = \frac{\psi(\xi_{i+1}) - \psi(\xi_i)}{\xi_{i+1} - \xi_i} \tag{49}$$ + +!!! Note + The state of the system at the outer and inner boundaries is not defined by Eqs. (48) and (49); any quantity $\psi$ or $\partial\psi/\partial\xi$ is unknown at $\xi_{cmb}$ and $\xi_{top}$. + +The energy balance is implemented in **non-dimensional** form, using reference values for temperature, time, radius, and density, such that the order of magnitude of each physical quantity is close to one. + +--- + +## 4.2 Boundary conditions + +### 4.2.1 Neumann boundary condition + +A Neumann boundary condition, where the total heat flux $q_{tot}$ is imposed at the inner or outer boundary (or both), applies naturally in a finite-volume formulation. However, the individual components of the heat flux (and the thermal state) remain unknown at the boundary. To estimate these, a **linear extrapolation** from the two closest interior points is applied. + +For the core-mantle boundary, with $i = 1$ denoting the lowermost cell: + +$$\psi_{cmb} = \frac{2\Delta\xi_1 + \Delta\xi_2}{\Delta\xi_1 + \Delta\xi_2}\,\psi(r_1) - \frac{\Delta\xi_1}{\Delta\xi_1 + \Delta\xi_2}\,\psi(r_2) \tag{50}$$ + +$$\left.\frac{\partial \psi}{\partial \xi}\right|_{cmb} = \left(\frac{\Delta\xi_2}{\Delta\xi_1} + 1\right)\frac{\psi(\xi_2) - \psi(\xi_1)}{\xi_2 - \xi_1} - \frac{\Delta\xi_2}{\Delta\xi_1}\frac{\psi(\xi_3) - \psi(\xi_2)}{\xi_3 - \xi_2} \tag{51}$$ + +Similar relationships apply at the top boundary. These provide estimates of the individual flux components, which may not be strictly consistent with the imposed total heat flux value, though this does not affect the time evolution. + +At the top of the planet, the heat flux can optionally be expressed as **radiative exchange** between the ground and a blackbody atmosphere: + +$$q_{top} = \varepsilon\sigma\left(T_{top}^4 - T_{atm}^4\right) \tag{52}$$ + +where $\varepsilon$ is the emissivity of the ground. Equation (52) is technically a mixed boundary condition (involving the unknown surface temperature), but it is implemented as a flux boundary condition using a surface temperature extrapolated from the inner node via an expression analogous to Eq. (50). + +### 4.2.2 Dirichlet Boundary Condition + +When a Dirichlet boundary condition is applied (i.e., the temperature is imposed at a boundary), the thermal state is fully defined at that boundary. The temperature gradient (and the melt fraction gradient) must be computed accordingly to obtain correct heat fluxes. + +For the **top boundary**, with $i = N$ being the uppermost cell and $\xi_{top} = \xi_{N+1/2}$: + +$$\left.\frac{\partial \psi}{\partial \xi}\right|_{top} = \frac{\psi_{top} - \psi(\xi_N)}{\xi_{top} - \xi_N} \tag{53}$$ + +For the **core-mantle boundary**, with $i = 1$ being the lowermost cell and $\xi_{cmb} = \xi_{1/2}$: + +$$\left.\frac{\partial \psi}{\partial \xi}\right|_{cmb} = \frac{\psi(\xi_1) - \psi_{cmb}}{\xi_1 - \xi_{cmb}} \tag{54}$$ + +### 4.2.3 Core-cooling model + +When using a flux boundary condition at the core-mantle boundary, the following **core cooling model** may be used to estimate $q_{cmb}$. + +Starting from the enthalpy balance of the core: + +$$(\rho c_p V)_{core} \frac{dT_{core}}{dt} = -S_{cmb}\, q_{cmb} \tag{55}$$ + +The core temperature $T_{core}$ is assumed to be linearly related to the temperature of the lowermost cell $T_1$, as are their time derivatives: + +$$T_{core} \simeq \hat{T}_{core}\, T_1, \qquad \frac{\partial T_{core}}{\partial t} \simeq \hat{T}_{core} \frac{\partial T_1}{\partial t} \tag{56}$$ + +using the proportionality constant $\hat{T}_{core} = 1.147$ (see Ref. [1]). + +The thermal balance at the lowermost cell $i = 1$ gives: + +$$(\rho c_p V)_1 \left.\frac{\partial T}{\partial t}\right|_1 = -q_{1+1/2}\, S_{1+1/2} + q_{cmb}\, S_{cmb} \tag{57}$$ + +Combining Eqs. (55) and (57) with the scaling of Eq. (56) yields the following estimate for the CMB heat flux: + +$$q_{cmb} = \frac{S_{1+1/2}}{S_{core}} \left[1 + \frac{(\rho c_p V)_1}{(\rho c_p V)_{core}\,\hat{T}_{core}}\right]^{-1} q_{1+1/2} \tag{58}$$ + +!!! Note + Volumetric heating rates have been neglected in Eqs. (55) and (57) in deriving this expression. + +--- + +## 4.3 Time integration + +Equation (47) is integrated in time using an **implicit multi-step variable-order backward differentiation** method. + +Although any temperature field may be provided as an initial condition, the default is to begin the time integration on an **adiabat**, such that: + +$$\frac{\partial T}{\partial r} = \left.\frac{\partial T}{\partial r}\right|_S = -\frac{g\alpha T}{c_p} \tag{59}$$ + +In the general case, this equation is solved numerically since $g$, $\alpha$, and $c_p$ are spatially dependent. When these properties are constant, the following analytical temperature profile is obtained: + +$$T(r) = T_{top} \exp\left(\frac{g\alpha}{c_p}(r_{top} - r)\right) \tag{60}$$ + +with $T_{top}$ being the surface temperature. This profile is then mapped onto the mass coordinate mesh. \ No newline at end of file diff --git a/docs/Explanations/thermodynamics.md b/docs/Explanations/thermodynamics.md new file mode 100644 index 0000000..5b6c2b8 --- /dev/null +++ b/docs/Explanations/thermodynamics.md @@ -0,0 +1,53 @@ +# Aragog: model overview + +## Thermodynamics + +Temperature is the only prognostic variable. The pressure is computed following a given equation of state in [`mesh.py`](https://github.com/FormingWorlds/aragog/blob/main/aragog/mesh.py). The melt fraction is calculated as a function of pressure and temperature in [`phase.py`](https://github.com/FormingWorlds/aragog/blob/main/aragog/phase.py). + +--- + +## 2.1 Melt fraction + +The mass fraction of the melt $\phi$ is defined as follows: + +$$\phi = \begin{cases} +0 & T < T_{sol} \\ +\dfrac{T - T_{sol}}{T_{liq} - T_{sol}} & T_{sol} \leq T \leq T_{liq} \\ +1 & T > T_{liq} +\end{cases} \tag{19}$$ + +The mass fraction of the solid is correspondingly $1 - \phi$. The solidus $T_{sol}$ and liquidus $T_{liq}$ temperatures are assumed to depend solely on pressure, with $T_{liq} > T_{sol}$. + +--- + +## 2.2 Pressure + +The **Adams–Williamson model** is the default model used to derive the relationship between pressure and radius, assuming constant gravitational acceleration. It is also possible to specify arbitrary relationships between pressure, radius, and pseudo-density from a planetary structure calculation, in discretized form, which additionally allows for spatially dependent gravitational acceleration. + +The Adams–Williamson model assumes an exponential relationship between density and pressure: + +$$\rho^*(P) = \rho^*_{top} \exp\left(\frac{P}{B}\right) \tag{20}$$ + +where $B$ is the adiabatic bulk modulus and $\rho^*_{top}$ is the density at the surface. The notation $\rho^*$ emphasizes that this is a **pseudo-density** used to estimate the pressure field and the mass of each control volume (assumed constant in time). It may differ to a limited extent from the actual density $\rho$ used for solving thermal transport, which varies due to phase change. The pressure field is assumed to not vary in time. + +A balance between pressure forces and weight gives: + +$$\frac{dP}{dr} = -\rho^*(P)\, g \tag{21}$$ + +Integrating this expression yields the pressure field: + +$$P(r) = -B \log\left(1 + \frac{\rho^*_{top}\, g\, (r - r_{top})}{B}\right) \tag{22}$$ + +Equation (22) assumes zero surface pressure, but the integration can be performed for any surface pressure. + +The pseudo-density field as a function of radius is: + +$$\rho^*(r) = \frac{\rho^*_{top}\, B}{B + \rho^*_{top}\, g\, (r - r_{top})} \tag{23}$$ + +The total mass of the mantle $M$ is retrieved by integrating the pseudo-density field from the core-mantle boundary $r_{cmb}$ to the surface $r_{top}$: + +$$M = \int_{r_{cmb}}^{r_{top}} \rho^*(r)\, 4\pi r^2 \, dr \tag{24}$$ + +$$= \int_{r_{cmb}}^{r_{top}} \frac{4\pi B}{g} \frac{r^2}{\beta + r} \, dr, \qquad \beta = \frac{B}{\rho^*_{top}\, g} - r_{top} \tag{25}$$ + +$$= \frac{4\pi B}{g} \left[-3\beta^2 - 2\beta r + \frac{r^2}{2} + \beta^2 \log|\beta + r|\right]_{r_{cmb}}^{r_{top}} \tag{26}$$ \ No newline at end of file diff --git a/docs/Explanations/transport.md b/docs/Explanations/transport.md new file mode 100644 index 0000000..2f07de0 --- /dev/null +++ b/docs/Explanations/transport.md @@ -0,0 +1,112 @@ +# Aragog: model overview + +## Transport properties + +Transport properties in Aragog are implemented in [`phase.py`](https://github.com/FormingWorlds/aragog/blob/main/aragog/phase.py), except for the eddy diffusivity, which is found in [`solver.py`](https://github.com/FormingWorlds/aragog/blob/main/aragog/solver.py). + +--- + +## 3.1 Thermophysical properties + +All thermophysical quantities — density $\rho$, conductivity $\lambda$, heat capacity $c_p$, thermal expansion coefficient $\alpha$, and dynamic viscosity $\eta$ — are assumed to be functions of both temperature and pressure. Properties in the melt phase and solid phase are denoted with subscripts $m$ and $s$, respectively. + +In the **mixed phase region**, the density is estimated as: + +$$\frac{1}{\rho} = \frac{\phi}{\rho_m} + \frac{1 - \phi}{\rho_s} \tag{27}$$ + +As noted in Sec. 2.2, this density may differ from the pseudo-density $\rho^*$ used to estimate the pressure field. + +The **thermal conductivity** in the mixed phase is: + +$$\lambda = \phi \lambda_m + (1 - \phi) \lambda_s \tag{28}$$ + +The **dynamic viscosity** in the mixed phase is formulated to capture the rheological transition, where the aggregate viscosity changes abruptly between the melt and solid viscosity at a critical melt fraction [1]: + +$$\log_{10} \eta = z \log_{10}(\eta_m) + (1 - z) \log_{10}(\eta_s) \tag{29}$$ + +$$z(\phi) = \frac{1}{2}\left[1 + \tanh\left(\frac{\phi - \phi^\eta_c}{\Delta\phi^\eta_w}\right)\right] \tag{30}$$ + +where $\phi^\eta_c$ is the rheological transition melt fraction and $\Delta\phi^\eta_w$ is the rheological transition width. These are input parameters motivated by geochemical experiments. + +The **heat capacity** and **thermal expansivity** in the mixed phase region are expressed following Ref. [2] as: + +$$c_p = \left.\frac{\partial h}{\partial T}\right|_P = c_p^0 + \Delta h \left.\frac{\partial \phi}{\partial T}\right|_P \simeq \frac{\Delta h}{T_{liq} - T_{sol}} \tag{31}$$ + +$$\alpha = \rho \left.\frac{\partial (1/\rho)}{\partial T}\right|_P = \alpha^0 + \frac{\rho}{\rho_m \rho_s} \Delta\rho \left.\frac{\partial \phi}{\partial T}\right|_P \simeq \frac{\rho_s - \rho_m}{\rho(T_{liq} - T_{sol})} \tag{32}$$ + +where the phase-change terms dominate, such that $c_p \gg c_p^0$ and $\alpha \gg \alpha^0$. The definition of the adiabatic temperature gradient in Eq. (5) still holds in the mixed phase region with the corresponding thermophysical properties. + +The **porosity** in the mixed phase is defined as: + +$$\zeta = \frac{\rho_s - \rho}{\rho_s - \rho_m} \tag{33}$$ + +It is related to the melt fraction as: + +$$\frac{\rho_m}{\rho}\zeta = \phi, \qquad \frac{\rho_s}{\rho}(1 - \zeta) = (1 - \phi) \tag{34}$$ + +Because the melt fraction is not a continuous quantity and some properties exhibit a jump at the mixed-phase boundaries, an **additional smoothing** is applied to all thermophysical quantities $\beta$. + +Near the interface between the mixed phase and the **melt**: + +$$\tilde{\beta} = z_m(\phi^*)\,\beta_m + (1 - z_m(\phi^*))\,\beta \tag{35}$$ + +$$z_m(\phi^*) = \frac{1}{2}\left[1 + \tanh\left(\frac{\phi^* - 1}{\Delta\phi^*_w}\right)\right] \tag{36}$$ + +Near the interface between the mixed phase and the **solid**: + +$$\tilde{\beta} = z_s(\phi^*)\,\beta + (1 - z_s(\phi^*))\,\beta_s \tag{37}$$ + +$$z_s(\phi^*) = \frac{1}{2}\left[1 + \tanh\left(\frac{\phi^*}{\Delta\phi^*_w}\right)\right] \tag{38}$$ + +where $\phi^* = \frac{T - T_{sol}}{T_{liq} - T_{sol}}$ is the extended melt fraction profile (with $\phi^* < 0$ in the solid phase and $\phi^* > 1$ in the melt phase), and $\Delta\phi^*_w$ is the phase transition width. For the kinematic viscosity, this smoothing is applied in logarithmic space. + +--- + +## 3.2 Eddy diffusivity + +The eddy diffusivity, which affects the convective flux (Eq. 4) and convective mixing flux (Eq. 7), is derived from **mixing length theory**. It equals the product of a velocity scale and the mixing length, and depends on the flow regime: + +$$\kappa_h = \begin{cases} +0 & \text{for } Re = 0 \\ +u_{visc}\, l & \text{for } 0 \leq Re \leq 9/8 \\ +u_{invis}\, l & \text{for } Re > 9/8 +\end{cases} \tag{39}$$ + +where $l$ is the mixing length and $Re = u_{visc}\,l/\nu$ is the Reynolds number based on the viscous velocity. The velocity scales are: + +$$u_{visc} = -\frac{\alpha g l^3}{18\nu}\left(\frac{\partial T}{\partial r} - \left.\frac{\partial T}{\partial r}\right|_S\right) \tag{40}$$ + +$$u_{invis} = \sqrt{-\frac{\alpha g l^2}{16}\left(\frac{\partial T}{\partial r} - \left.\frac{\partial T}{\partial r}\right|_S\right)} \tag{41}$$ + +The necessary condition for convection to occur is: + +$$\frac{\partial T}{\partial r} - \left.\frac{\partial T}{\partial r}\right|_S < 0 \tag{42}$$ + +and the velocity is set to zero if this condition is not satisfied. + +The **mixing length** $l$ is either set constant according to the size of the domain: + +$$l = 0.25\,(r_{top} - r_{cmb}) \tag{43}$$ + +or set equal to the distance to the nearest boundary: + +$$l(r) = \min(r_{top} - r,\; r - r_{cmb}) \tag{44}$$ + +--- + +## 3.3 Permeability + +The permeability factor $K$ in Eq. (9), which affects the gravitational separation flux, depends on the porosity $\zeta$ and varies with the flow regime [3]: + +$$K = \begin{cases} +\dfrac{2}{9} a^2 & \zeta > 0.771462 \quad \text{(Stokes)} \\[8pt] +0.001\, a^2 \dfrac{\zeta^2}{(1 - \zeta)^2} & 0.0769452 \leq \zeta \leq 0.771462 \quad \text{(Blake–Kozeny–Carman)} \\[8pt] +\dfrac{5}{7} a^2 \zeta^{4.5} & \zeta < 0.0769452 \quad \text{(Rumpf–Gupte)} +\end{cases} \tag{45}$$ + +This expression comes from Ref. [3], where the derivation uses a factor $F(\phi)$ as a function of melt fraction related to the permeability factor by: + +$$K = a^2 \frac{(\rho_s - \rho_m)\phi + \rho_m}{\rho\,\phi(1 - \phi)}\,F(\phi) \tag{46}$$ + +!!! Note + The condition $\zeta > \beta$ is equivalent to $\phi > \rho_m / (\gamma \rho_s + \rho_m)$ using $\gamma = (1 - \beta)/\beta$. \ No newline at end of file diff --git a/docs/How-to/installation.md b/docs/How-to/installation.md index f06e99a..67293d4 100644 --- a/docs/How-to/installation.md +++ b/docs/How-to/installation.md @@ -17,7 +17,7 @@ Alternatively, you can create and activate a [virtual environment](https://docs. Finally, install Aragog into the activated environment: ```sh -pip install aragog +pip install fwl-aragog ``` ## Developer install diff --git a/docs/Reference/api.md b/docs/Reference/api/api_overview.md similarity index 51% rename from docs/Reference/api.md rename to docs/Reference/api/api_overview.md index 570a0b1..7bfb588 100644 --- a/docs/Reference/api.md +++ b/docs/Reference/api/api_overview.md @@ -1,6 +1,6 @@ # API overview -This is a detailed overview of Aragog's API for the user's reference. If you want to understand the underlying model, please visit the [model overview](../Explanations/model.md). +This is a detailed overview of Aragog's API for the user's reference. If you want to understand the underlying model, please visit the [model overview](../Explanations/enthalpy_balance.md). ## Directory structure @@ -37,83 +37,4 @@ Aragog is structured around a small number of components: 3. **Phase/property evaluators** ([`phase.py`](https://github.com/FormingWorlds/aragog/tree/main/aragog/phase.py), [`interfaces.py`](https://github.com/FormingWorlds/aragog/tree/main/aragog/interfaces.py)) 4. **State evaluation (fluxes, heating)** ([`solver.py`](https://github.com/FormingWorlds/aragog/tree/main/aragog/solver.py)) 5. **Time integration** ([`solver.py`](https://github.com/FormingWorlds/aragog/tree/main/aragog/solver.py) → `scipy.integrate.solve_ivp`) -6. **Postprocessing and export** ([`output.py`](https://github.com/FormingWorlds/aragog/tree/main/aragog/output.py)) - -## Module reference - -### aragog.cli -::: aragog.cli - options: - members: true - inherited_members: true - show_source: true - -### aragog.data -::: aragog.data - options: - members: true - inherited_members: true - show_source: true - -### aragog.core -::: aragog.core - options: - members: true - inherited_members: true - show_source: true - -### aragog.interfaces -::: aragog.interfaces - options: - members: true - inherited_members: true - show_source: true - -### aragog.mesh -::: aragog.mesh - options: - members: true - inherited_members: true - show_source: true - -### aragog.output -::: aragog.output - options: - members: true - inherited_members: true - show_source: true - -### aragog.parser -::: aragog.parser - options: - members: true - inherited_members: true - show_source: true - -### aragog.phase -::: aragog.phase - options: - members: true - inherited_members: true - show_source: true - -### aragog.solver -::: aragog.solver - options: - members: true - inherited_members: true - show_source: true - -### aragog.utilities -::: aragog.utilities - options: - members: true - inherited_members: true - show_source: true - -### aragog (package) -::: aragog - options: - members: true - inherited_members: true - show_source: true +6. **Postprocessing and export** ([`output.py`](https://github.com/FormingWorlds/aragog/tree/main/aragog/output.py)) \ No newline at end of file diff --git a/docs/Reference/api/core.md b/docs/Reference/api/core.md new file mode 100644 index 0000000..4433116 --- /dev/null +++ b/docs/Reference/api/core.md @@ -0,0 +1,7 @@ +# aragog.core +::: aragog.core + options: + members: true + inherited_members: true + show_source: true + diff --git a/docs/Reference/api/data.md b/docs/Reference/api/data.md new file mode 100644 index 0000000..8263fc9 --- /dev/null +++ b/docs/Reference/api/data.md @@ -0,0 +1,6 @@ +# aragog.data +::: aragog.data + options: + members: true + inherited_members: true + show_source: true \ No newline at end of file diff --git a/docs/Reference/api/interfaces.md b/docs/Reference/api/interfaces.md new file mode 100644 index 0000000..a218723 --- /dev/null +++ b/docs/Reference/api/interfaces.md @@ -0,0 +1,6 @@ +# aragog.interfaces +::: aragog.interfaces + options: + members: true + inherited_members: true + show_source: true \ No newline at end of file diff --git a/docs/Reference/api/mesh.md b/docs/Reference/api/mesh.md new file mode 100644 index 0000000..be10ad0 --- /dev/null +++ b/docs/Reference/api/mesh.md @@ -0,0 +1,6 @@ +# aragog.mesh +::: aragog.mesh + options: + members: true + inherited_members: true + show_source: true \ No newline at end of file diff --git a/docs/Reference/api/output.md b/docs/Reference/api/output.md new file mode 100644 index 0000000..ca1ff71 --- /dev/null +++ b/docs/Reference/api/output.md @@ -0,0 +1,6 @@ +# aragog.output +::: aragog.output + options: + members: true + inherited_members: true + show_source: true \ No newline at end of file diff --git a/docs/Reference/api/package.md b/docs/Reference/api/package.md new file mode 100644 index 0000000..86d4baa --- /dev/null +++ b/docs/Reference/api/package.md @@ -0,0 +1,6 @@ +# aragog (package) +::: aragog + options: + members: true + inherited_members: true + show_source: true diff --git a/docs/Reference/api/parser.md b/docs/Reference/api/parser.md new file mode 100644 index 0000000..3ee7c7f --- /dev/null +++ b/docs/Reference/api/parser.md @@ -0,0 +1,6 @@ +# aragog.parser +::: aragog.parser + options: + members: true + inherited_members: true + show_source: true \ No newline at end of file diff --git a/docs/Reference/api/phase.md b/docs/Reference/api/phase.md new file mode 100644 index 0000000..10065e3 --- /dev/null +++ b/docs/Reference/api/phase.md @@ -0,0 +1,6 @@ +# aragog.phase +::: aragog.phase + options: + members: true + inherited_members: true + show_source: true \ No newline at end of file diff --git a/docs/Reference/api/solver.md b/docs/Reference/api/solver.md new file mode 100644 index 0000000..065ae0d --- /dev/null +++ b/docs/Reference/api/solver.md @@ -0,0 +1,6 @@ +# aragog.solver +::: aragog.solver + options: + members: true + inherited_members: true + show_source: true \ No newline at end of file diff --git a/docs/Reference/api/utilities.md b/docs/Reference/api/utilities.md new file mode 100644 index 0000000..a33d287 --- /dev/null +++ b/docs/Reference/api/utilities.md @@ -0,0 +1,6 @@ +# aragog.utilities +::: aragog.utilities + options: + members: true + inherited_members: true + show_source: true \ No newline at end of file diff --git a/docs/Tutorials/firstrun.md b/docs/Tutorials/firstrun.md index deb6c7c..c9c027a 100644 --- a/docs/Tutorials/firstrun.md +++ b/docs/Tutorials/firstrun.md @@ -11,9 +11,9 @@ Get to a **first successful model run** and a **NetCDF output and plots**. ## Assumptions - You're using Python 3.10+ (3.12 recommended). - - You hava Aragog installed according to the [installation instructions](../How-to/installation.md). + - You have Aragog installed according to the [installation instructions](../How-to/installation.md). -## 1. OPTIONAL: Choose a data directory +## 1. Choose a data directory [optional] Aragog’s data helper uses `FWL_DATA` to decide where lookup tables/logs go. If you have not set this up yet, set it to something you control: 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..ff84c46 --- /dev/null +++ b/docs/getting_started.md @@ -0,0 +1,52 @@ +# Getting started + +!!! note "Usage within the PROTEUS framework" + Aragog is most commonly installed and used as integrated into the PROTEUS framework. Understand how to use PROTEUS [here](https://proteus-framework.org/PROTEUS). + +## Quick path + +Here is the quickest path to getting started: + +1. **Install Aragog** + Follow the installation steps.
+ → [Installation guide](How-to/installation.md) + +2. **Run your first model**
+ Follow a minimal example run and generate a quick plot.
+ → [First run tutorial](Tutorials/firstrun.md) + +--- + +## What do you want to do? + +
+ +- :material-download: **Install** + + [Go to installation guide](How-to/installation.md) + +- :material-rocket-launch: **Run Aragog** + + [Go to tutorials](Tutorials/first_run.md) + +- :material-book-open-variant: **Understand the model** + + [Go to model overview](Explanations/enthalpy_balance.md) + +- :material-bookshelf: **Check Aragog publications** + + [Go to publications](Reference/publications.md) + +- :material-github: **Browse API** + + [Go to API reference](Reference/api/api_overview.md) + +- :material-bug: **Raise an issue** + + [Go to issues](https://github.com/FormingWorlds/Aragog/issues) + +- :material-email: **Get in touch** + + [Go to contact](Community/contact.md) + +
\ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 79c4bd7..b90c75b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,36 +1,14 @@ -# Aragog (PROTEUS Framework) +# Aragog -**Aragog** is an open-source Python package for computing one-dimensional interior dynamics of rocky planets, including partially molten and fully solid regimes. +**Aragog** is an open-source Python package for computing one-dimensional interior dynamics of rocky planets, including partially molten and fully solid regimes. It is the interior evolution model of the PROTEUS exoplanet modelling framework. !!! note This documentation describes the version integrated into the [PROTEUS framework](https://proteus-framework.org/PROTEUS). For documentation of the original project, see [ExPlanetology](https://aragog.readthedocs.io). -**License:** [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html) - -## Getting started - -- If you want learning oriented, step-by-step instructions, follow the **Tutorials** section. -- If you want task-oriented recipes for common workflows, go to **How-to guides**. -- If you want concepts and model background, see **Explanations**. -- If you want reference information such as function and parameter lookup, see **Reference**. - -An easy way to get started is to go through our [First Run tutorial](Tutorials/firstrun.md). -If you plan to contribute to aragog, please read our [Code of Conduct](CODE_OF_CONDUCT.md). +If you plan to contribute to Aragog, please read our [Code of Conduct](Community/CODE_OF_CONDUCT.md). If you are running into problems, please do not hesitate to raise an [issue](https://github.com/FormingWorlds/aragog/issues). -### Installation -Follow the project’s installation instructions: - -- [Installation guide](How-to/installation.md) - -## Code availability -- [PROTEUS distribution (Forming Worlds)](https://github.com/FormingWorlds/aragog) -- [Upstream repository (ExPlanetology)](https://github.com/Explanetology/aragog) +**License:** [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html) ## Citation -If you use Aragog, please cite: - -Bower, D.J., Sanan, P., & Wolf, A.S. (2018). *Numerical solution of a non-linear conservation law applicable to the interior dynamics of partially molten planets*. **Physics of the Earth and Planetary Interiors**, 274, 49–62. [https://doi.org/10.1016/j.pepi.2017.11.004](https://doi.org/10.1016/j.pepi.2017.11.004) -## Open-access versions -- [arXiv](https://arxiv.org/abs/1711.07303) -- [EarthArXiv](https://eartharxiv.org/repository/view/1535/) +Bower, D.J., Sanan, P., & Wolf, A.S. (2018). *Numerical solution of a non-linear conservation law applicable to the interior dynamics of partially molten planets*. **Physics of the Earth and Planetary Interiors**, 274, 49–62. [https://doi.org/10.1016/j.pepi.2017.11.004](https://doi.org/10.1016/j.pepi.2017.11.004) \ No newline at end of file diff --git a/docs/javascripts/header-links.js b/docs/javascripts/header-links.js new file mode 100644 index 0000000..7f1f768 --- /dev/null +++ b/docs/javascripts/header-links.js @@ -0,0 +1,28 @@ +console.log("header-links.js loaded"); + +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 /SPIDER/ when hosted there, else "/" (mkdocs serve) + const href = location.href; + const docsHome = href.includes("/SPIDER/") + ? href.split("/SPIDER/")[0] + "/SPIDER/" + : 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/proteus_framework.md b/docs/proteus_framework.md new file mode 100644 index 0000000..4256a2b --- /dev/null +++ b/docs/proteus_framework.md @@ -0,0 +1,20 @@ +

+ +
+ + +
+
+

+ +Aragog is the interior evolution module 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/extra.css b/docs/stylesheets/docstrings.css similarity index 100% rename from docs/stylesheets/extra.css rename to docs/stylesheets/docstrings.css 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/mkdocs.yml b/mkdocs.yml index 57d4a32..f9b12cf 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,8 +3,12 @@ site_url: https://proteus-framework.org/aragog repo_url: https://github.com/FormingWorlds/aragog repo_name: GitHub +copyright: '© 2023-2026 Forming Worlds Lab' + nav: - - Home: index.md + - Home: + - About: index.md + - Getting started: getting_started.md - How-to guides: - Installation: How-to/installation.md @@ -14,65 +18,89 @@ nav: - First run: Tutorials/firstrun.md - Explanations: - - Model overview: Explanations/model.md + - Model overview: + - Enthalpy balance: Explanations/enthalpy_balance.md + - Thermodynamics: Explanations/thermodynamics.md + - Transport: Explanations/transport.md + - Numerical methods: Explanations/numerical_methods.md + - Reference: - - API reference: Reference/api.md + - API reference: + - Overview: Reference/api/api_overview.md + - Core: Reference/api/core.md + - Mesh: Reference/api/mesh.md + - Interfaces: Reference/api/interfaces.md + - Solver: Reference/api/solver.md + - Phases: Reference/api/phase.md + - Utilities: Reference/api/utilities.md + - Parser: Reference/api/parser.md + - Data: Reference/api/data.md + - Output: Reference/api/output.md + - Package: Reference/api/package.md + - Publications: Reference/publications.md - - Code of Conduct: CODE_OF_CONDUCT.md + - Community: + - Code of Conduct: Community/CODE_OF_CONDUCT.md + - Contact: Community/contact.md + - Developers: https://proteus-framework.org/people + - Source code: https://github.com/FormingWorlds/aragog - - Issues page: https://github.com/FormingWorlds/aragog/issues - - 🔗 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/ - - 🔗 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/ + + - Other PROTEUS modules: + - PROTEUS submodules: 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/ + - 🔗 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/ + - 🔗 SOCRATES: https://proteus-framework.org/SOCRATES/ 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: - # Auto: follow system preference (and show a toggle) - media: "(prefers-color-scheme: light)" scheme: default - primary: black - accent: deep orange + primary: custom + accent: custom favicon: assets/PROTEUS_black_on_white_logo_only.png logo: assets/PROTEUS_white_on_black.png toggle: - icon: material/weather-night + icon: lucide/moon name: Switch to dark mode - media: "(prefers-color-scheme: dark)" scheme: slate - primary: black - accent: deep orange + primary: custom + accent: custom favicon: assets/PROTEUS_white_on_black_logo_only.png logo: assets/PROTEUS_white_on_black.png toggle: - icon: material/weather-sunny + icon: lucide/sun name: Switch to light mode -extra_css: - - stylesheets/extra.css - markdown_extensions: - admonition - attr_list @@ -81,44 +109,72 @@ markdown_extensions: - 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-aragog/ + name: PROTEUS on PyPI + - icon: fontawesome/brands/github + link: https://github.com/FormingWorlds/aragog + name: PROTEUS on GitHub extra_javascript: - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js + - javascripts/header-links.js + +extra_css: + - stylesheets/docstrings.css + - stylesheets/proteus_theme.css plugins: -- search -- mkdocstrings: - # https://mkdocstrings.github.io/usage/ - handlers: - python: - paths: [src] - inventories: - - https://installer.readthedocs.io/en/stable/objects.inv - - https://docs.python.org/3/objects.inv - - https://numpy.org/doc/stable/objects.inv - - https://docs.scipy.org/doc/scipy/objects.inv - - https://pandas.pydata.org/docs/objects.inv - - https://matplotlib.org/stable/objects.inv - options: - docstring_style: numpy - docstring_options: - ignore_init_summary: yes - show_submodules: no - show_source: true - show_symbol_type_heading: True - show_root_heading: true - show_root_toc_entry: true - show_docstring_attributes: true - show_root_full_path: false - docstring_section_style: list - members_order: alphabetical - merge_init_into_class: yes - filters: ["!^_"] - docstring_section_style: list + - search + - mkdocstrings: + handlers: + python: + paths: [aragog] + inventories: + - https://installer.readthedocs.io/en/stable/objects.inv + - https://docs.python.org/3/objects.inv + - https://numpy.org/doc/stable/objects.inv + - https://docs.scipy.org/doc/scipy/objects.inv + - https://pandas.pydata.org/docs/objects.inv + - https://matplotlib.org/stable/objects.inv + options: + docstring_style: numpy + docstring_section_style: table + docstring_options: + ignore_init_summary: yes + show_submodules: no + show_source: true + show_symbol_type_heading: true + show_root_heading: true + show_root_toc_entry: true + show_docstring_attributes: true + show_root_full_path: false + members_order: alphabetical + merge_init_into_class: yes + filters: ["!^_"] use_directory_urls: false watch: - aragog/ - docs/ - - README.md \ No newline at end of file + - README.md + - CODE_OF_CONDUCT.md diff --git a/pyproject.toml b/pyproject.toml index 4ec18e2..8474336 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,7 @@ pytest-dependency = ">=1.0.0" [tool.poetry.group.docs.dependencies] +zensical = "*" markdown-include = "^0.8" mkdocs = "^1.6" mkdocs-material = "^9.5" @@ -57,6 +58,7 @@ mkdocs-bibtex = "^4.4.0" [tool.poetry.extras] docs = [ + "zensical", "markdown-include", "mkdocs", "mkdocs-material",