Loading [MathJax]/extensions/tex2jax.js
ITS.Propagation.LFMF 1.1
Part of the NTIA/ITS Propagation Library
All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
LFMF.h File Reference

Interface header for this library. More...

Go to the source code of this file.

Classes

struct  ITS::Propagation::LFMF::Result
 Structure to hold LF/MF model outputs. More...
 

Enumerations

enum class  ITS::Propagation::LFMF::Polarization { HORIZONTAL = 0 , VERTICAL = 1 }
 Valid RF polarizations for use of this model. More...
 
enum class  ITS::Propagation::LFMF::SolutionMethod { FLAT_EARTH_CURVE , RESIDUE_SERIES }
 Solution method used to generate model result. More...
 
enum class  ITS::Propagation::LFMF::AiryKind {
  AIRY = 1 , AIRYD , BAIRY , BAIRYD ,
  WTWO , DWTWO , WONE , DWONE
}
 Kinds of Airy functions to specify for Airy() and WiRoot() operation. More...
 
enum class  ITS::Propagation::LFMF::AiryScaling { HUFFORD , WAIT , NONE }
 Multiplicative scaling to use when dealing with Airy functions. More...
 
enum  ITS::Propagation::LFMF::ReturnCode {
  ITS::Propagation::LFMF::SUCCESS = 0 , ITS::Propagation::LFMF::ERROR__TX_TERMINAL_HEIGHT = 32 , ITS::Propagation::LFMF::ERROR__RX_TERMINAL_HEIGHT , ITS::Propagation::LFMF::ERROR__FREQUENCY ,
  ITS::Propagation::LFMF::ERROR__TX_POWER , ITS::Propagation::LFMF::ERROR__SURFACE_REFRACTIVITY , ITS::Propagation::LFMF::ERROR__PATH_DISTANCE , ITS::Propagation::LFMF::ERROR__EPSILON ,
  ITS::Propagation::LFMF::ERROR__SIGMA , ITS::Propagation::LFMF::ERROR__POLARIZATION
}
 Return Codes defined by this software (0-127) More...
 

Functions

ReturnCode ITS::Propagation::LFMF::LFMF (const double h_tx__meter, const double h_rx__meter, const double f__mhz, const double P_tx__watt, const double N_s, const double d__km, const double epsilon, const double sigma, const int pol, Result &result)
 Compute the LFMF propagation prediction.
 
char * ITS::Propagation::LFMF::GetReturnStatusCharArray (const int code)
 Get an error message string (as C-style string) from a return code.
 
void ITS::Propagation::LFMF::FreeReturnStatusCharArray (char *c_msg)
 Free the memory allocated by GetReturnStatusCharArray.
 
ReturnCode ITS::Propagation::LFMF::LFMF_CPP (const double h_tx__meter, const double h_rx__meter, const double f__mhz, const double P_tx__watt, const double N_s, const double d__km, const double epsilon, const double sigma, const Polarization pol, Result &result)
 Compute the LFMF propagation prediction.
 
std::string ITS::Propagation::LFMF::GetReturnStatus (int code)
 Get an error message string from a return code.
 
double ITS::Propagation::LFMF::FlatEarthCurveCorrection (const std::complex< double > delta, const std::complex< double > q, const double h_1__km, const double h_2__km, const double d__km, const double k, const double a_e__km)
 Calculates the groundwave field strength using the flat Earth approximation with curvature correction.
 
double ITS::Propagation::LFMF::ResidueSeries (const double k, const double h_1__km, const double h_2__km, const double nu, const double theta__rad, const std::complex< double > q)
 Calculates the groundwave field strength using the Residue Series method.
 
std::complex< double > ITS::Propagation::LFMF::wofz (const std::complex< double > z)
 This function computes the Faddeeva function \( W(z) = e^{-z^2} \mathrm{erfc}(-iz) \).
 
std::complex< double > ITS::Propagation::LFMF::Airy (const std::complex< double > Z, const AiryKind kind, const AiryScaling scaling)
 Finds the functions and their derivatives for Airy functions of the first, second, and third (following Hufford) kind.
 
std::complex< double > ITS::Propagation::LFMF::WiRoot (const int i, std::complex< double > &DWi, const std::complex< double > q, std::complex< double > &Wi, const AiryKind kind, const AiryScaling scaling)
 Finds the roots to the equation \( Wi'(ti) - q*Wi(ti) = 0 \).
 
ReturnCode ITS::Propagation::LFMF::ValidateInput (const double h_tx__meter, const double h_rx__meter, const double f__mhz, const double P_tx__watt, const double N_s, const double d__km, const double epsilon, const double sigma)
 Validate that model input values are within valid ranges.
 
ReturnCode ITS::Propagation::LFMF::ValidatePolarization (const Polarization pol)
 Perform input Polarization validation.
 
bool ITS::Propagation::LFMF::AlmostEqualRelative (const double A, const double B, const double maxRelDiff)
 Relative epsilon comparisons method.
 

Variables

constexpr double ITS::Propagation::LFMF::PI = 3.1415926535897932384
 Approximate value of \( \pi \).
 
constexpr double ITS::Propagation::LFMF::epsilon_0 = 8.854187817e-12
 Vacuum permittivity (F/m)
 
constexpr double ITS::Propagation::LFMF::a_0__km = 6370
 Earth radius, in km.
 
constexpr double ITS::Propagation::LFMF::C = 299792458.0
 Speed of light (m/s)
 
constexpr double ITS::Propagation::LFMF::ETA = 119.9169832 * PI
 Intrinsic impedance of free space (ohms)
 

Detailed Description

Interface header for this library.

Enumeration Type Documentation

◆ AiryKind

Kinds of Airy functions to specify for Airy() and WiRoot() operation.

The members of this enum allow specification of Airy functions of the first (AIRY), second (BAIRY), or third (WONE and WTWO) kind. These Airy functions of a third kind are specified by Hufford in NTIA Report 87-219. The enum also allows selection of derivatives of any of these functions.

Note
Hufford's Airy functions of a third kind \( \mathrm{Wi}^{(1)} \) and \( \mathrm{Wi}^{(2)} \) are, aside from a multiplicative constant, the same as Wait's \( w_2 \) and \( w_1 \).
See also
ITS::Propagation::LFMF::Airy
ITS::Propagation::LFMF::WiRoot
ITS::Propagation::LFMF::AiryScaling
Enumerator
AIRY 

Airy function of the first kind, \( \mathrm{Ai}(x) \).

AIRYD 

Derivative of AIRY, \( \mathrm{Ai}'(x) \).

BAIRY 

Airy function of the second kind, \( \mathrm{Bi}(x) \).

BAIRYD 

Derivative of BAIRY, \( \mathrm{Bi}'(x) \).

WTWO 

Hufford's Airy function of a third kind, \( \mathrm{Wi}^{(2)} \) (Wait's \( w_1 \))

DWTWO 

Derivative of WTWO, \( \mathrm{Wi}'^{(2)} \) (Wait's \( w_1' \))

WONE 

Hufford's Airy function of a third kind, \( \mathrm{Wi}'^{(1)} \) (Wait's \( w_2 \))

DWONE 

Derivative of WONE, \( \mathrm{Wi}'^{(1)} \) (Wait's \( w_2' \))

◆ AiryScaling

Multiplicative scaling to use when dealing with Airy functions.

The differences in these scaling options are discussed at length in the documentation for ITS::Propagation::LFMF::Airy.

See also
ITS::Propagation::LFMF::Airy
ITS::Propagation::LFMF::WiRoot
ITS::Propagation::LFMF::AiryKind
Enumerator
HUFFORD 

Use Hufford scaling.

WAIT 

Use Wait scaling.

NONE 

No Scaling.

◆ Polarization

Valid RF polarizations for use of this model.

Enumerator
HORIZONTAL 

Horizontal polarization.

VERTICAL 

Vertical polarization.

◆ ReturnCode

Return Codes defined by this software (0-127)

Enumerator
SUCCESS 

Return Success.

ERROR__TX_TERMINAL_HEIGHT 

TX terminal height is out of range.

ERROR__RX_TERMINAL_HEIGHT 

RX terminal height is out of range.

ERROR__FREQUENCY 

Frequency is out of range.

ERROR__TX_POWER 

Transmit power is out of range.

ERROR__SURFACE_REFRACTIVITY 

Surface refractivity is out of range.

ERROR__PATH_DISTANCE 

Path distance is out of range.

ERROR__EPSILON 

Epsilon is out of range.

ERROR__SIGMA 

Sigma is out of range.

ERROR__POLARIZATION 

Invalid value for polarization.

◆ SolutionMethod

Solution method used to generate model result.

Enumerator
FLAT_EARTH_CURVE 

Flat earth curve method.

RESIDUE_SERIES 

Residue series method.

Function Documentation

◆ Airy()

std::complex< double > ITS::Propagation::LFMF::Airy ( const std::complex< double > Z,
const AiryKind kind,
const AiryScaling scaling )

Finds the functions and their derivatives for Airy functions of the first, second, and third (following Hufford) kind.

The function accepts a complex input argument and computes the result from a shifted Taylor series or by asymptotic approximation depending of the location of the input argument.

This routine determines the so-called "Airy Functions of the third kind" \( Wi(1) \) and \( Wi(2) \) that are found in equation 38 of NTIA Report 87-219 "A General Theory of Radio Propagation through a Stratified Atmosphere", George Hufford, July 1987.

The Airy function that appeared in the original FORTRAN GWINT and GWRES implementations had the switches all mangled from what George Hufford had in mind. This routine has the corrected switches. Please see the Airy function code that appears in the appendix of OT/ITS RR 11 "A Wave Hop Propagation Program for an Anisotropic Ionosphere" L. A. Berry and J. E. Herman, April 1971.

Parameters
[in]ZComplex input argument
[in]kindThe type of Airy function to solve
[in]scalingType of scaling to use (HUFFORD or WAIT) when solving Airy functions of the third kind. This parameter is ignored for AIRY, AIRYD, BAIRY, and BAIRYD values of kind.
Returns
The desired Airy function calculated at Z
Exceptions
std::invalid_argumentIf the values provided for kind or scaling are not valid for this function. This includes when scaling NONE is provided for Airy functions of the third kind.
std::range_errorIf the calculation requires expansion data outside the range of what is known by this program.
Note
The following is a note on scaling the output from this program.

There is a definitional problem with the Airy function which is inevitable relative to how it was defined in the original LFMF code originated with the Hufford's AIRY subroutine.

Using the scaling equal to HUFFORD in this program follows the definitions of \( \mathrm{Wi}^{(1)} \) and \( \mathrm{Wi}^{(2)} \) as defined by Hufford (87-219).

Using the scaling equal to WAIT in this program uses the definitions of \( W_1 \) and \( W_2 \) defined in DeMinco (99-368) and in the original LFMF code following Berry via Wait.

The two solutions differ by a constant. As Hufford notes concerning \( \mathrm{Wi}^{(1)} \) and \( \mathrm{Wi}^{(2)} \) in 87-219:

‍"Except for multiplicative constants they correspond to what Fock (1965) calls W1 and W2 and to what Wait (1962) calls W2 and W1.


The following are the multiplicative constants that allow for the translation between Hufford \( \mathrm{Wi}^{(1)} \) and \( \mathrm{Wi}^{(2)} \) with Wait \( w_1 \) and \( w_2 \), respectively. These are given here as a reference if this function is used for programs other than LFMF.

// Wait
complex<double> WW2 = complex<double>( sqrt(3.0*PI), sqrt(PI));
complex<double> WDW2 = complex<double>(-1.0*sqrt(3.0*PI), sqrt(PI));
complex<double> WW1 = complex<double>( sqrt(3.0*PI), -1.0*sqrt(PI));
complex<double> WDW1 = complex<double>(-1.0*sqrt(3.0*PI), -1.0*sqrt(PI));
// Hufford
complex<double> HW2 = 2.0*complex<double>(cos( PI/3.0), sin( PI/3.0));
complex<double> HDW2 = 2.0*complex<double>(cos(-PI/3.0), sin(-PI/3.0));
complex<double> HW1 = 2.0*complex<double>(cos(-PI/3.0), sin(-PI/3.0));
complex<double> HDW1 = 2.0*complex<double>(cos( PI/3.0), sin( PI/3.0));
// (Multiplicative constant) * Hufford's Wi'(1) = Wait W1'
// So the multiplicative constants are:
complex<double> uDW2 = WDW2/HDW1; // uDW2 = complex<double>(0.0, sqrt(PI))
complex<double> uW2 = WW2/HW1; // uW2 = complex<double>(0.0, sqrt(PI))
complex<double> uDW1 = WDW1/HDW2; // uDW1 = complex<double>(0.0, -sqrt(PI))
complex<double> uW1 = WW1/HW2; // uW1 = complex<double>(0.0, -sqrt(PI))

To make the solutions that are generated by this program for the Hufford Airy functions of the "3rd kind" abundantly clear please examine the following examples.

For \( z = 8.0 + 8.0i \) the Asymptotic Solution is used.

Ai( 8.0 + 8.0 i) = 6.576933e-007 + 9.312331e-006 i
Ai'(8.0 + 8.0 i) = 9.79016e-006 + -2.992170e-005 i
Bi( 8.0 + 8.0 i) = -1.605154e+003 + -4.807200e+003 i
Bi'(8.0 + 8.0 i) = 1301.23 + -16956 i
Wi(1)(8.0 + 8.0 i) = -4.807200e+003 + 1.605154e+003 i
Wi(2)(8.0 + 8.0 i) = 4.807200e+003 + -1.605154e+003 i
Ai(z) - j*Bi(z) = -4.807200e+003 + 1.605154e+003 i
Ai(z) + j*Bi(z) = 4.807200e+003 + -1.605154e+003 i

For \( z = 1.0 - 2.0i \) the Taylor series with a shifted center of expansion solution is used.

Ai( 1.0 - 2.0 i) = -2.193862e-001 + 1.753859e-001 i
Ai'(1.0 - 2.0 i) = 0.170445 + -0.387622 i
Bi( 1.0 - 2.0 i) = 4.882205e-002 + -1.332740e-001 i
Bi'(1.0 - 2.0 i) = -0.857239 + -0.495506 i
Wi(1)(1.0 - 2.0 i) = -3.526603e-001 + 1.265638e-001 i
Wi(2)(1.0 - 2.0 i) = -8.611221e-002 + 2.242079e-001 i
Ai(z) - j*Bi(z) = -3.526603e-001 + 1.265639e-001 i
Ai(z) + j*Bi(z) = -8.611221e-002 + 2.242080e-001 i
See also
ITS::Propagation::LFMF::AiryKind
ITS::Propagation::LFMF::AiryScaling
ITS::Propagation::LFMF::WiRoot

◆ AlmostEqualRelative()

bool ITS::Propagation::LFMF::AlmostEqualRelative ( const double A,
const double B,
const double maxRelDiff )

Relative epsilon comparisons method.

Parameters
[in]AFirst double to compare
[in]BSecond double to compare
[in]maxRelDiffMaximum relative difference, defaults to DBL_EPSILON
Returns
If it is equal of the two doubles

◆ FlatEarthCurveCorrection()

double ITS::Propagation::LFMF::FlatEarthCurveCorrection ( const std::complex< double > delta,
const std::complex< double > q,
const double h_1__km,
const double h_2__km,
const double d__km,
const double k,
const double a_e__km )

Calculates the groundwave field strength using the flat Earth approximation with curvature correction.

References:

  • NTIA Report 99-368 "Medium Frequency Propagation Prediction Techniques and Antenna Modeling for Intelligent Transportation Systems (ITS) Broadcast Applications", Nicholas DeMinco. Eq (31)
  • J. Wait, "Radiation From a Vertical Antenna Over a Curved Stratified Ground", Journal of Research of the National Bureau of Standards Vol 56, No. 4, April 1956 Research Paper 2671
Parameters
[in]deltaSurface impedance
[in]qIntermediate value -j*nu*delta
[in]h_1__kmHeight of the higher antenna, in km
[in]h_2__kmHeight of the lower antenna, in km
[in]d__kmPath distance, in km
[in]kWavenumber, in rad/km
[in]a_e__kmEffective earth radius, in km
Returns
Normalized field strength in mV/m

◆ FreeReturnStatusCharArray()

DLLEXPORT void ITS::Propagation::LFMF::FreeReturnStatusCharArray ( char * c_msg)

Free the memory allocated by GetReturnStatusCharArray.

Parameters
[in]c_msgThe status message C-style string to delete

◆ GetReturnStatus()

std::string ITS::Propagation::LFMF::GetReturnStatus ( int code)

Get an error message string from a return code.

Parameters
[in]codeInteger return code.
Returns
A status message corresponding to the input code.

◆ GetReturnStatusCharArray()

DLLEXPORT char * ITS::Propagation::LFMF::GetReturnStatusCharArray ( const int code)

Get an error message string (as C-style string) from a return code.

Parameters
[in]codeInteger return code.
Returns
A status message corresponding to the input code.

◆ LFMF()

DLLEXPORT ReturnCode ITS::Propagation::LFMF::LFMF ( const double h_tx__meter,
const double h_rx__meter,
const double f__mhz,
const double P_tx__watt,
const double N_s,
const double d__km,
const double epsilon,
const double sigma,
const int pol,
Result & result )

Compute the LFMF propagation prediction.

Parameters
[in]h_tx__meterHeight of the transmitter, in meter
[in]h_rx__meterHeight of the receiver, in meter
[in]f__mhzFrequency, in MHz
[in]P_tx__wattTransmitter power, in watts
[in]N_sSurface refractivity, in N-Units
[in]d__kmPath distance, in km
[in]epsilonRelative permittivity
[in]sigmaConductivity
[in]polPolarization: 0 = Horizontal, 1 = Vertical
[out]resultResult structure
Returns
Return code
See also
ITS::Propagation::LFMF::Result
ITS::Propagation::LFMF::ReturnCode

◆ LFMF_CPP()

ReturnCode ITS::Propagation::LFMF::LFMF_CPP ( const double h_tx__meter,
const double h_rx__meter,
const double f__mhz,
const double P_tx__watt,
const double N_s,
const double d__km,
const double epsilon,
const double sigma,
const Polarization pol,
Result & result )

Compute the LFMF propagation prediction.

Parameters
[in]h_tx__meterHeight of the transmitter, in meter
[in]h_rx__meterHeight of the receiver, in meter
[in]f__mhzFrequency, in MHz
[in]P_tx__wattTransmitter power, in watts
[in]N_sSurface refractivity, in N-Units
[in]d__kmPath distance, in km
[in]epsilonRelative permittivity
[in]sigmaConductivity
[in]polPolarization: 0 = Horizontal, 1 = Vertical
[out]resultResult structure
Returns
Return code
See also
ITS::Propagation::LFMF::Polarization
ITS::Propagation::LFMF::Result
ITS::Propagation::LFMF::ReturnCode

◆ ResidueSeries()

double ITS::Propagation::LFMF::ResidueSeries ( const double k,
const double h_1__km,
const double h_2__km,
const double nu,
const double theta__rad,
const std::complex< double > q )

Calculates the groundwave field strength using the Residue Series method.

Parameters
[in]kWavenumber, in rad/km
[in]h_1__kmHeight of the lower antenna, in km
[in]h_2__kmHeight of the higher antenna, in km
[in]nuIntermediate value, pow(a_e__km * k / 2.0, THIRD);
[in]theta__radAngular distance of path, in radians
[in]qIntermediate value -j*nu*delta
Returns
Normalized field strength in mV/m

◆ ValidateInput()

ReturnCode ITS::Propagation::LFMF::ValidateInput ( const double h_tx__meter,
const double h_rx__meter,
const double f__mhz,
const double P_tx__watt,
const double N_s,
const double d__km,
const double epsilon,
const double sigma )

Validate that model input values are within valid ranges.

Parameters
[in]h_tx__meterHeight of the transmitter, in meters
[in]h_rx__meterHeight of the receiver, in meters
[in]f__mhzFrequency, in MHz
[in]P_tx__wattTransmitter power, in watts
[in]N_sSurface refractivity, in N-Units
[in]d__kmPath distance, in km
[in]epsilonRelative permittivity
[in]sigmaConductivity, in siemens per meter
Returns
Return code

◆ ValidatePolarization()

ReturnCode ITS::Propagation::LFMF::ValidatePolarization ( const Polarization pol)

Perform input Polarization validation.

Parameters
[in]polPolarization
Returns
Return code

◆ WiRoot()

std::complex< double > ITS::Propagation::LFMF::WiRoot ( const int i,
std::complex< double > & DWi,
const std::complex< double > q,
std::complex< double > & Wi,
const AiryKind kind,
const AiryScaling scaling )

Finds the roots to the equation \( Wi'(ti) - q*Wi(ti) = 0 \).

The parameter i selects the \(i\)-th root of the equation. The function \( Wi(ti) \) is the "Airy function of the third kind" as defined by Hufford [1] and Wait. The root is found by iteration starting from a real root.

Note
Although roots that are found for \( w_1 \) (Wait) and \( \mathrm{Wi}^{(2)} \) (Hufford) will be equal, and the roots found for \( w_2 \) (Wait) and \( \mathrm{Wi}^{(1)} \) (Hufford) will be equal, the return values for Wi and DWi will not be the same. The input parameters for kind and scale are used here as they are in Airy() for consistency.
Parameters
[in]iThe \( i \)-th complex root of \( Wi'^{(2)}(ti) - q*Wi^{(2)}(ti) \), starting with 1.
[in]qIntermediate value: \( -j \nu \delta \)
[in]kindKind of Airy function to use, either WONE or WTWO
[in]scalingType of scaling to use, either HUFFORD or WAIT
[out]DWiDerivative of "Airy function of the third kind" \( Wi'^{(2)}(ti) \)
[out]Wi"Airy function of the third kind" \( Wi^{(2)}(ti) \)
Returns
The \( i \)-th complex root of the "Airy function of the third kind"
Exceptions
std::invalid_argumentIf the values provided for i, kind, or scaling are not valid for this function.
std::runtime_errorIf the root finding algorithm fails to converge.

References

  • "Airy Functions of the third kind" are found in equation 38 of NTIA Report 87-219 "A General Theory of Radio Propagation through a Stratified Atmosphere", George Hufford, July 1987.
See also
ITS::Propagation::LFMF::AiryKind
ITS::Propagation::LFMF::AiryScaling
ITS::Propagation::LFMF::Airy

◆ wofz()

std::complex< double > ITS::Propagation::LFMF::wofz ( const std::complex< double > z)

This function computes the Faddeeva function \( W(z) = e^{-z^2} \mathrm{erfc}(-iz) \).

Given a complex input argument \( z \), this function computes the value of the above equation, in which \(\mathrm{erfc}\) is the complex complementary error function and \( i \) is \( \sqrt{-1} \).

The basis for this function is Algorithm 680, Collected Algorithms from ACM, (reference provided below). This version of the function accepts a single complex input argument z and returns a single complex output. The following note is restated from the original implementation's description:

Note
The accuracy of the algorithm for \( z \) in the 1st and 2nd quadrant is 14 significant digits; in the 3rd and 4th it is 13 significant digits outside a circular region with radius 0.126 around a zero of the function.
Parameters
[in]zInput argument
Returns
The desired \( W(z) \) function calculated at z

Lineage

  • The original FORTRAN implementation was translated to C/C++ by I. Stevanovic (OFCOM CH).
  • Direct comparisons of double values with == were removed by C. Heroy, who implemented AlmostEqualRelative().

References

Privacy Policy FOIA Accessibility Information Quality