MOM6
mom_kpp Module Reference

Detailed Description

Provides the K-Profile Parameterization (KPP) of Large et al., 1994, via CVMix.

The K-Profile Parameterization

The K-Profile Parameterization (KPP) of Large et al., 1994, (http://dx.doi.org/10.1029/94RG01872) is implemented via the Community Vertical Mixing package, CVmix, which is called directly by this module.

The formulation and implementation of KPP is described in great detail in the CVMix manual (written by our own Stephen Griffies).

KPP in a nutshell

Large et al., 1994, decompose the parameterized boundary layer turbulent flux of a scalar, \( s \), as

\[ \overline{w^\prime s^\prime} = -K \partial_z s + K \gamma_s(\sigma), \]

where \( \sigma = -z/h \) is a non-dimensional coordinate within the boundary layer of depth \( h \). \( K \) is the eddy diffusivity and is a function of position within the boundary layer as well as a function of the surface forcing:

\[ K = h w_s(\sigma) G(\sigma) . \]

Here, \( w_s \) is the vertical velocity scale of the boundary layer turbulence and \( G(\sigma) \) is a "shape function" which is described later. The last term is the "non-local transport" which involves a function \( \gamma_s(\sigma) \) that is matched to the forcing but is not actually needed in the final implementation. Instead, the entire non-local transport term can be equivalently written

\[ K \gamma_s(\sigma) = C_s G(\sigma) Q_s \]

where \( Q_s \) is the surface flux of \( s \) and \( C_s \) is a constant. The vertical structure of the redistribution (non-local) term is solely due to the shape function, \( G(\sigma) \). In our implementation of KPP, we allow the shape functions used for \( K \) and for the non-local transport to be chosen independently.

The particular shape function most widely used in the atmospheric community is

\[ G(\sigma) = \sigma (1-\sigma)^2 \]

which satisfies the boundary conditions \( G(0) = 0 \), \( G(1) = 0 \), \( G^\prime(0) = 1 \), and \( G^\prime(1) = 0 \). Large et al, 1994, alter the function so as to match interior diffusivities but we have found that this leads to inconsistencies within the formulation (see google groups thread Extreme values of non-local transport). Instead, we use either the above form, or even simpler forms that use alternative upper boundary conditions.

The KPP boundary layer depth is a function of the bulk Richardson number, Rib. But to compute Rib, we need the boundary layer depth. To address this circular logic, we compute Rib for each vertical cell in a column, assuming the BL depth equals to the depth of the given grid cell. Once we have a vertical array of Rib(k), we then call the OBLdepth routine from CVMix to compute the actual OBLdepth. We optionally then "correct" the OBLdepth by cycling through once more, this time knowing the OBLdepth from the first pass. This "correction" step is not used by NCAR. It has been found in idealized MOM6 tests to not be necessary.

See also
kpp_calculate(), kpp_applynonlocaltransport()

Data Types

type  kpp_cs
 Control structure for containing KPP parameters/data. More...
 

Functions/Subroutines

logical function, public kpp_init (paramFile, G, diag, Time, CS, passive)
 Initialize the CVmix KPP module and set up diagnostics Returns True if KPP is to be used, False otherwise. More...
 
subroutine, public kpp_calculate (CS, G, GV, h, Temp, Salt, u, v, EOS, uStar, buoyFlux, Kt, Ks, Kv, nonLocalTransHeat, nonLocalTransScalar)
 KPP vertical diffusivity/viscosity and non-local tracer transport. More...
 
subroutine, public kpp_nonlocaltransport_temp (CS, G, GV, h, nonLocalTrans, surfFlux, dt, scalar, C_p)
 Apply KPP non-local transport of surface fluxes for temperature. More...
 
subroutine, public kpp_nonlocaltransport_saln (CS, G, GV, h, nonLocalTrans, surfFlux, dt, scalar)
 Apply KPP non-local transport of surface fluxes for salinity. This routine is a useful prototype for other material tracers. More...
 
subroutine, public kpp_end (CS)
 Clear pointers, deallocate memory. More...
 

Variables

integer, parameter, private nlt_shape_cvmix = 0
 Use the CVmix profile. More...
 
integer, parameter, private nlt_shape_linear = 1
 Linear, \( G(\sigma) = 1-\sigma \). More...
 
integer, parameter, private nlt_shape_parabolic = 2
 Parabolic, \( G(\sigma) = (1-\sigma)^2 \). More...
 
integer, parameter, private nlt_shape_cubic = 3
 Cubic, \( G(\sigma) = 1 + (2\sigma-3) \sigma^2\). More...
 
integer, parameter, private nlt_shape_cubic_lmd = 4
 Original shape, \( G(\sigma) = \frac{27}{4} \sigma (1-\sigma)^2 \). More...
 
integer, parameter, private sw_method_all_sw = 0
 Use all shortwave radiation. More...
 
integer, parameter, private sw_method_mxl_sw = 1
 Use shortwave radiation absorbed in mixing layer. More...
 
integer, parameter, private sw_method_lv1_sw = 2
 Use shortwave radiation absorbed in layer 1. More...
 
logical, parameter verbose = .False.
 

Function/Subroutine Documentation

◆ kpp_calculate()

subroutine, public mom_kpp::kpp_calculate ( type(kpp_cs), pointer  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  Temp,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  Salt,
real, dimension( g %isdb: g %iedb, g %jsd: g %jed, g %ke), intent(in)  u,
real, dimension( g %isd: g %ied, g %jsdb: g %jedb, g %ke), intent(in)  v,
type(eos_type), pointer  EOS,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(in)  uStar,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(in)  buoyFlux,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(inout)  Kt,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(inout)  Ks,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(inout)  Kv,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(inout)  nonLocalTransHeat,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(inout)  nonLocalTransScalar 
)

KPP vertical diffusivity/viscosity and non-local tracer transport.

Parameters
csControl structure
[in]gOcean grid
[in]gvOcean vertical grid
[in]hLayer/level thicknesses (units of H)
[in]temppotential/cons temp (deg C)
[in]saltSalinity (ppt)
[in]uVelocity i-component (m/s)
[in]vVelocity j-component (m/s)
eosEquation of state
[in]ustarSurface friction velocity (m/s)
[in]buoyfluxSurface buoyancy flux (m2/s3)
[in,out]kt(in) Vertical diffusivity of heat w/o KPP (m2/s) (out) Vertical diffusivity including KPP (m2/s)
[in,out]ks(in) Vertical diffusivity of salt w/o KPP (m2/s) (out) Vertical diffusivity including KPP (m2/s)
[in,out]kv(in) Vertical viscosity w/o KPP (m2/s) (out) Vertical viscosity including KPP (m2/s)
[in,out]nonlocaltransheatTemp non-local transport (m/s)
[in,out]nonlocaltransscalarscalar non-local transport (m/s)

Definition at line 413 of file MOM_KPP.F90.

References nlt_shape_cubic, nlt_shape_cubic_lmd, nlt_shape_linear, nlt_shape_parabolic, sw_method_all_sw, sw_method_lv1_sw, and sw_method_mxl_sw.

413 
414  ! Arguments
415  type(kpp_cs), pointer :: cs !< Control structure
416  type(ocean_grid_type), intent(in) :: g !< Ocean grid
417  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid
418  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thicknesses (units of H)
419  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: temp !< potential/cons temp (deg C)
420  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: salt !< Salinity (ppt)
421  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Velocity i-component (m/s)
422  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Velocity j-component (m/s)
423  type(eos_type), pointer :: eos !< Equation of state
424  real, dimension(SZI_(G),SZJ_(G)), intent(in) :: ustar !< Surface friction velocity (m/s)
425  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: buoyflux !< Surface buoyancy flux (m2/s3)
426  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: kt !< (in) Vertical diffusivity of heat w/o KPP (m2/s)
427  !< (out) Vertical diffusivity including KPP (m2/s)
428  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: ks !< (in) Vertical diffusivity of salt w/o KPP (m2/s)
429  !< (out) Vertical diffusivity including KPP (m2/s)
430  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: kv !< (in) Vertical viscosity w/o KPP (m2/s)
431  !< (out) Vertical viscosity including KPP (m2/s)
432  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: nonlocaltransheat !< Temp non-local transport (m/s)
433  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: nonlocaltransscalar !< scalar non-local transport (m/s)
434 
435  ! Local variables
436  integer :: i, j, k, km1,kp1 ! Loop indices
437  real, dimension( G%ke ) :: cellheight ! Cell center heights referenced to surface (m) (negative in ocean)
438  real, dimension( G%ke+1 ) :: ifaceheight ! Interface heights referenced to surface (m) (negative in ocean)
439  real, dimension( G%ke+1 ) :: n2_1d ! Brunt-Vaisala frequency squared, at interfaces (1/s2)
440  real, dimension( G%ke+1 ) :: n_1d ! Brunt-Vaisala frequency at interfaces (1/s) (floored at 0)
441  real, dimension( G%ke ) :: ws_1d ! Profile of vertical velocity scale for scalars (m/s)
442  real, dimension( G%ke ) :: wm_1d ! Profile of vertical velocity scale for momentum (m/s)
443  real, dimension( G%ke ) :: vt2_1d ! Unresolved velocity for bulk Ri calculation/diagnostic (m2/s2)
444  real, dimension( G%ke ) :: bulkri_1d ! Bulk Richardson number for each layer
445  real, dimension( G%ke ) :: deltarho ! delta Rho in numerator of Bulk Ri number
446  real, dimension( G%ke ) :: deltau2 ! square of delta U (shear) in denominator of Bulk Ri (m2/s2)
447  real, dimension( G%ke+1, 2) :: kdiffusivity ! Vertical diffusivity at interfaces (m2/s)
448  real, dimension( G%ke+1 ) :: kviscosity ! Vertical viscosity at interfaces (m2/s)
449  real, dimension( G%ke+1, 2) :: nonlocaltrans ! Non-local transport for heat/salt at interfaces (non-dimensional)
450  real, dimension( G%ke ) :: surfbuoyflux2
451 
452  ! for EOS calculation
453  real, dimension( 3*G%ke ) :: rho_1d
454  real, dimension( 3*G%ke ) :: pres_1d
455  real, dimension( 3*G%ke ) :: temp_1d
456  real, dimension( 3*G%ke ) :: salt_1d
457 
458  real :: kobl, obldepth_0d, surffricvel, surfbuoyflux, coriolis
459  real :: gorho, pref, rho1, rhok, rhokm1, uk, vk, sigma
460 
461  real :: zbottomminusoffset ! Height of bottom plus a little bit (m)
462  real :: sldepth_0d ! Surface layer depth = surf_layer_ext*OBLdepth.
463  real :: htot ! Running sum of thickness used in the surface layer average (m)
464  real :: delh ! Thickness of a layer (m)
465  real :: surfhtemp, surftemp ! Integral and average of temp over the surface layer
466  real :: surfhsalt, surfsalt ! Integral and average of saln over the surface layer
467  real :: surfhu, surfu ! Integral and average of u over the surface layer
468  real :: surfhv, surfv ! Integral and average of v over the surface layer
469  real :: dh ! The local thickness used for calculating interface positions (m)
470  real :: hcorr ! A cumulative correction arising from inflation of vanished layers (m)
471  integer :: kk, ksfc, ktmp
472 
473 #ifdef __DO_SAFETY_CHECKS__
474  if (cs%debug) then
475  call hchksum(h, "KPP in: h",g%HI,haloshift=0, scale=gv%H_to_m)
476  call hchksum(temp, "KPP in: T",g%HI,haloshift=0)
477  call hchksum(salt, "KPP in: S",g%HI,haloshift=0)
478  call hchksum(u, "KPP in: u",g%HI,haloshift=0)
479  call hchksum(v, "KPP in: v",g%HI,haloshift=0)
480  call hchksum(ustar, "KPP in: uStar",g%HI,haloshift=0)
481  call hchksum(buoyflux, "KPP in: buoyFlux",g%HI,haloshift=0)
482  call hchksum(kt, "KPP in: Kt",g%HI,haloshift=0)
483  call hchksum(ks, "KPP in: Ks",g%HI,haloshift=0)
484  endif
485 #endif
486 
487  ! some constants
488  gorho = gv%g_Earth / gv%Rho0
489  nonlocaltrans(:,:) = 0.0
490 
491  if (cs%id_Kd_in > 0) call post_data(cs%id_Kd_in, kt, cs%diag)
492 
493 !$OMP parallel do default(none) shared(G,GV,CS,EOS,uStar,Temp,Salt,u,v,h,GoRho, &
494 !$OMP buoyFlux, nonLocalTransHeat, &
495 !$OMP nonLocalTransScalar,Kt,Ks,Kv) &
496 !$OMP firstprivate(nonLocalTrans) &
497 !$OMP private(Coriolis,surfFricVel,SLdepth_0d,hTot,surfTemp, &
498 !$OMP surfHtemp,surfSalt,surfHsalt,surfU, &
499 !$OMP surfHu,surfV,surfHv,iFaceHeight, &
500 !$OMP pRef,km1,cellHeight,Uk,Vk,deltaU2, &
501 !$OMP rho1,rhoK,rhoKm1,deltaRho,N2_1d,N_1d,delH, &
502 !$OMP surfBuoyFlux,Ws_1d,Vt2_1d,BulkRi_1d, &
503 !$OMP OBLdepth_0d,zBottomMinusOffset,Kdiffusivity, &
504 !$OMP Kviscosity,sigma,kOBL,kk,pres_1D,Temp_1D, &
505 !$OMP Salt_1D,rho_1D,surfBuoyFlux2,ksfc,dh,hcorr)
506 
507  ! loop over horizontal points on processor
508  do j = g%jsc, g%jec
509  do i = g%isc, g%iec
510 
511  ! skip calling KPP for land points
512  if (g%mask2dT(i,j)==0.) cycle
513 
514  ! things independent of position within the column
515  coriolis = 0.25*( (g%CoriolisBu(i,j) + g%CoriolisBu(i-1,j-1)) &
516  +(g%CoriolisBu(i-1,j) + g%CoriolisBu(i,j-1)) )
517  surffricvel = ustar(i,j)
518 
519  ! Bullk Richardson number computed for each cell in a column,
520  ! assuming OBLdepth = grid cell depth. After Rib(k) is
521  ! known for the column, then CVMix interpolates to find
522  ! the actual OBLdepth. This approach avoids need to iterate
523  ! on the OBLdepth calculation. It follows that used in MOM5
524  ! and POP.
525  ifaceheight(1) = 0.0 ! BBL is all relative to the surface
526  pref = 0.
527  hcorr = 0.
528  do k=1,g%ke
529 
530  ! cell center and cell bottom in meters (negative values in the ocean)
531  dh = h(i,j,k) * gv%H_to_m ! Nominal thickness to use for increment
532  dh = dh + hcorr ! Take away the accumulated error (could temporarily make dh<0)
533  hcorr = min( dh - cs%min_thickness, 0. ) ! If inflating then hcorr<0
534  dh = max( dh, cs%min_thickness ) ! Limit increment dh>=min_thickness
535  cellheight(k) = ifaceheight(k) - 0.5 * dh
536  ifaceheight(k+1) = ifaceheight(k) - dh
537 
538  ! find ksfc for cell where "surface layer" sits
539  sldepth_0d = cs%surf_layer_ext*max( max(-cellheight(k),-ifaceheight(2) ), cs%minOBLdepth )
540  ksfc = k
541  do ktmp = 1,k
542  if (-1.0*ifaceheight(ktmp+1) >= sldepth_0d) then
543  ksfc = ktmp
544  exit
545  endif
546  enddo
547 
548  ! average temp, saln, u, v over surface layer
549  ! use C-grid average to get u,v on T-points.
550  surfhtemp=0.0
551  surfhsalt=0.0
552  surfhu =0.0
553  surfhv =0.0
554  htot =0.0
555  do ktmp = 1,ksfc
556 
557  ! SLdepth_0d can be between cell interfaces
558  delh = min( max(0.0, sldepth_0d - htot), h(i,j,ktmp)*gv%H_to_m )
559 
560  ! surface layer thickness
561  htot = htot + delh
562 
563  ! surface averaged fields
564  surfhtemp = surfhtemp + temp(i,j,ktmp) * delh
565  surfhsalt = surfhsalt + salt(i,j,ktmp) * delh
566  surfhu = surfhu + 0.5*(u(i,j,ktmp)+u(i-1,j,ktmp)) * delh
567  surfhv = surfhv + 0.5*(v(i,j,ktmp)+v(i,j-1,ktmp)) * delh
568 
569  enddo
570  surftemp = surfhtemp / htot
571  surfsalt = surfhsalt / htot
572  surfu = surfhu / htot
573  surfv = surfhv / htot
574 
575  ! vertical shear between present layer and
576  ! surface layer averaged surfU,surfV.
577  ! C-grid average to get Uk and Vk on T-points.
578  uk = 0.5*(u(i,j,k)+u(i-1,j,k)) - surfu
579  vk = 0.5*(v(i,j,k)+v(i,j-1,k)) - surfv
580  deltau2(k) = uk**2 + vk**2
581 
582  ! pressure, temp, and saln for EOS
583  ! kk+1 = surface fields
584  ! kk+2 = k fields
585  ! kk+3 = km1 fields
586  km1 = max(1, k-1)
587  kk = 3*(k-1)
588  pres_1d(kk+1) = pref
589  pres_1d(kk+2) = pref
590  pres_1d(kk+3) = pref
591  temp_1d(kk+1) = surftemp
592  temp_1d(kk+2) = temp(i,j,k)
593  temp_1d(kk+3) = temp(i,j,km1)
594  salt_1d(kk+1) = surfsalt
595  salt_1d(kk+2) = salt(i,j,k)
596  salt_1d(kk+3) = salt(i,j,km1)
597 
598  ! pRef is pressure at interface between k and km1.
599  ! iterate pRef for next pass through k-loop.
600  pref = pref + gv%H_to_Pa * h(i,j,k)
601 
602  ! this difference accounts for penetrating SW
603  surfbuoyflux2(k) = buoyflux(i,j,1) - buoyflux(i,j,k+1)
604 
605  enddo ! k-loop finishes
606 
607  ! compute in-situ density
608  call calculate_density(temp_1d, salt_1d, pres_1d, rho_1d, 1, 3*g%ke, eos)
609 
610  ! N2 (can be negative) and N (non-negative) on interfaces.
611  ! deltaRho is non-local rho difference used for bulk Richardson number.
612  ! N_1d is local N (with floor) used for unresolved shear calculation.
613  do k = 1, g%ke
614  km1 = max(1, k-1)
615  kk = 3*(k-1)
616  deltarho(k) = rho_1d(kk+2) - rho_1d(kk+1)
617  n2_1d(k) = (gorho * (rho_1d(kk+2) - rho_1d(kk+3)) ) / &
618  ((0.5*(h(i,j,km1) + h(i,j,k))+gv%H_subroundoff)*gv%H_to_m)
619  n_1d(k) = sqrt( max( n2_1d(k), 0.) )
620  enddo
621  n2_1d(g%ke+1 ) = 0.0
622  n_1d(g%ke+1 ) = 0.0
623 
624  ! turbulent velocity scales w_s and w_m computed at the cell centers.
625  ! Note that if sigma > CS%surf_layer_ext, then CVmix_kpp_compute_turbulent_scales
626  ! computes w_s and w_m velocity scale at sigma=CS%surf_layer_ext. So we only pass
627  ! sigma=CS%surf_layer_ext for this calculation.
628  call cvmix_kpp_compute_turbulent_scales( &
629  cs%surf_layer_ext, & ! (in) Normalized surface layer depth; sigma = CS%surf_layer_ext
630  -cellheight, & ! (in) Assume here that OBL depth (m) = -cellHeight(k)
631  surfbuoyflux2, & ! (in) Buoyancy flux at surface (m2/s3)
632  surffricvel, & ! (in) Turbulent friction velocity at surface (m/s)
633  w_s=ws_1d, & ! (out) Turbulent velocity scale profile (m/s)
634  cvmix_kpp_params_user=cs%KPP_params )
635 
636  ! Calculate Bulk Richardson number from eq (21) of LMD94
637  bulkri_1d = cvmix_kpp_compute_bulk_richardson( &
638  cellheight(1:g%ke), & ! Depth of cell center (m)
639  gorho*deltarho, & ! Bulk buoyancy difference, Br-B(z) (1/s)
640  deltau2, & ! Square of resolved velocity difference (m2/s2)
641  ws_cntr=ws_1d, & ! Turbulent velocity scale profile (m/s)
642  n_iface=n_1d) ! Buoyancy frequency (1/s)
643 
644 
645  surfbuoyflux = buoyflux(i,j,1) ! This is only used in kpp_compute_OBL_depth to limit
646  ! h to Monin-Obukov (default is false, ie. not used)
647 
648  call cvmix_kpp_compute_obl_depth( &
649  bulkri_1d, & ! (in) Bulk Richardson number
650  ifaceheight, & ! (in) Height of interfaces (m)
651  obldepth_0d, & ! (out) OBL depth (m)
652  kobl, & ! (out) level (+fraction) of OBL extent
653  zt_cntr=cellheight, & ! (in) Height of cell centers (m)
654  surf_fric=surffricvel, & ! (in) Turbulent friction velocity at surface (m/s)
655  surf_buoy=surfbuoyflux, & ! (in) Buoyancy flux at surface (m2/s3)
656  coriolis=coriolis, & ! (in) Coriolis parameter (1/s)
657  cvmix_kpp_params_user=cs%KPP_params ) ! KPP parameters
658 
659  ! A hack to avoid KPP reaching the bottom. It was needed during development
660  ! because KPP was unable to handle vanishingly small layers near the bottom.
661  if (cs%deepOBLoffset>0.) then
662  zbottomminusoffset = ifaceheight(g%ke+1) + min(cs%deepOBLoffset,-0.1*ifaceheight(g%ke+1))
663  obldepth_0d = min( obldepth_0d, -zbottomminusoffset )
664  endif
665 
666  ! apply some constraints on OBLdepth
667  if(cs%fixedOBLdepth) obldepth_0d = cs%fixedOBLdepth_value
668  obldepth_0d = max( obldepth_0d, -ifaceheight(2) ) ! no shallower than top layer
669  obldepth_0d = min( obldepth_0d, -ifaceheight(g%ke+1) ) ! no deeper than bottom
670  kobl = cvmix_kpp_compute_kobl_depth( ifaceheight, cellheight, obldepth_0d )
671 
672 !*************************************************************************
673 ! smg: remove code below
674 
675 ! Following "correction" step has been found to be unnecessary.
676 ! Code should be removed after further testing.
677  if (cs%correctSurfLayerAvg) then
678 
679  sldepth_0d = cs%surf_layer_ext * obldepth_0d
680  htot = h(i,j,1)
681  surftemp = temp(i,j,1) ; surfhtemp = surftemp * htot
682  surfsalt = salt(i,j,1) ; surfhsalt = surfsalt * htot
683  surfu = 0.5*(u(i,j,1)+u(i-1,j,1)) ; surfhu = surfu * htot
684  surfv = 0.5*(v(i,j,1)+v(i,j-1,1)) ; surfhv = surfv * htot
685  pref = 0.0
686 
687  do k = 2, g%ke
688 
689  ! Recalculate differences with surface layer
690  uk = 0.5*(u(i,j,k)+u(i-1,j,k)) - surfu
691  vk = 0.5*(v(i,j,k)+v(i,j-1,k)) - surfv
692  deltau2(k) = uk**2 + vk**2
693  pref = pref + gv%H_to_Pa * h(i,j,k)
694  call calculate_density(surftemp, surfsalt, pref, rho1, eos)
695  call calculate_density(temp(i,j,k), salt(i,j,k), pref, rhok, eos)
696  deltarho(k) = rhok - rho1
697 
698  ! Surface layer averaging (needed for next k+1 iteration of this loop)
699  if (htot < sldepth_0d) then
700  delh = min( max(0., sldepth_0d - htot), h(i,j,k)*gv%H_to_m )
701  htot = htot + delh
702  surfhtemp = surfhtemp + temp(i,j,k) * delh ; surftemp = surfhtemp / htot
703  surfhsalt = surfhsalt + salt(i,j,k) * delh ; surfsalt = surfhsalt / htot
704  surfhu = surfhu + 0.5*(u(i,j,k)+u(i-1,j,k)) * delh ; surfu = surfhu / htot
705  surfhv = surfhv + 0.5*(v(i,j,k)+v(i,j-1,k)) * delh ; surfv = surfhv / htot
706  endif
707 
708  enddo
709 
710  bulkri_1d = cvmix_kpp_compute_bulk_richardson( &
711  cellheight(1:g%ke), & ! Depth of cell center (m)
712  gorho*deltarho, & ! Bulk buoyancy difference, Br-B(z) (1/s)
713  deltau2, & ! Square of resolved velocity difference (m2/s2)
714  ws_cntr=ws_1d, & ! Turbulent velocity scale profile (m/s)
715  n_iface=n_1d ) ! Buoyancy frequency (1/s)
716 
717  surfbuoyflux = buoyflux(i,j,1) ! This is only used in kpp_compute_OBL_depth to limit
718  ! h to Monin-Obukov (default is false, ie. not used)
719 
720  call cvmix_kpp_compute_obl_depth( &
721  bulkri_1d, & ! (in) Bulk Richardson number
722  ifaceheight, & ! (in) Height of interfaces (m)
723  obldepth_0d, & ! (out) OBL depth (m)
724  kobl, & ! (out) level (+fraction) of OBL extent
725  zt_cntr=cellheight, & ! (in) Height of cell centers (m)
726  surf_fric=surffricvel, & ! (in) Turbulent friction velocity at surface (m/s)
727  surf_buoy=surfbuoyflux, & ! (in) Buoyancy flux at surface (m2/s3)
728  coriolis=coriolis, & ! (in) Coriolis parameter (1/s)
729  cvmix_kpp_params_user=cs%KPP_params ) ! KPP parameters
730 
731  if (cs%deepOBLoffset>0.) then
732  zbottomminusoffset = ifaceheight(g%ke+1) + min(cs%deepOBLoffset,-0.1*ifaceheight(g%ke+1))
733  obldepth_0d = min( obldepth_0d, -zbottomminusoffset )
734  kobl = cvmix_kpp_compute_kobl_depth( ifaceheight, cellheight, obldepth_0d )
735  endif
736 
737  ! apply some constraints on OBLdepth
738  if(cs%fixedOBLdepth) obldepth_0d = cs%fixedOBLdepth_value
739  obldepth_0d = max( obldepth_0d, -ifaceheight(2) ) ! no shallower than top layer
740  obldepth_0d = min( obldepth_0d, -ifaceheight(g%ke+1) ) ! no deep than bottom
741  kobl = cvmix_kpp_compute_kobl_depth( ifaceheight, cellheight, obldepth_0d )
742 
743  endif ! endif for "correction" step
744 
745 ! smg: remove code above
746 ! **********************************************************************
747 
748 
749  ! Call CVMix/KPP to obtain OBL diffusivities, viscosities and non-local transports
750 
751  ! Unlike LMD94, we do not match to interior diffusivities. If using the original
752  ! LMD94 shape function, not matching is equivalent to matching to a zero diffusivity.
753 
754  !BGR/ Add option for use of surface buoyancy flux with total sw flux.
755  if (cs%SW_METHOD .eq. sw_method_all_sw) then
756  surfbuoyflux = buoyflux(i,j,1)
757  elseif (cs%SW_METHOD .eq. sw_method_mxl_sw) then
758  surfbuoyflux = buoyflux(i,j,1) - buoyflux(i,j,int(kobl)+1) ! We know the actual buoyancy flux into the OBL
759  elseif (cs%SW_METHOD .eq. sw_method_lv1_sw) then
760  surfbuoyflux = buoyflux(i,j,1) - buoyflux(i,j,2)
761  endif
762 
763  ! If option "MatchBoth" is selected in CVMix, MOM should be capable of matching.
764  if (.not. (cs%MatchTechnique.eq.'MatchBoth')) then
765  kdiffusivity(:,:) = 0. ! Diffusivities for heat and salt (m2/s)
766  kviscosity(:) = 0. ! Viscosity (m2/s)
767  else
768  kdiffusivity(:,1) = kt(i,j,:)
769  kdiffusivity(:,2) = ks(i,j,:)
770  kviscosity(:)=kv(i,j,:)
771  endif
772 
773  call cvmix_coeffs_kpp(kviscosity, & ! (inout) Total viscosity (m2/s)
774  kdiffusivity(:,1), & ! (inout) Total heat diffusivity (m2/s)
775  kdiffusivity(:,2), & ! (inout) Total salt diffusivity (m2/s)
776  ifaceheight, & ! (in) Height of interfaces (m)
777  cellheight, & ! (in) Height of level centers (m)
778  kviscosity, & ! (in) Original viscosity (m2/s)
779  kdiffusivity(:,1), & ! (in) Original heat diffusivity (m2/s)
780  kdiffusivity(:,2), & ! (in) Original salt diffusivity (m2/s)
781  obldepth_0d, & ! (in) OBL depth (m)
782  kobl, & ! (in) level (+fraction) of OBL extent
783  nonlocaltrans(:,1),& ! (out) Non-local heat transport (non-dimensional)
784  nonlocaltrans(:,2),& ! (out) Non-local salt transport (non-dimensional)
785  surffricvel, & ! (in) Turbulent friction velocity at surface (m/s)
786  surfbuoyflux, & ! (in) Buoyancy flux at surface (m2/s3)
787  g%ke, & ! (in) Number of levels to compute coeffs for
788  g%ke, & ! (in) Number of levels in array shape
789  cvmix_kpp_params_user=cs%KPP_params )
790 
791 
792  ! Over-write CVMix NLT shape function with one of the following choices.
793  ! The CVMix code has yet to update for thse options, so we compute in MOM6.
794  ! Note that nonLocalTrans = Cs * G(sigma) (LMD94 notation), with
795  ! Cs = 6.32739901508.
796  ! Start do-loop at k=2, since k=1 is ocean surface (sigma=0)
797  ! and we do not wish to double-count the surface forcing.
798  ! Only compute nonlocal transport for 0 <= sigma <= 1.
799  ! MOM6 recommended shape is the parabolic; it gives deeper boundary layer
800  ! and no spurious extrema.
801  if (surfbuoyflux < 0.0) then
802  if (cs%NLT_shape == nlt_shape_cubic) then
803  do k = 2, g%ke
804  sigma = min(1.0,-ifaceheight(k)/obldepth_0d)
805  nonlocaltrans(k,1) = (1.0 - sigma)**2 * (1.0 + 2.0*sigma) !*
806  nonlocaltrans(k,2) = nonlocaltrans(k,1)
807  enddo
808  elseif (cs%NLT_shape == nlt_shape_parabolic) then
809  do k = 2, g%ke
810  sigma = min(1.0,-ifaceheight(k)/obldepth_0d)
811  nonlocaltrans(k,1) = (1.0 - sigma)**2 !*CS%CS2
812  nonlocaltrans(k,2) = nonlocaltrans(k,1)
813  enddo
814  elseif (cs%NLT_shape == nlt_shape_linear) then
815  do k = 2, g%ke
816  sigma = min(1.0,-ifaceheight(k)/obldepth_0d)
817  nonlocaltrans(k,1) = (1.0 - sigma)!*CS%CS2
818  nonlocaltrans(k,2) = nonlocaltrans(k,1)
819  enddo
820  elseif (cs%NLT_shape == nlt_shape_cubic_lmd) then
821  ! Sanity check (should agree with CVMix result using simple matching)
822  do k = 2, g%ke
823  sigma = min(1.0,-ifaceheight(k)/obldepth_0d)
824  nonlocaltrans(k,1) = cs%CS2 * sigma*(1.0 -sigma)**2
825  nonlocaltrans(k,2) = nonlocaltrans(k,1)
826  enddo
827  endif
828  endif
829 
830  ! we apply nonLocalTrans in subroutines
831  ! KPP_NonLocalTransport_temp and KPP_NonLocalTransport_saln
832  nonlocaltransheat(i,j,:) = nonlocaltrans(:,1) ! temp
833  nonlocaltransscalar(i,j,:) = nonlocaltrans(:,2) ! saln
834 
835  ! set the KPP diffusivity and viscosity to zero for testing purposes
836  if(cs%KPPzeroDiffusivity) then
837  kdiffusivity(:,1) = 0.0
838  kdiffusivity(:,2) = 0.0
839  kviscosity(:) = 0.0
840  endif
841 
842  ! recompute wscale for diagnostics, now that we in fact know boundary layer depth
843  if (cs%id_Ws > 0) then
844  call cvmix_kpp_compute_turbulent_scales( &
845  -cellheight/obldepth_0d, & ! (in) Normalized boundary layer coordinate
846  obldepth_0d, & ! (in) OBL depth (m)
847  surfbuoyflux, & ! (in) Buoyancy flux at surface (m2/s3)
848  surffricvel, & ! (in) Turbulent friction velocity at surface (m/s)
849  w_s=ws_1d, & ! (out) Turbulent velocity scale profile (m/s)
850  cvmix_kpp_params_user=cs%KPP_params & ! KPP parameters
851  )
852  cs%Ws(i,j,:) = ws_1d(:)
853  endif
854 
855  ! compute unresolved squared velocity for diagnostics
856  if (cs%id_Vt2 > 0) then
857  vt2_1d(:) = cvmix_kpp_compute_unresolved_shear( &
858  cellheight(1:g%ke), & ! Depth of cell center (m)
859  ws_cntr=ws_1d, & ! Turbulent velocity scale profile, at centers (m/s)
860  n_iface=n_1d, & ! Buoyancy frequency at interface (1/s)
861  cvmix_kpp_params_user=cs%KPP_params ) ! KPP parameters
862  cs%Vt2(i,j,:) = vt2_1d(:)
863  endif
864 
865  ! Copy 1d data into 3d diagnostic arrays
866  if (cs%id_OBLdepth > 0) cs%OBLdepth(i,j) = obldepth_0d
867  if (cs%id_BulkDrho > 0) cs%dRho(i,j,:) = deltarho(:)
868  if (cs%id_BulkUz2 > 0) cs%Uz2(i,j,:) = deltau2(:)
869  if (cs%id_BulkRi > 0) cs%BulkRi(i,j,:) = bulkri_1d(:)
870  if (cs%id_sigma > 0) then
871  cs%sigma(i,j,:) = 0.
872  if (obldepth_0d>0.) cs%sigma(i,j,:) = -ifaceheight/obldepth_0d
873  endif
874  if (cs%id_N > 0) cs%N(i,j,:) = n_1d(:)
875  if (cs%id_N2 > 0) cs%N2(i,j,:) = n2_1d(:)
876  if (cs%id_Kt_KPP > 0) cs%Kt_KPP(i,j,:) = kdiffusivity(:,1)
877  if (cs%id_Ks_KPP > 0) cs%Ks_KPP(i,j,:) = kdiffusivity(:,2)
878  if (cs%id_Kv_KPP > 0) cs%Kv_KPP(i,j,:) = kviscosity(:)
879  if (cs%id_Tsurf > 0) cs%Tsurf(i,j) = surftemp
880  if (cs%id_Ssurf > 0) cs%Ssurf(i,j) = surfsalt
881  if (cs%id_Usurf > 0) cs%Usurf(i,j) = surfu
882  if (cs%id_Vsurf > 0) cs%Vsurf(i,j) = surfv
883 
884 
885  ! Update output of routine
886  if (.not. cs%passiveMode) then
887  if (cs%KPPisAdditive) then
888  do k=1, g%ke+1
889  kt(i,j,k) = kt(i,j,k) + kdiffusivity(k,1)
890  ks(i,j,k) = ks(i,j,k) + kdiffusivity(k,2)
891  kv(i,j,k) = kv(i,j,k) + kviscosity(k)
892  enddo
893  else ! KPP replaces prior diffusivity when former is non-zero
894  do k=1, g%ke+1
895  if (kdiffusivity(k,1) /= 0.) kt(i,j,k) = kdiffusivity(k,1)
896  if (kdiffusivity(k,2) /= 0.) ks(i,j,k) = kdiffusivity(k,2)
897  if (kviscosity(k) /= 0.) kv(i,j,k) = kviscosity(k)
898  enddo
899  endif
900  endif
901 
902 
903  ! end of the horizontal do-loops over the vertical columns
904  enddo ! i
905  enddo ! j
906 
907 
908 #ifdef __DO_SAFETY_CHECKS__
909  if (cs%debug) then
910  call hchksum(kt, "KPP out: Kt",g%HI,haloshift=0)
911  call hchksum(ks, "KPP out: Ks",g%HI,haloshift=0)
912  endif
913 #endif
914 
915  ! send diagnostics to post_data
916  if (cs%id_OBLdepth > 0) call post_data(cs%id_OBLdepth, cs%OBLdepth, cs%diag)
917  if (cs%id_BulkDrho > 0) call post_data(cs%id_BulkDrho, cs%dRho, cs%diag)
918  if (cs%id_BulkUz2 > 0) call post_data(cs%id_BulkUz2, cs%Uz2, cs%diag)
919  if (cs%id_BulkRi > 0) call post_data(cs%id_BulkRi, cs%BulkRi, cs%diag)
920  if (cs%id_sigma > 0) call post_data(cs%id_sigma, cs%sigma, cs%diag)
921  if (cs%id_Ws > 0) call post_data(cs%id_Ws, cs%Ws, cs%diag)
922  if (cs%id_N > 0) call post_data(cs%id_N, cs%N, cs%diag)
923  if (cs%id_N2 > 0) call post_data(cs%id_N2, cs%N2, cs%diag)
924  if (cs%id_Vt2 > 0) call post_data(cs%id_Vt2, cs%Vt2, cs%diag)
925  if (cs%id_uStar > 0) call post_data(cs%id_uStar, ustar, cs%diag)
926  if (cs%id_buoyFlux > 0) call post_data(cs%id_buoyFlux, buoyflux, cs%diag)
927  if (cs%id_Kt_KPP > 0) call post_data(cs%id_Kt_KPP, cs%Kt_KPP, cs%diag)
928  if (cs%id_Ks_KPP > 0) call post_data(cs%id_Ks_KPP, cs%Ks_KPP, cs%diag)
929  if (cs%id_Kv_KPP > 0) call post_data(cs%id_Kv_KPP, cs%Kv_KPP, cs%diag)
930  if (cs%id_NLTt > 0) call post_data(cs%id_NLTt, nonlocaltransheat, cs%diag)
931  if (cs%id_NLTs > 0) call post_data(cs%id_NLTs, nonlocaltransscalar,cs%diag)
932  if (cs%id_Tsurf > 0) call post_data(cs%id_Tsurf, cs%Tsurf, cs%diag)
933  if (cs%id_Ssurf > 0) call post_data(cs%id_Ssurf, cs%Ssurf, cs%diag)
934  if (cs%id_Usurf > 0) call post_data(cs%id_Usurf, cs%Usurf, cs%diag)
935  if (cs%id_Vsurf > 0) call post_data(cs%id_Vsurf, cs%Vsurf, cs%diag)
936 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19

◆ kpp_end()

subroutine, public mom_kpp::kpp_end ( type(kpp_cs), pointer  CS)

Clear pointers, deallocate memory.

Parameters
csControl structure

Definition at line 1062 of file MOM_KPP.F90.

1062  type(kpp_cs), pointer :: cs !< Control structure
1063 
1064  deallocate(cs)

◆ kpp_init()

logical function, public mom_kpp::kpp_init ( type(param_file_type), intent(in)  paramFile,
type(ocean_grid_type), intent(in)  G,
type(diag_ctrl), intent(in), target  diag,
type(time_type), intent(in)  Time,
type(kpp_cs), pointer  CS,
logical, intent(out), optional  passive 
)

Initialize the CVmix KPP module and set up diagnostics Returns True if KPP is to be used, False otherwise.

Parameters
[in]paramfileFile parser
[in]gOcean grid
[in]diagDiagnostics
csControl structure
[out]passiveCopy of passiveMode

Definition at line 133 of file MOM_KPP.F90.

References mom_file_parser::closeparameterblock(), mom_error_handler::mom_error(), nlt_shape_cubic, nlt_shape_cubic_lmd, nlt_shape_cvmix, nlt_shape_linear, nlt_shape_parabolic, mom_file_parser::openparameterblock(), mom_diag_mediator::register_diag_field(), sw_method_all_sw, sw_method_lv1_sw, and sw_method_mxl_sw.

133 
134  ! Arguments
135  type(param_file_type), intent(in) :: paramfile !< File parser
136  type(ocean_grid_type), intent(in) :: g !< Ocean grid
137  type(diag_ctrl), target, intent(in) :: diag !< Diagnostics
138  type(time_type), intent(in) :: time !< Time
139  type(kpp_cs), pointer :: cs !< Control structure
140  logical, optional, intent(out) :: passive !< Copy of %passiveMode
141 
142  ! Local variables
143 #include "version_variable.h"
144  character(len=40) :: mdl = 'MOM_KPP' ! name of this module
145  character(len=20) :: string ! local temporary string
146  logical :: cs_is_one=.false.
147 
148  if (associated(cs)) call mom_error(fatal, 'MOM_KPP, KPP_init: '// &
149  'Control structure has already been initialized')
150  allocate(cs)
151 
152  ! Read parameters
153  call log_version(paramfile, mdl, version, 'This is the MOM wrapper to CVmix:KPP\n' // &
154  'See http://code.google.com/p/cvmix/')
155  call get_param(paramfile, mdl, "USE_KPP", kpp_init, &
156  "If true, turns on the [CVmix] KPP scheme of Large et al., 1994,\n"// &
157  "to calculate diffusivities and non-local transport in the OBL.", &
158  default=.false.)
159  ! Forego remainder of initialization if not using this scheme
160  if (.not. kpp_init) return
161 
162  call openparameterblock(paramfile,'KPP')
163  call get_param(paramfile, mdl, 'PASSIVE', cs%passiveMode, &
164  'If True, puts KPP into a passive-diagnostic mode.', &
165  default=.false.)
166  if (present(passive)) passive=cs%passiveMode ! This is passed back to the caller so
167  ! the caller knows to not use KPP output
168  call get_param(paramfile, mdl, 'APPLY_NONLOCAL_TRANSPORT', cs%applyNonLocalTrans, &
169  'If True, applies the non-local transport to heat and scalars.\n'// &
170  'If False, calculates the non-local transport and tendencies but\n'//&
171  'purely for diagnostic purposes.', &
172  default=.not. cs%passiveMode)
173  call get_param(paramfile, mdl, 'RI_CRIT', cs%Ri_crit, &
174  'Critical bulk Richardson number used to define depth of the\n'// &
175  'surface Ocean Boundary Layer (OBL).', &
176  units='nondim', default=0.3)
177  call get_param(paramfile, mdl, 'VON_KARMAN', cs%vonKarman, &
178  'von Karman constant.', &
179  units='nondim', default=0.40)
180  call get_param(paramfile, mdl, 'ENHANCE_DIFFUSION', cs%enhance_diffusion, &
181  'If True, adds enhanced diffusion at the based of the boundary layer.', &
182  default=.true.)
183  call get_param(paramfile, mdl, 'INTERP_TYPE', cs%interpType, &
184  'Type of interpolation to determine the OBL depth.\n'// &
185  'Allowed types are: linear, quadratic, cubic.', &
186  default='cubic')
187  call get_param(paramfile, mdl, 'COMPUTE_EKMAN', cs%computeEkman, &
188  'If True, limit OBL depth to be no deeper than Ekman depth.', &
189  default=.false.)
190  call get_param(paramfile, mdl, 'COMPUTE_MONIN_OBUKHOV', cs%computeMoninObukhov, &
191  'If True, limit the OBL depth to be no deeper than\n'// &
192  'Monin-Obukhov depth.', &
193  default=.false.)
194  call get_param(paramfile, mdl, 'CS', cs%cs, &
195  'Parameter for computing velocity scale function.', &
196  units='nondim', default=98.96)
197  call get_param(paramfile, mdl, 'CS2', cs%cs2, &
198  'Parameter for computing non-local term.', &
199  units='nondim', default=6.32739901508)
200  call get_param(paramfile, mdl, 'DEEP_OBL_OFFSET', cs%deepOBLoffset, &
201  'If non-zero, the distance above the bottom to which the OBL is clipped\n'// &
202  'if it would otherwise reach the bottom. The smaller of this and 0.1D is used.', &
203  units='m',default=0.)
204  call get_param(paramfile, mdl, 'FIXED_OBLDEPTH', cs%fixedOBLdepth, &
205  'If True, fix the OBL depth to FIXED_OBLDEPTH_VALUE\n'// &
206  'rather than using the OBL depth from CVMix.\n'// &
207  'This option is just for testing purposes.', &
208  default=.false.)
209  call get_param(paramfile, mdl, 'FIXED_OBLDEPTH_VALUE', cs%fixedOBLdepth_value, &
210  'Value for the fixed OBL depth when fixedOBLdepth==True. \n'// &
211  'This parameter is for just for testing purposes. \n'// &
212  'It will over-ride the OBLdepth computed from CVMix.', &
213  units='m',default=30.0)
214  call get_param(paramfile, mdl, 'SURF_LAYER_EXTENT', cs%surf_layer_ext, &
215  'Fraction of OBL depth considered in the surface layer.', &
216  units='nondim',default=0.10)
217  call get_param(paramfile, mdl, 'MINIMUM_OBL_DEPTH', cs%minOBLdepth, &
218  'If non-zero, a minimum depth to use for KPP OBL depth. Independent of\n'// &
219  'this parameter, the OBL depth is always at least as deep as the first layer.', &
220  units='m',default=0.)
221  call get_param(paramfile, mdl, 'MINIMUM_VT2', cs%minVtsqr, &
222  'Min of the unresolved velocity Vt2 used in Rib CVMix calculation. \n'// &
223  'Scaling: MINIMUM_VT2 = const1*d*N*ws, with d=1m, N=1e-5/s, ws=1e-6 m/s.', &
224  units='m2/s2',default=1e-10)
225 
226 ! smg: for removal below
227  call get_param(paramfile, mdl, 'CORRECT_SURFACE_LAYER_AVERAGE', cs%correctSurfLayerAvg, &
228  'If true, applies a correction step to the averaging of surface layer\n'// &
229  'properties. This option is obsolete.', default=.false.)
230  call get_param(paramfile, mdl, 'FIRST_GUESS_SURFACE_LAYER_DEPTH', cs%surfLayerDepth, &
231  'The first guess at the depth of the surface layer used for averaging\n'// &
232  'the surface layer properties. If =0, the top model level properties\n'// &
233  'will be used for the surface layer. If CORRECT_SURFACE_LAYER_AVERAGE=True, a\n'// &
234  'subsequent correction is applied. This parameter is obsolete', units='m', default=0.)
235 ! smg: for removal above
236 
237  call get_param(paramfile, mdl, 'NLT_SHAPE', string, &
238  'MOM6 method to set nonlocal transport profile.\n'// &
239  'Over-rides the result from CVMix. Allowed values are: \n'// &
240  '\t CVMIX - Uses the profiles from CVmix specified by MATCH_TECHNIQUE\n'//&
241  '\t LINEAR - A linear profile, 1-sigma\n'// &
242  '\t PARABOLIC - A parablic profile, (1-sigma)^2\n'// &
243  '\t CUBIC - A cubic profile, (1-sigma)^2(1+2*sigma)\n'// &
244  '\t CUBIC_LMD - The original KPP profile', &
245  default='CVMIX')
246  select case ( trim(string) )
247  case ("CVMIX") ; cs%NLT_shape = nlt_shape_cvmix
248  case ("LINEAR") ; cs%NLT_shape = nlt_shape_linear
249  case ("PARABOLIC") ; cs%NLT_shape = nlt_shape_parabolic
250  case ("CUBIC") ; cs%NLT_shape = nlt_shape_cubic
251  case ("CUBIC_LMD") ; cs%NLT_shape = nlt_shape_cubic_lmd
252  case default ; call mom_error(fatal,"KPP_init: "// &
253  "Unrecognized NLT_SHAPE option"//trim(string))
254  end select
255  call get_param(paramfile, mdl, 'MATCH_TECHNIQUE', cs%MatchTechnique, &
256  'CVMix method to set profile function for diffusivity and NLT,\n'// &
257  'as well as matching across OBL base. Allowed values are: \n'// &
258  '\t SimpleShapes = sigma*(1-sigma)^2 for both diffusivity and NLT\n'// &
259  '\t MatchGradient = sigma*(1-sigma)^2 for NLT; diffusivity profile from matching\n'//&
260  '\t MatchBoth = match gradient for both diffusivity and NLT\n'// &
261  '\t ParabolicNonLocal = sigma*(1-sigma)^2 for diffusivity; (1-sigma)^2 for NLT', &
262  default='SimpleShapes')
263  if (cs%MatchTechnique.eq.'ParabolicNonLocal') then
264  ! This forces Cs2 (Cs in non-local computation) to equal 1 for parabolic non-local option.
265  ! May be used during CVmix initialization.
266  cs_is_one=.true.
267  endif
268  call get_param(paramfile, mdl, 'KPP_ZERO_DIFFUSIVITY', cs%KPPzeroDiffusivity, &
269  'If True, zeroes the KPP diffusivity and viscosity; for testing purpose.',&
270  default=.false.)
271  call get_param(paramfile, mdl, 'KPP_IS_ADDITIVE', cs%KPPisAdditive, &
272  'If true, adds KPP diffusivity to diffusivity from other schemes.'//&
273  'If false, KPP is the only diffusivity wherever KPP is non-zero.', &
274  default=.true.)
275  call get_param(paramfile, mdl, 'KPP_SHORTWAVE_METHOD',string, &
276  'Determines contribution of shortwave radiation to KPP surface '// &
277  'buoyancy flux. Options include:\n'// &
278  ' ALL_SW: use total shortwave radiation\n'// &
279  ' MXL_SW: use shortwave radiation absorbed by mixing layer\n'// &
280  ' LV1_SW: use shortwave radiation absorbed by top model layer', &
281  default='MXL_SW')
282  select case ( trim(string) )
283  case ("ALL_SW") ; cs%SW_METHOD = sw_method_all_sw
284  case ("MXL_SW") ; cs%SW_METHOD = sw_method_mxl_sw
285  case ("LV1_SW") ; cs%SW_METHOD = sw_method_lv1_sw
286  case default ; call mom_error(fatal,"KPP_init: "// &
287  "Unrecognized KPP_SHORTWAVE_METHOD option"//trim(string))
288  end select
289  call get_param(paramfile, mdl, 'CVMIX_ZERO_H_WORK_AROUND', cs%min_thickness, &
290  'A minimum thickness used to avoid division by small numbers in the vicinity\n'// &
291  'of vanished layers. This is independent of MIN_THICKNESS used in other parts of MOM.', &
292  units='m', default=0.)
293 
294  call closeparameterblock(paramfile)
295  call get_param(paramfile, mdl, 'DEBUG', cs%debug, default=.false., do_not_log=.true.)
296 
297  call cvmix_init_kpp( ri_crit=cs%Ri_crit, &
298  minobldepth=cs%minOBLdepth, &
299  minvtsqr=cs%minVtsqr, &
300  vonkarman=cs%vonKarman, &
301  surf_layer_ext=cs%surf_layer_ext, &
302  interp_type=cs%interpType, &
303  lekman=cs%computeEkman, &
304  lmonob=cs%computeMoninObukhov, &
305  matchtechnique=cs%MatchTechnique, &
306  lenhanced_diff=cs%enhance_diffusion,&
307  lnonzero_surf_nonlocal=cs_is_one ,&
308  cvmix_kpp_params_user=cs%KPP_params )
309 
310  ! Register diagnostics
311  cs%diag => diag
312  cs%id_OBLdepth = register_diag_field('ocean_model', 'KPP_OBLdepth', diag%axesT1, time, &
313  'Thickness of the surface Ocean Boundary Layer calculated by [CVmix] KPP', 'meter', &
314  cmor_field_name='oml', cmor_long_name='ocean_mixed_layer_thickness_defined_by_mixing_scheme', &
315  cmor_units='m', cmor_standard_name='Ocean Mixed Layer Thickness Defined by Mixing Scheme')
316  ! CMOR names are placeholders; must be modified by time period
317  ! for CMOR compliance. Diag manager will be used for omlmax and
318  ! omldamax.
319  cs%id_BulkDrho = register_diag_field('ocean_model', 'KPP_BulkDrho', diag%axesTL, time, &
320  'Bulk difference in density used in Bulk Richardson number, as used by [CVmix] KPP', 'kg/m3')
321  cs%id_BulkUz2 = register_diag_field('ocean_model', 'KPP_BulkUz2', diag%axesTL, time, &
322  'Square of bulk difference in resolved velocity used in Bulk Richardson number via [CVmix] KPP', 'm2/s2')
323  cs%id_BulkRi = register_diag_field('ocean_model', 'KPP_BulkRi', diag%axesTL, time, &
324  'Bulk Richardson number used to find the OBL depth used by [CVmix] KPP', 'nondim')
325  cs%id_Sigma = register_diag_field('ocean_model', 'KPP_sigma', diag%axesTi, time, &
326  'Sigma coordinate used by [CVmix] KPP', 'nondim')
327  cs%id_Ws = register_diag_field('ocean_model', 'KPP_Ws', diag%axesTL, time, &
328  'Turbulent vertical velocity scale for scalars used by [CVmix] KPP', 'm/s')
329  cs%id_N = register_diag_field('ocean_model', 'KPP_N', diag%axesTi, time, &
330  '(Adjusted) Brunt-Vaisala frequency used by [CVmix] KPP', '1/s')
331  cs%id_N2 = register_diag_field('ocean_model', 'KPP_N2', diag%axesTi, time, &
332  'Square of Brunt-Vaisala frequency used by [CVmix] KPP', '1/s2')
333  cs%id_Vt2 = register_diag_field('ocean_model', 'KPP_Vt2', diag%axesTL, time, &
334  'Unresolved shear turbulence used by [CVmix] KPP', 'm2/s2')
335  cs%id_uStar = register_diag_field('ocean_model', 'KPP_uStar', diag%axesT1, time, &
336  'Friction velocity, u*, as used by [CVmix] KPP', 'm/s')
337  cs%id_buoyFlux = register_diag_field('ocean_model', 'KPP_buoyFlux', diag%axesTi, time, &
338  'Surface (and penetrating) buoyancy flux, as used by [CVmix] KPP', 'm2/s3')
339  cs%id_QminusSW = register_diag_field('ocean_model', 'KPP_QminusSW', diag%axesT1, time, &
340  'Net temperature flux ignoring short-wave, as used by [CVmix] KPP', 'K m/s')
341  cs%id_netS = register_diag_field('ocean_model', 'KPP_netSalt', diag%axesT1, time, &
342  'Effective net surface salt flux, as used by [CVmix] KPP', 'ppt m/s')
343  cs%id_Kt_KPP = register_diag_field('ocean_model', 'KPP_Kheat', diag%axesTi, time, &
344  'Heat diffusivity due to KPP, as calculated by [CVmix] KPP', 'm2/s')
345  cs%id_Kd_in = register_diag_field('ocean_model', 'KPP_Kd_in', diag%axesTi, time, &
346  'Diffusivity passed to KPP', 'm2/s')
347  cs%id_Ks_KPP = register_diag_field('ocean_model', 'KPP_Ksalt', diag%axesTi, time, &
348  'Salt diffusivity due to KPP, as calculated by [CVmix] KPP', 'm2/s')
349  cs%id_Kv_KPP = register_diag_field('ocean_model', 'KPP_Kv', diag%axesTi, time, &
350  'Vertical viscosity due to KPP, as calculated by [CVmix] KPP', 'm2/s')
351  cs%id_NLTt = register_diag_field('ocean_model', 'KPP_NLtransport_heat', diag%axesTi, time, &
352  'Non-local transport (Cs*G(sigma)) for heat, as calculated by [CVmix] KPP', 'nondim')
353  cs%id_NLTs = register_diag_field('ocean_model', 'KPP_NLtransport_salt', diag%axesTi, time, &
354  'Non-local tranpsort (Cs*G(sigma)) for scalars, as calculated by [CVmix] KPP', 'nondim')
355  cs%id_NLT_dTdt = register_diag_field('ocean_model', 'KPP_NLT_dTdt', diag%axesTL, time, &
356  'Temperature tendency due to non-local transport of heat, as calculated by [CVmix] KPP', 'K/s')
357  cs%id_NLT_dSdt = register_diag_field('ocean_model', 'KPP_NLT_dSdt', diag%axesTL, time, &
358  'Salinity tendency due to non-local transport of salt, as calculated by [CVmix] KPP', 'ppt/s')
359  cs%id_NLT_temp_budget = register_diag_field('ocean_model', 'KPP_NLT_temp_budget', diag%axesTL, time, &
360  'Heat content change due to non-local transport, as calculated by [CVmix] KPP', 'W/m^2')
361  cs%id_NLT_saln_budget = register_diag_field('ocean_model', 'KPP_NLT_saln_budget', diag%axesTL, time, &
362  'Salt content change due to non-local transport, as calculated by [CVmix] KPP', 'kg/(sec*m^2)')
363  cs%id_Tsurf = register_diag_field('ocean_model', 'KPP_Tsurf', diag%axesT1, time, &
364  'Temperature of surface layer (10% of OBL depth) as passed to [CVmix] KPP', 'C')
365  cs%id_Ssurf = register_diag_field('ocean_model', 'KPP_Ssurf', diag%axesT1, time, &
366  'Salinity of surface layer (10% of OBL depth) as passed to [CVmix] KPP', 'ppt')
367  cs%id_Usurf = register_diag_field('ocean_model', 'KPP_Usurf', diag%axesCu1, time, &
368  'i-component flow of surface layer (10% of OBL depth) as passed to [CVmix] KPP', 'm/s')
369  cs%id_Vsurf = register_diag_field('ocean_model', 'KPP_Vsurf', diag%axesCv1, time, &
370  'j-component flow of surface layer (10% of OBL depth) as passed to [CVmix] KPP', 'm/s')
371 
372  if (cs%id_OBLdepth > 0) allocate( cs%OBLdepth( szi_(g), szj_(g) ) )
373  if (cs%id_OBLdepth > 0) cs%OBLdepth(:,:) = 0.
374  if (cs%id_BulkDrho > 0) allocate( cs%dRho( szi_(g), szj_(g), szk_(g) ) )
375  if (cs%id_BulkDrho > 0) cs%dRho(:,:,:) = 0.
376  if (cs%id_BulkUz2 > 0) allocate( cs%Uz2( szi_(g), szj_(g), szk_(g) ) )
377  if (cs%id_BulkUz2 > 0) cs%Uz2(:,:,:) = 0.
378  if (cs%id_BulkRi > 0) allocate( cs%BulkRi( szi_(g), szj_(g), szk_(g) ) )
379  if (cs%id_BulkRi > 0) cs%BulkRi(:,:,:) = 0.
380  if (cs%id_Sigma > 0) allocate( cs%sigma( szi_(g), szj_(g), szk_(g)+1 ) )
381  if (cs%id_Sigma > 0) cs%sigma(:,:,:) = 0.
382  if (cs%id_Ws > 0) allocate( cs%Ws( szi_(g), szj_(g), szk_(g) ) )
383  if (cs%id_Ws > 0) cs%Ws(:,:,:) = 0.
384  if (cs%id_N > 0) allocate( cs%N( szi_(g), szj_(g), szk_(g)+1 ) )
385  if (cs%id_N > 0) cs%N(:,:,:) = 0.
386  if (cs%id_N2 > 0) allocate( cs%N2( szi_(g), szj_(g), szk_(g)+1 ) )
387  if (cs%id_N2 > 0) cs%N2(:,:,:) = 0.
388  if (cs%id_Vt2 > 0) allocate( cs%Vt2( szi_(g), szj_(g), szk_(g) ) )
389  if (cs%id_Vt2 > 0) cs%Vt2(:,:,:) = 0.
390  if (cs%id_Kt_KPP > 0) allocate( cs%Kt_KPP( szi_(g), szj_(g), szk_(g)+1 ) )
391  if (cs%id_Kt_KPP > 0) cs%Kt_KPP(:,:,:) = 0.
392  if (cs%id_Ks_KPP > 0) allocate( cs%Ks_KPP( szi_(g), szj_(g), szk_(g)+1 ) )
393  if (cs%id_Ks_KPP > 0) cs%Ks_KPP(:,:,:) = 0.
394  if (cs%id_Kv_KPP > 0) allocate( cs%Kv_KPP( szi_(g), szj_(g), szk_(g)+1 ) )
395  if (cs%id_Kv_KPP > 0) cs%Kv_KPP(:,:,:) = 0.
396  if (cs%id_Tsurf > 0) allocate( cs%Tsurf( szi_(g), szj_(g)) )
397  if (cs%id_Tsurf > 0) cs%Tsurf(:,:) = 0.
398  if (cs%id_Ssurf > 0) allocate( cs%Ssurf( szi_(g), szj_(g)) )
399  if (cs%id_Ssurf > 0) cs%Ssurf(:,:) = 0.
400  if (cs%id_Usurf > 0) allocate( cs%Usurf( szib_(g), szj_(g)) )
401  if (cs%id_Usurf > 0) cs%Usurf(:,:) = 0.
402  if (cs%id_Vsurf > 0) allocate( cs%Vsurf( szi_(g), szjb_(g)) )
403  if (cs%id_Vsurf > 0) cs%Vsurf(:,:) = 0.
404 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:

◆ kpp_nonlocaltransport_saln()

subroutine, public mom_kpp::kpp_nonlocaltransport_saln ( type(kpp_cs), intent(in)  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(in)  nonLocalTrans,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(in)  surfFlux,
real, intent(in)  dt,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(inout)  scalar 
)

Apply KPP non-local transport of surface fluxes for salinity. This routine is a useful prototype for other material tracers.

Parameters
[in]csControl structure
[in]gOcean grid
[in]gvOcean vertical grid
[in]hLayer/level thickness (units of H)
[in]nonlocaltransNon-local transport (non-dimensional)
[in]surffluxSurface flux of scalar (H/s * scalar)
[in]dtTime-step (s)
[in,out]scalarScalar (scalar units)

Definition at line 1003 of file MOM_KPP.F90.

Referenced by mom_diabatic_driver::diabatic().

1003 
1004  type(kpp_cs), intent(in) :: cs !< Control structure
1005  type(ocean_grid_type), intent(in) :: g !< Ocean grid
1006  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid
1007  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thickness (units of H)
1008  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: nonlocaltrans !< Non-local transport (non-dimensional)
1009  real, dimension(SZI_(G),SZJ_(G)), intent(in) :: surfflux !< Surface flux of scalar (H/s * scalar)
1010  real, intent(in) :: dt !< Time-step (s)
1011  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: scalar !< Scalar (scalar units)
1012 
1013  integer :: i, j, k
1014  real, dimension( SZI_(G), SZJ_(G), SZK_(G) ) :: dtracer
1015 
1016 
1017  dtracer(:,:,:) = 0.0
1018 !$OMP parallel do default(none) shared(G,GV,dtracer,nonLocalTrans,h,surfFlux,CS,scalar,dt)
1019  do k = 1, g%ke
1020  do j = g%jsc, g%jec
1021  do i = g%isc, g%iec
1022  dtracer(i,j,k) = ( nonlocaltrans(i,j,k) - nonlocaltrans(i,j,k+1) ) / &
1023  ( h(i,j,k) + gv%H_subroundoff ) * surfflux(i,j)
1024  enddo
1025  enddo
1026  enddo
1027 
1028  ! Update tracer due to non-local redistribution of surface flux
1029  if (cs%applyNonLocalTrans) then
1030  do k = 1, g%ke
1031  do j = g%jsc, g%jec
1032  do i = g%isc, g%iec
1033  scalar(i,j,k) = scalar(i,j,k) + dt * dtracer(i,j,k)
1034  enddo
1035  enddo
1036  enddo
1037  endif
1038 
1039  ! Diagnostics
1040  if (cs%id_netS > 0) call post_data(cs%id_netS, surfflux, cs%diag)
1041  if (cs%id_NLT_dSdt > 0) call post_data(cs%id_NLT_dSdt, dtracer, cs%diag)
1042  if (cs%id_NLT_saln_budget > 0) then
1043  dtracer(:,:,:) = 0.0
1044  do k = 1, g%ke
1045  do j = g%jsc, g%jec
1046  do i = g%isc, g%iec
1047  dtracer(i,j,k) = (nonlocaltrans(i,j,k) - nonlocaltrans(i,j,k+1)) * &
1048  surfflux(i,j) * gv%H_to_kg_m2
1049  enddo
1050  enddo
1051  enddo
1052  call post_data(cs%id_NLT_saln_budget, dtracer, cs%diag)
1053  endif
1054 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the caller graph for this function:

◆ kpp_nonlocaltransport_temp()

subroutine, public mom_kpp::kpp_nonlocaltransport_temp ( type(kpp_cs), intent(in)  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(in)  nonLocalTrans,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(in)  surfFlux,
real, intent(in)  dt,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(inout)  scalar,
real, intent(in)  C_p 
)

Apply KPP non-local transport of surface fluxes for temperature.

Parameters
[in]csControl structure
[in]gOcean grid
[in]gvOcean vertical grid
[in]hLayer/level thickness (units of H)
[in]nonlocaltransNon-local transport (non-dimensional)
[in]surffluxSurface flux of scalar (H/s * scalar)
[in]dtTime-step (s)
[in,out]scalartemperature
[in]c_pSeawater specific heat capacity (J/(kg*K))

Definition at line 944 of file MOM_KPP.F90.

Referenced by mom_diabatic_driver::diabatic().

944 
945  type(kpp_cs), intent(in) :: cs !< Control structure
946  type(ocean_grid_type), intent(in) :: g !< Ocean grid
947  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid
948  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thickness (units of H)
949  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: nonlocaltrans !< Non-local transport (non-dimensional)
950  real, dimension(SZI_(G),SZJ_(G)), intent(in) :: surfflux !< Surface flux of scalar (H/s * scalar)
951  real, intent(in) :: dt !< Time-step (s)
952  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: scalar !< temperature
953  real, intent(in) :: c_p !< Seawater specific heat capacity (J/(kg*K))
954 
955  integer :: i, j, k
956  real, dimension( SZI_(G), SZJ_(G), SZK_(G) ) :: dtracer
957 
958 
959  dtracer(:,:,:) = 0.0
960 !$OMP parallel do default(none) shared(G,GV,dtracer,nonLocalTrans,h,surfFlux,CS,scalar,dt)
961  do k = 1, g%ke
962  do j = g%jsc, g%jec
963  do i = g%isc, g%iec
964  dtracer(i,j,k) = ( nonlocaltrans(i,j,k) - nonlocaltrans(i,j,k+1) ) / &
965  ( h(i,j,k) + gv%H_subroundoff ) * surfflux(i,j)
966  enddo
967  enddo
968  enddo
969 
970  ! Update tracer due to non-local redistribution of surface flux
971  if (cs%applyNonLocalTrans) then
972  do k = 1, g%ke
973  do j = g%jsc, g%jec
974  do i = g%isc, g%iec
975  scalar(i,j,k) = scalar(i,j,k) + dt * dtracer(i,j,k)
976  enddo
977  enddo
978  enddo
979  endif
980 
981  ! Diagnostics
982  if (cs%id_QminusSW > 0) call post_data(cs%id_QminusSW, surfflux, cs%diag)
983  if (cs%id_NLT_dTdt > 0) call post_data(cs%id_NLT_dTdt, dtracer, cs%diag)
984  if (cs%id_NLT_temp_budget > 0) then
985  dtracer(:,:,:) = 0.0
986  do k = 1, g%ke
987  do j = g%jsc, g%jec
988  do i = g%isc, g%iec
989  dtracer(i,j,k) = (nonlocaltrans(i,j,k) - nonlocaltrans(i,j,k+1)) * &
990  surfflux(i,j) * c_p * gv%H_to_kg_m2
991  enddo
992  enddo
993  enddo
994  call post_data(cs%id_NLT_temp_budget, dtracer, cs%diag)
995  endif
996 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the caller graph for this function:

Variable Documentation

◆ nlt_shape_cubic

integer, parameter, private mom_kpp::nlt_shape_cubic = 3
private

Cubic, \( G(\sigma) = 1 + (2\sigma-3) \sigma^2\).

Definition at line 40 of file MOM_KPP.F90.

Referenced by kpp_calculate(), and kpp_init().

40 integer, private, parameter :: nlt_shape_cubic = 3 !< Cubic, \f$ G(\sigma) = 1 + (2\sigma-3) \sigma^2\f$

◆ nlt_shape_cubic_lmd

integer, parameter, private mom_kpp::nlt_shape_cubic_lmd = 4
private

Original shape, \( G(\sigma) = \frac{27}{4} \sigma (1-\sigma)^2 \).

Definition at line 41 of file MOM_KPP.F90.

Referenced by kpp_calculate(), and kpp_init().

41 integer, private, parameter :: nlt_shape_cubic_lmd = 4 !< Original shape, \f$ G(\sigma) = \frac{27}{4} \sigma (1-\sigma)^2 \f$

◆ nlt_shape_cvmix

integer, parameter, private mom_kpp::nlt_shape_cvmix = 0
private

Use the CVmix profile.

Definition at line 37 of file MOM_KPP.F90.

Referenced by kpp_init().

37 integer, private, parameter :: nlt_shape_cvmix = 0 !< Use the CVmix profile

◆ nlt_shape_linear

integer, parameter, private mom_kpp::nlt_shape_linear = 1
private

Linear, \( G(\sigma) = 1-\sigma \).

Definition at line 38 of file MOM_KPP.F90.

Referenced by kpp_calculate(), and kpp_init().

38 integer, private, parameter :: nlt_shape_linear = 1 !< Linear, \f$ G(\sigma) = 1-\sigma \f$

◆ nlt_shape_parabolic

integer, parameter, private mom_kpp::nlt_shape_parabolic = 2
private

Parabolic, \( G(\sigma) = (1-\sigma)^2 \).

Definition at line 39 of file MOM_KPP.F90.

Referenced by kpp_calculate(), and kpp_init().

39 integer, private, parameter :: nlt_shape_parabolic = 2 !< Parabolic, \f$ G(\sigma) = (1-\sigma)^2 \f$

◆ sw_method_all_sw

integer, parameter, private mom_kpp::sw_method_all_sw = 0
private

Use all shortwave radiation.

Definition at line 43 of file MOM_KPP.F90.

Referenced by kpp_calculate(), and kpp_init().

43 integer, private, parameter :: sw_method_all_sw = 0 !< Use all shortwave radiation

◆ sw_method_lv1_sw

integer, parameter, private mom_kpp::sw_method_lv1_sw = 2
private

Use shortwave radiation absorbed in layer 1.

Definition at line 45 of file MOM_KPP.F90.

Referenced by kpp_calculate(), and kpp_init().

45 integer, private, parameter :: sw_method_lv1_sw = 2 !< Use shortwave radiation absorbed in layer 1

◆ sw_method_mxl_sw

integer, parameter, private mom_kpp::sw_method_mxl_sw = 1
private

Use shortwave radiation absorbed in mixing layer.

Definition at line 44 of file MOM_KPP.F90.

Referenced by kpp_calculate(), and kpp_init().

44 integer, private, parameter :: sw_method_mxl_sw = 1 !< Use shortwave radiation absorbed in mixing layer

◆ verbose

logical, parameter mom_kpp::verbose = .False.

Definition at line 125 of file MOM_KPP.F90.

125 logical, parameter :: verbose = .false.