Jspice3
ckttrunc.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  /* CKTtrunc(ckt)
9  * this is a driver program to iterate through all the various
10  * truncation error functions provided for the circuit elements in the
11  * given circuit
12  */
13 
14 #include "spice.h"
15 #include <stdio.h>
16 #include <math.h>
17 #include "devdefs.h"
18 #include "util.h"
19 #include "sperror.h"
20 #include "cktext.h"
21 
22 
23 extern SPICEdev *DEVices[];
24 
25 int
26 CKTtrunc(ckt,timeStep)
27 
28 CKTcircuit *ckt;
29 double *timeStep;
30 {
31  double timetemp;
32  double temp;
33  struct sCKTmodHead *mh;
34  int error;
35  int (*func)();
36  double dd[6];
37  double *dtmp;
38 
39  timetemp = HUGE;
40 
41  /* For trapezoid integration, cache the parameters for
42  * fast evaluation.
43  */
44  if (ckt->CKTintegrateMethod == TRAPEZOIDAL) {
45  if (ckt->CKTorder == 1) {
46 
47  dd[0] = 1/ckt->CKTdeltaOld[0];
48  dd[1] = 1/ckt->CKTdeltaOld[1];
49  dd[2] = .5/(ckt->CKTdeltaOld[0] + ckt->CKTdeltaOld[1]);
50 
51  dd[0] *= dd[2];
52  dd[1] *= dd[2];
53  }
54  else {
55  dd[0] = 1/ckt->CKTdeltaOld[0];
56  dd[1] = 1/ckt->CKTdeltaOld[1];
57  dd[2] = 1/ckt->CKTdeltaOld[2];
58  dd[3] = 1/(ckt->CKTdeltaOld[0] + ckt->CKTdeltaOld[1]);
59  dd[4] = 1/(ckt->CKTdeltaOld[1] + ckt->CKTdeltaOld[2]);
60  dd[5] = .08333333333/(ckt->CKTdeltaOld[0] + ckt->CKTdeltaOld[1] +
61  ckt->CKTdeltaOld[2]);
62 
63  dd[3] *= dd[5];
64  dd[4] *= dd[5];
65  dd[0] *= dd[3];
66  dd[1] *= dd[3]+dd[4];
67  dd[2] *= dd[4];
68  }
69  }
70  /* cache this */
71  dd[5] = ckt->CKTreltol/ckt->CKTdelta;
72 
73  /* temporary use of CKTsols[0] to pass coeffs (to CKTterr()) */
74  dtmp = ckt->CKTsols[0];
75  ckt->CKTsols[0] = dd;
76 
77  for (mh = ckt->CKTheadList; mh != NULL; mh = mh->next) {
78  if ((func = DEVices[mh->type]->DEVtrunc) != NULL) {
79 
80 #ifdef STEPDEBUG
81  temp = timetemp;
82 #endif /* STEPDEBUG */
83  error = (*func)(mh->head,ckt,&timetemp);
84  if (error) {
85  return (error);
86  }
87 #ifdef STEPDEBUG
88  if (temp != timetemp) {
89  printf("timestep cut by device type %s from %g to %g\n",
90  DEVices[mh->type]->DEVpublic.name, temp,timetemp);
91  }
92 #endif /* STEPDEBUG */
93  }
94  }
95 
96  /* Here we normalize to integration order ( not in CKTterr() ) to
97  * avoid the math operation at each call. This works directly for
98  * all devices which simply call CKTterr() in the trunc functions.
99  *
100  * !!!> The LTRAtrunc() code needs fixing if you change this <!!!
101  *
102  */
103  if (ckt->CKTorder == 2) {
104  timetemp = sqrt(timetemp);
105  }
106  else if (ckt->CKTorder > 2) {
107  timetemp = exp(log(timetemp)/ckt->CKTorder);
108  }
109 
110  ckt->CKTsols[0] = dtmp;
111  temp = *timeStep;
112  temp += temp;
113  *timeStep = MIN(temp,timetemp);
114  return(OK);
115 }
116 
SPICEdev * DEVices[]
Definition: sconfig.c:109
struct sCKTmodHead * next
Definition: cktdefs.h:58
#define MIN(a, b)
Definition: spdefs.h:136
#define TRAPEZOIDAL
Definition: cktdefs.h:92
IFdevice DEVpublic
Definition: devdefs.h:44
#define OK
Definition: iferrmsg.h:17
#define NULL
Definition: spdefs.h:121
char * name
Definition: ifsim.h:293
Definition: fteparse.h:37
int type
Definition: cktdefs.h:56
int CKTtrunc(CKTcircuit *ckt, double *timeStep)
Definition: ckttrunc.c:26
GENmodel * head
Definition: cktdefs.h:57
int(* DEVtrunc)()
Definition: devdefs.h:96
#define HUGE
Definition: spice.h:128