Skip to content
Merged

V1 #22

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,9 @@ Consult our :ref:`Roadmap <roadmap>` for planned feature implementations.
.. note::

This project is still in early development and documentation may be incomplete. Version 1.0 is scheduled for release in early 2026. Stay tuned!


.. toctree::
:hidden:

references
5 changes: 5 additions & 0 deletions docs/source/references.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
References
==========

.. bibliography:: ./refs.bib
:style: unsrt
6 changes: 0 additions & 6 deletions docs/source/tutorials/channel_flow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,3 @@ Lizzy will save the following fields: "FillFactor", "FreeSurface", "Pressure", "
:width: 60%
:align: center


References
----------

.. bibliography:: ../refs.bib
:style: unsrt
19 changes: 9 additions & 10 deletions docs/source/user_guide/assigning_boundary_conditions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ Boundary conditions operations
In this section we look at various boundary condition operations, including creating boundary conditions and modifying them at runtime.
All operations can be performed using the :class:`~lizzy.LizzyModel` user-facing methods.


Creation and assignment of inlets
----------------------------------

The following operations are to be performed **before** the solver is initialised by calling :meth:`~lizzy.LizzyModel.initialise_solver`.
.. note::
The following operations are to be performed **before** the solver is initialised by calling :meth:`~lizzy.LizzyModel.initialise_solver`.

Creating an inlet
~~~~~~~~~~~~~~~~~~
Expand All @@ -29,13 +29,13 @@ Let's say we have imported a mesh with one boundary named "left_edge" and one bo
Physical domains: ['domain']
Physical lines: ['left_edge', 'right_edge']

First, we will create an inlet using the :meth:`~lizzy.LizzyModel.create_inlet` method. This method requires two arguments: the inlet initial pressure (in Pa) and a unique string identifier for the inlet. Let's create an inlet with a pressure of 1.0E05 Pa tagged as "inlet_1":
First, we will create an inlet using the :meth:`~lizzy.LizzyModel.create_inlet` method. This method requires two arguments: a unique name for the inlet and the inlet initial pressure (in Pa). Let's create an inlet named "inlet_1" with a pressure of 1.0E05 Pa:

.. code-block::

model.create_inlet(1e5, "inlet_1")
model.create_inlet("inlet_1", 1e5)

An :class:`~lizzy.gates.Inlet` object is created and stored in the model, but it is not assigned yet. To assign the inlet to a specific boundary, we use the :meth:`~lizzy.LizzyModel.assign_inlet` method, providing the name of the inlet and the name of the mesh boundary where we want to assign it:
An :class:`~lizzy.gates.Inlet` object is created and stored in the model, but it is not assigned yet to any boundary. To do so, we use the :meth:`~lizzy.LizzyModel.assign_inlet` method, providing the name of the inlet and the name of the mesh boundary where we want to assign it:

.. code-block::

Expand All @@ -47,14 +47,14 @@ An :class:`~lizzy.gates.Inlet` object is created and stored in the model, but it

.. code-block::

new_inlet = model.create_inlet(1e5, "inlet_1")
new_inlet = model.create_inlet("inlet_1", 1e5)
model.assign_inlet(new_inlet, "left_edge")

Once an inlet is assigned, it is set to "open" state by default. We can check its state at any time using the :attr:`~lizzy.gates.Inlet.is_open` property (read-only).

.. code-block:: console

>>> new_inlet = model.create_inlet(1e5, "inlet_1")
>>> new_inlet = model.create_inlet("inlet_1", 1e5)
>>> model.assign_inlet(new_inlet, "left_edge")
>>> new_inlet.is_open

Expand All @@ -78,8 +78,8 @@ This expression returns the :class:`~lizzy.gates.Inlet` object with that name. W
Runtime operations
-------------------

The following operations can be performed at any time **after** the solver has been initialised by calling :meth:`~lizzy.LizzyModel.initialise_solver`.

.. note::
The following operations can be performed at any time **after** the solver has been initialised by calling :meth:`~lizzy.LizzyModel.initialise_solver`.

Opening / closing inlets
~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -141,7 +141,6 @@ This will produce the same effect as using the :meth:`~lizzy.LizzyModel.open_inl

>>> Fatal error: The application has terminated.
>>> No inlets are currently open. At least one inlet must be open at all times.


Modifying inlet pressure
~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
47 changes: 47 additions & 0 deletions docs/source/user_guide/basics.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Basics
======

The philosophy of Lizzy is inspired to popular FE libraries like `FEniCS <https://fenicsproject.org>`_: we provide a flexible scripting API that allows the user to define any type of infusion scenario. Everything in Lizzy is accomplished by writing a Python script.

Lizzy workflow
-----------------

The basic workflow for using Lizzy in a Python script involves the following key steps:

1. Import the Lizzy package.
2. Instantiate a :class:`~lizzy.LizzyModel` object.
3. Use the :class:`~lizzy.LizzyModel` API to define and run the simulation.
4. Save results.

Lizzy is designed so that most of the operations can be performed using the :class:`~lizzy.LizzyModel` class.

Units and conventions
----------------------
The solver assumes consistent units and does not enforce any. The user is free to use any system of units, as long as they are consistent throughout the script. We recommend to stick to the SI units:

- Permeability: m²
- Viscosity: Pa·s
- Length: m
- Time: s
- Pressure: Pa
- Velocity: m/s


The LizzyModel class
---------------------

The :class:`~lizzy.LizzyModel` class is the main protagonist of any Lizzy script. This class provides APIs to execute all the core fucntionalities of the solver.
When writing a Lizzy script, typically the first step (after importing the library) is to instantiate a :class:`~lizzy.LizzyModel` object:

.. code-block::

model = liz.LizzyModel()

The Lizzy API is designed so that, in most cases, the :class:`~lizzy.LizzyModel` class is the only one the user needs do access to do any operation:

.. code-block::

operation_output = model.some_method(args)


The :ref:`using_lizzy` section of this documentation is dedicated to showing how elementary operations can be done in Lizzy. The :ref:`api_reference_index` provides detailed information about the LizzyModel functionalities anf other namespaces of Lizzy.
24 changes: 0 additions & 24 deletions docs/source/user_guide/components/inlet_operations.rst

This file was deleted.

55 changes: 46 additions & 9 deletions docs/source/user_guide/managing_materials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,62 @@ Materials in Lizzy

In Lizzy, a material is represented by the :class:`~lizzy.materials.PorousMaterial` class. This class encapsulates the properties of a porous material, including its permeability, porosity, and thickness. Each material is defined by the following properties:

- **Name**: A unique string identifier for the material.
- **Permeability (k1, k2, k3)**: The permeability of the material in three principal directions (in m²).
- **Porosity**: The porosity of the material (dimensionless, between 0 and 1).
- **Thickness**: The thickness of the material (in meters). A material can represent a single layer of fabric, or a multi-layer laminate. In the latter case, the thickness represents the total thickness of the laminate.
- **Name**: A unique string identifier for the material.
- **Thickness**: The thickness of the material (in m). A material can represent a single layer of fabric, or a multi-layer laminate. In the latter case, the thickness represents the total thickness of the laminate.

The current version of Lizzy does not allow to compose a multi-layer laminate automatically by defining its layers. Instead, the user must compute the equivalent permeability, porosity, and thickness of the laminate externally and define a single :class:`~lizzy.materials.PorousMaterial` object representing the entire laminate. This is tipically done using arithmetic average schemes :cite:`calado1996effective` :cite:`bancora2018effective`. We plan to implement an automated multi-layer laminate definition feature in future releases.


Creating materials
-------------------

We can create a porous material using the :meth:`~lizzy.LizzyModel.create_material` method. This method requires the permeability values, porosity, thickness, and a unique name for the material. For example, to create a material with permeability values of 1E-10 m² in all directions, a porosity of 0.5, a thickness of 1.0 m, and named "material_01", we would do:
.. note::
The following operations are to be performed **before** the solver is initialised by calling :meth:`~lizzy.LizzyModel.initialise_solver`.

We can create a porous material using the :meth:`~lizzy.LizzyModel.create_material` method. This method requires a unique name for the material, the permeability values (as a tuple), porosity and thickness. For example, to create a material named "material_01" with permeability values of 1E-10 m² in all directions, a porosity of 0.5 and a thickness of 1.0 mm, we would type:

.. code-block::

model.create_material("material_01", (1E-10, 1E-10, 1E-10), 0.5, 0.001)

A :class:`~lizzy.materials.PorousMaterial` object is created and stored in the model, but it is not assigned yet.

Creating an orientation Rosette
-------------------------------

When working with anisotropic materials, it is necessary to define how the principal directions of permeability are oriented in the domain. To do so, we can create a :class:`~lizzy.materials.Rosette` object. A rosette is a local basis :math:`\hat e_1, \hat e_2, \hat e_3` that defines an orientation in space. When associated to a material, the principal directions of permeability will be aligned with the basis defined by the rosette. In Lizzy, we don't define the basis components directly. Instead, for any given rosette, we define a single orientation vector :math:`u_1` that will be projected onto the mesh elements to calculate the local basis :math:`\hat e_1, \hat e_2, \hat e_3` (more on this below). To create a rosette, we can use the :meth:`~lizzy.LizzyModel.create_rosette` method by providing a name for the rosette and the vector :math:`u_1`. For example, we can create a rosette named "rosette_01" with a vector :math:`u_1` oriented along (1, 1, 0) by typing:

.. code-block::

model.create_material(1E-10, 1E-10, 1E-10, 0.5, 1.0, "material_01")
model.create_rosette("rosette_01", (1,1,0))

Assigning materials
--------------------

To assign a material to a labeled domain, we use the :meth:`~lizzy.LizzyModel.assign_material` method, providing the following arguments:

- the name of the material to assign
- the name of the mesh domain where we want to assign it
- the rosette of orientation

For example, to assign the material "material_01" to a mesh domain labelled as "domain_01" and orient it using using the rosette "rosette_01", we would type:

.. code-block::

model.assign_material("material_01", "domain_01", "rosette_01")

When the assignment happens, the remaining components of the local rosette (:math:`\hat e_1, \hat e_2, \hat e_3`) are calculated and registered for as follows:

- :math:`\hat e_1`: is calculated as the projection of :math:`u_1` along the normals of the elements in the domain
- :math:`\hat e_3`: is calculated as the normal of the elements in the domain
- :math:`\hat e_2`: is calculated as :math:`\hat e_1 \times \hat e_3`

References
----------
.. note::
If a rosette is not provided, a default orientation is used with :math:`\hat e_1, \hat e_2, \hat e_3` aligned with global axes :math:`e_1, e_2, e_3`. This can be convenient when working with isotropic materials, since we don't care about their orientation. For example:

.. bibliography:: ../refs.bib
:style: unsrt
.. code-block::

k_iso = 1.0E-11
model.create_material("material_iso", (k_iso, k_iso, k_iso), 0.5, 1.0)
model.assign_material("material_iso", "domain_01")
15 changes: 11 additions & 4 deletions docs/source/user_guide/reading_a_mesh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ Lizzy can read a mesh file that contains tagged domains and boundaries.
.. important::
Currently, the only supported mesh format is `.msh` (Version 4 ASCII). This is a typical mesh format that can be exported using software like GMSH. Continuing development, more formats will gradually be supported.

Mesh preparation
----------------

The `.msh` file has some requirements to be compatible with Lizzy:
Mesh preparation (GMSH version)
-------------------------------

- The mesh must be composed uniquely of 2D triangle elements (quads are not supported).
The GMSH `.msh` file has some requirements to be compatible with Lizzy:

- The mesh must be composed uniquely of 2D triangle elements (quads or 3D elements are not supported yet).
- Physical groups must be defined for all material domains and for all edges where a boundary condition will be applied. The name of the physical groups will be used to identify the different boundaries and materials in the mesh.

.. figure:: ../../images/physical_boundary_tag.png
:width: 60%
:align: center

An example of a GMSH mesh, where a physical boundary is being defined.

As an example, we provide a :download:`GMSH script <../../../examples/meshes/Rect.geo>` (.geo) that demonstrated how to create a simple rectangular mesh with physical groups for Lizzy.
The file can be opened in GMSH and exported as a `.msh` file.
To learn more about how to prepare mesh files and tag physical entities using GMSH, refer to the `GMSH documentation <https://gmsh.info/doc/texinfo/gmsh.html#Elementary-entities-vs-physical-groups>`_ .
Expand Down
7 changes: 7 additions & 0 deletions docs/source/user_guide/saving_results.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.. _saving_results:

Saving results
==============

In this section we look at how we can save simulation results to files that can be read externally.
All operations can be performed using the :class:`~lizzy.LizzyModel` user-facing methods. For more details about the underlying core components, please refer to the :ref:`api_reference_index` documentation.
Loading