Exemplo n.º 1
0
            public void AddNet(Net net)
            {
                NetVariables[net] = nextFreeVariable;
                VariableValues.PopFirst().Add(0);
                VariableIdentifier id = new VariableIdentifier();

                id.net = net;
                VariableData[nextFreeVariable] = id;
                nextFreeVariable++;
            }
Exemplo n.º 2
0
 private void AddNet(Net net)
 {
     if (!net.IsFixedVoltage)
     {
         NetVariables[net] = nextFreeVariable;
         VariableValues.Add(0.1);
         VariableIdentifier id = new VariableIdentifier();
         id.type = VariableType.NET;
         id.net  = net;
         VariableData[nextFreeVariable] = id;
         nextFreeVariable++;
     }
 }
Exemplo n.º 3
0
        //Add components and nets to be included in the solver
        private void AddComponent(Component c)
        {
            //Due to Kirchoff's Laws, for a component with n pins we only need n-1 equations

            ComponentVariables[c] = nextFreeVariable;
            nextFreeVariable     += c.GetNumberOfPins() - 1;
            for (int i = 0; i < c.GetNumberOfPins() - 1; i++)
            {
                VariableValues.Add(0.1);
                VariableIdentifier id = new VariableIdentifier();
                id.type      = VariableType.COMPONENT;
                id.component = c;
                id.pin       = i;
                VariableData[ComponentVariables[c] + i] = id;
            }
        }
Exemplo n.º 4
0
 public virtual double TransientDerivative(TransientSolver solver, int f, VariableIdentifier var)
 {
     return(0.0d);
 }
Exemplo n.º 5
0
 /*
  * Evaluate the partial derivatives for the above functions
  */
 public virtual double DCDerivative(DCSolver solver, int f, VariableIdentifier var)
 {
     return(0.0d);
 }
Exemplo n.º 6
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);
        }