1 /**********
2 Copyright 1990 Regents of the University of California. All rights reserved.
3 Author: 1988 Jaijeet S Roychowdhury
4 **********/
5
6 #include "ngspice/ngspice.h"
7 #include "ngspice/cktdefs.h"
8 #include "ngspice/distodef.h"
9 #include "ngspice/sperror.h"
10
11
12 static void
DISswap(double ** a,double ** b)13 DISswap(double **a, double **b)
14 {
15 SWAP(double *, *a, *b);
16 }
17
18 static void
DmemAlloc(double ** a,int size)19 DmemAlloc(double **a, int size)
20 {
21 *a = TMALLOC(double, size + 1);
22 }
23
24
25
26 static void
DstorAlloc(double *** header,int size)27 DstorAlloc(double ***header, int size)
28 {
29 *header = TMALLOC(double *, size);
30 }
31
32
33
34 int
DISTOan(CKTcircuit * ckt,int restart)35 DISTOan(CKTcircuit *ckt, int restart)
36 {
37
38 double freq;
39 static double freqTol; /* tolerence parameter for finding final frequency */
40 static int NoOfPoints;
41 static int size;
42 static int displacement;
43 int error;
44 int i;
45 int numNames;
46 IFuid *nameList;
47 IFuid freqUid;
48 runDesc *acPlot = NULL;
49 DISTOAN *job = (DISTOAN *) ckt->CKTcurJob;
50 static char *nof2src = "No source with f2 distortion input";
51 #ifdef DISTODEBUG
52 double time,time1;
53 #endif
54
55 NG_IGNORE(restart);
56
57
58 /* start at beginning */
59
60 #ifdef D_DBG_BLOCKTIMES
61 time1 = SPfrontEnd->IFseconds();
62 #endif
63 switch(job->DstepType) {
64
65 case DECADE:
66 job->DfreqDelta =
67 exp(log(10.0)/job->DnumSteps);
68 freqTol = job->DfreqDelta *
69 job->DstopF1 * ckt->CKTreltol;
70 NoOfPoints = 1 + (int)floor ((job->DnumSteps) / log(10.0) * log((job->DstopF1+freqTol)/(job->DstartF1)));
71 break;
72 case OCTAVE:
73 job->DfreqDelta =
74 exp(log(2.0)/job->DnumSteps);
75 freqTol = job->DfreqDelta *
76 job->DstopF1 * ckt->CKTreltol;
77 NoOfPoints = 1 + (int)floor ((job->DnumSteps) / log(2.0) * log((job->DstopF1+freqTol)/(job->DstartF1)));
78 break;
79 case LINEAR:
80 job->DfreqDelta =
81 (job->DstopF1 -
82 job->DstartF1)/
83 (job->DnumSteps+1);
84 freqTol = job->DfreqDelta * ckt->CKTreltol;
85 NoOfPoints = job->DnumSteps+1+ (int)floor(freqTol/(job->DfreqDelta));
86 break;
87 default:
88 return(E_BADPARM);
89 }
90
91 error = CKTop(ckt,
92 (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
93 (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
94 ckt->CKTdcMaxIter);
95 if(error) return(error);
96
97 ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
98 error = CKTload(ckt);
99 if(error) return(error);
100
101 error = CKTnames(ckt,&numNames,&nameList);
102 if(error) return(error);
103
104 if (ckt->CKTkeepOpInfo) {
105 /* Dump operating point. */
106 error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
107 "Distortion Operating Point",
108 NULL, IF_REAL,
109 numNames, nameList, IF_REAL,
110 &acPlot);
111 if(error) return(error);
112 CKTdump(ckt, 0.0, acPlot);
113 SPfrontEnd->OUTendPlot (acPlot);
114 acPlot = NULL;
115 }
116
117 #ifdef D_DBG_BLOCKTIMES
118 time1 = SPfrontEnd->IFseconds() - time1;
119 printf("Time for initial work (including op. pt.): %g seconds \n", time1);
120 #endif
121
122 #ifdef D_DBG_BLOCKTIMES
123 time1 = SPfrontEnd->IFseconds();
124 #endif
125 error = CKTdisto(ckt,D_SETUP);
126 #ifdef D_DBG_BLOCKTIMES
127 time1 = SPfrontEnd->IFseconds() - time1;
128 printf("Time outside D_SETUP: %g seconds \n", time1);
129 #endif
130 if (error) return(error);
131
132 displacement = 0;
133
134 #ifdef D_DBG_BLOCKTIMES
135 time1 = SPfrontEnd->IFseconds();
136 #endif
137 freq = job->DstartF1;
138 if (job->Df2wanted) {
139 /*
140 omegadelta = 2.0 * M_PI * freq *(1. - job->Df2ovrF1);
141 */
142 /* keeping f2 const to be compatible with spectre */
143 job->Domega2 = 2.0 * M_PI * freq * job->Df2ovrF1;
144 }
145 DstorAlloc( &(job->r1H1stor),NoOfPoints+2);
146 DstorAlloc( &(job->r2H11stor),NoOfPoints+2);
147 DstorAlloc( &(job->i1H1stor),NoOfPoints+2);
148 DstorAlloc( &(job->i2H11stor),NoOfPoints+2);
149 size = SMPmatSize(ckt->CKTmatrix);
150 if (! job->r1H1ptr)
151 {
152 DmemAlloc( &(job->r1H1ptr) , size+2);
153 if (! job->r1H1ptr) return (E_NOMEM);
154 }
155
156 if (! job->r2H11ptr)
157 {
158 DmemAlloc( &(job->r2H11ptr) , size+2);
159 if (! job->r2H11ptr) return (E_NOMEM);
160 }
161 if (! job->i1H1ptr)
162 {
163 DmemAlloc( &(job->i1H1ptr) , size+2);
164 if (! job->i1H1ptr) return (E_NOMEM);
165 }
166
167 if (! job->i2H11ptr)
168 {
169 DmemAlloc( &(job->i2H11ptr) , size+2);
170 if (! job->i2H11ptr) return (E_NOMEM);
171 }
172
173 if (! (job->Df2wanted))
174 {
175 DstorAlloc( &(job->r3H11stor),NoOfPoints+2);
176 DstorAlloc( &(job->i3H11stor),NoOfPoints+2);
177 if (! job->r3H11ptr)
178 {
179 DmemAlloc( &(job->r3H11ptr) , size+2);
180 if (! job->r3H11ptr) return (E_NOMEM);
181 }
182 if (! job->i3H11ptr)
183 {
184 DmemAlloc( &(job->i3H11ptr) , size+2);
185 if (! job->i3H11ptr) return (E_NOMEM);
186 }
187 } else {
188 DstorAlloc ( &(job->r1H2stor),NoOfPoints+2);
189 DstorAlloc ( &(job->i1H2stor),NoOfPoints+2);
190 DstorAlloc ( &(job->r2H12stor),NoOfPoints+2);
191 DstorAlloc ( &(job->i2H12stor),NoOfPoints+2);
192 DstorAlloc ( &(job->r2H1m2stor),NoOfPoints+2);
193 DstorAlloc ( &(job->i2H1m2stor),NoOfPoints+2);
194 DstorAlloc ( &(job->r3H1m2stor),NoOfPoints+2);
195 DstorAlloc ( &(job->i3H1m2stor),NoOfPoints+2);
196 if (! job->r1H2ptr)
197 {
198 DmemAlloc( &(job->r1H2ptr) , size+2);
199 if (! job->r1H2ptr) return (E_NOMEM);
200 }
201
202 if (! job->r2H12ptr)
203 {
204 DmemAlloc( &(job->r2H12ptr) , size+2);
205 if (! job->r2H12ptr) return (E_NOMEM);
206 }
207
208 if (! job->r2H1m2ptr)
209 {
210 DmemAlloc( &(job->r2H1m2ptr) , size+2);
211 if (! job->r2H1m2ptr) return (E_NOMEM);
212 }
213
214 if (! job->r3H1m2ptr)
215 {
216 DmemAlloc( &(job->r3H1m2ptr) , size+2);
217 if (! job->r3H1m2ptr) return (E_NOMEM);
218 }
219 if (! job->i1H2ptr)
220 {
221 DmemAlloc( &(job->i1H2ptr) , size+2);
222 if (! job->i1H2ptr) return (E_NOMEM);
223 }
224
225 if (! job->i2H12ptr)
226 {
227 DmemAlloc( &(job->i2H12ptr) , size+2);
228 if (! job->i2H12ptr) return (E_NOMEM);
229 }
230
231 if (! job->i2H1m2ptr)
232 {
233 DmemAlloc( &(job->i2H1m2ptr) , size+2);
234 if (! job->i2H1m2ptr) return (E_NOMEM);
235 }
236
237 if (! job->i3H1m2ptr)
238 {
239 DmemAlloc( &(job->i3H1m2ptr) , size+2);
240 if (! job->i3H1m2ptr) return (E_NOMEM);
241 }
242 }
243
244 #ifdef D_DBG_BLOCKTIMES
245 time1 = SPfrontEnd->IFseconds() - time1;
246 printf("Time for other setup (storage allocation etc.): %g seconds \n", time1);
247 #endif
248
249
250
251 #ifdef D_DBG_BLOCKTIMES
252 time1 = SPfrontEnd->IFseconds();
253 #endif
254 while(freq <= job->DstopF1+freqTol) {
255
256 /*
257 if(SPfrontEnd->IFpauseTest()) {
258 job->DsaveF1 = freq;
259 return(E_PAUSE);
260 }
261 */
262 ckt->CKTomega = 2.0 * M_PI *freq;
263 job->Domega1 = ckt->CKTomega;
264 ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEAC;
265 #ifdef D_DBG_SMALLTIMES
266 time = SPfrontEnd->IFseconds();
267 #endif
268 error = CKTacLoad(ckt);
269 #ifdef D_DBG_SMALLTIMES
270 time = SPfrontEnd->IFseconds() - time;
271 printf("Time for CKTacLoad: %g seconds \n", time);
272 #endif
273 if (error) return(error);
274 #ifdef D_DBG_SMALLTIMES
275 time = SPfrontEnd->IFseconds();
276 #endif
277 error = CKTdisto(ckt,D_RHSF1); /* sets up the RHS vector
278 for all inputs corresponding to F1 */
279 #ifdef D_DBG_SMALLTIMES
280 time = SPfrontEnd->IFseconds() - time;
281 printf("Time outside DISTO_RHSFIX: %g seconds \n", time);
282 #endif
283 if (error) return(error);
284 #ifdef D_DBG_SMALLTIMES
285 time = SPfrontEnd->IFseconds();
286 #endif
287 error = NIdIter(ckt);
288 #ifdef D_DBG_SMALLTIMES
289 time = SPfrontEnd->IFseconds() - time;
290 printf("Time for NIdIter: %g seconds \n", time);
291 #endif
292 if (error) return(error);
293 DISswap(&(ckt->CKTrhsOld),&(job->r1H1ptr));
294 DISswap(&(ckt->CKTirhsOld),&(job->i1H1ptr));
295
296 ckt->CKTomega *= 2;
297 error = CKTacLoad(ckt);
298 if (error) return(error);
299 #ifdef D_DBG_SMALLTIMES
300 time = SPfrontEnd->IFseconds();
301 #endif
302 error = CKTdisto(ckt,D_TWOF1);
303 #ifdef D_DBG_SMALLTIMES
304 time = SPfrontEnd->IFseconds() - time;
305 printf("Time outside D_TWOF1: %g seconds \n", time);
306 #endif
307 if (error) return(error);
308 error = NIdIter(ckt);
309 if (error) return(error);
310 DISswap(&(ckt->CKTrhsOld),&(job->r2H11ptr));
311 DISswap(&(ckt->CKTirhsOld),&(job->i2H11ptr));
312
313 if (! (job->Df2wanted ))
314 {
315
316
317 ckt->CKTomega = 3 * job->Domega1;
318 error = CKTacLoad(ckt);
319 if (error) return(error);
320 #ifdef D_DBG_SMALLTIMES
321 time = SPfrontEnd->IFseconds();
322 #endif
323 error = CKTdisto(ckt,D_THRF1);
324 #ifdef D_DBG_SMALLTIMES
325 time = SPfrontEnd->IFseconds() - time;
326 printf("Time outside D_THRF1: %g seconds \n", time);
327 #endif
328 if (error) return(error);
329 error = NIdIter(ckt);
330 if (error) return(error);
331 DISswap(&(ckt->CKTrhsOld),&(job->r3H11ptr));
332 DISswap(&(ckt->CKTirhsOld),&(job->i3H11ptr));
333
334
335 }
336 else if (job->Df2given)
337 {
338
339
340 /*
341 ckt->CKTomega = job->Domega1 - omegadelta;
342 job->Domega2 = ckt->CKTomega;
343 */
344 ckt->CKTomega = job->Domega2;
345 error = CKTacLoad(ckt);
346 if (error) return(error);
347 #ifdef D_DBG_SMALLTIMES
348 time = SPfrontEnd->IFseconds();
349 #endif
350 error = CKTdisto(ckt,D_RHSF2);
351 #ifdef D_DBG_SMALLTIMES
352 time = SPfrontEnd->IFseconds() - time;
353 printf("Time outside DISTO_RHSFIX: %g seconds \n", time);
354 #endif
355 if (error) return(error);
356 error = NIdIter(ckt);
357 if (error) return(error);
358 DISswap(&(ckt->CKTrhsOld),&(job->r1H2ptr));
359 DISswap(&(ckt->CKTirhsOld),&(job->i1H2ptr));
360
361
362 ckt->CKTomega = job->Domega1 +
363 job->Domega2;
364 error = CKTacLoad(ckt);
365 if (error) return(error);
366 #ifdef D_DBG_SMALLTIMES
367 time = SPfrontEnd->IFseconds();
368 #endif
369 error = CKTdisto(ckt,D_F1PF2);
370 #ifdef D_DBG_SMALLTIMES
371 time = SPfrontEnd->IFseconds() - time;
372 printf("Time outside D_F1PF2: %g seconds \n", time);
373 #endif
374 if (error) return(error);
375 error = NIdIter(ckt);
376 if (error) return(error);
377 DISswap(&(ckt->CKTrhsOld),&(job->r2H12ptr));
378 DISswap(&(ckt->CKTirhsOld),&(job->i2H12ptr));
379
380
381
382 ckt->CKTomega = job->Domega1 -
383 job->Domega2;
384 error = CKTacLoad(ckt);
385 if (error) return(error);
386 #ifdef D_DBG_SMALLTIMES
387 time = SPfrontEnd->IFseconds();
388 #endif
389 error = CKTdisto(ckt,D_F1MF2);
390 #ifdef D_DBG_SMALLTIMES
391 time = SPfrontEnd->IFseconds() - time;
392 printf("Time outside D_F1MF2: %g seconds \n", time);
393 #endif
394 if (error) return(error);
395 error = NIdIter(ckt);
396 if (error) return(error);
397 DISswap(&(ckt->CKTrhsOld),&(job->r2H1m2ptr));
398 DISswap(&(ckt->CKTirhsOld),&(job->i2H1m2ptr));
399
400
401 ckt->CKTomega = 2*job->Domega1 -
402 job->Domega2;
403 error = CKTacLoad(ckt);
404 if (error) return(error);
405 #ifdef D_DBG_SMALLTIMES
406 time = SPfrontEnd->IFseconds();
407 #endif
408 error = CKTdisto(ckt,D_2F1MF2);
409 #ifdef D_DBG_SMALLTIMES
410 time = SPfrontEnd->IFseconds() - time;
411 printf("Time outside D_2F1MF2: %g seconds \n", time);
412 #endif
413 if (error) return(error);
414 error = NIdIter(ckt);
415 if (error) return(error);
416 DISswap(&(ckt->CKTrhsOld),&(job->r3H1m2ptr));
417 DISswap(&(ckt->CKTirhsOld),&(job->i3H1m2ptr));
418
419
420 }
421 else
422 {
423 errMsg = TMALLOC(char, strlen(nof2src) + 1);
424 strcpy(errMsg,nof2src);
425 return(E_NOF2SRC);
426 }
427
428
429
430
431 DmemAlloc( &(job->r1H1stor[displacement]),size);
432 DISswap(&(job->r1H1stor[displacement]),&(job->r1H1ptr));
433 job->r1H1stor[displacement][0]=freq;
434 DmemAlloc( &(job->r2H11stor[displacement]),size);
435 DISswap(&(job->r2H11stor[displacement]),&((job->r2H11ptr)));
436 job->r2H11stor[displacement][0]=freq;
437 DmemAlloc( &(job->i1H1stor[displacement]),size);
438 DISswap(&(job->i1H1stor[displacement]),&((job->i1H1ptr)));
439 job->i1H1stor[displacement][0]=0.0;
440 DmemAlloc( &(job->i2H11stor[displacement]),size);
441 DISswap(&(job->i2H11stor[displacement]),&((job->i2H11ptr)));
442 job->i2H11stor[displacement][0]=0.0;
443 if (! (job->Df2wanted))
444 {
445 DmemAlloc( &(job->r3H11stor[displacement]),size);
446 DISswap(&(job->r3H11stor[displacement]),&((job->r3H11ptr)));
447 job->r3H11stor[displacement][0]=freq;
448 DmemAlloc( &(job->i3H11stor[displacement]),size);
449 DISswap(&(job->i3H11stor[displacement]),&((job->i3H11ptr)));
450 job->i3H11stor[displacement][0]=0.0;
451 } else {
452 DmemAlloc( &(job->r1H2stor[displacement]),size);
453 DISswap(&(job->r1H2stor[displacement]),&((job->r1H2ptr)));
454 job->r1H2stor[displacement][0]=freq;
455 DmemAlloc( &(job->r2H12stor[displacement]),size);
456 DISswap(&(job->r2H12stor[displacement]),&((job->r2H12ptr)));
457 job->r2H12stor[displacement][0]=freq;
458 DmemAlloc( &(job->r2H1m2stor[displacement]),size);
459 DISswap(&(job->r2H1m2stor[displacement]),&((job->r2H1m2ptr)));
460 job->r2H1m2stor[displacement][0]=freq;
461 DmemAlloc( &(job->r3H1m2stor[displacement]),size);
462 DISswap(&(job->r3H1m2stor[displacement]),&((job->r3H1m2ptr)));
463 job->r3H1m2stor[displacement][0]=freq;
464
465 DmemAlloc( &(job->i1H2stor[displacement]),size);
466 DISswap(&(job->i1H2stor[displacement]),&((job->i1H2ptr)));
467 job->i1H2stor[displacement][0]=0.0;
468 DmemAlloc( &(job->i2H12stor[displacement]),size);
469 DISswap(&(job->i2H12stor[displacement]),&((job->i2H12ptr)));
470 job->i2H12stor[displacement][0]=0.0;
471 DmemAlloc( &(job->i2H1m2stor[displacement]),size);
472 DISswap(&(job->i2H1m2stor[displacement]),&((job->i2H1m2ptr)));
473 job->i2H1m2stor[displacement][0]=0.0;
474 DmemAlloc( &(job->i3H1m2stor[displacement]),size);
475 DISswap(&(job->i3H1m2stor[displacement]),&((job->i3H1m2ptr)));
476 job->i3H1m2stor[displacement][0]=0.0;
477 }
478 displacement++;
479
480
481
482 switch(job->DstepType) {
483 case DECADE:
484 case OCTAVE:
485 freq *= job->DfreqDelta;
486 if(job->DfreqDelta==1) goto endsweep;
487 break;
488 case LINEAR:
489 freq += job->DfreqDelta;
490 if(job->DfreqDelta==0) goto endsweep;
491 break;
492 default:
493 return(E_INTERN);
494 }
495 }
496 #ifdef D_DBG_BLOCKTIMES
497 time1 = SPfrontEnd->IFseconds() - time1;
498 printf("Time inside frequency loop: %g seconds \n", time1);
499 #endif
500
501 endsweep:
502
503
504 /* output routines to process the H's and output actual ckt variable
505 values */
506 #ifdef D_DBG_BLOCKTIMES
507 time1 = SPfrontEnd->IFseconds();
508 #endif
509
510
511
512 if (! job->Df2wanted) {
513 error = CKTnames(ckt,&numNames,&nameList);
514 if(error) return(error);
515 SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
516 SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
517 "DISTORTION - 2nd harmonic",
518 freqUid, IF_REAL,
519 numNames, nameList, IF_COMPLEX,
520 &acPlot);
521 if (job->DstepType != LINEAR) {
522 SPfrontEnd->OUTattributes (acPlot, NULL, OUT_SCALE_LOG, NULL);
523 }
524 for (i=0; i< displacement ; i++)
525 {
526 DkerProc(D_TWOF1,job->r2H11stor[i],
527 job->i2H11stor[i],
528 size, job);
529 ckt->CKTrhsOld = job->r2H11stor[i];
530 ckt->CKTirhsOld = job->i2H11stor[i];
531 error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
532 if(error) return(error);
533 }
534 SPfrontEnd->OUTendPlot (acPlot);
535 acPlot = NULL;
536
537 error = CKTnames(ckt,&numNames,&nameList);
538 if(error) return(error);
539 SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
540 SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
541 "DISTORTION - 3rd harmonic",
542 freqUid, IF_REAL,
543 numNames, nameList, IF_COMPLEX,
544 &acPlot);
545 for (i=0; i< displacement ; i++)
546 {
547 DkerProc(D_THRF1,job->r3H11stor[i],
548 job->i3H11stor[i],
549 size, job);
550 ckt->CKTrhsOld = job->r3H11stor[i];
551 ckt->CKTirhsOld = job->i3H11stor[i];
552 error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
553 }
554 SPfrontEnd->OUTendPlot (acPlot);
555 acPlot = NULL;
556
557 } else {
558
559
560 error = CKTnames(ckt,&numNames,&nameList);
561 if(error) return(error);
562 SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
563 SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
564 "DISTORTION - IM: f1+f2",
565 freqUid, IF_REAL,
566 numNames, nameList, IF_COMPLEX,
567 &acPlot);
568 for (i=0; i< displacement ; i++)
569 {
570 DkerProc(D_F1PF2,job->r2H12stor[i],
571 job->i2H12stor[i],
572 size, job);
573 ckt->CKTrhsOld = job->r2H12stor[i];
574 ckt->CKTirhsOld = job->i2H12stor[i];
575 error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
576 if(error) return(error);
577 }
578 SPfrontEnd->OUTendPlot (acPlot);
579 acPlot = NULL;
580
581 error = CKTnames(ckt,&numNames,&nameList);
582 if(error) return(error);
583 SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
584 SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
585 "DISTORTION - IM: f1-f2",
586 freqUid, IF_REAL,
587 numNames, nameList, IF_COMPLEX,
588 &acPlot);
589 for (i=0; i< displacement ; i++)
590 {
591 DkerProc(D_F1MF2,
592 job->r2H1m2stor[i],
593 job->i2H1m2stor[i],
594 size, job);
595 ckt->CKTrhsOld = job->r2H1m2stor[i];
596 ckt->CKTirhsOld = job->i2H1m2stor[i];
597 error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
598 if(error) return(error);
599 }
600 SPfrontEnd->OUTendPlot (acPlot);
601 acPlot = NULL;
602
603 error = CKTnames(ckt,&numNames,&nameList);
604 if(error) return(error);
605 SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
606 SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
607 "DISTORTION - IM: 2f1-f2",
608 freqUid, IF_REAL,
609 numNames, nameList, IF_COMPLEX,
610 &acPlot);
611 for (i=0; i< displacement ; i++)
612 {
613 DkerProc(D_2F1MF2,
614 job->r3H1m2stor[i],
615 job->i3H1m2stor[i],
616 size, job);
617 ckt->CKTrhsOld = job->r3H1m2stor[i];
618 ckt->CKTirhsOld = job->i3H1m2stor[i];
619 error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
620 if(error) return(error);
621 }
622 SPfrontEnd->OUTendPlot (acPlot);
623 acPlot = NULL;
624
625 }
626 FREE(job->r1H1ptr);
627 FREE(job->i1H1ptr);
628 FREE(job->r2H11ptr);
629 FREE(job->i2H11ptr);
630
631 FREE(job->r1H1stor);
632 FREE(job->i1H1stor);
633 FREE(job->r2H11stor);
634 FREE(job->i2H11stor);
635
636 if (! (job->Df2wanted))
637 {
638 FREE(job->r3H11ptr);
639 FREE(job->i3H11ptr);
640
641 FREE(job->i3H11stor);
642 FREE(job->r3H11stor);
643 }
644 else {
645
646 FREE(job->r2H1m2ptr);
647 FREE(job->r3H1m2ptr);
648 FREE(job->r1H2ptr);
649 FREE(job->i1H2ptr);
650 FREE(job->r2H12ptr);
651 FREE(job->i2H12ptr);
652 FREE(job->i2H1m2ptr);
653 FREE(job->i3H1m2ptr);
654
655 FREE(job->r1H2stor);
656 FREE(job->r2H12stor);
657 FREE(job->r2H1m2stor);
658 FREE(job->r3H1m2stor);
659 FREE(job->i1H2stor);
660 FREE(job->i2H12stor);
661 FREE(job->i2H1m2stor);
662 FREE(job->i3H1m2stor);
663 }
664 #ifdef D_DBG_BLOCKTIMES
665 time1 = SPfrontEnd->IFseconds() - time1;
666 printf("Time for output and deallocation: %g seconds \n", time1);
667 #endif
668 return(OK);
669 }
670