Skip to content

Commit

Permalink
Add support for field data (#66)
Browse files Browse the repository at this point in the history
* Introduced functions 'get_field' and 'field_data'
in order to be able to read FieldData from VTK files.

* Introduced suggested changes in pull request

* Indented docstring

* Export the `get_field_data` function

* Add test for field data

* Update docstring references on `get_field_data`

* Ignore non DataArray elements

Co-authored-by: Hendrik Ranocha <[email protected]>

* Format field data test

* Add field data support to documentation

* format

---------

Co-authored-by: andresegido <[email protected]>
Co-authored-by: Hendrik Ranocha <[email protected]>
  • Loading branch information
3 people authored Oct 29, 2024
1 parent 67571e9 commit 45b6452
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Further example VTK files can be found in the
### What works
* Reading in VTK XML files of type `UnstructuredGrid`, `StructuredGrid`, `RectilinearGrid`,`ImageData`, `PUnstructuredGrid`,`PStructuredGrid` `PRectilinearGrid`,`PImageData`, or `PolyData`
* Extracting cell or point data
* Extracting field data
* Extracting point coordinates
* Extracting information about cell types
* Only for `ImageData`,`PImageData` files: get origin, spacing, and extent information
Expand Down
1 change: 1 addition & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Further example VTK files can be found in the
### What works
* Reading in VTK XML files of type `UnstructuredGrid`, `StructuredGrid`, `RectilinearGrid`,`ImageData`, `PUnstructuredGrid`, `PStructuredGrid`, `PRectilinearGrid`,`PImageData`, or `PolyData`
* Extracting cell or point data
* Extracting field data
* Extracting point coordinates
* Extracting information about cell types
* Only for `ImageData`,`PImageData` files: get origin, spacing, and extent information
Expand Down
43 changes: 36 additions & 7 deletions src/ReadVTK.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ using Reexport: @reexport

export VTKFile, VTKData, VTKDataArray, VTKCells, VTKPrimitives, # structs
PVTKFile, PVTKData, PVTKDataArray, PVDFile,
get_point_data, get_cell_data, get_data, get_data_reshaped, # get data functions
get_point_data, get_cell_data, get_field_data, get_data, # get data functions
get_data_reshaped,
get_points, get_cells, get_origin, get_spacing, get_primitives, # get geometry functions
get_coordinates, get_coordinate_data, # get geometry functions
get_example_file, # other functions
Expand Down Expand Up @@ -184,6 +185,11 @@ function piece(vtk_file::VTKFile)
return LightXML.root(vtk_file.xml_file)[vtk_file.file_type][1]["Piece"][1]
end

# Return `FieldData` XML element that contains all VTK field data
function field_data(vtk_file::VTKFile)
return LightXML.root(vtk_file.xml_file)[vtk_file.file_type][1]["FieldData"][1]
end

"""
isstructured(xml_file)
Expand Down Expand Up @@ -433,14 +439,37 @@ function get_data_section(vtk_file::VTKFile, section)
return VTKData(names, data_arrays, vtk_file)
end

"""
get_field_data(vtk_file::VTKFile)
Retrieve a lightweight `VTKData` object with the field data of the given VTK file.
See also: [`VTKData`](@ref), [`get_point_data`](@ref), [`get_cell_data`](@ref)
"""
function get_field_data(vtk_file::VTKFile)
names = String[]
data_arrays = XMLElement[]

# Iterate over XML elemens in the section
for xml_element in child_elements(field_data(vtk_file))
# We do not know how to handle anything other than `DataArray`s
LightXML.name(xml_element) != "DataArray" && continue

# Store the name and the XML element for each found data array
push!(names, attribute(xml_element, "Name", required = true))
push!(data_arrays, xml_element)
end

return VTKData(names, data_arrays, vtk_file)
end

"""
get_cell_data(vtk_file::VTKFile)
Retrieve a lightweight `VTKData` object with the cell data of the given VTK file.
Only numeric data (i.e., `DataArray`) elements will be read.
See also: [`VTKData`](@ref), [`get_point_data`](@ref)
See also: [`VTKData`](@ref), [`get_point_data`](@ref), [`get_field_data`](@ref)
"""
get_cell_data(vtk_file::VTKFile) = get_data_section(vtk_file, "CellData")

Expand All @@ -450,7 +479,7 @@ get_cell_data(vtk_file::VTKFile) = get_data_section(vtk_file, "CellData")
Retrieve a lightweight vector with `PVTKData` objects with the cell data of the given PVTK files.
Only numeric data (i.e., `DataArray`) elements will be read.
See also: [`PVTKData`](@ref), [`get_cell_data`](@ref)
See also: [`PVTKData`](@ref), [`get_point_data`](@ref), [`get_field_data`](@ref)
"""
function get_cell_data(pvtk_file::PVTKFile)
n_files = length(pvtk_file)
Expand All @@ -469,7 +498,7 @@ end
Retrieve a lightweight `VTKData` object with the point data of the given VTK file.
Only numeric data (i.e., `DataArray`) elements will be read.
See also: [`VTKData`](@ref), [`get_cell_data`](@ref)
See also: [`VTKData`](@ref), [`get_cell_data`](@ref), [`get_field_data`](@ref)
"""
get_point_data(vtk_file::VTKFile) = get_data_section(vtk_file, "PointData")

Expand All @@ -479,7 +508,7 @@ get_point_data(vtk_file::VTKFile) = get_data_section(vtk_file, "PointData")
Retrieve a lightweight vector with `PVTKData` objects with the point data of the given PVTK files.
Only numeric data (i.e., `DataArray`) elements will be read.
See also: [`PVTKData`](@ref), [`get_cell_data`](@ref)
See also: [`PVTKData`](@ref), [`get_cell_data`](@ref), [`get_field_data`](@ref)
"""
function get_point_data(pvtk_file::PVTKFile)
n_files = length(pvtk_file)
Expand All @@ -497,7 +526,7 @@ end
Retrieve a lightweight `VTKData` object with the coordinate data of the given VTK file.
Only coordinates of numeric data (i.e., `DataArray`) elements will be read.
See also: [`VTKData`](@ref), [`get_point_data`](@ref), [`get_cell_data`](@ref)
See also: [`VTKData`](@ref), [`get_point_data`](@ref), [`get_cell_data`](@ref), [`get_field_data`](@ref)
"""
get_coordinate_data(vtk_file::VTKFile) = get_data_section(vtk_file, "Coordinates")

Expand All @@ -507,7 +536,7 @@ get_coordinate_data(vtk_file::VTKFile) = get_data_section(vtk_file, "Coordinates
Retrieve a lightweight `{VTKData` object with the coordinate data of the given VTK file.
Only coordinates of numeric data (i.e., `DataArray`) elements will be read.
See also: [`PVTKData`](@ref), [`get_point_data`](@ref), [`get_cell_data`](@ref)
See also: [`PVTKData`](@ref), [`get_point_data`](@ref), [`get_cell_data`](@ref), [`get_field_data`](@ref)
"""
function get_coordinate_data(pvtk_file::PVTKFile)
return get_data_section.(pvtk_file.vtk_files, "Coordinates")
Expand Down
23 changes: 23 additions & 0 deletions test/fielddata.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Create some cells
points = rand(3, 5)
cells = [
MeshCell(VTKCellTypes.VTK_TRIANGLE, [1, 4, 2]),
MeshCell(VTKCellTypes.VTK_QUAD, [2, 4, 3, 5]),
]

scalar = 5.0
vector = [1.0, 2.0, 3.0]

path = joinpath(TEST_EXAMPLES_DIR, "fields")

vtk_grid(path, points, cells, append = false) do vtk
vtk["scalar"] = scalar
return vtk["vector"] = vector
end

vtk_read = VTKFile(path * ".vtu")
fielddata = get_field_data(vtk_read)

@test only(get_data(fielddata["scalar"])) == scalar

@test get_data(fielddata["vector"]) == vector
9 changes: 9 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -445,4 +445,13 @@ clean_directory(TEST_EXAMPLES_DIR) = @test_nowarn rm(TEST_EXAMPLES_DIR, recursiv
clean_directory(TEST_EXAMPLES_DIR)
end

@testset "Field data" begin
# Start with a clean environment: remove example file directory if it exists
create_directory(TEST_EXAMPLES_DIR)

include("fielddata.jl")

# Clean up afterwards: delete example file directory
clean_directory(TEST_EXAMPLES_DIR)
end
end

0 comments on commit 45b6452

Please sign in to comment.