C $Header: /u/gcmpack/MITgcm/pkg/fizhi/getpwhere.F,v 1.11 2010/03/16 00:19:33 jmc Exp $
C $Name:  $

#include "FIZHI_OPTIONS.h"
#undef CHECK_GETPWHERE

       subroutine GETPWHERE(myThid,numpress,pressures,levpressures)
C***********************************************************************
C subroutine getpwhere
C
C Purpose: Approximate (!) the level at which the mid-level pressure
C          is less than (ie, above in the atmosphere) a given value.
C
C Algorithm: Assume surface pressure of 1000 mb, and the pressure
c          thicknesses set in make_phys_grid, with drF thicknesses above
C
C Need:    Information about the dynamics grid vertical spacing
C
C Input:   myThid       - process(or) number
C          numpres      - Number of pressures to process
C          pressures    - Pressure values to find levels for
C
C Output:  levpressures - Array of levels at which pressures are found
C                         These pressure levels correspond to the fizhi
C                         levels, and assume that the levels are counted
C                         from top to bottom (CRITICAL!)
C
C NOTE: The new physics levels specified here MUST correspond to the
C       physics levels specified in make_phys_grid from gridalt package.
C***********************************************************************
       implicit none
c
#include "SIZE.h"
#include "fizhi_SIZE.h"
#include "GRID.h"
#ifdef CHECK_GETPWHERE
#include "EEPARAMS.h"
#include "PARAMS.h"
#endif /* CHECK_GETPWHERE */

       integer myThid,numpress
       _RL pressures(numpress)
       integer levpressures(numpress)
c
#ifdef CHECK_GETPWHERE
       INTEGER ioUnit, upperBnd
c      CHARACTER*(MAX_LEN_MBUF) msgBuf
#endif /* CHECK_GETPWHERE */
       integer n,L,dynlev
C Code that MUST correspond to make_phys_grid in the gridalt package!
C Require 12 bottom levels (300 mb worth) for the physics,
C    Counting from bottom to top, the dp(s) are:
       integer ntry,ntry10,ntry40
       parameter (ntry40=15)
       parameter (ntry10=12)
       _RL dptry(ntry40), dptry10(ntry10), dptry40(ntry40)
       _RL dptry_pedge(ntry40+1)
#ifdef TRY_NEW_GETPWHERE
       _RL rC_dyn(Nr), dpTop
#else
       _RL rF_pmid(Nr),rF_edge(Nr+1)
#endif
       _RL pref(Nrphys)
       integer tmplev
       data dptry10 /3.00, 6.00,10.00,14.00,17.00,25.00,
     .              25.00,25.00,25.00,50.00,50.00,50.00/
       data dptry40 /3.00, 6.00,10.00,14.00,17.00,25.00,
     .              25.00,25.00,25.00,25.00,25.00,25.00,
     .              25.00,25.00,25.00/

       if( (Nr.eq.10).or.(Nr.eq.20) ) then
        ntry = ntry10
        do L = 1,ntry
         dptry(L) = dptry10(L)
        enddo
       elseif ((Nr.eq.40).or.(Nr.eq.70)) then
        ntry = ntry40
        do L = 1,ntry
         dptry(L) = dptry40(L)
        enddo
       else
        print *,' Dont know how to set levels for given pressures '
        stop
       endif

C define the mid pressure for the levels that are specified - bottom 300 mb.
#ifdef TRY_NEW_GETPWHERE
       dptry_pedge(1) = rF(1)*1. _d -2
#else  /* TRY_NEW_GETPWHERE */
       dptry_pedge(1) = 1000.
#endif /* TRY_NEW_GETPWHERE */
       do L = 1,ntry
        dptry_pedge(L+1) = dptry_pedge(L) - dptry(L)
       enddo
       do L = 1,ntry
        pref(L) = (dptry_pedge(L) + dptry_pedge(L+1))/2.
       enddo
#ifdef CHECK_GETPWHERE
       ioUnit = errorMessageUnit
       WRITE(ioUnit,'(A)') '===== GETPWHERE: CHECK start ====='
       WRITE(ioUnit,'(4(A,I6),A)') '  Nr =', Nr,
     &                        ' , Nrphys=', Nrphys,
     &                        ' , ntry  =', ntry,
     &                        ' , pref(1:ntry):'
       WRITE(ioUnit,'(10F10.4)') (pref(L),L=1,ntry)
#endif /* CHECK_GETPWHERE */

#ifdef TRY_NEW_GETPWHERE
C top levels DP of 1 mb (or 0.01 mb for strat version)
       dpTop = 1. _d 0
       IF (Nr.EQ.70) dpTop = 1. _d -2
       DO L = ntry+1,Nrphys
        pref(L) = (Nrphys-L+0.5)*dpTop
       ENDDO
C define the rest of the mid pressures from the dynamics levels
       DO L = 1,Nr
        rC_dyn(L) = rC(L)*1. _d -2
       ENDDO

       dynlev = 0
       DO L = 1,Nr
         IF ( rC_dyn(L).GE.dptry_pedge(ntry+1) ) dynlev = L
       ENDDO
       DO L = ntry+1,MIN(Nrphys,ntry+Nr-dynlev)
         pref(L) = rC_dyn(dynlev+L-ntry)
       ENDDO
#else  /* TRY_NEW_GETPWHERE */
C define the rest of the mid pressures from the dynamics levels
       rF_edge(1) = 1000.
       do L = 2,Nr+1
        rF_edge(L) = rF_edge(L-1) - (drF(L-1)/100.)
       enddo
       do L = 1,Nr
        rF_pmid(L) = (rF_edge(L) + rF_edge(L+1))/2.
       enddo

       dynlev = 0
       do L = 1,Nr
        if(rF_pmid(L).ge.pref(ntry)) dynlev = L
       enddo
#ifdef CHECK_GETPWHERE
       IF ( rF_pmid(dynlev).ge.pref(ntry)-25. ) THEN
         upperBnd = ntry+Nr-dynlev
       ELSE
         upperBnd = ntry+Nr-dynlev-1
       ENDIF
       WRITE(ioUnit,'(1(A,I5),A)') ' Up-Bnd=', upperBnd,
     &                           ' , rF_pmid:'
       WRITE(ioUnit,'(10F10.4)') rF_pmid
       IF ( upperBnd.LT.Nrphys-1 ) THEN
         WRITE(ioUnit,'(A)')
     &   'ERROR: exeeding "rF_pmid" array bounds => pref ill defined'
c        STOP 'ABNORMAL END: S/R GETPWHERE'
       ENDIF
#endif /* CHECK_GETPWHERE */
       if(rF_pmid(dynlev).ge.pref(ntry)-25.) then
        do L = ntry+1,Nrphys-1
         pref(L) = rF_pmid(dynlev+L-ntry)
        enddo
       else
        pref(ntry) = rF_pmid(dynlev)
        do L = ntry+1,Nrphys-1
         pref(L) = rF_pmid(dynlev+L-ntry+1)
        enddo
       endif
C Add top level DP of 1 mb - p mid is at 0.5 mb (or 0.05 mb for strat version)
       pref(Nrphys) = 0.5
       if(Nr.eq.70)pref(Nrphys) = 0.005
#endif /* TRY_NEW_GETPWHERE */

       DO n = 1,numpress
        DO L = 1,Nrphys
         IF ( pref(L).GE.pressures(n) ) tmplev = L
        ENDDO

C and now flip the level numbers for the top down counting in fizhi
        levpressures(n) = Nrphys+1-tmplev
       ENDDO

#ifdef CHECK_GETPWHERE
       WRITE(ioUnit,'(3(A,I5),A)') ' dynlev=', dynlev,
     &                           ' , numpress=', numpress,
     &                           ' , pressures:'
       WRITE(ioUnit,'(10F10.4)') pressures
       WRITE(ioUnit,'(A)') 'pref(ntry:Nrphys):'
       WRITE(ioUnit,'(10F10.4)') (pref(L),L=ntry,Nrphys)
       WRITE(ioUnit,'(A)') 'levpressures:'
       WRITE(ioUnit,'(20I5)') levpressures
       WRITE(ioUnit,'(A)') '===== GETPWHERE: CHECK end   ====='
#endif /* CHECK_GETPWHERE */

       RETURN
       END