mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-08-06 04:21:33 +00:00
120 lines
3.4 KiB
Julia
120 lines
3.4 KiB
Julia
|
|
# SPDX-FileCopyrightText: 2015-2026 Jukka Aho
|
|||
|
|
# SPDX-License-Identifier: MIT
|
|||
|
|
|
|||
|
|
module JuliaFEMWriteVTKExt
|
|||
|
|
|
|||
|
|
using JuliaFEM
|
|||
|
|
using WriteVTK
|
|||
|
|
|
|||
|
|
const _VTK = WriteVTK.VTKCellTypes
|
|||
|
|
|
|||
|
|
function _vtk_cell_type(::Type{T}) where {T}
|
|||
|
|
if T === Hex8
|
|||
|
|
return _VTK.VTK_HEXAHEDRON
|
|||
|
|
elseif T === Tet4
|
|||
|
|
return _VTK.VTK_TETRA
|
|||
|
|
elseif T === Quad4
|
|||
|
|
return _VTK.VTK_QUAD
|
|||
|
|
elseif T === Tri3
|
|||
|
|
return _VTK.VTK_TRIANGLE
|
|||
|
|
elseif T === Seg2
|
|||
|
|
return _VTK.VTK_LINE
|
|||
|
|
else
|
|||
|
|
throw(
|
|||
|
|
ArgumentError(
|
|||
|
|
"VTK export does not support topology $T. " *
|
|||
|
|
"Supported: Hex8, Tet4, Quad4, Tri3, Seg2.",
|
|||
|
|
),
|
|||
|
|
)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
function _points_matrix(mesh::Mesh{N,T}) where {N,T}
|
|||
|
|
n = nnodes_total(mesh)
|
|||
|
|
pts = Matrix{Float64}(undef, 3, n)
|
|||
|
|
@inbounds for i in 1:n
|
|||
|
|
v = mesh.nodes[i]
|
|||
|
|
pts[1, i] = v[1]
|
|||
|
|
pts[2, i] = v[2]
|
|||
|
|
pts[3, i] = v[3]
|
|||
|
|
end
|
|||
|
|
return pts
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
function _mesh_cells(mesh::Mesh{N,T}) where {N,T}
|
|||
|
|
vtk_ct = _vtk_cell_type(T)
|
|||
|
|
ne = nelements(mesh)
|
|||
|
|
cells = Vector{MeshCell}(undef, ne)
|
|||
|
|
@inbounds for e in 1:ne
|
|||
|
|
conn = mesh.connectivity[e]
|
|||
|
|
cells[e] = MeshCell(vtk_ct, collect(Int, conn))
|
|||
|
|
end
|
|||
|
|
return cells
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
function _strip_vtu_extension(basepath::AbstractString)
|
|||
|
|
path = String(basepath)
|
|||
|
|
if endswith(lowercase(path), ".vtu")
|
|||
|
|
return path[1:(end - 4)]
|
|||
|
|
end
|
|||
|
|
return path
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
function _validate_point_data(mesh::Mesh, point_data::NamedTuple)
|
|||
|
|
n = nnodes_total(mesh)
|
|||
|
|
for (k, v) in pairs(point_data)
|
|||
|
|
if v isa AbstractVector
|
|||
|
|
length(v) == n ||
|
|||
|
|
throw(ArgumentError("point_data.$k: expected length $n (nnodes), got $(length(v))"))
|
|||
|
|
elseif v isa AbstractMatrix
|
|||
|
|
size(v, 2) == n ||
|
|||
|
|
throw(ArgumentError("point_data.$k: expected matrix with $n columns, got $(size(v))"))
|
|||
|
|
size(v, 1) in (1, 2, 3) ||
|
|||
|
|
throw(ArgumentError("point_data.$k: expected 1×n, 2×n, or 3×n matrix, got $(size(v))"))
|
|||
|
|
else
|
|||
|
|
throw(ArgumentError("point_data.$k: unsupported type $(typeof(v))"))
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
return nothing
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
function _validate_cell_data(mesh::Mesh, cell_data::NamedTuple)
|
|||
|
|
ne = nelements(mesh)
|
|||
|
|
for (k, v) in pairs(cell_data)
|
|||
|
|
v isa AbstractVector ||
|
|||
|
|
throw(ArgumentError("cell_data.$k: expected AbstractVector, got $(typeof(v))"))
|
|||
|
|
length(v) == ne ||
|
|||
|
|
throw(ArgumentError("cell_data.$k: expected length $ne (nelements), got $(length(v))"))
|
|||
|
|
end
|
|||
|
|
return nothing
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
function JuliaFEM.write_vtu_mesh(
|
|||
|
|
basepath::AbstractString,
|
|||
|
|
mesh::Mesh{N,T};
|
|||
|
|
point_data::NamedTuple = (;),
|
|||
|
|
cell_data::NamedTuple = (;),
|
|||
|
|
) where {N,T}
|
|||
|
|
_vtk_cell_type(T)
|
|||
|
|
root = _strip_vtu_extension(basepath)
|
|||
|
|
pts = _points_matrix(mesh)
|
|||
|
|
cells = _mesh_cells(mesh)
|
|||
|
|
isempty(point_data) || _validate_point_data(mesh, point_data)
|
|||
|
|
isempty(cell_data) || _validate_cell_data(mesh, cell_data)
|
|||
|
|
|
|||
|
|
vtk = vtk_grid(root, pts, cells)
|
|||
|
|
for (name, vals) in pairs(point_data)
|
|||
|
|
if vals isa AbstractVector
|
|||
|
|
vtk[String(name), VTKPointData()] = collect(Float64, vals)
|
|||
|
|
else
|
|||
|
|
vtk[String(name), VTKPointData()] = Float64.(vals)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
for (name, vals) in pairs(cell_data)
|
|||
|
|
vtk[String(name), VTKCellData()] = collect(Float64, vals)
|
|||
|
|
end
|
|||
|
|
return first(vtk_save(vtk))
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
end # module
|