@@ -45,18 +45,15 @@ function calc_mortar_flux_low_order!(surface_flux_values,
4545 mortar_idp:: LobattoLegendreMortarIDP ,
4646 surface_integral, dg:: DG , cache)
4747 @unpack surface_flux = surface_integral
48- @unpack neighbor_ids, node_indices, u, u_large = cache. mortars
49- @unpack contravariant_vectors = cache. elements
48+ @unpack elements, mortars = cache
49+ @unpack neighbor_ids, node_indices, u_large = mortars
50+ @unpack contravariant_vectors = elements
5051 (; mortar_weights, mortar_weights_sums) = mortar_idp
5152 index_range = eachnode (dg)
5253
5354 @assert mortar_idp. local_factor " local factor should be active"
5455
5556 @threaded for mortar in eachmortar (dg, cache)
56- large_element = cache. mortars. neighbor_ids[3 , mortar]
57- upper_element = cache. mortars. neighbor_ids[2 , mortar]
58- lower_element = cache. mortars. neighbor_ids[1 , mortar]
59-
6057 # Get index information on the small elements
6158 small_indices = node_indices[1 , mortar]
6259 small_direction = indices2direction (small_indices)
@@ -72,8 +69,11 @@ function calc_mortar_flux_low_order!(surface_flux_values,
7269 j_large_start, j_large_step = index_to_start_step_2d (large_indices[2 ],
7370 index_range)
7471
75- surface_flux_values[:, :, small_direction, lower_element] .= zero (eltype (surface_flux_values))
76- surface_flux_values[:, :, small_direction, upper_element] .= zero (eltype (surface_flux_values))
72+ for small_element_index in 1 : 2
73+ small_element = neighbor_ids[small_element_index, mortar]
74+ surface_flux_values[:, :, small_direction, small_element] .= zero (eltype (surface_flux_values))
75+ end
76+ large_element = neighbor_ids[3 , mortar]
7777 surface_flux_values[:, :, large_direction, large_element] .= zero (eltype (surface_flux_values))
7878
7979 i_small = i_small_start
@@ -82,105 +82,60 @@ function calc_mortar_flux_low_order!(surface_flux_values,
8282 for i in eachnode (dg)
8383 i_mortar = iszero (i_small_step) ? j_small : i_small
8484
85- # Get the normal direction on the small element.
86- # Note, contravariant vectors at interfaces in negative coordinate direction
87- # are pointing inwards. This is handled by `get_normal_direction`.
88- normal_direction_lower = get_normal_direction (small_direction,
89- contravariant_vectors,
90- i_small, j_small,
91- lower_element)
92- normal_direction_upper = get_normal_direction (small_direction,
93- contravariant_vectors,
94- i_small, j_small,
95- upper_element)
96-
97- # Lower element
98- u_lower_local, _ = get_surface_node_vars (u, equations, dg, 1 , i, mortar)
99-
100- i_large = i_large_start
101- j_large = j_large_start
102- for j in eachnode (dg)
103- j_mortar = iszero (i_large_step) ? j_large : i_large
104-
105- factor = mortar_weights[j_mortar, i_mortar, 1 ]
106- if ! isapprox (factor, zero (typeof (factor)))
107- u_large_local = get_node_vars (u_large, equations, dg, j, mortar)
108-
109- normal_direction_large = get_normal_direction (large_direction,
110- contravariant_vectors,
111- i_large, j_large,
112- large_element)
113- # TODO : What do I do with the normal_directions? Doesn't make sense right now. See theory.
114-
115- flux = surface_flux (u_lower_local, u_large_local,
116- normal_direction_lower, equations)
117-
118- # Lower element
119- multiply_add_to_node_vars! (surface_flux_values,
120- factor /
121- mortar_weights_sums[i_mortar, 1 ],
122- flux, equations, dg,
123- i, small_direction, lower_element)
124- # Large element
125- # The flux is calculated in the outward direction of the small elements,
126- # so the sign must be switched to get the flux in outward direction
127- # of the large element.
128- # The contravariant vectors of the large element (and therefore the normal
129- # vectors of the large element as well) are twice as large as the
130- # contravariant vectors of the small elements. Therefore, the flux needs
131- # to be scaled by a factor of 2 to obtain the flux of the large element.
132- multiply_add_to_node_vars! (surface_flux_values,
133- - 2 * factor /
134- mortar_weights_sums[j_mortar, 2 ],
135- flux, equations, dg,
136- j, large_direction, large_element)
137- end
138- i_large += i_large_step
139- j_large += j_large_step
140- end
141-
142- # Upper element
143- u_upper_local, _ = get_surface_node_vars (u, equations, dg, 2 , i, mortar)
144-
145- i_large = i_large_start
146- j_large = j_large_start
147- for j in eachnode (dg)
148- j_mortar = iszero (i_large_step) ? j_large : i_large
149-
150- factor = mortar_weights[j_mortar, i_mortar, 2 ]
151- if ! isapprox (factor, zero (typeof (factor)))
152- u_large_local = get_node_vars (u_large, equations, dg, j, mortar)
153-
154- normal_direction_large = get_normal_direction (large_direction,
155- contravariant_vectors,
156- i_large, j_large,
157- large_element)
158-
159- flux = surface_flux (u_upper_local, u_large_local,
160- normal_direction_upper, equations)
161-
162- # Upper element
163- multiply_add_to_node_vars! (surface_flux_values,
164- factor /
165- mortar_weights_sums[i_mortar, 1 ],
166- flux, equations, dg,
167- i, small_direction, upper_element)
168- # Large element
169- # The flux is calculated in the outward direction of the small elements,
170- # so the sign must be switched to get the flux in outward direction
171- # of the large element.
172- # The contravariant vectors of the large element (and therefore the normal
173- # vectors of the large element as well) are twice as large as the
174- # contravariant vectors of the small elements. Therefore, the flux needs
175- # to be scaled by a factor of 2 to obtain the flux of the large element.
176- multiply_add_to_node_vars! (surface_flux_values,
177- - 2 * factor /
178- mortar_weights_sums[j_mortar, 2 ],
179- flux, equations, dg,
180- j, large_direction, large_element)
85+ for small_element_index in 1 : 2
86+ small_element = neighbor_ids[small_element_index, mortar]
87+ u_small_local, _ = get_surface_node_vars (mortars. u, equations, dg,
88+ small_element_index, i, mortar)
89+
90+ # Get the normal direction on the small element.
91+ # Note, contravariant vectors at interfaces in negative coordinate direction
92+ # are pointing inwards. This is handled by `get_normal_direction`.
93+ normal_direction_small = get_normal_direction (small_direction,
94+ contravariant_vectors,
95+ i_small, j_small,
96+ small_element)
97+
98+ i_large = i_large_start
99+ j_large = j_large_start
100+ for j in eachnode (dg)
101+ j_mortar = iszero (i_large_step) ? j_large : i_large
102+
103+ factor = mortar_weights[j_mortar, i_mortar, small_element_index]
104+ if ! isapprox (factor, zero (typeof (factor)))
105+ u_large_local = get_node_vars (u_large, equations, dg, j, mortar)
106+
107+ normal_direction_large = get_normal_direction (large_direction,
108+ contravariant_vectors,
109+ i_large, j_large,
110+ large_element)
111+ # TODO : What do I do with the normal_directions? Doesn't make sense right now. See theory.
112+
113+ flux = surface_flux (u_small_local, u_large_local,
114+ normal_direction_small, equations)
115+
116+ # Add flux to small element
117+ multiply_add_to_node_vars! (surface_flux_values,
118+ factor /
119+ mortar_weights_sums[i_mortar, 1 ],
120+ flux, equations, dg,
121+ i, small_direction, small_element)
122+ # Add flux to large element
123+ # The flux is calculated in the outward direction of the small elements,
124+ # so the sign must be switched to get the flux in outward direction
125+ # of the large element.
126+ # The contravariant vectors of the large element (and therefore the normal
127+ # vectors of the large element as well) are twice as large as the
128+ # contravariant vectors of the small elements. Therefore, the flux needs
129+ # to be scaled by a factor of 2 to obtain the flux of the large element.
130+ multiply_add_to_node_vars! (surface_flux_values,
131+ - 2 * factor /
132+ mortar_weights_sums[j_mortar, 2 ],
133+ flux, equations, dg,
134+ j, large_direction, large_element)
135+ end
136+ i_large += i_large_step
137+ j_large += j_large_step
181138 end
182- i_large += i_large_step
183- j_large += j_large_step
184139 end
185140 i_small += i_small_step
186141 j_small += j_small_step
0 commit comments