Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorTimeSeriesProcessor.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorTimeSeriesProcessor.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorTimeSeriesProcessor.cs (revision 1591)
@@ -0,0 +1,611 @@
+// Copyright (C) Stichting Deltares 2018. All rights reserved.
+//
+// This file is part of the Dam Engine.
+//
+// The Dam Engine is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Deltares.Dam.Data.Sensors;
+using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStabilityCommon;
+using Deltares.DamEngine.Calculators.PlLinesCreator;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.PlLines;
+using Deltares.DamEngine.Data.General.Sensors;
+using Deltares.DamEngine.Data.General.Specifications;
+using Deltares.DamEngine.Data.General.Specifications.Extensions;
+using Deltares.DamEngine.Data.General.TimeSeries;
+using Deltares.DamEngine.Data.Standard;
+using log4net.Repository.Hierarchy;
+
+namespace Deltares.DamEngine.Calculators.Sensors
+{
+ public class SensorTimeSeriesProcessor : TimeSeriesProcessor
+ {
+ private int seriesCount = 0;
+ private string currentWorkingPath = "";
+ public const double NotCalculatedValue = -999;
+
+ ///
+ /// Specifies a location with valid sensor data. The objects that are satisfied by the
+ /// the specification (predicate) will be used in this processor.
+ /// See ReadSensorDataAndPrepareOutputSeries and Locations.GetBySpecification(p)
+ ///
+ private class LocationsWithSensorData : PredicateSpecification
+ {
+ public LocationsWithSensorData()
+ : base(l => l.HasSensorData && l.SensorData.SensorCount > 0)
+ {
+ }
+ }
+
+ public SensorTimeSeriesProcessor()
+ {
+ Calculator = new SensorLocationSafetyFactorCalculator();
+ OutputParameters = new[] { TimeSerieParameters.StabilityInsideFactor.ToString() };
+ }
+
+ ///
+ /// Gets the output location ID collection used for creating the output time series.
+ /// Setter is not used and will throw an exception when set. Use the Location property instead
+ ///
+ public override IEnumerable OutputLocations
+ {
+ get { return Locations.GetBySpecification(new LocationsWithSensorData()).Select(l => l.Name); }
+ set { throw new SensorTimeSeriesProcessorException("Do not set this property directly. Set the Locations property instead"); }
+ }
+
+ ///
+ /// Gets or sets the locations.
+ ///
+ ///
+ /// The DAM locations.
+ ///
+ public IEnumerable Locations { get; set; }
+
+ ///
+ /// Gets or sets the calculation parameters.
+ ///
+ ///
+ /// The calculation parameters.
+ ///
+ public CalculationParameters CalculationParameters { get; set; }
+
+ ///
+ /// Holds a reference to a dictionary of output date time entries
+ /// The keys represent the time step and the value part of the dictionary represents
+ /// the argument for the calculation
+ ///
+ /// TimeStep -> Location -> (Sensor, Value)
+ ///
+ /// Cardinality:
+ /// 1 -> N -> M
+ ///
+ private readonly IDictionary>> values =
+ new Dictionary>>();
+
+ ///
+ /// Holds a dictionary of time entries and project files that needs to be calculated (per entry a list of files)
+ ///
+ private readonly Dictionary> calculationQueue = new Dictionary>();
+
+ ///
+ /// Processes the actual input to the output collection.
+ /// This is a template method which will be called in the public Process() method of the super class
+ ///
+ protected override void CreateOutputSeries()
+ {
+ values.Clear();
+
+ // Set the output parameters (configured in the calculation parameter modules)
+ OutputParameters = GetFailureMechanisms().Select(GetOutputParameterId).ToList();
+
+ // counter to determine if locations are processed
+ int locationCount = 0;
+
+ var locations = Locations.GetBySpecification(new LocationsWithSensorData());
+ foreach (var location in locations)
+ {
+ PrepareSensorDataLookup(location);
+ InitializeOutputSeries(location);
+ locationCount++;
+ }
+
+ //Logger.LogDebug(string.Format("There are {0} locations with sensor data", locationCount));
+ if (locationCount == 0)
+ {
+ //Logger.LogDebug("No location to process.");
+ return;
+ }
+
+
+ foreach (var series in OutputTimeSeriesCollection.Series)
+ {
+ var failureMechanism = GetFailureMechanismByParameterID(series.ParameterId);
+ switch (failureMechanism)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ CreateStabilityOutputSeries(series);
+ break;
+ case FailureMechanismSystemType.Piping:
+ CreatePipingOutputSeries(series);
+ break;
+ default:
+ throw new SensorTimeSeriesProcessorException(String.Format("Failure mechanism {0} not implemented yet", failureMechanism.ToString()));
+ }
+ }
+ }
+
+ ///
+ /// Creates the piping output series.
+ ///
+ /// The series.
+ private void CreatePipingOutputSeries(TimeSerie series)
+ {
+ throw new NotImplementedException();
+// int entryCount = 0;
+// foreach (var entry in series.Entries)
+// {
+// entryCount++;
+// try
+// {
+// PlLines PlLines = null;
+// var location = Locations.First(l => series.LocationId == l.Name);
+// var sensorValues = values[entry.DateTime][location];
+// var sensorSetup = location.SensorData;
+// var lineTypes = location.SensorData.Sensors.SelectMany(s => s.PlLineMappings).Distinct().ToList();
+//
+// var requiredSafetyFactorPiping = 0.0; // normally only needed for design; it is used here because it is part of the parameterlist of the constructor
+// var modelParametersForPlLines = new ModelParametersForPlLines
+// {
+// PenetrationLength = location.ModelParametersForPlLines.PenetrationLength,
+// DampingFactorPl3 = location.ModelParametersForPlLines.DampingFactorPl3,
+// DampingFactorPl4 = location.ModelParametersForPlLines.DampingFactorPl4,
+// PlLineCreationMethod = location.ModelParametersForPlLines.PlLineCreationMethod
+// };
+// var pipingCalculatorWti2017 = new PipingCalculatorWti2017(modelParametersForPlLines,
+// requiredSafetyFactorPiping, location.GaugePlLines, location.Gauges, location.UpliftCriterionPiping.Value);
+// PlLines = CreateAllPlLines(sensorValues, sensorSetup, lineTypes);
+// double? pipingFactor = pipingCalculatorWti2017.CalculatePipingFactor(location, location.SurfaceLine,
+// location.Segment.GetMostProbableProfile(FailureMechanismSystemType.Piping), PlLines);
+// entry.Value = pipingFactor != null ? pipingFactor.Value: series.MissVal;
+// // entry.Value = CalculationHelper.DetermineSafetyFactor(calculationQueue[entry], ref basisFileName, stabilityExePath);
+// // entry.BasisFileName = Path.GetFileNameWithoutExtension(basisFileName);
+// }
+// catch (Exception e)
+// {
+// var dateTime = entry.DateTime;
+// var message = string.Format("Could not determine safety factor for entry nr. '{0}' and time step '{1}'", entryCount, dateTime);
+// //Logger.LogError(message, e);
+// }
+// }
+ }
+ ///
+ /// Creates the stability output series.
+ ///
+ /// The series.
+ private void CreateStabilityOutputSeries(TimeSerie series)
+ {
+ seriesCount++;
+ int entryCount = 0;
+ bool calculateAllAtOnce = CalculationParameters.CalculateAllAtOnce;
+ currentWorkingPath = Path.Combine(CalculationParameters.StabilityWorkingPath, String.Format("Series{0:000}", seriesCount));
+ string stabilityWorkingPath = Path.GetFullPath(currentWorkingPath);
+ System.IO.Directory.CreateDirectory(stabilityWorkingPath);
+ string stabilityExePath = CalculationParameters.StabilityExePath;
+
+ PrepareStabilityCalculationQueue(series);
+
+ // Calculate all project files
+ if (calculateAllAtOnce)
+ CalculationHelper.CalculateMStabProjects(stabilityWorkingPath, stabilityExePath);
+ foreach (var entry in series.Entries)
+ {
+ entryCount++;
+ try
+ {
+ if (!CalculationParameters.CalculateAllAtOnce)
+ CalculationHelper.CalculateMStabProjects(calculationQueue[entry], stabilityExePath);
+
+ string basisFileName = "";
+ entry.Value = series.MissVal;
+ entry.Value = CalculationHelper.DetermineSafetyFactor(calculationQueue[entry], ref basisFileName,
+ stabilityExePath);
+ entry.BasisFileName = Path.GetFileNameWithoutExtension(basisFileName);
+ }
+ catch (Exception e)
+ {
+ var dateTime = entry.DateTime;
+ var message = string.Format("Could not determine safety factor for entry nr. '{0}' and time step '{1}'",
+ entryCount, dateTime);
+ //Logger.LogError(message, e);
+ }
+ }
+ }
+
+ ///
+ /// Determines whether any of sensor values contains a missing value.
+ ///
+ /// The sensor values.
+ ///
+ ///
+ private bool ContainsMissingValues(IDictionary sensorValues, double missingValue)
+ {
+ foreach (var sensorValue in sensorValues)
+ {
+ if (sensorValues[sensorValue.Key].AlmostEquals(missingValue))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Prepares the calculation queue.
+ ///
+ private void PrepareStabilityCalculationQueue(TimeSerie series)
+ {
+ int entryIndex = 0;
+ foreach (var entry in series.Entries)
+ {
+ entryIndex++;
+
+ IEnumerable files = null;
+ var location = Locations.First(l => series.LocationId == l.Name);
+ var sensorValues = values[entry.DateTime][location];
+ if (!ContainsMissingValues(sensorValues, series.MissVal))
+ {
+ try
+ {
+ //var failureMechanism = GetFailureMechanismByParameterID(series.ParameterId);
+ files = CreateCalculationFiles(location, sensorValues, entryIndex, entry.DateTime).ToList();
+ }
+ catch (SensorPlLineCreatorException se)
+ {
+ throw se;
+ }
+ catch (Exception e)
+ {
+ string msg = string.Format("There was an error while preparing the calculation queue (stability project files)");
+
+ // Logger.LogFatal(msg, e);
+ throw new SensorTimeSeriesProcessorException(msg, e);
+ }
+
+ foreach (var file in files)
+ {
+ if (!calculationQueue.ContainsKey(entry))
+ calculationQueue.Add(entry, new List());
+
+ calculationQueue[entry].Add(file);
+
+ // Logger.LogDebug(string.Format("Project file '{0}' created", file));
+ }
+ }
+ else
+ {
+ //Logger.LogWarning(String.Format("In location '{0}' missing values are found in timestep {1}", location.Name, entry.DateTime));
+ }
+ }
+ }
+
+ ///
+ /// Gets the failure mechanism by parameter ID.
+ ///
+ /// The parameter id.
+ ///
+ private FailureMechanismSystemType GetFailureMechanismByParameterID(string parameterId)
+ {
+ if (string.IsNullOrWhiteSpace(parameterId))
+ throw new ArgumentNullException("parameterId");
+
+ if (parameterId == TimeSerieParameters.StabilityInsideFactor.ToString())
+ return FailureMechanismSystemType.StabilityInside;
+
+ if (parameterId == TimeSerieParameters.StabilityOutsideFactor.ToString())
+ return FailureMechanismSystemType.StabilityOutside;
+
+ if (parameterId == TimeSerieParameters.PipingFactorWti.ToString())
+ return FailureMechanismSystemType.Piping; // #the Here something should be done with piping models
+
+ throw new SensorTimeSeriesProcessorException("There is no failure mechanism mapping for parameterID " + parameterId);
+ }
+
+ ///
+ /// Gets all the supported failure mechanisms based on the calculation modules.
+ ///
+ ///
+ private IEnumerable GetFailureMechanisms()
+ {
+ var calculationModules = CalculationParameters.CalculationModules;
+ if (calculationModules == null)
+ throw new SensorTimeSeriesProcessorException("No calculation modules defined");
+
+ if (calculationModules.StabilityOutside)
+ yield return FailureMechanismSystemType.StabilityOutside;
+
+ if (calculationModules.Stability)
+ yield return FailureMechanismSystemType.StabilityInside;
+
+ if (calculationModules.PipingWti)
+ yield return FailureMechanismSystemType.Piping;
+ // throw new NotImplementedException("Piping WTI 2017 not yet supported");
+
+ if (calculationModules.PipingSellmeijer)
+ throw new NotImplementedException("Piping Sellmeijer not yet supported");
+
+ if (calculationModules.PipingBligh)
+ throw new NotImplementedException("Piping Bligh not yet supported");
+
+ if (calculationModules.PipingSellmeijerProbabilistic)
+ throw new NotImplementedException("Piping Sellmeijer Probabilistic not yet supported");
+
+ if (calculationModules.Overtopping)
+ throw new NotImplementedException("Overtopping not yet supported");
+ }
+
+
+ ///
+ /// Gets the ouput parameter ID.
+ ///
+ /// The type.
+ ///
+ private string GetOutputParameterId(FailureMechanismSystemType type)
+ {
+ switch (type)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ return TimeSerieParameters.StabilityInsideFactor.ToString();
+ case FailureMechanismSystemType.StabilityOutside:
+ return TimeSerieParameters.StabilityOutsideFactor.ToString();
+ case FailureMechanismSystemType.Piping:
+ // #The Piping now only supports 1 model: WTI 2017. But when more piping models are implemented, pipinggmodelType is needed here too!
+ return TimeSerieParameters.PipingFactorWti.ToString();
+ // case FailureMechanismType.PipingSellmeijer:
+ // return TimeSerieParameters.PipingFactorSellmeijer.ToString(); #Bka Piping not yet used. But when used, pipingmodelType is needed here too!
+ default:
+ throw new ArgumentOutOfRangeException("type");
+ }
+ }
+
+ ///
+ /// Creates the calculation files.
+ ///
+ /// The location.
+ /// The sensor values.
+ /// Index of the time entry.
+ /// The entry date time.
+ ///
+ /// No stability parameters set. Processing terminated
+ private IEnumerable CreateCalculationFiles(Location location, IDictionary sensorValues, int timeEntryIndex, DateTime entryDateTime)
+ {
+ var stabilityParams = CalculationParameters.MStabParameters;
+ if (stabilityParams == null)
+ throw new SensorTimeSeriesProcessorException("No stability parameters set. Processing terminated");
+
+ PlLines PlLines = null;
+ bool isCombined = stabilityParams.IsCombinedBishopUpliftVanCalculation;
+
+ var soilGeometry = CalculationHelper.GetSoilGeometryType(location, Path.GetDirectoryName(CalculationParameters.WorkingPath));
+ var sensorSetup = location.SensorData;
+ var lineTypes = location.SensorData.Sensors.SelectMany(s => s.PlLineMappings).Distinct().ToList();
+ //double waterLevel = sensorSetup.GetWaterLevelAtRiver(sensorValues);
+
+ PlLines = CreateAllPlLines(sensorValues, sensorSetup, lineTypes);
+
+ var models = CalculationHelper.GetStabilityModels(isCombined, location, PlLines, soilGeometry.SoilGeometryName, stabilityParams.Model);
+
+ // create all stability project files and return a list of file names.
+ return models.Select(
+ model => CalculationHelper.CreateStabilityProjectFile(
+ new StabilityProjectFileCreationArguments
+ {
+ DikeName = "dike",
+ Location = location,
+ SoilGeometry2DName = soilGeometry.SoilGeometryName,
+ SoilGeometryType = soilGeometry.SoilProfileType,
+ PlLines = PlLines,
+ Model = model,
+ EntryCount = timeEntryIndex,
+ EntryDateTime = entryDateTime,
+ FailureMechanismType = FailureMechanismSystemType.StabilityInside,
+ StabilityWorkingPath = currentWorkingPath,
+ StabilityExePath = CalculationParameters.StabilityExePath,
+ StabilityParameters = CalculationParameters.MStabParameters
+ }));
+ }
+
+ ///
+ /// Creates all the PL lines from the specified sensor values.
+ ///
+ /// The sensor values.
+ /// The sensor setup.
+ /// The line types.
+ /// The pl lines.
+ ///
+ ///
+ private static PlLines CreateAllPlLines(IDictionary sensorValues, SensorLocation sensorSetup, IEnumerable lineTypes)
+ {
+ PlLines PlLines;
+ var creator = SensorPlLineCreator.CreateInstance(sensorSetup, sensorValues, lineTypes);
+ try
+ {
+ PlLines = creator.CreateAllPlLines();
+ }
+ catch (InvalidOperationException e)
+ {
+ throw new SensorPlLineCreatorException(e.Message, e);
+ }
+ return PlLines;
+ }
+
+ ///
+ /// Prepares the output time series and the calculation arguments (sensor data).
+ ///
+ /// The location.
+ private void PrepareSensorDataLookup(Location location)
+ {
+ ThrowIfSensorsAreMissingInInputFile(location);
+
+ // these variable are used to determine differences in time series entries
+ var firstSeriesEntries = new HashSet();
+ bool hasFirstSeriesEntries = false;
+
+ foreach (var sensor in location.SensorData.Sensors)
+ {
+ IEnumerable series = InputTimeSeriesCollection.GetSeriesByLocationId(sensor.Name);
+ ThrowIfSensorNotExists(sensor, series.Any());
+
+ // Prepare the output time series and set sensor values
+ foreach (var timeSeries in series)
+ {
+ ThrowIfTimeEntryCountDontMatch(firstSeriesEntries, timeSeries, hasFirstSeriesEntries);
+
+ foreach (var entry in timeSeries.Entries)
+ {
+ var key = entry.DateTime;
+ if (hasFirstSeriesEntries)
+ {
+ ThrowIfTimeEntriesKeysDontMatch(key, firstSeriesEntries);
+ }
+
+ if (!hasFirstSeriesEntries)
+ {
+ firstSeriesEntries.Add(key);
+ }
+
+ // everything ok set data into internal lookup
+ SetSensorValue(key, entry.Value, sensor, location);
+ }
+ }
+ hasFirstSeriesEntries = true;
+ }
+ }
+
+ ///
+ /// Initializes the output series.
+ ///
+ private void InitializeOutputSeries(Location location)
+ {
+ foreach (var parameterID in OutputParameters)
+ {
+ var firstTimeSeries = InputTimeSeriesCollection.Series.First();
+ var copyOfSeries = firstTimeSeries.GetShallowCopy();
+ foreach (var entry in firstTimeSeries.Entries)
+ {
+ // get copy of the input entry
+ var copyOfEntry = entry.GetShallowCopy();
+
+ // set parameter and location id's and add the projected entry to the output
+ copyOfSeries.LocationId = location.Name;
+ copyOfSeries.ParameterId = parameterID;
+ copyOfSeries.Entries.Add(copyOfEntry);
+ }
+
+ // add the output series to the output collection
+ OutputTimeSeriesCollection.Series.Add(copyOfSeries);
+ }
+ }
+
+ ///
+ /// Sets the sensor value.
+ ///
+ /// The time step.
+ /// The value.
+ /// The sensor.
+ /// The location.
+ private void SetSensorValue(DateTime timeStep, double value, Sensor sensor, Location location)
+ {
+ if (!values.ContainsKey(timeStep))
+ values.Add(timeStep, new Dictionary>());
+
+ if (!values[timeStep].ContainsKey(location))
+ values[timeStep].Add(location, new Dictionary());
+
+ if (values[timeStep][location].ContainsKey(sensor))
+ {
+ var message = string.Format("Values for sensor with id {0} and name {1} and location {2} and time step {3} already exists. Check the time series data.",
+ sensor.ID, sensor.Name, location.Name, timeStep);
+
+ throw new SensorTimeSeriesProcessorException(message);
+ }
+
+ values[timeStep][location].Add(sensor, value);
+ }
+
+ ///
+ /// Throws when the sensor not exists.
+ ///
+ /// The sensor.
+ /// if set to true [has series by sensor ID].
+ private static void ThrowIfSensorNotExists(Sensor sensor, bool hasSeriesBySensorID)
+ {
+ if (!hasSeriesBySensorID)
+ {
+ // TODO log info
+ string message =
+ string.Format("Sensor with name '{0}' and parameter id '{1}' not found in the input time series",
+ sensor.Name, WaterPressureParameterID);
+
+ throw new SensorTimeSeriesProcessorException(message);
+ }
+ }
+
+ private static void ThrowIfTimeEntriesKeysDontMatch(DateTime key, HashSet firstSeriesEntries)
+ {
+ // TODO log info
+ if (!firstSeriesEntries.Contains(key))
+ throw new SensorTimeSeriesProcessorException(
+ "Invalid data in time series entries. Time entries (date time values) don't match");
+ }
+
+ private static void ThrowIfTimeEntryCountDontMatch(HashSet firstSeriesEntries, TimeSerie timeSeries,
+ bool hasFirstSeriesEntries)
+ {
+ if (hasFirstSeriesEntries)
+ {
+ // TODO log info
+ if (timeSeries.Entries.Count != firstSeriesEntries.Count)
+ throw new SensorTimeSeriesProcessorException(
+ "Invalid data in time series entries. Number of entries differ on each sensor");
+ }
+ }
+
+ private void ThrowIfSensorsAreMissingInInputFile(Location location)
+ {
+ var sensorsNotFound = (
+ from sensor in location.SensorData.Sensors
+ let series = InputTimeSeriesCollection.GetSeriesByLocationId(sensor.Name)
+ where !series.Any()
+ select sensor.Name).ToList();
+
+ if (sensorsNotFound.Any())
+ {
+ // TODO log info
+ string message =
+ string.Format("Sensor with name '{0}' and parameter id '{1}' not found in the input time series",
+ string.Join(", ", sensorsNotFound.ToArray()), WaterPressureParameterID);
+
+ throw new SensorTimeSeriesProcessorException(message);
+ }
+ }
+ }
+}
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/Resources.Designer.cs
===================================================================
diff -u -r1387 -r1591
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 1387)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 1591)
@@ -61,6 +61,15 @@
}
///
+ /// Looks up a localized string similar to The file name is not valid. Maybe due to a null or empty string and or invalid characters. Please use a valid file name.
+ ///
+ internal static string FileNameNotValid {
+ get {
+ return ResourceManager.GetString("FileNameNotValid", resourceCulture);
+ }
+ }
+
+ ///
/// Looks up a localized string similar to GetCotangentOfInnerSlope requires either of characteristic points ShoulderBaseInside or DikeToeAtPolder to be defined..
///
internal static string GetCotangentOfInnerSlopeDikeToeAtPolderRequired {
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Location.cs
===================================================================
diff -u -r1581 -r1591
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Location.cs (.../Location.cs) (revision 1581)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Location.cs (.../Location.cs) (revision 1591)
@@ -1603,5 +1603,19 @@
var factory = new SensorFactory();
SensorData = factory.CreateSensorLocation(this);
}
+ ///
+ /// Creates an instance of model parameters for pl lines.
+ ///
+ ///
+ public ModelParametersForPlLines CreateModelParametersForPlLines()
+ {
+ return new ModelParametersForPlLines
+ {
+ PenetrationLength = ModelParametersForPlLines.PenetrationLength,
+ DampingFactorPl3 = ModelParametersForPlLines.DampingFactorPl3,
+ DampingFactorPl4 = ModelParametersForPlLines.DampingFactorPl4,
+ PlLineCreationMethod = ModelParametersForPlLines.PlLineCreationMethod
+ };
+ }
}
}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorLocationSafetyFactorCalculator.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorLocationSafetyFactorCalculator.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorLocationSafetyFactorCalculator.cs (revision 1591)
@@ -0,0 +1,59 @@
+// Copyright (C) Stichting Deltares 2018. All rights reserved.
+//
+// This file is part of the Dam Engine.
+//
+// The Dam Engine is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.IO;
+using Deltares.DamEngine.Calculators.Sensors;
+using CalculationHelper = Deltares.DamEngine.Calculators.Sensors.CalculationHelper;
+
+namespace Deltares.Dam.Data.Sensors
+{
+ public class SensorLocationSafetyFactorCalculator : ICalculator
+ {
+ //internal LogHelper Logger = LogHelper.Create();
+ public const double NoValue = -999.99;
+
+ #region ICalculate Member
+
+ double? ICalculator.Calculate(params object[] args)
+ {
+ var arg = args[0] as SensorCalculationArgument;
+ if (arg != null)
+ return Calculate(arg);
+
+ return NoValue;
+ }
+
+ #endregion
+
+ public double? Calculate(SensorCalculationArgument args)
+ {
+ if (args == null) throw new ArgumentNullException("args");
+
+ string stabilityWorkingPath = Path.GetFullPath(args.StabilityWorkingPath);
+ CalculationHelper.CalculateMStabProjects(stabilityWorkingPath, args.StabilityExePath);
+
+ return NoValue;
+ }
+ }
+
+
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/Resources.resx
===================================================================
diff -u -r1387 -r1591
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/Resources.resx (.../Resources.resx) (revision 1387)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/Resources.resx (.../Resources.resx) (revision 1591)
@@ -117,6 +117,9 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ The file name is not valid. Maybe due to a null or empty string and or invalid characters. Please use a valid file name
+
GetCotangentOfInnerSlope requires either of characteristic points ShoulderBaseInside or DikeToeAtPolder to be defined.
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/TimeSerieCalculationException.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/TimeSerieCalculationException.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/TimeSerieCalculationException.cs (revision 1591)
@@ -0,0 +1,32 @@
+// Copyright (C) Stichting Deltares 2018. All rights reserved.
+//
+// This file is part of the Dam Engine.
+//
+// The Dam Engine is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+
+namespace Deltares.DamEngine.Calculators.Sensors
+{
+ public class TimeSerieCalculationException : Exception
+ {
+ public TimeSerieCalculationException(string message) : base(message)
+ {
+ }
+ }
+}
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/CalculationParameters.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/CalculationParameters.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/CalculationParameters.cs (revision 1591)
@@ -0,0 +1,71 @@
+// Copyright (C) Stichting Deltares 2018. All rights reserved.
+//
+// This file is part of the Dam Engine.
+//
+// The Dam Engine is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.IO;
+using Deltares.DamEngine.Data.General;
+
+namespace Deltares.DamEngine.Calculators.Sensors
+{
+ public class CalculationModules
+ {
+ public bool Stability { get; set; }
+ public bool StabilityOutside { get; set; }
+ public bool PipingWti { get; set; }
+ public bool PipingBligh { get; set; }
+ public bool PipingSellmeijer { get; set; }
+ public bool PipingSellmeijerProbabilistic { get; set; }
+ public bool PipingIJkdijk { get; set; }
+ public bool Overtopping { get; set; }
+ }
+
+ public class CalculationParameters
+ {
+ public string WorkingPath { get; set; }
+ public string StabilityWorkingPath { get; set; }
+ public string PipingWorkingPath { get; set; }
+ public string StabilityExePath { get; set; }
+
+ public bool CalculateAllAtOnce
+ {
+ get { return MStabParameters == null || MStabParameters.IsCalculateAllStabilityProjectsAtOnce; }
+ set { MStabParameters.IsCalculateAllStabilityProjectsAtOnce = value; }
+ }
+
+ public static CalculationParameters LoadFromFile(FileInfo xmlFile)
+ {
+ return LoadFromFile(xmlFile.FullName);
+ }
+
+ public static CalculationParameters LoadFromFile(string xmlFileName)
+ {
+ throw new NotImplementedException();
+// if (string.IsNullOrWhiteSpace(xmlFileName)) throw new ArgumentException("xmlFileName");
+//
+// XDocument calculationParametersFileDocument = XDocument.Load(xmlFileName);
+// var assembler = new CalculationParametersAssembler();
+// return assembler.CreateDomainObject(calculationParametersFileDocument);
+ }
+
+ public CalculationModules CalculationModules { get; set; }
+ public MStabParameters MStabParameters { get; set; }
+ }
+}
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorTimeSeriesProcessorException.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorTimeSeriesProcessorException.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorTimeSeriesProcessorException.cs (revision 1591)
@@ -0,0 +1,48 @@
+// Copyright (C) Stichting Deltares 2018. All rights reserved.
+//
+// This file is part of the Dam Engine.
+//
+// The Dam Engine is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Deltares.DamEngine.Calculators.Sensors
+{
+ [Serializable]
+ public class SensorTimeSeriesProcessorException : Exception
+ {
+ public SensorTimeSeriesProcessorException()
+ {
+ }
+
+ public SensorTimeSeriesProcessorException(string message) : base(message)
+ {
+ }
+
+ public SensorTimeSeriesProcessorException(string message, Exception inner) : base(message, inner)
+ {
+ }
+
+ protected SensorTimeSeriesProcessorException(
+ SerializationInfo info,
+ StreamingContext context) : base(info, context)
+ {
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ThrowHelper.cs
===================================================================
diff -u -r1040 -r1591
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ThrowHelper.cs (.../ThrowHelper.cs) (revision 1040)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ThrowHelper.cs (.../ThrowHelper.cs) (revision 1591)
@@ -20,6 +20,9 @@
// All rights reserved.
using System;
+using System.Resources;
+using Deltares.DamEngine.Data;
+using Deltares.DamEngine.Data.Properties;
namespace Deltares.DamEngine.Data.Standard
{
@@ -55,5 +58,34 @@
throw new ArgumentNullException(message);
}
+ ///
+ /// Throws if file name null or empty.
+ ///
+ /// Name of the file.
+ internal static void ThrowIfFileNameNullOrEmpty(string fileName)
+ {
+ ThrowIfFileNameNullOrEmpty(fileName, Resources.FileNameNotValid);
+ }
+ ///
+ /// Throws if file name null or empty.
+ ///
+ /// Name of the file.
+ /// The message.
+ internal static void ThrowIfFileNameNullOrEmpty(string fileName, string message)
+ {
+ ThrowIfFileNameNullOrEmpty(fileName, message);
+ }
+ ///
+ /// Throws if file name null or empty.
+ ///
+ /// The type of the exception.
+ /// Name of the file.
+ /// The message.
+ internal static void ThrowIfFileNameNullOrEmpty(string fileName, string message)
+ where TException : Exception
+ {
+ ThrowWhenConditionIsTrue(message,
+ () => string.IsNullOrEmpty(fileName) || fileName.Trim() == "");
+ }
}
}
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/ICalculator.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/ICalculator.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/ICalculator.cs (revision 1591)
@@ -0,0 +1,33 @@
+// Copyright (C) Stichting Deltares 2018. All rights reserved.
+//
+// This file is part of the Dam Engine.
+//
+// The Dam Engine is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+namespace Deltares.DamEngine.Calculators.Sensors
+{
+ public interface ICalculator
+ {
+ double? Calculate(params object[] args);
+ }
+
+ public interface ICalculator : ICalculator
+ {
+ double? Calculate(T args);
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj
===================================================================
diff -u -r1586 -r1591
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 1586)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 1591)
@@ -159,6 +159,15 @@
Resources.resx
+
+
+
+
+
+
+
+
+
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/TimeSeriesProcessor.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/TimeSeriesProcessor.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/TimeSeriesProcessor.cs (revision 1591)
@@ -0,0 +1,202 @@
+// Copyright (C) Stichting Deltares 2018. All rights reserved.
+//
+// This file is part of the Dam Engine.
+//
+// The Dam Engine is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using Deltares.DamEngine.Data.General.TimeSeries;
+using Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Calculators.Sensors
+{
+ public abstract class TimeSeriesProcessor
+ {
+// internal readonly static LogHelper Logger = LogHelper.Create("Time Series Processor");
+
+ #region Constants
+
+ ///
+ /// Defines the default output file
+ ///
+ private const string DefaultOutputFileName = "output.xml";
+
+ /// e
+ /// Defines the water level location id used in the FEWS time serie
+ ///
+ public const string WaterLevelInputLocationID = "outside";
+
+ ///
+ /// Defines the parameter id of the water level defined in the FEWS time serie
+ ///
+ public const string WaterLevelInputParameterID = "Waterlevel";
+
+ ///
+ /// Defines the parameter id for water pressure used in the FEWS time serie
+ ///
+ public const string WaterPressureParameterID = "Waterpressure";
+
+ ///
+ /// Defines the sensor state missing value
+ ///
+ internal const double MissingValue = -999;
+
+ #endregion
+
+ public ICalculator Calculator { protected get; set; }
+
+ ///
+ /// Gets or sets the output parameter ID.
+ ///
+ /// This name or ID is used in the output (FEWS) time series
+ ///
+ /// The output parameter ID.
+ ///
+ public IEnumerable OutputParameters { get; set; }
+
+ ///
+ /// Sets the input time series, used in the calculations
+ ///
+ public TimeSerieCollection InputTimeSeriesCollection { protected get; set; }
+
+ ///
+ /// Gets or sets the output location ID colletion used for creating the output time series
+ ///
+ public virtual IEnumerable OutputLocations { get; set; }
+
+ ///
+ /// Gets or the output time series
+ ///
+ public TimeSerieCollection OutputTimeSeriesCollection { get; set; }
+
+ ///
+ /// Resets the monitoring point list
+ ///
+ public virtual void Initialize()
+ {
+ if (OutputTimeSeriesCollection == null)
+ OutputTimeSeriesCollection = InputTimeSeriesCollection.GetShallowCopy();
+ else
+ OutputTimeSeriesCollection.Clear();
+ }
+
+ ///
+ /// Loads the input time series.
+ ///
+ /// Name of the file.
+ public void LoadInputTimeSeries(string fileName)
+ {
+ throw new NotImplementedException();
+// ThrowHelper.ThrowIfFileNameNullOrEmpty(fileName);
+// try
+// {
+// // load the input time serie containing all water levels
+// InputTimeSeriesCollection = TimeSerieCollection.LoadFromFile(fileName);
+// }
+// catch (Exception e)
+// {
+// throw new InvalidOperationException("There was an error loading the input time series", e);
+// }
+ }
+
+ ///
+ /// Saves the output time series to the specified file
+ ///
+ ///
+ /// The output file that will contain the monitored and calculated results for each time entry
+ public void SaveResultsToFile(string fileName)
+ {
+ throw new NotImplementedException();
+// if (OutputTimeSeriesCollection == null)
+// throw new InvalidOperationException("No output time series collection to write");
+//
+// if (string.IsNullOrWhiteSpace(fileName))
+// {
+// fileName = DefaultOutputFileName;
+// }
+//
+// // save the time serie to the output file
+// OutputTimeSeriesCollection.Save(fileName);
+ }
+
+ ///
+ /// Processes the FEWS input time series files to ouput
+ /// time series
+ ///
+ public virtual void Process()
+ {
+ if (InputTimeSeriesCollection == null)
+ return;
+
+ if (OutputTimeSeriesCollection == null)
+ throw new InvalidOperationException("No output time series set to write the results to");
+
+ if (OutputLocations == null)
+ throw new InvalidOperationException("No output locations set. Set or override OutputLocations");
+
+ if (OutputParameters == null)
+ throw new InvalidOperationException("No output parameters set. Set or override OutputParameters");
+
+ try
+ {
+ // Process the time series entries for each sensor and set the
+ // value in the output time series
+ CreateOutputSeries();
+ }
+ catch (Exception e)
+ {
+ const string message = "There was an error processing the time series";
+ // Logger.LogFatal(message, e);
+ throw new InvalidOperationException(message, e);
+ }
+ }
+
+ ///
+ /// Processes the actual input to the output collection. This is a template method which will
+ /// be called in the public ProcessSeries() method (if not overriden)
+ ///
+ protected virtual void CreateOutputSeries()
+ {
+ foreach (var timeSeries in InputTimeSeriesCollection.Series)
+ {
+ foreach (var location in OutputLocations)
+ {
+ foreach (var parameter in OutputParameters)
+ {
+ var copyOfSeries = timeSeries.GetShallowCopy();
+ foreach (var entry in timeSeries.Entries)
+ {
+ // get copy of the input entry
+ var copyOfEntry = entry.GetShallowCopy();
+ // calculate its value
+ copyOfEntry.Value = Calculator.Calculate(location, parameter) ?? MissingValue;
+
+ // set parameter and location id's and add the projected entry to the output
+ copyOfSeries.LocationId = location;
+ copyOfSeries.ParameterId = parameter;
+ copyOfSeries.Entries.Add(copyOfEntry);
+ }
+ // add the output series to the output collection
+ OutputTimeSeriesCollection.Series.Add(copyOfSeries);
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorCalculationArgument.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorCalculationArgument.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/SensorCalculationArgument.cs (revision 1591)
@@ -0,0 +1,29 @@
+// Copyright (C) Stichting Deltares 2018. All rights reserved.
+//
+// This file is part of the Dam Engine.
+//
+// The Dam Engine is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+namespace Deltares.DamEngine.Calculators.Sensors
+{
+ public class SensorCalculationArgument
+ {
+ public string StabilityWorkingPath { get; set; }
+ public string StabilityExePath { get; set; }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/TimeSerieCalculationHelper.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/TimeSerieCalculationHelper.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Sensors/TimeSerieCalculationHelper.cs (revision 1591)
@@ -0,0 +1,500 @@
+// Copyright (C) Stichting Deltares 2018. All rights reserved.
+//
+// This file is part of the Dam Engine.
+//
+// The Dam Engine is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Xml.Linq;
+using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStabilityCommon.Assemblers;
+using Deltares.DamEngine.Calculators.Stability;
+using Deltares.DamEngine.Calculators.Uplift;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.PlLines;
+using Deltares.DamEngine.Data.General.Results;
+using Deltares.DamEngine.Data.Geotechnics;
+
+namespace Deltares.DamEngine.Calculators.Sensors
+{
+ public class StabilityProjectFileCreationArguments
+ {
+ public string DikeName { get; set; }
+ public Location Location { get; set; }
+ public int EntryCount { get; set; }
+ public DateTime EntryDateTime { get; set; }
+ public MStabModelType Model { get; set; }
+ public string StabilityWorkingPath { get; set; }
+ public string SoilGeometry2DName { get; set; }
+ public SoilProfileType SoilGeometryType { get; set; }
+ public PlLines PlLines { get; set; }
+ public FailureMechanismSystemType FailureMechanismType { get; set; }
+ public MStabParameters StabilityParameters { get; set; }
+ public string StabilityExePath { get; set; }
+ }
+
+ internal class CalculationHelper
+ {
+ internal static string CreateStabilityProjectFile(StabilityProjectFileCreationArguments arg)
+ {
+ throw new NotImplementedException();
+// var location = arg.Location;
+// var model = arg.Model;
+//
+// var fileName = GetProjectFileName(arg.DikeName, location, null, model, arg.StabilityWorkingPath, arg.EntryDateTime);
+//
+// // get all the parameters needed for the calculation
+// var damCalculation = GetCalculationSpecification(arg, fileName);
+//
+// // Create the project file
+// CreateMStabProjectFile(damCalculation.FailureMechanismeParamatersMStab, arg.StabilityExePath);
+//
+// return fileName;
+ }
+
+
+ internal static IEnumerable GetStabilityModels(bool isCombinedBishopUpliftVan, Location location, PlLines PlLines, string soilGeometry2DName, MStabModelType defaultModel)
+ {
+ double? upliftFactor = GetLowestUpliftFactor(location.SurfaceLine,
+ location.Segment.GetMostProbableProfile(FailureMechanismSystemType.StabilityInside), soilGeometry2DName, PlLines, location);
+ return !isCombinedBishopUpliftVan ? new List { defaultModel } : GetMStabModelsToCalculate(upliftFactor);
+ }
+
+ internal static DamFailureMechanismeCalculationSpecification GetCalculationSpecification(StabilityProjectFileCreationArguments arguments, string projectFileName)
+ {
+ throw new NotImplementedException();
+// return GetCalculationSpecification(arguments.FailureMechanismType, arguments.Location,
+// arguments.SoilGeometry2DName, arguments.SoilGeometryType,
+// arguments.PlLines, arguments.StabilityParameters, arguments.Model,
+// arguments.Location.SoildatabaseName, projectFileName);
+ }
+
+ internal static DamFailureMechanismeCalculationSpecification GetCalculationSpecification(
+ FailureMechanismSystemType failureMechanismType,
+ Location location, string soilGeometry2DName,
+ SoilProfileType soilProfileType,
+ PlLines PlLines,
+ MStabParameters mstabParameters, MStabModelType model,
+ string soilDatabasePath, string projectFileName)
+ {
+ // Note: local use of new calculationSpecification for now ok but might be unwanted in future when you want to use multiple specifications
+ var calculationSpecification = new DamFailureMechanismeCalculationSpecification();
+ BuildDamCalculation(failureMechanismType, location, soilGeometry2DName, soilProfileType, PlLines, mstabParameters, model, calculationSpecification, soilDatabasePath, projectFileName);
+ return calculationSpecification;
+ }
+
+ ///
+ /// Fill damCalculation with the appropriate values
+ ///
+ internal static void BuildDamCalculation(FailureMechanismSystemType failureMechanismType, Location location, string soilGeometry2DName, SoilProfileType soilGeometryType,
+ PlLines PlLines,
+ MStabParameters mstabParameters, MStabModelType model,
+ DamFailureMechanismeCalculationSpecification damCalculation, string soilDatabasePath, string projectFileName)
+ {
+ throw new NotImplementedException();
+// damCalculation.FailureMechanismeParamatersMStab =
+// new FailureMechanismeParamatersMStab
+// {
+// Location = location,
+// SurfaceLine = location.LocalXZSurfaceLine2,
+// PlLines = PlLines,
+// DupuitPlLines = dupuitPlLines,
+// SoilProfile = location.Segment.GetMostProbableProfile(FailureMechanismSystemType.StabilityInside),
+// TrafficLoad = location.TrafficLoad,
+// MStabParameters =
+// new MStabParameters
+// {
+// SoilDatabaseName = soilDatabasePath,
+// Model = model,
+// ProjectFileName = projectFileName,
+// GeometryCreationOptions =
+// {
+// SoilProfileType = soilGeometryType,
+// SoilGeometry2DFilename = soilGeometry2DName,
+// MaterialForDike = location.DikeEmbankmentMaterial,
+// MaterialForShoulder = location.ShoulderEmbankmentMaterial,
+// XOffsetSoilGeometry2DOrigin = -location.XSoilGeometry2DOrigin,
+// IsUseOriginalPlLineAssignments = location.IsUseOriginalPlLineAssignments
+// }
+// }
+// };
+// damCalculation.FailureMechanismeParamatersMStab.MStabParameters.GridPosition =
+// failureMechanismType == FailureMechanismSystemType.StabilityOutside ? MStabGridPosition.Left : MStabGridPosition.Right;
+//
+// MStabParameters parameters = damCalculation.FailureMechanismeParamatersMStab.MStabParameters;
+// parameters.GeometryCreationOptions.PlLineAssignment = PlLineCreationMethod2PlLineAssignment(location.PlLineCreationMethod);
+// if (location.IsUseOriginalPlLineAssignments)
+// parameters.GeometryCreationOptions.PlLineAssignment = PlLineAssignment.OrginalPlLines;
+// parameters.GeometryCreationOptions.IntrusionVerticalWaterPressureType = location.IntrusionVerticalWaterPressure.Value;
+// parameters.GeometryCreationOptions.PenetrationLength = location.PenetrationLength;
+// switch (failureMechanismType)
+// {
+// case FailureMechanismSystemType.StabilityOutside:
+// parameters.GridPosition = MStabGridPosition.Left;
+// break;
+// default:
+// parameters.GridPosition = MStabGridPosition.Right;
+// break;
+// }
+//
+// parameters.ShearStrength = mstabParameters.ShearStrength;
+// parameters.IsProbabilistic = mstabParameters.IsProbabilistic;
+// parameters.SearchMethod = mstabParameters.SearchMethod;
+// parameters.CalculationOptions = mstabParameters.CalculationOptions;
+// parameters.CalculationOptions.MinimalCircleDepth = location.MinimalCircleDepth;
+//
+// if (location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope == null)
+// {
+// location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope = 1.0;
+// }
+//
+// parameters.ZoneAreas = new MStabZoneAreas
+// {
+// SafetyFactorZone1A = location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope.Value,
+// SafetyFactorZone1B = location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope.Value,
+// DikeTableHeight = location.SurfaceLine.GetDefaultDikeTableHeight().Value,
+// DikeTableWidth = location.ZoneAreaRestSlopeCrestWidth,
+// XCoordinateDikeTopAtPolder = location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X,
+// XCoordinateDikeTopAtRiver = location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X,
+// XCoordinateStartRestProfile = location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X
+// };
+//
+// // Slip circle definition for Uplift Van; TODO: Combine with code in StabilityCalculation
+// parameters.SlipCircleDefinition.Assign(mstabParameters.SlipCircleDefinition);
+// if (parameters.Model == MStabModelType.UpliftVan)
+// {
+// // Determine right side of slip plane grid (right grid)
+// // This is the location with the lowest uplift factor or, if present, the second NWO point
+// SurfaceLine2 surfaceLine = location.SurfaceLine;
+// var upliftLocationAndResult = GetLocationWithLowestUpliftFactor(surfaceLine, location.Segment.GetMostProbableProfile(FailureMechanismSystemType.StabilityInside), soilGeometry2DName, PlLines, location);
+// double upliftCriterion = location.UpliftCriterionStability.Value;
+// bool isUplift = !(upliftLocationAndResult == null) && (upliftLocationAndResult.UpliftFactor < upliftCriterion);
+// double xCoordinateLastUpliftPoint = isUplift ? upliftLocationAndResult.X : surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X;
+//// if (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint2) != null)
+//// {
+//// xCoordinateLastUpliftPoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint2).X;
+//// }
+// parameters.SlipCircleDefinition.XCoordinateLastUpliftPoint = xCoordinateLastUpliftPoint;
+// }
+//
+// if (parameters.CalculationOptions.ZonesType.Equals(MStabZonesType.ForbiddenZone))
+// {
+// var surfaceLine = damCalculation.FailureMechanismeParamatersMStab.SurfaceLine;
+// double maxZoneX = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X +
+// location.ForbiddenZoneFactor * (surfaceLine.GetDikeToeInward().X - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X);
+// parameters.ForbiddenZone = new MStabForbiddenZone
+// {
+// IsXEntryMinUsed = false,
+// XEntryMin = 0.0,
+// IsXEntryMaxUsed = true,
+// XEntryMax = maxZoneX
+// };
+// }
+ }
+
+ ///
+ /// Converts PlLineCreationMethod (from location) to PlLineAssignment
+ ///
+ /// The pl line creation method.
+ /// the pl line assignment method
+ public static PlLineAssignment PlLineCreationMethod2PlLineAssignment(PlLineCreationMethod PlLineCreationMethod)
+ {
+ PlLineAssignment PlLineAssignment = PlLineAssignment.ExpertKnowledge;
+ switch (PlLineCreationMethod)
+ {
+// case PlLineCreationMethod.DupuitDynamic:
+// case PlLineCreationMethod.DupuitStatic:
+// PlLineAssignment = PlLineAssignment.DikeFlow;
+// break;
+ case PlLineCreationMethod.ExpertKnowledgeRRD:
+ case PlLineCreationMethod.ExpertKnowledgeLinearInDike:
+ case PlLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD:
+ PlLineAssignment = PlLineAssignment.ExpertKnowledge;
+ break;
+ }
+ return PlLineAssignment;
+ }
+
+ ///
+ /// Gets the location with lowest uplift factor.
+ ///
+ /// The surface line.
+ /// The soil profile.
+ /// Name of the soil geometry2 D.
+ /// The pl lines.
+ /// The location.
+ ///
+ static public UpliftLocationAndResult GetLocationWithLowestUpliftFactor(SurfaceLine2 surfaceLine, SoilProfile1D soilProfile, string soilGeometry2DName, PlLines PlLines, Location location)
+ {
+ throw new NotImplementedException();
+// UpliftLocationDeterminator upliftLocationDeterminator = new UpliftLocationDeterminator()
+// {
+// SurfaceLine = surfaceLine,
+// SoilProfile = soilProfile,
+// SoilGeometry2DName = soilGeometry2DName,
+// SoilBaseDB = location.SoilbaseDB,
+// SoilList = location.SoilList,
+// DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(),
+// PlLines = PlLines,
+// XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin
+// };
+// return upliftLocationDeterminator.GetLocationAtWithLowestUpliftFactor();
+ }
+
+ ///
+ /// Calculate all generated MStab files
+ ///
+ ///
+ ///
+ internal static void CalculateMStabProjects(string directory, string mstabExePath)
+ {
+ throw new NotImplementedException();
+// var agent = new StabilityServiceAgent { MStabExePath = mstabExePath };
+// agent.CalculateMStabDirectory(directory);
+ }
+
+ ///
+ /// Calculate all generated MStab files
+ ///
+ internal static void CalculateMStabProjects(IEnumerable projectFilenames, string stabilityExePath)
+ {
+ throw new NotImplementedException();
+// var agent = new StabilityServiceAgent { MStabExePath = stabilityExePath };
+// foreach (string mstabProjectFilename in projectFilenames)
+// {
+// string mstabProjectFullFilename = Path.GetFullPath(mstabProjectFilename);
+// agent.CalculateMStabProject(mstabProjectFullFilename);
+// }
+ }
+
+ ///
+ /// Determine name of Stability project file
+ ///
+ internal static string GetProjectFileName(string dikeName, Location location, int? jobCount, MStabModelType? model, string stabilityWorkingPath, DateTime? dateTime)
+ {
+ string calculationName = String.Format("Dik({0})_Loc({1})", dikeName, location.Name);
+ if (jobCount != null)
+ {
+ calculationName = calculationName + String.Format("_Stp({0})", jobCount);
+ }
+ if (model != null)
+ {
+ calculationName = calculationName + String.Format("_Mdl({0})", model);
+ }
+ if (dateTime != null)
+ {
+ calculationName = calculationName + "_" + DateToTimeStamp(dateTime.Value);
+ }
+ calculationName = Regex.Replace(calculationName, @"[\\\/:\*\?""'<>|.]", "_");
+ // assemble the target project file name
+ return Path.Combine(stabilityWorkingPath, calculationName + ".sti");
+ }
+
+ ///
+ /// Convert Date to time stamp as needed by TNO AnySense.
+ ///
+ /// The date time.
+ ///
+ public static string DateToTimeStamp(DateTime dateTime)
+ {
+ // Following 2 lines is an example how to handle customization of this format.
+ // TNO at the last moment decided they did not need this change so we change it back to
+ // the default format
+ // string customFormat = "yyyy-MM-dd_HH-mm-ss";
+ // return dateTime.ToString(customFormat);
+ return dateTime.ToString("s", DateTimeFormatInfo.InvariantInfo);
+ }
+
+ ///
+ /// Select which models to calculate dependent on uplift factor
+ ///
+ internal static IList GetMStabModelsToCalculate(double? upliftFactor)
+ {
+ const double CBishopMinimum = 1.0;
+ const double CLiftVanMaximum = 1.2;
+
+ var models = new List();
+
+ if (!upliftFactor.HasValue || upliftFactor >= CBishopMinimum)
+ models.Add(MStabModelType.Bishop);
+ if (!upliftFactor.HasValue || upliftFactor <= CLiftVanMaximum)
+ models.Add(MStabModelType.UpliftVan);
+
+ return models;
+ }
+
+ ///
+ /// Determine where lowest uplift factor occurs and the value of that factor
+ ///
+ internal static double? GetLowestUpliftFactor(SurfaceLine2 surfaceLine, SoilProfile1D soilProfile, string soilGeometry2DName, PlLines PlLines, Location location)
+ {
+ throw new NotImplementedException();
+// var upliftLocationDeterminator = new UpliftLocationDeterminator()
+// {
+// SurfaceLine = surfaceLine,
+// SoilProfile = soilProfile,
+// SoilGeometry2DName = soilGeometry2DName,
+// SoilBaseDB = location.SoilbaseDB,
+// SoilList = location.SoilList,
+// DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(),
+// PlLines = PlLines,
+// XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin
+// };
+//
+// UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationAtWithLowestUpliftFactor();
+// if (upliftLocationAndResult != null)
+// return upliftLocationAndResult.UpliftFactor;
+//
+// return null;
+ }
+
+ ///
+ /// Creates all PL lines.
+ ///
+ /// The water level.
+ /// The location.
+ /// Name of the soil geometry2 D.
+ /// Type of the soil geometry.
+ ///
+ internal static PlLines CreateAllPlLines(double waterLevel, Location location, string soilGeometry2DName, SoilProfileType soilGeometryType)
+ {
+ // When calculating with timeseries, we want PL3 and PL4 to derive the head from the waterlevel.
+ // We can force that by overruling the location HeadPl3 and HeadPl4 with null,
+ // because then in PlLinesCreator the waterlevel is used as head for Pl3 and Pl4
+ // for stability this must set to true
+ var PlLinesCreator = new PlLinesCreator.PlLinesCreator
+ {
+ WaterLevelRiverHigh = waterLevel,
+ SurfaceLine = location.SurfaceLine,
+ WaterLevelPolder = location.PolderLevel,
+ HeadInPlLine2 = location.HeadPl2,
+ HeadInPlLine3 = null,
+ HeadInPlLine4 = null,
+ ModelParametersForPlLines = location.CreateModelParametersForPlLines(),
+ SoilProfile = location.Segment.GetMostProbableProfile(FailureMechanismSystemType.StabilityInside),
+ SoilGeometry2DName = soilGeometry2DName,
+ SoilProfileType = soilGeometryType,
+ GaugePlLines = location.GaugePlLines,
+ Gauges = location.Gauges,
+ GaugeMissVal = location.GaugeMissVal,
+ IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true,
+ PlLineOffsetBelowDikeTopAtRiver = location.PlLineOffsetBelowDikeTopAtRiver,
+ PlLineOffsetBelowDikeTopAtPolder = location.PlLineOffsetBelowDikeTopAtPolder,
+ PlLineOffsetBelowDikeCrestMiddle = location.PlLineOffsetBelowDikeCrestMiddle,
+ PlLineOffsetFactorBelowShoulderCrest = location.PlLineOffsetFactorBelowShoulderCrest,
+ UsePlLineOffsetBelowDikeCrestMiddle = location.UsePlLineOffsetBelowDikeCrestMiddle,
+ UsePlLineOffsetFactorBelowShoulderCrest = location.UsePlLineOffsetFactorBelowShoulderCrest,
+// SoilBaseDB = location.SoilbaseDB,
+ SoilList = location.SoilList,
+ DikeEmbankmentMaterial = location.SoilList.GetSoilByName(location.DikeEmbankmentMaterial),
+ XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin
+ };
+
+ PlLines PlLines = PlLinesCreator.CreateAllPlLines(location);
+ return PlLines;
+ }
+
+ ///
+ /// Create and write the XML definiton file for the MStab project
+ /// Call the stability agent to create the stability project file
+ ///
+ internal static void CreateMStabProjectFile()//FailureMechanismeParamatersMStab failureMechanismeParamatersMStab, string stabilityExePath)
+ {
+ throw new NotImplementedException();
+// var assembler = new DamMStabAssembler();
+// XDocument xDocument = assembler.CreateDataTransferObject(failureMechanismeParamatersMStab);
+// var fileName = failureMechanismeParamatersMStab.MStabParameters.ProjectFileName + ".xml";
+// xDocument.Save(fileName);
+//
+// // call the stability agent to create a MStab specific (xml) file
+// var agent = new StabilityServiceAgent { MStabExePath = stabilityExePath };
+// agent.CreateProjectFile(xDocument.ToString());
+ }
+
+ ///
+ /// Determine the minimal safety factor for a set of MStab projects
+ ///
+ internal static double DetermineSafetyFactor(IEnumerable mstabProjectPaths, ref string basisFileName, string stabilityExePath)
+ {
+ throw new NotImplementedException();
+// var agent = new StabilityServiceAgent { MStabExePath = stabilityExePath };
+//
+// double? minimumSafetyFactor = null;
+//
+// foreach (string path in mstabProjectPaths)
+// {
+// MStabResults mStabResults = agent.ExtractStabilityResults(path);
+// if (!minimumSafetyFactor.HasValue || mStabResults.zone1.safetyFactor < minimumSafetyFactor)
+// {
+// minimumSafetyFactor = mStabResults.zone1.safetyFactor;
+// basisFileName = path;
+// }
+// }
+//
+// return minimumSafetyFactor ?? 0;
+ }
+
+ public static SoilGeometryBase GetSoilGeometryType(Location location, string workingPath)
+ {
+ var geom = GetSoilGeometryType(location);
+ if (!geom.SoilGeometryName.Contains(workingPath))
+ geom.SoilGeometryName = Path.Combine(workingPath, geom.SoilGeometryName);
+ return geom;
+ }
+
+ private static SoilGeometryBase GetSoilGeometryType(Location location)
+ {
+ SoilProfileType soilGeometryType;
+ string soilGeometry2DName;
+ DetermineSoilGeometryType(location, out soilGeometryType, out soilGeometry2DName);
+ return new SoilGeometryBase { SoilProfileType = soilGeometryType, SoilGeometryName = soilGeometry2DName };
+ }
+
+ ///
+ /// Determines the type of the soil geometry (1D or 2D).
+ ///
+ /// The location.
+ /// Type of the soil geometry.
+ /// Name of the soil geometry2 D.
+ internal static void DetermineSoilGeometryType(Location location, out SoilProfileType soilGeometryType, out string soilGeometry2DName)
+ {
+ SoilProfile1D soilProfile = location.Segment.GetMostProbableProfile(FailureMechanismSystemType.StabilityInside);
+ soilGeometry2DName = location.Segment.GetMostProbableGeometry2DName(FailureMechanismSystemType.StabilityInside);
+ string mapForSoilGeometries2D = location.StabilityOptions.SoilGeometries2DPath;
+ if ((soilGeometry2DName != null) && (mapForSoilGeometries2D != null))
+ {
+ soilGeometry2DName = Path.Combine(mapForSoilGeometries2D, soilGeometry2DName);
+ }
+ if (soilProfile != null)
+ {
+ soilGeometryType = SoilProfileType.ProfileType1D;
+ }
+ else
+ {
+ if (soilGeometry2DName == null)
+ {
+ throw new TimeSerieCalculationException(String.Format("Location {0} does not have a soilprofile assigned", location.Name));
+ }
+ soilGeometryType = SoilProfileType.ProfileTypeStiFile;
+ }
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/Resources.nl-NL.resx
===================================================================
diff -u -r1387 -r1591
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/Resources.nl-NL.resx (.../Resources.nl-NL.resx) (revision 1387)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/Resources.nl-NL.resx (.../Resources.nl-NL.resx) (revision 1591)
@@ -120,6 +120,9 @@
GetPointSegmentIncluding(): Eindwaarde is kleiner dan de startwaarde
+
+ Bestandsnaam is ongeldig. Het bevat ofwel ongeldige karakters, of het is leeg. Geef een geldige naam op.
+
GetCotangentOfInnerSlope heeft karakteristiek punt insteek berm of dijk teen polderzijde nodig.