Jspice3
nicomcof.c
Go to the documentation of this file.
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: 1985 Thomas L. Quarles
5  1993 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 #include "spice.h"
9 #include <stdio.h>
10 #include "cktdefs.h"
11 #include "sperror.h"
12 #include "niext.h"
13 
14 #ifdef __STDC__
15 static int ni_gearcof(CKTcircuit*);
16 #else
17 static int ni_gearcof();
18 #endif
19 
20 
21 int
23 
24 CKTcircuit *ckt;
25 {
26 /* this routine calculates the timestep-dependent terms used in the
27  * numerical integration.
28  */
29 
30  if (ckt->CKTintegrateMethod == TRAPEZOIDAL) {
31 
32  if (ckt->CKTorder == 2) {
33  ckt->CKTag[0] = 2.0/ckt->CKTdelta;
34  ckt->CKTag[1] = 1.0;
35  /*
36  ckt->CKTag[0] = 1.0/ckt->CKTdelta/(1.0-0.5);
37  ckt->CKTag[1] = 0.5/(1.0 - 0.5);
38  above lines should have 'xmu' instead of .5 eventually
39  (in all three places)
40  */
41  return (OK);
42  }
43  if (ckt->CKTorder == 1) {
44  ckt->CKTag[0] = 1/ckt->CKTdelta;
45  ckt->CKTag[1] = -ckt->CKTag[0];
46  return (OK);
47  }
48  return(E_ORDER);
49  }
50  if (ckt->CKTintegrateMethod == GEAR) {
51  return (ni_gearcof(ckt));
52  }
53  return (E_METHOD);
54 }
55 
56 
57 static int
59 
60 CKTcircuit* ckt;
61 {
62  double mat[8][8]; /* matrix to compute the gear coefficients in */
63  int i,j,k; /* generic loop indicies */
64  double arg;
65  double arg1;
66 
67  if (ckt->CKTorder < 1 || ckt->CKTorder > 6)
68  return (E_ORDER);
69 
70  bzero(ckt->CKTag,7*sizeof(double));
71  ckt->CKTag[1] = -1/ckt->CKTdelta;
72  /* first, set up the matrix */
73  arg = 0;
74  for (i = 0; i <= ckt->CKTorder; i++) { mat[0][i]=1; }
75  for (i = 1; i <= ckt->CKTorder; i++) { mat[i][0]=0; }
76  /* SPICE2 difference warning
77  * the following block builds the corrector matrix
78  * using (sum of h's)/h(final) instead of just (sum of h's)
79  * because the h's are typically ~1e-10, so h^7 is an
80  * underflow on many machines, but the ratio is ~1
81  * and produces much better results
82  */
83  for (i = 1; i <= ckt->CKTorder; i++) {
84  arg += ckt->CKTdeltaOld[i-1];
85  arg1 = 1;
86  for (j = 1; j <= ckt->CKTorder; j++) {
87  arg1 *= arg/ckt->CKTdelta;
88  mat[j][i] = arg1;
89  }
90  }
91  /* lu decompose */
92  /* weirdness warning!
93  * The following loop (and the first one after the forward
94  * substitution comment) start at one instead of zero
95  * because of a SPECIAL CASE - the first column is 1 0 0 ...
96  * thus, the first iteration of both loops does nothing,
97  * so it is skipped
98  */
99  for (i = 1; i <= ckt->CKTorder; i++) {
100  for (j = i+1; j <= ckt->CKTorder; j++) {
101  mat[j][i] /= mat[i][i];
102  for (k = i+1; k <= ckt->CKTorder; k++) {
103  mat[j][k] -= mat[j][i]*mat[i][k];
104  }
105  }
106  }
107  /* forward substitution */
108  for (i = 1; i <= ckt->CKTorder; i++) {
109  for (j = i+1; j <= ckt->CKTorder; j++) {
110  ckt->CKTag[j] = ckt->CKTag[j]-mat[j][i]*ckt->CKTag[i];
111  }
112  }
113  /* backward substitution */
114  ckt->CKTag[ckt->CKTorder] /= mat[ckt->CKTorder][ckt->CKTorder];
115  for (i = ckt->CKTorder-1; i >= 0; i--) {
116  for (j = i+1; j <= ckt->CKTorder; j++) {
117  ckt->CKTag[i] = ckt->CKTag[i] - mat[i][j]*ckt->CKTag[j];
118  }
119  ckt->CKTag[i] /= mat[i][i];
120  }
121  return (OK);
122 }
#define E_ORDER
Definition: sperror.h:19
#define TRAPEZOIDAL
Definition: cktdefs.h:92
int bzero(char *ptr, int num)
Definition: string.c:357
#define OK
Definition: iferrmsg.h:17
#define GEAR
Definition: cktdefs.h:93
static int ni_gearcof()
double CKTag[7]
Definition: cktdefs.h:83
int NIcomCof(CKTcircuit *ckt)
Definition: nicomcof.c:22
#define E_METHOD
Definition: sperror.h:20