Skip to content

Commit 7f78189

Browse files
SimonCangithub-actions[bot]DanielDoehringsloedeJoshuaLampert
authored
WIP: Sc/Enhanced p4est mesh views (#2110)
* Sterted re-implementing p4est mesh views to be more powerful. * Added P4estMeshView specific methods for computing calc_node_coordinates. * Added p4est mesh views. * Removed some debugging. * Corrected matrix calculation in calc_node_coordinates for p4est mesh view. * Plae holders for p4est mesh view. Thius version runs, but does not have all features. * Some refactoring. * Removed most references to parent mesh. This now goes through with mesh view being equal to the orginal mesh. * Minor corrections. * Added commentson next steps. * Added real option of choosing elements of p4est mesh view. * Little clean up. * Added first batch of corrections for P4estMeshView. * Added place holders for p4est mesh view. * Added p4est -> p4est mesh view extraction routine. * Added flattened arrays. * Added prolong2interfaces to p4est mesh view. * Minor corrections. * Removed redundant P4estMeshView in calc_interface_flux. * Corrected extraction of interfaces given an array of cell ids to include in the p4est mesh view. * Write out of P4estMeshView data. Not finished yet. * Fixed issue with non-simply connected p4est mesh views. * Update src/callbacks_step/analysis_dg2d.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/meshes/mesh_io.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/callbacks_step/analysis_dg2d.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * No nead for P4estMeshView having its own prolong2interfaces function. * Corrected typo in comment. * Fixed typos. * Update src/solvers/dgsem_unstructured/dg_2d.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/solvers/dgsem_tree/dg_2d.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/callbacks_step/analysis_dg2d.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Applied autoformatter. * Fixed t8code issue. * Added p4est mesh view into tests. * Reduced the number of elements. * Added P4estMeshView to the error norms. * Fixed typo in example run. * Applied autoformatter. * Removed unused calc_node_coordinates for p4est mesh view. * Removed unused code. * Added 'cell-ids' attribute to mesh files read and write for P4estMeshView. * Added calc_node_coordinates function for P4estMeshView. Corrected real function for P4estMeshView. * Corrected tree indices. * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * We are now writing all the parent's boundary names into the mesh files. * removed debugging output. * Improved readability for function call. * Update src/meshes/mesh_io.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/callbacks_step/analysis_dg2d.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/callbacks_step/analysis_dg2d.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Moved P4estMeshView stuff into the same line. * Update save_solution_dg.jl * Update src/callbacks_step/save_solution_dg.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Added the calulcation of node coordinates for p4est mesh view. This should cover the calc_node_coordinates! routine in the tests. * Added the loading of a p4est mesh view file to improve code coverage. * Applied the Trixi autoformatter. * Update examples/p4est_2d_dgsem/elixir_advection_meshview.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Applied autoformatter. * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Daniel Doehring <[email protected]> * Removed unused code. * Update examples/p4est_2d_dgsem/elixir_advection_meshview.jl Co-authored-by: Michael Schlottke-Lakemper <[email protected]> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Michael Schlottke-Lakemper <[email protected]> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Michael Schlottke-Lakemper <[email protected]> * Added deepcopy of elements_parent and interfaces_parent to avoid overwrite of parent variables. Added warning on overwriting existing mesh files. * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Michael Schlottke-Lakemper <[email protected]> * Replaced 'elements' index with 'mesh_view_cell_id' index. * Corrected 'ncells' call in elixir. * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Michael Schlottke-Lakemper <[email protected]> * Generate a new elements, resize it and the populate it with the elements specified in mesh.cell_ids. * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update examples/p4est_2d_dgsem/elixir_advection_meshview.jl Co-authored-by: Joshua Lampert <[email protected]> * Update examples/p4est_2d_dgsem/elixir_advection_meshview.jl Co-authored-by: Joshua Lampert <[email protected]> * Update examples/p4est_2d_dgsem/elixir_advection_meshview.jl Co-authored-by: Joshua Lampert <[email protected]> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Michael Schlottke-Lakemper <[email protected]> * We now deepcopy the parent's elements to sve computational time. Removed commented code. * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Fixed minor typo in solve that happened after moving from OrdinaryDiffEq to OrdinaryDiffEqLowStorageRK. * Corrected typo with tree offset. * Fixed another typo related to tree indices. * REverted to original PRoject.toml. * Update examples/p4est_2d_dgsem/elixir_advection_meshview.jl Co-authored-by: Joshua Lampert <[email protected]> * Update examples/p4est_2d_dgsem/elixir_advection_meshview.jl Co-authored-by: Joshua Lampert <[email protected]> * Remove analysis_callback, as this is not implemented yet for the p4est mesh view. * Removed definition of analysis callback, since it is not used. * Update examples/p4est_2d_dgsem/elixir_advection_meshview.jl Co-authored-by: Joshua Lampert <[email protected]> * Update test/test_p4est_2d.jl Co-authored-by: Joshua Lampert <[email protected]> * Update examples/p4est_2d_dgsem/elixir_advection_meshview.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Added test for basic advection in 2d on p4est meshes with initial_refinement_level=0. * Update test/test_p4est_2d.jl Co-authored-by: Joshua Lampert <[email protected]> * Reinstated the definition of a AnalysisCallback for the test only. * For consistency moved create_cache function for mesh::P4estMeshView. * Interfaces for the p4est mesh views are now being resized from the parent. * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Michael Schlottke-Lakemper <[email protected]> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Michael Schlottke-Lakemper <[email protected]> * Update src/meshes/p4est_mesh_view.jl Co-authored-by: Michael Schlottke-Lakemper <[email protected]> * Reverted move of create_cache function. * Using @views to point to parent interface data. * Corrected error with neighbor_ids not being defined. * Update src/meshes/p4est_mesh_view.jl --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Daniel Doehring <[email protected]> Co-authored-by: Michael Schlottke-Lakemper <[email protected]> Co-authored-by: Joshua Lampert <[email protected]>
1 parent ab28d57 commit 7f78189

File tree

19 files changed

+430
-32
lines changed

19 files changed

+430
-32
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using OrdinaryDiffEqSSPRK, OrdinaryDiffEqLowStorageRK
2+
using Trixi
3+
4+
###############################################################################
5+
# Most basic p4est mesh view setup where the entire domain
6+
# is part of the single mesh view.
7+
8+
advection_velocity = (0.2, -0.7)
9+
equations = LinearScalarAdvectionEquation2D(advection_velocity)
10+
11+
# Create DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux
12+
solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs)
13+
14+
coordinates_min = (-1.0, -1.0) # minimum coordinates (min(x), min(y))
15+
coordinates_max = (1.0, 1.0) # maximum coordinates (max(x), max(y))
16+
17+
trees_per_dimension = (8, 8)
18+
19+
# Create parent P4estMesh with 8 x 8 trees and 8 x 8 elements
20+
parent_mesh = P4estMesh(trees_per_dimension, polydeg = 3,
21+
coordinates_min = coordinates_min,
22+
coordinates_max = coordinates_max,
23+
initial_refinement_level = 0)
24+
25+
# Define the mesh view covering the whole parent mesh.
26+
cell_ids = collect(1:Trixi.ncells(parent_mesh))
27+
mesh = P4estMeshView(parent_mesh, cell_ids)
28+
29+
# A semidiscretization collects data structures and functions for the spatial discretization
30+
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergence_test,
31+
solver)
32+
33+
###############################################################################
34+
# ODE solvers, callbacks etc.
35+
36+
# Create ODE problem with time span from 0.0 to 1.0
37+
ode = semidiscretize(semi, (0.0, 1.0))
38+
39+
# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup
40+
# and resets the timers
41+
summary_callback = SummaryCallback()
42+
43+
# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results
44+
# We require this definition for the test, even though we don't use it in the CallbackSet.
45+
analysis_callback = AnalysisCallback(semi)
46+
47+
# The SaveSolutionCallback allows to save the solution to a file in regular intervals
48+
save_solution = SaveSolutionCallback(interval = 100,
49+
solution_variables = cons2prim)
50+
51+
# The StepsizeCallback handles the re-calculation of the maximum Δt after each time step
52+
stepsize_callback = StepsizeCallback(cfl = 1.6)
53+
54+
# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver
55+
callbacks = CallbackSet(summary_callback, save_solution,
56+
stepsize_callback)
57+
58+
###############################################################################
59+
# run the simulation
60+
61+
# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks
62+
sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false);
63+
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
64+
ode_default_options()..., callback = callbacks);

src/Trixi.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ export lake_at_rest_error
238238
export ncomponents, eachcomponent
239239

240240
export TreeMesh, StructuredMesh, StructuredMeshView, UnstructuredMesh2D, P4estMesh,
241-
T8codeMesh
241+
P4estMeshView, T8codeMesh
242242

243243
export DG,
244244
DGSEM, LobattoLegendreBasis,

src/callbacks_step/analysis_dg2d.jl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ function create_cache_analysis(analyzer, mesh::TreeMesh{2},
3030
end
3131

3232
# Specialized cache for P4estMesh to allow for different ambient dimension from mesh dimension
33-
function create_cache_analysis(analyzer, mesh::P4estMesh{2, NDIMS_AMBIENT},
33+
function create_cache_analysis(analyzer,
34+
mesh::Union{P4estMesh{2, NDIMS_AMBIENT},
35+
P4estMeshView{2, NDIMS_AMBIENT}},
3436
equations, dg::DG, cache,
3537
RealT, uEltype) where {NDIMS_AMBIENT}
3638

@@ -138,7 +140,9 @@ end
138140

139141
function calc_error_norms(func, u, t, analyzer,
140142
mesh::Union{StructuredMesh{2}, StructuredMeshView{2},
141-
UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}},
143+
UnstructuredMesh2D,
144+
P4estMesh{2}, P4estMeshView{2},
145+
T8codeMesh{2}},
142146
equations,
143147
initial_condition, dg::DGSEM, cache, cache_analysis)
144148
@unpack vandermonde, weights = analyzer
@@ -239,7 +243,8 @@ end
239243

240244
function integrate(func::Func, u,
241245
mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2},
242-
UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}},
246+
UnstructuredMesh2D, P4estMesh{2}, P4estMeshView{2},
247+
T8codeMesh{2}},
243248
equations, dg::DG, cache; normalize = true) where {Func}
244249
integrate_via_indices(u, mesh, equations, dg, cache;
245250
normalize = normalize) do u, i, j, element, equations, dg

src/callbacks_step/save_solution_dg.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
function save_solution_file(u, time, dt, timestep,
99
mesh::Union{SerialTreeMesh, StructuredMesh,
1010
StructuredMeshView,
11-
UnstructuredMesh2D, SerialP4estMesh,
11+
UnstructuredMesh2D,
12+
SerialP4estMesh, P4estMeshView,
1213
SerialT8codeMesh},
1314
equations, dg::DG, cache,
1415
solution_callback,

src/callbacks_step/stepsize_dg2d.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ end
115115

116116
function max_dt(u, t,
117117
mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2},
118-
T8codeMesh{2}, StructuredMeshView{2}},
118+
P4estMeshView{2}, T8codeMesh{2}, StructuredMeshView{2}},
119119
constant_speed::True, equations, dg::DG, cache)
120120
@unpack contravariant_vectors, inverse_jacobian = cache.elements
121121

src/meshes/mesh_io.jl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
#! format: noindent
77

88
# Save current mesh with some context information as an HDF5 file.
9-
function save_mesh_file(mesh::Union{TreeMesh, P4estMesh, T8codeMesh}, output_directory,
9+
function save_mesh_file(mesh::Union{TreeMesh, P4estMesh, P4estMeshView, T8codeMesh},
10+
output_directory,
1011
timestep = 0)
1112
save_mesh_file(mesh, output_directory, timestep, mpi_parallel(mesh))
1213
end
@@ -401,6 +402,32 @@ function load_mesh_serial(mesh_file::AbstractString; n_cells_max, RealT)
401402

402403
mesh = P4estMesh{ndims}(p4est, tree_node_coordinates,
403404
nodes, boundary_names, mesh_file, false, true)
405+
elseif mesh_type == "P4estMeshView"
406+
p4est_filename, cell_ids, tree_node_coordinates,
407+
nodes, boundary_names_ = h5open(mesh_file, "r") do file
408+
return read(attributes(file)["p4est_file"]),
409+
read(attributes(file)["cell_ids"]),
410+
read(file["tree_node_coordinates"]),
411+
read(file["nodes"]),
412+
read(file["boundary_names"])
413+
end
414+
415+
boundary_names = boundary_names_ .|> Symbol
416+
417+
p4est_file = joinpath(dirname(mesh_file), p4est_filename)
418+
# Prevent Julia crashes when `p4est` can't find the file
419+
@assert isfile(p4est_file)
420+
421+
p4est = load_p4est(p4est_file, Val(ndims))
422+
423+
unsaved_changes = false
424+
p4est_partition_allow_for_coarsening = true
425+
parent_mesh = P4estMesh{ndims}(p4est, tree_node_coordinates,
426+
nodes, boundary_names, mesh_file,
427+
unsaved_changes,
428+
p4est_partition_allow_for_coarsening)
429+
430+
mesh = P4estMeshView(parent_mesh, cell_ids)
404431

405432
elseif mesh_type == "T8codeMesh"
406433
ndims, ntrees, nelements, tree_node_coordinates,

src/meshes/meshes.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ include("unstructured_mesh.jl")
1313
include("face_interpolant.jl")
1414
include("transfinite_mappings_3d.jl")
1515
include("p4est_mesh.jl")
16+
include("p4est_mesh_view.jl")
1617
include("t8code_mesh.jl")
1718
include("mesh_io.jl")
1819
include("dgmulti_meshes.jl")

src/meshes/p4est_mesh_view.jl

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).
2+
# Since these FMAs can increase the performance of many numerical algorithms,
3+
# we need to opt-in explicitly.
4+
# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.
5+
@muladd begin
6+
#! format: noindent
7+
8+
"""
9+
P4estMeshView{NDIMS, NDIMS_AMBIENT, RealT <: Real, Parent} <: AbstractMesh{NDIMS}
10+
11+
A view on a [`P4estMesh`](@ref).
12+
"""
13+
mutable struct P4estMeshView{NDIMS, NDIMS_AMBIENT, RealT <: Real, Parent} <:
14+
AbstractMesh{NDIMS}
15+
parent::Parent
16+
cell_ids::Vector{Int}
17+
unsaved_changes::Bool
18+
current_filename::String
19+
end
20+
21+
"""
22+
P4estMeshView(parent; cell_ids)
23+
24+
Create a `P4estMeshView` on a [`P4estMesh`](@ref) parent.
25+
26+
# Arguments
27+
- `parent`: the parent `P4estMesh`.
28+
- `cell_ids`: array of cell ids that are part of this view.
29+
"""
30+
function P4estMeshView(parent::P4estMesh{NDIMS, NDIMS_AMBIENT, RealT},
31+
cell_ids::Vector) where {NDIMS, NDIMS_AMBIENT, RealT}
32+
return P4estMeshView{NDIMS, NDIMS_AMBIENT, RealT, typeof(parent)}(parent, cell_ids,
33+
parent.unsaved_changes,
34+
parent.current_filename)
35+
end
36+
37+
@inline Base.ndims(::P4estMeshView{NDIMS}) where {NDIMS} = NDIMS
38+
@inline Base.real(::P4estMeshView{NDIMS, NDIMS_AMBIENT, RealT}) where {NDIMS, NDIMS_AMBIENT, RealT} = RealT
39+
40+
function extract_p4est_mesh_view(elements_parent,
41+
interfaces_parent,
42+
boundaries_parent,
43+
mortars_parent,
44+
mesh,
45+
equations,
46+
dg,
47+
::Type{uEltype}) where {uEltype <: Real}
48+
# Create deepcopy to get completely independent elements container
49+
elements = deepcopy(elements_parent)
50+
resize!(elements, length(mesh.cell_ids))
51+
52+
# Copy relevant entries from parent mesh
53+
@views elements.inverse_jacobian .= elements_parent.inverse_jacobian[..,
54+
mesh.cell_ids]
55+
@views elements.jacobian_matrix .= elements_parent.jacobian_matrix[..,
56+
mesh.cell_ids]
57+
@views elements.node_coordinates .= elements_parent.node_coordinates[..,
58+
mesh.cell_ids]
59+
@views elements.contravariant_vectors .= elements_parent.contravariant_vectors[..,
60+
mesh.cell_ids]
61+
@views elements.surface_flux_values .= elements_parent.surface_flux_values[..,
62+
mesh.cell_ids]
63+
# Extract interfaces that belong to mesh view
64+
interfaces = extract_interfaces(mesh, interfaces_parent)
65+
66+
return elements, interfaces, boundaries_parent, mortars_parent
67+
end
68+
69+
# Remove all interfaces that have a tuple of neighbor_ids where at least one is
70+
# not part of this meshview, i.e. mesh.cell_ids, and return the new interface container
71+
function extract_interfaces(mesh::P4estMeshView, interfaces_parent)
72+
# Identify interfaces that need to be retained
73+
mask = BitArray(undef, ninterfaces(interfaces_parent))
74+
for interface in 1:size(interfaces_parent.neighbor_ids)[2]
75+
mask[interface] = (interfaces_parent.neighbor_ids[1, interface] in mesh.cell_ids) &&
76+
(interfaces_parent.neighbor_ids[2, interface] in mesh.cell_ids)
77+
end
78+
79+
# Create deepcopy to get completely independent interfaces container
80+
interfaces = deepcopy(interfaces_parent)
81+
resize!(interfaces, sum(mask))
82+
83+
# Copy relevant entries from parent mesh
84+
@views interfaces.u .= interfaces_parent.u[.., mask]
85+
@views interfaces.node_indices .= interfaces_parent.node_indices[.., mask]
86+
@views neighbor_ids = interfaces_parent.neighbor_ids[.., mask]
87+
88+
# Transform the global (parent) indices into local (view) indices.
89+
interfaces.neighbor_ids = zeros(Int, size(neighbor_ids))
90+
for interface in 1:size(neighbor_ids)[2]
91+
interfaces.neighbor_ids[1, interface] = findall(id -> id ==
92+
neighbor_ids[1, interface],
93+
mesh.cell_ids)[1]
94+
interfaces.neighbor_ids[2, interface] = findall(id -> id ==
95+
neighbor_ids[2, interface],
96+
mesh.cell_ids)[1]
97+
end
98+
99+
return interfaces
100+
end
101+
102+
# Does not save the mesh itself to an HDF5 file. Instead saves important attributes
103+
# of the mesh, like its size and the type of boundary mapping function.
104+
# Then, within Trixi2Vtk, the P4estMeshView and its node coordinates are reconstructured from
105+
# these attributes for plotting purposes
106+
# | Warning: This overwrites any existing mesh file, either for a mesh view or parent mesh.
107+
function save_mesh_file(mesh::P4estMeshView, output_directory, timestep,
108+
mpi_parallel::False)
109+
# Create output directory (if it does not exist)
110+
mkpath(output_directory)
111+
112+
# Determine file name based on existence of meaningful time step
113+
if timestep > 0
114+
filename = joinpath(output_directory, @sprintf("mesh_%09d.h5", timestep))
115+
p4est_filename = @sprintf("p4est_data_%09d", timestep)
116+
else
117+
filename = joinpath(output_directory, "mesh.h5")
118+
p4est_filename = "p4est_data"
119+
end
120+
121+
p4est_file = joinpath(output_directory, p4est_filename)
122+
123+
# Save the complete connectivity and `p4est` data to disk.
124+
save_p4est!(p4est_file, mesh.parent.p4est)
125+
126+
# Open file (clobber existing content)
127+
h5open(filename, "w") do file
128+
# Add context information as attributes
129+
attributes(file)["mesh_type"] = get_name(mesh)
130+
attributes(file)["ndims"] = ndims(mesh)
131+
attributes(file)["p4est_file"] = p4est_filename
132+
attributes(file)["cell_ids"] = mesh.cell_ids
133+
134+
file["tree_node_coordinates"] = mesh.parent.tree_node_coordinates
135+
file["nodes"] = Vector(mesh.parent.nodes) # the mesh uses `SVector`s for the nodes
136+
# to increase the runtime performance
137+
# but HDF5 can only handle plain arrays
138+
file["boundary_names"] = mesh.parent.boundary_names .|> String
139+
end
140+
141+
return filename
142+
end
143+
144+
# Interpolate tree_node_coordinates to each quadrant at the specified nodes
145+
# Note: This is a copy of the corresponding function in src/solvers/dgsem_p4est/containers_2d.jl,
146+
# with modifications to skip cells not part of the mesh view
147+
function calc_node_coordinates!(node_coordinates,
148+
mesh::P4estMeshView{2, NDIMS_AMBIENT},
149+
nodes::AbstractVector) where {NDIMS_AMBIENT}
150+
# We use `StrideArray`s here since these buffers are used in performance-critical
151+
# places and the additional information passed to the compiler makes them faster
152+
# than native `Array`s.
153+
tmp1 = StrideArray(undef, real(mesh),
154+
StaticInt(NDIMS_AMBIENT), static_length(nodes),
155+
static_length(mesh.parent.nodes))
156+
matrix1 = StrideArray(undef, real(mesh),
157+
static_length(nodes), static_length(mesh.parent.nodes))
158+
matrix2 = similar(matrix1)
159+
baryweights_in = barycentric_weights(mesh.parent.nodes)
160+
161+
# Macros from `p4est`
162+
p4est_root_len = 1 << P4EST_MAXLEVEL
163+
p4est_quadrant_len(l) = 1 << (P4EST_MAXLEVEL - l)
164+
165+
trees = unsafe_wrap_sc(p4est_tree_t, mesh.parent.p4est.trees)
166+
167+
mesh_view_cell_id = 0
168+
for tree_id in eachindex(trees)
169+
tree_offset = trees[tree_id].quadrants_offset
170+
quadrants = unsafe_wrap_sc(p4est_quadrant_t, trees[tree_id].quadrants)
171+
172+
for i in eachindex(quadrants)
173+
parent_mesh_cell_id = tree_offset + i
174+
if !(parent_mesh_cell_id in mesh.cell_ids)
175+
# This cell is not part of the mesh view, thus skip it
176+
continue
177+
end
178+
mesh_view_cell_id += 1
179+
180+
quad = quadrants[i]
181+
182+
quad_length = p4est_quadrant_len(quad.level) / p4est_root_len
183+
184+
nodes_out_x = 2 * (quad_length * 1 / 2 * (nodes .+ 1) .+
185+
quad.x / p4est_root_len) .- 1
186+
nodes_out_y = 2 * (quad_length * 1 / 2 * (nodes .+ 1) .+
187+
quad.y / p4est_root_len) .- 1
188+
polynomial_interpolation_matrix!(matrix1, mesh.parent.nodes, nodes_out_x,
189+
baryweights_in)
190+
polynomial_interpolation_matrix!(matrix2, mesh.parent.nodes, nodes_out_y,
191+
baryweights_in)
192+
193+
multiply_dimensionwise!(view(node_coordinates, :, :, :, mesh_view_cell_id),
194+
matrix1, matrix2,
195+
view(mesh.parent.tree_node_coordinates, :, :, :,
196+
tree_id),
197+
tmp1)
198+
end
199+
end
200+
201+
return node_coordinates
202+
end
203+
204+
@inline mpi_parallel(mesh::P4estMeshView) = False()
205+
end # @muladd

src/semidiscretization/semidiscretization_hyperbolic.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ end
214214

215215
# No checks for these meshes yet available
216216
function check_periodicity_mesh_boundary_conditions(mesh::Union{P4estMesh,
217+
P4estMeshView,
217218
UnstructuredMesh2D,
218219
T8codeMesh,
219220
DGMultiMesh},

src/solvers/dg.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ end
447447

448448
const MeshesDGSEM = Union{TreeMesh, StructuredMesh, StructuredMeshView,
449449
UnstructuredMesh2D,
450-
P4estMesh, T8codeMesh}
450+
P4estMesh, P4estMeshView, T8codeMesh}
451451

452452
@inline function ndofs(mesh::MeshesDGSEM, dg::DG, cache)
453453
nelements(cache.elements) * nnodes(dg)^ndims(mesh)

0 commit comments

Comments
 (0)