diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..08df06c --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,25 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + builder: html + configuration: docs/conf.py + fail_on_warning: false + +# Optionally declare the Python requirements required to build your docs +python: + install: + - method: pip + path: . + diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ba31e6..60f0fa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,25 +1,25 @@ # Unreleased + +- Added five parametrisation examples (two DFN parametrisation examples from About:Energy open-source release, blended electrode definition, user-defined 0th-order hysteresis, and SPM parametrisation). ([#45](https://github.com/FaradayInstitution/BPX/pull/45)) - Allow user-defined parameters to be added using the field ["Parameterisation"]["User-defined"] ([#44](https://github.com/pybamm-team/BPX/pull/44)) - Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). - Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/pybamm-team/BPX/pull/33)) - Added validation of the STO limits subbed into the OCPs vs the upper/lower cut-off voltage limits for non-blended electrodes with the OCPs defined as functions ([#32](https://github.com/FaradayInstitution/BPX/pull/32)). The user can provide a tolerance by updating the settings variable `BPX.settings.tolerances["Voltage [V]"]` or by passing extra option `v_tol` to `parse_bpx_file()`, `parse_bpx_obj()` or `parse_bpx_str()` functions. Default value of the tolerance is 1 mV. The tolerance cannot be negative. - Added the target SOC check in `get_electrode_concentrations()` function. Raise a warning if the SOC is outside of [0,1] interval. -- In `get_electrode_stoichiometries()` function, raise a warning instead of an error if the SOC is outside of [0,1] interval. -- Added five parametrisation examples (two DFN parametrisation examples from About:Energy open-source release, blended electrode definition, user-defined 0th-order hysteresis, and SPM parametrisation). -# [v0.3.1](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) +# [v0.3.1](https://github.com/FaradayInstitution/BPX/releases/tag/v0.3.1) -- Temporarily pin Pydantic version ([#35](https://github.com/pybamm-team/BPX/pull/35)) +- Temporarily pin Pydantic version ([#35](https://github.com/FaradayInstitution/BPX/pull/35)) -# [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.0) +# [v0.3.0](https://github.com/FaradayInstitution/BPX/releases/tag/v0.3.0) - Added a missing factor of 2 in the definition of the interfacial current, see the Butler-Volmer equation (2a) in the associated BPX standard document. The interfacial current is now given by $j=2j_0\sinh(F\eta/2/R/T)$ instead of $j=j_0\sinh(F\eta/2/R/T)$. -# [v0.2.0](https://github.com/pybamm-team/BPX/releases/tag/v0.2.0) +# [v0.2.0](https://github.com/FaradayInstitution/BPX/releases/tag/v0.2.0) -- Parsing a BPX json file with additional (unexpected) fields now raises a `ValidationError` ([#16](https://github.com/pybamm-team/BPX/pull/16)) -- Fixed a bug in the experiment schema ([#13](https://github.com/pybamm-team/BPX/pull/13)) +- Parsing a BPX json file with additional (unexpected) fields now raises a `ValidationError` ([#16](https://github.com/FaradayInstitution/BPX/pull/16)) +- Fixed a bug in the experiment schema ([#13](https://github.com/FaradayInstitution/BPX/pull/13)) -# [v0.1.0](https://github.com/pybamm-team/BPX/releases/tag/v0.1.0) +# [v0.1.0](https://github.com/FaradayInstitution/BPX/releases/tag/v0.1.0) Initial release of the Battery Parameter eXchange (BPX) format. diff --git a/docs/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 100% rename from docs/CONTRIBUTING.md rename to CONTRIBUTING.md diff --git a/README.md b/README.md index cab36bd..8cce679 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# BPX -![tests](https://github.com/pybamm-team/BPX/actions/workflows/test.yml/badge.svg) -[![codecov](https://codecov.io/gh/pybamm-team/BPX/branch/main/graph/badge.svg?token=Krv0JW3gYZ)](https://codecov.io/gh/pybamm-team/BPX) +# 🔋 BPX +![tests](https://github.com/FaradayInstitution/BPX/actions/workflows/test.yml/badge.svg) +[![codecov](https://codecov.io/gh/FaradayInstitution/BPX/branch/main/graph/badge.svg?token=Krv0JW3gYZ)](https://codecov.io/gh/FaradayInstitution/BPX) An implementation of the Battery Parameter eXchange (BPX) format in Pydantic. BPX, an outcome of the Faraday Institution [Multi-scale Modelling project](https://www.faraday.ac.uk/research/lithium-ion/battery-system-modelling/), is an open standard for physics-based Li-ion battery models that has been developed to reduce costs and time-to-market through a common definition of physics-based battery models that can be used widely across industry. To find out more, visit the [BPX website](https://bpxstandard.com/). @@ -9,38 +9,26 @@ This repository features a Pydantic-based parser for JSON files in the BPX forma To support the new open standard, [About:Energy](https://www.aboutenergy.io/) have supplied two parameters sets for an NMC and LFP cell. The BPX files and associated examples and information can be found on the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/). To see how to use BPX with [PyBaMM](https://www.pybamm.org/), check out the [BPX example repository](https://github.com/pybamm-team/bpx-example). -## Prerequisites - -- Python 3+ - -## Installation - -Create a new virtual environment, or activate an existing one (this example uses the python `venv` module, but you could use Anaconda and a `conda` environment) - -```bash -python3 -m venv env -source env/bin/activate -``` - -Install the `BPX` module using pip +## 🚀 Installation +The BPX package can be installed using pip ```bash pip install bpx ``` -## Usage - -Create a python script similar to that below +BPX is available on GNU/Linux, MacOS and Windows. We strongly recommend to install PyBaMM within a python [virtual environment](https://docs.python.org/3/tutorial/venv.html), in order not to alter any distribution python files. +## 💻 Usage +To create a BPX object from a JSON file, you can use the `parse_bpx_file` function ```python import bpx filename = 'path/to/my/file.json' my_params = bpx.parse_bpx_file(filename) ``` +`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the `examples` folder, the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/), or the [BPX example repository](https://github.com/pybamm-team/bpx-example). -`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. For example, you can print out the initial temperature of the cell using - +Attributes of the class can be printed out using the standard Python dot notation, for example, you can print out the initial temperature of the cell using ```python print('Initial temperature of cell:', my_params.parameterisation.cell.initial_temperature) ``` @@ -51,15 +39,13 @@ my_params_dict = my_params.dict(by_alias=True) print('Initial temperature of cell:', my_params_dict["Parameterisation"]["Cell"]["Initial temperature [K]"]) ``` -If you want to pretty print the entire object, you can use the `devtools` package to do this (remember to `pip install devtools`) - +The entire BPX object can be pretty printed using the `devtools` package ```python from devtools import pprint pprint(my_params) ``` You can convert any `Function` objects in `BPX` to regular callable Python functions, for example: - ```python positive_electrode_diffusivity = my_params.parameterisation.positive_electrode.diffusivity.to_python_function() diff_at_one = positive_electrode_diffusivity(1.0) @@ -67,9 +53,21 @@ print('positive electrode diffusivity at x = 1.0:', diff_at_one) ``` If you want to output the complete JSON schema in order to build a custom tool yourself, you can do so: - ```python print(bpx.BPX.schema_json(indent=2)) ``` According to the `pydantic` docs, the generated schemas are compliant with the specifications: JSON Schema Core, JSON Schema Validation and OpenAPI. + +## 📖 Documentation +API documentation for the `bpx` package can be built locally using [Sphinx](https://www.sphinx-doc.org/en/master/). To build the documentation first [clone the repository](https://github.com/git-guides/git-clone), then run the following command: +```bash +sphinx-build docs docs/_build/html +``` +This will generate a number of html files in the `docs/_build/html` directory. To view the documentation, open the file `docs/_build/html/index.html` in a web browser, e.g. by running +```bash +open docs/_build/html/index.html +``` + +## 📫 Get in touch +If you have any questions please get in touch via email . diff --git a/bpx/expression_parser.py b/bpx/expression_parser.py index 8994ce8..58aa87d 100644 --- a/bpx/expression_parser.py +++ b/bpx/expression_parser.py @@ -8,6 +8,11 @@ class ExpressionParser: + """ + An expression parser for mathematical expressions. For valid expressions, + please see :class:`bpx.Function`. + """ + ParseException = pp.ParseException def __init__(self): diff --git a/bpx/function.py b/bpx/function.py index e913d58..4a73643 100644 --- a/bpx/function.py +++ b/bpx/function.py @@ -41,6 +41,16 @@ def __repr__(self): return f"Function({super().__repr__()})" def to_python_function(self, preamble: str = None) -> Callable: + """ + Return a python function that can be called with a single argument 'x' + + Parameters + ---------- + preamble: str, optional + A string of python code to be prepended to the function + definition. This can be used to import modules or define + helper functions. + """ if preamble is None: preamble = copy.copy(self.default_preamble) preamble += "\n\n" diff --git a/bpx/interpolated_table.py b/bpx/interpolated_table.py index 9647ef3..a8c3a7b 100644 --- a/bpx/interpolated_table.py +++ b/bpx/interpolated_table.py @@ -4,6 +4,11 @@ class InterpolatedTable(BaseModel): + """ + A table of values that can be interpolated to give a function. The table is defined + by two lists of floats, x and y. The function is defined by interpolation. + """ + x: List[float] y: List[float] diff --git a/bpx/parsers.py b/bpx/parsers.py index 49d9066..f0824ea 100644 --- a/bpx/parsers.py +++ b/bpx/parsers.py @@ -3,9 +3,10 @@ def parse_bpx_file(filename: str, v_tol: float = 0.001) -> BPX: """ + A convenience function to parse a bpx file into a BPX model. + Parameters ---------- - filename: str a filepath to a bpx file v_tol: float @@ -13,7 +14,7 @@ def parse_bpx_file(filename: str, v_tol: float = 0.001) -> BPX: Returns ------- - BPX: + BPX: :class:`bpx.BPX` a parsed BPX model """ if v_tol < 0: @@ -26,9 +27,10 @@ def parse_bpx_file(filename: str, v_tol: float = 0.001) -> BPX: def parse_bpx_obj(bpx: dict, v_tol: float = 0.001) -> BPX: """ + A convenience function to parse a bpx dict into a BPX model. + Parameters ---------- - bpx: dict a dict object in bpx format v_tol: float @@ -36,7 +38,7 @@ def parse_bpx_obj(bpx: dict, v_tol: float = 0.001) -> BPX: Returns ------- - BPX: + BPX: :class:`bpx.BPX` a parsed BPX model """ if v_tol < 0: @@ -49,9 +51,11 @@ def parse_bpx_obj(bpx: dict, v_tol: float = 0.001) -> BPX: def parse_bpx_str(bpx: str, v_tol: float = 0.001) -> BPX: """ + A convenience function to parse a json formatted string in bpx format into a BPX + model. + Parameters ---------- - bpx: str a json formatted string in bpx format v_tol: float diff --git a/bpx/schema.py b/bpx/schema.py index 05df972..13b9921 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -7,6 +7,10 @@ class ExtraBaseModel(BaseModel): + """ + A base model that forbids extra fields + """ + class Config: extra = Extra.forbid @@ -22,6 +26,11 @@ class settings: class Header(ExtraBaseModel): + """ + The header of a BPX file. Contains metadata about the file (e.g. BPX version, + title, description). + """ + bpx: float = Field( alias="BPX", example=1.0, @@ -53,6 +62,11 @@ class Header(ExtraBaseModel): class Cell(ExtraBaseModel): + """ + Cell-level parameters that are not specific to any individual component (electrode, + separator, or electrolyte). + """ + electrode_area: float = Field( alias="Electrode area [m2]", description="Electrode cross-sectional area", @@ -128,6 +142,10 @@ class Cell(ExtraBaseModel): class Electrolyte(ExtraBaseModel): + """ + Electrolyte parameters. + """ + initial_concentration: float = Field( alias="Initial concentration [mol.m-3]", example=1000, @@ -168,6 +186,10 @@ class Electrolyte(ExtraBaseModel): class ContactBase(ExtraBaseModel): + """ + Base class for parameters that are common to electrode and separator components. + """ + thickness: float = Field( alias="Thickness [m]", example=85.2e-6, @@ -176,6 +198,10 @@ class ContactBase(ExtraBaseModel): class Contact(ContactBase): + """ + Class for parameters that are common to electrode and separator components. + """ + porosity: float = Field( alias="Porosity", example=0.47, @@ -189,6 +215,10 @@ class Contact(ContactBase): class Particle(ExtraBaseModel): + """ + Class for particle parameters. + """ + minimum_stoichiometry: float = Field( alias="Minimum stoichiometry", example=0.1, @@ -256,6 +286,10 @@ class Particle(ExtraBaseModel): class Electrode(Contact): + """ + Class for electrode parameters. + """ + conductivity: float = Field( alias="Conductivity [S.m-1]", example=0.18, @@ -264,18 +298,36 @@ class Electrode(Contact): class ElectrodeSingle(Electrode, Particle): + """ + Class for electrode composed of a single active material. + """ + pass class ElectrodeBlended(Electrode): + """ + Class for electrode composed of a blend of active materials. + """ + particle: Dict[str, Particle] = Field(alias="Particle") class ElectrodeSingleSPM(ContactBase, Particle): + """ + Class for electrode composed of a single active material, for use with Single + Particle type models. + """ + pass class ElectrodeBlendedSPM(ContactBase): + """ + Class for electrode composed of a blend of active materials, for use with Single + Particle type models. + """ + particle: Dict[str, Particle] = Field(alias="Particle") @@ -304,6 +356,10 @@ def validate_extra_fields(cls, values): class Experiment(ExtraBaseModel): + """ + A class to store experimental data (time, current, voltage, temperature). + """ + time: List[float] = Field( alias="Time [s]", example=[0, 0.1, 0.2, 0.3, 0.4], @@ -328,6 +384,11 @@ class Experiment(ExtraBaseModel): class Parameterisation(ExtraBaseModel): + """ + A class to store parameterisation data for a cell. Consists of parameters for the + cell, electrolyte, negative electrode, positive electrode, and separator. + """ + cell: Cell = Field( alias="Cell", ) @@ -355,6 +416,12 @@ class Parameterisation(ExtraBaseModel): class ParameterisationSPM(ExtraBaseModel): + """ + A class to store parameterisation data for a cell. Consists of parameters for the + cell, electrolyte, negative electrode, and positive electrode. This class stores the + parameters needed for Single Particle type models. + """ + cell: Cell = Field( alias="Cell", ) @@ -376,6 +443,11 @@ class ParameterisationSPM(ExtraBaseModel): class BPX(ExtraBaseModel): + """ + A class to store a BPX model. Consists of a header, parameterisation, and optional + validation data. + """ + header: Header = Field( alias="Header", ) diff --git a/docs/_static/main.css b/docs/_static/main.css new file mode 100644 index 0000000..9705ee5 --- /dev/null +++ b/docs/_static/main.css @@ -0,0 +1,144 @@ +@import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&family=Open+Sans:ital,wght@0,400;0,600;1,400;1,600&display=swap"); + +.navbar-brand img { + height: 50px; +} + +.navbar-brand { + height: 50px; +} + +body { + font-family: "Open Sans", sans-serif; +} + +pre, +code { + font-size: 100%; + line-height: 155%; +} + +h1 { + font-family: "Lato", sans-serif; + color: #013243; + /* warm black */ +} + +h2 { + color: #4d77cf; + /* han blue */ + letter-spacing: -0.03em; +} + +h3 { + color: #013243; + /* warm black */ + letter-spacing: -0.03em; +} + +/* Style the active version button. + +- latest: orange +- stable: green +- old, PR: red + +Colors from: + +Wong, B. Points of view: Color blindness. +Nat Methods 8, 441 (2011). https://doi.org/10.1038/nmeth.1618 +*/ + +/* If the active version has the name "latest", style it orange */ +.version-switcher__button[data-active-version-name*="latest"] { + background-color: #e69f00; + border-color: #e69f00; + color: #000000; +} + +/* green for `stable` */ +.version-switcher__button[data-active-version-name*="stable"] { + background-color: #009e73; + border-color: #009e73; +} + +/* red for `old` */ +.version-switcher__button:not([data-active-version-name*="latest"], + [data-active-version-name*="stable"]) { + background-color: #980f0f; + border-color: #980f0f; +} + +/* Main page overview cards */ + +.sd-card { + background: #fff; + border-radius: 0; + padding: 30px 10px 20px 10px; + margin: 10px 0px; +} + +.sd-card .sd-card-header { + text-align: center; +} + +.sd-card .sd-card-header .sd-card-text { + margin: 0px; +} + +.sd-card .sd-card-img-top { + height: 52px; + width: 52px; + margin-left: auto; + margin-right: auto; +} + +.sd-card .sd-card-header { + border: none; + background-color: white; + color: #150458 !important; + font-size: var(--pst-font-size-h5); + font-weight: bold; + padding: 2.5rem 0rem 0.5rem 0rem; +} + +.sd-card .sd-card-footer { + border: none; + background-color: white; +} + +.sd-card .sd-card-footer .sd-card-text { + max-width: 220px; + margin-left: auto; + margin-right: auto; +} + +/* Dark theme tweaking */ +html[data-theme="dark"] .sd-card img[src*=".svg"] { + filter: invert(0.82) brightness(0.8) contrast(1.2); +} + +/* Main index page overview cards */ +html[data-theme="dark"] .sd-card { + background-color: var(--pst-color-background); +} + +html[data-theme="dark"] .sd-shadow-sm { + box-shadow: 0 0.1rem 1rem rgba(250, 250, 250, 0.6) !important; +} + +html[data-theme="dark"] .sd-card .sd-card-header { + background-color: var(--pst-color-background); + color: #150458 !important; +} + +html[data-theme="dark"] .sd-card .sd-card-footer { + background-color: var(--pst-color-background); +} + +html[data-theme="dark"] h1 { + color: var(--pst-color-primary); +} + +html[data-theme="dark"] h3 { + color: #0a6774; +} diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..d212099 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,254 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +import bpx + +# Path for repository root +sys.path.insert(0, os.path.abspath("../")) + +# Path for local Sphinx extensions +sys.path.append(os.path.abspath("./sphinxext/")) + + +# -- Project information ----------------------------------------------------- + +project = "BPX" +copyright = "2022-2023, University of Oxford" +author = "Edmund Dickinson, Ivan Korotkin, Martin Robinson, Robert Timms" + +# The short X.Y version +version = bpx.__version__ +# The full version, including alpha/beta/rc tags +release = version + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.mathjax", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", + "sphinx_design", + "sphinx_copybutton", + "myst_parser", + "sphinx_inline_tabs", +] + + +napoleon_use_rtype = True +napoleon_google_docstring = False + +doctest_global_setup = """ +from docs import * +""" + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = ".rst" + +# The master toctree document. +master_doc = "index" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = "en" + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".ipynb_checkpoints"] + +# Suppress warnings generated by Sphinx and/or by Sphinx extensions +suppress_warnings = ["git.too_shallow"] + +# -- Options for HTML output ------------------------------------------------- + +html_theme = "pydata_sphinx_theme" + +html_static_path = ["_static"] + +# Theme + +# pydata theme options (see +# https://pydata-sphinx-theme.readthedocs.io/en/latest/index.html# for more information) +# mostly copied from numpy, scipy, pandas +# html_logo = "_static/logo.png" +# html_favicon = "_static/favicon/favicon.png" + +html_theme_options = { + "icon_links": [ + { + "name": "GitHub", + "url": "https://github.com/FaradayInstitution/BPX", + "icon": "fa-brands fa-square-github", + }, + { + "name": "PyPI", + "url": "https://pypi.org/project/bpx/", + "icon": "fa-solid fa-box", + }, + ], + "collapse_navigation": True, + "external_links": [ + { + "name": "Contributing", + "url": "https://github.com/FaradayInstitution/BPX/tree/develop/CONTRIBUTING.md", + }, + ], + "footer_start": [ + "copyright", + "sphinx-version", + ], + "footer_end": [ + "theme-version", + "last-updated", + ], +} + +html_title = "%s v%s Manual" % (project, version) +html_last_updated_fmt = "%Y-%m-%d" +html_css_files = ["main.css"] +html_context = {"default_mode": "light"} +html_use_modindex = True +html_copy_source = False +html_domain_indices = False +html_file_suffix = ".html" + +htmlhelp_basename = "bpx" + +html_sidebars = {"**": ["sidebar-nav-bs.html"]} + +# For edit button +html_context = { + "github_user": "FaradayInstitution", + "github_repo": "BPX", + "github_version": "main", + "doc_path": "docs/", +} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = "BPXdoc" + + +# -- Options for LaTeX output ------------------------------------------------ + +# Note: we exclude the examples directory from the LaTeX build because it has +# problems with the creation of PDFs on Read the Docs +# https://github.com/readthedocs/readthedocs.org/issues/2045 + +# Detect if we are building LaTeX output through the invocation of the build commands +if any("latex" in arg for arg in sys.argv) or any("latexmk" in arg for arg in sys.argv): + exclude_patterns.append("source/examples/*") + print("Skipping compilation of .ipynb files for LaTeX build.") + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [(master_doc, "BPX.tex", "BPX Documentation", author, "manual")] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [(master_doc, "bpx", "BPX Documentation", [author], 1)] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + master_doc, + "BPX", + "BPX Documentation", + author, + "BPX", + "One line description of project.", + "Miscellaneous", + ) +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ["search.html"] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("https://docs.python.org/3/", None), + "sphinx": ("https://www.sphinx-doc.org/en/master/", None), + "numpy": ("https://numpy.org/doc/stable", None), + "scipy": ("https://docs.scipy.org/doc/scipy", None), + "matplotlib": ("https://matplotlib.org/stable/", None), +} diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..7423b0f --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,24 @@ +.. Root of all bpx docs + +################# +BPX documentation +################# + +.. This TOC defines what goes in the top navbar +.. toctree:: + :maxdepth: 1 + :hidden: + + User Guide + source/api/index + +**Version**: |version| + +**Useful links**: +`Project Home Page `_ | +`Installation `_ | +`Source Repository `_ | +`Issue Tracker `_ | +`Discussions `_ + +BPX, an outcome of the Faraday Institution Multi-scale Modelling project, is an open standard for physics-based Li-ion battery models that has been developed to reduce costs and time-to-market through a common definition of physics-based battery models that can be used widely across industry. diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..27f573b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/source/api/expression_parser.rst b/docs/source/api/expression_parser.rst new file mode 100644 index 0000000..5f74e22 --- /dev/null +++ b/docs/source/api/expression_parser.rst @@ -0,0 +1,5 @@ +Expression Parser +================= + +.. autoclass:: bpx.ExpressionParser + :members: diff --git a/docs/source/api/function.rst b/docs/source/api/function.rst new file mode 100644 index 0000000..0ceb1cb --- /dev/null +++ b/docs/source/api/function.rst @@ -0,0 +1,5 @@ +Function +======== + +.. autoclass:: bpx.Function + :members: diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst new file mode 100644 index 0000000..19e8b61 --- /dev/null +++ b/docs/source/api/index.rst @@ -0,0 +1,24 @@ +.. module:: bpx + +.. _api_docs: + +################# +API documentation +################# + +:Release: |version| +:Date: |today| + +This reference manual details functions, modules, and objects +included in BPX, describing what they are and what they do. +For a high-level introduction to BPX, see the :ref:`user guide `. + +.. toctree:: + :maxdepth: 2 + + expression_parser + function + interpolated_table + parsers + schema + utilities diff --git a/docs/source/api/interpolated_table.rst b/docs/source/api/interpolated_table.rst new file mode 100644 index 0000000..c6dcdcf --- /dev/null +++ b/docs/source/api/interpolated_table.rst @@ -0,0 +1,5 @@ +Interpolated Table +================== + +.. autoclass:: bpx.InterpolatedTable + :members: diff --git a/docs/source/api/parsers.rst b/docs/source/api/parsers.rst new file mode 100644 index 0000000..d5ece0b --- /dev/null +++ b/docs/source/api/parsers.rst @@ -0,0 +1,8 @@ +Parsers +======= + +.. autofunction:: bpx.parse_bpx_str + +.. autofunction:: bpx.parse_bpx_obj + +.. autofunction:: bpx.parse_bpx_file diff --git a/docs/source/api/schema.rst b/docs/source/api/schema.rst new file mode 100644 index 0000000..991f184 --- /dev/null +++ b/docs/source/api/schema.rst @@ -0,0 +1,5 @@ +Schema +====== + +.. autoclass:: bpx.BPX + :members: diff --git a/docs/source/api/utilities.rst b/docs/source/api/utilities.rst new file mode 100644 index 0000000..be4f5bf --- /dev/null +++ b/docs/source/api/utilities.rst @@ -0,0 +1,6 @@ +Utilities +========= + +.. autofunction:: bpx.get_electrode_stoichiometries + +.. autofunction:: bpx.get_electrode_concentrations diff --git a/docs/source/user_guide/getting_started.md b/docs/source/user_guide/getting_started.md new file mode 100644 index 0000000..0c99f41 --- /dev/null +++ b/docs/source/user_guide/getting_started.md @@ -0,0 +1,43 @@ +# Getting Started + +To get started, first install the `BPX` following the instructions given in [](installation). + +To create a BPX object from a JSON file, you can use the `parse_bpx_file` function +```python +import bpx + +filename = 'path/to/my/file.json' +my_params = bpx.parse_bpx_file(filename) +``` +`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/) or [BPX example repository](https://github.com/pybamm-team/bpx-example). + +Attributes of the class can be printed out using the standard Python dot notation, for example, you can print out the initial temperature of the cell using +```python +print('Initial temperature of cell:', my_params.parameterisation.cell.initial_temperature) +``` + +Alternatively, you can export the `BPX` object as a dictionary and use the string names (aliases) of the parameters from the standard +```python +my_params_dict = my_params.dict(by_alias=True) +print('Initial temperature of cell:', my_params_dict["Parameterisation"]["Cell"]["Initial temperature [K]"]) +``` + +The entire BPX object can be pretty printed using the `devtools` package +```python +from devtools import pprint +pprint(my_params) +``` + +You can convert any `Function` objects in `BPX` to regular callable Python functions, for example: +```python +positive_electrode_diffusivity = my_params.parameterisation.positive_electrode.diffusivity.to_python_function() +diff_at_one = positive_electrode_diffusivity(1.0) +print('positive electrode diffusivity at x = 1.0:', diff_at_one) +``` + +If you want to output the complete JSON schema in order to build a custom tool yourself, you can do so: +```python +print(bpx.BPX.schema_json(indent=2)) +``` + +According to the `pydantic` docs, the generated schemas are compliant with the specifications: JSON Schema Core, JSON Schema Validation and OpenAPI. diff --git a/docs/source/user_guide/index.md b/docs/source/user_guide/index.md new file mode 100644 index 0000000..f6981f2 --- /dev/null +++ b/docs/source/user_guide/index.md @@ -0,0 +1,16 @@ +(user_guide)= + +# BPX user guide + +This guide is an overview and explains the important features; +details are found in [](api_docs). + +```{toctree} +--- +caption: Contributing +maxdepth: 1 +--- + +installation +getting_started +``` diff --git a/docs/source/user_guide/installation.md b/docs/source/user_guide/installation.md new file mode 100644 index 0000000..97e1921 --- /dev/null +++ b/docs/source/user_guide/installation.md @@ -0,0 +1,50 @@ +# Installation +We recommend installing within a [virtual environment](https://docs.python.org/3/tutorial/venv.html) in order to not alter any python distribution files on your machine. + +## Linux/Mac OS + +To install BPX on Linux/Mac OS use the following terminal commands: + +1. Create a virtual environment + +```bash +virtualenv env +``` + +2. Activate the virtual environment + +```bash +source env/bin/activate +``` + +3. Install the `bpx` package + +```bash +pip install bpx +``` + +## Windows + +To install BPX on Windows use the following commands: + +1. Create a virtual environment + +```bash +python -m virtualenv env +``` + +2. Activate the virtual environment + +```bash +env\Scripts\activate +``` + +where `env` is the path to the environment created in step 3 (e.g. `C:\Users\'Username'\env\Scripts\activate.bat`). + +3. Install the `bpx` package + +```bash +pip install bpx +``` + +As an alternative, you can set up [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about). This allows you to run a full Linux distribution within Windows. diff --git a/pyproject.toml b/pyproject.toml index a1da97c..584f1b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,7 @@ authors = [{name = "Martin Robinson", email = "martin.robinson@dtc.ox.ac.uk"}] readme = "README.md" dynamic = ["version", "description"] dependencies = [ + "devtools", "pydantic<2", "pyparsing", ] @@ -16,4 +17,11 @@ dependencies = [ dev = [ 'coverage', # Coverage checking 'flake8>=3', # Style checking + "sphinx>=6", + "sphinx_rtd_theme>=0.5", + "pydata-sphinx-theme", + "sphinx_design", + "sphinx-copybutton", + "myst-parser", + "sphinx-inline-tabs", ]