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

Last change on this file since 373 was 347, checked in by dubos, 9 years ago

Synced with aquaplanet branch HEAT@45 - tested with DCMIP4

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