/[MITgcm]/MITgcm/pkg/opps/opps_calc.F
ViewVC logotype

Diff of /MITgcm/pkg/opps/opps_calc.F

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

revision 1.10 by mlosch, Tue Jul 19 13:08:24 2011 UTC revision 1.11 by jmc, Wed Jun 27 22:34:07 2012 UTC
# Line 2  C $Header$ Line 2  C $Header$
2  C $Name$  C $Name$
3    
4  #include "OPPS_OPTIONS.h"  #include "OPPS_OPTIONS.h"
5    #undef OPPS_ORGCODE
6    
7    C--  File opps_calc.F:
8    C--   Contents
9    C--   o OPPS_CALC
10    C--   o STATE1
11    C--   o NLOPPS
12    
13    C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
14  CBOP  CBOP
15  C !ROUTINE: OPPS_CALC  C !ROUTINE: OPPS_CALC
16    
# Line 14  C !INTERFACE: ========================== Line 22  C !INTERFACE: ==========================
22       I     I, J, bi, bj, myTime, myIter, myThid )       I     I, J, bi, bj, myTime, myIter, myThid )
23    
24  C !DESCRIPTION: \bv  C !DESCRIPTION: \bv
25  C     /=====================================================================\  C     *=====================================================================*
26  C     | SUBROUTINE OPPS_CALC                                                |  C     | SUBROUTINE OPPS_CALC                                                |
27  C     | o Compute all OPPS fields defined in OPPS.h                         |  C     | o Compute all OPPS fields defined in OPPS.h                         |
28  C     |=====================================================================|  C     *=====================================================================*
29  C     | This subroutine is based on the routine 3dconvection.F              |  C     | This subroutine is based on the routine 3dconvection.F              |
30  C     | by E. Skyllingstad (?)                                              |  C     | by E. Skyllingstad (?)                                              |
31  C     | plenty of modifications to make it work:                            |  C     | plenty of modifications to make it work:                            |
# Line 53  C     |   Td(:) = Pd(:,1), etc. Line 61  C     |   Td(:) = Pd(:,1), etc.
61  C     | o TODO:                                                             |  C     | o TODO:                                                             |
62  C     |   clean up the logic of the vertical loops and get rid off the      |  C     |   clean up the logic of the vertical loops and get rid off the      |
63  C     |   GOTO statements                                                   |  C     |   GOTO statements                                                   |
64  C     \=====================================================================/  C     *=====================================================================*
       IMPLICIT NONE  
 C  
 C--------------------------------------------------------------------  
   
65  C \ev  C \ev
66    
67          IMPLICIT NONE
68    
69  C !USES: ============================================================  C !USES: ============================================================
70  #include "SIZE.h"  #include "SIZE.h"
71  #include "EEPARAMS.h"  #include "EEPARAMS.h"
72  #include "PARAMS.h"  #include "PARAMS.h"
73  #include "OPPS.h"  #include "OPPS.h"
 #include "FFIELDS.h"  
74  #include "GRID.h"  #include "GRID.h"
75    
       EXTERNAL DIFFERENT_MULTIPLE  
       LOGICAL  DIFFERENT_MULTIPLE  
   
76  C !INPUT PARAMETERS: ===================================================  C !INPUT PARAMETERS: ===================================================
77  c Routine arguments  C Routine arguments
78  c     bi, bj - array indices on which to apply calculations  C     bi, bj :: array indices on which to apply calculations
79  c     myTime - Current time in simulation  C     myTime :: Current time in simulation
80    
81        INTEGER I, J, bi, bj, KMax, nTracer, nTracerInUse        INTEGER I, J, bi, bj, KMax, nTracer, nTracerInUse
82        INTEGER myThid, myIter        INTEGER myThid, myIter
# Line 82  c     myTime - Current time in simulatio Line 84  c     myTime - Current time in simulatio
84        _RL tracerEnv(Nr,nTracer),wVel(Nr)        _RL tracerEnv(Nr,nTracer),wVel(Nr)
85    
86  #ifdef ALLOW_OPPS  #ifdef ALLOW_OPPS
87    C !FUNCTIONS: ==========================================================
88    c     EXTERNAL DIFFERENT_MULTIPLE
89    c     LOGICAL  DIFFERENT_MULTIPLE
90          _RL STATE1
91    
92  C !LOCAL VARIABLES: ====================================================  C !LOCAL VARIABLES: ====================================================
93  c Local constants  C Local constants
94  C     imin, imax, jmin, jmax  - array computation indices  C     msgBuf      :: Informational/error message buffer
 C     msgBuf      - Informational/error message buffer  
95        CHARACTER*(MAX_LEN_MBUF) msgBuf        CHARACTER*(MAX_LEN_MBUF) msgBuf
96        INTEGER K, K2, K2m1, K2p1, ktr        INTEGER K, K2, K2m1, K2p1, ktr
97        INTEGER ntime,nn,kmx,ic        INTEGER ntime,nn,kmx,ic
# Line 93  C     msgBuf      - Informational/error Line 99  C     msgBuf      - Informational/error
99    
100        _RL wsqr,oldflux,newflux,entrainrate        _RL wsqr,oldflux,newflux,entrainrate
101        _RL pmix        _RL pmix
102        _RL D1,D2,state1        _RL D1, D2
103        _RL dz1,dz2        _RL dz1,dz2
104        _RL radius,StartingFlux        _RL radius,StartingFlux
105        _RL dtts,dt        _RL dtts,dt
# Line 101  C     Arrays Line 107  C     Arrays
107        _RL Paa(Nr,nTracer)        _RL Paa(Nr,nTracer)
108        _RL wda(Nr), mda(Nr), pda(Nr,nTracer)        _RL wda(Nr), mda(Nr), pda(Nr,nTracer)
109  C  C
110  C     Pd, Wd           - tracers, vertical velocity in plume  C     Pd, Wd           :: tracers, vertical velocity in plume
111  C     Md               - plume mass flux (?)  C     Md               :: plume mass flux (?)
112  C     Ad               - fractional area covered by plume  C     Ad               :: fractional area covered by plume
113  C     Dd               - density in plume  C     Dd               :: density in plume
114  C     De               - density of environment  C     De               :: density of environment
115  C     PlumeEntrainment -  C     PlumeEntrainment ::
116        _RL Ad(Nr),Wd(Nr),Dd(Nr),Md(Nr)        _RL Ad(Nr),Wd(Nr),Dd(Nr),Md(Nr)
117        _RL De(Nr)        _RL De(Nr)
118        _RL PlumeEntrainment(Nr)        _RL PlumeEntrainment(Nr)
119        _RL Pd(Nr,nTracer)        _RL Pd(Nr,nTracer)
120  CEOP  CEOP
121    
   
122  C--   Check to see if should convect now  C--   Check to see if should convect now
123  C      IF ( DIFFERENT_MULTIPLE(cAdjFreq,myTime,deltaTClock) ) THEN  C      IF ( DIFFERENT_MULTIPLE(cAdjFreq,myTime,deltaTClock) ) THEN
124        IF ( .true. ) THEN        IF ( .true. ) THEN
# Line 121  C     local initialization Line 126  C     local initialization
126    
127  C     Copy some arrays  C     Copy some arrays
128        dtts = dTtracerLev(1)        dtts = dTtracerLev(1)
129  C  
130  C     start k-loop  C     start k-loop
 C  
131    
132        DO k=1,KMax-1        DO k=1,KMax-1
133  c  
134  c initialize the plume T,S,density, and w velocity  C initialize the plume T,S,density, and w velocity
135  c  
136         DO ktr=1,nTracerInUse         DO ktr=1,nTracerInUse
137          Pd(k,ktr) = tracerEnv(k,ktr)          Pd(k,ktr) = tracerEnv(k,ktr)
138         ENDDO         ENDDO
139         Dd(k)=state1(Pd(k,2),Pd(k,1),i,j,k,bi,bj,myThid)         Dd(k)=STATE1(Pd(k,2),Pd(k,1),i,j,k,bi,bj,myThid)
140         De(k)=Dd(k)         De(k)=Dd(k)
141  CML       print *, 'ml-opps:', i,j,k,tracerEnv(k,2),tracerEnv(k,1),  CML       print *, 'ml-opps:', i,j,k,tracerEnv(k,2),tracerEnv(k,1),
142  CML     &      Dd(k),Pd(k,1),Pd(k,2)  CML     &      Dd(k),Pd(k,1),Pd(k,2)
# Line 142  CML( Line 146  CML(
146  CML    avoid division by zero  CML    avoid division by zero
147  CML       IF (Wd(K) .EQ. 0.D0) Wd(K) = 2.23e-16  CML       IF (Wd(K) .EQ. 0.D0) Wd(K) = 2.23e-16
148  CML)  CML)
149  c  
150  c guess at initial top grid cell vertical velocity  C guess at initial top grid cell vertical velocity
151  c  
152  CML          Wd(k) = 0.03  CML          Wd(k) = 0.03
153  c  
154  c these estimates of initial plume velocity based on plume size and  C these estimates of initial plume velocity based on plume size and
155  c top grid cell water mass  C top grid cell water mass
156  c  
157  c          Wd(k) = 0.5*drF(k)/(dtts*FRACTIONAL_AREA)  c          Wd(k) = 0.5*drF(k)/(dtts*FRACTIONAL_AREA)
158  c          Wd(k) = 0.5*drF(k)/dtts  c          Wd(k) = 0.5*drF(k)/dtts
159  c  
160         wsqr=Wd(k)*Wd(k)         wsqr=Wd(k)*Wd(k)
161         PlumeEntrainment(k) = 0.0         PlumeEntrainment(k) = 0.0
162  c  
 c  
 c  
163  #ifdef ALLOW_OPPS_DEBUG  #ifdef ALLOW_OPPS_DEBUG
164         IF ( OPPSdebugLevel.GE.debLevB ) THEN         IF ( OPPSdebugLevel.GE.debLevB ) THEN
165          WRITE(msgBuf,'(A,I3)')          WRITE(msgBuf,'(A,I3)')
# Line 172  c Line 174  c
174    
175         dz2=DrF(k)         dz2=DrF(k)
176         DO k2=k,KMax-1         DO k2=k,KMax-1
177          D1=state1( Pd(k2,2), Pd(k2,1),i,j,k2+1,bi,bj,myThid)          D1=STATE1( Pd(k2,2), Pd(k2,1),i,j,k2+1,bi,bj,myThid)
178          D2=state1( tracerEnv(k2+1,2), tracerEnv(k2+1,1),          D2=STATE1( tracerEnv(k2+1,2), tracerEnv(k2+1,1),
179       &                                i,j,k2+1,bi,bj,myThid)       &                                i,j,k2+1,bi,bj,myThid)
180          De(k2+1)=D2          De(k2+1)=D2
181  c  
182  c To start downward, parcel has to initially be heavier than environment  C To start downward, parcel has to initially be heavier than environment
183  c but after it has started moving, we continue plume until plume tke or  C but after it has started moving, we continue plume until plume tke or
184  c flux goes negative  C flux goes negative
185  c  
186  CML     &       _hFacC(i,j,k-1,bi,bj)  CML     &       _hFacC(i,j,k-1,bi,bj)
187  CML     &       *_hFacC(i,j,k,bi,bj) .GT. 0.  CML     &       *_hFacC(i,j,k,bi,bj) .GT. 0.
188  CML     &  .AND.  CML     &  .AND.
189          IF (D2-D1 .LT. STABILITY_THRESHOLD.or.k2.ne.k) THEN          IF (D2-D1 .LT. STABILITY_THRESHOLD.or.k2.ne.k) THEN
190           dz1=dz2           dz1=dz2
191           dz2=DrF(k2+1)           dz2=DrF(k2+1)
192  c  
193  C     find mass flux according to eq.(3) from paper by vertical integration  C     find mass flux according to eq.(3) from paper by vertical integration
194  c  
195           newflux=oldflux+e2*radius*Wd(k2)*Dd(k2)*           newflux=oldflux+e2*radius*Wd(k2)*Dd(k2)*
196       &        .5*(dz1+dz2)       &        .5*(dz1+dz2)
197  CML         print *, 'ml-opps:', i,j,k,oldflux,newflux,e2,radius,  CML         print *, 'ml-opps:', i,j,k,oldflux,newflux,e2,radius,
198  CML     &        Wd(k2),Dd(k2),Pd(k2,1),Pd(k2,2),dz1,dz2  CML     &        Wd(k2),Dd(k2),Pd(k2,1),Pd(k2,2),dz1,dz2
199  c  
200           PlumeEntrainment(k2+1) = newflux/StartingFlux           PlumeEntrainment(k2+1) = newflux/StartingFlux
201  c  
202           IF(newflux.LE.0.0) then           IF(newflux.LE.0.0) then
203  #ifdef ALLOW_OPPS_DEBUG  #ifdef ALLOW_OPPS_DEBUG
204            IF ( OPPSdebugLevel.GE.debLevA ) THEN            IF ( OPPSdebugLevel.GE.debLevA ) THEN
# Line 210  c Line 212  c
212            if(maxdepth.eq.k) goto 1000            if(maxdepth.eq.k) goto 1000
213            goto 1            goto 1
214           endif           endif
215  c  
216  c entrainment rate is basically a scaled mass flux dM/M  C entrainment rate is basically a scaled mass flux dM/M
217  c  
218           entrainrate = (newflux - oldflux)/newflux           entrainrate = (newflux - oldflux)/newflux
219           oldflux = newflux           oldflux = newflux
220  c  
221  c  C mix var(s) are the average environmental values over the two grid levels
222  c mix var(s) are the average environmental values over the two grid levels  
 c  
223           DO ktr=1,nTracerInUse           DO ktr=1,nTracerInUse
224            pmix=(dz1*tracerEnv(k2,ktr)+dz2*tracerEnv(k2+1,ktr))            pmix=(dz1*tracerEnv(k2,ktr)+dz2*tracerEnv(k2+1,ktr))
225       &         /(dz1+dz2)       &         /(dz1+dz2)
226            Pd(k2+1,ktr)=Pd(k2,ktr)            Pd(k2+1,ktr)=Pd(k2,ktr)
227       &         - entrainrate*(pmix - Pd(k2,ktr))       &         - entrainrate*(pmix - Pd(k2,ktr))
228           ENDDO           ENDDO
229  c  
230  c compute the density at this level for the buoyancy term in the  C compute the density at this level for the buoyancy term in the
231  c vertical k.e. equation  C vertical k.e. equation
232  c  
233           Dd(k2+1)=state1(Pd(k2+1,2),Pd(k2+1,1),i,j,k2+1,bi,bj,myThid)           Dd(k2+1)=STATE1(Pd(k2+1,2),Pd(k2+1,1),i,j,k2+1,bi,bj,myThid)
234  c  
235  c next, solve for the vertical velocity k.e. using combined eq. (4)  C next, solve for the vertical velocity k.e. using combined eq. (4)
236  c and eq (5) from the paper  C and eq (5) from the paper
237  c  
238  #ifdef ALLOW_OPPS_DEBUG  #ifdef ALLOW_OPPS_DEBUG
239           IF ( OPPSdebugLevel.GE.debLevA ) THEN           IF ( OPPSdebugLevel.GE.debLevA ) THEN
240            WRITE(msgBuf,'(A,3E12.4,I3)')            WRITE(msgBuf,'(A,3E12.4,I3)')
# Line 246  CML   insert Eq. (4) into Eq. (5) to get Line 247  CML   insert Eq. (4) into Eq. (5) to get
247           wsqr = wsqr - wsqr*abs(entrainrate)+ gravity*           wsqr = wsqr - wsqr*abs(entrainrate)+ gravity*
248       &        (dz1*(Dd(k2)-De(k2))/De(k2)       &        (dz1*(Dd(k2)-De(k2))/De(k2)
249       &        +dz2*(Dd(k2+1)-De(k2+1))/De(k2+1))       &        +dz2*(Dd(k2+1)-De(k2+1))/De(k2+1))
250  c  
251  c if negative k.e. then plume has reached max depth, get out of loop  C if negative k.e. then plume has reached max depth, get out of loop
252  c  
253           IF(wsqr.LE.0.0)then           IF(wsqr.LE.0.0)then
254            maxdepth = k2            maxdepth = k2
255  #ifdef ALLOW_OPPS_DEBUG  #ifdef ALLOW_OPPS_DEBUG
# Line 273  c Line 274  c
274            goto 1            goto 1
275           endif           endif
276           Wd(k2+1)=sqrt(wsqr)           Wd(k2+1)=sqrt(wsqr)
277  C  
278  C     compute a new radius based on the new mass flux at this grid level  C     compute a new radius based on the new mass flux at this grid level
279  C     from Eq. (4)  C     from Eq. (4)
280  C  
281           radius=sqrt(newflux/(Wd(k2)*Dd(k2)))           radius=sqrt(newflux/(Wd(k2)*Dd(k2)))
282          ELSE          ELSE
283           maxdepth=k2           maxdepth=k2
# Line 284  C Line 285  C
285           GOTO 1           GOTO 1
286          ENDIF          ENDIF
287         ENDDO         ENDDO
288  c  
289  c plume has reached the bottom  C plume has reached the bottom
290  c  
291         MaxDepth=kMax         MaxDepth=kMax
292  c  
293   1     CONTINUE   1     CONTINUE
294  c  
295         Ad(k)=FRACTIONAL_AREA         Ad(k)=FRACTIONAL_AREA
296         IC=0         IC=0
297  c  
298  c start iteration on fractional area, not used in OGCM implementation  C start iteration on fractional area, not used in OGCM implementation
299  c  
 c  
300         DO IC=1,Max_ABE_Iterations         DO IC=1,Max_ABE_Iterations
301  c  
302  c  C next compute the mass flux beteen each grid box using the entrainment
303  c next compute the mass flux beteen each grid box using the entrainment  
 c  
304          Md(k)=Wd(k)*Ad(k)          Md(k)=Wd(k)*Ad(k)
305  c  
306          DO k2=k+1,maxDepth          DO k2=k+1,maxDepth
307           Md(k2)=Md(k)*PlumeEntrainment(k2)           Md(k2)=Md(k)*PlumeEntrainment(k2)
308  #ifdef ALLOW_OPPS_DEBUG  #ifdef ALLOW_OPPS_DEBUG
# Line 315  c Line 314  c
314           ENDIF           ENDIF
315  #endif /* ALLOW_OPPS_DEBUG */  #endif /* ALLOW_OPPS_DEBUG */
316          ENDDO          ENDDO
317  c  
318  c Now move on to calculate new temperature using flux from  C Now move on to calculate new temperature using flux from
319  c Td, Sd, Wd, ta, sa, and we. Values for these variables are at  C Td, Sd, Wd, ta, sa, and we. Values for these variables are at
320  c center of grid cell, use weighted average to get boundary values  C center of grid cell, use weighted average to get boundary values
321  c  
322  c use a timestep limited by the GCM model timestep and the maximum plume  C use a timestep limited by the GCM model timestep and the maximum plume
323  c velocity (CFL criteria)  C velocity (CFL criteria)
324  c  
325  c  C calculate the weighted wd, td, and sd
 c calculate the weighted wd, td, and sd  
 c  
326          dt = dtts          dt = dtts
327          do k2=k,maxDepth-1          do k2=k,maxDepth-1
328           IF ( Wd(K2) .NE. 0. _d 0 ) dt = min(dt,drF(k2)/Wd(k2))           IF ( Wd(K2) .NE. 0. _d 0 ) dt = min(dt,drF(k2)/Wd(k2))
329  c  
330  c time integration will be integer number of steps to get one  C time integration will be integer number of steps to get one
331  c gcm time step  C gcm time step
332  c  
333           ntime = nint(0.5*int(dtts/dt))           ntime = nint(0.5*int(dtts/dt))
334           if(ntime.eq.0) then           if(ntime.eq.0) then
335            ntime = 1            ntime = 1
336           endif           endif
337  c  
338  c make sure area weighted vertical velocities match; in other words  C make sure area weighted vertical velocities match; in other words
339  c make sure mass in equals mass out at the intersection of each grid  C make sure mass in equals mass out at the intersection of each grid
340  c cell. Eq. (20)  C cell. Eq. (20)
341  c  
342           mda(k2) = (md(k2)*drF(k2)+md(k2+1)*drF(k2+1))/           mda(k2) = (md(k2)*drF(k2)+md(k2+1)*drF(k2+1))/
343       *        (drF(k2)+drF(k2+1))       *        (drF(k2)+drF(k2+1))
344  c  
345           wda(k2) = (wd(k2)*drF(k2)+wd(k2+1)*drF(k2+1))/           wda(k2) = (wd(k2)*drF(k2)+wd(k2+1)*drF(k2+1))/
346       *        (drF(k2)+drF(k2+1))       *        (drF(k2)+drF(k2+1))
347  c  
348           DO ktr = 1, nTracerInUse           DO ktr = 1, nTracerInUse
349            Pda(k2,ktr) = Pd(k2,ktr)            Pda(k2,ktr) = Pd(k2,ktr)
350            Paa(k2,ktr) = tracerEnv(k2+1,ktr)            Paa(k2,ktr) = tracerEnv(k2+1,ktr)
351           ENDDO           ENDDO
352  c  
353          enddo          enddo
354          dt = min(dt,dtts)          dt = min(dt,dtts)
355  #ifdef ALLOW_OPPS_DEBUG  #ifdef ALLOW_OPPS_DEBUG
# Line 366  c Line 363  c
363          DO ktr=1,nTracerInUse          DO ktr=1,nTracerInUse
364           Pda(maxdepth,ktr) = Pd(maxdepth,ktr)           Pda(maxdepth,ktr) = Pd(maxdepth,ktr)
365          ENDDO          ENDDO
366  C  
367          kmx = maxdepth-1          kmx = maxdepth-1
368          do nn=1,ntime          do nn=1,ntime
369  C  
370  C     top point  C     top point
371  C  
372           DO ktr = 1,nTracerInUse           DO ktr = 1,nTracerInUse
373            tracerEnv(k,ktr) =  tracerEnv(k,ktr)-            tracerEnv(k,ktr) =  tracerEnv(k,ktr)-
374       &        (mda(k)*(Pda(k,ktr)-Paa(k,ktr)))*dt*recip_drF(k)       &        (mda(k)*(Pda(k,ktr)-Paa(k,ktr)))*dt*recip_drF(k)
375           ENDDO           ENDDO
376  c  
377  c now do inner points if there are any  C now do inner points if there are any
378  c  
379  CML         if(Maxdepth-k.gt.1) then  CML         if(Maxdepth-k.gt.1) then
380  CML    This if statement is superfluous  CML    This if statement is superfluous
381  CML         IF ( k .LT. Maxdepth-1 ) THEN  CML         IF ( k .LT. Maxdepth-1 ) THEN
# Line 387  CML         mda(maxDepth) = 0. Line 384  CML         mda(maxDepth) = 0.
384           DO k2=k+1,kmx           DO k2=k+1,kmx
385            k2m1 = max(k,k2-1)            k2m1 = max(k,k2-1)
386            k2p1 = max(k2+1,maxDepth)            k2p1 = max(k2+1,maxDepth)
387  c  
388             DO ktr = 1,nTracerInUse             DO ktr = 1,nTracerInUse
389              tracerEnv(k2,ktr) = tracerEnv(k2,ktr) +              tracerEnv(k2,ktr) = tracerEnv(k2,ktr) +
390       &           (mda(k2m1)*(Pda(k2m1,ktr)-Paa(k2m1,ktr))       &           (mda(k2m1)*(Pda(k2m1,ktr)-Paa(k2m1,ktr))
# Line 397  c Line 394  c
394            ENDDO            ENDDO
395  CML    This if statement is superfluous  CML    This if statement is superfluous
396  CML         ENDIF  CML         ENDIF
397  C  
398  C     bottom point  C     bottom point
399  C  
400           DO ktr=1,nTracerInUse           DO ktr=1,nTracerInUse
401            tracerEnv(kmx+1,ktr) =  tracerEnv(kmx+1,ktr)+            tracerEnv(kmx+1,ktr) =  tracerEnv(kmx+1,ktr)+
402       &        mda(kmx)*(Pda(kmx,ktr)-Paa(kmx,ktr))*dt*recip_drF(kmx+1)       &        mda(kmx)*(Pda(kmx,ktr)-Paa(kmx,ktr))*dt*recip_drF(kmx+1)
403           ENDDO           ENDDO
404  c  
405  c     set the environmental temp and salinity to equal new fields  C     set the environmental temp and salinity to equal new fields
406  c  
407           DO ktr=1,nTracerInUse           DO ktr=1,nTracerInUse
408            DO k2=1,kmx            DO k2=1,kmx
409             paa(k2,ktr) = tracerEnv(k2+1,ktr)             paa(k2,ktr) = tracerEnv(k2+1,ktr)
410            ENDDO            ENDDO
411           ENDDO           ENDDO
412  c  
413  c end loop on number of time integration steps  C end loop on number of time integration steps
414  c  
415          enddo          enddo
416         ENDDO         ENDDO
417   999   continue   999   continue
418  C  
419  C     count convection event in this grid cell  C     count convection event in this grid cell
420  C  
421         OPPSconvectCount(I,J,K,bi,bj) =         OPPSconvectCount(I,J,K,bi,bj) =
422       &      OPPSconvectCount(I,J,K,bi,bj) + 1. _d 0       &      OPPSconvectCount(I,J,K,bi,bj) + 1. _d 0
423  C  
424  C     jump here if k = maxdepth or if level not unstable, go to next  C     jump here if k = maxdepth or if level not unstable, go to next
425  C     profile point  C     profile point
426  C  
427   1000  continue   1000  continue
428  c  
 C  
429  C     end  of k-loop  C     end  of k-loop
430  C  
431        ENDDO        ENDDO
432    
433  C--   End IF (DIFFERENT_MULTIPLE)  C--   End IF (DIFFERENT_MULTIPLE)
# Line 439  C--   End IF (DIFFERENT_MULTIPLE) Line 435  C--   End IF (DIFFERENT_MULTIPLE)
435    
436        RETURN        RETURN
437        END        END
438        _RL FUNCTION STATE1(sLoc,tLoc,I,J,KREF,bi,bj,mythid)  
439    C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
440    
441          _RL FUNCTION STATE1( sLoc, tLoc, i, j, kRef, bi, bj, myThid )
442    
443  C     !DESCRIPTION: \bv  C     !DESCRIPTION: \bv
444  C     *===============================================================*  C     *===============================================================*
445  C     | o SUBROUTINE STATE1  C     | o SUBROUTINE STATE1
# Line 456  C     == Global variables == Line 456  C     == Global variables ==
456  #include "SIZE.h"  #include "SIZE.h"
457  #include "EEPARAMS.h"  #include "EEPARAMS.h"
458  #include "PARAMS.h"  #include "PARAMS.h"
 #include "EOS.h"  
459  #include "GRID.h"  #include "GRID.h"
460  #include "DYNVARS.h"  #include "DYNVARS.h"
461    
462  C     !INPUT/OUTPUT PARAMETERS:  C     !INPUT/OUTPUT PARAMETERS:
463  C     == Routine arguments ==  C     == Routine arguments ==
464        INTEGER I,J,kRef,bi,bj,myThid        INTEGER i, j, kRef, bi, bj, myThid
465        _RL tLoc,sLoc        _RL tLoc, sLoc
466    
467  C     !LOCAL VARIABLES:  C     !LOCAL VARIABLES:
468  C     == Local variables ==  C     == Local variables ==
469        _RL rhoLoc, dRho        _RL rhoLoc
470        _RL pLoc        _RL pLoc
       _RL t1, t2, t3, t4, s1, s3o2, p1, p2, sp5, p1t1  
       _RL ct, sa, sqrtsa, p  
       _RL rfresh, rsalt, rhoP0  
       _RL bMfresh, bMsalt, bMpres, BulkMod  
       _RL rhoNum, rhoDen, den, epsln  
       PARAMETER ( epsln = 0.D0 )  
   
       character*(max_len_mbuf) msgbuf  
471    
472  CMLC     estimate pressure from depth at cell centers  CMLC     estimate pressure from depth at cell centers
473  CML      mtoSI = gravity*rhoConst  CML      mtoSI = gravity*rhoConst
474  CML      pLoc = ABS(rC(kRef))*mtoSI  CML      pLoc = ABS(rC(kRef))*mtoSI
475    
476        IF ( buoyancyRelation .EQ. 'OCEANIC' ) THEN        IF ( usingZCoords ) THEN
477  C     in Z coordinates the pressure is rho0 * (hydrostatic) Potential  C     in Z coordinates the pressure is rho0 * (hydrostatic) Potential
478         IF ( useDynP_inEos_Zc ) THEN         IF ( useDynP_inEos_Zc ) THEN
479  C----------  C----------
# Line 496  C---------- Line 487  C----------
487         ELSE         ELSE
488          pLoc = -rhoConst*rC(kRef)*gravity*maskC(i,j,kRef,bi,bj)          pLoc = -rhoConst*rC(kRef)*gravity*maskC(i,j,kRef,bi,bj)
489         ENDIF         ENDIF
490        ELSEIF ( buoyancyRelation .EQ. 'OCEANICP' ) THEN        ELSEIF ( usingPCoords ) THEN
491  C     in P coordinates the pressure is just the coordinate of  C     in P coordinates the pressure is just the coordinate of
492  C     the tracer point  C     the tracer point
493         pLoc = rC(kRef)* maskC(i,j,kRef,bi,bj)         pLoc = rC(kRef)* maskC(i,j,kRef,bi,bj)
494        ENDIF        ENDIF
495    
496        rhoLoc  = 0. _d 0        CALL FIND_RHO_SCALAR( tLoc, sLoc, pLoc, rhoLoc, myThid )
497        rhoP0   = 0. _d 0        STATE1 = rhoLoc
       bulkMod = 0. _d 0  
       rfresh  = 0. _d 0  
       rsalt   = 0. _d 0  
       bMfresh = 0. _d 0  
       bMsalt  = 0. _d 0  
       bMpres  = 0. _d 0  
       rhoNum  = 0. _d 0  
       rhoDen  = 0. _d 0  
       den     = 0. _d 0  
   
       t1 = tLoc  
       t2 = t1*t1  
       t3 = t2*t1  
       t4 = t3*t1  
   
       s1  = sLoc  
   
       IF ( equationOfState .EQ. 'LINEAR' ) THEN  
   
        dRho = rhoNil-rhoConst  
        rhoLoc=rhoNil* (  
      &        sBeta *(sLoc-sRef(kRef))  
      &      - tAlpha*(tLoc-tRef(KREF)) ) + dRho  
   
       ELSEIF (equationOfState.EQ.'POLY3') THEN  
   
 C     this is not correct, there is a field eosSig0 which should be use here  
 C     but I DO not intent to include the reference level in this routine  
          WRITE(*,'(a)')  
      &        ' FIND_RHO_SCALAR: for POLY3, the density is not'  
          WRITE(*,'(a)')  
      &         '                 computed correctly in this routine'  
          rhoLoc = 0. _d 0  
   
       ELSEIF ( equationOfState(1:5).EQ.'JMD95'  
      &      .OR. equationOfState.EQ.'UNESCO' ) THEN  
 C     nonlinear equation of state in pressure coordinates  
   
          s3o2 = s1*SQRT(s1)  
   
          p1 = pLoc*SItoBar  
          p2 = p1*p1  
   
 C     density of freshwater at the surface  
          rfresh =  
      &          eosJMDCFw(1)  
      &        + eosJMDCFw(2)*t1  
      &        + eosJMDCFw(3)*t2  
      &        + eosJMDCFw(4)*t3  
      &        + eosJMDCFw(5)*t4  
      &        + eosJMDCFw(6)*t4*t1  
 C     density of sea water at the surface  
          rsalt =  
      &        s1*(  
      &             eosJMDCSw(1)  
      &           + eosJMDCSw(2)*t1  
      &           + eosJMDCSw(3)*t2  
      &           + eosJMDCSw(4)*t3  
      &           + eosJMDCSw(5)*t4  
      &           )  
      &        + s3o2*(  
      &             eosJMDCSw(6)  
      &           + eosJMDCSw(7)*t1  
      &           + eosJMDCSw(8)*t2  
      &           )  
      &           + eosJMDCSw(9)*s1*s1  
   
          rhoP0 = rfresh + rsalt  
   
 C     secant bulk modulus of fresh water at the surface  
          bMfresh =  
      &             eosJMDCKFw(1)  
      &           + eosJMDCKFw(2)*t1  
      &           + eosJMDCKFw(3)*t2  
      &           + eosJMDCKFw(4)*t3  
      &           + eosJMDCKFw(5)*t4  
 C     secant bulk modulus of sea water at the surface  
          bMsalt =  
      &        s1*( eosJMDCKSw(1)  
      &           + eosJMDCKSw(2)*t1  
      &           + eosJMDCKSw(3)*t2  
      &           + eosJMDCKSw(4)*t3  
      &           )  
      &    + s3o2*( eosJMDCKSw(5)  
      &           + eosJMDCKSw(6)*t1  
      &           + eosJMDCKSw(7)*t2  
      &           )  
 C     secant bulk modulus of sea water at pressure p  
          bMpres =  
      &        p1*( eosJMDCKP(1)  
      &           + eosJMDCKP(2)*t1  
      &           + eosJMDCKP(3)*t2  
      &           + eosJMDCKP(4)*t3  
      &           )  
      &   + p1*s1*( eosJMDCKP(5)  
      &           + eosJMDCKP(6)*t1  
      &           + eosJMDCKP(7)*t2  
      &           )  
      &      + p1*s3o2*eosJMDCKP(8)  
      &      + p2*( eosJMDCKP(9)  
      &           + eosJMDCKP(10)*t1  
      &           + eosJMDCKP(11)*t2  
      &           )  
      &    + p2*s1*( eosJMDCKP(12)  
      &           + eosJMDCKP(13)*t1  
      &           + eosJMDCKP(14)*t2  
      &           )  
   
          bulkMod = bMfresh + bMsalt + bMpres  
   
 C     density of sea water at pressure p  
          rhoLoc = rhoP0/(1. _d 0 - p1/bulkMod) - rhoConst  
   
       ELSEIF ( equationOfState.EQ.'MDJWF' ) THEN  
   
          sp5 = SQRT(s1)  
   
          p1   = pLoc*SItodBar  
          p1t1 = p1*t1  
   
          rhoNum = eosMDJWFnum(0)  
      &        + t1*(eosMDJWFnum(1)  
      &        +     t1*(eosMDJWFnum(2) + eosMDJWFnum(3)*t1) )  
      &        + s1*(eosMDJWFnum(4)  
      &        +     eosMDJWFnum(5)*t1  + eosMDJWFnum(6)*s1)  
      &        + p1*(eosMDJWFnum(7) + eosMDJWFnum(8)*t2  
      &        +     eosMDJWFnum(9)*s1  
      &        +     p1*(eosMDJWFnum(10) + eosMDJWFnum(11)*t2) )  
   
   
          den = eosMDJWFden(0)  
      &        + t1*(eosMDJWFden(1)  
      &        +     t1*(eosMDJWFden(2)  
      &        +         t1*(eosMDJWFden(3) + t1*eosMDJWFden(4) ) ) )  
      &        + s1*(eosMDJWFden(5)  
      &        +     t1*(eosMDJWFden(6)  
      &        +         eosMDJWFden(7)*t2)  
      &        +     sp5*(eosMDJWFden(8) + eosMDJWFden(9)*t2) )  
      &        + p1*(eosMDJWFden(10)  
      &        +     p1t1*(eosMDJWFden(11)*t2 + eosMDJWFden(12)*p1) )  
   
          rhoDen = 1.0/(epsln+den)  
   
          rhoLoc = rhoNum*rhoDen - rhoConst  
   
       ELSEIF( equationOfState .EQ. 'TEOS10' ) THEN  
   
        ct      = tLoc  
        sa      = sLoc  
        IF ( sa .GT. 0. _d 0 ) THEN  
         sqrtsa = SQRT(sa)  
        ELSE  
         sa     = 0. _d 0  
         sqrtsa = 0. _d 0  
        ENDIF  
        p       = pLoc*SItodBar  
           
        rhoNum = teos(01)  
      &   + ct*(teos(02) + ct*(teos(03) + teos(04)*ct))    
      &   + sa*(teos(05) + ct*(teos(06) + teos(07)*ct)  
      &   + sqrtsa*(teos(08) + ct*(teos(09)  
      &            + ct*(teos(10) + teos(11)*ct))))  
      &   + p*(teos(12) + ct*(teos(13) + teos(14)*ct)  
      &                      + sa*(teos(15) + teos(16)*ct)  
      &   + p*(teos(17) + ct*(teos(18) + teos(19)*ct) + teos(20)*sa))  
           
        den = teos(21)  
      &   + ct*(teos(22) + ct*(teos(23) + ct*(teos(24) + teos(25)*ct)))  
      &   + sa*(teos(26) + ct*(teos(27) + ct*(teos(28)  
      &   + ct*(teos(29) + teos(30)*ct)))  
      &   + teos(36)*sa  
      %   + sqrtsa*(teos(31) + ct*(teos(32) + ct*(teos(33)  
      &            + ct*(teos(34) + teos(35)*ct)))))    
      %   + p*(teos(37) + ct*(teos(38) + ct*(teos(39) + teos(40)*ct))    
      %   + sa*(teos(41) + teos(42)*ct)  
      %   + p*(teos(43) + ct*(teos(44) + teos(45)*ct + teos(46)*sa)  
      %   + p*(teos(47) + teos(48)*ct)))  
           
           
        rhoDen = 1.0/(epsln+den)  
         
        rhoLoc = rhoNum*rhoDen  
   
       ELSEIF( equationOfState .EQ. 'IDEALG' ) THEN  
 C  
       ELSE  
        WRITE(msgbuf,'(3A)')  
      &        ' STATE1 : equationOfState = "',  
      &        equationOfState,'"'  
        CALL PRINT_ERROR( msgbuf, mythid )  
        STOP 'ABNORMAL END: S/R STATE1 in OPPS_CALC'  
       ENDIF  
   
       state1 = rhoLoc + rhoConst  
498    
499  #endif /* ALLOW_OPPS */  #endif /* ALLOW_OPPS */
500        RETURN        RETURN
501        END        END
502    
   
 #undef OPPS_ORGCODE  
503  #ifdef OPPS_ORGCODE  #ifdef OPPS_ORGCODE
504  c Listed below is the subroutine for use in parallel 3-d circulation code.  C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
505  c It has been used in the parallel semtner-chervin code and is now being used  
506  c In the POP code.  The subroutine is called nlopps (long story to explain why).  C Listed below is the subroutine for use in parallel 3-d circulation code.
507    C It has been used in the parallel semtner-chervin code and is now being used
508  c I've attached the version of lopps that we've been using in the simulations.  C In the POP code.  The subroutine is called nlopps (long story to explain why).
509  c There is one common block that is different from the standard model commons  
510  c (countc) and it is not needed if the array convadj is not used.  The routine  C I've attached the version of lopps that we've been using in the simulations.
511  c does need "kmp" which is why the boundc common is included. For massively  C There is one common block that is different from the standard model commons
512  c parallel codes (like POP) we think this will work well when converted from a  C (countc) and it is not needed if the array convadj is not used.  The routine
513  c "slab" (i=is,ie) to a column, which just means removing the "do i=is,ie" loop.  c There are differences between this  C does need "kmp" which is why the boundc common is included. For massively
514  c code and the 1-d code and the earlier scheme implemented in 3-d models. These c differences are described below.  C parallel codes (like POP) we think this will work well when converted from a
515    C "slab" (i=is,ie) to a column, which just means removing the "do i=is,ie" loop.  c There are differences between this
516    C code and the 1-d code and the earlier scheme implemented in 3-d models. These c differences are described below.
517    
518    
519        subroutine nlopps(j,is,ie,ta,sa,gcmdz)        subroutine nlopps(j,is,ie,ta,sa,gcmdz)
520  c  
521        parameter (imt = 361 , jmt = 301 , km = 30 )        parameter (imt = 361 , jmt = 301 , km = 30 )
 c  
 c     Nlopps:   E. Skyllingstad and T. Paluszkiewicz  
 c  
 c     Version: December 11, 1996  
 c  
 c     Nlopps:  This version of lopps is significantly different from  
 c     the original code developed by R. Romea and T. Paluskiewicz.  The  
 c     code uses a flux constraint to control the change in T and S at  
 c     each grid level.  First, a plume profile of T,S, and W are  
 c     determined using the standard plume model, but with a detraining  
 c     mass instead of entraining.  Thus, the T and S plume  
 c     characteristics still change, but the plume contracts in size  
 c     rather than expanding ala classical entraining plumes.  This  
 c     is heuristically more in line with large eddy simulation results.  
 c     At each grid level, the convergence of plume velocity determines  
 c     the flux of T and S, which is conserved by using an upstream  
 c     advection.  The vertical velocity is balanced so that the area  
 c     weighted upward velocity equals the area weighted downdraft  
 c     velocity, ensuring mass conservation. The present implementation  
 c     adjusts the plume for a time period equal to the time for 1/2 of  
 c     the mass of the fastest moving level to move downward.  As a  
 c     consequence, the model does not completely adjust the profile at  
 c     each model time step, but provides a smooth adjustment over time.  
 c  
 c  
522    
523    C     Nlopps:   E. Skyllingstad and T. Paluszkiewicz
524    
525  c  C     Version: December 11, 1996
526    
527    C     Nlopps:  This version of lopps is significantly different from
528    C     the original code developed by R. Romea and T. Paluskiewicz.  The
529    C     code uses a flux constraint to control the change in T and S at
530    C     each grid level.  First, a plume profile of T,S, and W are
531    C     determined using the standard plume model, but with a detraining
532    C     mass instead of entraining.  Thus, the T and S plume
533    C     characteristics still change, but the plume contracts in size
534    C     rather than expanding ala classical entraining plumes.  This
535    C     is heuristically more in line with large eddy simulation results.
536    C     At each grid level, the convergence of plume velocity determines
537    C     the flux of T and S, which is conserved by using an upstream
538    C     advection.  The vertical velocity is balanced so that the area
539    C     weighted upward velocity equals the area weighted downdraft
540    C     velocity, ensuring mass conservation. The present implementation
541    C     adjusts the plume for a time period equal to the time for 1/2 of
542    C     the mass of the fastest moving level to move downward.  As a
543    C     consequence, the model does not completely adjust the profile at
544    C     each model time step, but provides a smooth adjustment over time.
545    
546  c      include "params.h"  c      include "params.h"
547  c      include "plume_fast_inc.h"  c      include "plume_fast_inc.h"
# Line 759  c #include "loppsd.h" Line 551  c #include "loppsd.h"
551        real ta(imt,km),sa(imt,km),gcmdz(km),dz(km)        real ta(imt,km),sa(imt,km),gcmdz(km),dz(km)
552        real pdensity,wsqr,oldflux,newflux,entrainrate,adtemp        real pdensity,wsqr,oldflux,newflux,entrainrate,adtemp
553        REAL Del,D,dza1,dza2,kd,kd1,Smix,Thmix,PlumeS,PlumeT,PlumeD        REAL Del,D,dza1,dza2,kd,kd1,Smix,Thmix,PlumeS,PlumeT,PlumeD
 c  
 c  
554    
555        INTEGER i,j,k        INTEGER i,j,k
556  clfh  Clfh
557        integer is,ie,k2        integer is,ie,k2
558  clfh  Clfh
559        REAL D1,D2,state1,Density        REAL D1,D2,state1,Density
560        REAL dz1,dz2        REAL dz1,dz2
561        REAL radius,StartingFlux        REAL radius,StartingFlux
# Line 773  clfh Line 563  clfh
563        real wda(km),tda(km),sda(km),mda(km)        real wda(km),tda(km),sda(km),mda(km)
564        real dtts,dt,sumo,sumn        real dtts,dt,sumo,sumn
565        integer ntime,nn,kmx,ic        integer ntime,nn,kmx,ic
566  c  
 c  
567        LOGICAL debug,done        LOGICAL debug,done
568        INTEGER MAX_ABE_ITERATIONS        INTEGER MAX_ABE_ITERATIONS
569        PARAMETER(MAX_ABE_ITERATIONS=1)        PARAMETER(MAX_ABE_ITERATIONS=1)
# Line 798  c Line 587  c
587        REAL PlumeEntrainment(km)        REAL PlumeEntrainment(km)
588        REAL GridThickness(km)        REAL GridThickness(km)
589    
590  c  C input kmp through a common block
591  c input kmp through a common block  
 c  
592        common / boundc / wsx(imt,jmt),wsy(imt,jmt),hfs(imt,jmt),        common / boundc / wsx(imt,jmt),wsy(imt,jmt),hfs(imt,jmt),
593       1                  ple(imt,jmt),kmp(imt,jmt),kmq(imt,jmt)       1                  ple(imt,jmt),kmp(imt,jmt),kmq(imt,jmt)
594  cwmseas  cwmseas
595       &                 ,wsx1(imt,jmt),wsy1(imt,jmt)       &                 ,wsx1(imt,jmt),wsy1(imt,jmt)
596       1                 ,wsx2(imt,jmt),wsy2(imt,jmt)       1                 ,wsx2(imt,jmt),wsy2(imt,jmt)
597  c  
598  c input the variables through a common  C input the variables through a common
599  c  
600        logical problem        logical problem
601        common /countc/ convadj(imt,jmt,km),ics,depth(km),problem        common /countc/ convadj(imt,jmt,km),ics,depth(km),problem
602    
603    
604  c-----may want to setup an option to get this only on first call  C-----may want to setup an option to get this only on first call
605  c     otherwise it is repetive  C     otherwise it is repetive
606  c     griddz is initialize by call to setupgrid  C     griddz is initialize by call to setupgrid
 c  
 c  
607    
608          dtts = 2400          dtts = 2400
609  c  
610          do k=1,km          do k=1,km
611            dz(k) = 0.01*gcmdz(k)            dz(k) = 0.01*gcmdz(k)
612          enddo          enddo
613  c  
614          do k=1,km          do k=1,km
615             GridThickness(k) = dz(k)             GridThickness(k) = dz(k)
616          enddo          enddo
617  c  
618  c modified to loop over slab  C modified to loop over slab
619  c  
620        DO i=is,ie        DO i=is,ie
621    
622          numgridpoints=kmp(i,j)          numgridpoints=kmp(i,j)
623  c  
624  c  go to next column if only 1 grid point or on land  C  go to next column if only 1 grid point or on land
625  c  
626          if(numgridpoints.le.1) goto 1100          if(numgridpoints.le.1) goto 1100
627  c  
628  c loop over depth  C loop over depth
629  c  
 c  
630        debug = .false.        debug = .false.
631  c  
632  c first save copy of initial profile  C first save copy of initial profile
633  c  
634        DO k=1,NumGridPoints        DO k=1,NumGridPoints
635           stemp(k)=sa(i,k)           stemp(k)=sa(i,k)
636           ttemp(k)=ta(i,k)           ttemp(k)=ta(i,k)
637  c  
638  c do a check of t and s range, if out of bounds set flag  C do a check of t and s range, if out of bounds set flag
639  c  
640           if(problem) then           if(problem) then
641              write(0,*)"Code in trouble before this nlopps call"              write(0,*)"Code in trouble before this nlopps call"
642              return              return
643           endif           endif
644  c  
645           if(sa(i,k).gt.40..or.ta(i,k).lt.-4.0) then           if(sa(i,k).gt.40..or.ta(i,k).lt.-4.0) then
646              problem = .true.              problem = .true.
647              write(0,*)"t out of range at j ",j              write(0,*)"t out of range at j ",j
# Line 871  c Line 656  c
656        endif        endif
657    
658        DO k=1,NumGridPoints-1        DO k=1,NumGridPoints-1
659  c  
660  c initialize the plume T,S,density, and w velocity  C initialize the plume T,S,density, and w velocity
661  c  
662            Sd(k)=stemp(k)            Sd(k)=stemp(k)
663            Td(k)=ttemp(k)            Td(k)=ttemp(k)
664            Dd(k)=state1(stemp(k),ttemp(k),k)            Dd(k)=state1(stemp(k),ttemp(k),k)
665            De(k)=Dd(k)            De(k)=Dd(k)
666  c          Wd(k)=VERTICAL_VELOCITY  c          Wd(k)=VERTICAL_VELOCITY
667  c  
668  c guess at initial top grid cell vertical velocity  C guess at initial top grid cell vertical velocity
669  c  
670            Wd(k) = 0.03            Wd(k) = 0.03
671  c  
672  c these estimates of initial plume velocity based on plume size and  C these estimates of initial plume velocity based on plume size and
673  c top grid cell water mass  C top grid cell water mass
674  c  
675  c          Wd(k) = 0.5*dz(k)/(dtts*FRACTIONAL_AREA)  c          Wd(k) = 0.5*dz(k)/(dtts*FRACTIONAL_AREA)
676  c          Wd(k) = 0.5*dz(k)/dtts  c          Wd(k) = 0.5*dz(k)/dtts
677  c  
678            wsqr=Wd(k)*Wd(k)            wsqr=Wd(k)*Wd(k)
679            PlumeEntrainment(k) = 0.0            PlumeEntrainment(k) = 0.0
680  c  
 c  
 c  
681            if(debug) write(0,*) 'Doing old lowerparcel'            if(debug) write(0,*) 'Doing old lowerparcel'
682            radius=PlumeRadius            radius=PlumeRadius
683            StartingFlux=radius*radius*Wd(k)*Dd(k)            StartingFlux=radius*radius*Wd(k)*Dd(k)
# Line 905  c Line 688  c
688              D1=state1(Sd(k2),Td(k2),k2+1)              D1=state1(Sd(k2),Td(k2),k2+1)
689              D2=state1(stemp(k2+1),ttemp(k2+1),k2+1)              D2=state1(stemp(k2+1),ttemp(k2+1),k2+1)
690              De(k2+1)=D2              De(k2+1)=D2
691  c  
692  c To start downward, parcel has to initially be heavier than environment  C To start downward, parcel has to initially be heavier than environment
693  c but after it has started moving, we continue plume until plume tke or  C but after it has started moving, we continue plume until plume tke or
694  c flux goes negative  C flux goes negative
695  c  
696              IF (D2-D1 .LT. STABILITY_THRESHOLD.or.k2.ne.k) THEN              IF (D2-D1 .LT. STABILITY_THRESHOLD.or.k2.ne.k) THEN
697                   dz1=dz2                   dz1=dz2
698                   dz2=GridThickness(k2+1)                   dz2=GridThickness(k2+1)
699  c  
700  c define mass flux according to eq. 4 from paper  C define mass flux according to eq. 4 from paper
701  c  
702                   newflux=oldflux+e2*radius*Wd(k2)*Dd(k2)*0.50*                   newflux=oldflux+e2*radius*Wd(k2)*Dd(k2)*0.50*
703       .              (dz1+dz2)       .              (dz1+dz2)
704  c  
705                   PlumeEntrainment(k2+1) = newflux/StartingFlux                   PlumeEntrainment(k2+1) = newflux/StartingFlux
706  c  
707                   IF(newflux.LT.0.0) then                   IF(newflux.LT.0.0) then
708                       if(debug) then                       if(debug) then
709                        write(0,*)"Plume entrained to zero at ",k2                        write(0,*)"Plume entrained to zero at ",k2
# Line 929  c Line 712  c
712                       if(maxdepth.eq.k) goto 1000                       if(maxdepth.eq.k) goto 1000
713                       goto 1                       goto 1
714                   endif                   endif
715  c  
716  c entrainment rate is basically a scaled mass flux dM/M  C entrainment rate is basically a scaled mass flux dM/M
717  c  
718                   entrainrate = (newflux - oldflux)/newflux                   entrainrate = (newflux - oldflux)/newflux
719                   oldflux = newflux                   oldflux = newflux
720  c  
721  c  C mix var(s) are the average environmental values over the two grid levels
722  c mix var(s) are the average environmental values over the two grid levels  
 c  
723                   smix=(dz1*stemp(k2)+dz2*stemp(k2+1))/(dz1+dz2)                   smix=(dz1*stemp(k2)+dz2*stemp(k2+1))/(dz1+dz2)
724                   thmix=(dz1*ttemp(k2)+dz2*ttemp(k2+1))/(dz1+dz2)                   thmix=(dz1*ttemp(k2)+dz2*ttemp(k2+1))/(dz1+dz2)
725  c  
726  c first compute the new salinity and temperature for this level  C first compute the new salinity and temperature for this level
727  c using equations 3.6 and 3.7 from the paper  C using equations 3.6 and 3.7 from the paper
728  c  
 c  
 c  
729                    sd(k2+1)=sd(k2) - entrainrate*(smix - sd(k2))                    sd(k2+1)=sd(k2) - entrainrate*(smix - sd(k2))
730                    td(k2+1)=td(k2) - entrainrate*(thmix - td(k2))                    td(k2+1)=td(k2) - entrainrate*(thmix - td(k2))
731  c  
732  c  C compute the density at this level for the buoyancy term in the
733  c compute the density at this level for the buoyancy term in the  C vertical k.e. equation
734  c vertical k.e. equation  
 c  
735                   Dd(k2+1)=state1(Sd(k2+1),Td(k2+1),k2+1)                   Dd(k2+1)=state1(Sd(k2+1),Td(k2+1),k2+1)
736  c  
737  c next, solve for the vertical velocity k.e. using combined eq. 4  C next, solve for the vertical velocity k.e. using combined eq. 4
738  c and eq 5 from the paper  C and eq 5 from the paper
739  c  
740                   if(debug) then                   if(debug) then
741                    write(0,*)"Dd,De,entr,k ",Dd(k2),De(k2),entrainrate,k2                    write(0,*)"Dd,De,entr,k ",Dd(k2),De(k2),entrainrate,k2
742                   endif                   endif
743  c  
744                   wsqr = wsqr - wsqr*abs(entrainrate)+ 9.81*                   wsqr = wsqr - wsqr*abs(entrainrate)+ 9.81*
745       .             (dz1*(Dd(k2)-De(k2))/De(k2)       .             (dz1*(Dd(k2)-De(k2))/De(k2)
746       .             +dz2*(Dd(k2+1)-De(k2+1))/De(k2+1))       .             +dz2*(Dd(k2+1)-De(k2+1))/De(k2+1))
747  c  
748  c if negative k.e. then plume has reached max depth, get out of loop  C if negative k.e. then plume has reached max depth, get out of loop
749  c  
750                   IF(wsqr.LT.0.0)then                   IF(wsqr.LT.0.0)then
751                       maxdepth = k2                       maxdepth = k2
752                       if(debug) then                       if(debug) then
# Line 977  c Line 756  c
756                       goto 1                       goto 1
757                   endif                   endif
758                   Wd(k2+1)=sqrt(wsqr)                   Wd(k2+1)=sqrt(wsqr)
759  c  
760  c compute a new radius based on the new mass flux at this grid level  C compute a new radius based on the new mass flux at this grid level
761  c  
762                   radius=sqrt(newflux/(Wd(k2)*Dd(k2)))                   radius=sqrt(newflux/(Wd(k2)*Dd(k2)))
763                ELSE                ELSE
764                   maxdepth=k2                   maxdepth=k2
# Line 987  c Line 766  c
766                   GOTO 1                   GOTO 1
767                ENDIF                ENDIF
768            ENDDO            ENDDO
769  c  
770  c plume has reached the bottom  C plume has reached the bottom
771  c  
772            MaxDepth=NumGridPoints            MaxDepth=NumGridPoints
773  c  
774  1         continue  1         continue
775  c  
776            Ad(k)=FRACTIONAL_AREA            Ad(k)=FRACTIONAL_AREA
777            IC=0            IC=0
778  c  
779  c start iteration on fractional area, not used in OGCM implementation  C start iteration on fractional area, not used in OGCM implementation
780  c  
 c  
781            DO IC=1,Max_ABE_Iterations            DO IC=1,Max_ABE_Iterations
782  c  
783  c  C next compute the mass flux beteen each grid box using the entrainment
784  c next compute the mass flux beteen each grid box using the entrainment  
 c  
785   92          continue   92          continue
786               Md(k)=Wd(k)*Ad(k)               Md(k)=Wd(k)*Ad(k)
787  c  
788               DO k2=k+1,MaxDepth               DO k2=k+1,MaxDepth
789                 Md(k2)=Md(k)*PlumeEntrainment(k2)                 Md(k2)=Md(k)*PlumeEntrainment(k2)
790                 if(debug) then                 if(debug) then
791                   write(0,*)"Md, Wd, and  k are ",Md(k2),Wd(k2),k2                   write(0,*)"Md, Wd, and  k are ",Md(k2),Wd(k2),k2
792                 endif                 endif
793               ENDDO               ENDDO
794  c  
795  c Now move on to calculate new temperature using flux from  C Now move on to calculate new temperature using flux from
796  c Td, Sd, Wd, ta, sa, and we. Values for these variables are at  C Td, Sd, Wd, ta, sa, and we. Values for these variables are at
797  c center of grid cell, use weighted average to get boundary values  C center of grid cell, use weighted average to get boundary values
798  c  
799  c use a timestep limited by the GCM model timestep and the maximum plume  C use a timestep limited by the GCM model timestep and the maximum plume
800  c velocity (CFL criteria)  C velocity (CFL criteria)
801  c  
802  c  C calculate the weighted wd, td, and sd
803  c calculate the weighted wd, td, and sd  
 c  
804               dt = dtts               dt = dtts
805               do k2=k,maxdepth-1               do k2=k,maxdepth-1
806                  dt = min(dt,dz(k2)/wd(k2))                  dt = min(dt,dz(k2)/wd(k2))
807  c  
808  c time integration will be integer number of steps to get one  C time integration will be integer number of steps to get one
809  c gcm time step  C gcm time step
810  c  
811                  ntime = nint(0.5*int(dtts/dt))                  ntime = nint(0.5*int(dtts/dt))
812                  if(ntime.eq.0) then                  if(ntime.eq.0) then
813                     ntime = 1                     ntime = 1
814                  endif                  endif
815  c  
816  c make sure area weighted vertical velocities match; in other words  C make sure area weighted vertical velocities match; in other words
817  c make sure mass in equals mass out at the intersection of each grid  C make sure mass in equals mass out at the intersection of each grid
818  c cell.  C cell.
819  c  
820                  mda(k2) = (md(k2)*dz(k2)+md(k2+1)*dz(k2+1))/                  mda(k2) = (md(k2)*dz(k2)+md(k2+1)*dz(k2+1))/
821       *                    (dz(k2)+dz(k2+1))       *                    (dz(k2)+dz(k2+1))
822  c  
823                  wda(k2) = (wd(k2)*dz(k2)+wd(k2+1)*dz(k2+1))/                  wda(k2) = (wd(k2)*dz(k2)+wd(k2+1)*dz(k2+1))/
824       *                    (dz(k2)+dz(k2+1))       *                    (dz(k2)+dz(k2+1))
825  c  
826                  tda(k2) = td(k2)                  tda(k2) = td(k2)
827                  sda(k2) = sd(k2)                  sda(k2) = sd(k2)
828  c  
829                  taa(k2) = ttemp(k2+1)                  taa(k2) = ttemp(k2+1)
830                  saa(k2) = stemp(k2+1)                  saa(k2) = stemp(k2+1)
831  c  
832               enddo               enddo
833               dt = min(dt,dtts)               dt = min(dt,dtts)
834               if(debug) then               if(debug) then
# Line 1060  c Line 836  c
836               endif               endif
837               tda(maxdepth) = td(maxdepth)               tda(maxdepth) = td(maxdepth)
838               sda(maxdepth) = sd(maxdepth)               sda(maxdepth) = sd(maxdepth)
839  c  
840  c do top and bottom points first  C do top and bottom points first
841  c  
842               kmx = maxdepth-1               kmx = maxdepth-1
843               do nn=1,ntime               do nn=1,ntime
844    
845                 ttemp(k) =  ttemp(k)-                 ttemp(k) =  ttemp(k)-
846       *                  (mda(k)*(tda(k)-taa(k)))*dt*recip_drF(k)       *                  (mda(k)*(tda(k)-taa(k)))*dt*recip_drF(k)
847  c  
848                 stemp(k) =  stemp(k)-                 stemp(k) =  stemp(k)-
849       *                  (mda(k)*(sda(k)-saa(k)))*dt*recip_drF(k)       *                  (mda(k)*(sda(k)-saa(k)))*dt*recip_drF(k)
850  c  
851  c  C now do inner points if there are any
852  c now do inner points if there are any  
 c  
853                 if(Maxdepth-k.gt.1) then                 if(Maxdepth-k.gt.1) then
854                   do k2=k+1,Maxdepth-1                   do k2=k+1,Maxdepth-1
855  c  
856                     ttemp(k2) = ttemp(k2) +                     ttemp(k2) = ttemp(k2) +
857       *              (mda(k2-1)*(tda(k2-1)-taa(k2-1))-       *              (mda(k2-1)*(tda(k2-1)-taa(k2-1))-
858       *              mda(k2)*(tda(k2)-taa(k2)))       *              mda(k2)*(tda(k2)-taa(k2)))
859       *              *dt*recip_drF(k2)       *              *dt*recip_drF(k2)
860    
 c  
861                    stemp(k2) = stemp(k2) +                    stemp(k2) = stemp(k2) +
862       *              (mda(k2-1)*(sda(k2-1)-saa(k2-1))-       *              (mda(k2-1)*(sda(k2-1)-saa(k2-1))-
863       *              mda(k2)*(sda(k2)-saa(k2)))       *              mda(k2)*(sda(k2)-saa(k2)))
864       *              *dt*recip_drF(k2)       *              *dt*recip_drF(k2)
865    
 c  
866                   enddo                   enddo
867                 endif                 endif
868                 ttemp(kmx+1) =  ttemp(kmx+1)+                 ttemp(kmx+1) =  ttemp(kmx+1)+
869       *                  (mda(kmx)*(tda(kmx)-taa(kmx)))*       *                  (mda(kmx)*(tda(kmx)-taa(kmx)))*
870       *                  dt*recip_drF(kmx+1)       *                  dt*recip_drF(kmx+1)
871  c  
872                 stemp(kmx+1) =  stemp(kmx+1)+                 stemp(kmx+1) =  stemp(kmx+1)+
873       *                  (mda(kmx)*(sda(kmx)-saa(kmx)))*       *                  (mda(kmx)*(sda(kmx)-saa(kmx)))*
874       *                  dt*recip_drF(kmx+1)       *                  dt*recip_drF(kmx+1)
875  c  
876  c set the environmental temp and salinity to equal new fields  C set the environmental temp and salinity to equal new fields
877  c  
878                  do k2=1,maxdepth-1                  do k2=1,maxdepth-1
879                    taa(k2) = ttemp(k2+1)                    taa(k2) = ttemp(k2+1)
880                    saa(k2) = stemp(k2+1)                    saa(k2) = stemp(k2+1)
881                  enddo                  enddo
882  c  
883  c end loop on number of time integration steps  C end loop on number of time integration steps
884  c  
885               enddo               enddo
886            ENDDO            ENDDO
887  999       continue  999       continue
888  c  
889  c assume that it converged, so update the ta and sa with new fields  C assume that it converged, so update the ta and sa with new fields
890  c  
891  c          if(i.gt.180.and.j.gt.200.and.i.lt.240) then  c          if(i.gt.180.and.j.gt.200.and.i.lt.240) then
892  c            write(*,*)"Converged ",i,j,k,maxdepth,ttemp(k+1),ta(i,k+1)  c            write(*,*)"Converged ",i,j,k,maxdepth,ttemp(k+1),ta(i,k+1)
893  c          endif  c          endif
# Line 1126  c          endif Line 899  c          endif
899  c          if(i.gt.180.and.j.gt.200.and.i.lt.240) then  c          if(i.gt.180.and.j.gt.200.and.i.lt.240) then
900  c            write(*,*)"convadj ",convadj(i,j,k2)  c            write(*,*)"convadj ",convadj(i,j,k2)
901  c          endif  c          endif
902  c  
903  c see if nlopps messed up  C see if nlopps messed up
904  c  
905              if(sa(i,k).gt.40..or.ta(i,k).lt.-4.0) then              if(sa(i,k).gt.40..or.ta(i,k).lt.-4.0) then
906                 problem = .true.                 problem = .true.
907                 write(0,*)"t out of range at j after adjust",j                 write(0,*)"t out of range at j after adjust",j
908                 debug = .true.                 debug = .true.
909              endif              endif
910  c  
911            enddo            enddo
912  c  
913  c jump here if k = maxdepth or if level not unstable, go to next  C jump here if k = maxdepth or if level not unstable, go to next
914  c profile point  C profile point
915  c  
916  1000      continue  1000      continue
917  c  
918  c  C end loop on k, move on to next possible plume
919  c end loop on k, move on to next possible plume  
 c  
920        ENDDO        ENDDO
921  1100  continue  1100  continue
922  c  
923  c i loop  C i loop
924  c  
925        ENDDO        ENDDO
926        END        END
927    

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

  ViewVC Help
Powered by ViewVC 1.1.22