sysbuild.cpp
Download: netlist4.zip
#include "circuit.h" #include "matrix.h" // defined in ludcmp.cpp int ludcmp(Matrix &a, int order[]); void solvlu(const Matrix &a, const Vec &b, Vec &x, const int order[]); void nmAcc(Matrix &G,int i, int j, double val); void srcAcc(Vec &J, int i, int j, double val); void mnaVSrc(Matrix &G,int n, int i, int j); void gmAcc(Matrix &G, int j, int jp, int k, int kp, double value); void eCircuit::sysbuild() { int k; int nbr_nodes = ncount; const int devR = *(int *)(Resistor::code()); const int devI = *(int *)(CurrentSource::code()); const int devV = *(int *)(VoltageSource::code()); const int devC = *(int *)(Capacitor::code()); const int devL = *(int *)(Inductor::code()); const int devVCCS = *(int *)(VCCS::code()); int nC = 0; int nL = 0; int nV = 0; for (k=0; k<ndevices; k++) { eDevice &dev = *devices[k]; int code = dev.getCode(); if (code==devC) nC++; else if (code==devL) nL++; else if (code==devV) nV++; } int nrows = nbr_nodes + nV + nL; Vec J(nrows); Matrix G(nrows,nrows); Matrix B(nrows,nrows); J.set(0.0); G.set(0.0); B.set(0.0); for (k=0; k<ndevices; k++) { eDevice &dev = *devices[k]; double v = dev.value; int code = dev.getCode(); if (code==devR) nmAcc(G,dev.ndx[0],dev.ndx[1],1/v); else if (code==devI) srcAcc(J,dev.ndx[1],dev.ndx[0],v); else if (code==devC) nmAcc(B,dev.ndx[0],dev.ndx[1],v); else if (code==devVCCS) gmAcc(G,dev.ndx[2],dev.ndx[3],dev.ndx[0],dev.ndx[1],v); } // do voltage sources and inductors. int m = nbr_nodes; for (k=0; k<ndevices; k++) { eDevice &dev = *devices[k]; int code = dev.getCode(); if (code==devV) { mnaVSrc(G,m,dev.ndx[0],dev.ndx[1]); J[m] = dev.value; m++; } else if (code==devL) { mnaVSrc(G,m,dev.ndx[0],dev.ndx[1]); B[m][m] = -dev.value; m++; } } printf("\nG matrix:\n"); G.print(); if ((nC+nL)>0) { printf("\nB matrix:\n"); B.print(); } if (J.norm()==0) return; printf("\nJ vector:\n"); J.print(); Matrix a = G; Vec V(nrows); int *ipvt = new int[nrows]; ludcmp(a,ipvt); solvlu(a,J,V,ipvt); printf("\nV vector:\n"); V.print(); } //! Accumulate g = (1/R) or R values onto G Matrix // i and j are node (mesh) indices. void nmAcc(Matrix &G,int i, int j, double val) { if ((i<0) && (j<0)) return; // trivial case, both indices equal reference node if (i>=0) G[i][i] += val; if (j>=0) G[j][j] += val; if ( (i>=0) && (j>=0) ) { G[i][j] -= val; G[j][i] -= val; } } //! Accumulates Is or Vs values onto source Matrix J. /* Index i is "from" node (drop mesh). * Index j is "to" node (rise mesh). */ void srcAcc(Vec &J, int i, int j, double val) { if (j>=0) J[j] += val; if (i>=0) J[i] -= val; } //function amat = mnaVSrc(m,i,j,bmat) /* * Accumulation of Vsrc onto bmat for MNA analysis. * m is the index into the additional CE row. * i and j are the + and - nodes of the voltage source. */ void mnaVSrc(Matrix &G,int m, int i, int j) { if (i>=0) { G[m][i] = 1.0; G[i][m] = 1.0; } if (j>=0) { G[m][j] = -1.0; G[j][m] = -1.0; } } /* Voltage-Controlled Current Source (G source) * j and jp are + and i control nodes * k and kp are from and to nodes */ void gmAcc(Matrix &G, int j, int jp, int k, int kp, double value) { if ((k>=0) && (j>=0)) G[k][j] += value; if ((kp>=0) && (jp>=0)) G[kp][jp] += value; if ((k>=0) && (jp>=0)) G[k][jp] -= value; if ((kp>=0) && (j>=0)) G[kp][j] -= value; } /* Voltage-Controlled Voltage Source (E) * m is the index of the added constitutive equation row * j and jp are the + and - controlling nodes. * k and kp are the + and - nodes of the E source */ void mnaESrc(Matrix &G,int m, int j, int jp, int k, int kp,double value) { if (k>=0) { G[k][m] = 1.0; G[m][k] = 1.0; } if (kp>=0) { G[kp][m] = -1.0; G[m][kp] = -1.0; } if (j>=0) G[m][j] -= value; if (jp>=0) G[m][jp] += value; } /* Current-Controlled Current Source (F) * m is the index of the added consitutive equation row * j and jp are the from and to controlling nodes * k and kp are the from and to nodes of the F source */ void mnaFSrc(Matrix &G,int m, int j, int jp, int k, int kp,double value) { if (j>=0) { G[j][m] = 1.0; G[m][j] = 1.0; } if (jp>=0) { G[jp][m] = -1.0; G[m][jp] = -1.0; } if (k>=0) G[k][m] += value; if (kp>=0) G[kp][m] -= value; } /* Current-Controlled Voltage Source (H) * m and m+1 are rows for constutive equations * j and jp are + and - controlling nodes * k and kp are + and - nodes for H source */ void mnaHSrc(Matrix &G, int m, int j, int jp, int k, int kp, double value) { if (j>=0) { G[j][m] = 1.0; G[m][j] = 1.0; } if (jp>=0) { G[jp][m] = -1.0; G[m][jp] = -1.0; } int mp1 = m+1; if (k>=0) { G[k][mp1] = 1.0; G[mp1][k] = 1.0; } if (kp>=0) { G[kp][mp1] = -1.0; G[mp1][kp] = -1.0; } G[mp1][m] = -value; } /* ideal op-amp * m is the index of the added row. * j and jp are the noninverting and inverting op-amp input nodes. * k is the output node; */ void mnaOA(Matrix &G, int m, int j, int jp, int k) { if (j>=0) G[m][j] = 1.0; if (jp>=0) G[m][jp] = -1.0; if (k>=0) G[k][m] = 1.0; }
Maintained by John Loomis, updated Wed Feb 21 17:43:22 2007