Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/nschloe/pygmsh

:spider_web: Gmsh for Python
https://github.com/nschloe/pygmsh

engineering mathematics mesh-generation meshing pypi python

Last synced: about 2 months ago
JSON representation

:spider_web: Gmsh for Python

Awesome Lists containing this project

README

        


pygmsh

Gmsh for Python.

[![PyPi Version](https://img.shields.io/pypi/v/pygmsh.svg?style=flat-square)](https://pypi.org/project/pygmsh/)
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pygmsh.svg?style=flat-square)](https://pypi.org/project/pygmsh/)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1173105.svg?style=flat-square)](https://doi.org/10.5281/zenodo.1173105)
[![GitHub stars](https://img.shields.io/github/stars/nschloe/pygmsh.svg?style=flat-square&logo=github&label=Stars&logoColor=white)](https://github.com/nschloe/pygmsh)
[![PyPi downloads](https://img.shields.io/pypi/dm/pygmsh.svg?style=flat-square)](https://pypistats.org/packages/pygmsh)

[![Discord](https://img.shields.io/static/v1?logo=discord&label=chat&message=on%20discord&color=7289da&style=flat-square)](https://discord.gg/hnTJ5MRX2Y)
[![Documentation Status](https://readthedocs.org/projects/pygmsh/badge/?version=latest&style=flat-square)](https://pygmsh.readthedocs.io/en/latest/?badge=latest)

[![gh-actions](https://img.shields.io/github/workflow/status/nschloe/pygmsh/ci?style=flat-square)](https://github.com/nschloe/pygmsh/actions?query=workflow%3Aci)
[![codecov](https://img.shields.io/codecov/c/github/nschloe/pygmsh.svg?style=flat-square)](https://codecov.io/gh/nschloe/pygmsh)
[![LGTM](https://img.shields.io/lgtm/grade/python/github/nschloe/pygmsh.svg?style=flat-square)](https://lgtm.com/projects/g/nschloe/pygmsh)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)

pygmsh combines the power of [Gmsh](https://gmsh.info/) with the versatility of Python.
It provides useful abstractions from Gmsh's own Python interface so you can create
complex geometries more easily.

To use, install Gmsh itself and pygmsh from [pypi](https://pypi.org/project/pygmsh/):

```
[sudo] apt install python3-gmsh
pip install pygmsh
```

This document and the [`tests/`](https://github.com/nschloe/pygmsh/tree/main/tests/)
directory contain many small examples. See
[here](https://pygmsh.readthedocs.io/en/latest/index.html) for the full documentation.

#### Flat shapes

| | | |
| :-------------------------------------------------------------------: | :------------------------------------------------------------------: | :-------------------------------------------------------------------: |
| Polygon | Circle | (B-)Splines |

Codes:

```python
import pygmsh

with pygmsh.geo.Geometry() as geom:
geom.add_polygon(
[
[0.0, 0.0],
[1.0, -0.2],
[1.1, 1.2],
[0.1, 0.7],
],
mesh_size=0.1,
)
mesh = geom.generate_mesh()

# mesh.points, mesh.cells, ...
# mesh.write("out.vtk")
```

```python
import pygmsh

with pygmsh.geo.Geometry() as geom:
geom.add_circle([0.0, 0.0], 1.0, mesh_size=0.2)
mesh = geom.generate_mesh()
```

```python
import pygmsh

with pygmsh.geo.Geometry() as geom:
lcar = 0.1
p1 = geom.add_point([0.0, 0.0], lcar)
p2 = geom.add_point([1.0, 0.0], lcar)
p3 = geom.add_point([1.0, 0.5], lcar)
p4 = geom.add_point([1.0, 1.0], lcar)
s1 = geom.add_bspline([p1, p2, p3, p4])

p2 = geom.add_point([0.0, 1.0], lcar)
p3 = geom.add_point([0.5, 1.0], lcar)
s2 = geom.add_spline([p4, p3, p2, p1])

ll = geom.add_curve_loop([s1, s2])
pl = geom.add_plane_surface(ll)

mesh = geom.generate_mesh()
```

The return value is always a [meshio](https://pypi.org/project/meshio/) mesh, so to
store it to a file you can

```python
mesh.write("test.vtk")
```

The output file can be visualized with various tools, e.g.,
[ParaView](https://www.paraview.org/).

With

```python
pygmsh.write("test.msh")
```

you can access Gmsh's native file writer.

#### Extrusions

| | | |
| :-------------------------------------------------------------------: | :-------------------------------------------------------------------: | :-----------------------------------------------------------------: |
| `extrude` | `revolve` | `twist` |

```python
import pygmsh

with pygmsh.geo.Geometry() as geom:
poly = geom.add_polygon(
[
[0.0, 0.0],
[1.0, -0.2],
[1.1, 1.2],
[0.1, 0.7],
],
mesh_size=0.1,
)
geom.extrude(poly, [0.0, 0.3, 1.0], num_layers=5)
mesh = geom.generate_mesh()
```

```python
from math import pi
import pygmsh

with pygmsh.geo.Geometry() as geom:
poly = geom.add_polygon(
[
[0.0, 0.2, 0.0],
[0.0, 1.2, 0.0],
[0.0, 1.2, 1.0],
],
mesh_size=0.1,
)
geom.revolve(poly, [0.0, 0.0, 1.0], [0.0, 0.0, 0.0], 0.8 * pi)
mesh = geom.generate_mesh()
```

```python
from math import pi
import pygmsh

with pygmsh.geo.Geometry() as geom:
poly = geom.add_polygon(
[
[+0.0, +0.5],
[-0.1, +0.1],
[-0.5, +0.0],
[-0.1, -0.1],
[+0.0, -0.5],
[+0.1, -0.1],
[+0.5, +0.0],
[+0.1, +0.1],
],
mesh_size=0.05,
)

geom.twist(
poly,
translation_axis=[0, 0, 1],
rotation_axis=[0, 0, 1],
point_on_axis=[0, 0, 0],
angle=pi / 3,
)

mesh = geom.generate_mesh()
```

#### OpenCASCADE

| | | |
| :------------------------------------------------------------------------: | :---------------------------------------------------------------------------: | :------------------------------------------------------------------: |
| | |

Gmsh also supports OpenCASCADE (`occ`), allowing for a CAD-style geometry specification.

```python
from math import pi, cos
import pygmsh

with pygmsh.occ.Geometry() as geom:
geom.characteristic_length_max = 0.1
r = 0.5
disks = [
geom.add_disk([-0.5 * cos(7 / 6 * pi), -0.25], 1.0),
geom.add_disk([+0.5 * cos(7 / 6 * pi), -0.25], 1.0),
geom.add_disk([0.0, 0.5], 1.0),
]
geom.boolean_intersection(disks)

mesh = geom.generate_mesh()
```

```python
# ellpsoid with holes
import pygmsh

with pygmsh.occ.Geometry() as geom:
geom.characteristic_length_max = 0.1
ellipsoid = geom.add_ellipsoid([0.0, 0.0, 0.0], [1.0, 0.7, 0.5])

cylinders = [
geom.add_cylinder([-1.0, 0.0, 0.0], [2.0, 0.0, 0.0], 0.3),
geom.add_cylinder([0.0, -1.0, 0.0], [0.0, 2.0, 0.0], 0.3),
geom.add_cylinder([0.0, 0.0, -1.0], [0.0, 0.0, 2.0], 0.3),
]
geom.boolean_difference(ellipsoid, geom.boolean_union(cylinders))

mesh = geom.generate_mesh()
```

```python
# puzzle piece
import pygmsh

with pygmsh.occ.Geometry() as geom:
geom.characteristic_length_min = 0.1
geom.characteristic_length_max = 0.1

rectangle = geom.add_rectangle([-1.0, -1.0, 0.0], 2.0, 2.0)
disk1 = geom.add_disk([-1.2, 0.0, 0.0], 0.5)
disk2 = geom.add_disk([+1.2, 0.0, 0.0], 0.5)

disk3 = geom.add_disk([0.0, -0.9, 0.0], 0.5)
disk4 = geom.add_disk([0.0, +0.9, 0.0], 0.5)
flat = geom.boolean_difference(
geom.boolean_union([rectangle, disk1, disk2]),
geom.boolean_union([disk3, disk4]),
)

geom.extrude(flat, [0, 0, 0.3])

mesh = geom.generate_mesh()
```

#### Mesh refinement/boundary layers

| | | |
| :---------------------------------------------------------------------: | :------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------: |
| | |

```python
# boundary refinement
import pygmsh

with pygmsh.geo.Geometry() as geom:
poly = geom.add_polygon(
[
[0.0, 0.0],
[2.0, 0.0],
[3.0, 1.0],
[1.0, 2.0],
[0.0, 1.0],
],
mesh_size=0.3,
)

field0 = geom.add_boundary_layer(
edges_list=[poly.curves[0]],
lcmin=0.05,
lcmax=0.2,
distmin=0.0,
distmax=0.2,
)
field1 = geom.add_boundary_layer(
nodes_list=[poly.points[2]],
lcmin=0.05,
lcmax=0.2,
distmin=0.1,
distmax=0.4,
)
geom.set_background_mesh([field0, field1], operator="Min")

mesh = geom.generate_mesh()
```

```python
# mesh refinement with callback
import pygmsh

with pygmsh.geo.Geometry() as geom:
geom.add_polygon(
[
[-1.0, -1.0],
[+1.0, -1.0],
[+1.0, +1.0],
[-1.0, +1.0],
]
)
geom.set_mesh_size_callback(
lambda dim, tag, x, y, z: 6.0e-2 + 2.0e-1 * (x**2 + y**2)
)

mesh = geom.generate_mesh()
```

```python
# ball with mesh refinement
from math import sqrt
import pygmsh

with pygmsh.occ.Geometry() as geom:
geom.add_ball([0.0, 0.0, 0.0], 1.0)

geom.set_mesh_size_callback(
lambda dim, tag, x, y, z: abs(sqrt(x**2 + y**2 + z**2) - 0.5) + 0.1
)
mesh = geom.generate_mesh()
```

#### Optimization

pygmsh can optimize existing meshes, too.

```python
import meshio

mesh = meshio.read("mymesh.vtk")
optimized_mesh = pygmsh.optimize(mesh, method="")
```

You can also use the command-line utility

```
pygmsh-optimize input.vtk output.xdmf
```

where input and output can be any format supported by
[meshio](https://pypi.org/project/meshio/).

### Testing

To run the pygmsh unit tests, check out this repository and type

```
pytest
```

### Building Documentation

Docs are built using [Sphinx](http://www.sphinx-doc.org/en/stable/).

To build, run

```
sphinx-build -b html doc doc/_build
```

### License

This software is published under the [GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.en.html).