@@ -20,7 +20,7 @@ module g_backscatter
2020 ! ___________________________________________________________________________
2121 ! allocate backscatter arrays
2222 real (kind= WP), allocatable , dimension (:,:) :: v_back
23- real (kind= WP), allocatable , dimension (:,:) :: uke, uke_back, uke_dis, uke_dif
23+ real (kind= WP), allocatable , dimension (:,:) :: uke, uke_back, uke_dis, uke_dif, uke_adv
2424 real (kind= WP), allocatable , dimension (:,:) :: uke_rhs, uke_rhs_old
2525 real (kind= WP), allocatable , dimension (:,:) :: UV_dis_posdef_b2, UV_dis_posdef, UV_back_posdef
2626 real (kind= WP), allocatable , dimension (:,:,:):: UV_back, UV_dis
@@ -31,9 +31,10 @@ module g_backscatter
3131 !
3232 ! ___________________________________________________________________________
3333 ! allocate/initialise backscatter arrays
34- subroutine init_backscatter (partit , mesh )
34+ subroutine init_backscatter (dynamics , partit , mesh )
3535 implicit none
3636 integer :: elem_size
37+ type (t_dyn) , intent (inout ), target :: dynamics
3738 type (t_mesh), intent (in ), target :: mesh
3839 type (t_partit), intent (inout ), target :: partit
3940#include " associate_part_def.h"
@@ -66,6 +67,11 @@ subroutine init_backscatter(partit, mesh)
6667 UV_back = 0.0_WP
6768 UV_back_tend = 0.0_WP
6869 UV_total_tend = 0.0_WP
70+
71+ if (dynamics% uke_advection) then
72+ allocate (uke_adv( nl-1 , elem_size))
73+ uke_adv = 0.0_WP
74+ endif
6975
7076 end subroutine init_backscatter
7177
@@ -216,6 +222,139 @@ subroutine visc_filt_dbcksc(dynamics, partit, mesh)
216222 deallocate (uuu)
217223 end subroutine visc_filt_dbcksc
218224
225+
226+ subroutine backscatter_adv (dynamics , partit , mesh )
227+ IMPLICIT NONE
228+ type (t_dyn) , intent (inout ), target :: dynamics
229+ type (t_mesh), intent (in ), target :: mesh
230+ type (t_partit), intent (inout ), target :: partit
231+ integer :: n, nz, el1, el2, ul1
232+ integer :: nl1, nl2, nod(2 ), el, ed, k, nle
233+ real (kind= WP), dimension (:,:,:), pointer :: UV
234+ real (kind= WP), dimension (:,:), pointer :: Wvel_e
235+ real (kind= WP), allocatable , dimension (:) :: contr1, contr2, wuke
236+ real (kind= WP), allocatable , dimension (:,:) :: advnode
237+ #include " associate_part_def.h"
238+ #include " associate_mesh_def.h"
239+ #include " associate_part_ass.h"
240+ #include " associate_mesh_ass.h"
241+ Wvel_e = >dynamics% w_e(:,:)
242+ UV = >dynamics% UV(:,:,:)
243+
244+ allocate (contr1(1 :nl-1 ))
245+ allocate (contr2(1 :nl-1 ))
246+ allocate (wuke(1 :nl-1 ))
247+ allocate (advnode(nl-1 , myDim_nod2d+ eDim_nod2D))
248+
249+ advnode= 0.0_WP
250+ contr1= 0.0_WP
251+ contr2= 0.0_WP
252+ wuke= 0.0_WP
253+
254+ ! vertical advection
255+ do n= 1 ,myDim_nod2d
256+ nl1 = nlevels_nod2D(n)- 1
257+
258+ ! find average of uke between vertical layers
259+ do k= 1 ,nod_in_elem2D_num(n)
260+ el = nod_in_elem2D(k,n)
261+ nle = nlevels(el)- 1
262+
263+ wuke(1 ) = wuke(1 ) + uke(1 ,el)* elem_area(el)
264+ wuke(2 :nle) = wuke(2 :nle) + 0.5_WP * (uke(2 :nle,el)+ uke(1 :nle-1 ,el))* elem_area(el)
265+
266+ end do
267+
268+ wuke(1 :nl) = wuke(1 :nl1)* Wvel_e(1 :nl1,n)
269+
270+ do nz= 1 ,nl1
271+ ! Here 1/3 because 1/3 of the area is related to the node
272+ advnode(nz,n) = - (wuke(nz) - wuke(nz+1 ) ) / (3._WP * hnode(nz,n))
273+ end do
274+
275+ advnode(nl1+1 :nl-1 ,n) = 0._WP
276+
277+ end do
278+
279+ ! horizontal advection
280+ DO ed= 1 , myDim_edge2D
281+ nod = edges(:,ed)
282+ el1 = edge_tri(1 ,ed)
283+ el2 = edge_tri(2 ,ed)
284+ nl1 = nlevels(el1)- 1
285+
286+ ! calculate fluxes throught the each edge
287+ ! for the edges that are on the boundary and have only one element
288+ contr1(1 :nl1) = UV(2 ,1 :nl1,el1)* edge_cross_dxdy(1 ,ed) - UV(1 ,1 :nl1,el1)* edge_cross_dxdy(2 ,ed)
289+
290+ ! if we have the other element as well
291+ if (el2> 0 ) then
292+ nl2 = nlevels(el2)- 1
293+
294+ contr2(1 :nl2) = - UV(2 ,1 :nl2,el2)* edge_cross_dxdy(3 ,ed) + UV(1 ,1 :nl2,el2)* edge_cross_dxdy(4 ,ed)
295+
296+ contr1(nl1+1 :max (nl1,nl2)) = 0._WP
297+ contr2(nl2+1 :max (nl1,nl2)) = 0._WP
298+
299+ if (nod(1 ) <= myDim_nod2d) then
300+ do nz= 1 , max (nl1,nl2)
301+ advnode(nz,nod(1 )) = advnode(nz,nod(1 )) + contr1(nz)* uke(nz,el1) + contr2(nz)* uke(nz,el2)
302+ end do
303+ endif
304+
305+ if (nod(2 ) <= myDim_nod2d) then
306+ do nz= 1 , max (nl1,nl2)
307+ advnode(nz,nod(2 )) = advnode(nz,nod(2 )) - contr1(nz)* uke(nz,el1) - contr2(nz)* uke(nz,el2)
308+ end do
309+ endif
310+
311+ else ! ed is a boundary edge, there is only the contribution from el1
312+ if (nod(1 ) <= myDim_nod2d) then
313+ do nz= 1 , nl1
314+ advnode(nz,nod(1 )) = advnode(nz,nod(1 )) + contr1(nz)* uke(nz,el1)
315+ end do
316+ endif
317+ ! second edge node
318+ if (nod(2 ) <= myDim_nod2d) then
319+ do nz= 1 , nl1
320+ advnode(nz,nod(2 )) = advnode(nz,nod(2 )) - contr1(nz)* uke(nz,el1)
321+ end do
322+ endif
323+ endif
324+ end do
325+
326+ ! Multiply by the segment area
327+ do n= 1 ,myDim_nod2d
328+ nl1 = nlevels_nod2D(n)- 1
329+ advnode(1 :nl1,n) = advnode(1 :nl1,n) * area_inv(1 :nl1,n)
330+ end do
331+
332+ call exchange_nod(advnode, partit)
333+
334+ ! Calculate advection as an average across the nodes
335+ do n= 1 ,myDim_nod2d
336+ nl1 = nlevels_nod2D(n)- 1
337+ advnode(1 :nl1,n) = advnode(1 :nl1,n) * areasvol_inv(1 :nl1,n)
338+ end do
339+
340+ do el= 1 , myDim_elem2D
341+ nl1 = nlevels(el)- 1
342+ uke_adv(1 :nl1,el) = uke_adv(1 :nl1,el) &
343+ + elem_area(el)* (advnode(1 :nl1,elem2D_nodes(1 ,el)) &
344+ + advnode(1 :nl1,elem2D_nodes(2 ,el)) &
345+ + advnode(1 :nl1,elem2D_nodes(3 ,el)))/ 3.0_WP
346+
347+ do nz= 1 ,nlevels(el)- 1
348+ uke_adv(nz,el)= dt* uke_adv(nz,el)/ elem_area(el)
349+ end do
350+ end do
351+
352+ deallocate (contr1)
353+ deallocate (contr2)
354+ deallocate (wuke)
355+ deallocate (advnode)
356+ end subroutine backscatter_adv
357+
219358 !
220359 !
221360 ! _______________________________________________________________________________
@@ -374,13 +513,26 @@ subroutine uke_update(dynamics, partit, mesh)
374513 uke_dis(nz,:)= uuu
375514 END DO
376515
377- DO ed= 1 , myDim_elem2D
378- DO nz= 1 ,nlevels(ed)- 1
516+ if (dynamics% uke_advection) then
517+ call backscatter_adv(dynamics, partit, mesh)
518+ call exchange_elem(uke_adv, partit)
519+
520+ DO ed= 1 , myDim_elem2D
521+ DO nz= 1 ,nlevels(ed)- 1
522+ uke_rhs_old(nz,ed)= uke_rhs(nz,ed)
523+ uke_rhs(nz,ed)=- uke_dis(nz,ed)- uke_back(nz,ed)+ uke_dif(nz,ed)- uke_adv(nz, ed)
524+ uke(nz,ed)= uke(nz,ed)+ 1.5_WP * uke_rhs(nz,ed)- 0.5_WP * uke_rhs_old(nz,ed)
525+ END DO
526+ END DO
527+ else
528+ DO ed= 1 , myDim_elem2D
529+ DO nz= 1 ,nlevels(ed)- 1
379530 uke_rhs_old(nz,ed)= uke_rhs(nz,ed)
380531 uke_rhs(nz,ed)=- uke_dis(nz,ed)- uke_back(nz,ed)+ uke_dif(nz,ed)
381532 uke(nz,ed)= uke(nz,ed)+ 1.5_WP * uke_rhs(nz,ed)- 0.5_WP * uke_rhs_old(nz,ed)
533+ END DO
382534 END DO
383- END DO
535+ end if
384536
385537 call exchange_elem(uke, partit)
386538 deallocate (uuu)
0 commit comments