86 implicit none ; 
private    88 #include <MOM_memory.h>    94   real, 
dimension(:,:,:), 
pointer :: p => null()
    97   real, 
dimension(:,:), 
pointer :: p => null()
   101   logical :: bulkmixedlayer  
   104   integer :: isc, iec, jsc, jec  
   105   integer :: isd, ied, jsd, jed  
   110   integer, 
pointer :: col_i(:) => null()  
   111   integer, 
pointer :: col_j(:) => null()  
   112   real, 
pointer :: iresttime_col(:) => null()  
   114   real, 
pointer :: rcv_ml_ref(:) => null() 
   116   real, 
pointer :: ref_eta(:,:) => null() 
   118   type(
p3d) :: var(max_fields_)  
   119   type(
p2d) :: ref_val(max_fields_)  
   121   logical :: do_i_mean_sponge     
   122   real, 
pointer :: iresttime_im(:) => null()  
   124   real, 
pointer :: rcv_ml_ref_im(:) => null() 
   127   real, 
pointer :: ref_eta_im(:,:) => null() 
   129   type(
p2d) :: ref_val_im(max_fields_)  
   134   integer :: id_w_sponge = -1
   141                              Iresttime_i_mean, int_height_i_mean)
   143   real, 
dimension(SZI_(G),SZJ_(G)),       
intent(in) :: Iresttime
   144   real, 
dimension(SZI_(G),SZJ_(G),SZK_(G)+1), 
intent(in) :: int_height
   147   real, 
dimension(SZJ_(G)),     
optional, 
intent(in) :: Iresttime_i_mean
   148   real, 
dimension(SZJ_(G),SZK_(G)+1), 
optional, 
intent(in) :: int_height_i_mean
   164 #include "version_variable.h"   165   character(len=40)  :: mdl = 
"MOM_sponge"     166   logical :: use_sponge
   167   integer :: i, j, k, col, total_sponge_cols
   169   if (
associated(cs)) 
then   170     call mom_error(warning, 
"initialize_sponge called with an associated "// &
   171                             "control structure.")
   177   call get_param(param_file, mdl, 
"SPONGE", use_sponge, &
   178                  "If true, sponges may be applied anywhere in the domain. \n"//&
   179                  "The exact location and properties of those sponges are \n"//&
   180                  "specified from MOM_initialization.F90.", default=.false.)
   182   if (.not.use_sponge) 
return   185   if (
present(iresttime_i_mean) .neqv. 
present(int_height_i_mean)) &
   186     call mom_error(fatal, 
"initialize_sponge:  The optional arguments \n"//&
   187            "Iresttime_i_mean and int_height_i_mean must both be present \n"//&
   190   cs%do_i_mean_sponge = 
present(iresttime_i_mean)
   193   cs%isc = g%isc ; cs%iec = g%iec ; cs%jsc = g%jsc ; cs%jec = g%jec
   194   cs%isd = g%isd ; cs%ied = g%ied ; cs%jsd = g%jsd ; cs%jed = g%jed
   196   cs%bulkmixedlayer = .false.
   198   cs%num_col = 0 ; cs%fldno = 0
   199   do j=g%jsc,g%jec ; 
do i=g%isc,g%iec
   200     if ((iresttime(i,j)>0.0) .and. (g%mask2dT(i,j)>0)) &
   201       cs%num_col = cs%num_col + 1
   204   if (cs%num_col > 0) 
then   206     allocate(cs%Iresttime_col(cs%num_col)) ; cs%Iresttime_col = 0.0
   207     allocate(cs%col_i(cs%num_col))         ; cs%col_i = 0
   208     allocate(cs%col_j(cs%num_col))         ; cs%col_j = 0
   211     do j=g%jsc,g%jec ; 
do i=g%isc,g%iec
   212       if ((iresttime(i,j)>0.0) .and. (g%mask2dT(i,j)>0)) 
then   213         cs%col_i(col) = i ; cs%col_j(col) = j
   214         cs%Iresttime_col(col) = iresttime(i,j)
   219     allocate(cs%Ref_eta(cs%nz+1,cs%num_col))
   220     do col=1,cs%num_col ; 
do k=1,cs%nz+1
   221       cs%Ref_eta(k,col) = int_height(cs%col_i(col),cs%col_j(col),k)
   226   if (cs%do_i_mean_sponge) 
then   227     allocate(cs%Iresttime_im(g%jsd:g%jed)) ; cs%Iresttime_im(:) = 0.0
   228     allocate(cs%Ref_eta_im(g%jsd:g%jed,g%ke+1)) ; cs%Ref_eta_im(:,:) = 0.0
   231       cs%Iresttime_im(j) = iresttime_i_mean(j)
   233     do k=1,cs%nz+1 ; 
do j=g%jsc,g%jec
   234       cs%Ref_eta_im(j,k) = int_height_i_mean(j,k)
   238   total_sponge_cols = cs%num_col
   239   call sum_across_pes(total_sponge_cols)
   241   call log_param(param_file, mdl, 
"!Total sponge columns", total_sponge_cols, &
   242                  "The total number of columns where sponges are applied.")
   247   type(time_type),       
target, 
intent(in)    :: Time
   249   type(
diag_ctrl),       
target, 
intent(inout) :: diag
   262   if (.not.
associated(cs)) 
return   265   cs%id_w_sponge = register_diag_field(
'ocean_model', 
'w_sponge', diag%axesTi, &
   266       time, 
'The diapycnal motion due to the sponges', 
'meter second-1')
   272   real, 
dimension(SZI_(G),SZJ_(G),SZK_(G)),         
intent(in) :: sp_val
   273   real, 
dimension(SZI_(G),SZJ_(G),SZK_(G)), 
target, 
intent(in) :: f_ptr
   274   integer,                                          
intent(in) :: nlay
   276   real, 
dimension(SZJ_(G),SZK_(G)),       
optional, 
intent(in) :: sp_val_i_mean
   291   character(len=256) :: mesg 
   293   if (.not.
associated(cs)) 
return   295   cs%fldno = cs%fldno + 1
   297   if (cs%fldno > max_fields_) 
then   298     write(mesg,
'("Increase MAX_FIELDS_ to at least ",I3," in MOM_memory.h or decrease &   299            &the number of fields to be damped in the call to &   300            &initialize_sponge." )') cs%fldno
   301     call mom_error(fatal,
"set_up_sponge_field: "//mesg)
   304   allocate(cs%Ref_val(cs%fldno)%p(cs%nz,cs%num_col))
   305   cs%Ref_val(cs%fldno)%p(:,:) = 0.0
   308       cs%Ref_val(cs%fldno)%p(k,col) = sp_val(cs%col_i(col),cs%col_j(col),k)
   311       cs%Ref_val(cs%fldno)%p(k,col) = 0.0
   315   cs%var(cs%fldno)%p => f_ptr
   317   if (nlay/=cs%nz) 
then   318     write(mesg,
'("Danger: Sponge reference fields require nz (",I3,") layers.&   319         & A field with ",I3," layers was passed to set_up_sponge_field.")') &
   324   if (cs%do_i_mean_sponge) 
then   325     if (.not.
present(sp_val_i_mean)) 
call mom_error(fatal, &
   326       "set_up_sponge_field: sp_val_i_mean must be present with i-mean sponges.")
   328     allocate(cs%Ref_val_im(cs%fldno)%p(cs%jsd:cs%jed,cs%nz))
   329     cs%Ref_val(cs%fldno)%p(:,:) = 0.0
   330     do k=1,cs%nz ; 
do j=cs%jsc,cs%jec
   331       cs%Ref_val_im(cs%fldno)%p(j,k) = sp_val_i_mean(j,k)
   340   real, 
dimension(SZI_(G),SZJ_(G)),   
intent(in) :: sp_val
   342   real, 
dimension(SZJ_(G)), 
optional, 
intent(in) :: sp_val_i_mean
   352   character(len=256) :: mesg 
   354   if (.not.
associated(cs)) 
return   356   if (
associated(cs%Rcv_ml_ref)) 
then   357     call mom_error(fatal, 
"set_up_sponge_ML_density appears to have been "//&
   361   cs%bulkmixedlayer = .true.
   362   allocate(cs%Rcv_ml_ref(cs%num_col)) ; cs%Rcv_ml_ref(:) = 0.0
   364     cs%Rcv_ml_ref(col) = sp_val(cs%col_i(col),cs%col_j(col))
   367   if (cs%do_i_mean_sponge) 
then   368     if (.not.
present(sp_val_i_mean)) 
call mom_error(fatal, &
   369       "set_up_sponge_field: sp_val_i_mean must be present with i-mean sponges.")
   371     allocate(cs%Rcv_ml_ref_im(cs%jsd:cs%jed)) ; cs%Rcv_ml_ref_im(:) = 0.0
   373       cs%Rcv_ml_ref_im(j) = sp_val_i_mean(j)
   379 subroutine apply_sponge(h, dt, G, GV, ea, eb, CS, Rcv_ml)
   382   real, 
dimension(SZI_(G),SZJ_(G),SZK_(G)), 
intent(inout) :: h
   383   real,                                     
intent(in)    :: dt
   384   real, 
dimension(SZI_(G),SZJ_(G),SZK_(G)), 
intent(out)   :: ea
   385   real, 
dimension(SZI_(G),SZJ_(G),SZK_(G)), 
intent(out)   :: eb
   387   real, 
dimension(SZI_(G),SZJ_(G)), 
optional, 
intent(inout) :: Rcv_ml
   407   real, 
dimension(SZI_(G), SZJ_(G), SZK_(G)+1) :: &
   412   real, 
dimension(SZI_(G), SZJ_(G)) :: &
   417   real, 
dimension(SZJ_(G), SZK_(G)+1) :: &
   419   real, 
allocatable, 
dimension(:,:,:) :: &
   421   real, 
dimension(SZI_(G), SZK_(G)+1) :: &
   424   real, 
dimension(SZI_(G)) :: &
   443   integer :: c, m, nkmb, i, j, k, is, ie, js, je, nz
   444   is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
   446   if (.not.
associated(cs)) 
return   447   if (cs%bulkmixedlayer) nkmb = gv%nk_rho_varies
   448   if (cs%bulkmixedlayer .and. (.not.
present(rcv_ml))) &
   449     call mom_error(fatal, 
"Rml must be provided to apply_sponge when using "//&
   450                            "a bulk mixed layer.")
   452   if ((cs%id_w_sponge > 0) .or. cs%do_i_mean_sponge) 
then   453     do k=1,nz+1 ; 
do j=js,je ; 
do i=is,ie
   455     enddo ;
 enddo ;
 enddo   458   if (cs%do_i_mean_sponge) 
then   461     if (cs%bulkmixedlayer) 
call mom_error(fatal, 
"apply_sponge is not yet set up to "//&
   462                   "work properly with i-mean sponges and a bulk mixed layer.")
   464     do j=js,je ; 
do i=is,ie ; e_d(i,j,nz+1) = -g%bathyT(i,j) ;
 enddo ;
 enddo   465     do k=nz,1,-1 ; 
do j=js,je ; 
do i=is,ie
   466       e_d(i,j,k) = e_d(i,j,k+1) + h(i,j,k)
   467     enddo ;
 enddo ;
 enddo   470         dilate(i) = g%bathyT(i,j) / (e_d(i,j,1) + g%bathyT(i,j))
   472       do k=1,nz+1 ; 
do i=is,ie
   473         e_d(i,j,k) = dilate(i) * (e_d(i,j,k) + g%bathyT(i,j)) - g%bathyT(i,j)
   478       do j=js,je ; 
do i=is,ie
   479         eta_anom(i,j) = e_d(i,j,k) - cs%Ref_eta_im(j,k)
   480         if (cs%Ref_eta_im(j,k) < -g%bathyT(i,j)) eta_anom(i,j) = 0.0
   485     if (cs%fldno > 0) 
allocate(fld_mean_anom(g%isd:g%ied,nz,cs%fldno))
   487       do j=js,je ; 
do i=is,ie
   488         fld_anom(i,j) = cs%var(m)%p(i,j,k) - cs%Ref_val_im(m)%p(j,k)
   490       call global_i_mean(fld_anom(:,:), fld_mean_anom(:,k,m), g, h(:,:,k))
   493     do j=js,je ; 
if (cs%Iresttime_im(j) > 0.0) 
then   494       damp = dt*cs%Iresttime_im(j) ; damp_1pdamp = damp / (1.0 + damp)
   497         h_above(i,1) = 0.0 ; h_below(i,nz+1) = 0.0
   499       do k=nz,1,-1 ; 
do i=is,ie
   500         h_below(i,k) = h_below(i,k+1) + max(h(i,j,k)-gv%Angstrom, 0.0)
   502       do k=2,nz+1 ; 
do i=is,ie
   503         h_above(i,k) = h_above(i,k-1) + max(h(i,j,k-1)-gv%Angstrom, 0.0)
   508         w = damp_1pdamp * eta_mean_anom(j,k)
   511             w_int(i,j,k) = min(w, h_below(i,k))
   512             eb(i,j,k-1) = eb(i,j,k-1) + w_int(i,j,k)
   514             w_int(i,j,k) = max(w, -h_above(i,k))
   515             ea(i,j,k) = ea(i,j,k) - w_int(i,j,k)
   519       do k=1,nz ; 
do i=is,ie
   520         ea_k = max(0.0, -w_int(i,j,k))
   521         eb_k = max(0.0, w_int(i,j,k+1))
   523           cs%var(m)%p(i,j,k) = (h(i,j,k)*cs%var(m)%p(i,j,k) + &
   524               cs%Ref_val_im(m)%p(j,k) * (ea_k + eb_k)) / &
   525                      (h(i,j,k) + (ea_k + eb_k)) - &
   526               damp_1pdamp * fld_mean_anom(j,k,m)
   529         h(i,j,k) = max(h(i,j,k) + (w_int(i,j,k+1) - w_int(i,j,k)), &
   530                        min(h(i,j,k), gv%Angstrom))
   534     if (cs%fldno > 0) 
deallocate(fld_mean_anom)
   541     i = cs%col_i(c) ; j = cs%col_j(c)
   542     damp = dt*cs%Iresttime_col(c)
   544     e(1) = 0.0 ; e0 = 0.0
   546       e(k+1) = e(k) - h(i,j,k)
   548     e_str = e(nz+1) / cs%Ref_eta(nz+1,c)
   550     if ( cs%bulkmixedlayer ) 
then   551       i1pdamp = 1.0 / (1.0 + damp)
   552       if (
associated(cs%Rcv_ml_ref)) &
   553         rcv_ml(i,j) = i1pdamp * (rcv_ml(i,j) + cs%Rcv_ml_ref(c)*damp)
   556           cs%var(m)%p(i,j,k) = i1pdamp * &
   557               (cs%var(m)%p(i,j,k) + cs%Ref_val(m)%p(k,c)*damp)
   563         if (gv%Rlay(k) > rcv_ml(i,j)) 
then   564           w = min((((e(k)-e0) - e_str*cs%Ref_eta(k,c)) * damp), &
   565                     ((wb + h(i,j,k)) - gv%Angstrom))
   568             cs%var(m)%p(i,j,k) = (h(i,j,k)*cs%var(m)%p(i,j,k) + &
   569                      cs%Ref_val(m)%p(k,c)*(damp*h(i,j,k) + (wpb - wm))) / &
   570                      (h(i,j,k)*(1.0 + damp) + (wpb - wm))
   574             cs%var(m)%p(i,j,k) = i1pdamp * &
   575               (cs%var(m)%p(i,j,k) + cs%Ref_val(m)%p(k,c)*damp)
   577           w = wb + (h(i,j,k) - gv%Angstrom)
   580         eb(i,j,k) = eb(i,j,k) + wpb
   581         ea(i,j,k) = ea(i,j,k) - wm
   582         h(i,j,k)  = h(i,j,k)  + (wb - w)
   589           w = min((wb + (h(i,j,k) - gv%Angstrom)),0.0)
   590           h(i,j,k)  = h(i,j,k)  + (wb - w)
   591           ea(i,j,k) = ea(i,j,k) - w
   597           eb(i,j,k) = eb(i,j,k) + w
   601         h(i,j,k) = h(i,j,k) + w
   603           cs%var(m)%p(i,j,k) = (cs%var(m)%p(i,j,k)*h(i,j,k) + &
   604                                 cs%Ref_val(m)%p(k,c)*w) / (h(i,j,k) + w)
   610           cs%var(m)%p(i,j,k) = i1pdamp * &
   611               (cs%var(m)%p(i,j,k) + cs%Ref_val(m)%p(gv%nkml,c)*damp)
   620         w = min((((e(k)-e0) - e_str*cs%Ref_eta(k,c)) * damp), &
   621                   ((wb + h(i,j,k)) - gv%Angstrom))
   622         wm = 0.5*(w - abs(w))
   624           cs%var(m)%p(i,j,k) = (h(i,j,k)*cs%var(m)%p(i,j,k) + &
   625               cs%Ref_val(m)%p(k,c) * (damp*h(i,j,k) + (wpb - wm))) / &
   626                      (h(i,j,k)*(1.0 + damp) + (wpb - wm))
   628         eb(i,j,k) = eb(i,j,k) + wpb
   629         ea(i,j,k) = ea(i,j,k) - wm
   630         h(i,j,k)  = h(i,j,k)  + (wb - w)
   638   if (
associated(cs%diag)) 
then ; 
if (query_averaging_enabled(cs%diag)) 
then   640     if (cs%id_w_sponge > 0) 
call post_data(cs%id_w_sponge, idt*w_int, cs%diag)
   651   if (.not.
associated(cs)) 
return   653   if (
associated(cs%col_i)) 
deallocate(cs%col_i)
   654   if (
associated(cs%col_j)) 
deallocate(cs%col_j)
   656   if (
associated(cs%Iresttime_col)) 
deallocate(cs%Iresttime_col)
   657   if (
associated(cs%Rcv_ml_ref)) 
deallocate(cs%Rcv_ml_ref)
   658   if (
associated(cs%Ref_eta)) 
deallocate(cs%Ref_eta)
   660   if (
associated(cs%Iresttime_im)) 
deallocate(cs%Iresttime_im)
   661   if (
associated(cs%Rcv_ml_ref_im)) 
deallocate(cs%Rcv_ml_ref_im)
   662   if (
associated(cs%Ref_eta_im)) 
deallocate(cs%Ref_eta_im)
   665     if (
associated(cs%Ref_val(cs%fldno)%p)) 
deallocate(cs%Ref_val(cs%fldno)%p)
   666     if (
associated(cs%Ref_val_im(cs%fldno)%p)) &
   667       deallocate(cs%Ref_val_im(cs%fldno)%p)
 
Ocean grid type. See mom_grid for details. 
 
Provides the ocean grid type. 
 
subroutine, public sponge_end(CS)
 
subroutine, public init_sponge_diags(Time, G, diag, CS)
 
subroutine, public initialize_sponge(Iresttime, int_height, G, param_file, CS, Iresttime_i_mean, int_height_i_mean)
 
subroutine, public set_up_sponge_field(sp_val, f_ptr, G, nlay, CS, sp_val_i_mean)
 
subroutine, public global_i_mean(array, i_mean, G, mask)
 
logical function, public is_root_pe()
 
subroutine, public apply_sponge(h, dt, G, GV, ea, eb, CS, Rcv_ml)
 
subroutine, public set_up_sponge_ml_density(sp_val, G, CS, sp_val_i_mean)
 
subroutine, public mom_error(level, message, all_print)