source: codes/icosagcm/trunk/src/omega.f90 @ 200

Last change on this file since 200 was 186, checked in by ymipsl, 10 years ago

Add new openMP parallelism based on distribution of domains on threads. There is no more limitation of number of threads by MPI process.

YM

File size: 4.8 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  SUBROUTINE compute_omega(ps,u, w)
26    USE disvert_mod, ONLY : ap,bp
27    REAL(rstd),INTENT(IN) :: u(iim*3*jjm,llm), ps(iim*jjm)
28    REAL(rstd),INTENT(OUT):: w(iim*jjm,llm)
29    REAL(rstd):: convm(iim*jjm,llm+1)
30    REAL(rstd):: p(iim*jjm,llm+1), rhodz(iim*jjm,llm), Fe(iim*3*jjm,llm)
31    REAL(rstd):: ugradps
32    DO    l    = 1, llm+1
33       DO j=jj_begin-1,jj_end+1
34          DO i=ii_begin-1,ii_end+1
35             ij=(j-1)*iim+i
36             p(ij,l) = ap(l) + bp(l) * ps(ij)
37          ENDDO
38       ENDDO
39    ENDDO
40   
41!!! Compute mass
42    DO l = 1, llm
43       DO j=jj_begin-1,jj_end+1
44          DO i=ii_begin-1,ii_end+1
45             ij=(j-1)*iim+i
46             rhodz(ij,l) = ( p(ij,l) - p(ij,l+1) ) / g
47          ENDDO
48       ENDDO
49    ENDDO
50   
51!!!  Compute mass flux
52    DO l = 1, llm
53       DO j=jj_begin-1,jj_end+1
54          DO i=ii_begin-1,ii_end+1
55             ij=(j-1)*iim+i
56             Fe(ij+u_right,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_right,l))*u(ij+u_right,l)*le(ij+u_right)
57             Fe(ij+u_lup,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_lup,l))*u(ij+u_lup,l)*le(ij+u_lup)
58             Fe(ij+u_ldown,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_ldown,l))*u(ij+u_ldown,l)*le(ij+u_ldown)
59          ENDDO
60       ENDDO
61    ENDDO
62   
63!!! mass flux convergence computation 
64   
65    ! horizontal convergence
66    DO l = 1, llm
67       DO j=jj_begin,jj_end
68          DO i=ii_begin,ii_end
69             ij=(j-1)*iim+i
70             ! convm = +div(mass flux), sign convention as in Ringler et al. 2012, eq. 21
71             convm(ij,l)= 1./Ai(ij)*(ne(ij,right)*Fe(ij+u_right,l)   +  &
72                  ne(ij,rup)*Fe(ij+u_rup,l)       +  & 
73                  ne(ij,lup)*Fe(ij+u_lup,l)       +  & 
74                  ne(ij,left)*Fe(ij+u_left,l)     +  & 
75                  ne(ij,ldown)*Fe(ij+u_ldown,l)   +  & 
76                  ne(ij,rdown)*Fe(ij+u_rdown,l))
77          ENDDO
78       ENDDO
79    ENDDO
80   
81    ! vertical integration from up to down
82    DO  l = llm-1, 1, -1
83       DO j=jj_begin,jj_end
84          DO i=ii_begin,ii_end
85             ij=(j-1)*iim+i
86             convm(ij,l) = convm(ij,l) + convm(ij,l+1)
87          ENDDO
88       ENDDO
89    ENDDO
90    convm(:,llm+1)=0.
91
92!!! Compute dps
93    !  DO j=jj_begin,jj_end
94    !    DO i=ii_begin,ii_end
95    !      ij=(j-1)*iim+i
96    !      ! dps/dt = -int(div flux)dz
97    !      dps(ij)=-convm(ij,1) * g
98    !      convm(ij,llm+1)=0.
99    !    ENDDO
100    !  ENDDO
101   
102    ! Compute Omega = Dp/Dt
103    ! with p = A(eta)+B(eta)ps
104    !      Dp/Dt = dp/deta.Deta/Dt + B(eta)Dps/Dt
105    !            = -mg.Deta/Dt + B.Dps/Dt
106    ! By definition the mass flux through model levels is W=m.Deta/Dt with m=-1/g dp/deta
107    ! therefore
108    !  Dp/Dt = -g.W + B.dps/dt + Bu.grad ps
109    !        = B.u.grad ps - g*convm
110   
111!!! Compute vertical flux through model layers
112    !  DO l = 1,llm-1
113    !    DO j=jj_begin,jj_end
114    !      DO i=ii_begin,ii_end
115    !        ij=(j-1)*iim+i
116    !        ! w = int(z,ztop,div(flux)dz) + B(eta)dps/dt
117    !        ! => w>0 for upward transport
118    !        w( ij, l+1 ) = convm( ij, l+1 ) - bp(l+1) * convm( ij, 1 ) ! g.W = g.convm + B dps/dt
119    !      ENDDO
120    !    ENDDO
121    !  ENDDO
122   
123   
124!!! Compute omega
125    ! -grad ps : ( ne(ij,ldown)*ps(ij,l) + ne(ij+t_ldown,rup)*ps(ij+t_ldown,l) ) ) / de(ij+u_ldown)
126
127    DO l = 1,llm
128       DO j=jj_begin,jj_end
129          DO i=ii_begin,ii_end
130             toto = 1
131             ij=(j-1)*iim+i
132             ugradps = &
133                  le(ij+u_right)*u(ij+u_right,l)*( ne(ij,right)*ps(ij) + ne(ij+t_right,left)*ps(ij+t_right) )  &
134                  + le(ij+u_rup)*u(ij+u_rup,l)*( ne(ij,rup)*ps(ij) + ne(ij+t_rup,ldown)*ps(ij+t_rup) )  &
135                  + le(ij+u_lup)*u(ij+u_lup,l)*( ne(ij,lup)*ps(ij) + ne(ij+t_lup,rdown)*ps(ij+t_lup) )         &
136                  + le(ij+u_left)*u(ij+u_left,l)*( ne(ij,left)*ps(ij) + ne(ij+t_left,right)*ps(ij+t_left) )    &
137                  + le(ij+u_ldown)*u(ij+u_ldown,l)*( ne(ij,ldown)*ps(ij) + ne(ij+t_ldown,rup)*ps(ij+t_ldown) ) &
138                  + le(ij+u_rdown)*u(ij+u_rdown,l)*( ne(ij,rdown)*ps(ij) + ne(ij+t_rdown,lup)*ps(ij+t_rdown) )
139             ugradps = .5*(bp(l)+bp(l+1)) *ugradps/(-4*Ai(ij))  ! sign convention as in Ringler et al. 2010, Eq. 22 p.3072
140             w( ij, l) =  ugradps - .5*(convm( ij,l+1)+convm(ij,l)) 
141          ENDDO
142       ENDDO
143    ENDDO
144   
145  END SUBROUTINE compute_omega
146 
147END MODULE omega_mod
Note: See TracBrowser for help on using the repository browser.