Skip to content

Commit

Permalink
L2 Mortars for Parabolic Terms on TreeMeshes (#1571)
Browse files Browse the repository at this point in the history
* First try mortars for parabolic terms

* Use correct interface values in calc_fstar!

* Format parabolic 2d dgsem

* Remove unused function parameters

* L2 Mortars for 3D DGSEM TreeMesh

* Format

* Back to original example

* Dispatch 2D DGSEm rhs_parabolic for p4est and classic tree

* Re-use standard prolong2mortars in gradient comp

* Back to original version

* Add tests for L2 mortars for hyp-para

* remove whitespaces

* Use original analysis callback

* Test Taylor-Green with different integrator

* Remove whitespace

* check coverage status

* Stick to CK2N54 for 3D test

* Add more explicit dispatch

* Less invasive treatment for mortars and p4est

* Revert "Add more explicit dispatch"

This reverts commit 491c923.

* More explicit dispatch

* Remove additional end

* Remove doubled implementations

* kepp main updated with true main

* Add comment

* comment parabolic 3d

* whitespace

* Avoid allocations in parabolic boundary fluxes

* Update src/solvers/dgsem_tree/dg_2d_parabolic.jl

Co-authored-by: Andrew Winters <[email protected]>

* Update src/solvers/dgsem_tree/dg_3d_parabolic.jl

Co-authored-by: Andrew Winters <[email protected]>

* Update src/solvers/dgsem_tree/dg_3d_parabolic.jl

Co-authored-by: Andrew Winters <[email protected]>

* revert alloc BC (other PR)

* Revert alloc BC (other PR)

* Name & News

* Update NEWS.md

Co-authored-by: Andrew Winters <[email protected]>

* Update src/solvers/dgsem_p4est/dg_2d_parabolic.jl

Co-authored-by: Hendrik Ranocha <[email protected]>

* Update src/solvers/dgsem_p4est/dg_3d_parabolic.jl

Co-authored-by: Hendrik Ranocha <[email protected]>

* Check allocations

---------

Co-authored-by: Hendrik Ranocha <[email protected]>
Co-authored-by: Andrew Winters <[email protected]>
  • Loading branch information
3 people authored Aug 10, 2023
1 parent ce81702 commit 3ca93af
Show file tree
Hide file tree
Showing 8 changed files with 870 additions and 9 deletions.
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ are listed in alphabetical order:
* Jesse Chan
* Lars Christmann
* Christof Czernik
* Daniel Doehring
* Patrick Ersing
* Erik Faulhaber
* Gregor Gassner
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ for human readability.
#### Added

- Experimental support for 3D parabolic diffusion terms has been added.
- Non-uniform `TreeMesh` available for hyperbolic-parabolic equations.
- Capability to set truly discontinuous initial conditions in 1D.
- Wetting and drying feature and examples for 1D and 2D shallow water equations

Expand Down
91 changes: 91 additions & 0 deletions src/solvers/dgsem_p4est/dg_2d_parabolic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,97 @@ function create_cache_parabolic(mesh::P4estMesh{2}, equations_hyperbolic::Abstra
return cache
end

# TODO: Remove in favor of the implementation for the TreeMesh
# once the P4estMesh can handle mortars as well
function rhs_parabolic!(du, u, t, mesh::P4estMesh{2},
equations_parabolic::AbstractEquationsParabolic,
initial_condition, boundary_conditions_parabolic, source_terms,
dg::DG, parabolic_scheme, cache, cache_parabolic)
(; u_transformed, gradients, flux_viscous) = cache_parabolic

# Convert conservative variables to a form more suitable for viscous flux calculations
@trixi_timeit timer() "transform variables" begin
transform_variables!(u_transformed, u, mesh, equations_parabolic,
dg, parabolic_scheme, cache, cache_parabolic)
end

# Compute the gradients of the transformed variables
@trixi_timeit timer() "calculate gradient" begin
calc_gradient!(gradients, u_transformed, t, mesh, equations_parabolic,
boundary_conditions_parabolic, dg, cache, cache_parabolic)
end

# Compute and store the viscous fluxes
@trixi_timeit timer() "calculate viscous fluxes" begin
calc_viscous_fluxes!(flux_viscous, gradients, u_transformed, mesh,
equations_parabolic, dg, cache, cache_parabolic)
end

# The remainder of this function is essentially a regular rhs! for parabolic
# equations (i.e., it computes the divergence of the viscous fluxes)
#
# OBS! In `calc_viscous_fluxes!`, the viscous flux values at the volume nodes of each element have
# been computed and stored in `fluxes_viscous`. In the following, we *reuse* (abuse) the
# `interfaces` and `boundaries` containers in `cache_parabolic` to interpolate and store the
# *fluxes* at the element surfaces, as opposed to interpolating and storing the *solution* (as it
# is done in the hyperbolic operator). That is, `interfaces.u`/`boundaries.u` store *viscous flux values*
# and *not the solution*. The advantage is that a) we do not need to allocate more storage, b) we
# do not need to recreate the existing data structure only with a different name, and c) we do not
# need to interpolate solutions *and* gradients to the surfaces.

# TODO: parabolic; reconsider current data structure reuse strategy

# Reset du
@trixi_timeit timer() "reset ∂u/∂t" reset_du!(du, dg, cache)

# Calculate volume integral
@trixi_timeit timer() "volume integral" begin
calc_volume_integral!(du, flux_viscous, mesh, equations_parabolic, dg, cache)
end

# Prolong solution to interfaces
@trixi_timeit timer() "prolong2interfaces" begin
prolong2interfaces!(cache_parabolic, flux_viscous, mesh, equations_parabolic,
dg.surface_integral, dg, cache)
end

# Calculate interface fluxes
@trixi_timeit timer() "interface flux" begin
calc_interface_flux!(cache_parabolic.elements.surface_flux_values, mesh,
equations_parabolic, dg, cache_parabolic)
end

# Prolong solution to boundaries
@trixi_timeit timer() "prolong2boundaries" begin
prolong2boundaries!(cache_parabolic, flux_viscous, mesh, equations_parabolic,
dg.surface_integral, dg, cache)
end

# Calculate boundary fluxes
@trixi_timeit timer() "boundary flux" begin
calc_boundary_flux_divergence!(cache_parabolic, t,
boundary_conditions_parabolic, mesh,
equations_parabolic,
dg.surface_integral, dg)
end

# TODO: parabolic; extend to mortars
@assert nmortars(dg, cache) == 0

# Calculate surface integrals
@trixi_timeit timer() "surface integral" begin
calc_surface_integral!(du, u, mesh, equations_parabolic,
dg.surface_integral, dg, cache_parabolic)
end

# Apply Jacobian from mapping to reference element
@trixi_timeit timer() "Jacobian" begin
apply_jacobian_parabolic!(du, mesh, equations_parabolic, dg, cache_parabolic)
end

return nothing
end

function calc_gradient!(gradients, u_transformed, t,
mesh::P4estMesh{2}, equations_parabolic,
boundary_conditions_parabolic, dg::DG,
Expand Down
99 changes: 99 additions & 0 deletions src/solvers/dgsem_p4est/dg_3d_parabolic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,105 @@ function create_cache_parabolic(mesh::P4estMesh{3}, equations_hyperbolic::Abstra
return cache
end

# This file collects all methods that have been updated to work with parabolic systems of equations
#
# assumptions: parabolic terms are of the form div(f(u, grad(u))) and
# will be discretized first order form as follows:
# 1. compute grad(u)
# 2. compute f(u, grad(u))
# 3. compute div(f(u, grad(u))) (i.e., the "regular" rhs! call)
# boundary conditions will be applied to both grad(u) and div(f(u, grad(u))).
# TODO: Remove in favor of the implementation for the TreeMesh
# once the P4estMesh can handle mortars as well
function rhs_parabolic!(du, u, t, mesh::P4estMesh{3},
equations_parabolic::AbstractEquationsParabolic,
initial_condition, boundary_conditions_parabolic, source_terms,
dg::DG, parabolic_scheme, cache, cache_parabolic)
@unpack u_transformed, gradients, flux_viscous = cache_parabolic

# Convert conservative variables to a form more suitable for viscous flux calculations
@trixi_timeit timer() "transform variables" begin
transform_variables!(u_transformed, u, mesh, equations_parabolic,
dg, parabolic_scheme, cache, cache_parabolic)
end

# Compute the gradients of the transformed variables
@trixi_timeit timer() "calculate gradient" begin
calc_gradient!(gradients, u_transformed, t, mesh, equations_parabolic,
boundary_conditions_parabolic, dg, cache, cache_parabolic)
end

# Compute and store the viscous fluxes
@trixi_timeit timer() "calculate viscous fluxes" begin
calc_viscous_fluxes!(flux_viscous, gradients, u_transformed, mesh,
equations_parabolic, dg, cache, cache_parabolic)
end

# The remainder of this function is essentially a regular rhs! for parabolic
# equations (i.e., it computes the divergence of the viscous fluxes)
#
# OBS! In `calc_viscous_fluxes!`, the viscous flux values at the volume nodes of each element have
# been computed and stored in `fluxes_viscous`. In the following, we *reuse* (abuse) the
# `interfaces` and `boundaries` containers in `cache_parabolic` to interpolate and store the
# *fluxes* at the element surfaces, as opposed to interpolating and storing the *solution* (as it
# is done in the hyperbolic operator). That is, `interfaces.u`/`boundaries.u` store *viscous flux values*
# and *not the solution*. The advantage is that a) we do not need to allocate more storage, b) we
# do not need to recreate the existing data structure only with a different name, and c) we do not
# need to interpolate solutions *and* gradients to the surfaces.

# TODO: parabolic; reconsider current data structure reuse strategy

# Reset du
@trixi_timeit timer() "reset ∂u/∂t" reset_du!(du, dg, cache)

# Calculate volume integral
@trixi_timeit timer() "volume integral" begin
calc_volume_integral!(du, flux_viscous, mesh, equations_parabolic, dg, cache)
end

# Prolong solution to interfaces
@trixi_timeit timer() "prolong2interfaces" begin
prolong2interfaces!(cache_parabolic, flux_viscous, mesh, equations_parabolic,
dg.surface_integral, dg, cache)
end

# Calculate interface fluxes
@trixi_timeit timer() "interface flux" begin
calc_interface_flux!(cache_parabolic.elements.surface_flux_values, mesh,
equations_parabolic, dg, cache_parabolic)
end

# Prolong solution to boundaries
@trixi_timeit timer() "prolong2boundaries" begin
prolong2boundaries!(cache_parabolic, flux_viscous, mesh, equations_parabolic,
dg.surface_integral, dg, cache)
end

# Calculate boundary fluxes
@trixi_timeit timer() "boundary flux" begin
calc_boundary_flux_divergence!(cache_parabolic, t,
boundary_conditions_parabolic,
mesh, equations_parabolic,
dg.surface_integral, dg)
end

# TODO: parabolic; extend to mortars
@assert nmortars(dg, cache) == 0

# Calculate surface integrals
@trixi_timeit timer() "surface integral" begin
calc_surface_integral!(du, u, mesh, equations_parabolic,
dg.surface_integral, dg, cache_parabolic)
end

# Apply Jacobian from mapping to reference element
@trixi_timeit timer() "Jacobian" begin
apply_jacobian_parabolic!(du, mesh, equations_parabolic, dg, cache_parabolic)
end

return nothing
end

function calc_gradient!(gradients, u_transformed, t,
mesh::P4estMesh{3}, equations_parabolic,
boundary_conditions_parabolic, dg::DG,
Expand Down
Loading

0 comments on commit 3ca93af

Please sign in to comment.