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

Add AnalysisSurfaceIntegral #1812

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
99d0659
Add AnalysisSurfaceIntegral
Arpit-Babbar Jan 24, 2024
aee4cfa
Minor change
Arpit-Babbar Jan 24, 2024
9f8daef
Update elixir_euler_subsonic_cylinder.jl
Arpit-Babbar Jan 24, 2024
4054ed5
Apply suggestions from code review
Arpit-Babbar Jan 24, 2024
6b208c8
Fix labels, add tests
Arpit-Babbar Jan 24, 2024
c89e877
Attempt to fix CI
Arpit-Babbar Jan 24, 2024
5b24e2e
Obtain indices from user chosen function
Arpit-Babbar Jan 25, 2024
573ffc3
Formatting
Arpit-Babbar Jan 25, 2024
f565df6
Minor change
Arpit-Babbar Jan 24, 2024
9c0d5e1
Fix labels, add tests
Arpit-Babbar Jan 24, 2024
6de00dd
Attempt to fix CI
Arpit-Babbar Jan 24, 2024
8ada85c
Obtain indices from user chosen function
Arpit-Babbar Jan 25, 2024
a87ac8f
Add new elixirs
Arpit-Babbar Jan 25, 2024
4ac2a21
Add tests for NACA0012
Arpit-Babbar Feb 10, 2024
4d689b1
Fix tolerance, fix CI, add comments
Arpit-Babbar Feb 10, 2024
42e4b2d
Run formatter
Arpit-Babbar Feb 10, 2024
79d5eda
Minor changes
Arpit-Babbar Feb 15, 2024
809c250
Run formatter
Arpit-Babbar Feb 15, 2024
69b0f67
Fix type instability and need for a vector
Arpit-Babbar Feb 15, 2024
feab5b3
Fix typo!
Arpit-Babbar Feb 15, 2024
007bee6
Lower CFL to pass CI?
Arpit-Babbar Feb 16, 2024
1b85765
Reduce amr_interval to pass CI?
Arpit-Babbar Feb 16, 2024
dc8365c
Maybe positivity limiter will fix CI?
Arpit-Babbar Feb 16, 2024
62a57fa
Remove AMR from CI
Arpit-Babbar Feb 16, 2024
2afbc38
That CI fail was on me!
Arpit-Babbar Feb 16, 2024
881810c
Test for write permit
DanielDoehring Mar 19, 2024
d914526
forces via names
DanielDoehring Mar 19, 2024
a198ee0
Boundary Names for other examples
DanielDoehring Mar 19, 2024
45f262a
Merge branch 'main' into surface_pressure_forces
DanielDoehring Mar 19, 2024
ca9c0e8
Shift to SSPRK54 to pass CI?
Arpit-Babbar Mar 19, 2024
b2bec6f
docstrings
DanielDoehring Mar 19, 2024
92c2f68
Merge branch 'surface_pressure_forces' of https://github.com/Arpit-Ba…
DanielDoehring Mar 19, 2024
9fcbb04
alloc tests
DanielDoehring Mar 19, 2024
90ef9a8
fmt
DanielDoehring Mar 19, 2024
e3f6cbc
Apply suggestions from code review
Arpit-Babbar Mar 20, 2024
d1a3507
Format
Arpit-Babbar Mar 20, 2024
0fef9ad
non-allocating BC
DanielDoehring Mar 24, 2024
56f9fa1
Merge branch 'surface_pressure_forces' of https://github.com/Arpit-Ba…
DanielDoehring Mar 24, 2024
89f0559
comments
DanielDoehring Mar 27, 2024
e877dbc
comments
DanielDoehring Mar 27, 2024
71a5509
fmt
DanielDoehring Mar 27, 2024
fd50740
Update src/solvers/dgsem_unstructured/sort_boundary_conditions.jl
DanielDoehring Mar 27, 2024
23306b6
Update src/solvers/dgsem_unstructured/sort_boundary_conditions.jl
DanielDoehring Mar 27, 2024
e0977a9
comments
DanielDoehring Mar 27, 2024
d0a1e3e
make ready for review
DanielDoehring Mar 27, 2024
8aaab77
Merge branch 'main' into surface_pressure_forces
DanielDoehring Mar 27, 2024
ad4e995
typos
DanielDoehring Mar 27, 2024
7779eb1
Apply suggestions from code review
Arpit-Babbar Mar 28, 2024
16fc47f
Some fixes
Arpit-Babbar Mar 28, 2024
545e42a
Format
Arpit-Babbar Mar 28, 2024
d4981c3
Update NEWS.md
DanielDoehring Mar 29, 2024
7376dd4
Update src/callbacks_step/analysis_surface_integral_2d.jl
DanielDoehring Mar 29, 2024
c156876
Polish
DanielDoehring Mar 29, 2024
e76c617
Update examples/p4est_2d_dgsem/elixir_euler_NACA0012airfoil_mach085.jl
DanielDoehring Mar 29, 2024
62cc4c8
increase cfl
DanielDoehring Mar 29, 2024
815a724
fmt
DanielDoehring Mar 29, 2024
2810499
fix
DanielDoehring Mar 29, 2024
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
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ for human readability.
## Changes in the v0.7 lifecycle

#### Added
- Implementation of `TimeSeriesCallback` for curvilinear meshes on `UnstructuredMesh2D`.
- Implementation of `TimeSeriesCallback` for curvilinear meshes on `UnstructuredMesh2D` and extension
to 1D and 3D on `TreeMesh`.

- New analysis callback for 2D `P4estMesh` to compute integrated quantities along a boundary surface, e.g., pressure lift and drag coefficients.

## Changes when updating to v0.7 from v0.6.x

Expand Down
132 changes: 132 additions & 0 deletions examples/p4est_2d_dgsem/elixir_euler_NACA0012airfoil_mach085.jl
DanielDoehring marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using Downloads: download
using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the compressible Euler equations

equations = CompressibleEulerEquations2D(1.4)

p_inf() = 1.0
rho_inf() = p_inf() / (1.0 * 287.87) # p_inf = 1.0, T = 1, R = 287.87
mach_inf() = 0.85
aoa() = pi / 180.0 # 1 Degree angle of attack
c_inf(equations) = sqrt(equations.gamma * p_inf() / rho_inf())
u_inf(equations) = mach_inf() * c_inf(equations)

@inline function initial_condition_mach085_flow(x, t,
equations::CompressibleEulerEquations2D)
v1 = u_inf(equations) * cos(aoa())
v2 = u_inf(equations) * sin(aoa())

prim = SVector(rho_inf(), v1, v2, p_inf())
return prim2cons(prim, equations)
end

initial_condition = initial_condition_mach085_flow

volume_flux = flux_ranocha_turbo
surface_flux = flux_lax_friedrichs

polydeg = 3
basis = LobattoLegendreBasis(polydeg)
shock_indicator = IndicatorHennemannGassner(equations, basis,
alpha_max = 0.5,
alpha_min = 0.001,
alpha_smooth = true,
variable = density_pressure)
volume_integral = VolumeIntegralShockCapturingHG(shock_indicator;
volume_flux_dg = volume_flux,
volume_flux_fv = surface_flux)
solver = DGSEM(polydeg = polydeg, surface_flux = surface_flux,
volume_integral = volume_integral)

mesh_file = Trixi.download("https://gist.githubusercontent.com/Arpit-Babbar/339662b4b46164a016e35c81c66383bb/raw/8bf94f5b426ba907ace87405cfcc1dcc2ef7cbda/NACA0012.inp",
joinpath(@__DIR__, "NACA0012.inp"))

mesh = P4estMesh{2}(mesh_file)

# The outer boundary is constant but subsonic, so we cannot compute the
# boundary flux for the external information alone. Thus, we use the numerical flux to distinguish
# between inflow and outflow characteristics
@inline function boundary_condition_subsonic_constant(u_inner,
normal_direction::AbstractVector, x,
t,
surface_flux_function,
equations::CompressibleEulerEquations2D)
u_boundary = initial_condition_mach085_flow(x, t, equations)

return Trixi.flux_hll(u_inner, u_boundary, normal_direction, equations)
end

boundary_conditions = Dict(:Left => boundary_condition_subsonic_constant,
:Right => boundary_condition_subsonic_constant,
:Top => boundary_condition_subsonic_constant,
:Bottom => boundary_condition_subsonic_constant,
:AirfoilBottom => boundary_condition_slip_wall,
:AirfoilTop => boundary_condition_slip_wall)
DanielDoehring marked this conversation as resolved.
Show resolved Hide resolved

semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
boundary_conditions = boundary_conditions)

###############################################################################
# ODE solvers

# Run for a long time to reach a steady state
tspan = (0.0, 20.0)
ode = semidiscretize(semi, tspan)

# Callbacks

summary_callback = SummaryCallback()

analysis_interval = 2000

l_inf = 1.0 # Length of airfoil

force_boundary_names = [:AirfoilBottom, :AirfoilTop]
drag_coefficient = AnalysisSurfaceIntegral(semi, force_boundary_names,
DragCoefficientPressure(aoa(), rho_inf(),
u_inf(equations), l_inf))

lift_coefficient = AnalysisSurfaceIntegral(semi, force_boundary_names,
LiftCoefficientPressure(aoa(), rho_inf(),
u_inf(equations), l_inf))

analysis_callback = AnalysisCallback(semi, interval = analysis_interval,
output_directory = "out",
save_analysis = true,
analysis_integrals = (drag_coefficient,
lift_coefficient))

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_solution = SaveSolutionCallback(interval = 500,
save_initial_solution = true,
save_final_solution = true,
solution_variables = cons2prim)

stepsize_callback = StepsizeCallback(cfl = 1.0)

amr_indicator = IndicatorLöhner(semi, variable = Trixi.density)

amr_controller = ControllerThreeLevel(semi, amr_indicator,
base_level = 1,
med_level = 3, med_threshold = 0.05,
max_level = 4, max_threshold = 0.1)

amr_interval = 100
amr_callback = AMRCallback(semi, amr_controller,
interval = amr_interval,
adapt_initial_condition = true,
adapt_initial_condition_only_refine = true)

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

###############################################################################
# run the simulation
sol = solve(ode, SSPRK54(thread = OrdinaryDiffEq.True()),
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep = false, callback = callbacks);
summary_callback() # print the timer summary
125 changes: 125 additions & 0 deletions examples/p4est_2d_dgsem/elixir_euler_subsonic_cylinder.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using Downloads: download
using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the compressible Euler equations

equations = CompressibleEulerEquations2D(1.4)

@inline function initial_condition_mach038_flow(x, t,
equations::CompressibleEulerEquations2D)
# set the freestream flow parameters
rho_freestream = 1.4
v1 = 0.38
v2 = 0.0
p_freestream = 1.0

prim = SVector(rho_freestream, v1, v2, p_freestream)
return prim2cons(prim, equations)
end

initial_condition = initial_condition_mach038_flow

volume_flux = flux_ranocha_turbo # FluxRotated(flux_chandrashekar) can also be used
surface_flux = flux_lax_friedrichs

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

function mapping2cylinder(xi, eta)
xi_, eta_ = 0.5 * (xi + 1), 0.5 * (eta + 1.0) # Map from [-1,1] to [0,1] for simplicity

R2 = 50.0 # Bigger circle
R1 = 0.5 # Smaller circle

# Ensure an isotropic mesh by using elements with smaller radial length near the inner circle

r = R1 * exp(xi_ * log(R2 / R1))
theta = 2.0 * pi * eta_

x = r * cos(theta)
y = r * sin(theta)
return (x, y)
end

cells_per_dimension = (64, 64)
# xi = -1 maps to the inner circle and xi = +1 maps to the outer circle and we can specify boundary
# conditions there. However, the image of eta = -1, +1 coincides at the line y = 0. There is no
# physical boundary there so we specify `periodicity = true` there and the solver treats the
# element across eta = -1, +1 as neighbours which is what we want
mesh = P4estMesh(cells_per_dimension, mapping = mapping2cylinder, polydeg = polydeg,
periodicity = (false, true))

# The boundary condition on the outer cylinder is constant but subsonic, so we cannot compute the
# boundary flux from the external information alone. Thus, we use the numerical flux to distinguish
# between inflow and outflow characteristics
@inline function boundary_condition_subsonic_constant(u_inner,
normal_direction::AbstractVector, x,
t,
surface_flux_function,
equations::CompressibleEulerEquations2D)
u_boundary = initial_condition_mach038_flow(x, t, equations)

return surface_flux_function(u_inner, u_boundary, normal_direction, equations)
end

boundary_conditions = Dict(:x_neg => boundary_condition_slip_wall,
:x_pos => boundary_condition_subsonic_constant)

semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
boundary_conditions = boundary_conditions)

###############################################################################
# ODE solvers

# Run for a long time to reach a steady state
tspan = (0.0, 100.0)
ode = semidiscretize(semi, tspan)

# Callbacks

summary_callback = SummaryCallback()

analysis_interval = 2000

aoa = 0.0
rho_inf = 1.4
u_inf = 0.38
l_inf = 1.0 # Diameter of circle

drag_coefficient = AnalysisSurfaceIntegral(semi, :x_neg,
DragCoefficientPressure(aoa, rho_inf, u_inf,
l_inf))

lift_coefficient = AnalysisSurfaceIntegral(semi, :x_neg,
LiftCoefficientPressure(aoa, rho_inf, u_inf,
l_inf))

analysis_callback = AnalysisCallback(semi, interval = analysis_interval,
output_directory = "out",
save_analysis = true,
analysis_integrals = (drag_coefficient,
lift_coefficient))

alive_callback = AliveCallback(analysis_interval = analysis_interval)

save_solution = SaveSolutionCallback(interval = 500,
save_initial_solution = true,
save_final_solution = true,
solution_variables = cons2prim)

stepsize_callback = StepsizeCallback(cfl = 2.0)

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

###############################################################################
# run the simulation
sol = solve(ode,
CarpenterKennedy2N54(williamson_condition = false;
thread = OrdinaryDiffEq.True()),
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep = false, callback = callbacks);
summary_callback() # print the timer summary
Loading
Loading