1 /**********
2 Copyright 1990 Regents of the University of California.  All rights reserved.
3 Author: 1985 Thomas L. Quarles
4 Modified 1999 Emmanuel Rouat
5 **********/
6 
7     /*
8      * NIacIter(ckt)
9      *
10      *  This subroutine performs the actual numerical iteration.
11      *  It uses the sparse matrix stored in the NIstruct by NIinit,
12      *  along with the matrix loading program, the load data, the
13      *  convergence test function, and the convergence parameters
14      * - return value is non-zero for convergence failure
15      */
16 
17 #include "ngspice/ngspice.h"
18 #include "ngspice/trandefs.h"
19 #include "ngspice/cktdefs.h"
20 #include "ngspice/sperror.h"
21 
22 
23 int
NIacIter(CKTcircuit * ckt)24 NIacIter(CKTcircuit *ckt)
25 {
26     int error;
27     int ignore;
28     double startTime;
29 
30 retry:
31     ckt->CKTnoncon=0;
32 
33     error = CKTacLoad(ckt);
34     if(error) return(error);
35 
36     if(ckt->CKTniState & NIACSHOULDREORDER) {
37 	startTime = SPfrontEnd->IFseconds();
38         error = SMPcReorder(ckt->CKTmatrix,ckt->CKTpivotAbsTol,
39                 ckt->CKTpivotRelTol,&ignore);
40 	ckt->CKTstat->STATreorderTime +=
41 		SPfrontEnd->IFseconds()- startTime;
42         ckt->CKTniState &= ~NIACSHOULDREORDER;
43         if(error != 0) {
44             /* either singular equations or no memory, in either case,
45              * let caller handle problem
46              */
47             return(error);
48         }
49     } else {
50 	startTime = SPfrontEnd->IFseconds();
51         error = SMPcLUfac(ckt->CKTmatrix,ckt->CKTpivotAbsTol);
52 	ckt->CKTstat->STATdecompTime +=
53 		SPfrontEnd->IFseconds()-startTime;
54         if(error != 0) {
55             if(error == E_SINGULAR) {
56                 /* the problem is that the matrix can't be solved with the
57                  * current LU factorization.  Maybe if we reload and
58                  * try to reorder again it will help...
59                  */
60                 ckt->CKTniState |= NIACSHOULDREORDER;
61                 goto retry;
62             }
63             return(error); /* can't handle E_BADMATRIX, so let caller */
64         }
65     }
66     startTime = SPfrontEnd->IFseconds();
67     SMPcSolve(ckt->CKTmatrix,ckt->CKTrhs,
68             ckt->CKTirhs, ckt->CKTrhsSpare,
69             ckt->CKTirhsSpare);
70     ckt->CKTstat->STATsolveTime += SPfrontEnd->IFseconds() - startTime;
71 
72     ckt->CKTrhs[0] = 0;
73     ckt->CKTrhsSpare[0] = 0;
74     ckt->CKTrhsOld[0] = 0;
75     ckt->CKTirhs[0] = 0;
76     ckt->CKTirhsSpare[0] = 0;
77     ckt->CKTirhsOld[0] = 0;
78 
79     SWAP(double *, ckt->CKTirhs, ckt->CKTirhsOld);
80 
81     SWAP(double *, ckt->CKTrhs, ckt->CKTrhsOld);
82 
83     return(OK);
84 }
85