source: trunk/LMDZ.TITAN/libf/phytitan/physiq_mod.F90 @ 1971

Last change on this file since 1971 was 1967, checked in by jvatant, 7 years ago

Correct typos in r1966
--JVO

File size: 70.5 KB
Line 
1      module physiq_mod
2     
3      implicit none
4     
5      contains
6     
7      subroutine physiq(ngrid,nlayer,nq,   &
8                  nametrac,                &
9                  firstcall,lastcall,      &
10                  pday,ptime,ptimestep,    &
11                  pplev,pplay,pphi,        &
12                  pu,pv,pt,pq,             &
13                  flxw,                    &
14                  pdu,pdv,pdt,pdq,pdpsrf)
15 
16      use radinc_h, only : L_NSPECTI,L_NSPECTV
17      use radcommon_h, only: sigma, gzlat, gzlat_ig, Cmk, grav, BWNV
18      use surfdat_h, only: phisfi, zmea, zstd, zsig, zgam, zthe
19      use comchem_h, only: nkim, cnames, nlaykim_up, ykim_up, ykim_tot, botCH4
20      use comdiurn_h, only: coslat, sinlat, coslon, sinlon
21      use comsaison_h, only: mu0, fract, dist_star, declin, right_ascen
22      use comsoil_h, only: nsoilmx, layer, mlayer, inertiedat
23      use datafile_mod, only: datadir, corrkdir, banddir
24      use geometry_mod, only: latitude, longitude, cell_area
25      USE comgeomfi_h, only: totarea, totarea_planet
26      USE tracer_h
27      use time_phylmdz_mod, only: ecritphy, iphysiq, nday
28      use phyetat0_mod, only: phyetat0
29      use phyredem, only: physdem0, physdem1
30      use planetwide_mod, only: planetwide_minval,planetwide_maxval,planetwide_sumval
31      use mod_phys_lmdz_para, only : is_master
32      use planete_mod, only: apoastr, periastr, year_day, peri_day, &
33                            obliquit, nres, z0
34      use comcstfi_mod, only: pi, g, rcp, r, rad, mugaz, cpp
35      use time_phylmdz_mod, only: daysec
36      use logic_mod, only: moyzon_ch
37      use moyzon_mod, only:  zphibar, zphisbar, zplevbar, zplaybar, &
38                             zzlevbar, zzlaybar, ztfibar, zqfibar
39      use callkeys_mod
40      use vertical_layers_mod, only: presnivs, pseudoalt
41      use ioipsl_getin_p_mod, only: getin_p
42      use mod_phys_lmdz_omp_data, ONLY: is_omp_master
43#ifdef CPP_XIOS     
44      use xios_output_mod, only: initialize_xios_output, &
45                                 update_xios_timestep, &
46                                 send_xios_field
47      use wxios, only: wxios_context_init, xios_context_finalize
48#endif
49      use MMP_OPTICS
50      use muphy_diag
51      implicit none
52
53
54!==================================================================
55!     
56!     Purpose
57!     -------
58!     Central subroutine for all the physics parameterisations in the
59!     universal model. Originally adapted from the Mars LMDZ model.
60!
61!     The model can be run without or with tracer transport
62!     depending on the value of "tracer" in file "callphys.def".
63!
64!
65!   It includes:
66!
67!      I. Initialization :
68!         I.1 Firstcall initializations.
69!         I.2 Initialization for every call to physiq.
70!
71!      II. Compute radiative transfer tendencies (longwave and shortwave) :
72!         II.a Option 1 : Call correlated-k radiative transfer scheme.
73!         II.b Option 2 : Call Newtonian cooling scheme.
74!         II.c Option 3 : Atmosphere has no radiative effect.
75!
76!      III. Vertical diffusion (turbulent mixing) :
77!
78!      IV. Dry Convective adjustment :
79!
80!      V. Tracers
81!         V.1. Microphysics
82!         V.2. Chemistry
83!         V.3. Updates (pressure variations, surface budget).
84!         V.4. Surface Tracer Update.
85!
86!      VI. Surface and sub-surface soil temperature.
87!
88!      VII. Perform diagnostics and write output files.
89!
90!
91!   arguments
92!   ---------
93!
94!   INPUT
95!   -----
96!
97!    ngrid                 Size of the horizontal grid.
98!    nlayer                Number of vertical layers.
99!    nq                    Number of advected fields.
100!    nametrac              Name of corresponding advected fields.
101!
102!    firstcall             True at the first call.
103!    lastcall              True at the last call.
104!
105!    pday                  Number of days counted from the North. Spring equinoxe.
106!    ptime                 Universal time (0<ptime<1): ptime=0.5 at 12:00 UT.
107!    ptimestep             timestep (s).
108!
109!    pplay(ngrid,nlayer)   Pressure at the middle of the layers (Pa).
110!    pplev(ngrid,nlayer+1) Intermediate pressure levels (Pa).
111!    pphi(ngrid,nlayer)    Geopotential at the middle of the layers (m2.s-2).
112!
113!    pu(ngrid,nlayer)      u, zonal component of the wind (ms-1).
114!    pv(ngrid,nlayer)      v, meridional component of the wind (ms-1).
115!
116!    pt(ngrid,nlayer)      Temperature (K).
117!
118!    pq(ngrid,nlayer,nq)   Advected fields.
119!
120!    pudyn(ngrid,nlayer)    \
121!    pvdyn(ngrid,nlayer)     \ Dynamical temporal derivative for the
122!    ptdyn(ngrid,nlayer)     / corresponding variables.
123!    pqdyn(ngrid,nlayer,nq) /
124!    flxw(ngrid,nlayer)      vertical mass flux (kg/s) at layer lower boundary
125!
126!   OUTPUT
127!   ------
128!
129!    pdu(ngrid,nlayer)        \
130!    pdv(ngrid,nlayer)         \  Temporal derivative of the corresponding
131!    pdt(ngrid,nlayer)         /  variables due to physical processes.
132!    pdq(ngrid,nlayer)        /
133!    pdpsrf(ngrid)             /
134!
135!
136!     Authors
137!     -------
138!           Frederic Hourdin        15/10/93
139!           Francois Forget        1994
140!           Christophe Hourdin        02/1997
141!           Subroutine completely rewritten by F. Forget (01/2000)
142!           Water ice clouds: Franck Montmessin (update 06/2003)
143!           Radiatively active tracers: J.-B. Madeleine (10/2008-06/2009)
144!           New correlated-k radiative scheme: R. Wordsworth (2009)
145!           Many specifically Martian subroutines removed: R. Wordsworth (2009)       
146!           Improved water cycle: R. Wordsworth / B. Charnay (2010)
147!           To F90: R. Wordsworth (2010)
148!           New turbulent diffusion scheme: J. Leconte (2012)
149!           Loops converted to F90 matrix format: J. Leconte (2012)
150!           No more ngridmx/nqmx, F90 commons and adaptation to parallel: A. Spiga (2012)
151!           Purge of the code : M. Turbet (2015)
152!           Fork for Titan : J. Vatant d'Ollone (2017)
153!                + clean of all too-generic (ocean, water, co2 ...) routines
154!                + Titan's chemistry
155!           Microphysical moment model - J.Burgalat / J.Vatant d'Ollone (2017-2018)
156!============================================================================================
157
158
159!    0.  Declarations :
160!    ------------------
161
162include "netcdf.inc"
163
164! Arguments :
165! -----------
166
167!   INPUTS:
168!   -------
169
170
171      integer,intent(in) :: ngrid             ! Number of atmospheric columns.
172      integer,intent(in) :: nlayer            ! Number of atmospheric layers.
173      integer,intent(in) :: nq                ! Number of tracers.
174      character*20,intent(in) :: nametrac(nq) ! Names of the tracers taken from dynamics.
175     
176      logical,intent(in) :: firstcall ! Signals first call to physics.
177      logical,intent(in) :: lastcall  ! Signals last call to physics.
178     
179      real,intent(in) :: pday                  ! Number of elapsed sols since reference Ls=0.
180      real,intent(in) :: ptime                 ! "Universal time", given as fraction of sol (e.g.: 0.5 for noon).
181      real,intent(in) :: ptimestep             ! Physics timestep (s).
182      real,intent(in) :: pplev(ngrid,nlayer+1) ! Inter-layer pressure (Pa).
183      real,intent(in) :: pplay(ngrid,nlayer)   ! Mid-layer pressure (Pa).
184      real,intent(in) :: pphi(ngrid,nlayer)    ! Geopotential at mid-layer (m2s-2).
185      real,intent(in) :: pu(ngrid,nlayer)      ! Zonal wind component (m/s).
186      real,intent(in) :: pv(ngrid,nlayer)      ! Meridional wind component (m/s).
187      real,intent(in) :: pt(ngrid,nlayer)      ! Temperature (K).
188      real,intent(in) :: pq(ngrid,nlayer,nq)   ! Tracers (kg/kg_of_air).
189      real,intent(in) :: flxw(ngrid,nlayer)    ! Vertical mass flux (ks/s) at lower boundary of layer
190
191!   OUTPUTS:
192!   --------
193
194!     Physical tendencies :
195
196      real,intent(out) :: pdu(ngrid,nlayer)    ! Zonal wind tendencies (m/s/s).
197      real,intent(out) :: pdv(ngrid,nlayer)    ! Meridional wind tendencies (m/s/s).
198      real,intent(out) :: pdt(ngrid,nlayer)    ! Temperature tendencies (K/s).
199      real,intent(out) :: pdq(ngrid,nlayer,nq) ! Tracer tendencies (kg/kg_of_air/s).
200      real,intent(out) :: pdpsrf(ngrid)        ! Surface pressure tendency (Pa/s).
201
202! Local saved variables:
203! ----------------------
204
205      integer,save :: day_ini                                      ! Initial date of the run (sol since Ls=0).
206      integer,save :: icount                                       ! Counter of calls to physiq during the run.
207!$OMP THREADPRIVATE(day_ini,icount)
208
209      real, dimension(:),allocatable,save ::  tsurf                ! Surface temperature (K).
210      real, dimension(:,:),allocatable,save ::  tsoil              ! Sub-surface temperatures (K).
211      real, dimension(:,:),allocatable,save :: albedo              ! Surface Spectral albedo. By MT2015.
212      real, dimension(:),allocatable,save :: albedo_equivalent     ! Spectral Mean albedo.
213     
214!$OMP THREADPRIVATE(tsurf,tsoil,albedo,albedo_equivalent)
215
216      real,dimension(:),allocatable,save :: albedo_bareground ! Bare Ground Albedo. By MT 2015.
217     
218!$OMP THREADPRIVATE(albedo_bareground)
219
220      real,dimension(:),allocatable,save :: emis        ! Thermal IR surface emissivity.
221      real,dimension(:,:),allocatable,save :: dtrad     ! Net atmospheric radiative heating rate (K.s-1).
222      real,dimension(:),allocatable,save :: fluxrad_sky ! Radiative flux from sky absorbed by surface (W.m-2).
223      real,dimension(:),allocatable,save :: fluxrad     ! Net radiative surface flux (W.m-2).
224      real,dimension(:),allocatable,save :: capcal      ! Surface heat capacity (J m-2 K-1).
225      real,dimension(:),allocatable,save :: fluxgrd     ! Surface conduction flux (W.m-2).
226      real,dimension(:,:),allocatable,save :: qsurf     ! Tracer on surface (e.g. kg.m-2).
227      real,dimension(:,:),allocatable,save :: q2        ! Turbulent Kinetic Energy.
228     
229!$OMP THREADPRIVATE(emis,dtrad,fluxrad_sky,fluxrad,capcal,fluxgrd,qsurf,q2)
230
231
232! Local variables :
233! -----------------
234
235      real zh(ngrid,nlayer)               ! Potential temperature (K).
236      real pw(ngrid,nlayer)               ! Vertical velocity (m/s). (NOTE : >0 WHEN DOWNWARDS !!)
237
238      integer l,ig,ierr,iq,nw,isoil
239     
240      ! FOR DIAGNOSTIC :
241     
242      real,dimension(:),allocatable,save :: fluxsurf_lw     ! Incident Long Wave (IR) surface flux (W.m-2).
243      real,dimension(:),allocatable,save :: fluxsurf_sw     ! Incident Short Wave (stellar) surface flux (W.m-2).
244      real,dimension(:),allocatable,save :: fluxsurfabs_sw  ! Absorbed Short Wave (stellar) flux by the surface (W.m-2).
245      real,dimension(:),allocatable,save :: fluxtop_lw      ! Outgoing LW (IR) flux to space (W.m-2).
246      real,dimension(:),allocatable,save :: fluxabs_sw      ! Absorbed SW (stellar) flux (W.m-2).
247      real,dimension(:),allocatable,save :: fluxtop_dn      ! Incoming SW (stellar) radiation at the top of the atmosphere (W.m-2).
248      real,dimension(:),allocatable,save :: fluxdyn         ! Horizontal heat transport by dynamics (W.m-2).
249      real,dimension(:,:),allocatable,save :: OLR_nu        ! Outgoing LW radiation in each band (Normalized to the band width (W/m2/cm-1)).
250      real,dimension(:,:),allocatable,save :: OSR_nu        ! Outgoing SW radiation in each band (Normalized to the band width (W/m2/cm-1)).
251      real,dimension(:,:),allocatable,save :: zdtlw         ! LW heating tendencies (K/s).
252      real,dimension(:,:),allocatable,save :: zdtsw         ! SW heating tendencies (K/s).
253      real,dimension(:),allocatable,save :: sensibFlux      ! Turbulent flux given by the atmosphere to the surface (W.m-2).
254     
255!$OMP THREADPRIVATE(fluxsurf_lw,fluxsurf_sw,fluxsurfabs_sw,fluxtop_lw,fluxabs_sw,fluxtop_dn,fluxdyn,OLR_nu,OSR_nu,&
256       
257        !$OMP zdtlw,zdtsw,sensibFlux)
258
259      real zls                       ! Solar longitude (radians).
260      real zlss                      ! Sub solar point longitude (radians).
261      real zday                      ! Date (time since Ls=0, calculated in sols).
262      real zzlay(ngrid,nlayer)       ! Altitude at the middle of the atmospheric layers.
263      real zzlev(ngrid,nlayer+1)     ! Altitude at the atmospheric layer boundaries.
264
265! TENDENCIES due to various processes :
266
267      ! For Surface Temperature : (K/s)
268      real zdtsurf(ngrid)     ! Cumulated tendencies.
269      real zdtsurfmr(ngrid)   ! Mass_redistribution routine.
270      real zdtsdif(ngrid)     ! Turbdiff/vdifc routines.
271           
272      ! For Atmospheric Temperatures : (K/s)   
273      real zdtdif(ngrid,nlayer)                               ! Turbdiff/vdifc routines.
274      real zdtmr(ngrid,nlayer)                                ! Mass_redistribution routine.
275      real zdtsw1(ngrid,nlayer), zdtlw1(ngrid,nlayer)         ! Callcorrk routine.
276                             
277      ! For Surface Tracers : (kg/m2/s)
278      real dqsurf(ngrid,nq)                 ! Cumulated tendencies.
279      real zdqsdif(ngrid,nq)                ! Turbdiff/vdifc routines.
280      real zdqsurfmr(ngrid,nq)              ! Mass_redistribution routine.
281                 
282      ! For Tracers : (kg/kg_of_air/s)
283      real zdqadj(ngrid,nlayer,nq)    ! Convadj routine.
284      real zdqdif(ngrid,nlayer,nq)    ! Turbdiff/vdifc routines.
285      real zdqevap(ngrid,nlayer)      ! Turbdiff routine.
286      real zdqmr(ngrid,nlayer,nq)     ! Mass_redistribution routine.
287     
288      real zdqchi(ngrid,nlayer,nq)    ! Chemical tendency ( chemistry routine ).
289     
290      real zdqmufi(ngrid,nlayer,nq)   ! Microphysical tendency.
291     
292      real zdqfibar(ngrid,nlayer,nq)   ! For 2D chemistry
293      real zdqmufibar(ngrid,nlayer,nq) ! For 2D chemistry
294                       
295      ! For Winds : (m/s/s)
296      real zdvadj(ngrid,nlayer),zduadj(ngrid,nlayer) ! Convadj routine.
297      real zdumr(ngrid,nlayer),zdvmr(ngrid,nlayer)   ! Mass_redistribution routine.
298      real zdvdif(ngrid,nlayer),zdudif(ngrid,nlayer) ! Turbdiff/vdifc routines.
299      real zdhdif(ngrid,nlayer)                      ! Turbdiff/vdifc routines.
300      real zdhadj(ngrid,nlayer)                      ! Convadj routine.
301     
302      ! For Pressure and Mass :
303      real zdmassmr(ngrid,nlayer) ! Atmospheric Mass tendency for mass_redistribution (kg_of_air/m2/s).
304      real zdmassmr_col(ngrid)    ! Atmospheric Column Mass tendency for mass_redistribution (kg_of_air/m2/s).
305      real zdpsrfmr(ngrid)        ! Pressure tendency for mass_redistribution routine (Pa/s).
306
307     
308   
309! Local variables for LOCAL CALCULATIONS:
310! ---------------------------------------
311      real zflubid(ngrid)
312      real zplanck(ngrid),zpopsk(ngrid,nlayer)
313      real ztim1,ztim2,ztim3, z1,z2
314      real ztime_fin
315      real zdh(ngrid,nlayer)
316      real gmplanet
317      real taux(ngrid),tauy(ngrid)
318
319
320
321! local variables for DIAGNOSTICS : (diagfi & stat)
322! -------------------------------------------------
323      real ps(ngrid)                                     ! Surface Pressure.
324      real zt(ngrid,nlayer)                              ! Atmospheric Temperature.
325      real zu(ngrid,nlayer),zv(ngrid,nlayer)             ! Zonal and Meridional Winds.
326      real zq(ngrid,nlayer,nq)                           ! Atmospheric Tracers.
327      real zdtadj(ngrid,nlayer)                          ! Convadj Diagnostic.
328      real zdtdyn(ngrid,nlayer)                          ! Dynamical Heating (K/s).
329      real zdudyn(ngrid,nlayer)                          ! Dynamical Zonal Wind tendency (m.s-2).
330      real,allocatable,dimension(:,:),save :: ztprevious ! Previous loop Atmospheric Temperature (K)                                                         ! Useful for Dynamical Heating calculation.
331      real,allocatable,dimension(:,:),save :: zuprevious ! Previous loop Zonal Wind (m.s-1)                                                                  ! Useful for Zonal Wind tendency calculation.
332!$OMP THREADPRIVATE(ztprevious,zuprevious)
333
334      real vmr(ngrid,nlayer)                        ! volume mixing ratio
335      real time_phys
336     
337      real ISR,ASR,OLR,GND,DYN,GSR,Ts1,Ts2,Ts3,TsS ! for Diagnostic.
338     
339!     to test energy conservation (RW+JL)
340      real mass(ngrid,nlayer),massarea(ngrid,nlayer)
341      real dEtot, dEtots, AtmToSurf_TurbFlux
342      real,save :: dEtotSW, dEtotsSW, dEtotLW, dEtotsLW
343!$OMP THREADPRIVATE(dEtotSW, dEtotsSW, dEtotLW, dEtotsLW)
344      real dEzRadsw(ngrid,nlayer),dEzRadlw(ngrid,nlayer),dEzdiff(ngrid,nlayer)
345      real dEdiffs(ngrid),dEdiff(ngrid)
346     
347!JL12 conservation test for mean flow kinetic energy has been disabled temporarily
348
349      real dItot, dItot_tmp, dVtot, dVtot_tmp
350     
351      real dWtot, dWtot_tmp, dWtots, dWtots_tmp
352     
353     
354      ! For Clear Sky Case.
355      real fluxsurf_lw1(ngrid), fluxsurf_sw1(ngrid), fluxsurfabs_sw1(ngrid)  ! For SW/LW flux.
356      real fluxtop_lw1(ngrid), fluxabs_sw1(ngrid)                            ! For SW/LW flux.
357      real albedo_equivalent1(ngrid)                                         ! For Equivalent albedo calculation.
358      real tf, ntf   
359
360      real,allocatable,dimension(:,:),save :: qsurf_hist
361!$OMP THREADPRIVATE(qsurf_hist)
362   
363      ! Miscellaneous :
364      character(len=10) :: tmp1
365      character(len=10) :: tmp2
366
367! Local variables for Titan chemistry and microphysics
368! ----------------------------------------------------
369 
370      real,save :: ctimestep ! Chemistry timestep (s)
371!$OMP THREADPRIVATE(ctimestep)
372 
373      ! Chemical tracers in molar fraction
374      real, dimension(ngrid,nlayer,nkim)          :: ychim ! (mol/mol)
375      real, dimension(ngrid,nlayer,nkim)          :: ychimbar ! For 2D chemistry
376
377      ! Molar fraction tendencies ( chemistry, condensation and evaporation ) for tracers (mol/mol/s)
378      real, dimension(:,:,:), allocatable, save   :: dycchi         ! NB : Only for chem tracers. Saved since chemistry is not called every step.
379!$OMP THREADPRIVATE(dycchi)
380      real, dimension(ngrid,nlayer,nq)            :: dyccond        ! Condensation rate. NB : for all tracers, as we want to use indx on it.
381      real, dimension(ngrid,nlayer,nq)            :: dyccondbar     ! For 2D chemistry
382      real, dimension(ngrid)                      :: dycevapCH4     ! Surface "pseudo-evaporation" rate (forcing constant surface humidity).
383
384      ! Saturation profiles
385      real, dimension(ngrid,nlayer,nkim)          :: ysat ! (mol/mol)
386
387      ! Surface methane
388      real, dimension(:), allocatable, save       :: tankCH4    ! Depth of surface methane tank (m)
389!$OMP THREADPRIVATE(tankCH4)
390
391
392      ! -----******----- FOR MUPHYS OPTICS -----******-----
393      integer :: i,j
394      real :: pqo(ngrid,nlayer,nq)   ! Tracers for the optics (X/m2).
395      ! -----******----- END FOR MUPHYS OPTICS -----******-----
396
397      real :: i2e(ngrid,nlayer)      ! int 2 ext factor ( X.kg-1 -> X.m-3 or X.m-2 , depending if optics or diags )
398
399      real,save,dimension(:,:,:), allocatable :: tpq ! Tracers for decoupled microphysical tests ( temporary in 01/18 )
400!$OMP THREADPRIVATE(tpq)
401      real,dimension(ngrid,nlayer,nq) :: dtpq ! (temporary in 01/18)
402
403
404!-----------------------------------------------------------------------------
405    ! Interface to calmufi
406    !   --> needed in order to pass assumed-shape arrays. Otherwise we must put calmufi in a module
407    !       (to have an explicit interface generated by the compiler).
408    !   Or one can put calmufi in MMP_GCM module (in muphytitan).
409    INTERFACE
410      SUBROUTINE calmufi(dt, plev, zlev, play, zlay, g3d, temp, pq, zdqfi, zdq)
411        REAL(kind=8), INTENT(IN)                 :: dt    !! Physics timestep (s).
412        REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: plev  !! Pressure levels (Pa).
413        REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: zlev  !! Altitude levels (m).
414        REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: play  !! Pressure layers (Pa).
415        REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: zlay  !! Altitude at the center of each layer (m).
416        REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: g3d   !! Latitude-Altitude depending gravitational acceleration (m.s-2).
417        REAL(kind=8), DIMENSION(:,:), INTENT(IN) :: temp  !! Temperature at the center of each layer (K). 
418        REAL(kind=8), DIMENSION(:,:,:), INTENT(IN)  :: pq    !! Tracers (\(kg.kg^{-1}}\)).
419        REAL(kind=8), DIMENSION(:,:,:), INTENT(IN)  :: zdqfi !! Tendency from former processes for tracers (\(kg.kg^{-1}}\)).
420        REAL(kind=8), DIMENSION(:,:,:), INTENT(OUT) :: zdq   !! Microphysical tendency for tracers (\(kg.kg^{-1}}\)).
421      END SUBROUTINE calmufi
422    END INTERFACE
423     
424!==================================================================================================
425
426! -----------------
427! I. INITIALISATION
428! -----------------
429
430! --------------------------------
431! I.1   First Call Initialisation.
432! --------------------------------
433      if (firstcall) then
434        allocate(tpq(ngrid,nlayer,nq))
435        tpq(:,:,:) = pq(:,:,:)
436
437        ! Initialisation of nmicro as well as tracers names, indexes ...
438        if (ngrid.ne.1) then ! Already done in rcm1d
439           call initracer2(nq,nametrac) ! WARNING JB (27/03/2018): should be wrapped in an OMP SINGLE statement (see module notes)
440        endif
441
442        ! Allocate saved arrays.
443        ALLOCATE(tsurf(ngrid))
444        ALLOCATE(tsoil(ngrid,nsoilmx))   
445        ALLOCATE(albedo(ngrid,L_NSPECTV))
446        ALLOCATE(albedo_equivalent(ngrid))       
447        ALLOCATE(albedo_bareground(ngrid))               
448        ALLOCATE(emis(ngrid))   
449        ALLOCATE(dtrad(ngrid,nlayer))
450        ALLOCATE(fluxrad_sky(ngrid))
451        ALLOCATE(fluxrad(ngrid))   
452        ALLOCATE(capcal(ngrid))   
453        ALLOCATE(fluxgrd(ngrid)) 
454        ALLOCATE(qsurf(ngrid,nq)) 
455        ALLOCATE(q2(ngrid,nlayer+1))
456        ALLOCATE(tankCH4(ngrid))
457        ALLOCATE(ztprevious(ngrid,nlayer))
458        ALLOCATE(zuprevious(ngrid,nlayer))
459        ALLOCATE(qsurf_hist(ngrid,nq))
460        ALLOCATE(fluxsurf_lw(ngrid))
461        ALLOCATE(fluxsurf_sw(ngrid))
462        ALLOCATE(fluxsurfabs_sw(ngrid))
463        ALLOCATE(fluxtop_lw(ngrid))
464        ALLOCATE(fluxabs_sw(ngrid))
465        ALLOCATE(fluxtop_dn(ngrid))
466        ALLOCATE(fluxdyn(ngrid))
467        ALLOCATE(OLR_nu(ngrid,L_NSPECTI))
468        ALLOCATE(OSR_nu(ngrid,L_NSPECTV))
469        ALLOCATE(sensibFlux(ngrid))
470        ALLOCATE(zdtlw(ngrid,nlayer))
471        ALLOCATE(zdtsw(ngrid,nlayer))
472 
473        ! This is defined in comsaison_h
474        ALLOCATE(mu0(ngrid))
475        ALLOCATE(fract(ngrid))           
476         ! This is defined in radcommon_h
477        ALLOCATE(gzlat(ngrid,nlayer))
478        ALLOCATE(gzlat_ig(nlayer))
479        ALLOCATE(Cmk(nlayer))         
480
481!        Variables set to 0
482!        ~~~~~~~~~~~~~~~~~~
483         dtrad(:,:) = 0.0
484         fluxrad(:) = 0.0
485         zdtsw(:,:) = 0.0
486         zdtlw(:,:) = 0.0
487
488!        Initialize setup for correlated-k radiative transfer
489!        JVO 17 : Was in callcorrk firstcall, but we need spectral intervals for microphysics
490!        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
491
492         if (corrk) then
493         
494           call system('rm -f surf_vals_long.out')
495
496           write( tmp1, '(i3)' ) L_NSPECTI
497           write( tmp2, '(i3)' ) L_NSPECTV
498           banddir=trim(adjustl(tmp1))//'x'//trim(adjustl(tmp2))
499           banddir=trim(adjustl(corrkdir))//'/'//trim(adjustl(banddir))
500
501           call setspi            ! Basic infrared properties.
502           call setspv            ! Basic visible properties.
503           call sugas_corrk       ! Set up gaseous absorption properties.
504         
505           OLR_nu(:,:) = 0.
506           OSR_nu(:,:) = 0.
507           
508         endif
509
510!        Initialize names and timestep for chemistry
511!        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
512
513         if ( callchim ) then
514
515            if ( moyzon_ch .and. ngrid.eq.1 ) then
516               print *, "moyzon_ch=",moyzon_ch," and ngrid=1"
517               print *, "Please desactivate zonal mean for 1D !"
518               stop
519            endif
520
521            allocate(dycchi(ngrid,nlayer,nkim)) ! only for chemical tracers
522           
523            ! Chemistry timestep
524            ctimestep = ptimestep*REAL(ichim)
525
526            zdqchi(:,:,:)  = 0.0
527
528         endif
529
530!        Initialize microphysics.
531!        ~~~~~~~~~~~~~~~~~~~~~~~~
532
533         IF ( callmufi ) THEN
534           ! WARNING JB (27/03/2018): inimufi AND mmp_initialize_optics should be wrapped in an OMP SINGLE statement.
535           call inimufi(ptimestep)
536           ! Optical coupling of YAMMS is plugged but inactivated for now
537           ! as long as the microphysics only isn't fully debugged -- JVO 01/18
538           ! NOTE JB (03/18): mmp_optic_file is initialized in inimufi => mmp_initialize_optics must be called AFTER inimufi
539           IF (.NOT.uncoupl_optic_haze) call mmp_initialize_optics(mmp_optic_file)
540
541           ! initialize microphysics diagnostics arrays.
542           call ini_diag_arrays(ngrid,nlayer,nice)
543
544         ENDIF
545
546
547#ifdef CPP_XIOS
548        ! Initialize XIOS context
549        write(*,*) "physiq: call wxios_context_init"
550        CALL wxios_context_init
551#endif
552
553!        Read 'startfi.nc' file.
554!        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
555         call phyetat0(startphy_file,ngrid,nlayer,"startfi.nc",0,0,nsoilmx,nq,      &
556                       day_ini,time_phys,tsurf,tsoil,emis,q2,qsurf,tankCH4)                       
557         if (.not.startphy_file) then
558           ! additionnal "academic" initialization of physics
559           if (is_master) write(*,*) "Physiq: initializing tsurf(:) to pt(:,1) !!"
560           tsurf(:)=pt(:,1)
561           if (is_master) write(*,*) "Physiq: initializing tsoil(:) to pt(:,1) !!"
562           do isoil=1,nsoilmx
563             tsoil(:,isoil)=tsurf(:)
564           enddo
565           if (is_master) write(*,*) "Physiq: initializing day_ini to pdat !"
566           day_ini=pday
567         endif
568
569         if (pday.ne.day_ini) then
570           write(*,*) "ERROR in physiq.F90:"
571           write(*,*) "bad synchronization between physics and dynamics"
572           write(*,*) "dynamics day: ",pday
573           write(*,*) "physics day:  ",day_ini
574           stop
575         endif
576         write (*,*) 'In physiq day_ini =', day_ini
577
578!        Initialize albedo calculation.
579!        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
580         albedo(:,:)=0.0
581          albedo_bareground(:)=0.0
582         call surfini(ngrid,nq,qsurf,albedo,albedo_bareground)
583         
584!        Initialize orbital calculation.
585!        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
586         call iniorbit(apoastr,periastr,year_day,peri_day,obliquit)
587
588         if(tlocked)then
589            print*,'Planet is tidally locked at resonance n=',nres
590            print*,'Make sure you have the right rotation rate!!!'
591         endif
592
593
594!        Initialize soil.
595!        ~~~~~~~~~~~~~~~~
596         if (callsoil) then
597         
598            call soil(ngrid,nsoilmx,firstcall,lastcall,inertiedat, &
599                      ptimestep,tsurf,tsoil,capcal,fluxgrd)
600
601         else ! else of 'callsoil'.
602         
603            print*,'WARNING! Thermal conduction in the soil turned off'
604            capcal(:)=1.e6
605            fluxgrd(:)=intheat
606            print*,'Flux from ground = ',intheat,' W m^-2'
607           
608         endif ! end of 'callsoil'.
609         
610         icount=1
611           
612
613!        Initialize surface history variable.
614!        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
615         qsurf_hist(:,:)=qsurf(:,:)
616
617!        Initialize variable for dynamical heating and zonal wind tendency diagnostic
618!        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
619         ztprevious(:,:)=pt(:,:)
620         zuprevious(:,:)=pu(:,:)
621
622
623         if(meanOLR)then         
624            call system('rm -f rad_bal.out') ! to record global radiative balance.           
625            call system('rm -f tem_bal.out') ! to record global mean/max/min temperatures.           
626            call system('rm -f h2o_bal.out') ! to record global hydrological balance.
627         endif
628
629         if (ngrid.ne.1) then
630            ! Note : no need to create a restart file in 1d.
631            call physdem0("restartfi.nc",longitude,latitude,nsoilmx,ngrid,nlayer,nq, &
632                          ptimestep,pday+nday,time_phys,cell_area,          &
633                          albedo_bareground,inertiedat,zmea,zstd,zsig,zgam,zthe)
634         endif
635         
636         ! XIOS outputs
637#ifdef CPP_XIOS
638
639         write(*,*) "physiq: call initialize_xios_output"
640         call initialize_xios_output(pday,ptime,ptimestep,daysec, &
641                                     presnivs,pseudoalt)
642#endif
643         write(*,*) "physiq: end of firstcall"
644      endif ! end of 'firstcall'
645
646! ------------------------------------------------------
647! I.2   Initializations done at every physical timestep:
648! ------------------------------------------------------
649
650#ifdef CPP_XIOS     
651      ! update XIOS time/calendar
652      call update_xios_timestep
653#endif     
654
655      ! Initialize various variables
656      ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
657
658      pdt(:,:)    = 0.0     
659      zdtsurf(:)  = 0.0
660      pdq(:,:,:)  = 0.0
661      dqsurf(:,:) = 0.0
662      pdu(:,:)    = 0.0
663      pdv(:,:)    = 0.0
664      pdpsrf(:)   = 0.0
665      zflubid(:)  = 0.0     
666      taux(:)     = 0.0
667      tauy(:)     = 0.0
668
669      zday=pday+ptime ! Compute time, in sols (and fraction thereof).
670
671      ! Compute Stellar Longitude (Ls), and orbital parameters.
672      ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
673      if (season) then
674         call stellarlong(zday,zls)
675      else
676         call stellarlong(float(day_ini),zls)
677      end if
678
679      call orbite(zls,dist_star,declin,right_ascen)
680     
681      if (tlocked) then
682              zlss=Mod(-(2.*pi*(zday/year_day)*nres - right_ascen),2.*pi)
683      elseif (diurnal) then
684              zlss=-2.*pi*(zday-.5)
685      else if(diurnal .eqv. .false.) then
686              zlss=9999.
687      endif
688
689
690      ! Compute variations of g with latitude (oblate case).
691      ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
692      if (oblate .eqv. .false.) then     
693         gzlat(:,:) = g         
694      else if (flatten .eq. 0.0 .or. J2 .eq. 0.0 .or. Rmean .eq. 0.0 .or. MassPlanet .eq. 0.0) then     
695         print*,'I need values for flatten, J2, Rmean and MassPlanet to compute gzlat (else set oblate=.false.)'
696         call abort
697      else
698         gmplanet = MassPlanet*grav*1e24
699         do ig=1,ngrid
700            gzlat(ig,:)= gmplanet/(Rmean**2) * (1.D0 + 0.75 *J2 - 2.0*flatten/3. + (2.*flatten - 15./4.* J2) * cos(2. * (pi/2. - latitude(ig))))
701         end do
702      endif
703     
704      ! Compute altitudes with the geopotential coming from the dynamics.
705      ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
706
707      if (eff_gz .eqv. .false.) then
708     
709        do l=1,nlayer         
710           zzlay(:,l) = pphi(:,l) / gzlat(:,l)
711        enddo
712       
713      else ! In this case we consider variations of g with altitude
714     
715        do l=1,nlayer
716           zzlay(:,l) = g*rad*rad / ( g*rad - pphi(:,l) ) - rad
717           gzlat(:,l) = g*rad*rad / ( rad + zzlay(:,l) )**2
718        end do
719     
720      endif ! if eff_gz
721
722      zzlev(:,1)=0.
723      zzlev(:,nlayer+1)=1.e7 ! Dummy top of last layer above 10000 km...
724
725      do l=2,nlayer
726         do ig=1,ngrid
727            z1=(pplay(ig,l-1)+pplev(ig,l))/(pplay(ig,l-1)-pplev(ig,l))
728            z2=(pplev(ig,l)+pplay(ig,l))/(pplev(ig,l)-pplay(ig,l))
729            zzlev(ig,l)=(z1*zzlay(ig,l-1)+z2*zzlay(ig,l))/(z1+z2)
730         enddo
731      enddo     
732
733      ! Zonal averages needed for chemistry
734      ! ~~~~~~~ Taken from old Titan ~~~~~~
735      if (moyzon_ch) then
736         
737         if (eff_gz .eqv. .false.) then
738           zzlaybar(1,:)=(zphibar(1,:)+zphisbar(1))/g
739         else ! if we take into account effective altitude-dependent gravity field
740           zzlaybar(1,:)=g*rad*rad/(g*rad-(zphibar(1,:)+zphisbar(1)))-rad
741         endif
742         zzlevbar(1,1)=zphisbar(1)/g       
743         DO l=2,nlayer
744            z1=(zplaybar(1,l-1)+zplevbar(1,l))/(zplaybar(1,l-1)-zplevbar(1,l))
745            z2=(zplevbar(1,l)  +zplaybar(1,l))/(zplevbar(1,l)  -zplaybar(1,l))
746            zzlevbar(1,l)=(z1*zzlaybar(1,l-1)+z2*zzlaybar(1,l))/(z1+z2)
747         ENDDO
748         zzlevbar(1,nlayer+1)=zzlaybar(1,nlayer)+(zzlaybar(1,nlayer)-zzlevbar(1,nlayer))
749
750         DO ig=2,ngrid
751            if (latitude(ig).ne.latitude(ig-1)) then       
752               DO l=1,nlayer   
753                  if (eff_gz .eqv. .false.) then
754                    zzlaybar(ig,l)=(zphibar(ig,l)+zphisbar(ig))/g
755                  else ! if we take into account effective altitude-dependent gravity field
756                    zzlaybar(ig,l)=g*rad*rad/(g*rad-(zphibar(ig,l)+zphisbar(ig)))-rad
757                  endif           
758               ENDDO
759               zzlevbar(ig,1)=zphisbar(ig)/g
760               DO l=2,nlayer
761                  z1=(zplaybar(ig,l-1)+zplevbar(ig,l))/ (zplaybar(ig,l-1)-zplevbar(ig,l))
762                  z2=(zplevbar(ig,l)  +zplaybar(ig,l))/(zplevbar(ig,l)  -zplaybar(ig,l))
763                  zzlevbar(ig,l)=(z1*zzlaybar(ig,l-1)+z2*zzlaybar(ig,l))/(z1+z2)
764               ENDDO
765               zzlevbar(ig,nlayer+1)=zzlaybar(ig,nlayer)+(zzlaybar(ig,nlayer)-zzlevbar(ig,nlayer))         
766            else
767               zzlaybar(ig,:)=zzlaybar(ig-1,:)
768               zzlevbar(ig,:)=zzlevbar(ig-1,:)
769            endif         
770         ENDDO
771
772      endif  ! moyzon
773
774      ! -------------------------------------------------------------------------------------
775      ! Compute potential temperature
776      ! Note : Potential temperature calculation may not be the same in physiq and dynamic...
777      ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
778      do l=1,nlayer         
779         do ig=1,ngrid
780            zpopsk(ig,l)=(pplay(ig,l)/pplev(ig,1))**rcp
781            zh(ig,l)=pt(ig,l)/zpopsk(ig,l)
782            mass(ig,l)  = (pplev(ig,l) - pplev(ig,l+1))/gzlat(ig,l)
783            massarea(ig,l)=mass(ig,l)*cell_area(ig)
784         enddo
785      enddo
786
787     ! Compute vertical velocity (m/s) from vertical mass flux
788     ! w = F / (rho*area) and rho = P/(r*T)
789     ! But first linearly interpolate mass flux to mid-layers
790      do l=1,nlayer-1
791         pw(:,l)=0.5*(flxw(:,l)+flxw(:,l+1))
792      enddo
793      pw(:,nlayer)=0.5*flxw(:,nlayer) ! since flxw(nlayer+1)=0
794      do l=1,nlayer
795         pw(:,l)=(pw(:,l)*r*pt(:,l)) / (pplay(:,l)*cell_area(:))
796      enddo
797
798!---------------------------------
799! II. Compute radiative tendencies
800!---------------------------------
801
802      if (callrad) then
803         if( mod(icount-1,iradia).eq.0.or.lastcall) then
804
805          ! Compute local stellar zenith angles
806          ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
807            if (tlocked) then
808            ! JL14 corrects tidally resonant (and inclined) cases. nres=omega_rot/omega_orb
809               ztim1=SIN(declin)
810               ztim2=COS(declin)*COS(zlss)
811               ztim3=COS(declin)*SIN(zlss)
812
813               call stelang(ngrid,sinlon,coslon,sinlat,coslat,    &
814                            ztim1,ztim2,ztim3,mu0,fract, flatten)
815
816            elseif (diurnal) then
817               ztim1=SIN(declin)
818               ztim2=COS(declin)*COS(2.*pi*(zday-.5))
819               ztim3=-COS(declin)*SIN(2.*pi*(zday-.5))
820
821               call stelang(ngrid,sinlon,coslon,sinlat,coslat,    &
822                            ztim1,ztim2,ztim3,mu0,fract, flatten)
823            else if(diurnal .eqv. .false.) then
824
825               call mucorr(ngrid,declin,latitude,mu0,fract,10000.,rad,flatten)
826               ! WARNING: this function appears not to work in 1D
827
828            endif
829           
830            ! Eclipse incoming sunlight (e.g. Saturn ring shadowing).       
831            if(rings_shadow) then
832                call call_rings(ngrid, ptime, pday, diurnal)
833            endif   
834
835
836            if (corrk) then
837           
838! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
839! II.a Call correlated-k radiative transfer scheme
840! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
841
842               call call_profilgases(nlayer)
843
844               ! Convert (microphysical) tracers for optics: X.kg-1 --> X.m-2_
845               ! NOTE: it should be moved somewhere else: calmufi performs the same kind of
846               ! computations... waste of time...
847               i2e(:,1:nlayer) = ( pplev(:,1:nlayer)-pplev(:,2:nlayer+1) ) / gzlat(:,1:nlayer)
848               pqo(:,:,:) = 0.0
849               DO j=1,nmicro-nice
850                 pqo(:,:,j) = pq(:,:,j)*i2e(:,:)
851               ENDDO
852
853               ! standard callcorrk
854               call callcorrk(ngrid,nlayer,pqo,nq,qsurf,                          &
855                              albedo,albedo_equivalent,emis,mu0,pplev,pplay,pt,   &
856                              tsurf,fract,dist_star,                              &
857                              zdtlw,zdtsw,fluxsurf_lw,fluxsurf_sw,                &
858                              fluxsurfabs_sw,fluxtop_lw,                          &
859                              fluxabs_sw,fluxtop_dn,OLR_nu,OSR_nu,                &
860                              lastcall)
861
862               ! Radiative flux from the sky absorbed by the surface (W.m-2).
863               GSR=0.0
864               fluxrad_sky(:)=emis(:)*fluxsurf_lw(:)+fluxsurfabs_sw(:)
865
866                            !if(noradsurf)then ! no lower surface; SW flux just disappears
867                            !   GSR = SUM(fluxsurf_sw(:)*cell_area(:))/totarea
868                            !   fluxrad_sky(:)=emis(:)*fluxsurf_lw(:)
869                            !   print*,'SW lost in deep atmosphere = ',GSR,' W m^-2'
870                            !endif
871
872               ! Net atmospheric radiative heating rate (K.s-1)
873               dtrad(:,:)=zdtsw(:,:)+zdtlw(:,:)
874               
875            elseif(newtonian)then
876           
877! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
878! II.b Call Newtonian cooling scheme
879! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
880               call newtrelax(ngrid,nlayer,mu0,sinlat,zpopsk,pt,pplay,pplev,dtrad,firstcall)
881
882               zdtsurf(:) = +(pt(:,1)-tsurf(:))/ptimestep
883               ! e.g. surface becomes proxy for 1st atmospheric layer ?
884
885            else
886           
887! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
888! II.c Atmosphere has no radiative effect
889! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
890               fluxtop_dn(:)  = fract(:)*mu0(:)*Fat1AU/dist_star**2
891               if(ngrid.eq.1)then ! / by 4 globally in 1D case...
892                  fluxtop_dn(1)  = fract(1)*Fat1AU/dist_star**2/2.0
893               endif
894               fluxsurf_sw(:) = fluxtop_dn(:)
895               print*,'------------WARNING---WARNING------------' ! by MT2015.
896               print*,'You are in corrk=false mode, '
897               print*,'and the surface albedo is taken equal to the first visible spectral value'               
898               
899               fluxsurfabs_sw(:) = fluxtop_dn(:)*(1.-albedo(:,1))
900               fluxrad_sky(:)    = fluxsurfabs_sw(:)
901               fluxtop_lw(:)     = emis(:)*sigma*tsurf(:)**4
902
903               dtrad(:,:)=0.0 ! no atmospheric radiative heating
904
905            endif ! end of corrk
906
907         endif ! of if(mod(icount-1,iradia).eq.0)
908       
909
910         ! Transformation of the radiative tendencies
911         ! ------------------------------------------
912         zplanck(:)=tsurf(:)*tsurf(:)
913         zplanck(:)=emis(:)*sigma*zplanck(:)*zplanck(:)
914         fluxrad(:)=fluxrad_sky(:)-zplanck(:)
915         pdt(:,:)=pdt(:,:)+dtrad(:,:)
916         
917         ! Test of energy conservation
918         !----------------------------
919         if(enertest)then
920            call planetwide_sumval(cpp*massarea(:,:)*zdtsw(:,:)/totarea_planet,dEtotSW)
921            call planetwide_sumval(cpp*massarea(:,:)*zdtlw(:,:)/totarea_planet,dEtotLW)
922            !call planetwide_sumval(fluxsurf_sw(:)*(1.-albedo_equivalent(:))*cell_area(:)/totarea_planet,dEtotsSW) !JL13 carefull, albedo can have changed since the last time we called corrk
923            call planetwide_sumval(fluxsurfabs_sw(:)*cell_area(:)/totarea_planet,dEtotsSW) !JL13 carefull, albedo can have changed since the last time we called corrk
924            call planetwide_sumval((fluxsurf_lw(:)*emis(:)-zplanck(:))*cell_area(:)/totarea_planet,dEtotsLW)
925            dEzRadsw(:,:)=cpp*mass(:,:)*zdtsw(:,:)
926            dEzRadlw(:,:)=cpp*mass(:,:)*zdtlw(:,:)
927            if (is_master) then
928               print*,'---------------------------------------------------------------'
929               print*,'In corrk SW atmospheric heating       =',dEtotSW,' W m-2'
930               print*,'In corrk LW atmospheric heating       =',dEtotLW,' W m-2'
931               print*,'atmospheric net rad heating (SW+LW)   =',dEtotLW+dEtotSW,' W m-2'
932               print*,'In corrk SW surface heating           =',dEtotsSW,' W m-2'
933               print*,'In corrk LW surface heating           =',dEtotsLW,' W m-2'
934               print*,'surface net rad heating (SW+LW)       =',dEtotsLW+dEtotsSW,' W m-2'
935            endif
936         endif ! end of 'enertest'
937
938      endif ! of if (callrad)
939
940
941
942!  --------------------------------------------
943!  III. Vertical diffusion (turbulent mixing) :
944!  --------------------------------------------
945
946      if (calldifv) then
947     
948         zflubid(:)=fluxrad(:)+fluxgrd(:)
949
950         ! JL12 the following if test is temporarily there to allow us to compare the old vdifc with turbdiff.
951         if (UseTurbDiff) then
952         
953            call turbdiff(ngrid,nlayer,nq,                       &
954                          ptimestep,capcal,lwrite,               &
955                          pplay,pplev,zzlay,zzlev,z0,            &
956                          pu,pv,pt,zpopsk,pq,tsurf,emis,qsurf,   &
957                          pdt,pdq,zflubid,                       &
958                          zdudif,zdvdif,zdtdif,zdtsdif,          &
959                          sensibFlux,q2,zdqdif,zdqsdif,          &
960                          taux,tauy,lastcall)
961
962         else
963         
964            zdh(:,:)=pdt(:,:)/zpopsk(:,:)
965 
966            call vdifc(ngrid,nlayer,nq,zpopsk,                &
967                       ptimestep,capcal,lwrite,               &
968                       pplay,pplev,zzlay,zzlev,z0,            &
969                       pu,pv,zh,pq,tsurf,emis,qsurf,          &
970                       zdh,pdq,zflubid,                       &
971                       zdudif,zdvdif,zdhdif,zdtsdif,          &
972                       sensibFlux,q2,zdqdif,zdqsdif,          &
973                       taux,tauy,lastcall)
974
975            zdtdif(:,:)=zdhdif(:,:)*zpopsk(:,:) ! for diagnostic only
976            zdqevap(:,:)=0.
977
978         end if !end of 'UseTurbDiff'
979
980
981         pdv(:,:)=pdv(:,:)+zdvdif(:,:)
982         pdu(:,:)=pdu(:,:)+zdudif(:,:)
983         pdt(:,:)=pdt(:,:)+zdtdif(:,:)
984         zdtsurf(:)=zdtsurf(:)+zdtsdif(:)
985
986         if (tracer) then
987           pdq(:,:,:)=pdq(:,:,:)+ zdqdif(:,:,:)
988           dqsurf(:,:)=dqsurf(:,:) + zdqsdif(:,:)
989         end if ! of if (tracer)
990
991
992         ! test energy conservation
993         !-------------------------
994         if(enertest)then
995         
996            dEzdiff(:,:)=cpp*mass(:,:)*zdtdif(:,:)
997            do ig = 1, ngrid
998               dEdiff(ig)=SUM(dEzdiff (ig,:))+ sensibFlux(ig)! subtract flux to the ground
999               dEzdiff(ig,1)= dEzdiff(ig,1)+ sensibFlux(ig)! subtract flux to the ground
1000            enddo
1001           
1002            call planetwide_sumval(dEdiff(:)*cell_area(:)/totarea_planet,dEtot)
1003            dEdiffs(:)=capcal(:)*zdtsdif(:)-zflubid(:)-sensibFlux(:)
1004            call planetwide_sumval(dEdiffs(:)*cell_area(:)/totarea_planet,dEtots)
1005            call planetwide_sumval(sensibFlux(:)*cell_area(:)/totarea_planet,AtmToSurf_TurbFlux)
1006           
1007            if (is_master) then
1008           
1009               if (UseTurbDiff) then
1010                         print*,'In TurbDiff sensible flux (atm=>surf) =',AtmToSurf_TurbFlux,' W m-2'
1011                         print*,'In TurbDiff non-cons atm nrj change   =',dEtot,' W m-2'
1012                  print*,'In TurbDiff (correc rad+latent heat) surf nrj change =',dEtots,' W m-2'
1013               else
1014                         print*,'In vdifc sensible flux (atm=>surf)    =',AtmToSurf_TurbFlux,' W m-2'
1015                         print*,'In vdifc non-cons atm nrj change      =',dEtot,' W m-2'
1016                         print*,'In vdifc (correc rad+latent heat) surf nrj change =',dEtots,' W m-2'
1017               end if
1018            endif ! end of 'is_master'
1019           
1020         ! JL12 : note that the black body radiative flux emitted by the surface has been updated by the implicit scheme but not given back elsewhere.
1021         endif ! end of 'enertest'
1022
1023      else ! calldifv
1024
1025         if(.not.newtonian)then
1026
1027            zdtsurf(:) = zdtsurf(:) + (fluxrad(:) + fluxgrd(:))/capcal(:)
1028
1029         endif
1030
1031      endif ! end of 'calldifv'
1032
1033
1034!----------------------------------
1035!   IV. Dry convective adjustment :
1036!----------------------------------
1037
1038      if(calladj) then
1039
1040         zdh(:,:) = pdt(:,:)/zpopsk(:,:)
1041         zduadj(:,:)=0.0
1042         zdvadj(:,:)=0.0
1043         zdhadj(:,:)=0.0
1044
1045
1046         call convadj(ngrid,nlayer,nq,ptimestep,            &
1047                      pplay,pplev,zpopsk,                   &
1048                      pu,pv,zh,pq,                          &
1049                      pdu,pdv,zdh,pdq,                      &
1050                      zduadj,zdvadj,zdhadj,                 &
1051                      zdqadj)
1052
1053         pdu(:,:) = pdu(:,:) + zduadj(:,:)
1054         pdv(:,:) = pdv(:,:) + zdvadj(:,:)
1055         pdt(:,:)    = pdt(:,:) + zdhadj(:,:)*zpopsk(:,:)
1056         zdtadj(:,:) = zdhadj(:,:)*zpopsk(:,:) ! for diagnostic only
1057
1058         if(tracer) then
1059            pdq(:,:,:) = pdq(:,:,:) + zdqadj(:,:,:)
1060         end if
1061
1062         ! Test energy conservation
1063         if(enertest)then
1064            call planetwide_sumval(cpp*massarea(:,:)*zdtadj(:,:)/totarea_planet,dEtot)
1065            if (is_master) print*,'In convadj atmospheric energy change  =',dEtot,' W m-2'
1066         endif
1067
1068         
1069      endif ! end of 'calladj'
1070     
1071
1072!---------------------------------------------
1073!   V. Specific parameterizations for tracers
1074!---------------------------------------------
1075
1076      if (tracer) then
1077
1078  ! -------------------
1079  !   V.1 Microphysics
1080  ! -------------------
1081
1082         ! JVO 05/18 : We must call microphysics before chemistry, for condensation !
1083 
1084         if (callmufi) then
1085#ifdef USE_QTEST
1086            dtpq(:,:,:) = 0.0 ! we want tpq to go only through mufi
1087            call calmufi(ptimestep,pplev,zzlev,pplay,zzlay,gzlat,pt,tpq,dtpq,zdqmufi)
1088            tpq(:,:,:) = tpq(:,:,:) + zdqmufi(:,:,:)*ptimestep ! only manipulation of tpq->*ptimestep here
1089#else
1090            call calmufi(ptimestep,pplev,zzlev,pplay,zzlay,gzlat,pt,pq,pdq,zdqmufi)
1091            pdq(:,:,:) = pdq(:,:,:) + zdqmufi(:,:,:)
1092#endif
1093
1094            ! Microphysics condensation for 2D fields to sent non-saturated fields to photochem
1095            if ( callclouds .and. moyzon_ch .and. mod(icount-1,ichim).eq.0 ) then
1096              zdqfibar(:,:,:) = 0.0 ! We work in zonal average -> forget processes other than condensation
1097              call calmufi(ptimestep,zplevbar,zzlevbar,zplaybar,zzlaybar, &
1098                           gzlat,ztfibar,zqfibar,zdqfibar,zdqmufibar)
1099            endif
1100
1101         endif
1102     
1103  ! -----------------
1104  !   V.2. Chemistry
1105  ! -----------------
1106  !   NB : Must be call last ( brings fields back to an equilibrium )
1107
1108  ! Known bug ? ( JVO 18 ) : If you try to use chimi_indx instead of iq+nmicro
1109  ! it leads to weird results / crash on dev mod ( ok in debug ) ... Why ? Idk ...
1110
1111         if (callchim) then
1112
1113            ! o. Convert updated tracers to molar fraction
1114            ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1115            do iq = 1,nkim
1116               ychim(:,:,iq) = ( pq(:,:,iq+nmicro) + pdq(:,:,iq+nmicro) ) / rat_mmol(iq+nmicro)
1117            enddo
1118
1119            ! JVO 05/18 : We update zonally averaged fields with condensation
1120            ! as it is compulsory to have correct photochem production. But for other
1121            ! processes ( convadj ... ) we miss them in any case as we work in zonally/diurnal
1122            ! mean -> no fine diurnal/short time evolution, only seasonal evolution only.
1123            if ( moyzon_ch .and. mod(icount-1,ichim).eq. 0 ) then
1124              do iq = 1,nkim
1125                ychimbar(:,:,iq) =  zqfibar(:,:,iq+nmicro) / rat_mmol(iq+nmicro)
1126                  if ( callclouds ) then
1127                    ychimbar(:,:,iq) =  ychimbar(:,:,iq) + ( zdqmufibar(:,:,iq+nmicro) / rat_mmol(iq+nmicro) )
1128                  endif
1129              enddo
1130            endif
1131
1132            ! i. Condensation of the 3D tracers after the transport
1133            ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1134           
1135            call calc_ysat(ngrid,nlayer,pplay/100.0,pt,ysat) ! Compute saturation profiles for every grid point
1136
1137            dyccond(:,:,:) = 0.0 ! Default value -> no condensation
1138
1139            do iq=1,nkim
1140               where ( ychim(:,:,iq).gt.ysat(:,:,iq) )   &
1141                     dyccond(:,:,iq+nmicro) = ( -ychim(:,:,iq)+ysat(:,:,iq) ) / ptimestep
1142            enddo
1143
1144            if ( callclouds ) dyccond(:,:,ices_indx) = 0.0 ! Condensation have been calculated in the cloud microphysics
1145
1146            do iq=1,nkim
1147              ychim(:,:,iq) = ychim(:,:,iq) + dyccond(:,:,iq+nmicro) ! update molar ychim for following calchim
1148
1149              pdq(:,:,iq+nmicro) = pdq(:,:,iq+nmicro) + dyccond(:,:,iq+nmicro)*rat_mmol(iq+nmicro) ! convert tendencies to mass mixing ratio
1150            enddo
1151           
1152
1153            ! ii. 2D zonally averaged fields need to condense and evap before photochem
1154            ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1155            if ( moyzon_ch .and. mod(icount-1,ichim).eq. 0 ) then
1156
1157              call calc_ysat(ngrid,nlayer,zplaybar/100.0,ztfibar,ysat) ! Compute saturation profiles for every grid point for the zon-ave fields
1158
1159              dyccondbar(:,:,:) = 0.0 ! Default value -> no condensation
1160             
1161              do iq = 1,nkim
1162                 where ( ychimbar(:,:,iq).gt.ysat(:,:,iq) )  &
1163                       dyccondbar(:,:,iq+nmicro) = ( -ychimbar(:,:,iq)+ysat(:,:,iq) ) / ptimestep
1164              enddo
1165
1166              if ( callclouds ) dyccondbar(:,:,ices_indx) = 0.0 ! Condensation have been calculated in the cloud microphysics
1167
1168              do iq=1,nkim
1169                ychimbar(:,:,iq) = ychimbar(:,:,iq) + dyccondbar(:,:,iq+nmicro)
1170              enddo
1171
1172              ! Pseudo-evap ( forcing constant surface humidity )
1173              do ig=1,ngrid
1174                 if ( ychimbar(ig,1,7+nmicro) .lt. botCH4 ) ychimbar(ig,1,7+nmicro) = botCH4
1175              enddo
1176
1177            endif ! if ( moyzon_ch .and. mod(icount-1,ichim).eq. 0 )
1178
1179            ! iii. Photochemistry ( must be call after condensation (and evap of 2D) )
1180            ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1181            if( mod(icount-1,ichim).eq.0. ) then
1182               
1183               print *, "We enter in the chemistry ..."
1184
1185               if (moyzon_ch) then ! 2D zonally averaged chemistry
1186
1187                 ! Here we send zonal average fields ( corrected with cond ) from dynamics to chem. module
1188                 call calchim(ngrid,ychimbar,declin,ctimestep,ztfibar,zphibar,  &
1189                              zplaybar,zplevbar,zzlaybar,zzlevbar,dycchi)
1190               else ! 3D chemistry (or 1D run)
1191                 call calchim(ngrid,ychim,declin,ctimestep,pt,pphi,  &
1192                              pplay,pplev,zzlay,zzlev,dycchi)
1193               endif ! if moyzon
1194
1195            endif
1196           
1197            ! iv. Surface pseudo-evaporation
1198            ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1199            do ig=1,ngrid
1200               if ( (ychim(ig,1,7+nmicro)+dycchi(ig,1,7+nmicro)*ptimestep) .lt. botCH4 ) then ! +dycchi because ychim not yet updated
1201                  dycevapCH4(ig) = ( -ychim(ig,1,7+nmicro)+botCH4 ) / ptimestep - dycchi(ig,1,7+nmicro)
1202               else
1203                  dycevapCH4(ig) = 0.0
1204               endif
1205            enddo
1206
1207            pdq(:,1,7+nmicro) = pdq(:,1,7+nmicro) + dycevapCH4(:)*rat_mmol(7+nmicro)
1208           
1209            ! v. Updates and positivity check
1210            ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1211            do iq=1,nkim
1212              zdqchi(:,:,iq+nmicro) = dycchi(:,:,iq)*rat_mmol(iq+nmicro) ! convert tendencies to mass mixing ratio
1213
1214              where( (pq(:,:,iq+nmicro) + ( pdq(:,:,iq+nmicro)+zdqchi(:,:,iq+nmicro) )*ptimestep ) .LT. 0.)  & ! When using zonal means we set the same tendency
1215                      zdqchi(:,:,iq+nmicro) = 1.e-30 - pdq(:,:,iq+nmicro) - pq(:,:,iq+nmicro)/ptimestep        ! everywhere in longitude -> could lead to negs !
1216            enddo
1217
1218            pdq(:,:,:) = pdq(:,:,:) + zdqchi(:,:,:)
1219           
1220         endif ! end of 'callchim'
1221
1222  ! ---------------
1223  !   V.3 Updates
1224  ! ---------------
1225
1226         ! Updating Atmospheric Mass and Tracers budgets.
1227         if(mass_redistrib) then
1228
1229            zdmassmr(:,:) = mass(:,:) * zdqevap(:,:)
1230
1231            do ig = 1, ngrid
1232               zdmassmr_col(ig)=SUM(zdmassmr(ig,:))
1233            enddo
1234           
1235            call writediagfi(ngrid,"mass_evap","mass gain"," ",3,zdmassmr)
1236            call writediagfi(ngrid,"mass_evap_col","mass gain col"," ",2,zdmassmr_col)
1237            call writediagfi(ngrid,"mass","mass","kg/m2",3,mass)
1238
1239            call mass_redistribution(ngrid,nlayer,nq,ptimestep,                     &
1240                                     capcal,pplay,pplev,pt,tsurf,pq,qsurf,          &
1241                                     pu,pv,pdt,zdtsurf,pdq,pdu,pdv,zdmassmr,        &
1242                                     zdtmr,zdtsurfmr,zdpsrfmr,zdumr,zdvmr,zdqmr,zdqsurfmr)
1243         
1244            pdq(:,:,:)  = pdq(:,:,:)  + zdqmr(:,:,:)
1245            dqsurf(:,:) = dqsurf(:,:) + zdqsurfmr(:,:)
1246            pdt(:,:)    = pdt(:,:)    + zdtmr(:,:)
1247            pdu(:,:)    = pdu(:,:)    + zdumr(:,:)
1248            pdv(:,:)    = pdv(:,:)    + zdvmr(:,:)
1249            pdpsrf(:)   = pdpsrf(:)   + zdpsrfmr(:)
1250            zdtsurf(:)  = zdtsurf(:)  + zdtsurfmr(:)
1251           
1252         endif
1253
1254  ! -----------------------------
1255  !   V.4. Surface Tracer Update
1256  ! -----------------------------
1257
1258        qsurf(:,:) = qsurf(:,:) + ptimestep*dqsurf(:,:)
1259
1260         ! Add qsurf to qsurf_hist, which is what we save in diagfi.nc. At the same time, we set the water
1261         ! content of ocean gridpoints back to zero, in order to avoid rounding errors in vdifc, rain.
1262         qsurf_hist(:,:) = qsurf(:,:)
1263
1264      endif! end of if 'tracer'
1265
1266
1267!------------------------------------------------
1268!   VI. Surface and sub-surface soil temperature
1269!------------------------------------------------
1270
1271
1272      ! Increment surface temperature
1273
1274      tsurf(:)=tsurf(:)+ptimestep*zdtsurf(:)
1275
1276      ! Compute soil temperatures and subsurface heat flux.
1277      if (callsoil) then
1278         call soil(ngrid,nsoilmx,.false.,lastcall,inertiedat,   &
1279                   ptimestep,tsurf,tsoil,capcal,fluxgrd)     
1280      endif
1281
1282
1283      ! Test energy conservation
1284      if(enertest)then
1285         call planetwide_sumval(cell_area(:)*capcal(:)*zdtsurf(:)/totarea_planet,dEtots)         
1286         if (is_master) print*,'Surface energy change                 =',dEtots,' W m-2'
1287      endif
1288
1289
1290!---------------------------------------------------
1291!   VII. Perform diagnostics and write output files
1292!---------------------------------------------------
1293
1294      ! Note : For output only: the actual model integration is performed in the dynamics.
1295 
1296      ! Temperature, zonal and meridional winds.
1297      zt(:,:) = pt(:,:) + pdt(:,:)*ptimestep
1298      zu(:,:) = pu(:,:) + pdu(:,:)*ptimestep
1299      zv(:,:) = pv(:,:) + pdv(:,:)*ptimestep
1300
1301      ! Diagnostic.
1302      zdtdyn(:,:)     = (pt(:,:)-ztprevious(:,:)) / ptimestep
1303      ztprevious(:,:) = zt(:,:)
1304
1305      zdudyn(:,:)     = (pu(:,:)-zuprevious(:,:)) / ptimestep
1306      zuprevious(:,:) = zu(:,:)
1307
1308      if(firstcall)then
1309         zdtdyn(:,:)=0.0
1310         zdudyn(:,:)=0.0
1311      endif
1312
1313      ! Dynamical heating diagnostic.
1314      do ig=1,ngrid
1315         fluxdyn(ig)= SUM(zdtdyn(ig,:) *mass(ig,:))*cpp
1316      enddo
1317
1318      ! Tracers.
1319      zq(:,:,:) = pq(:,:,:) + pdq(:,:,:)*ptimestep
1320
1321      ! Surface pressure.
1322      ps(:) = pplev(:,1) + pdpsrf(:)*ptimestep
1323
1324
1325
1326      ! Surface and soil temperature information
1327      call planetwide_sumval(cell_area(:)*tsurf(:)/totarea_planet,Ts1)
1328      call planetwide_minval(tsurf(:),Ts2)
1329      call planetwide_maxval(tsurf(:),Ts3)
1330      if(callsoil)then
1331         TsS = SUM(cell_area(:)*tsoil(:,nsoilmx))/totarea        ! mean temperature at bottom soil layer
1332         if (is_master) then
1333            print*,'          ave[Tsurf]             min[Tsurf]             max[Tsurf]             ave[Tdeep]'
1334            print*,Ts1,Ts2,Ts3,TsS
1335         end if
1336      else
1337         if (is_master) then
1338            print*,'          ave[Tsurf]             min[Tsurf]             max[Tsurf]'
1339            print*,Ts1,Ts2,Ts3
1340         endif
1341      end if
1342
1343
1344      ! Check the energy balance of the simulation during the run
1345      if(corrk)then
1346
1347         call planetwide_sumval(cell_area(:)*fluxtop_dn(:)/totarea_planet,ISR)
1348         call planetwide_sumval(cell_area(:)*fluxabs_sw(:)/totarea_planet,ASR)
1349         call planetwide_sumval(cell_area(:)*fluxtop_lw(:)/totarea_planet,OLR)
1350         call planetwide_sumval(cell_area(:)*fluxgrd(:)/totarea_planet,GND)
1351         call planetwide_sumval(cell_area(:)*fluxdyn(:)/totarea_planet,DYN)
1352         do ig=1,ngrid
1353            if(fluxtop_dn(ig).lt.0.0)then
1354               print*,'fluxtop_dn has gone crazy'
1355               print*,'fluxtop_dn=',fluxtop_dn(ig)
1356               print*,'temp=   ',pt(ig,:)
1357               print*,'pplay=  ',pplay(ig,:)
1358               call abort
1359            endif
1360         end do
1361                     
1362         if(ngrid.eq.1)then
1363            DYN=0.0
1364         endif
1365         
1366         if (is_master) then
1367            print*,'  ISR            ASR            OLR            GND            DYN [W m^-2]'
1368            print*, ISR,ASR,OLR,GND,DYN
1369         endif
1370
1371         if(enertest .and. is_master)then
1372            print*,'SW flux/heating difference SW++ - ASR = ',dEtotSW+dEtotsSW-ASR,' W m-2'
1373            print*,'LW flux/heating difference LW++ - OLR = ',dEtotLW+dEtotsLW+OLR,' W m-2'
1374            print*,'LW energy balance LW++ + ASR = ',dEtotLW+dEtotsLW+ASR,' W m-2'
1375         endif
1376
1377         if(meanOLR .and. is_master)then
1378            if((ngrid.gt.1) .or. (mod(icount-1,ecritphy).eq.0))then
1379               ! to record global radiative balance
1380               open(92,file="rad_bal.out",form='formatted',position='append')
1381               write(92,*) zday,ISR,ASR,OLR
1382               close(92)
1383               open(93,file="tem_bal.out",form='formatted',position='append')
1384               if(callsoil)then
1385                         write(93,*) zday,Ts1,Ts2,Ts3,TsS
1386               else
1387                  write(93,*) zday,Ts1,Ts2,Ts3
1388               endif
1389               close(93)
1390            endif
1391         endif
1392
1393      endif ! end of 'corrk'
1394
1395
1396      ! Diagnostic to test radiative-convective timescales in code.
1397      if(testradtimes)then
1398         open(38,file="tau_phys.out",form='formatted',position='append')
1399         ig=1
1400         do l=1,nlayer
1401            write(38,*) -1./pdt(ig,l),pt(ig,l),pplay(ig,l)
1402         enddo
1403         close(38)
1404         print*,'As testradtimes enabled,'
1405         print*,'exiting physics on first call'
1406         call abort
1407      endif
1408
1409
1410      if (is_master) print*,'--> Ls =',zls*180./pi
1411     
1412     
1413!----------------------------------------------------------------------
1414!        Writing NetCDF file  "RESTARTFI" at the end of the run
1415!----------------------------------------------------------------------
1416
1417!        Note: 'restartfi' is stored just before dynamics are stored
1418!              in 'restart'. Between now and the writting of 'restart',
1419!              there will have been the itau=itau+1 instruction and
1420!              a reset of 'time' (lastacll = .true. when itau+1= itaufin)
1421!              thus we store for time=time+dtvr
1422
1423
1424
1425      if(lastcall) then
1426         ztime_fin = ptime + ptimestep/(float(iphysiq)*daysec)
1427
1428         if (ngrid.ne.1) then
1429            write(*,*)'PHYSIQ: for physdem ztime_fin =',ztime_fin
1430           
1431            call physdem1("restartfi.nc",nsoilmx,ngrid,nlayer,nq, &
1432                          ptimestep,ztime_fin,                    &
1433                          tsurf,tsoil,emis,q2,qsurf_hist,tankCH4)
1434         endif
1435    endif ! end of 'lastcall'
1436
1437
1438!-----------------------------------------------------------------------------------------------------
1439!           OUTPUT in netcdf file "DIAGFI.NC", containing any variable for diagnostic
1440!
1441!             Note 1 : output with  period "ecritphy", set in "run.def"
1442!
1443!             Note 2 : writediagfi can also be called from any other subroutine for any variable,
1444!                      but its preferable to keep all the calls in one place ...
1445!-----------------------------------------------------------------------------------------------------
1446
1447
1448      call writediagfi(ngrid,"Ls","solar longitude","deg",0,zls*180./pi)
1449      call writediagfi(ngrid,"Lss","sub solar longitude","deg",0,zlss*180./pi)
1450      call writediagfi(ngrid,"RA","right ascension","deg",0,right_ascen*180./pi)
1451      call writediagfi(ngrid,"Declin","solar declination","deg",0,declin*180./pi)
1452      call writediagfi(ngrid,"tsurf","Surface temperature","K",2,tsurf)
1453      call writediagfi(ngrid,"ps","Surface pressure","Pa",2,ps)
1454      call writediagfi(ngrid,"temp","temperature","K",3,zt)
1455      call writediagfi(ngrid,"teta","potential temperature","K",3,zh)
1456      call writediagfi(ngrid,"u","Zonal wind","m.s-1",3,zu)
1457      call writediagfi(ngrid,"v","Meridional wind","m.s-1",3,zv)
1458      call writediagfi(ngrid,"w","Vertical wind","m.s-1",3,pw)
1459      call writediagfi(ngrid,"p","Pressure","Pa",3,pplay)
1460
1461!     Subsurface temperatures
1462!        call writediagsoil(ngrid,"tsurf","Surface temperature","K",2,tsurf)
1463!        call writediagsoil(ngrid,"temp","temperature","K",3,tsoil)
1464
1465     
1466
1467      ! Total energy balance diagnostics
1468      if(callrad.and.(.not.newtonian))then
1469     
1470         !call writediagfi(ngrid,"ALB","Surface albedo"," ",2,albedo_equivalent)
1471         call writediagfi(ngrid,"ISR","incoming stellar rad.","W m-2",2,fluxtop_dn)
1472         call writediagfi(ngrid,"ASR","absorbed stellar rad.","W m-2",2,fluxabs_sw)
1473         call writediagfi(ngrid,"OLR","outgoing longwave rad.","W m-2",2,fluxtop_lw)
1474         
1475!           call writediagfi(ngrid,"ASRcs","absorbed stellar rad (cs).","W m-2",2,fluxabs_sw1)
1476!           call writediagfi(ngrid,"OLRcs","outgoing longwave rad (cs).","W m-2",2,fluxtop_lw1)
1477!           call writediagfi(ngrid,"fluxsurfsw","sw surface flux.","W m-2",2,fluxsurf_sw)
1478!           call writediagfi(ngrid,"fluxsurflw","lw back radiation.","W m-2",2,fluxsurf_lw)
1479!           call writediagfi(ngrid,"fluxsurfswcs","sw surface flux (cs).","W m-2",2,fluxsurf_sw1)
1480!           call writediagfi(ngrid,"fluxsurflwcs","lw back radiation (cs).","W m-2",2,fluxsurf_lw1)
1481
1482
1483         call writediagfi(ngrid,"GND","heat flux from ground","W m-2",2,fluxgrd)
1484         
1485         call writediagfi(ngrid,"DYN","dynamical heat input","W m-2",2,fluxdyn)
1486         
1487      endif ! end of 'callrad'
1488       
1489      if(enertest) then
1490     
1491         if (calldifv) then
1492         
1493            call writediagfi(ngrid,"q2","turbulent kinetic energy","J.kg^-1",3,q2)
1494            call writediagfi(ngrid,"sensibFlux","sensible heat flux","w.m^-2",2,sensibFlux)
1495           
1496!             call writediagfi(ngrid,"dEzdiff","turbulent diffusion heating (-sensible flux)","w.m^-2",3,dEzdiff)
1497!             call writediagfi(ngrid,"dEdiff","integrated turbulent diffusion heating (-sensible flux)","w.m^-2",2,dEdiff)
1498!             call writediagfi(ngrid,"dEdiffs","In TurbDiff (correc rad+latent heat) surf nrj change","w.m^-2",2,dEdiffs)
1499             
1500         endif
1501         
1502         if (corrk) then
1503            call writediagfi(ngrid,"dEzradsw","radiative heating","w.m^-2",3,dEzradsw)
1504            call writediagfi(ngrid,"dEzradlw","radiative heating","w.m^-2",3,dEzradlw)
1505         endif
1506         
1507      endif ! end of 'enertest'
1508
1509        ! Temporary inclusions for winds diagnostics.
1510        call writediagfi(ngrid,"zdudif","Turbdiff tend. zon. wind","m s-2",3,zdudif)
1511        call writediagfi(ngrid,"zdudyn","Dyn. tend. zon. wind","m s-2",3,zdudyn)
1512
1513        ! Temporary inclusions for heating diagnostics.
1514        call writediagfi(ngrid,"zdtsw","SW heating","T s-1",3,zdtsw)
1515        call writediagfi(ngrid,"zdtlw","LW heating","T s-1",3,zdtlw)
1516        call writediagfi(ngrid,"dtrad","radiative heating","K s-1",3,dtrad)
1517        call writediagfi(ngrid,"zdtdyn","Dyn. heating","T s-1",3,zdtdyn)
1518       
1519        ! For Debugging.
1520        call writediagfi(ngrid,'pphi','Geopotential',' ',3,pphi)
1521       
1522
1523      ! Output tracers.
1524      if (tracer) then
1525
1526         if (callmufi) then
1527           ! Microphysical tracers are expressed in unit/m3.
1528           ! convert X.kg-1 --> X.m-3 (whereas for optics was -> X.m-2)
1529           i2e(:,:) = ( pplev(:,1:nlayer)-pplev(:,2:nlayer+1) ) / gzlat(:,1:nlayer) /(zzlev(:,2:nlayer+1)-zzlev(:,1:nlayer))
1530
1531#ifdef USE_QTEST
1532            ! Microphysical tracers passed through dyn+phys(except mufi)
1533            call writediagfi(ngrid,"mu_m0as_dp","Dynphys only spherical mode 0th order moment",'m-3',3,zq(:,:,micro_indx(1))*i2e)
1534            call writediagfi(ngrid,"mu_m3as_dp","Dynphys only spherical mode 3rd order moment",'m3/m3',3,zq(:,:,micro_indx(2))*i2e)
1535            call writediagfi(ngrid,"mu_m0af_dp","Dynphys only fractal mode 0th order moment",'m-3',3,zq(:,:,micro_indx(3))*i2e)
1536            call writediagfi(ngrid,"mu_m3af_dp","Dynphys only fractal mode 3rd order moment",'m3/m3',3,zq(:,:,micro_indx(4))*i2e)
1537            ! Microphysical tracers passed through mufi only
1538            call writediagfi(ngrid,"mu_m0as_mo","Mufi only spherical mode 0th order moment",'m-3',3,tpq(:,:,micro_indx(1))*i2e)
1539            call writediagfi(ngrid,"mu_m3as_mo","Mufi only spherical mode 3rd order moment",'m3/m3',3,tpq(:,:,micro_indx(2))*i2e)
1540            call writediagfi(ngrid,"mu_m0af_mo","Mufi only fractal mode 0th order moment",'m-3',3,tpq(:,:,micro_indx(3))*i2e)
1541            call writediagfi(ngrid,"mu_m3af_mo","Mufi only fractal mode 3rd order moment",'m3/m3',3,tpq(:,:,micro_indx(4))*i2e)
1542#else
1543            call writediagfi(ngrid,"mu_m0as","Spherical mode 0th order moment",'m-3',3,zq(:,:,micro_indx(1))*i2e)
1544            call writediagfi(ngrid,"mu_m3as","Spherical mode 3rd order moment",'m3/m3',3,zq(:,:,micro_indx(2))*i2e)
1545            call writediagfi(ngrid,"mu_m0af","Fractal mode 0th order moment",'m-3',3,zq(:,:,micro_indx(3))*i2e)
1546            call writediagfi(ngrid,"mu_m3af","Fractal mode 3rd order moment",'m3/m3',3,zq(:,:,micro_indx(4))*i2e)
1547#endif
1548           
1549            ! Microphysical diagnostics
1550            call writediagfi(ngrid,"mmd_aer_prec","Total aerosols precipitations",'m',2,mmd_aer_prec)
1551            call writediagfi(ngrid,"mmd_aer_s_flux","Spherical aerosols sedimentation flux",'kg.m-2.s-1',3,mmd_aer_s_flux)
1552            call writediagfi(ngrid,"mmd_aer_f_flux","Fractal aerosols sedimentation flux",'kg.m-2.s-1',3,mmd_aer_f_flux)
1553            call writediagfi(ngrid,"mmd_rc_sph","Spherical mode caracteristic radius",'m',3,mmd_rc_sph)
1554            call writediagfi(ngrid,"mmd_rc_fra","Fractal mode caracteristic radius",'m',3,mmd_rc_fra)
1555
1556         endif ! end of 'callmufi'
1557
1558         ! Chemical tracers
1559         if (callchim) then
1560           do iq=1,nkim
1561             call writediagfi(ngrid,cnames(iq),cnames(iq),'mol/mol',3,zq(:,:,iq+nmicro)/rat_mmol(iq+nmicro))
1562           enddo
1563           call writediagfi(ngrid,"evapCH4","Surface CH4 pseudo-evaporation rate",'mol/mol/s',2,dycevapCH4)
1564         endif
1565
1566       endif ! end of 'tracer'
1567
1568! XIOS outputs
1569#ifdef CPP_XIOS     
1570      ! Send fields to XIOS: (NB these fields must also be defined as
1571      ! <field id="..." /> in context_lmdz_physics.xml to be correctly used)
1572      CALL send_xios_field("ls",zls*180./pi)
1573      CALL send_xios_field("lss",zlss*180./pi)
1574      CALL send_xios_field("RA",right_ascen*180./pi)
1575      CALL send_xios_field("Declin",declin*180./pi)
1576     
1577      ! Total energy balance diagnostics
1578      if (callrad.and.(.not.newtonian)) then
1579         CALL send_xios_field("ISR_TOA",fluxtop_dn)
1580         CALL send_xios_field("OLR_TOA",fluxtop_lw)
1581      endif
1582     
1583      CALL send_xios_field("area",cell_area)
1584      CALL send_xios_field("pphi",pphi)
1585      CALL send_xios_field("pphis",phisfi)
1586     
1587      CALL send_xios_field("ps",ps)
1588      CALL send_xios_field("tsurf",tsurf)
1589
1590      if(enertest) then
1591         if (calldifv) then
1592            CALL send_xios_field("sensibFlux",sensibFlux)
1593         endif
1594      endif
1595
1596      CALL send_xios_field("temp",zt)
1597      CALL send_xios_field("teta",zh)
1598      CALL send_xios_field("u",zu)
1599      CALL send_xios_field("v",zv)
1600      CALL send_xios_field("w",pw)
1601      CALL send_xios_field("p",pplay)
1602     
1603      ! Winds diagnostics.
1604      CALL send_xios_field("dudif",zdudif)
1605      CALL send_xios_field("dudyn",zdudyn)
1606
1607      ! Heating diagnostics.
1608      CALL send_xios_field("dtsw",zdtsw)
1609      CALL send_xios_field("dtlw",zdtlw)
1610      CALL send_xios_field("dtrad",dtrad)
1611      CALL send_xios_field("dtdyn",zdtdyn)
1612
1613      ! Chemical tracers
1614      if (callchim) then
1615     
1616        ! Advected fields
1617        do iq=1,nkim
1618          CALL send_xios_field(trim(cnames(iq)),zq(:,:,iq+nmicro)/rat_mmol(iq+nmicro)) ! kg/kg -> mol/mol
1619        enddo
1620       
1621        ! Upper chemistry fields
1622        do iq=1,nkim
1623          CALL send_xios_field(trim(cnames(iq))//"_up",ykim_up(iq,:,:)) ! mol/mol
1624        enddo
1625       
1626        ! Append fields in ykim_tot for output on the total vertical grid (0->1300km)
1627        do iq=1,nkim
1628         
1629          ! GCM levels
1630          do l=1,nlayer
1631            ykim_tot(iq,:,l) = zq(:,l,iq+nmicro)/rat_mmol(iq+nmicro)
1632          enddo
1633          ! Upper levels
1634          do l=1,nlaykim_up
1635            ykim_tot(iq,:,nlayer+l) = ykim_up(iq,:,l)
1636          enddo
1637         
1638          CALL send_xios_field(trim(cnames(iq))//"_tot",ykim_tot(iq,:,:)) ! mol/mol
1639         
1640        enddo
1641       
1642        ! Condensation tendencies ( mol/mol/s )
1643        CALL send_xios_field("dqcond_CH4",dyccond(:,:,7+nmicro))
1644        CALL send_xios_field("dqcond_C2H2",dyccond(:,:,10+nmicro))
1645        CALL send_xios_field("dqcond_C2H4",dyccond(:,:,12+nmicro))
1646        CALL send_xios_field("dqcond_C2H6",dyccond(:,:,14+nmicro))
1647        CALL send_xios_field("dqcond_C3H6",dyccond(:,:,17+nmicro))
1648        CALL send_xios_field("dqcond_C4H4",dyccond(:,:,21+nmicro))
1649        CALL send_xios_field("dqcond_CH3CCH",dyccond(:,:,24+nmicro))
1650        CALL send_xios_field("dqcond_C3H8",dyccond(:,:,25+nmicro))
1651        CALL send_xios_field("dqcond_C4H2",dyccond(:,:,26+nmicro))
1652        CALL send_xios_field("dqcond_C4H6",dyccond(:,:,27+nmicro))
1653        CALL send_xios_field("dqcond_C4H10",dyccond(:,:,28+nmicro))
1654        CALL send_xios_field("dqcond_AC6H6",dyccond(:,:,29+nmicro))
1655        CALL send_xios_field("dqcond_HCN",dyccond(:,:,36+nmicro))
1656        CALL send_xios_field("dqcond_CH3CN",dyccond(:,:,40+nmicro))
1657        CALL send_xios_field("dqcond_HC3N",dyccond(:,:,42+nmicro))
1658        CALL send_xios_field("dqcond_NCCN",dyccond(:,:,43+nmicro))
1659        CALL send_xios_field("dqcond_C4N2",dyccond(:,:,44+nmicro))
1660
1661        ! Pseudo-evaporation flux (mol/mol/s)
1662        CALL send_xios_field("evapCH4",dycevapCH4(:))
1663
1664      endif ! of 'if callchim'
1665
1666      ! Microphysical tracers
1667      if (callmufi) then
1668        CALL send_xios_field("mu_m0as",zq(:,:,micro_indx(1))*i2e)
1669        CALL send_xios_field("mu_m3as",zq(:,:,micro_indx(2))*i2e)
1670        CALL send_xios_field("mu_m0af",zq(:,:,micro_indx(3))*i2e)
1671        CALL send_xios_field("mu_m3af",zq(:,:,micro_indx(4))*i2e)
1672      endif       
1673
1674      if (lastcall.and.is_omp_master) then
1675        write(*,*) "physiq: call xios_context_finalize"
1676        call xios_context_finalize
1677      endif
1678#endif
1679
1680      icount=icount+1
1681
1682    end subroutine physiq
1683   
1684    end module physiq_mod
Note: See TracBrowser for help on using the repository browser.