Jspice3
nicomcof.c File Reference
#include "spice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "sperror.h"
#include "niext.h"
Include dependency graph for nicomcof.c:

Go to the source code of this file.

Functions

static int ni_gearcof ()
 
int NIcomCof (CKTcircuit *ckt)
 
static int ni_gearcof (CKTcircuit *ckt)
 

Function Documentation

static int ni_gearcof ( )
static
static int ni_gearcof ( CKTcircuit ckt)
static

Definition at line 58 of file nicomcof.c.

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
double CKTdelta
Definition: cktdefs.h:78
int bzero(char *ptr, int num)
Definition: string.c:357
int CKTorder
Definition: cktdefs.h:87
#define OK
Definition: iferrmsg.h:17
double CKTag[7]
Definition: cktdefs.h:83
double CKTdeltaOld[7]
Definition: cktdefs.h:79
int NIcomCof ( CKTcircuit ckt)

Definition at line 22 of file nicomcof.c.

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 }
#define E_ORDER
Definition: sperror.h:19
double CKTdelta
Definition: cktdefs.h:78
#define TRAPEZOIDAL
Definition: cktdefs.h:92
int CKTorder
Definition: cktdefs.h:87
#define OK
Definition: iferrmsg.h:17
#define GEAR
Definition: cktdefs.h:93
static int ni_gearcof()
double CKTag[7]
Definition: cktdefs.h:83
#define E_METHOD
Definition: sperror.h:20
int CKTintegrateMethod
Definition: cktdefs.h:89