-
Notifications
You must be signed in to change notification settings - Fork 9
Allow re-linking variables at Model creation #24
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
Comments
If subclassing process classes is supported, then the case explained above can be easily addressed: @xsimlab.process
class FlowRouterAfterUplift(FlowRouterD8):
original_elevation = xsimlab.link(Topography, 'elevation')
uplift = xsimlab.link(BlockUplift, 'uplift')
elevation = xsimlab.variable(('y', 'x'), yield_value=True)
def run_step(self, dt):
self.elevation = self.original_elevation + self.uplift
super(FlowRouterAfterUplift, self).run_step(dt)
alt_model = fastscape_model.update_processes(
{'flow_routing': FlowRouterAfterUplift}
) Additionally, to avoid having to update processes that depend on flow routing, we can chain linked variables, i.e., create a link that itself refers to a link. However, this does not really solves the problem. In the example below, @xsimlab.process
class StreamPower(object):
# ...
elevation = xsimlab.link(FlowRouterD8, 'elevation') A possible solution would be to accept a string for the 1st argument of @xsimlab.process
class StreamPower(object):
# ...
elevation = xsimlab.link('flow_routing', 'elevation') |
Another workaround would be to keep in the example above the link to Maybe this would impliy that a process class and one of its subclass cannot be both added to a model (which probably doesn't make sense anyway). |
Links (references) to foreign variables are defined at process class creation, but sometimes it might be needed to change these references depending on which processes are included in a model.
As a use case, let's consider the fastscape model implemented in xarray-topo.
FlowRouterD8
process needs topographic elevation values to compute flow routing.FlowRouterD8.elevation
currently refers toTopography.elevation
for which block uplift is applied independently at each time step. However, it might make sense (especially with large time steps) to force computing flow routing based on topography that has been block uplifted at the current time step. A nice, modular solution to this problem would be to add a new process that somehow "steals" theFlowRouterD8.elevation
reference and yield a value that is based on block uplifted topography. "stealing" a reference defined in a external process is not yet supported in xarray-simlab.Taking the example above and with the new design discussed in #19 (and #20) in mind, a possible solution would look like:
Here
relink=True
specifies thatFlowRouterD8.elevation
has to be re-linked toUpliftBeforeFlow.elevation_flow
(thus discarding its original link toTopography.elevation
).relink=True
is allowed only ifyield_value=True
and if the referenced external variable (i.e.,FlowRouterD8.elevation
in this example) is itself declared as a link withyield_value=False
. An error should be raised when creating the process class if it these conditions are not filled.Unfortunately, this solution is not straightforward to implement internally. A constraint is that we must leave
FlowRouterD8
untouched, which looks like:The problem is that
elevation
is already declared inUpliftBeforeFlow
and is different fromelevation_flow
:The text was updated successfully, but these errors were encountered: