Skip to content

Commit ce4f75d

Browse files
MarcoArtianoDanielDoehringandrewwinters5000patrickersingranocha
authored
Add flexibility to nonconservative BCs (#2200)
* adding flexibility to noncons BCs * minor fix * Dirichlet BC for noncons * formatting * Noncons Dirichlet BC * test_type.jl fix * dg multi fix * moving 0.5 factor internally * Update src/solvers/dgsem_p4est/dg_2d.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/shallow_water_2d.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/shallow_water_2d.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/equations.jl Co-authored-by: Daniel Doehring <[email protected]> * Update examples/dgmulti_2d/elixir_mhd_reflective_wall.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/shallow_water_2d.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/shallow_water_2d.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/shallow_water_2d.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/equations.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/equations.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/equations.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/shallow_water_1d.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/shallow_water_1d.jl Co-authored-by: Daniel Doehring <[email protected]> * Update src/equations/shallow_water_1d.jl Co-authored-by: Daniel Doehring <[email protected]> * minor fixes * fix test type stability * fix test type stability * Update src/equations/shallow_water_1d.jl Co-authored-by: Andrew Winters <[email protected]> * Update src/equations/shallow_water_2d.jl Co-authored-by: Andrew Winters <[email protected]> * Update src/basic_types.jl Co-authored-by: Patrick Ersing <[email protected]> * Update src/basic_types.jl Co-authored-by: Patrick Ersing <[email protected]> * Update src/solvers/dgsem_p4est/dg_2d.jl Co-authored-by: Patrick Ersing <[email protected]> * Update src/solvers/dgsem_unstructured/dg_2d.jl Co-authored-by: Patrick Ersing <[email protected]> * Update src/solvers/dgsem_unstructured/dg_2d.jl Co-authored-by: Patrick Ersing <[email protected]> * Update src/basic_types.jl Co-authored-by: Daniel Doehring <[email protected]> * formatting * Update src/basic_types.jl Co-authored-by: Daniel Doehring <[email protected]> * Update test/test_type.jl Co-authored-by: Hendrik Ranocha <[email protected]> * Update test/test_type.jl Co-authored-by: Hendrik Ranocha <[email protected]> * Update src/equations/equations.jl Co-authored-by: Hendrik Ranocha <[email protected]> * Update src/equations/equations.jl Co-authored-by: Hendrik Ranocha <[email protected]> * add docs --------- Co-authored-by: Daniel Doehring <[email protected]> Co-authored-by: Andrew Winters <[email protected]> Co-authored-by: Patrick Ersing <[email protected]> Co-authored-by: Hendrik Ranocha <[email protected]>
1 parent f586b0d commit ce4f75d

File tree

14 files changed

+155
-61
lines changed

14 files changed

+155
-61
lines changed

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ for human readability.
2323
Previously, only the first 8 digits were printed to file.
2424
Furthermore, the names of the printed fields are now only separated by a single white space,
2525
in contrast to before where this were multiple, depending on the actual name of the printed data.
26+
- The boundary conditions for non-conservative equations can now be defined separately from the conservative part.
27+
The `surface_flux_functions` tuple is now passed directly to the boundary condition call,
28+
returning a tuple with boundary condition values for both the conservative and non-conservative parts ([#2200]).
29+
2630

2731
#### Deprecated
2832

docs/literate/src/files/adding_nonconservative_equation.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ error_1 / error_2
177177
# As expected, the new error is roughly reduced by a factor of 16, corresponding
178178
# to an experimental order of convergence of 4 (for polynomials of degree 3).
179179

180+
# For non-trivial boundary conditions involving non-conservative terms,
181+
# please refer to the section on [Other available example elixirs with non-trivial BC](https://trixi-framework.github.io/Trixi.jl/stable/tutorials/non_periodic_boundaries/#Other-available-example-elixirs-with-non-trivial-BC).
182+
180183
# ## Summary of the code
181184

182185
# Here is the complete code that we used (without the callbacks since these

docs/literate/src/files/non_periodic_boundaries.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ end
158158
# ```
159159
# Source: [`Video`](https://www.youtube.com/watch?v=w0A9X38cSe4) on Trixi.jl's YouTube channel [`Trixi Framework`](https://www.youtube.com/watch?v=WElqqdMhY4A)
160160

161+
# Furthermore, Trixi.jl also handles equations that include non-conservative terms.
162+
# For such equations, the tuple of conservative and non-conservative surfaces fluxes is passed to the boundary condition,
163+
# which then returns a tuple containing the boundary condition values for both the conservative and non-conservative terms.
164+
# For instance, a 2D ideal compressible GLM-MHD setup with reflective walls can be found in the elixir ['elixir_mhd_reflective_wall.jl](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/dgmulti_2d/elixir_mhd_reflective_wall.jl).
165+
161166
# ## Package versions
162167

163168
# These results were obtained using the following versions.

examples/dgmulti_2d/elixir_mhd_reflective_wall.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ mesh = DGMultiMesh(solver, cells_per_dimension; periodicity = (false, false),
4848
# Create a "reflective-like" boundary condition by mirroring the velocity but leaving the magnetic field alone.
4949
# Note that this boundary condition is probably not entropy stable.
5050
function boundary_condition_velocity_slip_wall(u_inner, normal_direction::AbstractVector,
51-
x, t, surface_flux_function,
51+
x, t, surface_flux_functions,
5252
equations::IdealGlmMhdEquations2D)
53-
53+
surface_flux_function, nonconservative_flux_function = surface_flux_functions
5454
# Normalize the vector without using `normalize` since we need to multiply by the `norm_` later
5555
norm_ = norm(normal_direction)
5656
normal = normal_direction / norm_
@@ -62,8 +62,10 @@ function boundary_condition_velocity_slip_wall(u_inner, normal_direction::Abstra
6262
u_mirror = prim2cons(SVector(rho, v1 - 2 * v_normal * normal[1],
6363
v2 - 2 * v_normal * normal[2],
6464
v3, p, B1, B2, B3, psi), equations)
65-
66-
return surface_flux_function(u_inner, u_mirror, normal, equations) * norm_
65+
flux = surface_flux_function(u_inner, u_mirror, normal, equations) * norm_
66+
noncons_flux = nonconservative_flux_function(u_inner, u_mirror, normal, equations) *
67+
norm_
68+
return flux, noncons_flux
6769
end
6870

6971
boundary_conditions = (; x_neg = boundary_condition_velocity_slip_wall,

src/basic_types.jl

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,39 @@ struct BoundaryConditionDoNothing end
7171
orientation_or_normal_direction,
7272
direction::Integer, x, t, surface_flux,
7373
equations)
74-
return surface_flux(u_inner, u_inner, orientation_or_normal_direction, equations)
74+
return flux(u_inner, orientation_or_normal_direction, equations)
75+
end
76+
77+
# This version can be called by hyperbolic solvers on logically Cartesian meshes
78+
@inline function (::BoundaryConditionDoNothing)(u_inner,
79+
orientation_or_normal_direction,
80+
direction::Integer, x, t,
81+
surface_flux_functions::Tuple,
82+
equations)
83+
surface_flux_function, nonconservative_flux_function = surface_flux_functions
84+
return surface_flux_function(u_inner, u_inner,
85+
orientation_or_normal_direction, equations),
86+
nonconservative_flux_function(u_inner, u_inner,
87+
orientation_or_normal_direction, equations)
7588
end
7689

7790
# This version can be called by hyperbolic solvers on unstructured, curved meshes
7891
@inline function (::BoundaryConditionDoNothing)(u_inner,
7992
outward_direction::AbstractVector,
8093
x, t, surface_flux, equations)
81-
return surface_flux(u_inner, u_inner, outward_direction, equations)
94+
return flux(u_inner, outward_direction, equations)
95+
end
96+
97+
# Version for equations involving nonconservative fluxes
98+
@inline function (::BoundaryConditionDoNothing)(u_inner,
99+
outward_direction::AbstractVector,
100+
x, t, surface_flux_functions::Tuple,
101+
equations)
102+
surface_flux_function, nonconservative_flux_function = surface_flux_functions
103+
104+
return surface_flux_function(u_inner, u_inner, outward_direction, equations),
105+
nonconservative_flux_function(u_inner, u_inner, outward_direction,
106+
equations)
82107
end
83108

84109
# This version can be called by parabolic solvers

src/equations/equations.jl

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,36 @@ end
181181
return flux
182182
end
183183

184+
# Dirichlet-type boundary condition for use with TreeMesh or StructuredMesh
185+
# passing a tuple of surface flux functions for nonconservative terms
186+
@inline function (boundary_condition::BoundaryConditionDirichlet)(u_inner,
187+
orientation_or_normal,
188+
direction,
189+
x, t,
190+
surface_flux_functions::Tuple,
191+
equations)
192+
surface_flux_function, nonconservative_flux_function = surface_flux_functions
193+
194+
u_boundary = boundary_condition.boundary_value_function(x, t, equations)
195+
196+
# Calculate boundary flux
197+
if iseven(direction) # u_inner is "left" of boundary, u_boundary is "right" of boundary
198+
flux = surface_flux_function(u_inner, u_boundary, orientation_or_normal,
199+
equations)
200+
noncons_flux = nonconservative_flux_function(u_inner, u_boundary,
201+
orientation_or_normal,
202+
equations)
203+
else # u_boundary is "left" of boundary, u_inner is "right" of boundary
204+
flux = surface_flux_function(u_boundary, u_inner, orientation_or_normal,
205+
equations)
206+
noncons_flux = nonconservative_flux_function(u_boundary, u_inner,
207+
orientation_or_normal,
208+
equations)
209+
end
210+
211+
return flux, noncons_flux
212+
end
213+
184214
# Dirichlet-type boundary condition for use with UnstructuredMesh2D
185215
# Note: For unstructured we lose the concept of an "absolute direction"
186216
@inline function (boundary_condition::BoundaryConditionDirichlet)(u_inner,
@@ -197,6 +227,26 @@ end
197227
return flux
198228
end
199229

230+
# Dirichlet-type boundary condition for equations with non-conservative terms for use with UnstructuredMesh2D
231+
# passing a tuple of surface flux functions for nonconservative terms
232+
# Note: For unstructured we lose the concept of an "absolute direction"
233+
@inline function (boundary_condition::BoundaryConditionDirichlet)(u_inner,
234+
normal_direction::AbstractVector,
235+
x, t,
236+
surface_flux_functions::Tuple,
237+
equations)
238+
surface_flux_function, nonconservative_flux_function = surface_flux_functions
239+
240+
# get the external value of the solution
241+
u_boundary = boundary_condition.boundary_value_function(x, t, equations)
242+
243+
# Calculate boundary flux
244+
flux = surface_flux_function(u_inner, u_boundary, normal_direction, equations)
245+
noncons_flux = nonconservative_flux_function(u_inner, u_boundary, normal_direction,
246+
equations)
247+
return flux, noncons_flux
248+
end
249+
200250
# operator types used for dispatch on parabolic boundary fluxes
201251
struct Gradient end
202252
struct Divergence end

src/equations/shallow_water_1d.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,12 @@ For details see Section 9.2.5 of the book:
160160
"""
161161
@inline function boundary_condition_slip_wall(u_inner, orientation_or_normal, direction,
162162
x, t,
163-
surface_flux_function,
163+
surface_flux_functions,
164164
equations::ShallowWaterEquations1D)
165165

166+
# The boundary conditions for the non-conservative term are identically 0 here.
167+
# Bottom topography is assumed to be continuous at the boundary.
168+
surface_flux_function, nonconservative_flux_function = surface_flux_functions
166169
# create the "external" boundary solution state
167170
u_boundary = SVector(u_inner[1],
168171
-u_inner[2],
@@ -172,12 +175,18 @@ For details see Section 9.2.5 of the book:
172175
if iseven(direction) # u_inner is "left" of boundary, u_boundary is "right" of boundary
173176
flux = surface_flux_function(u_inner, u_boundary, orientation_or_normal,
174177
equations)
178+
noncons_flux = nonconservative_flux_function(u_inner, u_boundary,
179+
orientation_or_normal,
180+
equations)
175181
else # u_boundary is "left" of boundary, u_inner is "right" of boundary
176182
flux = surface_flux_function(u_boundary, u_inner, orientation_or_normal,
177183
equations)
184+
noncons_flux = nonconservative_flux_function(u_boundary, u_inner,
185+
orientation_or_normal,
186+
equations)
178187
end
179188

180-
return flux
189+
return flux, noncons_flux
181190
end
182191

183192
# Calculate 1D flux for a single point

src/equations/shallow_water_2d.jl

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,10 @@ For details see Section 9.2.5 of the book:
180180
"""
181181
@inline function boundary_condition_slip_wall(u_inner, normal_direction::AbstractVector,
182182
x, t,
183-
surface_flux_function,
183+
surface_flux_functions,
184184
equations::ShallowWaterEquations2D)
185+
surface_flux_function, nonconservative_flux_function = surface_flux_functions
186+
185187
# normalize the outward pointing direction
186188
normal = normal_direction / norm(normal_direction)
187189

@@ -196,8 +198,10 @@ For details see Section 9.2.5 of the book:
196198

197199
# calculate the boundary flux
198200
flux = surface_flux_function(u_inner, u_boundary, normal_direction, equations)
201+
noncons_flux = nonconservative_flux_function(u_inner, u_boundary, normal_direction,
202+
equations)
199203

200-
return flux
204+
return flux, noncons_flux
201205
end
202206

203207
"""
@@ -208,8 +212,11 @@ Should be used together with [`TreeMesh`](@ref).
208212
"""
209213
@inline function boundary_condition_slip_wall(u_inner, orientation,
210214
direction, x, t,
211-
surface_flux_function,
215+
surface_flux_functions,
212216
equations::ShallowWaterEquations2D)
217+
# The boundary conditions for the non-conservative term are identically 0 here.
218+
# Bottom topography is assumed to be continuous at the boundary.
219+
surface_flux_function, nonconservative_flux_function = surface_flux_functions
213220
## get the appropriate normal vector from the orientation
214221
if orientation == 1
215222
u_boundary = SVector(u_inner[1], -u_inner[2], u_inner[3], u_inner[4])
@@ -220,11 +227,15 @@ Should be used together with [`TreeMesh`](@ref).
220227
# Calculate boundary flux
221228
if iseven(direction) # u_inner is "left" of boundary, u_boundary is "right" of boundary
222229
flux = surface_flux_function(u_inner, u_boundary, orientation, equations)
230+
noncons_flux = nonconservative_flux_function(u_inner, u_boundary, orientation,
231+
equations)
223232
else # u_boundary is "left" of boundary, u_inner is "right" of boundary
224233
flux = surface_flux_function(u_boundary, u_inner, orientation, equations)
234+
noncons_flux = nonconservative_flux_function(u_boundary, u_inner, orientation,
235+
equations)
225236
end
226237

227-
return flux
238+
return flux, noncons_flux
228239
end
229240

230241
# Calculate 1D flux for a single point

src/solvers/dgmulti/dg.jl

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,6 @@ function calc_single_boundary_flux!(cache, t, boundary_condition, boundary_key,
523523
dg::DGMulti{NDIMS}) where {NDIMS}
524524
rd = dg.basis
525525
md = mesh.md
526-
surface_flux, nonconservative_flux = dg.surface_integral.surface_flux
527526

528527
# reshape face/normal arrays to have size = (num_points_on_face, num_faces_total).
529528
# mesh.boundary_faces indexes into the columns of these face-reshaped arrays.
@@ -550,21 +549,16 @@ function calc_single_boundary_flux!(cache, t, boundary_condition, boundary_key,
550549

551550
# Compute conservative and non-conservative fluxes separately.
552551
# This imposes boundary conditions on the conservative part of the flux.
553-
cons_flux_at_face_node = boundary_condition(u_face_values[i, f],
554-
face_normal, face_coordinates,
555-
t,
556-
surface_flux, equations)
557-
558-
# Compute pointwise nonconservative numerical flux at the boundary.
559-
noncons_flux_at_face_node = boundary_condition(u_face_values[i, f],
560-
face_normal,
561-
face_coordinates,
562-
t,
563-
nonconservative_flux,
564-
equations)
552+
cons_flux_at_face_node, noncons_flux_at_face_node = boundary_condition(u_face_values[i,
553+
f],
554+
face_normal,
555+
face_coordinates,
556+
t,
557+
dg.surface_integral.surface_flux,
558+
equations)
565559

566560
flux_face_values[i, f] = (cons_flux_at_face_node +
567-
0.5 * noncons_flux_at_face_node) * Jf[i, f]
561+
0.5f0 * noncons_flux_at_face_node) * Jf[i, f]
568562
end
569563
end
570564

src/solvers/dgsem_p4est/dg_2d.jl

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,6 @@ end
349349
boundary_index)
350350
@unpack boundaries = cache
351351
@unpack node_coordinates, contravariant_vectors = cache.elements
352-
surface_flux, nonconservative_flux = surface_integral.surface_flux
353352

354353
# Extract solution data from boundary container
355354
u_inner = get_node_vars(boundaries.u, equations, dg, node_index, boundary_index)
@@ -362,22 +361,19 @@ end
362361
x = get_node_coords(node_coordinates, equations, dg, i_index, j_index,
363362
element_index)
364363

365-
# Call pointwise numerical flux function for the conservative part
364+
# Call pointwise numerical flux functions for the conservative and nonconservative part
366365
# in the normal direction on the boundary
367-
flux_ = boundary_condition(u_inner, normal_direction, x, t, surface_flux, equations)
368-
369-
# Compute pointwise nonconservative numerical flux at the boundary.
370-
noncons_ = boundary_condition(u_inner, normal_direction, x, t, nonconservative_flux,
371-
equations)
366+
flux, noncons_flux = boundary_condition(u_inner, normal_direction, x, t,
367+
surface_integral.surface_flux, equations)
372368

373369
# Copy flux to element storage in the correct orientation
374370
for v in eachvariable(equations)
375371
# Note the factor 0.5 necessary for the nonconservative fluxes based on
376372
# the interpretation of global SBP operators coupled discontinuously via
377373
# central fluxes/SATs
378-
surface_flux_values[v, node_index, direction_index, element_index] = flux_[v] +
374+
surface_flux_values[v, node_index, direction_index, element_index] = flux[v] +
379375
0.5f0 *
380-
noncons_[v]
376+
noncons_flux[v]
381377
end
382378
end
383379

0 commit comments

Comments
 (0)