Transmission between an AntennaFieldRepresentation and ProbeAntennas
One of the most important tasks of AntennaFieldRepresentations.jl is to calculate the signal which is received by one or more ProbeAntennas when they are impinged by a certain electromagnetic field expressed by an AntennaFieldRepresentation.
The method
transmit(aut_field::AntennaFieldRepresentation, probe::ProbeAntenna)can be used to calculate the signal received by the probe[1]. The result will be a single complex number representing the amplitude and phase of the received signal.
Furthermore, one can calculate the received signal simultaneously for several probe antennas at different locations by the method
transmit(aut_field::AntennaFieldRepresentation, fieldsampling::FieldSampling)where the various probe antenna positions are specified by the FieldSampling. In this case, an array of complex numbers will be returned corresponding to all received signals by all probes at the positions specified in fieldsampling.
The transmit method calculates the $M$ probe output signals of the FieldSampling from the $N$ coefficients of the AntennaFieldRepresentation. The method essentially implements an $M \times N$ linear map between the $N$ coefficients of the field representation and the $M$ probe outputs.
TransmitMaps
For many convenient reasons it is very desireable to provide an explicit linear map to implement the transmit functionality. AntennaFieldRepresentations has a type TransmitMap which represents the $M \times N$ linear map between the $N$ coefficients of the field representation and the $M$ probe outputs. All required precalculations are stored in the TransmitMap which allows us to efficiently reuse allocated memory and save redundant operations for repeated method calls.
A TransmitMap is constructed via the constructor (expand "Setup Code" to see an example of how the input data is generated)
Setup Code
using AntennaFieldRepresentations
Z₀=376.730313669; # free-space wave impedance
f= 1.5e9; # frequency
λ = AntennaFieldRepresentations.c₀ / f; # wavelength
k0 = 2 * pi / λ; # wavenumber
# setup of spherical wave expansion as AntennaFieldRepresentation
sph_coefficients = SphericalCoefficients(ComplexF64.(collect(1:16)))
aut_field = SphericalWaveExpansion(Radiated(),sph_coefficients, k0)
################# setup SphericalFieldSampling ########################
Lmax = 2 # maximum mode order is 2 in this example
# spherical coefficients of incident field Hertzian dipole at 1.0m distance
αinc=AntennaFieldRepresentations.αinc_dipole(1.0, Lmax, k0)
Jθ= 2*Lmax + 1;
Jϕ= 2*Lmax + 1;
samplingstrategy= RegularθRegularϕSampling(Jθ, Jϕ)
################# End of setup SphericalFieldSampling ########################
fieldsampling = SphericalFieldSampling(samplingstrategy, αinc);A=TransmitMap(aut_field, fieldsampling)The probe outputs for an aut_field can be calculated by either using the TransmitMap as a function-like object
y = A(aut_field)or by making use of the fact that the TransmitMap implements a LinearMaps.LinearMap and therefore behaves like a matrix[2]
y = A * aut_fieldin fact, apart from aut_field any AbstractVector x of the same size as the coefficient vector aut_field is a valid input to the TransmitMap:
x = zeros(ComplexF64, length(aut_field))
y = A(x)y = A * x The coefficients of the AbstractVector x must correspond to the coefficients of a FieldRepresentation of the exact same type and size as has been used for the construction of the TransmitMap. Using AbstractVectors outside of this context will lead to unexpected results.
As explained in the "OperationMaps" Chapter of this documentation, each TransmitMap operates as linear map and its adjoint, transpose and inverse (if available) map can be constructed via
julia> Aᴴ = adjoint(A)
16×30 LinearMaps.AdjointMap{ComplexF64} of
30×16 SphericalTransmitMap{ComplexF64}
julia> Aᵀ = transpose(A)
16×30 LinearMaps.TransposeMap{ComplexF64} of
30×16 SphericalTransmitMap{ComplexF64}
julia> A⁻¹ = inverse(A)
16×30 AntennaFieldRepresentations.InverseSphericalTransmitMap{ComplexF64}Depending on the concrete types of the aut_field and the fieldsampling, different types of TransmitMap will be created to implement the most efficient agorithm for the transmission. The following cross table clarifies which type of TransmitMap is created by which pair of input types.
IrregularFieldSampling | SphericalFieldSampling | ||
|---|---|---|---|
DipoleArray | MLFMMTransmitMap | MLFMMSphericalTransmitMap | |
SphericalWaveExpansion | DirectTransmitMap | SphericalTransmitMap[3] | |
PlaneWaveExpansion | DirectTransmitMap | PlaneWaveSphericalTransmitMap[3] | |
SurfaceCurrents | MLFMMTransmitMap | MLFMMSphericalTransmitMap |
Not all types of TransmitMap allow to setup an inverse efficiently. In most cases, a direct inverse is not available but the inverse map is implemented via an iterative solver. The types of TransmitMap which have a direct inverse available, are annotated with a superscript [3] in the table above.
Since the different types of TransmitMap represent different algorithms for the computation of the transmission, they have different parameters which may be tuned by the user. The parameters of the TransmitMaps can be controlled by the user through several keyword arguments in the respective constructor, where the available keyword arguments depend on the concrete type of the TransmitMap
- 1If the
AntennaFieldrepresentationcorresponds to the field generated by the transmit antenna, excited by a unit input signal at port 1, and theProbeAntenna, connected to port 2, is scaled equivalently, the calculated signal corresponds exactly to the $S_{21}$- parameter between the transmit antenna and the probe antenna. - 2In fact, the
TransmitMapis one of many instances of anOperationMapinAntennaFieldRepresentations.jl. All availableOperationMaps inAntennaFieldRepresentations.jlcan be found in the "OperationMaps" section of this documentation. - 3A direct (non-iterative) inverse transmit map is available using the
inverse()command.