diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..a91e2e5b
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+[*.vb]
+tab_width = 4
+indent_size = 4
+end_of_line = crlf
+charset = utf-8
+trim_trailing_whitespace = true
+
+# IDE1006: Naming Styles
+dotnet_diagnostic.IDE1006.severity = none
diff --git a/BlueM.Opt.sln b/BlueM.Opt.sln
index 9e744783..b3ea9321 100644
--- a/BlueM.Opt.sln
+++ b/BlueM.Opt.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
-VisualStudioVersion = 18.6.11806.211 stable
+VisualStudioVersion = 18.6.11806.211
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BlueM.Opt.Algos", "BlueM.Opt.Algos", "{44D440EE-4641-44A1-B177-2DD0FDD6FB75}"
EndProject
@@ -38,6 +38,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BlueM.Opt.Tests", "BlueM.Op
EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "BlueM.Opt.Tests", "BlueM.Opt\Tests\BlueM.Opt.Tests\BlueM.Opt.Tests.vbproj", "{BBDDC177-F059-4139-9A0E-C4B7D03F2786}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5A9D3221-E48E-4A26-9F13-090359144136}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
diff --git a/BlueM.Opt/Apps/BlueM.Opt.Apps.vbproj b/BlueM.Opt/Apps/BlueM.Opt.Apps.vbproj
index dca74993..ebf6ea6b 100644
--- a/BlueM.Opt/Apps/BlueM.Opt.Apps.vbproj
+++ b/BlueM.Opt/Apps/BlueM.Opt.Apps.vbproj
@@ -117,9 +117,20 @@
+
+
+
+ TALSIM5_Dialog.vb
+
+
+ Form
+
+
+ Always
+
@@ -128,6 +139,9 @@
My.Resources
Designer
+
+ TALSIM5_Dialog.vb
+
@@ -192,6 +206,9 @@
+
+ 10.0.8
+
4.2023.4.18
diff --git a/BlueM.Opt/Apps/Sim.vb b/BlueM.Opt/Apps/Sim.vb
index 12ad8920..4f6affc4 100644
--- a/BlueM.Opt/Apps/Sim.vb
+++ b/BlueM.Opt/Apps/Sim.vb
@@ -534,7 +534,7 @@ Public MustInherit Class Sim
'ModellParameter aus OptParametern errechnen
'*******************************************
- Private Sub OptParameter_to_ModellParameter()
+ Protected Sub OptParameter_to_ModellParameter()
Dim i As Integer
Dim j As Integer
@@ -555,7 +555,7 @@ Public MustInherit Class Sim
'Die ModellParameter in die Eingabedateien des SimModells schreiben
'******************************************************************
- Public Sub Write_ModellParameter()
+ Public Overridable Sub Write_ModellParameter()
Dim WertStr As String
Dim AnzZeichen, AnzNachkomma As Short
diff --git a/BlueM.Opt/Apps/TALSIM/TALSIM.vb b/BlueM.Opt/Apps/TALSIM/TALSIM.vb
index 0518e887..21524a63 100644
--- a/BlueM.Opt/Apps/TALSIM/TALSIM.vb
+++ b/BlueM.Opt/Apps/TALSIM/TALSIM.vb
@@ -30,12 +30,12 @@ Public Class Talsim
#Region "Eigenschaften"
- Private exe_path As String
+ Private ReadOnly exe_path As String
'''
''' List of result file extensions to use (e.g. "WEL", "KTR.WEL", "CHLO.WEL", "WBL", etc.)
'''
- Private resultFiles As List(Of String)
+ Private ReadOnly resultFiles As List(Of String)
'**** Multithreading ****
Dim MyTalsimThreads() As TalsimThread
@@ -264,8 +264,9 @@ Public Class Talsim
Folder = getThreadWorkDir(Thread_ID)
MyTalsimThreads(Thread_ID) = New TalsimThread(Thread_ID, Child_ID, Folder, Datensatz)
- MyThreads(Thread_ID) = New Thread(AddressOf MyTalsimThreads(Thread_ID).launchSim)
- MyThreads(Thread_ID).IsBackground = True
+ MyThreads(Thread_ID) = New Thread(AddressOf MyTalsimThreads(Thread_ID).launchSim) With {
+ .IsBackground = True
+ }
MyThreads(Thread_ID).Start()
launchSim = True
@@ -325,12 +326,13 @@ Public Class Talsim
Dim errfile As String = IO.Path.Combine(Me.WorkDir_Current, Me.Datensatz & ".err")
Dim simendfile As String = IO.Path.Combine(Me.WorkDir_Current, Me.Datensatz & ".SIMEND")
Dim proc As Process
- Dim startInfo As New ProcessStartInfo()
- startInfo.FileName = Me.exe_path
- startInfo.Arguments = runfilename
- startInfo.UseShellExecute = True
- startInfo.WindowStyle = ProcessWindowStyle.Hidden
- startInfo.WorkingDirectory = IO.Path.GetDirectoryName(Me.exe_path)
+ Dim startInfo As New ProcessStartInfo With {
+ .FileName = Me.exe_path,
+ .Arguments = runfilename,
+ .UseShellExecute = True,
+ .WindowStyle = ProcessWindowStyle.Hidden,
+ .WorkingDirectory = IO.Path.GetDirectoryName(Me.exe_path)
+ }
'start
proc = Process.Start(startInfo)
'DEBUG: write to log
diff --git a/BlueM.Opt/Apps/TALSIM/TALSIM5.vb b/BlueM.Opt/Apps/TALSIM/TALSIM5.vb
new file mode 100644
index 00000000..6acbb0fe
--- /dev/null
+++ b/BlueM.Opt/Apps/TALSIM/TALSIM5.vb
@@ -0,0 +1,488 @@
+'BlueM.Opt
+'Copyright (C) BlueM Dev Group
+'Website:
+'
+'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 .
+'
+Imports System.Threading
+Imports System.Windows.Forms
+Imports BlueM.Opt.Common
+Imports Microsoft.Data.Sqlite
+
+'''
+''' Class TALSIM5 for carrying out simulations using TALSIM5 (same simulation executable but different dataset format than TALSIM4)
+'''
+'''
+Public Class Talsim5
+ Inherits Sim
+
+ Private ReadOnly exe_path As String
+ Private scenarioId As Integer
+ Private simulationId As Integer
+ Private timeseriesPath As String
+
+ '''
+ ''' List of result file extensions to use (e.g. "WEL", "KTR.WEL", "CHLO.WEL", "WBL", etc.)
+ '''
+ Private ReadOnly resultFiles As List(Of String)
+
+ '**** Multithreading ****
+ Dim MyTalsimThreads() As Talsim5Thread
+ Dim MyThreads() As Thread
+
+ '''
+ ''' Class to represent a scenario in a TALSIM5 database
+ '''
+ Friend Class Scenario
+ Public Id As Integer
+ Public Name As String
+ Public Overrides Function ToString() As String
+ Return $"{Id}: {Name}"
+ End Function
+ End Class
+
+ '''
+ ''' Class to represent a simulation in a Talsim5 database
+ '''
+ Friend Class Simulation
+ Public Id As Integer
+ Public Name As String
+ Public Overrides Function ToString() As String
+ Return $"{Id}: {Name}"
+ End Function
+ End Class
+
+ '''
+ ''' Alle Dateiendungen (ohne Punkt), die in einem Datensatz vorkommen können
+ '''
+ ''' Die erste Dateiendung in dieser Collection repräsentiert den Datensatz (wird z.B. als Filter für OpenFile-Dialoge verwendet)
+ Public Overrides ReadOnly Property DatensatzDateiendungen() As Collections.Specialized.StringCollection
+ Get
+ Dim exts As New Collections.Specialized.StringCollection()
+
+ exts.AddRange(New String() {"DB", "SCE", "QAB", "UPD", "VAR", "OPF", "ZIE", "PRO", "RFD", "ABZ"})
+
+ Return exts
+
+ End Get
+ End Property
+
+ '''
+ ''' Ob die Anwendung Multithreading unterstützt
+ '''
+ ''' True
+ Public Overrides ReadOnly Property MultithreadingSupported As Boolean = True
+
+ '''
+ ''' Path to the database file (in the current working directory)
+ '''
+ '''
+ Private ReadOnly Property DBFile As String
+ Get
+ Return IO.Path.Combine(Me.WorkDir_Current, Me.Datensatz & ".db")
+ End Get
+ End Property
+
+ 'Konstruktor
+ '***********
+ Public Sub New()
+
+ Call MyBase.New()
+
+ 'Daten belegen
+ '-------------
+ Me.resultFiles = New List(Of String)
+
+ 'Pfad zu talsimw64.exe bestimmen
+ '-------------------------------
+ 'attempt to get exe_path from UserSettings
+ exe_path = My.Settings.TALSIM_path
+
+ If (Not IO.File.Exists(exe_path)) Then
+ 'use default location instead
+ exe_path = IO.Path.Combine(System.Windows.Forms.Application.StartupPath(), "TALSIM\talsimw64.exe")
+ If My.Settings.TALSIM_path.Trim() <> "" Then
+ MsgBox($"UserSetting for TALSIM_path {My.Settings.TALSIM_path} was not found.{eol}Using default {exe_path} instead.", MsgBoxStyle.Information)
+ End If
+ End If
+
+ If (Not IO.File.Exists(exe_path)) Then
+ Throw New Exception(exe_path & " not found!")
+ End If
+
+ End Sub
+
+ '''
+ ''' TALSIM Simulationen vorbereiten
+ '''
+ Public Overrides Sub prepareSimulation()
+
+ Call MyBase.prepareSimulation()
+
+ 'Thread-Objekte instanzieren
+ Talsim5Thread.exe_path = Me.exe_path
+ ReDim MyTalsimThreads(n_Threads - 1)
+ For i = 0 To n_Threads - 1
+ MyTalsimThreads(i) = New Talsim5Thread(i, -1, "Folder", Datensatz, Me.scenarioId, Me.simulationId, Me.timeseriesPath)
+ MyTalsimThreads(i).set_is_OK()
+ Next
+ ReDim MyThreads(n_Threads - 1)
+
+ End Sub
+
+ Public Overrides Sub setProblem(ByRef prob As BlueM.Opt.Common.Problem)
+
+ Call MyBase.setProblem(prob)
+
+ 'TALSIM-spezifische Weiterverarbeitung von ZielReihen:
+ Dim objective As Common.ObjectiveFunction
+
+ 'Feststellen, welche WEL/WBL-Dateien in Zielfunktionen genutzt werden
+ For Each objective In Me.mProblem.List_ObjectiveFunctions
+ If Not IsNothing(objective.FileExtension) Then
+ Dim fileExtension As String = objective.FileExtension.ToUpper()
+ If Not Me.resultFiles.Contains(fileExtension) Then
+ Me.resultFiles.Add(fileExtension)
+ End If
+ End If
+ Next
+
+ 'Feststellen, welche WEL/WBL-Dateien in Constraints genutzt werden
+ For Each constr As Constraintfunction In Me.mProblem.List_Constraintfunctions
+ Dim fileExtension As String = constr.Datei.ToUpper()
+ If Not Me.resultFiles.Contains(fileExtension) Then
+ Me.resultFiles.Add(fileExtension)
+ End If
+ Next
+
+ End Sub
+
+ '''
+ ''' Simulationsparameter einlesen
+ '''
+ Protected Overrides Sub Read_SimParameter()
+
+ 'Show Talsim5 settings dialog
+ Dim dlg As New TALSIM5_Dialog(Me.DBFile)
+ If dlg.ShowDialog() <> DialogResult.OK Then
+ Throw New Exception("Talsim5 settings not set!")
+ End If
+ 'save settings from dialog
+ Me.scenarioId = dlg.SelectedScenario.Id
+ Me.simulationId = dlg.SelectedSimulation.Id
+ Me.timeseriesPath = dlg.TimeseriesPath
+
+ 'read simulation start and end from database
+ Using connection As New SqliteConnection($"Data Source={Me.DBFile}")
+ connection.Open()
+ Using command As SqliteCommand = connection.CreateCommand()
+ command.CommandText = "
+ SELECT SimulationStart, SimulationEnd, TimeStep
+ FROM Simulation
+ WHERE Id = @SimulationId
+ "
+ command.Parameters.AddWithValue("@SimulationId", Me.simulationId)
+ Using reader As SqliteDataReader = command.ExecuteReader()
+ While reader.Read()
+ Me.SimStart = reader.GetDateTime(0)
+ Me.SimEnde = reader.GetDateTime(1)
+ 'TODO: what if we have a monthly timestep?
+ Me.SimDT = New TimeSpan(0, reader.GetInt32(2), 0)
+ End While
+ End Using
+ End Using
+ connection.Close()
+ End Using
+
+ End Sub
+
+ '''
+ ''' Gibt zurück ob ein beliebiger Thread beendet ist und gibt die ID diesen freien Threads zurück
+ '''
+ '''
+ '''
+ '''
+ Protected Overrides Function ThreadFree(ByRef Thread_ID As Integer) As Boolean
+ ThreadFree = False
+
+ For Each Thr_C As Talsim5Thread In MyTalsimThreads
+ If Thr_C.Sim_Is_OK = True And Thr_C.get_Child_ID = -1 Then
+ ThreadFree = True
+ Thread_ID = Thr_C.get_Thread_ID
+ Exit For
+ End If
+ Next
+
+ End Function
+
+ '''
+ ''' Carry out a multithreaded simulation
+ '''
+ '''
+ '''
+ '''
+ ''' starts a new thread and gives it the Child_ID
+ Protected Overrides Function launchSim(ByVal Thread_ID As Integer, ByVal Child_ID As Integer) As Boolean
+
+ launchSim = False
+ Dim Folder As String
+
+ Folder = getThreadWorkDir(Thread_ID)
+ MyTalsimThreads(Thread_ID) = New Talsim5Thread(Thread_ID, Child_ID, Folder, Datensatz, Me.scenarioId, Me.simulationId, Me.timeseriesPath)
+ MyThreads(Thread_ID) = New Thread(AddressOf MyTalsimThreads(Thread_ID).launchSim) With {
+ .IsBackground = True
+ }
+ MyThreads(Thread_ID).Start()
+ launchSim = True
+
+ Return launchSim
+
+ End Function
+
+ '''
+ ''' Carry out a simulation (single-threaded)
+ '''
+ '''
+ '''
+ Protected Overrides Function launchSim() As Boolean
+
+ Dim filestr As IO.FileStream
+ Dim strread As IO.StreamReader
+ Dim simOK As Boolean
+ Dim isFinished As Boolean
+
+ Try
+
+ 'write the required settings into a new run file
+ 'this is done for every simulation because the workdir may change
+ Dim runfile As String = IO.Path.Combine(IO.Path.GetDirectoryName(exe_path), "talsim5.run")
+ If (Not IO.File.Exists(runfile)) Then
+ Throw New Exception(runfile & " not found!")
+ End If
+ Dim line As String
+ 'read the template run file
+ filestr = New IO.FileStream(runfile, IO.FileMode.Open, IO.FileAccess.Read)
+ strread = New IO.StreamReader(filestr, System.Text.Encoding.GetEncoding("iso8859-1"))
+ Dim lines As New Collections.Generic.List(Of String)
+ Do
+ line = strread.ReadLine()
+ lines.Add(line)
+ Loop Until strread.Peek = -1
+ strread.Close()
+ filestr.Close()
+
+ 'write a new run file
+ Dim runfilename As String = MyBase.Datensatz & ".run"
+ runfile = IO.Path.Combine(IO.Path.GetDirectoryName(Me.exe_path), runfilename)
+ Dim strwrite As New IO.StreamWriter(runfile, False, System.Text.Encoding.GetEncoding("iso8859-1"))
+ For Each line In lines
+ If line.StartsWith("Path=") Then
+ line = "Path=" & MyBase.WorkDir_Current
+ ElseIf line.StartsWith("System=") Then
+ line = "System=" & MyBase.Datensatz
+ ElseIf line.StartsWith("DBFile=") Then
+ line = "DBFile=" & Me.DBFile
+ ElseIf line.StartsWith("ZrePath=") Then
+ line = "ZrePath=" & Me.timeseriesPath & "\"
+ ElseIf line.StartsWith("ScenarioId=") Then
+ line = "ScenarioId=" & Me.scenarioId.ToString()
+ ElseIf line.StartsWith("SimulationId=") Then
+ line = "SimulationId=" & Me.simulationId.ToString()
+ End If
+ strwrite.WriteLine(line)
+ Next
+ strwrite.Close()
+
+ 'TALSIM starten
+ Dim errfile As String = IO.Path.Combine(Me.WorkDir_Current, Me.Datensatz & ".err")
+ Dim simendfile As String = IO.Path.Combine(Me.WorkDir_Current, Me.Datensatz & ".SIMEND")
+ Dim proc As Process
+ Dim startInfo As New ProcessStartInfo With {
+ .FileName = Me.exe_path,
+ .Arguments = runfilename,
+ .UseShellExecute = True,
+ .WindowStyle = ProcessWindowStyle.Hidden,
+ .WorkingDirectory = IO.Path.GetDirectoryName(Me.exe_path)
+ }
+ 'start
+ proc = Process.Start(startInfo)
+ 'DEBUG: write to log
+ 'BlueM.Opt.Common.Log.AddMessage(startInfo.FileName & " " & startInfo.Arguments)
+ 'wait until finished
+ Do
+ isFinished = proc.WaitForExit(100)
+ System.Windows.Forms.Application.DoEvents()
+ Loop Until isFinished
+ 'close the process
+ proc.Close()
+
+ 'if .ERR file exists, simulation finished with errors
+ If IO.File.Exists(errfile) Then
+ 'read err-file
+ Dim errmsg As String = "TALSIM simulation ended with errors:"
+ filestr = New IO.FileStream(errfile, IO.FileMode.Open, IO.FileAccess.Read)
+ strread = New IO.StreamReader(filestr, System.Text.Encoding.GetEncoding("iso8859-1"))
+ Do
+ line = strread.ReadLine()
+ errmsg &= BlueM.Opt.Common.eol & line
+ Loop Until strread.Peek = -1
+ strread.Close()
+ filestr.Close()
+
+ Throw New Exception(errmsg)
+ End If
+
+ 'if .SIMEND does not exist, simulation aborted prematurely
+ If Not IO.File.Exists(simendfile) Then
+ Throw New Exception("TALSIM simulation aborted prematurely!")
+ End If
+
+ 'Simulation erfolgreich
+ simOK = True
+
+ Catch ex As Exception
+
+ 'Simulationsfehler aufgetreten
+ Common.Log.AddMessage(Common.Log.levels.error, ex.Message)
+
+ 'Simulation nicht erfolgreich
+ simOK = False
+
+ Finally
+
+ 'nothing to do
+
+ End Try
+
+ Return simOK
+
+ End Function
+
+ '''
+ ''' Prüft ob das aktuelle Child mit der ID die oben übergeben wurde fertig ist
+ ''' Gibt die Thread ID zurück um zum auswerten in das Arbeitsverzeichnis zu wechseln
+ '''
+ '''
+ '''
+ '''
+ '''
+ '''
+ Protected Overrides Function ThreadReady(ByRef Thread_ID As Integer, ByRef SimIsOK As Boolean, ByVal Child_ID As Integer) As Boolean
+ ThreadReady = False
+
+ For Each Thr_C As Talsim5Thread In MyTalsimThreads
+ If Thr_C.launch_Ready = True And Thr_C.get_Child_ID = Child_ID Then
+ ThreadReady = True
+ SimIsOK = Thr_C.Sim_Is_OK
+ Thread_ID = Thr_C.get_Thread_ID
+ MyThreads(Thread_ID).Join()
+ MyTalsimThreads(Thread_ID) = New Talsim5Thread(Thread_ID, -1, "Folder", Datensatz, Me.scenarioId, Me.simulationId, Me.timeseriesPath)
+ MyTalsimThreads(Thread_ID).set_is_OK()
+ End If
+ Next
+
+ End Function
+
+ '''
+ ''' Update model parameters in database
+ '''
+ Public Overrides Sub Write_ModellParameter()
+
+ 'ModellParameter aus OptParametern kalkulieren()
+ Call MyBase.OptParameter_to_ModellParameter()
+
+ Try
+ Using connection As New SqliteConnection($"Data Source={Me.DBFile}")
+ connection.Open()
+ Dim i As Integer = 0
+ Using transaction As SqliteTransaction = connection.BeginTransaction()
+ For Each modParam As Struct_ModellParameter In Me.mProblem.List_ModellParameter
+ Try
+ Using command As SqliteCommand = connection.CreateCommand()
+ command.CommandText = $"
+ UPDATE {modParam.DBTable}
+ SET {modParam.DBField} = @Value
+ WHERE Id = @Id
+ "
+ command.Parameters.AddWithValue("@Value", Me.Akt.ModPara(i))
+ command.Parameters.AddWithValue("@Id", modParam.DBId)
+ Dim nrows As Integer = command.ExecuteNonQuery()
+ If nrows = 0 Then
+ Throw New Exception($"No row with Id {modParam.DBId} found in table {modParam.DBTable} for updating model parameter '{modParam.Bezeichnung}'!")
+ End If
+ i += 1
+ End Using
+ Catch ex As Exception
+ Throw New Exception($"Error while updating model parameter '{modParam.Bezeichnung}' in database: {ex.Message}", ex)
+ End Try
+ Next
+ transaction.Commit()
+ End Using
+ connection.Close()
+ End Using
+ Catch ex As Exception
+ Throw New Exception($"Error while updating model parameters in database: {ex.Message}", ex)
+ End Try
+
+ End Sub
+
+ '''
+ ''' Simulationsergebnis lesen
+ '''
+ '''
+ Protected Overrides Sub SIM_Ergebnis_Lesen()
+
+ 'Altes Simulationsergebnis löschen
+ Me.SimResult.Clear()
+
+ 'Collect required result files and series
+ 'TODO: das braucht eigentlich nicht nach jeder Simulation nochmal neu getan zu werden
+ Dim seriesMap As New Dictionary(Of String, List(Of String)) '{file: [series]}
+ For Each fileExtension As String In Me.resultFiles
+ seriesMap.Add(fileExtension, New List(Of String))
+ Next
+ For Each objfunc As ObjectiveFunction In Me.mProblem.List_ObjectiveFunctions
+ If objfunc.GetObjType = ObjectiveFunction.ObjectiveType.Series Or
+ objfunc.GetObjType = ObjectiveFunction.ObjectiveType.ValueFromSeries Then
+ If Not seriesMap(objfunc.FileExtension.ToUpper()).Contains(objfunc.SimResultName) Then
+ seriesMap(objfunc.FileExtension.ToUpper()).Add(objfunc.SimResultName)
+ End If
+ End If
+ Next
+ For Each constr As Constraintfunction In Me.mProblem.List_Constraintfunctions
+ If Not seriesMap(constr.Datei.ToUpper()).Contains(constr.SimGr) Then
+ seriesMap(constr.Datei.ToUpper()).Add(constr.SimGr)
+ End If
+ Next
+
+ 'Read result series from file
+ For Each fileExtension As String In Me.resultFiles
+
+ 'get a file instance
+ Dim fileInstance As Wave.TimeSeriesFile = Wave.TimeSeriesFile.getInstance(IO.Path.Combine(Me.WorkDir_Current, Me.Datensatz & "." & fileExtension))
+ 'select required series for import
+ For Each series As String In seriesMap(fileExtension)
+ fileInstance.selectSeries(series)
+ Next
+ 'read the file
+ fileInstance.readFile()
+ 'add time series to SimResults
+ For Each ts As Wave.TimeSeries In fileInstance.TimeSeries.Values
+ Me.SimResult.Series.Add(ts.Title, ts)
+ Next
+ Next
+
+ End Sub
+
+ End Class
\ No newline at end of file
diff --git a/BlueM.Opt/Apps/TALSIM/TALSIM5Thread.vb b/BlueM.Opt/Apps/TALSIM/TALSIM5Thread.vb
new file mode 100644
index 00000000..e93a9f89
--- /dev/null
+++ b/BlueM.Opt/Apps/TALSIM/TALSIM5Thread.vb
@@ -0,0 +1,223 @@
+'BlueM.Opt
+'Copyright (C) BlueM Dev Group
+'Website:
+'
+'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 .
+'
+'''
+''' Klasse beinhaltet alle Infomationen für einen Simulationslauf im Thread
+'''
+'''
+Public Class Talsim5Thread
+
+ Private ReadOnly Thread_ID As Integer
+ Private ReadOnly Child_ID As Integer
+ Private ReadOnly WorkFolder As String
+ Private ReadOnly DS_Name As String
+ Private ReadOnly ScenarioId As Integer
+ Private ReadOnly SimulationId As Integer
+ Private ReadOnly TimeseriesPath As String
+ Private SimIsOK As Boolean
+ Private launchReady As Boolean
+ Public Shared exe_path As String
+
+ '''
+ ''' Path to the database file (in the thread's working directory)
+ '''
+ '''
+ Private ReadOnly Property DBFile As String
+ Get
+ Return IO.Path.Combine(Me.WorkFolder, Me.DS_Name & ".db")
+ End Get
+ End Property
+
+ Public Sub New(_Thread_ID As Integer, _Child_ID As Integer, _WorkFolder As String, _DS_Name As String, scenarioId As Integer, simulationId As Integer, timeseriesPath As String)
+ Me.Thread_ID = _Thread_ID
+ Me.Child_ID = _Child_ID
+ Me.WorkFolder = _WorkFolder
+ Me.DS_Name = _DS_Name
+ Me.ScenarioId = scenarioId
+ Me.SimulationId = simulationId
+ Me.TimeseriesPath = timeseriesPath
+ End Sub
+
+ '''
+ ''' Die Funktion startet die Simulation mit dem entsprechendem WorkingDir
+ '''
+ '''
+ Public Sub launchSim()
+
+ Dim filestr As IO.FileStream
+ Dim strread As IO.StreamReader
+
+ Me.SimIsOK = False
+ Dim isFinished As Boolean
+ Me.launchReady = False
+
+ 'Priority
+ System.Threading.Thread.CurrentThread.Priority = Threading.ThreadPriority.Normal
+
+ Try
+ 'write the required settings into a new run file
+ 'this is done for every simulation because otherwise we would have to keep track of runfiles and thread IDs separately
+ Dim runfile As String = IO.Path.Combine(IO.Path.GetDirectoryName(exe_path), "talsim5.run")
+ If (Not IO.File.Exists(runfile)) Then
+ Throw New Exception(runfile & " not found!")
+ End If
+ Dim line As String
+ 'read the template run file
+ filestr = New IO.FileStream(runfile, IO.FileMode.Open, IO.FileAccess.Read)
+ strread = New IO.StreamReader(filestr, System.Text.Encoding.GetEncoding("iso8859-1"))
+ Dim lines As New Collections.Generic.List(Of String)
+ Do
+ line = strread.ReadLine()
+ lines.Add(line)
+ Loop Until strread.Peek = -1
+ strread.Close()
+ filestr.Close()
+
+ 'write a new run file
+ Dim runfilename As String = $"{Me.DS_Name}_{Me.Thread_ID}.run"
+ runfile = IO.Path.Combine(IO.Path.GetDirectoryName(Talsim5Thread.exe_path), runfilename)
+ Dim strwrite As New IO.StreamWriter(runfile, False, System.Text.Encoding.GetEncoding("iso8859-1"))
+ For Each line In lines
+ If line.StartsWith("Path=") Then
+ line = "Path=" & Me.WorkFolder
+ ElseIf line.StartsWith("System=") Then
+ line = "System=" & Me.DS_Name
+ ElseIf line.StartsWith("DBFile=") Then
+ line = "DBFile=" & Me.dbfile
+ ElseIf line.StartsWith("ZrePath=") Then
+ line = "ZrePath=" & Me.TimeseriesPath & "\"
+ ElseIf line.StartsWith("ScenarioId=") Then
+ line = "ScenarioId=" & Me.scenarioId.ToString()
+ ElseIf line.StartsWith("SimulationId=") Then
+ line = "SimulationId=" & Me.simulationId.ToString()
+ End If
+ strwrite.WriteLine(line)
+ Next
+ strwrite.Close()
+
+ 'TALSIM starten
+ Dim errfile As String = IO.Path.Combine(Me.WorkFolder, Me.DS_Name & ".err")
+ Dim errmsg As String
+ Dim simendfile As String = IO.Path.Combine(Me.WorkFolder, Me.DS_Name & ".SIMEND")
+ Dim proc As Process
+ Dim startInfo As New ProcessStartInfo With {
+ .FileName = Talsim5Thread.exe_path,
+ .Arguments = runfilename,
+ .UseShellExecute = True,
+ .WindowStyle = ProcessWindowStyle.Hidden,
+ .WorkingDirectory = IO.Path.GetDirectoryName(Talsim5Thread.exe_path)
+ }
+
+ 'Carry out up to 5 simulation attempts, because TALSIM sometimes blocks access to the time series files in multithreading mode
+ Dim n_attempts As Integer = 5
+ For i_attempt As Integer = 1 To n_attempts
+
+ errmsg = ""
+ Me.SimIsOK = False
+
+ 'start
+ proc = Process.Start(startInfo)
+ 'DEBUG: write to log
+ 'BlueM.Opt.Common.Log.AddMessage($"Thread {Me.Thread_ID}: {startInfo.FileName} {startInfo.Arguments}")
+ 'wait until finished
+ Do
+ isFinished = proc.WaitForExit(100)
+ System.Windows.Forms.Application.DoEvents()
+ Loop Until isFinished
+ 'close the process
+ proc.Close()
+
+ 'Simulation erfolgreich?
+ If Not IO.File.Exists(errfile) And IO.File.Exists(simendfile) Then
+ Me.SimIsOK = True
+ Exit For
+ End If
+
+ 'if .ERR file exists, simulation finished with errors
+ If IO.File.Exists(errfile) Then
+ 'read err-file
+ errmsg = $"Thread {Me.Thread_ID}: TALSIM simulation ended with errors:"
+ filestr = New IO.FileStream(errfile, IO.FileMode.Open, IO.FileAccess.Read)
+ strread = New IO.StreamReader(filestr, System.Text.Encoding.GetEncoding("iso8859-1"))
+ Do
+ line = strread.ReadLine()
+ errmsg &= BlueM.Opt.Common.eol & line
+ Loop Until strread.Peek = -1
+ strread.Close()
+ filestr.Close()
+ End If
+
+ 'if .SIMEND does not exist, simulation aborted prematurely
+ If Not IO.File.Exists(simendfile) Then
+ errmsg = $"Thread {Me.Thread_ID}: TALSIM simulation aborted prematurely!"
+ End If
+
+ 'Log error message
+ Common.Log.AddMessage(Common.Log.levels.error, errmsg)
+
+ If i_attempt < n_attempts Then
+ Common.Log.AddMessage(Common.Log.levels.error, $"Thread {Me.Thread_ID}: TALSIM simulation attempt {i_attempt} was unsuccessful, trying again...")
+ System.Threading.Thread.Sleep(100)
+ Else
+ Common.Log.AddMessage(Common.Log.levels.error, $"Thread {Me.Thread_ID}: TALSIM simulation attempt {i_attempt} was unsuccessful, parameter set will be discarded!")
+ End If
+
+ Next
+
+ Catch ex As Exception
+
+ 'Simulationsfehler aufgetreten
+ Common.Log.AddMessage(Common.Log.levels.error, ex.Message)
+
+ 'Simulation nicht erfolgreich
+ Me.SimIsOK = False
+
+ Finally
+
+ 'ready for next sim
+ Me.launchReady = True
+
+ End Try
+
+ End Sub
+
+ Public Function Sim_Is_OK() As Boolean
+
+ Sim_Is_OK = Me.SimIsOK
+ End Function
+
+ Public Function launch_Ready() As Boolean
+
+ launch_Ready = Me.launchReady
+ End Function
+
+ Public Sub set_is_OK()
+
+ Me.SimIsOK = True
+ End Sub
+
+ Public Function get_Thread_ID() As Integer
+
+ get_Thread_ID = Me.Thread_ID
+ End Function
+
+ Public Function get_Child_ID() As Integer
+
+ get_Child_ID = Me.Child_ID
+ End Function
+
+End Class
\ No newline at end of file
diff --git a/BlueM.Opt/Apps/TALSIM/TALSIM5_Dialog.Designer.vb b/BlueM.Opt/Apps/TALSIM/TALSIM5_Dialog.Designer.vb
new file mode 100644
index 00000000..f2c7c296
--- /dev/null
+++ b/BlueM.Opt/Apps/TALSIM/TALSIM5_Dialog.Designer.vb
@@ -0,0 +1,205 @@
+ _
+Partial Class TALSIM5_Dialog
+ Inherits System.Windows.Forms.Form
+
+ 'Form overrides dispose to clean up the component list.
+ _
+ Protected Overrides Sub Dispose(ByVal disposing As Boolean)
+ Try
+ If disposing AndAlso components IsNot Nothing Then
+ components.Dispose()
+ End If
+ Finally
+ MyBase.Dispose(disposing)
+ End Try
+ End Sub
+
+ 'Required by the Windows Form Designer
+ Private components As System.ComponentModel.IContainer
+
+ 'NOTE: The following procedure is required by the Windows Form Designer
+ 'It can be modified using the Windows Form Designer.
+ 'Do not modify it using the code editor.
+ _
+ Private Sub InitializeComponent()
+ Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(TALSIM5_Dialog))
+ Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel()
+ Me.OK_Button = New System.Windows.Forms.Button()
+ Me.Cancel_Button = New System.Windows.Forms.Button()
+ Me.Label_DBPath = New System.Windows.Forms.Label()
+ Me.Label2 = New System.Windows.Forms.Label()
+ Me.Label3 = New System.Windows.Forms.Label()
+ Me.Label4 = New System.Windows.Forms.Label()
+ Me.Label5 = New System.Windows.Forms.Label()
+ Me.ComboBox_Scenario = New System.Windows.Forms.ComboBox()
+ Me.ComboBox_Simulation = New System.Windows.Forms.ComboBox()
+ Me.TextBox_TimeseriesPath = New System.Windows.Forms.TextBox()
+ Me.Button_BrowseFolder = New System.Windows.Forms.Button()
+ Me.FolderBrowserDialog1 = New System.Windows.Forms.FolderBrowserDialog()
+ Me.TableLayoutPanel1.SuspendLayout()
+ Me.SuspendLayout()
+ '
+ 'TableLayoutPanel1
+ '
+ Me.TableLayoutPanel1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
+ Me.TableLayoutPanel1.ColumnCount = 2
+ Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
+ Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
+ Me.TableLayoutPanel1.Controls.Add(Me.OK_Button, 0, 0)
+ Me.TableLayoutPanel1.Controls.Add(Me.Cancel_Button, 1, 0)
+ Me.TableLayoutPanel1.Location = New System.Drawing.Point(172, 119)
+ Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
+ Me.TableLayoutPanel1.RowCount = 1
+ Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
+ Me.TableLayoutPanel1.Size = New System.Drawing.Size(146, 29)
+ Me.TableLayoutPanel1.TabIndex = 0
+ '
+ 'OK_Button
+ '
+ Me.OK_Button.Anchor = System.Windows.Forms.AnchorStyles.None
+ Me.OK_Button.Location = New System.Drawing.Point(3, 3)
+ Me.OK_Button.Name = "OK_Button"
+ Me.OK_Button.Size = New System.Drawing.Size(67, 23)
+ Me.OK_Button.TabIndex = 0
+ Me.OK_Button.Text = "OK"
+ '
+ 'Cancel_Button
+ '
+ Me.Cancel_Button.Anchor = System.Windows.Forms.AnchorStyles.None
+ Me.Cancel_Button.DialogResult = System.Windows.Forms.DialogResult.Cancel
+ Me.Cancel_Button.Location = New System.Drawing.Point(76, 3)
+ Me.Cancel_Button.Name = "Cancel_Button"
+ Me.Cancel_Button.Size = New System.Drawing.Size(67, 23)
+ Me.Cancel_Button.TabIndex = 1
+ Me.Cancel_Button.Text = "Cancel"
+ '
+ 'Label1
+ '
+ Me.Label_DBPath.AutoSize = True
+ Me.Label_DBPath.Location = New System.Drawing.Point(12, 9)
+ Me.Label_DBPath.Name = "Label1"
+ Me.Label_DBPath.Size = New System.Drawing.Size(56, 13)
+ Me.Label_DBPath.TabIndex = 1
+ Me.Label_DBPath.Text = "Database:"
+ '
+ 'Label2
+ '
+ Me.Label2.AutoSize = True
+ Me.Label2.Location = New System.Drawing.Point(12, 34)
+ Me.Label2.Name = "Label2"
+ Me.Label2.Size = New System.Drawing.Size(52, 13)
+ Me.Label2.TabIndex = 2
+ Me.Label2.Text = "Scenario:"
+ '
+ 'Label3
+ '
+ Me.Label3.AutoSize = True
+ Me.Label3.Location = New System.Drawing.Point(13, 61)
+ Me.Label3.Name = "Label3"
+ Me.Label3.Size = New System.Drawing.Size(58, 13)
+ Me.Label3.TabIndex = 3
+ Me.Label3.Text = "Simulation:"
+ '
+ 'Label4
+ '
+ Me.Label4.AutoSize = True
+ Me.Label4.Location = New System.Drawing.Point(13, 90)
+ Me.Label4.Name = "Label4"
+ Me.Label4.Size = New System.Drawing.Size(89, 13)
+ Me.Label4.TabIndex = 4
+ Me.Label4.Text = "Timeseries folder:"
+ '
+ 'Label5
+ '
+ Me.Label5.AutoSize = True
+ Me.Label5.Location = New System.Drawing.Point(114, 9)
+ Me.Label5.Name = "Label5"
+ Me.Label5.Size = New System.Drawing.Size(74, 13)
+ Me.Label5.TabIndex = 5
+ Me.Label5.Text = "pathDatabase"
+ '
+ 'ComboBox_Scenario
+ '
+ Me.ComboBox_Scenario.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
+ Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
+ Me.ComboBox_Scenario.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
+ Me.ComboBox_Scenario.FormattingEnabled = True
+ Me.ComboBox_Scenario.Location = New System.Drawing.Point(117, 31)
+ Me.ComboBox_Scenario.Name = "ComboBox_Scenario"
+ Me.ComboBox_Scenario.Size = New System.Drawing.Size(201, 21)
+ Me.ComboBox_Scenario.TabIndex = 6
+ '
+ 'ComboBox_Simulation
+ '
+ Me.ComboBox_Simulation.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
+ Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
+ Me.ComboBox_Simulation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
+ Me.ComboBox_Simulation.FormattingEnabled = True
+ Me.ComboBox_Simulation.Location = New System.Drawing.Point(117, 58)
+ Me.ComboBox_Simulation.Name = "ComboBox_Simulation"
+ Me.ComboBox_Simulation.Size = New System.Drawing.Size(201, 21)
+ Me.ComboBox_Simulation.TabIndex = 7
+ '
+ 'TextBox_TimeseriesPath
+ '
+ Me.TextBox_TimeseriesPath.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
+ Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
+ Me.TextBox_TimeseriesPath.Location = New System.Drawing.Point(117, 87)
+ Me.TextBox_TimeseriesPath.Name = "TextBox_TimeseriesPath"
+ Me.TextBox_TimeseriesPath.Size = New System.Drawing.Size(165, 20)
+ Me.TextBox_TimeseriesPath.TabIndex = 8
+ '
+ 'Button1
+ '
+ Me.Button_BrowseFolder.Anchor = CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
+ Me.Button_BrowseFolder.Location = New System.Drawing.Point(288, 85)
+ Me.Button_BrowseFolder.Name = "Button1"
+ Me.Button_BrowseFolder.Size = New System.Drawing.Size(30, 23)
+ Me.Button_BrowseFolder.TabIndex = 9
+ Me.Button_BrowseFolder.Text = "..."
+ Me.Button_BrowseFolder.UseVisualStyleBackColor = True
+ '
+ 'TALSIM5_Dialog
+ '
+ Me.AcceptButton = Me.OK_Button
+ Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
+ Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
+ Me.CancelButton = Me.Cancel_Button
+ Me.ClientSize = New System.Drawing.Size(330, 160)
+ Me.Controls.Add(Me.Button_BrowseFolder)
+ Me.Controls.Add(Me.TextBox_TimeseriesPath)
+ Me.Controls.Add(Me.ComboBox_Simulation)
+ Me.Controls.Add(Me.ComboBox_Scenario)
+ Me.Controls.Add(Me.Label5)
+ Me.Controls.Add(Me.Label4)
+ Me.Controls.Add(Me.Label3)
+ Me.Controls.Add(Me.Label2)
+ Me.Controls.Add(Me.Label_DBPath)
+ Me.Controls.Add(Me.TableLayoutPanel1)
+ Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
+ Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
+ Me.MaximizeBox = False
+ Me.MinimizeBox = False
+ Me.Name = "TALSIM5_Dialog"
+ Me.ShowInTaskbar = False
+ Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
+ Me.Text = "Talsim5 settings"
+ Me.TableLayoutPanel1.ResumeLayout(False)
+ Me.ResumeLayout(False)
+ Me.PerformLayout()
+
+ End Sub
+ Friend WithEvents TableLayoutPanel1 As System.Windows.Forms.TableLayoutPanel
+ Friend WithEvents OK_Button As System.Windows.Forms.Button
+ Friend WithEvents Cancel_Button As System.Windows.Forms.Button
+ Friend WithEvents Label_DBPath As Windows.Forms.Label
+ Friend WithEvents Label2 As Windows.Forms.Label
+ Friend WithEvents Label3 As Windows.Forms.Label
+ Friend WithEvents Label4 As Windows.Forms.Label
+ Friend WithEvents Label5 As Windows.Forms.Label
+ Friend WithEvents ComboBox_Scenario As Windows.Forms.ComboBox
+ Friend WithEvents ComboBox_Simulation As Windows.Forms.ComboBox
+ Friend WithEvents TextBox_TimeseriesPath As Windows.Forms.TextBox
+ Friend WithEvents Button_BrowseFolder As Windows.Forms.Button
+ Friend WithEvents FolderBrowserDialog1 As Windows.Forms.FolderBrowserDialog
+End Class
diff --git a/BlueM.Opt/Apps/TALSIM/TALSIM5_Dialog.resx b/BlueM.Opt/Apps/TALSIM/TALSIM5_Dialog.resx
new file mode 100644
index 00000000..80dc2770
--- /dev/null
+++ b/BlueM.Opt/Apps/TALSIM/TALSIM5_Dialog.resx
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+
+ AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDg4Njb29vv2dnZ79oaGhjAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAhYWFKYGBgQ6QkJACl5eX6svLy//BwcH/cnJy6nFxcQJycnIOZGRkKQAA
+ AAAAAAAAAAAAAAAAAAAAAAAAl5eXm4WFhf17e3vnjIyMGZiYmOfW1tb/09PT/3l5eedxcXEZbm5u52Rk
+ ZP1fX1+bAAAAAAAAAAAAAAAAtbW1e8nJyf/l5eX/t7e3/5iYmPSampr+0NDQ/8/Pz/+EhIT+hISE9Li4
+ uP/b29v/lZWV/2hoaHsAAAAAAAAAALy8vH23t7f+3t7e/9HR0f/W1tb/29vb/9TU1P/T09P/19fX/9LS
+ 0v/Kysr/1tbW/4SEhP5+fn59AAAAAAAAAAAAAAAAvb29hdHR0f/Ozs7/0dHR/9PT0/+7u7v/uLi4/87O
+ zv/Ly8v/xMTE/7u7u/+AgICFAAAAAAAAAAC1tbXNo6Oj47Kysu7Z2dn/0tLS/9fX1/+wsLDGq6urRKen
+ p0Sjo6PGzc3N/8nJyf/IyMj/enp67m9vb+NpaWnNzMzM/ejo6P/c3Nz/0tLS/9jY2P/BwcH/pqamRAAA
+ AAAAAAAAqKioRLm5uf/Pz8//xcXF/83Nzf/c3Nz/eHh4/dDQ0P3u7u7/39/f/9XV1f/Y2Nj/t7e3/5mZ
+ mUQAAAAAAAAAAK2trUS8vLz/0NDQ/8jIyP/S0tL/5OTk/4KCgv3T09PN0NDQ487Ozu7h4eH/2NjY/8rK
+ yv+Xl5fGjY2NRJOTk0Sjo6PG0NDQ/8/Pz//Y2Nj/oaGh7pubm+OYmJjNAAAAAAAAAADR0dGF3d3d/9fX
+ 1//U1NT/yMjI/66urv+zs7P/z8/P/9LS0v/Ozs7/xcXF/56enoUAAAAAAAAAAAAAAADV1dV90NDQ/uTk
+ 5P/d3d3/4eHh/+Pj4//f39//3t7e/+Li4v/b29v/1tbW/9PT0/+Pj4/+h4eHfQAAAAAAAAAA2trae+Pj
+ 4//x8fH/4+Pj/8/Pz/TLy8v+39/f/97e3v/AwMD+vb299NbW1v/t7e3/xsbG/5+fn3sAAAAAAAAAAAAA
+ AADb29ub2NjY/dXV1efS0tIZzs7O5+Xl5f/l5eX/wsLC58HBwRm9vb3nuLi4/bS0tJsAAAAAAAAAAAAA
+ AAAAAAAAAAAAANvb2ynZ2dkO1tbWAtPT0+rr6+v/6urq/7y8vOrExMQCwcHBDr6+vikAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADW1tZj0tLSv9HR0b/MzMxjAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAA/n8AAPw/AADEIwAAwAMAAMADAADAAwAAAYAAAAPAAAADwAAAAYAAAMADAADAAwAAwAMAAMQj
+ ///8P////n///w==
+
+
+
\ No newline at end of file
diff --git a/BlueM.Opt/Apps/TALSIM/TALSIM5_Dialog.vb b/BlueM.Opt/Apps/TALSIM/TALSIM5_Dialog.vb
new file mode 100644
index 00000000..c85a228f
--- /dev/null
+++ b/BlueM.Opt/Apps/TALSIM/TALSIM5_Dialog.vb
@@ -0,0 +1,180 @@
+'BlueM.Opt
+'Copyright (C) BlueM Dev Group
+'Website:
+'
+'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 .
+'
+Imports Microsoft.Data.Sqlite
+Imports System.Windows.Forms
+
+Friend Class TALSIM5_Dialog
+
+ Private dbPath As String
+
+ '''
+ ''' Selected scenario in the dialog, or null if no scenario is selected
+ '''
+ '''
+ Friend ReadOnly Property SelectedScenario As Talsim5.Scenario
+ Get
+ Try
+ Return CType(ComboBox_Scenario.SelectedItem, Talsim5.Scenario)
+ Catch
+ Return Nothing
+ End Try
+ End Get
+ End Property
+
+ '''
+ ''' Selected simulation in the dialog, or null if no simulation is selected
+ '''
+ '''
+ Friend ReadOnly Property SelectedSimulation As Talsim5.Simulation
+ Get
+ Try
+ Return CType(ComboBox_Simulation.SelectedItem, Talsim5.Simulation)
+ Catch
+ Return Nothing
+ End Try
+ End Get
+ End Property
+
+ '''
+ ''' Selected timeseries path in the dialog
+ '''
+ '''
+ Friend ReadOnly Property TimeseriesPath As String
+ Get
+ Return Me.TextBox_TimeseriesPath.Text.Trim()
+ End Get
+ End Property
+
+ '''
+ ''' Create a new instance of the dialog with the given database path.
+ ''' The dialog will read the scenarios and simulations from the database and show them in the corresponding combo boxes.
+ '''
+ ''' Path to the database
+ Public Sub New(dbPath As String)
+ ' Dieser Aufruf ist für den Designer erforderlich.
+ InitializeComponent()
+ ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
+ Me.dbPath = dbPath
+
+ 'show database path
+ Me.Label_DBPath.Text = dbPath
+
+ 'read scenarios from database
+ Dim scenarios As New List(Of Talsim5.Scenario)
+ Using connection As New SQLiteConnection($"Data Source={dbPath}")
+ connection.Open()
+ Using command As SQLiteCommand = connection.CreateCommand()
+ command.CommandText = "
+ SELECT Id, Name
+ FROM Scenario
+ ORDER BY id
+ "
+ Using reader As SQLiteDataReader = command.ExecuteReader()
+ While reader.Read()
+ Dim id As Integer = reader.GetInt32(0)
+ Dim name As String = reader.GetString(1)
+ Dim scenario As New Talsim5.Scenario() With {
+ .Id = id,
+ .Name = name
+ }
+ scenarios.Add(scenario)
+ End While
+ End Using
+ End Using
+ connection.Close()
+ End Using
+
+ Me.ComboBox_Scenario.Items.AddRange(scenarios.ToArray())
+ Me.ComboBox_Scenario.SelectedIndex = 0
+
+ End Sub
+
+ Private Sub ComboBox_Scenario_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox_Scenario.SelectedIndexChanged
+ 'read simulations of currently selected scenario from database
+ Dim simulations As New List(Of Talsim5.Simulation)
+ Using connection As New SQLiteConnection($"Data Source={dbPath}")
+ connection.Open()
+ Using command As SQLiteCommand = connection.CreateCommand()
+ command.CommandText = "
+ SELECT Id, Description
+ FROM Simulation
+ WHERE ScenarioId = @ScenarioId
+ ORDER BY id
+ "
+ command.Parameters.AddWithValue("@ScenarioId", Me.SelectedScenario.Id)
+ Using reader As SQLiteDataReader = command.ExecuteReader()
+ While reader.Read()
+ Dim id As Integer = reader.GetInt32(0)
+ Dim name As String = reader.GetString(1)
+ Dim simulation As New Talsim5.Simulation() With {
+ .Id = id,
+ .Name = name
+ }
+ simulations.Add(simulation)
+ End While
+ End Using
+ End Using
+ connection.Close()
+ End Using
+
+ Me.ComboBox_Simulation.Items.Clear()
+ Me.ComboBox_Simulation.Items.AddRange(simulations.ToArray())
+ Me.ComboBox_Simulation.SelectedIndex = 0
+
+ If simulations.Count = 0 Then
+ MessageBox.Show("The selected scenario does not contain any simulations!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
+ End If
+
+ End Sub
+
+ Private Sub Button_BrowseFolder_Click(sender As Object, e As EventArgs) Handles Button_BrowseFolder.Click
+ If Me.TimeseriesPath <> "" Then
+ Me.FolderBrowserDialog1.SelectedPath = Me.TimeseriesPath
+ End If
+ If Me.FolderBrowserDialog1.ShowDialog() <> DialogResult.OK Then
+ Return
+ End If
+ Me.TextBox_TimeseriesPath.Text = Me.FolderBrowserDialog1.SelectedPath
+ End Sub
+
+ Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
+ If Me.SelectedScenario Is Nothing Then
+ MessageBox.Show("Please select a scenario!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
+ Return
+ End If
+ If Me.SelectedSimulation Is Nothing Then
+ MessageBox.Show("Please select a simulation!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
+ Return
+ End If
+ If Me.TimeseriesPath = "" Then
+ MessageBox.Show("Please select a timeseries path!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
+ Return
+ ElseIf Not IO.Directory.Exists(Me.TimeseriesPath) Then
+ MessageBox.Show("The selected timeseries path does not exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
+ Return
+ End If
+ Me.DialogResult = System.Windows.Forms.DialogResult.OK
+ Me.Close()
+ End Sub
+
+ Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
+ Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
+ Me.Close()
+ End Sub
+
+End Class
diff --git a/BlueM.Opt/Apps/TALSIM/TALSIMThread.vb b/BlueM.Opt/Apps/TALSIM/TALSIMThread.vb
index 67d9dd5d..ea2c1441 100644
--- a/BlueM.Opt/Apps/TALSIM/TALSIMThread.vb
+++ b/BlueM.Opt/Apps/TALSIM/TALSIMThread.vb
@@ -21,10 +21,10 @@
'''
Public Class TalsimThread
- Private Thread_ID As Integer
- Private Child_ID As Integer
- Private WorkFolder As String
- Private DS_Name As String
+ Private ReadOnly Thread_ID As Integer
+ Private ReadOnly Child_ID As Integer
+ Private ReadOnly WorkFolder As String
+ Private ReadOnly DS_Name As String
Private SimIsOK As Boolean
Private launchReady As Boolean
Public Shared exe_path As String
@@ -92,12 +92,13 @@ Public Class TalsimThread
Dim errmsg As String
Dim simendfile As String = IO.Path.Combine(Me.WorkFolder, Me.DS_Name & ".SIMEND")
Dim proc As Process
- Dim startInfo As New ProcessStartInfo()
- startInfo.FileName = TalsimThread.exe_path
- startInfo.Arguments = runfilename
- startInfo.UseShellExecute = True
- startInfo.WindowStyle = ProcessWindowStyle.Hidden
- startInfo.WorkingDirectory = IO.Path.GetDirectoryName(TalsimThread.exe_path)
+ Dim startInfo As New ProcessStartInfo With {
+ .FileName = TalsimThread.exe_path,
+ .Arguments = runfilename,
+ .UseShellExecute = True,
+ .WindowStyle = ProcessWindowStyle.Hidden,
+ .WorkingDirectory = IO.Path.GetDirectoryName(TalsimThread.exe_path)
+ }
'Carry out up to 5 simulation attempts, because TALSIM sometimes blocks access to the time series files in multithreading mode
Dim n_attempts As Integer = 5
diff --git a/BlueM.Opt/Apps/TALSIM/talsim5.run b/BlueM.Opt/Apps/TALSIM/talsim5.run
new file mode 100644
index 00000000..1d2c2ea4
--- /dev/null
+++ b/BlueM.Opt/Apps/TALSIM/talsim5.run
@@ -0,0 +1,10 @@
+[TALSIM]
+Path=
+System=
+DBFile=
+ZrePath=
+ScenarioId=
+SimulationId=
+VariationId=0
+Language=en
+Debug=1
diff --git a/BlueM.Opt/Common/Constants.vb b/BlueM.Opt/Common/Constants.vb
index 939db40a..f4af5ad1 100644
--- a/BlueM.Opt/Common/Constants.vb
+++ b/BlueM.Opt/Common/Constants.vb
@@ -38,6 +38,7 @@ Public Module Constants
Public Const ANW_SMUSI As String = "SMUSI"
Public Const ANW_SWMM As String = "SWMM"
Public Const ANW_TALSIM As String = "TALSIM"
+ Public Const ANW_TALSIM5 As String = "TALSIM5"
Public Const ANW_TESTPROBLEMS As String = "Testproblems"
Public Const ANW_TSP As String = "Traveling Salesman"
diff --git a/BlueM.Opt/Common/Modellparameter.vb b/BlueM.Opt/Common/Modellparameter.vb
index 81195a85..d699b1e9 100644
--- a/BlueM.Opt/Common/Modellparameter.vb
+++ b/BlueM.Opt/Common/Modellparameter.vb
@@ -59,6 +59,34 @@ Public Structure Struct_ModellParameter
'''
''' ModellParameter = OptimierungsParameter * Faktor
Public Faktor As Double
+
+ '''
+ ''' Name of the table in the database, in which the parameter is defined
+ '''
+ Public ReadOnly Property DBTable As String
+ Get
+ Return Me.Datei
+ End Get
+ End Property
+
+ '''
+ ''' Name of the field of the table, in which the parameter is defined
+ '''
+ Public ReadOnly Property DBField As String
+ Get
+ Return Me.Element
+ End Get
+ End Property
+
+ '''
+ ''' Id of the row to update
+ '''
+ Public ReadOnly Property DBId As Integer
+ Get
+ Return Me.ZeileNr
+ End Get
+ End Property
+
'''
''' Klont einen Modellparameter
'''
diff --git a/BlueM.Opt/Common/Problem.vb b/BlueM.Opt/Common/Problem.vb
index 4aadaa59..23afa629 100644
--- a/BlueM.Opt/Common/Problem.vb
+++ b/BlueM.Opt/Common/Problem.vb
@@ -403,8 +403,8 @@ Public Class Problem
.Datei = array(4).Trim()
.Element = array(5).Trim()
.ZeileNr = Convert.ToInt16(array(6).Trim())
- .SpVon = Convert.ToInt16(array(7).Trim())
- .SpBis = Convert.ToInt16(array(8).Trim())
+ .SpVon = If(array(7).Trim() <> "", Convert.ToInt16(array(7).Trim()), 0)
+ .SpBis = If(array(8).Trim() <> "", Convert.ToInt16(array(8).Trim()), 0)
.Faktor = Convert.ToDouble(array(9).Trim(), Common.Provider.FortranProvider)
End With
i += 1
diff --git a/BlueM.Opt/Main/BLUEM.OPT_RELEASE-NOTES.txt b/BlueM.Opt/Main/BLUEM.OPT_RELEASE-NOTES.txt
index 60808da0..26795c22 100644
--- a/BlueM.Opt/Main/BLUEM.OPT_RELEASE-NOTES.txt
+++ b/BlueM.Opt/Main/BLUEM.OPT_RELEASE-NOTES.txt
@@ -2,8 +2,12 @@
BlueM.Opt Release Notes
===============================================================
-Version X.X.X
+Version 2.6.0
-------------
+NEW:
+* Added support for Talsim datasets in Talsim5 database format (select `TALSIM5` as the app)
+
+CHANGED:
* Updated Talsim.Engine to v4.1.22
* Updated BlueM.Wave to v2.17.0
diff --git a/BlueM.Opt/Main/Form1.vb b/BlueM.Opt/Main/Form1.vb
index 7118c176..afc46a26 100644
--- a/BlueM.Opt/Main/Form1.vb
+++ b/BlueM.Opt/Main/Form1.vb
@@ -145,7 +145,7 @@ Partial Public Class Form1
'---------
'Liste der Anwendungen in ComboBox schreiben und Anfangseinstellung wählen
Me.ComboBox_Anwendung.Items.Clear()
- Me.ComboBox_Anwendung.Items.AddRange(New Object() {"", ANW_BLUEM, ANW_SWMM, ANW_TALSIM, ANW_TESTPROBLEMS, ANW_TSP}) 'ANW_SMUSI entfernt (#184)
+ Me.ComboBox_Anwendung.Items.AddRange(New Object() {"", ANW_BLUEM, ANW_SWMM, ANW_TALSIM, ANW_TALSIM5, ANW_TESTPROBLEMS, ANW_TSP}) 'ANW_SMUSI entfernt (#184)
Me.ComboBox_Anwendung.SelectedIndex = 0
'Datensatz
@@ -431,6 +431,13 @@ Partial Public Class Form1
Sim1 = New BlueM.Opt.Apps.Talsim()
+ Case ANW_TALSIM5 'Anwendung TALSIM5
+ 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+ 'Objekt der Klasse Talsim5 initialisieren
+ Sim1 = New BlueM.Opt.Apps.Talsim5()
+
+
Case ANW_SWMM 'Anwendung SWMM
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -904,7 +911,7 @@ Partial Public Class Form1
'=================
Select Case Me.Anwendung
- Case ANW_BLUEM, ANW_SMUSI, ANW_SWMM, ANW_TALSIM
+ Case ANW_BLUEM, ANW_SMUSI, ANW_SWMM, ANW_TALSIM, ANW_TALSIM5
'Bei allen Sim-Anwendungen
'-----------------------------------------------------
@@ -1037,7 +1044,7 @@ Partial Public Class Form1
Select Case Anwendung
- Case ANW_BLUEM, ANW_SMUSI, ANW_SWMM, ANW_TALSIM
+ Case ANW_BLUEM, ANW_SMUSI, ANW_SWMM, ANW_TALSIM, ANW_TALSIM5
'Sim-Anwendungen
'Save settings to file
@@ -1272,7 +1279,7 @@ Partial Public Class Form1
Call Testprobleme1.DiagInitialise(Me.Hauptdiagramm1)
- Case ANW_BLUEM, ANW_SMUSI, ANW_SWMM, ANW_TALSIM
+ Case ANW_BLUEM, ANW_SMUSI, ANW_SWMM, ANW_TALSIM, ANW_TALSIM5
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Select Case Me.mProblem.Method
diff --git a/BlueM.Opt/Main/My Project/AssemblyInfo.vb b/BlueM.Opt/Main/My Project/AssemblyInfo.vb
index 1a1bb5c1..753416fd 100644
--- a/BlueM.Opt/Main/My Project/AssemblyInfo.vb
+++ b/BlueM.Opt/Main/My Project/AssemblyInfo.vb
@@ -12,9 +12,9 @@ Imports BlueM.Opt.Common.Constants
+ & "* Talsim (https://www.talsim.de/)")>
@@ -32,6 +32,6 @@ Imports BlueM.Opt.Common.Constants
' mit '*' verwenden. Siehe unten
-
+