!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| module pressure_grad !BOP ! !MODULE: pressure_grad ! ! !DESCRIPTION: ! Contains routines for computing the pressure gradient force, ! including the use of pressure averaging. ! ! !REVISION HISTORY: ! SVN:$Id: pressure_grad.F90 808 2006-04-28 17:06:38Z njn01 $ ! !USES: use kinds_mod, only: log_kind, r8, int_kind use domain_size ! use domain, only: use blocks, only: nx_block, ny_block, block ! use distribution, only: use constants, only: grav, p5, delim_fmt, blank_fmt, c1, p25, c2, c0, ndelim_fmt use operators, only: grad use grid, only: dzw use broadcast, only: broadcast_scalar use communicate, only: my_task, master_task ! use io, only: use io_types, only: stdout, nml_in, nml_filename use state_mod, only: ref_pressure use time_management, only: max_blocks_clinic, km, leapfrogts use exit_mod, only: sigAbort, exit_pop, flushm implicit none private save ! !PUBLIC MEMBER FUNCTIONS: public :: init_pressure_grad, & gradp ! !PUBLIC DATA MEMBERS: logical (log_kind), public :: & lpressure_avg ! flag to turn on averaging of ! pressure across three time levels !EOP !BOC !----------------------------------------------------------------------- ! ! module variables ! !----------------------------------------------------------------------- real (r8), dimension(nx_block,ny_block,max_blocks_clinic) :: & SUMX, SUMY, &! incremental k sum of Grad{x,y}(P(k)) RHOKMX, RHOKMY ! x,y gradient of density at k-1 level !----------------------------------------------------------------------- ! ! The factor, r(p), removes the contribution of pressure- ! dependent compressibility from the density and thereby ! improves the accuracy of the Boussinesq approximation ! for the pressure gradient. ! ! See Dukowicz, J. K., 2000: Reduction of Pressure and ! Pressure Gradient Errors in Ocean Simulations, J. Phys. ! Oceanogr., submitted. ! !----------------------------------------------------------------------- logical (log_kind) :: & lbouss_correct ! flag for correction to Bouss. approx. real (r8), dimension(km) :: & bouss ! 1/r(p) factor for correction to Bouss. !EOC !*********************************************************************** contains !*********************************************************************** !BOP ! !IROUTINE: init_pressure_grad ! !INTERFACE: subroutine init_pressure_grad ! !DESCRIPTION: ! Initializes pressure gradient options and allocates space for ! pressure gradient integrals. ! ! !REVISION HISTORY: ! same as module !EOP !BOC !----------------------------------------------------------------------- ! ! local variables ! !----------------------------------------------------------------------- integer (int_kind) :: & k, &! vertical level index nml_error ! namelist i/o error flag namelist /pressure_grad_nml/ lpressure_avg, lbouss_correct !----------------------------------------------------------------------- ! ! read options from input namelist and broadcast ! !----------------------------------------------------------------------- lpressure_avg = .true. lbouss_correct = .false. if (my_task == master_task) then open (nml_in, file=nml_filename, status='old',iostat=nml_error) if (nml_error /= 0) then nml_error = -1 else nml_error = 1 endif do while (nml_error > 0) read(nml_in, nml=pressure_grad_nml,iostat=nml_error) end do if (nml_error == 0) close(nml_in) endif call broadcast_scalar(nml_error, master_task) if (nml_error /= 0) then call exit_POP(sigAbort,'ERROR reading pressure_grad_nml') endif if (my_task == master_task) then write(stdout,blank_fmt) write(stdout,ndelim_fmt) write(stdout,blank_fmt) write(stdout,'(a26)') ' Pressure gradient options' write(stdout,blank_fmt) write(stdout,delim_fmt) if (lpressure_avg) then write(stdout,'(a28)') ' Pressure averaging enabled ' else write(stdout,'(a28)') ' Pressure averaging disabled' endif if (lbouss_correct) then write(stdout,'(a28)') ' Density correction enabled ' else write(stdout,'(a28)') ' Density correction disabled' endif endif call broadcast_scalar(lpressure_avg, master_task) call broadcast_scalar(lbouss_correct, master_task) !----------------------------------------------------------------------- ! ! Density correction factor at level k. ! !----------------------------------------------------------------------- if (lbouss_correct) then do k=1,km bouss(k) = c1/(1.02819_r8 + 4.4004e-5_r8*ref_pressure(k) - & 2.93161e-4_r8*exp(-0.05_r8*ref_pressure(k))) end do else bouss(:) = c1 endif !----------------------------------------------------------------------- !EOC end subroutine init_pressure_grad !*********************************************************************** !BOP ! !IROUTINE: gradp ! !INTERFACE: subroutine gradp(k, PKX, PKY, RHOK_OLD, RHOK_CUR, RHOK_NEW, this_block) ! !DESCRIPTION: ! This routine computes the gradient of hydrostatic pressure at ! level $k$: ! ! \begin{eqnarray} ! \delta_x \overline{p_k}^y &=& \delta_x \overline{p_s}^y + ! g \sum_{m=1}^k{ {1\over 2}\left[ ! \delta_x \overline{\rho_{m-1}}^y + ! \delta_x \overline{\rho_m}^y \right] dz_{m-{1\over 2}} } \\ ! \delta_y \overline{p_k}^x &=& \delta_y \overline{p_s}^x + ! g \sum_{m=1}^k{ {1\over 2}\left[ ! \delta_y \overline{\rho_{m-1}}^x + ! \delta_y \overline{\rho_m}^x \right] dz_{m-{1\over 2}} } ! \end{eqnarray} ! where $p_k$ is the hydrostatic pressure at level $k$, ! $\rho_m$ is the density at level $m$, and $\rho_0=\rho_1$ for $k=0$. ! ! This routine must be called successively with $k = 1,2,3,...$ ! ! !REVISION HISTORY: ! same as module ! !INPUT PARAMETERS: integer (int_kind), intent(in) :: k ! depth level index type (block), intent(in) :: & this_block ! block information for current block real (r8), dimension(nx_block,ny_block), intent(in) :: & RHOK_OLD, &! density at level k and old time level RHOK_CUR, &! density at level k and current time level RHOK_NEW ! density at level k and new time level ! !OUTPUT PARAMETERS: real (r8), dimension(nx_block,ny_block), intent(out) :: & PKX,PKY ! {x,y} components of the pressure gradient !EOP !BOC !----------------------------------------------------------------------- ! ! local or common variables: ! !----------------------------------------------------------------------- integer (int_kind) :: bid ! local block address real (r8) :: factor ! temporary factor real (r8), dimension(nx_block,ny_block) :: & RHOKX, RHOKY, &! x,y gradients of level k density RHOAVG ! avg density when pressure avg on !----------------------------------------------------------------------- ! ! gradient of density at level k ! !----------------------------------------------------------------------- bid = this_block%local_id !----------------------------------------------------------------------- ! ! calculate density at new time for pressure averaging ! !----------------------------------------------------------------------- if (lpressure_avg .and. leapfrogts) then RHOAVG = p25*(RHOK_NEW + c2*RHOK_CUR + RHOK_OLD)*bouss(k) else RHOAVG = RHOK_CUR*bouss(k) endif call grad(k,RHOKX,RHOKY,RHOAVG,this_block) !----------------------------------------------------------------------- ! ! set Rho(0) = Rho(1) at top level, ! initialize sum for pressure gradients to zero. ! !----------------------------------------------------------------------- if (k == 1) then RHOKMX(:,:,bid) = RHOKX RHOKMY(:,:,bid) = RHOKY SUMX (:,:,bid) = c0 SUMY (:,:,bid) = c0 endif !----------------------------------------------------------------------- ! ! obtain pressure gradient by incrementing sum of density gradients ! from top level down to level k. ! !----------------------------------------------------------------------- factor = dzw(k-1)*grav*p5 SUMX(:,:,bid) = SUMX(:,:,bid) + factor*(RHOKX + RHOKMX(:,:,bid)) SUMY(:,:,bid) = SUMY(:,:,bid) + factor*(RHOKY + RHOKMY(:,:,bid)) PKX = SUMX(:,:,bid) PKY = SUMY(:,:,bid) !----------------------------------------------------------------------- ! ! overwrite level k-1 with level k density gradients for next pass ! !----------------------------------------------------------------------- RHOKMX(:,:,bid) = RHOKX RHOKMY(:,:,bid) = RHOKY !----------------------------------------------------------------------- !EOC end subroutine gradp !*********************************************************************** end module pressure_grad !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||