[docs]@dataclassclasskWaveMedium(object):# sound speed distribution within the acoustic medium [m/s] | required to be definedsound_speed:np.array# reference sound speed used within the k-space operator (phase correction term) [m/s]sound_speed_ref:np.array=None# density distribution within the acoustic medium [kg/m^3]density:np.array=None# power law absorption coefficient [dB/(MHz^y cm)]alpha_coeff:np.array=None# power law absorption exponentalpha_power:np.array=None# optional input to force either the absorption or dispersion terms in the equation of state to be excluded;# valid inputs are 'no_absorption' or 'no_dispersion'alpha_mode:np.array=None# frequency domain filter applied to the absorption and dispersion terms in the equation of statealpha_filter:np.array=None# two element array used to control the sign of absorption and dispersion terms in the equation of statealpha_sign:np.array=None# parameter of nonlinearityBonA:np.array=None# is the medium absorbing?absorbing:bool=False# is the medium absorbing stokes?stokes:bool=False# """# Note: For heterogeneous medium parameters, medium.sound_speed and# medium.density must be given in matrix form with the same dimensions as# kgrid. For homogeneous medium parameters, these can be given as single# numeric values. If the medium is homogeneous and velocity inputs or# outputs are not required, it is not necessary to specify medium.density.# """def__post_init__(self):self.sound_speed=np.atleast_1d(self.sound_speed)
[docs]defcheck_fields(self,kgrid_shape:np.ndarray)->None:""" Check whether the given properties are valid Args: kgrid_shape: Shape of the kWaveGrid Returns: None """# check the absorption mode input is validifself.alpha_modeisnotNone:assertself.alpha_modein["no_absorption","no_dispersion","stokes",],"medium.alpha_mode must be set to 'no_absorption', 'no_dispersion', or 'stokes'."# check the absorption filter input is validifself.alpha_filterisnotNoneandnot(self.alpha_filter.shape==kgrid_shape).all():raiseValueError("medium.alpha_filter must be the same size as the computational grid.")# check the absorption sign input is validifself.alpha_signisnotNoneand(notkwave.utils.checkutils.is_number(self.alpha_sign)or(self.alpha_sign.size!=2)):raiseValueError("medium.alpha_sign must be given as a ""2 element numerical array controlling absorption and dispersion, respectively.")# check alpha_coeff is non-negative and realifnotnp.all(np.isreal(self.alpha_coeff))ornp.any(self.alpha_coeff<0):raiseValueError("medium.alpha_coeff must be non-negative and real.")
[docs]defis_defined(self,*fields)->List[bool]:""" Check if the field(s) are defined or None Args: *fields: String list of the fields Returns: Boolean list """results=[]forfinfields:results.append(getattr(self,f)isnotNone)returnresults
[docs]defensure_defined(self,*fields)->None:""" Assert that the field(s) are defined (not None) Args: *fields: String list of the fields Returns: None """forfinfields:assertgetattr(self,f)isnotNone,f"The field {f} must be not be None"
[docs]defis_nonlinear(self)->bool:""" Check if the medium is nonlinear Returns: whether the fluid simulation is nonlinear """returnself.BonAisnotNone
[docs]defset_absorbing(self,is_absorbing,is_stokes=False)->None:""" Change medium's absorbing and stokes properties Args: is_absorbing: Is the medium absorbing is_stokes: Is the medium stokes Returns: None """# only stokes absorption is supported in the axisymmetric codeself.absorbing,self.stokes=is_absorbing,is_stokesifis_absorbing:ifis_stokes:self._check_absorbing_with_stokes()else:self._check_absorbing_without_stokes()
def_check_absorbing_without_stokes(self)->None:""" Check if the medium properties are set correctly for absorbing simulation without stokes Returns: None """# enforce both absorption parametersself.ensure_defined("alpha_coeff","alpha_power")# check y is a scalarassertnp.isscalar(self.alpha_power),"medium.alpha_power must be scalar."# check y is real and within 0 to 3assertnp.all(np.isreal(self.alpha_coeff))and0<self.alpha_power<3,"medium.alpha_power must be a real number between 0 and 3."# display warning if y is close to 1 and the dispersion term has not been set to zeroifself.alpha_mode!="no_dispersion":assertself.alpha_power!=1,"""The power law dispersion term in the equation of state is not valid for medium.alpha_power = 1. This error can be avoided by choosing a power law exponent close to, but not exactly, 1. If modelling acoustic absorption for medium.alpha_power = 1 is important and modelling dispersion is not critical, this error can also be avoided by setting medium.alpha_mode to 'no_dispersion'"""def_check_absorbing_with_stokes(self):""" Check if the medium properties are set correctly for absorbing simulation with stokes Returns: None """# enforce absorption coefficientself.ensure_defined("alpha_coeff")# give warning if y is specifiedifself.alpha_powerisnotNoneand(self.alpha_power.size!=1orself.alpha_power!=2):logging.log(logging.WARN,"the axisymmetric code and stokes absorption assume alpha_power = 2, user value ignored.")# overwrite y valueself.alpha_power=2# don't allow medium.alpha_mode with the axisymmetric codeifself.alpha_modeisnotNoneand(self.alpha_modein["no_absorption","no_dispersion"]):raiseNotImplementedError("Input option medium.alpha_mode is not supported with the axisymmetric code ""or medium.alpha_mode = ""stokes"".")# don't allow alpha_filter with stokes absorption (no variables are applied in k-space)assertself.alpha_filterisNone,("Input option medium.alpha_filter is not supported with the axisymmetric code ""or medium.alpha_mode = 'stokes'. ")########################################### Elastic-code related properties - raise error when accessed##########################################_ELASTIC_CODE_ACCESS_ERROR_TEXT_="Elastic simulation and related properties are not supported!"@propertydefsound_speed_shear(self):# pragma: no cover""" Shear sound speed (used in elastic simulations | not supported currently!) """raiseNotImplementedError(self._ELASTIC_CODE_ACCESS_ERROR_TEXT_)@propertydefsound_speed_ref_shear(self):# pragma: no cover""" Shear sound speed reference (used in elastic simulations | not supported currently!) """raiseNotImplementedError(self._ELASTIC_CODE_ACCESS_ERROR_TEXT_)@propertydefsound_speed_compression(self):# pragma: no cover""" Compression sound speed (used in elastic simulations | not supported currently!) """raiseNotImplementedError(self._ELASTIC_CODE_ACCESS_ERROR_TEXT_)@propertydefsound_speed_ref_compression(self):# pragma: no cover""" Compression sound speed reference (used in elastic simulations | not supported currently!) """raiseNotImplementedError(self._ELASTIC_CODE_ACCESS_ERROR_TEXT_)@propertydefalpha_coeff_compression(self):# pragma: no cover""" Compression alpha coefficient (used in elastic simulations | not supported currently!) """raiseNotImplementedError(self._ELASTIC_CODE_ACCESS_ERROR_TEXT_)@propertydefalpha_coeff_shear(self):# pragma: no cover""" Shear alpha coefficient (used in elastic simulations | not supported currently!) """raiseNotImplementedError(self._ELASTIC_CODE_ACCESS_ERROR_TEXT_)