Browse Source

Merge branch 'experiments/tc-meier'

1.02.00
Sven Karsten 11 months ago
parent
commit
ab176c62e4
  1. 9
      src/flux_calculator_basic.F90
  2. 75
      src/flux_calculator_calculate.F90
  3. 49
      src/flux_calculator_prepare.F90
  4. 12
      src/flux_lib/flux_library.F90
  5. 70
      src/flux_lib/heat/flux_heat_sensible.F90
  6. 77
      src/flux_lib/mass/flux_mass_evap.F90
  7. 64
      src/flux_lib/momentum/flux_momentum.F90

9
src/flux_calculator_basic.F90

@ -39,10 +39,11 @@ MODULE flux_calculator_basic
! (3) declare idx_varname !
! (4) add a line in init_varname_idx !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
INTEGER, PARAMETER :: MAX_VARNAMES = 32
INTEGER, PARAMETER :: MAX_VARNAMES = 35
CHARACTER(len=4), PARAMETER, DIMENSION(MAX_VARNAMES) :: varnames = [ &
'ALBE', 'ALBA', 'AMOI', 'AMOM', 'FARE', 'FICE', 'PATM', 'PSUR', &
'QATM', 'TATM', 'TSUR', 'UATM', 'VATM', 'U10M', 'V10M', & ! variables read in
'CMOM', 'CMOI', 'CHEA', & ! transfer coefficients from ocean model
'QSUR', & ! auxiliary variables calculated
'HLAT', 'HSEN', & ! heat fluxes
'MEVA', 'MPRE', 'MRAI', 'MSNO', & ! mass fluxes
@ -51,6 +52,7 @@ MODULE flux_calculator_basic
INTEGER :: idx_ALBE, idx_ALBA, idx_AMOI, idx_AMOM, idx_FARE, idx_FICE, idx_PATM, idx_PSUR
INTEGER :: idx_QATM, idx_TATM, idx_TSUR, idx_UATM, idx_VATM, idx_U10M, idx_V10M
INTEGER :: idx_CMOM, idx_CMOI, idx_CHEA
INTEGER :: idx_QSUR
INTEGER :: idx_HLAT, idx_HSEN
INTEGER :: idx_MEVA, idx_MPRE, idx_MRAI, idx_MSNO
@ -146,7 +148,7 @@ MODULE flux_calculator_basic
input_field(num_input_fields)%which_grid = which_grid
input_field(num_input_fields)%field => local_field%var(i)%field
input_field(num_input_fields)%early=.FALSE.
IF ((myname=="FARE") .OR. (myname=="TSUR") .OR. (myname=="ALBE")) THEN
IF ((myname=="FARE") .OR. (myname=="TSUR") .OR. (myname=="ALBE") .OR. (myname=="CMOM") .OR. (myname=="CMOI") .OR. (myname=="CHEA")) THEN
input_field(num_input_fields)%early=.TRUE.
ENDIF
input_field(num_input_fields)%surface_type = surface_type
@ -537,6 +539,9 @@ MODULE flux_calculator_basic
IF (varnames(i) == 'VATM') idx_VATM = i ! Northward velocity in lowest atmospheric grid cell (m/s)
IF (varnames(i) == 'U10M') idx_U10M = i ! Eastward velocity 10m above the surface (m/s)
IF (varnames(i) == 'V10M') idx_V10M = i ! Northward velocity 10m above the surface (m/s)
IF (varnames(i) == 'CMOM') idx_CMOM = i ! Momentum transfer coefficient fom ocean model (1)
IF (varnames(i) == 'CMOI') idx_CMOI = i ! Moisture transfer coefficient fom ocean model (1)
IF (varnames(i) == 'CHEA') idx_CHEA = i ! Heat transfer coefficient fom ocean model (1)
! AUXILIARY VARIABLES:
IF (varnames(i) == 'QSUR') idx_QSUR = i ! Moisture content directly above the surface (kg/kg)
! FLUXES: (all are positive upward, such that e.g. precipitation is always negative)

75
src/flux_calculator_calculate.F90

@ -74,6 +74,25 @@ 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)=='MOM5') THEN
DO j=1,grid_size(1)
CALL flux_mass_evap_mom5(local_field(i,1)%var(idx_MEVA)%field(j), &
local_field(i,1)%var(idx_CMOI)%field(j), &
local_field(i,1)%var(idx_PSUR)%field(j), &
local_field(i,1)%var(idx_QATM)%field(j), &
local_field(i,1)%var(idx_QSUR)%field(j), &
local_field(i,1)%var(idx_TATM)%field(j), &
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
@ -142,6 +161,26 @@ 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)=='MOM5') THEN
DO j=1,grid_size(1)
CALL flux_heat_sensible_mom5(local_field(i,1)%var(idx_HSEN)%field(j), &
local_field(i,1)%var(idx_CHEA)%field(j), &
local_field(i,1)%var(idx_PATM)%field(j), &
local_field(i,1)%var(idx_PSUR)%field(j), &
local_field(i,1)%var(idx_QATM)%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
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
@ -179,6 +218,24 @@ 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)=='MOM5') THEN
DO j=1,grid_size(which_grid)
CALL flux_momentum_mom5(local_field(i,which_grid)%var(idx_UMOM)%field(j), &
dummy, &
local_field(i,which_grid)%var(idx_CMOM)%field(j), &
local_field(i,which_grid)%var(idx_PSUR)%field(j), &
local_field(i,which_grid)%var(idx_QSUR)%field(j), &
local_field(i,which_grid)%var(idx_TSUR)%field(j), &
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
@ -214,6 +271,24 @@ 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)=='MOM5') THEN
DO j=1,grid_size(which_grid)
CALL flux_momentum_mom5(dummy, &
local_field(i,which_grid)%var(idx_VMOM)%field(j), &
local_field(i,which_grid)%var(idx_CMOM)%field(j), &
local_field(i,which_grid)%var(idx_PSUR)%field(j), &
local_field(i,which_grid)%var(idx_QSUR)%field(j), &
local_field(i,which_grid)%var(idx_TSUR)%field(j), &
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

49
src/flux_calculator_prepare.F90

@ -94,6 +94,19 @@ 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)=='MOM5') THEN
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_CMOI)%field )) missing_field=trim(missing_field)//' CMOI'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_PSUR)%field )) missing_field=trim(missing_field)//' PSUR'
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)//' QSUR'
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. "
@ -155,6 +168,20 @@ 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)=='MOM5') THEN
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_CHEA)%field )) missing_field=trim(missing_field)//' CHEA'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_PATM)%field )) missing_field=trim(missing_field)//' PATM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_PSUR)%field )) missing_field=trim(missing_field)//' PSUR'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_QSUR)%field )) missing_field=trim(missing_field)//' QSUR'
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'
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. "
@ -187,6 +214,16 @@ 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)=='MOM5') THEN
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_CMOM)%field )) missing_field=trim(missing_field)//' CMOM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_PSUR)%field )) missing_field=trim(missing_field)//' PSUR'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_QSUR)%field )) missing_field=trim(missing_field)//' QSUR'
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. "
@ -217,7 +254,17 @@ 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'
ELSE
ELSEIF (trim(method)=='MOM5') THEN
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_CMOM)%field )) missing_field=trim(missing_field)//' CMOM'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_PSUR)%field )) missing_field=trim(missing_field)//' PSUR'
IF (.NOT. ASSOCIATED( local_field(surface_type,which_grid)%var(idx_QSUR)%field )) missing_field=trim(missing_field)//' QSUR'
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. "
CALL mpi_finalize(1)

12
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
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
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
use flux_momentum, only: flux_momentum_cclm, flux_momentum_mom5, flux_momentum_meier
implicit none ; private
@ -32,8 +32,14 @@ module flux_library
public flux_heat_latent_ice
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

70
src/flux_lib/heat/flux_heat_sensible.F90

@ -16,6 +16,8 @@ module flux_heat_sensible
! expose all functions
public flux_heat_sensible_cclm
public flux_heat_sensible_mom5
public flux_heat_sensible_meier
contains
@ -95,6 +97,74 @@ contains
flux_heat_sensible = flux_air * heat_capacity_air * & ! sensible heat flux (W/m2)
(temperature_surface - temperature_atmos * EF)
end subroutine flux_heat_sensible_cclm
subroutine flux_heat_sensible_mom5( &
flux_heat_sensible, & ! RESULT (W/m2)
diffusion_coefficient_moisture, & ! a_{moisture} (1)
pressure_atmos, & ! p_a (Pa)
pressure_surface, & ! p_s (Pa)
specific_vapor_content_surface, & ! q_{v,s} (kg/kg)
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) :: diffusion_coefficient_moisture ! a_{moisture} (1)
real(prec), intent(in) :: pressure_atmos ! p_a (Pa)
real(prec), intent(in) :: pressure_surface ! p_s (Pa)
real(prec), intent(in) :: specific_vapor_content_surface ! q_{v,s} (kg/kg)
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)
call flux_heat_sensible_cclm(flux_heat_sensible, & ! RESULT (W/m2)
diffusion_coefficient_moisture, & ! a_{moisture} (1)
pressure_atmos, & ! p_a (Pa)
pressure_surface, & ! p_s (Pa)
specific_vapor_content_surface, & ! q_{v,s} (kg/kg)
temperature_atmos, & ! T_a (K)
temperature_surface, & ! T_s (K)
u_atmos, & ! u_a (m/s)
v_atmos & ! v_a (m/s)
)
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

77
src/flux_lib/mass/flux_mass_evap.F90

@ -14,6 +14,8 @@ module flux_mass_evap
! expose all functions
public flux_mass_evap_cclm
public flux_mass_evap_mom5
public flux_mass_evap_meier
contains
@ -77,9 +79,82 @@ 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
subroutine flux_mass_evap_mom5( &
flux_mass_evap, & ! RESULT (kg/m2/s)
diffusion_coefficient_moisture, & ! a_{moisture} (1)
pressure_surface, & ! p_s (Pa)
specific_vapor_content_atmos, & ! q_{v,a} (kg/kg)
specific_vapor_content_surface, & ! q_{v,s} (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) :: diffusion_coefficient_moisture ! a_{moisture} (1)
real(prec), intent(in) :: pressure_surface ! p_s (Pa)
real(prec), intent(in) :: specific_vapor_content_atmos ! q_{v,a} (kg/kg)
real(prec), intent(in) :: specific_vapor_content_surface ! q_{v,s} (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)
call flux_mass_evap_cclm(flux_mass_evap, & ! RESULT (kg/m2/s)
diffusion_coefficient_moisture, & ! a_{moisture} (1)
pressure_surface, & ! p_s (Pa)
specific_vapor_content_atmos, & ! q_{v,a} (kg/kg)
specific_vapor_content_surface, & ! q_{v,s} (kg/kg)
temperature_surface, & ! T_s (K)
u_atmos, & ! u_a (m/s)
v_atmos & ! v_a (m/s)
)
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

64
src/flux_lib/momentum/flux_momentum.F90

@ -14,6 +14,8 @@ module flux_momentum
! expose all functions
public flux_momentum_cclm
public flux_momentum_mom5
public flux_momentum_meier
contains
@ -73,4 +75,66 @@ contains
end subroutine flux_momentum_cclm
subroutine flux_momentum_mom5( &
flux_momentum_east, & ! RESULT (N/m2)
flux_momentum_north, & ! RESULT (N/m2)
diffusion_coefficient_momentum, & ! a_{momentum} (1)
pressure_surface, & ! p_s (Pa)
specific_vapor_content_surface, & ! q_{v,s} (kg/kg)
temperature_surface, & ! T_s (K)
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) :: diffusion_coefficient_momentum ! a_{momentum} (1)
real(prec), intent(in) :: pressure_surface ! p_s (Pa)
real(prec), intent(in) :: specific_vapor_content_surface ! q_{v,s} (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)
call flux_momentum_cclm(flux_momentum_east, & ! RESULT (N/m2)
flux_momentum_north, & ! RESULT (N/m2)
diffusion_coefficient_momentum, & ! a_{momentum} (1)
pressure_surface, & ! p_s (Pa)
specific_vapor_content_surface, & ! q_{v,s} (kg/kg)
temperature_surface, & ! T_s (K)
u_atmos, & ! u_a (m/s)
v_atmos & ! v_a (m/s)
)
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