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

Subcell positivity IDP limiting for conservative variables #1476

Merged
merged 46 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
d37fa21
Add IDP positivity limiting for conservative variables
bennibolm May 15, 2023
a139380
Add elixir with modified blast wave
bennibolm May 17, 2023
891526f
Add documentation
bennibolm May 17, 2023
a24ae11
Merge branch 'main' into IDPlimiting-positivity-cons
bennibolm May 22, 2023
b9ea8cf
Fix parameter type
bennibolm May 24, 2023
f228b0a
Adjust output of summary callback
bennibolm May 24, 2023
ea548da
Merge changes from `subcell-limiting` and `main`
bennibolm Jun 2, 2023
d801349
Merge branch 'main' into IDPlimiting-positivity-cons
bennibolm Jun 2, 2023
4359416
Fix test with right time stepping
bennibolm Jun 2, 2023
8f1f02f
Implement first suggestions
bennibolm Jun 3, 2023
68806e0
Implement suggestions
bennibolm Jun 5, 2023
cf66b94
Fix elixir
bennibolm Jun 5, 2023
a689a6c
Relocate `perform_idp_correction!`
bennibolm Jun 6, 2023
ecc4a18
Rename variable in `snake_case`
bennibolm Jun 6, 2023
8be446a
Implement other suggestions
bennibolm Jun 6, 2023
7acc24f
Rename container variables using `snake_case`
bennibolm Jun 6, 2023
6a46217
Delete timer
bennibolm Jun 6, 2023
e2262e5
Merge `subcell-limiting` (Adapt docstrings)
bennibolm Jun 6, 2023
70d3476
Merge `subcell-limiting`
bennibolm Jun 6, 2023
7979558
Merge `subcell-limiting` (Renaming and dispatch)
bennibolm Jun 10, 2023
b290d5b
Fix documentation
bennibolm Jun 10, 2023
01741c0
Merge branch 'main' into IDPlimiting-positivity-cons
bennibolm Jun 12, 2023
374fccf
Implement positivty limiter with numbers of cons vars
bennibolm Jun 14, 2023
a05a793
Merge branch 'main' into IDPlimiting-positivity-cons
bennibolm Jun 14, 2023
4e693d4
Merge branch 'IDPlimiting-positivity-cons' of https://github.com/benn…
bennibolm Jun 14, 2023
8dc8041
Merge branch 'main' into IDPlimiting-positivity-cons
bennibolm Jun 16, 2023
5f21d5d
Merge branch 'IDPlimiting-positivity-cons' into IDPlimiting-positivit…
bennibolm Jun 16, 2023
1ab075c
Merge suggestions already implemented in `subcell-limiting`
bennibolm Jun 16, 2023
3c7633d
Fix elixir
bennibolm Jun 16, 2023
43de3b7
Merge branch 'IDPlimiting-positivity-cons' into IDPlimiting-positivit…
bennibolm Jun 16, 2023
6cfbbff
Merge pull request #113 from bennibolm/IDPlimiting-positivity-cons-2
bennibolm Jun 19, 2023
b85e9b8
Merge branch 'main' into IDPlimiting-positivity-cons
bennibolm Jun 20, 2023
1785623
Merge branch 'IDPlimiting-positivity-cons' of https://github.com/benn…
bennibolm Jun 20, 2023
dd75ff6
Update docstring and output
bennibolm Jun 20, 2023
5cd186a
Restructure parameter for positivity limiting
bennibolm Jun 21, 2023
9d6d6f5
Add test for "show" routine
bennibolm Jun 21, 2023
7cb8597
Rename Limiters and Containers
bennibolm Jul 5, 2023
f4b6542
Rename antidiffusive stage callback
bennibolm Jul 6, 2023
0c634ed
Relocate subcell limiter code
bennibolm Jul 7, 2023
b055542
Move create_cache routine to specific file
bennibolm Jul 10, 2023
c287c96
Merge branch 'main' into IDPlimiting-positivity-cons
bennibolm Jul 10, 2023
111b334
Merge branch 'main' into IDPlimiting-positivity-cons
bennibolm Aug 9, 2023
0aad20b
Implement suggestions
bennibolm Aug 9, 2023
5c88cf2
Merge branch 'main' into IDPlimiting-positivity-cons
ranocha Aug 9, 2023
2b88d61
Merge branch 'main' into IDPlimiting-positivity-cons
sloede Aug 17, 2023
0fca290
Implement suggestions
bennibolm Aug 18, 2023
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
1 change: 1 addition & 0 deletions src/Trixi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ export DG,
VolumeIntegralFluxDifferencing,
VolumeIntegralPureLGLFiniteVolume,
VolumeIntegralShockCapturingHG, IndicatorHennemannGassner,
VolumeIntegralShockCapturingSubcell, IndicatorIDP,
VolumeIntegralUpwind,
SurfaceIntegralWeakForm, SurfaceIntegralStrongForm,
SurfaceIntegralUpwind,
Expand Down
41 changes: 41 additions & 0 deletions src/solvers/dg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,47 @@ function Base.show(io::IO, ::MIME"text/plain", integral::VolumeIntegralPureLGLFi
end


"""
VolumeIntegralShockCapturingSubcell(indicator;
volume_flux_dg, volume_flux_fv)

A shock-capturing volume integral type for DG methods based on a subcell blending approach
with a low-order FV method from the preprint paper
- Rueda-Ramírez, Pazner, Gassner (2022)
"Subcell Limiting Strategies for Discontinuous Galerkin Spectral Element Methods"

!!! warning "Experimental implementation"
This is an experimental feature and may change in future releases.

See also: [`VolumeIntegralShockCapturingHG`](@ref)
"""
struct VolumeIntegralShockCapturingSubcell{VolumeFluxDG, VolumeFluxFV, Indicator} <: AbstractVolumeIntegral
volume_flux_dg::VolumeFluxDG
volume_flux_fv::VolumeFluxFV
indicator::Indicator
end

function VolumeIntegralShockCapturingSubcell(indicator; volume_flux_dg,
volume_flux_fv)
VolumeIntegralShockCapturingSubcell{typeof(volume_flux_dg), typeof(volume_flux_fv), typeof(indicator)}(
volume_flux_dg, volume_flux_fv, indicator)
end

function Base.show(io::IO, ::MIME"text/plain", integral::VolumeIntegralShockCapturingSubcell)
@nospecialize integral # reduce precompilation time

if get(io, :compact, false)
show(io, integral)
else
setup = [
"volume flux dg" => integral.volume_flux_dg,
"volume flux fv" => integral.volume_flux_fv,
"indicator" => integral.indicator
]
summary_box(io, "VolumeIntegralShockCapturingSubcell", setup)
end
end

# TODO: FD. Should this definition live in a different file because it is
# not strictly a DG method?
"""
Expand Down
118 changes: 118 additions & 0 deletions src/solvers/dgsem_tree/containers_2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1255,6 +1255,124 @@ function init_mpi_mortars!(mpi_mortars, elements, mesh::TreeMesh2D)
end


# Container data structure (structure-of-arrays style) for FCT-type antidiffusive fluxes
# (i, j+1)
# |
# flux2(i, j+1)
# |
# (i-1, j) ---flux1(i, j)--- (i, j) ---flux1(i+1, j)--- (i+1, j)
# |
# flux2(i, j)
# |
# (i, j-1)
mutable struct ContainerAntidiffusiveFlux2D{uEltype<:Real}
antidiffusive_flux1::Array{uEltype, 4} # [variables, i, j, elements]
antidiffusive_flux2::Array{uEltype, 4} # [variables, i, j, elements]
# internal `resize!`able storage
_antidiffusive_flux1::Vector{uEltype}
_antidiffusive_flux2::Vector{uEltype}
end

function ContainerAntidiffusiveFlux2D{uEltype}(capacity::Integer, n_variables, n_nodes) where uEltype<:Real
nan_uEltype = convert(uEltype, NaN)

# Initialize fields with defaults
_antidiffusive_flux1 = fill(nan_uEltype, n_variables * (n_nodes+1) * n_nodes * capacity)
antidiffusive_flux1 = unsafe_wrap(Array, pointer(_antidiffusive_flux1),
(n_variables, n_nodes+1, n_nodes, capacity))

_antidiffusive_flux2 = fill(nan_uEltype, n_variables * n_nodes * (n_nodes+1) * capacity)
antidiffusive_flux2 = unsafe_wrap(Array, pointer(_antidiffusive_flux2),
(n_variables, n_nodes, n_nodes+1, capacity))

return ContainerAntidiffusiveFlux2D{uEltype}(antidiffusive_flux1, antidiffusive_flux2,
_antidiffusive_flux1, _antidiffusive_flux2)
end

nvariables(fluxes::ContainerAntidiffusiveFlux2D) = size(fluxes.antidiffusive_flux1, 1)
nnodes(fluxes::ContainerAntidiffusiveFlux2D) = size(fluxes.antidiffusive_flux1, 3)

# Only one-dimensional `Array`s are `resize!`able in Julia.
# Hence, we use `Vector`s as internal storage and `resize!`
# them whenever needed. Then, we reuse the same memory by
# `unsafe_wrap`ping multi-dimensional `Array`s around the
# internal storage.
function Base.resize!(fluxes::ContainerAntidiffusiveFlux2D, capacity)
n_nodes = nnodes(fluxes)
n_variables = nvariables(fluxes)

@unpack _antidiffusive_flux1, _antidiffusive_flux2 = fluxes

resize!(_antidiffusive_flux1, n_variables * (n_nodes+1) * n_nodes * capacity)
fluxes.antidiffusive_flux1 = unsafe_wrap(Array, pointer(_antidiffusive_flux1),
(n_variables, n_nodes+1, n_nodes, capacity))
resize!(_antidiffusive_flux2, n_variables * n_nodes * (n_nodes+1) * capacity)
fluxes.antidiffusive_flux2 = unsafe_wrap(Array, pointer(_antidiffusive_flux2),
(n_variables, n_nodes, n_nodes+1, capacity))

return nothing
end


mutable struct ContainerShockCapturingIndicatorIDP{uEltype<:Real}
bennibolm marked this conversation as resolved.
Show resolved Hide resolved
alpha::Array{uEltype, 3} # [i, j, element]
alpha1::Array{uEltype, 3}
alpha2::Array{uEltype, 3}
var_bounds::Vector{Array{uEltype, 3}}
bennibolm marked this conversation as resolved.
Show resolved Hide resolved
# internal `resize!`able storage
_alpha::Vector{uEltype}
_alpha1::Vector{uEltype}
_alpha2::Vector{uEltype}
_var_bounds::Vector{Vector{uEltype}}
end

function ContainerShockCapturingIndicatorIDP{uEltype}(capacity::Integer, n_nodes, number_bounds) where uEltype<:Real
nan_uEltype = convert(uEltype, NaN)

# Initialize fields with defaults
_alpha = fill(nan_uEltype, n_nodes * n_nodes * capacity)
alpha = unsafe_wrap(Array, pointer(_alpha), (n_nodes, n_nodes, capacity))
_alpha1 = fill(nan_uEltype, (n_nodes+1) * n_nodes * capacity)
alpha1 = unsafe_wrap(Array, pointer(_alpha1), (n_nodes+1, n_nodes, capacity))
_alpha2 = fill(nan_uEltype, n_nodes * (n_nodes+1) * capacity)
alpha2 = unsafe_wrap(Array, pointer(_alpha2), (n_nodes, n_nodes+1, capacity))

_var_bounds = Vector{Vector{uEltype}}(undef, number_bounds)
var_bounds = Vector{Array{uEltype, 3}}(undef, number_bounds)
for i in 1:number_bounds
_var_bounds[i] = fill(nan_uEltype, n_nodes * n_nodes * capacity)
var_bounds[i] = unsafe_wrap(Array, pointer(_var_bounds[i]), (n_nodes, n_nodes, capacity))
end

return ContainerShockCapturingIndicatorIDP{uEltype}(alpha, alpha1, alpha2, var_bounds,
_alpha, _alpha1, _alpha2, _var_bounds)
end

nnodes(indicator::ContainerShockCapturingIndicatorIDP) = size(indicator.alpha, 1)

# Only one-dimensional `Array`s are `resize!`able in Julia.
# Hence, we use `Vector`s as internal storage and `resize!`
# them whenever needed. Then, we reuse the same memory by
# `unsafe_wrap`ping multi-dimensional `Array`s around the
# internal storage.
function Base.resize!(indicator::ContainerShockCapturingIndicatorIDP, capacity)
n_nodes = nnodes(indicator)

@unpack _alpha, _alpha1, _alpha2 = indicator
resize!(_alpha, n_nodes * n_nodes * capacity)
indicator.alpha = unsafe_wrap(Array, pointer(_alpha), (n_nodes, n_nodes, capacity))
resize!(_alpha1, (n_nodes + 1) * n_nodes * capacity)
indicator.alpha1 = unsafe_wrap(Array, pointer(_alpha1), (n_nodes + 1, n_nodes, capacity))
resize!(_alpha2, n_nodes * (n_nodes + 1) * capacity)
indicator.alpha2 = unsafe_wrap(Array, pointer(_alpha2), (n_nodes, n_nodes + 1, capacity))

@unpack _var_bounds = indicator
for i in 1:length(_var_bounds)
resize!(_var_bounds[i], n_nodes * n_nodes * capacity)
indicator.var_bounds[i] = unsafe_wrap(Array, pointer(_var_bounds[i]), (n_nodes, n_nodes, capacity))
end

return nothing
end

end # @muladd
Loading