// Copyright (C) Stichting Deltares 2019. 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.Linq; using Deltares.DamEngine.Calculators.KernelWrappers.Common; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using Deltares.MacroStability.CSharpWrapper; using Waternet = Deltares.DamEngine.Data.Geometry.Waternet; using Deltares.MacroStability.CSharpWrapper.Input; using CharacteristicPointType = Deltares.DamEngine.Data.Geotechnics.CharacteristicPointType; using KernelUpliftVanCalculationGrid = Deltares.MacroStability.CSharpWrapper.UpliftVanCalculationGrid; using KernelWaternet = Deltares.MacroStability.CSharpWrapper.Waternet; using KernelMacroStabilityInput = Deltares.MacroStability.CSharpWrapper.Input.MacroStabilityInput; using KernelPoint2D = Deltares.MacroStability.CSharpWrapper.Point2D; using KernelWaternetLine = Deltares.MacroStability.CSharpWrapper.WaternetLine; using KernelHeadLine = Deltares.MacroStability.CSharpWrapper.HeadLine; namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo { /// /// Fills the Macro Stability Wrapper from the DAM Engine data /// public class FillMacroStabilityWrapperInputFromEngine { private readonly Dictionary soilsDictionary = new Dictionary(); /// Gets or sets the UpliftVan calculation grid. /// The uplift van calculation grid. public UpliftVanCalculationGrid UpliftVanCalculationGrid { get; set; } /// Gets or sets the traffic load. /// The traffic load. public TrafficLoad TrafficLoad { get; set; } /// /// Creates the macro stability input. /// /// The dam kernel input. /// The failure mechanism parameters for MStab. /// The WaterNet. /// public MacroStabilityInput CreateMacroStabilityInput(DamKernelInput damKernelInput, FailureMechanismParametersMStab failureMechanismParametersMStab, Data.Geometry.Waternet waterNet) { soilsDictionary.Clear(); var macroStabilityInput = new KernelMacroStabilityInput(); macroStabilityInput.StabilityModel = new StabilityInput(); // ToDo check whether this is needed. macroStabilityInput.PreprocessingInput = new PreprocessingInput(); // ToDo check whether this is needed. macroStabilityInput.StabilityModel.UpliftVanCalculationGrid = new KernelUpliftVanCalculationGrid(); failureMechanismParametersMStab.MStabParameters.Model = MStabModelType.UpliftVanWti; TransferStabilityModelProperties(failureMechanismParametersMStab, macroStabilityInput.StabilityModel); TransferSoils(damKernelInput.Location.SoilList, macroStabilityInput.StabilityModel.Soils); macroStabilityInput.StabilityModel.ConstructionStages.Add(new ConstructionStage()); // ToDo check whether this is needed. var lastStage = macroStabilityInput.StabilityModel.ConstructionStages.Last(); lastStage.SoilProfile = new MacroStability.CSharpWrapper.Input.SoilProfile(); // ToDo check whether this is needed. lastStage.PreconsolidationStresses = new List(); // ToDo check whether this is needed. TransferSoilProfile(damKernelInput.SubSoilScenario.SoilProfile2D, lastStage.SoilProfile, lastStage.PreconsolidationStresses); macroStabilityInput.PreprocessingInput.PreConstructionStages.Add(new PreConstructionStage()); // ToDo check whether this is needed. var preConstructionLastStage = macroStabilityInput.PreprocessingInput.PreConstructionStages.Last(); preConstructionLastStage.SurfaceLine = new SurfaceLine(); TransferSurfaceLine(damKernelInput.Location.SurfaceLine, preConstructionLastStage.SurfaceLine); lastStage.Waternet = new KernelWaternet(); TransferWaternet(waterNet, lastStage.Waternet); var top = damKernelInput.Location.SurfaceLine.CharacteristicPoints .GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; var bottom = damKernelInput.SubSoilScenario.SoilProfile2D.Geometry.MinGeometryPointsZ; var slipCircleDefinition = damKernelInput.DamFailureMechanismeCalculationSpecification .FailureMechanismParametersMStab.MStabParameters.SlipCircleDefinition; SearchAreaConditions preprocessingSearchAreaConditions = macroStabilityInput.PreprocessingInput.SearchAreaConditions; TransferUpliftVanCalculationGridSettings(slipCircleDefinition, top, bottom, preprocessingSearchAreaConditions); TransferUpliftVanCalculationGrid(UpliftVanCalculationGrid, macroStabilityInput.StabilityModel.UpliftVanCalculationGrid, preprocessingSearchAreaConditions.AutoTangentLines); lastStage.UniformLoads = new List(); // ToDo check whether this is needed. TransferUniformLoads(TrafficLoad, lastStage.UniformLoads); return macroStabilityInput; } private void TransferStabilityModelProperties(FailureMechanismParametersMStab damFailureMechanismParametersMStab, StabilityInput kernelStabilityInput) { kernelStabilityInput.MoveGrid = true; // is not in DamEngine but MUST be true as we use the brute force approach. kernelStabilityInput.MaximumSliceWidth = 1.0; // is not in DamEngine datamodel kernelStabilityInput.SearchAlgorithm = ConversionHelper.ConvertToMacroStabilitySearchMethod(damFailureMechanismParametersMStab.MStabParameters.SearchMethod); kernelStabilityInput.ModelOption = ConversionHelper.ConvertToModelOptions(damFailureMechanismParametersMStab.MStabParameters.Model); kernelStabilityInput.Orientation = ConversionHelper.ConvertToGridOrientation(damFailureMechanismParametersMStab.MStabParameters.GridPosition); } private void TransferSoils(SoilList damSoilList, ICollection kernelSoils) { // Transfer all soils if (damSoilList != null) { foreach (var damSoil in damSoilList.Soils) { var kernelSoil = ConversionHelper.ConvertToMacroStabilitySoil(damSoil); kernelSoils.Add(kernelSoil); soilsDictionary.Add(damSoil.Name, kernelSoil); } } } private void TransferSoilProfile(SoilProfile2D damSoilProfile2D, MacroStability.CSharpWrapper.Input.SoilProfile kernelSoilProfile, ICollection preconsolidationStresses) { // Add points var pointsDictionary = new Dictionary(); kernelSoilProfile.Geometry = new Geometry(); kernelSoilProfile.Geometry.Points = new List(); foreach (var damPoint in damSoilProfile2D.Geometry.Points) { var kernelPoint = new KernelPoint2D(damPoint.X, damPoint.Z); kernelSoilProfile.Geometry.Points.Add(kernelPoint); pointsDictionary.Add(damPoint, kernelPoint); } // Add curves var curvesDictionary = new Dictionary(); kernelSoilProfile.Geometry.Curves = new List(); foreach (var damCurve in damSoilProfile2D.Geometry.Curves) { var kernelCurve = new Curve { HeadPoint = pointsDictionary[damCurve.HeadPoint], EndPoint = pointsDictionary[damCurve.EndPoint] }; kernelSoilProfile.Geometry.Curves.Add(kernelCurve); curvesDictionary.Add(damCurve, kernelCurve); } // Add loops var loopsDictionary = new Dictionary(); kernelSoilProfile.Geometry.Loops = new List(); foreach (var damLoop in damSoilProfile2D.Geometry.Loops) { var kernelLoop = new Loop(); kernelLoop.Curves = new List(); foreach (var geometryCurve in damLoop.CurveList) { kernelLoop.Curves.Add(curvesDictionary[geometryCurve]); } kernelSoilProfile.Geometry.Loops.Add(kernelLoop); loopsDictionary.Add(damLoop, kernelLoop); } // Add geometry surfaces var geometrySurfacesDictionary = new Dictionary(); kernelSoilProfile.Geometry.Surfaces = new List(); foreach (var damSurface in damSoilProfile2D.Surfaces) { var kernelGeometrySurface = new Surface(); GeometrySurface damGeometrySurface = damSurface.GeometrySurface; kernelGeometrySurface.OuterLoop = loopsDictionary[damGeometrySurface.OuterLoop]; geometrySurfacesDictionary.Add(damGeometrySurface, kernelGeometrySurface); kernelGeometrySurface.InnerLoops = new List(damGeometrySurface.InnerLoops.Count); foreach (var damSurfaceInnerLoop in damGeometrySurface.InnerLoops) { kernelGeometrySurface.InnerLoops.Add(loopsDictionary[damSurfaceInnerLoop]); } kernelSoilProfile.Geometry.Surfaces.Add(kernelGeometrySurface); } // Add soil surfaces kernelSoilProfile.SoilSurfaces = new List(); foreach (var damSoilLayer2D in damSoilProfile2D.Surfaces) { var kernelSoilLayer2D = new SoilProfileSurface(); kernelSoilLayer2D.Surface = geometrySurfacesDictionary[damSoilLayer2D.GeometrySurface]; kernelSoilLayer2D.Soil = soilsDictionary[damSoilLayer2D.Soil.Name]; kernelSoilLayer2D.IsAquifer = damSoilLayer2D.IsAquifer; kernelSoilLayer2D.WaterPressureInterpolationModel = ConversionHelper.ConvertToMacroStabilityWaterpressureInterpolationModel(damSoilLayer2D .WaterpressureInterpolationModel); kernelSoilProfile.SoilSurfaces.Add(kernelSoilLayer2D); } // Add the preconsolidation stresses foreach (var preconsolidationStress in damSoilProfile2D.PreconsolidationStresses) { var kernelPrecon = new PreconsolidationStress(); kernelPrecon.Point = new KernelPoint2D(preconsolidationStress.X, preconsolidationStress.Z); kernelPrecon.StressValue = preconsolidationStress.StressValue; preconsolidationStresses.Add(kernelPrecon); } } private void TransferSurfaceLine(SurfaceLine2 damSurfaceLine, SurfaceLine kernelSurfaceLine) { kernelSurfaceLine.CharacteristicPoints = new List(); foreach (var damCharPoint in damSurfaceLine.CharacteristicPoints) { var kernelCharPoint = new SurfaceLineCharacteristicPoint(); kernelCharPoint.CharacteristicPoint = ConversionHelper.ConvertToMacroStabilityCharacteristicPointType( damCharPoint.CharacteristicPointType); kernelCharPoint.GeometryPoint = new KernelPoint2D(damCharPoint.X, damCharPoint.Z); kernelSurfaceLine.CharacteristicPoints.Add(kernelCharPoint); } } private void TransferWaternet(Waternet damWaternet, KernelWaternet kernelWaternet) { var headLineMapping = new Dictionary(); kernelWaternet.Name = damWaternet.Name; // Phreatic Line PhreaticLine phreaticLine = damWaternet.PhreaticLine; kernelWaternet.PhreaticLine = CreateLine(phreaticLine); headLineMapping.Add(damWaternet.PhreaticLine, kernelWaternet.PhreaticLine); // Head Lines foreach (var damHeadLine in damWaternet.HeadLineList) { var kernelHeadLine = CreateLine(damHeadLine); kernelWaternet.HeadLines.Add(kernelHeadLine); headLineMapping.Add(damHeadLine, kernelHeadLine); } // Waternet Lines foreach (var damWaternetLine in damWaternet.WaternetLineList) { var kernelWaternetLine = CreateLine(damWaternetLine); kernelWaternetLine.AssociatedHeadLine = headLineMapping[damWaternetLine.HeadLine]; kernelWaternet.ReferenceLines.Add(kernelWaternetLine); // .WaternetLines } } private static TKernelLineType CreateLine(GeometryPointString geometry) where TKernelLineType : KernelWaternetLine, new() { var line = new TKernelLineType { Name = geometry.Name, Points = geometry.CalcPoints.Select(p => new KernelPoint2D(p.X, p.Z)).ToList() }; return line; } private void TransferUpliftVanCalculationGridSettings(SlipCircleDefinition slipCircleDefinition, double top, double bottom, SearchAreaConditions kernelSearchAreaConditions) { kernelSearchAreaConditions.AutoSearchArea = slipCircleDefinition.GridSizeDetermination == GridSizeDetermination.Automatic; kernelSearchAreaConditions.AutoTangentLines = slipCircleDefinition.UpliftVanTangentLinesDefinition == TangentLinesDefinition.Specified; if (kernelSearchAreaConditions.AutoTangentLines) { kernelSearchAreaConditions.TangentLineNumber = Convert.ToInt32(Math.Floor((top - bottom) / slipCircleDefinition.UpliftVanTangentLinesDistance) + 1); kernelSearchAreaConditions.TangentLineZTop = top; kernelSearchAreaConditions.TangentLineZBottom = bottom; } } private void TransferUpliftVanCalculationGrid(UpliftVanCalculationGrid damUpliftVanCalculationGrid, KernelUpliftVanCalculationGrid kernelUpliftVanCalculationGrid, bool isAutoTangentLines) { if (damUpliftVanCalculationGrid == null) throw new ArgumentNullException(nameof(damUpliftVanCalculationGrid)); if (kernelUpliftVanCalculationGrid == null) throw new ArgumentNullException(nameof(kernelUpliftVanCalculationGrid)); kernelUpliftVanCalculationGrid.LeftGrid = new CalculationGrid { GridXNumber = damUpliftVanCalculationGrid.LeftGridXCount, GridXLeft = damUpliftVanCalculationGrid.LeftGridXLeft, GridXRight = damUpliftVanCalculationGrid.LeftGridXRight, GridZNumber = damUpliftVanCalculationGrid.LeftGridZCount, GridZTop = damUpliftVanCalculationGrid.LeftGridZTop, GridZBottom = damUpliftVanCalculationGrid.LeftGridZBottom }; kernelUpliftVanCalculationGrid.RightGrid = new CalculationGrid { GridXNumber = damUpliftVanCalculationGrid.RightGridXCount, GridXLeft = damUpliftVanCalculationGrid.RightGridXLeft, GridXRight = damUpliftVanCalculationGrid.RightGridXRight, GridZNumber = damUpliftVanCalculationGrid.RightGridZCount, GridZTop = damUpliftVanCalculationGrid.RightGridZTop, GridZBottom = damUpliftVanCalculationGrid.RightGridZBottom }; if(!isAutoTangentLines) { kernelUpliftVanCalculationGrid.TangentLines = damUpliftVanCalculationGrid.TangentLineLevels.ToArray(); } } private void TransferUniformLoads(TrafficLoad damTrafficLoad, ICollection kernelUniformLoads) { if (damTrafficLoad != null) { kernelUniformLoads.Add(new UniformLoad() { XStart = damTrafficLoad.XStart, XEnd = damTrafficLoad.XEnd, Pressure = damTrafficLoad.Pressure, DistributionAngle = 0.0, }); } } } }