@@ -84,4 +84,128 @@ function perform_idp_correction!(u, dt,
8484
8585 return nothing
8686end
87+
88+ function perform_idp_mortar_correction (u, dt, mesh:: TreeMesh{3} , equations, dg, cache)
89+ (; orientations, limiting_factor) = cache. mortars
90+
91+ (; surface_flux_values) = cache. elements
92+ (; surface_flux_values_high_order) = cache. antidiffusive_fluxes
93+ (; boundary_interpolation) = dg. basis
94+
95+ for mortar in eachmortar (dg, cache)
96+ if isapprox (limiting_factor[mortar], one (eltype (limiting_factor)))
97+ continue
98+ end
99+
100+ if cache. mortars. large_sides[mortar] == 1 # -> small elements on right side
101+ if orientations[mortar] == 1
102+ direction_small = 1
103+ direction_large = 2
104+ elseif orientations[mortar] == 2
105+ direction_small = 3
106+ direction_large = 4
107+ else # orientations[mortar] == 3
108+ direction_small = 5
109+ direction_large = 6
110+ end
111+ # In `apply_jacobian`, `du` is multiplied with inverse jacobian and a negative sign.
112+ # This sign switch is directly applied to the boundary interpolation factors here.
113+ factor_small = boundary_interpolation[1 , 1 ]
114+ factor_large = - boundary_interpolation[nnodes (dg), 2 ]
115+ else # large_sides[mortar] == 2 -> small elements on left side
116+ if orientations[mortar] == 1
117+ direction_small = 2
118+ direction_large = 1
119+ elseif orientations[mortar] == 2
120+ direction_small = 4
121+ direction_large = 3
122+ else # orientations[mortar] == 3
123+ direction_small = 6
124+ direction_large = 5
125+ end
126+ # In `apply_jacobian`, `du` is multiplied with inverse jacobian and a negative sign.
127+ # This sign switch is directly applied to the boundary interpolation factors here.
128+ factor_large = boundary_interpolation[1 , 1 ]
129+ factor_small = - boundary_interpolation[nnodes (dg), 2 ]
130+ end
131+
132+ for j in eachnode (dg), i in eachnode (dg)
133+ if cache. mortars. large_sides[mortar] == 1 # -> small elements on right side
134+ if orientations[mortar] == 1
135+ # L2 mortars in x-direction
136+ indices_small = (1 , i, j)
137+ indices_large = (nnodes (dg), i, j)
138+ elseif orientations[mortar] == 2
139+ # L2 mortars in y-direction
140+ indices_small = (i, 1 , j)
141+ indices_large = (i, nnodes (dg), j)
142+ else # orientations[mortar] == 3
143+ # L2 mortars in z-direction
144+ indices_small = (i, j, 1 )
145+ indices_large = (i, j, nnodes (dg))
146+ end
147+ else # large_sides[mortar] == 2 -> small elements on left side
148+ if orientations[mortar] == 1
149+ # L2 mortars in x-direction
150+ indices_small = (nnodes (dg), i, j)
151+ indices_large = (1 , i, j)
152+ elseif orientations[mortar] == 2
153+ # L2 mortars in y-direction
154+ indices_small = (i, nnodes (dg), j)
155+ indices_large = (i, 1 , j)
156+ else # orientations[mortar] == 3
157+ # L2 mortars in z-direction
158+ indices_small = (i, j, nnodes (dg))
159+ indices_large = (i, j, 1 )
160+ end
161+ end
162+
163+ # small elements
164+ for small_element_index in 1 : 4
165+ small_element = cache. mortars. neighbor_ids[small_element_index, mortar]
166+ inverse_jacobian_small = get_inverse_jacobian (cache. elements. inverse_jacobian,
167+ mesh, indices_small... ,
168+ small_element)
169+
170+ flux_small_high_order = get_node_vars (surface_flux_values_high_order,
171+ equations, dg,
172+ i, j, direction_small,
173+ small_element)
174+ flux_small_low_order = get_node_vars (surface_flux_values, equations, dg,
175+ i, j, direction_small,
176+ small_element)
177+ flux_difference_small = factor_small *
178+ (flux_small_high_order .- flux_small_low_order)
179+
180+ multiply_add_to_node_vars! (u,
181+ dt * inverse_jacobian_small *
182+ (1 - limiting_factor[mortar]),
183+ flux_difference_small, equations, dg,
184+ indices_small... , small_element)
185+ end
186+
187+ # large element
188+ large_element = cache. mortars. neighbor_ids[5 , mortar]
189+ inverse_jacobian_large = get_inverse_jacobian (cache. elements. inverse_jacobian,
190+ mesh, indices_large... ,
191+ large_element)
192+
193+ flux_large_high_order = get_node_vars (surface_flux_values_high_order,
194+ equations, dg, i, j, direction_large,
195+ large_element)
196+ flux_large_low_order = get_node_vars (surface_flux_values, equations, dg,
197+ i, j, direction_large, large_element)
198+ flux_difference_large = factor_large *
199+ (flux_large_high_order .- flux_large_low_order)
200+
201+ multiply_add_to_node_vars! (u,
202+ dt * inverse_jacobian_large *
203+ (1 - limiting_factor[mortar]),
204+ flux_difference_large, equations, dg,
205+ indices_large... , large_element)
206+ end
207+ end
208+
209+ return nothing
210+ end
87211end # @muladd
0 commit comments