source: LMDZ6/branches/Portage_acc/libf/dyn3d/driver.F90 @ 4152

Last change on this file since 4152 was 4152, checked in by Ehouarn Millour, 2 years ago

Update Openacc directives for driver.
EM

File size: 15.4 KB
Line 
1PROGRAM driver
2
3  USE IOIPSL, ONLY: getin, ymds2ju, ioconf_calendar
4  USE mod_const_mpi, ONLY: COMM_LMDZ
5  USE control_mod, ONLY: planet_type, config_inca, offline
6  USE control_mod, ONLY: nday, day_step, iphysiq, dayref, anneeref
7  USE infotrac, ONLY: type_trac, nqtot, infotrac_init
8  USE temps_mod, ONLY: calend,start_time,annee_ref,day_ref
9  USE temps_mod, ONLY: itau_dyn,itau_phy,day_ini,jD_ref,jH_ref,day_end,year_len
10  USE comconst_mod, ONLY: cpp, kappa, daysec, dtphys, dtvr, g, r, rad
11  USE comconst_mod, ONLY: daylen, year_day, pi, omeg
12  USE logic_mod, ONLY: iflag_phys
13  USE comvert_mod, ONLY: preff, pa
14  USE inigeomphy_mod, ONLY: inigeomphy
15  USE iniphysiq_mod, ONLY: iniphysiq
16
17  IMPLICIT NONE
18
19  include "dimensions.h"
20  include "paramet.h"
21  include "comgeom.h"
22
23!  INTEGER :: step_per_day = 24 ! # of physics steps per day
24
25  INTEGER :: ngrid ! # of grid points on physics grid = 2+(jjm-1)*iim-1/jjm
26
27!  REAL, PARAMETER :: unjours=86400.,    & ! solar day in seconds
28!       &             radius=6.4e6,      & ! planetary radius
29!       &             g=9.8,             & ! gravity
30!       &             cpp=1004.,         & ! Cp
31!       &             kappa=296.945007/cpp ! R/Cp
32!  REAL :: timestep !=unjours/step_per_day ! physics time step (s)
33
34!  REAL :: psurf=1e5, ptop=1e4, Temp=250. ! initial values of surface pressure, temperature
35
36  ! dynamics (to load data from start.nc)
37  REAL,ALLOCATABLE :: ucov(:,:) ! covariant zonal wind
38  REAL,ALLOCATABLE :: vcov(:,:) ! covariant meridional wind
39  REAL,ALLOCATABLE :: teta(:,:) ! potential temperature
40  REAL,ALLOCATABLE :: q(:,:,:) ! tracers
41  REAL,ALLOCATABLE :: masse(:,:) ! air mass
42  REAL,ALLOCATABLE :: ps(:) ! surface pressure
43  REAL,ALLOCATABLE :: phis(:) ! surface geopotential
44  REAL :: time_0
45 
46  ! physics
47  REAL,ALLOCATABLE :: pplev(:,:)  ! pressure at interfaces
48  REAL,ALLOCATABLE :: pplay(:,:) ! pressure at full levels
49  REAL,ALLOCATABLE :: pphi(:,:) ! geopotential at full levels
50  REAL,ALLOCATABLE :: pphis(:) ! surface geopotential
51  REAL,ALLOCATABLE :: pt(:,:) ! temperature at full levels
52  REAL,ALLOCATABLE :: pu(:,:) ! zonal wind at full levels
53  REAL,ALLOCATABLE :: pv(:,:) ! meridional wind at full levels
54  REAL,ALLOCATABLE :: pq(:,:,:)! tracers
55  REAL,ALLOCATABLE :: pr(:,:) ! vorticity
56
57
58! 0. Preliminary stuff: read in parameters from run.def
59  call conf_gcm( 99, .TRUE.)
60!  call conf_planete
61 
62  daysec=86400. ! day length(s)
63  daylen=daysec
64  year_day=360 ! # days per year
65  rad=6.4e6 ! planet radius (m)
66  g=9.81 ! gravity
67  cpp=1004. ! Cp
68  r=287.05967 ! R
69  kappa=287.05967/cpp ! R/Cp
70  preff=101325.0
71  pa=preff/2.
72  pi=2.*asin(1.)
73  omeg=2.*pi/daysec*(1./daylen+1./year_day)
74 
75!  nday = 1 ! simulation lenght (days)
76!  CALL getin("nday",nday)
77  WRITE(*,*)"driver: nday=",nday
78 
79!  CALL getin("day_step",day_step)
80  WRITE(*,*)"driver: day_step=",day_step
81  dtphys=daysec/(day_step/iphysiq) ! physics time step (s)
82  dtvr=daysec/day_step
83  WRITE(*,*)"driver: timestep= dtphys=",dtphys
84 
85 
86 
87! 1. Initialize setup (geometry, physics)
88! 1.0. Parameters
89  planet_type="earth"
90  COMM_LMDZ=1
91  iflag_phys=1
92 
93
94! 1.1. Tracers-related
95  type_trac="lmdz"
96  config_inca="none"
97  offline=.false.
98 
99  call infotrac_init
100 
101  ! 1.2. Geometry
102
103!  CALL init_latlon(lat, lon)
104!  WRITE(*,*)"driver: LAT = " , minval(lat), maxval(lat)
105!  WRITE(*,*)"driver: LON = " , minval(lon), maxval(lon)
106  ! initialize dyn constants and geometry
107  CALL iniconst
108  CALL inigeom
109
110  ! 1.3. Initial conditions
111  ! dynamics
112  ALLOCATE(ucov(ip1jmp1,llm))
113  ALLOCATE(vcov(ip1jm,llm))
114  ALLOCATE(teta(ip1jmp1,llm))
115  ALLOCATE(q(ip1jmp1,llm,nqtot))
116  ALLOCATE(masse(ip1jmp1,llm))
117  ALLOCATE(ps(ip1jmp1))
118  ALLOCATE(phis(ip1jmp1))
119 
120  CALL dynetat0("start.nc",vcov,ucov,teta,q,masse,ps,phis,time_0)
121 
122
123  ! 1.3. Calendar
124!  annee_ref=2000
125!  dayref=1
126  if (calend == 'earth_360d' ) then
127    call ioconf_calendar('360d')
128  else
129    write(*,*) "potential calendar problem with IOIPSL!!"
130  endif
131  year_len=360
132
133!  annee_ref = anneeref
134!  day_ref = dayref
135!  day_ini = dayref
136  itau_dyn = 0
137  itau_phy = 0
138
139  ! Calendar
140!  call ymds2ju(annee_ref, mois, day_ref, heure, jD_ref)
141  call ymds2ju(annee_ref, 1, day_ref, 0., jD_ref)
142  jH_ref = jD_ref - int(jD_ref)
143  jD_ref = int(jD_ref)
144!  call ioconf_startdate(INT(jD_ref), jH_ref)
145 
146
147  day_end = day_ini + nday
148
149  ! 1.4. Initialize physics
150  ngrid=2+(jjm-1)*iim-1/jjm
151  write(*,*) "driver: ngrid=",ngrid
152  CALL iniphysiq(iim,jjm,llm, &
153          ngrid,comm_lmdz, &
154          daysec,day_ini,dtphys, &
155          rlatu,rlatv,rlonu,rlonv,aire,cu,cv,rad,g,r,cpp, &
156          iflag_phys)
157
158 
159! 2. Initialize fields on physics grid
160
161  ALLOCATE(pplev(ngrid,llm+1)) ! pressure at interfaces
162  ALLOCATE(pplay(ngrid,llm)) ! pressure at full levels
163  ALLOCATE(pphi(ngrid,llm)) ! geopotential at full levels
164  ALLOCATE(pphis(ngrid)) ! surface geopotential
165  ALLOCATE(pt(ngrid,llm)) ! temperature (K) at full levels
166  ALLOCATE(pu(ngrid,llm)) ! zonal wind (m/s) at full levels
167  ALLOCATE(pr(ngrid,llm)) ! relative vorticity
168  ALLOCATE(pv(ngrid,llm)) ! meridional wind at full levels
169  ALLOCATE(pq(ngrid,llm,nqtot)) ! tracers
170
171  !$acc data create(pplev, pplay, pphi, pphis, pt, pu, pv, pq, pr)
172
173  CALL init_temperature_pressure_geopot(ps,masse,teta,phis, &
174                                        ngrid,pplev,pplay,pphi,pphis,pt)
175  CALL init_winds_tracers(ucov,vcov,q,nqtot, &
176                          ngrid,pu,pv,pr,pq)
177
178! 3. Temporal loop 
179
180  CALL timeloop(ngrid,llm,nqtot,nday,day_step/iphysiq,dtphys,&
181                pplev,pplay,pphi,pphis,&
182                pu,pv,pr,pt,pq)
183
184  !$acc end data
185
186  write(*,*)"driver: Everything is cool :-)"
187
188CONTAINS
189
190!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
191
192   SUBROUTINE timeloop(ngrid,llm,nqtot,nday,calls_per_day,dtphys,&
193                pplev,pplay,pphi,pphis,&
194                pu,pv,pr,pt,pq)
195
196   USE comvert_mod, ONLY: presnivs
197   USE physiq_mod, ONLY: physiq
198   USE comconst_mod, ONLY: r
199   IMPLICIT NONE
200
201   INTEGER,INTENT(IN) :: ngrid ! # number of atmospheric columns
202   INTEGER,INTENT(IN) :: llm ! # number of vertical levels
203   INTEGER,INTENT(IN) :: nqtot ! # of tracers
204   INTEGER,INTENT(IN) :: nday ! # of days to run
205   INTEGER,INTENT(IN) :: calls_per_day ! # number of calls to physics per day
206   REAL,INTENT(IN) :: dtphys ! physics time step (s)
207   REAL,INTENT(INOUT) :: pplev(ngrid,llm+1) ! pressure at interfaces
208   REAL,INTENT(INOUT) :: pplay(ngrid,llm) ! pressure at mid-layer
209   REAL,INTENT(INOUT) :: pphi(ngrid,llm) ! geopotential at mid-layer
210   REAL,INTENT(INOUT) :: pphis(ngrid) ! surface geopotential
211   REAL,INTENT(INOUT) :: pu(ngrid,llm) ! zonal wind (m/s)
212   REAL,INTENT(INOUT) :: pv(ngrid,llm) ! meridional wind (m/s)
213   REAL,INTENT(INOUT) :: pr(ngrid,llm) ! relative vorticity
214   REAL,INTENT(INOUT) :: pt(ngrid,llm) ! temperature (K)
215   REAL,INTENT(INOUT) :: pq(ngrid,llm,nqtot) ! tracers
216   
217   LOGICAL,SAVE :: firstcall=.true.
218   LOGICAL,SAVE :: lastcall=.false.
219   REAL :: JD_cur ! Julian day
220   REAL :: JH_cur ! Julian hour (fraction of day)
221   ! tendencies from the physics
222   REAL :: pdu(ngrid,llm)
223   REAL :: pdv(ngrid,llm)
224   REAL :: pdt(ngrid,llm)
225   REAL :: pdq(ngrid,llm,nqtot)
226   REAL :: pdps(ngrid)
227   
228   INTEGER :: iday,istep
229   INTEGER :: ig,l
230   REAL :: rho,gdz
231
232   REAL :: flxw(ngrid,llm) ! vertical mass flux ! set to zero here.
233   REAL :: phi_top(ngrid)
234   !$acc data present(pplev,pplay,pphi,pphis,pu,pv,pt,pq) &
235   !$acc & create(phi_top,flxw,pdu,pdv,pdt,pdq,pdps)
236   
237   flxw(1:ngrid,1:llm)=0.
238   
239   DO iday=1,nday
240     JD_cur=iday
241     DO istep = 0, calls_per_day-1
242       JH_cur=istep/calls_per_day
243       if ((iday==nday).and.(istep==calls_per_day-1)) lastcall=.true.
244       CALL physiq(ngrid,llm,firstcall,lastcall,dtphys, &
245                   pplev,pplay,pphi,pphis, &
246                   presnivs, &
247                   pu,pv,pr,pt,pq,flxw, &
248                   pdu,pdv,pdt,pdq,pdps)
249       firstcall=.false.
250       
251       ! add increments sent back from physics:
252       !$acc kernels default(present)
253       pt(:,:)=pt(:,:)+dtphys*pdt(:,:)
254       pu(:,:)=pu(:,:)+dtphys*pdu(:,:)
255       pv(:,:)=pv(:,:)+dtphys*pdv(:,:)
256       pq(:,:,:)=pq(:,:,:)+dtphys*pdq(:,:,:)
257       
258       ! Recomputation of relative geopotential:
259       phi_top(:)=0
260       !$acc loop private(rho, gdz)
261       do l=1,llm
262         do ig=1,ngrid
263           ! rho=p/RT
264           rho=r*pplay(ig,l)/pt(ig,l)
265           gdz=(pplev(ig,l)-pplev(ig,l+1))/rho ! layer thickness * g
266           pphi(ig,l)=phi_top(ig)+0.5*gdz ! geopotential at mid-layer
267           phi_top(ig)=phi_top(ig)+gdz ! geopotential at layer top
268         enddo
269       enddo
270       !$acc end kernels
271       
272     ENDDO ! of DO istep = 0, day_step-1
273   ENDDO ! of DO iday=0,nday-1
274   
275   !$acc end data
276   
277   END SUBROUTINE timeloop
278
279
280!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
281
282   SUBROUTINE init_winds_tracers(ucov,vcov,q,nqtot, &
283                                 ngrid,pu,pv,pr,pq)
284
285    USE comconst_mod, ONLY: pi
286   
287    IMPLICIT NONE
288
289    include "dimensions.h"
290    include "paramet.h"
291    include "comgeom2.h"
292
293     REAL,INTENT(IN) :: ucov(iip1,jjp1,llm) ! covariant meridional velocity
294     REAL,INTENT(IN) :: vcov(iip1,jjm,llm) ! covariant zonal wind
295     REAL,INTENT(IN) :: q(iip1,jjp1,llm,nqtot) ! tracers
296     INTEGER,INTENT(IN) :: nqtot ! # of tracers
297     INTEGER,INTENT(IN) :: ngrid ! # of physics columns
298     REAL,INTENT(OUT) :: pu(ngrid,llm) ! zonal wind speed on physics grid
299     REAL,INTENT(OUT) :: pv(ngrid,llm) ! meridional wind speed on physics grid
300     REAL,INTENT(OUT) :: pr(ngrid,llm) ! vorticity on physics grid
301     REAL,INTENT(OUT) :: pq(ngrid,llm,nqtot) ! tracers on physics grid
302     
303     INTEGER :: i,j,l,iq,ig0
304     REAL :: rot(iim,jjm,llm) ! rot, on dynamics grid
305     REAL :: z1(iim),zsin(iim),zcos(iim)
306     REAL,EXTERNAL :: ssum
307     
308     ! 1. Compute zonal wind on physics grid
309     do l=1,llm
310       do j=2,jjm
311         ig0=1+(j-2)*iim
312         pu(ig0+1,l)=0.5*(ucov(iim,j,l)/cu(iim,j) + ucov(1,j,l)/cu(1,j))
313         do i=2,iim
314           pu(ig0+i,l)=0.5*(ucov(i-1,j,l)/cu(i-1,j) + ucov(i,j,l)/cu(i,j))
315         enddo
316       enddo ! of do j=2,jjm
317     enddo ! of do l=1,llm
318     
319     ! North pole: u = 1/pi * Integral[v * cos(long) * d long]
320     do l=1,llm
321       z1(1)=(rlonu(1)-rlonu(iim)+2.*pi)*vcov(1,1,l)/cv(1,1)
322       do i=2,iim
323         z1(i)=(rlonu(i)-rlonu(i-1))*vcov(i,1,l)/cv(i,1)
324       enddo
325       zcos(1:iim)=cos(rlonv(1:iim))*z1(1:iim)
326       pu(1,l)=ssum(iim,zcos,1)/pi
327     enddo ! of l=1,llm
328     
329     ! South pole: u = 1/pi * Integral[v * cos(long) * d long]
330     do l=1,llm
331       z1(1)=(rlonu(1)-rlonu(iim)+2.*pi)*vcov(1,jjm,l)/cv(1,jjm)
332       do i=2,iim
333         z1(i)=(rlonu(i)-rlonu(i-1))*vcov(i,jjm,l)/cv(i,jjm)
334       enddo
335       zcos(1:iim)=cos(rlonv(1:iim))*z1(1:iim)
336       pu(ngrid,l)=ssum(iim,zcos,1)/pi     
337     enddo ! of do l=1,llm
338     
339     
340     ! 2. Compute meridional wind on physics grid
341     do l=1,llm
342       do j=2,jjm
343         ig0=1+(j-2)*iim
344         do i=1,iim
345           pv(ig0+i,l)=0.5*(vcov(i,j-1,l)/cv(i,j-1) + vcov(i,j,l)/cv(i,j))
346         enddo
347       enddo ! of do j=2,jjm
348     enddo ! of do l=1,llm
349     
350     ! North pole: v = 1/pi * Integral[v * sin(long) * d long ]
351     do l=1,llm
352       z1(1)=(rlonu(1)-rlonu(iim)+2.*pi)*vcov(1,1,l)/cv(1,1)
353       do i=2,iim
354         z1(i)=(rlonu(i)-rlonu(i-1))*vcov(i,1,l)/cv(i,1)
355       enddo
356       zsin(1:iim)=sin(rlonv(1:iim))*z1(1:iim)
357       pv(1,l)=ssum(iim,zsin,1)/pi
358     enddo ! of l=1,llm
359     
360     ! South pole: v = 1/pi * Integral[v * sin(long) * d long ]
361     do l=1,llm
362       z1(1)=(rlonu(1)-rlonu(iim)+2.*pi)*vcov(1,jjm,l)/cv(1,jjm)
363       do i=2,iim
364         z1(i)=(rlonu(i)-rlonu(i-1))*vcov(i,jjm,l)/cv(i,jjm)
365       enddo
366       zsin(1:iim)=sin(rlonv(1:iim))*z1(1:iim)
367       pv(ngrid,l)=ssum(iim,zsin,1)/pi
368     enddo  ! of do l=1,llm
369     
370     
371     ! 3. Compute vorticity, first on dynamics grid
372     do l=1,llm
373       do i=1,iim
374         do j=1,jjm
375           rot(i,j,l)=(vcov(i+1,j,l)-vcov(i,j,l) + ucov(i,j+1,l)-ucov(i,j,l)) / &
376                      ((cu(i,j)+cu(i,j+1))*(cv(i+1,j)+cv(i,j))*4)
377         enddo
378       enddo ! of do i=1,iim
379     enddo  ! of do l=1,llm
380     
381     ! compute vorticity, on physics grid
382     do l=1,llm
383       ! North Pole:
384       pr(1,l)=0.
385       do j=2,jjm
386         ig0=1+(j-2)*iim
387         pr(ig0+1,l)=0.25*(rot(iim,j-1,l)+rot(iim,j,l)+ &
388                           rot(1,j-1,l)+rot(1,j,l))
389         do i=2,iim
390           pr(ig0+i,l)=0.25*(rot(i-1,j-1,l)+rot(i-1,j,l)+ &
391                             rot(i,j-1,l)+rot(i,j,l))
392         enddo
393       enddo ! of do j=2,jjm
394       ! South pole
395       pr(ngrid,l)=0.
396     enddo ! of do l=1,llm
397     
398     ! 4. Tracers, copy them over to the physics grid
399     do iq=1,nqtot
400       CALL gr_dyn_fi(llm,iip1,jjp1,ngrid,q(1,1,1,iq),pq(1,1,iq))
401     enddo
402     
403  END SUBROUTINE init_winds_tracers
404
405!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
406
407  SUBROUTINE init_temperature_pressure_geopot(ps,masse,teta,phis, &
408                                              ngrid,pplev,pplay,pphi,pphis,pt)
409
410    USE comvert_mod, ONLY: ap,bp
411    USE exner_hyb_m, ONLY: exner_hyb
412    USE comconst_mod, ONLY: cpp
413
414    IMPLICIT NONE
415
416    include "dimensions.h"
417    include "paramet.h"
418
419    REAL,INTENT(IN) :: ps(ip1jmp1)   ! surface pressure (Pa) on dyn grid
420    REAL,INTENT(IN) :: masse(ip1jmp1,llm) ! air mass on dyn. grid
421    REAL,INTENT(IN) :: teta(ip1jmp1,llm) ! potential temperature on dyn grid
422    REAL,INTENT(IN) :: phis(ip1jmp1)   ! surface geopotential on dyn grid
423    INTEGER,INTENT(IN) :: ngrid ! # of physics columns
424    REAL,INTENT(OUT) :: pplev(ngrid,llm+1) ! pressure at interfaces
425    REAL,INTENT(OUT) :: pplay(ngrid, llm) ! pressure at mid-layer
426    REAL,INTENT(OUT) :: pphi(ngrid, llm) ! geopotential phi=gz at mid-layer
427    REAL,INTENT(OUT) :: pphis(ngrid) ! surface geopotential
428    REAL,INTENT(OUT) :: pt(ngrid, llm) ! temperature at mid-layer
429
430    REAL :: p(ip1jmp1,llmp1) ! interlayer pressure on dynamics grid
431    REAL :: pks(ip1jmp1) ! Exner at the surface
432    REAL :: pk(ip1jmp1,llm) ! Exner at mid-layer
433    REAL :: phi(ip1jmp1,llm) ! Geopotential on dynamics grid
434   
435    REAL :: ppk(ngrid,llm) ! Exner at mid-layer on physics grid
436    REAL :: pteta(ngrid,llm) ! potential temperature on physics grid
437   
438    INTEGER :: ig,l
439
440    ! 1. Compute necessary intermediate variables on dynamics grid
441    ! Compute pressure on dynamics grid
442    CALL pression(ip1jmp1,ap,bp,ps,p)
443    ! Compute Exner on dynamics grid
444    CALL exner_hyb(ip1jmp1,ps,p,pks,pk)
445    ! Compute geopotential on dynamics grid
446    CALL geopot(ip1jmp1,teta,pk,pks,phis,phi)
447   
448    ! 2. Output fields, on physics grid
449   
450    ! Copy over p() to pplev()
451    CALL gr_dyn_fi(llm+1,iip1,jjp1,ngrid,p,pplev)
452   
453    ! Compute pplay() based on ab(),bp() and pplev(:,1) (surface pressure)
454    do ig=1,ngrid
455      pplay(ig,1:llm)=0.5*(ap(1:llm)+bp(1:llm)*pplev(ig,1)+&
456                           ap(2:llm+1)+bp(2:llm+1)*pplev(ig,1))
457    enddo
458   
459    ! Copy surface geopotential phis() to pphis()
460    CALL gr_dyn_fi(1,iip1,jjp1,ngrid,phis,pphis)
461   
462    ! Copy geopotential phi() to pphi()
463    CALL gr_dyn_fi(llm,iip1,jjp1,ngrid,phi,pphi)
464    ! and make pphi relative to surface
465    do l=1,llm
466      pphi(1:ngrid,l)=pphi(1:ngrid,l)-pphis(1:ngrid)
467    enddo
468   
469    ! Compute temperature from teta, on physics grid
470    CALL gr_dyn_fi(llm,iip1,jjp1,ngrid,pk,ppk)
471    CALL gr_dyn_fi(llm,iip1,jjp1,ngrid,teta,pteta)
472    do l=1,llm
473      pt(1:ngrid,l)=pteta(1:ngrid,l)*ppk(1:ngrid,l)/cpp
474    enddo
475   
476
477  END SUBROUTINE init_temperature_pressure_geopot
478
479END PROGRAM driver
Note: See TracBrowser for help on using the repository browser.