Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cpwline.cpp
Go to the documentation of this file.
1 /*
2  * cpwline.cpp - coplanar waveguide line class implementation
3  *
4  * Copyright (C) 2004, 2005 Vincent Habchi, F5RCS <10.50@free.fr>
5  * Copyright (C) 2004, 2005, 2006, 2008 Stefan Jahn <stefan@lkcc.org>
6  *
7  * This is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this package; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  * $Id$
23  *
24  */
25 
26 #if HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #include "component.h"
31 #include "substrate.h"
32 #include "cpwline.h"
33 
34 using namespace qucs;
35 
36 cpwline::cpwline () : circuit (2) {
37  Zl = Er = 0;
38  type = CIR_CPWLINE;
39 }
40 
48 void cpwline::ellipke (nr_double_t arg, nr_double_t &k, nr_double_t &e) {
49  int iMax = 16;
50  if (arg == 1.0) {
51  k = NR_INF; // infinite
52  e = 0;
53  }
54  else if (std::isinf (arg) && arg < 0) {
55  k = 0;
56  e = NR_INF; // infinite
57  }
58  else {
59  nr_double_t a, b, c, f, s, fk = 1, fe = 1, t, da = arg;
60  int i;
61  if (arg < 0) {
62  fk = 1 / qucs::sqrt (1 - arg);
63  fe = qucs::sqrt (1 - arg);
64  da = -arg / (1 - arg);
65  }
66  a = 1;
67  b = qucs::sqrt (1 - da);
68  c = qucs::sqrt (da);
69  f = 0.5;
70  s = f * c * c;
71  for (i = 0; i < iMax; i++) {
72  t = (a + b) / 2;
73  c = (a - b) / 2;
74  b = qucs::sqrt (a * b);
75  a = t;
76  f *= 2;
77  s += f * c * c;
78  if (c / a < NR_EPSI) break;
79  }
80  if (i >= iMax) {
81  k = 0; e = 0;
82  }
83  else {
84  k = M_PI_2 / a;
85  e = M_PI_2 * (1 - s) / a;
86  if (arg < 0) {
87  k *= fk;
88  e *= fe;
89  }
90  }
91  }
92 }
93 
94 /* We need to know only K(k), and if possible KISS. */
95 nr_double_t cpwline::ellipk (nr_double_t k) {
96  nr_double_t r, lost;
97  ellipke (k, r, lost);
98  return r;
99 }
100 
101 /* More or less accurate approximation of K(k)/K'(k). Suggested by
102  publications dealing with coplanar components. */
103 nr_double_t cpwline::ellipa (nr_double_t k) {
104  nr_double_t r, kp;
105  if (k < M_SQRT1_2) {
106  kp = qucs::sqrt (1 - k * k);
107  r = M_PI / qucs::log (2 * (1 + qucs::sqrt (kp)) / (1 - qucs::sqrt (kp)));
108  }
109  else {
110  r = qucs::log (2 * (1 + qucs::sqrt (k)) / (1 - qucs::sqrt (k))) / M_PI;
111  }
112  return r;
113 }
114 
115 void cpwline::initSP (void) {
116  // allocate S-parameter matrix
117  allocMatrixS ();
118  // pre-compute propagation factors
119  initPropagation ();
120 }
121 
123  // get properties of substrate and coplanar line
124  nr_double_t W = getPropertyDouble ("W");
125  nr_double_t s = getPropertyDouble ("S");
127  nr_double_t er = subst->getPropertyDouble ("er");
128  nr_double_t h = subst->getPropertyDouble ("h");
129  nr_double_t t = subst->getPropertyDouble ("t");
130  int backMetal = !strcmp (getPropertyString ("Backside"), "Metal");
131  int approx = !strcmp (getPropertyString ("Approx"), "yes");
132 
133  tand = subst->getPropertyDouble ("tand");
134  rho = subst->getPropertyDouble ("rho");
135  len = getPropertyDouble ("L");
136 
137  // other local variables (quasi-static constants)
138  nr_double_t k1, kk1, kpk1, k2, k3, q1, q2, q3 = 0, qz, er0 = 0;
139 
140  // compute the necessary quasi-static approx. (K1, K3, er(0) and Z(0))
141  k1 = W / (W + s + s);
142  kk1 = ellipk (k1);
143  kpk1 = ellipk (qucs::sqrt (1 - k1 * k1));
144  if (approx) {
145  q1 = ellipa (k1);
146  } else {
147  q1 = kk1 / kpk1;
148  }
149 
150  // backside is metal
151  if (backMetal) {
152  k3 = qucs::tanh ((M_PI / 4) * (W / h)) / qucs::tanh ((M_PI / 4) * (W + s + s) / h);
153  if (approx) {
154  q3 = ellipa (k3);
155  } else {
156  q3 = ellipk (k3) / ellipk (qucs::sqrt (1 - k3 * k3));
157  }
158  qz = 1 / (q1 + q3);
159  er0 = 1 + q3 * qz * (er - 1);
160  zl_factor = Z0 / 2 * qz;
161  }
162  // backside is air
163  else {
164  k2 = qucs::sinh ((M_PI / 4) * (W / h)) / qucs::sinh ((M_PI / 4) * (W + s + s) / h);
165  if (approx) {
166  q2 = ellipa (k2);
167  } else {
168  q2 = ellipk (k2) / ellipk (qucs::sqrt (1 - k2 * k2));
169  }
170  er0 = 1 + (er - 1) / 2 * q2 / q1;
171  zl_factor = Z0 / 4 / q1;
172  }
173 
174  // adds effect of strip thickness
175  if (t > 0) {
176  nr_double_t d, se, We, ke, qe;
177  d = (t * 1.25 / M_PI) * (1 + qucs::log (4 * M_PI * W / t));
178  se = s - d;
179  We = W + d;
180 
181  // modifies k1 accordingly (k1 = ke)
182  ke = We / (We + se + se); // ke = k1 + (1 - k1 * k1) * d / 2 / s;
183  if (approx) {
184  qe = ellipa (ke);
185  } else {
186  qe = ellipk (ke) / ellipk (qucs::sqrt (1 - ke * ke));
187  }
188  // backside is metal
189  if (backMetal) {
190  qz = 1 / (qe + q3);
191  er0 = 1 + q3 * qz * (er - 1);
192  zl_factor = Z0 / 2 * qz;
193  }
194  // backside is air
195  else {
196  zl_factor = Z0 / 4 / qe;
197  }
198 
199  // modifies er0 as well
200  er0 = er0 - (0.7 * (er0 - 1) * t / s) / (q1 + (0.7 * t / s));
201  }
202 
203  // pre-compute square roots
204  sr_er = qucs::sqrt (er);
205  sr_er0 = qucs::sqrt (er0);
206 
207  // cut-off frequency of the TE0 mode
208  fte = (C0 / 4) / (h * qucs::sqrt (er - 1));
209 
210  // dispersion factor G
211  nr_double_t p = qucs::log (W / h);
212  nr_double_t u = 0.54 - (0.64 - 0.015 * p) * p;
213  nr_double_t v = 0.43 - (0.86 - 0.54 * p) * p;
214  G = qucs::exp (u * qucs::log (W / s) + v);
215 
216  // loss constant factors (computed only once for efficency sake)
217  nr_double_t ac = 0;
218  if (t > 0) {
219  // equations by GHIONE
220  nr_double_t n = (1 - k1) * 8 * M_PI / (t * (1 + k1));
221  nr_double_t a = W / 2;
222  nr_double_t b = a + s;
223  ac = (M_PI + qucs::log (n * a)) / a + (M_PI + qucs::log (n * b)) / b;
224  }
225  ac_factor = ac / (4 * Z0 * kk1 * kpk1 * (1 - k1 * k1));
226  ac_factor *= qucs::sqrt (M_PI * MU0 * rho); // Rs factor
227  ad_factor = (er / (er - 1)) * tand * M_PI / C0;
228 
229  bt_factor = 2 * M_PI / C0;
230 }
231 
232 void cpwline::calcAB (nr_double_t f, nr_double_t& zl, nr_double_t& al,
233  nr_double_t& bt) {
234  nr_double_t sr_er_f = sr_er0;
235  nr_double_t ac = ac_factor;
236  nr_double_t ad = ad_factor;
237 
238  // by initializing as much as possible outside this function, the
239  // overhead is minimal
240 
241  // add the dispersive effects to er0
242  sr_er_f += (sr_er - sr_er0) / (1 + G * qucs::pow (f / fte, -1.8));
243 
244  // computes impedance
245  zl /= sr_er_f;
246 
247  // for now, the loss are limited to strip losses (no radiation
248  // losses yet) losses in neper/length
249  ad *= f * (sr_er_f - 1 / sr_er_f);
250  ac *= qucs::sqrt (f) * sr_er0;
251 
252  al = ac + ad;
253  bt *= sr_er_f * f;
254 
255  Er = sqr (sr_er_f);
256  Zl = zl;
257 }
258 
259 void cpwline::saveCharacteristics (nr_double_t) {
260  setCharacteristic ("Zl", Zl);
261  setCharacteristic ("Er", Er);
262 }
263 
264 void cpwline::calcSP (nr_double_t frequency) {
265 
266  nr_double_t zl = zl_factor;
267  nr_double_t beta = bt_factor;
268  nr_double_t alpha;
269 
270  calcAB (frequency, zl, alpha, beta);
271 
272  // calculate and set S-parameters
273  nr_double_t z = zl / z0;
274  nr_double_t y = 1 / z;
275  nr_complex_t g = nr_complex_t (alpha, beta);
276  nr_complex_t n = 2.0 * cosh (g * len) + (z + y) * sinh (g * len);
277  nr_complex_t s11 = (z - y) * sinh (g * len) / n;
278  nr_complex_t s21 = 2.0 / n;
279 
280  setS (NODE_1, NODE_1, s11); setS (NODE_2, NODE_2, s11);
281  setS (NODE_1, NODE_2, s21); setS (NODE_2, NODE_1, s21);
282 }
283 
284 /* The function calculates the quasi-static impedance of a coplanar
285  waveguide line and the value of the effective dielectric constant
286  for the given coplanar line and substrate properties. */
287 void cpwline::analyseQuasiStatic (nr_double_t W, nr_double_t s, nr_double_t h,
288  nr_double_t t, nr_double_t er, int backMetal,
289  nr_double_t& ZlEff, nr_double_t& ErEff) {
290 
291  // local variables (quasi-static constants)
292  nr_double_t k1, k2, k3, q1, q2, q3 = 0, qz;
293 
294  ErEff = er;
295  ZlEff = 0;
296 
297  // compute the necessary quasi-static approx. (K1, K3, er(0) and Z(0))
298  k1 = W / (W + s + s);
299  q1 = ellipk (k1) / ellipk (qucs::sqrt (1 - k1 * k1));
300 
301  // backside is metal
302  if (backMetal) {
303  k3 = qucs::tanh ((M_PI / 4) * (W / h)) / qucs::tanh ((M_PI / 4) * (W + s + s) / h);
304  q3 = ellipk (k3) / ellipk (qucs::sqrt (1 - k3 * k3));
305  qz = 1 / (q1 + q3);
306  ErEff = 1 + q3 * qz * (er - 1);
307  ZlEff = Z0 / 2 * qz;
308  }
309  // backside is air
310  else {
311  k2 = qucs::sinh ((M_PI / 4) * (W / h)) / qucs::sinh ((M_PI / 4) * (W + s + s) / h);
312  q2 = ellipk (k2) / ellipk (qucs::sqrt (1 - k2 * k2));
313  ErEff = 1 + (er - 1) / 2 * q2 / q1;
314  ZlEff = Z0 / 4 / q1;
315  }
316 
317  // adds effect of strip thickness
318  if (t > 0) {
319  nr_double_t d, se, We, ke, qe;
320  d = (t * 1.25 / M_PI) * (1 + qucs::log (4 * M_PI * W / t));
321  se = s - d;
322  We = W + d;
323 
324  // modifies k1 accordingly (k1 = ke)
325  ke = We / (We + se + se); // ke = k1 + (1 - k1 * k1) * d / 2 / s;
326  qe = ellipk (ke) / ellipk (qucs::sqrt (1 - ke * ke));
327 
328  // backside is metal
329  if (backMetal) {
330  qz = 1 / (qe + q3);
331  ErEff = 1 + q3 * qz * (er - 1);
332  ZlEff = Z0 / 2 * qz;
333  }
334  // backside is air
335  else {
336  ZlEff = Z0 / 4 / qe;
337  }
338 
339  // modifies ErEff as well
340  ErEff = ErEff - (0.7 * (ErEff - 1) * t / s) / (q1 + (0.7 * t / s));
341  }
342  ErEff = qucs::sqrt (ErEff);
343  ZlEff /= ErEff;
344 }
345 
346 /* This function calculates the frequency dependent value of the
347  effective dielectric constant and the coplanar line impedance for
348  the given frequency. */
349 void cpwline::analyseDispersion (nr_double_t W, nr_double_t s, nr_double_t h,
350  nr_double_t er, nr_double_t ZlEff,
351  nr_double_t ErEff, nr_double_t frequency,
352  nr_double_t& ZlEffFreq,
353  nr_double_t& ErEffFreq) {
354  // local variables
355  nr_double_t fte, G;
356 
357  ErEffFreq = ErEff;
358  ZlEffFreq = ZlEff * ErEff;
359 
360  // cut-off frequency of the TE0 mode
361  fte = (C0 / 4) / (h * qucs::sqrt (er - 1));
362 
363  // dispersion factor G
364  nr_double_t p = qucs::log (W / h);
365  nr_double_t u = 0.54 - (0.64 - 0.015 * p) * p;
366  nr_double_t v = 0.43 - (0.86 - 0.54 * p) * p;
367  G = qucs::exp (u * qucs::log (W / s) + v);
368 
369  // add the dispersive effects to er0
370  ErEffFreq += (qucs::sqrt (er) - ErEff) / (1 + G * qucs::pow (frequency / fte, -1.8));
371 
372  // computes impedance
373  ZlEffFreq /= ErEffFreq;
374 }
375 
376 void cpwline::calcNoiseSP (nr_double_t) {
377  // calculate noise using Bosma's theorem
378  nr_double_t T = getPropertyDouble ("Temp");
379  matrix s = getMatrixS ();
380  matrix e = eye (getSize ());
381  setMatrixN (kelvin (T) / T0 * (e - s * transpose (conj (s))));
382 }
383 
384 void cpwline::initDC (void) {
385  // a DC short (voltage source V = 0 volts)
386  setVoltageSources (1);
388  allocMatrixMNA ();
389  clearY ();
391 }
392 
393 void cpwline::initTR (void) {
394  initDC ();
395 }
396 
397 void cpwline::initAC (void) {
398  setVoltageSources (0);
399  allocMatrixMNA ();
400  initPropagation ();
401 }
402 
403 void cpwline::calcAC (nr_double_t frequency) {
404 
405  nr_double_t zl = zl_factor;
406  nr_double_t beta = bt_factor;
407  nr_double_t alpha;
408 
409  calcAB (frequency, zl, alpha, beta);
410 
411  // calculate and set Y-parameters
412  nr_complex_t g = nr_complex_t (alpha, beta);
413  nr_complex_t y11 = coth (g * len) / zl;
414  nr_complex_t y21 = -cosech (g * len) / zl;
415 
416  setY (NODE_1, NODE_1, y11); setY (NODE_2, NODE_2, y11);
417  setY (NODE_1, NODE_2, y21); setY (NODE_2, NODE_1, y21);
418 }
419 
420 void cpwline::calcNoiseAC (nr_double_t) {
421  // calculate noise using Bosma's theorem
422  nr_double_t T = getPropertyDouble ("Temp");
423  setMatrixN (4 * kelvin (T) / T0 * real (getMatrixY ()));
424 }
425 
426 // properties
427 PROP_REQ [] = {
428  { "W", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
429  { "S", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
430  { "L", PROP_REAL, { 10e-3, PROP_NO_STR }, PROP_POS_RANGE },
431  { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE },
432  PROP_NO_PROP };
433 PROP_OPT [] = {
434  { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
435  { "Backside", PROP_STR, { PROP_NO_VAL, "Metal" },
436  PROP_RNG_STR2 ("Metal", "Air") },
437  { "Approx", PROP_STR, { PROP_NO_VAL, "no" }, PROP_RNG_YESNO },
438  PROP_NO_PROP };
439 struct define_t cpwline::cirdef =
std::complex< nr_double_t > nr_complex_t
Definition: complex.h:31
static nr_double_t ellipk(nr_double_t)
Definition: cpwline.cpp:95
#define MU0
magnetic constant of vacuum ( )
Definition: constants.h:49
#define PROP_POS_RANGE
Definition: netdefs.h:129
void clearY(void)
Definition: circuit.cpp:740
#define NODE_2
Definition: circuit.h:35
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
#define T0
standard temperature
Definition: constants.h:61
#define kelvin(x)
Definition: constants.h:108
substrate * subst
Definition: circuit.h:350
#define PROP_DEF
Definition: netdefs.h:189
#define PROP_RNG_STR2(s1, s2)
Definition: netdefs.h:145
nr_complex_t coth(const nr_complex_t z)
Compute complex hyperbolic cotangent.
Definition: complex.cpp:320
nr_double_t getPropertyDouble(const char *)
Definition: object.cpp:176
nr_complex_t pow(const nr_complex_t z, const nr_double_t d)
Compute power function with real exponent.
Definition: complex.cpp:238
#define PROP_REAL
Definition: netdefs.h:174
substrate * getSubstrate(void)
Definition: circuit.cpp:332
void setInternalVoltageSource(bool i)
Definition: circuit.h:184
t
Definition: parse_vcd.y:290
#define PROP_NO_PROP
Definition: netdefs.h:122
void setVoltageSources(int)
Definition: circuit.cpp:607
#define K
Absolute 0 in centigrade.
Definition: constants.h:59
#define PROP_NO_RANGE
Definition: netdefs.h:126
PROP_NO_SUBSTRATE
Definition: cpwline.cpp:440
#define M_SQRT1_2
Inverse of Square root of 2 ( )
Definition: consts.h:95
#define PROP_NO_STR
Definition: netdefs.h:125
void allocMatrixS(void)
Definition: circuit.cpp:251
n
Definition: parse_citi.y:147
#define PROP_LINEAR
Definition: netdefs.h:120
static const nr_double_t z0
Definition: circuit.h:320
h
Definition: parse_vcd.y:214
r
Definition: parse_mdl.y:515
matrix getMatrixY(void)
Definition: circuit.cpp:696
int getSize(void)
Get the number of ports the circuit element has.
Definition: circuit.h:143
PROP_REQ[]
Definition: cpwline.cpp:427
nr_complex_t cosh(const nr_complex_t z)
Compute complex hyperbolic cosine.
Definition: complex.cpp:135
#define VSRC_1
Definition: circuit.h:40
i
Definition: parse_mdl.y:516
void calcAC(nr_double_t)
Definition: cpwline.cpp:403
nr_double_t ac_factor
Definition: cpwline.h:62
nr_complex_t sqr(const nr_complex_t z)
Square of complex number.
Definition: complex.cpp:673
#define M_PI_2
Half of Archimedes' constant ( )
Definition: consts.h:51
void initPropagation(void)
Definition: cpwline.cpp:122
#define NR_INF
Definition: precision.h:113
nr_complex_t sqrt(const nr_complex_t z)
Compute principal value of square root.
Definition: complex.cpp:271
void calcSP(nr_double_t)
Definition: cpwline.cpp:264
void calcAB(nr_double_t, nr_double_t &, nr_double_t &, nr_double_t &)
Definition: cpwline.cpp:232
void saveCharacteristics(nr_double_t)
Definition: cpwline.cpp:259
nr_double_t len
Definition: cpwline.h:66
void initTR(void)
Definition: cpwline.cpp:393
nr_double_t tand
Definition: cpwline.h:66
static void analyseDispersion(nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t &, nr_double_t &)
Definition: cpwline.cpp:349
nr_complex_t cosech(const nr_complex_t z)
Compute complex argument hyperbolic cosec.
Definition: complex.cpp:364
nr_complex_t tanh(const nr_complex_t z)
Compute complex hyperbolic tangent.
Definition: complex.cpp:153
nr_double_t bt_factor
Definition: cpwline.h:64
#define PROP_COMPONENT
Definition: netdefs.h:116
nr_double_t fte
Definition: cpwline.h:65
void calcNoiseSP(nr_double_t)
Definition: cpwline.cpp:376
static void ellipke(nr_double_t, nr_double_t &, nr_double_t &)
Definition: cpwline.cpp:48
#define M_PI
Archimedes' constant ( )
Definition: consts.h:47
matrix transpose(matrix a)
Matrix transposition.
Definition: matrix.cpp:492
nr_double_t sr_er0
Definition: cpwline.h:60
matrix getMatrixS(void)
Definition: circuit.cpp:654
void setY(int, int, nr_complex_t)
Definition: circuit.cpp:452
#define PROP_MIN_VAL(k)
Definition: netdefs.h:133
void calcNoiseAC(nr_double_t)
Definition: cpwline.cpp:420
void initDC(void)
Definition: cpwline.cpp:384
nr_double_t rho
Definition: cpwline.h:66
v
Definition: parse_zvr.y:141
void allocMatrixMNA(void)
Definition: circuit.cpp:267
void initAC(void)
Definition: cpwline.cpp:397
PROP_OPT[]
Definition: cpwline.cpp:433
nr_complex_t sinh(const nr_complex_t z)
Compute complex hyperbolic sine.
Definition: complex.cpp:144
#define PROP_STR
Definition: netdefs.h:175
nr_double_t Zl
Definition: cpwline.h:67
y
Definition: parse_mdl.y:499
static void analyseQuasiStatic(nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, int, nr_double_t &, nr_double_t &)
Definition: cpwline.cpp:287
#define NODE_1
Definition: circuit.h:34
#define C0
speed of light in vacuum ( )
Definition: constants.h:47
void voltageSource(int, int, int, nr_double_t value=0.0)
Definition: circuit.cpp:748
void setMatrixN(matrix)
Definition: circuit.cpp:664
nr_double_t G
Definition: cpwline.h:65
matrix eye(int rs, int cs)
Create identity matrix with specified number of rows and columns.
Definition: matrix.cpp:603
nr_complex_t exp(const nr_complex_t z)
Compute complex exponential.
Definition: complex.cpp:205
void setS(int, int, nr_complex_t)
Definition: circuit.cpp:587
matrix conj(matrix a)
Conjugate complex matrix.
Definition: matrix.cpp:505
#define PROP_NO_VAL
Definition: netdefs.h:124
nr_double_t sr_er
Definition: cpwline.h:59
void setCharacteristic(const char *, nr_double_t)
Definition: circuit.cpp:566
#define PROP_RNG_YESNO
Definition: netdefs.h:158
char * getPropertyString(const char *)
Definition: object.cpp:159
nr_complex_t log(const nr_complex_t z)
Compute principal value of natural logarithm of z.
Definition: complex.cpp:215
void initSP(void)
placehoder for S-Parameter initialisation function
Definition: cpwline.cpp:115
#define Z0
Wave impedance in vacuum ( )
Definition: constants.h:53
nr_double_t ad_factor
Definition: cpwline.h:63
matrix arg(matrix a)
Computes the argument of each matrix element.
Definition: matrix.cpp:555
nr_double_t zl_factor
Definition: cpwline.h:61
nr_double_t Er
Definition: cpwline.h:67
static nr_double_t ellipa(nr_double_t)
Definition: cpwline.cpp:103