def test_constrain_with_unit(self, varunit, conunit): create = dict(value=3., unit=varunit, hasOld=True) name = 'MyVar' conval = PhysicalField(5, conunit) constraints = dict(top=conval, ) v = ModelVariable(name=name, create=create, constraints=constraints) domain = SedimentDBLDomain() v.set_domain(domain) try: varval = conval.inUnitsOf(varunit) except TypeError: # incompatible units varval = None if varval is None: with pytest.raises(TypeError): v.setup() else: v.setup() v.var.updateOld() assert v.var.faceValue[0] == conval
def test_constrain(self, constraints): # test that boundary conditions get applied create = dict(value=3.3, unit='mol/l') name = 'var' constraints = dict(constraints) v = ModelVariable(name=name, create=create, constraints=constraints) domain = SedimentDBLDomain() v.set_domain(domain) v.setup() assert v.var is not None assert v.var.name == v.name constraints_count = sum( [1 for c in constraints if c not in ('top', 'bottom')]) assert len(v.var.constraints) == constraints_count, 'Var constraints: {} does not match ' \ 'specified: {}'.format( (v.var.constraints), constraints ) if 'top' in constraints: numerix.array_equal(v.var[0], constraints['top']) if 'bottom' in constraints: numerix.array_equal(v.var[-1], constraints['bottom']) if 'dbl' in constraints: assert (v.var[:domain.idx_surface] == constraints['dbl']).all() if 'sediment' in constraints: assert ( v.var[domain.idx_surface:] == constraints['sediment']).all()
def test_create_var(self, value, unit, hasOld): # creation casts it into base units create = dict(value=value, unit=unit, hasOld=hasOld) name = 'myVar' v = ModelVariable(name=name, create=create) domain = SedimentDBLDomain() v.set_domain(domain) v.setup() assert v.var is domain[name] assert v.var.name == v.name assert v.var.shape == domain.mesh.shape assert (v.var() == PhysicalField(value, unit).inBaseUnits()).all()
def test_seed_normal(self, unit, loc, scale, coeff, error): create = dict(value=3., unit=unit, hasOld=True) name = 'MyVar' seed = dict(profile='normal', params=dict(loc=loc, scale=scale, coeff=coeff)) v = ModelVariable(name=name, create=create, seed=seed) domain = SedimentDBLDomain() v.domain = domain if error: with pytest.raises(error): v.setup() return else: v.setup() from scipy.stats import norm from fipy.tools import numerix C = 1.0 / numerix.sqrt(2 * numerix.pi) # loc and scale should be in units of the domain mesh if hasattr(loc, 'unit'): loc_ = loc.inUnitsOf(domain.depths.unit).value else: loc_ = loc if hasattr(scale, 'unit'): scale_ = scale.inUnitsOf(domain.depths.unit).value else: scale_ = scale if unit: coeff = PF(coeff, unit) normrv = norm(loc=loc_, scale=C**2 * scale_) val = coeff * normrv.pdf(domain.depths) * C * scale_ # from pprint import pprint # pprint(zip(v.var, val)) print(type(val), type(v.var)) if unit: # array comparison between variable & physicalfield is problematic val = val.numericValue assert numerix.allclose(v.var.numericValue, val)
def test_seed_linear_from_constraints(self, params, constraints, error): seed = dict(profile='linear') if params: seed['params'] = params unit = 'km/kg' N = 10 v = ModelVariable( name='mvar', create=dict(value=3.2, unit=unit), seed=seed, constraints=constraints, ) v.domain = mock.Mock(SedimentDBLDomain) v.domain.create_var.return_value = PhysicalField([34] * N, unit) v.domain.mesh = mock.Mock() v.domain.idx_surface = mock.Mock() v.constrain = mock.Mock() if error: with pytest.raises(error): v.setup() else: v.setup() if params is None: params = {} if constraints is None: constraints = {} startval = PhysicalField( params.get('start', constraints.get('top')), unit).inUnitsOf(unit).value stopval = PhysicalField( params.get('stop', constraints.get('bottom')), unit).inUnitsOf(unit).value expected = PhysicalField(numerix.linspace(startval, stopval, N), unit) assert numerix.array_equal(v.var, expected)