예제 #1
0
        public List <string> Solve()
        {
            List <string> output = new List <string>();

            foreach (var element in outputCurrent)
            {
                output.Add($"Current [id={element}] =");
            }
            foreach (var element in outputNodeVoltage)
            {
                ElementsAC.Element el = acGraph.elements[element];
                if (el is ElementsAC.Element2N)
                {
                    output.Add($"Voltage difference [id={element}] =");
                }
            }
            foreach (var nodePair in outputVoltageDifference)
            {
                output.Add($"Voltage difference [n1={nodeLabels[nodePair.node1]}, n2={nodeLabels[nodePair.node2]}] =");
            }
            //Решение
            //Решение схемы с источниками разных частот является композицией
            //множества решений схемы для источников отдельных частот
            foreach (float frequency in frequencies)
            {
                float           hz          = (float)(frequency);
                ACGraphSolution solution    = acGraph.SolveEquationsAC(frequency);
                int             outputIndex = 0;
                foreach (var element in outputCurrent)
                {
                    Complex32 current = solution.currents[element];
                    output[outputIndex++] += ($" [{hz} Hz]({current.Magnitude}@{MathUtils.MathUtils.Degrees(current.Phase)})");
                }
                foreach (var element in outputNodeVoltage)
                {
                    ElementsAC.Element el = acGraph.elements[element];
                    if (el is ElementsAC.Element2N)
                    {
                        Complex32 voltageDrop = solution.voltageDrops[element];
                        output[outputIndex++] += ($" [{hz} Hz]({voltageDrop.Magnitude}@{MathUtils.MathUtils.Degrees(voltageDrop.Phase)})");
                    }
                }
                foreach (var nodePair in outputVoltageDifference)
                {
                    Complex32 diff = solution.voltages[nodePair.node2] - solution.voltages[nodePair.node1];
                    output[outputIndex++] += ($" [{hz} Hz]({diff.Magnitude}@{MathUtils.MathUtils.Degrees(diff.Phase)})");
                }
            }
            return(output);
        }
        public ACGraphSolution SolveEquationsAC(float frequency)
        {
            string equations = EquationGeneration(frequency);
            //create solver
            Compiler compiler = new Compiler();
            NonlinearEquationDescription compiledEquation = compiler.CompileEquations(equations);

            MathUtils.NonlinearSystemSymbolicAnalytic system = new MathUtils.NonlinearSystemSymbolicAnalytic(compiledEquation);
            //calc solution
            Vector <double> values = MathUtils.NewtonRaphsonSolver.Solve(
                system,
                Vector <double> .Build.DenseOfArray(compiledEquation.InitialValues),
                25,
                0.005,
                1.0
                );
            NonlinearSystemSolution solution = compiledEquation.GetSolution(values);

            ACGraphSolution acSolution = new ACGraphSolution();

            acSolution.frequency = frequency;

            for (int i = 0; i < nodesList.Count; i++)
            {
                var real = $"v_{i}_re";
                var im   = $"v_{i}_im";
                acSolution.voltages.Add(new Complex32((float)solution.GetValue(real),
                                                      (float)solution.GetValue(im)));
            }
            foreach (var element in elements)
            {
                acSolution.currents.Add(element.GetCurrent(solution, frequency));
                acSolution.voltageDrops.Add(element.GetVoltageDrop(solution));
            }
            return(acSolution);

            /*for (int i = 0; i < elements.Count; i++)
             * {
             *  ElementsAC.Element element = elements[i];
             *  switch (element.ElementType)
             *  {
             *      case ElementsAC.ElementTypeEnum.Capacitor:
             *          {
             *              Complex32 voltageDrop = solution.voltages[element.nodes[1]] - solution.voltages[element.nodes[0]];
             *              Complex32 current = voltageDrop * new Complex32(0.0f, frequency * ((ElementsAC.Capacitor)element).capacity);
             *              solution.currents.Add(current);
             *              break;
             *          }
             *      case ElementsAC.ElementTypeEnum.Resistor:
             *          {
             *              Complex32 voltageDrop = solution.voltages[element.nodes[1]] - solution.voltages[element.nodes[0]];
             *              solution.currents.Add(voltageDrop / ((ElementsAC.Resistor)element).resistance);
             *              break;
             *          }
             *      case ElementsAC.ElementTypeEnum.CurrentSource:
             *          ElementsAC.CurrentSource csel = (ElementsAC.CurrentSource)element;
             *          solution.currents.Add(Complex32.FromPolarCoordinates(csel.current, csel.phase));
             *          break;
             *      case ElementsAC.ElementTypeEnum.Transformer2w:
             *          solution.currents.Add(0.0f);
             *          break;
             *      case ElementsAC.ElementTypeEnum.Inductor:
             *      case ElementsAC.ElementTypeEnum.Ground:
             *      case ElementsAC.ElementTypeEnum.Line:
             *      case ElementsAC.ElementTypeEnum.VoltageSource:
             *          solution.currents.Add(0.0f);//Пропуск значений, поскольку данные токи присутствуют в векторе решения
             *          break;
             *  }
             * }*/
        }