Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve internal error handling, add unit tests for WiRoot and Airy #11

Open
wants to merge 24 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
35ebcf1
Shorten enum name for AiryKind and AiryScaling
aromanielloNTIA Jan 14, 2025
3fe6179
Convert enums to enum classes, always use namespace
aromanielloNTIA Jan 14, 2025
bedb701
Throw std::invalid_argument for invalid inputs
aromanielloNTIA Jan 14, 2025
a1e04de
Fixes for use of enum class
aromanielloNTIA Jan 14, 2025
a9453fc
Cleanup Airy
aromanielloNTIA Jan 14, 2025
5c40c55
docs formatting
aromanielloNTIA Jan 14, 2025
bee0311
Throw invalid_argument exception for bad inputs
aromanielloNTIA Jan 14, 2025
552148b
Throw range_error when N is out of range
aromanielloNTIA Jan 14, 2025
a951b7e
Remove endl from error message text
aromanielloNTIA Jan 14, 2025
208e58b
Add unit tests for WiRoot
aromanielloNTIA Jan 15, 2025
5e2efe7
Throw runtime error if root finding fails
aromanielloNTIA Jan 15, 2025
d22397c
Expand WiRoot test coverage
aromanielloNTIA Jan 15, 2025
3221eaa
Make LFMF a thin wrapper around LFMF_CPP
aromanielloNTIA Jan 15, 2025
0ca63a0
Update ValidationPolarization declaration
aromanielloNTIA Jan 15, 2025
fec8022
Use C++ entrypoint and types in driver
aromanielloNTIA Jan 15, 2025
b8d32d3
Improve test fixture use, remove invalid test cases
aromanielloNTIA Jan 15, 2025
dc6c1fd
Add WiRoot tests to CMakeLists.txt
aromanielloNTIA Jan 15, 2025
65ffde9
Fix file name
aromanielloNTIA Jan 15, 2025
4b00a14
Add documentation
aromanielloNTIA Jan 15, 2025
1a3bf33
Make test fixture setup protected
aromanielloNTIA Jan 15, 2025
7f634d7
Allow AIRYD and BAIRYD
aromanielloNTIA Jan 15, 2025
572c9e8
Clarify usage of `scaling`
aromanielloNTIA Jan 15, 2025
62159a6
Add tests for Airy
aromanielloNTIA Jan 15, 2025
ae653ae
Loosen tolerances for cross-platform testing
aromanielloNTIA Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/include/Structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct LFMFParams {
double d__km; /**< Path distance, in km */
double epsilon; /**< Relative permittivity */
double sigma; /**< Conductivity, in siemens per meter */
int pol; /**< Polarization, 0 = Horizontal, 1 = Vertical */
ITS::Propagation::LFMF::Polarization pol; /**< Polarization (enum) */
};

/** Key names for LFMF Model input file parameters */
Expand Down
14 changes: 9 additions & 5 deletions app/src/LFMFModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const std::string LFMFInputKeys::pol = "pol";
******************************************************************************/
ReturnCode CallLFMFModel(LFMFParams &lfmf_params, Result &result) {
ReturnCode rtn;
rtn = LFMF(
rtn = LFMF_CPP(
lfmf_params.h_tx__meter,
lfmf_params.h_rx__meter,
lfmf_params.f__mhz,
Expand Down Expand Up @@ -94,9 +94,13 @@ DrvrReturnCode
if (rtn == DRVRERR__PARSE)
rtn = DRVRERR__PARSE_SIGMA;
} else if (key.compare(LFMFInputKeys::pol) == 0) {
rtn = ParseInteger(value, lfmf_params.pol);
if (rtn == DRVRERR__PARSE)
int pol_int;
rtn = ParseInteger(value, pol_int);
if (rtn == DRVRERR__PARSE) {
rtn = DRVRERR__PARSE_POLARIZATION;
} else {
lfmf_params.pol = static_cast<Polarization>(pol_int);
}
} else {
std::cerr << "Unknown parameter: " << key << std::endl;
rtn = DRVRERR__PARSE;
Expand Down Expand Up @@ -143,7 +147,7 @@ void WriteLFMFInputs(std::ofstream &fp, const LFMFParams &params) {
fp PRINT LFMFInputKeys::d__km SETW13 params.d__km << "[km]";
fp PRINT LFMFInputKeys::epsilon SETW13 params.epsilon;
fp PRINT LFMFInputKeys::sigma SETW13 params.sigma;
fp PRINT LFMFInputKeys::pol SETW13 params.pol
fp PRINT LFMFInputKeys::pol SETW13 static_cast<int>(params.pol)
<< "[0 = Horizontal, 1 = Vertical]";
}

Expand All @@ -161,6 +165,6 @@ void WriteLFMFOutputs(std::ofstream &fp, const Result &result) {
fp PRINT "Received power" SETW13 std::fixed << std::setprecision(2)
<< result.P_rx__dbm << "[dB]";
fp PRINT "Solution method" SETW13 std::fixed
<< std::setprecision(0) << result.method
<< std::setprecision(0) << static_cast<int>(result.method)
<< "[0 = Flat earth with curve correction, 1 = Residue series]";
}
22 changes: 10 additions & 12 deletions include/LFMF.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ namespace LFMF {
// Enums

/** Valid RF polarizations for use of this model */
enum Polarization {
enum class Polarization {
HORIZONTAL = 0, /**< Horizontal polarization */
VERTICAL = 1, /**< Vertical polarization */
};

/** Solution method used to generate model result */
enum SolutionMethod {
enum class SolutionMethod {
FLAT_EARTH_CURVE, /**< Flat earth curve method */
RESIDUE_SERIES, /**< Residue series method */
};
Expand All @@ -49,10 +49,10 @@ enum SolutionMethod {
* the same as Wait's @f$ w_2 @f$ and @f$ w_1 @f$.
* @see ITS::Propagation::LFMF::Airy
* @see ITS::Propagation::LFMF::WiRoot
* @see ITS::Propagation::LFMF::AiryFunctionScaling
* @see ITS::Propagation::LFMF::AiryScaling
******************************************************************************/
// clang-format off
enum AiryFunctionKind {
enum class AiryKind {
AIRY = 1, /**< Airy function of the first kind, @f$ \mathrm{Ai}(x) @f$ */
AIRYD, /**< Derivative of `AIRY`, @f$ \mathrm{Ai}'(x) @f$ */
BAIRY, /**< Airy function of the second kind, @f$ \mathrm{Bi}(x) @f$ */
Expand All @@ -72,9 +72,9 @@ enum AiryFunctionKind {
*
* @see ITS::Propagation::LFMF::Airy
* @see ITS::Propagation::LFMF::WiRoot
* @see ITS::Propagation::LFMF::AiryFunctionKind
* @see ITS::Propagation::LFMF::AiryKind
******************************************************************************/
enum AiryFunctionScaling {
enum class AiryScaling {
HUFFORD, /**< Use Hufford scaling */
WAIT, /**< Use Wait scaling */
NONE, /**< No Scaling */
Expand Down Expand Up @@ -175,17 +175,15 @@ double ResidueSeries(
);
std::complex<double> wofz(const std::complex<double> z);
std::complex<double> Airy(
const std::complex<double> Z,
const AiryFunctionKind kind,
const AiryFunctionScaling scaling
const std::complex<double> Z, const AiryKind kind, const AiryScaling scaling
);
std::complex<double> WiRoot(
const int i,
std::complex<double> &DWi,
const std::complex<double> q,
std::complex<double> &Wi,
const AiryFunctionKind kind,
const AiryFunctionScaling scaling
const AiryKind kind,
const AiryScaling scaling
);
ReturnCode ValidateInput(
const double h_tx__meter,
Expand All @@ -197,7 +195,7 @@ ReturnCode ValidateInput(
const double epsilon,
const double sigma
);
ReturnCode ValidatePolarization(const int pol);
ReturnCode ValidatePolarization(const Polarization pol);
bool AlmostEqualRelative(
const double A, const double B, const double maxRelDiff = DBL_EPSILON
);
Expand Down
Loading
Loading