def busses_add_comps(c, *args): r""" Add components to busses according to data from .csv file. Parameters ---------- c : pandas.core.series.Series Component information from .csv-file. args[0] : pandas.core.frame.DataFrame DataFrame containing all created busses. args[1] : pandas.core.frame.DataFrame DataFrame containing all created characteristic lines. """ i = 0 for b in c.busses: p, P_ref, char = c.bus_param[i], c.bus_P_ref[i], c.bus_char[i] values = char == args[1]['id'] char = char_line(x=args[1][values].x.values[0], y=args[1][values].y.values[0]) # add component with corresponding details to bus args[0].instance[b == args[0]['label']].values[0].add_comps({ 'c': c.instance, 'p': p, 'P_ref': P_ref, 'char': char }) i += 1
def test_char_line_evaluation(): """Test the characteristc line evaluation.""" # create a characteristc line with values of y=(x-2)^2 line = char_line(x=[0, 1, 2, 3, 4], y=[4, 1, 0, 1, 4]) # test evaluation at given x value (x=3, y=1) x = 3 y = line.evaluate(x) msg = ("The evaluation of x=" + str(x) + " must be 1.0, but is " + str(y) + ".") assert y == 1.0, msg # test evaluation at x=0.5 to force interpolation, result: y=2.5 x = 0.5 y = line.evaluate(x) msg = ("The evaluation of x=" + str(x) + " must be 2.5, but is " + str(y) + ".") assert y == 2.5, msg # test evaluation at x=-1 to check lower limits, result: y=4 x = -1 y = line.evaluate(x) msg = ("The evaluation of x=" + str(x) + " must be 4, but is " + str(y) + ".") assert y == 4.0, msg # test evaluation at x=5 to check upper limits, result: y=4 x = 5 y = line.evaluate(x) msg = ("The evaluation of x=" + str(x) + " must be 4, but is " + str(y) + ".") assert y == 4.0, msg
def __init__(self, label, **kwargs): self.comps = pd.DataFrame(columns=['param', 'P_ref', 'char']) self.label = label self.P = dc_cp(val=np.nan, is_set=False) self.char = char_line(x=np.array([0, 3]), y=np.array([1, 1])) self.printout = True self.set_attr(**kwargs) msg = 'Created bus ' + self.label + '.' logging.debug(msg)
def comp_init(self, nw): r""" Perform component initialization in network preprocessing. Parameters ---------- nw : tespy.networks.network Network this component is integrated in. """ self.num_nw_fluids = len(nw.fluids) self.nw_fluids = nw.fluids self.num_nw_vars = self.num_nw_fluids + 3 self.it = 0 self.vec_res = [] self.mat_deriv = None self.num_eq = 0 self.vars = {} self.num_vars = 0 var = self.attr() for key, val in var.items(): if isinstance(val, dc_cp): if self.get_attr(key).is_var: self.get_attr(key).var_pos = self.num_vars self.num_vars += 1 self.vars[self.get_attr(key)] = key # characteristics creation elif isinstance(val, dc_cc): if self.get_attr(key).func is None: try: self.get_attr(key).func = ldc(self.component(), key, 'DEFAULT', char_line) except KeyError: self.get_attr(key).func = char_line(x=[0, 1], y=[1, 1]) if self.char_warnings is True: msg = ('Created characteristic line for parameter ' + key + ' at component ' + self.label + ' from ' 'default data.\n' 'You can specify your own data using ' 'component.' + key + '.set_attr(func=custom_char).\n' 'If you want to disable these warnings use ' 'component.char_warnings=False.') logging.warning(msg) msg = ('The component ' + self.label + ' has ' + str(self.num_vars) + ' custom variables.') logging.debug(msg)
def test_turbine_missing_char_parameter(): """Turbine with invalid parameter for eta_s_char function.""" nw = network(['CH4']) so = basics.source('source') si = basics.sink('sink') instance = turbomachinery.turbine('turbine') c1 = connection(so, 'out1', instance, 'in1') c2 = connection(instance, 'out1', si, 'in1') nw.add_conns(c1, c2) instance.set_attr(eta_s_char=dc_cc( func=char_line([0, 1], [1, 2]), is_set=True, param=None)) nw.solve('design', init_only=True) with raises(ValueError): instance.eta_s_char_func()
def test_valve(self): """ Test component properties of valves. """ instance = valve('valve') self.setup_piping_network(instance) # parameter specification self.c1.set_attr(fluid={'CH4': 1}, m=10, p=10, T=120) self.c2.set_attr(p=1) # test variable pressure ration instance.set_attr(pr='var') self.nw.solve('design') convergence_check(self.nw.lin_dep) pr = round(self.c2.p.val_SI / self.c1.p.val_SI, 2) msg = ('Value of pressure ratio must be ' + str(pr) + ', is ' + str(round(instance.pr.val, 2)) + '.') eq_(pr, round(instance.pr.val, 2), msg) # test variable zeta value zeta = round(instance.zeta.val, 0) instance.set_attr(zeta='var', pr=np.nan) self.nw.solve('design') convergence_check(self.nw.lin_dep) msg = ('Value of dimension independent zeta value must be ' + str(zeta) + ', is ' + str(round(instance.zeta.val, 0)) + '.') eq_(zeta, round(instance.zeta.val, 0), msg) # dp char x = np.array([8, 9, 10, 11, 12]) y = np.array([5, 8, 9, 9.5, 9.6]) * 1e5 dp_char = char_line(x, y) instance.set_attr(zeta=np.nan, dp_char=dc_cc(func=dp_char, is_set=True)) m = 11 self.c1.set_attr(m=m) self.c2.set_attr(p=np.nan) self.nw.solve('design') convergence_check(self.nw.lin_dep) self.nw.print_results() dp = round(-dp_char.evaluate(m), 0) dp_act = round(self.c2.p.val_SI - self.c1.p.val_SI) msg = ('The pressure drop at the valve should be ' + str(dp) + ' but ' 'is ' + str(dp_act) + '.') eq_(dp, dp_act, msg)
def test_get_attr_errors(): """Test errors of get_attr methods.""" nw = network(['water', 'air']) comb = combustion.combustion_engine('combustion engine') pipeline = piping.pipe('pipeline') conn = connection(comb, 'out1', pipeline, 'in1') mybus = bus('mybus') sub = subsystems.subsystem('MySub') get_attr_KeyError(comb, 'wow') get_attr_KeyError(conn, 'key') get_attr_KeyError(mybus, 'components') get_attr_KeyError(nw, 'missing') get_attr_KeyError(ref(conn, 1, 0), 'comp') get_attr_KeyError(sub, 'test') get_attr_KeyError(char_line(), 'test') get_attr_KeyError(data_container(), 'somekey') get_attr_KeyError(char_map(), 'Stuff')
def test_char_line_extrapolation(): """Test the characteristc line with extrapolation.""" # create a characteristc line with values of y=(x-2)^2 line = char_line(x=[0, 1, 2, 3, 4], y=[4, 1, 0, 1, 4], extrapolate=True) # test evaluation at x=-1 to check lower limits, result: y=7 x = -1 y = line.evaluate(x) msg = ("The evaluation of x=" + str(x) + " must be 7, but is " + str(y) + ".") assert y == 7.0, msg # test evaluation at x=5 to check upper limits, result: y=7 x = 5 y = line.evaluate(x) msg = ("The evaluation of x=" + str(x) + " must be 7, but is " + str(y) + ".") assert y == 7.0, msg
def add_comps(self, *args): r""" Add components to a bus. Parameters ---------- c : dict Dictionary containing the component information to be added to the bus. These information are described in the notes! Note ---- Keys for the dictionary c: - c (tespy.components.components.component): Component you want to add to the bus. - p (str): Bus parameter, optional. - You do not need to provide a parameter, if the component only has one option for the bus (turbomachines, heat exchangers, combustion chamber). - For instance, you do neet do provide a parameter, if you want to add a combustion engine ('Q', 'Q1', 'Q2', 'TI', 'P', 'Qloss'). - char (float/tespy.components.characteristics.characteristics): Characteristic function for this components share to the bus value, optional. - If you do not provide a characteristic line at all, TESPy assumes a constant factor of 1. - If you provide a numeric value instead of a characteristic line, TESPy takes this numeric value as a constant factor. - Provide a TESPy.characteristic (cmp_char), if you want the factor to follow a characteristic line. - P_ref (float): Energy flow specification for reference case, :math:`P \text{/W}`, optional. """ for c in args: if isinstance(c, dict): if 'c' in c.keys(): if isinstance(c['c'], component): self.comps.loc[c['c']] = [None, np.nan, self.char] else: msg = ('Keyword c must hold a TESPy component.') logging.error(msg) raise TypeError(msg) else: msg = ('You must provide the component c.') logging.error(msg) raise TypeError(msg) for k, v in c.items(): if k == 'p': if isinstance(v, str) or v is None: self.comps.loc[c['c']]['param'] = v else: msg = ('Parameter p must be a string.') logging.error(msg) raise TypeError(msg) elif k == 'char': if isinstance(v, char_line): self.comps.loc[c['c']]['char'] = v elif (isinstance(v, float) or isinstance(v, np.float64) or isinstance(v, np.int64) or isinstance(v, int)): x = np.array([0, 3]) y = np.array([1, 1]) * v self.comps.loc[c['c']]['char'] = (char_line(x=x, y=y)) else: msg = ('Char must be a number or a TESPy ' 'characteristics.') logging.error(msg) raise TypeError(msg) elif k == 'P_ref': if (v is None or isinstance(v, float) or isinstance(v, np.float64) or isinstance(v, np.int64) or isinstance(v, int)): self.comps.loc[c['c']]['P_ref'] = v else: msg = ('Reference value must be numeric.') logging.error(msg) raise TypeError(msg) else: msg = ('Provide arguments as dicts. See the documentation of ' 'bus.add_comps() for more information.') logging.error(msg) raise TESPyConnectionError(msg) msg = ('Added component ' + c['c'].label + ' to bus ' + self.label + '.') logging.debug(msg)
def add_comps(self, *args): r""" Add components to a bus. Parameters ---------- *args : dict Dictionaries containing the component information to be added to the bus. The information are described below. Note ---- **Required Key** - comp (tespy.components.components.component): Component you want to add to the bus. **Optional Keys** - param (str): Bus parameter, optional. - You do not need to provide a parameter, if the component only has one option for the bus (turbomachines, heat exchangers, combustion chamber). - For instance, you do neet do provide a parameter, if you want to add a combustion engine ('Q', 'Q1', 'Q2', 'TI', 'P', 'Qloss'). - char (float/tespy.components.characteristics.characteristics): Characteristic function for this components share to the bus value, optional. - If you do not provide a characteristic line at all, TESPy assumes a constant factor of 1. - If you provide a numeric value instead of a characteristic line, TESPy takes this numeric value as a constant factor. - Provide a TESPy.characteristic (cmp_char), if you want the factor to follow a characteristic line. - P_ref (float): Energy flow specification for reference case, :math:`P \text{/W}`, optional. - base (str): Base value for characteristic line and efficiency calculation. The base can either be :code:`'component'` (default) or :code:`'bus'`. - In case you choose :code:`'component'`, the characteristic line input will follow the value of the component's bus function and the efficiency definition is :math:`\eta=\frac{P_\mathrm{bus}}{P_\mathrm{component}}`. - In case you choose :code:`'bus'`, the characteristic line input will follow the bus value of the component and the efficiency definition is :math:`\eta=\frac{P_\mathrm{component}}{P_\mathrm{bus}}`. """ for c in args: if isinstance(c, dict): if 'comp' in c.keys() or 'c' in c.keys(): if 'c' in c.keys(): comp = c['c'] msg = ( 'The dictionary keyword "c" will be removed in ' 'TESPy version 0.4.0. Please use "comp" instead.') warnings.warn(msg, FutureWarning, stacklevel=2) else: comp = c['comp'] # default values if isinstance(comp, component): self.comps.loc[comp] = [ None, np.nan, self.char, np.nan, 'component' ] else: msg = 'Keyword "comp" must hold a TESPy component.' logging.error(msg) raise TypeError(msg) else: msg = 'You must provide the component "comp".' logging.error(msg) raise TypeError(msg) for k, v in c.items(): if k == 'param' or k == 'p': if k == 'p': msg = ( 'The dictionary keyword "p" will be removed ' 'TESPy version 0.4.0. Please use "param" ' 'instead.') warnings.warn(msg, FutureWarning, stacklevel=2) if isinstance(v, str) or v is None: self.comps.loc[comp, 'param'] = v else: msg = ('The bus parameter selection must be a ' 'string (at bus ' + self.label + ').') logging.error(msg) raise TypeError(msg) elif k == 'char': if isinstance(v, char_line): self.comps.loc[comp, 'char'] = v elif (isinstance(v, float) or isinstance(v, np.float64) or isinstance(v, np.int64) or isinstance(v, int)): x = np.array([0, 3]) y = np.array([1, 1]) * v self.comps.loc[comp, 'char'] = (char_line(x=x, y=y)) else: msg = ('Char must be a number or a TESPy ' 'characteristics char line.') logging.error(msg) raise TypeError(msg) elif k == 'P_ref': if (v is None or isinstance(v, float) or isinstance(v, np.float64) or isinstance(v, np.int64) or isinstance(v, int)): self.comps.loc[comp, 'P_ref'] = v else: msg = 'Reference value must be numeric.' logging.error(msg) raise TypeError(msg) elif k == 'base': if v in ['bus', 'component']: self.comps.loc[comp, 'base'] = v else: msg = ( 'The base value must be "bus" or "component".') logging.error(msg) raise ValueError(msg) else: msg = ( 'Provide arguments as dictionaries. See the documentation ' 'of bus.add_comps() for more information.') logging.error(msg) raise TypeError(msg) msg = ('Added component ' + comp.label + ' to bus ' + self.label + '.') logging.debug(msg)
def test_set_attr_errors(self): # labels = [5, 'Label,', 'Labe;l', 'Label.'] for l in labels: self.cmp_instanciation_ValueError(l) # ValueErrors self.set_attr_ValueError(self.comp, offdesign=['Q']) self.set_attr_ValueError(self.conn, offdesign=['f']) self.set_attr_ValueError(self.conn, state='f') self.set_attr_ValueError(self.nw, m_unit='kg') self.set_attr_ValueError(self.nw, h_unit='kg') self.set_attr_ValueError(self.nw, p_unit='kg') self.set_attr_ValueError(self.nw, T_unit='kg') self.set_attr_ValueError(self.nw, v_unit='kg') self.create_connection_ValueError('source') self.create_connection_ValueError('target') # TypeErrors self.set_attr_TypeError(self.comp, P=[5]) self.set_attr_TypeError(self.comp, tiP_char=None) self.set_attr_TypeError(self.comp, design='f') self.set_attr_TypeError(self.comp, design_path=7) self.set_attr_TypeError(self.comp, local_design=5) self.set_attr_TypeError(self.comp, local_offdesign=5) self.set_attr_TypeError(self.pipe, hydro_group=5) self.set_attr_TypeError(self.comp, printout=5) self.set_attr_TypeError(self.conn, design='h') self.set_attr_TypeError(self.conn, fluid_balance=1) self.set_attr_TypeError(self.conn, h0=[4]) self.set_attr_TypeError(self.conn, fluid=5) self.set_attr_TypeError(self.conn, state=5) self.set_attr_TypeError(self.conn, design_path=5) self.set_attr_TypeError(self.conn, local_design=5) self.set_attr_TypeError(self.conn, local_offdesign=5) self.set_attr_TypeError(self.conn, printout=5) self.set_attr_TypeError(self.nw, m_range=5) self.set_attr_TypeError(self.nw, p_range=5) self.set_attr_TypeError(self.nw, h_range=5) self.set_attr_TypeError(self.nw, T_range=5) self.set_attr_TypeError(self.nw, iterinfo=5) self.set_attr_TypeError(self.bus, P='some value') self.set_attr_TypeError(self.bus, printout=5) self.bus_add_comps_TypeError({'c': self.conn}) self.bus_add_comps_TypeError({'f': self.comp}) self.bus_add_comps_TypeError({'c': self.comp, 'char': 'Hi'}) self.bus_add_comps_TypeError({'c': self.comp, 'p': 5}) self.bus_add_comps_TypeError({'c': self.comp, 'P_ref': 'what'}) self.create_ref_TypeError([self.conn, 7, 'hi']) self.create_ref_TypeError([self.conn, 'hi', 0]) self.create_ref_TypeError([self.comp, 1, 0]) # KeyErrors self.set_attr_KeyError(self.comp, wow=5) self.set_attr_KeyError(self.conn, jey=5) self.set_attr_KeyError(self.bus, power_output=100000) self.get_attr_KeyError(self.comp, 'wow') self.get_attr_KeyError(self.conn, 'key') self.get_attr_KeyError(self.bus, 'components') self.get_attr_KeyError(self.nw, 'missing') self.get_attr_KeyError(ref(self.conn, 1, 0), 'comp') self.get_attr_KeyError(self.sub, 'test') self.get_attr_KeyError(char_line(), 'test') self.get_attr_KeyError(data_container(), 'somekey')
def test_char_number_of_points(): char_line(x=[0, 1, 2], y=[1, 2, 3, 4])
def test_pump(self): """Test component properties of pumps.""" instance = pump('pump') self.setup_network(instance) fl = {'N2': 0, 'O2': 0, 'Ar': 0, 'INCOMP::DowQ': 1, 'NH3': 0} self.c1.set_attr(fluid=fl, v=1, p=5, T=50) self.c2.set_attr(p=7) instance.set_attr(eta_s=1) self.nw.solve('design') # test calculated value for efficiency eta_s = ((instance.h_os('') - self.c1.h.val_SI) / (self.c2.h.val_SI - self.c1.h.val_SI)) msg = ('Value of isentropic efficiency must be ' + str(eta_s) + ', is ' + str(instance.eta_s.val) + '.') eq_(eta_s, instance.eta_s.val, msg) # isentropic efficiency of 1 means inlet and outlet entropy are # identical s1 = round(s_mix_ph(self.c1.to_flow()), 4) s2 = round(s_mix_ph(self.c2.to_flow()), 4) msg = ('Value of entropy must be identical for inlet (' + str(s1) + ') and outlet (' + str(s2) + ') at 100 % isentropic efficiency.') eq_(s1, s2, msg) # specify realistic value for efficiency, outlet pressure from flow # char eta_s_d = 0.8 instance.set_attr(eta_s=eta_s_d) self.nw.solve('design') self.nw.save('tmp') self.c2.set_attr(p=np.nan) # flow char (pressure rise vs. volumetric flow) x = [0, 0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4] y = np.array([14, 13.5, 12.5, 11, 9, 6.5, 3.5, 0]) * 1e5 char = dc_cc(func=char_line(x, y), is_set=True) # apply flow char and eta_s char instance.set_attr(flow_char=char, eta_s=np.nan, eta_s_char=dc_cc(func=ldc('pump', 'eta_s_char', 'DEFAULT', char_line), is_set=True)) self.nw.solve('offdesign', design_path='tmp') # value for difference pressure dp = 650000.0 msg = ('Value of pressure rise must be ' + str(dp) + ', is ' + str(self.c2.p.val_SI - self.c1.p.val_SI) + '.') eq_(round(self.c2.p.val_SI - self.c1.p.val_SI, 0), dp, msg) # test ohter volumetric flow on flow char self.c1.set_attr(v=0.9) self.nw.solve('offdesign', design_path='tmp') dp = 775000.0 msg = ('Value of pressure rise must be ' + str(dp) + ', is ' + str(self.c2.p.val_SI - self.c1.p.val_SI) + '.') eq_(self.c2.p.val_SI - self.c1.p.val_SI, dp, msg) # test value of isentropic efficiency eta_s = round( eta_s_d * instance.eta_s_char.func.evaluate( self.c1.v.val_SI / self.c1.v.design), 3) msg = ('Value of isentropic efficiency must be ' + str(eta_s) + ', is ' + str(instance.eta_s.val) + '.') eq_(eta_s, round(instance.eta_s.val, 3), msg) instance.eta_s_char.is_set = False # test boundaries of characteristic line: # lower boundary self.c2.set_attr(T=ref(self.c1, 0, 20)) self.c1.set_attr(v=-0.1) self.nw.solve('design') msg = ('Value of power must be ' + str(14e5) + ', is ' + str(self.c2.p.val_SI - self.c1.p.val_SI) + '.') eq_(self.c2.p.val_SI - self.c1.p.val_SI, 14e5, msg) # upper boundary self.c1.set_attr(v=1.5) self.nw.solve('design') msg = ('Value of power must be ' + str(0) + ', is ' + str(self.c2.p.val_SI - self.c1.p.val_SI) + '.') eq_(self.c2.p.val_SI - self.c1.p.val_SI, 0, msg) shutil.rmtree('./tmp', ignore_errors=True)
0.031246175549793, 0.033199061521655, 0.035151947493517, 0.037104833465379, 0.039057719437241, 0.041010605409104, 0.042963491380966, 0.044916377352828, 0.04686926332469, 0.048822149296552, 0.050775035268414, 0.052727921240276, 0.054680807212138, 0.056633693184 ]) # provide head in Pa y = np.array([ 0.47782539, 0.47725723, 0.47555274, 0.47271192, 0.46873478, 0.46362130, 0.45737151, 0.44998538, 0.44146293, 0.43180416, 0.4220905, 0.40907762, 0.39600986, 0.38180578, 0.36646537, 0.34998863, 0.33237557, 0.31362618, 0.29374046, 0.27271841, 0.25056004, 0.22726535, 0.20283432, 0.17726697, 0.15056329, 0.12272329, 0.09374696, 0.06363430, 0.03238531, 0.00000000 ]) * 1e5 char = char_line(x=x, y=y) pu.set_attr(flow_char=dc_cc(func=char, is_set=True)) pu.set_attr(eta_s=0.90) # bhes bhe1.set_attr(D=2, L=0.1, ks=0.00001) bhe2.set_attr(D=2, L=0.1, ks=0.00001) bhe3.set_attr(D=2, L=0.1, ks=0.00001) # consumer cons.set_attr(D=2, L=0.1, ks=0.00001) # busses heat = bus('consumer heat demand') heat.add_comps({'c': cons, 'p': 'P'}) btes.add_busses(heat) # consumer heat demand
nw.add_conns(cp_c_out) # %% busses # motor efficiency x = np.array([ 0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.05, 1.1, 1.15, 1.2, 10 ]) y = 1 / (np.array([ 0.01, 0.3148, 0.5346, 0.6843, 0.7835, 0.8477, 0.8885, 0.9145, 0.9318, 0.9443, 0.9546, 0.9638, 0.9724, 0.9806, 0.9878, 0.9938, 0.9982, 1.0009, 1.002, 1.0015, 1, 0.9977, 0.9947, 0.9909, 0.9853, 0.9644 ]) * 0.98) mot1 = char_line(x=x, y=y) mot2 = char_line(x=x, y=y) mot3 = char_line(x=x, y=y) mot4 = char_line(x=x, y=y) power = bus('total compressor power') power.add_comps({ 'c': cp, 'char': mot1 }, { 'c': pu, 'char': mot2 }, { 'c': dhp, 'char': mot3 }, {
def setup(self): # %% network self.nw = network(fluids=['water', 'NH3'], T_unit='C', p_unit='bar', h_unit='kJ / kg', m_unit='kg / s') # %% components # sources & sinks c_in = source('coolant in') cb = source('consumer back flow') cf = sink('consumer feed flow') amb_in = source('source ambient') amb_out = sink('sink ambient') ic_in = source('source intercool') ic_out = sink('sink intercool') c_out = sink('coolant out') # consumer system cd = heat_exchanger('condenser') rp = pump('recirculation pump') cons = heat_exchanger_simple('consumer') # evaporator system va = valve('valve') dr = drum('drum') ev = heat_exchanger('evaporator') su = heat_exchanger('superheater') pu = pump('pump evaporator') # compressor-system cp1 = compressor('compressor 1') cp2 = compressor('compressor 2') he = heat_exchanger('intercooler') # busses self.power = bus('total compressor power') self.power.add_comps({'c': cp1}, {'c': cp2}) self.heat = bus('total delivered heat') self.heat.add_comps({'c': cd, 'char': -1}) self.nw.add_busses(self.power, self.heat) # %% connections # consumer system c_in_cd = connection(c_in, 'out1', cd, 'in1') cb_rp = connection(cb, 'out1', rp, 'in1') rp_cd = connection(rp, 'out1', cd, 'in2') self.cd_cons = connection(cd, 'out2', cons, 'in1') cons_cf = connection(cons, 'out1', cf, 'in1') self.nw.add_conns(c_in_cd, cb_rp, rp_cd, self.cd_cons, cons_cf) # connection condenser - evaporator system cd_va = connection(cd, 'out1', va, 'in1') self.nw.add_conns(cd_va) # evaporator system va_dr = connection(va, 'out1', dr, 'in1') dr_pu = connection(dr, 'out1', pu, 'in1') pu_ev = connection(pu, 'out1', ev, 'in2') ev_dr = connection(ev, 'out2', dr, 'in2') dr_su = connection(dr, 'out2', su, 'in2') self.nw.add_conns(va_dr, dr_pu, pu_ev, ev_dr, dr_su) self.amb_in_su = connection(amb_in, 'out1', su, 'in1') su_ev = connection(su, 'out1', ev, 'in1') ev_amb_out = connection(ev, 'out1', amb_out, 'in1') self.nw.add_conns(self.amb_in_su, su_ev, ev_amb_out) # connection evaporator system - compressor system su_cp1 = connection(su, 'out2', cp1, 'in1') self.nw.add_conns(su_cp1) # compressor-system cp1_he = connection(cp1, 'out1', he, 'in1') he_cp2 = connection(he, 'out1', cp2, 'in1') cp2_c_out = connection(cp2, 'out1', c_out, 'in1') ic_in_he = connection(ic_in, 'out1', he, 'in2') he_ic_out = connection(he, 'out2', ic_out, 'in1') self.nw.add_conns(cp1_he, he_cp2, ic_in_he, he_ic_out, cp2_c_out) # %% component parametrization # condenser system x = np.array([ 0, 0.0625, 0.125, 0.1875, 0.25, 0.3125, 0.375, 0.4375, 0.5, 0.5625, 0.6375, 0.7125, 0.7875, 0.9, 0.9875, 1, 1.0625, 1.125, 1.175, 1.2125, 1.2375, 1.25 ]) y = np.array([ 0.0076, 0.1390, 0.2731, 0.4003, 0.5185, 0.6263, 0.7224, 0.8056, 0.8754, 0.9312, 0.9729, 1.0006, 1.0203, 1.0158, 1.0051, 1.0000, 0.9746, 0.9289, 0.8832, 0.8376, 0.7843, 0.7614 ]) rp.set_attr(eta_s=0.8, design=['eta_s'], offdesign=['eta_s_char'], eta_s_char=dc_cc(func=char_line(x, y), param='m')) cons.set_attr(pr=1, design=['pr'], offdesign=['zeta']) # evaporator system x = np.linspace(0, 2.5, 26) y = np.array([ 0.000, 0.164, 0.283, 0.389, 0.488, 0.581, 0.670, 0.756, 0.840, 0.921, 1.000, 1.078, 1.154, 1.228, 1.302, 1.374, 1.446, 1.516, 1.585, 1.654, 1.722, 1.789, 1.855, 1.921, 1.986, 2.051 ]) kA_char1 = dc_cc(func=char_line(x, y), param='m') x = np.array([ 0.0100, 0.0400, 0.0700, 0.1100, 0.1500, 0.2000, 0.2500, 0.3000, 0.3500, 0.4000, 0.4500, 0.5000, 0.5500, 0.6000, 0.6500, 0.7000, 0.7500, 0.8000, 0.8500, 0.9000, 0.9500, 1.0000, 1.5000, 2.0000 ]) y = np.array([ 0.0185, 0.0751, 0.1336, 0.2147, 0.2997, 0.4118, 0.5310, 0.6582, 0.7942, 0.9400, 0.9883, 0.9913, 0.9936, 0.9953, 0.9966, 0.9975, 0.9983, 0.9988, 0.9992, 0.9996, 0.9998, 1.0000, 1.0008, 1.0014 ]) kA_char2 = dc_cc(func=char_line(x, y), param='m') ev.set_attr(pr1=1, pr2=.999, ttd_l=5, design=['ttd_l'], offdesign=['kA'], kA_char1=kA_char1, kA_char2=kA_char2) # no kA modification for hot side! x = np.array([0, 1]) y = np.array([1, 1]) kA_char1 = dc_cc(func=char_line(x, y), param='m') # characteristic line for superheater kA x = np.array( [0, 0.045, 0.136, 0.244, 0.43, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2]) y = np.array( [0, 0.037, 0.112, 0.207, 0.5, 0.8, 0.85, 0.9, 0.95, 1, 1.04, 1.07]) kA_char2 = dc_cc(func=char_line(x, y), param='m') su.set_attr(kA_char1=kA_char1, kA_char2=kA_char2, offdesign=['zeta1', 'zeta2', 'kA']) x = np.array([ 0, 0.0625, 0.125, 0.1875, 0.25, 0.3125, 0.375, 0.4375, 0.5, 0.5625, 0.6375, 0.7125, 0.7875, 0.9, 0.9875, 1, 1.0625, 1.125, 1.175, 1.2125, 1.2375, 1.25 ]) y = np.array([ 0.0076, 0.1390, 0.2731, 0.4003, 0.5185, 0.6263, 0.7224, 0.8056, 0.8754, 0.9312, 0.9729, 1.0006, 1.0203, 1.0158, 1.0051, 1.0000, 0.9746, 0.9289, 0.8832, 0.8376, 0.7843, 0.7614 ]) pu.set_attr(eta_s=0.8, design=['eta_s'], offdesign=['eta_s_char'], eta_s_char=dc_cc(func=char_line(x, y), param='m')) # compressor system x = np.array([0, 0.4, 1, 1.2]) y = np.array([0.5, 0.9, 1, 1.1]) cp1.set_attr(eta_s=0.8, design=['eta_s'], offdesign=['eta_s_char'], eta_s_char=dc_cc(func=char_line(x, y), param='m')) cp2.set_attr(eta_s=0.8, design=['eta_s'], offdesign=['eta_s_char'], eta_s_char=dc_cc(func=char_line(x, y), param='m')) # characteristic line for intercooler kA x = np.linspace(0, 2.5, 26) y = np.array([ 0.0000, 0.2455, 0.3747, 0.4798, 0.5718, 0.6552, 0.7323, 0.8045, 0.8727, 0.9378, 1.0000, 1.0599, 1.1176, 1.1736, 1.2278, 1.2806, 1.3320, 1.3822, 1.4313, 1.4792, 1.5263, 1.5724, 1.6176, 1.6621, 1.7058, 1.7488 ]) # x = np.array([0, 1]) # y = np.array([1, 1]) kA_char1 = dc_cc(func=char_line(x, y), param='m') x = np.linspace(0, 2.5, 26) y = np.array([ 0.000, 0.164, 0.283, 0.389, 0.488, 0.581, 0.670, 0.756, 0.840, 0.921, 1.000, 1.078, 1.154, 1.228, 1.302, 1.374, 1.446, 1.516, 1.585, 1.654, 1.722, 1.789, 1.855, 1.921, 1.986, 2.051 ]) # x = np.array([0, 1]) # y = np.array([1, 1]) kA_char2 = dc_cc(func=char_line(x, y), param='m') he.set_attr(kA_char1=kA_char1, kA_char2=kA_char2, offdesign=['zeta1', 'zeta2', 'kA']) # characteristic line for condenser kA x = np.linspace(0, 2.5, 26) y = np.array([ 0.0000, 0.2455, 0.3747, 0.4798, 0.5718, 0.6552, 0.7323, 0.8045, 0.8727, 0.9378, 1.0000, 1.0599, 1.1176, 1.1736, 1.2278, 1.2806, 1.3320, 1.3822, 1.4313, 1.4792, 1.5263, 1.5724, 1.6176, 1.6621, 1.7058, 1.7488 ]) kA_char1 = dc_cc(func=char_line(x, y), param='m') x = np.linspace(0, 2.5, 26) y = np.array([ 0.000, 0.164, 0.283, 0.389, 0.488, 0.581, 0.670, 0.756, 0.840, 0.921, 1.000, 1.078, 1.154, 1.228, 1.302, 1.374, 1.446, 1.516, 1.585, 1.654, 1.722, 1.789, 1.855, 1.921, 1.986, 2.051 ]) kA_char2 = dc_cc(func=char_line(x, y), param='m') cd.set_attr(kA_char1=kA_char1, kA_char2=kA_char2, pr2=0.9998, design=['pr2'], offdesign=['zeta2', 'kA']) # %% connection parametrization # condenser system c_in_cd.set_attr(fluid={'water': 0, 'NH3': 1}, p=60) rp_cd.set_attr(T=60, fluid={'water': 1, 'NH3': 0}, p=10) self.cd_cons.set_attr(T=105) cons_cf.set_attr(h=ref(cb_rp, 1, 0), p=ref(cb_rp, 1, 0)) cd_va.set_attr(p=ref(c_in_cd, 1, -1000), Td_bp=-5, h0=500, design=['Td_bp']) # evaporator system cold side pu_ev.set_attr(m=ref(va_dr, 10, 0), p0=5) dr_su.set_attr(p0=5, T=5) su_cp1.set_attr(p=ref(dr_su, 1, -5000), Td_bp=5, h0=1700, design=['Td_bp', 'p']) # evaporator system hot side self.amb_in_su.set_attr(m=20, T=12, p=1, fluid={'water': 1, 'NH3': 0}) su_ev.set_attr(p=ref(self.amb_in_su, 1, -100), design=['p']) ev_amb_out.set_attr() # compressor-system cp1_he.set_attr(p=15) he_cp2.set_attr(T=40, p=ref(cp1_he, 1, -1000), design=['T', 'p']) ic_in_he.set_attr(p=1, T=20, m=5, fluid={'water': 1, 'NH3': 0}) he_ic_out.set_attr(p=ref(ic_in_he, 1, -200), design=['p']) cp2_c_out.set_attr(p=ref(c_in_cd, 1, 0), h=ref(c_in_cd, 1, 0))
def test_char_number_of_points(): with raises(ValueError): char_line(x=[0, 1, 2], y=[1, 2, 3, 4])
# valve_1.set_attr(pr=1) # District Heating dh_heater.set_attr(pr1=0.99, pr2=0.99, ttd_u=5, design=['ttd_u', 'pr1', 'pr2'], offdesign=['kA', 'zeta1', 'zeta2']) # %% Busses # characteristic function for generator efficiency x = np.array([0, 0.2, 0.4, 0.6, 0.8, 1, 1.2]) y = np.array([0, 0.86, 0.9, 0.93, 0.95, 0.96, 0.95]) gen = char_line(x=x, y=y) gas_turbine_bus = bus('gas_turbine_bus') gas_turbine_bus.add_comps({ 'c': compressor_gtp, 'char': gen }, { 'c': gas_turbine, 'char': gen }) steam_turbine_bus = bus('steam_turbine_bus') steam_turbine_bus.add_comps({ 'c': hp_turbine, 'char': gen }, {
'N2': 0, 'H2O': 1, 'CH4': 0, 'CO2': 0, 'O2': 0 }) dh_heat_exchanger.dh_sink.set_attr(T=t_dh_out) # %% Busses # power bus power = bus('power output') x = np.array([0.2, 0.4, 0.6, 0.8, 1.0, 1.1]) y = np.array([0.85, 0.93, 0.95, 0.96, 0.97, 0.96]) # create a characteristic line for a generator gen1 = char_line(x=x, y=y) power.add_comps({ 'comp': gas_turbine, 'char': gen1 }, { 'comp': steam_turbine, 'char': gen1 }, {'comp': air_compressor}) nw.add_busses(power) # heat bus heat = bus('heat output') heat.add_comps({'comp': dh_heat_exchanger}) nw.add_busses(heat)
def setup(self): """Set up the model.""" # %% network setup fluid_list = ['Ar', 'N2', 'O2', 'CO2', 'CH4', 'H2O'] self.nw = network(fluids=fluid_list, p_unit='bar', T_unit='C', p_range=[0.5, 20], T_range=[10, 2000]) # %% components amb = source('ambient') sf = source('fuel') cc = combustion_chamber('combustion') cp = compressor('compressor') gt = turbine('turbine') fg = sink('flue gas outlet') # %% connections amb_cp = connection(amb, 'out1', cp, 'in1', label='ambient air flow') cp_cc = connection(cp, 'out1', cc, 'in1') sf_cc = connection(sf, 'out1', cc, 'in2') cc_gt = connection(cc, 'out1', gt, 'in1') gt_fg = connection(gt, 'out1', fg, 'in1') self.nw.add_conns(amb_cp, cp_cc, sf_cc, cc_gt, gt_fg) # %% component parameters cc.set_attr(lamb=3) cp.set_attr(eta_s=0.9, pr=15) gt.set_attr(eta_s=0.9) # %% connection parameters amb_cp.set_attr(T=20, p=1, m=100, fluid={ 'Ar': 0.0129, 'N2': 0.7553, 'H2O': 0, 'CH4': 0, 'CO2': 0.0004, 'O2': 0.2314 }) sf_cc.set_attr(T=20, fluid={ 'CO2': 0.04, 'Ar': 0, 'N2': 0, 'O2': 0, 'H2O': 0, 'CH4': 0.96 }) gt_fg.set_attr(p=1) # motor efficiency x = np.array([ 0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.05, 1.1, 1.15, 1.2, 10 ]) y = np.array([ 0.01, 0.3148, 0.5346, 0.6843, 0.7835, 0.8477, 0.8885, 0.9145, 0.9318, 0.9443, 0.9546, 0.9638, 0.9724, 0.9806, 0.9878, 0.9938, 0.9982, 0.999, 0.9995, 0.9999, 1, 0.9977, 0.9947, 0.9909, 0.9853, 0.9644 ]) * 0.975 self.motor_bus_based = char_line(x=x, y=y) self.motor_comp_based = char_line(x=x, y=1 / y) # generator efficiency x = np.array([ 0.100, 0.345, 0.359, 0.383, 0.410, 0.432, 0.451, 0.504, 0.541, 0.600, 0.684, 0.805, 1.000, 1.700, 10 ]) y = np.array([ 0.976, 0.989, 0.990, 0.991, 0.992, 0.993, 0.994, 0.995, 0.996, 0.997, 0.998, 0.999, 1.000, 0.999, 0.99 ]) * 0.975 self.generator = char_line(x=x, y=y) power_bus_total = bus('total power output') power_bus_total.add_comps( { 'comp': cp, 'char': self.motor_bus_based, 'base': 'bus' }, { 'comp': gt, 'char': self.generator }) thermal_input = bus('thermal input') thermal_input.add_comps({'comp': cc}) compressor_power_comp = bus('compressor power input') compressor_power_comp.add_comps({ 'comp': cp, 'char': self.motor_comp_based }) compressor_power_bus = bus('compressor power input bus based') compressor_power_bus.add_comps({ 'comp': cp, 'char': self.motor_bus_based, 'base': 'bus' }) self.nw.add_busses(power_bus_total, thermal_input, compressor_power_comp, compressor_power_bus) # %% solving self.nw.solve('design') self.nw.save('tmp')
fw_el = connection(fw, "out1", el, "in2") el_comp = connection(el, 'out3', comp, 'in1') comp_hydro = connection(comp, 'out1', hydro, 'in1') el_oxy = connection(el, 'out2', oxy, 'in1') cw_cold_el = connection(cw_cold, 'out1', el, 'in1') el_cw_hot = connection(el, 'out1', cw_hot, 'in1') nw.add_conns(fw_el, el_comp, comp_hydro, el_oxy, cw_cold_el, el_cw_hot) # %% busses # create characteristic line for the compressor motor x = np.array([0.2, 0.4, 0.6, 0.8, 1.0, 1.1]) y = np.array([0.85, 0.93, 0.95, 0.96, 0.97, 0.96]) mot1 = char_line(x=x, y=y) power = bus('total power bus') power.add_comps({'comp': el, 'param': 'P'}, {'comp': comp, 'char': mot1}) nw.add_busses(power) # %% parameters comp.set_attr(eta_s=0.9) el.set_attr(P=Q_hydro * 1e6 / 0.8, eta=eta_e, pr_c=0.99, design=['eta', 'pr_c'], offdesign=['eta_char', 'zeta']) fw_el.set_attr(p=10, T=15)
def construct_comps(c, *args): r""" Create TESPy component from class name and set parameters. Parameters ---------- c : pandas.core.series.Series Component information from .csv-file. args[0] : pandas.core.frame.DataFrame DataFrame containing the data of characteristic lines. args[1] : pandas.core.frame.DataFrame DataFrame containing the data of characteristic maps. Returns ------- instance : tespy.components.components.component TESPy component object. """ target_class = comp_target_classes[c.cp] instance = target_class(c.label) kwargs = {} # basic properties for key in [ 'design', 'offdesign', 'design_path', 'local_design', 'local_offdesign' ]: if key in c: kwargs[key] = c[key] for key, value in instance.variables.items(): if key in c: # component parameters if isinstance(value, dc_cp): kwargs[key] = dc_cp(val=c[key], is_set=c[key + '_set'], is_var=c[key + '_var']) # component parameters elif isinstance(value, dc_simple): kwargs[key] = dc_simple(val=c[key], is_set=c[key + '_set']) # component characteristics elif isinstance(value, dc_cc): # finding x and y values of the characteristic function values = args[0]['id'] == c[key] try: x = args[0][values].x.values[0] y = args[0][values].y.values[0] extrapolate = False if 'extrapolate' in args[0].columns: extrapolate = args[0][values].extrapolate.values[0] char = char_line(x=x, y=y, extrapolate=extrapolate) except IndexError: char = None msg = ('Could not find x and y values for characteristic ' 'line, using defaults instead for function ' + key + ' at component ' + c.label + '.') logging.warning(msg) kwargs[key] = dc_cc(is_set=c[key + '_set'], param=c[key + '_param'], func=char) # component characteristics elif isinstance(value, dc_cm): # finding x and y values of the characteristic function values = args[1]['id'] == c[key] try: x = list(args[1][values].x.values[0]) y = list(args[1][values].y.values[0]) z1 = list(args[1][values].z1.values[0]) z2 = list(args[1][values].z2.values[0]) target_class = map_target_classes[args[1] [values].type.values[0]] char = target_class(x=x, y=y, z1=z1, z2=z2) except IndexError: char = None msg = ('Could not find x, y, z1 and z2 values for ' 'characteristic map of component ' + c.label + '!') logging.warning(msg) kwargs[key] = dc_cm(is_set=c[key + '_set'], param=c[key + '_param'], func=char) # grouped component parameters elif isinstance(value, dc_gcp): kwargs[key] = dc_gcp(method=c[key]) instance.set_attr(**kwargs) return instance
nw.add_conns(cw_i, cw_o, dh_i, dh_o) # %% busses # motor efficiency x = np.array([ 0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.05, 1.1, 1.15, 1.2, 10 ]) y = 1 / (np.array([ 0.01, 0.3148, 0.5346, 0.6843, 0.7835, 0.8477, 0.8885, 0.9145, 0.9318, 0.9443, 0.9546, 0.9638, 0.9724, 0.9806, 0.9878, 0.9938, 0.9982, 1.0009, 1.002, 1.0015, 1, 0.9977, 0.9947, 0.9909, 0.9853, 0.9644 ]) * 0.97) mot1 = char_line(x=x, y=y) mot2 = char_line(x=x, y=y) mot3 = char_line(x=x, y=y) # generator efficiency x = np.array([ 0.100, 0.345, 0.359, 0.383, 0.410, 0.432, 0.451, 0.504, 0.541, 0.600, 0.684, 0.805, 1.000, 1.700, 10 ]) y = np.array([ 0.976, 0.989, 0.990, 0.991, 0.992, 0.993, 0.994, 0.995, 0.996, 0.997, 0.998, 0.999, 1.000, 0.999, 0.99 ]) * 0.984 gen1 = char_line(x=x, y=y) gen2 = char_line(x=x, y=y)