Time-varying bedload¶
The following example demonstrates how to configure a subclassing model with a time-varying parameter.
In this example, the time-varying behavior arises by managing two “switches”, self._changed
and self._changed_back
, which change the state of the f_bedload
parameters at a predetermined time in the mode sequence.
The following codes produce two runs (using matrix expansion from the Preprocessor), which has a baseline f_bedload value of either 0.3
or 0.7
, and for a period in the middle of the run, the f_bedload values are mirrored by self.f_bedload = (1 - self.f_bedload)
, i.e., briefly switching the bedload values.
class VariableBedloadModel(pyDeltaRCM.DeltaModel):
def __init__(self, input_file=None, **kwargs):
super().__init__(input_file, **kwargs)
self._changed = False
self._changed_back = False
def hook_solve_water_and_sediment_timestep(self):
"""Change the state depending on the _time.
"""
# check if the state has been changed, and time to change it
if (not self._changed) and (self._time > 459909090):
self.f_bedload = (1 - self.f_bedload)
self._changed = True
_msg = 'Bedload changed to {f_bedload}'.format(
f_bedload=self.f_bedload)
self.log_info(_msg, verbosity=0)
# check if the state has been changed back, and time to change it back
if (not self._changed_back) and (self._time > 714545454):
self.f_bedload = (1 - self.f_bedload)
self._changed_back = True
_msg = 'Bedload changed back to {f_bedload}'.format(
f_bedload=self.f_bedload)
self.log_info(_msg, verbosity=0)
Checking on the state-change effect
To demonstrate how this works, let’s loop through time and check the model state. Here, we will change the model time value directly, so that we can verify that the model is working as intended, but you should never do this in practice.
mdl_muddy = VariableBedloadModel(f_bedload=0.3)
mdl_sandy = VariableBedloadModel(f_bedload=0.7)
Important
You should never modify the model time via self._time
directly when working with the model.
# create a figure
fig, ax = plt.subplots()
# set the "simulation" range
_times = np.linspace(0, 1e9, num=100)
fb_mdl_muddy = np.zeros_like(_times)
fb_mdl_sandy = np.zeros_like(_times)
# loop through time, change the model time and grab f_bedload values
for i, _time in enumerate(_times):
# change the model time directly
mdl_muddy._time = _time # you should never do this
mdl_sandy._time = _time # you should never do this
# run the hooked method
mdl_muddy.hook_solve_water_and_sediment_timestep()
mdl_sandy.hook_solve_water_and_sediment_timestep()
# grab the state of the `f_bedload` parameter
fb_mdl_muddy[i] = mdl_muddy.f_bedload # get the value
fb_mdl_sandy[i] = mdl_sandy.f_bedload # get the value
# add it to the plot
ax.plot(_times, fb_mdl_muddy, '-', c='saddlebrown', lw=2, label='muddy')
ax.plot(_times, fb_mdl_sandy, '--', c='goldenrod', lw=2, label='sandy')
ax.legend()
# clean up
ax.set_ylim(0, 1)
ax.set_ylabel('f_bedload')
ax.set_xlabel('model time (s)')
plt.show()
Running the model for real
Given a yaml file (variable_bedload.yaml
):
Length: 5000.
Width: 10000.
dx: 50
N0_meters: 500
C0_percent: 0.05
SLR: 1.5e-8
h0: 2
u0: 1.1
coeff_U_dep_mud: 0.5
parallel: True
matrix:
f_bedload:
- 0.3
- 0.7
and a script to run the code:
if __name__ == '__main__':
# base yaml configuration
base_yaml = 'variable_bedload.yaml'
pp = pyDeltaRCM.Preprocessor(
base_yaml,
timesteps=12000)
# run the jobs
pp.run_jobs(DeltaModel=VariableBedloadModel)