Skip to content

Commit bacd12f

Browse files
authored
Merge branch 'JuliaGeodynamics:main' into main
2 parents 626a260 + 951d924 commit bacd12f

File tree

6 files changed

+161
-4
lines changed

6 files changed

+161
-4
lines changed

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ makedocs(;
108108
"Projection" => "man/projection.md",
109109
"Surfaces" => "man/surfaces.md",
110110
"Paraview output" => "man/paraview_output.md",
111+
"Paraview collection" => "man/paraview_collection.md",
111112
"Tools" => "man/tools.md",
112113
"Visualisation" => "man/visualise.md",
113114
"Gravity code" => "man/gravity_code.md",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Paraview collection
2+
3+
We have one main routine to generate `*.pvd` files from existing `vtk` files. This is useful if no `*.pvd` file was generated during the simulation, or if you want to generate a `*.pvd` file from a collection of `vtk` files that were generated in different simulations. The `*.pvd` file can be used to animate temporal data in paraview. You can either provide a Vector of the files or the specific time step or the function reads the directory and assigns a pseudo time step to the `*.pvd` file.
4+
```@docs
5+
GeophysicalModelGenerator.make_paraview_collection
6+
```

src/GeophysicalModelGenerator.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ include("coord_conversion.jl")
3636
include("nearest_points.jl")
3737
include("utils.jl")
3838
include("Paraview_output.jl")
39+
include("Paraview_collection.jl")
3940
include("transformation.jl")
4041
include("voxel_gravity.jl")
4142
include("LaMEM_io.jl")
@@ -52,13 +53,13 @@ include("movies_from_pics.jl")
5253
# GMT routines
5354

5455
"""
55-
ImportTopo
56+
ImportTopo
5657
Optional routine that imports topography. It requires you to load `GMT`
5758
"""
5859
function ImportTopo end
5960

6061
"""
61-
ImportGeoTIFF
62+
ImportGeoTIFF
6263
Optional routine that imports GeoTIFF images. It requires you to load `GMT`
6364
"""
6465
function ImportGeoTIFF end

src/Paraview_collection.jl

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using LightXML
2+
using WriteVTK, Printf
3+
4+
export make_paraview_collection
5+
6+
"""
7+
make_paraview_collection(; dir=pwd(), pvd_name=nothing, files=nothing, file_extension = ".vts", time = nothing)
8+
9+
In case one has a list of `*.vtk` files, this routine creates a `*.pvd` file that can be opened in Paraview.
10+
This is useful if you previously saved vtk files but didnt save it as a collection in the code itself.
11+
12+
Optional options
13+
===
14+
- `dir`: directory where the `*.vtk` are stored.
15+
- `pvd_name`: filename of the resulting `*.pvd` file without extension; if not specified, `full_simulation` is used.
16+
- `files`: Vector of the `*.vtk` files without extension; if not specified, all `*.vtk` files in the directory are used.
17+
- `file_extension`: file extension of the vtk files. Default is `.vts` but all `vt*` work.
18+
- `time`: Vector of the timesteps; if not specified, pseudo time steps are assigned.
19+
"""
20+
function make_paraview_collection(; dir=pwd(), pvd_name=nothing, files=nothing, file_extension = ".vts", time = nothing)
21+
22+
# if no files are given, use all vtm files in the directory
23+
curdir = pwd()
24+
cd(dir)
25+
if isnothing(files)
26+
files = filter(endswith(file_extension), readdir())
27+
files = joinpath.(dir, files)
28+
end
29+
# if no time is given, use pseudo time steps
30+
if isnothing(time)
31+
time = [string(i) for i in 1:length(files)]
32+
end
33+
# Check that the arrays have the same length
34+
@assert length(time) == length(files)
35+
@assert length(files) > 0
36+
37+
# Create a new paraview collection
38+
if isnothing(pvd_name)
39+
pvd_name = "full_simulation"
40+
end
41+
42+
pvd_name = joinpath(curdir, pvd_name)
43+
44+
make_paraview_collection(pvd_name, files, time)
45+
cd(curdir) # return to original directory
46+
return pvd_name
47+
end
48+
49+
"""
50+
make_paraview_collection(pvd_name::String, files::Vector{String}, time::Vector{String})
51+
This function makes a `*.pvd` file from a provided list of `*.vtk` files and time steps.
52+
53+
Inputs are:
54+
- `pvd_name`: filename of the resulting `*.pvd` file without extension.
55+
- `files`: Vector of desired files to be included in the `*.pvd` file.
56+
- `time`: Vector of time steps corresponding to the `files` vector.
57+
"""
58+
59+
function make_paraview_collection(pvd_name::String, files::Vector{String}, time::Vector{String})
60+
# Check that the arrays have the same length
61+
@assert length(time) == length(files)
62+
63+
# Create a new paraview collection
64+
pvd = paraview_collection(pvd_name)
65+
# save the collection
66+
vtk_save(pvd)
67+
68+
# Parse the XML file
69+
xdoc = parse_file("$pvd_name.pvd")
70+
71+
# Find the <Collection> element
72+
collection = find_element(root(xdoc), "Collection")
73+
74+
# Loop over the time and data values
75+
for i in 1:length(time)
76+
# Create a new <DataSet> element
77+
new_dataset = new_child(collection, "DataSet")
78+
# Set the attributes of the new <DataSet> element
79+
set_attribute(new_dataset, "timestep", time[i])
80+
set_attribute(new_dataset, "part", "0")
81+
set_attribute(new_dataset, "file", files[i])
82+
end
83+
84+
# Write the modified XML to a new file of your choice (or overwrite the original)
85+
open("$pvd_name.pvd", "w") do f
86+
print(f, xdoc)
87+
end
88+
# pretty print the xml file
89+
str = read("$pvd_name.pvd", String)
90+
str_out = replace(str, "/>" => "/>\n")
91+
open("$pvd_name.pvd", "w") do f
92+
print(f, str_out)
93+
end
94+
return pvd_name
95+
end

test/runtests.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ end
1010
@testset "Paraview" begin
1111
include("test_paraview.jl")
1212
end
13+
@testset "Paraview collection" begin
14+
include("test_paraview_collection.jl")
15+
end
1316
@testset "Gravity model" begin
1417
include("test_voxel_gravity.jl")
1518
end
@@ -57,8 +60,7 @@ end
5760
include("test_create_movie.jl")
5861
end
5962

60-
# Cleanup
63+
# Cleanup
6164
foreach(rm, filter(endswith(".vts"), readdir()))
6265
foreach(rm, filter(endswith(".vtu"), readdir()))
6366
rm("./markers/",recursive=true)
64-

test/test_paraview_collection.jl

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using Test
2+
using GeophysicalModelGenerator, WriteVTK
3+
@testset "Paraview collection" begin
4+
5+
x, y, z = 0:10, 1:6, 2:0.1:3
6+
times = range(0, 1; step = 1)
7+
8+
#generate `*.vti` files
9+
for (n, time) enumerate(times)
10+
vtk_grid("./test_files/test_vti_$n", x, y, z) do vtk
11+
vtk["Pressure"] = rand(length(x), length(y), length(z))
12+
end
13+
end
14+
15+
# Generate a 3D grid
16+
Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);
17+
Data = Depth*2; # some data
18+
Data_set = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))
19+
Write_Paraview(Data_set, "./test_files/test_depth3D")
20+
21+
make_paraview_collection(;dir = "./test_files", pvd_name="test", file_extension=".vti")
22+
@test isfile("test.pvd")
23+
@test filesize("test.pvd") == 317
24+
25+
make_paraview_collection(;dir = "./test_files", file_extension=".vti")
26+
@test isfile("full_simulation.pvd")
27+
@test filesize("full_simulation.pvd") == 317
28+
29+
make_paraview_collection(;dir = "./test_files")
30+
@test isfile("full_simulation.pvd")
31+
@test filesize("full_simulation.pvd") == 251
32+
33+
34+
files = ["test_files/test_vti_1.vti", "test_files/test_vti_2.vti"]
35+
time = ["1.0", "2.0"]
36+
make_paraview_collection("test2", files, time)
37+
@test isfile("test2.pvd")
38+
@test filesize("test2.pvd") == 317
39+
40+
make_paraview_collection(; pvd_name="test3", files=files, time=time)
41+
@test isfile("test3.pvd")
42+
@test filesize("test3.pvd") == 317
43+
44+
rm("test.pvd")
45+
rm("full_simulation.pvd")
46+
rm("test_files/test_depth3D.vts")
47+
rm("test_files/test_vti_1.vti")
48+
rm("test_files/test_vti_2.vti")
49+
rm("test2.pvd")
50+
rm("test3.pvd")
51+
52+
end

0 commit comments

Comments
 (0)