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: Well-balanced mortars #45

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
122 changes: 122 additions & 0 deletions examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@

using Downloads: download
using OrdinaryDiffEq
using Trixi
using TrixiShallowWater

###############################################################################
# semidiscretization of the shallow water equations with a continuous
# bottom topography function

equations = ShallowWaterEquationsWetDry2D(gravity_constant = 9.812, H0 = 2.1)

function initial_condition_perturbation(x, t, equations::ShallowWaterEquationsWetDry2D)

Check warning on line 13 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl#L13

Added line #L13 was not covered by tests
# Calculate primitive variables
H = equations.H0
v1 = 0.0
v2 = 0.0

Check warning on line 17 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl#L15-L17

Added lines #L15 - L17 were not covered by tests

x1, x2 = x
b = (1.75 / exp(0.5 * ((x1 - 1.0)^2 + (x2 + 1.0)^2))

Check warning on line 20 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl#L19-L20

Added lines #L19 - L20 were not covered by tests
+
0.8 / exp(0.5 * ((x1 + 1.0)^2 + (x2 - 1.0)^2))
-
0.5 / exp(3.5 * ((x1 - 0.4)^2 + (x2 - 0.325)^2)))

# Waterheight perturbation
H = H + 0.5 * exp(-40.0 * ((x[1])^2 + (x[2])^2))

Check warning on line 27 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl#L27

Added line #L27 was not covered by tests

return prim2cons(SVector(H, v1, v2, b), equations)

Check warning on line 29 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl#L29

Added line #L29 was not covered by tests
end

initial_condition = initial_condition_perturbation

# Wall BCs
boundary_condition = Dict(:all => boundary_condition_slip_wall)

###############################################################################
# Get the DG approximation space

volume_flux = (flux_wintermeyer_etal, flux_nonconservative_wintermeyer_etal)

surface_flux = (FluxHydrostaticReconstruction(flux_hll_chen_noelle, hydrostatic_reconstruction_chen_noelle),
flux_nonconservative_chen_noelle)

# Create the solver
solver = DGSEM(polydeg = 3, surface_flux = surface_flux,
volume_integral = VolumeIntegralFluxDifferencing(volume_flux))

###############################################################################
# This setup is for the curved, split form well-balancedness testing

# Unstructured mesh with 24 cells of the square domain [-1, 1]^2
mesh_file = Trixi.download("https://gist.githubusercontent.com/efaulhaber/63ff2ea224409e55ee8423b3a33e316a/raw/7db58af7446d1479753ae718930741c47a3b79b7/square_unstructured_2.inp",
joinpath(@__DIR__, "square_unstructured_2.inp"))

# Affine type mapping to take the [-1,1]^2 domain from the mesh file
# and warp it as described in https://arxiv.org/abs/2012.12040
# Warping with the coefficient 0.2 is even more extreme.
function mapping_twist(xi, eta)
y = eta + 0.175 * cos(1.5 * pi * xi) * cos(0.5 * pi * eta)
x = xi + 0.175 * cos(0.5 * pi * xi) * cos(2.0 * pi * y)
return SVector(x, y)

Check warning on line 62 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl#L59-L62

Added lines #L59 - L62 were not covered by tests
end

mesh = P4estMesh{2}(mesh_file, polydeg = 3,
mapping = mapping_twist,
initial_refinement_level = 0)

# Create the semi discretization object
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
boundary_conditions = boundary_condition)

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

tspan = (0.0, 0.5)
ode = semidiscretize(semi, tspan)

###############################################################################

summary_callback = SummaryCallback()

analysis_interval = 100
analysis_callback = AnalysisCallback(semi, interval = analysis_interval)

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_solution = SaveSolutionCallback(dt = 0.04,
save_initial_solution = true,
save_final_solution = true)

# Define a better variable to use in the AMR indicator
@inline function total_water_height(u, equations::ShallowWaterEquationsWetDry2D)
return u[1] + u[4]

Check warning on line 94 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation.jl#L93-L94

Added lines #L93 - L94 were not covered by tests
end

amr_controller = ControllerThreeLevel(semi, IndicatorMax(semi, variable = total_water_height),
base_level = 0,
med_level = 1, med_threshold = 2.01,
max_level = 4, max_threshold = 2.15)

amr_callback = AMRCallback(semi, amr_controller,
interval = 1,
adapt_initial_condition = false, # to setup discontinuous bottom easier
adapt_initial_condition_only_refine = false)

stepsize_callback = StepsizeCallback(cfl = 1.0)

callbacks = CallbackSet(summary_callback,
analysis_callback,
alive_callback,
save_solution,
amr_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
# adaptive = false,
save_everystep = false, callback = callbacks);
summary_callback() # print the timer summary
211 changes: 211 additions & 0 deletions examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@

using Downloads: download
using OrdinaryDiffEq
using Trixi
using TrixiShallowWater

# TODO: This elixir is for debugging purposes of the AMR + well-balanced mortars.
# Currently this crashes very early in the simulation. ONe possible explanation is that
# the projection / interpolation of the solution as it is refined / coarsened may need
# to use a similar strategy as the mortar projection where we ensure that a constant solution
# is projected on the dry elements. Further investigation is needed to see if this is indeed
# the case.

###############################################################################
# semidiscretization of the shallow water equations with a continuous
# bottom topography function

equations = ShallowWaterEquationsWetDry2D(gravity_constant = 9.812, H0 = 1.235)

function initial_condition_perturbation(x, t, equations::ShallowWaterEquationsWetDry2D)

Check warning on line 20 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L20

Added line #L20 was not covered by tests
# Calculate primitive variables
H = equations.H0
v1 = 0.0
v2 = 0.0

Check warning on line 24 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L22-L24

Added lines #L22 - L24 were not covered by tests

x1, x2 = x
b = (1.5 / exp(0.5 * ((x1 - 1.0)^2 + (x2 + 1.0)^2))

Check warning on line 27 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L26-L27

Added lines #L26 - L27 were not covered by tests
+
0.8 / exp(0.5 * ((x1 + 1.0)^2 + (x2 - 1.0)^2))
-
0.5 / exp(3.5 * ((x1 - 0.4)^2 + (x2 - 0.325)^2)))

# for testing
# b = zero(eltype(x))

H = max(equations.H0, b + equations.threshold_limiter)

Check warning on line 36 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L36

Added line #L36 was not covered by tests

return prim2cons(SVector(H, v1, v2, b), equations)

Check warning on line 38 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L38

Added line #L38 was not covered by tests
end

initial_condition = initial_condition_perturbation

# Wall BCs
boundary_condition = Dict(:all => boundary_condition_slip_wall)

###############################################################################
# Get the DG approximation space

volume_flux = (flux_wintermeyer_etal, flux_nonconservative_wintermeyer_etal)

surface_flux = (FluxHydrostaticReconstruction(flux_hll_chen_noelle, hydrostatic_reconstruction_chen_noelle),
flux_nonconservative_chen_noelle)

# # Create the solver (for fully wet!)
# solver = DGSEM(polydeg = 3, surface_flux = surface_flux,
# volume_integral = VolumeIntegralFluxDifferencing(volume_flux))

# Create the solver
basis = LobattoLegendreBasis(3)

indicator_sc = IndicatorHennemannGassnerShallowWater(equations, basis,
alpha_max = 0.5,
alpha_min = 0.001,
alpha_smooth = true,
variable = Trixi.waterheight) # waterheight_pressure)
volume_integral = VolumeIntegralShockCapturingHG(indicator_sc;
volume_flux_dg = volume_flux,
volume_flux_fv = surface_flux)

solver = DGSEM(basis, surface_flux, volume_integral)

###############################################################################
# This setup is for the curved, split form well-balancedness testing

# Unstructured mesh with 24 cells of the square domain [-1, 1]^2
mesh_file = Trixi.download("https://gist.githubusercontent.com/efaulhaber/63ff2ea224409e55ee8423b3a33e316a/raw/7db58af7446d1479753ae718930741c47a3b79b7/square_unstructured_2.inp",
joinpath(@__DIR__, "square_unstructured_2.inp"))

# Affine type mapping to take the [-1,1]^2 domain from the mesh file
# and warp it as described in https://arxiv.org/abs/2012.12040
# Warping with the coefficient 0.2 is even more extreme.
function mapping_twist(xi, eta)
y = eta + 0.15 * cos(1.5 * pi * xi) * cos(0.5 * pi * eta)
x = xi + 0.15 * cos(0.5 * pi * xi) * cos(2.0 * pi * y)
return SVector(x, y)

Check warning on line 85 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L82-L85

Added lines #L82 - L85 were not covered by tests
end

mesh = P4estMesh{2}(mesh_file, polydeg = 3,
mapping = mapping_twist,
initial_refinement_level = 0)

# Refine bottom left quadrant of each tree to level 2
function refine_fn(p4est, which_tree, quadrant)
quadrant_obj = unsafe_load(quadrant)
if quadrant_obj.x == 0 && quadrant_obj.y == 0 && quadrant_obj.level < 3

Check warning on line 95 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L93-L95

Added lines #L93 - L95 were not covered by tests
# return true (refine)
return Cint(1)

Check warning on line 97 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L97

Added line #L97 was not covered by tests
else
# return false (don't refine)
return Cint(0)

Check warning on line 100 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L100

Added line #L100 was not covered by tests
end
end

# Refine recursively until each bottom left quadrant of a tree has level 3
# The mesh will be rebalanced before the simulation starts
refine_fn_c = @cfunction(refine_fn, Cint,
(Ptr{Trixi.p4est_t}, Ptr{Trixi.p4est_topidx_t},
Ptr{Trixi.p4est_quadrant_t}))
Trixi.refine_p4est!(mesh.p4est, true, refine_fn_c, C_NULL)

# Create the semi discretization object
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
boundary_conditions = boundary_condition)

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

tspan = (0.0, 0.5)
ode = semidiscretize(semi, tspan)

function initial_condition_discontinuous_well_balancedness(x, t, element_id, equations::ShallowWaterEquationsWetDry2D)

Check warning on line 121 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L121

Added line #L121 was not covered by tests
# Set the background values for velocity
H = equations.H0
v1 = zero(H)
v2 = zero(H)

Check warning on line 125 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L123-L125

Added lines #L123 - L125 were not covered by tests

x1, x2 = x
b = (1.75 / exp(0.6 * ((x1 - 1.0)^2 + (x2 + 1.0)^2))

Check warning on line 128 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L127-L128

Added lines #L127 - L128 were not covered by tests
+
0.8 / exp(0.5 * ((x1 + 1.0)^2 + (x2 - 1.0)^2))
-
0.5 / exp(3.5 * ((x1 - 0.4)^2 + (x2 - 0.325)^2)))

# Setup a discontinuous bottom topography using the element id number
if element_id > 207 && element_id < 300 # for the forced hanging node grid with with < 3 in function above
b = (0.75 / exp(0.5 * ((x1 - 1.0)^2 + (x2 + 1.0)^2))

Check warning on line 136 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L135-L136

Added lines #L135 - L136 were not covered by tests
+
0.4 / exp(0.5 * ((x1 + 1.0)^2 + (x2 - 1.0)^2))
-
0.25 / exp(3.5 * ((x1 - 0.4)^2 + (x2 - 0.325)^2)))
end

# Put in a discontinous purturbation using the element number

Check warning on line 143 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"discontinous" should be "discontinuous".
if element_id in [232, 224, 225, 226, 227, 228, 229, 230]
H = H + 0.3

Check warning on line 145 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L144-L145

Added lines #L144 - L145 were not covered by tests
end

# Clip the initialization to avoid negative water heights and division by zero
h = max(equations.threshold_limiter, H - b)

Check warning on line 149 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L149

Added line #L149 was not covered by tests

# Return the conservative variables
return SVector(h, h * v1, h * v2, b)

Check warning on line 152 in examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl

View check run for this annotation

Codecov / codecov/patch

examples/p4est_2d_dgsem/elixir_shallowwater_perturbation_wet_dry.jl#L152

Added line #L152 was not covered by tests
end

# point to the data we want to augment
u = Trixi.wrap_array(ode.u0, semi)
# reset the initial condition
for element in eachelement(semi.solver, semi.cache)
for j in eachnode(semi.solver), i in eachnode(semi.solver)
x_node = Trixi.get_node_coords(semi.cache.elements.node_coordinates, equations, semi.solver, i, j, element)
u_node = initial_condition_discontinuous_well_balancedness(x_node, first(tspan), element, equations)
Trixi.set_node_vars!(u, u_node, equations, semi.solver, i, j, element)
end
end

###############################################################################

summary_callback = SummaryCallback()

analysis_interval = 1000
analysis_callback = AnalysisCallback(semi, interval = analysis_interval)

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_solution = SaveSolutionCallback(interval=20, #dt = 0.04,
save_initial_solution = true,
save_final_solution = true)

# # Define a better variable to use in the AMR indicator
# @inline function total_water_height(u, equations::ShallowWaterEquationsWetDry2D)
# return u[1] + u[4]
# end

# amr_controller = ControllerThreeLevel(semi, IndicatorMax(semi, variable = total_water_height),
# base_level = 1,
# med_level = 2, med_threshold = 1.225, # 2.01,
# max_level = 4, max_threshold = 1.245) # 2.15)

# amr_callback = AMRCallback(semi, amr_controller,
# interval = 1,
# adapt_initial_condition = false,
# adapt_initial_condition_only_refine = false)

stepsize_callback = StepsizeCallback(cfl = 0.2)

callbacks = CallbackSet(summary_callback,
analysis_callback,
alive_callback,
save_solution,
# amr_callback,
stepsize_callback)

stage_limiter! = PositivityPreservingLimiterShallowWater(variables = (Trixi.waterheight,))

###############################################################################
# run the simulation
sol = solve(ode, SSPRK43(stage_limiter!),
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
adaptive = false,
save_everystep = false, callback = callbacks);
summary_callback() # print the timer summary
Loading
Loading