source: codes/icosagcm/trunk/src/diagnostics/omega.f90 @ 581

Last change on this file since 581 was 548, checked in by dubos, 7 years ago

trunk : reorganize source tree

File size: 5.0 KB
Line 
1MODULE omega_mod
2
3  USE icosa
4  PRIVATE
5
6  PUBLIC :: w_omega, compute_omega
7
8CONTAINS
9
10  SUBROUTINE w_omega(f_ps, f_u, f_omega) ! Compute omega = Dp/Dt
11    TYPE(t_field),POINTER :: f_ps(:), f_u(:), f_omega(:)
12    INTEGER :: ind
13    REAL(rstd),POINTER :: ps(:), u(:,:), om(:,:)
14    DO ind=1,ndomain
15       IF (.NOT. assigned_domain(ind)) CYCLE
16       CALL swap_dimensions(ind)
17       CALL swap_geometry(ind)
18       ps=f_ps(ind)
19       u=f_u(ind)
20       om=f_omega(ind)
21       CALL compute_omega(ps,u,om)
22    END DO
23  END SUBROUTINE W_omega
24
25
26
27  SUBROUTINE compute_omega(ps,u, w)
28    USE disvert_mod, ONLY : ap,bp
29    USE omp_para
30    IMPLICIT NONE
31    REAL(rstd),INTENT(IN) :: u(iim*3*jjm,llm), ps(iim*jjm)
32    REAL(rstd),INTENT(OUT):: w(iim*jjm,llm)
33    REAL(rstd):: convm(iim*jjm,llm+1)
34    REAL(rstd):: p(iim*jjm,llm+1), rhodz(iim*jjm,llm), Fe(iim*3*jjm,llm)
35    REAL(rstd):: ugradps
36   
37    INTEGER :: i,j,l,ij
38
39!$OMP BARRIER   
40    IF (is_omp_level_master) THEN
41      DO    l    = 1, llm+1
42         DO j=jj_begin-1,jj_end+1
43           DO i=ii_begin-1,ii_end+1
44               ij=(j-1)*iim+i
45               p(ij,l) = ap(l) + bp(l) * ps(ij)
46            ENDDO
47         ENDDO
48      ENDDO
49   
50!!! Compute mass
51      DO l = 1, llm
52         DO j=jj_begin-1,jj_end+1
53            DO i=ii_begin-1,ii_end+1
54               ij=(j-1)*iim+i
55               rhodz(ij,l) = ( p(ij,l) - p(ij,l+1) ) / g
56            ENDDO
57         ENDDO
58      ENDDO
59   
60!!!  Compute mass flux
61      DO l = 1, llm
62         DO j=jj_begin-1,jj_end+1
63            DO i=ii_begin-1,ii_end+1
64               ij=(j-1)*iim+i
65               Fe(ij+u_right,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_right,l))*u(ij+u_right,l)*le(ij+u_right)
66               Fe(ij+u_lup,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_lup,l))*u(ij+u_lup,l)*le(ij+u_lup)
67               Fe(ij+u_ldown,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_ldown,l))*u(ij+u_ldown,l)*le(ij+u_ldown)
68            ENDDO
69         ENDDO
70      ENDDO
71   
72!!! mass flux convergence computation 
73   
74    ! horizontal convergence
75      DO l = 1, llm
76         DO j=jj_begin,jj_end
77            DO i=ii_begin,ii_end
78               ij=(j-1)*iim+i
79               ! convm = +div(mass flux), sign convention as in Ringler et al. 2012, eq. 21
80               convm(ij,l)= 1./Ai(ij)*(ne(ij,right)*Fe(ij+u_right,l)   +  &
81                    ne(ij,rup)*Fe(ij+u_rup,l)       +  & 
82                    ne(ij,lup)*Fe(ij+u_lup,l)       +  & 
83                    ne(ij,left)*Fe(ij+u_left,l)     +  & 
84                    ne(ij,ldown)*Fe(ij+u_ldown,l)   +  & 
85                    ne(ij,rdown)*Fe(ij+u_rdown,l))
86            ENDDO
87         ENDDO
88      ENDDO
89   
90      ! vertical integration from up to down
91      DO  l = llm-1, 1, -1
92         DO j=jj_begin,jj_end
93            DO i=ii_begin,ii_end
94               ij=(j-1)*iim+i
95               convm(ij,l) = convm(ij,l) + convm(ij,l+1)
96            ENDDO
97         ENDDO
98      ENDDO
99      convm(:,llm+1)=0.
100
101!!! Compute dps
102    !  DO j=jj_begin,jj_end
103    !    DO i=ii_begin,ii_end
104    !      ij=(j-1)*iim+i
105    !      ! dps/dt = -int(div flux)dz
106    !      dps(ij)=-convm(ij,1) * g
107    !      convm(ij,llm+1)=0.
108    !    ENDDO
109    !  ENDDO
110   
111    ! Compute Omega = Dp/Dt
112    ! with p = A(eta)+B(eta)ps
113    !      Dp/Dt = dp/deta.Deta/Dt + B(eta)Dps/Dt
114    !            = -mg.Deta/Dt + B.Dps/Dt
115    ! By definition the mass flux through model levels is W=m.Deta/Dt with m=-1/g dp/deta
116    ! therefore
117    !  Dp/Dt = -g.W + B.dps/dt + Bu.grad ps
118    !        = B.u.grad ps - g*convm
119   
120!!! Compute vertical flux through model layers
121    !  DO l = 1,llm-1
122    !    DO j=jj_begin,jj_end
123    !      DO i=ii_begin,ii_end
124    !        ij=(j-1)*iim+i
125    !        ! w = int(z,ztop,div(flux)dz) + B(eta)dps/dt
126    !        ! => w>0 for upward transport
127    !        w( ij, l+1 ) = convm( ij, l+1 ) - bp(l+1) * convm( ij, 1 ) ! g.W = g.convm + B dps/dt
128    !      ENDDO
129    !    ENDDO
130    !  ENDDO
131   
132   
133!!! Compute omega
134    ! -grad ps : ( ne(ij,ldown)*ps(ij,l) + ne(ij+t_ldown,rup)*ps(ij+t_ldown,l) ) ) / de(ij+u_ldown)
135
136       DO l = 1,llm
137         DO j=jj_begin,jj_end 
138           DO i=ii_begin,ii_end
139             ij=(j-1)*iim+i
140             ugradps = &
141                  le(ij+u_right)*u(ij+u_right,l)*( ne(ij,right)*ps(ij) + ne(ij+t_right,left)*ps(ij+t_right) )  &
142                  + le(ij+u_rup)*u(ij+u_rup,l)*( ne(ij,rup)*ps(ij) + ne(ij+t_rup,ldown)*ps(ij+t_rup) )  &
143                  + le(ij+u_lup)*u(ij+u_lup,l)*( ne(ij,lup)*ps(ij) + ne(ij+t_lup,rdown)*ps(ij+t_lup) )         &
144                  + le(ij+u_left)*u(ij+u_left,l)*( ne(ij,left)*ps(ij) + ne(ij+t_left,right)*ps(ij+t_left) )    &
145                  + le(ij+u_ldown)*u(ij+u_ldown,l)*( ne(ij,ldown)*ps(ij) + ne(ij+t_ldown,rup)*ps(ij+t_ldown) ) &
146                  + le(ij+u_rdown)*u(ij+u_rdown,l)*( ne(ij,rdown)*ps(ij) + ne(ij+t_rdown,lup)*ps(ij+t_rdown) )
147             ugradps = .5*(bp(l)+bp(l+1)) *ugradps/(-4*Ai(ij))  ! sign convention as in Ringler et al. 2010, Eq. 22 p.3072
148             w( ij, l) =  ugradps - g*.5*(convm( ij,l+1)+convm(ij,l)) 
149          ENDDO
150        ENDDO
151      ENDDO
152    ENDIF
153!$OMP BARRIER
154   
155  END SUBROUTINE compute_omega
156 
157END MODULE omega_mod
Note: See TracBrowser for help on using the repository browser.