// 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,
});
}
}
}
}