"""Acoustic relations calculator"""
import os
from typing import Union, Any
if os.environ.get('__USE_CUDA', '0') == '1':
import cupy as np
else:
import numpy as np
from g3d.defs import CFlowVariableType
from .calculator import G3DCalculator
[docs]
class G3DAcousticsCalculator(G3DCalculator):
"""Class collecting functions related to acoustic evaluations"""
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Initialize calculator parameters"""
super().__init__(*args, **kwargs)
self._pref = 2.e-5
def _set_default(self):
super()._set_default()
self.__dP = self._vars.add(name="dP", long_name="Pressure fluctuation", type=CFlowVariableType.PRESSURE)
self.__SPL = self._vars.add(name="SPL", long_name="Decibel", dim="dB")
self.__Cinf = self._vars.add(name="Cinf", long_name="Speed of sound (far field)",
type=CFlowVariableType.VELOCITY)
self.__ROinf = self._vars.add(name="ROinf", long_name="Density (far field)", type=CFlowVariableType.DENSITY)
@property
def pref(self) -> float:
"""Reference pressure [Pa] (default value: 2.e-5 Pa)"""
return self._pref
@pref.setter
def pref(self, p: float) -> None:
self._pref = p
[docs]
def get_dB_from_dp(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
.. deprecated:: 2.6
redirects to :func:`get_SPL_from_dp`
"""
return self.get_SPL_from_dp(*args, **kwargs)
[docs]
def get_SPL_from_dp(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""Calculates sound pressure level (SPL [dB]) from pressure fluctuation (dP [Pa], RMS)
input: pressure fluctuation (dP [Pa], RMS)
supported data types: float, list[float], ndarray
Parameters
----------
*args : Any
arguments (optional input):
pressure fluctuation RMS [Pa] value(s)
**kwargs : Any
keyword-value pairs (optional input):
valid keywords: 'dP'
Returns
-------
float, ndarray
sound pressure level [dB]
Examples
--------
Basic usage:
$_>>> from g3d import cflow
$_>>> SPL = cflow.acoustics.get_SPL_from_dp(dP=10.)
"""
return self._eval(["dP"], self.__get_SPL_from_dp, *args, **kwargs)
def __get_SPL_from_dp(self, dP: float = None) -> float:
if dP is None:
dP = self.__dP.value
return 20. * np.log10(dP / (self._pref * np.sqrt(2)))
[docs]
def get_dp_from_dB(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
.. deprecated:: 2.6
redirects to :func:`get_dp_from_SPL`
"""
return self.get_dp_from_SPL(*args, **kwargs)
[docs]
def get_dp_from_SPL(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""Calculates pressure fluctuation (dP [Pa], RMS) from sound pressure level (SPL [dB])
input: sound pressure level (SPL [dB])
supported data types: float, list[float], ndarray
Parameters
----------
*args : Any
arguments (optional input):
sound pressure level [dB] value(s)
**kwargs : Any
keyword-value pairs (optional input):
valid keywords: 'SPL'
Returns
-------
float, ndarray
pressure fluctuation (RMS dP) [Pa]
Examples
--------
Basic usage:
$_>>> from g3d import cflow
$_>>> dP = cflow.acoustics.get_dp_from_SPL(SPL=70.)
"""
return self._eval(["SPL"], self.__get_dp_from_SPL, *args, **kwargs)
def __get_dp_from_SPL(self, SPL: float = None) -> float:
if SPL is None:
SPL = self.__SPL.value
return 10. ** (SPL / 20.) * self._pref * np.sqrt(2)
[docs]
def get_du(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""Calculates sound wave induced flow velocity (dU [m/s])
input: far-field speed of sound (Cinf [m/s]), far-field density (ROinf [kg/m^3]),
and RMS pressure fluctuation (dP [Pa])
supported data types: float, list[float], ndarray
Parameters
----------
*args : Any
arguments (optional input):
1. far-field speed of sound [m/s]
2. far field density [kg/m^3]
3. pressure fluctuation [Pa]
variable value(s) in above-listed order
**kwargs : Any
keyword-value pairs (optional input):
valid keywords: 'Cinf', 'ROinf', 'dP'
Returns
-------
float, ndarray
induced velocity (u) [m/s]
Examples
--------
Basic usage:
$_>>> from g3d import cflow
$_>>> dU = cflow.acoustics.get_du(Cinf=340., ROinf=1.2, dP=10.)
"""
return self._eval(["Cinf", "ROinf", "dP"], self.__get_du, *args, **kwargs)
def __get_du(self, Cinf: float = None, ROinf: float = None, dP: float = None) -> float:
if Cinf is None:
Cinf = self.__Cinf.value
if ROinf is None:
ROinf = self.__ROinf.value
if dP is None:
dP = self.__dP.value
return (1. / (Cinf * ROinf)) * dP
[docs]
def get_dro(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""Calculates sound wave induced density fluctuation (dRO [kg/m^3])
input: far-field speed of sound (Cinf [m/s]) and RMS pressure fluctuation (dP [Pa])
example: dRO = get_dro(Cinf=Cinf, dP=dP)
supported data types: float, list[float], ndarray
Parameters
----------
*args : Any
arguments (optional input):
1. far-field speed of sound [m/s]
2. pressure fluctuation [Pa]
variable value(s) in above-listed order
**kwargs : Any
keyword-value pairs (optional input):
valid keywords: 'Cinf', 'dP'
Examples
--------
Basic usage:
$_>>> from g3d import cflow
$_>>> dRO = cflow.acoustics.get_dro(Cinf=340., dP=10.)
"""
return self._eval(["Cinf", "dP"], self.__get_dro, *args, **kwargs)
def __get_dro(self, Cinf: float = None, dP: float = None) -> float:
if Cinf is None:
Cinf = self.__Cinf.value
if dP is None:
dP = self.__dP.value
return (1. / Cinf ** 2) * dP