diff --git a/src/maths/ni/niaciter.c b/src/maths/ni/niaciter.c index 676d2cef9..47019cbe1 100644 --- a/src/maths/ni/niaciter.c +++ b/src/maths/ni/niaciter.c @@ -64,6 +64,9 @@ retry: } } startTime = SPfrontEnd->IFseconds(); + /* solve(CKTmatrix . x = CKTrhs), then assign CKTrhs <== x + * CKTrhsSpare is not used + */ SMPcSolve(ckt->CKTmatrix,ckt->CKTrhs, ckt->CKTirhs, ckt->CKTrhsSpare, ckt->CKTirhsSpare); diff --git a/src/maths/ni/niconv.c b/src/maths/ni/niconv.c index 9c70b8120..78a1c1518 100644 --- a/src/maths/ni/niconv.c +++ b/src/maths/ni/niconv.c @@ -17,6 +17,9 @@ Author: 1985 Thomas L. Quarles extern bool ft_ngdebug; +/* here: + * CKTrhs is newest solution, CKTrhsOld the previous solution + */ int NIconvTest(CKTcircuit *ckt) { diff --git a/src/maths/ni/niditer.c b/src/maths/ni/niditer.c index 78ee0864a..990ee027e 100644 --- a/src/maths/ni/niditer.c +++ b/src/maths/ni/niditer.c @@ -65,6 +65,9 @@ skip: return(error); /* can't handle E_BADMATRIX, so let caller */ } } + /* solve(CKTmatrix . x = CKTrhs), then assign CKTrhs <== x + * CKTrhsSpare is not used + */ SMPcSolve(ckt->CKTmatrix,ckt->CKTrhs, ckt->CKTirhs, ckt->CKTrhsSpare, ckt->CKTirhsSpare); diff --git a/src/maths/ni/niiter.c b/src/maths/ni/niiter.c index a2bec8b07..18beb0969 100644 --- a/src/maths/ni/niiter.c +++ b/src/maths/ni/niiter.c @@ -36,6 +36,10 @@ NIiter(CKTcircuit *ckt, int maxIter) maxIter = 100; if ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) { + /* save current CKTrhs (the last solution) in CKTrhsOld + * CKTrhs will be zeroed and then DEVload'ed in CKTload(), + * and later overwritten with the next solution + */ SWAP(double *, ckt->CKTrhs, ckt->CKTrhsOld); error = CKTload(ckt); if (error) @@ -52,6 +56,9 @@ NIiter(CKTcircuit *ckt, int maxIter) #endif if (ckt->CKTniState & NIUNINITIALIZED) { + /* CKTrhs, CKTrhsOld and CKTrhsSpare + * are zeroed in NIreinit() + */ error = NIreinit(ckt); if (error) { #ifdef STEPDEBUG @@ -72,6 +79,8 @@ NIiter(CKTcircuit *ckt, int maxIter) #endif { + /* CKTrhs is zeroed, and then DEVload'ed in CKTload() + */ error = CKTload(ckt); /* printf("loaded, noncon is %d\n", ckt->CKTnoncon); */ /* fflush(stdout); */ @@ -159,6 +168,9 @@ NIiter(CKTcircuit *ckt, int maxIter) (size_t) ckt->CKTnumStates * sizeof(double)); startTime = SPfrontEnd->IFseconds(); + /* solve(CKTmatrix . x = CKTrhs), then assign CKTrhs <== x + * CKTrhsSpare is not used + */ SMPsolve(ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare); ckt->CKTstat->STATsolveTime += SPfrontEnd->IFseconds() - startTime; @@ -189,6 +201,10 @@ NIiter(CKTcircuit *ckt, int maxIter) return(E_ITERLIM); } + /* we have the newest solution CKTrhs, + * and the previous in CKTrhsOld + * when calling NIconvTest() + */ if ((ckt->CKTnoncon == 0) && (iterno != 1)) ckt->CKTnoncon = NIconvTest(ckt); else @@ -237,6 +253,10 @@ NIiter(CKTcircuit *ckt, int maxIter) if (ckt->CKTnoncon == 0) { ckt->CKTstat->STATnumIter += iterno; FREE(OldCKTstate0); + /* now copy the newest solution over to CKTrhsOld + * where it will be expected when returning this function + * CKTrhs won't be used + */ SWAP(double *, ckt->CKTrhs, ckt->CKTrhsOld); return(OK); } @@ -266,6 +286,10 @@ NIiter(CKTcircuit *ckt, int maxIter) } /* build up the lvnim1 array from the lvn array */ + /* save the newest solution in CKRrhsOld + * CKTrhs is unused now and ready to be zeroed and DEVload'ed + * in the next CKTload() invocation + */ SWAP(double *, ckt->CKTrhs, ckt->CKTrhsOld); /* printf("after loading, after solving\n"); */ /* CKTdump(ckt); */ diff --git a/src/maths/ni/niniter.c b/src/maths/ni/niniter.c index fc83a4e86..34d212e61 100644 --- a/src/maths/ni/niniter.c +++ b/src/maths/ni/niniter.c @@ -31,6 +31,9 @@ NInzIter(CKTcircuit *ckt, int posDrive, int negDrive) ckt->CKTrhs [posDrive] = 1.0; /* apply unit current excitation */ ckt->CKTrhs [negDrive] = -1.0; + /* solve(CKTmatrix^T . x = CKTrhs), then assign CKTrhs <== x + * CKTrhsSpare is not used + */ SMPcaSolve(ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTirhs, ckt->CKTrhsSpare, ckt->CKTirhsSpare);