Download: jar file
netlist4sysbuildPassiveAnalogNodeDeviceCircuitnetlist4.java01: // 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.java001: /* 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.java01: 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.java01: 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.java01: 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.java01: 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: }
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