Skip to content

Include parent classes in process name/class reverse lookup #45

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

Merged
merged 7 commits into from
Sep 23, 2019

Conversation

benbovy
Copy link
Member

@benbovy benbovy commented Aug 29, 2018

A possible way to customize processes is to use class inheritance. However, a current limitation is that foreign variables hard-code external classes, making it difficult to customize a model by replacing a process class by one of its sub-classes.

This PR address this issue by also including parent classes in the process name/class reverse lookup that is used to link foreign variables to their corresponding process when building a new model. Using the example in the docs, it is now possible to do something like:

@xs.process
class AlternativeGrid1D(UniformGrid1D):
    """Give number of nodes instead of total length as input."""

    spacing = xs.variable(description='uniform spacing')
    nnodes = xs.variable(description='number of nodes')
    
    length = xs.variable(intent='out')
    x = xs.variable(dims='x', intent='out')

    def initialize(self):
        self.length = (self.nnodes - 1) * self.spacing
        super(AlternativeGrid1D, self).initialize()


# no error "Process class 'UniformGrid1D' missing in Model"
alt_model = model2.update_processes({'grid': AlternativeGrid1D})

In the example above, the foreign variables declared in other processes of alt_model are now correctly linked to the 'grid' process even if they were declared like xs.foreign(UniformGrid1D, 'x'), as AlternativeGrid1D inherits from UniformGrid1D.

One drawback (and possible breaking change) is that linking foreign variables is ambiguous when both conditions below are met:

  • two different processes in a model have a common class in their MRO (except object)
  • a third process have a foreign variable that links to that specific class

For example:

 # this gives an error
alt_model = xs.Model({'grid': UniformGrid1D,
                      'grid2': AlternativeGrid1D,
                      'profile': ProfileU,
                      'init': InitUGauss,   # does init.x refers to grid.x or grid2.x?
                      'advect': AdvectionLax})

While the example above doesn't make any sense, I can't think about a real case where this should happen.

This feature is quite robust IMO, but it should be considered as experimental.

@benbovy benbovy force-pushed the rev-lookup-parent-classes branch from 70b5890 to a4e2552 Compare September 18, 2019 10:40
@benbovy benbovy merged commit b01c792 into master Sep 23, 2019
@benbovy benbovy mentioned this pull request Sep 29, 2019
5 tasks
@benbovy benbovy deleted the rev-lookup-parent-classes branch December 11, 2019 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow re-linking variables at Model creation
1 participant