Jspice3
acan.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  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 #define ANAL_EXT
9 
10 #include "spice.h"
11 #include <stdio.h>
12 #include <math.h>
13 #include "srcdefs.h"
14 #include "sperror.h"
15 #include "outdata.h"
16 #include "acdefs.h"
17 #include "util.h"
18 #include "cktext.h"
19 #include "niext.h"
20 
21 #ifdef __STDC__
22 static int ac_init(CKTcircuit*,struct sOUTdata*);
23 static int ac_dcoperation(CKTcircuit*,struct sOUTdata*,int);
24 static int ac_operation(CKTcircuit*,struct sOUTdata*,int);
25 #else
26 static int ac_init();
27 static int ac_dcoperation();
28 static int ac_operation();
29 #endif
30 
31 
32 int
33 ACan(cktp,restart)
34 
35 GENERIC *cktp;
36 int restart;
37 {
38  CKTcircuit *ckt = (CKTcircuit *)cktp;
39  static struct sOUTdata outd;
40  int error;
41 
42  if (ckt->CKTjjPresent) {
43  (*(SPfrontEnd->IFerror))(ERR_FATAL,
44  "AC analysis not possible with Josephson junctions", NULL);
45  return (OK);
46  }
47 
48  if (restart) {
49  error = ac_init(ckt,&outd);
50  if (error)
51  return (error);
52  }
53  error = DCTloop(ac_dcoperation,ckt,restart,
54  &((ACAN*)ckt->CKTcurJob)->DC,&outd);
55  if (error == E_PAUSE)
56  return (error);
57 
58  (*(SPfrontEnd->OUTendPlot))(*outd.plotPtr);
59  return (error);
60 }
61 
62 
63 static int
64 ac_dcoperation(ckt,outd,restart)
65 
66 CKTcircuit *ckt;
67 struct sOUTdata *outd;
68 int restart;
69 {
70  int error;
71 
72  error = CKTic(ckt);
73  if (error)
74  return (error);
75 
76  error = CKTop(ckt,
79  ckt->CKTdcMaxIter);
80  if (error)
81  return (error);
82 
83  ckt->CKTmode = MODEDCOP | MODEINITSMSIG;
84 
85  error = CKTload(ckt);
86  if (error)
87  return (error);
88 
89  error = ACloop(ac_operation,ckt,restart,
90  &((ACAN*)ckt->CKTcurJob)->AC,outd);
91  if (error)
92  return (error);
93 
94  return (OK);
95 }
96 
97 
98 static int
99 ac_init(ckt,outd)
100 
101 CKTcircuit *ckt;
102 struct sOUTdata *outd;
103 {
104  int i;
105  int code;
106  int error;
107  ACAN *job = (ACAN*)ckt->CKTcurJob;
108 
109  if (job->DC.eltName[0] != NULL) {
110  /* DC source was given */
111  code = CKTtypelook("Source");
112 
113  for (i = 0; i <= job->DC.nestLevel; i++) {
114  SRCinstance *here;
115 
116  here = (SRCinstance*)NULL;
117  error = CKTfndDev((GENERIC*)ckt,&code,(GENERIC**)&here,
118  job->DC.eltName[i], (GENERIC *)NULL,(IFuid)NULL);
119 
120  if (error) {
121  (*(SPfrontEnd->IFerror))(ERR_FATAL,
122  "DCtrCurv: source %s not in circuit",
123  &(job->DC.eltName[i]));
124  return (E_NOTFOUND);
125  }
126  job->DC.elt[i] = (GENinstance*)here;
127  job->DC.vsave[i] = here->SRCdcValue;
128  }
129  }
130 
131  error = CKTnames(ckt,&outd->numNames,&outd->dataNames);
132  if (error)
133  return (error);
134 
135  (*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&outd->refName,(IFuid)NULL,
136  "frequency", UID_OTHER,(GENERIC **)NULL);
137 
138  outd->circuitPtr = (GENERIC *)ckt;
139  outd->analysisPtr = (GENERIC*)ckt->CKTcurJob;
140  outd->analName = ckt->CKTcurJob->JOBname;
141  outd->refType = IF_REAL;
142  outd->dataType = IF_COMPLEX;
143  outd->plotPtr = &job->ACplot;
144  outd->numPts = 1;
145  outd->initValue = ((ACAN*)ckt->CKTcurJob)->AC.fstart;
146  outd->finalValue = ((ACAN*)ckt->CKTcurJob)->AC.fstop;
147  outd->step = 0;
148  outd->count = 0;
149  (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)outd);
150  return (OK);
151 }
152 
153 
154 /* ARGSUSED */
155 static int
156 ac_operation(ckt,outd,restart)
157 
158 CKTcircuit *ckt;
159 struct sOUTdata *outd;
160 int restart;
161 {
162  int error;
163 
164  error = NIacIter(ckt);
165  if (error)
166  return (error);
167 
168  error = CKTacDump(ckt,ckt->CKTomega/(2*M_PI),*outd->plotPtr);
169  if (error)
170  return (error);
171  outd->count++;
172  return (OK);
173 }
174 
175 
176 int
177 ACloop(func,ckt,restart,ac,outd)
178 
179 #ifdef __STDC__
180 int (*func)(CKTcircuit*,struct sOUTdata*,int);
181 #else
182 int (*func)();
183 #endif
184 CKTcircuit *ckt;
185 int restart;
186 struct sACprms *ac;
187 struct sOUTdata *outd;
188 {
189  double freq;
190  double freqTol, freqDel;
191  int error;
192 
193  switch (ac->stepType) {
194  case DECADE:
195  if (ac->fstart <= 0.0)
196  ac->fstart = 1e-3;
197  if (ac->fstop <= ac->fstart)
198  ac->fstop = 10.0 * ac->fstart;
199  freqDel = exp(log(10.0)/ac->numSteps);
200  freqTol = freqDel * ac->fstop * ckt->CKTreltol;
201  case OCTAVE:
202  if (ac->fstart <= 0.0)
203  ac->fstart = 1e-3;
204  if (ac->fstop <= ac->fstart)
205  ac->fstop = 2.0 * ac->fstart;
206  freqDel = exp(log(2.0)/ac->numSteps);
207  freqTol = freqDel * ac->fstop * ckt->CKTreltol;
208  break;
209  case LINEAR:
210  freqDel = (ac->fstop - ac->fstart)/(ac->numSteps+1);
211  freqTol = freqDel * ckt->CKTreltol;
212  break;
213  case DCSTEP:
214  return ( (*func)(ckt,outd,restart) );
215  default:
216  return (E_BADPARM);
217  }
218 
219  if (restart) {
220  /* reset static variables */
221  ac->fsave = ac->fstart;
222  }
223 
224  freq = ac->fsave;
225 
226  while (freq <= ac->fstop + freqTol) {
227 
228  if ( (*(SPfrontEnd->IFpauseTest))() ) {
229  /* user asked us to pause via an interrupt */
230  ac->fsave = freq;
231  return (E_PAUSE);
232  }
233  ckt->CKTomega = 2.0 * M_PI * freq;
234  ckt->CKTmode = MODEAC;
235 
236  error = (*func)(ckt,outd,restart);
237  if (error) {
238  ac->fsave = freq;
239  return (error);
240  }
241  if (*SPfrontEnd->OUTendit) {
242  *SPfrontEnd->OUTendit = 0;
243  return (OK);
244  }
245 
246  /* increment frequency */
247 
248  switch (ac->stepType) {
249  case DECADE:
250  case OCTAVE:
251  freq *= freqDel;
252  if (freqDel == 1)
253  return (OK);
254  break;
255  case LINEAR:
256  freq += freqDel;
257  if (freqDel == 0)
258  return (OK);
259  break;
260  default:
261  return (E_INTERN);
262  }
263  }
264 
265  return (OK);
266 }
267 
268 
269 int
271 
272 CKTcircuit *ckt;
273 /* CKTacLoad(ckt)
274  * this is a driver program to iterate through all the various
275  * ac load functions provided for the circuit elements in the
276  * given circuit
277  */
278 {
279  extern SPICEdev *DEVices[];
280  int i;
281  int size;
282  int error;
283  struct sCKTmodHead *mh;
284  int (*func)();
285 
286  size = spGetSize(ckt->CKTmatrix,1);
287  for (i = 0; i <= size; i++) {
288  *(ckt->CKTrhs+i) = 0;
289  *(ckt->CKTirhs+i) = 0;
290  }
291  spSetComplex(ckt->CKTmatrix);
292  spClear(ckt->CKTmatrix);
293 
294  for (mh = ckt->CKTheadList; mh != NULL; mh = mh->next) {
295  if ((func = DEVices[mh->type]->DEVacLoad) != NULL) {
296  error = (*func)(mh->head,ckt);
297  if (error)
298  return (error);
299  }
300  }
301  return (OK);
302 }
#define E_INTERN
Definition: sperror.h:15
#define E_PAUSE
Definition: iferrmsg.h:15
int numPts
Definition: outdata.h:22
#define MODEAC
Definition: cktdefs.h:146
double initValue
Definition: outdata.h:24
#define IF_COMPLEX
Definition: ifsim.h:109
int CKTacLoad(CKTcircuit *ckt)
Definition: acan.c:270
int CKTnames()
#define MODEDCTRANCURVE
Definition: cktdefs.h:152
int refType
Definition: outdata.h:17
int(* DEVacLoad)()
Definition: devdefs.h:98
struct sCKTmodHead * next
Definition: cktdefs.h:58
IFuid * dataNames
Definition: outdata.h:19
int ACan(GENERIC *cktp, int restart)
Definition: acan.c:33
int * OUTendit
Definition: ifsim.h:513
IFuid analName
Definition: outdata.h:15
if(TDesc==NULL)
Definition: cd.c:1326
SPICEdev * DEVices[]
Definition: sconfig.c:109
int numNames
Definition: outdata.h:18
#define MODEINITFLOAT
Definition: cktdefs.h:156
#define ERR_FATAL
Definition: ifsim.h:518
struct sDCTprms DC
Definition: acdefs.h:21
#define M_PI
Definition: spice.h:132
int ACloop(int(*func)(), CKTcircuit *ckt, int restart, struct sACprms *ac, struct sOUTdata *outd)
Definition: acan.c:177
#define E_NOTFOUND
Definition: iferrmsg.h:35
int DCTloop(int(*func)(), CKTcircuit *ckt, int restart, struct sDCTprms *dc, struct sOUTdata *outd)
Definition: dctan.c:177
static double e
Definition: vectors.c:17
IFfrontEnd * SPfrontEnd
Definition: main.c:917
#define E_BADPARM
Definition: iferrmsg.h:26
double SRCdcValue
Definition: srcdefs.h:77
int CKTtypelook()
double step
Definition: outdata.h:26
#define OCTAVE
Definition: analysis.h:48
IFuid eltName[DCTNESTLEVEL]
Definition: analysis.h:34
double fsave
Definition: analysis.h:62
#define OK
Definition: iferrmsg.h:17
GENERIC * IFuid
Definition: ifsim.h:72
int CKTacDump()
static int ac_init()
#define NULL
Definition: spdefs.h:121
GENERIC * circuitPtr
Definition: outdata.h:13
#define LINEAR
Definition: analysis.h:49
#define MODEINITSMSIG
Definition: cktdefs.h:159
Definition: acdefs.h:15
int CKTjjPresent
Definition: cktdefs.h:168
int numSteps
Definition: analysis.h:63
static int ac_dcoperation()
int CKTload()
int spGetSize()
double vsave[DCTNESTLEVEL]
Definition: analysis.h:30
void spClear()
int CKTic()
#define IF_REAL
Definition: ifsim.h:108
double finalValue
Definition: outdata.h:25
Definition: fteparse.h:37
#define DCSTEP
Definition: analysis.h:46
void spSetComplex()
int CKTop()
int type
Definition: cktdefs.h:56
double fstop
Definition: analysis.h:61
int count
Definition: outdata.h:23
#define UID_OTHER
Definition: ifsim.h:85
GENERIC * analysisPtr
Definition: outdata.h:14
GENERIC * ACplot
Definition: acdefs.h:19
int CKTfndDev()
GENmodel * head
Definition: cktdefs.h:57
int NIacIter()
#define DECADE
Definition: analysis.h:47
double fstart
Definition: analysis.h:60
static int ac_operation()
#define MODEDCOP
Definition: cktdefs.h:150
GENERIC ** plotPtr
Definition: outdata.h:21
JOB * CKTcurJob
Definition: cktdefs.h:216
IFuid refName
Definition: outdata.h:16
#define MODEINITJCT
Definition: cktdefs.h:157
int stepType
Definition: analysis.h:64
int nestLevel
Definition: analysis.h:35
GENinstance * elt[DCTNESTLEVEL]
Definition: analysis.h:33
char GENERIC
Definition: ifsim.h:27
int dataType
Definition: outdata.h:20