KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_rectwaveguide.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <cmath>
23
27
28
29namespace TC = TRANSLINE_CALCULATIONS;
31
32
33namespace
34{
35// WR-90 geometry and copper-on-air defaults. Individual tests override FREQUENCY and,
36// where relevant, EPSILONR / TAND.
37void SetWR90( RECTWAVEGUIDE& aCalc )
38{
39 aCalc.SetParameter( TCP::EPSILONR, 1.0 );
40 aCalc.SetParameter( TCP::TAND, 0.0 );
41 aCalc.SetParameter( TCP::SIGMA, 5.8e7 );
42 aCalc.SetParameter( TCP::MUR, 1.0 );
43 aCalc.SetParameter( TCP::MURC, 1.0 );
44 aCalc.SetParameter( TCP::PHYS_WIDTH, 22.86 * TC::UNIT_MM ); // a = 0.9"
45 aCalc.SetParameter( TCP::PHYS_S, 10.16 * TC::UNIT_MM ); // b = 0.4"
46 aCalc.SetParameter( TCP::PHYS_LEN, 100.0 * TC::UNIT_MM );
47 aCalc.SetParameter( TCP::FREQUENCY, 10.0e9 );
48 aCalc.SetParameter( TCP::Z0, 0.0 );
49 aCalc.SetParameter( TCP::ANG_L, 0.0 );
50}
51} // namespace
52
53
54BOOST_AUTO_TEST_SUITE( RectWaveguideCalculations )
55
56
57// WR-90 air-filled at 10 GHz. TE10 cutoff c/(2a) ≈ 6.557 GHz. Fictive-voltage Z0 ≈ 499.4 Ω.
58// Conductor loss on copper per the Ramo/Whinnery/Van Duzer summation is ~0.11 dB/m; allow
59// ±30 % because the task pins an approximate value, not a specific textbook cell.
60BOOST_AUTO_TEST_CASE( WR90AirFilledReference )
61{
62 RECTWAVEGUIDE calc;
63 SetWR90( calc );
64
65 calc.Analyse();
66
67 auto& results = calc.GetAnalysisResults();
68
69 const double fc = results.at(TCP::CUTOFF_FREQUENCY).first;
70 BOOST_TEST( fc == 6.557e9, boost::test_tools::tolerance( 0.005 ) );
71
72 const double Z0 = results.at(TCP::Z0).first;
73 BOOST_TEST( Z0 == 500.0, boost::test_tools::tolerance( 20.0 / 500.0 ) );
74
75 // 100 mm of WR-90 on copper: α_c * L should land near 11 mdB (0.11 dB/m * 0.1 m).
76 const double loss_c = results.at(TCP::LOSS_CONDUCTOR).first;
77 BOOST_TEST( std::isfinite( loss_c ) );
78 BOOST_TEST( loss_c > 0.0 );
79 BOOST_TEST( loss_c == 0.011, boost::test_tools::tolerance( 0.30 ) );
80}
81
82
83// Below TE10 cutoff: TE mode string empty, TM string empty.
84// Above TE10 cutoff: TE string starts with the dominant "H(1,0) " token.
85BOOST_AUTO_TEST_CASE( TE10ModeString )
86{
87 RECTWAVEGUIDE calc;
88 SetWR90( calc );
89
90 // f = 4 GHz is below TE10 cutoff (~6.56 GHz). Both mode strings must be empty.
91 calc.SetParameter( TCP::FREQUENCY, 4.0e9 );
92 calc.Analyse();
93 BOOST_TEST( calc.GetTEModes() == std::string( "" ) );
94 BOOST_TEST( calc.GetTMModes() == std::string( "" ) );
95
96 // f = 10 GHz propagates TE10 only. Legacy format: "H(m,n) " with the dominant mode
97 // listed first (m-major order starting at m=0).
98 calc.SetParameter( TCP::FREQUENCY, 10.0e9 );
99 calc.Analyse();
100 const std::string teModes = calc.GetTEModes();
101 BOOST_TEST( teModes.rfind( "H(1,0) ", 0 ) == 0u );
102 BOOST_TEST( calc.GetTMModes() == std::string( "" ) );
103}
104
105
106// TE10 dielectric-filled waveguide, lossy dielectric. α_d must be finite, positive, and
107// scale monotonically with tan δ (doubling tan δ doubles α_d for fixed k and beta).
108BOOST_AUTO_TEST_CASE( DielectricLossIsFiniteAndPositive )
109{
110 RECTWAVEGUIDE calc;
111 SetWR90( calc );
112 calc.SetParameter( TCP::EPSILONR, 2.1 );
113 calc.SetParameter( TCP::TAND, 0.001 );
114 calc.SetParameter( TCP::FREQUENCY, 10.0e9 );
115
116 calc.Analyse();
117
118 const double loss_d_lo = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
119 BOOST_TEST( std::isfinite( loss_d_lo ) );
120 BOOST_TEST( loss_d_lo > 0.0 );
121
122 // Double tan δ → loss_d doubles (α_d is linear in tan δ).
123 calc.SetParameter( TCP::TAND, 0.002 );
124 calc.Analyse();
125 const double loss_d_hi = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
126 BOOST_TEST( loss_d_hi == 2.0 * loss_d_lo, boost::test_tools::tolerance( 1e-9 ) );
127}
128
129
130// Round-trip synthesis. Set Z0 target at 500 Ω, solve for a, re-analyse, confirm Z0 hits.
131BOOST_AUTO_TEST_CASE( SynthesisRoundTripSolveForA )
132{
133 RECTWAVEGUIDE calc;
134 SetWR90( calc );
135 calc.SetParameter( TCP::Z0, 500.0 );
136 calc.SetParameter( TCP::ANG_L, M_PI / 2.0 );
137 calc.SetParameter( TCP::FREQUENCY, 10.0e9 );
138
141
142 const double a_synth = calc.GetParameter( TCP::PHYS_WIDTH );
143 BOOST_TEST( std::isfinite( a_synth ) );
144 BOOST_TEST( a_synth > 0.0 );
145
146 // Re-analyse and verify Z0 sits within 1 Ω of the 500 Ω target.
147 calc.Analyse();
148 const double Z0_check = calc.GetAnalysisResults()[TCP::Z0].first;
149 BOOST_TEST( Z0_check == 500.0, boost::test_tools::tolerance( 1.0 / 500.0 ) );
150}
151
152
153// High-frequency excitation of WR-90. At 40 GHz, cutoff frequencies:
154// TE10 ≈ 6.56 GHz
155// TE20 ≈ 13.12 GHz
156// TE01 ≈ 14.76 GHz
157// TE11 = TM11 ≈ 16.16 GHz
158// ... many more propagate below 40 GHz.
159// The TE mode list must enumerate several tokens; TM must enumerate at least one.
160BOOST_AUTO_TEST_CASE( HigherModeListing )
161{
162 RECTWAVEGUIDE calc;
163 SetWR90( calc );
164 calc.SetParameter( TCP::FREQUENCY, 40.0e9 );
165
166 calc.Analyse();
167
168 const std::string teModes = calc.GetTEModes();
169 const std::string tmModes = calc.GetTMModes();
170
171 // TE list must include the dominant and at least the next higher horizontal / vertical
172 // modes; TM list must include the fundamental TM11.
173 BOOST_TEST( teModes.find( "H(1,0)" ) != std::string::npos );
174 BOOST_TEST( teModes.find( "H(2,0)" ) != std::string::npos );
175 BOOST_TEST( teModes.find( "H(0,1)" ) != std::string::npos );
176 BOOST_TEST( teModes.find( "H(1,1)" ) != std::string::npos );
177 BOOST_TEST( tmModes.find( "E(1,1)" ) != std::string::npos );
178}
179
180
Rectangular waveguide calculation.
std::string GetTEModes() const
Returns a UI-friendly string enumerating propagating TE_mn modes at the current frequency.
bool Synthesize(SYNTHESIZE_OPTS aOpts) override
Synthesize the broad dimension a from a target Z0. Only PHYS_WIDTH is a valid target.
std::string GetTMModes() const
Returns a UI-friendly string enumerating propagating TM_mn modes at the current frequency.
void Analyse() override
Analyse waveguide geometry to produce Z0, electrical length, loss, and mode cutoffs.
void SetSynthesizeTarget(TRANSLINE_PARAMETERS aTarget) override
Choose which geometry parameter will be solved for during synthesis.
double GetParameter(const TRANSLINE_PARAMETERS aParam) const
Gets the given calculation property.
void SetParameter(const TRANSLINE_PARAMETERS aParam, const double aValue)
Sets the given calculation property.
std::unordered_map< TRANSLINE_PARAMETERS, std::pair< double, TRANSLINE_STATUS > > & GetAnalysisResults()
Gets the output parameters following analysis.
TRANSLINE_PARAMETERS TCP
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST(netlist.find("R_G1 ARM_OUT1 DIE_B R='0.001 / ((SW_STATE)") !=std::string::npos)
BOOST_AUTO_TEST_CASE(WR90AirFilledReference)
#define M_PI
TRANSLINE_PARAMETERS
All possible parameters used (as inputs or outputs) by the transmission line calculations.