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