Example #1
0
        CalcSubnets <TID>(

            Edge[] edges, Node <TID>[] nodes, List <int[]> subnets,
            Dictionary <int, PipeNetCalc.WellInfo <TID> > nodeWell,
            Func <int, StreamWriter> GetTgfStream = null,
            Func <int, string> GetTgfNodeName     = null
            )
            where TID : struct
        {
#if DEBUG
            var parOpts = new ParallelOptions()
            {
                MaxDegreeOfParallelism = 1
            };
#else
            var parOpts = new ParallelOptions()
            {
                MaxDegreeOfParallelism = 5
            };
#endif

            var edgesRecs = new HydrCalcDataRec <TID> [edges.Length];
            PressureDrop.StepHandler stepHandler = (pos, gd, ctx, cookie) =>
            {
                if (pos != 0 && pos != 1d)
                {
                    return;
                }

                int direction = Math.Sign(cookie);
                int iEdge     = cookie * direction - 1;

                var r = edgesRecs[iEdge];

                if (direction > 0 ^ pos == 1d)
                {
                    r.From.Fill(ctx, gd, direction);
                }
                else
                {
                    r.To.Fill(ctx, gd, direction);
                }
            };

            var calcTime = DateTime.UtcNow;

            Parallel.ForEach(Enumerable.Range(0, subnets.Count), parOpts, iSubnet =>
            {
                int[] subnetEdges = subnets[iSubnet];
                if (subnetEdges.Length == 0)
                {
                    return;
                }

                foreach (var iEdge in subnetEdges)
                {
                    var r = new HydrCalcDataRec <TID>()
                    {
                        Calc_Time = calcTime, Subnet_Number = iSubnet,
                    };
                    r.From.Measure   = 0;
                    r.To.Measure     = edges[iEdge].L;
                    edgesRecs[iEdge] = r;
                }

                var(edgeI, nodeI) = PipeNetCalc.Calc(edges, nodes, subnetEdges, nodeWell, stepHandler);

                if (edgeI.Count == 0 && nodeI.Count == 0)
                {
                    return;
                }

                foreach (var p in edgeI)
                {
                    int iEdge = p.Key;
                    var r     = edgesRecs[iEdge];
                    var e     = edges[iEdge];
                    var P0    = nodeI.TryGetValue(e.iNodeA, out var N0) ? N0.nodeP : double.NaN;
                    var P1    = nodeI.TryGetValue(e.iNodeB, out var N1) ? N1.nodeP : double.NaN;

                    r.Fill(p.Value.fluid, P0, P1);
                }

                if (GetTgfStream != null)
                {
                    using (var tw = GetTgfStream(iSubnet))
                        PipeNetCalc.ExportTGF <TID>(tw, edges, nodes, subnetEdges,
                                                    iNode => GetTgfNodeName?.Invoke(iNode),
                                                    iNode => nodeI.TryGetValue(iNode, out var I) ? FormattableString.Invariant($" P={I.nodeP:0.###}") : null,
                                                    iEdge => edgeI.TryGetValue(iEdge, out var I) ? FormattableString.Invariant($" Q={I.edgeQ:0.#}") : null
                                                    );
                }
            });

            return(edgesRecs);
        }
Example #2
0
        CalcSubnets(

            Edge[] edges, Node[] nodes, List <int[]> subnets,
            Dictionary <int, NetCalc.WellInfo> nodeWell,
            Func <int, StreamWriter> GetTgfStream = null,
            Func <int, string> GetTgfNodeName     = null
            )
        {
#if DEBUG
            var parOpts = new ParallelOptions()
            {
                MaxDegreeOfParallelism = 1
            };
#else
            var parOpts = new ParallelOptions()
            {
                MaxDegreeOfParallelism = 5
            };
#endif

            var edgesRecs = new HydrCalcDataRec[edges.Length];

            PressureDrop.StepHandler stepHandler = (pos, gd, ctx, cookie) =>
            {
                if (pos == 0 || pos == 1d)
                {
                    var(iEdge, reversedEdge, reversedCalc) = NetCalc.DecodeCalcCookie(cookie);
                    int edgeDirection = reversedEdge ? -1 : +1;
                    var r             = edgesRecs[iEdge];

                    int flowDirection = (reversedEdge ^ reversedCalc) ? -1 : +1;

                    if (edgeDirection > 0 ^ pos == 1d)
                    {
                        r.From.Fill(ctx, gd, flowDirection);
                        r.CalcStatus++;
                    }
                    else
                    {
                        r.To.Fill(ctx, gd, flowDirection);
                        r.CalcStatus++;
                    }
                }
                else if (pos == -1)
                {   // called from pressure drop calculation function before calculation
                    var(iEdge, reversedEdge, reversedCalc) = NetCalc.DecodeCalcCookie(cookie);
                    //int edgeDirection = reversedEdge ? -1 : +1;
                    int flowDirection = (reversedEdge ^ reversedCalc) ? -1 : +1;
                    var r             = edgesRecs[iEdge];

                    if (gd != null)
                    {
                        r.CalcStatus         = CalcStatus._Started;
                        r.OilVolumeRate_sc   = (float)gd.Q_oil_rate * flowDirection;
                        r.WaterVolumeRate_sc = (float)gd.Q_water_rate * flowDirection;
                        r.GasVolumeRate_sc   = (float)gd.Q_gas_rate * flowDirection;
                    }
                    else
                    {
                        r.CalcStatus       = CalcStatus.Failed;
                        r.OilVolumeRate_sc = r.WaterVolumeRate_sc = r.GasVolumeRate_sc = float.NaN;
                    }
                }
            };

            Parallel.ForEach(Enumerable.Range(0, subnets.Count), parOpts, iSubnet =>
            {
                int[] subnetEdges = subnets[iSubnet];
                if (subnetEdges.Length == 0)
                {
                    return;
                }

                foreach (var iEdge in subnetEdges)
                {
                    var r = new HydrCalcDataRec()
                    {
                        Subnet_Number = iSubnet,
                    };
                    r.From.Measure   = 0;
                    r.To.Measure     = edges[iEdge].L;
                    edgesRecs[iEdge] = r;
                }

                var(edgeI, nodeI) = NetCalc.Calc(edges, nodes, subnetEdges, nodeWell, stepHandler);

                if (edgeI.Count == 0 && nodeI.Count == 0)
                {
                    return;
                }

                foreach (var p in edgeI)
                {
                    int iEdge = p.Key;
                    var r     = edgesRecs[iEdge];
                    var e     = edges[iEdge];
                    var P0    = nodeI.TryGetValue(e.iNodeA, out var N0) ? N0.nodeP : double.NaN;
                    var P1    = nodeI.TryGetValue(e.iNodeB, out var N1) ? N1.nodeP : double.NaN;

                    r.Fill(p.Value.fluid, P0, P1);
                }

                if (GetTgfStream != null)
                {
                    var tw = GetTgfStream(iSubnet);
                    if (tw != null)
                    {
                        using (tw)
                            PipeGraph.ExportToTGF(tw, edges, nodes, subnetEdges,
                                                  iNode => GetTgfNodeName?.Invoke(iNode),
                                                  iNode => nodeI.TryGetValue(iNode, out var I) ? I.StrTGF() : null,
                                                  iEdge => edgeI.TryGetValue(iEdge, out var I) ? I.StrTGF() : null
                                                  );
                    }
                }
            });

            return(edgesRecs);
        }