using IStation.Epanet.Enums;
|
using IStation.Epanet.Network.Structures;
|
using System.Diagnostics;
|
|
namespace IStation.Epanet.Network
|
{
|
|
///<summary>Units report properties & conversion support class</summary>
|
public class FieldsMap
|
{
|
///<summary>Report fields properties.</summary>
|
private readonly Dictionary<FieldType, Field> _fields = new Dictionary<FieldType, Field>();
|
///<summary>Fields units values.</summary>
|
private readonly Dictionary<FieldType, double> _units = new Dictionary<FieldType, double>();
|
|
///<summary>Init fields default configuration</summary>
|
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());
|
}
|
}
|
|
///<summary>Get report field properties from type.</summary>
|
/// <param name="fieldType">Field type.</param>
|
/// <returns>Report field.</returns>
|
/// <remarks>
|
/// Throws <see cref="EnException"/>
|
/// If specified type not found.
|
/// </remarks>
|
public Field GetField(FieldType fieldType)
|
{
|
if (!_fields.TryGetValue(fieldType, out Field value))
|
throw new EnException(ErrorCode.Err201, fieldType.ParseStr());
|
|
return value;
|
}
|
|
///<summary>Get conversion value from field type.</summary>
|
/// <param name="fieldType">Field type.</param>
|
/// <returns>Conversion units value (from user units to system units).</returns>
|
/// <remarks>
|
/// Throws <see cref="EnException"/> If specified type not found.
|
/// </remarks>
|
public double GetUnits(FieldType fieldType)
|
{
|
if (!_units.TryGetValue(fieldType, out double value))
|
throw new EnException(ErrorCode.Err201, fieldType.ParseStr());
|
|
return value;
|
}
|
|
///<summary>Update fields and units, after loading the INP.</summary>
|
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;
|
}
|
}
|
|
/// <summary>Revert system units to user units.</summary>
|
/// <param name="fieldType">Field type.</param>
|
/// <param name="value">Value to be converted.</param>
|
/// <returns>Value in user units.</returns>
|
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);
|
}
|
|
///<summary>Set conversion value from field type.</summary>
|
/// <param name="fieldType">Field type.</param>
|
/// <param name="value">Field value.</param>
|
private void SetUnits(FieldType fieldType, double value)
|
{
|
_units[fieldType] = value;
|
}
|
|
}
|
|
}
|