using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; namespace Deltares.RtcTools.Net { public class RtcToolsDll : IRtcToolsDll { // TODO: remove the directory change once the RtcTools computational core can handle file paths private string _rtcToolsWorkingDirectory; // this is a by definition a relative path, coming from the omi file of the RTC-Tools model private string _rtcToolsWorkingDirectoryAbsolute; // this is the corresponding absolute path private string _oldDirectory; private void RtcToolsWorkDirAbsolute() { if (!String.IsNullOrEmpty(_rtcToolsWorkingDirectory)) { _rtcToolsWorkingDirectoryAbsolute = Environment.CurrentDirectory + "\\" + _rtcToolsWorkingDirectory; } } private void ChangeDir() { if (!String.IsNullOrEmpty(_rtcToolsWorkingDirectory)) { if (!Environment.CurrentDirectory.Equals(_rtcToolsWorkingDirectory)) { _oldDirectory = Environment.CurrentDirectory; Environment.CurrentDirectory = _rtcToolsWorkingDirectory; } } } private void RestoreDir() { if (_oldDirectory != null) { Environment.CurrentDirectory = _oldDirectory; _oldDirectory = null; } } private IntPtr _pRtcToolsClass; // initialization and time frame /// /// Empty constructor, use to force loading the DLL /// public RtcToolsDll() { RtcToolsDllNative.LoadRtcToolsDll(); } public virtual void Initialize(string directoryPathForXmlFiles, string schemaLocation) { try { _rtcToolsWorkingDirectory = directoryPathForXmlFiles; ChangeDir(); _pRtcToolsClass = RtcToolsDllNative.CreateOmiAccessableRtcToolsClass((IntPtr)Marshal.StringToHGlobalAnsi(schemaLocation)); RestoreDir(); } catch (Exception e) { StringBuilder errormessage = new StringBuilder(); errormessage.Append("RtcToolsDll.Initialize: Could not create OmiAccessableRtcToolsClass. " + e); Console.WriteLine(errormessage); Debug.WriteLine(errormessage); throw new Exception(errormessage.ToString()); } // executing the initialize function of the RtcTools c++ class, the pointer is used. try { ChangeDir(); RtcToolsDllNative.OmiInitialize(_pRtcToolsClass); RestoreDir(); } catch (Exception) { throw new Exception("RtcToolsDll.Initialize: Error in executing DllImport function OmiInitialize"); } } public string GetStartTimeString() { try { string datetime = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiGetStartTimeString(_pRtcToolsClass)); return datetime; } catch (Exception) { throw new Exception(GetType() + ".RtcToolsDll.GetStartTimeString: Error in executing DllImport function OmiGetStartTimeString"); } } public double GetStartTimeAsMJD() { var datetime = GetStartTimeString(); var dtStartTime = DateTime.Parse(datetime); return Gregorian2ModifiedJulian(dtStartTime); } public string GetEndTimeString() { try { string datetime = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiGetEndTimeString(_pRtcToolsClass)); return datetime; } catch (Exception) { throw new Exception(GetType() + ".RtcToolsDll.GetEndTimeString: Error in executing DllImport function OmiGetEndTimeString"); } } public double GetEndTimeAsMJD() { var datetime = GetEndTimeString(); var dtEndTime = DateTime.Parse(datetime); return Gregorian2ModifiedJulian(dtEndTime); } // exchange items ------------------------------------------------------------ public int GetInputExchangeItemCount() { try { return RtcToolsDllNative.OmiGetInputExchangeItemCount(_pRtcToolsClass); } catch (Exception) { throw new Exception( "RtcToolsDll.GetExchangeItemCount: Error in executing DllImport function OmiGetInputExchangeItemCount"); } } public string InputExchangeItemGetQuantityId(int index) { try { string sQuantity = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiInputExchangeItemGetQuantityId(_pRtcToolsClass, index)); return sQuantity; } catch (Exception) { throw new Exception( "RtcToolsDll.InputExchangeItemGetQuantityId: Error in executing DllImport function OmiInputExchangeItemGetQuantityId"); } } public string InputExchangeItemGetElementId(int index) { try { string sExchangeItem = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiInputExchangeItemGetElementId(_pRtcToolsClass, index)); return sExchangeItem; } catch (Exception) { throw new Exception(GetType() + ".InputExchangeItemGetElementId: Error in executing DllImport function OmiInputExchangeItemGetLocation(index " + index + ")"); } } public string InputExchangeItemGetUnit(int index) { try { string sUnit = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiInputExchangeItemGetUnit(_pRtcToolsClass, index)); return sUnit; } catch (Exception) { throw new Exception(GetType() + ".InputExchangeItemGetUnit: Error in executing DllImport function OmiInputExchangeItemGetUnit(index " + index + ")"); } } public int GetOutputExchangeItemCount() { try { return RtcToolsDllNative.OmiGetOutputExchangeItemCount(_pRtcToolsClass); } catch (Exception) { throw new Exception( "RtcToolsDll.GetExchangeItemCount: Error in executing DllImport function OmiGetOutputExchangeItemCount"); } } public string OutputExchangeItemGetQuantityId(int index) { try { string sQuantity = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiOutputExchangeItemGetQuantityId(_pRtcToolsClass, index)); return sQuantity; } catch (Exception) { throw new Exception( "RtcToolsDll.OutputExchangeItemGetQuantityId: Error in executing DllImport function OmiOutputExchangeItemGetQuantityId"); } } public string OutputExchangeItemGetElementId(int index) { try { string sExchangeItem = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiOutputExchangeItemGetElementId(_pRtcToolsClass, index)); return sExchangeItem; } catch (Exception) { throw new Exception(GetType() + ".OutputExchangeItemGetElementId: Error in executing DllImport function OmiOutputExchangeItemGetLocation(index " + index + ")"); } } public string OutputExchangeItemGetUnit(int index) { try { string sUnit = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiOutputExchangeItemGetUnit(_pRtcToolsClass, index)); return sUnit; } catch (Exception) { throw new Exception(GetType() + ".OutputExchangeItemGetUnit: Error in executing DllImport function OmiOutputExchangeItemGetUnit(index " + index + ")"); } } // set values, run, get current time and get values public void SetValue(int index, double value) { try { RtcToolsDllNative.OmiSetInputValue(_pRtcToolsClass, index, value, 1); } catch (Exception) { throw new Exception(GetType() + ".SetValue: Error in executing DllImport function OmiSetInputValue with index " + index); } } /// /// /// /// /// /// public void SetValue(int index, double value, int timeStepCount) { try { RtcToolsDllNative.OmiSetInputValue(_pRtcToolsClass, index, value, timeStepCount); } catch (Exception) { throw new Exception(GetType() + ".SetValue2: Error in executing DllImport function OmiSetInputValue with index " + index); } } public void PerformTimeStep() { try { RtcToolsDllNative.OmiPerformTimeStep(_pRtcToolsClass, 1); } catch (Exception e) { throw new Exception(GetType() + ".PerformTimeStep: Error in executing DllImport function OmiPerformTimeStep"); } } public void PerformTimeStep(int timeStepCount) { try { RtcToolsDllNative.OmiPerformTimeStep(_pRtcToolsClass, timeStepCount); } catch (Exception e) { throw new Exception(GetType() + ".PerformTimeStep2: Error in executing DllImport function OmiPerformTimeStep"); } } public string GetCurrentTimeString() { try { string datetime = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiGetCurrentTimeString(_pRtcToolsClass)); return datetime; } catch (Exception) { throw new Exception(GetType() + ".RtcToolsDll.GetCurrentTimeString: Error in executing DllImport function OmiGetCurrentTimeString"); } } public double GetCurrentTimeAsMJD() { var datetime = GetCurrentTimeString(); var dtCurrentTime = DateTime.Parse(datetime); return Gregorian2ModifiedJulian(dtCurrentTime); } public double GetValue(int index) { double result; try { result = RtcToolsDllNative.OmiGetOutputValue(_pRtcToolsClass, index); } catch (Exception) { throw new Exception(GetType() + ".GetValue: Error in executing DllImport function OmiGetOutputValue(index " + index + ")"); } return result; } public void WriteState(string path, string filename) { ChangeDir(); RtcToolsDllNative.OmiWriteStateFile(_pRtcToolsClass, Marshal.StringToHGlobalAnsi(path), Marshal.StringToHGlobalAnsi(filename)); RestoreDir(); } public void Finish() { ChangeDir(); RtcToolsDllNative.FinishOmiAccessableRtcToolsClass(_pRtcToolsClass); RestoreDir(); } public void Dispose() { ChangeDir(); RtcToolsDllNative.DisposeOmiAccessableRtcToolsClass(_pRtcToolsClass); RestoreDir(); } /// /// Converts a DateTime object to modified julian date /// /// DateTime object /// Modified Julian Date (days since November 17, 1858) public static double Gregorian2ModifiedJulian(DateTime gregorianDate) { long ticks = gregorianDate.Ticks - new DateTime(1858, 11, 17).Ticks; return (double) ticks/((double) TimeSpan.TicksPerDay); } } }