def get_coefficients( self, units: Optional[Dict[str, str]] = None) -> Optional[List[float]]: """ Get the coefficients of the 2nd order polynomial describing the pump curve. **Parameters:** - `units`: (*Optional[[Dict[str, str]]*)<br> Optional dictionary that contains the measuring units in which the returned coefficients must be expressed. Default is None, which means that the coefficients will be returned expressed in the measuring units passed in at the instantiation of the *PumpCurve* object. Keys: + 'flow_rate' + 'pressure' """ if units is not None: p_src = qty.Pressure(1.0, self._dest_units['pressure']) V_src = qty.VolumeFlowRate(1.0, self._dest_units['flow_rate']) p_des = p_src(units['pressure']) V_des = V_src(units['flow_rate']) else: p_des = 1.0 V_des = 1.0 a0 = self._coefficients[0] * p_des a1 = self._coefficients[1] * (p_des / V_des) a2 = self._coefficients[2] * (p_des / V_des**2) return [a0, a1, a2]
def flow_rate(self) -> qty.VolumeFlowRate: """Get the flow rate (*quantities.VolumeFlowRate*) that enters the network.""" start_node = self._nodes[self._start_node_id] V = 0.0 for section in start_node.outgoing: V += section.flow_rate() return qty.VolumeFlowRate(V)
def calculate_flow_rate(self, sum_zeta: float = 0.0) -> qty.VolumeFlowRate: """ Calculate flow rate through the pipe if nominal diameter and friction loss are known on creation. **Parameters:** - `sum_zeta`: (*float*) = sum of resistance coefficients of fittings/valves present in the pipe. **Returns:** (*quantities.VolumeFlowRate*) """ # given: friction loss and cross section (area and hydraulic diameter) rho = self._fluid.density() mu = self._fluid.kinematic_viscosity() di = self._cross_section.diameter() rel_pipe_rough = self._rough / di f = 1.325 / math.log10(rel_pipe_rough / 3.7)**2.0 i = 0 v = 0.0 while i < self._max_iterations: var = f * self._length / di + sum_zeta v = math.sqrt(2.0 * self._dp_fric / (rho * var)) re = reynolds_number(v, di, mu) f_new = darcy_friction_factor(re, rel_pipe_rough) if abs(f_new - f) <= 1.0e-5: break else: f = f_new i += 1 if i == self._max_iterations: raise OverflowError( 'too many iterations. no solution found') self._flow_rate = self._cross_section.area() * v return qty.VolumeFlowRate(self._flow_rate)
def flow_rate(self) -> qty.VolumeFlowRate: """ Get the flow rate (*quantities.VolumeFlowRate*) of the network, i.e. the sum of the leaving flow rates at the start node of the network, which is equal to the total flow rate that enters the network. """ start_node = self.nodes[self.start_node_id] V = 0.0 for section in start_node.outgoing: V += section.flow_rate() return qty.VolumeFlowRate(V)
def add_measuring_points(self, points: List[Tuple[float, float]], units: Dict[str, str]): """ Add some data points taken from the pump curve in the data sheet. This will execute the curve fitting algorithm that approaches the pump curve with a 2nd order polynomial. **Parameters:** - `points`: (*List[Tuple[float, float]]*)<br> List of tuples. The 1st element of the tuple is flow rate, the 2nd element is pressure. - `units`: (*Dict[str, str]*)<br> Dictionary that contains the measuring units in which the values of the data points are expressed. Keys: + 'flow_rate' + 'pressure' """ self._meas_points = [(qty.VolumeFlowRate(V, units['flow_rate']), qty.Pressure(p, units['pressure'])) for V, p in points] self._curve_fitting()
def set_coefficients(self, coeff: Tuple[float, float, float], units: Dict[str, str]): """ Set the known coefficients of the 2nd order polynomial describing the pump curve. **Parameters:** - `coeff`: (*Tuple[float, float, float]*)<br> Tuple of 3 floats: a0, a1 and a2 as in the equation dp_pump = a0 + a1 * V + a2 * V **2 - `units`: (*Dict[str, str]*)<br> Dictionary that contains the measuring units in which the pump coefficients are expressed. Keys: + 'flow_rate' + 'pressure' """ p_src = qty.Pressure(1.0, units['pressure']) V_src = qty.VolumeFlowRate(1.0, units['flow_rate']) p_des = p_src(self._dest_units['pressure']) V_des = V_src(self._dest_units['flow_rate']) a0 = coeff[0] * p_des a1 = coeff[1] * (p_des / V_des) a2 = coeff[2] * (p_des / V_des**2) self._coefficients = np.array([a0, a1, a2])
def create_system_curve(self, V_initial: qty.VolumeFlowRate, V_final: qty.VolumeFlowRate, num: int = 50): """ Calculate the system curve between an initial and final flow rate. **Parameters:** - `V_initial`: (*quantities.VolumeFlowRate*) = initial flow rate - `V_final`: (*quantities.VolumeFlowRate*) = final flow rate - `num`: (*int*) = number of calculation points (default = 50) **Returns:** (*Tuple[np.array, np.array]*) Tuple with 1st element a numpy array of the flow rates and 2nd element a numpy array of the corresponding pressures, both expressed in the desired measuring units set at instantiation of the *SystemCurve*-object. """ V_i = V_initial(self._V_unit) V_f = V_final(self._V_unit) V_arr = np.linspace(V_i, V_f, num, endpoint=True) p_arr = self._R_hyd * V_arr ** 2 + self._dp_stat + self._dp_elev V_qty = [qty.VolumeFlowRate(V, self._V_unit) for V in V_arr] p_qty = [qty.Pressure(p, self._p_unit) for p in p_arr] V_sys = [V(self._dest_units['flow_rate']) for V in V_qty] p_sys = [p(self._dest_units['pressure']) for p in p_qty] return V_sys, p_sys
""" DEMO 5 ------ Calculate pressure drop in a pipe. """ from pypeflow.core import Pipe from pypeflow.core.fluids import Water from pypeflow.core.pipe_schedules import PipeSchedule40 import quantities as qty pipe = Pipe.create( fluid=Water(10.0), pipe_schedule=PipeSchedule40, length=qty.Length(2.7, 'm'), flow_rate=qty.VolumeFlowRate(2.180, 'L/s'), nominal_diameter=qty.Length(40.0, 'mm'), sum_zeta=-0.029 ) print(f'Pressure drop = {pipe.pressure_loss("bar"):.3f} bar.')
pump_curve = PumpCurve(dest_units={'flow_rate': 'L/s', 'pressure': 'bar'}) pump_curve.add_measuring_points(points=[(0.0, 60.0), (2.4, 52.0), (4.2, 48.0), (6.0, 36.0)], units={ 'flow_rate': 'm^3/h', 'pressure': 'm' }) coeff1 = pump_curve.get_coefficients(units={ 'pressure': 'Pa', 'flow_rate': 'm^3/s' }) print(coeff1) coeff2 = pump_curve.get_coefficients(units={ 'pressure': 'bar', 'flow_rate': 'L/s' }) print(coeff2) graph_ = pump_curve.draw_pump_curve( V_initial=qty.VolumeFlowRate(0.0, 'm^3/h'), V_final=qty.VolumeFlowRate(7.2, 'm^3/h'), fig_size=(10, 8), dpi=150, num=100, V_max=qty.VolumeFlowRate(3.0, 'L/s'), V_step=qty.VolumeFlowRate(0.5, 'L/s'), p_max=qty.Pressure(8.0, 'bar'), p_step=qty.Pressure(2.0, 'bar')) graph_.show()
with pd.option_context('display.max_rows', None, 'display.max_columns', None, 'display.width', 320): print(df3) print() print('Flow paths') print() df4 = Designer.get_paths() with pd.option_context('display.max_rows', None, 'display.max_columns', None, 'display.width', 320): print(df4) print() print('DRAW THE SYSTEM CURVE') print('---------------------') R_hyd = Designer.network.hydraulic_resistance system_curve = SystemCurve(R_hyd, { 'flow_rate': 'm^3/s', 'pressure': 'Pa' }, { 'flow_rate': 'L/s', 'pressure': 'bar' }) graph = system_curve.draw_system_curve(V_initial=qty.VolumeFlowRate( 0.0, 'L/s'), V_final=qty.VolumeFlowRate(2.5, 'L/s'), V_max=qty.VolumeFlowRate(2.5, 'L/s'), V_step=qty.VolumeFlowRate(0.2, 'L/s')) graph.show()
def flow_rate(self) -> qty.VolumeFlowRate: """Get flow rate (*quantities.VolumeFlowRate*) of the section.""" return qty.VolumeFlowRate(self.V)
""" DEMO 8 ------ Create a check valve fitting """ import quantities as qty from pypeflow.core.fitting import Fitting from pypeflow.core.fluids import Water from pypeflow.core.cross_sections import Circular from pypeflow.core.pipe_schedules import PipeSchedule40 flow_rate = qty.VolumeFlowRate(1.696, 'L/s') cross_section = Circular.create(pipe_schedule=PipeSchedule40, dn=qty.Length(40.0, 'mm')) velocity = qty.Velocity(flow_rate() / cross_section.area()) check_valve = Fitting.create_w_velocity(type_='check_valve', fluid=Water(10.0), velocity=velocity, di=cross_section.diameter, ELR=55.0) # pressure drop across fitting dp_fitting = check_valve.pressure_drop print(f'Pressure drop across check valve = {dp_fitting("Pa"):.3f} Pa') # resistance coefficient of fitting zeta = check_valve.zeta print(f'Resistance coefficient of check valve = {zeta:.3f}')
def flow_rate(self) -> qty.VolumeFlowRate: """ Get/set the flow rate (*quantities.VolumeFlowRate*) through the fitting or valve. """ return qty.VolumeFlowRate(self._flow_rate)
""" DEMO 6 ------ Calculate flow coefficient and resistance coefficient of draw-off point from known flow rate and pressure drop. """ import quantities as qty from pypeflow.core.flow_coefficient import FlowCoefficient from pypeflow.core.resistance_coefficient import ResistanceCoefficient from pypeflow.core.pipe_schedules import PipeSchedule40 V = qty.VolumeFlowRate(0.29, 'L/s') dp = qty.Pressure(0.05, 'MPa') Kv = FlowCoefficient.calc_Kv(V, dp) print(f'flow coefficient = {Kv:.3f}') di = PipeSchedule40.inside_diameter(DN=qty.Length(15.0, 'mm')) print(f'inside diameter = {di("mm"):.3f} mm') zeta = ResistanceCoefficient.from_Kv(Kv, di) print(f'resistance coefficient = {zeta:.3f}')