Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
cde9904
Start
DanielDoehring Mar 4, 2026
ad69308
Revert "Start"
DanielDoehring Mar 4, 2026
8baf170
Start
DanielDoehring Mar 4, 2026
a20bdb2
test
DanielDoehring Mar 4, 2026
9a8fc4d
fmt
DanielDoehring Mar 4, 2026
4c40546
restrict
DanielDoehring Mar 4, 2026
9deee47
typo
DanielDoehring Mar 4, 2026
bbad434
Merge branch 'main' into GL_P4est2D_Periodic
ranocha Mar 4, 2026
54e40b5
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 5, 2026
15da164
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 7, 2026
94570f5
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 9, 2026
883d999
pre-comp
DanielDoehring Mar 9, 2026
89efbbe
optimize
DanielDoehring Mar 9, 2026
1e9284d
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 14, 2026
734b221
Interface normal directions
DanielDoehring Mar 15, 2026
f17dcd3
example
DanielDoehring Mar 15, 2026
d69e570
comment
DanielDoehring Mar 15, 2026
63eb696
3d dummy version
DanielDoehring Mar 15, 2026
4672a79
typo
DanielDoehring Mar 15, 2026
920037b
fix
DanielDoehring Mar 15, 2026
2b797a4
comment
DanielDoehring Mar 15, 2026
5e67e89
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 15, 2026
9cce03b
rev
DanielDoehring Mar 15, 2026
6ba5bc7
db
DanielDoehring Mar 15, 2026
4a36ed9
rev
DanielDoehring Mar 15, 2026
7e63a5a
comment
DanielDoehring Mar 15, 2026
c9ff85f
fmt
DanielDoehring Mar 15, 2026
602a8ba
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 15, 2026
5f79f2e
other version t8coe
DanielDoehring Mar 15, 2026
825872d
inc
DanielDoehring Mar 15, 2026
b22dfe7
Merge branch 'GL_P4est2D_Periodic' of github.com:DanielDoehring/Trixi…
DanielDoehring Mar 15, 2026
4f288c8
Merge branch 'main' into GL_P4est2D_Periodic
ranocha Mar 15, 2026
022244d
restore
DanielDoehring Mar 15, 2026
2c82916
fix
DanielDoehring Mar 15, 2026
da16a96
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 15, 2026
bbf38c4
check if function is trixi atmo compatible
DanielDoehring Mar 17, 2026
ed1473e
restore
DanielDoehring Mar 17, 2026
19690e0
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 22, 2026
fb71bee
comments
DanielDoehring Mar 22, 2026
5e3c2e3
unions
DanielDoehring Mar 22, 2026
3f81bdf
order yp eparams
DanielDoehring Mar 22, 2026
596854b
db
DanielDoehring Mar 22, 2026
0e0104f
typo
DanielDoehring Mar 22, 2026
bd670cd
lift
DanielDoehring Mar 22, 2026
3263c11
rev
DanielDoehring Mar 22, 2026
c304077
ac
DanielDoehring Mar 22, 2026
5fff783
rm
DanielDoehring Mar 22, 2026
dab10d9
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 23, 2026
b141982
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 28, 2026
084a539
Merge branch 'GL_P4est2D_Periodic' of github.com:DanielDoehring/Trixi…
DanielDoehring Mar 28, 2026
9d598b1
adapt
DanielDoehring Mar 28, 2026
a39aa9b
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 31, 2026
3c54c19
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Mar 31, 2026
7047203
adapt
DanielDoehring Mar 31, 2026
96ff9fa
cont
DanielDoehring Mar 31, 2026
69d898c
modularize
DanielDoehring Apr 1, 2026
d5e7b49
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Apr 2, 2026
6c80410
Update examples/p4est_2d_dgsem/elixir_advection_flag_gauss_legendre.jl
DanielDoehring Apr 2, 2026
bc2f70c
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Apr 2, 2026
7f96827
Merge branch 'main' into GL_P4est2D_Periodic
DanielDoehring Apr 5, 2026
2d57922
Merge branch 'main' into GL_P4est2D_Periodic
ranocha Apr 5, 2026
4fe7262
Update src/solvers/dgsem_p4est/containers_2d.jl
DanielDoehring Apr 6, 2026
e2c0029
rev
DanielDoehring Apr 6, 2026
ad35542
rm
DanielDoehring Apr 6, 2026
4608071
Update examples/p4est_2d_dgsem/elixir_advection_flag_gauss_legendre.jl
DanielDoehring Apr 6, 2026
40acf2b
test
DanielDoehring Apr 6, 2026
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
49 changes: 49 additions & 0 deletions examples/p4est_2d_dgsem/elixir_advection_flag_gauss_legendre.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using OrdinaryDiffEqLowStorageRK
using Trixi

###############################################################################
# semidiscretization of the linear advection equation

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

solver = DGSEM(polydeg = 4, surface_flux = flux_lax_friedrichs,
basis_type = GaussLegendreBasis)

# Deformed rectangle that looks like a waving flag,
# lower and upper faces are sinus curves, left and right are vertical lines.
f1(s) = SVector(-1.0, s - 1.0)
f2(s) = SVector(1.0, s + 1.0)
f3(s) = SVector(s, -1.0 + sinpi(0.5 * s))
f4(s) = SVector(s, 1.0 + sinpi(0.5 * s))

# Create P4estMesh with 3 x 2 trees and 6 x 4 elements,
# approximate the geometry with a smaller polydeg for testing.
trees_per_dimension = (3, 2)
mesh = P4estMesh(trees_per_dimension, polydeg = 3,
faces = (f1, f2, f3, f4),
periodicity = true,
initial_refinement_level = 1)

semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition_convergence_test,
solver;
boundary_conditions = boundary_condition_periodic)

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

ode = semidiscretize(semi, (0.0, 0.2))

summary_callback = SummaryCallback()
analysis_callback = AnalysisCallback(semi, interval = 100)
stepsize_callback = StepsizeCallback(cfl = 0.5)

callbacks = CallbackSet(summary_callback, analysis_callback,
stepsize_callback)

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

sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false);
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
ode_default_options()..., callback = callbacks);
4 changes: 4 additions & 0 deletions src/meshes/p4est_mesh_view.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ function extract_interfaces(mesh::P4estMeshView, interfaces_parent)

# Copy relevant entries from parent mesh
@views interfaces.u .= interfaces_parent.u[.., mask]
if interfaces.normal_directions !== nothing # Needed for Gauss-Legendre basis
@views interfaces.normal_directions .= interfaces_parent.normal_directions[..,
mask]
end
@views interfaces.node_indices .= interfaces_parent.node_indices[.., mask]
@views neighbor_ids = interfaces_parent.neighbor_ids[.., mask]

Expand Down
119 changes: 89 additions & 30 deletions src/solvers/dgsem_p4est/containers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,8 @@ function Adapt.adapt_structure(to,
size(elements.surface_flux_values))

new_type_params = (NDIMS,
RealT,
uEltype,
NDIMS + 1,
NDIMS + 2,
NDIMS + 3,
RealT, uEltype,
NDIMS + 1, NDIMS + 2, NDIMS + 3,
typeof(inverse_jacobian), # ArrayRealTNDIMSP1
typeof(node_coordinates), # ArrayRealTNDIMSP2
typeof(jacobian_matrix), # ArrayRealTNDIMSP3
Expand All @@ -213,38 +210,48 @@ function Adapt.adapt_structure(to,
_surface_flux_values)
end

mutable struct P4estInterfaceContainer{NDIMS, uEltype <: Real, NDIMSP2,
mutable struct P4estInterfaceContainer{NDIMS, RealT <: Real, uEltype <: Real,
NDIMSP1, NDIMSP2,
uArray <: DenseArray{uEltype, NDIMSP2},
NormalArray <:
Union{DenseArray{RealT, NDIMSP1}, Nothing},
IdsMatrix <: DenseMatrix{Int},
IndicesMatrix <:
DenseMatrix{NTuple{NDIMS, Symbol}},
uVector <: DenseVector{uEltype},
NormalVector <:
Union{DenseVector{RealT}, Nothing},
IdsVector <: DenseVector{Int},
IndicesVector <:
DenseVector{NTuple{NDIMS, Symbol}}} <:
AbstractInterfaceContainer
u::uArray # [primary/secondary, variable, i, j, interface]
neighbor_ids::IdsMatrix # [primary/secondary, interface]
node_indices::IndicesMatrix # [primary/secondary, interface]
u::uArray # [primary/secondary, variable, i, j, interface]
normal_directions::NormalArray # [dimension, i, j, interface]
neighbor_ids::IdsMatrix # [primary/secondary, interface]
node_indices::IndicesMatrix # [primary/secondary, interface]

# internal `resize!`able storage
_u::uVector
_normal_directions::NormalVector
_neighbor_ids::IdsVector
_node_indices::IndicesVector
end

# `trivial` means that the interface normals can be taken from
# the outer/surface element nodes
@inline trivial_interface_normals(::LobattoLegendreBasis) = true
# For Gauss-Legendre basis, the interface normals need to be interpolated,
# analogous to the surface values.
@inline trivial_interface_normals(::GaussLegendreBasis) = false

@inline function ninterfaces(interfaces::P4estInterfaceContainer)
return size(interfaces.neighbor_ids, 2)
end
@inline Base.ndims(::P4estInterfaceContainer{NDIMS}) where {NDIMS} = NDIMS
@inline function Base.eltype(::P4estInterfaceContainer{NDIMS, uEltype}) where {NDIMS,
uEltype}
return uEltype
end

# See explanation of Base.resize! for the element container
function Base.resize!(interfaces::P4estInterfaceContainer, capacity)
@unpack _u, _neighbor_ids, _node_indices = interfaces
@unpack _u, _normal_directions, _neighbor_ids, _node_indices = interfaces

n_dims = ndims(interfaces)
n_nodes = size(interfaces.u, 3)
Expand All @@ -256,6 +263,18 @@ function Base.resize!(interfaces::P4estInterfaceContainer, capacity)
(2, n_variables, ntuple(_ -> n_nodes, n_dims - 1)...,
capacity))

if _normal_directions === nothing # trivial interface normals, e.g. for Lobatto-Legendre basis
interfaces.normal_directions = nothing
else # non-trivial interface normals, e.g. for Gauss-Legendre basis
resize!(_normal_directions, n_dims * n_nodes^(n_dims - 1) * capacity)
interfaces.normal_directions = unsafe_wrap(ArrayType,
pointer(_normal_directions),
(n_dims,
ntuple(_ -> n_nodes,
n_dims - 1)...,
capacity))
end

resize!(_neighbor_ids, 2 * capacity)
interfaces.neighbor_ids = unsafe_wrap(ArrayType, pointer(_neighbor_ids),
(2, capacity))
Expand All @@ -271,6 +290,7 @@ end
function init_interfaces(mesh::Union{P4estMesh, P4estMeshView, T8codeMesh}, equations,
basis, elements)
NDIMS = ndims(elements)
RealT = real(mesh)
uEltype = eltype(elements)

# Initialize container
Expand All @@ -283,59 +303,94 @@ function init_interfaces(mesh::Union{P4estMesh, P4estMeshView, T8codeMesh}, equa
(2, nvariables(equations), ntuple(_ -> nnodes(basis), NDIMS - 1)...,
n_interfaces))

if !trivial_interface_normals(basis)
_normal_directions = Vector{RealT}(undef,
NDIMS * nnodes(basis)^(NDIMS - 1) *
n_interfaces)
normal_directions = unsafe_wrap(Array, pointer(_normal_directions),
(NDIMS,
ntuple(_ -> nnodes(basis), NDIMS - 1)...,
n_interfaces))
else
_normal_directions = nothing
normal_directions = nothing
end

_neighbor_ids = Vector{Int}(undef, 2 * n_interfaces)
neighbor_ids = unsafe_wrap(Array, pointer(_neighbor_ids), (2, n_interfaces))

_node_indices = Vector{NTuple{NDIMS, Symbol}}(undef, 2 * n_interfaces)
node_indices = unsafe_wrap(Array, pointer(_node_indices), (2, n_interfaces))

interfaces = P4estInterfaceContainer{NDIMS, uEltype, NDIMS + 2,
typeof(u), typeof(neighbor_ids),
typeof(node_indices), typeof(_u),
interfaces = P4estInterfaceContainer{NDIMS, RealT, uEltype,
NDIMS + 1, NDIMS + 2,
typeof(u), typeof(normal_directions),
typeof(neighbor_ids), typeof(node_indices),
typeof(_u), typeof(_normal_directions),
typeof(_neighbor_ids), typeof(_node_indices)}(u,
normal_directions,
neighbor_ids,
node_indices,
_u,
_normal_directions,
_neighbor_ids,
_node_indices)

init_interfaces!(interfaces, mesh)
init_interfaces!(interfaces, elements, mesh, basis)

return interfaces
end

function init_interfaces!(interfaces, mesh::Union{P4estMesh, P4estMeshView})
function init_interfaces!(interfaces, elements,
mesh::Union{P4estMesh, P4estMeshView}, basis)
init_surfaces!(interfaces, nothing, nothing, mesh)
init_normal_directions!(interfaces, basis, elements)

return interfaces
end

function Adapt.parent_type(::Type{<:P4estInterfaceContainer{<:Any, <:Any, <:Any,
<:Any, <:Any,
ArrayT}}) where {ArrayT}
return ArrayT
end

# Manual adapt_structure since we have aliasing memory
function Adapt.adapt_structure(to, interfaces::P4estInterfaceContainer)
function Adapt.adapt_structure(to,
interfaces::P4estInterfaceContainer{NDIMS,
RealT,
uEltype}) where {
NDIMS,
uEltype,
RealT
}
# Adapt underlying storage
_u = adapt(to, interfaces._u)
_normal_directions = interfaces._normal_directions === nothing ? nothing :
adapt(to, interfaces._normal_directions)
_neighbor_ids = adapt(to, interfaces._neighbor_ids)
_node_indices = adapt(to, interfaces._node_indices)
# Wrap arrays again
u = unsafe_wrap_or_alloc(to, _u, size(interfaces.u))
normal_directions = _normal_directions === nothing ? nothing : # Check if interface normals are trivial
unsafe_wrap_or_alloc(to, _normal_directions,
size(interfaces.normal_directions))
neighbor_ids = unsafe_wrap_or_alloc(to, _neighbor_ids,
size(interfaces.neighbor_ids))
node_indices = unsafe_wrap_or_alloc(to, _node_indices,
size(interfaces.node_indices))

NDIMS = ndims(interfaces)
new_type_params = (NDIMS,
eltype(_u),
NDIMS + 2,
typeof(u), typeof(neighbor_ids), typeof(node_indices),
typeof(_u), typeof(_neighbor_ids), typeof(_node_indices))
return P4estInterfaceContainer{new_type_params...}(u, neighbor_ids, node_indices,
_u, _neighbor_ids, _node_indices)
RealT, eltype(_u),
NDIMS + 1, NDIMS + 2,
typeof(u), typeof(normal_directions),
typeof(neighbor_ids), typeof(node_indices),
typeof(_u), typeof(_normal_directions),
typeof(_neighbor_ids), typeof(_node_indices))
return P4estInterfaceContainer{new_type_params...}(u, normal_directions,
neighbor_ids, node_indices,
_u, _normal_directions,
_neighbor_ids, _node_indices)
end

mutable struct P4estBoundaryContainer{NDIMS, uEltype <: Real, NDIMSP1,
Expand Down Expand Up @@ -618,8 +673,7 @@ function Adapt.adapt_structure(to, mortars::P4estMortarContainer)
NDIMS = ndims(mortars)
new_type_params = (NDIMS,
eltype(_u),
NDIMS + 1,
NDIMS + 3,
NDIMS + 1, NDIMS + 3,
typeof(u), typeof(neighbor_ids), typeof(node_indices),
typeof(_u), typeof(_neighbor_ids), typeof(_node_indices))
return P4estMortarContainer{new_type_params...}(u, neighbor_ids, node_indices,
Expand Down Expand Up @@ -655,7 +709,12 @@ function reinitialize_containers!(mesh::P4estMesh, equations, dg::DGSEM, cache)

# re-initialize containers together to reduce
# the number of iterations over the mesh in `p4est`
return init_surfaces!(interfaces, mortars, boundaries, mesh)
init_surfaces!(interfaces, mortars, boundaries, mesh)

# init_normal_directions! requires that `node_indices` have been initialized
init_normal_directions!(interfaces, dg.basis, elements)

return nothing
end

# A helper struct used in initialization methods below
Expand Down
Loading
Loading