Download: jar file
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: }
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