In this tutorial, we will explore in particular the `bvpy.domains` module. The goal is to get familiar with the concept of integration domain and in particular with its implementation in the **Bvpy** library.
**Covered topics:**
- Basic operations on domains: instanciation, `.info()`, `.discretize()` and `set_cell_size()` methods.
- Quick domain visualization: `plot()` function from the `bvpy.utils.visu` sub-module.
- Basic geometrical domains overview: `Rectangle()`, `Disk()` and other primitives.
- Constructive Solid Geometry (*CSG*) manipulation of geometrical primitives.
- Generation of domains from existing files: `CustomDomain` and `CustomPolygonalDomain` classes.
Download the notebook: [bvpy_tutorial_2](https://gitlab.inria.fr/mosaic/publications/bvpy/-/raw/develop/tutorials/bvpy_tutorial_2_domains.ipynb?inline=false).
%% Cell type:markdown id: tags:
## Basic operations with domains
%% Cell type:markdown id: tags:
### Geometrical domain instanciation
Let's first see how to implement a simple domain and perform basic task with it. Various domain classes are gathered in the `bvpy.domains` modules. Within this module they are sorted in various submodules depending on their characteristics. The `bvpy.domains.primitives` submodule gathers purely geometrical domains built with the **Gmsh** library.
**Remark:** To import a specific domain class you do not need to call the corresponding submodule, calling the `bvpy.domains` module is enough.
%% Cell type:code id: tags:
``` python
frombvpy.domainsimportRectangle
domain=Rectangle()
```
%% Cell type:code id: tags:
``` python
# useless comment
```
%% Cell type:markdown id: tags:
### Domain meshing
With the previous line, we have justed instanciated the default rectangular domain. As mentioned in the documentation [click](file:///Users/oali/Documents/Work/Research/Devlp/bvpy/doc/build/html/library_description.html#domains), in order to mesh the domain with triangles, one needs to call the `discretize()` method:
%% Cell type:code id: tags:
``` python
try:
# domain.mesh.num_cells()
# print(f"Number of triangles within the domain BEFORE discretization: {domain.mesh.num_cells()}")
print(f"Number of triangles within the domain AFTER discretization: {number_triangles}")
```
%% Cell type:markdown id: tags:
### Get information about the considered domain
Useful informations about the domain are available through the `info()` method:
%% Cell type:code id: tags:
``` python
domain.info()
```
%% Cell type:markdown id: tags:
### Quick visualization of the meshed domains
A quick visualization can be performed thanks to the `plot()` function from the `bvpy.utils.visu` sub-module:
%% Cell type:code id: tags:
``` python
frombvpy.utils.visuimportplot,set_renderer
set_renderer('notebook')
plot(domain)
```
%% Cell type:markdown id: tags:
**Remarks:**
* The `plot()`function requires the existence of the mesh within the domain but can be called upon a domain that has not been discretized... In this case the plot function calls itself the `domain.discretize()` method.
* The `set_renderer('notebook')` is a required instruction to enable the encapsulation of plotly objects in notebooks.
%% Cell type:markdown id: tags:
### Resizing domains
Size and resolution can be adjusted at will, either at instanciation or afterwards:
%% Cell type:code id: tags:
``` python
frombvpy.utils.visuimportplot,set_renderer
frombvpy.domainsimportRectangle
set_renderer('notebook')
d1=Rectangle(length=2,width=3,clear=True)
d1.set_cell_size(.05)
plot(d1)
```
%% Cell type:markdown id: tags:
## Available geometrical primitives
Let's now have a look at the geometrical primitives that we can instantiate thanls to the `bvpy.domains.primitives` sub-module.
> **Note:** You can see in the first line above we added the argument `clear=True` at the first domain instanciation. When multiple domains are instanciated, they share the same **Gmsh** factory and are, so to speak, “super-imposed" on one another. This can create conflicts latter on when domains are processed. For instance, when the `plot` function probes the factory for a specific domain, It might not return the desired one but all the previously instanced ones contained within the factory. to avoid this, we added a call to the `gmsh.clear()` (triggered with the argument `clear` is set to `True`) method within our `AbstractDomain` class. This **Gmsh** method resets the domain factory and avoids visualization conflits.
%% Cell type:markdown id: tags:
### Combining curved surfaces:
%% Cell type:code id: tags:
``` python
frombvpy.domainsimportSphere
frombvpy.utils.visuimportplot,set_renderer
sph1=Sphere(clear=True)
sph2=Sphere(center=[0,1,0],radius=.5)
pin=sph1+sph2
pin.set_cell_size(.1)
plot(pin)
```
%% Cell type:markdown id: tags:
### Combining volumes
This CSG feature can also be used to combine volumes together and carve complex 3D domains.
One can be able to import within **bvpy** his/her own custom domain of interest. To do so, we enabled the generation of domains from existing meshes, recorded in the widespread `.ply` format.
The `bvpy.domains.custom_domain` sub-module contains the `CustomDomain` class that takes as input such an existing mesh structure and generate a proper *bvpy domain* from it.
**Remarks:**
* Once again, the subdomain `custom_domain` does not have to be mentioned within the import command.
* The `read` static method of the `CustomDomain` class relies on the **meshio** library. The `.ply` file used as imput should not contain too much properties. And their header should look like:
```
ply
format ascii 1.0
element vertex 7359
property float x
property float y
property float z
element face 14304
property list int int vertex_indices
end_header
```
%% Cell type:code id: tags:
``` python
frombvpy.domainsimportCustomDomain
frombvpy.utils.visuimportplot
path='../data/example_meristem.ply'
cd=CustomDomain.read(path)
cd.info()
plot(cd)
```
%% Cell type:markdown id: tags:
## Importing piecewise polygonal surfaces
In a biological context it is important to be able to handle data structure that account for cellularized tissues.
This can be done with the `CustomPolygonalDomain` class from the `bvpy.domains.custom_polygonal` sub-module.