{"id":13408092,"url":"https://github.com/nschloe/pygmsh","last_synced_at":"2025-05-15T04:06:31.962Z","repository":{"id":10990021,"uuid":"13310568","full_name":"nschloe/pygmsh","owner":"nschloe","description":":spider_web: Gmsh for Python","archived":false,"fork":false,"pushed_at":"2023-10-04T10:11:37.000Z","size":3591,"stargazers_count":899,"open_issues_count":58,"forks_count":162,"subscribers_count":39,"default_branch":"main","last_synced_at":"2025-04-14T05:55:53.035Z","etag":null,"topics":["engineering","mathematics","mesh-generation","meshing","pypi","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nschloe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"nschloe","ko-fi":"nschloe"}},"created_at":"2013-10-03T21:40:30.000Z","updated_at":"2025-04-14T04:41:29.000Z","dependencies_parsed_at":"2024-05-06T20:59:08.524Z","dependency_job_id":null,"html_url":"https://github.com/nschloe/pygmsh","commit_stats":{"total_commits":1116,"total_committers":38,"mean_commits":29.36842105263158,"dds":"0.21057347670250892","last_synced_commit":"5415fb97cb07df9846c7bb178be2fc494f1f4ca3"},"previous_names":["meshpro/pygmsh"],"tags_count":110,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nschloe%2Fpygmsh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nschloe%2Fpygmsh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nschloe%2Fpygmsh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nschloe%2Fpygmsh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nschloe","download_url":"https://codeload.github.com/nschloe/pygmsh/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254270646,"owners_count":22042859,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["engineering","mathematics","mesh-generation","meshing","pypi","python"],"created_at":"2024-07-30T20:00:50.702Z","updated_at":"2025-05-15T04:06:26.946Z","avatar_url":"https://github.com/nschloe.png","language":"Python","funding_links":["https://github.com/sponsors/nschloe","nschloe"],"categories":["CAE","Meshing","Python","Mesh","CAD \u0026 Geometry"],"sub_categories":["Triangular and tetrahedral meshing","Verified vs declared","Books"],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/nschloe/pygmsh\"\u003e\u003cimg alt=\"pygmsh\" src=\"https://nschloe.github.io/pygmsh/logo-with-text.svg\" width=\"60%\"\u003e\u003c/a\u003e\n  \u003cp align=\"center\"\u003eGmsh for Python.\u003c/p\u003e\n\u003c/p\u003e\n\n[![PyPi Version](https://img.shields.io/pypi/v/pygmsh.svg?style=flat-square)](https://pypi.org/project/pygmsh/)\n[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pygmsh.svg?style=flat-square)](https://pypi.org/project/pygmsh/)\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1173105.svg?style=flat-square)](https://doi.org/10.5281/zenodo.1173105)\n[![GitHub stars](https://img.shields.io/github/stars/nschloe/pygmsh.svg?style=flat-square\u0026logo=github\u0026label=Stars\u0026logoColor=white)](https://github.com/nschloe/pygmsh)\n[![PyPi downloads](https://img.shields.io/pypi/dm/pygmsh.svg?style=flat-square)](https://pypistats.org/packages/pygmsh)\n\n[![Discord](https://img.shields.io/static/v1?logo=discord\u0026label=chat\u0026message=on%20discord\u0026color=7289da\u0026style=flat-square)](https://discord.gg/hnTJ5MRX2Y)\n[![Documentation Status](https://readthedocs.org/projects/pygmsh/badge/?version=latest\u0026style=flat-square)](https://pygmsh.readthedocs.io/en/latest/?badge=latest)\n\n[![gh-actions](https://img.shields.io/github/workflow/status/nschloe/pygmsh/ci?style=flat-square)](https://github.com/nschloe/pygmsh/actions?query=workflow%3Aci)\n[![codecov](https://img.shields.io/codecov/c/github/nschloe/pygmsh.svg?style=flat-square)](https://codecov.io/gh/nschloe/pygmsh)\n[![LGTM](https://img.shields.io/lgtm/grade/python/github/nschloe/pygmsh.svg?style=flat-square)](https://lgtm.com/projects/g/nschloe/pygmsh)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)\n\npygmsh combines the power of [Gmsh](https://gmsh.info/) with the versatility of Python.\nIt provides useful abstractions from Gmsh's own Python interface so you can create\ncomplex geometries more easily.\n\nTo use, install Gmsh itself and pygmsh from [pypi](https://pypi.org/project/pygmsh/):\n\n```\n[sudo] apt install python3-gmsh\npip install pygmsh\n```\n\nThis document and the [`tests/`](https://github.com/nschloe/pygmsh/tree/main/tests/)\ndirectory contain many small examples. See\n[here](https://pygmsh.readthedocs.io/en/latest/index.html) for the full documentation.\n\n#### Flat shapes\n\n| \u003cimg src=\"https://nschloe.github.io/pygmsh/polygon.svg\" width=\"100%\"\u003e | \u003cimg src=\"https://nschloe.github.io/pygmsh/circle.svg\" width=\"100%\"\u003e | \u003cimg src=\"https://nschloe.github.io/pygmsh/splines.svg\" width=\"100%\"\u003e |\n| :-------------------------------------------------------------------: | :------------------------------------------------------------------: | :-------------------------------------------------------------------: |\n|                                Polygon                                |                                Circle                                |                              (B-)Splines                              |\n\nCodes:\n\n```python\nimport pygmsh\n\nwith pygmsh.geo.Geometry() as geom:\n    geom.add_polygon(\n        [\n            [0.0, 0.0],\n            [1.0, -0.2],\n            [1.1, 1.2],\n            [0.1, 0.7],\n        ],\n        mesh_size=0.1,\n    )\n    mesh = geom.generate_mesh()\n\n# mesh.points, mesh.cells, ...\n# mesh.write(\"out.vtk\")\n```\n\n```python\nimport pygmsh\n\nwith pygmsh.geo.Geometry() as geom:\n    geom.add_circle([0.0, 0.0], 1.0, mesh_size=0.2)\n    mesh = geom.generate_mesh()\n```\n\n```python\nimport pygmsh\n\nwith pygmsh.geo.Geometry() as geom:\n    lcar = 0.1\n    p1 = geom.add_point([0.0, 0.0], lcar)\n    p2 = geom.add_point([1.0, 0.0], lcar)\n    p3 = geom.add_point([1.0, 0.5], lcar)\n    p4 = geom.add_point([1.0, 1.0], lcar)\n    s1 = geom.add_bspline([p1, p2, p3, p4])\n\n    p2 = geom.add_point([0.0, 1.0], lcar)\n    p3 = geom.add_point([0.5, 1.0], lcar)\n    s2 = geom.add_spline([p4, p3, p2, p1])\n\n    ll = geom.add_curve_loop([s1, s2])\n    pl = geom.add_plane_surface(ll)\n\n    mesh = geom.generate_mesh()\n```\n\nThe return value is always a [meshio](https://pypi.org/project/meshio/) mesh, so to\nstore it to a file you can\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\nmesh.write(\"test.vtk\")\n```\n\nThe output file can be visualized with various tools, e.g.,\n[ParaView](https://www.paraview.org/).\n\nWith\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\npygmsh.write(\"test.msh\")\n```\n\nyou can access Gmsh's native file writer.\n\n#### Extrusions\n\n| \u003cimg src=\"https://nschloe.github.io/pygmsh/extrude.png\" width=\"100%\"\u003e | \u003cimg src=\"https://nschloe.github.io/pygmsh/revolve.png\" width=\"100%\"\u003e | \u003cimg src=\"https://nschloe.github.io/pygmsh/twist.png\" width=\"100%\"\u003e |\n| :-------------------------------------------------------------------: | :-------------------------------------------------------------------: | :-----------------------------------------------------------------: |\n|                               `extrude`                               |                               `revolve`                               |                               `twist`                               |\n\n```python\nimport pygmsh\n\nwith pygmsh.geo.Geometry() as geom:\n    poly = geom.add_polygon(\n        [\n            [0.0, 0.0],\n            [1.0, -0.2],\n            [1.1, 1.2],\n            [0.1, 0.7],\n        ],\n        mesh_size=0.1,\n    )\n    geom.extrude(poly, [0.0, 0.3, 1.0], num_layers=5)\n    mesh = geom.generate_mesh()\n```\n\n```python\nfrom math import pi\nimport pygmsh\n\nwith pygmsh.geo.Geometry() as geom:\n    poly = geom.add_polygon(\n        [\n            [0.0, 0.2, 0.0],\n            [0.0, 1.2, 0.0],\n            [0.0, 1.2, 1.0],\n        ],\n        mesh_size=0.1,\n    )\n    geom.revolve(poly, [0.0, 0.0, 1.0], [0.0, 0.0, 0.0], 0.8 * pi)\n    mesh = geom.generate_mesh()\n```\n\n```python\nfrom math import pi\nimport pygmsh\n\nwith pygmsh.geo.Geometry() as geom:\n    poly = geom.add_polygon(\n        [\n            [+0.0, +0.5],\n            [-0.1, +0.1],\n            [-0.5, +0.0],\n            [-0.1, -0.1],\n            [+0.0, -0.5],\n            [+0.1, -0.1],\n            [+0.5, +0.0],\n            [+0.1, +0.1],\n        ],\n        mesh_size=0.05,\n    )\n\n    geom.twist(\n        poly,\n        translation_axis=[0, 0, 1],\n        rotation_axis=[0, 0, 1],\n        point_on_axis=[0, 0, 0],\n        angle=pi / 3,\n    )\n\n    mesh = geom.generate_mesh()\n```\n\n#### OpenCASCADE\n\n| \u003cimg src=\"https://nschloe.github.io/pygmsh/intersection.png\" width=\"100%\"\u003e | \u003cimg src=\"https://nschloe.github.io/pygmsh/ellipsoid-holes.png\" width=\"100%\"\u003e | \u003cimg src=\"https://nschloe.github.io/pygmsh/puzzle.png\" width=\"100%\"\u003e |\n| :------------------------------------------------------------------------: | :---------------------------------------------------------------------------: | :------------------------------------------------------------------: |\n|                                                                            |                                                                               |\n\nGmsh also supports OpenCASCADE (`occ`), allowing for a CAD-style geometry specification.\n\n```python\nfrom math import pi, cos\nimport pygmsh\n\nwith pygmsh.occ.Geometry() as geom:\n    geom.characteristic_length_max = 0.1\n    r = 0.5\n    disks = [\n        geom.add_disk([-0.5 * cos(7 / 6 * pi), -0.25], 1.0),\n        geom.add_disk([+0.5 * cos(7 / 6 * pi), -0.25], 1.0),\n        geom.add_disk([0.0, 0.5], 1.0),\n    ]\n    geom.boolean_intersection(disks)\n\n    mesh = geom.generate_mesh()\n```\n\n```python\n# ellpsoid with holes\nimport pygmsh\n\nwith pygmsh.occ.Geometry() as geom:\n    geom.characteristic_length_max = 0.1\n    ellipsoid = geom.add_ellipsoid([0.0, 0.0, 0.0], [1.0, 0.7, 0.5])\n\n    cylinders = [\n        geom.add_cylinder([-1.0, 0.0, 0.0], [2.0, 0.0, 0.0], 0.3),\n        geom.add_cylinder([0.0, -1.0, 0.0], [0.0, 2.0, 0.0], 0.3),\n        geom.add_cylinder([0.0, 0.0, -1.0], [0.0, 0.0, 2.0], 0.3),\n    ]\n    geom.boolean_difference(ellipsoid, geom.boolean_union(cylinders))\n\n    mesh = geom.generate_mesh()\n```\n\n```python\n# puzzle piece\nimport pygmsh\n\nwith pygmsh.occ.Geometry() as geom:\n    geom.characteristic_length_min = 0.1\n    geom.characteristic_length_max = 0.1\n\n    rectangle = geom.add_rectangle([-1.0, -1.0, 0.0], 2.0, 2.0)\n    disk1 = geom.add_disk([-1.2, 0.0, 0.0], 0.5)\n    disk2 = geom.add_disk([+1.2, 0.0, 0.0], 0.5)\n\n    disk3 = geom.add_disk([0.0, -0.9, 0.0], 0.5)\n    disk4 = geom.add_disk([0.0, +0.9, 0.0], 0.5)\n    flat = geom.boolean_difference(\n        geom.boolean_union([rectangle, disk1, disk2]),\n        geom.boolean_union([disk3, disk4]),\n    )\n\n    geom.extrude(flat, [0, 0, 0.3])\n\n    mesh = geom.generate_mesh()\n```\n\n#### Mesh refinement/boundary layers\n\n| \u003cimg src=\"https://nschloe.github.io/pygmsh/boundary0.svg\" width=\"100%\"\u003e | \u003cimg src=\"https://nschloe.github.io/pygmsh/mesh-refinement-2d.svg\" width=\"100%\"\u003e | \u003cimg src=\"https://nschloe.github.io/pygmsh/ball-mesh-refinement.png\" width=\"70%\"\u003e |\n| :---------------------------------------------------------------------: | :------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------: |\n|                                                                         |                                                                                  |\n\n```python\n# boundary refinement\nimport pygmsh\n\nwith pygmsh.geo.Geometry() as geom:\n    poly = geom.add_polygon(\n        [\n            [0.0, 0.0],\n            [2.0, 0.0],\n            [3.0, 1.0],\n            [1.0, 2.0],\n            [0.0, 1.0],\n        ],\n        mesh_size=0.3,\n    )\n\n    field0 = geom.add_boundary_layer(\n        edges_list=[poly.curves[0]],\n        lcmin=0.05,\n        lcmax=0.2,\n        distmin=0.0,\n        distmax=0.2,\n    )\n    field1 = geom.add_boundary_layer(\n        nodes_list=[poly.points[2]],\n        lcmin=0.05,\n        lcmax=0.2,\n        distmin=0.1,\n        distmax=0.4,\n    )\n    geom.set_background_mesh([field0, field1], operator=\"Min\")\n\n    mesh = geom.generate_mesh()\n```\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\n# mesh refinement with callback\nimport pygmsh\n\nwith pygmsh.geo.Geometry() as geom:\n    geom.add_polygon(\n        [\n            [-1.0, -1.0],\n            [+1.0, -1.0],\n            [+1.0, +1.0],\n            [-1.0, +1.0],\n        ]\n    )\n    geom.set_mesh_size_callback(\n        lambda dim, tag, x, y, z: 6.0e-2 + 2.0e-1 * (x**2 + y**2)\n    )\n\n    mesh = geom.generate_mesh()\n```\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\n# ball with mesh refinement\nfrom math import sqrt\nimport pygmsh\n\n\nwith pygmsh.occ.Geometry() as geom:\n    geom.add_ball([0.0, 0.0, 0.0], 1.0)\n\n    geom.set_mesh_size_callback(\n        lambda dim, tag, x, y, z: abs(sqrt(x**2 + y**2 + z**2) - 0.5) + 0.1\n    )\n    mesh = geom.generate_mesh()\n```\n\n#### Optimization\n\npygmsh can optimize existing meshes, too.\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\nimport meshio\n\nmesh = meshio.read(\"mymesh.vtk\")\noptimized_mesh = pygmsh.optimize(mesh, method=\"\")\n```\n\nYou can also use the command-line utility\n\n```\npygmsh-optimize input.vtk output.xdmf\n```\n\nwhere input and output can be any format supported by\n[meshio](https://pypi.org/project/meshio/).\n\n### Testing\n\nTo run the pygmsh unit tests, check out this repository and type\n\n```\npytest\n```\n\n### Building Documentation\n\nDocs are built using [Sphinx](http://www.sphinx-doc.org/en/stable/).\n\nTo build, run\n\n```\nsphinx-build -b html doc doc/_build\n```\n\n### License\n\nThis software is published under the [GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.en.html).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnschloe%2Fpygmsh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnschloe%2Fpygmsh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnschloe%2Fpygmsh/lists"}