61 template <
class nr_type_t>
66 reltol = abstol = vntol = 0;
68 calculate_func = NULL;
77 template <
class nr_type_t>
82 reltol = abstol = vntol = 0;
84 calculate_func = NULL;
93 template <
class nr_type_t>
95 if (nlist)
delete nlist;
107 template <
class nr_type_t>
109 nlist = o.nlist ?
new nodelist (*(o.nlist)) : NULL;
119 calculate_func = o.calculate_func;
132 template <
class nr_type_t>
152 if (d >= countNodes ()) {
154 e->
setText (
"voltage source `%s' conflicts with some other voltage "
155 "source", findVoltageSource(d)->getName ());
158 e->
setText (
"circuit admittance matrix in %s solver is singular at "
159 "node `%s' connected to [%s]", desc, nlist->get (d),
160 nlist->getNodeString (d));
168 if (d < countNodes ()) {
170 "node `%s' connected to [%s]\n", getName (), nlist->get (d),
171 nlist->getNodeString (d));
183 if (!error) saveSolution ();
189 template <
class nr_type_t>
191 delete nlist; nlist = NULL;
195 template <
class nr_type_t>
203 nlist->assignNodes ();
204 assignVoltageSources ();
210 int M = countVoltageSources ();
211 int N = countNodes ();
225 template <
class nr_type_t>
227 if (
x == NULL || nlist == NULL)
return;
230 if (nokeep)
for (
int i = 0;
i <
x->getSize ();
i++)
x->set (
i, 0);
233 for (
nodeset *
n = subnet->getNodeset ();
n;
n =
n->getNext ()) {
234 struct nodelist_t * nl = nlist->getNode (
n->getName ());
236 x->set (nl->
n,
n->getValue ());
240 "initialize node\n", getName (),
n->getName ());
243 if (xprev != NULL) *xprev = *
x;
249 template <
class nr_type_t>
252 int convergence, run = 0, MaxIterations,
error = 0;
253 nr_double_t gStep, gPrev;
256 MaxIterations = getPropertyInteger (
"MaxIter") / 4 + 1;
269 error = solve_once ();
272 convergence = (run > 0) ? checkConvergence () : 0;
273 savePreviousIteration ();
278 while (!convergence && run < MaxIterations);
282 if (run >= MaxIterations || error) {
288 e->
setText (
"no convergence in %s analysis after %d gMinStepping "
289 "iterations", desc, iterations);
293 gMin =
MAX (gPrev - gStep, 0);
298 gMin =
MAX (gMin - gStep, 0);
310 template <
class nr_type_t>
313 int convergence, run = 0, MaxIterations,
error = 0;
314 nr_double_t sStep, sPrev;
317 MaxIterations = getPropertyInteger (
"MaxIter") / 4 + 1;
322 sPrev = srcFactor = 0;
330 subnet->setSrcFactor (srcFactor);
331 error = solve_once ();
334 convergence = (run > 0) ? checkConvergence () : 0;
335 savePreviousIteration ();
340 while (!convergence && run < MaxIterations);
344 if (run >= MaxIterations || error) {
349 restorePreviousIteration ();
355 e->
setText (
"no convergence in %s analysis after %d sourceStepping "
356 "iterations", desc, iterations);
360 srcFactor =
MIN (sPrev + sStep, 1);
363 else if (run < MaxIterations / 4) {
365 srcFactor =
MIN (srcFactor + sStep, 1);
369 srcFactor =
MIN (srcFactor + sStep, 1);
375 subnet->setSrcFactor (1);
381 template <
class nr_type_t>
384 return "RHS attenuation";
387 return "line search";
390 return "steepest descent";
393 return "gMin stepping";
396 return "source stepping";
402 template <
class nr_type_t>
405 int convergence, run = 0, MaxIterations,
error = 0;
408 MaxIterations = getPropertyInteger (
"MaxIter");
409 reltol = getPropertyDouble (
"reltol");
410 abstol = getPropertyDouble (
"abstol");
411 vntol = getPropertyDouble (
"vntol");
417 error = solve_nonlinear_continuation_gMin ();
422 error = solve_nonlinear_continuation_Source ();
428 error = solve_once ();
431 convergence = (run > 0) ? checkConvergence () : 0;
432 savePreviousIteration ();
436 if (convergence && !updateMatrix) {
440 else updateMatrix = 0;
445 while (!convergence &&
446 run < MaxIterations * (1 + convHelper ? 1 : 0));
448 if (run >= MaxIterations || error) {
450 e->
setText (
"no convergence in %s analysis after %d iterations",
460 template <
class nr_type_t>
463 return solve_once ();
470 template <
class nr_type_t>
488 int N = countNodes ();
489 int M = countVoltageSources ();
490 for (
int n = 0;
n < N +
M;
n++) {
491 A->set (
n,
n,
A->get (
n,
n) + gMin);
508 #define MatVal(x) MatValX (x, (nr_type_t *) 0)
510 template <
class nr_type_t>
515 template <
class nr_type_t>
528 template <
class nr_type_t>
530 int N = countNodes ();
531 int M = countVoltageSources ();
537 for (
int c = 0;
c <
M;
c++) {
538 vs = findVoltageSource (
c);
540 for (
int r = 0; r <
N; r++) {
542 n = nlist->getNode (r);
550 A->set (r,
c + N, val);
563 template <
class nr_type_t>
565 int N = countNodes ();
566 int M = countVoltageSources ();
572 for (
int r = 0; r <
M; r++) {
573 vs = findVoltageSource (r);
575 for (
int c = 0;
c <
N;
c++) {
577 n = nlist->getNode (
c);
585 A->set (r + N,
c, val);
592 template <
class nr_type_t>
594 int M = countVoltageSources ();
595 int N = countNodes ();
598 for (
int r = 0; r <
M; r++) {
599 vsr = findVoltageSource (r);
600 for (
int c = 0;
c <
M;
c++) {
601 vsc = findVoltageSource (
c);
606 A->set (r + N,
c + N, val);
620 template <
class nr_type_t>
622 int pr, pc, N = countNodes ();
628 for (
int c = 0;
c <
N;
c++) {
629 nc = nlist->getNode (
c);
631 for (
int r = 0; r <
N; r++) {
632 nr = nlist->getNode (r);
635 for (
int a = 0; a < nc->
nNodes; a++)
651 template <
class nr_type_t>
653 int pr, pc, N = countNodes ();
654 int M = countVoltageSources ();
657 int r,
c, a,
b, ri,
ci,
i;
665 for (c = 0; c <
N; c++) {
666 nc = nlist->getNode (c);
668 for (r = 0; r <
N; r++) {
669 nr = nlist->getNode (r);
672 for (a = 0; a < nc->
nNodes; a++)
673 for (b = 0; b < nr->
nNodes; b++)
688 for (r = 0; r <
M; r++) {
689 vsr = findVoltageSource (r);
690 for (c = 0; c <
M; c++) {
691 vsc = findVoltageSource (c);
698 C->set (r + N, c + N, val);
703 for (r = 0; r <
M; r++) {
704 vsr = findVoltageSource (r);
706 for (c = 0; c <
N; c++) {
708 n = nlist->getNode (c);
709 for (i = 0; i < n->
nNodes; i++) {
718 C->set (r + N, c, val);
723 for (c = 0; c <
M; c++) {
724 vsc = findVoltageSource (c);
726 for (r = 0; r <
N; r++) {
728 n = nlist->getNode (r);
729 for (i = 0; i < n->
nNodes; i++) {
738 C->set (r, c + N, val);
749 template <
class nr_type_t>
751 int N = countNodes ();
757 for (
int r = 0; r <
N; r++) {
759 n = nlist->getNode (r);
775 template <
class nr_type_t>
777 int N = countNodes ();
778 int M = countVoltageSources ();
783 for (
int r = 0; r <
M; r++) {
784 vs = findVoltageSource (r);
792 template <
class nr_type_t>
799 template <
class nr_type_t>
801 return nlist->length () - 1;
805 template <
class nr_type_t>
807 return nlist->getNodeNr (str);
812 template <
class nr_type_t>
814 int N = countNodes ();
816 for (
int r = 0; r <
N; r++) {
817 n = nlist->getNode (r);
827 template <
class nr_type_t>
829 return subnet->getVoltageSources ();
835 template <
class nr_type_t>
837 circuit * root = subnet->getRoot ();
839 if (n >=
c->getVoltageSource () &&
840 n <=
c->getVoltageSource () +
c->getVoltageSources () - 1)
849 template <
class nr_type_t>
851 circuit * root = subnet->getRoot ();
854 if (
c->getVoltageSources () > 0) {
855 c->setVoltageSource (nSources);
856 nSources +=
c->getVoltageSources ();
859 subnet->setVoltageSources (nSources);
864 template <
class nr_type_t>
868 eqns->setAlgo (eqnAlgo);
869 eqns->passEquationSys (updateMatrix ?
A : NULL,
x, z);
887 template <
class nr_type_t>
889 nr_double_t alpha = 1.0, nMax;
898 alpha =
MIN (0.9, g / nMax);
899 if (alpha < 0.1) alpha = 0.1;
903 *
x = *xprev + alpha * dx;
912 template <
class nr_type_t>
914 nr_double_t alpha = 0.5,
n, nMin, aprev = 1.0, astep = 0.5, adiff;
923 *
x = *xprev + alpha * dx;
935 adiff = fabs (alpha - aprev);
940 if (alpha == 1) dir = -dir;
941 alpha += astep * dir;
944 alpha += 1.5 * astep * dir;
948 while (adiff > 0.005);
951 assert (alpha > 0 && alpha <= 1);
952 *
x = *xprev + alpha * dx;
959 template <
class nr_type_t>
961 nr_double_t alpha = 1.0, sl,
n;
970 *
x = *xprev + alpha * dx;
980 if (
norm (*z) < n + alpha * sl)
break;
983 while (alpha > 0.001);
986 *
x = *xprev + alpha * dx;
992 template <
class nr_type_t>
994 int N = countNodes ();
995 int M = countVoltageSources ();
996 nr_double_t v_abs, v_rel, i_abs, i_rel;
999 for (r = 0; r <
N; r++) {
1000 v_abs =
abs (
x->get (r) - xprev->get (r));
1001 v_rel =
abs (
x->get (r));
1002 if (v_abs >= vntol + reltol * v_rel)
return 0;
1004 i_abs =
abs (z->get (r) - zprev->get (r));
1005 i_rel =
abs (z->get (r));
1006 if (i_abs >= abstol + reltol * i_rel)
return 0;
1009 for (r = 0; r <
M; r++) {
1010 i_abs =
abs (
x->get (r + N) - xprev->get (r + N));
1011 i_rel =
abs (
x->get (r + N));
1012 if (i_abs >= abstol + reltol * i_rel)
return 0;
1014 v_abs =
abs (z->get (r + N) - zprev->get (r + N));
1015 v_rel =
abs (z->get (r + N));
1016 if (v_abs >= vntol + reltol * v_rel)
return 0;
1024 template <
class nr_type_t>
1038 template <
class nr_type_t>
1040 if (xprev != NULL) *
x = *xprev;
1041 if (zprev != NULL) *z = *zprev;
1046 template <
class nr_type_t>
1048 circuit * root = subnet->getRoot ();
1050 if (
c->isNonLinear ())
c->restartDC ();
1057 template <
class nr_type_t>
1059 int N = countNodes ();
1062 for (
int r = 0; r <
N; r++) {
1063 n = nlist->getNode (r);
1069 n = nlist->getNode (-1);
1078 template <
class nr_type_t>
1080 int N = countNodes ();
1081 int M = countVoltageSources ();
1084 for (
int r = 0; r <
M; r++) {
1085 vs = findVoltageSource (r);
1086 vs->
setJ (r,
x->get (r + N));
1091 template <
class nr_type_t>
1093 saveNodeVoltages ();
1094 saveBranchCurrents ();
1098 template <
class nr_type_t>
1103 int N = countNodes ();
1104 int M = countVoltageSources ();
1106 for (r = 0; r <
N; r++) {
1108 solution.add (n->
name,
x->get (r), 0);
1111 for (r = 0; r <
M; r++) {
1112 circuit * vs = findVoltageSource (r);
1114 solution.add (vs->
getName (),
x->get (r + N), vn);
1119 template <
class nr_type_t>
1122 int N = countNodes ();
1123 int M = countVoltageSources ();
1126 for (r = 0; r <
N; r++) {
1128 if ((na = solution.find (n->
name, 0)) != NULL)
1132 for (r = 0; r <
M; r++) {
1133 circuit * vs = findVoltageSource (r);
1135 if ((na = solution.find (vs->
getName (), vn)) != NULL)
1136 x->set (r + N, na->
value);
1142 template <
class nr_type_t>
1144 int saveOPs,
vector * f) {
1145 int N = countNodes ();
1146 int M = countVoltageSources ();
1151 for (
int r = 0; r <
N; r++) {
1152 if ((n = createV (r, volts, saveOPs)) != NULL) {
1153 saveVariable (n,
x->get (r), f);
1161 for (
int r = 0; r <
M; r++) {
1162 if ((n = createI (r, amps, saveOPs)) != NULL) {
1163 saveVariable (n,
x->get (r + N), f);
1171 circuit * root = subnet->getRoot ();
1173 if (!
c->isProbe ())
continue;
1174 if (
c->getSubcircuit () && !(saveOPs &
SAVE_ALL))
continue;
1175 if (strcmp (volts,
"vn"))
1176 c->saveOperatingPoints ();
1177 n = createOP (
c->getName (), volts);
1178 saveVariable (n,
rect (
c->getOperatingPoint (
"Vr"),
1179 c->getOperatingPoint (
"Vi")), f);
1186 circuit * root = subnet->getRoot ();
1188 if (!
c->isNonLinear ())
continue;
1189 if (
c->getSubcircuit () && !(saveOPs &
SAVE_ALL))
continue;
1190 c->calcOperatingPoints ();
1194 n = createOP (
c->getName (), p->
getName ());
1195 saveVariable (n, p->
getValue (), f);
1204 template <
class nr_type_t>
1206 char * text = (
char *) malloc (strlen (c) + strlen (n) + 2);
1207 sprintf (text,
"%s.%s", c, n);
1213 template <
class nr_type_t>
1215 if (nlist->isInternal (n))
return NULL;
1216 char *
node = nlist->get (n);
1218 char * text = (
char *) malloc (strlen (node) + 2 + strlen (volts));
1219 sprintf (text,
"%s.%s", node, volts);
1225 template <
class nr_type_t>
1227 circuit * vs = findVoltageSource (n);
1244 char * text = (
char *) malloc (strlen (name) + 4 + strlen (amps));
1248 sprintf (text,
"%s.%s", name, amps);