source: codes/icosagcm/devel/src/diagnostics/compute_omega.F90 @ 919

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

devel : DYSL for compute_omega

File size: 5.5 KB
Line 
1MODULE compute_omega_mod
2  USE icosa
3  IMPLICIT NONE
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#ifdef BEGIN_DYSL
26
27KERNEL(compute_omega)
28
29  ! Pressure
30  FORALL_CELLS_EXT()
31    ON_PRIMAL
32      p(CELL) = AP(CELL) + BP(CELL)*ps(HIDX(CELL))
33    END_BLOCK
34  END_BLOCK
35
36  BARRIER
37
38  ! Mass and grad(ps)
39  FORALL_CELLS_EXT()
40    ON_PRIMAL
41      rhodz(CELL) = (p(CELL)-p(UP(CELL)))*(1./g)
42    END_BLOCK
43    ON_EDGES
44      CST_IFTHEN(IS_BOTTOM_LEVEL)
45        gradps(HIDX(EDGE)) = (ps(HIDX(CELL2))-ps(HIDX(CELL1)))*SIGN*LE
46      CST_ENDIF
47    END_BLOCK
48  END_BLOCK
49 
50  ! Mass flux
51  FORALL_CELLS_EXT()
52    ON_EDGES
53      Fe(EDGE)=0.5*(rhodz(CELL1)+rhodz(CELL2)*LE
54    END_BLOCK
55  END_BLOCK
56
57  ! Mass flux divergence
58  ! convm = +div(mass flux), sign convention as in Ringler et al. 2012, eq. 21
59  FORALL_CELLS()
60    ON_PRIMAL
61      divflux=0.
62      FORALL_EDGES
63        divflux = divflux + SIGN*Fe(EDGE)
64      END_BLOCK
65      convm(CELL) = divflux*(1./AI)
66    END_BLOCK
67  END_BLOCK
68
69  ! Barrier needed before and after doing a vertical recurrence
70  BARRIER
71
72  ! vertical integration from up to down
73  SEQUENCE_C1
74    PROLOGUE('llm')
75      convm(CELL)=0.
76    END_BLOCK
77    BODY('llm-1,1,-1') 
78      convm(CELL) = convm(CELL) + convm(UP(CELL))
79    END_BLOCK
80  END_BLOCK
81
82  BARRIER
83
84  ! omega = dp/dt = u.grad p + \pdiff{p}{t}
85  FORALL_CELLS()
86    ON_PRIMAL
87      ugradps=0.
88      FORALL_EDGES
89        ugradps = ugradps + u(EDGE)*gradps(HIDX(EDGE))
90      END_BLOCK
91      ugradps = .5*(BP(CELL)+BP(UP(CELL)))*ugradps/(-4.*AI)  ! sign convention as in Ringler et al. 2010, Eq. 22 p.3072
92      w(CELL) =  ugradps - g*.5*(convm(CELL)+convm(UP(CELL)))
93    END_BLOCK
94  END_BLOCK
95END_BLOCK
96
97#endif END_DYSL
98
99  SUBROUTINE compute_omega(ps,u, w)
100    USE disvert_mod, ONLY : ap,bp
101    USE omp_para
102    REAL(rstd),INTENT(IN) :: u(iim*3*jjm,llm), ps(iim*jjm)
103    REAL(rstd),INTENT(OUT):: w(iim*jjm,llm)
104    REAL(rstd):: convm(iim*jjm,llm+1)
105    REAL(rstd):: p(iim*jjm,llm+1), rhodz(iim*jjm,llm), Fe(iim*3*jjm,llm)
106    REAL(rstd):: gradps(3*iim*jjm)
107    REAL(rstd):: ugradps
108   
109    INTEGER :: i,j,l,ij
110
111!$OMP BARRIER   
112    IF (is_omp_level_master) THEN
113      DO    l    = 1, llm+1
114         DO j=jj_begin-1,jj_end+1
115           DO i=ii_begin-1,ii_end+1
116               ij=(j-1)*iim+i
117               p(ij,l) = ap(l) + bp(l) * ps(ij)
118            ENDDO
119         ENDDO
120      ENDDO
121   
122!!! Compute mass
123      DO l = 1, llm
124         DO j=jj_begin-1,jj_end+1
125            DO i=ii_begin-1,ii_end+1
126               ij=(j-1)*iim+i
127               rhodz(ij,l) = ( p(ij,l) - p(ij,l+1) ) / g
128            ENDDO
129         ENDDO
130      ENDDO
131
132      !DIR$ SIMD
133      DO ij=ij_begin_ext, ij_end_ext
134         gradps(ij+u_right) = (ps(ij)-ps(ij+t_right))*ne_right*le(ij+u_right)
135         gradps(ij+u_lup)   = (ps(ij)-ps(ij+t_lup))  *ne_lup  *le(ij+u_lup)
136         gradps(ij+u_ldown) = (ps(ij)-ps(ij+t_ldown))*ne_ldown*le(ij+u_ldown)
137      END DO
138   
139!!!  Compute mass flux
140      DO l = 1, llm
141         DO j=jj_begin-1,jj_end+1
142            DO i=ii_begin-1,ii_end+1
143               ij=(j-1)*iim+i
144               Fe(ij+u_right,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_right,l))*u(ij+u_right,l)*le(ij+u_right)
145               Fe(ij+u_lup,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_lup,l))*u(ij+u_lup,l)*le(ij+u_lup)
146               Fe(ij+u_ldown,l)=0.5*(rhodz(ij,l)+rhodz(ij+t_ldown,l))*u(ij+u_ldown,l)*le(ij+u_ldown)
147            ENDDO
148         ENDDO
149      ENDDO
150   
151!!! mass flux convergence computation 
152   
153    ! horizontal convergence
154      DO l = 1, llm
155         DO j=jj_begin,jj_end
156            DO i=ii_begin,ii_end
157               ij=(j-1)*iim+i
158               ! convm = +div(mass flux), sign convention as in Ringler et al. 2012, eq. 21
159               convm(ij,l)= 1./Ai(ij)*(ne(ij,right)*Fe(ij+u_right,l)   +  &
160                    ne(ij,rup)*Fe(ij+u_rup,l)       +  & 
161                    ne(ij,lup)*Fe(ij+u_lup,l)       +  & 
162                    ne(ij,left)*Fe(ij+u_left,l)     +  & 
163                    ne(ij,ldown)*Fe(ij+u_ldown,l)   +  & 
164                    ne(ij,rdown)*Fe(ij+u_rdown,l))
165            ENDDO
166         ENDDO
167      ENDDO
168   
169      ! vertical integration from up to down
170      DO  l = llm-1, 1, -1
171         DO j=jj_begin,jj_end
172            DO i=ii_begin,ii_end
173               ij=(j-1)*iim+i
174               convm(ij,l) = convm(ij,l) + convm(ij,l+1)
175            ENDDO
176         ENDDO
177      ENDDO
178      convm(:,llm+1)=0.
179
180!!! Compute omega
181
182       DO l = 1,llm
183         DO j=jj_begin,jj_end 
184           DO i=ii_begin,ii_end
185             ij=(j-1)*iim+i
186             ugradps = &
187                  u(ij+u_rup,l)*gradps(ij+u_rup)       &
188                  + u(ij+u_lup,l)*gradps(ij+u_lup)     &
189                  + u(ij+u_left,l)*gradps(ij+u_left)   &
190                  + u(ij+u_ldown,l)*gradps(ij+u_ldown) &
191                  + u(ij+u_rdown,l)*gradps(ij+u_rdown) &
192                  + u(ij+u_right,l)*gradps(ij+u_right)
193
194             ugradps = .5*(bp(l)+bp(l+1)) *ugradps/(-4*Ai(ij))  ! sign convention as in Ringler et al. 2010, Eq. 22 p.3072
195             w( ij, l) =  ugradps - g*.5*(convm( ij,l+1)+convm(ij,l)) 
196          ENDDO
197        ENDDO
198      ENDDO
199    ENDIF
200!$OMP BARRIER
201   
202  END SUBROUTINE compute_omega
203 
204END MODULE compute_omega_mod
Note: See TracBrowser for help on using the repository browser.