source: codes/icosagcm/trunk/src/exner.f90 @ 352

Last change on this file since 352 was 295, checked in by ymipsl, 10 years ago

Merging OpenMP parallisme mode : by subdomain and on vertical level.
This feature is actually experimental but may be retro-compatible with the last method based only on subdomain

YM

File size: 3.6 KB
Line 
1MODULE exner_mod
2
3  INTEGER,SAVE :: caldyn_exner
4!$OMP THREADPRIVATE(caldyn_exner)
5
6  INTEGER, PARAMETER :: lmdz=3, direct=4
7
8CONTAINS
9 
10  SUBROUTINE exner(f_ps,f_p,f_pks,f_pk)
11  USE icosa
12  IMPLICIT NONE
13    TYPE(t_field), POINTER :: f_ps(:)
14    TYPE(t_field), POINTER :: f_p(:)
15    TYPE(t_field), POINTER :: f_pks(:)
16    TYPE(t_field), POINTER :: f_pk(:)
17 
18    REAL(rstd), POINTER :: ps(:)
19    REAL(rstd), POINTER :: p(:,:)
20    REAL(rstd), POINTER :: pks(:)
21    REAL(rstd), POINTER :: pk(:,:)
22    INTEGER :: ind
23
24!$OMP BARRIER
25    DO ind=1,ndomain
26      IF (.NOT. assigned_domain(ind)) CYCLE
27      CALL swap_dimensions(ind)
28      CALL swap_geometry(ind)
29      ps=f_ps(ind)
30      p=f_p(ind)
31      pks=f_pks(ind)
32      pk=f_pk(ind)
33      CALL compute_exner(ps, p, pks, pk, 0)
34    ENDDO
35!$OMP BARRIER
36 
37  END SUBROUTINE exner
38 
39  SUBROUTINE compute_exner(ps,p,pks,pk,offset)
40  USE icosa
41  USE disvert_mod
42  USE pression_mod
43  USE omp_para
44  IMPLICIT NONE
45    REAL(rstd),INTENT(IN) :: ps(iim*jjm)
46    REAL(rstd),INTENT(IN) :: p(iim*jjm,llm+1)
47    REAL(rstd),INTENT(OUT) :: pks(iim*jjm)
48    REAL(rstd),INTENT(OUT) :: pk(iim*jjm,llm)
49    INTEGER,INTENT(IN) :: offset
50    INTEGER :: i,j,ij,l
51    REAL(rstd) :: alpha(iim*jjm,llm),beta(iim*jjm,llm)
52    REAL(rstd) :: delta 
53   
54    IF(caldyn_exner == lmdz) THEN          ! LMD-Z style calculation of Exner pressure
55       !! Compute Alpha and Beta
56       
57       IF (is_omp_level_master) THEN
58       ! for llm layer
59         DO j=jj_begin-offset,jj_end+offset
60            DO i=ii_begin-offset,ii_end+offset
61               ij=(j-1)*iim+i
62               alpha(ij,llm) = 0.
63               beta (ij,llm) = 1./ (1+ 2*kappa)
64            ENDDO
65         ENDDO
66       
67       ! for other layer   
68         DO l = llm-1 , 2 , -1
69            DO j=jj_begin-offset,jj_end+offset
70               DO i=ii_begin-offset,ii_end+offset
71                  ij=(j-1)*iim+i
72                  delta = p(ij,l)* (1+2*kappa) + p(ij,l+1)* ( beta(ij,l+1)- (1+2*kappa) )
73                  alpha(ij,l)  = - p(ij,l+1) / delta * alpha(ij,l+1)
74                  beta (ij,l)  =   p(ij,l  ) / delta   
75               ENDDO
76            ENDDO
77         ENDDO
78       
79         !! Compute pk
80       
81         ! for first layer
82         DO j=jj_begin-offset,jj_end+offset
83            DO i=ii_begin-offset,ii_end+offset
84               ij=(j-1)*iim+i
85               pks(ij) = cpp * ( ps(ij)/preff ) ** kappa
86               pk(ij,1) = ( p(ij,1)*pks(ij) - 0.5*alpha(ij,2)*p(ij,2) )     /    &
87                    (  p(ij,1)* (1.+kappa) + 0.5*( beta(ij,2)-(1.+2*kappa) )* p(ij,2) )
88            ENDDO
89         ENDDO
90       
91       ! for other layers
92       
93         DO l = 2, llm
94            DO j=jj_begin-offset,jj_end+offset
95               DO i=ii_begin-offset,ii_end+offset
96                  ij=(j-1)*iim+i
97                  pk(ij,l) = alpha(ij,l) + beta(ij,l) * pk(ij,l-1)
98               ENDDO
99            ENDDO
100         ENDDO
101
102       ENDIF
103
104    ELSE ! Simple calculation of Exner pressure based on centered average
105       ! surface : pks
106       IF (is_omp_level_master) THEN
107
108         DO j=jj_begin-offset,jj_end+offset
109            DO i=ii_begin-offset,ii_end+offset
110               ij=(j-1)*iim+i
111               pks(ij) = cpp * ( ps(ij)/preff ) ** kappa
112            ENDDO
113         ENDDO
114
115       ENDIF
116
117         ! 3D : pk
118       DO l = 1, llm
119          DO j=jj_begin-offset,jj_end+offset
120             DO i=ii_begin-offset,ii_end+offset
121               ij=(j-1)*iim+i
122               pk(ij,l) = cpp * ((.5/preff)*(p(ij,l)+p(ij,l+1))) ** kappa
123             ENDDO
124          ENDDO
125       ENDDO
126
127    END IF
128   
129  END SUBROUTINE compute_exner
130 
131END MODULE exner_mod
Note: See TracBrowser for help on using the repository browser.