Source code for xopto.materials.density.water

# -*- coding: utf-8 -*-
################################ Begin license #################################
# Copyright (C) Laboratory of Imaging technologies,
#               Faculty of Electrical Engineering,
#               University of Ljubljana.
#
# This file is part of PyXOpto.
#
# PyXOpto is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyXOpto is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PyXOpto. If not, see <https://www.gnu.org/licenses/>.
################################# End license ##################################

import warnings

import numpy as np

from .base import Density


[docs]class McCutcheon(Density): material = 'water' def __init__(self, t: float = 293): ''' Density of water as given in: Water density as function of temperature and salt concentration McCutcheon, S.C., Martin, J.L, Barnwell, T.O. Jr. 1993. Water Quality in Maidment, D.R. (Editor). Handbook of Hydrology, McGraw-Hill, New York, NY (p. 11.3). The density of water :math:`\\rho` follows the folowing temperature T (C :sup:`o`) dependence. :math:`\\rho = 1000(1 - (T + 288.9414)/(508929.2*(T + 68.12963))*(T - 3.9863)^2)` Water density :math:`\\rho' as a function of temperature and salinity :math:`s` kg/m :sup:`3` as a function of temperature and salinity :math:`s` in g/kg. .. math:: \\rho &= \\rho + As + Bs^{3/2} + Cs^2 A &= 8.24493 10^{-1} - 4.0899 10^{-3}T + 7.6438 10^{-5}T^2 - 8.2467 10^{-7}T^3 + 5.3675 10^{-9}T^4 B &= -5.724 10^{-3} + 1.0227 10^{-4}T - 1.6546 10^{-6}T^2 C &= 4.8314 10^{-4} Parameters ---------- t: float Temperature of the medium (K). ''' self._salinity_range = None super().__init__(t=t, trange=None)
[docs] def is_valid_salinity(self, salinity: float or np.ndarray) -> bool: ''' Check if the salinity is within the valid range. Parameters ---------- salinity: float or np.ndarray Water salinity from 0.0 to 1.0. Returns ------- valid: bool True if the salinity is within the valid range. ''' if self._salinity_range is not None: salinity = np.asarray(salinity) res = np.logical_and(salinity >= self._salinity_range[0], salinity <= self._salinity_range[1]) return np.all(res) return True
[docs] def check_salinity(self, salinity: float or np.ndarray): ''' Check if the salinity is within valid range and display a warning if not. Parameters ---------- salinity: float Salinity from 0.0 to 0.035. ''' if not self.is_valid_salinity(salinity): warnings.warn( 'Salinity is out of valid range '\ '[{:.1f}, {:.1f}] %!'.format( 1e2*self._salinity_range[0], 1e2*self._salinity_range[1]) )
def __call__(self, temperature: float or None = None, salinity: float = 0.0) -> float or np.ndarray: ''' Calculate the density of the medium. Parameters ---------- wavelength: float or np.ndarray Wavelength of light (m) salinity: float Seawater salinity from in kg/kg. temperature: float or None Use this temperature instead of the default temperature. Returns ------- ri: float or np.ndarray Refractive index at the given wavelength(s). ''' if temperature is None: temperature = self.t t = float(temperature) self.check_temperature(t) salinity = float(salinity) self.check_salinity(salinity) T = temperature - 273.0 # temperature must be in C T2 = T*T T3 = T2*T T4 = T2*T2 rho = 1000*(1 - (T + 288.9414)/(508929.2*(T + 68.12963))*(T - 3.9863)**2) S = salinity*1e3 A = 8.24493e-1 - 4.0899e-3*T + 7.6438e-5*T2 -8.2467e-7*T3 + 5.3675e-9*T4 B = -5.724e-3 + 1.0227e-4*T - 1.6546e-6*T2 C = 4.8314e-4 rho = rho + A*S + B*S**(3/2) + C*S**2 if isinstance(temperature, float) and isinstance(salinity, float): rho = float(rho) return rho
mccutcheon = McCutcheon() default = mccutcheon