source: trunk/LMDZ.GENERIC/libf/phystd/soil.F @ 867

Last change on this file since 867 was 787, checked in by aslmd, 12 years ago

LMDZ.GENERIC. (Sorry for long text but this is a quite major commit)

Paving the path for parallel computations. And moving towards a more flexible code.

Automatic allocation is used within all routines in phystd. No further mention to ngridmx and nqmx.

  1. ngridmx and nqmx are still used in LMDZ.GENERIC in the dyn3d part
  2. if the LMDZ4/LMDZ5 dynamical core is used, there is no more fixed dimensions ngridmx and nqmx --> a fully flexible parallel implementation is now possible (e.g. no need to recompile when changing numbers of processors)

The important stuff :

  • Compilation checked with ifort. OK with and without debug mode. No errors. Checked for: gcm, newstart, rcm1d, kcm1d
  • RUN GCM: Running an Earth test case. Comparison with previous revision --> debug mode : perfect match. bit by bit (diff command). checked with plots --> O1 mode : close match (checked with plots) --> O2 mode : sometimes up to 0.5 K departure.... BUT in this new version O2 and O1 are quite close while in previous version O1 and O2 differed by about, well, typically 0.5 K (pictures available on request)
  • RUN NEWSTART : perfect match (bit-by-bit) in either debug or normal mode.
  • RUN RCM1D : perfect match in normal mode.
  • RUN KCM1D : not tested (I don't know what is the use of kcm1d)

List of main changes :

  • Additional arguments to some subroutines (ngrid and nq)
  • F77 include strategy is obsolete and replaced by F90 module strategy In this new strategy arrays are allocatable and allocated once at first use This has to be done for all common featuring arrays defined with ngridmx or nqmx

surfdat.h >> surfdat_h.F90
tracer.h >> tracer_h.F90
comsaison.h >> comsaison_h.F90
comgeomfi.h >> comgeomfi_h.F90
comsoil.h >> comsoil_h.F90
comdiurn.h >> comdiurn_h.F90
fisice.h >> DELETED. was not used. probably a fossil.
watercap.h >> DELETED. variable put in surfdat_h.F90

  • F77 'save' strategy is obsolete and replaced by F90 'allocatable save' strategy (see previous point and e.g. new version of physiq.F90)
  • Suppressing any mention to advtrac.h which is a common in the dynamics and needs nqmx This was easily solved by adding an argument with tracer names, coming from the dynamics This is probably not a definitive solution, ... but this allows for generic physics to work easily with either LMDZ.GENERIC or LMDZ dynamical cores
  • Removing consistency tests between nq and nqmx ; and ngrid and ngridmx. No use now!
  • Adaptation of rcm1d, kcm1d, newstart given above-mentioned changes

A note on phyetat0 and soil_setting:

  • Now written so that a slice of horizontal size 'ngrid' starting at grid point 'cursor' is read in startfi.nc 'cursor' is defined in dimphys.h and initialized by inifis (or in newstart) this is useful for parallel computations. default behavior is the usual one : sequential runs, cursor is 1, size ngrid is the whole global domain

A note on an additional change :

  • nueffrad is now an argument to callcorrk as is the case for reffrad both are saved in physiq this is for consistency and lisibility (previously nueffrad was saved in callcorrk) ... but there is a call to a function which modifies nueffrad in physiq ... previously this was not modifying nueffrad (although it was quite cumbersome to detect this) ... to be conservative I kept this behaviour and highlighted it with an array nueffrad_dummy ... I added a comment because someone might want to change this
File size: 6.5 KB
RevLine 
[787]1      subroutine soil(ngrid,nsoil,firstcall,lastcall,
[135]2     &          therm_i,
3     &          timestep,tsurf,tsoil,
4     &          capcal,fluxgrd)
[787]5
6      use comsoil_h
7
[135]8      implicit none
9
10!-----------------------------------------------------------------------
11!  Author: Ehouarn Millour
12!
13!  Purpose: Compute soil temperature using an implict 1st order scheme
14
15!  Note: depths of layers and mid-layers, soil thermal inertia and
16!        heat capacity are commons in comsoil.h
17!-----------------------------------------------------------------------
18
19#include "dimensions.h"
20#include "dimphys.h"
21
22
23c-----------------------------------------------------------------------
24!  arguments
25!  ---------
26!  inputs:
27      integer ngrid     ! number of (horizontal) grid-points
28      integer nsoil     ! number of soil layers
29      logical firstcall ! identifier for initialization call
[787]30      logical lastcall
[135]31      real therm_i(ngrid,nsoil) ! thermal inertia
32      real timestep         ! time step
33      real tsurf(ngrid)   ! surface temperature
34! outputs:
35      real tsoil(ngrid,nsoil) ! soil (mid-layer) temperature
36      real capcal(ngrid) ! surface specific heat
37      real fluxgrd(ngrid) ! surface diffusive heat flux
38
39! local saved variables:
[787]40      real,dimension(:,:),save,allocatable :: mthermdiff ! mid-layer thermal diffusivity
41      real,dimension(:,:),save,allocatable :: thermdiff ! inter-layer thermal diffusivity
42      real,dimension(:),save,allocatable :: coefq ! q_{k+1/2} coefficients
43      real,dimension(:,:),save,allocatable :: coefd ! d_k coefficients
44      real,dimension(:,:),save,allocatable :: alph ! alpha_k coefficients
45      real,dimension(:,:),save,allocatable :: beta ! beta_k coefficients
46      real,save :: mu
[253]47           
[135]48! local variables:
49      integer ig,ik
50
[253]51
52!      print*,'tsoil=',tsoil
53!      print*,'tsurf=',tsurf
54
[135]55! 0. Initialisations and preprocessing step
56      if (firstcall) then
57      ! note: firstcall is set to .true. or .false. by the caller
58      !       and not changed by soil.F
[787]59
60      ALLOCATE(mthermdiff(ngrid,0:nsoilmx-1)) ! mid-layer thermal diffusivity
61      ALLOCATE(thermdiff(ngrid,nsoilmx-1))    ! inter-layer thermal diffusivity
62      ALLOCATE(coefq(0:nsoilmx-1))              ! q_{k+1/2} coefficients
63      ALLOCATE(coefd(ngrid,nsoilmx-1))        ! d_k coefficients
64      ALLOCATE(alph(ngrid,nsoilmx-1))         ! alpha_k coefficients
65      ALLOCATE(beta(ngrid,nsoilmx-1))         ! beta_k coefficients
66
[135]67! 0.1 Build mthermdiff(:), the mid-layer thermal diffusivities
68      do ig=1,ngrid
69        do ik=0,nsoil-1
70          mthermdiff(ig,ik)=therm_i(ig,ik+1)*therm_i(ig,ik+1)/volcapa
71!         write(*,*),'soil: ik: ',ik,' mthermdiff:',mthermdiff(ig,ik)
72        enddo
73      enddo
74
75! 0.2 Build thermdiff(:), the "interlayer" thermal diffusivities
76      do ig=1,ngrid
77        do ik=1,nsoil-1
78      thermdiff(ig,ik)=((layer(ik)-mlayer(ik-1))*mthermdiff(ig,ik)
79     &                +(mlayer(ik)-layer(ik))*mthermdiff(ig,ik-1))
80     &                    /(mlayer(ik)-mlayer(ik-1))
81!       write(*,*),'soil: ik: ',ik,' thermdiff:',thermdiff(ig,ik)
82        enddo
83      enddo
84
85! 0.3 Build coefficients mu, q_{k+1/2}, d_k, alpha_k and capcal
86      ! mu
87      mu=mlayer(0)/(mlayer(1)-mlayer(0))
88
89      ! q_{1/2}
90      coefq(0)=volcapa*layer(1)/timestep
91        ! q_{k+1/2}
92        do ik=1,nsoil-1
93          coefq(ik)=volcapa*(layer(ik+1)-layer(ik))
94     &                 /timestep
95        enddo
96
97      do ig=1,ngrid
98        ! d_k
99        do ik=1,nsoil-1
100          coefd(ig,ik)=thermdiff(ig,ik)/(mlayer(ik)-mlayer(ik-1))
101        enddo
102       
103        ! alph_{N-1}
104        alph(ig,nsoil-1)=coefd(ig,nsoil-1)/
105     &                  (coefq(nsoil-1)+coefd(ig,nsoil-1))
106        ! alph_k
107        do ik=nsoil-2,1,-1
108          alph(ig,ik)=coefd(ig,ik)/(coefq(ik)+coefd(ig,ik+1)*
109     &                              (1.-alph(ig,ik+1))+coefd(ig,ik))
110        enddo
111
112        ! capcal
113! Cstar
114        capcal(ig)=volcapa*layer(1)+
115     &              (thermdiff(ig,1)/(mlayer(1)-mlayer(0)))*
116     &              (timestep*(1.-alph(ig,1)))
117! Cs
118        capcal(ig)=capcal(ig)/(1.+mu*(1.0-alph(ig,1))*
119     &                         thermdiff(ig,1)/mthermdiff(ig,0))
[253]120      !write(*,*)'soil: ig=',ig,' capcal(ig)=',capcal(ig)
[135]121      enddo ! of do ig=1,ngrid
122           
123      else ! of if (firstcall)
124
[253]125
[135]126!  1. Compute soil temperatures
127! First layer:
128      do ig=1,ngrid
129        tsoil(ig,1)=(tsurf(ig)+mu*beta(ig,1)*
130     &                         thermdiff(ig,1)/mthermdiff(ig,0))/
131     &              (1.+mu*(1.0-alph(ig,1))*
132     &               thermdiff(ig,1)/mthermdiff(ig,0))
133      enddo
134! Other layers:
135      do ik=1,nsoil-1
136        do ig=1,ngrid
137          tsoil(ig,ik+1)=alph(ig,ik)*tsoil(ig,ik)+beta(ig,ik)
138        enddo
139      enddo
140     
141      endif! of if (firstcall)
142
143!  2. Compute beta coefficients (preprocessing for next time step)
144! Bottom layer, beta_{N-1}
145      do ig=1,ngrid
146        beta(ig,nsoil-1)=coefq(nsoil-1)*tsoil(ig,nsoil)
147     &                   /(coefq(nsoil-1)+coefd(ig,nsoil-1))
148      enddo
149! Other layers
150      do ik=nsoil-2,1,-1
151        do ig=1,ngrid
152          beta(ig,ik)=(coefq(ik)*tsoil(ig,ik+1)+
153     &                 coefd(ig,ik+1)*beta(ig,ik+1))/
154     &                 (coefq(ik)+coefd(ig,ik+1)*(1.0-alph(ig,ik+1))
155     &                  +coefd(ig,ik))
156        enddo
157      enddo
158
[253]159
[135]160!  3. Compute surface diffusive flux & calorific capacity
161      do ig=1,ngrid
162! Cstar
163!        capcal(ig)=volcapa(ig,1)*layer(ig,1)+
164!     &              (thermdiff(ig,1)/(mlayer(ig,1)-mlayer(ig,0)))*
165!     &              (timestep*(1.-alph(ig,1)))
166! Fstar
[253]167
168!         print*,'this far in soil 1'
169!         print*,'thermdiff=',thermdiff(ig,1)
170!         print*,'mlayer=',mlayer
171!         print*,'beta=',beta(ig,1)
172!         print*,'alph=',alph(ig,1)
173!         print*,'tsoil=',tsoil(ig,1)
174
[135]175        fluxgrd(ig)=(thermdiff(ig,1)/(mlayer(1)-mlayer(0)))*
176     &              (beta(ig,1)+(alph(ig,1)-1.0)*tsoil(ig,1))
177
178!        mu=mlayer(ig,0)/(mlayer(ig,1)-mlayer(ig,0))
179!        capcal(ig)=capcal(ig)/(1.+mu*(1.0-alph(ig,1))*
180!     &                         thermdiff(ig,1)/mthermdiff(ig,0))
181! Fs
182        fluxgrd(ig)=fluxgrd(ig)+(capcal(ig)/timestep)*
183     &              (tsoil(ig,1)*(1.+mu*(1.0-alph(ig,1))*
184     &                         thermdiff(ig,1)/mthermdiff(ig,0))
185     &               -tsurf(ig)-mu*beta(ig,1)*
186     &                          thermdiff(ig,1)/mthermdiff(ig,0))
187      enddo
188
[787]189      if (lastcall) then
190        IF ( ALLOCATED(mthermdiff)) DEALLOCATE(mthermdiff)
191        IF ( ALLOCATED(thermdiff)) DEALLOCATE(thermdiff)
192        IF ( ALLOCATED(coefq)) DEALLOCATE(coefq)
193        IF ( ALLOCATED(coefd)) DEALLOCATE(coefd)
194        IF ( ALLOCATED(alph)) DEALLOCATE(alph)
195        IF ( ALLOCATED(beta)) DEALLOCATE(beta)
196      endif
[253]197
[135]198      end
199
Note: See TracBrowser for help on using the repository browser.