SCALE-RM
scale_ocean_sfc_slab.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
10 !-------------------------------------------------------------------------------
12  !-----------------------------------------------------------------------------
13  !
14  !++ used modules
15  !
16  use scale_precision
17  use scale_stdio
19  !-----------------------------------------------------------------------------
20  implicit none
21  private
22  !-----------------------------------------------------------------------------
23  !
24  !++ Public procedure
25  !
26  public :: ocean_sfc_slab_setup
27  public :: ocean_sfc_slab
29 
30  !-----------------------------------------------------------------------------
31  !
32  !++ Public parameters & variables
33  !
34  !-----------------------------------------------------------------------------
35  !
36  !++ Private procedure
37  !
38  !-----------------------------------------------------------------------------
39  !
40  !++ Private parameters & variables
41  !
42  !-----------------------------------------------------------------------------
43  logical, private :: sst_update
44 
45  logical, allocatable, private :: is_ocn(:,:)
46 
47 contains
48  !-----------------------------------------------------------------------------
50  subroutine ocean_sfc_slab_setup( OCEAN_TYPE )
51  use scale_process, only: &
53  use scale_landuse, only: &
55  implicit none
56 
57  character(len=*), intent(in) :: OCEAN_TYPE
58 
59  integer :: i, j
60  !---------------------------------------------------------------------------
61 
62  if( io_l ) write(io_fid_log,*)
63  if( io_l ) write(io_fid_log,*) '++++++ Module[SLAB] / Categ[OCEAN SFC] / Origin[SCALElib]'
64 
65  select case( ocean_type )
66  case ( 'CONST' )
67  sst_update = .false.
68  case ( 'SLAB', 'FILE' )
69  sst_update = .true.
70  case default
71  write(*,*) 'xxx wrong OCEAN_TYPE. Check!'
72  call prc_mpistop
73  end select
74 
75  ! judge to run slab ocean model
76  allocate( is_ocn(ia,ja) )
77 
78  do j = js, je
79  do i = is, ie
80  if( landuse_fact_ocean(i,j) > 0.0_rp ) then
81  is_ocn(i,j) = .true.
82  else
83  is_ocn(i,j) = .false.
84  end if
85  end do
86  end do
87 
88  return
89  end subroutine ocean_sfc_slab_setup
90 
91  !-----------------------------------------------------------------------------
92  subroutine ocean_sfc_slab( &
93  SST_t, & ! [OUT]
94  ZMFLX, & ! [OUT]
95  XMFLX, & ! [OUT]
96  YMFLX, & ! [OUT]
97  SHFLX, & ! [OUT]
98  LHFLX, & ! [OUT]
99  WHFLX, & ! [OUT]
100  U10, & ! [OUT]
101  V10, & ! [OUT]
102  T2, & ! [OUT]
103  Q2, & ! [OUT]
104  TMPA, & ! [IN]
105  PRSA, & ! [IN]
106  WA, & ! [IN]
107  UA, & ! [IN]
108  VA, & ! [IN]
109  RHOA, & ! [IN]
110  QVA, & ! [IN]
111  Z1, & ! [IN]
112  PBL, & ! [IN]
113  PRSS, & ! [IN]
114  LWD, & ! [IN]
115  SWD, & ! [IN]
116  TW, & ! [IN]
117  SST, & ! [IN]
118  ALB_LW, & ! [IN]
119  ALB_SW, & ! [IN]
120  Z0M, & ! [IN]
121  Z0H, & ! [IN]
122  Z0E, & ! [IN]
123  dt ) ! [IN]
125  use scale_process, only: &
127  use scale_const, only: &
128  cpdry => const_cpdry, &
129  stb => const_stb
130  use scale_bulkflux, only: &
131  bulkflux
132  use scale_atmos_thermodyn, only: &
133  atmos_thermodyn_templhv
134  use scale_atmos_saturation, only: &
135  qsat => atmos_saturation_pres2qsat_all
136  implicit none
137 
138  ! arguments
139  real(RP), intent(out) :: SST_t(ia,ja) ! tendency of sea surface temperature
140  real(RP), intent(out) :: ZMFLX(ia,ja) ! z-momentum flux at the surface [kg/m2/s]
141  real(RP), intent(out) :: XMFLX(ia,ja) ! x-momentum flux at the surface [kg/m2/s]
142  real(RP), intent(out) :: YMFLX(ia,ja) ! y-momentum flux at the surface [kg/m2/s]
143  real(RP), intent(out) :: SHFLX(ia,ja) ! sensible heat flux at the surface [W/m2]
144  real(RP), intent(out) :: LHFLX(ia,ja) ! latent heat flux at the surface [W/m2]
145  real(RP), intent(out) :: WHFLX(ia,ja) ! water heat flux at the surface [W/m2]
146  real(RP), intent(out) :: U10 (ia,ja) ! velocity u at 10m [m/s]
147  real(RP), intent(out) :: V10 (ia,ja) ! velocity v at 10m [m/s]
148  real(RP), intent(out) :: T2 (ia,ja) ! temperature at 2m [K]
149  real(RP), intent(out) :: Q2 (ia,ja) ! water vapor at 2m [kg/kg]
150 
151  real(RP), intent(in) :: TMPA(ia,ja) ! temperature at the lowest atmospheric layer [K]
152  real(RP), intent(in) :: PRSA(ia,ja) ! pressure at the lowest atmospheric layer [Pa]
153  real(RP), intent(in) :: WA (ia,ja) ! velocity w at the lowest atmospheric layer [m/s]
154  real(RP), intent(in) :: UA (ia,ja) ! velocity u at the lowest atmospheric layer [m/s]
155  real(RP), intent(in) :: VA (ia,ja) ! velocity v at the lowest atmospheric layer [m/s]
156  real(RP), intent(in) :: RHOA(ia,ja) ! density at the lowest atmospheric layer [kg/m3]
157  real(RP), intent(in) :: QVA (ia,ja) ! ratio of water vapor mass to total mass at the lowest atmospheric layer [kg/kg]
158  real(RP), intent(in) :: Z1 (ia,ja) ! cell center height at the lowest atmospheric layer [m]
159  real(RP), intent(in) :: PBL (ia,ja) ! the top of atmospheric mixing layer [m]
160  real(RP), intent(in) :: PRSS(ia,ja) ! pressure at the surface [Pa]
161  real(RP), intent(in) :: LWD (ia,ja) ! downward long-wave radiation flux at the surface [W/m2]
162  real(RP), intent(in) :: SWD (ia,ja) ! downward short-wave radiation flux at the surface [W/m2]
163 
164  real(RP), intent(in) :: TW (ia,ja) ! water temperature [K]
165  real(RP), intent(in) :: SST (ia,ja) ! sea surface temperature [K]
166  real(RP), intent(in) :: ALB_LW(ia,ja) ! surface albedo for LW [0-1]
167  real(RP), intent(in) :: ALB_SW(ia,ja) ! surface albedo for SW [0-1]
168  real(RP), intent(in) :: Z0M (ia,ja) ! roughness length for momentum [m]
169  real(RP), intent(in) :: Z0H (ia,ja) ! roughness length for heat [m]
170  real(RP), intent(in) :: Z0E (ia,ja) ! roughness length for vapor [m]
171  real(DP), intent(in) :: dt ! delta time
172 
173  ! works
174  real(RP) :: SST1(ia,ja)
175 
176  real(RP) :: Ustar ! friction velocity [m]
177  real(RP) :: Tstar ! friction temperature [K]
178  real(RP) :: Qstar ! friction mixing rate [kg/kg]
179  real(RP) :: Uabs ! modified absolute velocity [m/s]
180 
181  real(RP) :: SQV ! saturation water vapor mixing ratio at surface [kg/kg]
182  real(RP) :: LHV(ia,ja) ! latent heat for vaporization depending on temperature [J/kg]
183 
184  integer :: i, j
185  !---------------------------------------------------------------------------
186 
187  ! update surface temperature
188  do j = js, je
189  do i = is, ie
190  sst1(i,j) = tw(i,j) ! assumed well-mixed condition
191  end do
192  end do
193 
194  call atmos_thermodyn_templhv( lhv, tmpa )
195 
196  do j = js, je
197  do i = is, ie
198 
199  if( is_ocn(i,j) ) then
200 
201  ! saturation at the surface
202  call qsat( sqv, & ! [OUT]
203  sst1(i,j), & ! [IN]
204  prss(i,j) ) ! [IN]
205 
206  call bulkflux( &
207  ustar, & ! [OUT]
208  tstar, & ! [OUT]
209  qstar, & ! [OUT]
210  uabs, & ! [OUT]
211  tmpa(i,j), & ! [IN]
212  sst1(i,j), & ! [IN]
213  prsa(i,j), & ! [IN]
214  prss(i,j), & ! [IN]
215  qva(i,j), & ! [IN]
216  sqv, & ! [IN]
217  ua(i,j), & ! [IN]
218  va(i,j), & ! [IN]
219  z1(i,j), & ! [IN]
220  pbl(i,j), & ! [IN]
221  z0m(i,j), & ! [IN]
222  z0h(i,j), & ! [IN]
223  z0e(i,j) ) ! [IN]
224 
225  zmflx(i,j) = -rhoa(i,j) * ustar**2 / uabs * wa(i,j)
226  xmflx(i,j) = -rhoa(i,j) * ustar**2 / uabs * ua(i,j)
227  ymflx(i,j) = -rhoa(i,j) * ustar**2 / uabs * va(i,j)
228 
229  shflx(i,j) = -cpdry * rhoa(i,j) * ustar * tstar
230  lhflx(i,j) = -lhv(i,j) * rhoa(i,j) * ustar * qstar
231 
232  ! calculation for residual
233  whflx(i,j) = ( 1.0_rp - alb_sw(i,j) ) * swd(i,j) * (-1.0_rp) &
234  - ( 1.0_rp - alb_lw(i,j) ) * ( lwd(i,j) - stb * sst1(i,j)**4 ) &
235  + shflx(i,j) + lhflx(i,j)
236 
237  ! diagnositc variables
238  u10(i,j) = ua(i,j) * log( 10.0_rp / z0m(i,j) ) / log( z1(i,j) / z0m(i,j) )
239  v10(i,j) = va(i,j) * log( 10.0_rp / z0m(i,j) ) / log( z1(i,j) / z0m(i,j) )
240  t2(i,j) = sst1(i,j) + ( tmpa(i,j) - sst1(i,j) ) * ( log( 2.0_rp / z0m(i,j) ) * log( 2.0_rp / z0h(i,j) ) ) &
241  / ( log( z1(i,j) / z0m(i,j) ) * log( z1(i,j) / z0h(i,j) ) )
242  q2(i,j) = sqv + ( qva(i,j) - sqv ) * ( log( 2.0_rp / z0m(i,j) ) * log( 2.0_rp / z0e(i,j) ) ) &
243  / ( log( z1(i,j) / z0m(i,j) ) * log( z1(i,j) / z0e(i,j) ) )
244 
245  else
246  ! not calculate surface flux
247  zmflx(i,j) = 0.0_rp
248  xmflx(i,j) = 0.0_rp
249  ymflx(i,j) = 0.0_rp
250  shflx(i,j) = 0.0_rp
251  lhflx(i,j) = 0.0_rp
252  whflx(i,j) = 0.0_rp
253  u10(i,j) = 0.0_rp
254  v10(i,j) = 0.0_rp
255  t2(i,j) = 0.0_rp
256  q2(i,j) = 0.0_rp
257  end if
258 
259  enddo
260  enddo
261 
262  ! calculate tendency
263  if( sst_update ) then
264  do j = js, je
265  do i = is, ie
266  sst_t(i,j) = ( sst1(i,j) - sst(i,j) ) / dt
267  enddo
268  enddo
269  else
270  do j = js, je
271  do i = is, ie
272  sst_t(i,j) = 0.0_rp
273  enddo
274  enddo
275  end if
276 
277  return
278  end subroutine ocean_sfc_slab
279 
280  !-----------------------------------------------------------------------------
281  subroutine ocean_sfc_slab_simplealbedo( &
282  SFC_albedo_t, &
283  SFC_albedo, &
284  cosSZA, &
285  dt )
287  use scale_const, only: &
288  i_sw => const_i_sw, &
289  i_lw => const_i_lw
290  implicit none
291 
292  ! arguments
293  real(RP), intent(out) :: SFC_albedo_t(ia,ja,2) ! tendency of sea surface albedo [0-1]
294  real(RP), intent(in) :: SFC_albedo (ia,ja,2) ! sea surface [0-1]
295  real(RP), intent(in) :: cosSZA (ia,ja) ! cos(solar zenith angle) [0-1]
296  real(DP), intent(in) :: dt ! delta time
297 
298  ! works
299  real(RP) :: SFC_albedo1(ia,ja,2)
300  real(RP) :: am1
301 
302  real(RP), parameter :: c_ocean_albedo(3) = (/ -0.747900_rp, &
303  -4.677039_rp, &
304  1.583171_rp /)
305 
306  integer :: i, j
307  !---------------------------------------------------------------------------
308 
309  do j = js, je
310  do i = is, ie
311  am1 = max( min( cossza(i,j), 0.961_rp ), 0.0349_rp )
312 
313  ! SFC_albedo1(i,j,I_LW) = 0.5_RP do nothing
314  sfc_albedo1(i,j,i_sw) = exp( ( c_ocean_albedo(3)*am1 + c_ocean_albedo(2) )*am1 + c_ocean_albedo(1) )
315  enddo
316  enddo
317 
318  ! calculate tendency
319  do j = js, je
320  do i = is, ie
321  sfc_albedo_t(i,j,i_lw) = 0.0_rp
322  sfc_albedo_t(i,j,i_sw) = ( sfc_albedo1(i,j,i_sw) - sfc_albedo(i,j,i_sw) ) / dt
323  enddo
324  enddo
325 
326  return
327  end subroutine ocean_sfc_slab_simplealbedo
328 
329 end module scale_ocean_sfc_slab
integer, public is
start point of inner domain: x, local
integer, public je
end point of inner domain: y, local
real(rp), public const_cpdry
specific heat (dry air,constant pressure) [J/kg/K]
Definition: scale_const.F90:58
module ATMOSPHERE / Saturation adjustment
integer, public const_i_lw
long-wave radiation index
Definition: scale_const.F90:98
subroutine, public ocean_sfc_slab(SST_t, ZMFLX, XMFLX, YMFLX, SHFLX, LHFLX, WHFLX, U10, V10, T2, Q2, TMPA, PRSA, WA, UA, VA, RHOA, QVA, Z1, PBL, PRSS, LWD, SWD, TW, SST, ALB_LW, ALB_SW, Z0M, Z0H, Z0E, dt)
subroutine, public prc_mpistop
Abort MPI.
real(rp), parameter, public const_stb
Stefan-Boltzman constant [W/m2/K4].
Definition: scale_const.F90:51
logical, public io_l
output log or not? (this process)
Definition: scale_stdio.F90:59
module STDIO
Definition: scale_stdio.F90:12
subroutine, public ocean_sfc_slab_simplealbedo(SFC_albedo_t, SFC_albedo, cosSZA, dt)
module OCEAN / Surface flux with slab ocean model
module grid index
integer, public ia
of x whole cells (local, with HALO)
module LANDUSE
procedure(bc), pointer, public bulkflux
real(rp), dimension(:,:), allocatable, public landuse_fact_ocean
ocean factor
integer, public js
start point of inner domain: y, local
module PROCESS
subroutine, public log(type, message)
Definition: dc_log.f90:133
module CONSTANT
Definition: scale_const.F90:14
subroutine, public ocean_sfc_slab_setup(OCEAN_TYPE)
Setup.
integer, public ie
end point of inner domain: x, local
module Surface bulk flux
module ATMOSPHERE / Thermodynamics
integer, public const_i_sw
short-wave radiation index
Definition: scale_const.F90:99
module PRECISION
integer, public io_fid_log
Log file ID.
Definition: scale_stdio.F90:56
integer, public ja
of y whole cells (local, with HALO)