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

Pointwise boundary surface values #1920

Open
wants to merge 71 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
9284b11
Add analysis_surface_2d.jl
Arpit-Babbar Apr 26, 2024
0f6ad41
Format
Arpit-Babbar Apr 26, 2024
2e79e4e
Apply suggestions from code review
DanielDoehring Apr 30, 2024
500518a
Pointwise analysis
DanielDoehring Apr 30, 2024
eb93c31
Merge branch 'main' into surface_pressure_friction
DanielDoehring Apr 30, 2024
9c1cc7a
cosmetics
DanielDoehring May 3, 2024
9e4ad12
routines similar to timeseries
DanielDoehring May 3, 2024
0fef7b4
write pointwise data to jhdf5
DanielDoehring May 5, 2024
dd426b9
fmt
DanielDoehring May 5, 2024
b29b2a9
Merge branch 'main' into surface_pressure_friction
DanielDoehring May 5, 2024
f010eab
not needed
DanielDoehring May 5, 2024
c10c3c6
rm unnecessary
DanielDoehring May 5, 2024
a281eee
re-organize
DanielDoehring May 5, 2024
178af8c
remove todo
DanielDoehring May 5, 2024
e0e7320
Merge branch 'main' into surface_pressure_friction
DanielDoehring May 6, 2024
a0abcda
Apply suggestions from code review
DanielDoehring May 7, 2024
1310ade
Sort
DanielDoehring May 8, 2024
de99163
remove prnt
DanielDoehring May 8, 2024
3ba6031
Merge branch 'surface_pressure_friction' of https://github.com/Arpit-…
DanielDoehring May 8, 2024
bda1a2b
name/symbol
DanielDoehring May 8, 2024
e939485
Merge branch 'main' into surface_pressure_friction
DanielDoehring May 8, 2024
6f8eb63
Add analysis_surface_2d.jl
Arpit-Babbar Apr 26, 2024
9c51d7f
Format
Arpit-Babbar Apr 26, 2024
022dc28
Apply suggestions from code review
DanielDoehring Apr 30, 2024
8419088
Pointwise analysis
DanielDoehring Apr 30, 2024
10cfb00
cosmetics
DanielDoehring May 3, 2024
57d2b38
routines similar to timeseries
DanielDoehring May 3, 2024
b995e3f
write pointwise data to jhdf5
DanielDoehring May 5, 2024
cb826db
fmt
DanielDoehring May 5, 2024
f39d7f3
not needed
DanielDoehring May 5, 2024
cf2fb11
rm unnecessary
DanielDoehring May 5, 2024
2bc6001
re-organize
DanielDoehring May 5, 2024
f8b2473
remove todo
DanielDoehring May 5, 2024
cd18b83
Sort
DanielDoehring May 8, 2024
bdb82f1
remove prnt
DanielDoehring May 8, 2024
5f5f464
Apply suggestions from code review
DanielDoehring May 7, 2024
db33b64
name/symbol
DanielDoehring May 8, 2024
b9021a4
Update src/callbacks_step/analysis_surface_2d.jl
DanielDoehring May 9, 2024
bac4e4d
Add test
Arpit-Babbar May 13, 2024
29d2663
Bug fix
Arpit-Babbar May 13, 2024
a7b9ec1
Accidental add fix
Arpit-Babbar May 13, 2024
efe8ddf
Apply suggestions from code review
DanielDoehring May 14, 2024
6c7657e
Merge branch 'main' into surface_pressure_friction
DanielDoehring May 14, 2024
4180757
Update examples/p4est_2d_dgsem/elixir_navierstokes_NACA0012airfoil_ma…
DanielDoehring May 21, 2024
ed3abf0
Merge branch 'main' into surface_pressure_friction
DanielDoehring May 23, 2024
9fd0b58
Merge branch 'surface_pressure_friction' of https://github.com/Arpit-…
DanielDoehring May 24, 2024
9785a83
remove sorting
DanielDoehring May 24, 2024
e25e462
Update examples/p4est_2d_dgsem/elixir_navierstokes_NACA0012airfoil_ma…
DanielDoehring May 24, 2024
f0e7047
Update src/callbacks_step/analysis.jl
DanielDoehring May 24, 2024
012680c
pointwise
DanielDoehring May 24, 2024
880674e
rename
DanielDoehring May 24, 2024
1b52899
viscous spelled out
DanielDoehring May 24, 2024
c37b203
fmt
DanielDoehring May 24, 2024
e6ad84b
Merge branch 'main' into surface_pressure_friction
DanielDoehring May 24, 2024
a7b5f8f
distinguish func and var
DanielDoehring May 24, 2024
842eaeb
fix coords
DanielDoehring May 24, 2024
0374850
fmt
DanielDoehring May 24, 2024
ce61866
Merge branch 'main' into surface_pressure_friction
DanielDoehring Jul 5, 2024
f04c1ee
update
DanielDoehring Jul 5, 2024
42afa38
correct docstring
DanielDoehring Jul 5, 2024
b9d2fcb
sort arrays
DanielDoehring Jul 5, 2024
a289eb1
mno in place
DanielDoehring Jul 5, 2024
634f60c
Use counter instead of index to avoid confusion
DanielDoehring Sep 5, 2024
d3a57ed
Comments
DanielDoehring Sep 5, 2024
5fa43da
Merge branch 'main' into surface_pressure_friction
DanielDoehring Sep 5, 2024
84f1352
Update docstring
DanielDoehring Sep 5, 2024
3c952f7
More comments
DanielDoehring Sep 5, 2024
ed971ac
fmt
DanielDoehring Sep 5, 2024
2f79a03
update test vals
DanielDoehring Sep 5, 2024
9d7231d
do not pollute `analysis.dat`
DanielDoehring Sep 5, 2024
4745ec8
Merge branch 'main' into surface_pressure_friction
DanielDoehring Oct 7, 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
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,27 @@ lift_coefficient_shear_force = AnalysisSurfaceIntegral(force_boundary_names,
u_inf(equations),
l_inf()))

friction_coefficient = AnalysisSurfacePointwise(force_boundary_names,
SurfaceFrictionCoefficient(rho_inf(),
u_inf(equations),
l_inf()))

pressure_coefficient = AnalysisSurfacePointwise(force_boundary_names,
SurfacePressureCoefficient(p_inf(),
rho_inf(),
u_inf(equations),
l_inf()))

analysis_callback = AnalysisCallback(semi, interval = analysis_interval,
output_directory = "out",
save_analysis = true,
analysis_errors = Symbol[],
analysis_integrals = (drag_coefficient,
lift_coefficient,
drag_coefficient_shear_force,
lift_coefficient_shear_force))
lift_coefficient_shear_force),
analysis_pointwise = (friction_coefficient,
pressure_coefficient))

alive_callback = AliveCallback(analysis_interval = analysis_interval)

Expand Down
6 changes: 4 additions & 2 deletions src/Trixi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,10 @@ export SummaryCallback, SteadyStateCallback, AnalysisCallback, AliveCallback,
AMRCallback, StepsizeCallback,
GlmSpeedCallback, LBMCollisionCallback, EulerAcousticsCouplingCallback,
TrivialCallback, AnalysisCallbackCoupled,
AnalysisSurfaceIntegral, DragCoefficientPressure, LiftCoefficientPressure,
DragCoefficientShearStress, LiftCoefficientShearStress
AnalysisSurfacePointwise, AnalysisSurfaceIntegral,
DragCoefficientPressure, LiftCoefficientPressure,
DragCoefficientShearStress, LiftCoefficientShearStress,
SurfacePressureCoefficient, SurfaceFrictionCoefficient

export load_mesh, load_time, load_timestep, load_timestep!, load_dt,
load_adaptive_time_integrator!
Expand Down
114 changes: 99 additions & 15 deletions src/callbacks_step/analysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
# - analysis_interval part as PeriodicCallback called after a certain amount of simulation time
"""
AnalysisCallback(semi; interval=0,
save_analysis=false,
output_directory="out",
analysis_filename="analysis.dat",
extra_analysis_errors=Symbol[],
extra_analysis_integrals=())
save_analysis=false,
output_directory="out",
analysis_filename="analysis.dat",
analysis_errors = union(default_analysis_errors(equations),
extra_analysis_errors),
extra_analysis_integrals = (),
analysis_integrals = union(default_analysis_integrals(equations),
extra_analysis_integrals),
analysis_pointwise = ())

Analyze a numerical solution every `interval` time steps and print the
results to the screen. If `save_analysis`, the results are also saved in
Expand All @@ -35,6 +39,16 @@ solution and integrated over the computational domain. Some examples for this ar
[`entropy`](@ref), [`energy_kinetic`](@ref), [`energy_internal`](@ref), and [`energy_total`](@ref).
You can also write your own function with the same signature as the examples listed above and
pass it via `extra_analysis_integrals`.
The default `analysis_integrals` is `(entropy_timederivative,)`.
You can also request `extra_analysis_integrals` such as [`LiftCoefficientPressure`](@ref) or
[`DragCoefficientPressure`](@ref) by constructing an [`AnalysisSurfaceIntegral`](@ref) with one of
the previously mentioned functions.

Similarly, pointwise, i.e., per quadrature/interpolation point, quantities such at
[`SurfacePressureCoefficient`](@ref) or [`SurfaceFrictionCoefficient`](@ref) can be computed.
Instances of these need to be passed into [`AnalysisSurfacePointwise`](@ref) which is then in turn
passed to `analysis_pointwise`.

See the developer comments about `Trixi.analyze`, `Trixi.pretty_form_utf`, and
`Trixi.pretty_form_ascii` for further information on how to create custom analysis quantities.

Expand All @@ -43,7 +57,8 @@ evaluating the computational performance, such as the total runtime, the perform
(time/DOF/rhs!), the time spent in garbage collection (GC), or the current memory usage (alloc'd
memory).
"""
mutable struct AnalysisCallback{Analyzer, AnalysisIntegrals, InitialStateIntegrals,
mutable struct AnalysisCallback{Analyzer, AnalysisIntegrals, AnalysisPointwise,
InitialStateIntegrals,
Cache}
start_time::Float64
start_time_last_analysis::Float64
Expand All @@ -56,6 +71,7 @@ mutable struct AnalysisCallback{Analyzer, AnalysisIntegrals, InitialStateIntegra
analyzer::Analyzer
analysis_errors::Vector{Symbol}
analysis_integrals::AnalysisIntegrals
analysis_pointwise::AnalysisPointwise
initial_state_integrals::InitialStateIntegrals
cache::Cache
end
Expand All @@ -80,6 +96,9 @@ function Base.show(io::IO, ::MIME"text/plain",
for (idx, integral) in enumerate(analysis_callback.analysis_integrals)
push!(setup, "│ integral " * string(idx) => integral)
end
for (idx, quantity) in enumerate(analysis_callback.analysis_pointwise)
push!(setup, "│ pointwise " * string(idx) => quantity)
end
push!(setup,
"save analysis to file" => analysis_callback.save_analysis ? "yes" : "no")
if analysis_callback.save_analysis
Expand Down Expand Up @@ -109,6 +128,7 @@ function AnalysisCallback(mesh, equations::AbstractEquations, solver, cache;
extra_analysis_integrals = (),
analysis_integrals = union(default_analysis_integrals(equations),
extra_analysis_integrals),
analysis_pointwise = (),
RealT = real(solver),
uEltype = eltype(cache.elements),
kwargs...)
Expand All @@ -130,6 +150,7 @@ function AnalysisCallback(mesh, equations::AbstractEquations, solver, cache;
analysis_filename,
analyzer,
analysis_errors, Tuple(analysis_integrals),
Tuple(analysis_pointwise),
SVector(ntuple(_ -> zero(uEltype),
Val(nvariables(equations)))),
cache_analysis)
Expand All @@ -156,7 +177,7 @@ function initialize!(cb::DiscreteCallback{Condition, Affect!}, u_ode, du_ode, t,

analysis_callback = cb.affect!
analysis_callback.initial_state_integrals = initial_state_integrals
@unpack save_analysis, output_directory, analysis_filename, analysis_errors, analysis_integrals = analysis_callback
@unpack save_analysis, output_directory, analysis_filename, analysis_errors, analysis_integrals, analysis_pointwise = analysis_callback

if save_analysis && mpi_isroot()
mkpath(output_directory)
Expand Down Expand Up @@ -200,6 +221,8 @@ function initialize!(cb::DiscreteCallback{Condition, Affect!}, u_ode, du_ode, t,
for quantity in analysis_integrals
@printf(io, " %-14s", pretty_form_ascii(quantity))
end
# Pointwise quantities are not saved in `analysis_filename`,
# i.e., `analysis.dat` but handle their own output.

println(io)
end
Expand Down Expand Up @@ -337,8 +360,8 @@ function (analysis_callback::AnalysisCallback)(u_ode, du_ode, integrator, semi)
@notimeit timer() integrator.f(du_ode, u_ode, semi, t)
u = wrap_array(u_ode, mesh, equations, solver, cache)
du = wrap_array(du_ode, mesh, equations, solver, cache)
# Compute l2_error, linf_error
analysis_callback(io, du, u, u_ode, t, semi)
# Compute l2_error, linf_error among other quantities
analysis_callback(io, du, u, u_ode, t, semi, iter)

mpi_println("─"^100)
mpi_println()
Expand All @@ -365,8 +388,8 @@ end

# This method is just called internally from `(analysis_callback::AnalysisCallback)(integrator)`
# and serves as a function barrier. Additionally, it makes the code easier to profile and optimize.
function (analysis_callback::AnalysisCallback)(io, du, u, u_ode, t, semi)
@unpack analyzer, analysis_errors, analysis_integrals = analysis_callback
function (analysis_callback::AnalysisCallback)(io, du, u, u_ode, t, semi, iter)
@unpack analyzer, analysis_errors, analysis_integrals, analysis_pointwise = analysis_callback
cache_analysis = analysis_callback.cache
_, equations, _, _ = mesh_equations_solver_cache(semi)

Expand Down Expand Up @@ -485,6 +508,8 @@ function (analysis_callback::AnalysisCallback)(io, du, u, u_ode, t, semi)

# additional integrals
analyze_integrals(analysis_integrals, io, du, u, t, semi)
# additional pointwise quantities
analyze_pointwise(analysis_pointwise, du, u, t, semi, iter)

return nothing
end
Expand Down Expand Up @@ -570,6 +595,26 @@ function analyze_integrals(analysis_integrals::Tuple{}, io, du, u, t, semi)
nothing
end

# Iterate over tuples of pointwise analysis quantities in a type-stable way using "lispy tuple programming".
function analyze_pointwise(analysis_quantities::NTuple{N, Any}, du, u, t,
semi, iter) where {N}

# Extract the first pointwise analysis quantity and process it; keep the remaining to be processed later
quantity = first(analysis_quantities)
remaining_quantities = Base.tail(analysis_quantities)

analyze(quantity, du, u, t, semi, iter)

# Recursively call this method with the unprocessed pointwise analysis quantities
analyze_pointwise(remaining_quantities, du, u, t, semi, iter)
return nothing
end

# terminate the type-stable iteration over tuples
function analyze_pointwise(analysis_quantities::Tuple{}, du, u, t, semi, iter)
nothing
end

# used for error checks and EOC analysis
function (cb::DiscreteCallback{Condition, Affect!})(sol) where {Condition,
Affect! <:
Expand All @@ -591,6 +636,13 @@ function analyze(quantity, du, u, t, semi::AbstractSemidiscretization)
mesh, equations, solver, cache = mesh_equations_solver_cache(semi)
analyze(quantity, du, u, t, mesh, equations, solver, cache)
end
# `analyze` function that passes also the iteration number `iter`along.
# Required for callbacks that handle the write-off of results to disk themselves,
# such as `AnalysisSurfacePointwise`.
function analyze(quantity, du, u, t, semi::AbstractSemidiscretization, iter)
mesh, equations, solver, cache = mesh_equations_solver_cache(semi)
analyze(quantity, du, u, t, mesh, equations, solver, cache, iter)
end
function analyze(quantity, du, u, t, mesh, equations, solver, cache)
integrate(quantity, u, mesh, equations, solver, cache, normalize = true)
end
Expand Down Expand Up @@ -654,23 +706,27 @@ end # @muladd
include("analysis_dg1d.jl")
include("analysis_dg2d.jl")
include("analysis_surface_integral_2d.jl")
include("analysis_surface_pointwise_2d.jl")
include("analysis_dg2d_parallel.jl")
include("analysis_dg3d.jl")
include("analysis_dg3d_parallel.jl")

# This version of `analyze` is used for [`AnalysisSurfaceIntegral`](@ref) which requires
# `semi` to be passed along to retrieve the current boundary indices, which are non-static
# in the case of AMR.
function analyze(quantity::AnalysisSurfaceIntegral, du, u, t,
semi::AbstractSemidiscretization)
function analyze(quantity::AnalysisSurfaceIntegral{Variable},
du, u, t,
semi::AbstractSemidiscretization) where {Variable}
mesh, equations, solver, cache = mesh_equations_solver_cache(semi)
analyze(quantity, du, u, t, mesh, equations, solver, cache, semi)
end

# Special analyze for `SemidiscretizationHyperbolicParabolic` such that
# precomputed gradients are available. Required for `enstrophy` (see above) and viscous forces.
# Note that this needs to be included after `analysis_surface_integral_2d.jl` to
# have `VariableViscous` available.
# Note that this needs to be defined after `analysis_surface_integral_2d.jl` is included
# to have `VariableViscous` available.
# We require `semi` to be passed along to retrieve the current boundary indices, which are non-static
# in the case of AMR.
function analyze(quantity::AnalysisSurfaceIntegral{Variable},
du, u, t,
semi::SemidiscretizationHyperbolicParabolic) where {
Expand All @@ -682,3 +738,31 @@ function analyze(quantity::AnalysisSurfaceIntegral{Variable},
analyze(quantity, du, u, t, mesh, equations, equations_parabolic, solver, cache, semi,
cache_parabolic)
end

# This version of `analyze` is used for `AnalysisSurfacePointwise` such as `SurfacePressureCoefficient`.
# We need the iteration number `iter` to be passed in here
# as for `AnalysisSurfacePointwise` the writing to disk is handled by the callback itself.
function analyze(quantity::AnalysisSurfacePointwise{Variable},
du, u, t,
semi::AbstractSemidiscretization,
iter) where {Variable}
mesh, equations, solver, cache = mesh_equations_solver_cache(semi)
analyze(quantity, du, u, t, mesh, equations, solver, cache, semi, iter)
end
# Special analyze for `SemidiscretizationHyperbolicParabolic` such that
# precomputed gradients are available. Required for `AnalysisSurfacePointwise` equipped
# with `VariableViscous` such as `SurfaceFrictionCoefficient`.
# As for the inviscid version, we need to pass in the iteration number `iter` as
# for `AnalysisSurfacePointwise` the writing to disk is handled by the callback itself.
function analyze(quantity::AnalysisSurfacePointwise{Variable},
du, u, t,
semi::SemidiscretizationHyperbolicParabolic,
iter) where {
Variable <:
VariableViscous}
mesh, equations, solver, cache = mesh_equations_solver_cache(semi)
equations_parabolic = semi.equations_parabolic
cache_parabolic = semi.cache_parabolic
analyze(quantity, du, u, t, mesh, equations, equations_parabolic, solver, cache, semi,
cache_parabolic, iter)
end
Loading
Loading