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); }
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); }