/// <summary>Write simulation summary to one worksheet.</summary> /// <param name="inpFile">Hydraulic network file name.</param> /// <param name="net">Hydraulic network.</param> /// <param name="msxFile">MSX file.</param> /// <param name="msx">MSX solver.</param> public void WriteSummary(string inpFile, EpanetNetwork net, string msxFile, EpanetMSX msx) { var sh = _sheet.NewSpreadsheet("Summary"); try { FieldsMap fMap = net.FieldsMap; if (net.Title != null) { for (int i = 0; i < net.Title.Count && i < 3; i++) { if (!string.IsNullOrEmpty(net.Title[i])) { sh.AddData( net.Title[i].Length > 70 ? net.Title[i].Substring(0, 70) : net.Title[i]); } } } sh.AddData("\n"); sh.AddData(Text.FMT19, inpFile); sh.AddData(Text.FMT20, net.Junctions.Count()); int nReservoirs = net.Reservoirs.Count(); int nTanks = net.Tanks.Count(); int nValves = net.Valves.Count(); int nPumps = net.Pumps.Count(); int nPipes = net.Links.Count - nPumps - nValves; sh.AddData(Text.FMT21a, nReservoirs); sh.AddData(Text.FMT21b, nTanks); sh.AddData(Text.FMT22, nPipes); sh.AddData(Text.FMT23, nPumps); sh.AddData(Text.FMT24, nValves); sh.AddData(Text.FMT25, net.FormFlag.ParseStr()); sh.AddData(Text.FMT26, net.HStep.GetClockTime()); sh.AddData(Text.FMT27, net.HAcc); sh.AddData(Text.FMT27a, net.CheckFreq); sh.AddData(Text.FMT27b, net.MaxCheck); sh.AddData(Text.FMT27c, net.DampLimit); sh.AddData(Text.FMT28, net.MaxIter); switch (net.Duration == 0 ? QualType.NONE : net.QualFlag) { case QualType.NONE: sh.AddData(Text.FMT29, "None"); break; case QualType.CHEM: sh.AddData(Text.FMT30, net.ChemName); break; case QualType.TRACE: sh.AddData(Text.FMT31, "Trace From Node", net.GetNode(net.TraceNode).Name); break; case QualType.AGE: sh.AddData(Text.FMT32, "Age"); break; } if (net.QualFlag != QualType.NONE && net.Duration > 0) { sh.AddData(Text.FMT33, "Time Step", net.QStep.GetClockTime()); sh.AddData( Text.FMT34, "Tolerance", fMap.RevertUnit(FieldType.QUALITY, net.Ctol), fMap.GetField(FieldType.QUALITY).Units); } sh.AddData(Text.FMT36, net.SpGrav); sh.AddData(Text.FMT37a, net.Viscos / Constants.VISCOS); sh.AddData(Text.FMT37b, net.Diffus / Constants.DIFFUS); sh.AddData(Text.FMT38, net.DMult); sh.AddData( Text.FMT39, fMap.RevertUnit(FieldType.TIME, net.Duration), fMap.GetField(FieldType.TIME).Units); if (msxFile != null && msx != null) { sh.AddData(""); sh.AddData("MSX data file", msxFile); sh.AddData("Species"); Species[] spe = msx.Network.Species; for (int i = 1; i < msx.Network.Species.Length; i++) { sh.AddData(spe[i].Id, spe[i].Units); } } } catch (IOException) {} catch (ENException e) { Debug.Print(e.ToString()); } }
/// <summary>Report options dialog constructor.</summary> public ReportOptions(string inpFile, string msxFile) : this() { if (inpFile == null) { return; } _fileInp = inpFile; _net = new EpanetNetwork(); try { InputParser inpParser; string extension = Path.GetExtension(inpFile); switch (extension.ToLowerInvariant()) { case ".inp": inpParser = new InpParser(); break; case ".net": inpParser = new NetParser(); break; case ".xml": inpParser = new XmlParser(false); break; case ".gz": inpParser = new XmlParser(true); break; default: inpParser = new InpParser(); break; } _net = inpParser.Parse(new EpanetNetwork(), inpFile); } catch (ENException ex) { MessageBox.Show( ex.Message + "\nCheck epanet.log for detailed error description", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (msxFile == null) { return; } _fileMsx = msxFile; _epanetTk = new EnToolkit2(_net); _netMsx = new EpanetMSX(_epanetTk); try { ErrorCodeType ret = _netMsx.Load(_fileMsx); if (ret != 0) { MessageBox.Show("MSX parsing error " + ret, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); _fileMsx = null; _netMsx = null; _epanetTk = null; } } catch (IOException) { MessageBox.Show( "IO error while reading the MSX file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); _fileMsx = null; _netMsx = null; _epanetTk = null; } }
/// <summary>Generate multi-species quality report.</summary> /// <param name="msxBin">Name of the MSX simulation output file.</param> /// <param name="net">Hydraulic network.</param> /// <param name="netMsx">MSX network.</param> /// <param name="tk2">Hydraulic network - MSX bridge.</param> /// <param name="values">Species report flag.</param> public void CreateMsxReport(string msxBin, EpanetNetwork net, EpanetMSX netMsx, EnToolkit2 tk2, bool[] values) { Rtime = 0; var nodes = netMsx.Network.Node; var links = netMsx.Network.Link; string[] nSpecies = netMsx.GetSpeciesNames(); int reportCount = (int)((net.Duration - net.RStart) / net.RStep) + 1; var reader = new MsxReader( nodes.Length - 1, links.Length - 1, nSpecies.Length, netMsx.ResultsOffset); int totalSpecies = values == null ? nSpecies.Length : values.Count(b => b); reader.Open(msxBin); var nodesHead = new object[nSpecies.Length + 1]; nodesHead[0] = _sheet.TransposedMode ? "Node/Time" : "Time/Node"; var linksHead = new object[nSpecies.Length + 1]; linksHead[0] = _sheet.TransposedMode ? "Link/Time" : "Time/Link"; int count = 1; for (int i = 0; i < nSpecies.Length; i++) { if (values == null || values[i]) { nodesHead[count] = nSpecies[i]; linksHead[count++] = nSpecies[i]; } } var nodeRow = new object[totalSpecies + 1]; for (int i = 1; i < nodes.Length; i++) { if (!nodes[i].Rpt) { continue; } var spr = _sheet.NewSpreadsheet("Node<<" + tk2.ENgetnodeid(i) + ">>"); spr.AddHeader(nodesHead); for (long time = net.RStart, period = 0; time <= net.Duration; time += net.RStep, period++) { nodeRow[0] = time.GetClockTime(); for (int j = 0, ji = 0; j < nSpecies.Length; j++) { if (values == null || values[j]) { nodeRow[ji++ + 1] = reader.GetNodeQual((int)period, i, j + 1); } } spr.AddData(nodeRow); } } var linkRow = new object[totalSpecies + 1]; for (int i = 1; i < links.Length; i++) { if (!links[i].Rpt) { continue; } var spr = _sheet.NewSpreadsheet("Link<<" + tk2.ENgetlinkid(i) + ">>"); spr.AddHeader(linksHead); for (long time = net.RStart, period = 0; time <= net.Duration; time += net.RStep, period++) { linkRow[0] = time.GetClockTime(); for (int j = 0, ji = 0; j < nSpecies.Length; j++) { if (values == null || values[j]) { linkRow[ji++ + 1] = reader.GetLinkQual((int)period, i, j + 1); } } spr.AddData(linkRow); } } reader.Close(); }
private void RunSimulation(string fileName) { TraceListener simHandler = null; Simulated = true; _canselSimulation = false; progressBar.Value = 0; progressBar.Maximum = 100; progressBar.Minimum = 0; try { if (showHydraulicSolverEventsCheckBox.Checked) { string logFile = Path.Combine(Path.GetDirectoryName(fileName) ?? string.Empty, "hydEvents.log"); try { simHandler = new EpanetTraceListener(logFile, false); simHandler.TraceOutputOptions &= ~TraceOptions.DateTime; log.Listeners.Add(simHandler); } catch (IOException ex) { log.Error(ex); } } int reportPeriod = ((TimeStep)reportPeriodBox.SelectedItem).Time; int reportStartTime = (int)(Utilities.GetHour(textReportStart.Text) * 3600); int hydTStep = ((TimeStep)hydComboBox.SelectedItem).Time; int qualTStep = ((TimeStep)qualComboBox.SelectedItem).Time; int durationTime = (int)(Utilities.GetHour(textSimulationDuration.Text) * 3600); _net.RStart = reportStartTime; _net.RStep = reportPeriod; _net.HStep = hydTStep; _net.Duration = durationTime; _net.QStep = qualTStep; statusLabel.Text = "Simulating hydraulics"; try { _hydSim = new HydraulicSim(_net, log); RunThread( () => _hydSim.Simulate("hydFile.bin"), 10, 30, () => _hydSim.Htime, () => _hydSim.Htime / (double)_net.Duration); } catch (ENException ex) { if (ex.Code == ErrorCode.Err1000) { throw new ThreadInterruptedException(); } MessageBox.Show( ex.Message + "\nCheck epanet.log for detailed error description", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (_canselSimulation) { return; } if (_fileMsx != null && qualityMSXCheckBox.Checked) { statusLabel.Text = "Simulating MSX"; try { // reload MSX _netMsx = new EpanetMSX(_epanetTk); _netMsx.Load(_fileMsx); _netMsx.Network.Rstep = reportPeriod; _netMsx.Network.Qstep = qualTStep; _netMsx.Network.Rstart = reportStartTime; _netMsx.Network.Dur = durationTime; _epanetTk.Open("hydFile.bin"); RunThread( () => _netMsx.Run("msxFile.bin"), 30, 50, () => _netMsx.QTime, () => _netMsx.QTime / (double)_net.Duration); } catch (IOException) {} catch (ENException) { throw new ThreadInterruptedException(); } finally { _epanetTk.Close(); } // netMSX.getReport().MSXrpt_write(new "msxFile.bin"); } if (_canselSimulation) { return; } if (qualityCheckBox.Checked) { try { QualitySim qSim = new QualitySim(_net, log); statusLabel.Text = "Simulating Quality"; RunThread( () => qSim.Simulate("hydFile.bin", "qualFile.bin"), 30, 50, () => qSim.Qtime, () => qSim.Qtime / (double)_net.Duration); } catch (ENException ex) { MessageBox.Show( ex.Message + "\nCheck epanet.log for detailed error description", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (IOException e1) { Debug.Print(e1.ToString()); } } if (_canselSimulation) { return; } progressBar.Value = 50; statusLabel.Text = "Writting report"; _gen = new ReportGenerator(fileName); //log log.Information("Starting report write"); if (showSummaryCheckBox.Checked) { _gen.WriteSummary(_fileInp, _net, _fileMsx, _netMsx); } if (_canselSimulation) { return; } if (transposeResultsCheckBox.Checked) { _gen.TransposedMode = true; } if (hydraulicsCheckBox.Checked) { // Write hydraulic spreadsheets bool[] values = new bool[ReportGenerator.HydVariable.Values.Length]; for (int i = 0; i < ReportGenerator.HydVariable.Values.Length; i++) { values[i] = hydVariables.GetItemChecked(i); } statusLabel.Text = "Writing hydraulic report"; RunThread( () => _gen.CreateHydReport("hydFile.bin", _net, values), 50, 60, () => _gen.Rtime, () => (_gen.Rtime - _net.RStart) / (double)_net.Duration); } if (_canselSimulation) { return; } if (qualityCheckBox.Checked) { statusLabel.Text = "Writing quality report"; bool nodes = qualityVariables.GetItemChecked(0); bool links = qualityVariables.GetItemChecked(1); RunThread( () => _gen.CreateQualReport("qualFile.bin", _net, nodes, links), 60, 70, () => _gen.Rtime, () => (_gen.Rtime - _net.RStart) / (double)_net.Duration); } if (_canselSimulation) { return; } // Write MSX quality spreadsheets if (_fileMsx != null && qualityMSXCheckBox.Checked) { bool[] valuesMsx = new bool[speciesCheckList.Items.Count]; for (int i = 0; i < speciesCheckList.Items.Count; i++) { valuesMsx[i] = speciesCheckList.GetItemChecked(i); } _gen.CreateMsxReport( "msxFile.bin", _net, _netMsx, _epanetTk, valuesMsx); RunThread( () => _gen.CreateMsxReport( "msxFile.bin", _net, _netMsx, _epanetTk, valuesMsx), 70, 80, () => _netMsx.QTime, () => (_gen.Rtime - _net.RStart) / (double)_net.Duration); } if (_canselSimulation) { return; } statusLabel.Text = "Writing workbook"; _gen.WriteWorksheet(); log.Information("Ending report write"); } catch (ThreadInterruptedException) { log.Warning(0, "Simulation aborted!"); } finally { if (simHandler != null) { log.Listeners.Remove(simHandler); simHandler.Close(); } Simulated = false; } }