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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <cmath>
27
31
32
33namespace TC = TRANSLINE_CALCULATIONS;
35
36
37namespace
38{
39// WR-90 geometry and copper-on-air defaults. Individual tests override FREQUENCY and,
40// where relevant, EPSILONR / TAND.
41void SetWR90( RECTWAVEGUIDE& aCalc )
42{
43 aCalc.SetParameter( TCP::EPSILONR, 1.0 );
44 aCalc.SetParameter( TCP::TAND, 0.0 );
45 aCalc.SetParameter( TCP::SIGMA, 5.8e7 );
46 aCalc.SetParameter( TCP::MUR, 1.0 );
47 aCalc.SetParameter( TCP::MURC, 1.0 );
48 aCalc.SetParameter( TCP::PHYS_WIDTH, 22.86 * TC::UNIT_MM ); // a = 0.9"
49 aCalc.SetParameter( TCP::PHYS_S, 10.16 * TC::UNIT_MM ); // b = 0.4"
50 aCalc.SetParameter( TCP::PHYS_LEN, 100.0 * TC::UNIT_MM );
51 aCalc.SetParameter( TCP::FREQUENCY, 10.0e9 );
52 aCalc.SetParameter( TCP::Z0, 0.0 );
53 aCalc.SetParameter( TCP::ANG_L, 0.0 );
54}
55} // namespace
56
57
58BOOST_AUTO_TEST_SUITE( RectWaveguideCalculations )
59
60
61// WR-90 air-filled at 10 GHz. TE10 cutoff c/(2a) ≈ 6.557 GHz. Fictive-voltage Z0 ≈ 499.4 Ω.
62// Conductor loss on copper per the Ramo/Whinnery/Van Duzer summation is ~0.11 dB/m; allow
63// ±30 % because the task pins an approximate value, not a specific textbook cell.
64BOOST_AUTO_TEST_CASE( WR90AirFilledReference )
65{
66 RECTWAVEGUIDE calc;
67 SetWR90( calc );
68
69 calc.Analyse();
70
71 auto& results = calc.GetAnalysisResults();
72
73 const double fc = results.at(TCP::CUTOFF_FREQUENCY).first;
74 BOOST_TEST( fc == 6.557e9, boost::test_tools::tolerance( 0.005 ) );
75
76 const double Z0 = results.at(TCP::Z0).first;
77 BOOST_TEST( Z0 == 500.0, boost::test_tools::tolerance( 20.0 / 500.0 ) );
78
79 // 100 mm of WR-90 on copper: α_c * L should land near 11 mdB (0.11 dB/m * 0.1 m).
80 const double loss_c = results.at(TCP::LOSS_CONDUCTOR).first;
81 BOOST_TEST( std::isfinite( loss_c ) );
82 BOOST_TEST( loss_c > 0.0 );
83 BOOST_TEST( loss_c == 0.011, boost::test_tools::tolerance( 0.30 ) );
84}
85
86
87// Below TE10 cutoff: TE mode string empty, TM string empty.
88// Above TE10 cutoff: TE string starts with the dominant "H(1,0) " token.
89BOOST_AUTO_TEST_CASE( TE10ModeString )
90{
91 RECTWAVEGUIDE calc;
92 SetWR90( calc );
93
94 // f = 4 GHz is below TE10 cutoff (~6.56 GHz). Both mode strings must be empty.
95 calc.SetParameter( TCP::FREQUENCY, 4.0e9 );
96 calc.Analyse();
97 BOOST_TEST( calc.GetTEModes() == std::string( "" ) );
98 BOOST_TEST( calc.GetTMModes() == std::string( "" ) );
99
100 // f = 10 GHz propagates TE10 only. Legacy format: "H(m,n) " with the dominant mode
101 // listed first (m-major order starting at m=0).
102 calc.SetParameter( TCP::FREQUENCY, 10.0e9 );
103 calc.Analyse();
104 const std::string teModes = calc.GetTEModes();
105 BOOST_TEST( teModes.rfind( "H(1,0) ", 0 ) == 0u );
106 BOOST_TEST( calc.GetTMModes() == std::string( "" ) );
107}
108
109
110// TE10 dielectric-filled waveguide, lossy dielectric. α_d must be finite, positive, and
111// scale monotonically with tan δ (doubling tan δ doubles α_d for fixed k and beta).
112BOOST_AUTO_TEST_CASE( DielectricLossIsFiniteAndPositive )
113{
114 RECTWAVEGUIDE calc;
115 SetWR90( calc );
116 calc.SetParameter( TCP::EPSILONR, 2.1 );
117 calc.SetParameter( TCP::TAND, 0.001 );
118 calc.SetParameter( TCP::FREQUENCY, 10.0e9 );
119
120 calc.Analyse();
121
122 const double loss_d_lo = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
123 BOOST_TEST( std::isfinite( loss_d_lo ) );
124 BOOST_TEST( loss_d_lo > 0.0 );
125
126 // Double tan δ → loss_d doubles (α_d is linear in tan δ).
127 calc.SetParameter( TCP::TAND, 0.002 );
128 calc.Analyse();
129 const double loss_d_hi = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
130 BOOST_TEST( loss_d_hi == 2.0 * loss_d_lo, boost::test_tools::tolerance( 1e-9 ) );
131}
132
133
134// Round-trip synthesis. Set Z0 target at 500 Ω, solve for a, re-analyse, confirm Z0 hits.
135BOOST_AUTO_TEST_CASE( SynthesisRoundTripSolveForA )
136{
137 RECTWAVEGUIDE calc;
138 SetWR90( calc );
139 calc.SetParameter( TCP::Z0, 500.0 );
140 calc.SetParameter( TCP::ANG_L, M_PI / 2.0 );
141 calc.SetParameter( TCP::FREQUENCY, 10.0e9 );
142
145
146 const double a_synth = calc.GetParameter( TCP::PHYS_WIDTH );
147 BOOST_TEST( std::isfinite( a_synth ) );
148 BOOST_TEST( a_synth > 0.0 );
149
150 // Re-analyse and verify Z0 sits within 1 Ω of the 500 Ω target.
151 calc.Analyse();
152 const double Z0_check = calc.GetAnalysisResults()[TCP::Z0].first;
153 BOOST_TEST( Z0_check == 500.0, boost::test_tools::tolerance( 1.0 / 500.0 ) );
154}
155
156
157// High-frequency excitation of WR-90. At 40 GHz, cutoff frequencies:
158// TE10 ≈ 6.56 GHz
159// TE20 ≈ 13.12 GHz
160// TE01 ≈ 14.76 GHz
161// TE11 = TM11 ≈ 16.16 GHz
162// ... many more propagate below 40 GHz.
163// The TE mode list must enumerate several tokens; TM must enumerate at least one.
164BOOST_AUTO_TEST_CASE( HigherModeListing )
165{
166 RECTWAVEGUIDE calc;
167 SetWR90( calc );
168 calc.SetParameter( TCP::FREQUENCY, 40.0e9 );
169
170 calc.Analyse();
171
172 const std::string teModes = calc.GetTEModes();
173 const std::string tmModes = calc.GetTMModes();
174
175 // TE list must include the dominant and at least the next higher horizontal / vertical
176 // modes; TM list must include the fundamental TM11.
177 BOOST_TEST( teModes.find( "H(1,0)" ) != std::string::npos );
178 BOOST_TEST( teModes.find( "H(2,0)" ) != std::string::npos );
179 BOOST_TEST( teModes.find( "H(0,1)" ) != std::string::npos );
180 BOOST_TEST( teModes.find( "H(1,1)" ) != std::string::npos );
181 BOOST_TEST( tmModes.find( "E(1,1)" ) != std::string::npos );
182}
183
184
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_TEST(contains==c.ExpectedContains)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(WR90AirFilledReference)
#define M_PI
TRANSLINE_PARAMETERS
All possible parameters used (as inputs or outputs) by the transmission line calculations.