from __future__ import annotations
from osaft import BackgroundField, ViscousFluid, WaveType
from osaft.core.basecomposite import BaseSphereFrequencyComposite
from osaft.core.frequency import Frequency
from osaft.core.geometries import Sphere
from osaft.core.variable import ActiveVariable
[docs]class BaseDoinikov1994(BaseSphereFrequencyComposite):
"""Base class for Doinikov solutions from 1994
:param f: Frequency [Hz]
:param R_0: Radius of the sphere [m]
:param rho_f: Density of the fluid [kg/m^3]
:param c_f: Speed of sound of the fluid [m/s]
:param eta_f: shear viscosity [Pa s]
:param zeta_f: bulk viscosity [Pa s]
:param p_0: Pressure amplitude of the field [Pa]
:param wave_type: Type of wave, traveling or standing
:param position: Position in the standing wave field [rad]
"""
def __init__(
self,
f: Frequency | float | int,
R_0: Sphere | float | int,
rho_f: float,
c_f: float,
eta_f: float,
zeta_f: float,
p_0: float,
wave_type: None | WaveType = WaveType.STANDING,
position: None | float = None,
) -> None:
super().__init__(f, R_0)
self.fluid = ViscousFluid(self.frequency, rho_f, c_f, eta_f, zeta_f)
self.field = BackgroundField(self.fluid, p_0, wave_type, position)
# Dependent Variables
self._x = ActiveVariable(
self._compute_x,
"Dimensionless wavenumber",
)
self._x_0 = ActiveVariable(
self._compute_x_0,
"Real part of the dimensionless wavenumber ",
)
self._x_v = ActiveVariable(
self._compute_x_v,
"Dimensionless viscous wavenumber",
)
self._norm_delta = ActiveVariable(
self._compute_norm_delta,
"normalized boundary layer thickness",
)
self._x.is_computed_by(
self.fluid._k_f,
self.sphere._R_0,
)
self._x_0.is_computed_by(
self._x,
)
self._x_v.is_computed_by(
self.fluid._k_v,
self.sphere._R_0,
)
self._norm_delta.is_computed_by(
self.fluid._delta,
self.sphere._R_0,
)
# -------------------------------------------------------------------------
# Dependent Variables
# -------------------------------------------------------------------------
@property
def x(self) -> complex:
"""Product of :attr:`~.k_f` and :attr:`~.R_0`
:math:`\\hat{x}=k_f R_0`
"""
return self._x.value
def _compute_x(self) -> complex:
return self.k_f * self.R_0
@property
def x_v(self) -> complex:
"""Product of :attr:`~.k_v` and :attr:`~.R_0`
:math:`x_v=k_v R_0`
"""
return self._x_v.value
def _compute_x_v(self) -> complex:
return self.k_v * self.R_0
@property
def x_0(self) -> complex:
"""Real part of :math:`x`"""
return self._x_0.value
def _compute_x_0(self) -> complex:
return self.x.real
@property
def norm_delta(self) -> float:
"""normalized viscous boundary thickness
:math:`\\tilde{\\delta}=\\frac{\\delta}{R_0}`
"""
return self._norm_delta.value
def _compute_norm_delta(self):
return self.delta / self.R_0
# -------------------------------------------------------------------------
# Wrappers for Independent Field Attributes
# -------------------------------------------------------------------------
@property
def position(self) -> float:
"""Wraps to
:attr:`osaft.core.backgroundfields.BackgroundField.position`
"""
return self.field.position
@position.setter
def position(self, value: float) -> None:
self.field.position = value
@property
def p_0(self) -> float:
"""Wraps to
:attr:`osaft.core.backgroundfields.BackgroundField.p_0`
"""
return self.field.p_0
@p_0.setter
def p_0(self, value: float) -> None:
self.field.p_0 = value
@property
def wave_type(self) -> WaveType:
"""Wraps to
:attr:`osaft.core.backgroundfields.BackgroundField.wave_type`
"""
return self.field.wave_type
@wave_type.setter
def wave_type(self, value: WaveType) -> None:
self.field.wave_type = value
# -------------------------------------------------------------------------
# Wrappers for Independent Fluid Attributes
# -------------------------------------------------------------------------
@property
def rho_f(self) -> float:
"""Wraps to :attr:`osaft.core.fluids.ViscousFluid.rho_f`"""
return self.fluid.rho_f
@rho_f.setter
def rho_f(self, value: float) -> None:
self.fluid.rho_f = value
@property
def c_f(self) -> float:
"""Wraps to :attr:`osaft.core.fluids.ViscousFluid.c_f`"""
return self.fluid.c_f
@c_f.setter
def c_f(self, value: float) -> None:
self.fluid.c_f = value
@property
def eta_f(self) -> float:
"""Wraps to :attr:`osaft.core.fluids.ViscousFluid.eta_f`"""
return self.fluid.eta_f
@eta_f.setter
def eta_f(self, value: float) -> None:
self.fluid.eta_f = value
@property
def zeta_f(self) -> float:
"""Wraps to :attr:`osaft.core.fluids.ViscousFluid.zeta_f`"""
return self.fluid.zeta_f
@zeta_f.setter
def zeta_f(self, value: float) -> None:
self.fluid.zeta_f = value
# -------------------------------------------------------------------------
# Wrappers for Dependent Attributes
# -------------------------------------------------------------------------
@property
def rho_t(self) -> float:
"""Returns the ratio of the densities
:math:`\\tilde{\\rho}=\\frac{\\rho_f}{\\rho_s}`
"""
return self._rho_t.value
def _compute_rho_t(self) -> float:
return self.rho_f / self.rho_s
# -------------------------------------------------------------------------
# Wrappers for Dependent Fluid Attributes
# -------------------------------------------------------------------------
@property
def kappa_f(self) -> float:
"""Wraps to :attr:`osaft.core.fluids.ViscousFluid.kappa_f`"""
return self.fluid.kappa_f
@property
def k_f(self) -> complex:
"""Wraps to :attr:`osaft.core.fluids.ViscousFluid.k_f`"""
return self.fluid.k_f
@property
def k_v(self) -> complex:
"""Wraps to :attr:`osaft.core.fluids.ViscousFluid.k_v`"""
return self.fluid.k_v
@property
def delta(self) -> float:
"""Wraps to :attr:`osaft.core.fluids.ViscousFluid.delta`"""
return self.fluid.delta
# -------------------------------------------------------------------------
# Wrappers for Dependent Field Attributes
# -------------------------------------------------------------------------
@property
def abs_pos(self) -> float:
"""Wraps to
:attr:`osaft.core.backgroundfields.BackgroundField.abs_pos`
"""
return self.field.abs_pos
[docs] def A_in(self, n: int) -> complex:
"""Wraps to
:attr:`osaft.core.backgroundfields.BackgroundField.A_in`
:param n: mode number
"""
return self.field.A_in(n)
if __name__ == "__main__":
pass