1 /**********
2 Copyright 1990 Regents of the University of California.  All rights reserved.
3 Author: 1985 Thomas L. Quarles
4 
5 This function is obsolete (was used by an old sensitivity analysis)
6 **********/
7 
8 /* actually load the current ac sensitivity
9  * information into the  array previously provided
10  */
11 
12 #include "ngspice/ngspice.h"
13 #include "ngspice/cktdefs.h"
14 #include "ngspice/smpdefs.h"
15 #include "bjtdefs.h"
16 #include "ngspice/const.h"
17 #include "ngspice/sperror.h"
18 #include "ngspice/ifsim.h"
19 #include "ngspice/suffix.h"
20 
21 
22 int
BJTsAcLoad(GENmodel * inModel,CKTcircuit * ckt)23 BJTsAcLoad(GENmodel *inModel, CKTcircuit *ckt)
24 {
25 
26     BJTmodel *model = (BJTmodel*)inModel;
27     BJTinstance *here;
28     double SaveState[25];
29     int    error;
30     int    flag;
31     double vbeOp;
32     double vbcOp;
33     double A0;
34     double DELA = 0.0;
35     double Apert;
36     double DELAinv;
37     double vte = 0.0;
38     double gcpr;
39     double gepr;
40     double gpi;
41     double gmu;
42     double go;
43     double xgm;
44     double td;
45     double arg;
46     double gm;
47     double gx;
48     double xcpi;
49     double xcmu;
50     double xcbx;
51     double xccs;
52     double xcmcb;
53     double cx,icx;
54     double cbx,icbx;
55     double ccs,iccs;
56     double cbc,icbc;
57     double cbe,icbe;
58     double cce,icce;
59     double cb,icb;
60     double cbprm,icbprm;
61     double cc,icc;
62     double ccprm,iccprm;
63     double ce,ice;
64     double ceprm,iceprm;
65     double cs,ics;
66     double vcpr,ivcpr;
67     double vepr,ivepr;
68     double vx,ivx;
69     double vbx,ivbx;
70     double vcs,ivcs;
71     double vbc,ivbc;
72     double vbe,ivbe;
73     double vce,ivce;
74     double cb0,icb0;
75     double cbprm0,icbprm0;
76     double cc0,icc0;
77     double ccprm0,iccprm0;
78     double ce0,ice0;
79     double ceprm0,iceprm0;
80     double cs0,ics0;
81     double DvDp = 0.0;
82     int iparmno,i;
83     SENstruct *info;
84 
85 
86 #ifdef SENSDEBUG
87     printf("BJTsenacload \n");
88     printf("BJTsenacload \n");
89 #endif /* SENSDEBUG */
90 
91     info = ckt->CKTsenInfo;
92     info->SENstatus = PERTURBATION;
93 
94     /*  loop through all the models */
95     for( ; model != NULL; model = BJTnextModel(model)) {
96 
97         /* loop through all the instances of the model */
98         for (here = BJTinstances(model); here != NULL ;
99                 here=BJTnextInstance(here)) {
100 
101 
102             /* save the unperturbed values in the state vector */
103             for(i=0; i <= 20; i++) {
104                 *(SaveState + i) = *(ckt->CKTstate0 + here->BJTstate + i);
105             }
106 
107             vcpr = *(ckt->CKTrhsOld + here->BJTcolNode)
108                 - *(ckt->CKTrhsOld + here->BJTcolPrimeNode) ;
109             ivcpr = *(ckt->CKTirhsOld + here->BJTcolNode)
110                 - *(ckt->CKTirhsOld + here->BJTcolPrimeNode) ;
111             vepr = *(ckt->CKTrhsOld + here->BJTemitNode)
112                 - *(ckt->CKTrhsOld + here->BJTemitPrimeNode) ;
113             ivepr = *(ckt->CKTirhsOld + here->BJTemitNode)
114                 - *(ckt->CKTirhsOld + here->BJTemitPrimeNode) ;
115             vx = *(ckt->CKTrhsOld + here->BJTbaseNode)
116                 - *(ckt->CKTrhsOld + here->BJTbasePrimeNode) ;/* vb_bprm */
117             ivx = *(ckt->CKTirhsOld + here->BJTbaseNode)
118                 - *(ckt->CKTirhsOld + here->BJTbasePrimeNode) ;/* ivb_bprm */
119             vcs = *(ckt->CKTrhsOld + here->BJTcolPrimeNode)
120                 - *(ckt->CKTrhsOld + here->BJTsubstNode) ;
121             ivcs = *(ckt->CKTirhsOld + here->BJTcolPrimeNode)
122                 - *(ckt->CKTirhsOld + here->BJTsubstNode) ;
123             vbc = *(ckt->CKTrhsOld + here->BJTbasePrimeNode)
124                 - *(ckt->CKTrhsOld + here->BJTcolPrimeNode) ;/* vbprm_cprm */
125             ivbc = *(ckt->CKTirhsOld + here->BJTbasePrimeNode)
126                 - *(ckt->CKTirhsOld + here->BJTcolPrimeNode) ;/* ivbprm_cprm */
127             vbe = *(ckt->CKTrhsOld + here->BJTbasePrimeNode)
128                 - *(ckt->CKTrhsOld + here->BJTemitPrimeNode) ;/* vbprm_eprm */
129             ivbe = *(ckt->CKTirhsOld + here->BJTbasePrimeNode)
130                 - *(ckt->CKTirhsOld + here->BJTemitPrimeNode) ;/* ivbprm_eprm */
131             vce = vbe - vbc ;
132             ivce = ivbe - ivbc ;
133             vbx = vx + vbc ;
134             ivbx = ivx + ivbc ;
135 
136 
137 
138             vbeOp =model->BJTtype * ( *(ckt->CKTrhsOp +  here->BJTbasePrimeNode)
139                 -  *(ckt->CKTrhsOp +  here->BJTemitPrimeNode));
140             vbcOp =model->BJTtype * ( *(ckt->CKTrhsOp +  here->BJTbasePrimeNode)
141                 -  *(ckt->CKTrhsOp +  here->BJTcolPrimeNode));
142 
143 #ifdef SENSDEBUG
144             printf("\n without perturbation\n");
145 #endif /* SENSDEBUG */
146             /* without perturbation */
147             A0 = here->BJTarea;
148             here->BJTsenPertFlag = ON;
149             *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
150             *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
151             /* info->SENacpertflag == 1 only for first frequency */
152 
153             if(info->SENacpertflag == 1){
154 
155                 /* store the  unperturbed values of small signal parameters */
156 
157 	      if ((error = BJTload((GENmodel*)model,ckt)) != 0)
158 		     return(error);
159 
160                 *(here->BJTsenGpi)= *(ckt->CKTstate0 + here->BJTgpi);
161                 *(here->BJTsenGmu)= *(ckt->CKTstate0 + here->BJTgmu);
162                 *(here->BJTsenGm)= *(ckt->CKTstate0 + here->BJTgm);
163                 *(here->BJTsenGo)= *(ckt->CKTstate0 + here->BJTgo);
164                 *(here->BJTsenGx)= *(ckt->CKTstate0 + here->BJTgx);
165                 *(here->BJTsenCpi)= *(ckt->CKTstate0 + here->BJTcqbe);
166                 *(here->BJTsenCmu)= *(ckt->CKTstate0 + here->BJTcqbc);
167                 *(here->BJTsenCbx)= *(ckt->CKTstate0 + here->BJTcqbx);
168                 *(here->BJTsenCsub)= *(ckt->CKTstate0 + here->BJTcqsub);
169                 *(here->BJTsenCmcb)= *(ckt->CKTstate0 + here->BJTcexbc);
170             }
171             gcpr = here->BJTtcollectorConduct * A0;
172             gepr = here->BJTtemitterConduct * A0;
173             gpi= *(here->BJTsenGpi);
174             gmu= *(here->BJTsenGmu);
175             gm= *(here->BJTsenGm);
176             go= *(here->BJTsenGo);
177             gx= *(here->BJTsenGx);
178             xgm=0;
179             td=model->BJTexcessPhase;
180             if(td != 0) {
181                 arg = td*ckt->CKTomega;
182                 gm = gm+go;
183                 xgm = -gm * sin(arg);
184                 gm = gm * cos(arg)-go;
185             }
186             xcpi= *(here->BJTsenCpi) * ckt->CKTomega;
187             xcmu= *(here->BJTsenCmu) * ckt->CKTomega;
188             xcbx= *(here->BJTsenCbx) * ckt->CKTomega;
189             xccs= *(here->BJTsenCsub) * ckt->CKTomega;
190             xcmcb= *(here->BJTsenCmcb) * ckt->CKTomega;
191 
192 
193             cx=gx * vx ;
194             icx=gx * ivx;
195             cbx=( -xcbx * ivbx) ;
196             icbx= xcbx * vbx ;
197             ccs=( -xccs * ivcs) ;
198             iccs= xccs * vcs ;
199             cbc=(gmu * vbc -xcmu * ivbc) ;
200             icbc=xcmu * vbc +  gmu * ivbc ;
201             cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ;
202             icbe=xcpi * vbe +  gpi * ivbe + xcmcb * vbc;
203             cce= go * vce + gm * vbe - xgm * ivbe;
204             icce=go * ivce + gm * ivbe + xgm * vbe ;
205 
206             cc0=gcpr * vcpr ;
207             icc0=gcpr * ivcpr ;
208             ce0=gepr * vepr;
209             ice0=gepr * ivepr ;
210             cb0 = cx + cbx;
211             icb0 = icx + icbx;
212             if(here->BJTbaseNode != here->BJTbasePrimeNode){
213                 cbprm0 = (- cx + cbe + cbc);
214                 icbprm0 = (- icx + icbe + icbc);
215             }
216             else{
217                 cbprm0 = ( cbx + cbe + cbc);
218                 icbprm0 = (icbx + icbe + icbc);
219             }
220             ccprm0 = (- cbx - cc0 + ccs + cce - cbc);
221             iccprm0 = (- icbx - icc0 + iccs + icce - icbc);
222             ceprm0 = (- cbe - cce - ce0);
223             iceprm0 = (- icbe - icce - ice0);
224             cs0 = (- ccs) ;
225             ics0 = (- iccs) ;
226 
227 #ifdef SENSDEBUG
228             printf("gepr0 = %.7e , gcpr0 = %.7e , gmu0 = %.7e, gpi0 = %.7e\n",
229                     gepr,gcpr,gmu,gpi);
230             printf("gm0 = %.7e , go0 = %.7e , gx0 = %.7e, xcpi0 = %.7e\n",
231                     gm,go,gx,xcpi);
232             printf("xcmu0 = %.7e , xcbx0 = %.7e , xccs0 = %.7e, xcmcb0 = %.7e\n"
233                     ,xcmu,xcbx,xccs,xcmcb);
234             printf("vepr = %.7e + j%.7e , vcpr = %.7e + j%.7e\n",
235                     vepr,ivepr,vcpr,ivcpr);
236             printf("vbx = %.7e + j%.7e , vx = %.7e + j%.7e\n",
237                     vbx,ivbx,vx,ivx);
238             printf("vbc = %.7e + j%.7e , vbe = %.7e + j%.7e\n",
239                     vbc,ivbc,vbe,ivbe);
240             printf("vce = %.7e + j%.7e , vcs = %.7e + j%.7e\n",
241                     vce,ivce,vcs,ivcs);
242             printf("cce0 = %.7e + j%.7e , cbe0 = %.7e + j%.7e\n",
243                     cce,icce,cbe,icbe);
244             printf("cbc0 = %.7e + j%.7e\n",
245                     cbc,icbc);
246             printf("cc0 = %.7e + j%.7e , ce0 = %.7e + j%.7e\n",
247                     cc0,icc0,ce0,ice0);
248             printf("cb0 = %.7e + j%.7e , cs0 = %.7e + j%.7e\n",
249                     cb0,icb0,cs0,ics0);
250             printf("cbprm0 = %.7e + j%.7e , ceprm0 = %.7e + j%.7e\n",
251                     cbprm0,icbprm0,ceprm0,iceprm0);
252             printf("ccprm0 = %.7e + j%.7e \n",
253                     ccprm0,iccprm0);
254             printf("\nPerturbation of Area\n");
255 #endif /* SENSDEBUG */
256             /* Perturbation of Area */
257             if(here->BJTsenParmNo == 0){
258                 flag = 0;
259                 goto next1;
260             }
261 
262             DELA = info->SENpertfac * A0;
263             Apert = A0 + DELA;
264             DELAinv = 1.0/DELA;
265             here->BJTarea = Apert;
266 
267             *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
268             *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
269             if(info->SENacpertflag == 1){
270 
271                 /* store the  small signal parameters
272                  * corresponding to perturbed area
273                  */
274                 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
275 		  return(error);
276 
277                 *(here->BJTsenGpi + 1)= *(ckt->CKTstate0 + here->BJTgpi);
278                 *(here->BJTsenGmu + 1)= *(ckt->CKTstate0 + here->BJTgmu);
279                 *(here->BJTsenGm + 1)= *(ckt->CKTstate0 + here->BJTgm);
280                 *(here->BJTsenGo + 1)= *(ckt->CKTstate0 + here->BJTgo);
281                 *(here->BJTsenGx + 1)= *(ckt->CKTstate0 + here->BJTgx);
282                 *(here->BJTsenCpi + 1)= *(ckt->CKTstate0 + here->BJTcqbe);
283                 *(here->BJTsenCmu + 1)= *(ckt->CKTstate0 + here->BJTcqbc);
284                 *(here->BJTsenCbx + 1)= *(ckt->CKTstate0 + here->BJTcqbx);
285                 *(here->BJTsenCsub + 1)= *(ckt->CKTstate0 + here->BJTcqsub);
286                 *(here->BJTsenCmcb + 1)= *(ckt->CKTstate0 + here->BJTcexbc);
287             }
288 
289 
290             flag = 0;
291             goto load;
292 
293 
294 
295 pertvbx:    /* Perturbation of vbx */
296 #ifdef SENSDEBUG
297             printf("\nPerturbation of vbx\n");
298 #endif /* SENSDEBUG */
299             here->BJTarea = A0;
300             A0 = model->BJTtype * (*(ckt->CKTrhsOp + here->BJTbaseNode)
301                 - *(ckt->CKTrhsOp + here->BJTcolPrimeNode));
302             DELA = info->SENpertfac * A0 + 1e-8;
303             Apert = A0 + DELA;
304             DELAinv = model->BJTtype * 1.0/DELA;
305             *(ckt->CKTrhsOp + here->BJTbaseNode) += DELA;
306             *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
307             *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
308 
309             if(info->SENacpertflag == 1){
310 
311                 /* store the  small signal parameters
312                  * corresponding to perturbed vbx
313                  */
314                 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
315 		  return(error);
316 
317                 *(here->BJTsenGpi + 2)= *(ckt->CKTstate0 + here->BJTgpi);
318                 *(here->BJTsenGmu + 2)= *(ckt->CKTstate0 + here->BJTgmu);
319                 *(here->BJTsenGm + 2)= *(ckt->CKTstate0 + here->BJTgm);
320                 *(here->BJTsenGo + 2)= *(ckt->CKTstate0 + here->BJTgo);
321                 *(here->BJTsenGx + 2)= *(ckt->CKTstate0 + here->BJTgx);
322                 *(here->BJTsenCpi + 2)= *(ckt->CKTstate0 + here->BJTcqbe);
323                 *(here->BJTsenCmu + 2)= *(ckt->CKTstate0 + here->BJTcqbc);
324                 *(here->BJTsenCbx + 2)= *(ckt->CKTstate0 + here->BJTcqbx);
325                 *(here->BJTsenCsub + 2)= *(ckt->CKTstate0 + here->BJTcqsub);
326                 *(here->BJTsenCmcb + 2)= *(ckt->CKTstate0 + here->BJTcexbc);
327             }
328 
329 
330             flag = 1;
331             goto load;
332 
333 
334 pertvbe:    /* Perturbation of vbe */
335 #ifdef SENSDEBUG
336             printf("\nPerturbation of vbe\n");
337 #endif /* SENSDEBUG */
338             if (*(here->BJTsenCbx) != 0){
339                 *(ckt->CKTrhsOp + here ->BJTbaseNode) -= DELA;
340             }
341             vte=model->BJTleakBEemissionCoeff*CONSTvt0;
342             A0 = vbeOp;
343             DELA = info->SENpertfac * vte ;
344             Apert = A0 + DELA;
345             DELAinv = 1.0/DELA;
346             *(ckt->CKTstate0 + here->BJTvbe) = Apert;
347             *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
348 
349             if(info->SENacpertflag == 1){
350 
351                 /* store the  small signal parameters
352                  * corresponding to perturbed vbe
353                  */
354                 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
355 		  return(error);
356 
357                 *(here->BJTsenGpi + 3)= *(ckt->CKTstate0 + here->BJTgpi);
358                 *(here->BJTsenGmu + 3)= *(ckt->CKTstate0 + here->BJTgmu);
359                 *(here->BJTsenGm + 3)= *(ckt->CKTstate0 + here->BJTgm);
360                 *(here->BJTsenGo + 3)= *(ckt->CKTstate0 + here->BJTgo);
361                 *(here->BJTsenGx + 3)= *(ckt->CKTstate0 + here->BJTgx);
362                 *(here->BJTsenCpi + 3)= *(ckt->CKTstate0 + here->BJTcqbe);
363                 *(here->BJTsenCmu + 3)= *(ckt->CKTstate0 + here->BJTcqbc);
364                 *(here->BJTsenCbx + 3)= *(ckt->CKTstate0 + here->BJTcqbx);
365                 *(here->BJTsenCsub + 3)= *(ckt->CKTstate0 + here->BJTcqsub);
366                 *(here->BJTsenCmcb + 3)= *(ckt->CKTstate0 + here->BJTcexbc);
367             }
368 
369 
370             flag = 2;
371             goto load;
372 
373 
374 pertvbc:    /* Perturbation of vbc */
375 #ifdef SENSDEBUG
376             printf("\nPerturbation of vbc\n");
377 #endif /* SENSDEBUG */
378             *(ckt->CKTstate0 + here->BJTvbe) = A0;
379 
380             A0 = vbcOp;
381             DELA = info->SENpertfac * vte ;
382             Apert = A0 + DELA;
383             DELAinv = 1.0/DELA;
384 
385 
386             *(ckt->CKTstate0 + here->BJTvbc) = Apert;
387 
388             *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
389 
390 
391 
392             if(info->SENacpertflag == 1){
393 
394                 /* store the  small signal parameters
395                  * corresponding to perturbed vbc
396                  */
397                 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
398 		  return(error);
399                 *(here->BJTsenGpi + 4)= *(ckt->CKTstate0 + here->BJTgpi);
400                 *(here->BJTsenGmu + 4)= *(ckt->CKTstate0 + here->BJTgmu);
401                 *(here->BJTsenGm + 4)= *(ckt->CKTstate0 + here->BJTgm);
402                 *(here->BJTsenGo + 4)= *(ckt->CKTstate0 + here->BJTgo);
403                 *(here->BJTsenGx + 4)= *(ckt->CKTstate0 + here->BJTgx);
404                 *(here->BJTsenCpi + 4)= *(ckt->CKTstate0 + here->BJTcqbe);
405                 *(here->BJTsenCmu + 4)= *(ckt->CKTstate0 + here->BJTcqbc);
406                 *(here->BJTsenCbx + 4)= *(ckt->CKTstate0 + here->BJTcqbx);
407                 *(here->BJTsenCsub + 4)= *(ckt->CKTstate0 + here->BJTcqsub);
408                 *(here->BJTsenCmcb + 4)= *(ckt->CKTstate0 + here->BJTcexbc);
409 
410             }
411 
412 
413             flag = 3;
414             goto load;
415 
416 
417 
418 pertvcs:    /* Perturbation of vcs */
419 #ifdef SENSDEBUG
420             printf("\nPerturbation of vcs\n");
421 #endif /* SENSDEBUG */
422             *(ckt->CKTstate0 + here->BJTvbc) = A0;
423             A0 = model->BJTtype * (*(ckt->CKTrhsOp + here->BJTsubstNode)
424                 -  *(ckt->CKTrhsOp + here->BJTcolPrimeNode));
425             DELA = info->SENpertfac * A0 + 1e-8;
426             Apert = A0 + DELA;
427             DELAinv = model->BJTtype * 1.0/DELA;
428             *(ckt->CKTrhsOp + here->BJTsubstNode) += DELA;
429             *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
430             *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
431 
432             if(info->SENacpertflag == 1){
433 
434                 /* store the  small signal parameters
435                  * corresponding to perturbed vcs
436                  */
437                 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
438 		  return(error);
439                 *(here->BJTsenCsub + 5)= *(ckt->CKTstate0 + here->BJTcqsub);
440 
441             }
442 
443 
444             flag = 4;
445 
446             *(ckt->CKTrhsOp + here->BJTsubstNode) -= DELA;
447             xccs= *(here->BJTsenCsub + 5) * ckt->CKTomega;
448 
449             ccs=( -xccs * ivcs) ;
450             iccs= xccs * vcs ;
451             cs = -ccs;
452             ics = -iccs;
453             ccprm = ccprm0 +  cs0 - cs;
454             iccprm = iccprm0 + ics0 - ics;
455             cbprm = cbprm0;
456             icbprm = icbprm0;
457             ceprm = ceprm0;
458             iceprm = iceprm0;
459             cc = cc0;
460             icc = icc0;
461             ce = ce0;
462             ice = ice0;
463             cb = cb0;
464             icb = icb0;
465             goto next2;
466 
467 load:
468             gcpr=here->BJTtcollectorConduct * here->BJTarea;
469             gepr=here->BJTtemitterConduct * here->BJTarea;
470             gpi= *(here->BJTsenGpi + flag+1);
471             gmu= *(here->BJTsenGmu + flag+1);
472             gm= *(here->BJTsenGm + flag+1);
473             go= *(here->BJTsenGo + flag+1);
474             gx= *(here->BJTsenGx + flag+1);
475             xgm=0;
476             td=model->BJTexcessPhase;
477             if(td != 0) {
478                 arg = td*ckt->CKTomega;
479                 gm = gm+go;
480                 xgm = -gm * sin(arg);
481                 gm = gm * cos(arg)-go;
482             }
483             xcpi= *(here->BJTsenCpi + flag+1) * ckt->CKTomega;
484             xcmu= *(here->BJTsenCmu + flag+1) * ckt->CKTomega;
485             xcbx= *(here->BJTsenCbx + flag+1) * ckt->CKTomega;
486             xccs= *(here->BJTsenCsub + flag+1) * ckt->CKTomega;
487             xcmcb= *(here->BJTsenCmcb + flag+1) * ckt->CKTomega;
488 
489 
490             cc=gcpr * vcpr ;
491             icc=gcpr * ivcpr ;
492             ce=gepr * vepr;
493             ice=gepr * ivepr ;
494             cx=gx * vx ;
495             icx=gx * ivx;
496             cbx=( -xcbx * ivbx) ;
497             icbx= xcbx * vbx ;
498             ccs=( -xccs * ivcs) ;
499             iccs= xccs * vcs ;
500             cbc=(gmu * vbc -xcmu * ivbc) ;
501             icbc=xcmu * vbc +  gmu * ivbc ;
502             cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ;
503             icbe=xcpi * vbe +  gpi * ivbe + xcmcb * vbc;
504             cce= go * vce + gm * vbe - xgm * ivbe;
505             icce=go * ivce + gm * ivbe + xgm * vbe ;
506 
507 
508             cb= cx + cbx;
509             icb= icx + icbx;
510             if(here->BJTbaseNode != here->BJTbasePrimeNode){
511                 cbprm=(- cx + cbe + cbc);
512                 icbprm=(- icx + icbe + icbc);
513             }
514             else{
515                 cbprm=( cbx + cbe + cbc);
516                 icbprm=(icbx + icbe + icbc);
517             }
518             ccprm=(- cbx - cc + ccs + cce - cbc);
519             iccprm=(- icbx - icc + iccs + icce - icbc);
520             ceprm=(- cbe - cce - ce);
521             iceprm=(- icbe - icce - ice);
522             cs= (- ccs) ;
523             ics= (- iccs) ;
524 
525 #ifdef SENSDEBUG
526             printf("A0 = %.7e , Apert = %.7e , DELA = %.7e\n"
527                     ,A0,Apert,DELA);
528             printf("gepr = %.7e , gcpr = %.7e , gmu = %.7e, gpi = %.7e\n"
529                     ,gepr,gcpr,gmu,gpi);
530             printf("gm = %.7e , go = %.7e , gx = %.7e, xcpi = %.7e\n"
531                     ,gm,go,gx,xcpi);
532             printf("xcmu = %.7e , xcbx = %.7e , xccs = %.7e, xcmcb = %.7e\n"
533                     ,xcmu,xcbx,xccs,xcmcb);
534 
535             printf("cx = %.7e + j%.7e , cbx = %.7e + j%.7e\n"
536                     ,cx,icx,cbx,icbx);
537             printf("ccs %.7e + j%.7e , cbc = %.7e + j%.7e"
538                     ,ccs,iccs,cbc,icbc);
539             printf("cbe %.7e + j%.7e , cce = %.7e + j%.7e\n"
540                     ,cbe,icbe,cce,icce);
541 
542             printf("cc = %.7e + j%.7e , ce = %.7e + j%.7e,",
543                     cc,icc,ce,ice);
544             printf("ccprm = %.7e + j%.7e , ceprm = %.7e + j%.7e",
545                     ccprm,iccprm,ceprm,iceprm);
546             printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ",
547                     cb,icb,cbprm,icbprm);
548             printf("cs = %.7e + j%.7e\n",
549                     cs,ics);
550 #endif /* SENSDEBUG */
551 
552 
553             /* load the RHS matrix */
554 next2:
555             for(iparmno = 1;iparmno<=info->SENparms;iparmno++){
556                 if( (!flag) && (iparmno != here->BJTsenParmNo) ) continue;
557                 switch(flag){
558 
559                 case 0:
560                     /* area : so no DC sensitivity term involved */
561                     DvDp = 1.0;
562 
563                     break;
564                     /* calculate the DC sensitivities of operating points */
565                 case 1:
566                     DvDp = model->BJTtype *
567                             (info->SEN_Sap[here->BJTbaseNode][iparmno]
568                             -  info->SEN_Sap[here->BJTcolPrimeNode][iparmno]);
569                     break;
570                 case 2:
571                     DvDp = model->BJTtype *
572                             (info->SEN_Sap[here->BJTbasePrimeNode][iparmno]
573                             -  info->SEN_Sap[here->BJTemitPrimeNode][iparmno]);
574                     break;
575                 case 3:
576                     DvDp = model->BJTtype *
577                             (info->SEN_Sap[here->BJTbasePrimeNode][iparmno]
578                             -  info->SEN_Sap[here->BJTcolPrimeNode][iparmno]);
579                     break;
580                 case 4:
581                     DvDp = model->BJTtype *
582                             (info->SEN_Sap[here->BJTsubstNode][iparmno]
583                             -  info->SEN_Sap[here->BJTcolPrimeNode][iparmno]);
584                     break;
585                 }
586 #ifdef SENSDEBUG
587                 printf("before loading\n");
588                 printf("BJTtype = %d\n",model->BJTtype);
589                 printf("DvDp = %.7e , flag = %d , iparmno = %d,senparmno = %d\n"
590                         ,DvDp,flag,iparmno,here->BJTsenParmNo);
591                 printf("senb = %.7e + j%.7e\n "
592                         ,*(info->SEN_RHS[here->BJTbaseNode] + iparmno),
593                         *(info->SEN_iRHS[here->BJTbaseNode] + iparmno));
594                 printf("senbrm = %.7e + j%.7e\n "
595                         ,*(info->SEN_RHS[here->BJTbasePrimeNode] + iparmno),
596                         *(info->SEN_iRHS[here->BJTbasePrimeNode] + iparmno));
597                 printf("senc = %.7e + j%.7e\n "
598                         ,*(info->SEN_RHS[here->BJTcolNode] + iparmno),
599                         *(info->SEN_iRHS[here->BJTcolNode] + iparmno));
600                 printf("sencprm = %.7e + j%.7e\n "
601                         ,*(info->SEN_RHS[here->BJTcolPrimeNode] + iparmno),
602                         *(info->SEN_iRHS[here->BJTcolPrimeNode] + iparmno));
603                 printf("sene = %.7e + j%.7e\n "
604                         ,*(info->SEN_RHS[here->BJTemitNode] + iparmno),
605                         *(info->SEN_iRHS[here->BJTemitNode] + iparmno));
606                 printf("seneprm = %.7e + j%.7e\n "
607                         ,*(info->SEN_RHS[here->BJTemitPrimeNode] + iparmno),
608                         *(info->SEN_iRHS[here->BJTemitPrimeNode] + iparmno));
609                 printf("sens = %.7e + j%.7e\n "
610                         ,*(info->SEN_RHS[here->BJTsubstNode] + iparmno),
611                         *(info->SEN_iRHS[here->BJTsubstNode] + iparmno));
612 #endif /* SENSDEBUG */
613 
614 
615                 if(here->BJTbaseNode != here->BJTbasePrimeNode){
616                     *(info->SEN_RHS[here->BJTbaseNode] + iparmno) -=
617                             ( cb  - cb0) * DELAinv * DvDp;
618                     *(info->SEN_iRHS[here->BJTbaseNode] + iparmno) -=
619                             ( icb  - icb0) * DELAinv * DvDp;
620                 }
621 
622                 *(info->SEN_RHS[here->BJTbasePrimeNode] + iparmno) -=
623                         ( cbprm  - cbprm0) * DELAinv * DvDp;
624                 *(info->SEN_iRHS[here->BJTbasePrimeNode] + iparmno) -=
625                         ( icbprm  - icbprm0) * DELAinv * DvDp;
626 
627                 if(here->BJTcolNode != here->BJTcolPrimeNode){
628                     *(info->SEN_RHS[here->BJTcolNode] + iparmno) -=
629                             ( cc  - cc0) * DELAinv * DvDp;
630                     *(info->SEN_iRHS[here->BJTcolNode] + iparmno) -=
631                             ( icc  - icc0) * DELAinv * DvDp;
632                 }
633 
634                 *(info->SEN_RHS[here->BJTcolPrimeNode] + iparmno) -=
635                         ( ccprm  - ccprm0) * DELAinv * DvDp;
636                 *(info->SEN_iRHS[here->BJTcolPrimeNode] + iparmno) -=
637                         ( iccprm  - iccprm0) * DELAinv * DvDp;
638 
639                 if(here->BJTemitNode != here->BJTemitPrimeNode){
640                     *(info->SEN_RHS[here->BJTemitNode] + iparmno) -=
641                             ( ce  - ce0) * DELAinv * DvDp;
642                     *(info->SEN_iRHS[here->BJTemitNode] + iparmno) -=
643                             ( ice  - ice0) * DELAinv * DvDp;
644                 }
645 
646                 *(info->SEN_RHS[here->BJTemitPrimeNode] + iparmno) -=
647                         ( ceprm  - ceprm0) * DELAinv * DvDp;
648                 *(info->SEN_iRHS[here->BJTemitPrimeNode] + iparmno) -=
649                         ( iceprm  - iceprm0) * DELAinv * DvDp;
650                 *(info->SEN_RHS[here->BJTsubstNode] + iparmno) -=
651                         ( cs  - cs0) * DELAinv * DvDp;
652                 *(info->SEN_iRHS[here->BJTsubstNode] + iparmno) -=
653                         ( ics  - ics0) * DELAinv * DvDp;
654 #ifdef SENSDEBUG
655                 printf("after loading\n");
656 
657                 printf("senb = %.7e + j%.7e\n "
658                         ,*(info->SEN_RHS[here->BJTbaseNode] + iparmno),
659                         *(info->SEN_iRHS[here->BJTbaseNode] + iparmno));
660                 printf("senbrm = %.7e + j%.7e\n "
661                         ,*(info->SEN_RHS[here->BJTbasePrimeNode] + iparmno),
662                         *(info->SEN_iRHS[here->BJTbasePrimeNode] + iparmno));
663                 printf("senc = %.7e + j%.7e\n "
664                         ,*(info->SEN_RHS[here->BJTcolNode] + iparmno),
665                         *(info->SEN_iRHS[here->BJTcolNode] + iparmno));
666                 printf("sencprm = %.7e + j%.7e\n "
667                         ,*(info->SEN_RHS[here->BJTcolPrimeNode] + iparmno),
668                         *(info->SEN_iRHS[here->BJTcolPrimeNode] + iparmno));
669                 printf("sene = %.7e + j%.7e\n "
670                         ,*(info->SEN_RHS[here->BJTemitNode] + iparmno),
671                         *(info->SEN_iRHS[here->BJTemitNode] + iparmno));
672                 printf("seneprm = %.7e + j%.7e\n "
673                         ,*(info->SEN_RHS[here->BJTemitPrimeNode] + iparmno),
674                         *(info->SEN_iRHS[here->BJTemitPrimeNode] + iparmno));
675                 printf("sens = %.7e + j%.7e\n "
676                         ,*(info->SEN_RHS[here->BJTsubstNode] + iparmno),
677                         *(info->SEN_iRHS[here->BJTsubstNode] + iparmno));
678 #endif /* SENSDEBUG */
679 
680             }
681 
682 
683 next1:
684             switch(flag){
685             case 0:
686                 if (*(here->BJTsenCbx) == 0){
687                     here->BJTarea = A0;
688                     goto pertvbe ;
689                 }
690                 else{
691                     goto pertvbx;
692                 }
693             case 1:
694                 goto pertvbe ;
695             case 2:
696                 goto pertvbc ;
697             case 3:
698                 goto pertvcs ;
699             case 4:
700                 break;
701             }
702 
703             /* put the unperturbed values back into the state vector */
704             for(i=0; i <= 20; i++) {
705                 *(ckt->CKTstate0 + here->BJTstate + i) = *(SaveState + i);
706             }
707             here->BJTsenPertFlag = OFF;
708         }
709 
710     }
711     info->SENstatus = NORMAL;
712 #ifdef SENSDEBUG
713     printf("BJTsenacload end\n");
714 #endif /* SENSDEBUG */
715     return(OK);
716 }
717 
718