using IStation.Epanet.Enums; using IStation.Epanet.Network.Structures; using System; using System.Collections.Generic; using System.Diagnostics; namespace IStation.Epanet.Network { ///Units report properties & conversion support class public class FieldsMap { ///Report fields properties. private readonly Dictionary _fields = new Dictionary(); ///Fields units values. private readonly Dictionary _units = new Dictionary(); ///Init fields default configuration public FieldsMap() { try { foreach (FieldType type in Enum.GetValues(typeof(FieldType))) _fields[type] = new Field(type); GetField(FieldType.FRICTION).Precision = 3; for (var i = FieldType.DEMAND; i <= FieldType.QUALITY; i++) GetField(i).Enabled = true; for (var i = FieldType.FLOW; i <= FieldType.HEADLOSS; i++) GetField(i).Enabled = true; } catch (EnException e) { Debug.Print(e.ToString()); } } ///Get report field properties from type. /// Field type. /// Report field. /// /// Throws /// If specified type not found. /// public Field GetField(FieldType fieldType) { if (!_fields.TryGetValue(fieldType, out Field value)) throw new EnException(ErrorCode.Err201, fieldType.ParseStr()); return value; } ///Get conversion value from field type. /// Field type. /// Conversion units value (from user units to system units). /// /// Throws If specified type not found. /// public double GetUnits(FieldType fieldType) { if (!_units.TryGetValue(fieldType, out double value)) throw new EnException(ErrorCode.Err201, fieldType.ParseStr()); return value; } ///Update fields and units, after loading the INP. public void Prepare( UnitsType targetUnits, FlowUnitsType flowFlag, PressUnitsType pressFlag, QualType qualFlag, string chemUnits, double spGrav, TimeSpan hstep) { double dcf, ccf, qcf, hcf, pcf, wcf; if (targetUnits == UnitsType.SI) { GetField(FieldType.DEMAND).Units = flowFlag.ToString(); GetField(FieldType.ELEV).Units = Keywords.u_METERS; GetField(FieldType.HEAD).Units = Keywords.u_METERS; GetField(FieldType.PRESSURE).Units = pressFlag == PressUnitsType.METERS ? Keywords.u_METERS : Keywords.u_KPA; GetField(FieldType.LENGTH).Units = Keywords.u_METERS; GetField(FieldType.DIAM).Units = Keywords.u_MMETERS; GetField(FieldType.FLOW).Units = flowFlag.ToString(); GetField(FieldType.VELOCITY).Units = Keywords.u_MperSEC; GetField(FieldType.HEADLOSS).Units = "m" + Keywords.u_per1000M; GetField(FieldType.FRICTION).Units = ""; GetField(FieldType.POWER).Units = Keywords.u_KW; dcf = 1000.0 * Constants.MperFT; qcf = Constants.LPSperCFS; switch (flowFlag) { case FlowUnitsType.Lpm: qcf = Constants.LPMperCFS; break; case FlowUnitsType.Mld: qcf = Constants.MLDperCFS; break; case FlowUnitsType.Cmh: qcf = Constants.CMHperCFS; break; case FlowUnitsType.Cmd: qcf = Constants.CMDperCFS; break; } hcf = Constants.MperFT; if (pressFlag == PressUnitsType.METERS) pcf = Constants.MperFT * spGrav; else pcf = Constants.KPAperPSI * Constants.PSIperFT * spGrav; wcf = Constants.KWperHP; } else { GetField(FieldType.DEMAND).Units = flowFlag.ToString(); GetField(FieldType.ELEV).Units = Keywords.u_FEET; GetField(FieldType.HEAD).Units = Keywords.u_FEET; GetField(FieldType.PRESSURE).Units = Keywords.u_PSI; GetField(FieldType.LENGTH).Units = Keywords.u_FEET; GetField(FieldType.DIAM).Units = Keywords.u_INCHES; GetField(FieldType.FLOW).Units = flowFlag.ToString(); GetField(FieldType.VELOCITY).Units = Keywords.u_FTperSEC; GetField(FieldType.HEADLOSS).Units = "ft" + Keywords.u_per1000FT; GetField(FieldType.FRICTION).Units = ""; GetField(FieldType.POWER).Units = Keywords.u_HP; dcf = 12.0; qcf = 1.0; switch (flowFlag) { case FlowUnitsType.Gpm: qcf = Constants.GPMperCFS; break; case FlowUnitsType.Mgd: qcf = Constants.MGDperCFS; break; case FlowUnitsType.Imgd: qcf = Constants.IMGDperCFS; break; case FlowUnitsType.Afd: qcf = Constants.AFDperCFS; break; } hcf = 1.0; pcf = Constants.PSIperFT * spGrav; wcf = 1.0; } GetField(FieldType.QUALITY).Units = ""; ccf = 1.0; switch (qualFlag) { case QualType.Chem: ccf = 1.0 / Constants.LperFT3; GetField(FieldType.QUALITY).Units = chemUnits; GetField(FieldType.REACTRATE).Units = chemUnits + Keywords.t_PERDAY; break; case QualType.Age: GetField(FieldType.QUALITY).Units = Keywords.u_HOURS; break; case QualType.Trace: GetField(FieldType.QUALITY).Units = Keywords.u_PERCENT; break; } SetUnits(FieldType.DEMAND, qcf); SetUnits(FieldType.ELEV, hcf); SetUnits(FieldType.HEAD, hcf); SetUnits(FieldType.PRESSURE, pcf); SetUnits(FieldType.QUALITY, ccf); SetUnits(FieldType.LENGTH, hcf); SetUnits(FieldType.DIAM, dcf); SetUnits(FieldType.FLOW, qcf); SetUnits(FieldType.VELOCITY, hcf); SetUnits(FieldType.HEADLOSS, hcf); SetUnits(FieldType.LINKQUAL, ccf); SetUnits(FieldType.REACTRATE, ccf); SetUnits(FieldType.FRICTION, 1.0); SetUnits(FieldType.POWER, wcf); SetUnits(FieldType.VOLUME, hcf * hcf * hcf); if (hstep.TotalSeconds < 1800) { SetUnits(FieldType.TIME, 1.0 / 60.0); GetField(FieldType.TIME).Units = Keywords.u_MINUTES; } else { SetUnits(FieldType.TIME, 1.0 / 3600.0); GetField(FieldType.TIME).Units = Keywords.u_HOURS; } } /// Revert system units to user units. /// Field type. /// Value to be converted. /// Value in user units. public double RevertUnit(FieldType fieldType, double value) { return fieldType == (FieldType)(-1) ? value : value * GetUnits(fieldType); } public double ConvertUnitToSystem(FieldType fieldType, double value) { return value / GetUnits(fieldType); } ///Set conversion value from field type. /// Field type. /// Field value. private void SetUnits(FieldType fieldType, double value) { _units[fieldType] = value; } } }