source: codes/icosagcm/devel/src/diagnostics/compute_velocity.F90 @ 977

Last change on this file since 977 was 914, checked in by dubos, 5 years ago

devel : moved diagnostics of temperature and velocity into separate modules

File size: 3.5 KB
Line 
1MODULE compute_velocity_mod
2  USE icosa
3  USE caldyn_vars_mod
4  IMPLICIT NONE
5  PRIVATE
6
7  PUBLIC :: velocity
8
9CONTAINS
10 
11 !------------------- Conversion from momentum to horizontal velocity  ------------------
12
13  SUBROUTINE velocity(f_geopot, f_ps, f_rhodz, f_u, f_W, f_buf_Fel, f_uh, f_uz)
14    USE disvert_mod, ONLY : caldyn_eta, eta_mass
15    USE compute_diagnostics_mod, ONLY : compute_rhodz
16    TYPE(t_field), POINTER :: f_geopot(:), f_ps(:), f_rhodz(:), &
17         f_u(:), f_W(:),    &  ! IN
18         f_buf_Fel(:), &          ! BUF
19         f_uh(:), f_uz(:)      ! OUT
20    REAL(rstd),POINTER :: geopot(:,:), ps(:), rhodz(:,:), u(:,:), W(:,:), uh(:,:), uz(:,:), F_el(:,:)
21    INTEGER :: ind
22   
23    DO ind=1,ndomain
24       IF (.NOT. assigned_domain(ind)) CYCLE
25       CALL swap_dimensions(ind)
26       CALL swap_geometry(ind)
27       geopot = f_geopot(ind)
28       rhodz = f_rhodz(ind)
29       u = f_u(ind)
30       W = f_W(ind)
31       uh  = f_uh(ind)
32       F_el  = f_buf_Fel(ind)
33       IF(caldyn_eta==eta_mass) THEN
34          ps=f_ps(ind)
35          CALL compute_rhodz(.TRUE., ps, rhodz)
36       END IF
37       uz = f_uz(ind)
38       !$OMP BARRIER
39       CALL compute_velocity(geopot,rhodz,u,W, F_el, uh,uz)
40       !$OMP BARRIER
41    END DO
42  END SUBROUTINE velocity
43 
44  SUBROUTINE compute_velocity(Phi, rhodz, u, W, F_el, uh, uz)
45    USE omp_para
46    REAL(rstd), INTENT(IN) :: Phi(iim*jjm,llm+1)
47    REAL(rstd), INTENT(IN) :: rhodz(iim*jjm,llm)
48    REAL(rstd), INTENT(IN) :: u(3*iim*jjm,llm)
49    REAL(rstd), INTENT(IN) :: W(iim*jjm,llm+1)
50    REAL(rstd), INTENT(OUT) :: uh(3*iim*jjm,llm)
51    REAL(rstd), INTENT(OUT) :: uz(iim*jjm,llm)
52    INTEGER :: ij,l
53    REAL(rstd) :: F_el(3*iim*jjm,llm+1)
54    REAL(rstd) :: uu_right, uu_lup, uu_ldown, W_el, DePhil
55    ! NB : u and uh are not in DEC form, they are normal components   
56    ! => we must divide by de
57    IF(hydrostatic) THEN
58       uh(:,:)=u(:,:)
59       uz(:,:)=0.
60    ELSE
61       DO l=ll_begin, ll_endp1 ! compute on l levels (interfaces)
62          DO ij=ij_begin_ext, ij_end_ext
63             ! Compute on edge 'right'
64             W_el   = .5*( W(ij,l)+W(ij+t_right,l) )
65             DePhil = ne_right*(Phi(ij+t_right,l)-Phi(ij,l))
66             F_el(ij+u_right,l)   = DePhil*W_el/de(ij+u_right)
67             ! Compute on edge 'lup'
68             W_el   = .5*( W(ij,l)+W(ij+t_lup,l) )
69             DePhil = ne_lup*(Phi(ij+t_lup,l)-Phi(ij,l))
70             F_el(ij+u_lup,l)   = DePhil*W_el/de(ij+u_lup)
71             ! Compute on edge 'ldown'
72             W_el   = .5*( W(ij,l)+W(ij+t_ldown,l) )
73             DePhil = ne_ldown*(Phi(ij+t_ldown,l)-Phi(ij,l))
74             F_el(ij+u_ldown,l) = DePhil*W_el/de(ij+u_ldown)
75          END DO
76       END DO
77
78       ! We need a barrier here because we compute F_el above and do a vertical average below
79       !$OMP BARRIER
80
81       DO l=ll_begin, ll_end ! compute on k levels (full levels)
82          DO ij=ij_begin_ext, ij_end_ext
83             ! w = vertical momentum = g^-2*dPhi/dt = uz/g
84             uz(ij,l) = (.5*g)*(W(ij,l)+W(ij,l+1))/rhodz(ij,l)
85             ! uh = u-w.grad(Phi) = u - uz.grad(z)
86             uh(ij+u_right,l) = u(ij+u_right,l) - (F_el(ij+u_right,l)+F_el(ij+u_right,l+1)) / (rhodz(ij,l)+rhodz(ij+t_right,l))
87             uh(ij+u_lup,l)   = u(ij+u_lup,l)   - (F_el(ij+u_lup,l)+F_el(ij+u_lup,l+1))     / (rhodz(ij,l)+rhodz(ij+t_lup,l))
88             uh(ij+u_ldown,l) = u(ij+u_ldown,l) - (F_el(ij+u_ldown,l)+F_el(ij+u_ldown,l+1)) / (rhodz(ij,l)+rhodz(ij+t_ldown,l))
89          END DO
90       END DO
91
92    END IF
93  END SUBROUTINE compute_velocity
94
95END MODULE compute_velocity_mod
Note: See TracBrowser for help on using the repository browser.