Path: blob/main/src/solvers/fdsbp_unstructured/containers_2d.jl
5591 views
# !!! warning "Experimental implementation (curvilinear FDSBP)"1# This is an experimental feature and may change in future releases.23# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).4# Since these FMAs can increase the performance of many numerical algorithms,5# we need to opt-in explicitly.6# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.7@muladd begin8#! format: noindent910# initialize all the values in the container of a general FD block (either straight sided or curved)11# OBS! Requires the SBP derivative matrix in order to compute metric terms.12function init_element!(elements, element, basis::AbstractDerivativeOperator,13corners_or_surface_curves)14calc_node_coordinates!(elements.node_coordinates, element, get_nodes(basis),15corners_or_surface_curves)1617calc_metric_terms!(elements.jacobian_matrix, element, basis,18elements.node_coordinates)1920calc_inverse_jacobian!(elements.inverse_jacobian, element, elements.jacobian_matrix)2122calc_contravariant_vectors!(elements.contravariant_vectors, element,23elements.jacobian_matrix)2425calc_normal_directions!(elements.normal_directions, element,26elements.jacobian_matrix)2728return elements29end3031# Specialization to pass the central differencing matrix from an upwind SBP operator32function calc_metric_terms!(jacobian_matrix, element,33D_SBP::SummationByPartsOperators.UpwindOperators,34node_coordinates)35return calc_metric_terms!(jacobian_matrix, element, D_SBP.central, node_coordinates)36end3738# construct the metric terms for a FDSBP element "block". Directly use the derivative matrix39# applied to the node coordinates.40function calc_metric_terms!(jacobian_matrix, element, D_SBP::AbstractDerivativeOperator,41node_coordinates)4243# storage format:44# jacobian_matrix[1,1,:,:,:] <- X_xi45# jacobian_matrix[1,2,:,:,:] <- X_eta46# jacobian_matrix[2,1,:,:,:] <- Y_xi47# jacobian_matrix[2,2,:,:,:] <- Y_eta4849# Compute the xi derivatives by applying D on the left50# This is basically the same as51# jacobian_matrix[1, 1, :, :, element] = Matrix(D_SBP) * node_coordinates[1, :, :, element]52# but uses only matrix-vector products instead of a matrix-matrix product.53for j in eachnode(D_SBP)54mul!(view(jacobian_matrix, 1, 1, :, j, element), D_SBP,55view(node_coordinates, 1, :, j, element))56end57# jacobian_matrix[2, 1, :, :, element] = Matrix(D_SBP) * node_coordinates[2, :, :, element]58for j in eachnode(D_SBP)59mul!(view(jacobian_matrix, 2, 1, :, j, element), D_SBP,60view(node_coordinates, 2, :, j, element))61end6263# Compute the eta derivatives by applying transpose of D on the right64# jacobian_matrix[1, 2, :, :, element] = node_coordinates[1, :, :, element] * Matrix(D_SBP)'65for i in eachnode(D_SBP)66mul!(view(jacobian_matrix, 1, 2, i, :, element), D_SBP,67view(node_coordinates, 1, i, :, element))68end69# jacobian_matrix[2, 2, :, :, element] = node_coordinates[2, :, :, element] * Matrix(D_SBP)'70for i in eachnode(D_SBP)71mul!(view(jacobian_matrix, 2, 2, i, :, element), D_SBP,72view(node_coordinates, 2, i, :, element))73end7475return jacobian_matrix76end7778# construct the normal direction vectors (but not actually normalized) for a curved sided FDSBP element "block"79# normalization occurs on the fly during the surface flux computation80# OBS! This assumes that the boundary points are included.81function calc_normal_directions!(normal_directions, element, jacobian_matrix)8283# normal directions on the boundary for the left (local side 4) and right (local side 2)84N = size(jacobian_matrix, 4)85for j in 1:N86# +x side or side 2 in the local indexing87X_xi = jacobian_matrix[1, 1, N, j, element]88X_eta = jacobian_matrix[1, 2, N, j, element]89Y_xi = jacobian_matrix[2, 1, N, j, element]90Y_eta = jacobian_matrix[2, 2, N, j, element]91Jtemp = X_xi * Y_eta - X_eta * Y_xi92normal_directions[1, j, 2, element] = sign(Jtemp) * (Y_eta)93normal_directions[2, j, 2, element] = sign(Jtemp) * (-X_eta)9495# -x side or side 4 in the local indexing96X_xi = jacobian_matrix[1, 1, 1, j, element]97X_eta = jacobian_matrix[1, 2, 1, j, element]98Y_xi = jacobian_matrix[2, 1, 1, j, element]99Y_eta = jacobian_matrix[2, 2, 1, j, element]100Jtemp = X_xi * Y_eta - X_eta * Y_xi101normal_directions[1, j, 4, element] = -sign(Jtemp) * (Y_eta)102normal_directions[2, j, 4, element] = -sign(Jtemp) * (-X_eta)103end104105# normal directions on the boundary for the top (local side 3) and bottom (local side 1)106N = size(jacobian_matrix, 3)107for i in 1:N108# -y side or side 1 in the local indexing109X_xi = jacobian_matrix[1, 1, i, 1, element]110X_eta = jacobian_matrix[1, 2, i, 1, element]111Y_xi = jacobian_matrix[2, 1, i, 1, element]112Y_eta = jacobian_matrix[2, 2, i, 1, element]113Jtemp = X_xi * Y_eta - X_eta * Y_xi114normal_directions[1, i, 1, element] = -sign(Jtemp) * (-Y_xi)115normal_directions[2, i, 1, element] = -sign(Jtemp) * (X_xi)116117# +y side or side 3 in the local indexing118X_xi = jacobian_matrix[1, 1, i, N, element]119X_eta = jacobian_matrix[1, 2, i, N, element]120Y_xi = jacobian_matrix[2, 1, i, N, element]121Y_eta = jacobian_matrix[2, 2, i, N, element]122Jtemp = X_xi * Y_eta - X_eta * Y_xi123normal_directions[1, i, 3, element] = sign(Jtemp) * (-Y_xi)124normal_directions[2, i, 3, element] = sign(Jtemp) * (X_xi)125end126127return normal_directions128end129end # @muladd130131132