Loading numerical_labelling/constraints.py +144 −78 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ from itertools import product from sympy.core.numbers import int_valued module_path = os.path.join(os.path.dirname(os.path.abspath(''))) module_path = os.path.join(os.path.dirname(os.path.abspath(""))) if module_path not in sys.path: sys.path.insert(0, module_path) else: Loading @@ -22,36 +22,48 @@ from numerical_labelling.labelling import * from math import gcd class labelConstraint(sy.core.add.Add): """ making a class for constraint, only additional field is the type fields are the type and unit """ def __new__(cls, *args, type=None, **kwargs): def __new__(cls, *args, type=None, processunit=None, **kwargs): obj = super().__new__(cls, *args, **kwargs) obj._type = type obj._processunit = processunit return obj @property def type(self): return getattr(self, '_type', None) return getattr(self, "_type", None) @property def processunit(self): return getattr(self, "_processunit", None) @type.setter def type(self, value): self._type = value @processunit.setter def processunit(self, value): self._processunit = value @property def add_expr(self): return getattr(self, '_add_expr', None) return getattr(self, "_add_expr", None) @add_expr.setter def add_expr(self, value): self._add_expr = value @classmethod def from_add(cls, add_expr, type=None): def from_add(cls, add_expr, type=None, processunit=None): # Extract args from the existing Add expression new_obj = cls(*add_expr.args, type=type) new_obj = cls(*add_expr.args, type=type, processunit=processunit) new_obj.add_expr = add_expr return new_obj Loading @@ -59,6 +71,7 @@ class labelConstraint(sy.core.add.Add): def lcm(a, b): return abs(a * b) // gcd(a, b) def get_consts(cfa, cfb): lcm_value = lcm(cfa, cfb) const_1 = lcm_value / cfa Loading Loading @@ -134,26 +147,42 @@ def add_sltn(sltn_dict, varb_name, constr): raise ValueError(f"multiple solutions when trying to solve for {varb_name}") if varb_name in sltn_dict.keys(): print(f"variable {varb_name} in eq {constr} already solved for in eq {sltn_dict[varb_name]}") ''' print( f"variable {varb_name} in eq {constr} already solved for in eq {sltn_dict[varb_name]}" ) ''' # raise KeyError(f"{varb_name} already solved for") sltn_dict.update({varb_name: sltn[0]}) return sltn_dict def add_constraint(constr_dict, eqn, type=None): def add_constraint(constr_dict, eqn, type=None, processunit=None): """ add constraint to constraint dict """ indx = len(constr_dict) constr_dict[indx] = labelConstraint.from_add(eqn, type=type) constr_dict[indx] = labelConstraint.from_add( eqn, type=type, processunit=processunit, ) return constr_dict def constr_split( min, mout1, mout2, xin, xout1, xout2, pin, pout1, pout2, constr, sltns=None, min, mout1, mout2, xin, xout1, xout2, pin, pout1, pout2, constr, sltns=None, ): """ constraint for splitter unit Loading @@ -176,11 +205,9 @@ def constr_split( return constr, sltns return constr def constr_mix_21( min1, min2, mout, xin1, xin2, xout, pin1, pin2, pout, constr, sltns=None min1, min2, mout, xin1, xin2, xout, pin1, pin2, pout, constr, sltns=None ): """ constraint for 2 pipes coming together, 1 outlet Loading @@ -201,11 +228,22 @@ def constr_mix_21( return constr, sltns return constr def constr_mix_31( min1, min2, min3, mout, xin1, xin2, xin3, xout, pin1, pin2, pin3, pout, constr, sltns=None min1, min2, min3, mout, xin1, xin2, xin3, xout, pin1, pin2, pin3, pout, constr, sltns=None, ): """ constraint for 3 pipes coming together, 1 outlet Loading @@ -232,13 +270,24 @@ def constr_mix_31( def constr_mex( mfeed, mperm, mret, xfeed,xperm, xret, pfeed, pperm, pret, a, ap, app, b, bp, c, cp, constr, sltns = None mfeed, mperm, mret, xfeed, xperm, xret, pfeed, pperm, pret, a, ap, app, b, bp, c, cp, constr, sltns=None, ): """ a, ap, app are A, A', and A'' for the osmotic pressure constraint Loading @@ -250,8 +299,12 @@ def constr_mex( constr_hyd = mfeed - mperm - mret constr_component = xfeed * mfeed - xperm * mperm - xret * mret constr_osm_press = a * mperm - ap * ((pfeed - pperm) - app * (xfeed - xperm)) constr_diff_conc = b*mperm*xperm - bp*(xfeed-xperm) # xperm may be very small, but for integer example maybe it's better to keep constr_major_loss = c*(pfeed - pret) - cp*(mfeed+mret)**2 # major loss from feed to concentrate side. constr_diff_conc = b * mperm * xperm - bp * ( xfeed - xperm ) # xperm may be very small, but for integer example maybe it's better to keep constr_major_loss = ( c * (pfeed - pret) - cp * (mfeed + mret) ** 2 ) # major loss from feed to concentrate side. constr = add_constraint(constr, constr_hyd, type="lin_hydraulic") constr = add_constraint(constr, constr_component, type="bl_component") constr = add_constraint(constr, constr_osm_press, type="nl_pressure") Loading @@ -269,11 +322,18 @@ def constr_mex( def constr_pump( min, mout, xin, xout, pin, pout, E, H, G, J, constr, sltns=None, min, mout, xin, xout, pin, pout, E, H, G, J, constr, sltns=None, ): """ E: second order coefficient (Ex^2) Loading @@ -295,13 +355,17 @@ def constr_pump( return constr def constr_valve( min, mout, xin, xout, pin, pout, K, L, constr, sltns= None, min, mout, xin, xout, pin, pout, K, L, constr, sltns=None, ): # # see if multiple a, b, c, and ds defined # A, B, C, D = sy.symbols("A, B, C, D") Loading @@ -311,7 +375,9 @@ def constr_valve( constr_mass = mout - min constr_conc = xout - xin constr_major_loss = L*(pin - pout) - K*(min)**2 # major loss from feed to concentrate side. constr_major_loss = ( L * (pin - pout) - K * (min) ** 2 ) # major loss from feed to concentrate side. constr = add_constraint(constr, constr_mass, type="lin_hydraulic") constr = add_constraint(constr, constr_conc, type="bl_component") Loading Loading
numerical_labelling/constraints.py +144 −78 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ from itertools import product from sympy.core.numbers import int_valued module_path = os.path.join(os.path.dirname(os.path.abspath(''))) module_path = os.path.join(os.path.dirname(os.path.abspath(""))) if module_path not in sys.path: sys.path.insert(0, module_path) else: Loading @@ -22,36 +22,48 @@ from numerical_labelling.labelling import * from math import gcd class labelConstraint(sy.core.add.Add): """ making a class for constraint, only additional field is the type fields are the type and unit """ def __new__(cls, *args, type=None, **kwargs): def __new__(cls, *args, type=None, processunit=None, **kwargs): obj = super().__new__(cls, *args, **kwargs) obj._type = type obj._processunit = processunit return obj @property def type(self): return getattr(self, '_type', None) return getattr(self, "_type", None) @property def processunit(self): return getattr(self, "_processunit", None) @type.setter def type(self, value): self._type = value @processunit.setter def processunit(self, value): self._processunit = value @property def add_expr(self): return getattr(self, '_add_expr', None) return getattr(self, "_add_expr", None) @add_expr.setter def add_expr(self, value): self._add_expr = value @classmethod def from_add(cls, add_expr, type=None): def from_add(cls, add_expr, type=None, processunit=None): # Extract args from the existing Add expression new_obj = cls(*add_expr.args, type=type) new_obj = cls(*add_expr.args, type=type, processunit=processunit) new_obj.add_expr = add_expr return new_obj Loading @@ -59,6 +71,7 @@ class labelConstraint(sy.core.add.Add): def lcm(a, b): return abs(a * b) // gcd(a, b) def get_consts(cfa, cfb): lcm_value = lcm(cfa, cfb) const_1 = lcm_value / cfa Loading Loading @@ -134,26 +147,42 @@ def add_sltn(sltn_dict, varb_name, constr): raise ValueError(f"multiple solutions when trying to solve for {varb_name}") if varb_name in sltn_dict.keys(): print(f"variable {varb_name} in eq {constr} already solved for in eq {sltn_dict[varb_name]}") ''' print( f"variable {varb_name} in eq {constr} already solved for in eq {sltn_dict[varb_name]}" ) ''' # raise KeyError(f"{varb_name} already solved for") sltn_dict.update({varb_name: sltn[0]}) return sltn_dict def add_constraint(constr_dict, eqn, type=None): def add_constraint(constr_dict, eqn, type=None, processunit=None): """ add constraint to constraint dict """ indx = len(constr_dict) constr_dict[indx] = labelConstraint.from_add(eqn, type=type) constr_dict[indx] = labelConstraint.from_add( eqn, type=type, processunit=processunit, ) return constr_dict def constr_split( min, mout1, mout2, xin, xout1, xout2, pin, pout1, pout2, constr, sltns=None, min, mout1, mout2, xin, xout1, xout2, pin, pout1, pout2, constr, sltns=None, ): """ constraint for splitter unit Loading @@ -176,11 +205,9 @@ def constr_split( return constr, sltns return constr def constr_mix_21( min1, min2, mout, xin1, xin2, xout, pin1, pin2, pout, constr, sltns=None min1, min2, mout, xin1, xin2, xout, pin1, pin2, pout, constr, sltns=None ): """ constraint for 2 pipes coming together, 1 outlet Loading @@ -201,11 +228,22 @@ def constr_mix_21( return constr, sltns return constr def constr_mix_31( min1, min2, min3, mout, xin1, xin2, xin3, xout, pin1, pin2, pin3, pout, constr, sltns=None min1, min2, min3, mout, xin1, xin2, xin3, xout, pin1, pin2, pin3, pout, constr, sltns=None, ): """ constraint for 3 pipes coming together, 1 outlet Loading @@ -232,13 +270,24 @@ def constr_mix_31( def constr_mex( mfeed, mperm, mret, xfeed,xperm, xret, pfeed, pperm, pret, a, ap, app, b, bp, c, cp, constr, sltns = None mfeed, mperm, mret, xfeed, xperm, xret, pfeed, pperm, pret, a, ap, app, b, bp, c, cp, constr, sltns=None, ): """ a, ap, app are A, A', and A'' for the osmotic pressure constraint Loading @@ -250,8 +299,12 @@ def constr_mex( constr_hyd = mfeed - mperm - mret constr_component = xfeed * mfeed - xperm * mperm - xret * mret constr_osm_press = a * mperm - ap * ((pfeed - pperm) - app * (xfeed - xperm)) constr_diff_conc = b*mperm*xperm - bp*(xfeed-xperm) # xperm may be very small, but for integer example maybe it's better to keep constr_major_loss = c*(pfeed - pret) - cp*(mfeed+mret)**2 # major loss from feed to concentrate side. constr_diff_conc = b * mperm * xperm - bp * ( xfeed - xperm ) # xperm may be very small, but for integer example maybe it's better to keep constr_major_loss = ( c * (pfeed - pret) - cp * (mfeed + mret) ** 2 ) # major loss from feed to concentrate side. constr = add_constraint(constr, constr_hyd, type="lin_hydraulic") constr = add_constraint(constr, constr_component, type="bl_component") constr = add_constraint(constr, constr_osm_press, type="nl_pressure") Loading @@ -269,11 +322,18 @@ def constr_mex( def constr_pump( min, mout, xin, xout, pin, pout, E, H, G, J, constr, sltns=None, min, mout, xin, xout, pin, pout, E, H, G, J, constr, sltns=None, ): """ E: second order coefficient (Ex^2) Loading @@ -295,13 +355,17 @@ def constr_pump( return constr def constr_valve( min, mout, xin, xout, pin, pout, K, L, constr, sltns= None, min, mout, xin, xout, pin, pout, K, L, constr, sltns=None, ): # # see if multiple a, b, c, and ds defined # A, B, C, D = sy.symbols("A, B, C, D") Loading @@ -311,7 +375,9 @@ def constr_valve( constr_mass = mout - min constr_conc = xout - xin constr_major_loss = L*(pin - pout) - K*(min)**2 # major loss from feed to concentrate side. constr_major_loss = ( L * (pin - pout) - K * (min) ** 2 ) # major loss from feed to concentrate side. constr = add_constraint(constr, constr_mass, type="lin_hydraulic") constr = add_constraint(constr, constr_conc, type="bl_component") Loading