public TransientAnalysis()
     : base()
 {
     Step      = "1u";
     FinalTime = "100u";
     Solver    = new TransientSolver();
 }
 private void DrawCurrent(TransientSolver sol5, string name)
 {
     foreach (var data in sol5.Currents)
     {
         foreach (var item in data.Value)
         {
             if (item.Key == name)
             {
                 Tuple <double, double> p = new Tuple <double, double>(data.Key, item.Value);
                 source1.Collection.Add(p);
             }
         }
     }
 }
        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 Redraw()
        {
            if (cir2 == null || propgrid.SelectedObject == null)
            {
                return;
            }

            if (source1 != null)
            {
                source1.Collection.Clear();
            }

            TransientSolver sol5 = (TransientSolver)cir2.Setup[0].Solver;

            if (propgrid.SelectedObject is Node)
            {
                //if (cir.Nodes.ContainsKey(txtPlotted.Text))
                //{
                //    DrawVoltage(sol5, txtPlotted.Text);
                //}
                //else
                //{
                DrawVoltage(sol5, ((Node)propgrid.SelectedObject).Name);
                txtPlotted.Text = ((Node)propgrid.SelectedObject).Name;
                //}
            }
            else if (propgrid.SelectedObject is Dipole)
            {
                DrawCurrent(sol5, ((Dipole)propgrid.SelectedObject).Name);
                txtPlotted.Text = ((Dipole)propgrid.SelectedObject).Name;
                //foreach (var item in cir.Components)
                //{
                //    if (item.Name == txtPlotted.Text)
                //    {
                //        DrawCurrent(sol5, item.Name);
                //        txtPlotted.Text = item.Name;
                //    }
                //}
            }
        }
示例#5
0
 private static void interactiveTick(TransientSolver solver)
 {
     Console.Write("RESULT " + solver.GetTimeAtTick(solver.GetCurrentTick()) + ",");
     for (int i = 0; i < circuit.Nets.Count; i++)
     {
         Console.Write(solver.GetNetVoltage(circuit.Nets[i]) + ",");
     }
     for (int i = 0; i < circuit.Components.Count; i++)
     {
         for (int j = 0; j < circuit.Components[i].GetNumberOfPins(); j++)
         {
             Console.Write(solver.GetPinCurrent(circuit.Components[i], j) + ",");
         }
     }
     Console.WriteLine();
     lineBufferMutex.WaitOne();
     foreach (var line in lineBuffer)
     {
         List <string> parts = new List <string>();
         foreach (string part in line.Split(new[] { ' ' }))
         {
             parts.Add(part);
         }
         if (parts.Count > 2)
         {
             if (parts[0] == "CHANGE")
             {
                 foreach (Component c in circuit.Components)
                 {
                     if (c.ComponentID == parts[1])
                     {
                         c.SetParameters(new ParameterSet(parts));
                     }
                 }
             }
         }
     }
     lineBuffer.Clear();
     lineBufferMutex.ReleaseMutex();
 }
示例#6
0
 public virtual double TransientDerivative(TransientSolver solver, int f, VariableIdentifier var)
 {
     return(0.0d);
 }
示例#7
0
 /*
  * Returns a function that can be used by the non-linear transient solver
  * to solve as f(x) = 0
  * For components with greater than 2 pins, f is the indentifier of the function 0 <= f < n-1
  */
 public virtual double TransientFunction(TransientSolver solver, int f)
 {
     return(0.0d);
 }
示例#8
0
        static void Main(string[] args)
        {
            string line     = "";
            string netlist  = "";
            double simSpeed = 0;
            int    testid   = 0;

            while (true)
            {
                line = ForTesting[testid++];
                // line = Console.ReadLine();
                if (line.Contains("START"))
                {
                    simSpeed = Convert.ToDouble(line.Substring(6));
                    break;
                }
                netlist += line;
                netlist += "\n";
            }

            circuit.ReadNetlist(netlist);
            Console.Write("VARS t,");

            for (int i = 0; i < circuit.Nets.Count; i++)
            {
                Console.Write("V(" + circuit.Nets[i].NetName + "),");
            }
            for (int i = 0; i < circuit.Components.Count; i++)
            {
                for (int j = 0; j < circuit.Components[i].GetNumberOfPins(); j++)
                {
                    Console.Write("I(" + circuit.Components[i].ComponentID + "." + j + "),");
                }
            }
            Console.WriteLine();

            DCSolver solver = new DCSolver(circuit);
            bool     result = false;

            try
            {
                result = solver.Solve();
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to obtain initial operating point");
                circuit.ReportError("EXCEPTION", true);
            }
            if (!result)
            {
                circuit.ReportError("CONVERGENCE", false);
            }

            TransientSolver tranSolver = new TransientSolver(solver);

            tranSolver.InteractiveCallback = interactiveTick;
            Thread updaterThread = new Thread(new ThreadStart(iothread));

            updaterThread.Start();
            tranSolver.RunInteractive(simSpeed);
        }
示例#9
0
 public double TransientFunction(TransientSolver solver)
 {
     return(0.0d);
 }
示例#10
0
        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();
        }
示例#11
0
        //Run a solve routine, returning whether or not successful
        //[0]
        public bool Solve(double tol = 1e-8, int maxIter = 200, bool attemptRamp = true)
        {
            int    n        = VariableValues.Count;
            double worstTol = 0;

            //The matrix to solve by Gaussian elimination for the next Newton-Raphson iteration, the rows representing functions. The first n-1 columns are
            //the Jacobian matrix of partial derivatives (each column representing a variable), and the final column is the value of -f(x) for that function
            //This is solved to find the values of (x_n+1 - x_n)
            double[][] matrix = new double[n][];
            int        i;

            for (i = 0; i < n; i++)
            {
                matrix[i] = new double[n + 1];
            }

            // [1]
            for (i = 0; i < maxIter; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    VariableIdentifier varData = VariableData[j];
                    if (varData.type == VariableType.COMPONENT)
                    {
                        //Set the value of -f(x)
                        matrix[j][n] = -varData.component.DCFunction(this, varData.pin);
                        //Populate the matrix of derivatives
                        for (int k = 0; k < n; k++)
                        {
                            matrix[j][k] = varData.component.DCDerivative(this, varData.pin, VariableData[k]);
                        }
                    }
                    else
                    {
                        //Set the value of -f(x)
                        matrix[j][n] = -varData.net.DCFunction(this);
                        //Populate the matrix of derivatives
                        for (int k = 0; k < n; k++)
                        {
                            matrix[j][k] = varData.net.DCDerivative(this, VariableData[k]);
                        }
                    }
                }


                worstTol = 0;
                for (int j = 0; j < n; j++)
                {
                    if (System.Math.Abs(matrix[j][n]) > worstTol)
                    {
                        worstTol = System.Math.Abs(matrix[j][n]);
                    }
                }
                if (worstTol < tol)
                {
                    break;
                }
                //Call the Newton-Raphson solver, which updates VariableValues with their new values
                Math.newtonIteration(n, VariableValues, matrix);
            }

            //If conventional Newton's method solution to find the operating point fails
            //Fixed nets are ramped up from zero volts to full in 10% steps in an attempt to find the operating point
            //This works to prevent convergence failures in unstable circuits such as oscillators
            // [2]
            if ((i == maxIter) && (worstTol > 1))
            {
                if (attemptRamp)
                {
                    Console.WriteLine("WARNING: DC simulation failed to converge (error=" + worstTol + ")");
                    Dictionary <Net, double> netVoltages = new Dictionary <Net, double>();
                    foreach (Net net in SolverCircuit.Nets)
                    {
                        if ((net.IsFixedVoltage) && (net.NetVoltage != 0))
                        {
                            netVoltages[net] = net.NetVoltage;
                            net.NetVoltage   = 0;
                        }
                        for (int j = 0; j < VariableValues.Count; j++)
                        {
                            VariableValues[j] = 0;
                        }
                        Solve(tol, maxIter, false);
                        TransientSolver rampSolver = new TransientSolver(this);
                        int             ticks;
                        ticks = rampSolver.RampUp(netVoltages);
                        for (int j = 0; j < VariableValues.Count; j++)
                        {
                            VariableValues[j] = rampSolver.GetVarValue(j, ticks - 1);
                        }
                    }
                }
                else
                {
                    Console.WriteLine("WARNING: DC Ramp analysis OP failed to converge (error=" + worstTol + ")");
                    return(false);
                }
            }
            return(true);
        }