def test_constructor(self): var_list = VariableList([Variable(()), Variable(('x'))]) assert isinstance(var_list, tuple) with pytest.raises(ValueError) as excinfo: _ = VariableList([2, Variable(())]) assert "found variables mixed" in str(excinfo.value)
def test_constructor(self): # verify allowed_dims for allowed_dims in (tuple(), list(), ''): var = Variable(allowed_dims) assert var.allowed_dims == ((), ) for allowed_dims in ('x', ['x'], tuple(['x'])): var = Variable(allowed_dims) assert var.allowed_dims == (('x', ), ) var = Variable([(), 'x', ('x', 'y')]) assert var.allowed_dims, ((), ('x', ), ('x', 'y'))
class Grid(Process): x_size = Variable((), optional=True, description='grid size') x = Variable('x', provided=True) class Meta: time_dependent = False def validate(self): if np.asscalar(self.x_size.value) is None: self.x_size.value = 5 def initialize(self): self.x.value = np.arange(self.x_size.value)
class ExampleProcess(Process): """A full example of process interface. """ var = Variable((), provided=True) var_list = VariableList([Variable('x'), Variable(((), 'x'))]) var_group = VariableGroup('group') no_var = 'this is not a variable object' class Meta: time_dependent = False @diagnostic def diag(self): return 1
def test_to_xarray_variable(self): attrs = {'units': 'm'} description = 'x var' xr_var_attrs = attrs.copy() xr_var_attrs.update({'description': description}) var = Variable('x', description=description, attrs=attrs) xr_var = var.to_xarray_variable(('x', [1, 2])) expected_xr_var = xr.Variable('x', data=[1, 2], attrs=xr_var_attrs) xr.testing.assert_identical(xr_var, expected_xr_var) var = Variable((), default_value=1) xr_var = var.to_xarray_variable(2) expected_xr_var = xr.Variable((), data=2) xr.testing.assert_identical(xr_var, expected_xr_var) # test default value xr_var = var.to_xarray_variable(None) expected_xr_var = xr.Variable((), data=1) xr.testing.assert_identical(xr_var, expected_xr_var) # test variable name xr_var = var.to_xarray_variable([1, 2]) expected_xr_var = xr.Variable('this_variable', data=[1, 2]) expected_xr_var = expected_xr_var.to_index_variable() xr.testing.assert_identical(xr_var, expected_xr_var)
class OtherProcess(Process): x = ForeignVariable(Grid, 'x') quantity = ForeignVariable(Quantity, 'quantity') other_param = Variable((), default_value=1, description='other parameter') other_effect = Variable('x', group='effect', provided=True) # OtherProcess should always appear after SomeProcess in a model copy_param = ForeignVariable(SomeProcess, 'copy_param') def run_step(self, dt): self.other_effect.value = self.x.value * self.copy_param.value - dt @diagnostic def x2(self): return self.x * 2
class PlugProcess(Process): meta_param = Variable(()) some_param = ForeignVariable(SomeProcess, 'some_param', provided=True) x = ForeignVariable(Grid, 'x') def run_step(self, *args): self.some_param.value = self.meta_param.value
def test_is_input(self, model): assert model.is_input(model.grid.x_size) is True assert model.is_input(('grid', 'x_size')) is True assert model.is_input(model.quantity.all_effects) is False assert model.is_input(('other_process', 'copy_param')) is False external_variable = Variable(()) assert model.is_input(external_variable) is False var_list = [Variable(()), Variable(()), Variable(())] variable_list = VariableList(var_list) assert model.is_input(variable_list) is False variable_group = VariableGroup('group') variable_group._set_variables({}) assert model.is_input(variable_group) is False
class SomeProcess(Process): some_param = Variable((), default_value=1, description='some parameter') x = ForeignVariable(Grid, 'x') quantity = ForeignVariable(Quantity, 'quantity') some_effect = Variable('x', group='effect', provided=True) # SomeProcess always appears before OtherProcess in a model copy_param = Variable((), provided=True) def initialize(self): self.copy_param.value = self.some_param.value def run_step(self, dt): self.some_effect.value = self.x.value * self.some_param.value + dt def finalize(self): self.some_effect.rate = 0
def test_validate_dimensions(self): var = Variable([(), 'x', ('x', 'y')]) with pytest.raises(ValidationError) as excinfo: var.validate_dimensions(('x', 'z')) assert 'invalid dimensions' in str(excinfo.value) var.validate_dimensions(('time', 'x'), ignore_dims=['time'])
class Quantity(Process): quantity = Variable('x', description='a quantity') all_effects = VariableGroup('effect') def run_step(self, *args): self.quantity.change = sum((var.value for var in self.all_effects)) def finalize_step(self): self.quantity.state += self.quantity.change @diagnostic def some_derived_quantity(self): """some derived quantity.""" return 1 @diagnostic({'units': 'm'}) def other_derived_quantity(self): """other derived quantity.""" return 2
class InvalidProcess(ExampleProcess): var = Variable(())
def test_repr(self): var = Variable(((), 'x', ('x', 'y'))) expected_repr = "<xsimlab.Variable (), ('x'), ('x', 'y')>" assert repr(var) == expected_repr