1 /* ===========================================================================
2 FILE    CMmeters.c
3 
4 MEMBER OF process XSPICE
5 
6 Public Domain
7 
8 Georgia Tech Research Corporation
9 Atlanta, Georgia 30332
10 PROJECT A-8503
11 
12 AUTHORS
13 
14     9/12/91  Bill Kuhn
15 
16 MODIFICATIONS
17 
18     <date> <person name> <nature of modifications>
19 
20 SUMMARY
21 
22     This file contains functions callable from code models.
23     These functions are primarily designed for use by the
24     "cmeter" and "lmeter" models provided in the XSPICE
25     code model library.
26 
27 INTERFACES
28 
29     cm_netlist_get_c()
30     cm_netlist_get_l()
31 
32 REFERENCED FILES
33 
34     None.
35 
36 NON-STANDARD FEATURES
37 
38     None.
39 
40 =========================================================================== */
41 #include "ngspice/ngspice.h"
42 #include "ngspice/cm.h"
43 #include "ngspice/mif.h"
44 
45 #include "ngspice/cktdefs.h"
46 
47 #include "ngspice/mifdefs.h"
48 #include "cap/capdefs.h"
49 #include "ind/inddefs.h"
50 #include "vsrc/vsrcdefs.h"
51 #include "ngspice/inpdefs.h"
52 
53 
54 
55 /*
56 cm_netlist_get_c()
57 
58 This is a special function designed for use with the c_meter
59 model.  It returns the parallel combination of the capacitance
60 connected to the first port on the instance.
61 */
62 
cm_netlist_get_c(void)63 double cm_netlist_get_c(void)
64 {
65     CKTcircuit          *ckt;
66 
67     MIFinstance         *cmeter_inst;
68     CAPinstance         *cap_inst;
69     VSRCinstance        *vsrc_inst;
70 
71     CAPmodel            *cap_head;
72     CAPmodel            *cap_model;
73     VSRCmodel           *vsrc_head;
74     VSRCmodel           *vsrc_model;
75 
76     int                 cap_type;
77     int                 vsrc_type;
78 
79     int                 cmeter_node;
80     int                 vsrc_node;
81 
82     double              c;
83 
84 
85     /* Get the circuit data structure and current instance */
86     ckt = g_mif_info.ckt;
87     cmeter_inst = g_mif_info.instance;
88 
89     /* Get internal node number for positive node of cmeter input */
90     cmeter_node = cmeter_inst->conn[0]->port[0]->smp_data.pos_node;
91 
92     /* Initialize total capacitance value to zero */
93     c = 0.0;
94 
95 
96     /* ****************************************************** */
97     /* Look for capacitors connected directly to cmeter input */
98     /* ****************************************************** */
99 
100     /* Get the head of the list of capacitor models in the circuit */
101     cap_type = INPtypelook("Capacitor");
102     if(cap_type < 0) {
103         printf("\nERROR - Capacitor type not supported in this binary\n");
104         return(0);
105     }
106     cap_head = (CAPmodel *) ckt->CKThead[cap_type];
107 
108     /* Scan through all capacitor instances and add in values */
109     /* of any capacitors connected to cmeter input */
110 
111     for(cap_model = cap_head; cap_model; cap_model = CAPnextModel(cap_model)) {
112         for(cap_inst = CAPinstances(cap_model);
113                 cap_inst;
114                 cap_inst = CAPnextInstance(cap_inst)) {
115             if((cmeter_node == cap_inst->CAPposNode) ||
116                     (cmeter_node == cap_inst->CAPnegNode)) {
117                 c += cap_inst->CAPcapac;
118             }
119         }
120     }
121 
122 
123     /* ***************************************************************** */
124     /* Look for capacitors connected through zero-valued voltage sources */
125     /* ***************************************************************** */
126 
127     /* Get the head of the list of voltage source models in the circuit */
128     vsrc_type = INPtypelook("Vsource");
129     if(vsrc_type < 0) {
130         printf("\nERROR - Vsource type not supported in this binary\n");
131         return(0);
132     }
133     vsrc_head = (VSRCmodel *) ckt->CKThead[vsrc_type];
134 
135     /* Scan through all voltage source instances and add in values */
136     /* of any capacitors connected to cmeter input through voltage source */
137 
138     for(vsrc_model = vsrc_head; vsrc_model; vsrc_model = VSRCnextModel(vsrc_model)) {
139         for(vsrc_inst = VSRCinstances(vsrc_model);
140                 vsrc_inst;
141                 vsrc_inst = VSRCnextInstance(vsrc_inst)) {
142 
143             /* Skip to next if not DC source with value = 0.0 */
144             if((vsrc_inst->VSRCfunctionType != 0) ||
145                     (vsrc_inst->VSRCdcValue != 0.0))
146                 continue;
147 
148             /* See if voltage source is connected to cmeter input */
149             /* If so, get other node voltage source is connected to */
150             /* If not, skip to next source */
151             if(cmeter_node == vsrc_inst->VSRCposNode)
152                 vsrc_node = vsrc_inst->VSRCnegNode;
153             else if(cmeter_node == vsrc_inst->VSRCnegNode)
154                 vsrc_node = vsrc_inst->VSRCposNode;
155             else
156                 continue;
157 
158 
159             /* Scan through all capacitor instances and add in values */
160             /* of any capacitors connected to the voltage source node */
161 
162             for(cap_model = cap_head; cap_model; cap_model = CAPnextModel(cap_model)) {
163                 for(cap_inst = CAPinstances(cap_model);
164                         cap_inst;
165                         cap_inst = CAPnextInstance(cap_inst)) {
166                     if((vsrc_node == cap_inst->CAPposNode) ||
167                             (vsrc_node == cap_inst->CAPnegNode)) {
168                         c += cap_inst->CAPcapac;
169                     }
170                 }
171             }
172 
173 
174         } /* end for all vsrc instances */
175     } /* end for all vsrc models */
176 
177 
178     /* Return the total capacitance value */
179     return(c);
180 }
181 
182 
183 
184 
185 /*
186 cm_netlist_get_l()
187 
188 This is a special function designed for use with the l_meter
189 model.  It returns the equivalent value of inductance
190 connected to the first port on the instance.
191 */
192 
193 
cm_netlist_get_l(void)194 double cm_netlist_get_l(void)
195 {
196     CKTcircuit          *ckt;
197 
198     MIFinstance         *lmeter_inst;
199     INDinstance         *ind_inst;
200     VSRCinstance        *vsrc_inst;
201 
202     INDmodel            *ind_head;
203     INDmodel            *ind_model;
204     VSRCmodel           *vsrc_head;
205     VSRCmodel           *vsrc_model;
206 
207     int                 ind_type;
208     int                 vsrc_type;
209 
210     int                 lmeter_node;
211     int                 vsrc_node;
212 
213     double              l;
214 
215 
216     /* Get the circuit data structure and current instance */
217     ckt = g_mif_info.ckt;
218     lmeter_inst = g_mif_info.instance;
219 
220     /* Get internal node number for positive node of lmeter input */
221     lmeter_node = lmeter_inst->conn[0]->port[0]->smp_data.pos_node;
222 
223     /* Initialize total inductance to infinity */
224     l = 1.0e12;
225 
226 
227     /* ****************************************************** */
228     /* Look for inductors connected directly to lmeter input */
229     /* ****************************************************** */
230 
231     /* Get the head of the list of inductor models in the circuit */
232     ind_type = INPtypelook("Inductor");
233     if(ind_type < 0) {
234         printf("\nERROR - Inductor type not supported in this binary\n");
235         return(0);
236     }
237     ind_head = (INDmodel *) ckt->CKThead[ind_type];
238 
239     /* Scan through all inductor instances and add in values */
240     /* of any inductors connected to lmeter input */
241 
242     for(ind_model = ind_head; ind_model; ind_model = INDnextModel(ind_model)) {
243         for(ind_inst = INDinstances(ind_model);
244                 ind_inst;
245                 ind_inst = INDnextInstance(ind_inst)) {
246             if((lmeter_node == ind_inst->INDposNode) ||
247                     (lmeter_node == ind_inst->INDnegNode)) {
248                 l = 1.0 / ( (1.0 / l) + (1.0 / ind_inst->INDinduct) );
249             }
250         }
251     }
252 
253 
254     /* ***************************************************************** */
255     /* Look for inductors connected through zero-valued voltage sources */
256     /* ***************************************************************** */
257 
258     /* Get the head of the list of voltage source models in the circuit */
259     vsrc_type = INPtypelook("Vsource");
260     if(vsrc_type < 0) {
261         printf("\nERROR - Vsource type not supported in this binary\n");
262         return(0);
263     }
264     vsrc_head = (VSRCmodel *) ckt->CKThead[vsrc_type];
265 
266     /* Scan through all voltage source instances and add in values */
267     /* of any inductors connected to lmeter input through voltage source */
268 
269     for(vsrc_model = vsrc_head; vsrc_model; vsrc_model = VSRCnextModel(vsrc_model)) {
270         for(vsrc_inst = VSRCinstances(vsrc_model);
271                 vsrc_inst;
272                 vsrc_inst = VSRCnextInstance(vsrc_inst)) {
273 
274             /* Skip to next if not DC source with value = 0.0 */
275             if((vsrc_inst->VSRCfunctionType != 0) ||
276                     (vsrc_inst->VSRCdcValue != 0.0))
277                 continue;
278 
279             /* See if voltage source is connected to lmeter input */
280             /* If so, get other node voltage source is connected to */
281             /* If not, skip to next source */
282             if(lmeter_node == vsrc_inst->VSRCposNode)
283                 vsrc_node = vsrc_inst->VSRCnegNode;
284             else if(lmeter_node == vsrc_inst->VSRCnegNode)
285                 vsrc_node = vsrc_inst->VSRCposNode;
286             else
287                 continue;
288 
289 
290             /* Scan through all inductor instances and add in values */
291             /* of any inductors connected to the voltage source node */
292 
293             for(ind_model = ind_head; ind_model; ind_model = INDnextModel(ind_model)) {
294                 for(ind_inst = INDinstances(ind_model);
295                         ind_inst;
296                         ind_inst = INDnextInstance(ind_inst)) {
297                     if((vsrc_node == ind_inst->INDposNode) ||
298                             (vsrc_node == ind_inst->INDnegNode)) {
299                         l = 1.0 / ( (1.0 / l) + (1.0 / ind_inst->INDinduct) );
300                     }
301                 }
302             }
303 
304 
305         } /* end for all vsrc instances */
306     } /* end for all vsrc models */
307 
308 
309     /* Return the total capacitance value */
310     return(l);
311 }
312 
313 
314