Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Sc/Enhanced p4est mesh views #2110

Draft
wants to merge 47 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
0a3a59f
Sterted re-implementing p4est mesh views to be more powerful.
SimonCan Oct 14, 2024
6e10434
Added P4estMeshView specific methods for computing calc_node_coordina…
SimonCan Oct 14, 2024
ac9b417
Added p4est mesh views.
SimonCan Oct 15, 2024
6f50db4
Removed some debugging.
SimonCan Oct 15, 2024
7056c46
Corrected matrix calculation in calc_node_coordinates for p4est mesh …
SimonCan Oct 15, 2024
805ea71
Plae holders for p4est mesh view.
SimonCan Oct 16, 2024
c766456
Some refactoring.
SimonCan Oct 17, 2024
ff167a7
Removed most references to parent mesh.
SimonCan Oct 17, 2024
a5ce210
Minor corrections.
SimonCan Oct 17, 2024
4b04cd2
Added commentson next steps.
SimonCan Oct 18, 2024
a08b10f
Added real option of choosing elements of p4est mesh view.
SimonCan Oct 23, 2024
3de317a
Little clean up.
SimonCan Nov 6, 2024
0777a00
Added first batch of corrections for P4estMeshView.
SimonCan Nov 7, 2024
90e98bc
Added place holders for p4est mesh view.
SimonCan Nov 14, 2024
23e89d3
Added p4est -> p4est mesh view extraction routine.
SimonCan Nov 15, 2024
b0edd8d
Added flattened arrays.
SimonCan Nov 15, 2024
db837de
Added prolong2interfaces to p4est mesh view.
SimonCan Nov 20, 2024
9f5ae86
Minor corrections.
SimonCan Nov 21, 2024
03651bd
Removed redundant P4estMeshView in calc_interface_flux.
SimonCan Nov 25, 2024
b36e643
Corrected extraction of interfaces given an array of cell ids to incl…
SimonCan Nov 27, 2024
8821ff2
Write out of P4estMeshView data.
SimonCan Nov 28, 2024
240918f
Fixed issue with non-simply connected p4est mesh views.
SimonCan Dec 16, 2024
9cae5b5
Update src/callbacks_step/analysis_dg2d.jl
SimonCan Dec 16, 2024
d21b636
Update src/meshes/mesh_io.jl
SimonCan Dec 16, 2024
8a14d1f
Update src/callbacks_step/analysis_dg2d.jl
SimonCan Dec 16, 2024
cc87c3a
Update src/meshes/p4est_mesh_view.jl
SimonCan Dec 16, 2024
3af246e
Update src/meshes/p4est_mesh_view.jl
SimonCan Dec 16, 2024
fe26e98
No nead for P4estMeshView having its own prolong2interfaces function.
SimonCan Dec 16, 2024
43ab4d5
Corrected typo in comment.
SimonCan Dec 16, 2024
226843d
Merge branch 'sc/p4est-view-enhanced' of github.com:trixi-framework/T…
SimonCan Dec 16, 2024
4fc16b8
Merge branch 'main' into sc/p4est-view-enhanced
SimonCan Dec 16, 2024
86f984b
Fixed typos.
SimonCan Dec 17, 2024
eb4c2bf
Merge branch 'sc/p4est-view-enhanced' of github.com:trixi-framework/T…
SimonCan Dec 17, 2024
0af7185
Update src/solvers/dgsem_unstructured/dg_2d.jl
SimonCan Dec 17, 2024
8d011a6
Update src/solvers/dgsem_tree/dg_2d.jl
SimonCan Dec 17, 2024
8bf43a9
Update src/callbacks_step/analysis_dg2d.jl
SimonCan Dec 17, 2024
c51b0ae
Applied autoformatter.
SimonCan Dec 17, 2024
4d1eaaf
Merge branch 'sc/p4est-view-enhanced' of github.com:trixi-framework/T…
SimonCan Dec 17, 2024
4264718
Fixed t8code issue.
SimonCan Dec 18, 2024
d9811df
Merge branch 'main' into sc/p4est-view-enhanced
SimonCan Dec 18, 2024
647bba2
Merge branch 'main' into sc/p4est-view-enhanced
SimonCan Dec 19, 2024
b56d1d7
Added p4est mesh view into tests.
SimonCan Dec 19, 2024
ecf74d1
Reduced the number of elements.
SimonCan Dec 19, 2024
07e89ed
Added P4estMeshView to the error norms.
SimonCan Dec 19, 2024
fe8b209
Fixed typo in example run.
SimonCan Dec 19, 2024
cd61fcd
Merge branch 'sc/p4est-view-enhanced' of github.com:trixi-framework/T…
SimonCan Dec 19, 2024
84d22c8
Applied autoformatter.
SimonCan Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions examples/p4est_2d_dgsem/elixir_advection_meshview.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using OrdinaryDiffEq
using Trixi

###############################################################################
# Most basic p4est mesh view setup where the entire domain
# is part of the single mesh view.

advection_velocity = (0.2, -0.7)
equations = LinearScalarAdvectionEquation2D(advection_velocity)

# Create DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux
solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs)

coordinates_min = (-1.0, -1.0) # minimum coordinates (min(x), min(y))
coordinates_max = (1.0, 1.0) # maximum coordinates (max(x), max(y))

trees_per_dimension = (8, 8)

# Create parent P4estMesh with 8 x 8 trees and 8 x 8 elements
parent_mesh = P4estMesh(trees_per_dimension, polydeg = 3,
coordinates_min = coordinates_min,
coordinates_max = coordinates_max,
initial_refinement_level = 0)

# Define the mesh view covering the whole parent mesh.
cell_ids = Vector(1:prod(trees_per_dimension))
mesh = P4estMeshView(parent_mesh, cell_ids)

# A semidiscretization collects data structures and functions for the spatial discretization
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergence_test,
solver)

###############################################################################
# ODE solvers, callbacks etc.

# Create ODE problem with time span from 0.0 to 1.0
ode = semidiscretize(semi, (0.0, 1.0))

# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup
# and resets the timers
summary_callback = SummaryCallback()

# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results
analysis_callback = AnalysisCallback(semi, interval = 100)

# The SaveSolutionCallback allows to save the solution to a file in regular intervals
save_solution = SaveSolutionCallback(interval = 100,
solution_variables = cons2prim)

# The StepsizeCallback handles the re-calculation of the maximum Δt after each time step
stepsize_callback = StepsizeCallback(cfl = 1.6)

# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver
callbacks = CallbackSet(summary_callback, save_solution, stepsize_callback)

###############################################################################
# run the simulation

# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks
sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false),
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep = false, callback = callbacks);

# Print the timer summary
summary_callback()
2 changes: 1 addition & 1 deletion src/Trixi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ export lake_at_rest_error
export ncomponents, eachcomponent

export TreeMesh, StructuredMesh, StructuredMeshView, UnstructuredMesh2D, P4estMesh,
T8codeMesh
P4estMeshView, T8codeMesh

export DG,
DGSEM, LobattoLegendreBasis,
Expand Down
11 changes: 8 additions & 3 deletions src/callbacks_step/analysis_dg2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ function create_cache_analysis(analyzer, mesh::TreeMesh{2},
end

# Specialized cache for P4estMesh to allow for different ambient dimension from mesh dimension
function create_cache_analysis(analyzer, mesh::P4estMesh{2, NDIMS_AMBIENT},
function create_cache_analysis(analyzer,
mesh::Union{P4estMesh{2, NDIMS_AMBIENT},
P4estMeshView{2, NDIMS_AMBIENT}},
equations, dg::DG, cache,
RealT, uEltype) where {NDIMS_AMBIENT}

Expand Down Expand Up @@ -138,7 +140,9 @@ end

function calc_error_norms(func, u, t, analyzer,
mesh::Union{StructuredMesh{2}, StructuredMeshView{2},
UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}},
UnstructuredMesh2D, P4estMesh{2},
P4estMeshView{2},
T8codeMesh{2}},
equations,
initial_condition, dg::DGSEM, cache, cache_analysis)
@unpack vandermonde, weights = analyzer
Expand Down Expand Up @@ -239,7 +243,8 @@ end

function integrate(func::Func, u,
mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2},
UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}},
UnstructuredMesh2D, P4estMesh{2}, P4estMeshView{2},
T8codeMesh{2}},
equations, dg::DG, cache; normalize = true) where {Func}
integrate_via_indices(u, mesh, equations, dg, cache;
normalize = normalize) do u, i, j, element, equations, dg
Expand Down
1 change: 1 addition & 0 deletions src/callbacks_step/save_solution_dg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ function save_solution_file(u, time, dt, timestep,
mesh::Union{SerialTreeMesh, StructuredMesh,
StructuredMeshView,
UnstructuredMesh2D, SerialP4estMesh,
P4estMeshView,
SerialT8codeMesh},
equations, dg::DG, cache,
solution_callback,
Expand Down
2 changes: 1 addition & 1 deletion src/callbacks_step/stepsize_dg2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ end

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

Expand Down
5 changes: 3 additions & 2 deletions src/meshes/mesh_io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#! format: noindent

# Save current mesh with some context information as an HDF5 file.
function save_mesh_file(mesh::Union{TreeMesh, P4estMesh, T8codeMesh}, output_directory,
function save_mesh_file(mesh::Union{TreeMesh, P4estMesh, P4estMeshView, T8codeMesh},
output_directory,
timestep = 0)
save_mesh_file(mesh, output_directory, timestep, mpi_parallel(mesh))
end
Expand Down Expand Up @@ -382,7 +383,7 @@ function load_mesh_serial(mesh_file::AbstractString; n_cells_max, RealT)
periodicity = periodicity_,
unsaved_changes = false)
mesh.current_filename = mesh_file
elseif mesh_type == "P4estMesh"
elseif mesh_type == "P4estMesh" || mesh_type == "P4estMeshView"
p4est_filename, tree_node_coordinates,
nodes, boundary_names_ = h5open(mesh_file, "r") do file
return read(attributes(file)["p4est_file"]),
Expand Down
1 change: 1 addition & 0 deletions src/meshes/meshes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ include("unstructured_mesh.jl")
include("face_interpolant.jl")
include("transfinite_mappings_3d.jl")
include("p4est_mesh.jl")
include("p4est_mesh_view.jl")
include("t8code_mesh.jl")
include("mesh_io.jl")
include("dgmulti_meshes.jl")
Expand Down
143 changes: 143 additions & 0 deletions src/meshes/p4est_mesh_view.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).
# Since these FMAs can increase the performance of many numerical algorithms,
# we need to opt-in explicitly.
# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.
@muladd begin
#! format: noindent

"""
P4estMeshView{NDIMS, NDIMS_AMBIENT, RealT <: Real, Parent} <: AbstractMesh{NDIMS}

A view on a p4est mesh.
"""
mutable struct P4estMeshView{NDIMS, NDIMS_AMBIENT, RealT <: Real, Parent} <:
AbstractMesh{NDIMS}
parent::Parent
cell_ids::Vector{Int}
unsaved_changes::Bool
current_filename::String
end

"""
P4estMeshView(parent; cell_ids)

Create a P4estMeshView on a P4estMesh parent.

# Arguments
- `parent`: the parent P4estMesh.
- `cell_ids`: array of cell ids that are part of this view.
"""
function P4estMeshView(parent::P4estMesh{NDIMS, NDIMS_AMBIENT, RealT},
cell_ids::Vector) where {NDIMS, NDIMS_AMBIENT, RealT}
return P4estMeshView{NDIMS, NDIMS_AMBIENT, RealT, typeof(parent)}(parent, cell_ids,
parent.unsaved_changes,
parent.current_filename)
end

@inline Base.ndims(::P4estMeshView{NDIMS}) where {NDIMS} = NDIMS
@inline Base.real(::P4estMeshView{NDIMS, RealT}) where {NDIMS, RealT} = RealT
@inline ndims_ambient(::P4estMeshView{NDIMS}) where {NDIMS} = NDIMS

@inline balance!(::P4estMeshView) = nothing
@inline ncells(mesh::P4estMeshView) = length(mesh.cell_ids)

function extract_p4est_mesh_view(elements_parent,
interfaces_parent,
boundaries_parent,
mortars_parent,
mesh)
elements = elements_parent
elements.inverse_jacobian = elements_parent.inverse_jacobian[.., mesh.cell_ids]
elements.jacobian_matrix = elements_parent.jacobian_matrix[.., mesh.cell_ids]
elements.node_coordinates = elements_parent.node_coordinates[.., mesh.cell_ids]
elements.contravariant_vectors = elements_parent.contravariant_vectors[..,
mesh.cell_ids]
elements.surface_flux_values = elements_parent.surface_flux_values[..,
mesh.cell_ids]
elements._inverse_jacobian = vec(elements.inverse_jacobian)
elements._jacobian_matrix = vec(elements.jacobian_matrix)
elements._node_coordinates = vec(elements.node_coordinates)
elements._node_coordinates = vec(elements.node_coordinates)
elements._surface_flux_values = vec(elements.surface_flux_values)
interfaces = extract_interfaces(mesh, interfaces_parent)

return elements, interfaces, boundaries_parent, mortars_parent
end

function extract_interfaces(mesh::P4estMeshView, interfaces_parent)
"""
Remove all interfaces that have a tuple of neighbor_ids where at least one is
not part of this meshview, i.e. mesh.cell_ids.
"""

mask = BitArray(undef, size(interfaces_parent.neighbor_ids)[2])
for interface in 1:size(interfaces_parent.neighbor_ids)[2]
mask[interface] = (interfaces_parent.neighbor_ids[1, interface] in mesh.cell_ids) &&
(interfaces_parent.neighbor_ids[2, interface] in mesh.cell_ids)
end
interfaces = interfaces_parent
interfaces.u = interfaces_parent.u[.., mask]
interfaces.node_indices = interfaces_parent.node_indices[.., mask]
neighbor_ids = interfaces_parent.neighbor_ids[.., mask]
# Transform the global (parent) indices into local (view) indices.
interfaces.neighbor_ids = zeros(Int, size(neighbor_ids))
for interface in 1:size(neighbor_ids)[2]
interfaces.neighbor_ids[1, interface] = findall(id -> id ==
neighbor_ids[1, interface],
mesh.cell_ids)[1]
interfaces.neighbor_ids[2, interface] = findall(id -> id ==
neighbor_ids[2, interface],
mesh.cell_ids)[1]
end

# Flatten the arrays.
interfaces._u = vec(interfaces.u)
interfaces._node_indices = vec(interfaces.node_indices)
interfaces._neighbor_ids = vec(interfaces.neighbor_ids)

return interfaces
end

# Does not save the mesh itself to an HDF5 file. Instead saves important attributes
# of the mesh, like its size and the type of boundary mapping function.
# Then, within Trixi2Vtk, the P4estMeshView and its node coordinates are reconstructured from
# these attributes for plotting purposes
function save_mesh_file(mesh::P4estMeshView, output_directory, timestep,
mpi_parallel::False)
# Create output directory (if it does not exist)
mkpath(output_directory)

# Determine file name based on existence of meaningful time step
if timestep > 0
filename = joinpath(output_directory, @sprintf("mesh_%09d.h5", timestep))
p4est_filename = @sprintf("p4est_data_%09d", timestep)
else
filename = joinpath(output_directory, "mesh.h5")
p4est_filename = "p4est_data"
end

p4est_file = joinpath(output_directory, p4est_filename)

# Save the complete connectivity and `p4est` data to disk.
save_p4est!(p4est_file, mesh.parent.p4est)

# Open file (clobber existing content)
h5open(filename, "w") do file
# Add context information as attributes
attributes(file)["mesh_type"] = get_name(mesh)
attributes(file)["ndims"] = ndims(mesh)
attributes(file)["p4est_file"] = p4est_filename

file["tree_node_coordinates"] = mesh.parent.tree_node_coordinates[..,
mesh.cell_ids]
file["nodes"] = Vector(mesh.parent.nodes) # the mesh uses `SVector`s for the nodes
# to increase the runtime performance
# but HDF5 can only handle plain arrays
file["boundary_names"] = mesh.parent.boundary_names .|> String
end

return filename
end

@inline mpi_parallel(mesh::P4estMeshView) = False()
end # @muladd
1 change: 1 addition & 0 deletions src/semidiscretization/semidiscretization_hyperbolic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ end

# No checks for these meshes yet available
function check_periodicity_mesh_boundary_conditions(mesh::Union{P4estMesh,
P4estMeshView,
UnstructuredMesh2D,
T8codeMesh,
DGMultiMesh},
Expand Down
2 changes: 1 addition & 1 deletion src/solvers/dg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ end

const MeshesDGSEM = Union{TreeMesh, StructuredMesh, StructuredMeshView,
UnstructuredMesh2D,
P4estMesh, T8codeMesh}
P4estMesh, P4estMeshView, T8codeMesh}

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