Path: blob/main/src/solvers/dgsem_unstructured/mappings_geometry_curved_2d.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: noindent67# transfinite mapping formula from a point (xi, eta) in reference space [-1,1]^2 to a point8# (x,y) in physical coordinate space for a quadrilateral element with general curved sides9# Alg. 98 from the blue book of Kopriva10function transfinite_quad_map(xi, eta, surface_curves::AbstractVector{<:CurvedSurface})1112# evaluate the gamma curves to get the four corner points of the element13x_corner1, y_corner1 = evaluate_at(-1, surface_curves[1])14x_corner2, y_corner2 = evaluate_at(1, surface_curves[1])15x_corner3, y_corner3 = evaluate_at(1, surface_curves[3])16x_corner4, y_corner4 = evaluate_at(-1, surface_curves[3])1718# evaluate along the gamma curves at a particular point (ξ, η) in computational space to get19# the value (x,y) in physical space20x1, y1 = evaluate_at(xi, surface_curves[1])21x2, y2 = evaluate_at(eta, surface_curves[2])22x3, y3 = evaluate_at(xi, surface_curves[3])23x4, y4 = evaluate_at(eta, surface_curves[4])2425x = (0.5f0 * ((1 - xi) * x4 + (1 + xi) * x2 + (1 - eta) * x1 + (1 + eta) * x3)26-270.25f0 * ((1 - xi) * ((1 - eta) * x_corner1 + (1 + eta) * x_corner4) +28(1 + xi) * ((1 - eta) * x_corner2 + (1 + eta) * x_corner3)))2930y = (0.5f0 * ((1 - xi) * y4 + (1 + xi) * y2 + (1 - eta) * y1 + (1 + eta) * y3)31-320.25f0 * ((1 - xi) * ((1 - eta) * y_corner1 + (1 + eta) * y_corner4) +33(1 + xi) * ((1 - eta) * y_corner2 + (1 + eta) * y_corner3)))3435return x, y36end3738# Compute the metric terms for the general curved sided quadrilateral transfitie mapping39# Alg. 99 from the blue book of Kopriva40function transfinite_quad_map_metrics(xi, eta,41surface_curves::AbstractVector{<:CurvedSurface})4243# evaluate the gamma curves to get the four corner points of the element44x_corner1, y_corner1 = evaluate_at(-1, surface_curves[1])45x_corner2, y_corner2 = evaluate_at(1, surface_curves[1])46x_corner3, y_corner3 = evaluate_at(1, surface_curves[3])47x_corner4, y_corner4 = evaluate_at(-1, surface_curves[3])4849# evaluate along the gamma curves at a particular point (ξ, η) in computational space to get50# the value (x,y) in physical space51x1, y1 = evaluate_at(xi, surface_curves[1])52x2, y2 = evaluate_at(eta, surface_curves[2])53x3, y3 = evaluate_at(xi, surface_curves[3])54x4, y4 = evaluate_at(eta, surface_curves[4])5556# evaluate along the derivative of the gamma curves at a particular point (ξ, η) in57# computational space to get the value (x_prime,y_prime) in physical space58x1_prime, y1_prime = derivative_at(xi, surface_curves[1])59x2_prime, y2_prime = derivative_at(eta, surface_curves[2])60x3_prime, y3_prime = derivative_at(xi, surface_curves[3])61x4_prime, y4_prime = derivative_at(eta, surface_curves[4])6263X_xi = (0.5f0 * (x2 - x4 + (1 - eta) * x1_prime + (1 + eta) * x3_prime)64-650.25f0 * ((1 - eta) * (x_corner2 - x_corner1) +66(1 + eta) * (x_corner3 - x_corner4)))6768X_eta = (0.5f0 * ((1 - xi) * x4_prime + (1 + xi) * x2_prime + x3 - x1)69-700.25f0 * ((1 - xi) * (x_corner4 - x_corner1) +71(1 + xi) * (x_corner3 - x_corner2)))7273Y_xi = (0.5f0 * (y2 - y4 + (1 - eta) * y1_prime + (1 + eta) * y3_prime)74-750.25f0 * ((1 - eta) * (y_corner2 - y_corner1) +76(1 + eta) * (y_corner3 - y_corner4)))7778Y_eta = (0.5f0 * ((1 - xi) * y4_prime + (1 + xi) * y2_prime + y3 - y1)79-800.25f0 * ((1 - xi) * (y_corner4 - y_corner1) +81(1 + xi) * (y_corner3 - y_corner2)))8283return X_xi, X_eta, Y_xi, Y_eta84end8586# construct the (x,y) node coordinates in the volume of a curved sided element87function calc_node_coordinates!(node_coordinates::AbstractArray{<:Any, 4}, element,88nodes,89surface_curves::AbstractVector{<:CurvedSurface})90for j in eachindex(nodes), i in eachindex(nodes)91node_coordinates[:, i, j, element] .= transfinite_quad_map(nodes[i], nodes[j],92surface_curves)93end9495return node_coordinates96end9798# construct the metric terms for a curved sided element99function calc_metric_terms!(jacobian_matrix, element, nodes,100surface_curves::AbstractVector{<:CurvedSurface})101102# storage format:103# jacobian_matrix[1,1,:,:,:] <- X_xi104# jacobian_matrix[1,2,:,:,:] <- X_eta105# jacobian_matrix[2,1,:,:,:] <- Y_xi106# jacobian_matrix[2,2,:,:,:] <- Y_eta107for j in eachindex(nodes), i in eachindex(nodes)108(jacobian_matrix[1, 1, i, j, element],109jacobian_matrix[1, 2, i, j, element],110jacobian_matrix[2, 1, i, j, element],111jacobian_matrix[2, 2, i, j, element]) = transfinite_quad_map_metrics(nodes[i],112nodes[j],113surface_curves)114end115116return jacobian_matrix117end118119# construct the normal direction vectors (but not actually normalized) for a curved sided element120# normalization occurs on the fly during the surface flux computation121function calc_normal_directions!(normal_directions, element, nodes,122surface_curves::AbstractVector{<:CurvedSurface})123124# normal directions on the boundary for the left (local side 4) and right (local side 2)125for j in eachindex(nodes)126# side 2127X_xi, X_eta, Y_xi, Y_eta = transfinite_quad_map_metrics(1, nodes[j],128surface_curves)129Jtemp = X_xi * Y_eta - X_eta * Y_xi130normal_directions[1, j, 2, element] = sign(Jtemp) * (Y_eta)131normal_directions[2, j, 2, element] = sign(Jtemp) * (-X_eta)132133# side 4134X_xi, X_eta, Y_xi, Y_eta = transfinite_quad_map_metrics(-1, nodes[j],135surface_curves)136Jtemp = X_xi * Y_eta - X_eta * Y_xi137normal_directions[1, j, 4, element] = -sign(Jtemp) * (Y_eta)138normal_directions[2, j, 4, element] = -sign(Jtemp) * (-X_eta)139end140141# normal directions on the boundary for the top (local side 3) and bottom (local side 1)142for i in eachindex(nodes)143# side 1144X_xi, X_eta, Y_xi, Y_eta = transfinite_quad_map_metrics(nodes[i], -1,145surface_curves)146Jtemp = X_xi * Y_eta - X_eta * Y_xi147normal_directions[1, i, 1, element] = -sign(Jtemp) * (-Y_xi)148normal_directions[2, i, 1, element] = -sign(Jtemp) * (X_xi)149150# side 3151X_xi, X_eta, Y_xi, Y_eta = transfinite_quad_map_metrics(nodes[i], 1,152surface_curves)153Jtemp = X_xi * Y_eta - X_eta * Y_xi154normal_directions[1, i, 3, element] = sign(Jtemp) * (-Y_xi)155normal_directions[2, i, 3, element] = sign(Jtemp) * (X_xi)156end157158return normal_directions159end160end # @muladd161162163