feat(mesh,io): stub Gmsh reader and VTU writer without optional deps

Without Gmsh or WriteVTK loaded, read_gmsh_msh and write_vtu_mesh raise clear
ErrorException messages pointing users at the weak extension packages.

- Add gmsh_stub.jl docstrings, read_gmsh_msh stub, mesh_from_current_gmsh_model
- Add write_vtu.jl docstring and write_vtu_mesh stub for WriteVTK extension
This commit is contained in:
Jukka Aho
2026-05-11 02:58:08 +03:00
parent 6657ec8419
commit 40350b2da1
2 changed files with 88 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: 2015-2026 Jukka Aho
# SPDX-License-Identifier: MIT
"""
write_vtu_mesh(basepath::AbstractString, mesh::Mesh; point_data = (;), cell_data = (;)) -> String
Write a single-block VTU (VTK XML unstructured grid) for `mesh`.
`basepath` must not include a file extension; WriteVTK appends `.vtu`.
# Point and cell fields
- `point_data`: `NamedTuple` of nodal fields. Each value is either a length-`nnodes_total(mesh)`
vector (scalar) or a `3 × nnodes_total` matrix (3-vector per node, e.g. displacement).
- `cell_data`: `NamedTuple` of per-element fields; each value is a length-`nelements(mesh)` vector.
# Weak dependency
This entry point is implemented in `JuliaFEMWriteVTKExt` when
[`WriteVTK.jl`](https://github.com/JuliaVTK/WriteVTK.jl) is loaded after JuliaFEM:
```julia
using JuliaFEM, WriteVTK
write_vtu_mesh(joinpath(outdir, "solution"), mesh; point_data = (; u = uvec))
```
Supported topologies: linear `Seg2`, `Tri3`, `Quad4`, `Tet4`, and `Hex8` only.
See also: [`read_gmsh_msh`](@ref) for the Gmsh reader extension.
"""
function write_vtu_mesh(args...; kwargs...)
throw(
ErrorException(
"write_vtu_mesh requires the WriteVTK.jl package. " *
"Add it to your environment (`import Pkg; Pkg.add(\"WriteVTK\")`) " *
"and run `using WriteVTK` after `using JuliaFEM` so the " *
"`JuliaFEMWriteVTKExt` extension can load.",
),
)
end
+48
View File
@@ -0,0 +1,48 @@
# SPDX-FileCopyrightText: 2015-2026 Jukka Aho
# SPDX-License-Identifier: MIT
"""
read_gmsh_msh(path::AbstractString; kwargs...) -> Mesh
Read a Gmsh `.msh` file into a concrete [`Mesh`](@ref).
Supported volume/surface Gmsh element types (linear only): **3-node triangle** (2),
**4-node quadrilateral** (3), **4-node tetrahedron** (4), **8-node hexahedron** (5).
Mixed cell types in the same file are not supported.
Keyword `dim` may be `2` or `3` to select surface or volume elements; the default
chooses dimension **3** if the model has 3D cells, otherwise **2**.
Physical groups on the mesh dimension populate [`element_sets`](@ref) using
sanitized physical names (fallback `physical_{dim}_{tag}`). Physical groups one
dimension lower (boundary curves in 2D, boundary faces in 3D) populate
[`node_sets`](@ref).
Implemented in `JuliaFEMGmshExt` when [`Gmsh.jl`](https://github.com/JuliaFEM/Gmsh.jl)
is loaded after `using JuliaFEM` (`import Pkg; Pkg.add("Gmsh")` then `using Gmsh`).
Without that package, calling `read_gmsh_msh` with a path string raises an
`ErrorException` with install instructions (other arities always raise here).
"""
function read_gmsh_msh(args...; kwargs...)
throw(
ErrorException(
"read_gmsh_msh requires the Gmsh.jl package. " *
"Add it to your environment (`import Pkg; Pkg.add(\"Gmsh\")`) " *
"and run `using Gmsh` after `using JuliaFEM` so the " *
"`JuliaFEMGmshExt` extension can load.",
),
)
end
"""
mesh_from_current_gmsh_model(; kwargs...) -> Mesh
Build a [`Mesh`](@ref) from the **currently active** Gmsh model (after
`Gmsh.initialize`, geometry, and `gmsh.model.mesh.generate`).
The same element-type rules and keyword `dim` apply as for [`read_gmsh_msh`](@ref).
Implemented in `JuliaFEMGmshExt` when `Gmsh` is loaded. Without it, you get a
`MethodError` (no method defined).
"""
function mesh_from_current_gmsh_model end