-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdynInitColumnsMod.F90
More file actions
268 lines (227 loc) · 12.3 KB
/
dynInitColumnsMod.F90
File metadata and controls
268 lines (227 loc) · 12.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
module dynInitColumnsMod
!---------------------------------------------------------------------------
!
! !DESCRIPTION:
! Handle initialization of columns that just switched from inactive to active
!
! !USES:
#include "shr_assert.h"
use shr_kind_mod , only : r8 => shr_kind_r8
use shr_log_mod , only : errMsg => shr_log_errMsg
use decompMod , only : bounds_type, subgrid_level_column
use abortutils , only : endrun, write_point_context
use clm_varctl , only : iulog
use TemperatureType , only : temperature_type
use WaterType , only : water_type
use SoilHydrologyType , only : soilhydrology_type
use GridcellType , only : grc
use LandunitType , only : lun
use ColumnType , only : col
use dynColumnTemplateMod , only : template_col_from_landunit, TEMPLATE_NONE_FOUND
!
! !PUBLIC MEMBER FUNCTIONS:
implicit none
private
!
! The following is the public interface to the routines in this module:
public :: initialize_new_columns ! Do initialization for all columns that are newly-active in this time step
! The following are public only for unit testing purposes, and should not be called
! directly by application code:
public :: initial_template_col_crop ! Find column to use as a template for a crop column that has newly become active
!
! !PRIVATE MEMBER FUNCTIONS:
private :: initial_template_col_dispatcher ! Find column to use as a template; dispatcher to the appropriate routine based on landunit type
private :: initial_template_col_soil ! Find column to use as a template for a vegetated column that has newly become active
private :: copy_state ! Copy a subset of state variables from template column to newly-active column
character(len=*), parameter, private :: sourcefile = &
__FILE__
!---------------------------------------------------------------------------
contains
!-----------------------------------------------------------------------
subroutine initialize_new_columns(bounds, cactive_prior, &
temperature_inst, water_inst)
!
! !DESCRIPTION:
! Do initialization for all columns that are newly-active in this time step
!
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds ! bounds
logical , intent(in) :: cactive_prior( bounds%begc: ) ! column-level active flags from prior time step
type(temperature_type) , intent(inout) :: temperature_inst
type(water_type) , intent(inout) :: water_inst
!
! !LOCAL VARIABLES:
integer :: c ! column index
integer :: c_template ! index of template column
character(len=*), parameter :: subname = 'initialize_new_columns'
!-----------------------------------------------------------------------
SHR_ASSERT_ALL_FL((ubound(cactive_prior) == (/bounds%endc/)), sourcefile, __LINE__)
do c = bounds%begc, bounds%endc
! If this column is newly-active, then we need to initialize it using the routines in this module
if (col%active(c) .and. .not. cactive_prior(c)) then
c_template = initial_template_col_dispatcher(bounds, c, cactive_prior(bounds%begc:bounds%endc))
if (c_template /= TEMPLATE_NONE_FOUND) then
call copy_state(c, c_template, &
temperature_inst, water_inst)
else
write(iulog,*) subname// ' WARNING: No template column found to initialize newly-active column'
write(iulog,*) '-- keeping the state that was already in memory, possibly from arbitrary initialization'
call write_point_context(subgrid_index=c, subgrid_level=subgrid_level_column)
end if
end if
end do
end subroutine initialize_new_columns
!-----------------------------------------------------------------------
function initial_template_col_dispatcher(bounds, c_new, cactive_prior) result(c_template)
!
! !DESCRIPTION:
! Find column to use as a template for the given column that has newly become active;
! this is a dispatcher that calls the appropriate routine based on the landunit type of c_new.
!
! Returns TEMPLATE_NONE_FOUND if there is no column to use for initialization
!
! !USES:
use landunit_varcon, only : istsoil, istcrop, istice, istdlak, istwet, isturb_MIN, isturb_MAX
!
! !ARGUMENTS:
integer :: c_template ! function result
type(bounds_type) , intent(in) :: bounds ! bounds
integer , intent(in) :: c_new ! column index that needs initialization
logical , intent(in) :: cactive_prior( bounds%begc: ) ! column-level active flags from prior time step
!
! !LOCAL VARIABLES:
integer :: l ! landunit index
integer :: ltype ! landunit type
character(len=*), parameter :: subname = 'initial_template_col_dispatcher'
!-----------------------------------------------------------------------
SHR_ASSERT_ALL_FL((ubound(cactive_prior) == (/bounds%endc/)), sourcefile, __LINE__)
l = col%landunit(c_new)
ltype = lun%itype(l)
select case(ltype)
case(istsoil)
c_template = initial_template_col_soil(c_new)
case(istcrop)
c_template = initial_template_col_crop(bounds, c_new, cactive_prior(bounds%begc:bounds%endc))
case(istice)
write(iulog,*) subname// ' ERROR: Ability to initialize a newly-active glacier mec column not yet implemented'
write(iulog,*) 'Expectation is that glacier mec columns should be active from the start of the run wherever they can grow'
call endrun(subgrid_index=c_new, subgrid_level=subgrid_level_column, msg=errMsg(sourcefile, __LINE__))
case(istdlak)
write(iulog,*) subname// ' ERROR: Ability to initialize a newly-active lake column not yet implemented'
call endrun(subgrid_index=c_new, subgrid_level=subgrid_level_column, msg=errMsg(sourcefile, __LINE__))
case(istwet)
write(iulog,*) subname// ' ERROR: Ability to initialize a newly-active wetland column not yet implemented'
call endrun(subgrid_index=c_new, subgrid_level=subgrid_level_column, msg=errMsg(sourcefile, __LINE__))
!YS case(isturb_MIN:isturb_MAX)
!YS
case(isturb_MIN:)
!YS
write(iulog,*) subname// ' ERROR: Ability to initialize a newly-active urban column not yet implemented'
call endrun(subgrid_index=c_new, subgrid_level=subgrid_level_column, msg=errMsg(sourcefile, __LINE__))
case default
write(iulog,*) subname// ' ERROR: Unknown landunit type: ', ltype
call endrun(subgrid_index=c_new, subgrid_level=subgrid_level_column, msg=errMsg(sourcefile, __LINE__))
end select
end function initial_template_col_dispatcher
!-----------------------------------------------------------------------
function initial_template_col_soil(c_new) result(c_template)
!
! !DESCRIPTION:
! Find column to use as a template for a vegetated column that has newly become active.
!
! For now, we assume that the only vegetated columns that can newly become active are
! ones with 0 weight on the grid cell (i.e., virtual columns). For these, we simply
! keep the state at the current value (likely arbitrary initial conditions), and so
! return TEMPLATE_NONE_FOUND from this function. Within this function, we check this assumption.
!
! !USES:
!
! !ARGUMENTS:
integer :: c_template ! function result
integer , intent(in) :: c_new ! column index that needs initialization
!
! !LOCAL VARIABLES:
character(len=*), parameter :: subname = 'initial_template_col_soil'
!-----------------------------------------------------------------------
if (col%wtgcell(c_new) > 0._r8) then
write(iulog,*) subname// ' ERROR: Expectation is that the only vegetated columns that&
& can newly become active are ones with 0 weight on the grid cell'
call endrun(subgrid_index=c_new, subgrid_level=subgrid_level_column, msg=errMsg(sourcefile, __LINE__))
end if
c_template = TEMPLATE_NONE_FOUND
end function initial_template_col_soil
!-----------------------------------------------------------------------
function initial_template_col_crop(bounds, c_new, cactive_prior) result(c_template)
!
! !DESCRIPTION:
! Find column to use as a template for a crop column that has newly become active
!
! Returns TEMPLATE_NONE_FOUND if there is no column to use for initialization
!
! !USES:
use landunit_varcon, only : istsoil, istcrop
!
! !ARGUMENTS:
integer :: c_template ! function result
type(bounds_type) , intent(in) :: bounds ! bounds
integer , intent(in) :: c_new ! column index that needs initialization
logical , intent(in) :: cactive_prior( bounds%begc: ) ! column-level active flags from prior time step
!
! !LOCAL VARIABLES:
character(len=*), parameter :: subname = 'initial_template_col_crop'
!-----------------------------------------------------------------------
SHR_ASSERT_ALL_FL((ubound(cactive_prior) == (/bounds%endc/)), sourcefile, __LINE__)
! First try to find an active column on the vegetated landunit; if there is none, then
! find the first active column on the crop landunit; if there is none, then
! template_col will be TEMPLATE_NONE_FOUND
c_template = template_col_from_landunit(bounds, c_new, istsoil, cactive_prior(bounds%begc:bounds%endc))
if (c_template == TEMPLATE_NONE_FOUND) then
c_template = template_col_from_landunit(bounds, c_new, istcrop, cactive_prior(bounds%begc:bounds%endc))
end if
end function initial_template_col_crop
!-----------------------------------------------------------------------
subroutine copy_state(c_new, c_template, &
temperature_inst, water_inst)
!
! !DESCRIPTION:
! Copy a subset of state variables from a template column (c_template) to a newly-
! active column (c_new)
!
! !USES:
!
! !ARGUMENTS:
integer, intent(in) :: c_new ! index of newly-active column
integer, intent(in) :: c_template ! index of column to use as a template
type(temperature_type) , intent(inout) :: temperature_inst
type(water_type) , intent(inout) :: water_inst
!
! !LOCAL VARIABLES:
integer :: i
character(len=*), parameter :: subname = 'copy_state'
!-----------------------------------------------------------------------
! For now, just copy a few key variables
! TODO(wjs, 2016-08-31) Figure out what else should be copied here
! We only copy the below-ground portion of these multi-level variables, not the
! above-ground (snow) portion. This is because it is challenging to initialize the
! snow pack in a consistent state, requiring copying many more state variables - and
! if you initialize it in a partly-inconsistent state, you get balance errors. So, for
! now at least, we (Dave Lawrence, Keith Oleson, Bill Sacks) have decided that it's
! safest to just let the snow pack in the new column start at cold start conditions.
temperature_inst%t_soisno_col(c_new,1:) = temperature_inst%t_soisno_col(c_template,1:)
do i = water_inst%bulk_and_tracers_beg, water_inst%bulk_and_tracers_end
associate( &
waterstate_inst => water_inst%bulk_and_tracers(i)%waterstate_inst)
! TODO(wjs, 2016-08-31) If we had more general uses of this initial template col
! infrastructure (copying state between very different landunits), then we might need
! to handle bedrock layers - e.g., zeroing out any water that would be added to a
! bedrock layer(?). But for now we just use this initial template col infrastructure
! for nat veg -> crop, for which the bedrock will be the same, so we're not dealing
! with that complexity for now.
waterstate_inst%h2osoi_liq_col(c_new,1:) = waterstate_inst%h2osoi_liq_col(c_template,1:)
waterstate_inst%h2osoi_ice_col(c_new,1:) = waterstate_inst%h2osoi_ice_col(c_template,1:)
waterstate_inst%h2osoi_vol_col(c_new,1:) = waterstate_inst%h2osoi_vol_col(c_template,1:)
waterstate_inst%wa_col(c_new) = waterstate_inst%wa_col(c_template)
end associate
end do
end subroutine copy_state
end module dynInitColumnsMod