nr_double_t msvia::calcResistance (void) { // fetch substrate and component properties substrate * subst = getSubstrate (); nr_double_t h = subst->getPropertyDouble ("h"); nr_double_t t = subst->getPropertyDouble ("t"); nr_double_t rho = subst->getPropertyDouble ("rho"); nr_double_t r = getPropertyDouble ("D") / 2; nr_double_t v = h / M_PI / (sqr (r) - sqr (r - t)); return R = rho * v; }
void vcvs::initDC (void) { nr_double_t g = getPropertyDouble ("G"); allocMatrixMNA (); setC (VSRC_1, NODE_1, +g); setC (VSRC_1, NODE_2, -1.0); setC (VSRC_1, NODE_3, +1.0); setC (VSRC_1, NODE_4, -g); setB (NODE_1, VSRC_1, +0); setB (NODE_2, VSRC_1, -1.0); setB (NODE_3, VSRC_1, +1.0); setB (NODE_4, VSRC_1, +0); setD (VSRC_1, VSRC_1, 0.0); setE (VSRC_1, 0.0); }
void digisource::initDC (void) { char * init = getPropertyString ("init"); nr_double_t v = getPropertyDouble ("V"); bool lo = !strcmp (init, "low"); allocMatrixMNA (); setC (VSRC_1, NODE_1, 1.0); setB (NODE_1, VSRC_1, 1.0); setD (VSRC_1, VSRC_1, 0.0); setE (VSRC_1, lo ? 0 : v); }
void vcvs::initTR (void) { nr_double_t t = getPropertyDouble ("T"); initDC (); deleteHistory (); if (t > 0.0) { setHistory (true); initHistory (t); setC (VSRC_1, NODE_1, 0.0); setC (VSRC_1, NODE_4, 0.0); } }
void cpwstep::checkProperties (void) { nr_double_t W1 = getPropertyDouble ("W1"); nr_double_t W2 = getPropertyDouble ("W2"); nr_double_t s = getPropertyDouble ("S"); if (W1 == W2) { logprint (LOG_ERROR, "ERROR: Strip widths of step discontinuity do not " "differ\n"); } if (W1 >= s || W2 >= s) { logprint (LOG_ERROR, "ERROR: Strip widths of step discontinuity larger " "than groundplane gap\n"); } substrate * subst = getSubstrate (); nr_double_t er = subst->getPropertyDouble ("er"); if (er < 2 || er > 14) { logprint (LOG_ERROR, "WARNING: Model for coplanar step valid for " "2 < er < 14 (er = %g)\n", er); } }
void inductor::calcAC (nr_double_t frequency) { nr_double_t l = getPropertyDouble ("L"); // for non-zero inductance usual MNA entries if (l != 0.0) { nr_complex_t y = rect (0, -1 / (2.0 * M_PI * frequency * l)); setY (NODE_1, NODE_1, +y); setY (NODE_2, NODE_2, +y); setY (NODE_1, NODE_2, -y); setY (NODE_2, NODE_1, -y); } }
void dcfeed::calcTR (nr_double_t) { nr_double_t l = getPropertyDouble ("L"); nr_double_t r, v; nr_double_t i = real (getJ (VSRC_1)); setState (fState, i * l); integrate (fState, l, r, v); setD (VSRC_1, VSRC_1, -r); setE (VSRC_1, v); }
void cccs::initDC (void) { setISource (false); allocMatrixMNA (); nr_double_t g = getPropertyDouble ("G"); setC (VSRC_1, NODE_1, +1.0); setC (VSRC_1, NODE_2, +0.0); setC (VSRC_1, NODE_3, +0.0); setC (VSRC_1, NODE_4, -1.0); setB (NODE_1, VSRC_1, +1/g); setB (NODE_2, VSRC_1, +1.0); setB (NODE_3, VSRC_1, -1.0); setB (NODE_4, VSRC_1, -1/g); setD (VSRC_1, VSRC_1, 0.0); setE (VSRC_1, 0.0); }
void vccs::initTR (void) { nr_double_t t = getPropertyDouble ("T"); initDC (); deleteHistory (); if (t > 0.0) { setISource (true); setHistory (true); initHistory (t); clearY (); } }
void tline4p::calcAC (nr_double_t frequency) { nr_double_t l = getPropertyDouble ("L"); nr_double_t z = getPropertyDouble ("Z"); nr_double_t a = getPropertyDouble ("Alpha"); nr_double_t b = 2 * M_PI * frequency / C0; a = log (a) / 2; if (l != 0.0) { nr_complex_t g = rect (a, b); nr_complex_t y11 = coth (g * l) / z; nr_complex_t y21 = -cosech (g * l) / z; setY (NODE_1, NODE_1, +y11); setY (NODE_2, NODE_2, +y11); setY (NODE_3, NODE_3, +y11); setY (NODE_4, NODE_4, +y11); setY (NODE_1, NODE_4, -y11); setY (NODE_4, NODE_1, -y11); setY (NODE_2, NODE_3, -y11); setY (NODE_3, NODE_2, -y11); setY (NODE_1, NODE_2, +y21); setY (NODE_2, NODE_1, +y21); setY (NODE_3, NODE_4, +y21); setY (NODE_4, NODE_3, +y21); setY (NODE_1, NODE_3, -y21); setY (NODE_3, NODE_1, -y21); setY (NODE_2, NODE_4, -y21); setY (NODE_4, NODE_2, -y21); } }
// Initialize transient analysis. void digital::initTR (void) { nr_double_t t = getPropertyDouble ("t"); initDC (); deleteHistory (); if (t > 0.0) { delay = true; setHistory (true); initHistory (t); setC (VSRC_1, NODE_OUT, 1); } }
void tline::initDC (void) { nr_double_t z = getPropertyDouble ("Z"); nr_double_t a = getPropertyDouble ("Alpha"); nr_double_t l = getPropertyDouble ("L"); a = log (a) / 2; if (a * l != 0.0) { setVoltageSources (0); allocMatrixMNA (); a = exp (a * l); nr_double_t f = 1 / z / (a - 1); nr_double_t y11 = +f * (a + 1); nr_double_t y21 = -f * 2 * sqrt (a); setY (NODE_1, NODE_1, y11); setY (NODE_2, NODE_2, y11); setY (NODE_1, NODE_2, y21); setY (NODE_2, NODE_1, y21); } else { setVoltageSources (1); allocMatrixMNA (); voltageSource (VSRC_1, NODE_1, NODE_2); } }
void tline::initAC (void) { nr_double_t l = getPropertyDouble ("L"); if (l != 0.0) { setVoltageSources (0); allocMatrixMNA (); } else { setVoltageSources (1); allocMatrixMNA (); voltageSource (VSRC_1, NODE_1, NODE_2); } }
void capacitor::calcTR (nr_double_t) { /* if this is a controlled capacitance then do nothing here */ if (hasProperty ("Controlled")) return; nr_double_t c = getPropertyDouble ("C"); nr_double_t g, i; nr_double_t v = real (getV (NODE_1) - getV (NODE_2)); /* apply initial condition if requested */ if (getMode () == MODE_INIT && isPropertyGiven ("V")) { v = getPropertyDouble ("V"); } setState (qState, c * v); integrate (qState, c, g, i); setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g); setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g); setI (NODE_1 , -i); setI (NODE_2 , +i); }
void dcblock::calcTR (nr_double_t) { nr_double_t c = getPropertyDouble ("C"); nr_double_t g, i; nr_double_t v = real (getV (NODE_1) - getV (NODE_2)); setState (qState, c * v); integrate (qState, c, g, i); setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g); setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g); setI (NODE_1 , -i); setI (NODE_2 , +i); }
void tline4p::initTR (void) { nr_double_t l = getPropertyDouble ("L"); nr_double_t z = getPropertyDouble ("Z"); deleteHistory (); if (l > 0.0) { setVoltageSources (2); allocMatrixMNA (); setHistory (true); initHistory (l / C0); setB (NODE_1, VSRC_1, +1); setB (NODE_2, VSRC_2, +1); setB (NODE_4, VSRC_1, -1); setB (NODE_3, VSRC_2, -1); setC (VSRC_1, NODE_1, +1); setC (VSRC_2, NODE_2, +1); setC (VSRC_1, NODE_4, -1); setC (VSRC_2, NODE_3, -1); setD (VSRC_1, VSRC_1, -z); setD (VSRC_2, VSRC_2, -z); } else { setVoltageSources (2); allocMatrixMNA (); voltageSource (VSRC_1, NODE_1, NODE_2); voltageSource (VSRC_2, NODE_3, NODE_4); } }
void cccs::initTR (void) { nr_double_t t = getPropertyDouble ("T"); initDC (); deleteHistory (); if (t > 0.0) { setISource (true); setHistory (true); initHistory (t); setB (NODE_1, VSRC_1, +1.0); setB (NODE_2, VSRC_1, +0.0); setB (NODE_3, VSRC_1, -0.0); setB (NODE_4, VSRC_1, -1.0); } }
void coaxline::initDC (void) { nr_double_t l = getPropertyDouble ("L"); nr_double_t d = getPropertyDouble ("d"); nr_double_t rho = getPropertyDouble ("rho"); if (d != 0.0 && rho != 0.0 && l != 0.0) { // a tiny resistance nr_double_t g = M_PI * sqr (d / 2) / rho / l; setVoltageSources (0); allocMatrixMNA (); setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g); setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g); } else { // a DC short setVoltageSources (1); setInternalVoltageSource (1); allocMatrixMNA (); voltageSource (VSRC_1, NODE_1, NODE_2); } }
void irect::calcTR (nr_double_t t) { nr_double_t i = getPropertyDouble ("I"); nr_double_t th = getPropertyDouble ("TH"); nr_double_t tl = getPropertyDouble ("TL"); nr_double_t tr = getPropertyDouble ("Tr"); nr_double_t tf = getPropertyDouble ("Tf"); nr_double_t td = getPropertyDouble ("Td"); nr_double_t it = 0; nr_double_t s = getNet()->getSrcFactor (); if (tr > th) tr = th; if (tf > tl) tf = tl; if (t > td) { // after delay t = t - td; t = t - (th + tl) * floor (t / (th + tl)); if (t < tr) { // rising edge it = + i / tr * t; } else if (t < th) { // high pulse it = i; } else if (t < th + tf) { // falling edge it = - i / tf * (t - (th + tf)); } } setI (NODE_1, +it * s); setI (NODE_2, -it * s); }
void coaxline::calcPropagation (nr_double_t frequency) { nr_double_t er = getPropertyDouble ("er"); nr_double_t mur = getPropertyDouble ("mur"); nr_double_t rho = getPropertyDouble ("rho"); nr_double_t tand = getPropertyDouble ("tand"); nr_double_t d = getPropertyDouble ("d"); nr_double_t D = getPropertyDouble ("D"); nr_double_t ad, ac, rs; // check cutoff frequency if (frequency > fc) { logprint (LOG_ERROR, "WARNING: Operating frequency (%g) beyond " "cutoff frequency (%g).\n", frequency, fc); } // calculate losses ad = M_PI / C0 * frequency * sqrt (er) * tand; rs = sqrt (M_PI * frequency * mur * MU0 * rho); ac = sqrt (er) * (1 / d + 1 / D) / log (D / d) * rs / Z0; // calculate propagation constants and reference impedance alpha = ac + ad; beta = sqrt (er * mur) * 2 * M_PI * frequency / C0; zl = Z0 / 2 / M_PI / sqrt (er) * log (D / d); }
void coaxline::calcAC (nr_double_t frequency) { nr_double_t l = getPropertyDouble ("L"); // calculate propagation constants calcPropagation (frequency); // calculate Y-parameters nr_complex_t g = rect (alpha, beta); nr_complex_t y11 = coth (g * l) / zl; nr_complex_t y21 = -cosech (g * l) / zl; setY (NODE_1, NODE_1, y11); setY (NODE_2, NODE_2, y11); setY (NODE_1, NODE_2, y21); setY (NODE_2, NODE_1, y21); }
matrix cpwgap::calcMatrixY (nr_double_t frequency) { nr_double_t W = getPropertyDouble ("W"); nr_double_t g = getPropertyDouble ("G"); substrate * subst = getSubstrate (); nr_double_t er = subst->getPropertyDouble ("er"); // calculate series capacitance er = (er + 1) / 2; nr_double_t p = g / 4 / W; nr_double_t C = 2 * E0 * er * W / M_PI * (p - sqrt (1 + p * p) + log ((1 + sqrt (1 + p * p)) / p)); // build Y-parameter matrix nr_complex_t y11 = rect (0.0, 2.0 * M_PI * frequency * C); matrix y (2); y.set (0, 0, +y11); y.set (0, 1, -y11); y.set (1, 0, -y11); y.set (1, 1, +y11); return y; }
void itrafo::initSP (void) { allocMatrixS (); nr_double_t z = getPropertyDouble ("Z"); nr_double_t n = 2 * z0 + z; setS (NODE_1, NODE_1, (2.0 * z0 - z) / n); setS (NODE_1, NODE_2, (2.0 * sqrt (z0 * z)) / n); setS (NODE_1, NODE_3, -(2.0 * sqrt (z0 * z)) / n); setS (NODE_2, NODE_1, (2.0 * sqrt (z0 * z)) / n); setS (NODE_2, NODE_2, (z) / n); setS (NODE_2, NODE_3, (2.0 * z0) / n); setS (NODE_3, NODE_1, -(2.0 * sqrt (z0 * z)) / n); setS (NODE_3, NODE_2, (2.0 * z0) / n); setS (NODE_3, NODE_3, (z) / n); }
void isolator::initDC (void) { nr_double_t z1 = getPropertyDouble ("Z1"); nr_double_t z2 = getPropertyDouble ("Z2"); #if AUGMENTED nr_double_t z21 = 2 * sqrt (z1 * z2); setVoltageSources (2); allocMatrixMNA (); setB (NODE_1, VSRC_1, +1.0); setB (NODE_1, VSRC_2, +0.0); setB (NODE_2, VSRC_1, +0.0); setB (NODE_2, VSRC_2, +1.0); setC (VSRC_1, NODE_1, -1.0); setC (VSRC_1, NODE_2, +0.0); setC (VSRC_2, NODE_1, +0.0); setC (VSRC_2, NODE_2, -1.0); setD (VSRC_1, VSRC_1, +z1); setD (VSRC_2, VSRC_2, +z2); setD (VSRC_1, VSRC_2, +0.0); setD (VSRC_2, VSRC_1, +z21); setE (VSRC_1, +0.0); setE (VSRC_2, +0.0); #else setVoltageSources (0); allocMatrixMNA (); setY (NODE_1, NODE_1, 1 / z1); setY (NODE_1, NODE_2, 0); setY (NODE_2, NODE_1, -2 / sqrt (z1 * z2)); setY (NODE_2, NODE_2, 1 / z2); #endif }
void inductor::initAC (void) { nr_double_t l = getPropertyDouble ("L"); // for non-zero inductance usual MNA entries if (l != 0.0) { setVoltageSources (0); allocMatrixMNA (); } // for zero inductance create a zero voltage source else { initDC (); calcDC (); } }
void circulator::calcSP (nr_double_t) { nr_double_t z1 = getPropertyDouble ("Z1"); nr_double_t z2 = getPropertyDouble ("Z2"); nr_double_t z3 = getPropertyDouble ("Z3"); nr_double_t r1 = (z0 - z1) / (z0 + z1); nr_double_t r2 = (z0 - z2) / (z0 + z2); nr_double_t r3 = (z0 - z3) / (z0 + z3); nr_double_t d = 1 - r1 * r2 * r3; setS (NODE_1, NODE_1, (r2 * r3 - r1) / d); setS (NODE_2, NODE_2, (r1 * r3 - r2) / d); setS (NODE_3, NODE_3, (r1 * r2 - r3) / d); setS (NODE_1, NODE_2, sqrt (z2 / z1) * (z1 + z0) / (z2 + z0) * r3 * (1 - r1 * r1) / d); setS (NODE_2, NODE_3, sqrt (z3 / z2) * (z2 + z0) / (z3 + z0) * r1 * (1 - r2 * r2) / d); setS (NODE_3, NODE_1, sqrt (z1 / z3) * (z3 + z0) / (z1 + z0) * r2 * (1 - r3 * r3) / d); setS (NODE_2, NODE_1, sqrt (z1 / z2) * (z2 + z0) / (z1 + z0) * (1 - r2 * r2) / d); setS (NODE_1, NODE_3, sqrt (z3 / z1) * (z1 + z0) / (z3 + z0) * (1 - r1 * r1) / d); setS (NODE_3, NODE_2, sqrt (z2 / z3) * (z3 + z0) / (z2 + z0) * (1 - r3 * r3) / d); }
void digisource::calcTR (nr_double_t t) { char * init = getPropertyString ("init"); nr_double_t v = getPropertyDouble ("V"); vector * values = getPropertyVector ("times"); bool lo = !strcmp (init, "low"); nr_double_t ti = 0; t = t - T * floor (t / T); for (int i = 0; i < values->getSize (); i++) { ti += real (values->get (i)); if (t >= ti) lo = !lo; else break; } setE (VSRC_1, lo ? 0 : v); }
void twistedpair::initDC (void) { nr_double_t d = getPropertyDouble ("d"); nr_double_t rho = getPropertyDouble ("rho"); calcLength (); if (d != 0.0 && rho != 0.0 && len != 0.0) { // tiny resistances nr_double_t g1 = M_PI * sqr (d / 2) / rho / len; nr_double_t g2 = g1; setVoltageSources (0); allocMatrixMNA (); setY (NODE_1, NODE_1, +g1); setY (NODE_2, NODE_2, +g1); setY (NODE_1, NODE_2, -g1); setY (NODE_2, NODE_1, -g1); setY (NODE_3, NODE_3, +g2); setY (NODE_4, NODE_4, +g2); setY (NODE_3, NODE_4, -g2); setY (NODE_4, NODE_3, -g2); } else { // DC shorts setVoltageSources (2); allocMatrixMNA (); voltageSource (VSRC_1, NODE_1, NODE_2); voltageSource (VSRC_2, NODE_3, NODE_4); } }
nr_double_t twistedpair::calcLoss (nr_double_t frequency) { nr_double_t d = getPropertyDouble ("d"); nr_double_t rho = getPropertyDouble ("rho"); nr_double_t mur = getPropertyDouble ("mur"); nr_double_t tand = getPropertyDouble ("tand"); nr_double_t delta, rout, rin, ad, ac, l0; // calculate conductor losses rout = d / 2; if (frequency > 0.0) { delta = sqrt (rho / (M_PI * frequency * MU0 * mur)); rin = rout - delta; if (rin < 0.0) rin = 0.0; } else rin = 0.0; ac = (rho * M_1_PI) / (rout * rout - rin * rin) / zl; // calculate dielectric losses l0 = C0 / frequency; ad = M_PI * tand * sqrt (ereff) / l0; alpha = ac + ad; return alpha; }
void coaxline::calcSP (nr_double_t frequency) { nr_double_t l = getPropertyDouble ("L"); // calculate propagation constants calcPropagation (frequency); // calculate S-parameters nr_double_t z = zl / z0; nr_double_t y = 1 / z; nr_complex_t g = rect (alpha, beta); nr_complex_t n = 2.0 * cosh (g * l) + (z + y) * sinh (g * l); nr_complex_t s11 = (z - y) * sinh (g * l) / n; nr_complex_t s21 = 2.0 / n; setS (NODE_1, NODE_1, s11); setS (NODE_2, NODE_2, s11); setS (NODE_1, NODE_2, s21); setS (NODE_2, NODE_1, s21); }