// 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 System.Linq; using System.Text; using System.Xml.Linq; using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStabilityCommon.Assemblers; using Deltares.DamEngine.Calculators.Stability; using Deltares.DamEngine.Data.Geotechnics; namespace Deltares.DamEngine.Calculators.General { /// /// Exception class for Geometry2DTo1DConverter /// public class Geometry2DTo1DConverterException : ApplicationException { public Geometry2DTo1DConverterException(string message) : base(message) { } } /// /// Object to determine soilprofile below point on surfaceline /// public class Geometry2DTo1DConverter { /// /// Initializes a new instance of the class. /// /// Name of the soil geometry2 D. /// The surface line. /// The dike embankment material. /// The soil list. public Geometry2DTo1DConverter(string soilGeometry2DName, SurfaceLine2 surfaceLine, Soil dikeEmbankmentMaterial, SoilList soilList) { SoilGeometry2DName = soilGeometry2DName; SurfaceLine = surfaceLine; DikeEmbankmentMaterial = dikeEmbankmentMaterial; this.SoilList = soilList; XOffsetSoilGeometry2DOrigin = 0; } /// /// Initializes a new instance of the class. /// /// Name of the soil geometry2 D. /// The surface line. /// The dike embankment material. /// The soil list. /// The x offset soil geometry2 D origin. public Geometry2DTo1DConverter(string soilGeometry2DName, SurfaceLine2 surfaceLine, Soil dikeEmbankmentMaterial, SoilList soilList, double xOffsetSoilGeometry2DOrigin) { SoilGeometry2DName = soilGeometry2DName; SurfaceLine = surfaceLine; DikeEmbankmentMaterial = dikeEmbankmentMaterial; this.SoilList = soilList; XOffsetSoilGeometry2DOrigin = xOffsetSoilGeometry2DOrigin; } public string SoilGeometry2DName { get; set; } public SurfaceLine2 SurfaceLine { get; set; } public Soil DikeEmbankmentMaterial { get; set; } private SoilList SoilList { get; set; } public double XOffsetSoilGeometry2DOrigin { get; set; } /// /// Make section on specified x-coordinate. /// Material above surfacelevel of geometry and below surfaceline will be specified as dikeEmbankmentMaterial /// /// The x coordinate. /// public SoilProfile1D Convert(double xCoordinate) { //xCoordinate = Math.Min(xCoordinate, this.SurfaceLine[CharacteristicPointType.SurfaceLevelInside].X - 0.1); //xCoordinate = this.SurfaceLine[CharacteristicPointType.SurfaceLevelInside].X-0.25; DAMMStabGeometry2DSectionAssembler assembler = new DAMMStabGeometry2DSectionAssembler(); var geometry2DSectionParameters = new Geometry2DSectionParameters(); geometry2DSectionParameters.SoilGeometry2DName = System.IO.Path.GetFullPath(SoilGeometry2DName); geometry2DSectionParameters.XCoordinateSection = xCoordinate + XOffsetSoilGeometry2DOrigin; XDocument doc = assembler.CreateDataTransferObject(geometry2DSectionParameters); String LXMLInput = doc.ToString(); // Following file for debugging // SaveXMLInputFile(xCoordinate, doc); StringBuilder LXMLOutput = null; var stabilityServiceAgent = new StabilityServiceAgent(); stabilityServiceAgent.ConvertGeometry2DTo1D(LXMLInput, ref LXMLOutput); XDocument docOut = XDocument.Parse(LXMLOutput.ToString()); Geometry2DSectionParameters geometry2DSectionParametersOut = assembler.CreateOutputObject(docOut); SoilProfile1D soilProfile = geometry2DSectionParametersOut.SoilProfile; AddDikeMaterialIfSurfaceLineAboveGeometrySurface(ref soilProfile, xCoordinate); AssignSoilsFromSoilbaseToProfile(soilProfile); return soilProfile; } /// /// Saves the XML input file for debugging. /// /// The x coordinate. /// The document. private void SaveXMLInputFile(double xCoordinate, XDocument doc) { string directoryGeometry2DSectionParameters = "Geometry2DSectionParameters"; string filenameGeometry2DSectionParameters = String.Format("Geometry2DSectionParameters_{0}_{1}.xml", Path.GetFileNameWithoutExtension(SoilGeometry2DName), xCoordinate); if (!Directory.Exists(directoryGeometry2DSectionParameters)) { Directory.CreateDirectory(directoryGeometry2DSectionParameters); } doc.Save(Path.Combine(directoryGeometry2DSectionParameters, filenameGeometry2DSectionParameters)); } /// /// Add toplayer made of dikeEmbankmentMaterial when the surfaceline is higher then the defined 2D-geometry /// /// The soil profile. /// The x coordinate. private void AddDikeMaterialIfSurfaceLineAboveGeometrySurface(ref SoilProfile1D soilProfile, double xCoordinate) { double surfaceLevel = this.SurfaceLine.Geometry.GetZAtUnsortedX(xCoordinate); if (surfaceLevel > soilProfile.Layers[0].TopLevel) { // Add toplayer ThrowIfNoDikeMaterialAssigned(); var topLayer = new SoilLayer1D(); topLayer.Name = soilProfile.GetNewUniqueLayerName(); topLayer.SoilName = DikeEmbankmentMaterial.Name; topLayer.TopLevel = surfaceLevel; soilProfile.Layers.Insert(0, topLayer); } } /// /// Read soilparameters from soilbase and assign to soil in layers /// /// private void AssignSoilsFromSoilbaseToProfile(SoilProfile1D soilProfile) { foreach (SoilLayer1D layer in soilProfile.Layers) { layer.Soil = SoilList.GetSoilByName(layer.SoilName); if (layer.Soil == null) { throw new Geometry2DTo1DConverterException(String.Format("Soil material '{0}' belonging to layer '{1}' not available in soillist", layer.SoilName, layer.Name)); } if (SoilList.AquiferDictionary.ContainsKey(layer.Soil)) { layer.IsAquifer = SoilList.AquiferDictionary[layer.Soil]; } } var aquifers = soilProfile.GetAquiferLayers(); if (aquifers.Count == 0) { soilProfile.Layers.Last().IsAquifer = true; } } /// /// Check if dikeEmbankmentmaterial assigned /// private void ThrowIfNoDikeMaterialAssigned() { if (DikeEmbankmentMaterial == null) { throw new Geometry2DTo1DConverterException(String.Format("No dikeEmbankmentmaterial assigned for surfaceline '{0}'", SurfaceLine.Name)); } } } }