Skip to content
Snippets Groups Projects
Select Git revision
  • a39ea01cf912b435604aa95615028e98d37cde02
  • master default protected
  • ao2g15-master-patch-59788
  • v1.3
  • v1.1
  • v1.0-rc4
  • v2.2-rc1
  • v1.0-rc3
  • v1.0-rc2
  • v2.0
  • v1.0-rc1
  • v0.9
  • v0.9.1
  • v1.0-rc
14 results

uosdocs.dtx

Blame
  • Forked from UoS LaTeX Group / University of Southampton Thesis Template
    Source project has a limited visibility.
    planeWave.m 5.08 KiB
    %% Calculate wavefield generated by plane waves in the frequency domain
    % --------------------------------------------------
    % Author: Achilles Kappis
    % e-mail: axilleaz@protonmail.com
    %
    % Date: 30/07/2024 (DD/MM/YYYY)
    %
    % Copyright: MIT
    % --------------------------------------------------
    % Functionality: Calculate the wavefield generated by plane waves at
    %                specified directions in the frequency domain.
    % --------------------------------------------------
    % Input
    % 
    % sDir [numeric]: The direction of incidence of the plane waves. This can
    %                 be either an Nx2 matrix with N being the number of angles
    %                 of incidence in [azimuth, elevation] format, expressed in
    %                 radians, or an Nx3 matrix with the entried corresponding
    %                 to the wavenumbers along each of the Cartesian axes. See
    %                 "notes" for more information.
    % 
    % rPos [numeric]: The position of the receivers in Cartesian coordinates.
    %                 The variable must be a matrix with dimensions Mx3 where
    %                 M is the number of receivers and the columns represent
    %                 the x, y and z coordinates respectively.
    % 
    % f [numeric]: The frequencies for which to calculate the wave field. It
    %              must be a scalar or vector.
    % 
    % Q [numeric] (Optional): The source strength of the plane waves. This
    %                         variable must be either a scalar corresponding to
    %                         all sources having the same strength, or a matrix
    %                         with dimensions NxK, where K is the number of
    %                         frequencies of interest. The strengths can be
    %                         complex numbers. [Default: 1].
    % 
    % c [numeric] (Optional): The speed of sound in m/s. This variable is not
    %                         used if the wavenumbers are provided in the sDir
    %                         argument. [Default: 343].
    % 
    % --------------------------------------------------
    % Output
    % 
    % waveField [numeric]: The complex pressures at the position of the
    %                      receivers. The variable is a matrix of dimensions
    %                      MxNxF where M is the number of receivers, N the
    %                      number of sources and F the number of frequencies.
    % 
    % --------------------------------------------------
    % Notes
    % 
    % If the variable "sDir" provides the wavenumbers along the Cartesian axes,
    % it is the responsibility of the user to make sure that the condition
    % k^2 = kx^2 + ky^2 + kz^2 holds true.
    % 
    % --------------------------------------------------
    function waveField = planeWave(sDir, rPos, f, Q, c)
        % ====================================================
        % Check for number of arguments
        % ====================================================
        narginchk(3, 5);
        nargoutchk(0, 1);
    
        % ====================================================
        % Validate input arguments
        % ====================================================
        % Validate mandatory arguments
        validateattributes(sDir, "numeric", {'finite', 'nonnan', 'nonempty', 'real'}, mfilename, "Source positions", 1);
    
        % Check form of sDir (directions or wavenumbers are provided)
        if sum(size(sDir, 2) ~= 2) > 0
            error("The size of the directions matrix must be either Nx2 (incidence angles), or Nx3 (wavenumbers along the Cartesian axes)");
        end
    
        validateattributes(rPos, "numeric", {'2d', 'ncols', 3, 'finite', 'nonnan', 'nonempty', 'real'}, mfilename, "Receiver positions", 2);
        validateattributes(f, "numeric", {'vector', 'finite', 'nonnan', 'nonempty', 'real'}, mfilename, "Frequencies", 3);
    
        % Validate optional arguments
        if nargin > 3 && ~isempty(Q)
            validateattributes(Q, "numeric", {'2d', 'finite', 'nonempty', 'nonnan'}, mfilename, "Source strength(s)", 5);
    
            % Make sure Q has the correct dimensions
            if ~isscalar(Q) && sum((size(Q) ~= [size(sDir, 1), length(f)])) > 0
                error("Source strength(s) must be either a scalar or its length must match the number of sources.");
            end
        else
            Q = 1;
        end
    
        if nargin > 4 && ~isempty(c)
            validateattributes(c, "numeric", {'scalar', 'finite', 'positive', 'nonnan', 'nonempty', 'real'}, mfilename, "Speed of propagation", 6);
        else
            c = 343;
        end
    
        % ====================================================
        % Pre-process
        % ====================================================
        % Make sure frequencies is a column vector
        f = f(:);
    
        % Calculate wavenumber from angles of indidence to wavenumber (if needed)
        if size(sDir, 2) == 2
            [kx, ky, kz] = sph2cart(sDir(:, 1), sDir(:, 2), ones(size(sDir, 1), 1));
            k = [kx, ky, kz] .* (2 * pi * permute(f, [3, 2, 1])/c);
        end
    
        % Create a source strength vector (if needed)
        if isscalar(Q)
            Q = ones(size(k, 1), length(f)) * Q;
        end
    
        % =============================================
        % Calculate wavefield
        % ============================================
        % Go through the frequencies
        for fIdx = length(f):-1:1
            waveField(:, :, fIdx) = Q(:, fIdx).' .* exp(-1j * rPos * k(:, :, fIdx));
        end
    end