source: codes/icosagcm/trunk/src/exner.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: 3.4 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    DO ind=1,ndomain
25      IF (.NOT. assigned_domain(ind)) CYCLE
26      CALL swap_dimensions(ind)
27      CALL swap_geometry(ind)
28      ps=f_ps(ind)
29      p=f_p(ind)
30      pks=f_pks(ind)
31      pk=f_pk(ind)
32      CALL compute_exner(ps, p, pks, pk, 0)
33    ENDDO
34 
35  END SUBROUTINE exner
36 
37  SUBROUTINE compute_exner(ps,p,pks,pk,offset)
38  USE icosa
39  USE disvert_mod
40  USE pression_mod
41  IMPLICIT NONE
42    REAL(rstd),INTENT(IN) :: ps(iim*jjm)
43    REAL(rstd),INTENT(IN) :: p(iim*jjm,llm+1)
44    REAL(rstd),INTENT(OUT) :: pks(iim*jjm)
45    REAL(rstd),INTENT(OUT) :: pk(iim*jjm,llm)
46    INTEGER,INTENT(IN) :: offset
47    INTEGER :: i,j,ij,l
48    REAL(rstd) :: alpha(iim*jjm,llm),beta(iim*jjm,llm)
49    REAL(rstd) :: delta 
50   
51    IF(caldyn_exner == lmdz) THEN          ! LMD-Z style calculation of Exner pressure
52       !! Compute Alpha and Beta
53       
54       ! for llm layer
55       DO j=jj_begin-offset,jj_end+offset
56          DO i=ii_begin-offset,ii_end+offset
57             ij=(j-1)*iim+i
58             alpha(ij,llm) = 0.
59             beta (ij,llm) = 1./ (1+ 2*kappa)
60          ENDDO
61       ENDDO
62       
63       ! for other layer   
64       DO l = llm-1 , 2 , -1
65          DO j=jj_begin-offset,jj_end+offset
66             DO i=ii_begin-offset,ii_end+offset
67                ij=(j-1)*iim+i
68                delta = p(ij,l)* (1+2*kappa) + p(ij,l+1)* ( beta(ij,l+1)- (1+2*kappa) )
69                alpha(ij,l)  = - p(ij,l+1) / delta * alpha(ij,l+1)
70                beta (ij,l)  =   p(ij,l  ) / delta   
71             ENDDO
72          ENDDO
73       ENDDO
74       
75       !! Compute pk
76       
77       ! for first layer
78       DO j=jj_begin-offset,jj_end+offset
79          DO i=ii_begin-offset,ii_end+offset
80             ij=(j-1)*iim+i
81             pks(ij) = cpp * ( ps(ij)/preff ) ** kappa
82             pk(ij,1) = ( p(ij,1)*pks(ij) - 0.5*alpha(ij,2)*p(ij,2) )     /    &
83                  (  p(ij,1)* (1.+kappa) + 0.5*( beta(ij,2)-(1.+2*kappa) )* p(ij,2) )
84          ENDDO
85       ENDDO
86       
87       ! for other layers
88       
89       DO l = 2, llm
90          DO j=jj_begin-offset,jj_end+offset
91             DO i=ii_begin-offset,ii_end+offset
92                ij=(j-1)*iim+i
93                pk(ij,l) = alpha(ij,l) + beta(ij,l) * pk(ij,l-1)
94             ENDDO
95          ENDDO
96       ENDDO
97       
98    ELSE ! Simple calculation of Exner pressure based on centered average
99       ! surface : pks
100       DO j=jj_begin-offset,jj_end+offset
101          DO i=ii_begin-offset,ii_end+offset
102             ij=(j-1)*iim+i
103             pks(ij) = cpp * ( ps(ij)/preff ) ** kappa
104          ENDDO
105       ENDDO
106
107       ! 3D : pk
108       DO l = 1, llm
109          DO j=jj_begin-offset,jj_end+offset
110             DO i=ii_begin-offset,ii_end+offset
111                ij=(j-1)*iim+i
112                pk(ij,l) = cpp * ((.5/preff)*(p(ij,l)+p(ij,l+1))) ** kappa
113             ENDDO
114          ENDDO
115       ENDDO
116    END IF
117   
118  END SUBROUTINE compute_exner
119 
120END MODULE exner_mod
Note: See TracBrowser for help on using the repository browser.