diff --git a/aguaclara/research/floc_model.py b/aguaclara/research/floc_model.py index 6f6d5f9e..6c2d06e6 100644 --- a/aguaclara/research/floc_model.py +++ b/aguaclara/research/floc_model.py @@ -29,7 +29,7 @@ def __init__(self, name, diameter, density, molecWeight): :param density: Density of the material (mass/volume) :type density: float :param molecWeight: Molecular weight of the material (mass/mole) - :type moleWeight: float + :type molecWeight: float """ self.name = name self.Diameter = diameter @@ -57,6 +57,16 @@ def __init__(self, name, diameter, density, molecWeight, Precipitate, self.PrecipName = Precipitate def define_Precip(self, diameter, density, molecweight, alumMPM): + """Define a precipitate for the chemical. + + :param diameter: Diameter of the precipitate in particulate form + :type diameter: float + :param density: Density of the material (mass/volume) + :type density: float + :param molecWeight: Molecular weight of the material (mass/mole) + :type molecWeight: float + :param alumMPM: + """ self.PrecipDiameter = diameter self.PrecipDensity = density self.PrecipMolecWeight = molecweight @@ -64,38 +74,57 @@ def define_Precip(self, diameter, density, molecweight, alumMPM): ################## Material Definitions ################## -# name, diameter in m, density in kg/m³, molecular weight in kg/mole + +#: A Material representing clay with a diameter of 7e-6 m and density of 2650 +#: kg/m^3. Clay = Material('Clay', 7 * 10**-6 * u.m, 2650 * u.kg/u.m**3, None) + +#: A Material representing polyaluminum chloride (PACl) with a diameter of +#: 9e-8m, density of 1138 kg/m^2, and molecular weight of 1.039 kg/mol. It is +#: its own precipitate. PACl = Chemical('PACl', 9 * 10 **-8 * u.m, 1138 * u.kg/u.m**3, 1.039 * u.kg/u.mol, 'PACl', AluminumMPM=13) + +#: A Material representing alum with a diameter of 7e-8 m, density of +#: 2420 kg/m^3, and molecular weight of 0.59921 kg/mol. It's precipitate is +#: AlOH3, with the same diameter and density, and a molecular weight of 0.078 +#: kg/mol. Alum = Chemical('Alum', 7 * 10 **-8 * u.m, 2420 * u.kg/u.m**3, 0.59921 * u.kg/u.mol, 'AlOH3', AluminumMPM=2) Alum.define_Precip(7 * 10 **-8 * u.m, 2420 * u.kg/u.m**3, 0.078 * u.kg/u.mol, 1) + +#: A Material representing humic acid with a diameter of 7.2e-8 m and density +#: of 1780 kg/m^3. It is its own precipitate. HumicAcid = Chemical('Humic Acid', 72 * 10**-9 * u.m, 1780 * u.kg/u.m**3, None, 'Humic Acid') ################### Necessary Constants ################### -# Fractal dimension, based on data from published in Environmental Engineering -# Science, "Fractal Models for Floc Density, Sedimentation Velocity, and Floc -# Volume Fraction for High Peclet Number Reactors" by Monroe Weber-Shirk and -# Leonard Lion (2015). +#: Fractal dimension, based on data from published in Environmental Engineering +#: Science, "Fractal Models for Floc Density, Sedimentation Velocity, and Floc +#: Volume Fraction for High Peclet Number Reactors" by Monroe Weber-Shirk and +#: Leonard Lion (2015). DIM_FRACTAL = 2.3 -# Ratio of clay platelet height to diameter. + +#: Ratio of clay platelet height to diameter. RATIO_HEIGHT_DIAM = 0.1 -# Ratio between inner viscous length scale and Kolmogorov length scale. + +#: Ratio between inner viscous length scale and Kolmogorov length scale. RATIO_KOLMOGOROV = 50 -# Shape factor for drag on flocs used in terminal velocity equation. + +#: Shape factor for drag on flocs used in terminal velocity equation. PHI_FLOC = 45/24 -# The Avogadro constant. + +#: The Avogadro constant. NUM_AVOGADRO = 6.0221415 * 10**23 -# Molecular weight of aluminum in kg/mole. -MOLEC_WEIGHT_ALUMINUM = 0.027 + +#: Molecular weight of aluminum in kg/mole. +MOLEC_WEIGHT_ALUMINUM = 0.027 * u.kg / u.mol ######################## Functions ######################## -@u.wraps(u.kg/u.m**3, None, False) +# @u.wraps(u.kg/u.m**3, None, False) def dens_alum_nanocluster(coag): """Return the density of the aluminum in the nanocluster. @@ -107,7 +136,7 @@ def dens_alum_nanocluster(coag): return density -@u.wraps(u.kg/u.m**3, [u.kg/u.m**3, u.degK], False) +# @u.wraps(u.kg/u.m**3, [u.kg/u.m**3, u.degK], False) def dens_pacl_solution(ConcAluminum, temp): """Return the density of the PACl solution. @@ -120,62 +149,88 @@ def dens_pacl_solution(ConcAluminum, temp): ) -@u.wraps(u.kg/u.m**3, [u.kg/u.m**3, None], False) def conc_precipitate(ConcAluminum, coag): """Return coagulant precipitate concentration given aluminum dose. + This function assumes complete precipitation of coagulant into Al13. + Note that conc_precipitate returns a value that varies from the equivalent MathCAD function beginning at the third decimal place. The majority of functions below this point in the file ultimately call on conc_precipitate at some point, and will not return the same value as their equivalent function in MathCAD. This is known. + + :param ConcAluminum: Concentration of aluminum in solution + :type ConcAluminum: float + :param coag: Type of coagulant in solution, e.g. floc_model.PACl + :type coag: floc_model.Material + + :return: Concentration of coagulant precipitates + :rtype: float """ return ((ConcAluminum / MOLEC_WEIGHT_ALUMINUM) * (coag.PrecipMolecWeight / coag.PrecipAluminumMPM) ) -@u.wraps(u.kg/u.m**3, [u.kg/u.m**3, u.kg/u.m**3, None], False) +# @u.wraps(u.kg/u.m**3, [u.kg/u.m**3, u.kg/u.m**3, None], False) def conc_floc(ConcAluminum, concClay, coag): """Return floc density given aluminum dose, turbidity, and coagulant""" return conc_precipitate(ConcAluminum, coag).magnitude + concClay -@u.wraps(u.mol/u.m**3, u.kg/u.m**3, False) +# @u.wraps(u.mol/u.m**3, u.kg/u.m**3, False) def moles_aluminum(ConcAluminum): """Return the # of moles aluminum given aluminum concentration.""" return (ConcAluminum / MOLEC_WEIGHT_ALUMINUM) -@u.wraps(u.m, u.kg/u.m**3, False) +# @u.wraps(u.m, u.kg/u.m**3, False) def sep_dist_aluminum(ConcAluminum): """Return the separation distance between aluminum molecules.""" return (1 / (NUM_AVOGADRO * moles_aluminum(ConcAluminum).magnitude))**(1/3) -@u.wraps(1/u.m**3, [u.kg/u.m**3, u.m], False) -def num_clay(ConcClay, material): - """Return the number of clay particles in suspension.""" - return ConcClay / ((material.Density * np.pi * material.Diameter**3) / 6) +def particle_number_concentration(ConcMat, material): + """Return the number of particles in suspension. + + :param ConcMat: Concentration of the material + :type ConcMat: float + :param material: The material in solution + :type material: floc_model.Material + """ + return ConcMat.to(material.Density.units) / ((material.Density * np.pi * material.Diameter**3) / 6) -@u.wraps(u.m, [u.kg/u.m**3, u.m], False) +# @u.wraps(u.m, [u.kg/u.m**3, u.m], False) def sep_dist_clay(ConcClay, material): """Return the separation distance between clay particles.""" return ((material.Density/ConcClay)*((np.pi * material.Diameter ** 3)/6))**(1/3) -@u.wraps(1/u.m**3, [u.kg/u.m**3, None], False) +# @u.wraps(1/u.m**3, [u.kg/u.m**3, None], False) def num_nanoclusters(ConcAluminum, coag): """Return the number of Aluminum nanoclusters.""" return (ConcAluminum / (dens_alum_nanocluster(coag).magnitude * np.pi * coag.Diameter**3)) -@u.wraps(None, [u.kg/u.m**3, u.kg/u.m**3, None, None], False) def frac_vol_floc_initial(ConcAluminum, ConcClay, coag, material): - """Return the fraction of flocs initially present.""" + """Return the volume fraction of flocs initially present, accounting for both suspended particles and coagulant precipitates. + + :param ConcAluminum: Concentration of aluminum in solution + :type ConcAluminum: float + :param ConcClay: Concentration of particle in suspension + :type ConcClay: float + :param coag: Type of coagulant in solution + :type coag: float + :param material: Type of particles in suspension, e.g. floc_model.Clay + :type material: floc_model.Material + + :return: Volume fraction of particles initially present + :rtype: float + """ return ((conc_precipitate(ConcAluminum, coag).magnitude/coag.PrecipDensity) + (ConcClay / material.Density)) @@ -190,13 +245,13 @@ def invp(pC, Cprime): #################### Fractal functions #################### -@u.wraps(u.m, [u.dimensionless, u.m, u.dimensionless], False) +# @u.wraps(u.m, [u.dimensionless, u.m, u.dimensionless], False) def diam_fractal(DIM_FRACTAL, DiamInitial, NumCol): """Return the diameter of a floc given NumCol doubling collisions.""" return DiamInitial * 2**(NumCol / DIM_FRACTAL) -@u.wraps(None, [u.dimensionless, None, u.m], False) +# @u.wraps(None, [u.dimensionless, None, u.m], False) def num_coll_reqd(DIM_FRACTAL, material, DiamTarget): """Return the number of doubling collisions required. @@ -206,8 +261,8 @@ def num_coll_reqd(DIM_FRACTAL, material, DiamTarget): return DIM_FRACTAL * np.log2(DiamTarget/material.Diameter) -@u.wraps(u.m, [u.kg/u.m**3, u.kg/u.m**3, None, None, - u.dimensionless, u.m], False) +# @u.wraps(u.m, [u.kg/u.m**3, u.kg/u.m**3, None, None, + # u.dimensionless, u.m], False) def sep_dist_floc(ConcAluminum, ConcClay, coag, material, DIM_FRACTAL, DiamTarget): """Return separation distance as a function of floc size.""" @@ -220,8 +275,8 @@ def sep_dist_floc(ConcAluminum, ConcClay, coag, material, ) -@u.wraps(u.m, [u.kg/u.m**3, u.kg/u.m**3, None, u.dimensionless, - None, u.m], False) +# @u.wraps(u.m, [u.kg/u.m**3, u.kg/u.m**3, None, u.dimensionless, +# None, u.m], False) def frac_vol_floc(ConcAluminum, ConcClay, coag, DIM_FRACTAL, material, DiamTarget): """Return the floc volume fraction.""" @@ -230,7 +285,7 @@ def frac_vol_floc(ConcAluminum, ConcClay, coag, DIM_FRACTAL, ) -@u.wraps(u.kg/u.m**3, [u.kg/u.m**3, u.kg/u.m**3, None, None], False) +# @u.wraps(u.kg/u.m**3, [u.kg/u.m**3, u.kg/u.m**3, None, None], False) def dens_floc_init(ConcAluminum, ConcClay, coag, material): """Return the density of the initial floc. @@ -242,7 +297,7 @@ def dens_floc_init(ConcAluminum, ConcClay, coag, material): #################### Flocculation Model #################### -@u.wraps(None, u.m, False) +# @u.wraps(None, u.m, False) def ratio_clay_sphere(RatioHeightDiameter): """Return the surface area to volume ratio for clay. @@ -251,13 +306,24 @@ def ratio_clay_sphere(RatioHeightDiameter): return (1/2 + RatioHeightDiameter) * (2 / (3*RatioHeightDiameter))**(2/3) -@u.wraps(None, [u.kg/u.m**3, None, u.m, u.dimensionless], False) def ratio_area_clay_total(ConcClay, material, DiamTube, RatioHeightDiameter): """Return the surface area of clay normalized by total surface area. Total surface area is a combination of clay and reactor wall surface areas. This function is used to estimate how much coagulant actually goes to the clay. + + :param ConcClay: Concentration of clay in suspension + :type ConcClay: float + :param material: Type of clay in suspension, e.g. floc_model.Clay + :type material: floc_model.Material + :param DiamTube: Diameter of flocculator tube (assumes tube flocculator for calculation of reactor surface area) + :type DiamTube: float + :param RatioHeightDiameter: Dimensionless ratio describing ratio of clay height to clay diameter + :type RatioHeightDiameter: float + + :return: The ratio of clay surface area to total available surface area (accounting for reactor walls) + :rtype: float """ return (1 / (1 @@ -270,8 +336,6 @@ def ratio_area_clay_total(ConcClay, material, DiamTube, RatioHeightDiameter): ) -@u.wraps(None, [u.kg/u.m**3, u.kg/u.m**3, None, None, - u.m, u.dimensionless], False) def gamma_coag(ConcClay, ConcAluminum, coag, material, DiamTube, RatioHeightDiameter): """Return the coverage of clay with nanoglobs. @@ -280,11 +344,27 @@ def gamma_coag(ConcClay, ConcAluminum, coag, material, and a poisson distribution on the clay given random hits by the nanoglobs. The poisson distribution results in the coverage only gradually approaching full coverage as coagulant dose increases. + + :param ConcClay: Concentration of clay in suspension + :type ConcClay: float + :param ConcAluminum: Concentration of aluminum in solution + :type ConcAluminum: float + :param coag: Type of coagulant in solution, e.g. floc_model.PACl + :type coag: floc_model.Material + :param material: Type of clay in suspension, e.g. floc_model.Clay + :type material: floc_model.Material + :param DiamTube: Diameter of flocculator tube (assumes tube flocculator for calculation of reactor surface area) + :type DiamTube: float + :param RatioHeightDiameter: Dimensionless ratio of clay height to clay diameter + :type RatioHeightDiameter: float + + :return: Fraction of the clay surface area that is coated with coagulant precipitates + :rtype: float """ return (1 - np.exp(( - (-frac_vol_floc_initial(ConcAluminum, 0, coag, material) + (-frac_vol_floc_initial(ConcAluminum, 0*u.kg/u.m**3, coag, material) * material.Diameter) - / (frac_vol_floc_initial(0, ConcClay, coag, material) + / (frac_vol_floc_initial(0*u.kg/u.m**3, ConcClay, coag, material) * coag.Diameter)) * (1 / np.pi) * (ratio_area_clay_total(ConcClay, material, @@ -292,26 +372,22 @@ def gamma_coag(ConcClay, ConcAluminum, coag, material, / ratio_clay_sphere(RatioHeightDiameter)) )) - -@u.wraps(None, [u.kg/u.m**3, u.kg/u.m**3, None, None], False) -@ut.list_handler() +# @u.wraps(None, [u.kg/u.m**3, u.kg/u.m**3, None, None], False) +# @ut.list_handler() def gamma_humic_acid_to_coag(ConcAl, ConcNatOrgMat, NatOrgMat, coag): """Return the fraction of the coagulant that is coated with humic acid. - Parameters - ---------- - var1 : float - Concentration of alumninum in solution - var2 : float - Concentration of natural organic matter in solution - var3 : ? - var4 : ? - - Returns - ------- - float - fraction of the coagulant that is coated with humic acid - + :param ConcAl: Concentration of alumninum in solution + :type ConcAl: float + :param ConcNatOrgMat: Concentration of natural organic matter in solution + :type ConcNatOrgMat: float + :param NatOrgMat: type of natural organic matter, e.g. floc_model.HumicAcid + :type NatOrgMat: floc_model.Material + :param coag: Type of coagulant in solution, e.g. floc_model.PACl + :type coag: floc_model.Material + + :return: fraction of the coagulant that is coated with humic acid + :rtype: float """ return min(((ConcNatOrgMat / conc_precipitate(ConcAl, coag).magnitude) * (coag.Density / NatOrgMat.Density) @@ -320,34 +396,32 @@ def gamma_humic_acid_to_coag(ConcAl, ConcNatOrgMat, NatOrgMat, coag): 1) -@u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, None, - None, None, u.dimensionless], False) +# @u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, None, +# None, None, u.dimensionless], False) def pacl_term(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, NatOrgMat, coag, material, RatioHeightDiameter): """Return the fraction of the surface area that is covered with coagulant that is not covered with humic acid. - Parameters - ---------- - var1 : float - Diameter of the dosing tube - var2 : float - Concentration of clay in solution - var3 : float - Concentration of alumninum in solution - var4 : float - Concentration of natural organic matter in solution - var5 : ? - var6 : ? - var7 : float - Ratio between inner viscous length scale and Kolmogorov length scale - - Returns - ------- - float - fraction of the surface area that is covered with coagulant that is not - covered with humic acid - + :param DiamTube: Diameter of the dosing tube + :type Diamtube: float + :param ConcClay: Concentration of clay in solution + :type ConcClay: float + :param ConcAl: Concentration of alumninum in solution + :type ConcAl: float + :param ConcNatOrgMat: Concentration of natural organic matter in solution + :type ConcNatOrgMat: float + :param NatOrgMat: type of natural organic matter, e.g. floc_model.HumicAcid + :type NatOrgMat: floc_model.Material + :param coag: Type of coagulant in solution, e.g. floc_model.PACl + :type coag: floc_model.Material + :param material: Type of clay in suspension, e.g. floc_model.Clay + :type material: floc_model.Material + :param RatioHeightDiameter: Dimensionless ratio of clay height to clay diameter + :type RatioHeightDiameter: float + + :return: fraction of the surface area that is covered with coagulant that is not covered with humic acid + :rtype: float """ return (gamma_coag(ConcClay, ConcAl, coag, material, DiamTube, RatioHeightDiameter) @@ -356,8 +430,8 @@ def pacl_term(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, NatOrgMat, ) -@u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, - None, None, None, u.dimensionless], False) +# @u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, +# None, None, None, u.dimensionless], False) def alpha_pacl_clay(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, NatOrgMat, coag, material, RatioHeightDiameter): """""" @@ -367,8 +441,8 @@ def alpha_pacl_clay(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, DiamTube, RatioHeightDiameter))) -@u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, - None, None, None, u.dimensionless], False) +# @u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, +# None, None, None, u.dimensionless], False) def alpha_pacl_pacl(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, NatOrgMat, coag, material, RatioHeightDiameter): """""" @@ -377,8 +451,8 @@ def alpha_pacl_pacl(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, return PAClTerm ** 2 -@u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, - None, None, None, u.dimensionless], False) +# @u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, +# None, None, None, u.dimensionless], False) def alpha_pacl_nat_org_mat(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, NatOrgMat, coag, material, RatioHeightDiameter): """""" @@ -390,8 +464,8 @@ def alpha_pacl_nat_org_mat(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, * gamma_humic_acid_to_coag(ConcAl, ConcNatOrgMat, NatOrgMat, coag)) -@u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, - None, None, None, u.dimensionless], False) +# @u.wraps(None, [u.m, u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, +# None, None, None, u.dimensionless], False) def alpha(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, NatOrgMat, coag, material, RatioHeightDiameter): """""" @@ -405,9 +479,9 @@ def alpha(DiamTube, ConcClay, ConcAl, ConcNatOrgMat, ) -@u.wraps(None, [u.W/u.kg, u.degK, u.s, u.m, - u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, None, - None, None, u.dimensionless, u.dimensionless], False) +# @u.wraps(None, [u.W/u.kg, u.degK, u.s, u.m, +# u.kg/u.m**3, u.kg/u.m**3, u.kg/u.m**3, None, +# None, None, u.dimensionless, u.dimensionless], False) def pc_viscous(EnergyDis, Temp, Time, DiamTube, ConcClay, ConcAl, ConcNatOrgMat, NatOrgMat, coag, material, FittingParam, RatioHeightDiameter): @@ -426,8 +500,8 @@ def pc_viscous(EnergyDis, Temp, Time, DiamTube, ) -@u.wraps(u.kg/u.m**3, [u.kg/u.m**3, u.kg/u.m**3, u.dimensionless, u.m, - None, None, u.degK], False) +# @u.wraps(u.kg/u.m**3, [u.kg/u.m**3, u.kg/u.m**3, u.dimensionless, u.m, +# None, None, u.degK], False) def dens_floc(ConcAl, ConcClay, DIM_FRACTAL, DiamTarget, coag, material, Temp): """Calculate floc density as a function of size.""" WaterDensity = pc.density_water(Temp).magnitude @@ -439,8 +513,8 @@ def dens_floc(ConcAl, ConcClay, DIM_FRACTAL, DiamTarget, coag, material, Temp): ) -@u.wraps(u.m/u.s, [u.kg/u.m**3, u.kg/u.m**3, None, None, u.dimensionless, - u.m, u.degK], False) +# @u.wraps(u.m/u.s, [u.kg/u.m**3, u.kg/u.m**3, None, None, u.dimensionless, +# u.m, u.degK], False) def vel_term_floc(ConcAl, ConcClay, coag, material, DIM_FRACTAL, DiamTarget, Temp): """Calculate floc terminal velocity.""" @@ -457,8 +531,8 @@ def vel_term_floc(ConcAl, ConcClay, coag, material, DIM_FRACTAL, ) -@u.wraps(u.m, [u.kg/u.m**3, u.kg/u.m**3, None, None, - u.dimensionless, u.m/u.s, u.degK], False) +# @u.wraps(u.m, [u.kg/u.m**3, u.kg/u.m**3, None, None, +# u.dimensionless, u.m/u.s, u.degK], False) def diam_floc_vel_term(ConcAl, ConcClay, coag, material, DIM_FRACTAL, VelTerm, Temp): """Calculate floc diamter as a function of terminal velocity.""" @@ -478,9 +552,9 @@ def diam_floc_vel_term(ConcAl, ConcClay, coag, material, ) -@u.wraps(u.s, [u.W/u.kg, u.degK, u.kg/u.m**3, u.kg/u.m**3, None, None, - u.m, u.m, u.dimensionless, u.dimensionless], - False) +# @u.wraps(u.s, [u.W/u.kg, u.degK, u.kg/u.m**3, u.kg/u.m**3, None, None, +# u.m, u.m, u.dimensionless, u.dimensionless], +# False) def time_col_laminar(EnergyDis, Temp, ConcAl, ConcClay, coag, material, DiamTarget, DiamTube, DIM_FRACTAL, RatioHeightDiameter): """Calculate single collision time for laminar flow mediated collisions. @@ -498,8 +572,8 @@ def time_col_laminar(EnergyDis, Temp, ConcAl, ConcClay, coag, material, ) -@u.wraps(u.s, [u.W/u.kg, u.kg/u.m**3, u.kg/u.m**3, None, None, - u.m, u.dimensionless], False) +# @u.wraps(u.s, [u.W/u.kg, u.kg/u.m**3, u.kg/u.m**3, None, None, +# u.m, u.dimensionless], False) def time_col_turbulent(EnergyDis, ConcAl, ConcClay, coag, material, DiamTarget, DIM_FRACTAL): """Calculate single collision time for turbulent flow mediated collisions. @@ -513,18 +587,18 @@ def time_col_turbulent(EnergyDis, ConcAl, ConcClay, coag, material, ########### Kolmogorov and viscous length scales ########### -@u.wraps(u.m, [u.W/u.kg, u.degK], False) +# @u.wraps(u.m, [u.W/u.kg, u.degK], False) def eta_kolmogorov(EnergyDis, Temp): return ((pc.viscosity_kinematic(Temp).magnitude ** 3) / EnergyDis) ** (1 / 4) -@u.wraps(u.m, [u.W/u.kg, u.degK], False) +# @u.wraps(u.m, [u.W/u.kg, u.degK], False) def lambda_vel(EnergyDis, Temp): return RATIO_KOLMOGOROV * eta_kolmogorov(EnergyDis, Temp).magnitude -@u.wraps(u.m, [u.W/u.kg, u.degK, u.kg/u.m**3, u.kg/u.m**3, None, None, - u.dimensionless], False) +# @u.wraps(u.m, [u.W/u.kg, u.degK, u.kg/u.m**3, u.kg/u.m**3, None, None, +# u.dimensionless], False) def diam_kolmogorov(EnergyDis, Temp, ConcAl, ConcClay, coag, material, DIM_FRACTAL): """Return the size of the floc with separation distances equal to @@ -539,8 +613,8 @@ def diam_kolmogorov(EnergyDis, Temp, ConcAl, ConcClay, coag, material, ) -@u.wraps(u.m, [u.W/u.kg, u.degK, u.kg/u.m**3, u.kg/u.m**3, None, None, - u.dimensionless], False) +# @u.wraps(u.m, [u.W/u.kg, u.degK, u.kg/u.m**3, u.kg/u.m**3, None, None, +# u.dimensionless], False) def diam_vel(EnergyDis, Temp, ConcAl, ConcClay, coag, material, DIM_FRACTAL): return (material.Diameter * ((lambda_vel(EnergyDis, Temp).magnitude / material.Diameter) @@ -551,7 +625,7 @@ def diam_vel(EnergyDis, Temp, ConcAl, ConcClay, coag, material, DIM_FRACTAL): ) -@u.wraps(u.m, u.W/u.kg, False) +# @u.wraps(u.m, u.W/u.kg, False) def diam_floc_max(epsMax): """Return floc size as a function of energy dissipation rate. @@ -570,7 +644,7 @@ def diam_floc_max(epsMax): return 9.5 * 10**-5 * (1 / (epsMax)**(1/3)) -@u.wraps(u.W/u.kg, u.m, False) +# @u.wraps(u.W/u.kg, u.m, False) def ener_dis_diam_floc(Diam): """Return max energy dissipation rate as a function of max floc diameter. @@ -580,18 +654,18 @@ def ener_dis_diam_floc(Diam): ##### Velocity gradient in tubing for lab scale laminar flow flocculators ##### -@u.wraps(1/u.s, [u.m**3/u.s, u.m], False) +# @u.wraps(1/u.s, [u.m**3/u.s, u.m], False) def g_straight(PlantFlow, IDTube): return 64 * PlantFlow / (3 * np.pi * IDTube**3) -@u.wraps(None, [u.m**3/u.s, u.m, u.degK], False) +# @u.wraps(None, [u.m**3/u.s, u.m, u.degK], False) def reynolds_rapid_mix(PlantFlow, IDTube, Temp): return (4 * PlantFlow / (np.pi * IDTube * pc.viscosity_kinematic(Temp).magnitude)) -@u.wraps(None, [u.m**3/u.s, u.m, u.m, u.degK], False) +# @u.wraps(None, [u.m**3/u.s, u.m, u.m, u.degK], False) def dean_number(PlantFlow, IDTube, RadiusCoil, Temp): """Return the Dean Number. @@ -605,7 +679,7 @@ def dean_number(PlantFlow, IDTube, RadiusCoil, Temp): ) -@u.wraps(1/u.s, [u.m**3/u.s, u.m, u.m, u.degK], False) +# @u.wraps(1/u.s, [u.m**3/u.s, u.m, u.m, u.degK], False) def g_coil(FlowPlant, IDTube, RadiusCoil, Temp): """We need a reference for this. @@ -619,13 +693,13 @@ def g_coil(FlowPlant, IDTube, RadiusCoil, Temp): ) -@u.wraps(u.s, [u.m, u.m, u.m**3/u.s], False) +# @u.wraps(u.s, [u.m, u.m, u.m**3/u.s], False) def time_res_tube(IDTube, LengthTube, FlowPlant): """Calculate residence time in the flocculator.""" return LengthTube * np.pi * (IDTube**2 / 4) / FlowPlant -@u.wraps(None, [u.m**3/u.s, u.m, u.m, u.m, u.degK], False) +# @u.wraps(None, [u.m**3/u.s, u.m, u.m, u.m, u.degK], False) def g_time_res(FlowPlant, IDTube, RadiusCoil, LengthTube, Temp): """G Residence Time calculated for a coiled tube flocculator.""" return (g_coil(FlowPlant, IDTube, RadiusCoil, Temp).magnitude diff --git a/docs/source/research/floc_model.rst b/docs/source/research/floc_model.rst new file mode 100644 index 00000000..954381d3 --- /dev/null +++ b/docs/source/research/floc_model.rst @@ -0,0 +1,16 @@ +Floc Model +========== + +.. autoclass:: aguaclara.research.floc_model.Material + :members: + + .. automethod:: __init__ + +.. autoclass:: aguaclara.research.floc_model.Chemical + :members: + + .. automethod:: __init__ + +.. automodule:: aguaclara.research.floc_model + :members: + :exclude-members: Material, Chemical diff --git a/docs/source/research/research.rst b/docs/source/research/research.rst index 7d3ab553..184c0f43 100644 --- a/docs/source/research/research.rst +++ b/docs/source/research/research.rst @@ -5,6 +5,7 @@ Research :maxdepth: 2 environmental_processes_analysis + floc_model peristaltic_pump procoda_parser stock_qc diff --git a/setup.py b/setup.py index 31b52659..c8f74e2a 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages setup(name='aguaclara', - version='0.0.24.1', + version='0.0.25', description='Open source functions for AguaClara water treatment research and plant design.', url='https://github.com/AguaClara/aguaclara', author='AguaClara at Cornell',