// Copyright (C) Stichting Deltares 2017. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU 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 General Public License for more details. // // You should have received a copy of the GNU 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.WTIStability.Data.Geo; using Deltares.WTIStability.Data.Standard; using Ringtoets.MacroStabilityInwards.KernelWrapper.Calculators.Input; using Point2D = Core.Common.Base.Geometry.Point2D; using WtiStabilityPoint2D = Deltares.WTIStability.Data.Geo.Point2D; namespace Ringtoets.MacroStabilityInwards.KernelWrapper.Creators.Input { /// /// Creates instances which are required in a calculation. /// internal static class SoilProfileCreator { /// /// Creates a based on and /// . /// /// The preconsolidation stresses to use in the . /// The layer data to use in the . /// A new . /// Thrown when any parameter is null. public static SoilProfile2D Create(IEnumerable preconsolidationStresses, IEnumerable layersWithSoil) { if (preconsolidationStresses == null) { throw new ArgumentNullException(nameof(preconsolidationStresses)); } if (layersWithSoil == null) { throw new ArgumentNullException(nameof(layersWithSoil)); } var profile = new SoilProfile2D(); profile.PreconsolidationStresses.AddRange(CreatePreconsolidationStresses(preconsolidationStresses)); var alreadyCreatedPoints = new List(); var alreadyCreatedCurves = new List(); var alreadyCreatedLoops = new List(); foreach (LayerWithSoil layerWithSoil in layersWithSoil) { profile.Surfaces.Add(new SoilLayer2D { IsAquifer = layerWithSoil.IsAquifer, Soil = layerWithSoil.Soil, GeometrySurface = CreateGeometrySurface(layerWithSoil, alreadyCreatedPoints, alreadyCreatedCurves, alreadyCreatedLoops), WaterpressureInterpolationModel = layerWithSoil.WaterPressureInterpolationModel }); } profile.Geometry = CreateGeometryData(profile); return profile; } private static IEnumerable CreatePreconsolidationStresses(IEnumerable preconsolidationStresses) { return preconsolidationStresses.Select(preconsolidationStress => new PreConsolidationStress { StressValue = preconsolidationStress.Stress, X = preconsolidationStress.Coordinate.X, Z = preconsolidationStress.Coordinate.Y }).ToArray(); } private static GeometrySurface CreateGeometrySurface(LayerWithSoil layer, List alreadyCreatedPoints, List alreadyCreatedCurves, List alreadyCreatedLoops) { var surface = new GeometrySurface { OuterLoop = CreateGeometryLoop(layer.OuterRing, alreadyCreatedPoints, alreadyCreatedCurves, alreadyCreatedLoops) }; surface.InnerLoops.AddRange(layer.InnerRings.Select(ir => CreateGeometryLoop(ir, alreadyCreatedPoints, alreadyCreatedCurves, alreadyCreatedLoops)).ToArray()); return surface; } private static GeometryLoop CreateGeometryLoop(Point2D[] points, List alreadyCreatedPoints, List alreadyCreatedCurves, List alreadyCreatedLoops) { GeometryLoop loop = alreadyCreatedLoops.FirstOrDefault(l => l.CurveList.Select(cl => cl.HeadPoint.X).SequenceEqual(points.Select(p => p.X)) && l.CurveList.Select(cl => cl.HeadPoint.Z).SequenceEqual(points.Select(p => p.Y))); if (loop == null) { loop = new GeometryLoop(); loop.CurveList.AddRange(CreateGeometryCurves(points, alreadyCreatedPoints, alreadyCreatedCurves)); alreadyCreatedLoops.Add(loop); } return loop; } private static GeometryCurve[] CreateGeometryCurves(Point2D[] points, List alreadyCreatedPoints, List alreadyCreatedCurves) { var curves = new List(); WtiStabilityPoint2D[] stabilityPoints = points.Select(p => GetPoint(p, alreadyCreatedPoints)).ToArray(); int stabilityPointsLength = stabilityPoints.Length; for (var i = 0; i < stabilityPointsLength; i++) { curves.Add(GetCurve(stabilityPoints[i], i == stabilityPointsLength - 1 ? stabilityPoints[0] : stabilityPoints[i + 1], alreadyCreatedCurves)); } return curves.ToArray(); } private static WtiStabilityPoint2D GetPoint(Point2D point2D, List alreadyCreatedPoints) { WtiStabilityPoint2D stabilityPoint = alreadyCreatedPoints.FirstOrDefault(p => p.X.Equals(point2D.X) && p.Z.Equals(point2D.Y)); if (stabilityPoint == null) { stabilityPoint = new WtiStabilityPoint2D(point2D.X, point2D.Y); alreadyCreatedPoints.Add(stabilityPoint); } return stabilityPoint; } private static GeometryCurve GetCurve(WtiStabilityPoint2D headPoint, WtiStabilityPoint2D endPoint, List alreadyCreatedCurves) { GeometryCurve curve = alreadyCreatedCurves.FirstOrDefault(c => ReferenceEquals(c.HeadPoint, headPoint) && ReferenceEquals(c.EndPoint, endPoint) || ReferenceEquals(c.HeadPoint, endPoint) && ReferenceEquals(c.EndPoint, headPoint)); if (curve == null) { curve = new GeometryCurve { HeadPoint = headPoint, EndPoint = endPoint }; alreadyCreatedCurves.Add(curve); } return curve; } private static GeometryData CreateGeometryData(SoilProfile2D profile) { var geometryData = new GeometryData(); geometryData.Surfaces.AddRange(profile.Surfaces .Select(s => s.GeometrySurface)); geometryData.Loops.AddRange(geometryData.Surfaces .Select(gs => gs.OuterLoop)); geometryData.Curves.AddRange(geometryData.Loops .SelectMany(l => l.CurveList) .Distinct()); geometryData.Points.AddRange(geometryData.Curves .SelectMany(c => new[] { c.HeadPoint, c.EndPoint }).Distinct()); geometryData.Rebox(); return geometryData; } } }