Changeset 2559


Ignore:
Timestamp:
Sep 7, 2021, 12:10:35 PM (3 years ago)
Author:
emillour
Message:

Mars GCM:
Some code cleanup and refactoring around wstats:

  • turn wstats.F90 in a module
  • remove no useless statto_mod.F90
  • incorporate auxilliary inistats and mkstats routines in wstats_mod.F90
  • move flag "callstats" from callkeys.h to being a module variable of wstats_mod

EM

Location:
trunk/LMDZ.MARS
Files:
3 deleted
6 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.MARS/README

    r2558 r2559  
    24662466microphysics (just like water clouds). The amplitude is spantCO2, also read from callphys.def
    24672467- The previous logical microphysco2 has been removed.
    2468 - Cloud opacity at 1µm is now computed in the co2cloud.F routine
     2468- Cloud opacity at 1µm is now computed in the co2cloud.F routine
    24692469- Most of the co2 ice clouds scheme writediagfi are now in co2clouds.F
    24702470- Some cleaning of the CO2 ice clouds routine has been done. Not perfect yet!
     
    24822482  if a gravity wave propagates to the mesosphere or not (wheter the wave saturates on its way or not).
    24832483  The sub-grid temperature distribution is cancelled if the saturation index value of the column (between 12 and 80 km) is > 0.1, and is applied (+/- 3K) otherwise. if the keyword satindexco2=.true. in callphys.def (only applies if CLFvaryingCO2=.true. anyway). If set to .false., deactivate this filter and the sub grid T distribution applies everywhere and everytime. See comments in co2clouds.F
    2484 - All that you need to launch a GCM run with co2 clouds is described in co2clouds.F comments. Ehouarn Millour and Anni Määttänen have the files.
     2484- All that you need to launch a GCM run with co2 clouds is described in co2clouds.F comments. Ehouarn Millour and Anni Määttänen have the files.
    24852485 
    24862486== 15/11/2017 == EM
     
    34433443(between levels with no missing values in both files, which vary with space and time) and outputs
    34443444the ratio tau_GCM/tau_MCS to be used to normalize the GCM dust opacity profiles when comparing to MCS
     3445
     3446== 07/09/2021 == EM
     3447Some code cleanup and refactoring around wstats:
     3448- turn wstats.F90 in a module
     3449- remove no useless statto_mod.F90
     3450- incorporate auxilliary inistats and mkstats routines in wstats_mod.F90
     3451- move flag "callstats" from callkeys.h to being a module variable of wstats_mod
  • trunk/LMDZ.MARS/libf/aeronomars/calchim_mod.F90

    r2461 r2559  
    3131      use photolysis_mod, only: init_photolysis, nphot
    3232      use iono_h, only: temp_elect
     33      use wstats_mod, only: callstats, wstats
    3334
    3435      implicit none
  • trunk/LMDZ.MARS/libf/aeronomars/surfacearea.F

    r2030 r2559  
    88     &                      igcm_ccn_number, varian, ccn_factor
    99      use conc_mod, only: rnew
    10       USE comcstfi_h
     10      use comcstfi_h, only: pi
     11      use wstats_mod, only: callstats, wstats
    1112      implicit none
    1213
  • trunk/LMDZ.MARS/libf/phymars/callkeys.h

    r2522 r2559  
    77
    88      COMMON/callkeys_l/callrad,calldifv,calladj,callcond,callsoil      &
    9      &   ,season,diurnal,lwrite,calllott,callstats,calleofdump          &
     9     &   ,season,diurnal,lwrite,calllott,calleofdump                    &
    1010     &   ,callnirco2,callnlte,callthermos,callconduct,calleuv           &
    1111     &   ,callmolvis,callmoldiff,thermochem,thermoswater,callemis       &
     
    2828      LOGICAL callrad,calldifv,calladj,callcond,callsoil,               &
    2929     &   season,diurnal,lwrite,calllott,calllott_nonoro                 &
    30      &   ,callstats,calleofdump                                         &
     30     &   ,calleofdump                                                   &
    3131     &   ,callnirco2,callnlte,callthermos,callconduct,                  &
    3232     &    calleuv,callmolvis,callmoldiff,thermochem,thermoswater        &
  • trunk/LMDZ.MARS/libf/phymars/conf_phys.F

    r2522 r2559  
    4343     &                      ini_scatterers,tauvis
    4444      use datafile_mod, only: datadir
     45      use wstats_mod, only: callstats
    4546      use calchim_mod, only: ichemistry
    4647      use co2condens_mod, only: scavco2cond
  • trunk/LMDZ.MARS/libf/phymars/physiq_mod.F

    r2551 r2559  
    8484      use phyredem, only: physdem0, physdem1
    8585      use phyetat0_mod, only: phyetat0, tab_cntrl_mod
     86      use wstats_mod, only: callstats, wstats, mkstats
    8687      use eofdump_mod, only: eofdump
    8788      USE vertical_layers_mod, ONLY: ap,bp,aps,bps,presnivs,pseudoalt
  • trunk/LMDZ.MARS/libf/phymars/wstats_mod.F90

    r2557 r2559  
     1module wstats_mod
     2
     3! module containing parameters and routines to generate the "stats.nc" file
     4! which will contain a mean statistical day of variables extracted at set
     5! times of day every day of the simulation, and the standard deviations thereof
     6
     7implicit none
     8
     9logical,save :: callstats ! global flag to trigger generating a stats.nc
     10                          ! file or not. Initialized in conf_gcm()
     11!$OMP THREADPRIVATE(callstats)
     12
     13integer,save :: istats ! calculate stats every istats physics timestep,
     14                       ! starting at first call. Initialized by inistats()
     15!$OMP THREADPRIVATE(istats)
     16
     17integer,parameter :: istime=12 ! number of time steps per sol to store
     18
     19integer,save :: count(istime) ! count tab to know the variable record
     20!$OMP THREADPRIVATE(istats,count)
     21
     22contains
     23
    124subroutine wstats(ngrid,nom,titre,unite,dim,px)
    225
    3 use statto_mod, only: istats,istime,count
     26! Main routine to call to trigger writing a given field to the "stats.nc" file
     27
    428use mod_phys_lmdz_para, only : is_mpi_root, is_master, gather, klon_mpi_begin
    529use mod_grid_phy_lmdz, only : klon_glo, Grid1Dto2D_glo, &
     
    335359end subroutine wstats
    336360
    337 !======================================================
     361!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     362
     363subroutine inistats(ierr)
     364
     365! routine to initialize the stats file (i.e. create file, write
     366! time independent coordinates, etc.)
     367
     368use mod_phys_lmdz_para, only : is_master
     369USE vertical_layers_mod, ONLY: ap,bp,aps,bps,preff,pseudoalt,presnivs
     370USE nrtype, ONLY: pi
     371USE time_phylmdz_mod, ONLY: daysec,dtphys
     372USE regular_lonlat_mod, ONLY: lon_reg, lat_reg
     373USE mod_grid_phy_lmdz, ONLY: nbp_lon, nbp_lat, nbp_lev
     374implicit none
     375
     376include "netcdf.inc"
     377
     378integer,intent(out) :: ierr
     379
     380integer :: nid
     381integer :: l,nsteppd
     382real, dimension(nbp_lev) ::  sig_s
     383real,allocatable :: lon_reg_ext(:) ! extended longitudes
     384integer :: idim_lat,idim_lon,idim_llm,idim_llmp1,idim_time
     385real, dimension(istime) :: lt
     386integer :: nvarid
     387
     388
     389IF (nbp_lon*nbp_lat==1) THEN
     390  ! 1D model
     391  ALLOCATE(lon_reg_ext(1))
     392ELSE
     393  ! 3D model
     394  ALLOCATE(lon_reg_ext(nbp_lon+1))
     395ENDIF
     396
     397write (*,*)
     398write (*,*) '                        || STATS ||'
     399write (*,*)
     400write (*,*) 'daysec',daysec
     401write (*,*) 'dtphys',dtphys
     402nsteppd=nint(daysec/dtphys)
     403write (*,*) 'nsteppd=',nsteppd
     404
     405if (abs(float(nsteppd)-daysec/dtphys).gt.1.e-8*daysec) then
     406  call abort_physic("inistats",'1 sol .ne. n physics steps',1)
     407endif
     408
     409if(mod(nsteppd,istime).ne.0) then
     410  call abort_physic("inistats",'1 sol .ne. n*istime physics steps',1)
     411endif
     412
     413istats=nsteppd/istime
     414write (*,*) 'istats=',istats
     415write (*,*) 'Storing ',istime,'times per day'
     416write (*,*) 'thus every ',istats,'physical timestep '
     417write (*,*)
     418
     419do l= 1, nbp_lev
     420  sig_s(l)=((ap(l)+ap(l+1))/preff+bp(l)+bp(l+1))/2.
     421  pseudoalt(l)=-10.*log(presnivs(l)/preff)   
     422enddo
     423
     424lon_reg_ext(1:nbp_lon)=lon_reg(1:nbp_lon)
     425IF (nbp_lon*nbp_lat/=1) THEN
     426  ! In 3D, add extra redundant point (180 degrees,
     427  ! since lon_reg starts at -180)
     428  lon_reg_ext(nbp_lon+1)=-lon_reg_ext(1)
     429ENDIF
     430
     431if (is_master) then
     432  ! only the master needs do this
     433  ierr = NF_CREATE("stats.nc",IOR(NF_CLOBBER,NF_64BIT_OFFSET),nid)
     434  if (ierr.ne.NF_NOERR) then
     435    write (*,*) NF_STRERROR(ierr)
     436    call abort_physic("inistats",'failed creating stats.nc',1)
     437  endif
     438
     439  ierr = NF_DEF_DIM (nid, "latitude", nbp_lat, idim_lat)
     440  IF (nbp_lon*nbp_lat==1) THEN
     441    ierr = NF_DEF_DIM (nid, "longitude", 1, idim_lon)
     442  ELSE
     443    ierr = NF_DEF_DIM (nid, "longitude", nbp_lon+1, idim_lon)
     444  ENDIF
     445  ierr = NF_DEF_DIM (nid, "altitude", nbp_lev, idim_llm)
     446  ierr = NF_DEF_DIM (nid, "llmp1", nbp_lev+1, idim_llmp1)
     447  ierr = NF_DEF_DIM (nid, "Time", NF_UNLIMITED, idim_time)
     448
     449  ierr = NF_ENDDEF(nid)
     450
     451  call def_var_stats(nid,"Time","Time", &
     452                     "days since 0000-00-0 00:00:00",1, &
     453                     [idim_time],nvarid,ierr)
     454  ! Time is initialised later by mkstats subroutine
     455
     456  call def_var_stats(nid,"latitude","latitude", &
     457                     "degrees_north",1,[idim_lat],nvarid,ierr)
     458#ifdef NC_DOUBLE
     459  ierr = NF_PUT_VAR_DOUBLE (nid,nvarid,lat_reg/pi*180)
     460#else
     461  ierr = NF_PUT_VAR_REAL (nid,nvarid,lat_reg/pi*180)
     462#endif
     463
     464  call def_var_stats(nid,"longitude","East longitude", &
     465                     "degrees_east",1,[idim_lon],nvarid,ierr)
     466#ifdef NC_DOUBLE
     467  ierr = NF_PUT_VAR_DOUBLE (nid,nvarid,lon_reg_ext/pi*180)
     468#else
     469  ierr = NF_PUT_VAR_REAL (nid,nvarid,lon_reg_ext/pi*180)
     470#endif
     471
     472  ! Niveaux verticaux, aps et bps
     473  ierr = NF_REDEF (nid)
     474#ifdef NC_DOUBLE
     475  ierr = NF_DEF_VAR (nid,"altitude", NF_DOUBLE, 1,idim_llm,nvarid)
     476#else
     477  ierr = NF_DEF_VAR (nid,"altitude", NF_FLOAT, 1,idim_llm,nvarid)
     478#endif
     479  ierr = NF_PUT_ATT_TEXT (nid,nvarid,"long_name",8,"altitude")
     480  ierr = NF_PUT_ATT_TEXT (nid,nvarid,'units',2,"km")
     481  ierr = NF_PUT_ATT_TEXT (nid,nvarid,'positive',2,"up")
     482  ierr = NF_ENDDEF(nid)
     483#ifdef NC_DOUBLE
     484  ierr = NF_PUT_VAR_DOUBLE (nid,nvarid,pseudoalt)
     485#else
     486  ierr = NF_PUT_VAR_REAL (nid,nvarid,pseudoalt)
     487#endif
     488  call def_var_stats(nid,"aps","hybrid pressure at midlayers", &
     489                     " ",1,[idim_llm],nvarid,ierr)
     490#ifdef NC_DOUBLE
     491  ierr = NF_PUT_VAR_DOUBLE (nid,nvarid,aps)
     492#else
     493  ierr = NF_PUT_VAR_REAL (nid,nvarid,aps)
     494#endif
     495
     496  call def_var_stats(nid,"bps","hybrid sigma at midlayers", &
     497                     " ",1,[idim_llm],nvarid,ierr)
     498#ifdef NC_DOUBLE
     499  ierr = NF_PUT_VAR_DOUBLE (nid,nvarid,bps)
     500#else
     501  ierr = NF_PUT_VAR_REAL (nid,nvarid,bps)
     502#endif
     503
     504  ierr=NF_CLOSE(nid)
     505
     506endif ! of if (is_master)
     507
     508end subroutine inistats
     509
     510!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     511
    338512subroutine inivar(nid,varid,ngrid,dim,indx,px,ierr)
     513
     514! routine to initialize writing a variable in the stats file
     515
    339516use mod_grid_phy_lmdz, only : nbp_lon, nbp_lat, nbp_lev, klon_glo
    340517
     
    516693end subroutine def_var_stats
    517694
     695!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     696
     697subroutine mkstats(ierr)
     698
     699!  This routine finalizes tha stats.nc file from sums and sums of squares
     700!  to means and standard deviations. The data file is overwritten in place.
     701
     702use mod_phys_lmdz_para, only : is_master
     703use mod_grid_phy_lmdz, only : nbp_lon, nbp_lat, nbp_lev, klon_glo
     704
     705implicit none
     706
     707include "netcdf.inc"
     708
     709integer,intent(out) :: ierr ! netCDF return error code
     710integer :: nid,nbvar,i,ndims,lt,nvarid
     711integer, dimension(4) :: id,varid,start,size
     712integer, dimension(5) :: dimids
     713character (len=50) :: name,nameout,units,title
     714real,allocatable :: sum3d(:,:,:),square3d(:,:,:),mean3d(:,:,:),sd3d(:,:,:)
     715real,allocatable :: sum2d(:,:),square2d(:,:),mean2d(:,:),sd2d(:,:)
     716real, dimension(istime) :: time
     717real, dimension(nbp_lat) :: lat
     718real,allocatable :: lon(:)
     719real, dimension(nbp_lev) :: alt
     720logical :: lcopy=.true.
     721!integer :: latid,lonid,altid,timeid
     722integer :: meanid,sdid
     723!integer, dimension(4) :: dimout
     724
     725if (is_master) then
     726! only the master needs do all this
     727
     728! Incrementation of count for the last step, which is not done in wstats
     729count(istime)=count(istime)+1
     730
     731if (klon_glo>1) then
     732  allocate(lon(nbp_lon+1))
     733  allocate(sum3d(nbp_lon+1,nbp_lat,nbp_lev))
     734  allocate(square3d(nbp_lon+1,nbp_lat,nbp_lev))
     735  allocate(mean3d(nbp_lon+1,nbp_lat,nbp_lev))
     736  allocate(sd3d(nbp_lon+1,nbp_lat,nbp_lev))
     737  allocate(sum2d(nbp_lon+1,nbp_lat))
     738  allocate(square2d(nbp_lon+1,nbp_lat))
     739  allocate(mean2d(nbp_lon+1,nbp_lat))
     740  allocate(sd2d(nbp_lon+1,nbp_lat))
     741else ! 1D model case
     742  allocate(lon(1))
     743  allocate(sum3d(1,1,nbp_lev))
     744  allocate(square3d(1,1,nbp_lev))
     745  allocate(mean3d(1,1,nbp_lev))
     746  allocate(sd3d(1,1,nbp_lev))
     747  allocate(sum2d(1,1))
     748  allocate(square2d(1,1))
     749  allocate(mean2d(1,1))
     750  allocate(sd2d(1,1))
     751endif
     752
     753ierr = NF_OPEN("stats.nc",NF_WRITE,nid)
     754
     755! We catch the id of dimensions of the stats file
     756
     757ierr= NF_INQ_DIMID(nid,"latitude",id(1))
     758ierr= NF_INQ_DIMID(nid,"longitude",id(2))
     759ierr= NF_INQ_DIMID(nid,"altitude",id(3))
     760ierr= NF_INQ_DIMID(nid,"Time",id(4))
     761
     762ierr= NF_INQ_VARID(nid,"latitude",varid(1))
     763ierr= NF_INQ_VARID(nid,"longitude",varid(2))
     764ierr= NF_INQ_VARID(nid,"altitude",varid(3))
     765ierr= NF_INQ_VARID(nid,"Time",varid(4))
     766
     767! Time initialisation
     768
     769do i=1,istime
     770   time(i)=i*24./istime
     771#ifdef NC_DOUBLE
     772   ierr= NF_PUT_VARA_DOUBLE(nid,varid(4),i,1,time(i))
     773#else
     774   ierr= NF_PUT_VARA_REAL(nid,varid(4),i,1,time(i))
     775#endif
     776enddo
     777
     778! We catche the values of the variables
     779
     780#ifdef NC_DOUBLE
     781         ierr = NF_GET_VAR_DOUBLE(nid,varid(1),lat)
     782         ierr = NF_GET_VAR_DOUBLE(nid,varid(2),lon)
     783         ierr = NF_GET_VAR_DOUBLE(nid,varid(3),alt)
     784#else
     785         ierr = NF_GET_VAR_REAL(nid,varid(1),lat)
     786         ierr = NF_GET_VAR_REAL(nid,varid(2),lon)
     787         ierr = NF_GET_VAR_REAL(nid,varid(3),alt)
     788#endif
     789
     790! We catch the number of variables in the stats file
     791ierr = NF_INQ_NVARS(nid,nbvar)
     792
     793! to catche the "real" number of variables (without the "additionnal variables")
     794nbvar=(nbvar-4)/2
     795
     796do i=1,nbvar
     797   varid=(i-1)*2+5
     798
     799   ! What's the variable's name?
     800   ierr=NF_INQ_VARNAME(nid,varid,name)
     801   write(*,*) "OK variable ",name
     802   ! Its units?
     803   units=" "
     804   ierr=NF_GET_ATT_TEXT(nid,varid,"units",units)
     805   ! Its title?
     806   title=" "
     807   ierr=NF_GET_ATT_TEXT(nid,varid,"title",title)
     808   ! Its number of dimensions?   
     809   ierr=NF_INQ_VARNDIMS(nid,varid,ndims)
     810   ! Its values?
     811
     812   if(ndims==4) then ! lat, lon, alt & time
     813
     814!      dimout(1)=lonid
     815!      dimout(2)=latid
     816!      dimout(3)=altid
     817!      dimout(4)=timeid
     818
     819      if (klon_glo>1) then ! general case
     820        size=(/nbp_lon+1,nbp_lat,nbp_lev,1/)
     821      else ! 1D model
     822        size=(/1,1,nbp_lev,1/)
     823      endif
     824      do lt=1,istime
     825         start=(/1,1,1,lt/)
     826         ! Extraction of the "source" variables
     827#ifdef NC_DOUBLE
     828         ierr = NF_GET_VARA_DOUBLE(nid,varid,start,size,sum3d)
     829         ierr = NF_GET_VARA_DOUBLE(nid,varid+1,start,size,square3d)
     830#else
     831         ierr = NF_GET_VARA_REAL(nid,varid,start,size,sum3d)
     832         ierr = NF_GET_VARA_REAL(nid,varid+1,start,size,square3d)
     833#endif
     834         ! Calculation of these variables
     835         mean3d=sum3d/count(lt)
     836         sd3d=sqrt(max(0.,square3d/count(lt)-mean3d**2))
     837         ! Writing of the variables
     838#ifdef NC_DOUBLE
     839         ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,size,mean3d)
     840         ierr = NF_PUT_VARA_DOUBLE(nid,varid+1,start,size,sd3d)
     841#else
     842         ierr = NF_PUT_VARA_REAL(nid,varid,start,size,mean3d)
     843         ierr = NF_PUT_VARA_REAL(nid,varid+1,start,size,sd3d)
     844#endif
     845      enddo
     846
     847    else if (ndims.eq.3) then
     848
     849!      dimout(1)=lonid
     850!      dimout(2)=latid
     851!      dimout(3)=timeid
     852
     853      if (klon_glo>1) then ! general case
     854        size=(/nbp_lon+1,nbp_lat,1,0/)
     855      else
     856        size=(/1,1,1,0/)
     857      endif
     858      do lt=1,istime
     859         start=(/1,1,lt,0/)
     860         ! Extraction of the "source" variables
     861#ifdef NC_DOUBLE
     862         ierr = NF_GET_VARA_DOUBLE(nid,varid,start,size,sum2d)
     863         ierr = NF_GET_VARA_DOUBLE(nid,varid+1,start,size,square2d)
     864#else
     865         ierr = NF_GET_VARA_REAL(nid,varid,start,size,sum2d)
     866         ierr = NF_GET_VARA_REAL(nid,varid+1,start,size,square2d)
     867#endif
     868         ! Calculation of these variables
     869         mean2d=sum2d/count(lt)
     870         sd2d=sqrt(max(0.,square2d/count(lt)-mean2d**2))
     871         ! Writing of the variables
     872#ifdef NC_DOUBLE
     873         ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,size,mean2d)
     874         ierr = NF_PUT_VARA_DOUBLE(nid,varid+1,start,size,sd2d)
     875#else
     876         ierr = NF_PUT_VARA_REAL(nid,varid,start,size,mean2d)
     877         ierr = NF_PUT_VARA_REAL(nid,varid+1,start,size,sd2d)
     878#endif
     879      enddo
     880
     881    endif
     882enddo
     883
     884ierr= NF_CLOSE(nid)
     885
     886endif ! of if (is_master)
     887
     888end subroutine mkstats
     889
     890!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     891
     892end module wstats_mod
Note: See TracChangeset for help on using the changeset viewer.