Path: blob/main/src/solvers/dgsem_structured/dg_1d.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 prolong2interfaces!(cache, u, mesh::StructuredMesh{1}, equations, dg::DG)8@unpack interfaces_u = cache.elements910@threaded for element in eachelement(dg, cache)11# Negative side (direction 1, left/negative x face)12for v in eachvariable(equations)13interfaces_u[v, 1, element] = u[v, 1, element]14end15# Positive side (direction 2, right/positive x face)16for v in eachvariable(equations)17interfaces_u[v, 2, element] = u[v, nnodes(dg), element]18end19end2021return nothing22end2324function prolong2interfaces!(cache, u, mesh::StructuredMesh{1}, equations,25dg::DGSEM{<:GaussLegendreBasis})26@unpack interfaces_u = cache.elements27@unpack boundary_interpolation = dg.basis2829@threaded for element in eachelement(dg, cache)30for v in eachvariable(equations)31interface_u_1 = zero(eltype(interfaces_u))32interface_u_2 = zero(eltype(interfaces_u))33for i in eachnode(dg)34# Left/negative x face35interface_u_1 = interface_u_1 +36u[v, i, element] * boundary_interpolation[i, 1]3738# Right/positive x face39interface_u_2 = interface_u_2 +40u[v, i, element] * boundary_interpolation[i, 2]41end42interfaces_u[v, 1, element] = interface_u_143interfaces_u[v, 2, element] = interface_u_244end45end4647return nothing48end4950function calc_interface_flux!(surface_flux_values, mesh::StructuredMesh{1},51nonconservative_terms, # can be True/False52equations, surface_integral, dg::DG, cache)53@unpack surface_flux = surface_integral54@unpack interfaces_u = cache.elements5556@threaded for element in eachelement(dg, cache)57left_element = cache.elements.left_neighbors[1, element]58# => `element` is the right element of the interface5960if left_element > 0 # left_element = 0 at boundaries61u_ll = get_node_vars(interfaces_u, equations, dg, 2, left_element)62u_rr = get_node_vars(interfaces_u, equations, dg, 1, element)6364f1 = surface_flux(u_ll, u_rr, 1, equations)6566for v in eachvariable(equations)67surface_flux_values[v, 2, left_element] = f1[v]68surface_flux_values[v, 1, element] = f1[v]69end70end71end7273return nothing74end7576function calc_boundary_flux!(cache, t, boundary_conditions::NamedTuple,77mesh::StructuredMesh{1}, equations, surface_integral,78dg::DG)79@unpack surface_flux = surface_integral80@unpack surface_flux_values, boundary_node_coordinates, interfaces_u = cache.elements81# Boundary values are for `StructuredMesh` stored in the interface datastructure82boundaries_u = interfaces_u8384orientation = 18586# Negative x-direction87direction = 18889u_rr = get_node_vars(boundaries_u, equations, dg, direction, 1)90x = get_node_coords(boundary_node_coordinates, equations, dg, direction)9192flux = boundary_conditions[direction](u_rr, orientation, direction, x, t,93surface_flux, equations)9495# Only flux contribution for left element, left face is the boundary flux96for v in eachvariable(equations)97surface_flux_values[v, direction, 1] = flux[v]98end99100# Positive x-direction101direction = 2102103u_rr = get_node_vars(boundaries_u, equations, dg, direction, nelements(dg, cache))104x = get_node_coords(boundary_node_coordinates, equations, dg, direction)105106flux = boundary_conditions[direction](u_rr, orientation, direction, x, t,107surface_flux, equations)108109# Only flux contribution for right element, right face is the boundary flux110for v in eachvariable(equations)111surface_flux_values[v, direction, nelements(dg, cache)] = flux[v]112end113114return nothing115end116117function apply_jacobian!(backend::Nothing, du, mesh::StructuredMesh{1},118equations, dg::DG, cache)119@unpack inverse_jacobian = cache.elements120121@threaded for element in eachelement(dg, cache)122for i in eachnode(dg)123# Negative sign included to account for the negated surface and volume terms,124# see e.g. the computation of `derivative_hat` in the basis setup and125# the comment in `calc_surface_integral!`.126factor = -inverse_jacobian[i, element]127128for v in eachvariable(equations)129du[v, i, element] *= factor130end131end132end133134return nothing135end136end # @muladd137138139