-
Notifications
You must be signed in to change notification settings - Fork 115
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
Curvilinear FDSBP #1295
Closed
andrewwinters5000
wants to merge
19
commits into
trixi-framework:main
from
andrewwinters5000:curvi-fdsbp
Closed
Curvilinear FDSBP #1295
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
77cd96e
add FDSBP for curvilinear meshes
andrewwinters5000 00b0eff
new elixirs for free-stream and convergence test
andrewwinters5000 6229c85
add tests
andrewwinters5000 ef47e92
avoid allocations in init_element!
ranocha f512d03
avoid allocations in calc_surface_integral!
ranocha 5f968f7
Apply suggestions from code review
andrewwinters5000 3cf1886
add helper function to get the derivative matrix from basis
andrewwinters5000 14b1d96
increased tolerance for free stream test
ranocha 46a9866
WIP: improve performance of volume terms
ranocha e3b2772
remove allocations in volume terms
ranocha 6e6aedc
improve performance of volume terms
ranocha 674bddd
Merge branch 'main' into curvi-fdsbp
ranocha 89e97b3
Merge branch 'curvi-fdsbp' of github.com:andrewwinters5000/Trixi.jl i…
andrewwinters5000 c2d1877
fix summary output when discretization uses VolumeIntegralStrongForm
andrewwinters5000 101aa57
unify UnstructuredElement2D constructors for DGSEM and FDSBP. Removes…
andrewwinters5000 9230503
Merge branch 'main' into curvi-fdsbp
andrewwinters5000 3c2b1e6
new container type for biased metric terms. Upwind volume integral wi…
andrewwinters5000 588453e
add two tests for the upwind curvilinear solver
andrewwinters5000 c545a6b
Merge branch 'main' into curvi-fdsbp
andrewwinters5000 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
examples/unstructured_2d_fdsbp/elixir_euler_convergence.jl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
|
||
using Downloads: download | ||
using OrdinaryDiffEq | ||
using Trixi | ||
|
||
############################################################################### | ||
# semidiscretization of the compressible Euler equations | ||
|
||
equations = CompressibleEulerEquations2D(1.4) | ||
|
||
initial_condition = initial_condition_convergence_test | ||
|
||
############################################################################### | ||
# Get the FDSBP approximation operator | ||
|
||
D_SBP = derivative_operator(SummationByPartsOperators.MattssonNordström2004(), | ||
derivative_order=1, accuracy_order=4, | ||
xmin=-1.0, xmax=1.0, N=12) | ||
solver = FDSBP(D_SBP, | ||
surface_integral=SurfaceIntegralStrongForm(flux_lax_friedrichs), | ||
volume_integral=VolumeIntegralStrongForm()) | ||
|
||
############################################################################### | ||
# Get the curved quad mesh from a file (downloads the file if not available locally) | ||
|
||
default_mesh_file = joinpath(@__DIR__, "mesh_periodic_square_with_twist.mesh") | ||
isfile(default_mesh_file) || download("https://gist.githubusercontent.com/andrewwinters5000/12ce661d7c354c3d94c74b964b0f1c96/raw/8275b9a60c6e7ebbdea5fc4b4f091c47af3d5273/mesh_periodic_square_with_twist.mesh", | ||
default_mesh_file) | ||
mesh_file = default_mesh_file | ||
|
||
mesh = UnstructuredMesh2D(mesh_file, periodicity=true) | ||
|
||
############################################################################### | ||
# create the semi discretization object | ||
|
||
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, | ||
source_terms=source_terms_convergence_test) | ||
|
||
############################################################################### | ||
# ODE solvers, callbacks etc. | ||
|
||
tspan = (0.0, 1.0) | ||
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(interval=100, | ||
save_initial_solution=true, | ||
save_final_solution=true) | ||
|
||
callbacks = CallbackSet(summary_callback, analysis_callback, | ||
alive_callback, save_solution) | ||
|
||
############################################################################### | ||
# run the simulation | ||
|
||
sol = solve(ode, SSPRK43(), abstol=1.0e-9, reltol=1.0e-9, | ||
save_everystep=false, callback=callbacks) | ||
summary_callback() # print the timer summary |
111 changes: 111 additions & 0 deletions
111
examples/unstructured_2d_fdsbp/elixir_euler_convergence_upwind.jl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
|
||
using Downloads: download | ||
using OrdinaryDiffEq | ||
using Trixi | ||
|
||
############################################################################### | ||
# semidiscretization of the compressible Euler equations | ||
|
||
equations = CompressibleEulerEquations2D(1.4) | ||
|
||
# Modify the manufactured solution test to use `L = sqrt(2)` in the initial and source terms | ||
# such that testing works on the flipped mesh | ||
function initial_condition_convergence_upwind(x, t, equations::CompressibleEulerEquations2D) | ||
c = 2 | ||
A = 0.1 | ||
L = sqrt(2) | ||
f = 1/L | ||
ω = 2 * pi * f | ||
ini = c + A * sin(ω * (x[1] + x[2] - t)) | ||
|
||
rho = ini | ||
rho_v1 = ini | ||
rho_v2 = ini | ||
rho_e = ini^2 | ||
|
||
return SVector(rho, rho_v1, rho_v2, rho_e) | ||
end | ||
|
||
@inline function source_terms_convergence_upwind(u, x, t, equations::CompressibleEulerEquations2D) | ||
# Same settings as in `initial_condition` | ||
c = 2 | ||
A = 0.1 | ||
L = sqrt(2) | ||
f = 1/L | ||
ω = 2 * pi * f | ||
γ = equations.gamma | ||
|
||
x1, x2 = x | ||
si, co = sincos(ω * (x1 + x2 - t)) | ||
rho = c + A * si | ||
rho_x = ω * A * co | ||
# Note that d/dt rho = -d/dx rho = -d/dy rho. | ||
|
||
tmp = (2 * rho - 1) * (γ - 1) | ||
|
||
du1 = rho_x | ||
du2 = rho_x * (1 + tmp) | ||
du3 = du2 | ||
du4 = 2 * rho_x * (rho + tmp) | ||
|
||
return SVector(du1, du2, du3, du4) | ||
end | ||
|
||
initial_condition = initial_condition_convergence_upwind | ||
|
||
############################################################################### | ||
# Get the FDSBP approximation operator | ||
|
||
D_upw = upwind_operators(SummationByPartsOperators.Mattsson2017, | ||
derivative_order=1, | ||
accuracy_order=4, | ||
xmin=-1.0, xmax=1.0, | ||
N=10) | ||
|
||
flux_splitting = splitting_lax_friedrichs | ||
solver = FDSBP(D_upw, | ||
surface_integral=SurfaceIntegralStrongForm(FluxUpwind(flux_splitting)), | ||
volume_integral=VolumeIntegralUpwind(flux_splitting)) | ||
|
||
############################################################################### | ||
# Get the curved quad mesh from a file (downloads the file if not available locally) | ||
default_mesh_file = joinpath(@__DIR__, "mesh_multiple_flips.mesh") | ||
isfile(default_mesh_file) || download("https://gist.githubusercontent.com/andrewwinters5000/b434e724e3972a9c4ee48d58c80cdcdb/raw/9a967f066bc5bf081e77ef2519b3918e40a964ed/mesh_multiple_flips.mesh", | ||
default_mesh_file) | ||
|
||
mesh_file = default_mesh_file | ||
|
||
mesh = UnstructuredMesh2D(mesh_file, periodicity=true) | ||
|
||
############################################################################### | ||
# create the semi discretization object | ||
|
||
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, | ||
source_terms=source_terms_convergence_upwind) | ||
|
||
############################################################################### | ||
# ODE solvers, callbacks etc. | ||
|
||
tspan = (0.0, 1.0) | ||
ode = semidiscretize(semi, tspan) | ||
|
||
summary_callback = SummaryCallback() | ||
|
||
analysis_interval = 1000 | ||
analysis_callback = AnalysisCallback(semi, interval=analysis_interval) | ||
|
||
alive_callback = AliveCallback(analysis_interval=analysis_interval) | ||
|
||
save_solution = SaveSolutionCallback(interval=100, | ||
save_initial_solution=true, | ||
save_final_solution=true) | ||
|
||
callbacks = CallbackSet(summary_callback, analysis_callback, | ||
alive_callback, save_solution) | ||
|
||
############################################################################### | ||
# run the simulation | ||
|
||
sol = solve(ode, SSPRK43(), abstol=1.0e-9, reltol=1.0e-9, | ||
save_everystep=false, callback=callbacks) | ||
summary_callback() # print the timer summary |
76 changes: 76 additions & 0 deletions
76
examples/unstructured_2d_fdsbp/elixir_euler_free_stream.jl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
|
||
using Downloads: download | ||
using OrdinaryDiffEq | ||
using Trixi | ||
|
||
############################################################################### | ||
# semidiscretization of the compressible Euler equations | ||
|
||
equations = CompressibleEulerEquations2D(1.4) | ||
|
||
# Free-stream initial condition | ||
initial_condition = initial_condition_constant | ||
|
||
# Boundary conditions for free-stream testing | ||
boundary_condition_free_stream = BoundaryConditionDirichlet(initial_condition) | ||
boundary_conditions = Dict( :Body => boundary_condition_free_stream, | ||
:Button1 => boundary_condition_free_stream, | ||
:Button2 => boundary_condition_free_stream, | ||
:Eye1 => boundary_condition_free_stream, | ||
:Eye2 => boundary_condition_free_stream, | ||
:Smile => boundary_condition_free_stream, | ||
:Bowtie => boundary_condition_free_stream ) | ||
|
||
############################################################################### | ||
# Get the FDSBP approximation space | ||
|
||
D_SBP = derivative_operator(SummationByPartsOperators.MattssonNordström2004(), | ||
derivative_order=1, accuracy_order=4, | ||
xmin=-1.0, xmax=1.0, N=9) | ||
solver = FDSBP(D_SBP, | ||
surface_integral=SurfaceIntegralStrongForm(flux_hll), | ||
volume_integral=VolumeIntegralStrongForm()) | ||
|
||
############################################################################### | ||
# Get the curved quad mesh from a file (downloads the file if not available locally) | ||
|
||
default_mesh_file = joinpath(@__DIR__, "mesh_gingerbread_man.mesh") | ||
isfile(default_mesh_file) || download("https://gist.githubusercontent.com/andrewwinters5000/2c6440b5f8a57db131061ad7aa78ee2b/raw/1f89fdf2c874ff678c78afb6fe8dc784bdfd421f/mesh_gingerbread_man.mesh", | ||
default_mesh_file) | ||
mesh_file = default_mesh_file | ||
|
||
mesh = UnstructuredMesh2D(mesh_file) | ||
|
||
############################################################################### | ||
# create the semi discretization object | ||
|
||
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, | ||
boundary_conditions=boundary_conditions) | ||
|
||
############################################################################### | ||
# ODE solvers, callbacks etc. | ||
|
||
tspan = (0.0, 5.0) | ||
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(interval=100, | ||
save_initial_solution=true, | ||
save_final_solution=true) | ||
|
||
callbacks = CallbackSet(summary_callback, analysis_callback, | ||
alive_callback, save_solution) | ||
|
||
############################################################################### | ||
# run the simulation | ||
|
||
# set small tolerances for the free-stream preservation test | ||
sol = solve(ode, SSPRK43(), abstol=1.0e-12, reltol=1.0e-12, | ||
save_everystep=false, callback=callbacks) | ||
summary_callback() # print the timer summary |
78 changes: 78 additions & 0 deletions
78
examples/unstructured_2d_fdsbp/elixir_euler_free_stream_upwind.jl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
|
||
using Downloads: download | ||
using OrdinaryDiffEq | ||
using Trixi | ||
|
||
############################################################################### | ||
# semidiscretization of the compressible Euler equations | ||
|
||
equations = CompressibleEulerEquations2D(1.4) | ||
|
||
# Free-stream initial condition | ||
initial_condition = initial_condition_constant | ||
|
||
# Boundary conditions for free-stream testing | ||
boundary_condition_free_stream = BoundaryConditionDirichlet(initial_condition) | ||
|
||
boundary_conditions = Dict( :Top => boundary_condition_free_stream, | ||
:Bottom => boundary_condition_free_stream, | ||
:Right => boundary_condition_free_stream, | ||
:Left => boundary_condition_free_stream ) | ||
|
||
############################################################################### | ||
# Get the Upwind FDSBP approximation space | ||
|
||
D_upw = upwind_operators(SummationByPartsOperators.Mattsson2017, | ||
derivative_order=1, | ||
accuracy_order=4, | ||
xmin=-1.0, xmax=1.0, | ||
N=9) | ||
|
||
flux_splitting = splitting_lax_friedrichs | ||
solver = FDSBP(D_upw, | ||
surface_integral=SurfaceIntegralStrongForm(FluxUpwind(flux_splitting)), | ||
volume_integral=VolumeIntegralUpwind(flux_splitting)) | ||
|
||
############################################################################### | ||
# Get the curved quad mesh from a file (downloads the file if not available locally) | ||
default_mesh_file = joinpath(@__DIR__, "mesh_multiple_flips.mesh") | ||
isfile(default_mesh_file) || download("https://gist.githubusercontent.com/andrewwinters5000/b434e724e3972a9c4ee48d58c80cdcdb/raw/9a967f066bc5bf081e77ef2519b3918e40a964ed/mesh_multiple_flips.mesh", | ||
default_mesh_file) | ||
|
||
mesh_file = default_mesh_file | ||
|
||
mesh = UnstructuredMesh2D(mesh_file) | ||
|
||
############################################################################### | ||
# create the semi discretization object | ||
|
||
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, | ||
boundary_conditions=boundary_conditions) | ||
|
||
############################################################################### | ||
# ODE solvers, callbacks etc. | ||
|
||
tspan = (0.0, 5.0) | ||
ode = semidiscretize(semi, tspan) | ||
|
||
summary_callback = SummaryCallback() | ||
|
||
analysis_interval = 1000 | ||
analysis_callback = AnalysisCallback(semi, interval=analysis_interval) | ||
|
||
alive_callback = AliveCallback(analysis_interval=analysis_interval) | ||
|
||
save_solution = SaveSolutionCallback(interval=1000, | ||
save_initial_solution=true, | ||
save_final_solution=true) | ||
|
||
callbacks = CallbackSet(summary_callback, analysis_callback, | ||
alive_callback, save_solution) | ||
|
||
############################################################################### | ||
# run the simulation | ||
|
||
# set small tolerances for the free-stream preservation test | ||
sol = solve(ode, SSPRK43(), abstol=1.0e-12, reltol=1.0e-12, | ||
save_everystep=false, callback=callbacks) | ||
summary_callback() # print the timer summary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -780,7 +780,7 @@ end | |
rho_2gamma = 0.5 * rho / equations.gamma | ||
f1m = rho_2gamma * alpha_m | ||
f2m = rho_2gamma * alpha_m * v1 | ||
f3m = rho_2gamma * (alpha_m * v2 + a * (lambda2_m-lambda3_m)) | ||
f3m = rho_2gamma * (alpha_m * v2 + a * (lambda2_m - lambda3_m)) | ||
f4m = rho_2gamma * (alpha_m * 0.5 * (v1^2 + v2^2) + a * v2 * (lambda2_m - lambda3_m) | ||
+ a^2 * (lambda2_m + lambda3_m) * equations.inv_gamma_minus_one) | ||
end | ||
|
@@ -970,6 +970,46 @@ end | |
return SVector(f1m, f2m, f3m, f4m) | ||
end | ||
|
||
@inline function splitting_lax_friedrichs(u, ::Val{:plus}, normal_direction::AbstractVector, | ||
equations::CompressibleEulerEquations2D) | ||
rho, rho_v1, rho_v2, rho_e = u | ||
v1 = rho_v1 / rho | ||
v2 = rho_v2 / rho | ||
v_dot_n = normal_direction[1] * v1 + normal_direction[2] * v2 | ||
p = (equations.gamma - 1) * (rho_e - 0.5 * (rho_v1 * v1 + rho_v2 * v2)) | ||
|
||
a = sqrt(equations.gamma * p / rho) | ||
H = (rho_e + p) / rho | ||
lambda = 0.5 * (v_dot_n + a * norm(normal_direction)) | ||
|
||
f1p = 0.5 * rho * v_dot_n + lambda * u[1] | ||
f2p = 0.5 * rho * v_dot_n * v1 + 0.5 * p * normal_direction[1] + lambda * u[2] | ||
f3p = 0.5 * rho * v_dot_n * v2 + 0.5 * p * normal_direction[2] + lambda * u[3] | ||
f4p = 0.5 * rho * v_dot_n * H + lambda * u[4] | ||
|
||
return SVector(f1p, f2p, f3p, f4p) | ||
end | ||
Comment on lines
+974
to
+991
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not the same as rotating to x, applying the Cartesian splitting, and rotating back: julia> using Revise; using Trixi
julia> equations = CompressibleEulerEquations2D(1.4)
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ CompressibleEulerEquations2D │
│ ════════════════════════════ │
│ #variables: ………………………………………………… 4 │
│ │ variable 1: …………………………………………… rho │
│ │ variable 2: …………………………………………… rho_v1 │
│ │ variable 3: …………………………………………… rho_v2 │
│ │ variable 4: …………………………………………… rho_e │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
julia> u = SVector(1.0, 0.2, -0.3, 2.0)
4-element SVector{4, Float64} with indices SOneTo(4):
1.0
0.2
-0.3
2.0
julia> normal_direction = SVector(0.3, -0.5)
2-element SVector{2, Float64} with indices SOneTo(2):
0.3
-0.5
julia> let
norm_ = Trixi.norm(normal_direction)
normal_vector = normal_direction / norm_
u_rotated = Trixi.rotate_to_x(u, normal_vector, equations)
f = splitting_lax_friedrichs(u_rotated, Val{:plus}(), 1, equations)
f_rotated = Trixi.rotate_from_x(f, normal_vector, equations) * norm_
f_rotated - splitting_lax_friedrichs(u, Val{:plus}(), normal_direction, equations)
end
4-element SVector{4, Float64} with indices SOneTo(4):
0.00011898020814316013
2.3796041628665332e-5
-3.5694062443025754e-5
0.0002379604162865423 You mentioned some unusual behavior required for the splittings in general. Is this behavior what we want/need? |
||
|
||
@inline function splitting_lax_friedrichs(u, ::Val{:minus}, normal_direction::AbstractVector, | ||
equations::CompressibleEulerEquations2D) | ||
rho, rho_v1, rho_v2, rho_e = u | ||
v1 = rho_v1 / rho | ||
v2 = rho_v2 / rho | ||
v_dot_n = normal_direction[1] * v1 + normal_direction[2] * v2 | ||
p = (equations.gamma - 1) * (rho_e - 0.5 * (rho_v1 * v1 + rho_v2 * v2)) | ||
|
||
a = sqrt(equations.gamma * p / rho) | ||
H = (rho_e + p) / rho | ||
lambda = 0.5 * (v_dot_n + a * norm(normal_direction)) | ||
|
||
f1m = 0.5 * rho * v_dot_n - lambda * u[1] | ||
f2m = 0.5 * rho * v_dot_n * v1 + 0.5 * p * normal_direction[1] - lambda * u[2] | ||
f3m = 0.5 * rho * v_dot_n * v2 + 0.5 * p * normal_direction[2] - lambda * u[3] | ||
f4m = 0.5 * rho * v_dot_n * H - lambda * u[4] | ||
|
||
return SVector(f1m, f2m, f3m, f4m) | ||
end | ||
|
||
|
||
# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation as the | ||
# maximum velocity magnitude plus the maximum speed of sound | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to remember to update the docstring of
splitting_lax_friedrichs