diff --git a/LICENSE b/LICENSE index 5f716e7..f553220 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2021, Politecnico di Torino, MuSyChEn group developers +Copyright (c) 2023, Politecnico di Torino, MuSyChEn group developers All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index 6227708..3e9ace4 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,91 @@ # Wet Synthesis -A collection of wrappers around solvers to simulate the wet-synthesis of Ni-Mn-Co Hydroxides -*Contact*: [Mohsen Shiea](mailto:mohsen.shiea@polito.it), + + +A collection of [SimPhoNy](https://github.com/simphony/simphony-osp) +[wrappers](https://simphony.readthedocs.io/en/v3.9.0/overview.html#fetch-data-from-a-database-run-a-simulation-and-immediately-store-the-results) +around a CFD-PBE solver to simulate the wet-synthesis of Ni-Mn-Co Hydroxides. + +- CFD-PBE Wrapper: This wrapper prepares a simulation case folder based on the + user inputs and executes a solver for Computational Fluid Dynamics-Population + Balance Equation (CFD-PBE) simulation of NMC hydroxide precipitation. + +- Compartment Wrapper: This wrapper is aimed at simulating the NMC hydroxide + precipitation in a pilot CSTR reactor, by using the compartment model. + Currently, it can be used only to divide the reactor into the compartments. + +*Contact*: [Andrea Querio](mailto:andrea.querio@polito.it), [Daniele Marchisio](mailto:daniele.marchisio@polito.it), [Antonio Buffo](mailto:antonio.buffo@polito.it) and [Gianluca Boccardo](mailto:gianluca.boccardo@polito.it) from the -Multiphase Systems and Chemical Engineering research group, Politecnico di Torino. +[Multiphase Systems and Chemical Engineering research group](https://www.disat.polito.it/research/research_groups/musychen), +[Politecnico di Torino](https://www.polito.it/). -**Index** -- [Wet Synthesis](#Wet-Synthesis) - - [CFD-PBE Wrapper](#CFD-PBE-Wrapper) - - [Compartment Wrapper](#Compartment-Wrapper) - - [Compatibility](#Compatibility) - - [Requirements](#Requirements) - - [Installation](#Installation) - - [Docker Container](#Docker-Container) - - [Usage](#Usage) + -## CFD-PBE Wrapper -This wrapper prepares a simulation case folder based on the user inputs and executes a solver for Computational Fluid Dynamics-Population Balance Equation (CFD-PBE) simulation of NMC hydroxide precipitation. -## Compartment Wrapper -This wrapper is aimed at simulating the NMC hydroxide precipitation in a pilot CSTR reactor, by using the compartment model. Currently, it can be used only to divide the reactor into the compartments. +## Installation -## Requirements -- [OSP core](https://github.com/simphony/osp-core) -- [OpenFOAM](https://openfoam.org/) -- [Ansys Fluent](https://www.ansys.com/products/fluids/ansys-fluent) -- [7-zip](https://www.7-zip.org/) + -## Compatibility +The wet synthesis wrappers require a working installation of +[OpenFOAM 8](https://openfoam.org/version/8/), +[SUNDIALS](https://github.com/LLNL/sundials) +([v6.1.1](https://github.com/LLNL/sundials/releases/tag/v6.1.1) is known to +work), +[7-zip](https://www.7-zip.org/), +[Anaconda3](https://www.anaconda.com/) +([v4.8.2](https://repo.anaconda.com/archive/) is known to work), and the [CFD-PBE solver from the GitHub repository of Politecnico di Torino](https://github.com/mulmopro/wet-synthesis-route). Follow the links to find +installation instructions for each tool. -The following table describes the version compatibility between the [OSP core](https://github.com/simphony/osp-core) package and documentation presented in this project. +Once the requirements have been installed, clone the Wet Synthesis Wrappers +repository and install them. -| __Wrapper development__ | __OSP core__ | -|:-----------------------:|:------------:| -| 1.0.0 | 3.4.x | +```shell +git clone https://github.com/simphony/simdome_wet_synthesis.git +pip install ./simdome_wet_synthesis +``` -The releases of OSP core are available [here](https://github.com/simphony/osp-core). +Then install the required ontology. -## Installation -### ontology: -```sh -pico install ontology.wet_synthesis.yml +```shell +pico install simdome_wet_synthesis/ontology.wet_synthesis.yml # If you have issues using pico directly, you can use -python -m osp.core.pico install ontology.wet_synthesis.yml +# python -m osp.core.pico install simdome_wet_synthesis/ontology.wet_synthesis.yml ``` -### wrappers: -```sh -python3 setup.py install -apt-get install graphviz + + + + + +### Docker + +Alternatively, it is possible to execute the wrapper in a Docker container. +Clone the repository and enter the newly created directory + +```shell +git clone https://github.com/simphony/simdome_wet_synthesis.git +cd simdome_wet_synthesis ``` -More information can be found in the documentation for [installation of OSP core](https://simphony.readthedocs.io/en/latest/installation.html) -## Docker Container -### Image creation: +and then run + ```sh -./docker_install.sh +docker build -t simdome/wet_synthesis . ``` -### Launch container: + +to create the docker image. After that, run + ```sh ./run_container.sh ``` -## Usage -Two scripts are provided in the folder "examples" for the usage of the wrappers. It should be noted that the user is responsible for providing the OpenFOAM solver or Ansys Fluent executables. Moreover, the user should place the template case folders and mesh files in the corresponding folders found in the address "osp/wrappers/wet_synthesis_wrappers/cases/precNMC". +to get access to a shell inside a container based on the image that has just +been built. + + + +## Documentation + +Visit [the documentation](https://simdomewetsynthesis.readthedocs.io) +to learn how to use the wrappers. diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..d2db4d3 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,54 @@ +"""Configuration file for the Sphinx documentation builder.""" + +# --- Project information --- # + +project = "Wet Synthesis" +copyright = ( + "2023, Multiphase Systems and Chemical Engineering research group," + "Politecnico di Torino" +) +author = ( + "Multiphase Systems and Chemical Engineering research group," + "Politecnico di Torino" +) + +# --- General configuration --- # + +extensions = [ + "myst_parser", # Markdown support + "sphinx.ext.autodoc", # API reference + "sphinx.ext.napoleon", # Google and NumPy style docstrings support + "sphinx.ext.viewcode", # Link to source in API reference + "sphinx_copybutton", # Copy button for code blocks + "nbsphinx", # Jupyter notebook support + "IPython.sphinxext.ipython_console_highlighting", # Syntax highlighting + "sphinx.ext.autosectionlabel", # Auto-generate section labels. + "sphinx_panels", # Show panels in a grid layout or as drop-downs +] + +master_doc = "index" + +myst_heading_anchors = 5 + +suppress_warnings = ["autosectionlabel.*"] +exclude_patterns = ["**.ipynb_checkpoints"] +nbsphinx_allow_errors = False + + +# --- HTML output options --- # +html_theme = "sphinx_book_theme" +html_favicon = "static/favicon.png" # Noto Sans open book emoji +html_logo = "static/logo.png" +html_theme_options = { + "github_url": "https://github.com/simphony/simdome_wet_synthesis", + "repository_url": "https://github.com/simphony/simdome_wet_synthesis", + "use_repository_button": True, + "repository_branch": "main", + "path_to_docs": "docs", + "logo_only": True, + "show_navbar_depth": 1, +} + + +html_static_path = ["static"] +html_css_files = ["custom.css"] diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..18b51c1 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,15 @@ +# Wet Synthesis + +```{include} ../README.md + :start-after: + :end-before: +``` + +```{toctree} +:hidden: true +:maxdepth: 2 + +installation +usage +Licence +``` diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..adc3dfa --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,26 @@ +# Installation + +```{include} ../README.md + :start-after: + :end-before: +``` + +```{note} +OpenFOAM uses a collection of files packed together in a so-called +"case folder" as input. The Wet Synthesis Wrappers include templates for those +case folders, that are modified before running each simulation according to the +parameters passed from SimPhoNy in the form of +[CUDS objects](https://simphony.readthedocs.io/en/v3.9.0/jupyter/cuds_api.html) +(see the [usage section](./usage.md)). + +Such templates are included in the Python package, in the folder +`osp/wrappers/wet_synthesis_wrappers/cases`. If you wish OpenFOAM to behave +in a way that is not covered by the parameters that are passed from SimPhoNy, +then you will have to modify the case folder templates before installing the +package. +``` + +```{include} ../README.md + :start-after: + :end-before: +``` diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..20fbd1b --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,10 @@ +jinja2 >= 3.0.3, < 4 +jupyter >= 1.0.0, < 2 +markupsafe >= 2.1.1, < 3 +myst-parser >= 0.18.0, < 0.19 +nbsphinx >= 0.8.9, < 0.9 +sphinx >= 4.4.0, < 5 +sphinx-autobuild==2021.3.14 +sphinx_book_theme >= 0.3.2, < 0.4 +sphinx-copybutton >= 0.5.0, < 0.6 +sphinx-panels >= 0.6.0, < 0.7 diff --git a/docs/static/custom.css b/docs/static/custom.css new file mode 100644 index 0000000..23853a6 --- /dev/null +++ b/docs/static/custom.css @@ -0,0 +1,25 @@ +.caption-text, +h1, +h2, +h3, +h4 { + color: #6580a1 !important; +} + +.btn-outline-primary { + border-color: #6580a1 !important; +} + +.btn-outline-primary:hover { + background-color: #6580a1 !important; + color: azure !important; +} + +@media (min-width: 1200px) { + .container-xl { + max-width: 1550px; + } + #site-navigation { + max-width: 20%; + } +} diff --git a/docs/static/favicon.png b/docs/static/favicon.png new file mode 100644 index 0000000..902ba57 Binary files /dev/null and b/docs/static/favicon.png differ diff --git a/docs/static/graph_pattern.drawio.svg b/docs/static/graph_pattern.drawio.svg new file mode 100644 index 0000000..57885fe --- /dev/null +++ b/docs/static/graph_pattern.drawio.svg @@ -0,0 +1,4 @@ + + + +
ns:Compartment
ns:Compartment
ns: <http://www.osp-core.com/wet_synthesis#>
ns: <http://www.osp-core.com/wet_synthesis#>
value
ns:type
value...
ns:Class
ns:Class
Ontology individual belonging to class <ns:Class>. 
Ontology individual belonging to class <ns:Cla...
ns:rel
ns:rel
Ontology relationship <ns:rel>. 
Ontology relationship <ns:rel>. 
ns:attr
ns:attr
Ontology attribute <ns:attr>. 
Ontology attribute <ns:attr>. 
xsd: <https://www.w3.org/2001/XMLSchema#>
xsd: <https://www.w3.org/2001/XMLSchema#>
Attribute value "value" with data type <ns:type>. 
Attribute value "value" with data type <ns:typ...
ns:WetSynthesisWrapper
ns:WetSynthesisWrapper
ns:SliderAccuracyLevel
ns:SliderAccuracyLevel
"0"
xsd:integer
"0"...
ns:number
ns:number
ns:hasPart
ns:hasPa...
ns:Pressure
ns:Pressure
ns:Temperature
ns:Temperature
ns:value
ns:value
"101325"
ns:float
"101325"...
ns:unit
ns:unit
"Pa"
xsd:string
"Pa"...
ns:value
ns:value
"298.15"
xsd:float
"298.15"...
ns:unit
ns:unit
"K"
xsd:string
"K"...
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
ns:RotationalSpeed
ns:RotationalSpeed
ns:value
ns:value
"200"
xsd:float
"200"...
ns:unit
ns:unit
"rpm"
xsd:string
"rpm"...
ns:hasPart
ns:hasPa...
ns:Density
ns:Density
ns:unit
ns:unit
"kg/m^3"
xsd:string
"kg/m^3"...
ns:value
ns:value
"3953"
xsd:float
"3953"...
ns:MolecularWeight
ns:MolecularWeight
ns:value
ns:value
"92.338"
xsd:float
"92.338"...
ns:unit
ns:unit
"g/mol"
xsd:string
"g/mol"...
ns:ShapeFactor
ns:ShapeFactor
ns:value
ns:value
"0.523599"
xsd:float
"0.523599"...
ns:unit
ns:unit
ns:SolidParticle
ns:SolidParticle
ns:hasProperty
ns:hasPr...
ns:hasProperty
ns:hasPr...
ns:hasProperty
ns:hasPr...
ns:Feed
ns:Feed
ns:name
ns:name
"nh3"
xsd:string
"nh3"...
ns:hasPart
ns:hasPa...
ns:Component
ns:Component
ns:name
ns:name
"nh3"
xsd:string
"nh3"...
ns:MolarConcentration
ns:MolarConcentration
ns:hasPart
ns:hasPa...
ns:value
ns:value
"10"
xsd:float
"10"...
ns:unit
ns:unit
"mol/lit"
xsd:string
"mol/lit"...
ns:FlowRate
ns:FlowRate
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
ns:value
ns:value
"0.30666132"
xsd:float
"0.30666132"...
ns:unit
ns:unit
"lit/hr"
xsd:string
"lit/hr"...
ns:SizeDistribution
ns:SizeDistribution
ns:hasPart
ns:hasPa...
""
xsd:string
""...
SliderAccuracyLevel should be
be between 0-10:
- 0-5: Compartment approach
- 6-10: Directly coupled CFD

However, at the moment the
accuracy level is ignored. The
kind of session used determines
the approach used (directly
coupled CFD or Compartment),
and for each approach there is
only one mesh available.
SliderAccuracyLevel should be...
Example value,
can be set
differently
Example value,...
Example value,
can be set
differently
Example value,...
Example value,
can be set differently
Example value,...
Example value,
can be set differently
Example value,...
Example value,
can be set differently
Example value,...
Create an instance of Feed
per each reactor inlet stream.
(e.g.: solid inlet stream,
NH3 inlet stream)
Create an instance of Feed...
Example of a Feed instance
for a NH3 inlet stream
Example of a Feed instance...
Example value,
can be set differently
Example value,...
Example value,
can be set differently
Example value,...
Create a component instance
per each species in the feed
Create a component instance...
Example value,
can be set differently
Example value,...
Example value,
can be set differently
Example value,...
Simulation results added to 
SizeDistribution object
Simulation results added to...
ns:CompartmentNetwork
ns:CompartmentNetwork
ns:hasPart
ns:hasPa...
Simulation inputs (common to all use cases)
Simulation inputs (common to all use cases)
Simulation inputs (CFD-PBE Wrapper)
Simulation inputs (CFD-PBE Wrapper)
ns:Feed
ns:Feed
...
...
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
Simulation inputs (Compartment Wrapper)
Simulation inputs (Compartment Wrapper)
Simulation outputs (CFD-PBE Wrapper)
Simulation outputs (CFD-PBE Wrapper)
ns:Bin
ns:Bin
ns:ParticleDiameter
ns:ParticleDiameter
ns:value
ns:value
"10"
xsd:float
"10"...
ns:unit
ns:unit
"micrometer"
xsd:string
"micrometer"...
Example value,
can be different
Example value,...
ns:ParticleVolumePercentage
ns:ParticleVolumePercentage
ns:value
ns:value
"23"
xsd:float
"23"...
ns:unit
ns:unit
""
xsd:string
""...
Example value,
can be diferent
Example value,...
"0"
xsd:integer
"0"...
ns:number
ns:number
ns:hasPart
ns:hasPa...
ns:Bin
ns:Bin
"n"
xsd:integer
"n"...
ns:number
ns:number
ns:hasPart
ns:hasPa...
...
...
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
...
...
ns:hasPart
ns:hasPa...
Simulation outputs (Compartment Wrapper)
Simulation outputs (Compartment Wrapper)
Simulation results added
to CompartmentNetwork
object
Simulation results added...
ns:Compartment
ns:Compartment
ns:Volume
ns:Volume
ns:value
ns:value
"0.5"
xsd:float
"0.5"...
ns:unit
ns:unit
"m3"
xsd:string
"m3"...
Example value,
can be different
Example value,...
ns:TurbulentDissipationRate
ns:TurbulentDissipationRate
ns:value
ns:value
"0.4"
xsd:float
"0.4"...
ns:unit
ns:unit
"m2/s3"
xsd:string
"m2/s3"...
Example value,
can be diferent
Example value,...
"0"
xsd:integer
"0"...
ns:ID
ns:ID
ns:hasPart
ns:hasPa...
"n"
xsd:integer
"n"...
ns:ID
ns:ID
ns:hasPart
ns:hasPa...
...
...
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
...
...
ns:hasPart
ns:hasPa...
ns:OutletBoundaryFlux
ns:OutletBoundaryFlux
ns:value
ns:value
"0.4"
xsd:float
"0.4"...
ns:unit
ns:unit
"m3/s"
xsd:string
"m3/s"...
Example value,
can be diferent
Example value,...
ns:name
ns:name
"outlet"
xsd:string
"outlet"...
ns:InletBoundaryFlux
ns:InletBoundaryFlux
ns:value
ns:value
"0.2"
xsd:float
"0.2"...
ns:unit
ns:unit
"m3/s"
xsd:string
"m3/s"...
Example value,
can be diferent
Example value,...
ns:name
ns:name
"5"
xsd:string
"5"...
ns:OutgoingFlux
ns:OutgoingFlux
ns:value
ns:value
"0.8"
xsd:float
"0.8"...
ns:unit
ns:unit
"m3/s"
xsd:string
"m3/s"...
Example value,
can be diferent
Example value,...
ns:ID
ns:ID
"5"
xsd:integer
"5"...
Example value,
can be diferent
Example value,...
Example value,
can be diferent
Example value,...
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
ns:hasPart
ns:hasPa...
ns:LiquidDensity
ns:LiquidDensity
ns:hasPart
ns:hasPa...
ns:value
ns:value
"998.2"
xsd:float
"998.2"...
ns:unit
ns:unit
"kg/m^3"
xsd:string
"kg/m^3"...
Example value,
can be set
differently
Example value,...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/docs/static/logo.png b/docs/static/logo.png new file mode 100644 index 0000000..3cd71f1 Binary files /dev/null and b/docs/static/logo.png differ diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..db4fa6f --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,95 @@ +# Usage + +The SimDOME Wet Synthesis Wrappers can be applied to two use-cases. + +- CFD-PBE Wrapper +- Compartment Wrapper + +A brief description of each use case can be found on the +[introductory page](index.md). + +The simulation inputs must be instantiated as +[CUDS objects](https://simphony.readthedocs.io/en/v3.9.0/jupyter/cuds_api.html) +using the entities from the `wet_synthesis` namespace. The namespace is +included in the Wet Synthesis ontology (see +[installation](installation.md)). The instantiation can be done directly in the +corresponding wrapper session, by spawning either a +`osp.wrappers.wet_synthesis_wrappers.CfdPbeSession` object for the CFD-PBE +Wrapper use-case or a `osp.wrappers.wet_synthesis_wrappers.CompartmentSession` +for the Compartment Wrapper use-case. To access the `wet_synthesis` namespace +and the two session classes, you may import them as follows. + +```python +from osp.core.namespaces import wet_synthesis +from osp.wrappers.wet_synthesis_wrappers import CfdPbeSession +from osp.wrappers.wet_synthesis_wrappers import CompartmentSession +``` + +A diagram depicting the input and output patterns of CUDS objects that the +wrappers expect and produce is shown below. + +
+ +![Wet Synthesis inputs and outputs](./static/graph_pattern.drawio.svg) + +
+ +_Diagram showing the pattern of input CUDS objects that the Wet Synthesis +Wrappers expect to find in the session's knowledge graph and the CUDS objects +that are produced as simulation outputs._ + +
+ +
+ +Once you have imported the namespace and the session class of your choice, you +may instantiate your inputs, run the simulation, and process the results. + +```python +with CfdPbeSession(end_time=None, write_interval=None, + num_moments=4, num_proc=1, + dummy=False) as session: + # Initialize the session with a `WetSynthesisWrapper` object. + wrapper = wet_synthesis.WetSynthesisWrapper(session=session) + + # Create and link your CUDS objects here. + # accuracy_level = ..., pressure = ..., temperature = ... + # ... + # solid_particle.add(density, molecular_weight, shape_factor, + # rel=wet_synthesis.hasProperty) + # ... + # wrapper.add(accuracy_level, pressure, size_distribution, ...) + # ... + + # Run the simulation + session.run() + + # Process and/or export your simulation results + # ... +``` + +Both session classes accept several keyword arguments that control the +simulation in various ways: + +- `delete_simulation_files` _(default: `True`)_: As described in the + [installation section](installation.md), a "case folder" for OpenFOAM is + created from a template before the simulation is run. The folder is + additionally populated with results produced by OpenFOAM during the + simulation. Some results are transformed into CUDS objects, but others are + not. You can peek into this folder to get this extra information, or + alternatively, set this keyword argument to `True` if you do not need it, so + that the folder is automatically deleted when the simulation ends. +- `end_time`: Amount of simulated time to run OpenFOAM for (e.g. `0.03`). If + set to `None`, an automatic guess will be used instead. +- `write_interval`: Controls how often data is written to the OpenFOAM output + file. If set to `None`, a default of `100` time steps is used. +- `num_moments`: A value needs to be set, but it will be ignored and replaced + by `4`, since at the moment, the wrapper is not capable of adapting the case + template to more/fewer moments. +- `num_proc`: Number of processors to be used for the calculation (e.g. `3`). +- `dummy`: When set to `True`, a special dummy set of moments is used so that + the simulation ends after a short time, useful for development and debugging + purposes. It should normally be set to `False`. + +Two complete examples of use (one for each use case) are provided in the +[`examples` folder](https://github.com/simphony/simdome_wet_synthesis/tree/master/examples). diff --git a/osp/wrappers/wet_synthesis_wrappers/cases/precNMC/precNMC_foamTemplate/system/controlDict b/osp/wrappers/wet_synthesis_wrappers/cases/precNMC/precNMC_foamTemplate/system/controlDict old mode 100755 new mode 100644