Jspice3
distan.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1988 Jaijeet S. Roychowhury
5  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 #include "spice.h"
9 #include <stdio.h>
10 #include <math.h>
11 #include "srcdefs.h"
12 #include "distodef.h"
13 #include "sperror.h"
14 #include "outdata.h"
15 #include "util.h"
16 #include "cktext.h"
17 #include "distoext.h"
18 #include "niext.h"
19 
20 
21 static void
23 
24 double **a, **b;
25 {
26  double *c;
27 
28  c = *a;
29  *a = *b;
30  *b = c;
31 }
32 
33 
34 static void
35 DmemAlloc(a,size)
36 
37 double **a;
38 int size;
39 
40 {
41  *a = (double *) MALLOC( sizeof(double) * size );
42 }
43 
44 
45 static void
46 DstorAlloc(header,size)
47 
48 double ***header;
49 int size;
50 {
51  *header = (double **) MALLOC( sizeof(double *)*size);
52 }
53 
54 
55 #ifdef STDC
56 extern int CKTdisto(CKTcircuit*, int);
57 extern int DkerProc(int,double*,double*,int,DISTOan*);
58 #else
59 extern int CKTdisto();
60 extern int DkerProc();
61 #endif
62 
63 
64 int
65 DISTOan(cktp,restart)
66 
67 GENERIC *cktp;
68 int restart;
69 {
70 
71  CKTcircuit *ckt = (CKTcircuit *)cktp;
72  struct sOUTdata outd;
73  double freq;
74  static double freqTol; /* tolerence for finding final frequency */
75  static int NoOfPoints;
76  static int size;
77  static int displacement;
78  int error;
79  double omegadelta;
80  long save;
81  int save1;
82  int i;
83  int numNames;
84  IFuid *nameList;
85  IFuid freqUid;
86  GENERIC *acPlot = NULL;
87  DISTOAN* job = (DISTOAN *) (ckt->CKTcurJob);
88  static char *nof2src = "No source with f2 distortion input";
89 #ifdef DISTODEBUG
90  double time,time1;
91 #endif
92 
93  if (ckt->CKTjjPresent) {
94  (*(SPfrontEnd->IFerror))(ERR_FATAL,
95  "Distortion analysis not possible with Josephson junctions",
96  NULL);
97  return (OK);
98  }
99 
100  /* start at beginning */
101 
102 #ifdef D_DBG_BLOCKTIMES
103 time1 = (*(SPfrontEnd->IFseconds))();
104 #endif
105  switch(job->DstepType) {
106 
107  case DECADE:
108  job->DfreqDelta = exp(log(10.0)/job->DnumSteps);
109  freqTol = job->DfreqDelta *
110  job->DstopF1 * ckt->CKTreltol;
111  NoOfPoints = 1 + floor((job->DnumSteps) / log(10.0) *
112  log((job->DstopF1+freqTol)/(job->DstartF1)));
113  break;
114 
115  case OCTAVE:
116  job->DfreqDelta = exp(log(2.0)/job->DnumSteps);
117  freqTol = job->DfreqDelta *
118  job->DstopF1 * ckt->CKTreltol;
119  NoOfPoints = 1 + floor((job->DnumSteps) / log(2.0) *
120  log((job->DstopF1+freqTol)/(job->DstartF1)));
121  break;
122 
123  case LINEAR:
124  job->DfreqDelta = (job->DstopF1 - job->DstartF1)/
125  (job->DnumSteps+1);
126  freqTol = job->DfreqDelta * ckt->CKTreltol;
127  NoOfPoints = job->DnumSteps+ 1 + floor(freqTol/(job->DfreqDelta));
128  break;
129 
130  default:
131  return(E_BADPARM);
132  }
133 
134  /* freqUid is used as temporary storage */
135  freqUid = job->JOBname;
136  job->JOBname = "DISTORTION - operating pt.";
137  error = DCOan(ckt,0);
138  if (error) return(error);
139 
140  job->JOBname = freqUid;
141 
142 #ifdef D_DBG_BLOCKTIMES
143 time1 = (*(SPfrontEnd->IFseconds))() - time1;
144 printf("Time for initial work (including op. pt.): %g seconds \n", time1);
145 #endif
146 
147 #ifdef D_DBG_BLOCKTIMES
148 time1 = (*(SPfrontEnd->IFseconds))();
149 #endif
150 
151  error = CKTdisto(ckt,D_SETUP);
152 
153 #ifdef D_DBG_BLOCKTIMES
154 time1 = (*(SPfrontEnd->IFseconds))() - time1;
155 printf("Time outside D_SETUP: %g seconds \n", time1);
156 #endif
157 
158  if (error) return(error);
159 
160  displacement = 0;
161 
162 #ifdef D_DBG_BLOCKTIMES
163 time1 = (*(SPfrontEnd->IFseconds))();
164 #endif
165 
166  freq = job->DstartF1;
167  if (job->Df2wanted) {
168  /*
169  omegadelta = 2.0 * M_PI * freq *(1. - job->Df2ovrF1);
170  */
171  /* keeping f2 const to be compatible with spectre */
172  job->Domega2 = 2.0 * M_PI * freq * job->Df2ovrF1;
173  }
174  DstorAlloc(&(job->r1H1stor),NoOfPoints+2);
175  DstorAlloc(&(job->r2H11stor),NoOfPoints+2);
176  DstorAlloc(&(job->i1H1stor),NoOfPoints+2);
177  DstorAlloc(&(job->i2H11stor),NoOfPoints+2);
178  size = spGetSize(ckt->CKTmatrix,1);
179 
180  if (!job->r1H1ptr) {
181  DmemAlloc( &(job->r1H1ptr) , size+2);
182  if (!job->r1H1ptr) return (E_NOMEM);
183  }
184 
185  if (!job->r2H11ptr) {
186  DmemAlloc( &(job->r2H11ptr) , size+2);
187  if (!job->r2H11ptr) return (E_NOMEM);
188  }
189 
190  if (!job->i1H1ptr) {
191  DmemAlloc( &(job->i1H1ptr) , size+2);
192  if (!job->i1H1ptr) return (E_NOMEM);
193  }
194 
195  if (!job->i2H11ptr) {
196  DmemAlloc( &(job->i2H11ptr) , size+2);
197  if (!job->i2H11ptr) return (E_NOMEM);
198  }
199 
200  if (!job->Df2wanted) {
201  DstorAlloc(&(job->r3H11stor),NoOfPoints+2);
202  DstorAlloc(&(job->i3H11stor),NoOfPoints+2);
203  if (!job->r3H11ptr) {
204  DmemAlloc(&(job->r3H11ptr), size+2);
205  if (!job->r3H11ptr) return (E_NOMEM);
206  }
207  if (!job->i3H11ptr) {
208  DmemAlloc(&(job->i3H11ptr), size+2);
209  if (!job->i3H11ptr) return (E_NOMEM);
210  }
211  }
212  else {
213  DstorAlloc(&(job->r1H2stor),NoOfPoints+2);
214  DstorAlloc(&(job->i1H2stor),NoOfPoints+2);
215  DstorAlloc(&(job->r2H12stor),NoOfPoints+2);
216  DstorAlloc(&(job->i2H12stor),NoOfPoints+2);
217  DstorAlloc(&(job->r2H1m2stor),NoOfPoints+2);
218  DstorAlloc(&(job->i2H1m2stor),NoOfPoints+2);
219  DstorAlloc(&(job->r3H1m2stor),NoOfPoints+2);
220  DstorAlloc(&(job->i3H1m2stor),NoOfPoints+2);
221  if (!job->r1H2ptr) {
222  DmemAlloc(&(job->r1H2ptr), size+2);
223  if (!job->r1H2ptr) return (E_NOMEM);
224  }
225  if (!job->r2H12ptr) {
226  DmemAlloc(&(job->r2H12ptr) , size+2);
227  if (! job->r2H12ptr) return (E_NOMEM);
228  }
229  if (!job->r2H1m2ptr) {
230  DmemAlloc(&(job->r2H1m2ptr), size+2);
231  if (!job->r2H1m2ptr) return (E_NOMEM);
232  }
233  if (!job->r3H1m2ptr) {
234  DmemAlloc(&(job->r3H1m2ptr), size+2);
235  if (!job->r3H1m2ptr) return (E_NOMEM);
236  }
237  if (!job->i1H2ptr) {
238  DmemAlloc(&(job->i1H2ptr), size+2);
239  if (!job->i1H2ptr) return (E_NOMEM);
240  }
241  if (! job->i2H12ptr) {
242  DmemAlloc(&(job->i2H12ptr), size+2);
243  if (!job->i2H12ptr) return (E_NOMEM);
244  }
245  if (!job->i2H1m2ptr) {
246  DmemAlloc(&(job->i2H1m2ptr), size+2);
247  if (!job->i2H1m2ptr) return (E_NOMEM);
248  }
249  if (!job->i3H1m2ptr) {
250  DmemAlloc(&(job->i3H1m2ptr), size+2);
251  if (!job->i3H1m2ptr) return (E_NOMEM);
252  }
253  }
254 
255 #ifdef D_DBG_BLOCKTIMES
256 time1 = (*(SPfrontEnd->IFseconds))() - time1;
257 printf("Time for other setup (storage allocation etc.): %g seconds \n", time1);
258 #endif
259 
260 #ifdef D_DBG_BLOCKTIMES
261 time1 = (*(SPfrontEnd->IFseconds))();
262 #endif
263 
264  while(freq <= job->DstopF1+freqTol) {
265 
266  /*
267  if( (*(SPfrontEnd->IFpauseTest))() ) {
268  job->DsaveF1 = freq;
269  return(E_PAUSE);
270  }
271  */
272 
273  ckt->CKTomega = 2.0 * M_PI * freq;
274  job->Domega1 = ckt->CKTomega;
275  ckt->CKTmode = MODEAC;
276 
277 #ifdef D_DBG_SMALLTIMES
278 time = (*(SPfrontEnd->IFseconds))();
279 #endif
280 
281  error = CKTacLoad(ckt);
282 
283 #ifdef D_DBG_SMALLTIMES
284 time = (*(SPfrontEnd->IFseconds))() - time;
285 printf("Time for CKTacLoad: %g seconds \n", time);
286 #endif
287 
288  if (error) return(error);
289 
290 #ifdef D_DBG_SMALLTIMES
291 time = (*(SPfrontEnd->IFseconds))();
292 #endif
293 
294  error = CKTdisto(ckt,D_RHSF1);
295  /* sets up the RHS vector
296  for all inputs corresponding to F1 */
297 
298 #ifdef D_DBG_SMALLTIMES
299 time = (*(SPfrontEnd->IFseconds))() - time;
300 printf("Time outside DISTO_RHSFIX: %g seconds \n", time);
301 #endif
302 
303  if (error) return(error);
304 
305 #ifdef D_DBG_SMALLTIMES
306 time = (*(SPfrontEnd->IFseconds))();
307 #endif
308 
309  error = NIdIter(ckt);
310 
311 #ifdef D_DBG_SMALLTIMES
312 time = (*(SPfrontEnd->IFseconds))() - time;
313 printf("Time for NIdIter: %g seconds \n", time);
314 #endif
315 
316  if (error) return(error);
317  DISswap(&(ckt->CKTrhsOld),&(job->r1H1ptr));
318  DISswap(&(ckt->CKTirhsOld),&(job->i1H1ptr));
319 
320  ckt->CKTomega *= 2;
321  error = CKTacLoad(ckt);
322  if (error) return(error);
323 
324 #ifdef D_DBG_SMALLTIMES
325 time = (*(SPfrontEnd->IFseconds))();
326 #endif
327 
328  error = CKTdisto(ckt,D_TWOF1);
329 
330 #ifdef D_DBG_SMALLTIMES
331 time = (*(SPfrontEnd->IFseconds))() - time;
332 printf("Time outside D_TWOF1: %g seconds \n", time);
333 #endif
334 
335  if (error) return(error);
336  error = NIdIter(ckt);
337  if (error) return(error);
338  DISswap(&(ckt->CKTrhsOld),&(job->r2H11ptr));
339  DISswap(&(ckt->CKTirhsOld),&(job->i2H11ptr));
340 
341  if (!job->Df2wanted) {
342 
343  ckt->CKTomega = 3 * job->Domega1;
344  error = CKTacLoad(ckt);
345  if (error) return(error);
346 
347 #ifdef D_DBG_SMALLTIMES
348 time = (*(SPfrontEnd->IFseconds))();
349 #endif
350 
351  error = CKTdisto(ckt,D_THRF1);
352 
353 #ifdef D_DBG_SMALLTIMES
354 time = (*(SPfrontEnd->IFseconds))() - time;
355 printf("Time outside D_THRF1: %g seconds \n", time);
356 #endif
357 
358  if (error) return(error);
359  error = NIdIter(ckt);
360  if (error) return(error);
361  DISswap(&(ckt->CKTrhsOld),&(job->r3H11ptr));
362  DISswap(&(ckt->CKTirhsOld),&(job->i3H11ptr));
363  }
364  else if (job->Df2given) {
365 
366  /*
367  ckt->CKTomega = job->Domega1 - omegadelta;
368  job->Domega2 = ckt->CKTomega;
369  */
370  ckt->CKTomega = job->Domega2;
371  error = CKTacLoad(ckt);
372  if (error) return(error);
373 
374 #ifdef D_DBG_SMALLTIMES
375 time = (*(SPfrontEnd->IFseconds))();
376 #endif
377 
378  error = CKTdisto(ckt,D_RHSF2);
379 
380 #ifdef D_DBG_SMALLTIMES
381 time = (*(SPfrontEnd->IFseconds))() - time;
382 printf("Time outside DISTO_RHSFIX: %g seconds \n", time);
383 #endif
384 
385  if (error) return(error);
386  error = NIdIter(ckt);
387  if (error) return(error);
388  DISswap(&(ckt->CKTrhsOld),&(job->r1H2ptr));
389  DISswap(&(ckt->CKTirhsOld),&(job->i1H2ptr));
390 
391  ckt->CKTomega = job->Domega1 + job->Domega2;
392  error = CKTacLoad(ckt);
393  if (error) return(error);
394 
395 #ifdef D_DBG_SMALLTIMES
396 time = (*(SPfrontEnd->IFseconds))();
397 #endif
398 
399  error = CKTdisto(ckt,D_F1PF2);
400 
401 #ifdef D_DBG_SMALLTIMES
402 time = (*(SPfrontEnd->IFseconds))() - time;
403 printf("Time outside D_F1PF2: %g seconds \n", time);
404 #endif
405 
406  if (error) return(error);
407  error = NIdIter(ckt);
408  if (error) return(error);
409  DISswap(&(ckt->CKTrhsOld),&(job->r2H12ptr));
410  DISswap(&(ckt->CKTirhsOld),&(job->i2H12ptr));
411 
412  ckt->CKTomega = job->Domega1 - job->Domega2;
413  error = CKTacLoad(ckt);
414  if (error) return(error);
415 
416 #ifdef D_DBG_SMALLTIMES
417 time = (*(SPfrontEnd->IFseconds))();
418 #endif
419 
420  error = CKTdisto(ckt,D_F1MF2);
421 
422 #ifdef D_DBG_SMALLTIMES
423 time = (*(SPfrontEnd->IFseconds))() - time;
424 printf("Time outside D_F1MF2: %g seconds \n", time);
425 #endif
426 
427  if (error) return(error);
428  error = NIdIter(ckt);
429  if (error) return(error);
430  DISswap(&(ckt->CKTrhsOld),&(job->r2H1m2ptr));
431  DISswap(&(ckt->CKTirhsOld),&(job->i2H1m2ptr));
432 
433  ckt->CKTomega = 2*job->Domega1 - job->Domega2;
434  error = CKTacLoad(ckt);
435  if (error) return(error);
436 
437 #ifdef D_DBG_SMALLTIMES
438 time = (*(SPfrontEnd->IFseconds))();
439 #endif
440 
441  error = CKTdisto(ckt,D_2F1MF2);
442 
443 #ifdef D_DBG_SMALLTIMES
444 time = (*(SPfrontEnd->IFseconds))() - time;
445 printf("Time outside D_2F1MF2: %g seconds \n", time);
446 #endif
447 
448  if (error) return(error);
449  error = NIdIter(ckt);
450  if (error) return(error);
451  DISswap(&(ckt->CKTrhsOld),&(job->r3H1m2ptr));
452  DISswap(&(ckt->CKTirhsOld),&(job->i3H1m2ptr));
453  }
454  else {
455  errMsg = MALLOC(strlen(nof2src)+1);
456  strcpy(errMsg,nof2src);
457  return(E_NOF2SRC);
458  }
459 
460  DmemAlloc( &(job->r1H1stor[displacement]),size);
461  DISswap(&(job->r1H1stor[displacement]),&(job->r1H1ptr));
462  job->r1H1stor[displacement][0]=freq;
463  DmemAlloc( &(job->r2H11stor[displacement]),size);
464  DISswap(&(job->r2H11stor[displacement]),&((job->r2H11ptr)));
465  job->r2H11stor[displacement][0]=freq;
466  DmemAlloc( &(job->i1H1stor[displacement]),size);
467  DISswap(&(job->i1H1stor[displacement]),&((job->i1H1ptr)));
468  job->i1H1stor[displacement][0]=0.0;
469  DmemAlloc( &(job->i2H11stor[displacement]),size);
470  DISswap(&(job->i2H11stor[displacement]),&((job->i2H11ptr)));
471  job->i2H11stor[displacement][0]=0.0;
472 
473  if (! (job->Df2wanted)) {
474  DmemAlloc( &(job->r3H11stor[displacement]),size);
475  DISswap(&(job->r3H11stor[displacement]),&((job->r3H11ptr)));
476  job->r3H11stor[displacement][0]=freq;
477  DmemAlloc( &(job->i3H11stor[displacement]),size);
478  DISswap(&(job->i3H11stor[displacement]),&((job->i3H11ptr)));
479  job->i3H11stor[displacement][0]=0.0;
480  }
481  else {
482  DmemAlloc( &(job->r1H2stor[displacement]),size);
483  DISswap(&(job->r1H2stor[displacement]),&((job->r1H2ptr)));
484  job->r1H2stor[displacement][0]=freq;
485  DmemAlloc( &(job->r2H12stor[displacement]),size);
486  DISswap(&(job->r2H12stor[displacement]),&((job->r2H12ptr)));
487  job->r2H12stor[displacement][0]=freq;
488  DmemAlloc( &(job->r2H1m2stor[displacement]),size);
489  DISswap(&(job->r2H1m2stor[displacement]),&((job->r2H1m2ptr)));
490  job->r2H1m2stor[displacement][0]=freq;
491  DmemAlloc( &(job->r3H1m2stor[displacement]),size);
492  DISswap(&(job->r3H1m2stor[displacement]),&((job->r3H1m2ptr)));
493  job->r3H1m2stor[displacement][0]=freq;
494 
495  DmemAlloc( &(job->i1H2stor[displacement]),size);
496  DISswap(&(job->i1H2stor[displacement]),&((job->i1H2ptr)));
497  job->i1H2stor[displacement][0]=0.0;
498  DmemAlloc( &(job->i2H12stor[displacement]),size);
499  DISswap(&(job->i2H12stor[displacement]),&((job->i2H12ptr)));
500  job->i2H12stor[displacement][0]=0.0;
501  DmemAlloc( &(job->i2H1m2stor[displacement]),size);
502  DISswap(&(job->i2H1m2stor[displacement]),&((job->i2H1m2ptr)));
503  job->i2H1m2stor[displacement][0]=0.0;
504  DmemAlloc( &(job->i3H1m2stor[displacement]),size);
505  DISswap(&(job->i3H1m2stor[displacement]),&((job->i3H1m2ptr)));
506  job->i3H1m2stor[displacement][0]=0.0;
507  }
508  displacement++;
509 
510  switch(job->DstepType) {
511  case DECADE:
512  case OCTAVE:
513  freq *= job->DfreqDelta;
514  if (job->DfreqDelta == 1) goto endsweep;
515  break;
516 
517  case LINEAR:
518  freq += job->DfreqDelta;
519  if (job->DfreqDelta == 0) goto endsweep;
520  break;
521 
522  default:
523  return(E_INTERN);
524  }
525  }
526 
527 #ifdef D_DBG_BLOCKTIMES
528 time1 = (*(SPfrontEnd->IFseconds))() - time1;
529 printf("Time inside frequency loop: %g seconds \n", time1);
530 #endif
531 
532 endsweep:
533 
534 
535  /* output routines to process the H's and output actual ckt variable
536  values */
537 
538 #ifdef D_DBG_BLOCKTIMES
539 time1 = (*(SPfrontEnd->IFseconds))();
540 #endif
541 
542  if (!job->Df2wanted) {
543  error = CKTnames(ckt,&numNames,&nameList);
544  if (error) return (error);
545  (*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&freqUid,(IFuid)NULL,
546  "frequency", UID_OTHER,(GENERIC **)NULL);
547 
548  outd.circuitPtr = (GENERIC *)ckt;
549  outd.analysisPtr = (GENERIC*)ckt->CKTcurJob;
550  outd.analName = "DISTORTION - 2nd harmonic";
551  outd.refName = freqUid;
552  outd.refType = IF_REAL;
553  outd.numNames = numNames;
554  outd.dataNames = nameList;
555  outd.dataType = IF_COMPLEX;
556  outd.plotPtr = &acPlot;
557  outd.numPts = 1;
558  outd.initValue = 0;
559  outd.finalValue = 0;
560  outd.step = 0;
561  (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)&outd);
562 
563  for (i=0; i< displacement ; i++) {
564  DkerProc(D_TWOF1,*(job->r2H11stor + i),
565  *(job->i2H11stor + i),
566  size, job);
567  ckt->CKTrhsOld = *((job->r2H11stor) + i);
568  ckt->CKTirhsOld = *((job->i2H11stor) + i);
569  error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
570  if (error) return(error);
571  }
572  (*(SPfrontEnd->OUTendPlot))(acPlot);
573 
574  error = CKTnames(ckt,&numNames,&nameList);
575  if (error) return(error);
576  (*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&freqUid,(IFuid)NULL,
577  "frequency", UID_OTHER,(GENERIC **)NULL);
578 
579  outd.circuitPtr = (GENERIC *)ckt;
580  outd.analysisPtr = (GENERIC*)ckt->CKTcurJob;
581  outd.analName = "DISTORTION - 3rd harmonic";
582  outd.refName = freqUid;
583  outd.refType = IF_REAL;
584  outd.numNames = numNames;
585  outd.dataNames = nameList;
586  outd.dataType = IF_COMPLEX;
587  outd.plotPtr = &acPlot;
588  outd.numPts = 1;
589  outd.initValue = 0;
590  outd.finalValue = 0;
591  outd.step = 0;
592  (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)&outd);
593 
594  for (i=0; i< displacement ; i++) {
595  DkerProc(D_THRF1,*(job->r3H11stor + i),
596  *(job->i3H11stor + i),
597  size, job);
598  ckt->CKTrhsOld = *((job->r3H11stor) + i);
599  ckt->CKTirhsOld = *((job->i3H11stor) + i);
600  error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
601  }
602  (*(SPfrontEnd->OUTendPlot))(acPlot);
603 
604  }
605  else {
606 
607  error = CKTnames(ckt,&numNames,&nameList);
608  if (error) return(error);
609  (*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&freqUid,(IFuid)NULL,
610  "frequency", UID_OTHER,(GENERIC **)NULL);
611 
612  outd.circuitPtr = (GENERIC *)ckt;
613  outd.analysisPtr = (GENERIC*)ckt->CKTcurJob;
614  outd.analName = "DISTORTION - IM: f1+f2";
615  outd.refName = freqUid;
616  outd.refType = IF_REAL;
617  outd.numNames = numNames;
618  outd.dataNames = nameList;
619  outd.dataType = IF_COMPLEX;
620  outd.plotPtr = &acPlot;
621  outd.numPts = 1;
622  outd.initValue = 0;
623  outd.finalValue = 0;
624  outd.step = 0;
625  (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)&outd);
626 
627  for (i=0; i< displacement ; i++) {
628  DkerProc(D_F1PF2,*(job->r2H12stor + i),
629  *(job->i2H12stor + i),
630  size, job);
631  ckt->CKTrhsOld = *((job->r2H12stor) + i);
632  ckt->CKTirhsOld = *((job->i2H12stor) + i);
633  error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
634  if (error) return (error);
635  }
636  (*(SPfrontEnd->OUTendPlot))(acPlot);
637 
638  error = CKTnames(ckt,&numNames,&nameList);
639  if (error) return (error);
640  (*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&freqUid,(IFuid)NULL,
641  "frequency", UID_OTHER,(GENERIC **)NULL);
642 
643  outd.circuitPtr = (GENERIC *)ckt;
644  outd.analysisPtr = (GENERIC*)ckt->CKTcurJob;
645  outd.analName = "DISTORTION - IM: f1-f2";
646  outd.refName = freqUid;
647  outd.refType = IF_REAL;
648  outd.numNames = numNames;
649  outd.dataNames = nameList;
650  outd.dataType = IF_COMPLEX;
651  outd.plotPtr = &acPlot;
652  outd.numPts = 1;
653  outd.initValue = 0;
654  outd.finalValue = 0;
655  outd.step = 0;
656  (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)&outd);
657 
658  for (i=0; i< displacement ; i++) {
660  *(job->r2H1m2stor + i),
661  *(job->i2H1m2stor + i),
662  size, job);
663  ckt->CKTrhsOld = *((job->r2H1m2stor) + i);
664  ckt->CKTirhsOld = *((job->i2H1m2stor) + i);
665  error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
666  if (error) return(error);
667  }
668  (*(SPfrontEnd->OUTendPlot))(acPlot);
669 
670  error = CKTnames(ckt,&numNames,&nameList);
671  if (error) return (error);
672  (*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&freqUid,(IFuid)NULL,
673  "frequency", UID_OTHER,(GENERIC **)NULL);
674 
675  outd.circuitPtr = (GENERIC *)ckt;
676  outd.analysisPtr = (GENERIC*)ckt->CKTcurJob;
677  outd.analName = "DISTORTION - IM: 2f1-f2";
678  outd.refName = freqUid;
679  outd.refType = IF_REAL;
680  outd.numNames = numNames;
681  outd.dataNames = nameList;
682  outd.dataType = IF_COMPLEX;
683  outd.plotPtr = &acPlot;
684  outd.numPts = 1;
685  outd.initValue = 0;
686  outd.finalValue = 0;
687  outd.step = 0;
688  (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)&outd);
689 
690  for (i=0; i< displacement ; i++) {
692  *(job->r3H1m2stor + i),
693  *(job->i3H1m2stor + i),
694  size, job);
695  ckt->CKTrhsOld = *((job->r3H1m2stor) + i);
696  ckt->CKTirhsOld = *((job->i3H1m2stor) + i);
697  error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
698  if (error) return (error);
699  }
700  (*(SPfrontEnd->OUTendPlot))(acPlot);
701 
702  }
703  FREE(job->r1H1ptr);
704  FREE(job->i1H1ptr);
705  FREE(job->r2H11ptr);
706  FREE(job->i2H11ptr);
707 
708  FREE(job->r1H1stor);
709  FREE(job->i1H1stor);
710  FREE(job->r2H11stor);
711  FREE(job->i2H11stor);
712 
713  if (! (job->Df2wanted)) {
714  FREE(job->r3H11ptr);
715  FREE(job->i3H11ptr);
716 
717  FREE(job->i3H11stor);
718  FREE(job->r3H11stor);
719  }
720  else {
721 
722  FREE(job->r2H1m2ptr);
723  FREE(job->r3H1m2ptr);
724  FREE(job->r1H2ptr);
725  FREE(job->i1H2ptr);
726  FREE(job->r2H12ptr);
727  FREE(job->i2H12ptr);
728  FREE(job->i2H1m2ptr);
729  FREE(job->i3H1m2ptr);
730 
731  FREE(job->r1H2stor);
732  FREE(job->r2H12stor);
733  FREE(job->r2H1m2stor);
734  FREE(job->r3H1m2stor);
735  FREE(job->i1H2stor);
736  FREE(job->i2H12stor);
737  FREE(job->i2H1m2stor);
738  FREE(job->i3H1m2stor);
739  }
740 
741 #ifdef D_DBG_BLOCKTIMES
742 time1 = (*(SPfrontEnd->IFseconds))() - time1;
743 printf("Time for output and deallocation: %g seconds \n", time1);
744 #endif
745 
746  return(OK);
747 }
748 
749 
750 
751 /*
752  * CKTdisto (ckt, mode)
753  */
754 
755 
756 #ifdef __STDC__
757 static void dset(CKTcircuit*,int,DISTOAN*);
758 #else
759 static void dset();
760 #endif
761 
762 int
763 CKTdisto (ckt, mode)
764 
765 CKTcircuit *ckt;
766 int mode;
767 {
768  extern SPICEdev *DEVices[];
769  DISTOAN* cv = (DISTOAN*) (ckt->CKTcurJob);
770  int i;
771  int error;
772  int size;
773  struct sCKTmodHead *mh;
774  int (*func)();
775 
776  switch (mode) {
777 
778  case D_TWOF1:
779  case D_THRF1:
780  case D_F1PF2:
781  case D_F1MF2:
782  case D_2F1MF2:
783 
784  size = spGetSize(ckt->CKTmatrix,1);
785  for (i = 1; i <= size; i++) {
786  *(ckt->CKTrhs + i) = 0;
787  *(ckt->CKTirhs + i) = 0;
788  }
789 
790  case D_SETUP:
791  for (mh = ckt->CKTheadList; mh != NULL; mh = mh->next) {
792  if ((func = DEVices[mh->type]->DEVdisto) != NULL) {
793  error = (*func)(mode,mh->head,ckt);
794  if (error)
795  return (error);
796  }
797  }
798  break;
799 
800  case D_RHSF1:
801 
802  cv->Df2given = 0; /* will change if any F2 source is found */
803 
804  case D_RHSF2:
805 
806  dset(ckt,mode,cv);
807  error = 0;
808  break;
809 
810  default:
811 
812  error = E_BADPARM;
813  break;
814  }
815 
816  return (error);
817 }
818 
819 
820 static void
821 dset(ckt,mode,cv)
822 
823 CKTcircuit *ckt;
824 int mode;
825 DISTOAN* cv;
826 {
827  SRCinstance *here;
828  SRCmodel *model;
829  double mag, phase;
830  int i, code, size;
831 
832  size = spGetSize(ckt->CKTmatrix,1);
833  for (i = 0; i <= size; i++) {
834  *(ckt->CKTrhs+i) = 0;
835  *(ckt->CKTirhs+i) = 0;
836  }
837 
838  code = CKTtypelook("Source");
839 
840  if (code < 0)
841  return;
842 
843  for (model = (SRCmodel *)ckt->CKThead[code]; model != NULL;
844  model = model->SRCnextModel) {
845  for (here = model->SRCinstances; here!=NULL;
846  here = here->SRCnextInstance) {
847 
848  /* check if the source has a distortion input*/
849 
850  if (here->SRCdGiven) {
851  if (here->SRCdF2given)
852  cv->Df2given = 1;
853  if ((here->SRCdF1given) && (mode == D_RHSF1)) {
854  mag = here->SRCdF1mag;
855  phase = here->SRCdF1phase;
856  }
857  else if ((here->SRCdF2given) && (mode == D_RHSF2)) {
858  mag = here->SRCdF2mag;
859  phase = here->SRCdF2phase;
860  }
861  if (((here->SRCdF1given) && (mode == D_RHSF1)) ||
862  ((here->SRCdF2given) && (mode == D_RHSF2))) {
863  if (here->SRCtype == SRC_V) {
864  *(ckt->CKTrhs + here->SRCbranch) =
865  0.5*mag* cos(M_PI*phase/180.0);
866  *(ckt->CKTirhs + here->SRCbranch) =
867  0.5*mag*sin(M_PI*phase/180.0);
868  }
869  else {
870  *(ckt->CKTrhs + here->SRCposNode) =
871  - 0.5*mag*cos(M_PI*phase/180.0);
872  *(ckt->CKTrhs + here->SRCnegNode) =
873  0.5*mag*cos(M_PI*phase/180.0);
874  *(ckt->CKTirhs + here->SRCposNode) =
875  - 0.5*mag*sin(M_PI*phase/180.0);
876  *(ckt->CKTirhs + here->SRCnegNode) =
877  0.5*mag*sin(M_PI*phase/180.0);
878  }
879  }
880  }
881  }
882  }
883 }
#define E_INTERN
Definition: sperror.h:15
double SRCdF2mag
Definition: srcdefs.h:94
int numPts
Definition: outdata.h:22
struct sSRCinstance * SRCnextInstance
Definition: srcdefs.h:26
#define MODEAC
Definition: cktdefs.h:146
double initValue
Definition: outdata.h:24
#define IF_COMPLEX
Definition: ifsim.h:109
double ** i3H11stor
Definition: distodef.h:129
unsigned SRCdF2given
Definition: srcdefs.h:186
#define SRC_V
Definition: srcdefs.h:217
int CKTnames()
static void DISswap(double **a, double **b)
Definition: distan.c:22
double DfreqDelta
Definition: distodef.h:97
#define D_SETUP
Definition: distodef.h:158
char * strcpy()
int refType
Definition: outdata.h:17
struct sCKTmodHead * next
Definition: cktdefs.h:58
IFuid * dataNames
Definition: outdata.h:19
int DCOan()
static void DstorAlloc(double ***header, int size)
Definition: distan.c:46
double ** i3H1m2stor
Definition: distodef.h:137
IFuid analName
Definition: outdata.h:15
double * i1H2ptr
Definition: distodef.h:116
int SRCnegNode
Definition: srcdefs.h:38
SPICEdev * DEVices[]
Definition: sconfig.c:109
int numNames
Definition: outdata.h:18
#define ERR_FATAL
Definition: ifsim.h:518
SMPmatrix * CKTmatrix
Definition: cktdefs.h:95
int NIdIter()
#define M_PI
Definition: spice.h:132
char * errMsg
Definition: main.c:42
IFfrontEnd * SPfrontEnd
Definition: main.c:917
int SRCposNode
Definition: srcdefs.h:35
#define E_BADPARM
Definition: iferrmsg.h:26
double * r1H1ptr
Definition: distodef.h:109
unsigned SRCdF1given
Definition: srcdefs.h:185
double CKTreltol
Definition: cktdefs.h:183
int CKTtypelook()
double * r2H12ptr
Definition: distodef.h:117
double step
Definition: outdata.h:26
double ** i2H12stor
Definition: distodef.h:133
double ** r2H1m2stor
Definition: distodef.h:134
#define FREE(ptr)
Definition: spdefs.h:436
double * r2H1m2ptr
Definition: distodef.h:119
#define OCTAVE
Definition: analysis.h:48
int DnumSteps
Definition: distodef.h:101
double * r3H11ptr
Definition: distodef.h:113
double * r1H2ptr
Definition: distodef.h:115
int CKTdisto()
double DstartF1
Definition: distodef.h:94
double * i3H1m2ptr
Definition: distodef.h:122
unsigned SRCdGiven
Definition: srcdefs.h:184
int DstepType
Definition: distodef.h:100
#define OK
Definition: iferrmsg.h:17
double * CKTrhsOld
Definition: cktdefs.h:98
GENERIC * IFuid
Definition: ifsim.h:72
char * JOBname
Definition: distodef.h:93
double ** i2H11stor
Definition: distodef.h:127
int SRCbranch
Definition: srcdefs.h:47
int CKTacDump()
#define MALLOC(x)
Definition: util.h:9
#define D_2F1MF2
Definition: distodef.h:165
#define NULL
Definition: spdefs.h:121
SRCinstance * SRCinstances
Definition: srcdefs.h:205
double * i2H1m2ptr
Definition: distodef.h:120
#define E_NOMEM
Definition: iferrmsg.h:27
int Df2given
Definition: distodef.h:103
GENERIC * circuitPtr
Definition: outdata.h:13
Definition: sced.h:120
double cos()
double Domega2
Definition: distodef.h:107
double CKTomega
Definition: cktdefs.h:198
double * i2H12ptr
Definition: distodef.h:118
#define LINEAR
Definition: analysis.h:49
double SRCdF1phase
Definition: srcdefs.h:97
double DstopF1
Definition: distodef.h:96
double ** r2H12stor
Definition: distodef.h:132
double ** r1H2stor
Definition: distodef.h:130
int CKTacLoad()
#define D_RHSF2
Definition: distodef.h:167
static double c
Definition: vectors.c:16
double sin()
int CKTjjPresent
Definition: cktdefs.h:168
double * r2H11ptr
Definition: distodef.h:111
#define D_RHSF1
Definition: distodef.h:166
static void DmemAlloc(double **a, int size)
Definition: distan.c:35
double * i2H11ptr
Definition: distodef.h:112
int spGetSize()
double SRCdF2phase
Definition: srcdefs.h:100
#define IF_REAL
Definition: ifsim.h:108
static char model[32]
Definition: subckt.c:76
double finalValue
Definition: outdata.h:25
double * CKTirhsOld
Definition: cktdefs.h:101
Definition: fteparse.h:37
double ** r2H11stor
Definition: distodef.h:126
static void dset()
double ** i1H2stor
Definition: distodef.h:131
int type
Definition: cktdefs.h:56
double ** r3H1m2stor
Definition: distodef.h:136
int Df2wanted
Definition: distodef.h:102
double ** r3H11stor
Definition: distodef.h:128
double * r3H1m2ptr
Definition: distodef.h:121
#define UID_OTHER
Definition: ifsim.h:85
GENERIC * analysisPtr
Definition: outdata.h:14
#define D_TWOF1
Definition: distodef.h:161
double SRCdF1mag
Definition: srcdefs.h:91
double ** i2H1m2stor
Definition: distodef.h:135
int(* DEVdisto)()
Definition: devdefs.h:108
#define E_NOF2SRC
Definition: sperror.h:30
GENmodel * head
Definition: cktdefs.h:57
#define D_F1PF2
Definition: distodef.h:163
#define DECADE
Definition: analysis.h:47
double Df2ovrF1
Definition: distodef.h:104
int DISTOan(GENERIC *cktp, int restart)
Definition: distan.c:65
double * i1H1ptr
Definition: distodef.h:110
int DkerProc()
int SRCtype
Definition: srcdefs.h:65
GENERIC ** plotPtr
Definition: outdata.h:21
#define D_F1MF2
Definition: distodef.h:164
double Domega1
Definition: distodef.h:106
JOB * CKTcurJob
Definition: cktdefs.h:216
long CKTmode
Definition: cktdefs.h:139
IFuid refName
Definition: outdata.h:16
double ** i1H1stor
Definition: distodef.h:125
double * i3H11ptr
Definition: distodef.h:114
#define D_THRF1
Definition: distodef.h:162
double ** r1H1stor
Definition: distodef.h:124
struct sSRCmodel * SRCnextModel
Definition: srcdefs.h:202
char GENERIC
Definition: ifsim.h:27
int dataType
Definition: outdata.h:20