source: trunk/LMDZ.GENERIC/libf/phystd/dyn1d/rcm1d.F @ 1644

Last change on this file since 1644 was 1621, checked in by emillour, 8 years ago

Further work on full dynamics/physics separation.

LMDZ.COMMON:

  • added phy_common/vertical_layers_mod.F90 to store information on vertical grid. This is where routines in the physics should get the information.
  • The contents of vertical_layers_mod intialized via dynphy_lonlat/inigeomphy_mod.F90.

LMDZ.MARS:

  • physics now completely decoupled from dynamics; the physics package may now be compiled as a library (-libphy option of makelmdz_fcm).
  • created an "ini_tracer_mod" routine in module "tracer_mod" for a cleaner initialization of the later.
  • removed some purely dynamics-related outputs (etot0, zoom parameters, etc.) from diagfi.nc and stats.nc outputs as these informations are not available in the physics.

LMDZ.GENERIC:

  • physics now completely decoupled from dynamics; the physics package may now be compiled as a library (-libphy option of makelmdz_fcm).
  • added nqtot to tracer_h.F90.
  • removed some purely dynamics-related outputs (etot0, zoom parameters, etc.) from diagfi.nc and stats.nc outputs as these informations are not available in the physics.

LMDZ.VENUS:

  • physics now completely decoupled from dynamics; the physics package may now be compiled as a library (-libphy option of makelmdz_fcm).
  • added infotrac_phy.F90 to store information on tracers in the physics. Initialized via iniphysiq.
  • added cpdet_phy_mod.F90 to store t2tpot etc. functions to be used in the physics. Initialized via iniphysiq. IMPORTANT: there are some hard-coded constants! These should match what is in cpdet_mod.F90 in the dynamics.
  • got rid of references to moyzon_mod module within the physics. The required variables (tmoy, plevmoy) are passed to the physics as arguments to physiq.

LMDZ.TITAN:

  • added infotrac_phy.F90 to store information on tracers in the physics. Initialized via iniphysiq.
  • added cpdet_phy_mod.F90 to store t2tpot etc. functions to be used in the physics.
  • Extra work required to completely decouple physics and dynamics: moyzon_mod should be cleaned up and information passed from dynamics to physics as as arguments. Likewise moyzon_ch and moyzon_mu should not be queried from logic_mod (which is in the dynamics).

EM

  • Property svn:executable set to *
File size: 32.6 KB
Line 
1      program rcm1d
2
3! to use  'getin'
4      use ioipsl_getincom, only: getin
5      use dimphy, only : init_dimphy
6      use mod_grid_phy_lmdz, only : regular_lonlat
7      use infotrac, only: nqtot, tname
8      use surfdat_h, only: albedodat, phisfi, dryness, watercaptag,
9     &                     zmea, zstd, zsig, zgam, zthe,
10     &                     emissiv, emisice, iceradius,
11     &                     dtemisice
12      use comdiurn_h, only: sinlat, coslat, sinlon, coslon
13      use comsoil_h, only: nsoilmx, layer, mlayer, inertiedat, volcapa
14      use phyredem, only: physdem0,physdem1
15      use geometry_mod, only: init_geometry
16      use slab_ice_h, only: noceanmx
17      use planete_mod, only: apoastr,periastr,year_day,peri_day,
18     &         obliquit,nres,z0,lmixmin,emin_turb,coefvis,coefir,
19     &         timeperi,e_elips,p_elips
20      use comcstfi_mod, only: pi, cpp, rad, g, r,
21     &                        mugaz, rcp, omeg
22      use time_phylmdz_mod, only: daysec, dtphys, day_step, ecritphy,
23     &                            nday, iphysiq
24      use callkeys_mod, only: tracer,check_cpp_match,rings_shadow,
25     &                        specOLR,water,pceil,ok_slab_ocean
26      USE comvert_mod, ONLY: ap,bp,aps,bps,pa,preff, sig,
27     &                       presnivs,pseudoalt,scaleheight
28      USE vertical_layers_mod, ONLY: init_vertical_layers
29      USE logic_mod, ONLY: hybrid,autozlevs
30      use regular_lonlat_mod, only: init_regular_lonlat
31      use planete_mod, only: ini_planete_mod
32      use physics_distribution_mod, only: init_physics_distribution
33      use regular_lonlat_mod, only: init_regular_lonlat
34      use mod_interface_dyn_phys, only: init_interface_dyn_phys
35      use inifis_mod, only: inifis
36      use physiq_mod, only: physiq
37      implicit none
38
39!==================================================================
40!     
41!     Purpose
42!     -------
43!     Run the physics package of the universal model in a 1D column.
44!     
45!     It can be compiled with a command like (e.g. for 25 layers):
46!                                  "makegcm -p std -d 25 rcm1d"
47!     It requires the files "callphys.def", "z2sig.def",
48!     "traceur.def", and "run.def" with a line "INCLUDEDEF=callphys.def"
49!
50!     Authors
51!     -------
52!     Frederic Hourdin
53!     R. Fournier
54!     F. Forget
55!     F. Montmessin (water ice added)
56!     R. Wordsworth
57!     B. Charnay
58!     A. Spiga
59!     J. Leconte (2012)
60!
61!==================================================================
62
63#include "dimensions.h"
64#include "paramet.h"
65!include "dimphys.h"
66#include "netcdf.inc"
67#include "comgeom.h"
68
69c --------------------------------------------------------------
70c  Declarations
71c --------------------------------------------------------------
72c
73      INTEGER unitstart      ! unite d'ecriture de "startfi"
74      INTEGER nlayer,nlevel,nsoil,ndt
75      INTEGER ilayer,ilevel,isoil,idt,iq
76      LOGICAl firstcall,lastcall
77c
78      INTEGER day0          ! date initial (sol ; =0 a Ls=0)
79      REAL day              ! date durant le run
80      REAL time             ! time (0<time<1 ; time=0.5 a midi)
81      REAL play(llm)        ! Pressure at the middle of the layers (Pa)
82      REAL plev(llm+1)      ! intermediate pressure levels (pa)
83      REAL psurf,tsurf(1)     
84      REAL u(llm),v(llm)    ! zonal, meridional wind
85      REAL gru,grv          ! prescribed "geostrophic" background wind
86      REAL temp(llm)        ! temperature at the middle of the layers
87      REAL,ALLOCATABLE :: q(:,:)      ! tracer mixing ratio (e.g. kg/kg)
88      REAL,ALLOCATABLE :: qsurf(:)    ! tracer surface budget (e.g. kg.m-2)
89      REAL,ALLOCATABLE :: tsoil(:)    ! subsurface soil temperature (K)
90!      REAL co2ice               ! co2ice layer (kg.m-2) !not used anymore
91      integer :: i_co2_ice=0     ! tracer index of co2 ice
92      integer :: i_h2o_ice=0     ! tracer index of h2o ice
93      integer :: i_h2o_vap=0     ! tracer index of h2o vapor
94      REAL emis(1)               ! surface layer
95      REAL q2(llm+1)             ! Turbulent Kinetic Energy
96      REAL zlay(llm)             ! altitude estimee dans les couches (km)
97
98c    Physical and dynamical tandencies (e.g.  m.s-2, K/s, Pa/s)
99      REAL du(llm),dv(llm),dtemp(llm)
100      REAL dudyn(llm),dvdyn(llm),dtempdyn(llm)
101      REAL dpsurf(1)   
102      REAL,ALLOCATABLE :: dq(:,:)
103      REAL,ALLOCATABLE :: dqdyn(:,:)
104
105c   Various intermediate variables
106!      INTEGER thermo
107      REAL zls
108      REAL phi(llm),h(llm),s(llm)
109      REAL pks, ptif, w(llm)
110      INTEGER ierr, aslun
111      REAL tmp1(0:llm),tmp2(0:llm)
112      integer :: nq !=1 ! number of tracers
113 
114      character*2 str2
115      character (len=7) :: str7
116      character(len=44) :: txt
117
118      logical oldcompare, earthhack,saveprofile
119
120!     added by RW for zlay computation
121      real Hscale, Hmax, rho, dz
122
123!     added by RW for autozlevs computation
124      real nu, xx, pMIN, zlev, Htop
125      real logplevs(llm)
126
127!     added by BC
128      REAL cloudfrac(1,llm)
129      REAL hice(1),totcloudfrac(1)
130
131!     added by BC for ocean
132      real rnat(1)
133      REAL tslab(1,noceanmx),tsea_ice(1),sea_ice(1)
134      real pctsrf_sic(1)
135
136
137
138!     added by AS to avoid the use of adv trac common
139      character*20,allocatable :: nametrac(:)   ! name of the tracer (no need for adv trac common)
140
141      real :: latitude(1), longitude(1), cell_area(1)
142
143c=======================================================================
144c INITIALISATION
145c=======================================================================
146! initialize "serial/parallel" related stuff
147!      CALL init_phys_lmdz(iim,jjm+1,llm,1,(/(jjm-1)*iim+2/))
148!      CALL init_phys_lmdz(1,1,llm,1,(/1/))
149!      call initcomgeomphy
150
151      !! those are defined in surfdat_h.F90
152      IF (.not. ALLOCATED(albedodat)) ALLOCATE(albedodat(1))
153      IF (.not. ALLOCATED(phisfi)) ALLOCATE(phisfi(1))
154      IF (.not. ALLOCATED(zmea)) ALLOCATE(zmea(1))
155      IF (.not. ALLOCATED(zstd)) ALLOCATE(zstd(1))
156      IF (.not. ALLOCATED(zsig)) ALLOCATE(zsig(1))
157      IF (.not. ALLOCATED(zgam)) ALLOCATE(zgam(1))
158      IF (.not. ALLOCATED(zthe)) ALLOCATE(zthe(1))
159      IF (.not. ALLOCATED(dryness)) ALLOCATE(dryness(1))
160      IF (.not. ALLOCATED(watercaptag)) ALLOCATE(watercaptag(1))
161      !! those are defined in comdiurn_h.F90
162      IF (.not.ALLOCATED(sinlat)) ALLOCATE(sinlat(1))
163      IF (.not.ALLOCATED(coslat)) ALLOCATE(coslat(1))
164      IF (.not.ALLOCATED(sinlon)) ALLOCATE(sinlon(1))
165      IF (.not.ALLOCATED(coslon)) ALLOCATE(coslon(1))
166
167      saveprofile=.false.
168      saveprofile=.true.
169
170c ----------------------------------------
171c  Default values  (corresponding to Mars)
172c ----------------------------------------
173
174      pi=2.E+0*asin(1.E+0)
175
176c     Parametres Couche limite et Turbulence
177c     --------------------------------------
178      z0 =  1.e-2                ! surface roughness (m) ~0.01
179      emin_turb = 1.e-6          ! energie minimale ~1.e-8
180      lmixmin = 30               ! longueur de melange ~100
181 
182c     propriete optiques des calottes et emissivite du sol
183c     ----------------------------------------------------
184      emissiv= 0.95              ! Emissivite du sol martien ~.95
185      emisice(1)=0.95            ! Emissivite calotte nord
186      emisice(2)=0.95            ! Emissivite calotte sud 
187
188      iceradius(1) = 100.e-6     ! mean scat radius of CO2 snow (north)
189      iceradius(2) = 100.e-6     ! mean scat radius of CO2 snow (south)
190      dtemisice(1) = 2.          ! time scale for snow metamorphism (north)
191      dtemisice(2) = 2.          ! time scale for snow metamorphism (south
192      hybrid=.false.
193
194c ------------------------------------------------------
195c  Load parameters from "run.def" and "gases.def"
196c ------------------------------------------------------
197
198! check if 'rcm1d.def' file is around
199      open(90,file='rcm1d.def',status='old',form='formatted',
200     &     iostat=ierr)
201      if (ierr.ne.0) then
202        write(*,*) 'Cannot find required file "rcm1d.def"'
203        write(*,*) 'which should contain some input parameters'
204        write(*,*) ' ... might as well stop here ...'
205        stop
206      else
207        close(90)
208      endif
209
210! now, run.def is needed anyway. so we create a dummy temporary one
211! for ioipsl to work. if a run.def is already here, stop the
212! program and ask the user to do a bit of cleaning
213      open(90,file='run.def',status='old',form='formatted',
214     &     iostat=ierr)
215      if (ierr.eq.0) then
216        close(90)
217        write(*,*) 'There is already a run.def file.'
218        write(*,*) 'This is not compatible with 1D runs.'
219        write(*,*) 'Please remove the file and restart the run.'
220        write(*,*) 'Runtime parameters are supposed to be in rcm1d.def'
221        stop
222      else
223        call system('touch run.def')
224        call system("echo 'INCLUDEDEF=callphys.def' >> run.def")
225        call system("echo 'INCLUDEDEF=rcm1d.def' >> run.def")
226      endif
227
228! check if we are going to run with or without tracers
229      write(*,*) "Run with or without tracer transport ?"
230      tracer=.false. ! default value
231      call getin("tracer",tracer)
232      write(*,*) " tracer = ",tracer
233
234! OK. now that run.def has been read once -- any variable is in memory.
235! so we can dump the dummy run.def
236!      call system("rm -rf run.def") ! Ehouarn: delay this to after inifis
237
238! while we're at it, check if there is a 'traceur.def' file
239! and preocess it, if necessary. Otherwise initialize tracer names
240      if (tracer) then
241      ! load tracer names from file 'traceur.def'
242        open(90,file='traceur.def',status='old',form='formatted',
243     &       iostat=ierr)
244        if (ierr.eq.0) then
245          write(*,*) "rcm1d: Reading file traceur.def"
246          ! read number of tracers:
247          read(90,*,iostat=ierr) nq
248          nqtot=nq ! set value of nqtot (in infotrac module) as nq
249          if (ierr.ne.0) then
250            write(*,*) "rcm1d: error reading number of tracers"
251            write(*,*) "   (first line of traceur.def) "
252            stop
253          endif
254          if (nq>0) then
255            allocate(tname(nq))
256            allocate(q(llm,nq))
257            allocate(qsurf(nq))
258            allocate(dq(llm,nq))
259            allocate(dqdyn(llm,nq))
260          else
261            write(*,*) "rcm1d: Error. You set tracer=.true."
262            write(*,*) "       but # of tracers in traceur.def is ",nq
263            stop
264          endif
265       
266          do iq=1,nq
267          ! minimal version, just read in the tracer names, 1 per line
268            read(90,*,iostat=ierr) tname(iq)
269            if (ierr.ne.0) then
270              write(*,*) 'rcm1d: error reading tracer names...'
271              stop
272            endif
273          enddo !of do iq=1,nq
274! check for co2_ice / h2o_ice tracers:
275         i_co2_ice=0
276         i_h2o_ice=0
277         i_h2o_vap=0
278         do iq=1,nq
279           if (tname(iq)=="co2_ice") then
280             i_co2_ice=iq
281           elseif (tname(iq)=="h2o_ice") then
282             i_h2o_ice=iq
283           elseif (tname(iq)=="h2o_vap") then
284             i_h2o_vap=iq
285           endif
286         enddo
287        else
288          write(*,*) 'Cannot find required file "traceur.def"'
289          write(*,*) ' If you want to run with tracers, I need it'
290          write(*,*) ' ... might as well stop here ...'
291          stop
292        endif
293        close(90)
294
295      else ! of if (tracer)
296        nqtot=0
297        nq=0
298        ! still, make allocations for 1 dummy tracer
299        allocate(tname(1))
300        allocate(qsurf(1))
301        allocate(q(llm,1))
302        allocate(dq(llm,1))
303     
304       ! Check that tracer boolean is compliant with number of tracers
305       ! -- otherwise there is an error (and more generally we have to be consistent)
306       if (nq .ge. 1) then
307          write(*,*) "------------------------------"
308          write(*,*) "rcm1d: You set tracer=.false."
309          write(*,*) " But set number of tracers to ",nq
310          write(*,*) " > If you want tracers, set tracer=.true."
311          write(*,*) "------------------------------"
312          stop
313       endif
314      endif ! of if (tracer)
315
316!!! We have to check that check_cpp_match is F for 1D computations
317!!! We think this check is better than make a particular case for 1D in inifis or calc_cpp_mugaz
318      check_cpp_match = .false.
319      call getin("check_cpp_match",check_cpp_match)
320      if (check_cpp_match) then
321          print*,"In 1D modeling, check_cpp_match is supposed to be F"
322          print*,"Please correct callphys.def"
323          stop
324      endif
325
326!!! GEOGRAPHICAL INITIALIZATIONS
327     !!! AREA. useless in 1D
328      cell_area(1)=1.E+0 !JL+EM to have access to the area in the diagfi.nc files.
329     !!! GEOPOTENTIAL. useless in 1D because control by surface pressure
330      phisfi(1)=0.E+0
331     !!! LATITUDE. can be set.
332      latitude=0 ! default value for latitude
333      PRINT *,'latitude (in degrees) ?'
334      call getin("latitude",latitude)
335      write(*,*) " latitude = ",latitude
336      latitude=latitude*pi/180.E+0
337     !!! LONGITUDE. useless in 1D.
338      longitude=0.E+0
339      longitude=longitude*pi/180.E+0
340
341
342!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343!!!! PLANETARY CONSTANTS !!!!
344!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
345
346      g = -99999.
347      PRINT *,'GRAVITY in m s-2 ?'
348      call getin("g",g)
349      IF (g.eq.-99999.) THEN
350          PRINT *,"STOP. I NEED g IN RCM1D.DEF."
351          STOP
352      ELSE
353          PRINT *,"--> g = ",g
354      ENDIF
355
356      rad = -99999.
357      PRINT *,'PLANETARY RADIUS in m ?'
358      call getin("rad",rad)
359      ! Planetary  radius is needed to compute shadow of the rings
360      IF (rad.eq.-99999. .and. rings_shadow .eqv. .true.) THEN
361          PRINT *,"STOP. I NEED rad IN RCM1D.DEF."
362          STOP
363      ELSE
364          PRINT *,"--> rad = ",rad
365      ENDIF
366
367      daysec = -99999.
368      PRINT *,'LENGTH OF A DAY in s ?'
369      call getin("daysec",daysec)
370      IF (daysec.eq.-99999.) THEN
371          PRINT *,"STOP. I NEED daysec IN RCM1D.DEF."
372          STOP
373      ELSE
374          PRINT *,"--> daysec = ",daysec
375      ENDIF
376      omeg=4.*asin(1.)/(daysec)
377      PRINT *,"OK. FROM THIS I WORKED OUT:"
378      PRINT *,"--> omeg = ",omeg
379
380      year_day = -99999.
381      PRINT *,'LENGTH OF A YEAR in days ?'
382      call getin("year_day",year_day)
383      IF (year_day.eq.-99999.) THEN
384          PRINT *,"STOP. I NEED year_day IN RCM1D.DEF."
385          STOP
386      ELSE
387          PRINT *,"--> year_day = ",year_day
388      ENDIF
389
390      periastr = -99999.
391      PRINT *,'MIN DIST STAR-PLANET in AU ?'
392      call getin("periastr",periastr)
393      IF (periastr.eq.-99999.) THEN
394          PRINT *,"STOP. I NEED periastr IN RCM1D.DEF."
395          STOP
396      ELSE
397          PRINT *,"--> periastr = ",periastr
398      ENDIF
399
400      apoastr = -99999.
401      PRINT *,'MAX DIST STAR-PLANET in AU ?'
402      call getin("apoastr",apoastr)
403      IF (apoastr.eq.-99999.) THEN
404          PRINT *,"STOP. I NEED apoastr IN RCM1D.DEF."
405          STOP
406      ELSE
407          PRINT *,"--> apoastr = ",apoastr
408      ENDIF
409
410      peri_day = -99999.
411      PRINT *,'DATE OF PERIASTRON in days ?'
412      call getin("peri_day",peri_day)
413      IF (peri_day.eq.-99999.) THEN
414          PRINT *,"STOP. I NEED peri_day IN RCM1D.DEF."
415          STOP
416      ELSE IF (peri_day.gt.year_day) THEN
417          PRINT *,"STOP. peri_day.gt.year_day"
418          STOP
419      ELSE 
420          PRINT *,"--> peri_day = ", peri_day
421      ENDIF
422
423      obliquit = -99999.
424      PRINT *,'OBLIQUITY in deg ?'
425      call getin("obliquit",obliquit)
426      IF (obliquit.eq.-99999.) THEN
427          PRINT *,"STOP. I NEED obliquit IN RCM1D.DEF."
428          STOP
429      ELSE
430          PRINT *,"--> obliquit = ",obliquit
431      ENDIF
432
433      psurf = -99999.
434      PRINT *,'SURFACE PRESSURE in Pa ?'
435      call getin("psurf",psurf)
436      IF (psurf.eq.-99999.) THEN
437          PRINT *,"STOP. I NEED psurf IN RCM1D.DEF."
438          STOP
439      ELSE
440          PRINT *,"--> psurf = ",psurf
441      ENDIF
442      !! we need reference pressures
443      pa=psurf/30.
444      preff=psurf ! these values are not needed in 1D  (are you sure JL12)
445
446!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
447!!!! END PLANETARY CONSTANTS !!!!
448!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
449
450c  Date et heure locale du debut du run
451c  ------------------------------------
452c    Date (en sols depuis le solstice de printemps) du debut du run
453      day0 = 0 ! default value for day0
454      write(*,*) 'Initial date (in martian sols ; =0 at Ls=0)?'
455      call getin("day0",day0)
456      day=float(day0)
457      write(*,*) " day0 = ",day0
458c  Heure de demarrage
459      time=0 ! default value for time
460      write(*,*)'Initial local time (in hours, between 0 and 24)?'
461      call getin("time",time)
462      write(*,*)" time = ",time
463      time=time/24.E+0 ! convert time (hours) to fraction of sol
464
465
466c  Discretisation (Definition de la grille et des pas de temps)
467c  --------------
468c
469      nlayer=llm
470      nlevel=nlayer+1
471
472      day_step=48 ! default value for day_step
473      PRINT *,'Number of time steps per sol ?'
474      call getin("day_step",day_step)
475      write(*,*) " day_step = ",day_step
476
477      iphysiq=1 ! in 1D model physics are called evry time step
478      ecritphy=day_step ! default value for ecritphy
479      PRINT *,'Nunber of steps between writediagfi ?'
480      call getin("ecritphy",ecritphy)
481      write(*,*) " ecritphy = ",ecritphy
482
483      ndt=10 ! default value for ndt
484      PRINT *,'Number of sols to run ?'
485      call getin("ndt",ndt)
486      write(*,*) " ndt = ",ndt
487      nday=ndt
488
489      ndt=ndt*day_step     
490      dtphys=daysec/day_step 
491      write(*,*)"-------------------------------------"
492      write(*,*)"-------------------------------------"
493      write(*,*)"--> Physical timestep is ",dtphys
494      write(*,*)"-------------------------------------"
495      write(*,*)"-------------------------------------"
496
497      ! initializations, as with iniphysiq.F90 for the 3D GCM
498      call init_physics_distribution(regular_lonlat,4,
499     &                               1,1,1,nlayer,1)
500      call init_interface_dyn_phys
501      CALL init_regular_lonlat(1,1,longitude,latitude,
502     &                   (/0.,0./),(/0.,0./))
503      call init_geometry(1,longitude,latitude,
504     &                   (/0.,0.,0.,0./),(/0.,0.,0.,0./),
505     &                   cell_area)
506! Ehouarn: init_vertial_layers called later (because disvert not called yet)
507!      call init_vertical_layers(nlayer,preff,scaleheight,
508!     &                      ap,bp,aps,bps,presnivs,pseudoalt)
509      call init_dimphy(1,nlayer) ! Initialize dimphy module
510      call ini_planete_mod(nlayer,preff,ap,bp)
511
512!!! CALL INIFIS
513!!! - read callphys.def
514!!! - calculate sine and cosine of longitude and latitude
515!!! - calculate mugaz and cp
516!!! NB: some operations are being done dummily in inifis in 1D
517!!! - physical constants: nevermind, things are done allright below
518!!! - physical frequency: nevermind, in inifis this is a simple print
519      cpp=1.d-7 !JL because we divide by cpp in inifis, there may be a more elegant solution
520      CALL inifis(1,llm,nq,day0,daysec,nday,dtphys,
521     .            latitude,longitude,cell_area,rad,g,r,cpp)
522
523      nsoil=nsoilmx
524      allocate(tsoil(nsoilmx))
525      !! those are defined in comsoil_h.F90
526      IF (.not.ALLOCATED(layer)) ALLOCATE(layer(nsoilmx))
527      IF (.not.ALLOCATED(mlayer)) ALLOCATE(mlayer(0:nsoilmx-1))
528      IF (.not.ALLOCATED(inertiedat)) ALLOCATE(inertiedat(1,nsoilmx))
529
530! At this point, both getin() and getin_p() functions have been used,
531! and the run.def file can be removed.
532      call system("rm -rf run.def")
533
534!!! We check everything is OK.
535      PRINT *,"CHECK"
536      PRINT *,"--> mugaz = ",mugaz
537      PRINT *,"--> cpp = ",cpp
538      r = 8.314511E+0 * 1000.E+0 / mugaz
539      rcp = r / cpp
540
541c output spectrum?
542      write(*,*)"Output spectral OLR?"
543      specOLR=.false.
544      call getin("specOLR",specOLR)
545      write(*,*)" specOLR = ",specOLR
546
547c
548c  pour le schema d'ondes de gravite
549c  ---------------------------------
550      zmea(1)=0.E+0
551      zstd(1)=0.E+0
552      zsig(1)=0.E+0
553      zgam(1)=0.E+0
554      zthe(1)=0.E+0
555
556c    Initialisation des traceurs
557c    ---------------------------
558
559      DO iq=1,nq
560        DO ilayer=1,nlayer
561           q(ilayer,iq) = 0.
562        ENDDO
563      ENDDO
564     
565      DO iq=1,nq
566        qsurf(iq) = 0.
567      ENDDO
568     
569      if (tracer) then ! Initialize tracers here.
570             
571         write(*,*) "rcm1d : initializing tracers profiles"
572
573         do iq=1,nq
574         
575            txt=""
576            write(txt,"(a)") tname(iq)
577            write(*,*)"  tracer:",trim(txt)
578             
579            ! CO2
580            if (txt.eq."co2_ice") then
581               q(:,iq)=0.   ! kg/kg of atmosphere
582               qsurf(iq)=0. ! kg/m2 at the surface               
583               ! Look for a "profile_co2_ice" input file
584               open(91,file='profile_co2_ice',status='old',
585     &         form='formatted',iostat=ierr)
586               if (ierr.eq.0) then
587                  read(91,*) qsurf(iq)
588                  do ilayer=1,nlayer
589                     read(91,*) q(ilayer,iq)
590                  enddo
591               else
592                  write(*,*) "No profile_co2_ice file!"
593               endif
594               close(91)
595            endif ! of if (txt.eq."co2")
596         
597            ! WATER VAPOUR
598            if (txt.eq."h2o_vap") then
599               q(:,iq)=0.   ! kg/kg of atmosphere
600               qsurf(iq)=0. ! kg/m2 at the surface
601               ! Look for a "profile_h2o_vap" input file   
602               open(91,file='profile_h2o_vap',status='old',
603     &         form='formatted',iostat=ierr)
604               if (ierr.eq.0) then
605                  read(91,*) qsurf(iq)
606                  do ilayer=1,nlayer
607                     read(91,*) q(ilayer,iq)
608                  enddo
609               else
610                  write(*,*) "No profile_h2o_vap file!"
611               endif
612               close(91)
613            endif ! of if (txt.eq."h2o_vap")
614           
615            ! WATER ICE
616            if (txt.eq."h2o_ice") then
617               q(:,iq)=0.   ! kg/kg of atmosphere
618               qsurf(iq)=0. ! kg/m2 at the surface
619               ! Look for a "profile_h2o_ice" input file
620               open(91,file='profile_h2o_ice',status='old',
621     &         form='formatted',iostat=ierr)
622               if (ierr.eq.0) then
623                  read(91,*) qsurf(iq)
624                  do ilayer=1,nlayer
625                     read(91,*) q(ilayer,iq)
626                  enddo
627               else
628                  write(*,*) "No profile_h2o_ice file!"
629               endif
630               close(91)
631            endif ! of if (txt.eq."h2o_ice")
632
633         enddo ! of do iq=1,nq
634         
635      endif ! of tracer
636
637c   Initialisation pour prendre en compte les vents en 1-D
638c   ------------------------------------------------------
639      ptif=2.E+0*omeg*sinlat(1)
640 
641
642c    vent geostrophique
643      gru=10. ! default value for gru
644      PRINT *,'zonal eastward component of the geostrophic wind (m/s) ?'
645      call getin("u",gru)
646      write(*,*) " u = ",gru
647      grv=0. !default value for grv
648      PRINT *,'meridional northward component of the geostrophic',
649     &' wind (m/s) ?'
650      call getin("v",grv)
651      write(*,*) " v = ",grv
652
653! To be clean, also set vertical winds to zero
654      w(1:nlayer)=0
655
656c     Initialisation des vents  au premier pas de temps
657      DO ilayer=1,nlayer
658         u(ilayer)=gru
659         v(ilayer)=grv
660      ENDDO
661
662c     energie cinetique turbulente
663      DO ilevel=1,nlevel
664         q2(ilevel)=0.E+0
665      ENDDO
666
667c  emissivity / surface co2 ice ( + h2o ice??)
668c  -------------------------------------------
669      emis(1)=emissiv ! default value for emissivity
670      PRINT *,'Emissivity of bare ground ?'
671      call getin("emis",emis(1))
672      write(*,*) " emis = ",emis(1)
673      emissiv=emis(1) ! we do this so that condense_co2 sets things to the right
674                   ! value if there is no snow
675
676      if(i_co2_ice.gt.0)then
677         qsurf(i_co2_ice)=0 ! default value for co2ice
678         print*,'Initial CO2 ice on the surface (kg.m-2)'
679         call getin("co2ice",qsurf(i_co2_ice))
680         write(*,*) " co2ice = ",qsurf(i_co2_ice)
681         IF (qsurf(i_co2_ice).ge.1.E+0) THEN
682            ! if we have some CO2 ice on the surface, change emissivity
683            if (latitude(1).ge.0) then ! northern hemisphere
684              emis(1)=emisice(1)
685            else ! southern hemisphere
686              emis(1)=emisice(2)
687            endif
688         ENDIF
689      endif
690
691c  calcul des pressions et altitudes en utilisant les niveaux sigma
692c  ----------------------------------------------------------------
693
694c    Vertical Coordinates
695c    """"""""""""""""""""
696      hybrid=.true.
697      PRINT *,'Hybrid coordinates ?'
698      call getin("hybrid",hybrid)
699      write(*,*) " hybrid = ", hybrid
700
701
702      autozlevs=.false.
703      PRINT *,'Auto-discretise vertical levels ?'
704      call getin("autozlevs",autozlevs)
705      write(*,*) " autozlevs = ", autozlevs
706
707      pceil = psurf / 1000.0 ! Pascals
708      PRINT *,'Ceiling pressure (Pa) ?'
709      call getin("pceil",pceil)
710      write(*,*) " pceil = ", pceil
711
712! Test of incompatibility:
713! if autozlevs used, cannot have hybrid too
714
715      if (autozlevs.and.hybrid) then
716         print*,'Cannot use autozlevs and hybrid together!'
717         call abort
718      endif
719
720      if(autozlevs)then
721           
722         open(91,file="z2sig.def",form='formatted')
723         read(91,*) Hscale
724         DO ilayer=1,nlayer-2
725            read(91,*) Hmax
726         enddo
727         close(91)
728 
729           
730         print*,'Hmax = ',Hmax,' km'
731         print*,'Auto-shifting Hscale to:'
732!     Hscale = Hmax / log(psurf/100.0)
733         Hscale = Hmax / log(psurf/pceil)
734         print*,'Hscale = ',Hscale,' km'
735         
736! none of this matters if we dont care about zlay
737         
738      endif
739
740      call disvert
741      ! now that disvert has been called, initialize module vertical_layers_mod
742      call init_vertical_layers(nlayer,preff,scaleheight,
743     &                      ap,bp,aps,bps,presnivs,pseudoalt)
744
745         if(.not.autozlevs)then
746            ! we want only the scale height from z2sig, in order to compute zlay
747            open(91,file="z2sig.def",form='formatted')
748            read(91,*) Hscale
749            close(91)
750         endif
751
752!         if(autozlevs)then
753!            open(94,file="Hscale.temp",form='formatted')
754!            read(94,*) Hscale
755!            close(94)
756!         endif
757
758         DO ilevel=1,nlevel
759            plev(ilevel)=ap(ilevel)+psurf*bp(ilevel)
760         ENDDO
761         
762         DO ilayer=1,nlayer
763            play(ilayer)=aps(ilayer)+psurf*bps(ilayer)
764         ENDDO
765         
766
767
768         DO ilayer=1,nlayer
769!     zlay(ilayer)=-300.E+0 *r*log(play(ilayer)/plev(1))
770!     &   /g
771            zlay(ilayer)=-1000.0*Hscale*log(play(ilayer)/plev(1))
772         ENDDO
773
774!      endif
775
776c  profil de temperature au premier appel
777c  --------------------------------------
778      pks=psurf**rcp
779
780c altitude en km dans profile: on divise zlay par 1000
781      tmp1(0)=0.E+0
782      DO ilayer=1,nlayer
783        tmp1(ilayer)=zlay(ilayer)/1000.E+0
784      ENDDO
785      call profile(nlayer+1,tmp1,tmp2)
786
787      tsurf(1)=tmp2(0)
788      DO ilayer=1,nlayer
789        temp(ilayer)=tmp2(ilayer)
790      ENDDO
791      print*,"check"
792      PRINT*,"INPUT SURFACE TEMPERATURE",tsurf(1)
793      PRINT*,"INPUT TEMPERATURE PROFILE",temp
794
795c  Initialisation albedo / inertie du sol
796c  --------------------------------------
797      albedodat(1)=0.2 ! default value for albedodat
798      PRINT *,'Albedo of bare ground ?'
799      call getin("albedo",albedodat(1))
800      write(*,*) " albedo = ",albedodat(1)
801
802      inertiedat(1,1)=400 ! default value for inertiedat
803      PRINT *,'Soil thermal inertia (SI) ?'
804      call getin("inertia",inertiedat(1,1))
805      write(*,*) " inertia = ",inertiedat(1,1)
806
807! Initialize soil properties and temperature
808! ------------------------------------------
809      volcapa=1.e6 ! volumetric heat capacity
810      DO isoil=1,nsoil
811         inertiedat(1,isoil)=inertiedat(1,1) ! soil thermal inertia
812         tsoil(isoil)=tsurf(1)  ! soil temperature
813      ENDDO
814
815! Initialize depths
816! -----------------
817      do isoil=0,nsoil-1
818        mlayer(isoil)=2.e-4*(2.**(isoil-0.5)) ! mid-layer depth
819      enddo
820      do isoil=1,nsoil
821        layer(isoil)=2.e-4*(2.**(isoil-1)) ! layer depth
822      enddo
823
824
825! Initialize slab ocean
826! -----------------
827      rnat=1. ! default value for rnat
828      if(inertiedat(1,1).GE.10000.)then
829         rnat=0.
830      endif
831      if(ok_slab_ocean)then
832      rnat=0.
833      tslab(1,1)=tsurf(1)
834      tslab(1,2)=tsurf(1)
835      tsea_ice=tsurf
836      pctsrf_sic=0.
837      sea_ice=0.
838      endif
839
840
841
842c  Write a "startfi" file
843c  --------------------
844c  This file will be read during the first call to "physiq".
845c  It is needed to transfert physics variables to "physiq"...
846
847      call physdem0("startfi.nc",longitude,latitude,nsoilmx,1,llm,nq,
848     &              dtphys,real(day0),time,cell_area,
849     &              albedodat,inertiedat,zmea,zstd,zsig,zgam,zthe)
850      call physdem1("startfi.nc",nsoilmx,1,llm,nq,
851     &                dtphys,time,
852     &                tsurf,tsoil,emis,q2,qsurf,
853     &                cloudfrac,totcloudfrac,hice,
854     &                rnat,pctsrf_sic,tslab,tsea_ice,sea_ice)
855
856c=======================================================================
857c  BOUCLE TEMPORELLE DU MODELE 1D
858c=======================================================================
859
860      firstcall=.true.
861      lastcall=.false.
862
863      DO idt=1,ndt
864        IF (idt.eq.ndt) then       !test
865         lastcall=.true.
866         call stellarlong(day*1.0,zls)
867!         write(103,*) 'Ls=',zls*180./pi
868!         write(103,*) 'Lat=', latitude(1)*180./pi
869!         write(103,*) 'RunEnd - Atmos. Temp. File'
870!         write(103,*) 'RunEnd - Atmos. Temp. File'
871!         write(104,*) 'Ls=',zls*180./pi
872!         write(104,*) 'Lat=', latitude(1)
873!         write(104,*) 'RunEnd - Atmos. Temp. File'
874        ENDIF
875
876c    calcul du geopotentiel
877c     ~~~~~~~~~~~~~~~~~~~~~
878
879
880      DO ilayer=1,nlayer
881
882!              if(autozlevs)then
883!                 s(ilayer)=(play(ilayer)/psurf)**rcp
884!              else
885          s(ilayer)=(aps(ilayer)/psurf+bps(ilayer))**rcp
886!              endif
887              !s(ilayer)=(aps(ilayer)/psurf+bps(ilayer))**rcp
888          h(ilayer)=cpp*temp(ilayer)/(pks*s(ilayer))
889       ENDDO
890
891!      DO ilayer=1,nlayer
892!        s(ilayer)=(aps(ilayer)/psurf+bps(ilayer))**rcp
893!        h(ilayer)=cpp*temp(ilayer)/(pks*s(ilayer))
894!      ENDDO
895      phi(1)=pks*h(1)*(1.E+0-s(1))
896      DO ilayer=2,nlayer
897         phi(ilayer)=phi(ilayer-1)+
898     &               pks*(h(ilayer-1)+h(ilayer))*.5E+0
899     &                  *(s(ilayer-1)-s(ilayer))
900
901      ENDDO
902
903c       appel de la physique
904c       --------------------
905
906
907      CALL physiq (1,llm,nq,
908     .     tname,
909     ,     firstcall,lastcall,
910     ,     day,time,dtphys,
911     ,     plev,play,phi,
912     ,     u, v,temp, q, 
913     ,     w,
914C - sorties
915     s     du, dv, dtemp, dq,dpsurf)
916
917
918c       evolution du vent : modele 1D
919c       -----------------------------
920 
921c       la physique calcule les derivees temporelles de u et v.
922c       on y rajoute betement un effet Coriolis.
923c
924c       DO ilayer=1,nlayer
925c          du(ilayer)=du(ilayer)+ptif*(v(ilayer)-grv)
926c          dv(ilayer)=dv(ilayer)+ptif*(-u(ilayer)+gru)
927c       ENDDO
928
929c       Pour certain test : pas de coriolis a l'equateur
930c       if(latitude(1).eq.0.) then
931          DO ilayer=1,nlayer
932             du(ilayer)=du(ilayer)+ (gru-u(ilayer))/1.e4
933             dv(ilayer)=dv(ilayer)+ (grv-v(ilayer))/1.e4
934          ENDDO
935c       end if
936c     
937c
938c       Calcul du temps au pas de temps suivant
939c       ---------------------------------------
940        firstcall=.false.
941        time=time+dtphys/daysec
942        IF (time.gt.1.E+0) then
943            time=time-1.E+0
944            day=day+1
945        ENDIF
946
947c       calcul des vitesses et temperature au pas de temps suivant
948c       ----------------------------------------------------------
949
950        DO ilayer=1,nlayer
951           u(ilayer)=u(ilayer)+dtphys*du(ilayer)
952           v(ilayer)=v(ilayer)+dtphys*dv(ilayer)
953           temp(ilayer)=temp(ilayer)+dtphys*dtemp(ilayer)
954        ENDDO
955
956c       calcul des pressions au pas de temps suivant
957c       ----------------------------------------------------------
958
959           psurf=psurf+dtphys*dpsurf(1)   ! evolution de la pression de surface
960           DO ilevel=1,nlevel
961              plev(ilevel)=ap(ilevel)+psurf*bp(ilevel)
962           ENDDO
963           DO ilayer=1,nlayer
964                 play(ilayer)=aps(ilayer)+psurf*bps(ilayer)
965           ENDDO
966
967c       calcul traceur au pas de temps suivant
968c       --------------------------------------
969
970        DO iq = 1, nq
971          DO ilayer=1,nlayer
972             q(ilayer,iq)=q(ilayer,iq)+dtphys*dq(ilayer,iq)
973          ENDDO
974        END DO
975
976c    ========================================================
977c    GESTION DES SORTIE
978c    ========================================================
979      if(saveprofile)then
980         OPEN(12,file='profile.out',form='formatted')
981         write(12,*) tsurf
982         DO ilayer=1,llm
983            write(12,*) temp(ilayer) !, play(ilayer) !AS12 only temp so that iprofile=8 can be used
984         ENDDO
985         CLOSE(12)
986      endif
987
988
989      ENDDO   ! fin de la boucle temporelle
990
991      write(*,*) "rcm1d: Everything is cool."
992
993c    ========================================================
994      end                       !rcm1d
995 
996
Note: See TracBrowser for help on using the repository browser.