Browse Source

First attempt to employ bulk formulas from Meier et al. 1999

Taken from Section 2.2 in "RCO - Rossby Centre regional Ocean
climate model: model description (version 1.0) and
first results from the hindcast period 1992/93"
experiments/tc-meier
Sven Karsten 1 year ago
parent
commit
df72314f52
  1. 30
      src/flux_calculator_calculate.F90
  2. 16
      src/flux_calculator_prepare.F90
  3. 9
      src/flux_lib/flux_library.F90
  4. 33
      src/flux_lib/heat/flux_heat_sensible.F90
  5. 43
      src/flux_lib/mass/flux_mass_evap.F90
  6. 31
      src/flux_lib/momentum/flux_momentum.F90

30
src/flux_calculator_calculate.F90

@ -85,6 +85,14 @@ MODULE flux_calculator_calculate
local_field(i,1)%var(idx_UATM)%field(j), &
local_field(i,1)%var(idx_VATM)%field(j))
ENDDO
ELSEIF (trim(method)=='MEIER') THEN
DO j=1,grid_size(1)
CALL flux_mass_evap_meier(local_field(i,1)%var(idx_MEVA)%field(j), &
local_field(i,1)%var(idx_QATM)%field(j), &
local_field(i,1)%var(idx_TSUR)%field(j), &
local_field(i,1)%var(idx_UATM)%field(j), &
local_field(i,1)%var(idx_VATM)%field(j))
ENDDO
ENDIF
ENDIF
ENDDO
@ -165,6 +173,14 @@ MODULE flux_calculator_calculate
local_field(i,1)%var(idx_UATM)%field(j), &
local_field(i,1)%var(idx_VATM)%field(j))
ENDDO
ELSEIF (trim(method)=='MEIER') THEN
DO j=1,grid_size(1)
CALL flux_heat_sensible_meier(local_field(i,1)%var(idx_HSEN)%field(j), &
local_field(i,1)%var(idx_TATM)%field(j), &
local_field(i,1)%var(idx_TSUR)%field(j), &
local_field(i,1)%var(idx_UATM)%field(j), &
local_field(i,1)%var(idx_VATM)%field(j))
ENDDO
ENDIF
ENDIF
ENDDO
@ -213,6 +229,13 @@ MODULE flux_calculator_calculate
local_field(i,which_grid)%var(idx_UATM)%field(j), &
local_field(i,which_grid)%var(idx_VATM)%field(j))
ENDDO
ELSEIF (trim(method)=='MEIER') THEN
DO j=1,grid_size(which_grid)
CALL flux_momentum_meier(local_field(i,which_grid)%var(idx_UMOM)%field(j), &
dummy, &
local_field(i,which_grid)%var(idx_UATM)%field(j), &
local_field(i,which_grid)%var(idx_VATM)%field(j))
ENDDO
ENDIF
ENDIF
ENDDO
@ -259,6 +282,13 @@ MODULE flux_calculator_calculate
local_field(i,which_grid)%var(idx_UATM)%field(j), &
local_field(i,which_grid)%var(idx_VATM)%field(j))
ENDDO
ELSEIF (trim(method)=='MEIER') THEN
DO j=1,grid_size(which_grid)
CALL flux_momentum_meier(dummy, &
local_field(i,which_grid)%var(idx_VMOM)%field(j), &
local_field(i,which_grid)%var(idx_UATM)%field(j), &
local_field(i,which_grid)%var(idx_VATM)%field(j))
ENDDO
ENDIF
ENDIF
ENDDO

16
src/flux_calculator_prepare.F90

@ -102,6 +102,11 @@ MODULE flux_calculator_prepare
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_TATM)%field )) missing_field=trim(missing_field)//' TATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_UATM)%field )) missing_field=trim(missing_field)//' UATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_VATM)%field )) missing_field=trim(missing_field)//' VATM'
ELSEIF (trim(method)=='MEIER') THEN
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_QATM)%field )) missing_field=trim(missing_field)//' QATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_QSUR)%field )) missing_field=trim(missing_field)//' TSUR'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_UATM)%field )) missing_field=trim(missing_field)//' UATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_VATM)%field )) missing_field=trim(missing_field)//' VATM'
ELSE
WRITE (w_unit,*) "Error calculating ",myvarname," for surface_type ",surface_type," on the grid ",grid_name(which_grid),":"
WRITE (w_unit,*) " Method ",method," is not known. "
@ -172,6 +177,11 @@ MODULE flux_calculator_prepare
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_TATM)%field )) missing_field=trim(missing_field)//' TSUR'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_UATM)%field )) missing_field=trim(missing_field)//' UATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_VATM)%field )) missing_field=trim(missing_field)//' VATM'
ELSEIF (trim(method)=='MEIER') THEN
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_TATM)%field )) missing_field=trim(missing_field)//' TATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_TATM)%field )) missing_field=trim(missing_field)//' TSUR'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_UATM)%field )) missing_field=trim(missing_field)//' UATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_VATM)%field )) missing_field=trim(missing_field)//' VATM'
ELSE
WRITE (w_unit,*) "Error calculating ",myvarname," for surface_type ",surface_type," on the grid ",grid_name(which_grid),":"
WRITE (w_unit,*) " Method ",method," is not known. "
@ -211,6 +221,9 @@ MODULE flux_calculator_prepare
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_TATM)%field )) missing_field=trim(missing_field)//' TATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_TATM)%field )) missing_field=trim(missing_field)//' TSUR'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_UATM)%field )) missing_field=trim(missing_field)//' UATM'
ELSEIF (trim(method)=='MEIER') THEN
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_UATM)%field )) missing_field=trim(missing_field)//' UATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_VATM)%field )) missing_field=trim(missing_field)//' VATM'
ELSE
WRITE (w_unit,*) "Error calculating ",myvarname," for surface_type ",surface_type," on the grid ",grid_name(which_grid),":"
WRITE (w_unit,*) " Method ",method," is not known. "
@ -248,6 +261,9 @@ MODULE flux_calculator_prepare
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_TATM)%field )) missing_field=trim(missing_field)//' TATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_TATM)%field )) missing_field=trim(missing_field)//' TSUR'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_UATM)%field )) missing_field=trim(missing_field)//' VATM'
ELSEIF (trim(method)=='MEIER') THEN
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_UATM)%field )) missing_field=trim(missing_field)//' UATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_VATM)%field )) missing_field=trim(missing_field)//' VATM'
ELSE
WRITE (w_unit,*) "Error calculating ",myvarname," for surface_type ",surface_type," on the grid ",grid_name(which_grid),":"
WRITE (w_unit,*) " Method ",method," is not known. "

9
src/flux_lib/flux_library.F90

@ -16,15 +16,15 @@ module flux_library
! import flux calculation functions from different modules:
! mass fluxes
use flux_mass_evap, only: flux_mass_evap_cclm, flux_mass_evap_mom5
use flux_mass_evap, only: flux_mass_evap_cclm, flux_mass_evap_mom5, flux_mass_evap_meier
! heat fluxes
use flux_heat_latent, only: flux_heat_latent_ice, flux_heat_latent_water
use flux_heat_sensible, only: flux_heat_sensible_cclm, flux_heat_sensible_mom5
use flux_heat_sensible, only: flux_heat_sensible_cclm, flux_heat_sensible_mom5, flux_heat_sensible_meier
! radiation fluxes
use flux_radiation_blackbody, only: flux_radiation_blackbody_StBo
use distribute_radiation_flux_mod, only: distribute_radiation_flux
! momentum fluxes
use flux_momentum, only: flux_momentum_cclm, flux_momentum_mom5
use flux_momentum, only: flux_momentum_cclm, flux_momentum_mom5, flux_momentum_meier
implicit none ; private
@ -33,10 +33,13 @@ module flux_library
public flux_heat_latent_water
public flux_heat_sensible_cclm
public flux_heat_sensible_mom5
public flux_heat_sensible_meier
public flux_mass_evap_cclm
public flux_mass_evap_mom5
public flux_mass_evap_meier
public flux_momentum_cclm
public flux_momentum_mom5
public flux_momentum_meier
public flux_radiation_blackbody_StBo
public distribute_radiation_flux
public spec_vapor_surface_cclm

33
src/flux_lib/heat/flux_heat_sensible.F90

@ -17,6 +17,7 @@ module flux_heat_sensible
! expose all functions
public flux_heat_sensible_cclm
public flux_heat_sensible_mom5
public flux_heat_sensible_meier
contains
@ -132,6 +133,38 @@ contains
)
end subroutine flux_heat_sensible_mom5
subroutine flux_heat_sensible_meier( &
flux_heat_sensible, & ! RESULT (W/m2)
temperature_atmos, & ! T_a (K)
temperature_surface, & ! T_s (K)
u_atmos, & ! u_a (m/s)
v_atmos & ! v_a (m/s)
)
real(prec), intent(out) :: flux_heat_sensible ! RESULT (W/m2)
real(prec), intent(in) :: temperature_atmos ! T_a (K)
real(prec), intent(in) :: temperature_surface ! T_s (K)
real(prec), intent(in) :: u_atmos ! u_a (m/s)
real(prec), intent(in) :: v_atmos ! v_a (m/s)
real(prec) :: rho_a = 1.225 ! air density [kg / m^3]
real(prec) :: c_pa = 1.008E+03 ! specific heat capacity of air [J / (kg K)]
real(prec) :: c_aw ! transfer coefficient for sensible heat (Stanton number) [1]
real(prec) :: vel ! absolute value of wind speed
! get Stanton number according to temperature difference
IF (temperature_atmos .lt. temperature_surface) THEN
c_aw = 1.13E-03 ! unstable
ELSE
c_aw = 0.66E-03 ! stable
ENDIF
vel = sqrt(u_atmos*u_atmos + v_atmos*v_atmos) ! atmospheric velocity (m/s)
flux_heat_sensible = rho_a * c_pa * c_aw * vel * (temperature_surface - temperature_atmos)
end subroutine flux_heat_sensible_meier
end module flux_heat_sensible

43
src/flux_lib/mass/flux_mass_evap.F90

@ -15,6 +15,7 @@ module flux_mass_evap
! expose all functions
public flux_mass_evap_cclm
public flux_mass_evap_mom5
public flux_mass_evap_meier
contains
@ -78,7 +79,7 @@ contains
max(vel, u_min_evap) * pressure_surface / &
(gas_constant_air * T_tilde)
flux_mass_evap = flux_air * (specific_vapor_content_surface - & ! mass flux of water (kg/m2/s)
flux_mass_evap = 0.8 * flux_air * (specific_vapor_content_surface - & ! mass flux of water (kg/m2/s)
specific_vapor_content_atmos)
end subroutine flux_mass_evap_cclm
@ -116,4 +117,44 @@ contains
end subroutine flux_mass_evap_mom5
subroutine flux_mass_evap_meier( &
flux_mass_evap, & ! RESULT (kg/m2/s)
specific_vapor_content_atmos, & ! q_{v,a} (kg/kg)
temperature_surface, & ! T_s (K)
u_atmos, & ! u_a (m/s)
v_atmos & ! v_a (m/s)
)
real(prec), intent(out) :: flux_mass_evap ! RESULT (kg/m2/s)
real(prec), intent(in) :: specific_vapor_content_atmos ! q_{v,a} (kg/kg)
real(prec), intent(in) :: temperature_surface ! T_s (K)
real(prec), intent(in) :: u_atmos ! u_a (m/s)
real(prec), intent(in) :: v_atmos ! v_a (m/s)
! use parameters according to Meier et al. 1999
real(prec) :: rho_a = 1.225 ! air density [kg / m^3]
real(prec) :: c_aw = 1.15E-03 ! transfer coefficient for latent heat (Dalton number) [1]
real(prec) :: epsilon = 0.62197
real(prec) :: P_0 = 1.013E+05 ! reference pressure [Pa]
real(prec) :: e_w ! water vapour pressure close to sea surface
real(prec) :: q_w ! specific vapor content close to sea surface
real(prec) :: vel ! absolute value of wind speed
real(prec) :: r = 6.1078E+02
real(prec) :: c_1 = 17.269
real(prec) :: c_2 = 35.86
! calculate water vapor pressure close to sea surface
e_w = r * exp(c_1 * (temperature_surface - 273.15) / (temperature_surface - c_2))
! calculate specific vapor content close to sea surface
q_w = epsilon * e_w / P_0
vel = sqrt(u_atmos*u_atmos + v_atmos*v_atmos) ! atmospheric velocity (m/s)
! mass flux of evaporation
flux_mass_evap = rho_a * c_aw * vel * (q_w - specific_vapor_content_atmos)
end subroutine flux_mass_evap_meier
end module flux_mass_evap

31
src/flux_lib/momentum/flux_momentum.F90

@ -15,6 +15,7 @@ module flux_momentum
! expose all functions
public flux_momentum_cclm
public flux_momentum_mom5
public flux_momentum_meier
contains
@ -106,4 +107,34 @@ contains
end subroutine flux_momentum_mom5
subroutine flux_momentum_meier( &
flux_momentum_east, & ! RESULT (N/m2)
flux_momentum_north, & ! RESULT (N/m2)
u_atmos, & ! u_a (m/s)
v_atmos & ! v_a (m/s)
)
real(prec), intent(out) :: flux_momentum_east ! RESULT (N/m2)
real(prec), intent(out) :: flux_momentum_north ! RESULT (N/m2)
real(prec), intent(in) :: u_atmos ! u_a (m/s)
real(prec), intent(in) :: v_atmos ! v_a (m/s)
real(prec) :: rho_a = 1.225 ! air density [kg / m^3]
real(prec) :: c_aw ! transfer coefficient for momentum [1]
real(prec) :: vel ! absolute value of wind speed
vel = sqrt(u_atmos*u_atmos + v_atmos*v_atmos) ! atmospheric velocity (m/s)
! get Stanton number according to temperature difference
IF (vel .lt. 11.0) THEN
c_aw = 1.2E-03
ELSE
c_aw = 0.49E-03 + 0.065E-03 * vel
ENDIF
flux_momentum_east = - rho_a * c_aw * vel * u_atmos
flux_momentum_north = - rho_a * c_aw * vel * v_atmos
end subroutine flux_momentum_meier
end module flux_momentum
Loading…
Cancel
Save