KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_twistedpair.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// Cat5e-style polyethylene-jacketed copper pair. AWG 24 conductor (0.511 mm) under a
40// 0.245 mm PE sheath (Dout = 1.0 mm), 49 twists/m. Individual tests override twist,
41// dielectric, and frequency.
42void SetCat5eLike( TWISTEDPAIR& aCalc )
43{
44 aCalc.SetParameter( TCP::EPSILONR, 2.3 );
45 aCalc.SetParameter( TCP::TAND, 0.0 );
46 aCalc.SetParameter( TCP::SIGMA, 5.8e7 );
47 aCalc.SetParameter( TCP::MURC, 1.0 );
50 aCalc.SetParameter( TCP::PHYS_LEN, 1.000 * TC::UNIT_M );
52 aCalc.SetParameter( TCP::Z0, 0.0 );
53 aCalc.SetParameter( TCP::ANG_L, 0.0 );
56}
57} // namespace
58
59
60BOOST_AUTO_TEST_SUITE( TwistedPairCalculations )
61
62
63// Cat5e-geometry pair using the Lefferson 1971 model with theta in degrees. At 49
64// twists/m and a 1.0 mm outer diameter the pitch angle is only ~8.75 deg, so the
65// twist raises epsEff from 1.325 to ~1.395 and drops Z0 from ~134.5 to ~131.2.
66// Real Cat5e reaches 100 ohm through tighter pair pitch and thinner insulation than
67// what this reference geometry exercises. We pin the math-core value so future
68// Lefferson refactors are caught immediately.
69BOOST_AUTO_TEST_CASE( Cat5eReferenceAnalysis )
70{
71 TWISTEDPAIR calc;
72 SetCat5eLike( calc );
73
74 calc.Analyse();
75
76 auto& results = calc.GetAnalysisResults();
77
78 const double Z0 = results.at(TCP::Z0).first;
79 BOOST_TEST( std::isfinite( Z0 ) );
80 BOOST_TEST( Z0 > 0.0 );
81 BOOST_TEST( Z0 == 131.16, boost::test_tools::tolerance( 0.01 ) );
82
83 const double epsEff = results.at(TCP::EPSILON_EFF).first;
84 BOOST_TEST( epsEff == 1.3947, boost::test_tools::tolerance( 0.01 ) );
85}
86
87
88// Air-spaced parallel wires with T=0 collapse to the untwisted TEM two-wire line and must
89// match (ZF0/π)·acosh(Dout/Din) exactly.
90BOOST_AUTO_TEST_CASE( DegenerateAirSpacedParallelWires )
91{
92 TWISTEDPAIR calc;
93 SetCat5eLike( calc );
94 calc.SetParameter( TCP::EPSILONR, 1.0 );
97
98 calc.Analyse();
99
100 auto& results = calc.GetAnalysisResults();
101
102 const double Din = 0.511e-3;
103 const double Dout = 1.000e-3;
104 const double expected = ( TC::ZF0 / M_PI ) * std::acosh( Dout / Din );
105
106 BOOST_TEST( results.at(TCP::Z0).first == expected, boost::test_tools::tolerance( 1e-9 ) );
107 BOOST_TEST( results.at(TCP::EPSILON_EFF).first == 1.0, boost::test_tools::tolerance( 1e-12 ) );
108}
109
110
111// Dielectric loss scales linearly with tan δ. Zero tan δ gives zero dielectric loss.
112BOOST_AUTO_TEST_CASE( DielectricLossScalesWithTanDelta )
113{
114 TWISTEDPAIR calc;
115 SetCat5eLike( calc );
116 calc.SetParameter( TCP::TAND, 0.0 );
117
118 calc.Analyse();
119 const double loss_zero = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
120 BOOST_TEST( loss_zero == 0.0, boost::test_tools::tolerance( 1e-12 ) );
121
122 calc.SetParameter( TCP::TAND, 0.001 );
123 calc.Analyse();
124 const double loss_lo = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
125 BOOST_TEST( std::isfinite( loss_lo ) );
126 BOOST_TEST( loss_lo > 0.0 );
127
128 // Double tan δ → loss_d doubles (α_d is linear in tan δ).
129 calc.SetParameter( TCP::TAND, 0.002 );
130 calc.Analyse();
131 const double loss_hi = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
132 BOOST_TEST( loss_hi == 2.0 * loss_lo, boost::test_tools::tolerance( 1e-9 ) );
133}
134
135
136// Round-trip synthesis. Set Z0 target, solve for Dout, re-analyse, confirm Z0 hits.
137BOOST_AUTO_TEST_CASE( SynthesisRoundTripSolveForDout )
138{
139 TWISTEDPAIR calc;
140 SetCat5eLike( calc );
141
142 // Ask for a 100 ohm pair. At 1.0 mm Dout the model sits near 131 ohm, so the
143 // solver will shrink Dout (expect ~0.78 mm) to hit the target.
144 constexpr double Z0_target = 100.0;
145 calc.SetParameter( TCP::Z0, Z0_target );
146 calc.SetParameter( TCP::ANG_L, M_PI / 2.0 );
147
150
151 const double Dout_synth = calc.GetParameter( TCP::PHYS_DIAM_OUT );
152 BOOST_TEST( std::isfinite( Dout_synth ) );
153 BOOST_TEST( Dout_synth > 0.0 );
154
155 // Re-analyse and verify Z0 is within 1 Ω of the 100 Ω target.
156 calc.SetParameter( TCP::Z0, 0.0 );
157 calc.Analyse();
158 const double Z0_check = calc.GetAnalysisResults()[TCP::Z0].first;
159 BOOST_TEST( Z0_check == Z0_target, boost::test_tools::tolerance( 1.0 / Z0_target ) );
160}
161
162
163// Increasing the twist count raises the pitch angle, which raises the twist weight
164// on (epsr - epsr_env) and therefore raises epsEff while lowering Z0. Monotonic in
165// both directions for epsr > epsr_env.
166BOOST_AUTO_TEST_CASE( TwistRaisesEpsEffLowersZ0 )
167{
168 TWISTEDPAIR calc;
169 SetCat5eLike( calc );
170
172 calc.Analyse();
173 const double eps0 = calc.GetAnalysisResults()[TCP::EPSILON_EFF].first;
174 const double z0_0 = calc.GetAnalysisResults()[TCP::Z0].first;
175
177 calc.Analyse();
178 const double eps49 = calc.GetAnalysisResults()[TCP::EPSILON_EFF].first;
179 const double z0_49 = calc.GetAnalysisResults()[TCP::Z0].first;
180
181 calc.SetParameter( TCP::TWISTEDPAIR_TWIST, 1000.0 );
182 calc.Analyse();
183 const double eps1000 = calc.GetAnalysisResults()[TCP::EPSILON_EFF].first;
184 const double z0_1000 = calc.GetAnalysisResults()[TCP::Z0].first;
185
186 BOOST_TEST( eps49 > eps0 );
187 BOOST_TEST( eps1000 > eps49 );
188 BOOST_TEST( z0_49 < z0_0 );
189 BOOST_TEST( z0_1000 < z0_49 );
190}
191
192
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.
Twisted-pair transmission line calculation.
bool Synthesize(SYNTHESIZE_OPTS aOpts) override
Synthesize Din or Dout to hit the target Z0. Length is recomputed from ANG_L.
void SetSynthesizeTarget(TRANSLINE_PARAMETERS aTarget) override
Choose which geometry parameter will be solved for during synthesis.
void Analyse() override
Analyse pair geometry to output Z0, electrical length, losses, skin depth, εeff.
TRANSLINE_PARAMETERS TCP
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_TEST(contains==c.ExpectedContains)
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
BOOST_AUTO_TEST_CASE(Cat5eReferenceAnalysis)
#define M_PI
TRANSLINE_PARAMETERS
All possible parameters used (as inputs or outputs) by the transmission line calculations.