/// <summary> /// Corriente incremental, dependiente del tiempo en algunos componentes /// </summary> /// <param name="referenceNode"></param> /// <param name="CurrentTime"></param> /// <returns></returns> public virtual double Current(Node referenceNode, double CurrentTime) { if (referenceNode == Nodes[0]) return _current.Real; else return -_current.Real; }
public virtual double NortonCurrent(Node referenceNode, double t) { if (CurrentImposser != null) { return Current(referenceNode, t); } double v = 0, z = 0; Dipole compo1 = null; Node node1 = null; foreach (var item in Components) { if (item.Nodes[0] == referenceNode || item.Nodes[1] == referenceNode) { compo1 = item; break; } } node1 = referenceNode; do { if (compo1 is Branch) v += ((Branch)compo1).TheveninVoltage(node1, t); else v += compo1.voltage(node1, t); z += compo1.Impedance().Real; node1 = compo1.OtherNode(node1); compo1 = node1.OtherComponent(compo1); } while (InternalNodes.Contains(node1)); return v / z; }
public virtual double TheveninVoltage(Node referenceNode, double t) { double v = 0; Dipole compo1 = null; Node node1 = null; foreach (var item in Components) { if (item.Nodes[0] == referenceNode || item.Nodes[1] == referenceNode) { compo1 = item; break; } } node1 = referenceNode; do { if (compo1 is Branch) v += ((Branch)compo1).TheveninVoltage(node1, t); else v += compo1.voltage(node1, t); node1 = compo1.OtherNode(node1); compo1 = node1.OtherComponent(compo1); } while (InternalNodes.Contains(node1)); return v; }
public override Complex32 voltage(Node ReferenceNode, Complex32 ?W) { if (ReferenceNode == Nodes[0]) return Voltage; if (ReferenceNode == Nodes[1]) return -Voltage; return Complex32.NaN; }
public override double Current(Node referenceNode, double CurrentTime) { Complex32 i = Voltage / Impedance(); if (referenceNode == Nodes[0]) return i.Real; else return -i.Real; }
public virtual Complex32 Current(Node referenceNode, Complex32? W = null) { //el signo contrario al pensado, entra por neagtivo y sale por positivo if (referenceNode == Nodes[0]) return -current; else return current; }
public override Complex32 Current(Node referenceNode, Complex32? W = null) { Complex32 i = Voltage / Impedance(W); if (referenceNode == Nodes[0]) return i; else return -i; }
public override Complex32 voltage(Node referenceNode, Complex32? W = null) { if (W == null || W.Value.IsZero()) { if (referenceNode == Nodes[0]) return new Complex32((float)Value, 0); return new Complex32((float)-Value, 0); } else { if (referenceNode == Nodes[0]) return ACVoltage; return ACVoltage; } }
public override double Current(Node referenceNode, double t) { double deltat = t - OwnerCircuit.CircuitTime; if (deltat < 0) { throw new NotImplementedException(); } //si ya se calculo la corriente devuelvo la calculada if (previoustime > 0 && previoustime == t) { if (referenceNode == Nodes[0]) return _current.Real; else if (referenceNode == Nodes[1]) return -_current.Real; else throw new NotImplementedException(); } previoustime = t; //recalculo la corriente double deltai = voltage(referenceNode, t) * deltat / Value; double i = _current.Real - deltai; if (referenceNode == Nodes[0]) _current = new Complex32((float)-i, 0); else if (referenceNode == Nodes[1]) _current = new Complex32((float)i, 0); else if (Owner is Branch) { Node nodo = ((Branch)Owner).FindComponentNode(referenceNode, this); if (nodo == null) throw new NotImplementedException(); if (nodo == Nodes[0]) _current = new Complex32((float)-i, 0); else if (nodo == Nodes[1]) _current = new Complex32((float)i, 0); } else throw new NotImplementedException(); return _current.Real; }
public override double voltage(Node referenceNode, double t) { double deltat = t - OwnerCircuit.CircuitTime; if (deltat < 0) { throw new Exception(); } //si ya se calculo la corriente devuelvo la calculada if (previoustime > 0 && previoustime == t) { if (referenceNode == Nodes[0]) return _voltage; else if (referenceNode == Nodes[1]) return -_voltage; else throw new NotImplementedException(); } previoustime = t; //recalculo la corriente double i = 0; if (Owner is Branch) { i = ((Branch)Owner).Current(referenceNode, t); } else i = Current(referenceNode, t); double vant = 0; if (referenceNode == Nodes[0]) vant = -_voltage; else if (referenceNode == Nodes[1]) vant = _voltage; double v = vant + i * deltat / Value; _voltage = v; return v; }
/// <summary> /// Read a netlist file (.net) containing componentsdescription y nodes /// A Circuit object with components y nodes will be created /// </summary> /// <param name="CircuitName"></param> public void ReadCircuit(string CircuitName) { if (!File.Exists(CircuitName)) { HasErrors = true; throw new FileNotFoundException(); } try { TextReader reader = File.OpenText(CircuitName); string txt = reader.ReadToEnd(); reader.Close(); string[] lines = txt.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < lines.Length; i++ ) { string item = lines[i]; //un comentario if (item.StartsWith("*")) continue; int j = i + 1; while (j < lines.Length && lines[j].StartsWith("+")) { item += " " + lines[j].Substring(1); j++; i++; } //R_R1 $N_0002 $N_0001 1k string[] elemn = item.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); ElectricComponent comp = null; string[] comp1 = elemn[0].Split("_".ToCharArray()); switch (comp1[0].ToUpper()) { case "R": comp = new Resistor(this, comp1[1], elemn[3]); break; case "V": if (elemn.Length == 4) comp = new VoltageGenerator(this, comp1[1], elemn[3]); else if (elemn.Length == 7 || elemn.Length == 8) { ACVoltageGenerator ac = new ACVoltageGenerator(this, comp1[1], elemn[4]); if (elemn.Length == 8) ac.ACVoltage = Complex32.FromPolarCoordinates((float)StringUtils.DecodeString(elemn[6]), (float)StringUtils.DecodeString(elemn[7])); else ac.ACVoltage = new Complex32((float)StringUtils.DecodeString(elemn[6]), 0); comp = (ACVoltageGenerator)ac; } else if (elemn.Length > 8) { //V_V1 $N_0001 0 DC 0 AC 1 //+SIN 1 1 1k 0 0 0 SineVoltageGenerator vsin = new SineVoltageGenerator(this, comp1[1]); //if (elemn.Length == 8) //vsin.ACVoltage = new Complex32((float)StringUtils.DecodeString(elemn[6]), // (float)StringUtils.DecodeString(elemn[6])); //else vsin.ACVoltage = new Complex32((float)StringUtils.DecodeString(elemn[6]), 0); vsin.Amplitude = elemn[9]; vsin.Offset = elemn[8]; vsin.Frequency = elemn[10]; vsin.Thau = elemn[12]; vsin.Delay = elemn[11]; vsin.Phase = elemn[13]; comp = vsin; } else { throw new NotImplementedException(); } break; case "I": if (elemn[3] == "DC") comp = new CurrentGenerator(this, comp1[1], elemn[4]); else //aun sin resolver para otros generadores comp = new CurrentGenerator(this, comp1[1], elemn[4]); break; case "L": comp = new Inductor(this, comp1[1], elemn[3]); break; case "C": comp = new Capacitor(this, comp1[1], elemn[3]); break; case "E": //E_E1 $N_0002 0 $N_0001 0 10 VoltageControlledGenerator E = new VoltageControlledGenerator(this, comp1[1]); E.Gain = elemn[5]; Node node1 = null; node1 = CreateOrFindNode(elemn[3]); E.InputNodes.Add(node1); node1 = CreateOrFindNode(elemn[4]); E.InputNodes.Add(node1); comp = E; break; default: throw new Exception(); } comp.Nodes.Clear(); //agrego los nodos al circuito y al componente Node n; if (!Nodes.ContainsKey(elemn[1])) { n = new Node(elemn[1]); Nodes.Add(n.Name, n); } else n = Nodes[elemn[1]]; comp.Nodes.Add(n); n.Components.Add(comp); if (n.Name == "0") { n.IsReference = true; Reference = n; } //agrego el segundo nodo if (!Nodes.ContainsKey(elemn[2])) { n = new Node(elemn[2]); Nodes.Add(elemn[2], n); } else n = Nodes[elemn[2]]; comp.Nodes.Add(n); n.Components.Add(comp); if (n.Name == "0") { n.IsReference = true; Reference = n; } Components.Add(comp); } State = CircuitState.FileLoaded; OriginalCircuit = this; } catch (Exception ex) { HasErrors = true; throw; } }
/// <summary> /// Dado un supernodo, recorre todas sus ramas para hallar la corriente en una de ellas /// </summary> /// <param name="nodo"></param> /// <param name="W"></param> /// <returns></returns> private static double CalculateSupernodeCurrent(Node nodo, Dipole comp, double t) { if (nodo.IsReference) nodo = comp.OtherNode(nodo); double i = 0; foreach (var comp2 in nodo.Components) { if (comp2 == comp) { continue; } if (comp2 is VoltageGenerator) { Node nodo1 = comp2.OtherNode(nodo); i += CalculateSupernodeCurrent(nodo1, comp2, t); } else i += comp2.Current(nodo, t); } return i; }
private Node CreateOrFindNode(string name) { Node n = null; if (Nodes.ContainsKey(name)) n = Nodes[name]; else { n = new Node(name); Nodes.Add(n.Name, n); } return n; }
/// <summary> /// Valida una rama y la agrega al circuito si corresponde /// En caso contrario solo agrega el componente indicado /// </summary> /// <param name="yaanalizados"></param> /// <param name="nodosnormales"></param> /// <param name="ramas"></param> /// <param name="nodo"></param> /// <param name="compo"></param> /// <param name="br"></param> protected static void ValidateBranch(List<Dipole> yaanalizados, List<Node> nodosnormales, List<Branch> ramas, Node nodo, Dipole compo, Branch br) { if (br.Components.Count <= 1) { if (compo is PasiveComponent) { Node other = compo.OtherNode(nodo); other.TypeOfNode = Node.NodeType.MultibranchCurrentNode; if (!nodosnormales.Contains(other)) nodosnormales.Add(other); } yaanalizados.Add(compo); } else { //rama valida ramas.Add(br); Node other = br.OtherNode(nodo); if (!nodosnormales.Contains(other)) nodosnormales.Add(other); yaanalizados.AddRange(br.Components); foreach (var comp in br.Components) { comp.Owner = br; } } }
/// <summary> /// barre una rama desde un nodo interno hacia la izquierda o derecha /// calculando la suma de las tensiones de generadores V1 /// y la suma de impedancias Z1 /// </summary> /// <param name="nodo"></param> /// <param name="compo1"></param> /// <param name="t"></param> /// <param name="v1"></param> /// <param name="z1"></param> private static void NavigateBranch(Node nodo, Dipole compo1, double t, ref double v1, ref double z1) { Node nodo1 = nodo; while (!(nodo1.TypeOfNode == Node.NodeType.MultibranchCurrentNode || nodo1.IsReference)) { if (compo1 is Resistor) { z1 += compo1.Impedance().Real; } else if (compo1 is VoltageGenerator || compo1 is Capacitor) { v1 += compo1.voltage(nodo1, t); } else { throw new NotImplementedException(); } nodo1 = compo1.OtherNode(nodo1); compo1 = nodo1.OtherComponent(compo1); } if (nodo1.TypeOfNode == Node.NodeType.MultibranchCurrentNode) { v1 += nodo1.Voltage.Real; } }
/// <summary> /// Dado un supernodo, recorre todas sus ramas para hallar la corriente en una de ellas /// </summary> /// <param name="nodo"></param> /// <param name="W"></param> /// <returns></returns> private static Complex32 CalculateSupernodeCurrent(Node nodo, Complex32 W, Dipole comp) { Complex32 i = Complex32.Zero; foreach (var comp2 in nodo.Components) { if (comp2 == comp) { continue; } if (comp2 is VoltageGenerator) { Node nodo1 = comp2.OtherNode(nodo); i += CalculateSupernodeCurrent(nodo1, W, comp2); }else i += comp2.Current(nodo, W); } return i; }
protected static Branch FindBranch(Circuit cir, Node initialNode, Dipole Component) { Branch br = new Branch(cir); Dipole compo = Component; Node nodo = Component.OtherNode(initialNode); br.Nodes.Clear(); //solo es valido si el circuito fue optimizado, y los paralelos //se reemplazaron por bloques paralelo while (nodo.Components.Count == 2 && cir.Reference != nodo) { br.Components.Add(compo); br.InternalNodes.Add(nodo); compo = nodo.OtherComponent(compo); nodo = compo.OtherNode(nodo); } br.Components.Add(compo); if (br.Components.Count > 1) { initialNode.Components.Remove(Component); initialNode.Components.Add(br); nodo.Components.Remove(compo); nodo.Components.Add(br); nodo.TypeOfNode = Node.NodeType.MultibranchCurrentNode; } br.Nodes.Add(initialNode); br.Nodes.Add(nodo); //hay que recorrer la rama para buscar los nodos intermedios flotantes //y aquellos dependientes de los flotantes nodo = compo.OtherNode(nodo); while (nodo != initialNode) { if (nodo.TypeOfNode == Node.NodeType.VoltageFixedNode) { // nothing, node was calculated } else if (compo is VoltageGenerator || compo is Capacitor) { if (nodo.TypeOfNode == Node.NodeType.Unknow) nodo.TypeOfNode = Node.NodeType.VoltageLinkedNode; else throw new NotImplementedException(); } else if (compo is Resistor) { if (nodo.TypeOfNode == Node.NodeType.Unknow) nodo.TypeOfNode = Node.NodeType.VoltageDivideNode; else throw new NotImplementedException(); } else if (compo is Inductor || compo is CurrentGenerator) { //nada, solo imponen la corriente } else { if (nodo.TypeOfNode == Node.NodeType.Unknow) nodo.TypeOfNode = Node.NodeType.InternalBranchNode; else throw new NotImplementedException(); } compo = nodo.OtherComponent(compo); nodo = compo.OtherNode(nodo); } return br; }
public virtual double voltage(Node referenceNode, double CurrentTime) { if (referenceNode == Nodes[0]) return Voltage.Real; return -Voltage.Real; }
public System.Drawing.Bitmap TakeSnapShot(Node node) { SelectedNode = node; ComplexPlainAnalysis SnapAnalysis = (ComplexPlainAnalysis)CurrentAnalysis;//.Clone(); //SnapAnalysis.Points = 300; //Solve(CurrentCircuit, SnapAnalysis); System.Drawing.Bitmap bmp = FileUtils.DrawImage(func, SnapAnalysis.Points, SnapAnalysis.Points); return bmp; }
public virtual Complex32 voltage(Node ReferenceNode, Complex32 ?W = null) { return 0; //if (ReferenceNode == Nodes[0]) // return Voltage; //if (ReferenceNode == Nodes[1]) // return -Voltage; //return Complex32.NaN; }
/// <summary> /// Dado 1 nodo interno de la rama, busca el nodo externo mas cercano al componente /// </summary> /// <param name="internalnode"></param> /// <returns></returns> public Node FindBranchExternalNode(Node internalnode, Dipole component) { if (!InternalNodes.Contains(internalnode)) { //la rama no contiene al nodo indicado, probablemene un error return null; } if (!component.Nodes.Contains(internalnode)) { //el componente no contiene el nodo, un error return null; } Dipole comp = null, comp2 = null; Node n = null; n = internalnode; throw new NotImplementedException(); while (!Nodes.Contains(n)) { //busco componente a componente, nodo a nodo comp2 = n.OtherComponent(comp); n = comp2.OtherNode(n); } return n; }
/// <summary> /// Dado 1 nodo extremo de la rama, busca el nodo mas cercano al componente /// </summary> /// <param name="externalnode">one of two exterior branch nodes</param> /// <returns></returns> public Node FindComponentNode(Node externalnode, Dipole component) { Node n = null; if (!Nodes.Contains(externalnode)) { //la rama no contiene al nodo indicado, probablemene un error return null; } Dipole comp = null; //if (Nodes.Contains(originalnode)) //identifico al componente que contiene el nodo externo foreach (var comp1 in Components) { if (comp1.Nodes[0] == externalnode || comp1.Nodes[1] == externalnode) { comp = comp1; break; } } n = externalnode; do { if (comp == component) { return n; } //busco componente a componente, nodo a nodo n = comp.OtherNode(n); comp = n.OtherComponent(comp); } while (InternalNodes.Contains(n)); //error, no se encontro elcompente que contine el nodo! return null; }
//la corriente puede variar en el tiempo public override double Current(Node referenceNode, double t) { //si ya se calculo la corriente devuelvo la calculada if (previoustime > 0 && previoustime == t) { if (referenceNode == Nodes[0]) return _current.Real; else if (referenceNode == Nodes[1]) return -_current.Real; else throw new NotImplementedException(); } double i = 0; if (CurrentImposser != null) { if (CurrentImposser.Nodes.Contains(referenceNode)) { i = CurrentImposser.Current(referenceNode, t); if (referenceNode == Nodes[0]) _current = new Complex32((float)i, 0); else _current = new Complex32((float)-i, 0); } else { //hay que buscar nodo a nodo Node nodo = FindComponentNode(referenceNode, CurrentImposser); i = CurrentImposser.Current(nodo, t); } } else { foreach (var comp in Components) { //los generadores de corriente imponen la corriente en una rama! if (comp is CurrentGenerator) { CurrentImposser = comp; i = comp.Current(referenceNode, t); break; } //si no hay generadores de corriente la corriente la imponen lo inductores else if (comp is Inductor) { CurrentImposser = comp; i = comp.Current(referenceNode, t); } else if (comp is Resistor) { CurrentImposser = comp; i = comp.Current(referenceNode, t); } } } if (CurrentImposser == null) i = _current.Real; if (referenceNode == Nodes[0]) return -i; else// if (referenceNode == Nodes[1]) return i; //else throw new NotImplementedException(); }
public virtual Complex32 NortonCurrent(Node referenceNode, Complex32 ?W = null) { Complex32 v = 0, z = 0; Dipole compo1 = null; Node node1 = null; //encuentro el componente unido al nodo de referencia foreach (var item in Components) { if (item.Nodes[0] == referenceNode || item.Nodes[1] == referenceNode) { compo1 = item; break; } } //a partir del nodo y el componente, escaneo la ramaenbusca de la Vthevenin y la Rthevenin node1 = referenceNode; do { if (compo1 is Branch) v += ((Branch)compo1).TheveninVoltage(node1, W); else if(compo1 is ACVoltageGenerator) v += compo1.voltage(node1, W); //los componentes pasivos no tienen tension en barrido en frecuencia z += compo1.Impedance(W); node1 = compo1.OtherNode(node1); compo1 = node1.OtherComponent(compo1); } while (InternalNodes.Contains(node1)); return v / z; }
public override Complex32 voltage(Node ReferenceNode, Complex32? W = null) { return 0; }
/// <summary> /// barre una rama desde un nodo interno hacia la izquierda o derecha /// calculando la suma de las tensiones de generadores V1 /// y la suma de impedancias Z1 /// </summary> /// <param name="nodo"></param> /// <param name="compo1"></param> /// <param name="W"></param> /// <param name="v1"></param> /// <param name="z1"></param> private static void NavigateBranch(Node nodo , Dipole compo1, Complex32 W, ref Complex32 v1, ref Complex32 z1) { Node nodo1 = nodo; while (!(nodo1.TypeOfNode == Node.NodeType.MultibranchCurrentNode || nodo1.IsReference)) { if (nodo1.TypeOfNode == Node.NodeType.VoltageFixedNode) { //llegue al final de la rama v1 += nodo1.Voltage; break; } if (compo1 is PasiveComponent) { z1 += compo1.Impedance(W); } else if (compo1 is VoltageGenerator) { v1 += compo1.voltage(nodo1, W); } else { throw new NotImplementedException(); } nodo1 = compo1.OtherNode(nodo1); compo1 = nodo1.OtherComponent(compo1); } if (nodo1.TypeOfNode == Node.NodeType.MultibranchCurrentNode && !nodo1.IsReference) { v1 += nodo1.Voltage; } }
public override Complex32 Current(Node referenceNode, Complex32? W = null) { return voltage(referenceNode) / Impedance(W); }
public Node OtherNode(Node thisnode) { if (thisnode == Nodes[0]) return Nodes[1]; return Nodes[0]; }