using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;
using Deltares.DamEngine.Calculators.General;
using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStability.Assemblers;
using Deltares.DamEngine.Data.Design;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard.Logging;
namespace Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStability
{
public static class MStabXmlDoc
{
///
/// Create XML definition for Stability calculation
///
///
///
///
///
///
///
///
///
///
///
///
public static XDocument CreateMStabXmlDoc(string mstabProjectFilename, DesignScenario scenario, SoilProfile1D soilProfile,
string soilGeometry2DName, double riverLevel,
MStabDesignEmbankment mstabDesignEmbankment, SurfaceLine2 surfaceLine,
double trafficLoad, double requiredSafetyFactor, out List errorMessages)
{
errorMessages = new List();
SoilProfile1D profile1D = soilProfile;
ConsistencyCheck(scenario, profile1D, soilGeometry2DName);
FailureMechanismeParamatersMStab failureMechanismeParamatersMStab = new FailureMechanismeParamatersMStab();
failureMechanismeParamatersMStab.Location = scenario.Location;
if (profile1D != null)
{
failureMechanismeParamatersMStab.SoilProfile = profile1D;
// 1d-geometry
failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.SoilProfileType =
SoilProfileType.ProfileType1D;
}
else
{
// 2d-geometry
failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.SoilProfileType =
SoilProfileType.ProfileType2D;
}
// Geometry Creation Options
failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.SoilGeometry2DFilename =
soilGeometry2DName;
failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.MaterialForDike =
scenario.Location.DikeEmbankmentMaterial;
failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.MaterialForShoulder =
scenario.Location.ShoulderEmbankmentMaterial;
failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.IsUseOriginalPLLineAssignments =
scenario.Location.IsUseOriginalPLLineAssignments;
failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.IsDesign =
(mstabDesignEmbankment != null);
failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.XOffsetSoilGeometry2DOrigin =
-scenario.Location.XSoilGeometry2DOrigin;
//ToDo zant PLLineCreationMethod is no longer property of Location
// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.PLLineAssignment =
// CalculationHelper.PLLineCreationMethod2PLLineAssignment(scenario.Location.PLLineCreationMethod);
failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.IntrusionVerticalWaterPressureType =
scenario.Location.IntrusionVerticalWaterPressure.Value;
//ToDo zant PenetrationLength is no longer property of Location
// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.PenetrationLength =
// scenario.Location.PenetrationLength;
// End of Geometry Creation Options
// Design options
failureMechanismeParamatersMStab.Design = mstabDesignEmbankment;
failureMechanismeParamatersMStab.SurfaceLine = surfaceLine;
failureMechanismeParamatersMStab.RiverLevel = riverLevel; // scenario.RiverLevel;
failureMechanismeParamatersMStab.DikeTableHeight =
scenario.DikeTableHeight ?? surfaceLine.GetDefaultDikeTableHeight() ?? 0;
failureMechanismeParamatersMStab.TrafficLoad = trafficLoad;
// Horizontal balance; TODO: Combine with code in StabilityCalculation
if (failureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.HorizontalBalance)
{
if (profile1D == null)
{
throw new DamFailureMechanismeCalculatorException(
"Model horizontal balance does not support 2d-geometries");
}
failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea = new HorizontalBalanceArea();
failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.XLeft =
surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X;
failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.XRight =
surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X;
failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YTop = riverLevel;
failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YBottom =
profile1D.InBetweenAquiferLayer != null
? profile1D.InBetweenAquiferLayer.TopLevel
: profile1D.BottomAquiferLayer.TopLevel;
int planeCount =
(int)(Math.Round((failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YTop -
failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YBottom) / 0.25));
failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.PlaneCount = Math.Min(planeCount, 50);
}
// Zonestype is ZoneAreas; TODO: Combine with code in StabilityCalculation
var dikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder);
if (
failureMechanismeParamatersMStab.MStabParameters.CalculationOptions.ZonesType.Equals(
MStabZonesType.ZoneAreas))
{
double? dikeTableHeight = scenario.DikeTableHeight ?? surfaceLine.GetDefaultDikeTableHeight() ?? null;
if (!dikeTableHeight.HasValue)
throw new DamFailureMechanismeCalculatorException("Surface line has no dike table height.");
failureMechanismeParamatersMStab.MStabParameters.ZoneAreas = new MStabZoneAreas
{
DikeTableHeight = dikeTableHeight.Value,
DikeTableWidth = scenario.Location.ZoneAreaRestSlopeCrestWidth,
SafetyFactorZone1A = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? requiredSafetyFactor,
SafetyFactorZone1B = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? requiredSafetyFactor,
XCoordinateDikeTopAtPolder = dikeTopAtPolder.X,
XCoordinateDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X,
XCoordinateStartRestProfile = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X
};
}
//ToDo zant Tmp disabled
// if (failureMechanismeParamatersMStab.MStabParameters.CalculationOptions.ZonesType.Equals(MStabZonesType.ForbiddenZone))
// {
// CreateForbiddenZone(scenario, surfaceLine);
// }
// Make sure riverlevel is correct with respect to surfaceline
double riverLevelLow = double.NaN;
if (failureMechanismeParamatersMStab.MStabParameters.GridPosition == MStabGridPosition.Left && scenario.RiverLevelLow.HasValue)
{
riverLevelLow = scenario.RiverLevelLow.Value;
}
double? riverLevelHigh = riverLevel;
var surfaceLevelOutside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside);
if (riverLevelHigh < surfaceLevelOutside.Z)
{
var riverLevelHighIsBelowSurfaceLevelOutside = Path.GetFileName(mstabProjectFilename) + ": " +
//ToDo zant
// LocalizationManager.GetTranslatedText(this.GetType(),
// "riverLevelHighIsBelowSurfaceLevelOutside");
"riverLevelHighIsBelowSurfaceLevelOutside";
LogMessage logMessage = new LogMessage(LogMessageType.Warning, null,
String.Format(riverLevelHighIsBelowSurfaceLevelOutside, riverLevelHigh,
surfaceLevelOutside.Z));
errorMessages.Add(logMessage);
}
var currentSurfaceLine = scenario.GetMostRecentSurfaceLine(soilProfile, Path.GetFileName(soilGeometry2DName));
if (currentSurfaceLine == null)
{
currentSurfaceLine = surfaceLine;
}
//ToDo zant CreateAllPLLines was changed
// failureMechanismeParamatersMStab.PLLines = CalculationHelper.CreateAllPLLines(scenario.Location, currentSurfaceLine,
// soilProfile, soilGeometry2DName, riverLevelHigh.Value, riverLevelLow);
// Slip circle definition for Uplift Van; TODO: Combine with code in StabilityCalculation
if (failureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.UpliftVan)
{
// Determine right side of slip plane grid (right grid)
// This is the location with the lowest uplift factor or, if present, the second NWO point
var upliftLocationAndResult = CalculationHelper.GetLocationWithLowestUpliftFactor(currentSurfaceLine, soilProfile,
soilGeometry2DName,
failureMechanismeParamatersMStab.PLLines,
scenario.Location);
double upliftCriterion =
scenario.GetUpliftCriterionStability(scenario.Location.ModelFactors.UpliftCriterionStability);
bool isUplift = !(upliftLocationAndResult == null) &&
(upliftLocationAndResult.UpliftFactor < upliftCriterion);
double xCoordinateLastUpliftPoint = isUplift
? upliftLocationAndResult.X
: currentSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X;
var nonWaterRetaining2 = currentSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint2);
if (nonWaterRetaining2 !=
null)
{
xCoordinateLastUpliftPoint =
nonWaterRetaining2.X;
}
failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.XCoordinateLastUpliftPoint =
xCoordinateLastUpliftPoint;
}
failureMechanismeParamatersMStab.MStabParameters.ProjectFileName = mstabProjectFilename;
failureMechanismeParamatersMStab.MStabParameters.SoilDatabaseName = scenario.Location.SoildatabaseName;
if (!failureMechanismeParamatersMStab.IsComplete)
{
throw new Exception("Not all required data is available");
}
DamMStabAssembler assembler = new DamMStabAssembler();
XDocument mstabXML = assembler.CreateDataTransferObject(failureMechanismeParamatersMStab);
return mstabXML;
}
///
///
///
///
///
///
public static void ConsistencyCheck(DesignScenario scenario, SoilProfile1D soilProfile, string soilGeometry2DName)
{
if (soilProfile != null)
{
if (soilProfile.BottomAquiferLayer == null)
{
throw new DamFailureMechanismeCalculatorException(
String.Format("Soilprofile '{0}' does not contain aquifer layers.", soilProfile.Name));
}
}
}
}
}