/*
* Copyright (C) 2016 Vyacheslav Shevelyov (slavash at aha dot ru)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
using IStation.Epanet.Enums;
using IStation.Epanet.Network.Structures;
namespace IStation.Epanet.Network
{
///Hydraulic network structure.
public sealed class Network
{
private readonly List _controls = new List();
private readonly ElementCollection _curves = new ElementCollection();
[NonSerialized]
private readonly FieldsMap _fields = new FieldsMap();
private readonly List _labels = new List();
private readonly ElementCollection _links = new ElementCollection ();
private readonly ElementCollection _nodes = new ElementCollection();
private readonly ElementCollection _patterns = new ElementCollection();
private readonly ElementCollection _rules = new ElementCollection();
public Network()
{
LoadDefaults();
}
public IList Controls => _controls;
public Curve GetCurve(string name) { return _curves[name]; }
public IList Curves => _curves;
///Fields map with report variables properties and conversion units.
public FieldsMap FieldsMap => _fields;
///Transient colleciton of junctions.
public IEnumerable Junctions
{
get { return _nodes.Where(x => x.NodeType == NodeType.Junction); }
}
public IList Labels => _labels;
public Link GetLink(string name) => _links[name];
public IList Links => _links;
public IEnumerable Pipes => _links.Where(x => x.LinkType == LinkType.Pipe).Cast();
public Node GetNode(string name) => _nodes[name];
public IList Nodes => _nodes;
public Pattern GetPattern(string name) => _patterns[name];
public IList Patterns => _patterns;
///Transient colleciton of pumps.
public IEnumerable Pumps
{
get { return _links.Where(x => x.LinkType == LinkType.Pump).Cast(); }
}
public Rule GetRule(string name) => _rules[name];
public IList Rules => _rules;
public IEnumerable Tanks
{
get { return _nodes.Where(x => x.NodeType == NodeType.Tank).Cast(); }
}
public IEnumerable Reservoirs
{
get { return _nodes.Where(x => x.NodeType == NodeType.Reservoir).Cast(); }
}
public List Title { get; } = new List();
///Transient colleciton of valves.
public IEnumerable Valves => _links.OfType();
#region properties map
private Dictionary _extraOptions;
#region properties accessors/mutators
public string AltReport { get; set; }
/// Bulk flow reaction order
public double BulkOrder { get; set; }
/// Hydraulics solver parameter.
public int CheckFreq { get; set; }
/// Name of chemical.
public string ChemName { get; set; }
/// Units of chemical.
public string ChemUnits { get; set; }
/// Limiting potential quality.
public double CLimit { get; set; }
/// Water quality tolerance.
public double Ctol { get; set; }
/// Solution damping threshold.
public double DampLimit { get; set; }
/// Energy demand charge/kw/day.
public double DCost { get; set; }
/// Default demand pattern ID.
public string DefPatId { get; set; }
/// Diffusivity (sq ft/sec).
public double Diffus { get; set; }
/// Demand multiplier.
public double DMult { get; set; }
/// Duration of simulation (sec).
public TimeSpan Duration { get; set; }
/// Base energy cost per kwh.
public double ECost { get; set; }
/// Peak energy usage.
public double EMax { get; set; }
/// Energy report flag.
public bool EnergyFlag { get; set; }
/// Energy cost time pattern.
public string EPatId { get; set; }
/// Global pump efficiency.
public double EPump { get; set; }
/// Extra hydraulic trials.
public int ExtraIter { get; set; }
/// Flow units flag.
public FlowUnitsType FlowFlag { get; set; }
/// Hydraulic formula flag.
public HeadLossFormulaType FormFlag { get; set; }
/// Hydraulics solution accuracy.
public double HAcc { get; set; }
/// Exponent in headloss formula.
public double HExp { get; set; }
/// Nominal hyd. time step (sec).
public TimeSpan HStep { get; set; }
/// Hydraulic head tolerance.
public double HTol { get; set; }
/// Hydraulics flag.
public HydType HydFlag { get; set; }
/// Hydraulics file name.
public string HydFname { get; set; }
/// Global bulk reaction coeff.
public double KBulk { get; set; }
/// Global wall reaction coeff.
public double KWall { get; set; }
/// Link report flag.
public ReportFlag LinkFlag { get; set; }
/// Map file name.
public string MapFname { get; set; }
/// Hydraulics solver parameter.
public int MaxCheck { get; set; }
/// Max. hydraulic trials.
public int MaxIter { get; set; }
/// Error/warning message flag.
public bool MessageFlag { get; set; }
/// Node report flag.
public ReportFlag NodeFlag { get; set; }
/// Lines/page in output report.
public int PageSize { get; set; }
/// Pressure units flag.
public PressUnitsType PressFlag { get; set; }
/// Starting pattern time (sec).
public TimeSpan PStart { get; set; }
/// Time pattern time step (sec).
public TimeSpan PStep { get; set; }
/// Exponent in orifice formula.
public double QExp { get; set; }
/// Quality time step (sec).
public TimeSpan QStep { get; set; }
/// Flow rate tolerance.
public double QTol { get; set; }
/// Water quality flag.
public QualType QualFlag { get; set; }
/// Roughness-reaction factor.
public double RFactor { get; set; }
/// Flow resistance tolerance.
public double RQtol { get; set; }
/// Time when reporting starts.
public TimeSpan RStart { get; set; }
/// Reporting time step (sec).
public TimeSpan RStep { get; set; }
/// Rule evaluation time step.
public TimeSpan RuleStep { get; set; }
/// Specific gravity.
public double SpGrav { get; set; }
/// Status report flag.
public StatusLevel StatFlag { get; set; }
/// Report summary flag.
public bool SummaryFlag { get; set; }
/// Tank reaction order.
public double TankOrder { get; set; }
/// Source node for flow tracing.
public string TraceNode { get; set; }
/// Starting time of day (sec).
public TimeSpan Tstart { get; set; }
/// Time statistics flag.
public TstatType TstatFlag { get; set; }
/// Unit system flag.
public UnitsType UnitsFlag { get; set; }
/// Kin. viscosity (sq ft/sec).
public double Viscos { get; set; }
/// Pipe wall reaction order.
public double WallOrder { get; set; }
#endregion
public Dictionary ExtraOptions => _extraOptions
?? (_extraOptions = new Dictionary(StringComparer.OrdinalIgnoreCase));
public bool AutoLength { get; set; }
/// Init properties with default value.
private void LoadDefaults()
{
BulkOrder = 1.0d; // 1st-order bulk reaction rate
TankOrder = 1.0d; // 1st-order tank reaction rate
WallOrder = 1.0d; // 1st-order wall reaction rate
RFactor = 1.0d; // No roughness-reaction factor
CLimit = 0.0d; // No limiting potential quality
KBulk = 0.0d; // No global bulk reaction
KWall = 0.0d; // No global wall reaction
DCost = 0.0d; // Zero energy demand charge
ECost = 0.0d; // Zero unit energy cost
EPatId = string.Empty; // No energy price pattern
EPump = Constants.EPUMP; // Default pump efficiency
PageSize = Constants.PAGESIZE;
StatFlag = StatusLevel.None;
SummaryFlag = true;
MessageFlag = true;
EnergyFlag = false;
NodeFlag = ReportFlag.FALSE;
LinkFlag = ReportFlag.FALSE;
TstatFlag = TstatType.None; // Generate time series output
HStep = new TimeSpan(TimeSpan.TicksPerHour); // 1 hr hydraulic time step
Duration = TimeSpan.Zero; // 0 sec duration (steady state)
QStep = TimeSpan.Zero; // No pre-set quality time step
RuleStep = TimeSpan.Zero; // No pre-set rule time step
PStep = TimeSpan.FromHours(1); // 1 hr time pattern period
PStart = TimeSpan.Zero; // Starting pattern period
RStep = TimeSpan.FromHours(1); // 1 hr reporting period
RStart = TimeSpan.Zero; // Start reporting at time 0
Tstart = TimeSpan.Zero; // Starting time of day
FlowFlag = FlowUnitsType.Gpm; // Flow units are gpm
PressFlag = PressUnitsType.PSI; // Pressure units are psi
FormFlag = HeadLossFormulaType.HW; // Use Hazen-Williams formula
HydFlag = HydType.SCRATCH; // No external hydraulics file
QualFlag = QualType.None; // No quality simulation
UnitsFlag = UnitsType.US; // US unit system
HydFname = "";
ChemName = Keywords.t_CHEMICAL;
ChemUnits = Keywords.u_MGperL; // mg/L
DefPatId = Constants.DEFPATID; // Default demand pattern index
MapFname = "";
AltReport = "";
TraceNode = ""; // No source tracing
ExtraIter = -1; // Stop if network unbalanced
Ctol = double.NaN; // No pre-set quality tolerance
Diffus = double.NaN; // Temporary diffusivity
DampLimit = Constants.DAMPLIMIT;
Viscos = double.NaN; // Temporary viscosity
SpGrav = Constants.SPGRAV; // Default specific gravity
MaxIter = Constants.MAXITER; // Default max. hydraulic trials
HAcc = Constants.HACC; // Default hydraulic accuracy
HTol = Constants.HTOL; // Default head tolerance
QTol = Constants.QTOL; // Default flow tolerance
RQtol = Constants.RQTOL; // Default hydraulics parameters
HExp = 0.0d;
QExp = 2.0d; // Flow exponent for emitters
CheckFreq = Constants.CHECKFREQ;
MaxCheck = Constants.MAXCHECK;
DMult = 1.0d; // Demand multiplier
EMax = 0.0d; // Zero peak energy usage
}
#endregion
public override string ToString()
{
return new System.Text.StringBuilder(0x200)
.AppendLine(" Network")
.Append(" Nodes : ").Append(_nodes.Count).AppendLine()
.Append(" Links : ").Append(_links.Count).AppendLine()
.Append(" Pattern : ").Append(_patterns.Count).AppendLine()
.Append(" Curves : ").Append(_curves.Count).AppendLine()
.Append(" Controls : ").Append(_controls.Count).AppendLine()
.Append(" Labels : ").Append(_labels.Count).AppendLine()
.Append(" Rules : ").Append(_rules.Count).AppendLine()
.Append(" Tanks : ").Append(Tanks.Count()).AppendLine()
.Append(" Reservoirs : ").Append(Reservoirs.Count()).AppendLine()
.Append(" Pumps : ").Append(Pumps.Count()).AppendLine()
.Append(" Valves : ").Append(Valves.Count()).AppendLine()
.ToString();
}
}
}