Hello.
I'd like to import a Parasolid's CAD file x_b
.
Doing so, gmsh tells me I shall compile it accordingly. However, the directory contrib/Parasolid/
is missing.
Is it still possible to compile gmsh such that one can import x_b
geometries?
Regards.
Which makes sense! Thanks :-)
Hello.
I'd like to import a Parasolid's CAD file x_b
.
Doing so, gmsh tells me I shall compile it accordingly. However, the directory contrib/Parasolid/
is missing.
Is it still possible to compile gmsh such that one can import x_b
geometries?
Regards.
Hi every1.
With gmsh, I have generated some meshes with tagged entities (physical groups) that I have exported as vtk
meshes.
The physical tags are written in the CELL_DATA
section.
However, when I read one of those mesh with gmsh, the physical tags (cell_data) are not read.
I can recover this information with some scripts, but I think it would make sense for gmsh to be able to read the section it wrote itself.
Hi every1.
I was wondering if it would be difficult to add the following feature:
defining a geometry using the Gmsh API (e.g. a python script), and then writing the corresponding CAD model in a .geo
file.
I personally prefer using the API when I need to define a complex geometry.
What are your thoughts about this?
Thanks a lot @geuzaine :-) I always appreciate learning such details.
If I'm correct, it means that it is not possible to export a CAD model if we mix CAD kernels to define a geometry.
Good to know.
Feel free to move this non-issue where it suits you ;-)
Hi every1.
I was wondering if it would be difficult to add the following feature:
defining a geometry using the Gmsh API (e.g. a python script), and then writing the corresponding CAD model in a .geo
file.
I personally prefer using the API when I need to define a complex geometry.
What are your thoughts about this?
Hi Chris. Thanks a lot for your reply. Is it better to proceed as you propose?
I managed to do as you wrote (see below), but I don't see any advantage doing so.
BTW, I know that gmsh is a bottom-up
mesher.
However, is there a way to improve the mesh by only refining the boundary (constrained) edges, automatically?
import numpy as np
import gmsh
points = np.array([[0.0, 0.0], [0.5, 0.0], [0.5, 0.5], [1.0, 0.5], [1.0, 1.0], [0.0, 1.0], [.25, .7], [.4, .6], [.3, .5], [.4, .7]])
constraints = np.array([[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0]])
nPts = points.shape[0]
nCst = constraints.shape[0]
pts = np.zeros([nPts, 3])
pts[:, :2] = points[:, :]
bnd_pts = np.unique(np.arange(0, nPts)[constraints])
isBnd = np.zeros([nPts], dtype=bool)
isBnd[bnd_pts] = True
gmsh.initialize([], False)
gmsh.model.addDiscreteEntity(1, 1)
gmsh.model.mesh.addNodes(1, 1, bnd_pts+1, pts[bnd_pts, :].reshape([-1]))
gmsh.model.mesh.addElements(1, 1, [1], [np.arange(1, nCst+1)], [constraints.reshape([-1])+1])
loop = gmsh.model.geo.addCurveLoop([1])
domain = gmsh.model.geo.addPlaneSurface([loop], 1)
gmsh.model.geo.synchronize()
gmsh.model.mesh.addNodes(2, domain, np.arange(1, nPts+1)[~isBnd], pts[~isBnd, :].reshape([-1]))
for i in np.arange(nPts)[~isBnd]:
gmsh.model.addDiscreteEntity(0, i+1)
gmsh.model.setCoordinates(i+1, pts[i, 0], pts[i, 1], pts[i, 2])
gmsh.model.mesh.embed(0, np.arange(1, nPts+1)[~isBnd], 2, domain)
gmsh.model.mesh.generate(2)
gmsh.write("L-toy.msh")
Dear developers,
If I understand the documentation correctly, getElementFaceNodes
works like this:
node_tags = gmsh.model.mesh.getElementFaceNodes(element_type, face_type)
where face_type
is 3 for triangular faces and 4 for quadrangular faces.
A prism element (element_type=6
) have both triangular and quadrilateral faces. Thus, I thought I would be able to do something like this for a mesh containing prisms:
entities = gmsh.model.getEntities(3)
for entity in entities:
element_types, _, _ = gmsh.model.mesh.getElements(entity[0], entity[1])
for element_type in element_types:
# Only consider prisms
if element_type == 6:
for face_type in [3, 4]:
print(face_type)
node_tags = gmsh.model.mesh.getElementFaceNodes(element_type, face_type)
print("ok")
This gives me a segmentation fault using both gmsh 4.9.3 (from pip) and latest dev (pip install ... gmsh-dev).
I've attached an example with the grid from tutorials/python/t3.py
.
Thanks!
@geuzaine indeed, it is now working :-)
I still have the same issue with Version : 4.9.4-git-02ca9402c
Valgrind output
...
Info : Done writing 't3.msh'
3
ok
4
==21869== Invalid write of size 8
==21869== at 0x7A749A8: gmsh::model::mesh::getElementFaceNodes(int, int, std::vector<unsigned long, std::allocator<unsigned long> >&, int, bool, unsigned long, unsigned long) (gmsh.cpp:4511)
==21869== by 0x8759950: gmshModelMeshGetElementFaceNodes (gmshc.cpp:1700)
==21869== by 0x4877D49: ??? (in /usr/lib/libffi.so.8.1.0)
==21869== by 0x4877266: ??? (in /usr/lib/libffi.so.8.1.0)
==21869== by 0x4858E9D: ??? (in /usr/lib/python3.10/lib-dynload/_ctypes.cpython-310-x86_64-linux-gnu.so)
==21869== by 0x48585FB: ??? (in /usr/lib/python3.10/lib-dynload/_ctypes.cpython-310-x86_64-linux-gnu.so)
==21869== by 0x49DE7CA: _PyObject_MakeTpCall (in /usr/lib/libpython3.10.so.1.0)
==21869== by 0x49D9E27: _PyEval_EvalFrameDefault (in /usr/lib/libpython3.10.so.1.0)
==21869== by 0x49E473B: _PyFunction_Vectorcall (in /usr/lib/libpython3.10.so.1.0)
==21869== by 0x49D94F0: _PyEval_EvalFrameDefault (in /usr/lib/libpython3.10.so.1.0)
==21869== by 0x49D3391: ??? (in /usr/lib/libpython3.10.so.1.0)
==21869== by 0x4A8BC13: PyEval_EvalCode (in /usr/lib/libpython3.10.so.1.0)
==21869== Address 0x2626bee0 is 0 bytes after a block of size 522,720 alloc'd
==21869== at 0x483F013: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21869== by 0x7A85166: allocate (new_allocator.h:121)
==21869== by 0x7A85166: allocate (alloc_traits.h:460)
==21869== by 0x7A85166: _M_allocate (stl_vector.h:346)
==21869== by 0x7A85166: std::vector<unsigned long, std::allocator<unsigned long> >::_M_default_append(unsigned long) (vector.tcc:635)
==21869== by 0x7A74AEF: resize (stl_vector.h:940)
==21869== by 0x7A74AEF: gmsh::model::mesh::getElementFaceNodes(int, int, std::vector<unsigned long, std::allocator<unsigned long> >&, int, bool, unsigned long, unsigned long) (gmsh.cpp:4492)
==21869== by 0x8759950: gmshModelMeshGetElementFaceNodes (gmshc.cpp:1700)
==21869== by 0x4877D49: ??? (in /usr/lib/libffi.so.8.1.0)
==21869== by 0x4877266: ??? (in /usr/lib/libffi.so.8.1.0)
==21869== by 0x4858E9D: ??? (in /usr/lib/python3.10/lib-dynload/_ctypes.cpython-310-x86_64-linux-gnu.so)
==21869== by 0x48585FB: ??? (in /usr/lib/python3.10/lib-dynload/_ctypes.cpython-310-x86_64-linux-gnu.so)
==21869== by 0x49DE7CA: _PyObject_MakeTpCall (in /usr/lib/libpython3.10.so.1.0)
==21869== by 0x49D9E27: _PyEval_EvalFrameDefault (in /usr/lib/libpython3.10.so.1.0)
==21869== by 0x49E473B: _PyFunction_Vectorcall (in /usr/lib/libpython3.10.so.1.0)
==21869== by 0x49D94F0: _PyEval_EvalFrameDefault (in /usr/lib/libpython3.10.so.1.0)
==21869==
valgrind: m_mallocfree.c:303 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 10246, hi = 629997568.
...
FYI
Build options : 64Bit ALGLIB[contrib] ANN[contrib] Bamg Blossom Cairo Cgns DIntegration Dlopen DomHex Eigen[contrib] Fltk GMP Gmm[contrib] Hxt Jpeg Kbipack LinuxJoystick MathEx[contrib] Med Mesh Metis[contrib] Mmg Mpeg Netgen ONELAB ONELABMetamodel OpenCASCADE OpenCASCADE-CAF OpenGL OpenMP OptHom Parser Plugins Png Post QuadMeshingTools QuadTri Solver TetGen/BR Voro++[contrib] WinslowUntangler Zlib
FLTK version : 1.3.8
OCC version : 7.5.3
MED version : 4.1.0
Inspired by previous examples (see above), I manage to get a working example
import numpy as np
import gmsh
points = np.array([[0.0, 0.0], [0.5, 0.0], [0.5, 0.5], [1.0, 0.5], [1.0, 1.0], [0.0, 1.0], [.25, .7], [.4, .6], [.3, .5], [.4, .7]])
constraints = np.array([[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0]])
nPts = points.shape[0]
nCst = constraints.shape[0]
isBnd = np.zeros([nPts], dtype=bool)
for i in range(2):
isBnd[constraints[:, i]] = True
gmsh.initialize([], False)
pts = np.zeros([nPts, 3])
pts[:, :2] = points[:, :]
for i in range(nPts):
gmsh.model.geo.addPoint(pts[i, 0], pts[i, 1], pts[i, 2], tag=i+1)
for i in range(nCst):
gmsh.model.geo.addLine(constraints[i, 0]+1, constraints[i, 1]+1, i+1)
bnd = gmsh.model.geo.addCurveLoop(np.arange(1, nCst+1))
domain = gmsh.model.geo.addPlaneSurface([bnd])
gmsh.model.geo.synchronize()
gmsh.model.mesh.embed(0, np.arange(1, nPts+1)[~isBnd], 2, domain)
gmsh.option.setNumber("Mesh.Algorithm", 3)
gmsh.model.mesh.generate(2)
gmsh.write("L-toy.msh")
gmsh.finalize()
Is there a better way to proceed?
Here is a non-working toy example based on x2.py
import numpy as np
import gmsh
points = np.array([[0.0, 0.0], [0.5, 0.0], [0.5, 0.5], [1.0, 0.5], [1.0, 1.0], [0.0, 1.0], [.25, .7], [.4, .6], [.3, .5], [.4, .7]])
constraints = np.array([[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0]])
nPts = points.shape[0]
nCst = constraints.shape[0]
gmsh.initialize([], False)
pts = np.zeros([nPts, 3])
pts[:, :2] = points[:, :]
for i in range(nPts):
gmsh.model.addDiscreteEntity(0, i+1)
gmsh.model.setCoordinates(i+1, pts[i, 0], pts[i, 1], pts[i, 2])
for i in range(nCst):
gmsh.model.addDiscreteEntity(1, i+1, constraints[i]+1)
gmsh.model.addDiscreteEntity(2, 1, np.arange(1, nCst+1))
gmsh.model.geo.synchronize()
gmsh.model.mesh.addNodes(2, 1, np.arange(1, nPts+1), pts.reshape([-1]))
for i in range(nPts):
gmsh.model.mesh.addElementsByType(i+1, 15, [], [i+1])
for i in range(nCst):
gmsh.model.mesh.addElementsByType(i+1, 1, [], constraints[i]+1)
gmsh.model.mesh.reclassifyNodes()
gmsh.model.mesh.createGeometry()
gmsh.option.setNumber("Mesh.Algorithm", 3)
gmsh.model.mesh.generate(2)
gmsh.write("L-toy.msh")
gmsh.finalize()
The surface is not meshed, while it does exist. What am I missing?
I had a look at the following examples:
but I didn't succeed in modifying those to achieve my goals (see above).
Is there a preferred way?
My inputs are respectively a list of coordinates (the points), and a list of pairs of integers (the constrained edges, defined by their nodes).
valgrind output
...
==5384== Invalid write of size 8
==5384== at 0x7A5F880: gmsh::model::mesh::getElementFaceNodes(int, int, std::vector<unsigned long, std::allocator<unsigned long> >&, int, bool, unsigned long, unsigned long) (gmsh.cpp:4500)
==5384== by 0x8744750: gmshModelMeshGetElementFaceNodes (gmshc.cpp:1687)
==5384== by 0x4876D49: ??? (in /usr/lib/libffi.so.8.1.0)
==5384== by 0x4876266: ??? (in /usr/lib/libffi.so.8.1.0)
==5384== by 0x48593D4: ??? (in /usr/lib/python3.10/lib-dynload/_ctypes.cpython-310-x86_64-linux-gnu.so)
==5384== by 0x485860F: ??? (in /usr/lib/python3.10/lib-dynload/_ctypes.cpython-310-x86_64-linux-gnu.so)
==5384== by 0x49D36B2: _PyObject_MakeTpCall (in /usr/lib/libpython3.10.so.1.0)
==5384== by 0x49CEE7A: _PyEval_EvalFrameDefault (in /usr/lib/libpython3.10.so.1.0)
==5384== by 0x49D9537: _PyFunction_Vectorcall (in /usr/lib/libpython3.10.so.1.0)
==5384== by 0x49CE55E: _PyEval_EvalFrameDefault (in /usr/lib/libpython3.10.so.1.0)
==5384== by 0x49C8601: ??? (in /usr/lib/libpython3.10.so.1.0)
==5384== by 0x4A7C89F: PyEval_EvalCode (in /usr/lib/libpython3.10.so.1.0)
==5384== Address 0x26954ee0 is 0 bytes after a block of size 522,720 alloc'd
==5384== at 0x483F013: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5384== by 0x7A6FFE6: allocate (new_allocator.h:121)
==5384== by 0x7A6FFE6: allocate (alloc_traits.h:460)
==5384== by 0x7A6FFE6: _M_allocate (stl_vector.h:346)
==5384== by 0x7A6FFE6: std::vector<unsigned long, std::allocator<unsigned long> >::_M_default_append(unsigned long) (vector.tcc:635)
==5384== by 0x7A5F6EF: resize (stl_vector.h:940)
==5384== by 0x7A5F6EF: gmsh::model::mesh::getElementFaceNodes(int, int, std::vector<unsigned long, std::allocator<unsigned long> >&, int, bool, unsigned long, unsigned long) (gmsh.cpp:4481)
==5384== by 0x8744750: gmshModelMeshGetElementFaceNodes (gmshc.cpp:1687)
==5384== by 0x4876D49: ??? (in /usr/lib/libffi.so.8.1.0)
==5384== by 0x4876266: ??? (in /usr/lib/libffi.so.8.1.0)
==5384== by 0x48593D4: ??? (in /usr/lib/python3.10/lib-dynload/_ctypes.cpython-310-x86_64-linux-gnu.so)
==5384== by 0x485860F: ??? (in /usr/lib/python3.10/lib-dynload/_ctypes.cpython-310-x86_64-linux-gnu.so)
==5384== by 0x49D36B2: _PyObject_MakeTpCall (in /usr/lib/libpython3.10.so.1.0)
==5384== by 0x49CEE7A: _PyEval_EvalFrameDefault (in /usr/lib/libpython3.10.so.1.0)
==5384== by 0x49D9537: _PyFunction_Vectorcall (in /usr/lib/libpython3.10.so.1.0)
==5384== by 0x49CE55E: _PyEval_EvalFrameDefault (in /usr/lib/libpython3.10.so.1.0)
==5384==
valgrind: m_mallocfree.c:303 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 10246, hi = 629997568.
...
@geuzaine I have the same issue on Arch Linux
...
-------------------------------------------------------
Version : 4.9.4-git-b91ac741d
License : GNU General Public License
Build OS : Linux64-sdk
Build date : 20220118
Build host : ***
Build options : 64Bit ALGLIB[contrib] ANN[contrib] Bamg Blossom Cairo Cgns DIntegration Dlopen DomHex Eigen[contrib] Fltk GMP Gmm[contrib] Hxt Jpeg Kbipack LinuxJoystick MathEx[contrib] Med Mesh Metis[contrib] Mmg Mpeg Netgen ONELAB ONELABMetamodel OpenCASCADE OpenCASCADE-CAF OpenGL OpenMP OptHom Parser Plugins Png Post QuadMeshingTools QuadTri Solver TetGen/BR Voro++[contrib] WinslowUntangler Zlib
FLTK version : 1.3.8
OCC version : 7.5.3
MED version : 4.1.0
Packaged by : ***
Web site : https://gmsh.info
Issue tracker : https://gitlab.onelab.info/gmsh/gmsh/issues
-------------------------------------------------------
3
ok
4
malloc(): mismatching next->prev_size (unsorted)
Aborted (core dumped)
If you want to create a physical group per model entity, you could do this in a python script, eg.:
import gmsh
gmsh.initialize()
gmsh.merge("myfile.someextension") # or gmsh.open
v = gmsh.model.getEntities(3)
for vi in v:
gmsh.model.addPhysicalGroup(3, [vi[1]], vi[1])
f = gmsh.model.getEntities(2)
for fi in f:
gmsh.model.addPhysicalGroup(2, [fi[1]], fi[1])
l = gmsh.model.getEntities(1)
for li in l:
gmsh.model.addPhysicalGroup(1, [li[1]], li[1])
p = gmsh.model.getEntities(0)
for pi in p:
gmsh.model.addPhysicalGroup(0, [pi[1]], pi[1])
# doing stuff
gmsh.finalize()
or in short
import gmsh
gmsh.initialize()
gmsh.merge("myfile.someextension") # or gmsh.open
for i in range(4):
E = gmsh.model.getEntities(i)
for ei in E:
gmsh.model.addPhysicalGroup(i, [ei[1]], ei[1])
# doing stuff
gmsh.finalize()
Thank you CĂ©lestin and Christophe for your help. I highly appreciate it :-)
Let's start simple: planar 2D case -- (points, constrained edges) |-> conforming Delaunay Triangulation.
I would like to triangulate a set of points in a Delaunay fashion, with some constrained edges.
There are two kinds of constrained edges: boundary ones, and inner ones.
Those constrained edges could intersect each other; if this is a nasty situation to handle, I could ignore those for the time being.
The triangulation should cover only the domain (which might be non-convex).
I'm able to achieve this using cgal
, but I'd rather use gmsh
:-)
However, the mesh is not that good close to the constrained edges
I cannot add any point in the domain, but I'm allowed to refine the constrained edges if this could improve the quality of those (upper) bad shaped triangles.
The lesser simple case: volumetric 3D case -- (points, constrained edges, constrained triangles) |-> conforming Delaunay tetrahedrization. The situation is quite analogous: a set of points, some constrained triangles and edges. Yet, intersections of those constraints shouldn't happen in 3D. The constraints might be refined to improve the quality.
In both cases (2D & 3D), the given points cannot be moved. I'm first interested in the planar 2D case, but soon I'd need to achieve the same task for the volumetric 3D case.
Hi every1.
Is there a way to generate a constrained Delaunay triangulation (tetrahedrization) from a set of points and constrained curves (resp, surfaces)?
This example seems promising, but does it handle some constraints, if I define some edges (triangles) in addition to the points?