Source code for osaft.solutions.basedoinikov2021.base

from abc import ABC, abstractmethod
from typing import Optional, Union

from osaft import (
    BackgroundField,
    ElasticSolid,
    ViscoelasticFluid,
    ViscousFluid,
    WaveType,
    log,
)
from osaft.core.basecomposite import BaseSphereFrequencyComposite
from osaft.core.frequency import Frequency
from osaft.core.geometries import Sphere
from osaft.core.helper import StringFormatter as SF
from osaft.core.variable import ActiveVariable
from osaft.solutions.base_solution import BaseSolution


[docs]class BaseDoinikov(BaseSphereFrequencyComposite, BaseSolution, ABC): """Base class for Doinikov (viscous fluid-elastic sphere; 2021) :param f: frequency [Hz] :param R_0: radius [m] :param rho_s: density of the particle [kg/m^3] :param E_s: Young's modulus of the particle [Pa] :param nu_s: Poisson's ratio of the particle [-] :param fluid: Fluid instance of the model :param p_0: pressure amplitude [Pa] :param wave_type: wave type :param position: position in the standing wave field [m] """ # Supported wave_type for the class supported_wavetypes = [WaveType.STANDING, WaveType.TRAVELLING] def __init__( self, f: Union[Frequency, float], R_0: Union[Sphere, float], rho_s: float, E_s: float, nu_s: float, fluid: Union[ViscousFluid, ViscoelasticFluid], p_0: float, wave_type: WaveType, position: Optional[float], ) -> None: """Constructor method """ # Init parent classes BaseSphereFrequencyComposite.__init__(self, f, R_0) BaseSolution.__init__(self, 'Doinikov2021Viscous') # Initializing fluid self.fluid = fluid # Making sure fluid has the same Frequency instance self.fluid.frequency = self.frequency # Initialize Components self.solid = ElasticSolid(self.frequency, E_s, nu_s, rho_s) self.field = BackgroundField( self.fluid, p_0, wave_type, position, ) # Dependent variables self._x_l = ActiveVariable( self._compute_x_l, 'dimensionless wavenumber x_l', ) self._x_t = ActiveVariable( self._compute_x_t, 'dimensionless wavenumber x_t', ) self._x_f = ActiveVariable( self._compute_x_f, 'dimensionless wavenumber x_f', ) self._x_v = ActiveVariable( self._compute_x_v, 'dimensionless wavenumber x_v', ) # Dependencies self._x_f.is_computed_by(self.fluid._k_f, self.sphere._R_0) self._x_v.is_computed_by(self.fluid._k_v, self.sphere._R_0) self._x_l.is_computed_by(self.solid._k_l, self.sphere._R_0) self._x_t.is_computed_by(self.solid._k_t, self.sphere._R_0) log.debug(repr(self)) log.info(str(self)) def __repr__(self): # pragma: no cover return ( f'BaseDoinikov({self.f}, {self.R_0}, {self.rho_s}, ' f'{self.E_s}), {self.nu_s}. {self.rho_f}, {self.c_f}, ' f'{self.eta_f}, {self.zeta_f}' f', {self.p_0}, {self.wave_type}, ' f'{self.field.position})' ) def __str__(self): out = 'Doinikov solution with following properties: \n' out += SF.get_str_text('Frequency', 'f', self.wave_type, 'Hz') out += SF.get_str_text( 'Wavelength', 'lambda_f', self.fluid.lambda_f, 'm', ) out += SF.get_str_text( 'Boundary Layer Thickness', 'delta', self.fluid.delta, 'm', ) out += SF.get_str_text( 'Viscous wavelength', 'lambda_v', self.lambda_v, 'm', ) out += SF.get_str_text('Radius', 'R_0', self.R_0, 'm') out += SF.get_str_text( 'Fluid shear viscosity', 'eta_f', self.eta_f, 'Pa s', ) out += SF.get_str_text( 'Fluid bulk viscosity', 'zeta_f', self.zeta_f, 'Pa s', ) return out # ------------------------------------------------------------------------- # Abstract Methods # ------------------------------------------------------------------------- @property @abstractmethod def eta(self) -> Union[float, complex]: """Fluid shear viscosity. For a :class:`osaft.core.fluids.ViscousFluid` returns :math:`\\eta_f`, for a :class:`osaft.core.fluids.ViscoelasticFluid` returns :math:`\\eta_c`. """ pass @property @abstractmethod def zeta(self) -> Union[float, complex]: """Fluid bulk viscosity. For a :class:`osaft.core.fluids.ViscousFluid` returns :math:`\\zeta_f`, for a :class:`osaft.core.fluids.ViscoelasticFluid` returns :math:`\\zeta_c`. """ pass # ------------------------------------------------------------------------- # Getters for Dependent Variables # ------------------------------------------------------------------------- @property def x_l(self): """Dimensionless primary wavenumber in the solid :math:`k_l \\cdot R_0` """ return self._x_l.value @property def x_t(self): """Dimensionless secondary wavenumber in the solid :math:`k_t \\cdot R_0` """ return self._x_t.value @property def x_f(self): """Dimensionless acoustic wavenumber in the fluid :math:`k_f \\cdot R_0` """ return self._x_f.value @property def x_v(self): """Dimensionless viscous wavenumber in the fluid :math:`k_v \\cdot R_0` """ return self._x_v.value # ------------------------------------------------------------------------- # Dependent Variables Methods # ------------------------------------------------------------------------- def _compute_x_l(self) -> complex: return self.R_0 * self.k_l def _compute_x_t(self) -> complex: return self.R_0 * self.k_t def _compute_x_f(self) -> complex: return self.R_0 * self.k_f def _compute_x_v(self) -> complex: return self.R_0 * self.k_v # ------------------------------------------------------------------------- # Wrappers for Independent Solid Attributes # ------------------------------------------------------------------------- @property def rho_s(self) -> float: """ Wraps to :attr:`osaft.core.solids.ElasticSolid.rho_s` """ return self.solid.rho_s @rho_s.setter def rho_s(self, value) -> None: self.solid.rho_s = value @property def E_s(self) -> float: """ Wraps to :attr:`osaft.core.solids.ElasticSolid.E_s` """ return self.solid.E_s @E_s.setter def E_s(self, value) -> None: self.solid.E_s = value @property def nu_s(self) -> float: """ Wraps to :attr:`osaft.core.solids.ElasticSolid.nu_s` """ return self.solid.nu_s @nu_s.setter def nu_s(self, value) -> None: self.solid.nu_s = value # ------------------------------------------------------------------------- # Wrappers for Dependent Solid Attributes # ------------------------------------------------------------------------- @property def k_l(self) -> float: """ Wraps to :attr:`osaft.core.solids.ElasticSolid.k_l` """ return self.solid.k_l @property def k_t(self) -> float: """ Wraps to :attr:`osaft.core.solids.ElasticSolid.k_t` """ return self.solid.k_t # ------------------------------------------------------------------------- # Wrappers for Dependent Fluid Attributes # ------------------------------------------------------------------------- @property def rho_f(self) -> float: """ Wraps to :attr:`osaft.core.fluids.ViscousFluid.rho_0` or to :attr:`osaft.core.fluids.ViscoelasticFluid.rho_0` """ return self.fluid.rho_f @rho_f.setter def rho_f(self, value) -> None: self.fluid.rho_f = value @property def c_f(self) -> float: """ Wraps to :attr:`osaft.core.fluids.ViscousFluid.c_f` or to :attr:`osaft.core.fluids.ViscoelasticFluid.c_f` """ return self.fluid.c_f @c_f.setter def c_f(self, value) -> None: self.fluid.c_f = value @property def eta_f(self) -> float: """ Wraps to :attr:`osaft.core.fluids.ViscousFluid.eta_f` or to :attr:`osaft.core.fluids.ViscoelasticFluid.eta_f` """ return self.fluid.eta_f @eta_f.setter def eta_f(self, value) -> None: self.fluid.eta_f = value @property def zeta_f(self) -> float: """ Wraps to :attr:`osaft.core.fluids.ViscousFluid.zeta_f` or to :attr:`osaft.core.fluids.ViscoelasticFluid.zeta_f` """ return self.fluid.zeta_f @zeta_f.setter def zeta_f(self, value) -> None: self.fluid.zeta_f = value # ------------------------------------------------------------------------- # Wrappers for Dependent Fluid Attributes # ------------------------------------------------------------------------- @property def k_f(self) -> complex: """ Wraps to :attr:`osaft.core.fluids.ViscousFluid.k_f` or to :attr:`osaft.core.fluids.ViscoelasticFluid.k_f` """ return self.fluid.k_f @property def k_v(self) -> complex: """ Wraps to :attr:`osaft.core.fluids.ViscousFluid.k_v` or to :attr:`osaft.core.fluids.ViscoelasticFluid.k_v` """ return self.fluid.k_v @property def delta(self) -> float: """ Wraps to :attr:`osaft.core.fluids.ViscousFluid.delta` or to :attr:`osaft.core.fluids.ViscoelasticFluid.delta` """ return self.fluid.delta @property def lambda_v(self) -> float: """ Wraps to :attr:`osaft.core.fluids.ViscousFluid.lambda_v` or to :attr:`osaft.core.fluids.ViscoelasticFluid.lambda_v` """ return self.fluid.lambda_v # ------------------------------------------------------------------------- # Wrappers for Independent Background 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) -> None: self.fluid.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) -> None: self.field.wave_type = value # ------------------------------------------------------------------------- # Wrappers for Background Field Methods # -------------------------------------------------------------------------
[docs] def A_in(self, n): """Wraps to :attr:`osaft.core.backgroundfields.BackgroundField.A_in` """ return self.field.A_in(n)
if __name__ == '__main__': pass