source: codes/icosagcm/trunk/src/physics.f90 @ 495

Last change on this file since 495 was 481, checked in by ymipsl, 8 years ago

Physic column : OpenMP on vertical levsl is managed.

YM

File size: 11.2 KB
RevLine 
[81]1MODULE physics_mod
2
[196]3  USE field_mod
4
5  PRIVATE
6
[402]7  INTEGER, PARAMETER :: phys_none=0, phys_HS94=1, phys_DCMIP=2, phys_lmdz_generic=3, phys_LB2012=4, phys_external=5,&
8                        phys_DCMIP2016=6
[196]9
[213]10  INTEGER :: phys_type
[481]11  TYPE(t_field),POINTER,SAVE :: f_extra_physics_2D(:), f_extra_physics_3D(:)
12  TYPE(t_field),POINTER,SAVE :: f_dulon(:), f_dulat(:)
13  TYPE(t_field),POINTER,SAVE :: f_ulon(:), f_ulat(:)
14  TYPE(t_field),POINTER,SAVE :: f_p(:), f_pk(:)
15  TYPE(t_field),POINTER,SAVE :: f_temp(:)
[196]16
[481]17  CHARACTER(LEN=255),SAVE :: physics_type
[186]18!$OMP THREADPRIVATE(physics_type)
[81]19
[196]20  PUBLIC :: physics, init_physics
[213]21
[81]22CONTAINS
23
[98]24  SUBROUTINE init_physics
[178]25    USE mpipara
26    USE etat0_mod
[170]27    USE icosa
[196]28    USE physics_interface_mod
[215]29    USE physics_dcmip_mod, ONLY : init_physics_dcmip=>init_physics
[381]30    USE physics_dcmip2016_mod, ONLY : init_physics_dcmip2016=>init_physics
[325]31    USE etat0_venus_mod, ONLY : init_phys_venus=>init_physics
[327]32    USE physics_lmdz_generic_mod, ONLY : init_physics_lmdz_generic=>init_physics
[347]33    USE physics_external_mod, ONLY : init_physics_external=>init_physics
[170]34    IMPLICIT NONE
35
[217]36    physics_inout%dt_phys = dt*itau_physics
37    physics_type='none'
[81]38    CALL getin("physics",physics_type)
39    SELECT CASE(TRIM(physics_type))
[217]40    CASE ('none')
41       IF(is_mpi_root) PRINT*,"NO PHYSICAL PACKAGE USED"
42       phys_type = phys_none
43    CASE ('held_suarez')
44       phys_type = phys_HS94
[325]45    CASE ('Lebonnois2012')
46       phys_type = phys_LB2012
47       CALL init_phys_venus
[327]48
49    CASE ('phys_lmdz_generic')
50       CALL init_physics_lmdz_generic
51       phys_type=phys_lmdz_generic
[347]52    CASE ('phys_external')
53       CALL init_physics_external
54       phys_type=phys_external
[170]55    CASE ('dcmip')
[217]56       CALL allocate_field(f_dulon,field_t,type_real,llm, name='dulon')
57       CALL allocate_field(f_dulat,field_t,type_real,llm, name='dulat')
[295]58       CALL allocate_field(f_temp,field_t,type_real,llm, name='temp')
[481]59       CALL allocate_field(f_ulon,field_t,type_real,llm, name='ulon')
60       CALL allocate_field(f_ulat,field_t,type_real,llm, name='ulat')
61       CALL allocate_field(f_p,field_t,type_real,llm+1, name='p')
62       CALL allocate_field(f_pk,field_t,type_real,llm, name='pk')
[217]63       CALL init_pack_before ! Compute physics_inout%ngrid and offsets used by pack/unpack
[214]64       CALL init_physics_dcmip
[217]65       CALL init_pack_after ! Defines Ai, lon, lat in physics_inout
[196]66       phys_type = phys_DCMIP
[381]67    CASE ('dcmip2016')
68       CALL allocate_field(f_dulon,field_t,type_real,llm, name='dulon')
69       CALL allocate_field(f_dulat,field_t,type_real,llm, name='dulat')
70       CALL allocate_field(f_temp,field_t,type_real,llm, name='temp')
[481]71       CALL allocate_field(f_ulon,field_t,type_real,llm, name='ulon')
72       CALL allocate_field(f_ulat,field_t,type_real,llm, name='ulat')
73       CALL allocate_field(f_p,field_t,type_real,llm+1, name='p')
74       CALL allocate_field(f_pk,field_t,type_real,llm, name='pk')
[381]75       CALL init_pack_before ! Compute physics_inout%ngrid and offsets used by pack/unpack
76       CALL init_physics_dcmip2016
77       CALL init_pack_after ! Defines Ai, lon, lat in physics_inout
78       phys_type = phys_DCMIP2016
[170]79    CASE DEFAULT
[196]80       IF(is_mpi_root) PRINT*, 'init_physics : Bad selector for variable physics <',&
[347]81            TRIM(physics_type), '> options are <none>, <held_suarez>, <Lebonnois2012>, <dcmip>', &
82                                '<phys_lmdz_generic>, <phys_external>'
[170]83       STOP
[81]84    END SELECT
[170]85
[214]86    IF(is_mpi_root) PRINT *, 'phys_type = ',phys_type
[81]87  END SUBROUTINE init_physics
88
[327]89  SUBROUTINE physics(it,f_phis, f_ps, f_theta_rhodz, f_ue, f_wflux, f_q)
[170]90    USE icosa
[196]91    USE physics_interface_mod
[327]92    USE physics_lmdz_generic_mod, ONLY : physics_lmdz_generic => physics
[347]93    USE physics_external_mod, ONLY : physics_external => physics
[213]94    USE physics_dcmip_mod, ONLY : write_physics_dcmip => write_physics
[381]95    USE physics_dcmip2016_mod, ONLY : write_physics_dcmip2016 => write_physics
[170]96    USE etat0_heldsz_mod
[325]97    USE etat0_venus_mod, ONLY : phys_venus => physics
[170]98    IMPLICIT NONE
[99]99    INTEGER, INTENT(IN)   :: it
[81]100    TYPE(t_field),POINTER :: f_phis(:)
101    TYPE(t_field),POINTER :: f_ps(:)
102    TYPE(t_field),POINTER :: f_theta_rhodz(:)
103    TYPE(t_field),POINTER :: f_ue(:)
[327]104    TYPE(t_field),POINTER :: f_wflux(:)
[81]105    TYPE(t_field),POINTER :: f_q(:)
[196]106
[149]107    LOGICAL:: firstcall,lastcall
[196]108    INTEGER :: ind
[213]109    TYPE(t_physics_inout) :: args
[170]110
[281]111    IF(MOD(it,itau_physics)==0) THEN
[213]112   
113       SELECT CASE(phys_type)
114       CASE (phys_none)
115          ! No physics, do nothing
116       CASE(phys_HS94)
117          CALL held_suarez(f_ps,f_theta_rhodz,f_ue) 
[327]118       CASE (phys_lmdz_generic)
119         CALL physics_lmdz_generic(it ,f_phis, f_ps, f_theta_rhodz, f_ue, f_wflux, f_q)
[347]120       CASE (phys_external)
121         CALL physics_external(it ,f_phis, f_ps, f_theta_rhodz, f_ue, f_wflux, f_q)
[325]122       CASE(phys_LB2012)
123          CALL phys_venus(f_ps,f_theta_rhodz,f_ue) 
[213]124       CASE DEFAULT
[214]125          CALL physics_column(it, f_phis, f_ps, f_theta_rhodz, f_ue, f_q)
[213]126       END SELECT
[149]127
[213]128       CALL transfert_request(f_theta_rhodz,req_i0)
129       CALL transfert_request(f_ue,req_e0_vect)
130       CALL transfert_request(f_q,req_i0)
131    END IF
[149]132
[213]133    IF (mod(it,itau_out)==0 ) THEN
134       SELECT CASE(phys_type)
135       CASE (phys_DCMIP)
136          CALL write_physics_dcmip
[381]137       CASE (phys_DCMIP2016)
138          CALL write_physics_dcmip2016
[213]139       END SELECT
140    END IF
141   
142  END SUBROUTINE physics
143
[214]144  SUBROUTINE physics_column(it, f_phis, f_ps, f_theta_rhodz, f_ue, f_q)
[213]145    USE icosa
146    USE physics_interface_mod
147    USE physics_dcmip_mod, ONLY : full_physics_dcmip => full_physics
[381]148    USE physics_dcmip2016_mod, ONLY : full_physics_dcmip2016 => full_physics
[295]149    USE theta2theta_rhodz_mod
[281]150    USE mpipara
[481]151    USE omp_para
152    USE checksum_mod
[213]153    IMPLICIT NONE
154    TYPE(t_field),POINTER :: f_phis(:)
155    TYPE(t_field),POINTER :: f_ps(:)
156    TYPE(t_field),POINTER :: f_theta_rhodz(:)
157    TYPE(t_field),POINTER :: f_ue(:)
158    TYPE(t_field),POINTER :: f_q(:)
159    REAL(rstd),POINTER :: phis(:)
160    REAL(rstd),POINTER :: ps(:)
[295]161    REAL(rstd),POINTER :: temp(:,:)
[213]162    REAL(rstd),POINTER :: ue(:,:)
163    REAL(rstd),POINTER :: dulon(:,:)
164    REAL(rstd),POINTER :: dulat(:,:)
165    REAL(rstd),POINTER :: q(:,:,:)
[481]166    REAL(rstd),POINTER :: p(:,:)
167    REAL(rstd),POINTER :: pk(:,:)
168    REAL(rstd),POINTER :: ulon(:,:)
169    REAL(rstd),POINTER :: ulat(:,:)
[213]170    INTEGER :: it, ind
171
[295]172    CALL theta_rhodz2temperature(f_ps,f_theta_rhodz,f_temp)
[381]173   
[213]174    DO ind=1,ndomain
175       IF (.NOT. assigned_domain(ind)) CYCLE
176       CALL swap_dimensions(ind)
177       CALL swap_geometry(ind)
178       phis=f_phis(ind)
179       ps=f_ps(ind)
[295]180       temp=f_temp(ind)
[213]181       ue=f_ue(ind)
182       q=f_q(ind)
[481]183       p=f_p(ind)
184       pk=f_pk(ind)
185       ulon=f_ulon(ind)
186       ulat=f_ulat(ind)
187       CALL pack_physics(pack_info(ind), phis, ps, temp, ue, q, p, pk, ulon, ulat)
[213]188    END DO
189
190    SELECT CASE(phys_type)
191    CASE (phys_DCMIP)
[481]192       IF (is_omp_level_master) CALL full_physics_dcmip
[381]193    CASE (phys_DCMIP2016)
[481]194       IF (is_omp_level_master) CALL full_physics_dcmip2016
[281]195    CASE DEFAULT
[481]196       IF(is_master) PRINT *,'Internal error : illegal value of phys_type', phys_type
[281]197       STOP
[196]198    END SELECT
[170]199
[213]200    DO ind=1,ndomain
201       IF (.NOT. assigned_domain(ind)) CYCLE
202       CALL swap_dimensions(ind)
203       CALL swap_geometry(ind)
204       ps=f_ps(ind)
[295]205       temp=f_temp(ind)
[213]206       q=f_q(ind)
207       dulon=f_dulon(ind)
208       dulat=f_dulat(ind)
[295]209       CALL unpack_physics(pack_info(ind), ps, temp, q, dulon, dulat)
[213]210    END DO
[481]211   
[295]212    CALL temperature2theta_rhodz(f_ps,f_temp,f_theta_rhodz)
[170]213
[213]214    ! Transfer dulon, dulat
215    CALL transfert_request(f_dulon,req_i0)
216    CALL transfert_request(f_dulat,req_i0)
217
218    DO ind=1,ndomain
219       IF (.NOT. assigned_domain(ind)) CYCLE
220       CALL swap_dimensions(ind)
221       CALL swap_geometry(ind)
222       ue=f_ue(ind)
223       dulon=f_dulon(ind)
224       dulat=f_dulat(ind)
225       CALL compute_update_velocity(dulon, dulat, ue)
226    END DO
227
[214]228  END SUBROUTINE physics_column
[213]229
[481]230  SUBROUTINE pack_physics(info, phis, ps, temp, ue, q, p, pk, ulon, ulat )
[213]231    USE icosa
232    USE wind_mod
233    USE pression_mod
234    USE theta2theta_rhodz_mod
235    USE physics_interface_mod
[381]236    USE exner_mod
[481]237    USE omp_para
[213]238    IMPLICIT NONE
239    TYPE(t_pack_info) :: info
240    REAL(rstd) :: phis(iim*jjm)
241    REAL(rstd) :: ps(iim*jjm)
[295]242    REAL(rstd) :: temp(iim*jjm,llm)
[381]243    REAL(rstd) :: pks(iim*jjm)
244    REAL(rstd) :: pk(iim*jjm,llm)
[213]245    REAL(rstd) :: ue(3*iim*jjm,llm)
246    REAL(rstd) :: q(iim*jjm,llm,nqtot)
247
248    REAL(rstd) :: p(iim*jjm,llm+1)
249    REAL(rstd) :: uc(iim*jjm,3,llm)
250    REAL(rstd) :: ulon(iim*jjm,llm)
251    REAL(rstd) :: ulat(iim*jjm,llm)
252
[295]253!$OMP BARRIER
[213]254    CALL compute_pression(ps,p,0)
[295]255!$OMP BARRIER
[381]256    CALL compute_exner(ps,p,pks,pk,0) 
257!$OMP BARRIER
[213]258    CALL compute_wind_centered(ue,uc)
259    CALL compute_wind_centered_lonlat_compound(uc, ulon, ulat)
[481]260!$OMP BARRIER
261    IF (is_omp_level_master) THEN
262      CALL pack_domain(info, phis, physics_inout%phis)
263      CALL pack_domain(info, p, physics_inout%p)
264      CALL pack_domain(info, pk, physics_inout%pk)
265      CALL pack_domain(info, Temp, physics_inout%Temp)
266      CALL pack_domain(info, ulon, physics_inout%ulon)
267      CALL pack_domain(info, ulat, physics_inout%ulat)
268      CALL pack_domain(info, q, physics_inout%q)
269    ENDIF
270!$OMP BARRIER
[213]271  END SUBROUTINE pack_physics
272
[295]273  SUBROUTINE unpack_physics(info, ps,temp, q, dulon, dulat)
[213]274    USE icosa
275    USE physics_interface_mod
276    USE theta2theta_rhodz_mod
[481]277    USE omp_para
[213]278    IMPLICIT NONE
279    TYPE(t_pack_info) :: info
280    REAL(rstd) :: ps(iim*jjm)
[295]281    REAL(rstd) :: temp(iim*jjm,llm)
[213]282    REAL(rstd) :: q(iim*jjm,llm,nqtot)
283    REAL(rstd) :: dulon(iim*jjm,llm)
284    REAL(rstd) :: dulat(iim*jjm,llm)
285
286    REAL(rstd) :: dq(iim*jjm,llm,nqtot)
287    REAL(rstd) :: dTemp(iim*jjm,llm)
[481]288
289!$OMP BARRIER
290    IF (is_omp_level_master) THEN
291      CALL unpack_domain(info, dulon, physics_inout%dulon)
292      CALL unpack_domain(info, dulat, physics_inout%dulat)
293      CALL unpack_domain(info, dq, physics_inout%dq)
294      CALL unpack_domain(info, Temp, physics_inout%Temp)
295      CALL unpack_domain(info, dTemp, physics_inout%dTemp)
296      q = q + physics_inout%dt_phys * dq
297      Temp = Temp + physics_inout%dt_phys * dTemp
298    ENDIF
299!$OMP BARRIER
300
[295]301!    CALL compute_temperature2theta_rhodz(ps,Temp,theta_rhodz,0)
[213]302  END SUBROUTINE unpack_physics
303
304  SUBROUTINE compute_update_velocity(dulon, dulat, ue)
305    USE icosa
306    USE physics_interface_mod
307    USE wind_mod
[481]308    USE omp_para
[213]309    IMPLICIT NONE
310    REAL(rstd) :: dulon(iim*jjm,llm)
311    REAL(rstd) :: dulat(iim*jjm,llm)
312    REAL(rstd) :: ue(3*iim*jjm,llm)
313    REAL(rstd) :: duc(iim*jjm,3,llm)
314    REAL(rstd) :: dt2, due
315    INTEGER :: i,j,ij,l
316    ! Reconstruct wind tendencies at edges and add to normal wind
317    CALL compute_wind_centered_from_lonlat_compound(dulon,dulat,duc)
318    dt2=.5*physics_inout%dt_phys
[481]319    DO l=ll_begin,ll_end
[213]320      DO j=jj_begin,jj_end
321        DO i=ii_begin,ii_end
322          ij=(j-1)*iim+i
323          due = sum( (duc(ij,:,l) + duc(ij+t_right,:,l))*ep_e(ij+u_right,:) )
324          ue(ij+u_right,l) = ue(ij+u_right,l) + dt2*due
325
326          due = sum( (duc(ij,:,l) + duc(ij+t_lup,:,l))*ep_e(ij+u_lup,:) )
327          ue(ij+u_lup,l)=ue(ij+u_lup,l) + dt2*due
328
329          due = sum( (duc(ij,:,l) + duc(ij+t_ldown,:,l))*ep_e(ij+u_ldown,:) )
330          ue(ij+u_ldown,l)=ue(ij+u_ldown,l) + dt2*due
331        ENDDO
332      ENDDO
333    ENDDO
334  END SUBROUTINE compute_update_velocity
335
[81]336END MODULE physics_mod
Note: See TracBrowser for help on using the repository browser.