Source code for ground_reflections

import numpy as np
from typing import Dict, Any
from scipy import special
from pyNA.src.data import Data


[docs]def ground_reflections(settings: Dict[str, Any], data: Data, r: np.float64, beta: np.float64, x_obs: np.ndarray, c_bar: np.float64, rho_0: np.float64) -> np.ndarray: """ Compute the ground reflection coefficients. :param settings: pyna settings :type settings: Dict[str, Any] :param data: pyna noise data :type data: Data :param r: distance source to observer [m] :type r: np.float64 :param beta: elevation angle [deg] :type beta: np.float64 :param x_obs: observer location [m, m, m] :type x_obs: np.ndarray :param c_bar: average ambient speed of sound between observer and source [m/s] :type c_bar: np.float64 :param rho_0: ambient density [kg/m3] :type rho_0: np.float64 :return: G :rtype: np.ndarray """ # Compute difference in direct and reflected distance between source and observer # Source: Zorumski report 1982 part 1. Chapter 5.1 Equation 16 r_r = np.sqrt(r ** 2 + 4 * x_obs[2] ** 2 + 4 * r * x_obs[2] * np.sin(beta * np.pi / 180.)) dr = r_r - r # Compute wave number # Source: Zorumski report 1982 part 1. Chapter 3.2 page 1 k = 2 * np.pi * data.f_sb / c_bar # Compute dimensionless frequency eta (note: for acoustically hard surface: eta = 0) # Source: Zorumski report 1982 part 1. Chapter 3.2 page 2 eta = 2 * np.pi * rho_0 * data.f_sb / settings.sigma # Compute the cosine of the incidence angle # Source: Zorumski report 1982 part 1. Chapter 5.1 Equation 18 cos_theta = (r * np.sin(beta * np.pi / 180.) + 2 * x_obs[2]) / r_r # Complex specific ground admittance nu # Source: Zorumski report 1982 part 1. Chapter 3.2 Equation 13 / adapted through Berton lateral attenuation paper nu = (1 + (6.86 * eta) ** (-0.75) + (4.36 * eta) ** (-0.73) * 1j) ** (-1) # Compute Gamma # Source: Zorumski report 1982 part 1. Chapter 3.2 Equation 5 Gamma = (cos_theta - nu) / (cos_theta + nu) # Compute tau # Source: Zorumski report 1982 part 1. Chapter 3.2 Equation 9 tau = np.sqrt(k * r_r / 2j) * (cos_theta + nu) # Compute complex spherical wave reflection coefficient # Source: Zorumski report 1982 part 1. Chapter 3.2 Equation 12 U = np.real(tau ** 0) U[np.where(-np.real(tau) == 0)] = 0.5 * np.ones(settings.N_b * settings.N_f, dtype=np.float64)[np.where(-np.real(tau) == 0)] U[np.where(-np.real(tau) < 0)] = np.zeros(settings.N_b * settings.N_f, dtype=np.float64)[np.where(-np.real(tau) < 0)] # Compute F # Source: Zorumski report 1982 part 1. Chapter 3.2 Equation 11 F = -2 * np.sqrt(np.pi) * U * tau * np.exp(tau ** 2) + 1. / (2. * tau ** 2) - 3. / (2 * tau ** 2) ** 2 # Compute complex spherical wave function F # Source: Zorumski report 1982 part 1. Chapter 3.2 Equation 10 (using Faddeeva function) F[np.where(np.absolute(tau)<10)] = (1 - np.sqrt(np.pi) * tau * (special.wofz(tau * 1j)))[np.where(np.absolute(tau)<10)] # Compute Z_cswfc # Source: Zorumski report 1982 part 1. Chapter 3.2 Equation 6 Z_cswfc = Gamma + (1 - Gamma) * F R = np.absolute(Z_cswfc) alpha = np.angle(Z_cswfc) # Compute the constant K and constant epsilon # Source: Zorumski report 1982 part 1. Chapter 3.2 Equation 16-17 K = 2 ** (1. / (6. * settings.N_b)) eps = K - 1 # Compute G # Source: Zorumski report 1982 part 1. Chapter 3.2 Equation 18 if dr > 0: G = 1 + R ** 2 + 2 * R * np.exp(-(settings.a_coh * k * dr) ** 2) * np.cos(alpha + k * dr) * np.sin(eps * k * dr) / (eps * k * dr) else: G = 1 + R ** 2 + 2 * R * np.exp(-(settings.a_coh * k * dr) ** 2) * np.cos(alpha + k * dr) return G