// 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.Linq; using Deltares.DamEngine.Calculators.Properties; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard; using Deltares.DamEngine.Data.Standard.Validation; namespace Deltares.DamEngine.Calculators.DikesDesign { /// /// Class for adapting the slope of a surfaceline /// public class SurfaceLineSlopeAdapter : SurfaceLineAdapter { /// /// Initializes a new instance of the class. /// /// /// public SurfaceLineSlopeAdapter(SurfaceLine2 surfaceLine, Location location) : base(surfaceLine, location) { } /// /// Constructs a new surface line with an adjusted slope /// Adapt slope by moving the toe of the dike horizontally with deltaXAtToeOfSlope /// /// /// /// The offset to shift to the right /// The adapted surface line public SurfaceLine2 ConstructNewSurfaceLine(double deltaXAtToeOfSlope) { ThrowHelper.ThrowWhenConditionIsTrue("deltaXAtToeOfSlope should be >= 0.0", () => deltaXAtToeOfSlope < 0.0); var dikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); var dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); var dikeBaseInside = surfaceLine.HasShoulderInside() ? surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside) : dikeToeAtPolder; var slopeTangent = (dikeTopAtPolder.Z - dikeBaseInside.Z) / (dikeBaseInside.X + deltaXAtToeOfSlope - dikeTopAtPolder.X); ConstructNewSurfaceLineBySlope(slopeTangent); return surfaceLine; } /// /// Constructs a new surface line with an adjusted slope /// Adapt slope by changing the slope to the specified slopeTangent /// The top of the dike will remain in place and the te of the dike will be moved /// /// /// public SurfaceLine2 ConstructNewSurfaceLineBySlope(double slopeTangent) { ThrowHelper.ThrowWhenConditionIsTrue("Slopetangent should be >= 0.0", () => slopeTangent < 0.0); // the given surface line must be valid to begin with. var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); if (validationError != null) { throw new SurfaceLineException(validationError.Text); } var orgMaxX = surfaceLine.Geometry.GetMaxX(); if (double.IsNaN(orgMaxX)) { orgMaxX = double.MaxValue; } var dikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); var dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); var dikeBaseInside = surfaceLine.HasShoulderInside() ? surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside) : dikeToeAtPolder; // Remove points on inside slope surfaceLine.RemoveSegmentBetween(dikeTopAtPolder.X, dikeBaseInside.X); // Store the ditch (if any) var ditchDefinition = GetDitchDefinition(); // Delete the ditch from the surfaceline (if any) RemoveExistingDitch(ditchDefinition); // Adjust for the new slope ReplaceBaseInsideForNewSlope(dikeTopAtPolder, slopeTangent); // Restore Ditch (if any) RestoreDitch(ditchDefinition); // Check whether the surface line is extended. This is not allowed! if (surfaceLine.Geometry.GetMaxX() > orgMaxX) { throw new SurfaceLineAdapterException(Resources.SurfaceLineShoulderAdapterNewShoulderHeightTooLargeError); } // Restore traffic load RestoreTrafficLoad(); surfaceLine.SortPoints(); return surfaceLine; } } }