Path: blob/main/src/solvers/dgmulti/volume_integral_adaptive.jl
5591 views
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).1# Since these FMAs can increase the performance of many numerical algorithms,2# we need to opt-in explicitly.3# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.4@muladd begin5#! format: noindent67function create_cache(mesh::DGMultiMesh, equations,8dg::DGMulti{NDIMS, ElemType, <:Polynomial,9<:SurfaceIntegralWeakForm,10<:VolumeIntegralAdaptive{<:IndicatorEntropyChange,11<:VolumeIntegralWeakForm,12<:VolumeIntegralFluxDifferencing}},13RealT, uEltype) where {NDIMS, ElemType}14# Construct temporary solvers for each sub-integral to reuse the `create_cache` functions1516# `VolumeIntegralAdaptive` for `DGMulti` currently limited to Weak Form & Flux Differencing combi17dg_WF = DG(dg.basis, dg.mortar, dg.surface_integral,18dg.volume_integral.volume_integral_default)19dg_FD = DG(dg.basis, dg.mortar, dg.surface_integral,20dg.volume_integral.volume_integral_stabilized)2122cache_WF = create_cache(mesh, equations, dg_WF, RealT, uEltype)23cache_FD = create_cache(mesh, equations, dg_FD, RealT, uEltype)2425# Set up structures required for `IndicatorEntropyChange`26rd = dg.basis27nvars = nvariables(equations)2829# Required for entropy change computation (`entropy_change_reference_element`)30du_values = similar(cache_FD.solution_container.u_values)3132# Thread-local buffer for face interpolation, which is required33# for computation of entropy potential at interpolated face nodes34# (`surface_integral_reference_element`)35u_face_local_threaded = [allocate_nested_array(uEltype, nvars, (rd.Nfq,), dg)36for _ in 1:Threads.maxthreadid()]3738return (; cache_FD...,39# Weak-form-specific fields for the default volume integral40weak_differentiation_matrices = cache_WF.weak_differentiation_matrices,41flux_threaded = cache_WF.flux_threaded,42rotated_flux_threaded = cache_WF.rotated_flux_threaded, # For non-affine meshes43# Required for `IndicatorEntropyChange`44du_values, u_face_local_threaded)45end4647# version for affine meshes (currently only supported one for `VolumeIntegralAdaptive`)48function calc_volume_integral!(du, u, mesh::DGMultiMesh,49have_nonconservative_terms::False, equations,50volume_integral::VolumeIntegralAdaptive{<:IndicatorEntropyChange},51dg::DGMultiFluxDiff, cache)52@unpack volume_integral_default, volume_integral_stabilized = volume_integral53@unpack maximum_entropy_increase = volume_integral.indicator5455# For weak form integral56@unpack u_values = cache.solution_container5758# For entropy production computation59rd = dg.basis60@unpack du_values = cache6162# interpolate to quadrature points63apply_to_each_field(mul_by!(rd.Vq), u_values, u) # required for weak form trial6465@threaded for e in eachelement(dg, cache)66# Try default volume integral first67volume_integral_kernel!(du, u, e, mesh,68have_nonconservative_terms, equations,69volume_integral_default, dg, cache)7071# Interpolate `du` to quadrature points after WF integral for entropy production calculation72du_local = view(du, :, e)73du_values_local = view(du_values, :, e)74apply_to_each_field(mul_by!(rd.Vq), du_values_local, du_local) # required for entropy production calculation7576# Compute entropy production of this volume integral77u_values_local = view(u_values, :, e)78dS_WF = -entropy_change_reference_element(du_values_local, u_values_local,79mesh, equations,80dg, cache)8182dS_true = surface_integral_reference_element(entropy_potential, u, e,83mesh, equations, dg, cache)8485entropy_change = dS_WF - dS_true86if entropy_change > maximum_entropy_increase # Recompute using EC FD volume integral87# Reset default volume integral contribution.88# Note that this assumes that the volume terms are computed first,89# before any surface terms are added.90fill!(du_local, zero(eltype(du_local)))9192# Recompute using stabilized volume integral. Note that the calculation of this volume integral requires the calculation of the entropy projection, which is done in `rhs!` specialized on the `DGMultiFluxDiff` solver type.93volume_integral_kernel!(du, u, e, mesh,94have_nonconservative_terms, equations,95volume_integral_stabilized, dg, cache)96end97end9899return nothing100end101end # @muladd102103104