1 /***************************************************************************
2 JSPICE3 adaptation of Spice3f2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California.  All rights reserved.
4 Authors: 1988 Jaijeet S. Roychowdhury
5          1993 Stephen R. Whiteley
6 ****************************************************************************/
7 
8     /*
9      * NIdIter(ckt)
10      *
11      * This is absolutely the same as NIacIter, except that the RHS
12      * vector is stored before acLoad so that it is not lost. Moreover,
13      * acLoading is done only if reordering is necessary
14      *
15      */
16 
17 #include "spice.h"
18 #include <stdio.h>
19 #include "cktdefs.h"
20 #include "util.h"
21 #include "sperror.h"
22 #include "cktext.h"
23 #include "niext.h"
24 
25 int
NIdIter(ckt)26 NIdIter(ckt)
27 
28 CKTcircuit * ckt;
29 {
30     int error;
31     int ignore;
32     double *temp;
33 
34     for (;;) {
35         ckt->CKTnoncon = 0;
36 
37         if (ckt->CKTniState & NIACSHOULDREORDER) {
38             spSetComplex(ckt->CKTmatrix);
39             error = spOrderAndFactor(ckt->CKTmatrix,NULL,
40                 ckt->CKTpivotRelTol,ckt->CKTpivotAbsTol,1);
41             ckt->CKTniState &= ~NIACSHOULDREORDER;
42             if (error != 0) {
43                 /* either singular equations or no memory, in either case,
44                  * let caller handle problem
45                  */
46                 return (error);
47             }
48         }
49         else {
50             spSetComplex(ckt->CKTmatrix);
51             error = spFactor(ckt->CKTmatrix);
52             if (error != 0) {
53                 if (error == E_SINGULAR) {
54                     /* the problem is that the matrix can't be solved with
55                      * the current LU factorization.  Maybe if we reload and
56                      * try to reorder again it will help...
57                      */
58                     ckt->CKTniState |= NIACSHOULDREORDER;
59                     temp = ckt->CKTrhs;
60                     ckt->CKTrhs = ckt->CKTrhsSpare;
61                     ckt->CKTrhsSpare = temp;
62 
63                     temp = ckt->CKTirhs;
64                     ckt->CKTirhs = ckt->CKTirhsSpare;
65                     ckt->CKTirhsSpare = temp;
66 
67                     error = CKTacLoad(ckt);
68                     if (error) return(error);
69 
70                     temp = ckt->CKTrhs;
71                     ckt->CKTrhs = ckt->CKTrhsSpare;
72                     ckt->CKTrhsSpare = temp;
73 
74                     temp = ckt->CKTirhs;
75                     ckt->CKTirhs = ckt->CKTirhsSpare;
76                     ckt->CKTirhsSpare = temp;
77                     continue;
78                 }
79                 return (error); /* can't handle E_BADMATRIX, so let caller */
80             }
81         }
82         break;
83     }
84     spSolve(ckt->CKTmatrix,ckt->CKTrhs,ckt->CKTrhs,
85             ckt->CKTirhs,ckt->CKTirhs);
86 
87     *ckt->CKTrhs = 0;
88     *ckt->CKTrhsSpare = 0;
89     *ckt->CKTrhsOld = 0;
90     *ckt->CKTirhs = 0;
91     *ckt->CKTirhsSpare = 0;
92     *ckt->CKTirhsOld = 0;
93 
94     temp = ckt->CKTirhsOld;
95     ckt->CKTirhsOld = ckt->CKTirhs;
96     ckt->CKTirhs = temp;
97 
98     temp = ckt->CKTrhsOld;
99     ckt->CKTrhsOld = ckt->CKTrhs;
100     ckt->CKTrhs = temp;
101     return (OK);
102 }
103