From d914526786fd5f74333cc8318359580dd42fe80f Mon Sep 17 00:00:00 2001 From: Daniel_Doehring Date: Tue, 19 Mar 2024 19:02:27 +0100 Subject: [PATCH] forces via names --- .../elixir_euler_NACA0012airfoil_mach085.jl | 9 +++--- src/callbacks_step/analysis_surface_2d.jl | 30 +++++++++++-------- .../sort_boundary_conditions.jl | 14 ++++++++- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/examples/p4est_2d_dgsem/elixir_euler_NACA0012airfoil_mach085.jl b/examples/p4est_2d_dgsem/elixir_euler_NACA0012airfoil_mach085.jl index 1f9eb90f3e6..d6a38e3827a 100644 --- a/examples/p4est_2d_dgsem/elixir_euler_NACA0012airfoil_mach085.jl +++ b/examples/p4est_2d_dgsem/elixir_euler_NACA0012airfoil_mach085.jl @@ -86,18 +86,17 @@ analysis_interval = 2000 linf = 1.0 # Length of airfoil -# The boundary on which we want to compute the forces is the one where boundary conditions -# are slip wall. -drag_coefficient = AnalysisSurfaceIntegral(semi, boundary_condition_slip_wall, +force_boundary_names = [:AirfoilBottom, :AirfoilTop] +drag_coefficient = AnalysisSurfaceIntegral(semi, force_boundary_names, DragCoefficient(aoa(), rho_inf(), U_inf(equations), linf)) -lift_coefficient = AnalysisSurfaceIntegral(semi, boundary_condition_slip_wall, +lift_coefficient = AnalysisSurfaceIntegral(semi, force_boundary_names, LiftCoefficient(aoa(), rho_inf(), U_inf(equations), linf)) analysis_callback = AnalysisCallback(semi, interval = analysis_interval, - output_directory = "analysis_results", + output_directory = "out", save_analysis = true, analysis_integrals = (drag_coefficient, lift_coefficient)) diff --git a/src/callbacks_step/analysis_surface_2d.jl b/src/callbacks_step/analysis_surface_2d.jl index 8de396fd05c..715f7cb95f3 100644 --- a/src/callbacks_step/analysis_surface_2d.jl +++ b/src/callbacks_step/analysis_surface_2d.jl @@ -20,20 +20,26 @@ # parts of boundary that are of interest struct AnalysisSurfaceIntegral{Semidiscretization, Variable} semi::Semidiscretization # Semidiscretization of PDE used by the solver - boundary_index::Int # Index in boundary_condition_indices where quantity of interest is computed + indices::Vector{Int} # Indices in `boundary_condition_indices` where quantity of interest is computed variable::Variable # Quantity of interest, like lift or drag - function AnalysisSurfaceIntegral(semi, boundary_condition_type, variable) - # The bc list as ordered in digest_boundary_conditions - ordered_bc = semi.boundary_conditions.boundary_condition_types - # The set of all indices that gives the bc where the surface integral is to be computed - index = sort(findall(x -> x == boundary_condition_type, ordered_bc)) + function AnalysisSurfaceIntegral(semi, boundary_symbol, variable) + @unpack boundary_symbol_indices = semi.boundary_conditions + indices = boundary_symbol_indices[boundary_symbol] - # digest_boundary_conditions clubs all indices with same boundary conditions into - # one. This is just checking that it is indeed the case for the next step. - @assert length(index) == 1 + return new{typeof(semi), typeof(variable)}(semi, indices, + variable) + end - return new{typeof(semi), typeof(variable)}(semi, index[1], + function AnalysisSurfaceIntegral(semi, boundary_symbols::Vector{Symbol}, variable) + @unpack boundary_symbol_indices = semi.boundary_conditions + indices = Vector{Int}() + for name in boundary_symbols + append!(indices, boundary_symbol_indices[name]) + end + sort!(indices) + + return new{typeof(semi), typeof(variable)}(semi, indices, variable) end end @@ -86,9 +92,7 @@ function analyze(surface_variable::AnalysisSurfaceIntegral, du, u, t, @unpack boundaries = cache @unpack surface_flux_values, node_coordinates, contravariant_vectors = cache.elements @unpack weights = dg.basis - @unpack semi, boundary_index, variable = surface_variable - - indices = semi.boundary_conditions.boundary_indices[boundary_index] + @unpack semi, indices, variable = surface_variable surface_integral = zero(eltype(u)) index_range = eachnode(dg) diff --git a/src/solvers/dgsem_unstructured/sort_boundary_conditions.jl b/src/solvers/dgsem_unstructured/sort_boundary_conditions.jl index b5388cadc8b..5c153af2640 100644 --- a/src/solvers/dgsem_unstructured/sort_boundary_conditions.jl +++ b/src/solvers/dgsem_unstructured/sort_boundary_conditions.jl @@ -17,6 +17,7 @@ mutable struct UnstructuredSortedBoundaryTypes{N, BCs <: NTuple{N, Any}} boundary_condition_types::BCs # specific boundary condition type(s), e.g. BoundaryConditionDirichlet boundary_indices::NTuple{N, Vector{Int}} # integer vectors containing global boundary indices boundary_dictionary::Dict{Symbol, Any} # boundary conditions as set by the user in the elixir file + boundary_symbol_indices::Dict{Symbol, Vector{Int}} # integer vectors containing global boundary indices per boundary identifier end # constructor that "eats" the original boundary condition dictionary and sorts the information @@ -28,10 +29,14 @@ function UnstructuredSortedBoundaryTypes(boundary_conditions::Dict, cache) n_boundary_types = length(boundary_condition_types) boundary_indices = ntuple(_ -> [], n_boundary_types) + # Initialize `boundary_symbol_indices` as an empty dictionary, filled later in `initialize!` + boundary_symbol_indices = Dict{Symbol, Vector{Int}}() + container = UnstructuredSortedBoundaryTypes{n_boundary_types, typeof(boundary_condition_types)}(boundary_condition_types, boundary_indices, - boundary_conditions) + boundary_conditions, + boundary_symbol_indices) initialize!(container, cache) end @@ -97,6 +102,13 @@ function initialize!(boundary_types_container::UnstructuredSortedBoundaryTypes{N # convert the work array with the boundary indices into a tuple boundary_types_container.boundary_indices = Tuple(_boundary_indices) + # Store boundary indices per symbol + for (symbol, _) in boundary_dictionary + indices = findall(x -> x === symbol, cache.boundaries.name) + # Store the indices in `boundary_symbol_indices` + boundary_types_container.boundary_symbol_indices[symbol] = sort!(indices) + end + return boundary_types_container end end # @muladd