Jspice3
ltraset.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: 1990 Jaijeet S. Roychowdhury
5  1993 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 #include "spice.h"
9 #include <stdio.h>
10 #include <math.h>
11 #include "ltradefs.h"
12 #include "sperror.h"
13 #include "util.h"
14 #include "cktext.h"
15 
16 
17 int
18 LTRAsetup(matrix,inModel,ckt,state)
19 
20 SMPmatrix *matrix;
21 GENmodel *inModel;
22 CKTcircuit *ckt;
23 int *state;
24 /* load the transmission line structure with those pointers needed later
25  * for fast matrix loading
26  */
27 {
28  LTRAmodel *model = (LTRAmodel *)inModel;
29  LTRAinstance *here;
30  int error;
31  double dummy1, dummy2;
32  CKTnode *tmp;
33 
34  /* loop through all the transmission line models */
35  for ( ; model != NULL; model = model->LTRAnextModel) {
36 
37 
38  if (!model->LTRAreltolGiven) {
39  model->LTRAreltol = 1;
40  }
41  if (!model->LTRAabstolGiven) {
42  model->LTRAabstol = 1;
43  }
44  if (!model->LTRAresistGiven) {
45  (*(SPfrontEnd->IFerror))(ERR_WARNING,
46  "%s: lossy line series resistance not given, assumed zero",
47  &(model->LTRAmodName));
48  model->LTRAresist = 0.0;
49  }
50 
51  if (model->LTRAstLineReltol == 0.0)
52  model->LTRAstLineReltol = ckt->CKTreltol;
53  if (model->LTRAstLineAbstol == 0.0)
54  model->LTRAstLineAbstol = ckt->CKTabstol;
55  /* LTRAchopReltol and LTRAchopAbstol default zero */
56 
57  if ((model->LTRAhowToInterp != LTRA_MOD_LININTERP) &&
60 
61  if (ckt->CKTtryToCompact) {
63  (*(SPfrontEnd->IFerror))(ERR_WARNING,
64  "%s: using linear interpolation because trytocompact option specified",
65  &(model->LTRAmodName));
66  }
67  else {
69  }
70  }
71 
72  if ((model->LTRAstepLimit != LTRA_MOD_NOSTEPLIMIT))
74 
75  if ((model->LTRAlteConType != LTRA_MOD_FULLCONTROL) &&
78 
79  if (!model->LTRAconductGiven) {
80  model->LTRAconduct = 0.0;
81  }
82  if (!model->LTRAinductGiven) {
83  (*(SPfrontEnd->IFerror))(ERR_WARNING,
84  "%s: lossy line series inductance not given, assumed zero",
85  &(model->LTRAmodName));
86  model->LTRAinduct = 0.0;
87  }
88  if (!model->LTRAcapacGiven) {
89  (*(SPfrontEnd->IFerror))(ERR_FATAL,
90  "%s: lossy line parallel capacitance not given, assumed zero",
91  &(model->LTRAmodName));
92  model->LTRAcapac = 0.0;
93  }
94  if (!model->LTRAlengthGiven) {
95  (*(SPfrontEnd->IFerror))(ERR_FATAL,
96  "%s: lossy line length must be given",
97  &(model->LTRAmodName));
98  return(E_BADPARM);
99  }
100 
101  if ((model->LTRAresist == 0) && (model->LTRAconduct == 0) &&
102  (model->LTRAcapac != 0) && (model->LTRAinduct != 0)) {
103  model->LTRAspecialCase = LTRA_MOD_LC;
104 
105 #ifdef LTRADEBUG
106  (*(SPfrontEnd->IFerror))(ERR_INFO,
107  "%s: lossless line",
108  &(model->LTRAmodName));
109 #endif
110  }
111 
112  if ((model->LTRAresist != 0) && (model->LTRAconduct == 0) &&
113  (model->LTRAcapac != 0) && (model->LTRAinduct != 0)) {
114  model->LTRAspecialCase = LTRA_MOD_RLC;
115 #ifdef LTRADEBUG
116  (*(SPfrontEnd->IFerror))(ERR_INFO,
117  "%s: RLC line",
118  &(model->LTRAmodName));
119 #endif
120  }
121 
122  if ((model->LTRAresist != 0) && (model->LTRAconduct == 0) &&
123  (model->LTRAcapac != 0) && (model->LTRAinduct == 0)) {
124  model->LTRAspecialCase = LTRA_MOD_RC;
125 #ifdef LTRADEBUG
126  (*(SPfrontEnd->IFerror))(ERR_INFO,
127  "%s: RC line",
128  &(model->LTRAmodName));
129 #endif
130  }
131 
132  if ((model->LTRAresist != 0) && (model->LTRAconduct == 0) &&
133  (model->LTRAcapac == 0) && (model->LTRAinduct != 0)) {
134  model->LTRAspecialCase = LTRA_MOD_RL;
135  (*(SPfrontEnd->IFerror))(ERR_FATAL,
136  "%s: RL line not supported yet",
137  &(model->LTRAmodName));
138  return(E_BADPARM);
139  }
140 
141  if ((model->LTRAresist != 0) && (model->LTRAconduct != 0) &&
142  (model->LTRAcapac == 0) && (model->LTRAinduct == 0)) {
143  model->LTRAspecialCase = LTRA_MOD_RG;
144 #ifdef LTRADEBUG
145  (*(SPfrontEnd->IFerror))(ERR_INFO,
146  "%s: RG line",
147  &(model->LTRAmodName));
148 #endif
149  }
150 
151  if ((model->LTRAconduct != 0) && ( (model->LTRAcapac != 0) ||
152  (model->LTRAinduct != 0))) {
154  (*(SPfrontEnd->IFerror))(ERR_FATAL,
155  "%s: Nonzero G (except RG) line not supported yet",
156  &(model->LTRAmodName));
157  return(E_BADPARM);
158  }
159 
160  if ((model->LTRAresist == 0.0 ? 0 : 1) +
161  (model->LTRAconduct == 0.0 ? 0 : 1) +
162  (model->LTRAinduct == 0.0 ? 0 : 1) +
163  (model->LTRAcapac == 0.0 ? 0 : 1) <= 1) {
164 
165  (*(SPfrontEnd->IFerror))(ERR_FATAL,
166  "%s: At least two of R,L,G,C must be specified and nonzero",
167  &(model->LTRAmodName));
168  return(E_BADPARM);
169  }
170 
171  switch (model->LTRAspecialCase) {
172 
173  case LTRA_MOD_LC:
174 
175  model->LTRAimped =
176  sqrt(model->LTRAinduct/model->LTRAcapac);
177  model->LTRAadmit = 1/model->LTRAimped;
178  model->LTRAtd =
179  sqrt(model->LTRAinduct*model->LTRAcapac)*
180  model->LTRAlength;
181  model->LTRAattenuation = 1.0;
182  break;
183 
184  case LTRA_MOD_RLC:
185  model->LTRAimped =
186  sqrt(model->LTRAinduct/model->LTRAcapac);
187  model->LTRAadmit = 1/model->LTRAimped;
188  model->LTRAtd =
189  sqrt(model->LTRAinduct*model->LTRAcapac)*
190  model->LTRAlength;
191  model->LTRAalpha =
192  0.5*(model->LTRAresist/model->LTRAinduct);
193  model->LTRAbeta = model->LTRAalpha;
194  model->LTRAattenuation = exp(- model->LTRAbeta *
195  model->LTRAtd);
196  if (model->LTRAalpha > 0.0) {
197  model->LTRAintH1dash = -1.0;
198  model->LTRAintH2 = 1.0 - model->LTRAattenuation;
199  model->LTRAintH3dash = - model->LTRAattenuation;
200  }
201  else if (model->LTRAalpha == 0.0) {
202  model->LTRAintH1dash = model->LTRAintH2 =
203  model->LTRAintH3dash = 0.0;
204  }
205  else {
206 #ifdef LTRADEBUG
207  fprintf(stdout,"LTRAtemp: error: alpha < 0.0\n");
208 #endif
209  }
210 
211  if (!model->LTRAtruncDontCut) {
212 
213  /*
214  There was a bug<?) in spice3 here - the args to
215  the second line check were identical to the first
216  call, so all of the y2 terms were superfluous.
217  Replacing with the y2 values in the original
218  algorithm cut the resulting step size too much, so
219  here we do a binary search to find a more accurate
220  value. This is worthwhile since maxSafeStep has a
221  profound effect on default simulation speed.
222  */
223 
224  double xbig, xsmall, xmid, y1big, y1small, y1mid;
225  double xdel, y2big, y2small, y2mid;
226  int done=0, done0=0, maxiter=50, iters=0;
227 
228  xbig = model->LTRAtd + 9*model->LTRAtd;
229  /* hack! ckt is not yet initialised... */
230  xsmall = model->LTRAtd;
231  xmid = 0.5*(xbig+xsmall);
232  y1small = LTRArlcH2Func(xsmall,(GENmodel*)model);
233  y2small = LTRArlcH3dashFunc(xsmall,model->LTRAtd,
234  model->LTRAbeta,model->LTRAbeta);
235  iters = 0;
236  for (;;) {
237  iters++;
238  y1big = LTRArlcH2Func(xbig,(GENmodel*)model);
239  y1mid = LTRArlcH2Func(xmid,(GENmodel*)model);
240  y2big = LTRArlcH3dashFunc(xbig,model->LTRAtd,
241  model->LTRAbeta,model->LTRAbeta);
242  y2mid = LTRArlcH3dashFunc(xmid,model->LTRAtd,
243  model->LTRAbeta,model->LTRAbeta);
244  done =
245  LTRAstraightLineCheck(xbig,y1big,xmid,y1mid,
246  xsmall,y1small,model->LTRAstLineReltol,
247  model->LTRAstLineAbstol) +
248  LTRAstraightLineCheck(xbig,y2big,xmid,y2mid,
249  xsmall,y2small,model->LTRAstLineReltol,
250  model->LTRAstLineAbstol);
251 
252  if (iters > maxiter)
253  break;
254  if (done == 2) {
255  if (!done0) {
256  maxiter = iters + 8;
257  done0 = 1;
258  xdel = xbig - xmid;
259  }
260  xbig += xdel;
261  xdel *= 0.5;
262  }
263  else {
264  if (done0) {
265  xbig -= xdel;
266  xdel *= 0.5;
267  }
268  else
269  xbig = xmid;
270  }
271  xmid = 0.5*(xbig + xsmall);
272  }
273  model->LTRAmaxSafeStep = xbig - model->LTRAtd;
274  }
275  break;
276 
277  case LTRA_MOD_RC:
278  model->LTRAcByR = model->LTRAcapac/model->LTRAresist;
279  model->LTRArclsqr = model->LTRAresist*model->LTRAcapac
280  *model->LTRAlength*model->LTRAlength;
281  model->LTRAintH1dash = 0.0;
282  model->LTRAintH2 = 1.0;
283  model->LTRAintH3dash = 0.0;
284 
285  model->LTRAh1dashCoeffs = (double *) NULL;
286  model->LTRAh2Coeffs = (double *) NULL;
287  model->LTRAh3dashCoeffs = (double *) NULL;
288 
289  break;
290 
291  case LTRA_MOD_RG:
292  dummy1 = model->LTRAlength*
293  sqrt(model->LTRAresist*model->LTRAconduct);
294  dummy2 = exp(-dummy1);
295  /* warning: may overflow! */
296  dummy1 = exp(dummy1);
297  model->LTRAcoshlrootGR = 0.5*(dummy1 + dummy2);
298 
299  if (model->LTRAconduct <= 1.0e-10) { /* hack! */
300  model->LTRArRsLrGRorG =
301  model->LTRAlength*model->LTRAresist;
302  }
303  else {
304  model->LTRArRsLrGRorG = 0.5*(dummy1 - dummy2)*
305  sqrt(model->LTRAresist/model->LTRAconduct);
306  }
307 
308  if (model->LTRAresist <= 1.0e-10) { /* hack! */
309  model->LTRArGsLrGRorR =
310  model->LTRAlength*model->LTRAconduct;
311  }
312  else {
313  model->LTRArGsLrGRorR = 0.5*(dummy1 - dummy2)*
314  sqrt(model->LTRAconduct/model->LTRAresist);
315  }
316  break;
317 
318  default:
319  return (E_BADPARM);
320  }
321 
322  FREE(model->LTRAh1dashCoeffs);
323  FREE(model->LTRAh2Coeffs);
324  FREE(model->LTRAh3dashCoeffs);
325 
326  /* loop through all the instances of the model */
327  for (here = model->LTRAinstances; here != NULL ;
328  here = here->LTRAnextInstance) {
329 
330  FREE(here->LTRAv1);
331  FREE(here->LTRAi1);
332  FREE(here->LTRAv2);
333  FREE(here->LTRAi2);
334 
335  if (here->LTRAbrEq1 == 0) {
336  error = CKTmkVolt(ckt,&tmp,here->LTRAname,"i1");
337  if (error) return (error);
338  here->LTRAbrEq1 = tmp->number;
339  }
340 
341  if (here->LTRAbrEq2==0) {
342  error = CKTmkVolt(ckt,&tmp,here->LTRAname,"i2");
343  if (error) return (error);
344  here->LTRAbrEq2 = tmp->number;
345  }
346 
347  TSTALLOC(LTRAibr1Pos1Ptr, LTRAbrEq1, LTRAposNode1)
348  TSTALLOC(LTRAibr1Neg1Ptr, LTRAbrEq1, LTRAnegNode1)
349  TSTALLOC(LTRAibr1Pos2Ptr, LTRAbrEq1, LTRAposNode2)
350  TSTALLOC(LTRAibr1Neg2Ptr, LTRAbrEq1, LTRAnegNode2)
351  TSTALLOC(LTRAibr1Ibr1Ptr, LTRAbrEq1, LTRAbrEq1)
352  TSTALLOC(LTRAibr1Ibr2Ptr, LTRAbrEq1, LTRAbrEq2)
353  TSTALLOC(LTRAibr2Pos1Ptr, LTRAbrEq2, LTRAposNode1)
354  TSTALLOC(LTRAibr2Neg1Ptr, LTRAbrEq2, LTRAnegNode1)
355  TSTALLOC(LTRAibr2Pos2Ptr, LTRAbrEq2, LTRAposNode2)
356  TSTALLOC(LTRAibr2Neg2Ptr, LTRAbrEq2, LTRAnegNode2)
357  TSTALLOC(LTRAibr2Ibr1Ptr, LTRAbrEq2, LTRAbrEq1)
358  TSTALLOC(LTRAibr2Ibr2Ptr, LTRAbrEq2, LTRAbrEq2)
359  TSTALLOC(LTRApos1Ibr1Ptr, LTRAposNode1, LTRAbrEq1)
360  TSTALLOC(LTRAneg1Ibr1Ptr, LTRAnegNode1, LTRAbrEq1)
361  TSTALLOC(LTRApos2Ibr2Ptr, LTRAposNode2, LTRAbrEq2)
362  TSTALLOC(LTRAneg2Ibr2Ptr, LTRAnegNode2, LTRAbrEq2)
363  /* the following are done so that SMPpreOrder does not
364  * screw up on occasion - for example, when one end
365  * of the lossy line is hanging
366  */
367  TSTALLOC(LTRApos1Pos1Ptr, LTRAposNode1, LTRAposNode1)
368  TSTALLOC(LTRAneg1Neg1Ptr, LTRAnegNode1, LTRAnegNode1)
369  TSTALLOC(LTRApos2Pos2Ptr, LTRAposNode2, LTRAposNode2)
370  TSTALLOC(LTRAneg2Neg2Ptr, LTRAnegNode2, LTRAnegNode2)
371 
372  here->LTRAstate = *state;
373  *state += 2;
374  }
375  }
376  return(OK);
377 }
#define LTRA_MOD_MIXEDINTERP
Definition: ltradefs.h:199
double LTRArGsLrGRorR
Definition: ltradefs.h:125
#define LTRA_MOD_NOSTEPLIMIT
Definition: ltradefs.h:196
double LTRAimped
Definition: ltradefs.h:112
unsigned LTRAresistGiven
Definition: ltradefs.h:142
double LTRAcapac
Definition: ltradefs.h:109
double LTRAintH2
Definition: ltradefs.h:120
int LTRAstate
Definition: ltradefs.h:24
#define LTRA_MOD_LININTERP
Definition: ltradefs.h:197
double LTRAalpha
Definition: ltradefs.h:114
if(TDesc==NULL)
Definition: cd.c:1326
#define ERR_FATAL
Definition: ifsim.h:518
#define LTRA_MOD_LTRA
Definition: ltradefs.h:184
double LTRAinduct
Definition: ltradefs.h:108
IFfrontEnd * SPfrontEnd
Definition: main.c:917
double LTRAintH1dash
Definition: ltradefs.h:119
int LTRAstepLimit
Definition: ltradefs.h:151
double LTRAlength
Definition: ltradefs.h:110
#define LTRA_MOD_RG
Definition: ltradefs.h:163
#define E_BADPARM
Definition: iferrmsg.h:26
unsigned LTRAtruncDontCut
Definition: ltradefs.h:137
unsigned LTRAlengthGiven
Definition: ltradefs.h:146
struct sLTRAinstance * LTRAnextInstance
Definition: ltradefs.h:21
double CKTreltol
Definition: cktdefs.h:183
#define FREE(ptr)
Definition: spdefs.h:436
int LTRAhowToInterp
Definition: ltradefs.h:149
int LTRAsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *state)
Definition: ltraset.c:18
double LTRAstLineReltol
Definition: ltradefs.h:128
#define LTRA_MOD_LC
Definition: ltradefs.h:164
#define ERR_INFO
Definition: ifsim.h:520
#define TSTALLOC(ptr, first, second)
Definition: devdefs.h:124
double LTRArRsLrGRorG
Definition: ltradefs.h:124
double LTRAintH3dash
Definition: ltradefs.h:121
double LTRAabstol
Definition: ltradefs.h:155
#define LTRA_MOD_FULLCONTROL
Definition: ltradefs.h:194
double CKTabstol
Definition: cktdefs.h:180
#define OK
Definition: iferrmsg.h:17
double * LTRAi2
Definition: ltradefs.h:42
double LTRAstLineAbstol
Definition: ltradefs.h:130
double LTRAreltol
Definition: ltradefs.h:156
LTRAinstance * LTRAinstances
Definition: ltradefs.h:84
#define LTRA_MOD_RL
Definition: ltradefs.h:165
#define NULL
Definition: spdefs.h:121
IFuid LTRAname
Definition: ltradefs.h:23
double * LTRAv2
Definition: ltradefs.h:41
int LTRAbrEq1
Definition: ltradefs.h:29
double LTRArlcH3dashFunc()
double * LTRAh2Coeffs
Definition: ltradefs.h:102
int number
Definition: cktdefs.h:39
unsigned LTRAinductGiven
Definition: ltradefs.h:144
double LTRArlcH2Func()
double LTRAcByR
Definition: ltradefs.h:117
#define ERR_WARNING
Definition: ifsim.h:517
IFuid LTRAmodName
Definition: ltradefs.h:86
double * LTRAi1
Definition: ltradefs.h:40
double LTRAmaxSafeStep
Definition: ltradefs.h:140
#define LTRA_MOD_HALFCONTROL
Definition: ltradefs.h:193
int LTRAlteConType
Definition: ltradefs.h:147
unsigned LTRAconductGiven
Definition: ltradefs.h:143
static char model[32]
Definition: subckt.c:76
double LTRAbeta
Definition: ltradefs.h:115
double LTRArclsqr
Definition: ltradefs.h:118
double * LTRAh3dashCoeffs
Definition: ltradefs.h:103
double LTRAtd
Definition: ltradefs.h:111
double LTRAcoshlrootGR
Definition: ltradefs.h:123
double LTRAadmit
Definition: ltradefs.h:113
unsigned int CKTtryToCompact
Definition: cktdefs.h:226
#define LTRA_MOD_RLC
Definition: ltradefs.h:161
#define LTRA_MOD_NOCONTROL
Definition: ltradefs.h:192
int LTRAstraightLineCheck()
int CKTmkVolt()
struct sLTRAmodel * LTRAnextModel
Definition: ltradefs.h:82
int LTRAbrEq2
Definition: ltradefs.h:30
double LTRAconduct
Definition: ltradefs.h:106
unsigned LTRAcapacGiven
Definition: ltradefs.h:145
#define SMPmatrix
Definition: smpdefs.h:11
unsigned LTRAreltolGiven
Definition: ltradefs.h:133
double LTRAattenuation
Definition: ltradefs.h:116
double * LTRAh1dashCoeffs
Definition: ltradefs.h:101
#define LTRA_MOD_QUADINTERP
Definition: ltradefs.h:198
#define LTRA_MOD_RC
Definition: ltradefs.h:162
double * LTRAv1
Definition: ltradefs.h:39
double LTRAresist
Definition: ltradefs.h:107
#define LTRA_MOD_STEPLIMIT
Definition: ltradefs.h:195
unsigned LTRAabstolGiven
Definition: ltradefs.h:134
int LTRAspecialCase
Definition: ltradefs.h:158