Skip to content

Commit 7f2a4a0

Browse files
committed
Calculate huss and other variables on the fly. COSIMA/access-om2#242
1 parent f309fc9 commit 7f2a4a0

File tree

3 files changed

+69
-11
lines changed

3 files changed

+69
-11
lines changed

libforcing/src/forcing_field.F90

+54-6
Original file line numberDiff line numberDiff line change
@@ -172,18 +172,66 @@ subroutine forcing_field_calculate(self, file_index, result_array)
172172
integer, intent(in) :: file_index
173173
real, dimension(:, :), intent(inout) :: result_array
174174

175+
real, dimension(:, :), allocatable, target :: tmp1, tmp2
176+
real, dimension(:, :), allocatable :: E
177+
real, dimension(:, :), pointer :: Td, sp
178+
179+
integer :: nx, ny
180+
real, parameter :: RDRY = 287.0597
181+
real, parameter :: RVAP = 461.5250
182+
real, parameter :: A1 = 611.21
183+
real, parameter :: A3 = 17.502
184+
real, parameter :: A4 = 32.19
185+
real, parameter :: T0 = 273.16
186+
175187
if (trim(self%product_name) == 'ERA5') then
188+
189+
nx = self%ncvars(1)%nx
190+
ny = self%ncvars(1)%ny
191+
allocate(tmp1(nx, ny), tmp2(nx, ny))
192+
176193
if (trim(self%coupling_name) == 'rain_ai') then
177-
! Rain is calculated as total precipitation - snow
178-
! FIXME: do calculation with field name checks
179-
call self%ncvars(1)%read_data(file_index, result_array)
194+
! Rain is calculated as mcpr
195+
! (mean convective precipitation rate [kg m**-2 s**-1]) plus
196+
! mlspr (mean large-scale precipitation rate [kg m**-2 s**-1])
197+
call self%ncvars(1)%read_data(file_index, tmp1)
198+
call self%ncvars(2)%read_data(file_index, tmp2)
199+
result_array(:, :) = tmp1(:, :) + tmp2(:, :)
200+
201+
elseif (trim(self%coupling_name) == 'runof_ai') then
202+
! Runoff is calculated as msror
203+
! (mean surface runoff rate [kg m**-2 s**-1]) plus
204+
! mssror (mean sub-surface runoff rate [kg m**-2 s**-1])
205+
206+
call self%ncvars(1)%read_data(file_index, tmp1)
207+
call self%ncvars(2)%read_data(file_index, tmp2)
208+
result_array(:, :) = tmp1(:, :) + tmp2(:, :)
209+
180210
elseif (trim(self%coupling_name) == 'qair_ai') then
181-
! Humidity is calculated using surface temperature and dew point
182-
! FIXME: do calculation with field name checks
183-
call self%ncvars(1)%read_data(file_index, result_array)
211+
! Specific humidity at 2m
212+
213+
call assert(self%ncvars(1)%name == 'd2m', &
214+
'Unexpected name for in huss calculation')
215+
call assert(self%ncvars(2)%name == 'sp', &
216+
'Unexpected name for surface pressure')
217+
218+
call self%ncvars(1)%read_data(file_index, tmp1)
219+
call self%ncvars(2)%read_data(file_index, tmp2)
220+
Td => tmp1
221+
sp => tmp2
222+
223+
! Saturation water vapour from Teten's formula
224+
allocate(E(nx, ny))
225+
E = A1*exp(A3*(Td-T0)/(Td-A4))
226+
227+
! Saturation specific humidity at 2m
228+
result_array(:, :) = (RDRY/RVAP)*E / (sp-((1-RDRY/RVAP)*E))
229+
deallocate(E)
184230
else
185231
call self%ncvars(1)%read_data(file_index, result_array)
186232
endif
233+
234+
deallocate(tmp1, tmp2)
187235
elseif (trim(self%product_name) == 'JRA55-do') then
188236
call self%ncvars(1)%read_data(file_index, result_array)
189237
else

libforcing/src/util.F90

+11-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ subroutine read_data(ncid, varid, varname, indx, dataout)
5151

5252
integer, dimension(:), allocatable :: count, start
5353
real, dimension(1) :: scalar_dataout
54-
integer :: ndims, nx, ny, time
54+
integer :: ndims, nx, ny, time, status
55+
real :: scale_factor, offset
5556

5657
call get_var_dims(ncid, varid, ndims, nx, ny, time)
5758
call assert(ndims == 1 .or. ndims == 2 .or. ndims == 3 .or. ndims == 4, &
@@ -85,6 +86,15 @@ subroutine read_data(ncid, varid, varname, indx, dataout)
8586
'Get var '//trim(varname))
8687
endif
8788

89+
status = nf90_get_att(ncid, varid, "scale_factor", scale_factor)
90+
if (status == nf90_noerr) then
91+
dataout(:, :) = dataout(:, :) * scale_factor
92+
endif
93+
status = nf90_get_att(ncid, varid, "add_offset", offset)
94+
if (status == nf90_noerr) then
95+
dataout(:, :) = dataout(:, :) + offset
96+
endif
97+
8898
deallocate(count, start)
8999

90100
end subroutine read_data

tests/ERA5/forcing.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,13 @@
8282
{
8383
"coupling_field_name": "qair_ai",
8484
"input_fields": [
85-
{
86-
"filename": "/g/data/rt52/era5/single-levels/reanalysis/2t/{{year}}/2t_era5_oper_sfc_{{year}}{{month}}{{start_day}}-{{year}}{{month}}{{end_day}}.nc",
87-
"fieldname": "t2m"
88-
},
8985
{
9086
"filename": "/g/data/rt52/era5/single-levels/reanalysis/2d/{{year}}/2d_era5_oper_sfc_{{year}}{{month}}{{start_day}}-{{year}}{{month}}{{end_day}}.nc",
9187
"fieldname": "d2m"
88+
},
89+
{
90+
"filename": "/g/data/rt52/era5/single-levels/reanalysis/sp/{{year}}/sp_era5_oper_sfc_{{year}}{{month}}{{start_day}}-{{year}}{{month}}{{end_day}}.nc",
91+
"fieldname": "sp"
9292
}
9393
]
9494
},

0 commit comments

Comments
 (0)