Circuit Analysis (Resistive Networks)

Download: jar file

Contents

netlist4
sysbuild
PassiveAnalog
Node
Device
Circuit

netlist4.java


01: // netlist4.java
02: 
03: import java.io.*;
04: 
05: public class netlist4 {
06: 
07:     static public void main(String args[])
08:     {
09:         String filename;
10:         FileInputStream instream;
11:         BufferedReader in;
12:         
13:         if (args.length < 1) {
14:             System.err.println("usage: java netlist4 source");
15:             System.exit(0);
16:         }
17:         try {
18:             filename = args[0];
19:             instream = new FileInputStream(filename);
20:             in = new BufferedReader(new InputStreamReader(instream));
21:             Circuit ckt = new Circuit();
22:             ckt.read(in);
23:             in.close();
24:             System.out.println("\nDevice list:\n");
25:             ckt.list_devices();
26:             ckt.build_node_list();
27:             System.out.println("\nNode list:\n");
28:             ckt.list_nodes();
29:             sysbuild sys = new sysbuild(ckt);
30:         } catch (IOException e) {  
31:                  System.out.println( e);
32:         }
33:     }
34: }
35: 
36:                 


sysbuild.java


001: /* defined in ludcmp.cpp
002: int ludcmp(Matrix &a, int order[]);
003: void solvlu(const Matrix &a, const Vec &b, Vec &x, const int order[]);
004: 
005: void nmAcc(Matrix &G,int i, int j, double val);
006: void srcAcc(Vec &J, int i, int j, double val);
007: void mnaVSrc(Matrix &G,int n, int i, int j);
008: void gmAcc(Matrix &G, int j, int jp, int k, int kp, double value);
009: */
010: 
011: public class sysbuild
012: {
013:     Circuit ckt;
014:     sysbuild(Circuit ckt) {
015:         this.ckt = ckt;
016:         int k;
017:         int nbr_nodes = ckt.nodes.size();
018:         /*
019:         const int devR = *(int *)(Resistor::code());
020:         const int devI = *(int *)(CurrentSource::code());
021:         const int devV = *(int *)(VoltageSource::code());
022:         const int devC = *(int *)(Capacitor::code());
023:         const int devL = *(int *)(Inductor::code());
024:         const int devVCCS = *(int *)(VCCS::code());
025:         */
026:         int nC = 0;
027:         int nL = 0;
028:         int nV = 0;
029:         for (Device dev: ckt.devices) {
030:             String code = dev.getCode();
031:             if (code.equals(PassiveAnalog.devV)) nV++;
032:             else if (code.equals(PassiveAnalog.devC)) nC++;
033:             else if (code.equals(PassiveAnalog.devL)) nL++;
034:         }    
035:         int nrows = nbr_nodes + nV + nL;
036:         Matrix J = new Matrix(nrows,1,0.0);
037:         Matrix G = new Matrix(nrows,nrows,0.0);
038:         Matrix B = new Matrix(nrows,nrows,0.0);
039:         for (Device dev: ckt.devices) {
040:             String code = dev.getCode();
041:             double v = dev.value;
042:             if (code.equals(PassiveAnalog.devR)) nmAcc(G,dev.ndx[0],dev.ndx[1],1/v);
043:             else if (code.equals(PassiveAnalog.devI)) srcAcc(J,dev.ndx[1],dev.ndx[0],v);
044:             else if (code.equals(PassiveAnalog.devC)) nmAcc(B,dev.ndx[0],dev.ndx[1],v);
045:             //else if (code==devVCCS) gmAcc(G,dev.ndx[2],dev.ndx[3],dev.ndx[0],dev.ndx[1],v);
046:         }
047:         // do voltage sources and inductors.
048:         int m = nbr_nodes;
049:         for (Device dev: ckt.devices) {
050:             String code = dev.getCode();
051:             if (code.equals(PassiveAnalog.devV)) {
052:                 mnaVSrc(G,m,dev.ndx[0],dev.ndx[1]);
053:                 J.set(m,0,dev.value);
054:                 m++;
055:             }
056:             else if (code.equals(PassiveAnalog.devL)) {
057:                 mnaVSrc(G,m,dev.ndx[0],dev.ndx[1]);
058:                 B.set(m,m,-dev.value);
059:                 m++;
060:             }
061:         }
062:         System.out.println("\nG matrix:\n");
063:         G.print("%10.3g");
064:         if ((nC+nL)>0) {
065:                 System.out.println("\nB matrix:\n");
066:                 B.print("%10.3g");
067:         }
068:         //if (J.norm()==0) return;
069:         System.out.println("\nJ vector:\n");
070:         J.print("%10.3g");
071:         /*
072:         Matrix a = G;
073:         Vec V(nrows);
074:         int *ipvt = new int[nrows];
075:         ludcmp(a,ipvt);
076:         solvlu(a,J,V,ipvt);
077:         printf("\nV vector:\n");
078:         V.print();
079:         */
080:         LUDecomposition LU = new LUDecomposition(G);
081:         System.out.println("\nV vector:\n");
082:         Matrix V = LU.solve(J);
083:         V.print("%6.0f");
084:     }
085:         
086:         
087: 
088: 
089: //! Accumulate g = (1/R) or R values onto G Matrix
090: //  i and j are node (mesh) indices.
091: 
092: void nmAcc(Matrix Gm,int i, int j, double val)
093: {
094:     double [][] G = Gm.getArray();
095:         if ((i<0) && (j<0)) return; // trivial case, both indices equal reference node
096:         if (i>=0) G[i][i] += val;
097:         if (j>=0) G[j][j] += val;
098:         if ( (i>=0) && (j>=0) ) {
099:                 G[i][j] -= val;
100:                 G[j][i] -= val;
101:         }
102: }
103: 
104: //!   Accumulates Is or Vs values onto source Matrix J.
105: /*    Index i is "from" node (drop mesh).
106: *     Index j is "to" node (rise mesh).
107: */
108: void srcAcc(Matrix Jv, int i, int j, double val)
109: {
110:         double [][] J = Jv.getArray();
111:         if (j>=0) J[j][0] += val;
112:         if (i>=0) J[i][0] -= val;
113: }
114: 
115: 
116: //function amat = mnaVSrc(m,i,j,bmat)
117: /*
118:  * Accumulation of Vsrc onto bmat for MNA analysis.
119: *   m is the index into the additional CE row.
120:  *   i and j are the + and - nodes of the voltage source.
121:  */
122: void mnaVSrc(Matrix Gm, int m, int i, int j)
123: {
124:     double [][] G = Gm.getArray();
125:         if (i>=0) {
126:                 G[m][i] = 1.0;
127:                 G[i][m] = 1.0;
128:         }
129:         if (j>=0) {
130:                 G[m][j] = -1.0;
131:                 G[j][m] = -1.0;
132:         }
133: }
134: 
135: /* Voltage-Controlled Current Source (G source)
136:  *  j and jp are + and i control nodes
137:  *  k and kp are from and to nodes
138:  */
139: 
140: void gmAcc(Matrix Gm, int j, int jp, int k, int kp, double value)
141: {
142:     double [][] G = Gm.getArray();
143:         if ((k>=0) && (j>=0)) G[k][j] += value;
144:         if ((kp>=0) && (jp>=0)) G[kp][jp] += value;
145:         if ((k>=0) && (jp>=0)) G[k][jp] -= value;
146:         if ((kp>=0) && (j>=0)) G[kp][j] -= value;
147: }
148: /* Voltage-Controlled Voltage Source (E)
149:  *   m is the index of the added constitutive equation row
150:  *   j and jp are the + and - controlling nodes.
151:  *   k and kp are the + and - nodes of the E source
152: */
153: void mnaESrc(Matrix Gm,int m, int j, int jp, int k, int kp,double value)
154: {
155:     double [][] G = Gm.getArray();
156:         if (k>=0) {
157:                 G[k][m] = 1.0;
158:                 G[m][k] = 1.0;
159:         }
160:         if (kp>=0) {
161:                 G[kp][m] = -1.0;
162:                 G[m][kp] = -1.0;
163:         }
164:         if (j>=0) G[m][j] -= value;
165:         if (jp>=0) G[m][jp] += value;
166: }
167: 
168: /* Current-Controlled Current Source (F) 
169:  *  m is the index of the added consitutive equation row
170:  *  j and jp are the from and to controlling nodes
171:  *  k and kp are the from and to nodes of the F source
172:  */
173: void mnaFSrc(Matrix Gm,int m, int j, int jp, int k, int kp,double value)
174: {
175:     double [][] G = Gm.getArray();
176:         if (j>=0) {
177:                 G[j][m] = 1.0;
178:                 G[m][j] = 1.0;
179:         }
180:         if (jp>=0) {
181:                 G[jp][m] = -1.0;
182:                 G[m][jp] = -1.0;
183:         }
184:         if (k>=0) G[k][m] += value;
185:         if (kp>=0) G[kp][m] -= value;
186: }
187: 
188: /* Current-Controlled Voltage Source (H)
189:  * m and m+1 are rows for constutive equations
190:  * j and jp are + and - controlling nodes
191:  * k and kp are + and - nodes for H source
192:  */
193: void mnaHSrc(Matrix Gm, int m, int j, int jp, int k, int kp, double value)
194: {
195:     double [][] G = Gm.getArray();
196:         if (j>=0) {
197:                 G[j][m] = 1.0;
198:                 G[m][j] = 1.0;
199:         }
200:         if (jp>=0) {
201:                 G[jp][m] = -1.0;
202:                 G[m][jp] = -1.0;
203:         }
204:         int mp1 = m+1;
205:         if (k>=0) {
206:                 G[k][mp1] = 1.0;
207:                 G[mp1][k] = 1.0;
208:         }
209:         if (kp>=0) {
210:                 G[kp][mp1] = -1.0;
211:                 G[mp1][kp] = -1.0;
212:         }
213:         G[mp1][m] = -value;
214: }
215: 
216: /* ideal op-amp
217:  *  m is the index of the added row.
218:  *  j and jp are the noninverting and inverting op-amp input nodes.
219:  *  k is the output node;
220:  */
221: void mnaOA(Matrix Gm, int m, int j, int jp, int k)
222: {
223:     double [][] G = Gm.getArray();
224:         if (j>=0) G[m][j] = 1.0;
225:         if (jp>=0) G[m][jp] = -1.0;
226:         if (k>=0) G[k][m] = 1.0;
227: }
228:     }
229:                 
230: 


PassiveAnalog.java


01: public class PassiveAnalog {
02:     static final String devR = Resistor.code;
03:     static final String devI = CurrentSource.code;
04:     static final String devV = VoltageSource.code;
05:     static final String devC = Capacitor.code;
06:     static final String devL = Inductor.code;
07: 
08:     
09:     static Device getNewDevice(String type)
10:     {
11:         if (type.equals(Resistor.code)) return new Resistor();
12:         if (type.equals(VoltageSource.code)) return new VoltageSource();
13:         if (type.equals(CurrentSource.code)) return new CurrentSource();
14:         if (type.equals(Capacitor.code)) return new Capacitor();
15:         if (type.equals(Inductor.code)) return new Inductor();
16:         return null;
17:     }
18: 
19:         /*
20:         const int devC = *(int *)(Capacitor::code());
21:         const int devL = *(int *)(Inductor::code());
22:         const int devVCCS = *(int *)(VCCS::code());
23:         */    
24: }
25: 
26: class Resistor extends Device {
27:     final static String code = "R";
28:     Resistor() {
29:         super(2);
30:         //code = "R";
31:         //type = "resistor";
32:     }
33:     String getType() { return "resistor"; }
34:     String getCode() { return Resistor.code; }
35: }
36: 
37: class VoltageSource extends Device
38: {
39:     final static String code = "V";
40:     VoltageSource() {
41:         super(2);
42:     }
43:     String getType() { return "voltage source"; }
44:     String getCode() { return VoltageSource.code; }
45: }
46: 
47: class CurrentSource extends Device
48: {
49:     final static String code = "I";
50:     CurrentSource() { super(2); }
51:     String getType() { return "current source"; }
52:     String getCode() { return CurrentSource.code; }
53: }
54: 
55: class Capacitor extends Device
56: {
57:     final static String code = "C";
58:     Capacitor() { super(2); }
59:     String getType() { return "capacitor"; }
60:     String getCode() { return Capacitor.code; }
61: }
62: 
63: class Inductor extends Device
64: {
65:     final static String code = "L";
66:     Inductor() { super(2); }
67:     String getType() { return "inductor"; }
68:     String getCode() { return Inductor.code; }
69: }


Node.java


01: import java.util.ArrayList;
02: 
03: public class Node
04: {
05:     String name;
06:     int index;
07:     ArrayList<Device> devices;
08:     Node(String str) {
09:         name = str;
10:         index = 0;
11:         devices = new ArrayList<Device>();
12:     }
13: 
14:     public String toString()
15:     {
16:         String str = name;
17:         for (Device d: devices) str += "\t" + d.name;
18:         return str;
19:     }
20: }
21: 
22:     
23:     


Device.java


01: import java.util.ArrayList;
02: 
03: public abstract class Device {
04:     String name;
05:     String [] nodes;
06:     int [] ndx;
07:     double value;
08: 
09:     Device(int n)
10:     {
11:         nodes = new String[n];
12:         ndx = new int[n];
13:         value = 0.0;
14:     }
15: 
16:     String getType() { return "device"; }
17:     String getCode() { return "device_code"; }
18: 
19:     public void parse(String tok[])
20:     {
21:         name = tok[1];
22:         int j, n, ntokens;
23:         ntokens = tok.length;
24:         n = nodes.length;
25:         if (ntokens < n+2) {
26:             System.out.printf("%d tokens %d needed\n",ntokens,n+2);
27:             System.err.println("Input error - device has insufficient nodes");
28:         }
29:         for (j=0; j<n; j++) nodes[j] = tok[2+j];
30:         n += 2;
31:         if (ntokens<=n) return;
32:         // logic may not have a value, but it might have an orientation
33:         value = parseValue(tok[n]);     
34:     }
35:     
36:     public String toString()
37:     {
38:         String str = getType() + " " + getCode() + " " + name;
39:         for (String s: nodes) str += " " + s;
40:         str += " " + value;
41:         return str;
42:     }
43:         
44:     static public double parseValue(String str)
45:     {
46:         final String suffix = "afpnumkKMGT";
47:         final double scales[] = {1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3, 1e3, 1e3, 1e6, 1e9, 1e12};
48:         char [] chars = str.toCharArray();
49:         int n = chars.length;
50:         while (n>0) {
51:             if (!Character.isLetter(chars[n-1])) break;
52:             n--;
53:         }
54:         double v;
55:         try {
56:             if (n<chars.length) {
57:                 v = Double.parseDouble(str.substring(0,n));
58:                 //System.out.printf("value %g suffix %s\n",v,str.substring(n));
59:                 n = suffix.indexOf(chars[n]);
60:                 if (n<0) return v;
61:                 else v *= scales[n];
62:             }
63:             else v = Double.parseDouble(str);
64:         }
65:         catch (NumberFormatException e) {
66:             System.out.println(e);
67:             v = 0.0;
68:         }
69:         return v;
70:     }
71: }


CIrcuit.java


01: import java.io.*;
02: import java.util.ArrayList;
03: 
04: public class Circuit
05: {
06:     String name;
07:     Node ref;
08:     ArrayList<Node> nodes;
09:     ArrayList<Device> devices;
10: 
11:     Circuit()
12:     {
13:         ref = new Node("0");
14:         devices = new ArrayList<Device>();
15:         nodes = new ArrayList<Node>();
16:     }
17: 
18:     public void read(BufferedReader inr) {
19:         LineNumberReader in = new LineNumberReader(inr);
20:         boolean done = false;
21:         while (!done) {
22:             int n = in.getLineNumber();
23:             try {
24:                 String inp = in.readLine();
25:                 if (inp==null) break;
26:                 System.out.println("Line " + n + ":  " + inp);
27:                 String [] str = inp.split("%"); // terminate at comment character
28:                 String [] tokens = str[0].split("\\s+");
29:                 if (tokens.length>1) {
30:                     Device d = null;
31:                     d = PassiveAnalog.getNewDevice(tokens[0]);
32:                     if (d!=null) {
33:                         d.parse(tokens);
34:                         devices.add(d);
35:                     }
36:                     else System.out.println("Unrecognized device: " + tokens[0]);
37:                 }
38:             }
39:             catch (IOException e) {
40:                 System.out.println(e);
41:             }
42:         }
43:         System.out.println();
44:     }
45: 
46:     int add_node(String str)
47:     {
48:         int i;
49:         Node node;
50:         if (ref.name.equals(str)) return -1; // ground (reference) node
51:         int ncount = nodes.size();
52:         for (i=0; i<ncount; i++) {
53:             node = nodes.get(i);
54:             if (node.name.equals(str)) return i;
55:         }
56:         nodes.add(new Node(str));
57:         return ncount;
58:     }
59: 
60:     void build_node_list()
61:     {
62:         int i, j;
63:         Device dev;
64:         int ndevices = devices.size();
65:         for (i=0; i<ndevices; i++) {
66:             dev = devices.get(i);
67:             int nodecount = dev.nodes.length;
68:             for (j=0; j<nodecount; j++) dev.ndx[j] = add_node(dev.nodes[j]);
69:         }
70:     }
71: 
72:     void list_nodes()
73:     {
74:         System.out.println(ref);
75:         for (Node node: nodes) System.out.println(node);
76:         /*
77:         int i;
78:         int ncount = nodes.size();
79:         for (i=0; i<ncount; i++) {
80:             Node node =  nodes.get(i);
81:             System.out.printf("%d\t %s\n",i,node);
82:         }
83:         */
84:     }
85:         
86: 
87:     void list_devices()
88:     {
89:         for (Device d: devices) System.out.println(d);
90:     }
91: }


Results

Line 0:  % Resistance in series
Line 1:  % alphanumeric node names
Line 2:  R R1 N_3  0  2  [0 0]
Line 3:  R R2 N_4 N_3 4  [1 0 1]
Line 4:  I I1 N_4 0 1   [-1 0]


Device list:

resistor R R1 N_3 0 2.0
resistor R R2 N_4 N_3 4.0
current source I I1 N_4 0 1.0

Node list:

0
N_3
N_4

G matrix:


     0.750    -0.250
    -0.250     0.250


J vector:


      0.00
      1.00


V vector:


     2
     6


Maintained by John Loomis, updated Mon Mar 31 16:16:38 2008