def nominal_diameter(cls,
                         d_int: Optional[qty.Length] = None,
                         d_ext: Optional[qty.Length] = None) -> qty.Length:
        """
        Get nearest nominal diameter when either inside or either outside diameter is given.

        **Parameters:**

        - `d_int`: (*quantities.Length*) = inside diameter (default None).
        - `d_ext`: (*quantities.Length*) = outside diameter (default None).

        **Returns:** (*quantities.Length*)

        """
        if d_int:
            d_int = d_int('mm')
            delta = [
                abs(d_int - d_int_40) for d_int_40 in cls.dimensions['d_int']
            ]
            idx = delta.index(min(delta))
            return qty.Length(cls.dimensions.index[idx], 'mm')
        elif d_ext:
            d_ext = d_ext('mm')
            delta = [d_ext - d_ext_40 for d_ext_40 in cls.dimensions['d_ext']]
            idx = delta.index(min(delta))
            return qty.Length(cls.dimensions.index[idx], 'mm')
Esempio n. 2
0
    def calculate_diameter(self) -> qty.Length:
        """
        Calculate the diameter of the pipe if flow rate and friction loss are given on creation.

        **Returns:** (*quantities.Length*) = calculated or theoretical inside diameter of the pipe.

        """
        # given: friction loss and flow rate
        rho = self._fluid.density()
        mu = self._fluid.kinematic_viscosity()
        pi = math.pi
        dpf = self._dp_fric
        V = self._flow_rate
        l = self._length
        f = 0.03
        i = 0
        di: float = 0.0
        while i < self._max_iterations:
            di = (f * l / dpf * rho * 8.0 / (pi**2.0) * V**2.0)**(1.0 / 5.0)
            A = pi * di**2.0 / 4.0
            v = V / A
            re = reynolds_number(v, di, mu)
            rel_pipe_rough = self._rough / di
            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._cross_section.diameter = qty.Length(di)
        return qty.Length(di)
    def inside_diameter(cls, DN: qty.Length) -> qty.Length:
        """
        Get inside diameter (*quantities.Length*) of pipe with nominal diameter DN (*quantities.Length*).

        """
        DN = int(DN('mm'))
        try:
            return qty.Length(cls.dimensions.loc[DN, 'd_int'], 'mm')
        except KeyError:
            return qty.Length(0.0, 'mm')
    def wall_thickness(cls, DN: qty.Length) -> qty.Length:
        """
        Get wall thickness (*quantities.Length*) of pipe with nominal diameter DN (*quantities.Length*).

        """
        DN = int(DN('mm'))
        return qty.Length(cls.dimensions.loc[DN, 't'], 'mm')
Esempio n. 5
0
    def diameter(self) -> qty.Length:
        """
        Get/set the inside diameter (object of type *quantities.Length*) of the pipe section the fitting or valve
        belongs to.

        """
        return qty.Length(self._di)
Esempio n. 6
0
 def velocity(self) -> qty.Velocity:
     """Get flow velocity (*quantities.Velocity*) in the section."""
     if self.type != 'pseudo':
         di = self._pipe_schedule.inside_diameter(self.nominal_diameter)
     else:
         di = qty.Length(math.nan)
     return qty.Velocity(self.V / (math.pi * di()**2 / 4.0))
class PipeSchedule40(PipeSchedule):
    """
    Class that holds dimensional data and pipe wall roughness for pipe schedule 40 (ANSI B36.10 - B36.19)
    for carbon and alloy steel + stainless steel.
    """
    d_ext = [
        10.3, 13.7, 17.1, 21.3, 26.7, 33.4, 42.2, 48.3, 60.3, 73.0, 88.9,
        101.6, 114.3
    ]  # [mm]
    t = [
        1.73, 2.24, 2.31, 2.77, 2.87, 3.38, 3.56, 3.68, 3.91, 5.16, 5.49, 5.74,
        6.02
    ]  # [mm]
    d_int = [
        6.84, 9.22, 12.5, 15.8, 21.0, 26.6, 35.1, 40.9, 52.5, 62.7, 77.9, 90.1,
        102.3
    ]  # [mm]
    d_nom = [6, 8, 10, 15, 20, 25, 32, 40, 50, 65, 80, 90, 100]  # [mm]
    dimensions = pd.DataFrame(data={
        'd_ext': d_ext,
        't': t,
        'd_int': d_int
    },
                              index=pd.Index(data=d_nom, name='DN'))
    pipe_roughness = qty.Length(0.046, 'mm')
    def outside_diameter(cls, DN: qty.Length) -> qty.Length:
        """
        Get outside diameter (*quantities.Length*) of pipe with nominal diameter DN (*quantities.Length*).

        """
        DN = int(DN('mm'))
        return qty.Length(cls.dimensions.loc[DN, 'd_ext'], 'mm')
Esempio n. 9
0
    def zeta(self) -> float:
        """
        Get the resistance coefficient (*float*) of the fitting or valve.

        """
        if not math.isnan(self._zeta_inf):
            dp = self._calc_pressure_drop_3K()
            vp = self._fluid.density('kg/m^3') * self._vel**2.0 / 2.0
            return dp / vp
        elif not math.isnan(self._zeta):
            return self._zeta
        elif not math.isnan(self._Kv):
            return ResistanceCoefficient.from_Kv(self._Kv,
                                                 qty.Length(self._di))
        elif not math.isnan(self._ELR):
            return ResistanceCoefficient.from_ELR(self._ELR,
                                                  qty.Length(self._di))
Esempio n. 10
0
    def nominal_diameter(self) -> qty.Length:
        """
        Get/set the nominal diameter (*quantities.Length*) of the cross section.

        The inside diameter that corresponds with the nominal diameter is also set based on the pipe schedule that
        was passed at the instance the CrossSection object was created.

        """
        return qty.Length(self._dn)
Esempio n. 11
0
    def diameter(self) -> qty.Length:
        """
        Get/set the inside diameter (*quantities.Length) of the cross section.

        This will also set the nearest nominal diameter and corresponding inside diameter based on the pipe schedule
        that was passed when creating the cross section.

        """
        return qty.Length(self._di)
Esempio n. 12
0
 def height(self) -> qty.Length:
     """
     Get the height difference (*quantities.Length*) between the end node of the last real section and the start node
     of first real section in the path. (Any pseudo sections in the path are ignored.)
     """
     first = self.get_first_real_section()
     last = self.get_last_real_section()
     z1 = first.start_node.height()
     z2 = last.end_node.height()
     return qty.Length(z2 - z1)
Esempio n. 13
0
 def configure_network_from_df(cls, df: pd.DataFrame, clear=False):
     """
     Configure network from a Pandas DataFrame object. If clear is set to True the internal network objects will
     be cleared first; this may be needed in case the network needs to be reconfigured.
     """
     if clear is True:
         cls.network.clear()
     for _, row in df.iterrows():
         row = cls._check_row(row)
         cls.network.add_section(
             loop_id=row[0],
             section_id=row[1],
             start_node_id=row[2],
             end_node_id=row[3],
             nominal_diameter=qty.Length(row[4], cls.units['diameter']),
             length=qty.Length(row[5], cls.units['length']),
             zeta=row[6],
             pump_curve=row[7],
             dp_fixed=row[8],
             flow_rate=qty.VolumeFlowRate(row[9], cls.units['flow_rate'])
         )
Esempio n. 14
0
 def _choose_zetas(cls):
     zeta1_pos = [i for i in range(1, 32, 4)]
     zeta2_pos = [i for i in range(7, 32, 4)]
     slider_values = [slider.value for slider in cls.sliders]
     Kv_values = [value / cls.ratio for value in slider_values]
     dn = qty.Length(40, 'mm')
     di = PipeSchedule40.inside_diameter(dn)
     zeta_values = [
         ResistanceCoefficient.from_Kv(Kv, di) for Kv in Kv_values
     ]
     cls.df_building.loc[zeta1_pos, 'zeta'] = zeta_values
     cls.df_building.loc[zeta2_pos, 'zeta'] = zeta_values[:-1]
Esempio n. 15
0
    def create(cls, id_: str, height: qty.Length = qty.Length(0.0)) -> 'Node':
        """
        Create network node.

        **Parameters:**

        - `id_`: (*str*) = the id of the node
        - height: (*quantities.Length*) = height of the node with respect to a reference plane

        **Returns:** (*Node*)

        """
        n = cls()
        n.id = id_
        n.height = height
        return n
Esempio n. 16
0
class GebMapressSteel(PipeSchedule):
    """
    Class that holds dimensional data and pipe wall roughness for Geberit Mapress C Steel.
    """
    d_ext = [
        12.0, 15.0, 18.0, 22.0, 28.0, 35.0, 42.0, 54.0, 76.1, 66.7, 88.9, 108.0
    ]  # [mm]
    t = [1.2, 1.2, 1.2, 1.5, 1.5, 1.5, 1.5, 1.5, 2.0, 1.5, 2.0, 2.0]  # [mm]
    d_int = [d_ext - 2 * t for d_ext, t in zip(d_ext, t)]  # [mm]
    d_nom = [10, 12, 15, 20, 25, 32, 40, 50, 65, 66.7, 80, 100]  # [mm]
    dimensions = pd.DataFrame(data={
        'd_ext': d_ext,
        't': t,
        'd_int': d_int
    },
                              index=pd.Index(data=d_nom, name='DN'))
    pipe_roughness = qty.Length(0.010, 'mm')
Esempio n. 17
0
 def height(self) -> qty.Length:
     """Get/set the height (*quantities.Length*) of the node with respect to a reference plane."""
     return qty.Length(self._height)
Esempio n. 18
0
 def length(self) -> qty.Length:
     """Get length (*quantities.Length*) of the section."""
     return qty.Length(self._length)
Esempio n. 19
0
 def _calc_pressure_drop_ELR(self) -> float:
     """Calculate pressure drop across fitting with Crane-K-method."""
     vp = self._fluid.density('kg/m^3') * self._vel**2.0 / 2.0
     zeta = ResistanceCoefficient.from_ELR(self._ELR, qty.Length(self._di))
     return zeta * vp
Esempio n. 20
0
    def diameter(self) -> qty.Length:
        """
        Get/set the (equivalent) diameter (*quantities.Length*) of the cross section.

        """
        return qty.Length()
Esempio n. 21
0
 def roughness(self) -> qty.Length:
     """Get/set the pipe wall roughness (*quantities.Length*) of the pipe."""
     return qty.Length(self._rough)
Esempio n. 22
0
 def length(self) -> qty.Length:
     """Get/set the length (*quantities.Length*) of the pipe."""
     return qty.Length(self._length)
Esempio n. 23
0
 def nominal_diameter(self) -> qty.Length:
     """Get diameter (*quantities.Length*) of the section."""
     return qty.Length(self._nom_diameter)
Esempio n. 24
0
    def calculated_diameter(self) -> qty.Length:
        """
        Get the calculated or theoretical inside diameter (*quantities.Length*) of the cross section.

        """
        return qty.Length(self._di_th)