Skip to content

Commit ff87e8a

Browse files
authored
Merge pull request #10 from NCAR/hgoelzer/tempunstag
Add initialization with unstaggered temperature from glide
2 parents b86fbe4 + 72cbf87 commit ff87e8a

File tree

5 files changed

+115
-48
lines changed

5 files changed

+115
-48
lines changed

libglide/glide_setup.F90

+3-2
Original file line numberDiff line numberDiff line change
@@ -689,11 +689,12 @@ subroutine print_options(model)
689689
'constant in time ', &
690690
'prognostic enthalpy ' /)
691691

692-
character(len=*), dimension(0:3), parameter :: temp_init = (/ &
692+
character(len=*), dimension(0:4), parameter :: temp_init = (/ &
693693
'set to 0 C ', &
694694
'set to surface air temp ', &
695695
'linear vertical profile ', &
696-
'advective-diffusive balance ' /)
696+
'advective-diffusive balance ',&
697+
'temp from external file ' /)
697698

698699
character(len=*), dimension(0:3), parameter :: flow_law = (/ &
699700
'const 1e-16 Pa^-n a^-1 ', &

libglide/glide_types.F90

+10
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ module glide_types
9595
integer, parameter :: TEMP_INIT_ARTM = 1
9696
integer, parameter :: TEMP_INIT_LINEAR = 2
9797
integer, parameter :: TEMP_INIT_ADVECTIVE_DIFFUSIVE = 3
98+
integer, parameter :: TEMP_INIT_EXTERNAL = 4
9899

99100
integer, parameter :: FLWA_CONST_FLWA = 0
100101
integer, parameter :: FLWA_PATERSON_BUDD_CONST_TEMP = 1
@@ -368,6 +369,7 @@ module glide_types
368369
!> \item[1] Initialize temperature to surface air temperature
369370
!> \item[2] Initialize temperature with a linear profile in each column
370371
!> \item[3] Initialize temperature with an advective-diffusive balance in each column
372+
!> \item[4] Initialize temperature from external file
371373
!> \end{description}
372374

373375
!> Method for calculating flow factor $A$:
@@ -1183,6 +1185,7 @@ module glide_types
11831185
! whereas bheatflx is defined as positive downward.
11841186

11851187
real(dp),dimension(:,:,:),pointer :: temp => null() !> 3D temperature field.
1188+
real(dp),dimension(:,:,:),pointer :: tempunstag => null()!> 3D temperature field unstaggered in the vertical.
11861189
real(dp),dimension(:,:), pointer :: bheatflx => null() !> basal heat flux (W/m^2) (geothermal, positive down)
11871190
real(dp),dimension(:,:,:),pointer :: flwa => null() !> Glen's flow factor $A$.
11881191
real(dp),dimension(:,:,:),pointer :: dissip => null() !> interior heat dissipation rate, divided by rhoi*Ci (deg/s)
@@ -1934,6 +1937,9 @@ subroutine glide_allocarr(model)
19341937
call coordsystem_allocate(model%general%ice_grid, upn, model%temper%dissip)
19351938
else ! glam/glissade dycore
19361939
allocate(model%temper%temp(0:upn,1:ewn,1:nsn))
1940+
! tempunstag has the same horizontal grid as the glam/glissade temp, but a
1941+
! vertical axis like the glide temp
1942+
allocate(model%temper%tempunstag(upn,1:ewn,1:nsn))
19371943
call coordsystem_allocate(model%general%ice_grid, upn-1, model%temper%flwa)
19381944
call coordsystem_allocate(model%general%ice_grid, upn-1, model%temper%dissip)
19391945
endif
@@ -1943,6 +1949,8 @@ subroutine glide_allocarr(model)
19431949
model%temper%temp(:,:,:) = unphys_val ! large negative number
19441950
model%temper%flwa(:,:,:) = unphys_val
19451951
model%temper%dissip(:,:,:) = 0.d0
1952+
if (associated(model%temper%tempunstag)) &
1953+
model%temper%tempunstag(:,:,:) = unphys_val
19461954

19471955
call coordsystem_allocate(model%general%ice_grid, model%temper%bheatflx)
19481956
call coordsystem_allocate(model%general%ice_grid, model%temper%bwat)
@@ -2264,6 +2272,8 @@ subroutine glide_deallocarr(model)
22642272

22652273
if (associated(model%temper%temp)) &
22662274
deallocate(model%temper%temp)
2275+
if (associated(model%temper%tempunstag)) &
2276+
deallocate(model%temper%tempunstag)
22672277
if (associated(model%temper%bheatflx)) &
22682278
deallocate(model%temper%bheatflx)
22692279
if (associated(model%temper%bwat)) &

libglide/glide_vars.def

+9
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,15 @@ standard_name: land_ice_temperature_stag
12161216
load: 1
12171217
coordinates: lon lat
12181218

1219+
[tempunstag]
1220+
dimensions: time, level, y1, x1
1221+
units: degree_Celsius
1222+
long_name: ice temperature on unstaggered vertical levels
1223+
data: data%temper%tempunstag(up,1:data%general%ewn,1:data%general%nsn)
1224+
standard_name: land_ice_temperature_unstag
1225+
load: 1
1226+
coordinates: lon lat
1227+
12191228
[bpmp]
12201229
dimensions: time, y1, x1
12211230
units: degree_Celsius

libglissade/glissade.F90

+15-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,8 @@ subroutine glissade_initialise(model, evolve_ice)
364364
model%climate%acab*thk0/tim0, & ! m/s
365365
model%temper%bheatflx, & ! W/m^2, positive down
366366
model%temper%pmp_offset, & ! deg C
367-
model%temper%temp) ! deg C
367+
model%temper%temp, & ! deg C
368+
model%temper%tempunstag) ! deg C
368369

369370
if (model%options%gthf == GTHF_COMPUTE) then
370371
call not_parallel(__FILE__,__LINE__)
@@ -985,6 +986,8 @@ subroutine glissade_thermal_solve(model, dt)
985986
bmlt_ground_unscaled, & ! basal melt rate for grounded ice (m/s)
986987
bwat_unscaled ! basal water thickness (m)
987988

989+
integer :: up
990+
988991
call t_startf('glissade_thermal_solve')
989992

990993
if (main_task .and. verbose_glissade) print*, 'Call glissade_therm_driver'
@@ -1034,6 +1037,17 @@ subroutine glissade_thermal_solve(model, dt)
10341037
model%basal_melt%bmlt_ground(:,:) = bmlt_ground_unscaled(:,:) * tim0/thk0
10351038
model%temper%bwat(:,:) = bwat_unscaled(:,:) / thk0
10361039

1040+
! Update tempunstag as sigma weighted interpolation from temp to layer interfaces
1041+
do up = 2, model%general%upn-1
1042+
model%temper%tempunstag(up,:,:) = model%temper%temp(up-1,:,:) + &
1043+
(model%temper%temp(up,:,:) - model%temper%temp(up-1,:,:)) * &
1044+
(model%numerics%sigma(up) - model%numerics%stagsigma(up-1)) / &
1045+
(model%numerics%stagsigma(up) - model%numerics%stagsigma(up-1))
1046+
end do
1047+
! boundary conditions are identical on both grids, but temp starts at index 0
1048+
model%temper%tempunstag(1,:,:) = model%temper%temp(0,:,:)
1049+
model%temper%tempunstag(model%general%upn,:,:) = model%temper%temp(model%general%upn,:,:)
1050+
10371051
!------------------------------------------------------------------------
10381052
! Halo updates
10391053
!------------------------------------------------------------------------

libglissade/glissade_therm.F90

+78-45
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ subroutine glissade_init_therm (temp_init, is_restart, &
102102
artm, &
103103
acab, &
104104
bheatflx, &
105-
pmp_offset, temp)
105+
pmp_offset, &
106+
temp, tempunstag)
106107

107108
! initialization subroutine for higher-order dycores, where temperature is defined at
108109
! the midpoint of each layer plus the upper and lower surfaces
@@ -137,6 +138,12 @@ subroutine glissade_init_therm (temp_init, is_restart, &
137138
temp ! ice temperature
138139
! intent(inout) because it might have been read already from an input file,
139140
! but otherwise is set in this subroutine
141+
142+
real(dp), dimension(:,:,:), intent(inout) :: &
143+
tempunstag ! ice temperature on unstaggered grid
144+
! may be used to initialize from an unstaggered glide temperature field
145+
! intent(inout) because it might have been read from an input file,
146+
! but otherwise it is set (diagnostically) in this subroutine
140147

141148
! Local variables
142149

@@ -146,12 +153,6 @@ subroutine glissade_init_therm (temp_init, is_restart, &
146153

147154
logical :: verbose_column ! if true, then write diagnostic info for the column
148155

149-
!WHL - option to overwrite initial temperature in input file
150-
! Can be useful is working with an input file that includes initial temperatures,
151-
! but we want to set a linear temperature profile instead
152-
!TODO - Make this a config option?
153-
logical, parameter :: overwrite_input_temps = .false.
154-
155156
! Precompute some grid quantities used in the vertical temperature solve
156157

157158
allocate(dups(upn+1,2)) !TODO - upn-1 instead?
@@ -171,61 +172,93 @@ subroutine glissade_init_therm (temp_init, is_restart, &
171172
up = upn-1
172173
dups(up,2) = 1.d0/((sigma(up+1) - sigma(up)) * (sigma(up+1) - stagsigma(up)) )
173174

174-
! Check for a possible input error. If the user supplies a file with the 'temp' field, which has
175-
! vertical dimension (1:upn), then the temperature in layers 1:upn may appear correct (though
176-
! staggered incorrectly), but the temperature in layer 0 will remain at an unphysical value.
177-
! Let the user know if this has happened.
178-
!WHL - Nov. 2014 - I verified that the code aborts here if temp (rather than tempstag) is in the restart file.
179-
180-
if (minval(temp(0,:,:)) < (-1.d0*trpt) .and. minval(temp(1:upn,:,:)) > (-1.d0*trpt)) then
181-
call write_log('Error, temperature field has been read incorrectly. Note that the ' &
182-
// 'Glissade dycore must be initialized with tempstag, not temp.', GM_FATAL)
183-
endif
184175

185176
!==== Initialize ice temperature.============
186-
! Six possibilities:
187-
! (1) Set ice temperature to 0 C everywhere in column (TEMP_INIT_ZERO).
188-
! (2) Set ice temperature to surface air temperature everywhere in column (TEMP_INIT_ARTM).
189-
! (3) Set up a linear temperature profile, with T = artm at the surface and T <= Tpmp
177+
! Following possibilities:
178+
! (0) Set ice temperature to 0 C everywhere in column (TEMP_INIT_ZERO).
179+
! (1) Set ice temperature to surface air temperature everywhere in column (TEMP_INIT_ARTM).
180+
! (2) Set up a linear temperature profile, with T = artm at the surface and T <= Tpmp
190181
! at the bed (TEMP_INIT_LINEAR).
191182
! A parameter (pmpt_offset) controls how far below Tpmp the initial bed temp is set.
192-
! (4) Set up a temperature profile based on advective-diffusive balance, with T = artm
183+
! (3) Set up a temperature profile based on advective-diffusive balance, with T = artm
193184
! at the surface and dT/dz = -F_geo/k at the bed (TEMP_INIT_ADVECTIVE_DIFFUSIVE).
194185
! The temperature at each level is capped at the value computed by method (3).
195-
! (5) Read ice temperature from an initial input file.
196-
! (6) Read ice temperature from a restart file.
186+
! (4) Read ice temperature from external file (TEMP_INIT_EXTERNAL).
187+
! (4a) If variable tempstag is present: Set ice temperature to tempstag from input file.
188+
! (4b) If variable tempunstag is present (and tempstag is not): interpolate tempunstag
189+
! to the staggered ice temperature needed by the Glissade dycore.
197190
!
198-
! The default is (2).
199-
! Method (4) may be optimal for reducing spinup time in the interior of large ice sheets.
200-
! If not restarting and the temperature field is present in the input file, we do (5).
201-
! If restarting, we always do (6).
202-
! If (5) or (6), then the temperature field should already have been read from a file,
203-
! and the rest of this subroutine will do nothing.
204-
! Otherwise, the initial temperature is controlled by model%options%temp_init,
205-
! which can be read from the config file.
191+
! The default is (1).
192+
! Methods (0-3) overwrite any temperature given in input files.
193+
! Method (3) may be optimal for reducing spinup time in the interior of large ice sheets.
194+
! Option (4) requires that temperature is present in the input file.
195+
196+
if (temp_init == TEMP_INIT_EXTERNAL) then
197+
198+
! Temperature from external file
199+
200+
! Check for a possible input error. If the user supplies a file with the 'temp' field, which has
201+
! vertical dimension (1:upn), then the temperature in layers 1:upn may appear correct (though
202+
! staggered incorrectly), but the temperature in layer 0 will remain at an unphysical value.
203+
! Let the user know if this has happened.
204+
!WHL - Nov. 2014 - I verified that the code aborts here if temp (rather than tempstag) is in the restart file.
205+
206+
if (minval(temp(0,:,:)) < (-1.d0*trpt) .and. minval(temp(1:upn,:,:)) > (-1.d0*trpt)) then
207+
call write_log('Error, temperature field has been read incorrectly. Note that the ' &
208+
// 'Glissade dycore must be initialized with tempstag, not temp.' &
209+
// 'You can rename temp to tempunstag if you want it to be interpolated ' &
210+
// 'to the vertically staggered tempstag (loss of detail).', GM_FATAL)
211+
endif
206212

207-
if (is_restart == RESTART_TRUE) then
208213

209-
! Temperature has already been initialized from a restart file.
210-
! (Temperature is always a restart variable.)
214+
if ( minval(temp) > (-1.0d0 * trpt)) then ! temperature has been read from an input file
215+
! Note: trpt = 273.15 K
211216

212-
call write_log('Initializing ice temperature from the restart file')
217+
! Temperature has already been initialized from a restart or input file.
218+
! We know this because the default initial temps of unphys_val
219+
! (a large negative number) have been overwritten.
213220

214-
!WHL - debug - option to overwrite input file
215-
!! elseif ( minval(temp) > (-1.0d0 * trpt) ) then ! temperature has been read from an input file
216-
elseif ( minval(temp) > (-1.0d0 * trpt) .and. .not.overwrite_input_temps) then ! temperature has been read from an input file
217-
! Note: trpt = 273.15 K
221+
! Initialise tempunstag, the temperature on unstaggered vertical grid
222+
! (not used for calculations)
223+
! Use sigma weighted interpolation from temp to layer interfaces
224+
do up = 2, upn-1
225+
tempunstag(up,:,:) = temp(up-1,:,:) + (temp(up,:,:) - temp(up-1,:,:)) * &
226+
(sigma(up) - stagsigma(up-1)) / (stagsigma(up) - stagsigma(up-1))
227+
end do
228+
! boundary conditions are identical on both grids, but temp starts at index 0
229+
tempunstag(1,:,:) = temp(0,:,:)
230+
tempunstag(upn,:,:) = temp(upn,:,:)
218231

219-
! Temperature has already been initialized from an input file.
220-
! We know this because the default initial temps of unphys_val (a large negative number) have been overwritten.
232+
call write_log('Initializing ice temperature from a restart/input file')
233+
234+
235+
elseif ( maxval(tempunstag(:,:,:)) > (-1.0d0 * trpt)) then
236+
237+
! Test if any temperature in physical range
238+
! If yes, we have data from restart or input for unstaggered tempunstag that we use to initialise temp
239+
240+
call write_log('Initializing ice temperature by interpolating tempunstag from restart/input file')
241+
242+
! Set temp to linear interpolation from tempunstag at layer interfaces
243+
do up = 1, upn-1
244+
temp(up,:,:) = (tempunstag(up,:,:) + tempunstag(up+1,:,:)) * 0.5d0
245+
end do
246+
! boundary conditions are identical on both grids, but temp starts at index 0
247+
temp(0,:,:) = tempunstag(1,:,:)
248+
temp(upn,:,:) = tempunstag(upn,:,:)
249+
250+
else
251+
! fatal error, neither tempstag nor tempunstag are present in the input files
252+
call write_log('Error, temp_init = 4 requires temperature variable tempstag or ' &
253+
// 'tempunstag specified in the restart or input files. ', GM_FATAL)
254+
endif
221255

222-
call write_log('Initializing ice temperature from an input file')
223256

224257
else ! not reading temperature from restart or input file
225-
! initialize it here based on temp_init
258+
! initialize it here based on temp_init = (0-3)
226259

227260
! initialize T = 0 C everywhere
228-
temp(:,:,:) = 0.0d0
261+
temp(:,:,:) = 0.0d0
229262

230263
! set temperature in each column based on the value of temp_init
231264

0 commit comments

Comments
 (0)