Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

integrate Da forcing module to t-route #637

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
508 changes: 508 additions & 0 deletions src/bmi_DAforcing.py

Large diffs are not rendered by default.

20 changes: 13 additions & 7 deletions src/bmi_reservoirs.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def __init__(self):
'OrificeC',
'OrificeA',
'LkMxE',
'waterbody_id',
'hl_link', # 'waterbody_id',
'ifd',
'upstream_ids',
'res_type',
Expand Down Expand Up @@ -138,11 +138,11 @@ def initialize(self, bmi_cfg_file=None):
self._values['OrificeC'] = np.zeros(1)
self._values['OrificeA'] = np.zeros(1)
self._values['LkMxE'] = np.zeros(1)
self._values['waterbody_id'] = np.zeros(1)
self._values['hl_link'] = np.zeros(1)
self._values['ifd'] = np.zeros(1)
self._values['upstream_ids'] = np.zeros(1, dtype=int)
self._values['reservoir_type'] = np.zeros(1)
self._values['lake_water~incoming__volume_flow_rate'] = np.zeros(12)
self._values['lake_water~incoming__volume_flow_rate'] = np.zeros(25)
self._values['lake_water~outgoing__volume_flow_rate'] = np.zeros(1)


Expand All @@ -158,19 +158,26 @@ def initialize(self, bmi_cfg_file=None):
#RFC DA
self._values['rfc_timeseries_offset_hours'] = np.zeros(1)
self._values['rfc_forecast_persist_days'] = np.zeros(1)

self._values['lake_number'] = np.zeros(1, dtype='<U19')
self._values['reservoir_type'] = np.zeros(1, dtype=int)
self._values['use_RFC'] = np.zeros(1, dtype=bool)
self._values['rfc_timeseries_discharges'] = np.zeros(289)
self._values['rfc_timeseries_idx'] = np.zeros(1)
self._values['rfc_timeseries_update_time'] = np.zeros(1)
self._values['rfc_da_time_step'] = np.zeros(1)
self._values['rfc_total_counts'] = np.zeros(1)
self._values['rfc_timeseries_file'] = np.zeros(1, dtype='<U19')

'''
for var_name in self._input_var_names + self._output_var_names:
# ---------- Temporarily set to 3 values ------------------#
# ---------- so just set to zero for now ------------------#
self._values[var_name] = np.zeros(3)
'''

def update(self):
"""Advance model by one time step."""
if self._model._time==0.0:
self._model.preprocess_static_vars(self._values)

self._model.run(self._values)

def update_until(self, until):
Expand All @@ -181,7 +188,6 @@ def update_until(self, until):
Time to run model until in seconds.
"""
n_steps = int(until/self._model._time_step)

for _ in range(int(n_steps)):
self.update()

Expand Down
88 changes: 62 additions & 26 deletions src/bmi_troute.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,16 @@ def initialize(self, bmi_cfg_file=None):
# -------------- Read in the BMI configuration -------------------------#
bmi_cfg_file = Path(bmi_cfg_file)
bmi_parameters = _read_config_file(bmi_cfg_file)
flowpath_columns = bmi_parameters.get('flowpath_columns')
attributes_columns = bmi_parameters.get('attributes_columns')
lakes_columns = bmi_parameters.get('waterbody_columns', [])
network_columns = bmi_parameters.get('network_columns', [])

n_segment = int(bmi_parameters.get('segment_number'))
n_waterbody = int(bmi_parameters.get('waterbody_number'))
n_io = int(bmi_parameters.get('io_number'))
n_upstream = int(bmi_parameters.get('upstream_number'))
n_gages = int(bmi_parameters.get('gage_number'))

# ------------- Initialize t-route model ------------------------------#
self._model = troute_model(bmi_cfg_file)
Expand All @@ -149,25 +155,26 @@ def initialize(self, bmi_cfg_file=None):
long_name in self._var_name_units_map.keys()}
self._var_units_map = {long_name:self._var_name_units_map[long_name][1] for \
long_name in self._var_name_units_map.keys()}


# -------------- Initalize all the variables --------------------------#
# -------------- so that they'll be picked up with the get functions --#
#FIXME Do this better..., load size of variables from config file??
self._values['segment_id'] = np.zeros(n_segment, dtype=int)
self._values['segment_toid'] = np.zeros(n_segment, dtype=int)
self._values['dx'] = np.zeros(n_segment)
for col in flowpath_columns + attributes_columns + lakes_columns + network_columns:
self._values[col] = np.zeros(0)

self._values['id'] = np.zeros(n_segment, dtype=int)
self._values['toid'] = np.zeros(n_segment, dtype=int)
self._values['lengthkm'] = np.zeros(n_segment)
self._values['n'] = np.zeros(n_segment)
self._values['ncc'] = np.zeros(n_segment)
self._values['s0'] = np.zeros(n_segment)
self._values['bw'] = np.zeros(n_segment)
self._values['tw'] = np.zeros(n_segment)
self._values['twcc'] = np.zeros(n_segment)
self._values['nCC'] = np.zeros(n_segment)
self._values['So'] = np.zeros(n_segment)
self._values['BtmWdth'] = np.zeros(n_segment)
self._values['TopWdth'] = np.zeros(n_segment)
self._values['TopWdthCC'] = np.zeros(n_segment)
self._values['alt'] = np.zeros(n_segment)
self._values['musk'] = np.zeros(n_segment)
self._values['musx'] = np.zeros(n_segment)
self._values['cs'] = np.zeros(n_segment)
self._values['waterbody_id'] = np.zeros(n_waterbody, dtype=int)
self._values['MusK'] = np.zeros(n_segment)
self._values['MusX'] = np.zeros(n_segment)
self._values['ChSlp'] = np.zeros(n_segment)
self._values['hl_link'] = np.zeros(n_waterbody, dtype=int)
self._values['waterbody_toid'] = np.zeros(n_waterbody, dtype=int)
self._values['LkArea'] = np.zeros(n_waterbody)
self._values['LkMxE'] = np.zeros(n_waterbody)
Expand All @@ -178,16 +185,19 @@ def initialize(self, bmi_cfg_file=None):
self._values['WeirE'] = np.zeros(n_waterbody)
self._values['WeirL'] = np.zeros(n_waterbody)
self._values['ifd'] = np.zeros(n_waterbody)
self._values['network_id'] = np.zeros(n_segment)
self._values['hydroseq'] = np.zeros(n_segment)
self._values['hl_uri'] = np.zeros(n_segment)
#self._values['qd0'] = np.zeros(1) #TODO will this come from a file or model engine?
#self._values['h0'] = np.zeros(1) #TODO will this come from a file or model engine?
self._values['reservoir_type'] = np.zeros(n_waterbody)
self._values['waterbody_connections__link'] = np.zeros(0)
self._values['waterbody_connections__lake'] = np.zeros(0)

self._values['land_surface_water_source__volume_flow_rate'] = np.zeros(n_io)
self._values['land_surface_water_source__id'] = np.zeros(n_io)
self._values['coastal_boundary__depth'] = np.zeros(0)
self._values['usgs_gage_observation__volume_flow_rate'] = np.zeros(0)
self._values['reservoir_usgs_gage_observation__volume_flow_rate'] = np.zeros(0)
self._values['reservoir_usace_gage_observation__volume_flow_rate'] = np.zeros(0)
self._values['rfc_gage_observation__volume_flow_rate'] = np.zeros(0)
self._values['lastobs__volume_flow_rate'] = np.zeros(0)

self._values['channel_exit_water_x-section__volume_flow_rate'] = np.zeros(n_io)
self._values['channel_water_flow__speed'] = np.zeros(n_io)
self._values['channel_water__mean_depth'] = np.zeros(n_io)
Expand All @@ -206,10 +216,36 @@ def initialize(self, bmi_cfg_file=None):
self._values['fvd_results'] = np.zeros(n_segment*3*12)
self._values['fvd_index'] = np.zeros(1)

"""
#TODO Update loading RFC data not through Fortran reservoir module.
self._values['rfc_gage_observation__volume_flow_rate'] = np.zeros(0)
"""
# Data assimilation values
self._values['gage_crosswalk__segID'] = np.zeros(0, dtype=int)
self._values['gage_crosswalk__gageID'] = np.zeros(0, dtype='<U19')
self._values['gages'] = np.zeros(6, dtype='<U19')
self._values['usgs_timeslice_discharge'] = np.zeros(10010)
self._values['usgs_timeslice_stationId'] = np.zeros(10010, dtype='<U19')
self._values['usgs_timeslice_time'] = np.zeros(10010, dtype='<U19')
self._values['usgs_timeslice_discharge_quality'] = np.zeros(10010)

self._values['gages'] = np.zeros(6, dtype='<U19')
self._values['usace_timeslice_discharge'] = np.zeros(5192)
self._values['usace_timeslice_stationId'] = np.zeros(5192, dtype='<U19')
self._values['usace_timeslice_time'] = np.zeros(5192, dtype='<U19')
self._values['usace_timeslice_discharge_quality'] = np.zeros(5192)

self._values['lastobs_discharge'] = np.zeros(76)
self._values['lastobs_stationIdInd'] = np.zeros(9, dtype=int)
self._values['lastobs_timeInd'] = np.zeros(9, dtype=int)
#self._values['lastobs_stationId'] = np.zeros(76, dtype='<S19') #S19 keep 'b'prefix
self._values['lastobs_stationId'] = np.zeros(76, dtype='<U19')
self._values['lastobs_time'] = np.zeros(9, dtype='<U19')
self._values['lastobs_modelTimeAtOutput'] = np.zeros(1, dtype='<U19')
self._values['time_since_lastobs'] = np.zeros(76)

self._values['rfc_discharges'] = np.zeros(289)
self._values['rfc_stationId'] = np.zeros(3, dtype='<U19')
self._values['rfc_synthetic_values'] = np.zeros(0)
self._values['rfc_totalCounts'] = np.zeros(0)
self._values['rfc_datetime'] = np.zeros(3, dtype='<U19')
self._values['rfc_timestep'] = np.zeros(0)

# Currently utilized BMI functions:
def update(self):
Expand Down Expand Up @@ -240,10 +276,10 @@ def set_value(self, var_name, src):
src : array_like
Array of new values.
"""
val = self.get_value_ptr(var_name)
val[:] = src.reshape(val.shape)
#val = self.get_value_ptr(var_name)
#val[:] = src.reshape(val.shape)

#self._values[var_name] = src
self._values[var_name] = src

def get_value(self, var_name):
"""Copy of values.
Expand Down
Loading