public void GenerateDatas()
        {
            try
            {
                Collection.Clear();
                Circuit cir = new Circuit();
                cir.ReadCircuit("Circuits/RCcharge.net");
                Circuit cir2 = (Circuit)cir.Clone();
                cir2.Setup.RemoveAt(0);
                ACAnalysis ac = new ACAnalysis();
                cir2.Setup.Add(ac);
                ACSweepSolver.Optimize(cir2);
                cir2.Solve();

                ACSweepSolver sol = (ACSweepSolver)ac.Solver;

                foreach (var res in sol.Voltages)
                {
                    //Console.Write(res.Key.ToString() + "rad/seg");
                    foreach (var nodo in res.Value)
                    {
                        if (nodo.Key == "$N_0001")
                            //Console.Write(nodo.Key + " " + nodo.Value.ToString() + "V\r\n");
                            this.Collection.Add(new Point(res.Key, nodo.Value.Real));
                    }
                }
            }
            catch (Exception ex)
            {
                
                throw;
            }
        
        }
        public void Simulate(string circuitname)
        {
            TxtStatus.Text = circuitname;
            cir = new Circuit();

            //cir.ReadCircuit("Circuits/RCL.net");
            cir.ReadCircuit(circuitname);
            cir2 = (Circuit)cir.Clone();
            cir2.Setup.RemoveAt(0);
            ACAnalysis ac = new ACAnalysis();
            cir2.Setup.Add(ac);
            ACSweepSolver.Optimize(cir2);
           
            Refresh();
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            model = new ComplexPlainViewModel();
            model.ColorCoding = ColorCoding.ByLights;

            Circuit cir = new Circuit();
            cir.ReadCircuit("Circuits/RCL.net");
            cir2 = (Circuit)cir.Clone();
            cir2.Setup.RemoveAt(0);
            ComplexPlainAnalysis ac1 = new ComplexPlainAnalysis();
            cir2.Setup.Add(ac1);
            ACSweepSolver.Optimize(cir2);
            cir2.Solve();
            sol1 = (ComplexPlainSolver)ac1.Solver;

            int scalefactor = 5000;
            model.MinX = ac1.SigmaMin / scalefactor;
            model.MaxX = ac1.SigmaMax / scalefactor;
            model.MaxY = ac1.WMax / scalefactor;
            model.MinY = ac1.WMin / scalefactor;
            model.Columns = ac1.Points;
            model.Rows = ac1.Points;
            var data = new Point3D[model.Rows, model.Columns];
            //public Tuple<Complex32, Complex32>[,] Results { get; set; }
            MathNet.Numerics.Complex32 W;
            for (int i = 0; i < model.Rows; i++)
                for (int j = 0; j < model.Columns; j++)
                {
                    W = sol1.WfromIndexes[new Tuple<int, int>(i, j)];
                    foreach (var node in sol1.Voltages[W])
                    {
                        if (node.Key == "out")
                            data[i, j] = new Point3D(W.Real /scalefactor, 
                                                    W.Imaginary /scalefactor,
                                                    //node.Value.Magnitude);
                                                    2 * Math.Log10(node.Value.Magnitude));
                    }
                }

            model.Data = data;
            model.UpdateModel(false);         
            //model.CreateDataArray(ModuleInDB);

            DataContext = model;

        }
        public void Simulate(string circuitname)
        {
            propgrid.SelectedObject = null;
            cir = new Circuit();
            cir.ReadCircuit(circuitname);
            cir2 = (Circuit)cir.Clone();
            cir2.Setup.RemoveAt(0);
            if (ac5 == null || cir2.Setup.Count == 0)
            {
                ac5 = new TransientAnalysis();
                ac5.Step = "50n";
                ac5.FinalTime = "50u";
                cir2.Setup.Add(ac5);
            }
            TransientSolver sol5 = (TransientSolver)ac5.Solver;
            TransientSolver.Optimize(cir2);
            Refresh();
            lbComponents.ItemsSource = cir.Components;
            lbNodes.ItemsSource = cir.Nodes.Values;

        }
        private void LoadField()
        {
            Circuit cir = new Circuit();
            cir.ReadCircuit("Circuits/RCL.net");
            cir2 = (Circuit)cir.Clone();
            cir2.Setup.RemoveAt(0);
            ComplexPlainAnalysis ac1 = new ComplexPlainAnalysis();
            cir2.Setup.Add(ac1);
            ACSweepSolver.Optimize(cir2);
            cir2.Solve();
            sol1 = (ComplexPlainSolver)ac1.Solver;

          
            int Rows = ac1.Points;
            int Columns = ac1.Points;
            double[,] data = new double[Rows, Columns];
            Point[,] gridData = new Point[Rows, Columns];
            MathNet.Numerics.Complex32 W;
            for (int i = 0; i < Rows; i++)
                for (int j = 0; j < Columns; j++)
                {
                    W = sol1.WfromIndexes[new Tuple<int, int>(i, j)];
                    foreach (var node in sol1.Voltages[W])
                    {
                        if (node.Key == "out")
                        {
                            data[i, j] = 20 * Math.Log10(node.Value.Magnitude);
                            //data[i, j] = 180 * node.Value.Phase / Math.PI;
                            gridData[i, j] = new Point(W.Real, W.Imaginary);
                        }
                        
                      
                    }
                }
            
            WarpedDataSource2D<double> dataSource = new WarpedDataSource2D<double>(data, gridData);
            isolineGraph.DataSource = dataSource;
            trackingGraph.DataSource = dataSource;

        }
 public object Clone()
 {
     Circuit cir = new Circuit();
     foreach (var node in Nodes)
     {
         cir.Nodes.Add(node.Key, node.Value);
     }
     cir.Components.AddRange(Components);
     foreach (var comp in cir.Components)
     {
         comp.OwnerCircuit = cir;
     }
     cir.Reference = Reference;
     cir.OriginalCircuit = this;
     return cir;
 }
        private void PreAnalizeToSolve(Circuit cir, List<Node> nodos, SolveInfo solveinfo)
        {
            nodos.AddRange(cir.Nodes.Values);
            nodos.Remove(cir.Reference);

            //guardo para futuro los nodos de los componentes especiales
            if (cir.OriginalCircuit != null)
            {
                foreach (var comp in cir.OriginalCircuit.Components)
                {
                    if (comp is ControlledDipole)
                    {
                        foreach (var nodo in comp.Nodes)
                        {
                            if (!nodo.IsReference)
                            {
                                SpecialComponentInfo info = new SpecialComponentInfo(comp);
                                info.ImportantOutputNodes.Add(nodo);
                                solveinfo.specialcomponents.Add(info);
                                if (!solveinfo.nortonnodes.Contains(nodo))
                                    solveinfo.nortonnodes.Add(nodo);
                                //especialcomponents.Add(nodo, comp);
                            }
                        }
                    }
                }
            }

            foreach (var compo in cir.Components)
            {
                if (compo is Branch)
                    solveinfo.ramas.Add((Branch)compo);
            }

            foreach (var nodo in nodos)
            {
                //los nodos de salida de un dispositivo VcV deben resolverse mediante matrices
              
                if (solveinfo.nortonnodes.Contains(nodo))
                    continue;
                if (nodo.TypeOfNode == Node.NodeType.MultibranchCurrentNode ||
                    nodo.TypeOfNode == Node.NodeType.VoltageLinkedNode
                    )
                    solveinfo.nortonnodes.Add(nodo);
                else if (nodo.TypeOfNode == Node.NodeType.VoltageDivideNode ||
                        nodo.TypeOfNode == Node.NodeType.VoltageFixedNode)
                {
                    solveinfo.calculablenodes.Add(nodo);
                }
            }

        }
        public bool Solve(Components.Circuit cir, BasicAnalysis ana)
        {
            List<Node> nodos = new List<Node>();
            Voltages = new Dictionary<double, Dictionary<string, double>>();
            Currents = new Dictionary<double, Dictionary<string, double>>();
            circuit = cir;

            SolveInfo solveinfo = new SolveInfo();

            //nodos.AddRange(cir.Nodes.Values);
            //nodos.Remove(cir.Reference);
           
            PreAnalizeToSolve(cir, nodos, solveinfo);
       
            TransientAnalysis analis = ana as TransientAnalysis;
            double t, tf, deltat;

            deltat = StringUtils.DecodeString(analis.Step);
            tf = StringUtils.DecodeString(analis.FinalTime);
            t = 0;
            cir.CircuitTime = t;
            cir.Reset();

            while (t < tf)
            {
                //Calculo de tensiones de nodos
                Calculate(solveinfo, t);

                Dictionary<string, double> result = new Dictionary<string, double>();

                #region almacenamiento temporal

                foreach (var nodo in nodos)
                {
                    result.Add(nodo.Name, nodo.Voltage.Real);
                }

                if (!Voltages.ContainsKey(t))
                    Voltages.Add(t, result);
                #endregion

                //calculo las corrientes:
                CalculateCurrents(cir, t);
                Dictionary<string, double> currents = new Dictionary<string, double>();
                StorageCurrents(cir, currents);
                Currents.Add(t, currents);


                cir.CircuitTime = t;
                t += deltat;
            }
            cir.State = Circuit.CircuitState.Solved;

            return true;
        }
        public static bool Optimize(Circuit cir)
        {
            List<Dipole> yaanalizados = new List<Dipole>();
            List<ParallelBlock> paralelos = new List<ParallelBlock>();
            List<Node> nodosnormales = new List<Node>();
            List<Branch> ramas = new List<Branch>();
            ParallelBlock para = null;

            #region Chequeo de nodos sueltos o componentes colgantes
            foreach (var nodo in cir.Nodes.Values)
            {
                if (nodo.Components.Count == 0)
                {
                    throw new NotImplementedException();
                }
                //componente con borne suelto
                //if (nodo.Components.Count == 1)
                //{
                //    throw new NotImplementedException();
                //}
            }
            #endregion

            #region busco componentes en paralelo

            if (false)
            //no se hace un paralelo si solo hay 2 componentes
            if (cir.Components.Count > 2)
            { 
                for (int i = 0; i < cir.Components.Count - 1; i++)
                {
                    if (yaanalizados.Contains(cir.Components[i]))
                        continue;
                    Dipole comp1 = cir.Components[i];

                    for (int j = i + 1; j < cir.Components.Count; j++)
                    {
                        if (yaanalizados.Contains(cir.Components[j]))
                            continue;
                        Dipole comp2 = cir.Components[j];

                        //comparten 2 nodos
                        if ((comp1.Nodes[0] == comp2.Nodes[0] && comp1.Nodes[1] == comp2.Nodes[1]) ||
                            (comp1.Nodes[0] == comp2.Nodes[1] && comp1.Nodes[1] == comp2.Nodes[0]))
                        {
                            if (para == null)
                            {
                                para = new ParallelBlock(cir, comp1, comp2);
                                paralelos.Add(para);
                                yaanalizados.Add(comp1);
                                yaanalizados.Add(comp2);
                            }
                            else
                            {
                                para.Components.Add(comp2);
                                yaanalizados.Add(comp2);
                            }
                        }
                    }
                }
            }
           

            #endregion

            #region reemplazo los componentes paralelos separados por
            //el correspondiente block paralelo
            foreach (var para1 in paralelos)
            {
                foreach (var compo in para1.Components)
                    cir.Components.Remove(compo);

                cir.Components.Add(para1);
            }
            #endregion

            #region identifico la tierra
            Node tierra = cir.Reference;

            if (tierra == null)
                foreach (var item in cir.Nodes.Values)
                {
                    if (item.IsReference)
                    {
                        tierra = item;
                        cir.Reference = tierra;
                        break;
                    }
                }
            #endregion

            #region arranco desde tierra he identifico los nodos de tension fija,
            //posibles nodos flotantes de corriente y ramas conectadas a tierra

            List<Dipole> componenttoearh = new List<Dipole>();
            componenttoearh.AddRange(tierra.Components);
            foreach (var compo in componenttoearh)
            {

                //los nodos de tension fija 
                if (compo is VoltageGenerator || compo is Capacitor)
                { 
                    Node other = compo.OtherNode(tierra);
                    other.TypeOfNode = Node.NodeType.VoltageFixedNode;
                    other.Voltage = compo.Voltage;
                }
                //if (compo is Capacitor)
                //{
                //    Node other = compo.OtherNode(tierra);
                //    other.TypeOfNode = Node.NodeType.VoltageVariableNode;
                //    other.Voltage = compo.Voltage;
                //}
                    
                foreach (var rama in ramas)
                {
                    if (rama.Components.Contains(compo))
                        goto end;
                }      
                //desde tierra los nodos son:
                //a: pertenecen a una rama. hay que levantar dicha rama...
                //b: son nodos normales flotantes (se aplica teorema de nodo)
                Branch br = FindBranch(cir, tierra, compo);
                //si no forma parte de una rama, la rama de 1 elemento se desecha
                ValidateBranch(yaanalizados, nodosnormales, ramas, tierra, compo, br);
        end: ;
            }
            #endregion

            #region Analizo las ramas faltantes desde los nodos normales encontrados

            foreach (var nodo in nodosnormales)
            {
                foreach (var compo in nodo.Components)
                {
                    if (ramas.Contains(compo) || yaanalizados.Contains(compo))
                        continue;

                    Branch br = FindBranch(cir, nodo, compo);
                    ValidateBranch(yaanalizados, nodosnormales, ramas, nodo, compo, br);
                }
            }

            #endregion

            //reemplazo los componentes que arman una rama por la propia rama
            foreach (var rama in ramas)
                foreach (var compo in rama.Components)
                    cir.Components.Remove(compo);


            cir.Components.AddRange(ramas);
            cir.State = Circuit.CircuitState.Optimized;

            return true;
        }
        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 override bool Solve(Circuit cir, BasicAnalysis ana)
        {
            List<Node> nodos = new List<Node>();
            Voltages = new Dictionary<double, Dictionary<string, Complex32>>();
            Currents = new Dictionary<double, Dictionary<string, Complex32>>();

            //List<Node> nodosnorton;
            //List<Node> nodoscalculables;
            //List<SpecialComponentInfo> specialcomponents;
            SolveInfo solveinfo = new SolveInfo();

            PreAnalizeToSolve(cir, nodos, solveinfo);

            ACAnalysis analis = ana as ACAnalysis;
            double w, wi, wf, deltaw, wx, pow = 1;

            wi = StringUtils.DecodeString(analis.StartFrequency);
            wf = StringUtils.DecodeString(analis.EndFrequency);
            w = wi;
            int i = (int)Math.Log10(wi) + 1;
            wx = Math.Pow(10, i);
            if (analis.ScanType == ACAnalysis.ACAnalysisScan.Linear)
                deltaw = (wf - wi) / analis.Points;
            else
            {
                deltaw = 1.0d / analis.Points;
                pow = Math.Pow(10, deltaw);
            }

            while (w < wf)
            {
                //Calculo de tensiones de nodos
                Complex32 W = new Complex32(0, (float)w);
                Calculate(solveinfo, W);

                Dictionary<string, Complex32> result = new Dictionary<string, Complex32>();

                #region almacenamiento temporal
 
                foreach (var nodo in nodos)
                {
                    result.Add(nodo.Name, nodo.Voltage);
                }

                if (!Voltages.ContainsKey(w))
                    Voltages.Add(w, result);
                #endregion

                //calculo las corrientes:
                CalculateCurrents(cir, W);
                Dictionary<string, Complex32> currents = new Dictionary<string, Complex32>();
                StorageCurrents(cir, currents);
                Currents.Add(w, currents);


                if (analis.ScanType == ACAnalysis.ACAnalysisScan.Linear)
                    w += deltaw;
                else
                {
                    w = w * pow;
                    if (w > 0.95 * wx)
                    {
                        i++;
                        wi = wx;
                        wx = Math.Pow(10, i);
                        w = wi;
                    }
                }
            }

            cir.State = Circuit.CircuitState.Solved;
            return true;
        }
        static void Main(string[] args)
        {
            int i = 2;

            switch (i)
            {
                case 0:
                    cir.ReadCircuit("circuits/RLcharge.net");
                    cir2 = (Circuit)cir.Clone();
                    DCSolver.Optimize(cir2);
                    DCAnalysis ac0 = (DCAnalysis)cir2.Setup[0];
                    DCSolver solver = (DCSolver)ac0.Solver;
                    //solver.Solve(cir2, );
                    cir2.Solve();
                    solver.ExportToCSV("e:/Test.csv");

                    break;
                case 1:
                    cir.ReadCircuit("circuits/testidc.net");
                    cir2 = (Circuit)cir.Clone();
                    DCSolver.Optimize(cir2);
                    DCAnalysis ac3 = (DCAnalysis)cir2.Setup[0];
                    DCSolver solver3 = (DCSolver)ac3.Solver;
                    //solver.Solve(cir2, );
                    cir2.Solve();
                    solver3.ExportToCSV("e:/Test.csv");

                    break;


                case 2:
                    cir.ReadCircuit("circuits/derivador.net");
                    //cir.ReadCircuit("RCL.net");
                    cir2 = (Circuit)cir.Clone();
                    cir2.Setup.RemoveAt(0);
                    ACAnalysis ac = new ACAnalysis();
                    cir2.Setup.Add(ac);
                    ACSweepSolver.Optimize(cir2);
                    cir2.Solve();

                    ACSweepSolver sol = (ACSweepSolver)ac.Solver;
                    sol.ExportToCSV("ACSweep.csv");
                    break;

                case 3:
                    //cir.ReadCircuit("derivador.net");
                    cir.ReadCircuit("circuits/RLC.net");
                    cir2 = (Circuit)cir.Clone();
                    cir2.Setup.RemoveAt(0);
                    ComplexPlainAnalysis ac1 = new ComplexPlainAnalysis();
                    cir2.Setup.Add(ac1);
                    ACSweepSolver.Optimize(cir2);
                    cir2.Solve();
                    sol1 = (ComplexPlainSolver)ac1.Solver;
                    sol1.SelectedNode = sol1.CurrentCircuit.Nodes["out"];
                   // sol1.
                    sol1.ExportToCSV("e:/plain.csv");
                    Bitmap bmp =  FileUtils.DrawImage(func, ac1.Points, ac1.Points);
                    bmp.Save("e:/plain.bmp");
                    break;


                case 4:
                    cir.ReadCircuit("circuits/RCL.net");
                    //cir.ReadCircuit("RCcharge.net");
                    cir2 = (Circuit)cir.Clone();
                    cir2.Setup.RemoveAt(0);
                    TransientAnalysis ac5 = new TransientAnalysis();
                    ac5.Step = "10n";
                    cir2.Setup.Add(ac5);
                    TransientSolver sol5 = (TransientSolver)ac5.Solver;
                    TransientSolver.Optimize(cir2);
                    cir2.Solve();
                    sol5.ExportToCSV("e:/time.csv");
                    break;

                case 5:
                    cir.ReadCircuit("circuits/vsingain.net");
                    //cir.ReadCircuit("RCcharge.net");
                    cir2 = (Circuit)cir.Clone();
                    cir2.Setup.RemoveAt(0);
                    TransientAnalysis ac6 = new TransientAnalysis();
                    ac6.Step = "100n";
                    cir2.Setup.Add(ac6);
                    TransientSolver sol6 = (TransientSolver)ac6.Solver;
                    TransientSolver.Optimize(cir2);
                    cir2.Solve();
                    sol6.ExportToCSV("e:/time.csv");
                    break;

                default:
                    break;
            }

      
       


            Console.ReadKey();  
      }
        public override bool Solve(Circuit cir, BasicAnalysis ana)
        {
            List<Node> nodos = new List<Node>();
            CurrentAnalysis = ana as ComplexPlainAnalysis;
            CurrentCircuit = cir;

            //List<Node> nodosnorton = new List<Node>();
            //List<Node> nodoscalculables = new List<Node>();
            //List<SpecialComponentInfo> especialcomponents;
            Voltages = new Dictionary<Complex32, Dictionary<string, Complex32>>();
            Currents = new Dictionary<Complex32, Dictionary<string, Complex32>>();
            WfromIndexes = new Dictionary<Tuple<int, int>, Complex32>();
            SolveInfo solveinfo = new SolveInfo();

            PreAnalizeToSolve(cir, nodos, solveinfo);


            ComplexPlainAnalysis analis = ana as ComplexPlainAnalysis;
            double w, sig, wi, wf, deltaw, deltasig, sigmamin, sigmamax;

            wi = analis.WMin;
            wf = analis.WMax;
            sigmamax = analis.SigmaMax;
            sigmamin = analis.SigmaMin;
            w = wi;
            sig = sigmamin;
            deltaw = (wf - wi) / analis.Points;
            deltasig = (sigmamax - sigmamin) / analis.Points;

            Complex32 W = Complex32.Zero;

            for (int i = 0; i <= analis.Points; i++)
            {

                for (int j = 0; j <= analis.Points; j++)
                {
                    //Calculo de tensiones de nodos
                    W = new Complex32((float)(sigmamin + j * deltasig), (float)(wi + i * deltaw));
                    ACSweepSolver.Calculate(solveinfo, W);
                    
                    //          Node    Voltage
                    Dictionary<string, Complex32> result = new Dictionary<string, Complex32>();

                    #region almacenamiento temporal
                  
                    foreach (var nodo in nodos)
                    {
                        result.Add(nodo.Name, nodo.Voltage);
                    }
                    if (!Voltages.ContainsKey(W))
                    {
                        Voltages.Add(W, result);
                        WfromIndexes.Add(new Tuple<int, int>(i, j), W);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                   // Results[i,j] = new Tuple<Complex32,Complex32>(W, 

                    #endregion

                    //calculo las corrientes:
                    CalculateCurrents(cir, W);
                    Dictionary<string, Complex32> currents = new Dictionary<string, Complex32>();
                    StorageCurrents(cir, currents);
                    Currents.Add(W, currents);

                }
            }
            cir.State = Circuit.CircuitState.Solved;

            return true;
        }
        private void Simulate(string FileName)
        {
            cir = new Circuit();
            cir.ReadCircuit(FileName);
            cir2 = (Circuit)cir.Clone();
            cir2.Setup.RemoveAt(0);
            ac1 = new ComplexPlainAnalysis();
            cir2.Setup.Add(ac1);
            ACSweepSolver.Optimize(cir2);

            Update();

            lbComponents.ItemsSource = cir.Components;
            lbNodes.ItemsSource = cir.Nodes.Values;
            //lbComponents.SelectedItem
            DataContext = model;
        }
        public virtual bool Solve(Circuit cir, BasicAnalysis ana)
        {
            //int fila = 0;
            List<Node> nodos = new List<Node>();
            circuit = cir;

            if (cir.Reference == null)
            {
                foreach (var nodo in cir.Nodes.Values)
                {
                    //creo una lista de nodos sin el nodo referencia
                    if (!nodo.IsReference)
                        nodos.Add(nodo);
                } 
            }
            else
            {
                nodos.AddRange(cir.Nodes.Values);
                nodos.Remove(cir.Reference);
            }
           

            List<Node> nodosnorton = new List<Node>();
            List<Node> nortoncopia = new List<Node>();

            foreach (var nodo in nodos)
            {
                if (nodo.TypeOfNode == Node.NodeType.MultibranchCurrentNode ||
                    nodo.TypeOfNode == Node.NodeType.VoltageLinkedNode ||
                    nodo.TypeOfNode == Node.NodeType.VoltageDivideNode)
                    nodosnorton.Add(nodo);
            }

            #region Calculo de tensiones de nodos

            nortoncopia.Clear();
            foreach (var item in nodosnorton)
            {
                nortoncopia.Add(item);
            }

            Calculate(nortoncopia);
            #endregion

            //#region almacenamiento temporal


            //#endregion
            
            //calculo las corrientes:
            CalculateCurrents(cir);


            cir.State = Circuit.CircuitState.Solved;
            return true;
        }
 protected static void AddComponentNodes(Circuit ciroptimizado, Dipole rama)
 {
     if (!ciroptimizado.Nodes.ContainsValue(rama.Nodes[0]))
         ciroptimizado.Nodes.Add(rama.Nodes[0].Name, rama.Nodes[0]);
     if (!ciroptimizado.Nodes.ContainsValue(rama.Nodes[1]))
         ciroptimizado.Nodes.Add(rama.Nodes[1].Name, rama.Nodes[1]);
 }