/[MITgcm]/MITgcm/pkg/exf/exf_bulkformulae.F
ViewVC logotype

Diff of /MITgcm/pkg/exf/exf_bulkformulae.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.6 by heimbach, Fri Jul 2 00:48:23 2004 UTC revision 1.25 by jmc, Thu Dec 22 19:03:41 2011 UTC
# Line 1  Line 1 
1  c $Header$  C $Header$
2    C $Name$
3    
4  #include "EXF_OPTIONS.h"  #include "EXF_OPTIONS.h"
5    
6        subroutine exf_bulkformulae(mycurrenttime, mycurrentiter, mythid)  CBOP
7    C     !ROUTINE: EXF_BULKFORMULAE
8  c     ==================================================================  C     !INTERFACE:
9  c     SUBROUTINE exf_bulkformulae        SUBROUTINE EXF_BULKFORMULAE( myTime, myIter, myThid )
10  c     ==================================================================  
11  c  C     !DESCRIPTION: \bv
12  c     o Read-in atmospheric state and/or surface fluxes from files.  C     *==========================================================*
13  c  C     | SUBROUTINE EXF_BULKFORMULAE
14  c     o Use bulk formulae to estimate turbulent and/or radiative  C     | o Calculate bulk formula fluxes over open ocean
15  c       fluxes at the surface.  C     |   either following
16  c  C     |   Large and Pond, 1981 & 1982
17  c     NOTES:  C     |   or (if defined ALLOW_BULK_LARGEYEAGER04)
18  c     ======  C     |   Large and Yeager, 2004, NCAR/TN-460+STR.
19  c  C     *==========================================================*
20  c     See EXF_OPTIONS.h for a description of the various possible  C     \ev
21  c     ocean-model forcing configurations.  C
22  c  C
23  c     The bulk formulae of pkg/exf are not valid for sea-ice covered  C     NOTES:
24  c     oceans but they can be used in combination with a sea-ice model,  C     ======
25  c     for example, pkg/seaice, to specify open water flux contributions.  C
26  c  C     See EXF_OPTIONS.h for a description of the various possible
27  c     ==================================================================  C     ocean-model forcing configurations.
28  c  C
29  c       The calculation of the bulk surface fluxes has been adapted from  C     The bulk formulae of pkg/exf are not valid for sea-ice covered
30  c       the NCOM model which uses the formulae given in Large and Pond  C     oceans but they can be used in combination with a sea-ice model,
31  c       (1981 & 1982 )  C     for example, pkg/seaice, to specify open water flux contributions.
32  c  C
33  c  C     ==================================================================
34  c       Header taken from NCOM version: ncom1.4.1  C
35  c       -----------------------------------------  C     for Large and Pond, 1981 & 1982
36  c  C
37  c       Following procedures and coefficients in Large and Pond  C     The calculation of the bulk surface fluxes has been adapted from
38  c       (1981 ; 1982)  C     the NCOM model which uses the formulae given in Large and Pond
39  c  C     (1981 & 1982 )
40  c       Output: Bulk estimates of the turbulent surface fluxes.  C
41  c       -------  C
42  c  C     Header taken from NCOM version: ncom1.4.1
43  c       hs  - sensible heat flux  (W/m^2), into ocean  C     -----------------------------------------
44  c       hl  - latent   heat flux  (W/m^2), into ocean  C
45  c  C     Following procedures and coefficients in Large and Pond
46  c       Input:  C     (1981 ; 1982)
47  c       ------  C
48  c  C     Output: Bulk estimates of the turbulent surface fluxes.
49  c       us  - mean wind speed (m/s)     at height hu (m)  C     -------
50  c       th  - mean air temperature (K)  at height ht (m)  C
51  c       qh  - mean air humidity (kg/kg) at height hq (m)  C     hs  - sensible heat flux  (W/m^2), into ocean
52  c       sst - sea surface temperature (K)  C     hl  - latent   heat flux  (W/m^2), into ocean
53  c       tk0 - Kelvin temperature at 0 Celsius (K)  C
54  c  C     Input:
55  c       Assume 1) a neutral 10m drag coefficient =  C     ------
56  c  C
57  c                 cdn = .0027/u10 + .000142 + .0000764 u10  C     us  - mean wind speed (m/s)     at height hu (m)
58  c  C     th  - mean air temperature (K)  at height ht (m)
59  c              2) a neutral 10m stanton number =  C     qh  - mean air humidity (kg/kg) at height hq (m)
60  c  C     sst - sea surface temperature (K)
61  c                 ctn = .0327 sqrt(cdn), unstable  C     tk0 - Kelvin temperature at 0 Celsius (K)
62  c                 ctn = .0180 sqrt(cdn), stable  C
63  c  C     Assume 1) a neutral 10m drag coefficient =
64  c              3) a neutral 10m dalton number =  C
65  c  C               cdn = .0027/u10 + .000142 + .0000764 u10
66  c                 cen = .0346 sqrt(cdn)  C
67  c  C            2) a neutral 10m stanton number =
68  c              4) the saturation humidity of air at  C
69  c  C               ctn = .0327 sqrt(cdn), unstable
70  c                 t(k) = exf_BulkqSat(t)  (kg/m^3)  C               ctn = .0180 sqrt(cdn), stable
71  c  C
72  c       Note:  1) here, tstar = <wt>/u*, and qstar = <wq>/u*.  C            3) a neutral 10m dalton number =
73  c              2) wind speeds should all be above a minimum speed,  C
74  c                 say 0.5 m/s.  C               cen = .0346 sqrt(cdn)
75  c              3) with optional iteration loop, niter=3, should suffice.  C
76  c              4) this version is for analyses inputs with hu = 10m and  C            4) the saturation humidity of air at
77  c                 ht = hq.  C
78  c              5) sst enters in Celsius.  C               t(k) = exf_BulkqSat(t)  (kg/m^3)
79  c  C
80  c     ==================================================================  C     Note:  1) here, tstar = <wt>/u*, and qstar = <wq>/u*.
81  c  C            2) wind speeds should all be above a minimum speed,
82  c       started: Christian Eckert eckert@mit.edu 27-Aug-1999  C               say 0.5 m/s.
83  c  C            3) with optional iteration loop, niter=3, should suffice.
84  c       changed: Christian Eckert eckert@mit.edu 14-Jan-2000  C            4) this version is for analyses inputs with hu = 10m and
85  c              - restructured the original version in order to have a  C               ht = hq.
86  c                better interface to the MITgcmUV.  C            5) sst enters in Celsius.
87  c  C
88  c              Christian Eckert eckert@mit.edu  12-Feb-2000  C     ==================================================================
89  c              - Changed Routine names (package prefix: exf_)  C
90  c  C       started: Christian Eckert eckert@mit.edu 27-Aug-1999
91  c              Patrick Heimbach, heimbach@mit.edu  04-May-2000  C
92  c              - changed the handling of precip and sflux with respect  C     changed: Christian Eckert eckert@mit.edu 14-Jan-2000
93  c                to CPP options ALLOW_BULKFORMULAE and ALLOW_ATM_TEMP  C            - restructured the original version in order to have a
94  c              - included some CPP flags ALLOW_BULKFORMULAE to make  C              better interface to the MITgcmUV.
95  c                sure ALLOW_ATM_TEMP, ALLOW_ATM_WIND are used only in  C
96  c                conjunction with defined ALLOW_BULKFORMULAE  C            Christian Eckert eckert@mit.edu  12-Feb-2000
97  c              - statement functions discarded  C            - Changed Routine names (package prefix: exf_)
98  c  C
99  c              Ralf.Giering@FastOpt.de 25-Mai-2000  C            Patrick Heimbach, heimbach@mit.edu  04-May-2000
100  c              - total rewrite using new subroutines  C            - changed the handling of precip and sflux with respect
101  c  C              to CPP options ALLOW_BULKFORMULAE and ALLOW_ATM_TEMP
102  c              Detlef Stammer: include river run-off. Nov. 21, 2001  C            - included some CPP flags ALLOW_BULKFORMULAE to make
103  c  C              sure ALLOW_ATM_TEMP, ALLOW_ATM_WIND are used only in
104  c              heimbach@mit.edu, 10-Jan-2002  C              conjunction with defined ALLOW_BULKFORMULAE
105  c              - changes to enable field swapping  C            - statement functions discarded
106  c  C
107  c       mods for pkg/seaice: menemenlis@jpl.nasa.gov 20-Dec-2002  C            Ralf.Giering@FastOpt.de 25-Mai-2000
108  c  C            - total rewrite using new subroutines
109  c     ==================================================================  C
110  c     SUBROUTINE exf_bulkformulae  C            Detlef Stammer: include river run-off. Nov. 21, 2001
111  c     ==================================================================  C
112    C            heimbach@mit.edu, 10-Jan-2002
113        implicit none  C            - changes to enable field swapping
114    C
115  c     == global variables ==  C     mods for pkg/seaice: menemenlis@jpl.nasa.gov 20-Dec-2002
116    C
117    C     martin.losch@awi.de: merged with exf_bulk_largeyeager04, 21-May-2010
118    C
119    C     ==================================================================
120    C
121    C     for Large and Yeager, 2004
122    C
123    C === Turbulent Fluxes :
124    C  * use the approach "B": shift coeff to height & stability of the
125    C    atmosphere state (instead of "C": shift temp & humid to the height
126    C    of wind, then shift the coeff to this height & stability of the atmos).
127    C  * similar to EXF (except over sea-ice) ; default parameter values
128    C    taken from Large & Yeager.
129    C  * assume that Qair & Tair inputs are from the same height (zq=zt)
130    C  * formulae in short:
131    C     wind stress = (ust,vst) = rhoA * Cd * Ws * (del.u,del.v)
132    C     Sensib Heat flux = fsha = rhoA * Ch * Ws * del.T * CpAir
133    C     Latent Heat flux = flha = rhoA * Ce * Ws * del.Q * Lvap
134    C                      = -Evap * Lvap
135    C   with Ws = wind speed = sqrt(del.u^2 +del.v^2) ;
136    C        del.T = Tair - Tsurf ; del.Q = Qair - Qsurf ;
137    C        Cd,Ch,Ce = drag coefficient, Stanton number and Dalton number
138    C              respectively [no-units], function of height & stability
139    
140    C     !USES:
141           IMPLICIT NONE
142    C     === Global variables ===
143  #include "EEPARAMS.h"  #include "EEPARAMS.h"
144  #include "SIZE.h"  #include "SIZE.h"
145  #include "PARAMS.h"  #include "PARAMS.h"
146  #include "DYNVARS.h"  #include "DYNVARS.h"
147  #include "GRID.h"  #include "GRID.h"
148    
149  #include "exf_param.h"  #include "EXF_PARAM.h"
150  #include "exf_fields.h"  #include "EXF_FIELDS.h"
151  #include "exf_constants.h"  #include "EXF_CONSTANTS.h"
152    
153  #ifdef ALLOW_AUTODIFF_TAMC  #ifdef ALLOW_AUTODIFF_TAMC
154  #include "tamc.h"  #include "tamc.h"
155  #endif  #endif
156    
157  c     == routine arguments ==  C     !INPUT/OUTPUT PARAMETERS:
158    C     input:
159        integer mythid  C     myTime  :: Current time in simulation
160        integer mycurrentiter  C     myIter  :: Current iteration number in simulation
161        _RL     mycurrenttime  C     myThid  :: My Thread Id number
162          _RL     myTime
163          INTEGER myIter
164          INTEGER myThid
165    C     output:
166    CEOP
167    
168  #ifdef ALLOW_BULKFORMULAE  #ifdef ALLOW_BULKFORMULAE
169    C     == external Functions
170    
171  c     == local variables ==  C     == Local variables ==
172    C     i,j      :: grid point indices
173        integer bi,bj  C     bi,bj    :: tile indices
174        integer i,j,k  C     ssq      :: saturation specific humidity [kg/kg] in eq. with Sea-Surface water
175          INTEGER i,j,bi,bj
176        _RL     aln  
177          _RL czol
178          _RL Tsf                   ! surface temperature [K]
179          _RL wsm                   ! limited wind speed [m/s] (> umin)
180          _RL t0                    ! virtual temperature [K]
181    C     these need to be 2D-arrays for vectorizing code
182          _RL tstar (1:sNx,1:sNy)   ! turbulent temperature scale [K]
183          _RL qstar (1:sNx,1:sNy)   ! turbulent humidity scale  [kg/kg]
184          _RL ustar (1:sNx,1:sNy)   ! friction velocity [m/s]
185          _RL tau   (1:sNx,1:sNy)   ! surface stress coef = rhoA * Ws * sqrt(Cd)
186          _RL rdn   (1:sNx,1:sNy)   ! neutral, zref (=10m) values of rd
187          _RL rd    (1:sNx,1:sNy)   ! = sqrt(Cd)          [-]
188          _RL delq  (1:sNx,1:sNy)   ! specific humidity difference [kg/kg]
189          _RL deltap(1:sNx,1:sNy)
190    C
191    #ifdef ALLOW_BULK_LARGEYEAGER04
192          _RL dzTmp
193    #endif
194          _RL SSTtmp
195          _RL ssq
196          _RL re                    ! = Ce / sqrt(Cd)     [-]
197          _RL rh                    ! = Ch / sqrt(Cd)     [-]
198          _RL ren, rhn              ! neutral, zref (=10m) values of re, rh
199          _RL usn, usm
200          _RL stable                ! = 1 if stable ; = 0 if unstable
201          _RL huol                  ! stability parameter at zwd [-] (=z/Monin-Obuklov length)
202          _RL htol                  ! stability parameter at zth [-]
203          _RL hqol
204          _RL x                     ! stability function  [-]
205          _RL xsq                   ! = x^2               [-]
206          _RL psimh                 ! momentum stability function
207          _RL psixh                 ! latent & sensib. stability function
208          _RL zwln                  ! = log(zwd/zref)
209          _RL ztln                  ! = log(zth/zref)
210          _RL tmpbulk
211          _RL recip_rhoConstFresh
212          INTEGER ksrf, ksrfp1
213          INTEGER iter
214    C     solve4Stress :: if F, by-pass momentum turb. flux (wind-stress) calculation
215          LOGICAL solve4Stress
216    #ifdef ALLOW_ATM_WIND
217          PARAMETER ( solve4Stress = .TRUE. )
218    #else
219    # ifdef ALLOW_ATM_TEMP
220          _RL windStress            ! surface wind-stress (@ grid cell center)
221    # endif
222    #endif
223    
 #ifdef ALLOW_ATM_TEMP  
       integer iter  
       _RL     delq  
       _RL     deltap  
       _RL     hqol  
       _RL     htol  
       _RL     huol  
       _RL     psimh  
       _RL     psixh  
       _RL     qstar  
       _RL     rd  
       _RL     re  
       _RL     rdn  
       _RL     rh  
       _RL     ssttmp  
       _RL     ssq  
       _RL     stable  
       _RL     tstar  
       _RL     t0  
       _RL     ustar  
       _RL     uzn  
       _RL     shn  
       _RL     xsq  
       _RL     x  
       _RL     tau  
224  #ifdef ALLOW_AUTODIFF_TAMC  #ifdef ALLOW_AUTODIFF_TAMC
225        integer ikey_1        integer ikey_1
226        integer ikey_2        integer ikey_2
227  #endif  #endif
 #endif /* ALLOW_ATM_TEMP */  
228    
229        _RL     ustmp  C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
       _RL     us  
       _RL     cw  
       _RL     sw  
       _RL     sh  
       _RL     hs(1-olx:snx+olx,1-oly:sny+oly,nsx,nsy)  
       _RL     hl(1-olx:snx+olx,1-oly:sny+oly,nsx,nsy)  
       _RL     hfl  
       _RL     tmpbulk  
   
 c     == external functions ==  
   
       integer  ilnblnk  
       external ilnblnk  
   
       _RL       exf_BulkqSat  
       external  exf_BulkqSat  
       _RL       exf_BulkCdn  
       external  exf_BulkCdn  
       _RL       exf_BulkRhn  
       external  exf_BulkRhn  
230    
231  #ifndef ALLOW_ATM_WIND  #ifndef ALLOW_ATM_WIND
232        _RL       TMP1  #ifdef ALLOW_BULK_LARGEYEAGER04
233        _RL       TMP2        solve4Stress = wspeedfile .NE. ' '
234        _RL       TMP3  #else
235        _RL       TMP4        solve4Stress = .FALSE.
236        _RL       TMP5  #endif
237  #endif  #endif
238    
239  c     == end of interface ==  C-- Set surface parameters :
240          zwln = LOG(hu/zref)
241  cph   This statement cannot be a PARAMETER statement in the header,        ztln = LOG(ht/zref)
242  cph   but must come here; it's not fortran77 standard        czol = hu*karman*gravity_mks
243        aln = log(ht/zref)  C--   abbreviation
244          recip_rhoConstFresh = 1. _d 0/rhoConstFresh
 c--   Use atmospheric state to compute surface fluxes.  
245    
246  c     Loop over tiles.  c     Loop over tiles.
247  #ifdef ALLOW_AUTODIFF_TAMC  #ifdef ALLOW_AUTODIFF_TAMC
248  C--   HPF directive to help TAMC  C--   HPF directive to help TAMC
249  CHPF$ INDEPENDENT  CHPF$ INDEPENDENT
250  #endif  #endif
251        do bj = mybylo(mythid),mybyhi(mythid)        DO bj = myByLo(myThid),myByHi(myThid)
252  #ifdef ALLOW_AUTODIFF_TAMC  #ifdef ALLOW_AUTODIFF_TAMC
253  C--    HPF directive to help TAMC  C--    HPF directive to help TAMC
254  CHPF$  INDEPENDENT  CHPF$  INDEPENDENT
255  #endif  #endif
256          do bi = mybxlo(mythid),mybxhi(mythid)         DO bi = myBxLo(myThid),myBxHi(myThid)
257            ksrf   = 1
258            k = 1          ksrfp1 = 2
259            DO j = 1,sNy
260            do j = 1,sny           DO i = 1,sNx
             do i = 1,snx  
261    
262  #ifdef ALLOW_AUTODIFF_TAMC  #ifdef ALLOW_AUTODIFF_TAMC
263                 act1 = bi - myBxLo(myThid)            act1 = bi - myBxLo(myThid)
264                 max1 = myBxHi(myThid) - myBxLo(myThid) + 1            max1 = myBxHi(myThid) - myBxLo(myThid) + 1
265                 act2 = bj - myByLo(myThid)            act2 = bj - myByLo(myThid)
266                 max2 = myByHi(myThid) - myByLo(myThid) + 1            max2 = myByHi(myThid) - myByLo(myThid) + 1
267                 act3 = myThid - 1            act3 = myThid - 1
268                 max3 = nTx*nTy            max3 = nTx*nTy
269                 act4 = ikey_dynamics - 1            act4 = ikey_dynamics - 1
270    
271                 ikey_1 = i            ikey_1 = i
272       &              + sNx*(j-1)       &         + sNx*(j-1)
273       &              + sNx*sNy*act1       &         + sNx*sNy*act1
274       &              + sNx*sNy*max1*act2       &         + sNx*sNy*max1*act2
275       &              + sNx*sNy*max1*max2*act3       &         + sNx*sNy*max1*max2*act3
276       &              + sNx*sNy*max1*max2*max3*act4       &         + sNx*sNy*max1*max2*max3*act4
 #endif  
   
 #ifdef ALLOW_DOWNWARD_RADIATION  
 c--   Compute net from downward and downward from net longwave and  
 c     shortwave radiation, if needed.  
 c     lwflux = Stefan-Boltzman constant * emissivity * SST - lwdown  
 c     swflux = - ( 1 - albedo ) * swdown  
   
 #ifdef ALLOW_ATM_TEMP  
       if ( lwfluxfile .EQ. ' ' .AND. lwdownfile .NE. ' ' )  
      &     lwflux(i,j,bi,bj) = 5.5 _d -08 *  
      &              ((theta(i,j,k,bi,bj)+cen2kel)**4)  
      &              - lwdown(i,j,bi,bj)  
       if ( lwfluxfile .NE. ' ' .AND. lwdownfile .EQ. ' ' )  
      &     lwdown(i,j,bi,bj) = 5.5 _d -08 *  
      &              ((theta(i,j,k,bi,bj)+cen2kel)**4)  
      &              - lwflux(i,j,bi,bj)  
 #endif  
   
 #if defined(ALLOW_ATM_TEMP) || defined(SHORTWAVE_HEATING)  
       if ( swfluxfile .EQ. ' ' .AND. swdownfile .NE. ' ' )  
      &     swflux(i,j,bi,bj) = -(1.0-exf_albedo) * swdown(i,j,bi,bj)  
       if ( swfluxfile .NE. ' ' .AND. swdownfile .EQ. ' ' )  
      &     swdown(i,j,bi,bj) = -swflux(i,j,bi,bj) / (1.0-exf_albedo)  
277  #endif  #endif
278    
 #endif /* ALLOW_DOWNWARD_RADIATION */  
   
 c--   Compute the turbulent surface fluxes.  
   
 #ifdef ALLOW_ATM_WIND  
 c             Wind speed and direction.  
               ustmp = uwind(i,j,bi,bj)*uwind(i,j,bi,bj) +  
      &                vwind(i,j,bi,bj)*vwind(i,j,bi,bj)  
               if ( ustmp .ne. 0. _d 0 ) then  
                 us = sqrt(ustmp)  
                 cw = uwind(i,j,bi,bj)/us  
                 sw = vwind(i,j,bi,bj)/us  
               else  
                 us = 0. _d 0  
                 cw = 0. _d 0  
                 sw = 0. _d 0  
               endif  
               sh = max(us,umin)  
 #else  /* ifndef ALLOW_ATM_WIND */  
279  #ifdef ALLOW_ATM_TEMP  #ifdef ALLOW_ATM_TEMP
280    
 c             The variables us, sh and rdn have to be computed from  
 c             given wind stresses inverting relationship for neutral  
 c             drag coeff. cdn.  
 c             The inversion is based on linear and quadratic form of  
 c             cdn(umps); ustar can be directly computed from stress;  
   
               ustmp = ustress(i,j,bi,bj)*ustress(i,j,bi,bj) +  
      &                vstress(i,j,bi,bj)*vstress(i,j,bi,bj)  
               if ( ustmp .ne. 0. _d 0 ) then  
                 ustar = sqrt(ustmp/atmrho)  
                 cw = ustress(i,j,bi,bj)/sqrt(ustmp)  
                 sw = vstress(i,j,bi,bj)/sqrt(ustmp)  
               else  
                  ustar = 0. _d 0  
                  cw    = 0. _d 0  
                  sw    = 0. _d 0  
               endif  
   
               if ( ustar .eq. 0. _d 0 ) then  
                 us = 0. _d 0  
               else if ( ustar .lt. ustofu11 ) then  
                 tmp1 = -cquadrag_2/cquadrag_1/2  
                 tmp2 = sqrt(tmp1*tmp1 + ustar*ustar/cquadrag_1)  
                 us   = sqrt(tmp1 + tmp2)  
               else  
                 tmp3 = clindrag_2/clindrag_1/3  
                 tmp4 = ustar*ustar/clindrag_1/2 - tmp3**3  
                 tmp5 = sqrt(ustar*ustar/clindrag_1*  
      &                      (ustar*ustar/clindrag_1/4 - tmp3**3))  
                 us   = (tmp4 + tmp5)**(1/3) +  
      &                 tmp3**2 * (tmp4 + tmp5)**(-1/3) - tmp3  
               endif  
   
               if ( us .ne. 0 ) then  
                  rdn = ustar/us  
               else  
                  rdn = 0. _d 0  
               end if  
   
               sh    = max(us,umin)  
 #endif /* ALLOW_ATM_TEMP */  
 #endif /* ifndef ALLOW_ATM_WIND */  
   
 #ifdef ALLOW_ATM_TEMP  
   
 c             Initial guess: z/l=0.0; hu=ht=hq=z  
 c             Iterations:    converge on z/l and hence the fluxes.  
 c             t0     : virtual temperature (K)  
 c             ssq    : sea surface humidity (kg/kg)  
 c             deltap : potential temperature diff (K)  
   
               if ( atemp(i,j,bi,bj) .ne. 0. _d 0 ) then  
                 t0     = atemp(i,j,bi,bj)*  
      &                   (exf_one + humid_fac*aqh(i,j,bi,bj))  
                 ssttmp = theta(i,j,k,bi,bj)  
                 tmpbulk= exf_BulkqSat(ssttmp + cen2kel)  
                 ssq    = saltsat*tmpbulk/atmrho  
                 deltap = atemp(i,j,bi,bj)   + gamma_blk*ht -  
      &                   ssttmp - cen2kel  
                 delq   = aqh(i,j,bi,bj) - ssq  
                 stable = exf_half + sign(exf_half, deltap)  
281  #ifdef ALLOW_AUTODIFF_TAMC  #ifdef ALLOW_AUTODIFF_TAMC
282  CADJ STORE sh     = comlev1_exf_1, key = ikey_1            deltap(i,j) = 0. _d 0
283              delq(i,j)   = 0. _d 0
284  #endif  #endif
285                  tmpbulk= exf_BulkCdn(sh)  C--- Compute turbulent surface fluxes
286                  rdn    = sqrt(tmpbulk)  C-   Pot. Temp and saturated specific humidity
287                  ustar  = rdn*sh            IF ( atemp(i,j,bi,bj) .NE. 0. _d 0 ) THEN
288                  tmpbulk= exf_BulkRhn(stable)  C-   Surface Temp.
289                  tstar  = tmpbulk*deltap             Tsf = theta(i,j,ksrf,bi,bj) + cen2kel
290                  qstar  = cdalton*delq             IF ( sstExtrapol.GT.0. _d 0 ) THEN
291                SSTtmp = sstExtrapol
292         &              *( theta(i,j,ksrf,bi,bj)-theta(i,j,ksrfp1,bi,bj) )
293         &              *  maskC(i,j,ksrfp1,bi,bj)
294                Tsf = Tsf + MAX( SSTtmp, 0. _d 0 )
295               ENDIF
296    c
297               tmpbulk = cvapor_fac*exp(-cvapor_exp/Tsf)
298               ssq = saltsat*tmpbulk/atmrho
299               deltap(i,j) = atemp(i,j,bi,bj) + gamma_blk*ht - Tsf
300               delq(i,j)   = aqh(i,j,bi,bj) - ssq
301    C--  no negative evaporation over ocean:
302               IF ( noNegativeEvap ) delq(i,j) = MIN( 0. _d 0, delq(i,j) )
303    
304    C--  initial guess for exchange coefficients:
305    C    take U_N = del.U ; stability from del.Theta ;
306               stable = exf_half + SIGN(exf_half, deltap(i,j))
307    
308                  do iter = 1,niter_bulk  #ifndef ALLOW_ATM_WIND
309               IF ( solve4Stress ) THEN
310    #endif
311    #ifdef ALLOW_AUTODIFF_TAMC
312    CADJ STORE sh(i,j,bi,bj)     = comlev1_exf_1, key = ikey_1
313    #endif /* ALLOW_AUTODIFF_TAMC */
314    C--   Wind speed
315                wsm        = sh(i,j,bi,bj)
316                tmpbulk    = exf_scal_BulkCdn *
317         &           ( cdrag_1/wsm + cdrag_2 + cdrag_3*wsm )
318                rdn(i,j)   = SQRT(tmpbulk)
319                ustar(i,j) = rdn(i,j)*wsm
320    #ifndef ALLOW_ATM_WIND
321               ELSE
322                rdn(i,j)   = 0. _d 0
323                windStress = wStress(i,j,bi,bj)
324                ustar(i,j) = sqrt(windStress/atmrho)
325    c           tau(i,j)   = windStress/ustar(i,j)
326                tau(i,j)   = sqrt(windStress*atmrho)
327               ENDIF
328    #endif /* ALLOW_ATM_WIND */
329    
330    C--  initial guess for exchange other coefficients:
331               rhn = (exf_one-stable)*cstanton_1 + stable*cstanton_2
332               ren = cDalton
333    C--  calculate turbulent scales
334               tstar(i,j)=rhn*deltap(i,j)
335               qstar(i,j)=ren*delq(i,j)
336    
337              ELSE
338    C     atemp(i,j,bi,bj) .EQ. 0.
339               tstar (i,j) = 0. _d 0
340               qstar (i,j) = 0. _d 0
341               ustar (i,j) = 0. _d 0
342               tau   (i,j) = 0. _d 0
343               rdn   (i,j) = 0. _d 0
344              ENDIF
345             ENDDO
346            ENDDO
347            DO iter=1,niter_bulk
348             DO j = 1,sNy
349              DO i = 1,sNx
350               IF ( atemp(i,j,bi,bj) .NE. 0. _d 0 ) THEN
351    C--- iterate with psi-functions to find transfer coefficients
352    
353  #ifdef ALLOW_AUTODIFF_TAMC  #ifdef ALLOW_AUTODIFF_TAMC
354                     ikey_2 = iter              ikey_2 = i
355       &                  + niter_bulk*(i-1)       &           + sNx*(j-1)
356       &                  + niter_bulk*sNx*(j-1)       &           + sNx*sNy*(iter-1)
357       &                  + niter_bulk*sNx*sNy*act1       &           + sNx*sNy*niter_bulk*act1
358       &                  + niter_bulk*sNx*sNy*max1*act2       &           + sNx*sNy*niter_bulk*max1*act2
359       &                  + niter_bulk*sNx*sNy*max1*max2*act3       &           + sNx*sNy*niter_bulk*max1*max2*act3
360       &                  + niter_bulk*sNx*sNy*max1*max2*max3*act4       &           + sNx*sNy*niter_bulk*max1*max2*max3*act4
361    CADJ STORE rdn   (i,j)       = comlev1_exf_2, key = ikey_2
362  CADJ STORE rdn    = comlev1_exf_2, key = ikey_2  CADJ STORE ustar (i,j)       = comlev1_exf_2, key = ikey_2
363  CADJ STORE ustar  = comlev1_exf_2, key = ikey_2  CADJ STORE qstar (i,j)       = comlev1_exf_2, key = ikey_2
364  CADJ STORE qstar  = comlev1_exf_2, key = ikey_2  CADJ STORE tstar (i,j)       = comlev1_exf_2, key = ikey_2
365  CADJ STORE tstar  = comlev1_exf_2, key = ikey_2  CADJ STORE sh    (i,j,bi,bj) = comlev1_exf_2, key = ikey_2
366  CADJ STORE sh     = comlev1_exf_2, key = ikey_2  CADJ STORE wspeed(i,j,bi,bj) = comlev1_exf_2, key = ikey_2
367  CADJ STORE us     = comlev1_exf_2, key = ikey_2  #endif
368  #endif  
369                t0   = atemp(i,j,bi,bj)*
370                    huol   = czol*(tstar/t0 +       &           (exf_one + humid_fac*aqh(i,j,bi,bj))
371       &                     qstar/(exf_one/humid_fac+aqh(i,j,bi,bj)))/              huol = ( tstar(i,j)/t0 +
372       &                           ustar**2       &               qstar(i,j)/(exf_one/humid_fac+aqh(i,j,bi,bj))
373                    huol   = max(huol,zolmin)       &              )*czol/(ustar(i,j)*ustar(i,j))
374                    stable = exf_half + sign(exf_half, huol)  #ifdef ALLOW_BULK_LARGEYEAGER04
375                    htol   = huol*ht/hu              tmpbulk = MIN(abs(huol),10. _d 0)
376                    hqol   = huol*hq/hu              huol   = SIGN(tmpbulk , huol)
377    #else
378    C--   Large&Pond1981:
379                huol   = max(huol,zolmin)
380    #endif /* ALLOW_BULK_LARGEYEAGER04 */
381                htol   = huol*ht/hu
382                hqol   = huol*hq/hu
383                stable = exf_half + sign(exf_half, huol)
384    
385  c                 Evaluate all stability functions assuming hq = ht.  c                 Evaluate all stability functions assuming hq = ht.
386                    xsq    = max(sqrt(abs(exf_one - 16.*huol)),exf_one)  #ifndef ALLOW_ATM_WIND
387                     x     = sqrt(xsq)              IF ( solve4Stress ) THEN
388                    psimh  = -psim_fac*huol*stable +  #endif
389       &                     (exf_one - stable)*  #ifdef ALLOW_BULK_LARGEYEAGER04
390       &                     log((exf_one + x*(exf_two + x))*  C--   Large&Yeager04:
391       &                     (exf_one + xsq)/8.) - exf_two*atan(x) +               xsq    = SQRT( ABS(exf_one - huol*16. _d 0) )
392       &                     pi*exf_half  #else
393                    xsq    = max(sqrt(abs(exf_one - 16.*htol)),exf_one)  C--   Large&Pond1981:
394                    psixh  = -psim_fac*htol*stable + (exf_one - stable)*               xsq    = max(sqrt(abs(exf_one - 16.*huol)),exf_one)
395       &                     exf_two*log((exf_one + xsq)/exf_two)  #endif /* ALLOW_BULK_LARGEYEAGER04 */
396                 x      = SQRT(xsq)
397  c                 Shift wind speed using old coefficient               psimh  = -psim_fac*huol*stable
398  ccc                  rd   = rdn/(exf_one + rdn/karman*       &               +(exf_one-stable)*
399  ccc     &                 (log(hu/zref) - psimh) )       &                ( LOG( (exf_one + exf_two*x + xsq)*
400                    rd     = rdn/(exf_one - rdn/karman*psimh )       &                       (exf_one+xsq)*.125 _d 0 )
401                    shn    = sh*rd/rdn       &                  -exf_two*ATAN(x) + exf_half*pi )
402                    uzn    = max(shn, umin)  #ifndef ALLOW_ATM_WIND
403                ELSE
404  c                 Update the transfer coefficients at 10 meters               psimh  = 0. _d 0
405  c                 and neutral stability.              ENDIF
406    #endif
407                    tmpbulk= exf_BulkCdn(uzn)  #ifdef ALLOW_BULK_LARGEYEAGER04
408                    rdn    = sqrt(tmpbulk)  C--   Large&Yeager04:
409                xsq   = SQRT( ABS(exf_one - htol*16. _d 0) )
410  c                 Shift all coefficients to the measurement height  #else
411  c                 and stability.  C--   Large&Pond1981:
412  c                 rd = rdn/(exf_one + rdn/karman*(log(hu/zref) - psimh))              xsq   = max(sqrt(abs(exf_one - 16.*htol)),exf_one)
413                    rd     = rdn/(exf_one - rdn/karman*psimh)  #endif /* ALLOW_BULK_LARGEYEAGER04 */
414                    tmpbulk= exf_BulkRhn(stable)              psixh = -psim_fac*htol*stable + (exf_one-stable)*
415                    rh     = tmpbulk/( exf_one +       &               ( exf_two*LOG(exf_half*(exf_one+xsq)) )
416       &                               tmpbulk/karman*(aln - psixh) )  
417                    re     = cdalton/( exf_one +  #ifndef ALLOW_ATM_WIND
418       &                               cdalton/karman*(aln - psixh) )              IF ( solve4Stress ) THEN
419    #endif
420  c                 Update ustar, tstar, qstar using updated, shifted  C-   Shift wind speed using old coefficient
421  c                 coefficients.  #ifdef ALLOW_BULK_LARGEYEAGER04
422                    ustar  = rd*sh    C--   Large&Yeager04:
423                    qstar  = re*delq               dzTmp = (zwln-psimh)/karman
424                    tstar  = rh*deltap               usn   = wspeed(i,j,bi,bj)/(exf_one + rdn(i,j)*dzTmp )
425                    tau    = atmrho*ustar**2  #else
426                    tau    = tau*us/sh  C--   Large&Pond1981:
427    c           rd(i,j)= rdn(i,j)/(exf_one - rdn(i,j)/karman*psimh )
428    c           usn    = sh(i,j,bi,bj)*rd(i,j)/rdn(i,j)
429    c     ML: the original formulation above is replaced below to be
430    c     similar to largeyeager04, but does not give the same results, strange
431                 usn   = sh(i,j,bi,bj)/(exf_one - rdn(i,j)/karman*psimh)
432    #endif /* ALLOW_BULK_LARGEYEAGER04 */
433                 usm   = MAX(usn, umin)
434    
435    C-   Update the 10m, neutral stability transfer coefficients (momentum)
436                 tmpbulk  = exf_scal_BulkCdn *
437         &            ( cdrag_1/usm + cdrag_2 + cdrag_3*usm )
438                 rdn(i,j)   = SQRT(tmpbulk)
439    #ifdef ALLOW_BULK_LARGEYEAGER04
440                 rd(i,j)    = rdn(i,j)/(exf_one + rdn(i,j)*dzTmp)
441    #else
442                 rd(i,j)    = rdn(i,j)/(exf_one - rdn(i,j)/karman*psimh)
443    #endif /* ALLOW_BULK_LARGEYEAGER04 */
444                 ustar(i,j) = rd(i,j)*sh(i,j,bi,bj)
445    C-   Coeff:
446                 tau(i,j)   = atmrho*rd(i,j)*wspeed(i,j,bi,bj)
447    #ifndef ALLOW_ATM_WIND
448                ENDIF
449    #endif
450    
451                  enddo  C-   Update the 10m, neutral stability transfer coefficients (sens&evap)
452                rhn = (exf_one-stable)*cstanton_1 + stable*cstanton_2
453                ren = cDalton
454    
455    C-   Shift all coefficients to the measurement height and stability.
456                rh = rhn/(exf_one + rhn*(ztln-psixh)/karman)
457                re = ren/(exf_one + ren*(ztln-psixh)/karman)
458    
459    C--  Update ustar, tstar, qstar using updated, shifted coefficients.
460                qstar(i,j) = re*delq(i,j)
461                tstar(i,j) = rh*deltap(i,j)
462    
463               ENDIF
464              ENDDO
465             ENDDO
466    c end of iteration loop
467            ENDDO
468            DO j = 1,sNy
469             DO i = 1,sNx
470              IF ( atemp(i,j,bi,bj) .NE. 0. _d 0 ) THEN
471    
472  #ifdef ALLOW_AUTODIFF_TAMC  #ifdef ALLOW_AUTODIFF_TAMC
473  CADJ STORE ustar  = comlev1_exf_1, key = ikey_1             ikey_1 = i
474  CADJ STORE qstar  = comlev1_exf_1, key = ikey_1       &          + sNx*(j-1)
475  CADJ STORE tstar  = comlev1_exf_1, key = ikey_1       &          + sNx*sNy*act1
476  CADJ STORE tau    = comlev1_exf_1, key = ikey_1       &          + sNx*sNy*max1*act2
477  CADJ STORE cw     = comlev1_exf_1, key = ikey_1       &          + sNx*sNy*max1*max2*act3
478  CADJ STORE sw     = comlev1_exf_1, key = ikey_1       &          + sNx*sNy*max1*max2*max3*act4
479    CADJ STORE qstar(i,j)    = comlev1_exf_1, key = ikey_1
480    CADJ STORE tstar(i,j)    = comlev1_exf_1, key = ikey_1
481    CADJ STORE tau  (i,j)    = comlev1_exf_1, key = ikey_1
482    CADJ STORE rd   (i,j)    = comlev1_exf_1, key = ikey_1
483    #endif /* ALLOW_AUTODIFF_TAMC */
484    
485    C-   Turbulent Fluxes
486               hs(i,j,bi,bj) = atmcp*tau(i,j)*tstar(i,j)
487               hl(i,j,bi,bj) = flamb*tau(i,j)*qstar(i,j)
488    #ifndef EXF_READ_EVAP
489    C   change sign and convert from kg/m^2/s to m/s via rhoConstFresh
490    c          evap(i,j,bi,bj) = -recip_rhonil*tau(i,j)*qstar(i,j)
491               evap(i,j,bi,bj) = -recip_rhoConstFresh*tau(i,j)*qstar(i,j)
492    C   but older version was using rhonil instead:
493    c           evap(i,j,bi,bj) = -recip_rhonil*tau(i,j)*qstar(i,j)
494    #endif
495    #ifdef ALLOW_ATM_WIND
496    c       ustress(i,j,bi,bj) = tau(i,j)*rd(i,j)*ws*cw(i,j,bi,bj)
497    c       vstress(i,j,bi,bj) = tau(i,j)*rd(i,j)*ws*sw(i,j,bi,bj)
498    C- jmc: below is how it should be written ; different from above when
499    C       both wind-speed & 2 compon. of the wind are specified, and in
500    C-      this case, formula below is better.
501               tmpbulk =  tau(i,j)*rd(i,j)
502               ustress(i,j,bi,bj) = tmpbulk*uwind(i,j,bi,bj)
503               vstress(i,j,bi,bj) = tmpbulk*vwind(i,j,bi,bj)
504  #endif  #endif
505    
506                  hs(i,j,bi,bj)      = atmcp*tau*tstar/ustar  c IF ( ATEMP(i,j,bi,bj) .NE. 0. )
507                  hl(i,j,bi,bj)      = flamb*tau*qstar/ustar            else
508  #ifndef EXF_READ_EVAP  #ifdef ALLOW_ATM_WIND
509  cdm             evap(i,j,bi,bj)    = tau*qstar/ustar             ustress(i,j,bi,bj) = 0. _d 0
510  cdm !!! need to change sign and to convert from kg/m^2/s to m/s !!!             vstress(i,j,bi,bj) = 0. _d 0
511                  evap(i,j,bi,bj)    = -recip_rhonil*tau*qstar/ustar  #endif /* ALLOW_ATM_WIND */
512  #endif             hflux  (i,j,bi,bj) = 0. _d 0
513                  ustress(i,j,bi,bj) = tau*cw             evap   (i,j,bi,bj) = 0. _d 0
514                  vstress(i,j,bi,bj) = tau*sw             hs     (i,j,bi,bj) = 0. _d 0
515                else             hl     (i,j,bi,bj) = 0. _d 0
516                  ustress(i,j,bi,bj) = 0. _d 0  
517                  vstress(i,j,bi,bj) = 0. _d 0  c IF ( ATEMP(i,j,bi,bj) .NE. 0. )
518                  hflux  (i,j,bi,bj) = 0. _d 0            endif
                 hs(i,j,bi,bj)      = 0. _d 0  
                 hl(i,j,bi,bj)      = 0. _d 0  
               endif  
519    
520  #else  /* ifndef ALLOW_ATM_TEMP */  #else  /* ifndef ALLOW_ATM_TEMP */
521  #ifdef ALLOW_ATM_WIND  #ifdef ALLOW_ATM_WIND
522                tmpbulk= exf_BulkCdn(sh)            wsm     = sh(i,j,bi,bj)
523                ustress(i,j,bi,bj) = atmrho*tmpbulk*us*            tmpbulk = exf_scal_BulkCdn *
524       &                             uwind(i,j,bi,bj)       &         ( cdrag_1/wsm + cdrag_2 + cdrag_3*wsm )
525                vstress(i,j,bi,bj) = atmrho*tmpbulk*us*            ustress(i,j,bi,bj) = atmrho*tmpbulk*wspeed(i,j,bi,bj)*
526       &                             vwind(i,j,bi,bj)       &                         uwind(i,j,bi,bj)
527              vstress(i,j,bi,bj) = atmrho*tmpbulk*wspeed(i,j,bi,bj)*
528         &                         vwind(i,j,bi,bj)
529  #endif  #endif
530  #endif /* ifndef ALLOW_ATM_TEMP */  #endif /* ifndef ALLOW_ATM_TEMP */
531              enddo           ENDDO
532            enddo          ENDDO
533          enddo         ENDDO
534        enddo        ENDDO
   
 c     Add all contributions.  
       do bj = mybylo(mythid),mybyhi(mythid)  
         do bi = mybxlo(mythid),mybxhi(mythid)  
           do j = 1,sny  
             do i = 1,snx  
 c             Net surface heat flux.  
 #ifdef ALLOW_ATM_TEMP  
               hfl = 0. _d 0  
               hfl = hfl - hs(i,j,bi,bj)  
               hfl = hfl - hl(i,j,bi,bj)  
               hfl = hfl + lwflux(i,j,bi,bj)  
 #ifndef SHORTWAVE_HEATING  
               hfl = hfl + swflux(i,j,bi,bj)  
 #endif  
 c             Heat flux:  
               hflux(i,j,bi,bj) = hfl  
 c             Salt flux from Precipitation and Evaporation.  
               sflux(i,j,bi,bj) = evap(i,j,bi,bj) - precip(i,j,bi,bj)  
 #endif /* ALLOW_ATM_TEMP */  
   
             enddo  
           enddo  
         enddo  
       enddo  
535    
536  #endif /* ALLOW_BULKFORMULAE */  #endif /* ALLOW_BULKFORMULAE */
537    
538        end        RETURN
539          END

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.25

  ViewVC Help
Powered by ViewVC 1.1.22