SCALE-RM
scale_ocean_dyn_slab.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
10 !-------------------------------------------------------------------------------
11 #include "scalelib.h"
13  !-----------------------------------------------------------------------------
14  !
15  !++ used modules
16  !
17  use scale_precision
18  use scale_io
19  use scale_prof
20  use scale_debug
21  !-----------------------------------------------------------------------------
22  implicit none
23  private
24  !-----------------------------------------------------------------------------
25  !
26  !++ Public procedure
27  !
28  public :: ocean_dyn_slab_setup
29  public :: ocean_dyn_slab
30 
31  !-----------------------------------------------------------------------------
32  !
33  !++ Public parameters & variables
34  !
35  !-----------------------------------------------------------------------------
36  !
37  !++ Private procedure
38  !
39  !-----------------------------------------------------------------------------
40  !
41  !++ Private parameters & variables
42  !
43  real(RP), private :: OCEAN_DYN_SLAB_HeatCapacity
44 
45  logical, private :: OCEAN_DYN_SLAB_nudging = .false.
46  real(DP), private :: OCEAN_DYN_SLAB_nudging_tausec
47  logical, private :: OCEAN_DYN_SLAB_offline_mode = .false.
48 
49  !-----------------------------------------------------------------------------
50 contains
51  !-----------------------------------------------------------------------------
53  subroutine ocean_dyn_slab_setup( DEPTH )
54  use scale_prc, only: &
55  prc_abort
56  use scale_const, only: &
57  undef => const_undef, &
58  dwatr => const_dwatr
59  use scale_atmos_hydrometeor, only: &
60  cv_water
61  use scale_calendar, only: &
63  use scale_file_external_input, only: &
65  implicit none
66  real(rp), intent(in) :: depth
67 
68  real(dp) :: ocean_dyn_slab_nudging_tau = 0.0_dp ! Relaxation time
69  character(len=H_SHORT) :: ocean_dyn_slab_nudging_tau_unit = "SEC"
70  character(len=H_LONG) :: ocean_dyn_slab_nudging_basename = ''
71  logical :: ocean_dyn_slab_nudging_basename_add_num = .false.
72  integer :: ocean_dyn_slab_nudging_number_of_files = 1
73  logical :: ocean_dyn_slab_nudging_enable_periodic_year = .false.
74  logical :: ocean_dyn_slab_nudging_enable_periodic_month = .false.
75  logical :: ocean_dyn_slab_nudging_enable_periodic_day = .false.
76  integer :: ocean_dyn_slab_nudging_step_fixed = 0
77  real(rp) :: ocean_dyn_slab_nudging_offset = 0.0_rp
78  real(rp) :: ocean_dyn_slab_nudging_defval ! = UNDEF
79  logical :: ocean_dyn_slab_nudging_check_coordinates = .true.
80  integer :: ocean_dyn_slab_nudging_step_limit = 0
81 
82  ! obsolete
83  real(rp) :: ocean_dyn_slab_depth = -1.0_rp
84 
85  namelist / param_ocean_dyn_slab / &
86  ocean_dyn_slab_nudging, &
87  ocean_dyn_slab_nudging_tau, &
88  ocean_dyn_slab_nudging_tau_unit, &
89  ocean_dyn_slab_nudging_basename, &
90  ocean_dyn_slab_nudging_basename_add_num, &
91  ocean_dyn_slab_nudging_number_of_files, &
92  ocean_dyn_slab_nudging_enable_periodic_year, &
93  ocean_dyn_slab_nudging_enable_periodic_month, &
94  ocean_dyn_slab_nudging_enable_periodic_day, &
95  ocean_dyn_slab_nudging_step_fixed, &
96  ocean_dyn_slab_nudging_offset, &
97  ocean_dyn_slab_nudging_defval, &
98  ocean_dyn_slab_nudging_check_coordinates, &
99  ocean_dyn_slab_nudging_step_limit, &
100  ocean_dyn_slab_depth
101 
102  integer :: ierr
103  !---------------------------------------------------------------------------
104 
105  log_newline
106  log_info("OCEAN_DYN_SLAB_setup",*) 'Setup'
107 
108  ocean_dyn_slab_nudging_defval = undef
109 
110  !--- read namelist
111  rewind(io_fid_conf)
112  read(io_fid_conf,nml=param_ocean_dyn_slab,iostat=ierr)
113  if( ierr < 0 ) then !--- missing
114  log_info("OCEAN_DYN_SLAB_setup",*) 'Not found namelist. Default used.'
115  elseif( ierr > 0 ) then !--- fatal error
116  log_error("OCEAN_DYN_SLAB_setup",*) 'Not appropriate names in namelist PARAM_OCEAN_DYN_SLAB. Check!'
117  call prc_abort
118  endif
119  log_nml(param_ocean_dyn_slab)
120 
121  if ( ocean_dyn_slab_depth >= 0.0 ) then
122  log_error("OCEAN_DYN_SLAB_setup",*) '"OCEAN_DYN_SLAB_DEPTH" is obsolete. USE "ODZ" of "PARAM_OCEAN_GRID_CARTESC"'
123  call prc_abort
124  end if
125 
126  ocean_dyn_slab_heatcapacity = dwatr * cv_water * depth
127 
128  log_newline
129  log_info("OCEAN_DYN_SLAB_setup",*) 'Slab ocean depth [m] : ', depth
130  log_info("OCEAN_DYN_SLAB_setup",*) 'Ocean heat capacity [J/K/m2] : ', ocean_dyn_slab_heatcapacity
131 
132  if ( ocean_dyn_slab_nudging ) then
133  call calendar_unit2sec( ocean_dyn_slab_nudging_tausec, ocean_dyn_slab_nudging_tau, ocean_dyn_slab_nudging_tau_unit )
134 
135  log_info("OCEAN_DYN_SLAB_setup",*) 'Use nudging for SST : ON'
136  log_info("OCEAN_DYN_SLAB_setup",*) 'Relaxation time Tau [sec] : ', ocean_dyn_slab_nudging_tausec
137 
138  if ( ocean_dyn_slab_nudging_tausec == 0.0_rp ) then
139  ocean_dyn_slab_offline_mode = .true.
140  log_info("OCEAN_DYN_SLAB_setup",*) 'Tau=0 means that SST is completely replaced by the external data.'
141  endif
142 
143  if ( ocean_dyn_slab_nudging_basename == '' ) then
144  log_error("OCEAN_DYN_SLAB_setup",*) 'OCEAN_DYN_SLAB_nudging_basename is necessary !!'
145  call prc_abort
146  endif
147  else
148  log_info("OCEAN_DYN_SLAB_setup",*) 'Use nudging for SST : OFF'
149  endif
150 
151  if ( ocean_dyn_slab_nudging ) then
152  call file_external_input_regist( ocean_dyn_slab_nudging_basename, & ! [IN]
153  ocean_dyn_slab_nudging_basename_add_num, & ! [IN]
154  ocean_dyn_slab_nudging_number_of_files, & ! [IN]
155  'OCEAN_TEMP', & ! [IN]
156  'OXY', & ! [IN]
157  ocean_dyn_slab_nudging_enable_periodic_year, & ! [IN]
158  ocean_dyn_slab_nudging_enable_periodic_month, & ! [IN]
159  ocean_dyn_slab_nudging_enable_periodic_day, & ! [IN]
160  ocean_dyn_slab_nudging_step_fixed, & ! [IN]
161  ocean_dyn_slab_nudging_offset, & ! [IN]
162  ocean_dyn_slab_nudging_defval, & ! [IN]
163  check_coordinates = ocean_dyn_slab_nudging_check_coordinates, & ! [IN]
164  step_limit = ocean_dyn_slab_nudging_step_limit, & ! [IN]
165  allow_missing = ( .not. ocean_dyn_slab_offline_mode ) ) ! [IN]
166  endif
167 
168  return
169  end subroutine ocean_dyn_slab_setup
170 
171  !-----------------------------------------------------------------------------
173  subroutine ocean_dyn_slab( &
174  OKMAX, OKS, OKE, &
175  OIA, OIS, OIE, &
176  OJA, OJS, OJE, &
177  OCEAN_TEMP_t, &
178  OCEAN_SFLX_G, &
179  OCEAN_SFLX_water, &
180  calc_flag, &
181  dt, NOWDAYSEC, &
182  OCEAN_TEMP, &
183  MASS_SUPL, &
184  ENGI_SUPL )
185  use scale_prc, only: &
186  prc_abort
187  use scale_const, only: &
188  undef => const_undef
189  use scale_file_external_input, only: &
190  file_external_input_update
191  use scale_atmos_hydrometeor, only: &
192  cv_water
193  implicit none
194 
195  integer, intent(in) :: okmax, oks, oke
196  integer, intent(in) :: oia, ois, oie
197  integer, intent(in) :: oja, ojs, oje
198  real(rp), intent(in) :: ocean_temp_t (okmax,oia,oja) ! tendency of ocean temperature
199  real(rp), intent(in) :: ocean_sflx_g (oia,oja) ! heat flux from surface to subsurface (open ocean/sea ice)
200  real(rp), intent(in) :: ocean_sflx_water(oia,oja) ! mass flux from surface to subsurface (open ocean/sea ice)
201  logical, intent(in) :: calc_flag (oia,oja) ! to decide calculate or not
202  real(dp), intent(in) :: dt
203  real(dp), intent(in) :: nowdaysec
204  real(rp), intent(inout) :: ocean_temp (okmax,oia,oja)
205  real(rp), intent(out) :: mass_supl (oia,oja)
206  real(rp), intent(out) :: engi_supl (oia,oja)
207 
208  real(rp) :: ocean_temp_t_ndg(okmax,oia,oja)
209  real(rp) :: ocean_temp_ref (okmax,oia,oja)
210  real(rp) :: rtau
211  real(rp) :: dcp
212 
213  logical :: error
214  integer :: k, i, j
215  !---------------------------------------------------------------------------
216 
217  log_progress(*) 'ocean / dynamics / slab'
218 
219  if ( ocean_dyn_slab_nudging ) then
220 
221  call file_external_input_update( 'OCEAN_TEMP', nowdaysec, ocean_temp_ref(:,:,:), error )
222 
223 
224  if ( error ) then
225  log_error("OCEAN_DYN_SLAB",*) 'Requested data is not found!'
226  call prc_abort
227  endif
228 
229  if ( .not. ocean_dyn_slab_offline_mode ) then
230 
231  ! if OCEAN_DYN_SLAB_nudging_tau < dt, Nudging acts as quasi-prescribed boundary
232  rtau = 1.0_rp / max(ocean_dyn_slab_nudging_tausec,dt)
233 
234  !$omp parallel do
235  do j = ojs, oje
236  do i = ois, oie
237  do k = oks, oke
238  if ( ocean_temp_ref(k,i,j) == undef ) then
239  ocean_temp_t_ndg(k,i,j) = 0.0_rp
240  else
241  ocean_temp_t_ndg(k,i,j) = ( ocean_temp_ref(k,i,j) - ocean_temp(k,i,j) ) * rtau
242  end if
243  enddo
244  enddo
245  enddo
246 
247  end if
248 
249  else
250  !$omp parallel do
251  do j = ojs, oje
252  do i = ois, oie
253  do k = oks, oke
254  ocean_temp_t_ndg(k,i,j) = 0.0_rp
255  end do
256  end do
257  end do
258  endif
259 
260  if ( ocean_dyn_slab_offline_mode ) then
261 
262  !$omp parallel do
263  do j = ojs, oje
264  do i = ois, oie
265  if ( calc_flag(i,j) ) then
266  ocean_temp(oks,i,j) = ocean_temp_ref(oks,i,j)
267  endif
268  mass_supl(i,j) = 0.0_rp
269  engi_supl(i,j) = 0.0_rp
270  enddo
271  enddo
272 
273  else
274 
275  !$omp parallel do private(dCP)
276  do j = ojs, oje
277  do i = ois, oie
278  if ( calc_flag(i,j) ) then
279  ! heat flux from atm/ice at uppermost ocean layer
280  dcp = cv_water * ocean_sflx_water(i,j) * dt
281  ocean_temp(oks,i,j) = ocean_temp(oks,i,j) &
282  + ( ocean_sflx_g(i,j) * dt - dcp * ocean_temp(oks,i,j) ) &
283  / ( ocean_dyn_slab_heatcapacity + dcp ) &
284  + ocean_temp_t_ndg(oks,i,j) * dt
285  do k = oks+1, oke
286  ocean_temp(k,i,j) = ocean_temp(k,i,j) + ocean_temp_t_ndg(k,i,j) * dt
287  enddo
288  mass_supl(i,j) = - ocean_sflx_water(i,j)
289  engi_supl(i,j) = cv_water * mass_supl(i,j) * ocean_temp(oks,i,j)
290  else
291  mass_supl(i,j) = 0.0_rp
292  engi_supl(i,j) = 0.0_rp
293  endif
294  enddo
295  enddo
296 
297  endif
298 
299  return
300  end subroutine ocean_dyn_slab
301 
302 end module scale_ocean_dyn_slab
scale_ocean_dyn_slab::ocean_dyn_slab
subroutine, public ocean_dyn_slab(OKMAX, OKS, OKE, OIA, OIS, OIE, OJA, OJS, OJE, OCEAN_TEMP_t, OCEAN_SFLX_G, OCEAN_SFLX_water, calc_flag, dt, NOWDAYSEC, OCEAN_TEMP, MASS_SUPL, ENGI_SUPL)
Slab ocean model.
Definition: scale_ocean_dyn_slab.F90:185
scale_prc::prc_abort
subroutine, public prc_abort
Abort Process.
Definition: scale_prc.F90:342
scale_file_external_input::file_external_input_regist
subroutine, public file_external_input_regist(basename, basename_add_num, number_of_files, varname, axistype, enable_periodic_year, enable_periodic_month, enable_periodic_day, step_fixed, offset, defval, check_coordinates, aggregate, allow_missing, step_limit, exist)
Regist data.
Definition: scale_file_external_input.F90:324
scale_precision
module PRECISION
Definition: scale_precision.F90:14
scale_atmos_hydrometeor
module atmosphere / hydrometeor
Definition: scale_atmos_hydrometeor.F90:12
scale_calendar
module CALENDAR
Definition: scale_calendar.F90:13
scale_ocean_dyn_slab::ocean_dyn_slab_setup
subroutine, public ocean_dyn_slab_setup(DEPTH)
Setup.
Definition: scale_ocean_dyn_slab.F90:54
scale_prc
module PROCESS
Definition: scale_prc.F90:11
scale_io
module STDIO
Definition: scale_io.F90:10
scale_const
module CONSTANT
Definition: scale_const.F90:11
scale_prof
module profiler
Definition: scale_prof.F90:11
scale_const::const_dwatr
real(rp), parameter, public const_dwatr
density of water [kg/m3]
Definition: scale_const.F90:82
scale_debug
module DEBUG
Definition: scale_debug.F90:11
scale_file_external_input
module file / external_input
Definition: scale_file_external_input.F90:12
scale_const::const_undef
real(rp), public const_undef
Definition: scale_const.F90:41
scale_io::io_fid_conf
integer, public io_fid_conf
Config file ID.
Definition: scale_io.F90:56
scale_atmos_hydrometeor::cv_water
real(rp), public cv_water
CV for water [J/kg/K].
Definition: scale_atmos_hydrometeor.F90:132
scale_ocean_dyn_slab
module ocean / dynamics / slab
Definition: scale_ocean_dyn_slab.F90:12
scale_calendar::calendar_unit2sec
subroutine, public calendar_unit2sec(second, value, unit)
Convert several units to second.
Definition: scale_calendar.F90:424