Source code for aguaclara.design.sed_chan

"""The sedimentation channel of an AguaClara water treatment plant ensures that
the sedimentation tanks do not exceed their maximum influent flow. If that were
to happen, the upflow velocity would be too great for flocs to settle out.

Example:
    >>> from aguaclara.design.sed_chan import *
    >>> sed_chan = SedimentationChannel(q = 20 * u.L / u.s, temp = 20 * u.degC)
    >>> round(sed_chan.inlet_w, 5)
    <Quantity(59.52756, 'inch')>
"""
from aguaclara.core.units import u
import aguaclara.core.constants as con
import aguaclara.core.materials as mat
import aguaclara.core.utility as ut
import aguaclara.core.physchem as pc
import aguaclara.core.pipes as pipe
import aguaclara.core.head_loss as hl
import aguaclara.design.human_access as ha
from aguaclara.design.component import Component
from aguaclara.design.pipeline import Pipe

import numpy as np
import math


[docs]class SedimentationChannel(Component): """Design an AguaClara sedimentation channel. The sedimentation channel relies on the number and dimensions of the sedimentation tanks in the same plant, but assumed/default values may be used to design a sedimentation channel by itself. To design these components in tandem, use :class:`aguaclara.design.sed.Sedimentor`. Constants: - ``SED_TANK_Q_RATIO (float)``: Permissible ratio of influent flow between the sedimentation tanks - ``PLANT_FREE_BOARD_H (float * u.cm)``: Freeboard height in the plant - ``WEIR_FREEBOARD_H (float * u.cm)``: Freeboard height of a channel weir - ``SED_DEPTH_EST (float * u.m)``: Estimated depth of the sedimentor Design Inputs: - ``q (float * u.L / u.s)``: Flow rate (recommended, defaults to 20L/s) - ``temp (float * u.degC)``: Water temperature (recommended, defaults to 20°C) - ``sed_tank_n (int)``: Number of sedimentation tanks (recommended, defaults to 4) - ``sed_tank_w_inner (float * u.inch)``: Inner width of the sedimentation tank (recommended, defaults to 42 in) - ``sed_tank_wall_thickness (float * u.cm)``: Wall thickness of the sedimentation tank (recommended, defaults to 15 cm) - ``sed_tank_inlet_man_nd (float * u.cm)``: Nominal diameter of the sedimentation tank's inlet manifold (recommended, defaults to 60 cm) - ``sed_tank_outlet_man_nd (float * u.cm)``: Nominal diameter of the sedimentation tank's outlet manifold (recommended, defaults to 60 cm) - ``sed_tank_outlet_man_hl (float * u.cm)``: Head loss in the sedimentation tank's outlet manifold (recommended, defaults to 4 cm) - ``sed_tank_diffuser_hl (float * u.mm)``: Head loss through a diffuser in the sedimentation tank (recommended, defaults to 0.09 cm) - ``sed_wall_thickness (float * u.cm)``: Wall thickness of the sedimentor (recommended, defaults to 15 cm) - ``weir_thickness (float * u.cm)``: Weir thickness (optional, defaults to 15 cm) - ``weir_hl (float * u.cm)``: Head loss over the weir (optional, defaults to 5 cm) - ``w_min (float * u.cm)``: Minimum width (optional, defaults to 30 cm) - ``fitting_s (float * u.cm)``: Fitting spacing (optional, defaults to 15 cm) - ``inlet_depth_max (float * u.cm)``: Maximum inlet channel depth (optional, defaults to 50 cm) - ``drain_sdr (int)``: SDR of the drain pipe (optional, defaults to 26) - ``outlet_free_h (float * u.cm)``: Permissible increase of water level in the outlet channel (optional, defaults to 5 cm) ``outlet_weir_depth``:The depth of the outlet weir. (optional, defaults to 5 cm) - ``outlet_pipe_sdr (int)``: SDR of the outlet pipe (optional, defaults to 41) - ``outlet_pipe_hl_max (float * u.cm)``: Maximum head loss through the outlet pipe (optional, defaults to 1 cm) - ``outlet_pipe_nd_max (float * u.inch)``: Maximum nominal diameter of the outlet pipe (optional, defaults to 8 in) """ SED_TANK_Q_RATIO = 0.95 PLANT_FREEBOARD_H = 5.0 * u.cm WEIR_FREEBOARD_H = 2.0 * u.cm SED_DEPTH_EST = 2.0 * u.m def __init__(self, **kwargs): self.sed_tank_n=4 self.sed_tank_w_inner=42.0 * u.inch self.sed_tank_wall_thickness = 15.0 * u.cm self.sed_tank_inlet_man_nd = 60.0 * u.cm self.sed_tank_outlet_man_nd = 60.0 * u.cm self.sed_tank_outlet_man_hl = 4.0 * u.cm self.sed_tank_diffuser_hl=0.09 * u.mm self.sed_wall_thickness = 15.0 * u.cm self.weir_thickness = 15.0 * u.cm self.weir_hl = 5 * u.cm self.w_min = 30.0 * u.cm self.fitting_s = 15. * u.cm self.inlet_depth_max = 50 * u.cm self.drain_spec = 'sdr26' self.outlet_free_h = 5.0 * u.cm self.outlet_pipe_spec = 'sdr41' self.outlet_pipe_hl_max = 1.0 * u.cm self.outlet_pipe_nd_max = 8.0 * u.inch self.drain_pipe = Pipe() self.outlet_pipe = Pipe() self.subcomponents = [self.drain_pipe, self.outlet_pipe] super().__init__(**kwargs) self._set_drain_pipe() self._set_outlet_pipe() super().set_subcomponents() @property def l(self): """Length of the sedimentation channel.""" l = (self.sed_tank_n * self.sed_tank_w_inner) + \ ((self.sed_tank_n-1) * self.sed_tank_wall_thickness) + \ self.sed_wall_thickness return l.to(u.m) @property def outlet_weir_hl(self): """Head loss over the outlet channel weir.""" weir_exit_hl = pc.headloss_weir_rect(self.q, self.l) return weir_exit_hl @property def inlet_hl_max(self): """Maximum head loss in the inlet channel.""" inlet_hl_max = (self.sed_tank_outlet_man_hl + self.sed_tank_diffuser_hl) * \ (1 - self.SED_TANK_Q_RATIO ** 2) return inlet_hl_max @property def _inlet_w_pre_weir_plumbing_min(self): """Minimum width of the inlet channel (pre-weir) to fit pipes.""" inlet_w_pre_weir_plumbing_min = pipe.fitting_od(self.sed_tank_inlet_man_nd) + \ 2 * self.fitting_s return inlet_w_pre_weir_plumbing_min @property def _inlet_w_pre_weir_hl_min(self): """Minimum width of the inlet channel (pre-weir) that doesn't exceed the permissible head loss. """ inlet_w_pre_weir_hl_min = pc.horiz_chan_w( self.q, self.inlet_depth_max, self.inlet_hl_max, self.l, pc.viscosity_kinematic_water(self.temp), mat.CONCRETE_PIPE_ROUGH, False, 0 ) return inlet_w_pre_weir_hl_min @property def inlet_w_pre_weir(self): """Width of the inlet channel (pre-weir).""" inlet_w_pre_weir = max( self._inlet_w_pre_weir_plumbing_min, self._inlet_w_pre_weir_hl_min) return inlet_w_pre_weir @property def _inlet_depth_plumbing_min(self): """Minimum depth of the inlet channel to fit pipes.""" inlet_plumbing_depth_min = self.sed_tank_outlet_man_hl + self.sed_tank_diffuser_hl + \ pipe.fitting_od(self.sed_tank_outlet_man_nd) + \ self.fitting_s + self.outlet_weir_hl return inlet_plumbing_depth_min @property def _inlet_depth_hl_min(self): """Minimum depth of the inlet channel to stay within acceptable head loss. """ inlet_chan_hl_depth = pc.horiz_chan_h( self.q, self.inlet_w_pre_weir, self.inlet_hl_max, self.l, pc.viscosity_kinematic_water(self.temp), mat.CONCRETE_PIPE_ROUGH, False) return inlet_chan_hl_depth @property def inlet_depth(self): """Depth of the inlet channel.""" inlet_depth = max(self._inlet_depth_plumbing_min, self._inlet_depth_hl_min) return inlet_depth @property def inlet_weir_hl(self): """Head loss through the inlet channel weir.""" inlet_weir_hl = pc.headloss_weir_rect(self.q, self.l) return inlet_weir_hl @property def inlet_h(self): """Height of the inlet channel.""" inlet_h = self.inlet_depth + self.PLANT_FREEBOARD_H return inlet_h @property def inlet_weir_h(self): """Height of the inlet channel weir.""" inlet_chan_h_weir = self.inlet_depth + self.WEIR_FREEBOARD_H return inlet_chan_h_weir @property def inlet_w_post_weir(self): """Width of the inlet channel (post-weir)""" inlet_w_post_weir = max( self.w_min, pc.horiz_chan_w( self.q, self.inlet_h, self.inlet_h, self.l, pc.viscosity_kinematic_water(self.temp), mat.CONCRETE_PIPE_ROUGH, 1, 0 )) return inlet_w_post_weir @property def inlet_w(self): """Width of the inlet channel""" inlet_w = self.inlet_w_pre_weir + self.weir_thickness + self.inlet_w_post_weir return inlet_w def _set_drain_pipe(self): drain_k_minor = hl.PIPE_ENTRANCE_K_MINOR + hl.PIPE_EXIT_K_MINOR + hl.EL90_K_MINOR drain_nd = pc.pipe_flow_nd( self.q, ut.get_sdr(self.drain_spec), self.SED_DEPTH_EST, self.SED_DEPTH_EST + self.inlet_w, pc.viscosity_kinematic_water(self.temp), mat.PVC_PIPE_ROUGH, drain_k_minor ) self.drain_pipe = Pipe( size = drain_nd, spec = self.drain_spec, k_minor = drain_k_minor, ) @property def inlet_drain_box_w(self): """Width of the inlet channel drain box""" inlet_drain_box_w = max( 2 * self.fitting_s + pipe.fitting_od(self.drain_pipe.size), self.inlet_w_post_weir) return inlet_drain_box_w @property def outlet_depth(self): """Depth of the outlet channel.""" outlet_depth = self.inlet_depth - self.sed_tank_outlet_man_hl - \ self.sed_tank_diffuser_hl return outlet_depth @property def outlet_weir_depth(self): """Depth of the outlet channel weir.""" outlet_weir_depth = self.outlet_depth - self.weir_hl - self.WEIR_FREEBOARD_H return outlet_weir_depth @property def outlet_w_pre_weir(self): """Width of the outlet channel (pre-weir).""" return self.w_min @property def outlet_pipe_k_minor(self): outlet_pipe_k_minor = 2 * hl.EL90_K_MINOR + hl.PIPE_ENTRANCE_K_MINOR + \ hl.PIPE_EXIT_K_MINOR return outlet_pipe_k_minor @property def outlet_pipe_l(self): outlet_pipe_l = ha.DRAIN_CHAN_WALKWAY_W + self.inlet_w + 1.0 * u.m return outlet_pipe_l @property def outlet_pipe_q_max(self): """Maximum flow through the outlet pipe.""" outlet_pipe_q_max = pc.flow_pipe( pipe.ID_SDR(self.outlet_pipe_nd_max, ut.get_sdr(self.outlet_pipe_spec)), self.outlet_pipe_hl_max, self.outlet_pipe_l, pc.viscosity_kinematic_water(self.temp), mat.PVC_PIPE_ROUGH, self.outlet_pipe_k_minor ) return ut.round_step( outlet_pipe_q_max.to(u.L / u.s), step = 0.0001 * u.L / u.s ) def _set_outlet_pipe(self): outlet_pipe_q = self.q / self.outlet_pipe_n # outlet_pipe_nd = pc.pipe_flow_nd( # outlet_pipe_q, # ut.get_sdr(self.outlet_pipe_spec), # self.outlet_pipe_hl_max, # self.outlet_pipe_l, # pc.viscosity_kinematic_water(self.temp), # mat.PVC_PIPE_ROUGH, # self.outlet_pipe_k_minor # ) outlet_pipe_nd = pc.pipe_flow_nd( outlet_pipe_q, ut.get_sdr(self.outlet_pipe_spec), self.outlet_pipe_hl_max, self.outlet_pipe_l, pc.viscosity_kinematic_water(self.temp), mat.PVC_PIPE_ROUGH, 2 * hl.EL90_K_MINOR + hl.PIPE_ENTRANCE_K_MINOR + \ hl.PIPE_EXIT_K_MINOR ) self.outlet_pipe = Pipe( l = self.outlet_pipe_l, q = outlet_pipe_q, size = outlet_pipe_nd, spec = self.outlet_pipe_spec, k_minor = self.outlet_pipe_k_minor ) @property def outlet_pipe_n(self): """Number of outlet pipes.""" outlet_pipe_n = math.ceil(self.q / self.outlet_pipe_q_max) return outlet_pipe_n @property def outlet_post_weir_w(self): """Width of the outlet channel (post-weir).""" outlet_post_weir_w = max( #need self.outlet_to_filter_nd self.fitting_s + pipe.fitting_od(self.outlet_pipe.size), self.fitting_s + pipe.fitting_od(self.drain_pipe.size), self.w_min, pc.horiz_chan_w( self.q, self.outlet_weir_depth - self.outlet_free_h, #what is outlet_free_h self.outlet_weir_depth, self.l, pc.viscosity_kinematic_water(self.temp), mat.PVC_PIPE_ROUGH, 1, hl.PIPE_ENTRANCE_K_MINOR + hl.PIPE_EXIT_K_MINOR + hl.EL90_K_MINOR ) ) return outlet_post_weir_w @property def outlet_w(self): """Width of the outlet channel.""" outlet_w = self.outlet_w_pre_weir + self.weir_thickness + \ self.outlet_post_weir_w return outlet_w @property def outlet_drain_box_w(self): """Width of the outlet channel drain box.""" outlet_drain_box_w = max( self.fitting_s + pipe.fitting_od(self.drain_pipe.size), self.outlet_post_weir_w ) return outlet_drain_box_w @property def outlet_weir_h(self): """Height of the outlet channel weir.""" outlet_weir_h = self.outlet_weir_depth + self.WEIR_FREEBOARD_H return outlet_weir_h @property def w_outer(self): """Outer width of the sedimentation channel.""" w_outer = self.outlet_w + 2 * self.weir_thickness + self.inlet_w + self.sed_wall_thickness return w_outer @property def inlet_last_coupling_h(self): """Height of the last coupling in the inlet channel.""" last_coupling_h = self.outlet_weir_depth - 2 * u.cm return last_coupling_h @property def inlet_step_h(self): """Height of the steps between each pipe in the inlet channel.""" step_h = self.inlet_last_coupling_h / max(1, self.sed_tank_n - 1) return step_h @property def inlet_slope_l(self): """Length of the slopes between each pipe in the inlet channel.""" inlet_slope_l = self.l + self.sed_wall_thickness - \ pipe.fitting_od(self.sed_tank_inlet_man_nd) - self.fitting_s return inlet_slope_l