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)63double 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)194double 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