Esempio n. 1
0
        void CalculateLoadFlowForSubGraph(Node source, List <KeyValuePair <long, LoadFlowResult> > result)
        {
            Dictionary <long, LoadFlowResult> lf = new Dictionary <long, LoadFlowResult>();

            EnergySource es = source.IO as EnergySource;

            if (es == null)
            {
                return;
            }

            Complex u1 = GetVoltageFromEnergySource(es);

            if (u1.IsNaN())
            {
                return;
            }

            Dictionary <long, Complex> currents = new Dictionary <long, Complex>();

            for (int iteration = 0; iteration < maxIterations; ++iteration)
            {
                double maxVoltageRelativeDelta = 0;

                Stack <Triple <Node, int, List <Complex> > > stack = new Stack <Triple <Node, int, List <Complex> > >();
                stack.Push(new Triple <Node, int, List <Complex> >(source, 0, new List <Complex>(source.AdjacentCount - 1)));

                HashSet <long> visited = new HashSet <long>();

                while (stack.Count > 0)
                {
                    Triple <Node, int, List <Complex> > triple = stack.Pop();
                    Node node        = triple.First;
                    int  childrenPos = triple.Second;
                    Func <Node, IEnumerable <Complex>, Dictionary <long, LoadFlowResult>, Complex> currentFunction = CalculateCurrentDefault;

                    visited.Add(node.IO.GID);
                    DMSType type = ModelCodeHelper.GetTypeFromGID(node.IO.GID);

                    switch (type)
                    {
                    case DMSType.Recloser:
                        continue;

                    case DMSType.ConnectivityNode:
                    {
                        LoadFlowResult lfr;

                        if (!lf.TryGetValue(node.IO.GID, out lfr))
                        {
                            lfr = new LoadFlowResult();
                            lfr.Add(new LoadFlowResultItem(u1.X, LoadFlowResultType.UR));
                            lfr.Add(new LoadFlowResultItem(u1.Y, LoadFlowResultType.UI));
                            lf[node.IO.GID] = lfr;
                        }
                    }
                    break;

                    case DMSType.EnergyConsumer:
                    {
                        currentFunction = CalculateCurrentForEnergyConsumer;

                        LoadFlowResult lfr;

                        if (!lf.TryGetValue(node.IO.GID, out lfr))
                        {
                            Complex s = GetPowerForEnergyConsumer(node.IO as EnergyConsumer);

                            lfr = new LoadFlowResult();
                            lfr.Add(new LoadFlowResultItem(s.X, LoadFlowResultType.SR));
                            lfr.Add(new LoadFlowResultItem(s.Y, LoadFlowResultType.SI));
                            lf[node.IO.GID] = lfr;
                        }
                    }
                    break;

                    case DMSType.Breaker:
                    case DMSType.Disconnector:
                    {
                        currentFunction = CalculateCurrentForSwitch;

                        if (childrenPos == 0)
                        {
                            double maxDelta = CalculateVoltageForSwitch(node, lf, currents);

                            if (maxDelta > maxVoltageRelativeDelta)
                            {
                                maxVoltageRelativeDelta = maxDelta;
                            }
                        }
                    }
                    break;

                    case DMSType.DistributionGenerator:
                    {
                        currentFunction = CalculateCurrentForDistributionGenerator;
                    }
                    break;

                    case DMSType.TransformerWinding:
                    {
                        currentFunction = CalculateCurrentForTransformerWinding;

                        if (childrenPos == 0)
                        {
                            double maxDelta = CalculateVoltageForTransformerWinding(node, lf, currents);

                            if (maxDelta > maxVoltageRelativeDelta)
                            {
                                maxVoltageRelativeDelta = maxDelta;
                            }
                        }
                    }
                    break;

                    case DMSType.ACLineSegment:
                    {
                        currentFunction = CalculateCurrentForACLineSegment;

                        if (childrenPos == 0)
                        {
                            double maxDelta = CalculateVoltageForACLineSegment(node, lf, currents);

                            if (maxDelta > maxVoltageRelativeDelta)
                            {
                                maxVoltageRelativeDelta = maxDelta;
                            }
                        }
                    }
                    break;
                    }

                    Node childNode = null;

                    for (int i = node.AdjacentOffset + childrenPos; i < node.AdjacentOffset + node.AdjacentCount; ++i)
                    {
                        Node adjacentNode = adjacency[i];

                        if (adjacentNode == null || visited.Contains(adjacentNode.IO.GID))
                        {
                            continue;
                        }

                        childNode = adjacentNode;
                        break;
                    }

                    if (childNode != null)
                    {
                        stack.Push(new Triple <Node, int, List <Complex> >(node, childrenPos + 1, triple.Third));
                        stack.Push(new Triple <Node, int, List <Complex> >(childNode, 0, new List <Complex>(childNode.AdjacentCount - 1)));
                        continue;
                    }

                    if (stack.Count > 0)
                    {
                        Complex current = currentFunction(node, triple.Third, lf);
                        stack.Peek().Third.Add(current);
                        currents[node.IO.GID] = current;
                    }
                }

                if (maxVoltageRelativeDelta < voltageRelativeDelta)
                {
                    break;
                }
            }

            result.AddRange(lf);
        }