1 /**********
2 Copyright 1990 Regents of the University of California. All rights reserved.
3 Author: 1985 Thomas L. Quarles
4 Modified: September 2003 Paolo Nenzi
5 **********/
6
7 #include "ngspice/ngspice.h"
8 #include "ngspice/cktdefs.h"
9 #include "ngspice/devdefs.h"
10 #include "capdefs.h"
11 #include "ngspice/ifsim.h"
12 #include "ngspice/sperror.h"
13 #include "ngspice/suffix.h"
14
15 /* ARGSUSED */
16 int
CAPask(CKTcircuit * ckt,GENinstance * inst,int which,IFvalue * value,IFvalue * select)17 CAPask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
18 IFvalue *select)
19 {
20 CAPinstance *here = (CAPinstance *)inst;
21 double vr;
22 double vi;
23 double sr;
24 double si;
25 double vm;
26 static char *msg = "Current and power not available for ac analysis";
27
28 switch(which) {
29 case CAP_TEMP:
30 value->rValue = here->CAPtemp - CONSTCtoK;
31 return(OK);
32 case CAP_DTEMP:
33 value->rValue = here->CAPdtemp;
34 return(OK);
35 case CAP_CAP:
36 value->rValue=here->CAPcapac;
37 value->rValue *= here->CAPm;
38 return(OK);
39 case CAP_IC:
40 value->rValue = here->CAPinitCond;
41 return(OK);
42 case CAP_WIDTH:
43 value->rValue = here->CAPwidth;
44 return(OK);
45 case CAP_LENGTH:
46 value->rValue = here->CAPlength;
47 return(OK);
48 case CAP_SCALE:
49 value->rValue = here->CAPscale;
50 return(OK);
51 case CAP_BV_MAX:
52 value->rValue = here->CAPbv_max;
53 return(OK);
54 case CAP_M:
55 value->rValue = here->CAPm;
56 return(OK);
57 case CAP_TC1:
58 value->rValue = here->CAPtc1;
59 return(OK);
60 case CAP_TC2:
61 value->rValue = here->CAPtc2;
62 return(OK);
63 case CAP_CURRENT:
64 if (ckt->CKTcurrentAnalysis & DOING_AC) {
65 errMsg = TMALLOC(char, strlen(msg) + 1);
66 errRtn = "CAPask";
67 strcpy(errMsg,msg);
68 return(E_ASKCURRENT);
69 } else if (ckt->CKTcurrentAnalysis & (DOING_DCOP | DOING_TRCV)) {
70 value->rValue = 0;
71 } else if (ckt->CKTcurrentAnalysis & DOING_TRAN) {
72 if (ckt->CKTmode & MODETRANOP) {
73 value->rValue = 0;
74 } else {
75 value->rValue = *(ckt->CKTstate0 + here->CAPccap);
76 }
77 } else value->rValue = *(ckt->CKTstate0 + here->CAPccap);
78
79 value->rValue *= here->CAPm;
80
81 return(OK);
82 case CAP_POWER:
83 if (ckt->CKTcurrentAnalysis & DOING_AC) {
84 errMsg = TMALLOC(char, strlen(msg) + 1);
85 errRtn = "CAPask";
86 strcpy(errMsg,msg);
87 return(E_ASKPOWER);
88 } else if (ckt->CKTcurrentAnalysis & (DOING_DCOP | DOING_TRCV)) {
89 value->rValue = 0;
90 } else if (ckt->CKTcurrentAnalysis & DOING_TRAN) {
91 if (ckt->CKTmode & MODETRANOP) {
92 value->rValue = 0;
93 } else {
94 value->rValue = *(ckt->CKTstate0 + here->CAPccap) *
95 (*(ckt->CKTrhsOld + here->CAPposNode) -
96 *(ckt->CKTrhsOld + here->CAPnegNode));
97 }
98 } else value->rValue = *(ckt->CKTstate0 + here->CAPccap) *
99 (*(ckt->CKTrhsOld + here->CAPposNode) -
100 *(ckt->CKTrhsOld + here->CAPnegNode));
101
102 value->rValue *= here->CAPm;
103
104 return(OK);
105 case CAP_QUEST_SENS_DC:
106 if(ckt->CKTsenInfo){
107 value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+
108 here->CAPsenParmNo);
109 }
110 return(OK);
111 case CAP_QUEST_SENS_REAL:
112 if(ckt->CKTsenInfo){
113 value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+
114 here->CAPsenParmNo);
115 }
116 return(OK);
117 case CAP_QUEST_SENS_IMAG:
118 if(ckt->CKTsenInfo){
119 value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+
120 here->CAPsenParmNo);
121 }
122 return(OK);
123 case CAP_QUEST_SENS_MAG:
124 if(ckt->CKTsenInfo){
125 vr = *(ckt->CKTrhsOld + select->iValue + 1);
126 vi = *(ckt->CKTirhsOld + select->iValue + 1);
127 vm = sqrt(vr*vr + vi*vi);
128 if(vm == 0){
129 value->rValue = 0;
130 return(OK);
131 }
132 sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+
133 here->CAPsenParmNo);
134 si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+
135 here->CAPsenParmNo);
136 value->rValue = (vr * sr + vi * si)/vm;
137 }
138 return(OK);
139 case CAP_QUEST_SENS_PH:
140 if(ckt->CKTsenInfo){
141 vr = *(ckt->CKTrhsOld + select->iValue + 1);
142 vi = *(ckt->CKTirhsOld + select->iValue + 1);
143 vm = vr*vr + vi*vi;
144 if(vm == 0){
145 value->rValue = 0;
146 return(OK);
147 }
148 sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+
149 here->CAPsenParmNo);
150 si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+
151 here->CAPsenParmNo);
152
153 value->rValue = (vr * si - vi * sr)/vm;
154 }
155 return(OK);
156
157 case CAP_QUEST_SENS_CPLX:
158 if(ckt->CKTsenInfo){
159 value->cValue.real=
160 *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+
161 here->CAPsenParmNo);
162 value->cValue.imag=
163 *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+
164 here->CAPsenParmNo);
165 }
166 return(OK);
167
168 default:
169 return(E_BADPARM);
170 }
171 }
172
173