source: codes/icosagcm/trunk/src/diagnostics/theta_rhodz.f90 @ 1057

Last change on this file since 1057 was 1046, checked in by ymipsl, 4 years ago

Introduce modification from A. Durocher github to make held&suarez testcase working on GPU

YM & AD

File size: 6.8 KB
RevLine 
[12]1MODULE theta2theta_rhodz_mod
[295]2  USE field_mod
[428]3  PRIVATE
[295]4  TYPE(t_field), POINTER, SAVE  :: f_p(:)
[12]5
[428]6  PUBLIC :: init_theta2theta_rhodz, theta_rhodz2theta, &
7       theta_rhodz2temperature, temperature2theta_rhodz, &
8       theta2theta_rhodz, &
9       compute_theta2theta_rhodz, compute_theta_rhodz2theta
[295]10
[12]11CONTAINS
[15]12 
[295]13  SUBROUTINE init_theta2theta_rhodz
14  USE icosa
15  USE field_mod
16  IMPLICIT NONE
[428]17    CALL allocate_field(f_p,field_t,type_real,llm+1,name='p (theta2theta_rhodz_mod)')   
[295]18  END SUBROUTINE init_theta2theta_rhodz
19
20
[15]21  SUBROUTINE theta_rhodz2theta(f_ps,f_theta_rhodz,f_theta)
[19]22  USE icosa
[15]23  IMPLICIT NONE
24    TYPE(t_field), POINTER :: f_ps(:)
25    TYPE(t_field), POINTER :: f_theta_rhodz(:)
26    TYPE(t_field), POINTER :: f_theta(:)
27 
28    REAL(rstd), POINTER :: ps(:)
29    REAL(rstd), POINTER :: theta_rhodz(:,:)
30    REAL(rstd), POINTER :: theta(:,:)
31    INTEGER :: ind
[12]32
[295]33!$OMP BARRIER
[15]34    DO ind=1,ndomain
[186]35      IF (.NOT. assigned_domain(ind)) CYCLE
[15]36      CALL swap_dimensions(ind)
37      CALL swap_geometry(ind)
38      ps=f_ps(ind)
39      theta_rhodz=f_theta_rhodz(ind)
40      theta=f_theta(ind)
[1046]41      CALL compute_theta_rhodz2theta(ps, theta_rhodz,theta,0, ondevice=.false.)
[15]42    ENDDO
[295]43!$OMP BARRIER
[15]44 
45  END SUBROUTINE theta_rhodz2theta
46
47  SUBROUTINE theta_rhodz2temperature(f_ps,f_theta_rhodz,f_temp)
[19]48  USE icosa
[295]49  USE pression_mod
[15]50  IMPLICIT NONE
51    TYPE(t_field), POINTER :: f_ps(:)
52    TYPE(t_field), POINTER :: f_theta_rhodz(:)
53    TYPE(t_field), POINTER :: f_temp(:)
54 
55    REAL(rstd), POINTER :: ps(:)
[387]56    REAL(rstd), POINTER :: theta_rhodz(:,:,:)
[15]57    REAL(rstd), POINTER :: temp(:,:)
[322]58    REAL(rstd), POINTER :: p(:,:)
[15]59    INTEGER :: ind
60
61    DO ind=1,ndomain
[186]62      IF (.NOT. assigned_domain(ind)) CYCLE
[15]63      CALL swap_dimensions(ind)
64      CALL swap_geometry(ind)
65      ps=f_ps(ind)
[295]66      p=f_p(ind)
[15]67      theta_rhodz=f_theta_rhodz(ind)
68      temp=f_temp(ind)
[295]69
70!$OMP BARRIER
71      CALL compute_pression(ps,p,0)
72!$OMP BARRIER
[428]73      CALL compute_theta_rhodz2temperature(p, theta_rhodz(:,:,1),temp,0)
[15]74    ENDDO
[295]75!$OMP BARRIER
[15]76 
77  END SUBROUTINE theta_rhodz2temperature
[295]78 
79  SUBROUTINE temperature2theta_rhodz(f_ps,f_temp,f_theta_rhodz)
80  USE icosa
81  USE pression_mod
82  USE exner_mod
83  IMPLICIT NONE
84    TYPE(t_field), POINTER :: f_ps(:)
85    TYPE(t_field), POINTER :: f_theta_rhodz(:)
86    TYPE(t_field), POINTER :: f_temp(:)
87 
88    REAL(rstd), POINTER :: ps(:)
[387]89    REAL(rstd), POINTER :: theta_rhodz(:,:,:)
[295]90    REAL(rstd), POINTER :: temp(:,:)
[322]91    REAL(rstd), POINTER :: p(:,:)
[295]92    INTEGER :: ind
93
94    DO ind=1,ndomain
95      IF (.NOT. assigned_domain(ind)) CYCLE
96      CALL swap_dimensions(ind)
97      CALL swap_geometry(ind)
98      ps=f_ps(ind)
99      p=f_p(ind)
100      theta_rhodz=f_theta_rhodz(ind)
101      temp=f_temp(ind)
102
103!$OMP BARRIER
104      CALL compute_pression(ps,p,0)
105!$OMP BARRIER
[428]106      CALL compute_temperature2theta_rhodz(p, temp, theta_rhodz(:,:,1), 0)
[295]107    ENDDO
108!$OMP BARRIER
109 
110  END SUBROUTINE temperature2theta_rhodz
111 
112 
[15]113   
[12]114  SUBROUTINE theta2theta_rhodz(f_ps,f_theta,f_theta_rhodz)
[19]115  USE icosa
[12]116  IMPLICIT NONE
117    TYPE(t_field), POINTER :: f_ps(:)
118    TYPE(t_field), POINTER :: f_theta(:)
119    TYPE(t_field), POINTER :: f_theta_rhodz(:)
120 
121    REAL(rstd), POINTER :: ps(:)
122    REAL(rstd), POINTER :: theta(:,:)
123    REAL(rstd), POINTER :: theta_rhodz(:,:)
124    INTEGER :: ind
125
[295]126!$OMP BARRIER
[12]127    DO ind=1,ndomain
[186]128      IF (.NOT. assigned_domain(ind)) CYCLE
[12]129      CALL swap_dimensions(ind)
130      CALL swap_geometry(ind)
131      ps=f_ps(ind)
132      theta=f_theta(ind)
133      theta_rhodz=f_theta_rhodz(ind)
[1046]134      CALL compute_theta2theta_rhodz(ps, theta, theta_rhodz,0,ondevice=.false.)
[12]135    ENDDO
[295]136!$OMP BARRIER
[12]137 
138  END SUBROUTINE theta2theta_rhodz
139 
[1046]140  SUBROUTINE compute_theta2theta_rhodz(ps,theta, theta_rhodz,offset, ondevice)
[19]141  USE icosa
[295]142  USE disvert_mod
143  USE omp_para
[12]144  IMPLICIT NONE
145    REAL(rstd),INTENT(IN) :: ps(iim*jjm)
146    REAL(rstd),INTENT(IN) :: theta(iim*jjm,llm)
147    REAL(rstd),INTENT(OUT) :: theta_rhodz(iim*jjm,llm)
148    INTEGER,INTENT(IN) :: offset
[1046]149    LOGICAL, INTENT(IN) :: ondevice
[323]150    REAL(rstd) :: rhodz
[12]151    INTEGER :: i,j,ij,l
152   
[295]153!$OMP BARRIER
[1046]154    !$acc parallel loop collapse(3) default(present) async if(ondevice)
[295]155    DO    l    = ll_begin, ll_end
[12]156      DO j=jj_begin-offset,jj_end+offset
157        DO i=ii_begin-offset,ii_end+offset
158          ij=(j-1)*iim+i
[323]159          rhodz = ( ap(l)-ap(l+1) + (bp(l)-bp(l+1))*ps(ij) )/g
160          theta_rhodz(ij,l) = theta(ij,l) * rhodz
[12]161        ENDDO
162      ENDDO
163    ENDDO
[295]164!$OMP BARRIER
[15]165
166
[12]167  END SUBROUTINE compute_theta2theta_rhodz
168
[1046]169  SUBROUTINE compute_theta_rhodz2theta(ps,theta_rhodz,theta,offset,ondevice)
[19]170  USE icosa
[295]171  USE disvert_mod
172  USE omp_para
[15]173  IMPLICIT NONE
174    REAL(rstd),INTENT(IN) :: ps(iim*jjm)
175    REAL(rstd),INTENT(IN) :: theta_rhodz(iim*jjm,llm)
176    REAL(rstd),INTENT(OUT) :: theta(iim*jjm,llm)
177    INTEGER,INTENT(IN) :: offset
[1046]178    LOGICAL, INTENT(IN) :: ondevice
[323]179    REAL(rstd) :: rhodz
[15]180    INTEGER :: i,j,ij,l
181
[295]182!$OMP BARRIER
[1046]183    !$acc parallel loop collapse(3) default(present) async if(ondevice)
[295]184    DO    l    = ll_begin, ll_end
[15]185      DO j=jj_begin-offset,jj_end+offset
186        DO i=ii_begin-offset,ii_end+offset
187          ij=(j-1)*iim+i
[323]188          rhodz = ( ap(l)-ap(l+1) + (bp(l)-bp(l+1))*ps(ij) )/g
189          theta(ij,l) = theta_rhodz(ij,l) / rhodz
[15]190        ENDDO
191      ENDDO
192    ENDDO
[295]193!$OMP BARRIER
[15]194
195   
196  END SUBROUTINE compute_theta_rhodz2theta
197
[295]198
199
200
201
202
[428]203  SUBROUTINE compute_theta_rhodz2temperature(p,theta_rhodz,temp,offset)
[19]204  USE icosa
[15]205  USE pression_mod
206  USE exner_mod
[295]207  USE omp_para
[15]208  IMPLICIT NONE
[295]209    REAL(rstd),INTENT(IN) :: p(iim*jjm,llm+1)
[15]210    REAL(rstd),INTENT(IN) :: theta_rhodz(iim*jjm,llm)
211    REAL(rstd),INTENT(OUT) :: temp(iim*jjm,llm)
212    INTEGER,INTENT(IN) :: offset
[428]213    REAL(rstd) :: pk_ij
[15]214    INTEGER :: i,j,ij,l
215       
[295]216! flush p
217!$OMP BARRIER
218    DO    l    = ll_begin, ll_end
[15]219      DO j=jj_begin-offset,jj_end+offset
220        DO i=ii_begin-offset,ii_end+offset
221          ij=(j-1)*iim+i
[428]222          pk_ij=((.5/preff)*(p(ij,l)+p(ij,l+1)))**kappa
223          temp(ij,l) = ( theta_rhodz(ij,l) / ((p(ij,l)-p(ij,l+1))/g) ) * pk_ij
[15]224        ENDDO
225      ENDDO
226    ENDDO
[295]227!$OMP BARRIER
[15]228   
[295]229   
[15]230  END SUBROUTINE compute_theta_rhodz2temperature
[35]231
[428]232  SUBROUTINE compute_temperature2theta_rhodz(p,temp,theta_rhodz,offset)
[35]233  USE icosa
234  USE pression_mod
235  USE exner_mod
[295]236  USE omp_para
[35]237  IMPLICIT NONE
[295]238    REAL(rstd),INTENT(IN)  :: p(iim*jjm,llm+1)
[35]239    REAL(rstd),INTENT(OUT) :: theta_rhodz(iim*jjm,llm)
[295]240    REAL(rstd),INTENT(IN)  :: temp(iim*jjm,llm)
[35]241    INTEGER,INTENT(IN) :: offset
[428]242    REAL(rstd) :: pk_ij
[35]243    INTEGER :: i,j,ij,l
244
245       
[295]246! flush p
247!$OMP BARRIER
248
249    DO    l    = ll_begin, ll_end
[35]250      DO j=jj_begin-offset,jj_end+offset
251        DO i=ii_begin-offset,ii_end+offset
252          ij=(j-1)*iim+i
[428]253          pk_ij=((.5/preff)*(p(ij,l)+p(ij,l+1)))**kappa
254          theta_rhodz(ij,l) = temp(ij,l) * ((p(ij,l)-p(ij,l+1))/g) / pk_ij
[35]255        ENDDO
256      ENDDO
257    ENDDO
[295]258!$OMP BARRIER
[35]259   
260  END SUBROUTINE compute_temperature2theta_rhodz
261   
[12]262END MODULE theta2theta_rhodz_mod
Note: See TracBrowser for help on using the repository browser.