//-----------------------------------------------------------------------
//
// Copyright (c) 2010 Deltares. All rights reserved.
//
// B.S.T.I.M. The
// tom.the@deltares.nl
// 15-06-2010
// Object to determine soilprofile below point on surfaceline
//-----------------------------------------------------------------------
using System.Linq;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
namespace Deltares.Dam.Data
{
using System;
using System.IO;
using System.Text;
using System.Xml.Linq;
using Deltares.Dam.Data.Assemblers;
using Deltares.Geotechnics;
using Deltares.Soilbase;
///
/// Exception class for Geometry2DTo1DConverter
///
public class Geometry2DTo1DConverterException : ApplicationException
{
public Geometry2DTo1DConverterException(string message)
: base(message)
{
}
}
///
/// Object to determine soilprofile below point on surfaceline
///
public class Geometry2DTo1DConverter
{
///
/// Initializes a new instance of the class.
///
/// Name of the soil geometry2 D.
/// The surface line.
/// The dike embankment material.
/// The soil base DB.
public Geometry2DTo1DConverter(string soilGeometry2DName, SurfaceLine2 surfaceLine, Soil dikeEmbankmentMaterial, SoilList soilList)
{
SoilGeometry2DName = soilGeometry2DName;
SurfaceLine = surfaceLine;
DikeEmbankmentMaterial = dikeEmbankmentMaterial;
this.SoilList = soilList;
XOffsetSoilGeometry2DOrigin = 0;
}
///
/// Initializes a new instance of the class.
///
/// Name of the soil geometry2 D.
/// The surface line.
/// The dike embankment material.
/// The soil base DB.
/// The x offset soil geometry2 D origin.
public Geometry2DTo1DConverter(string soilGeometry2DName, SurfaceLine2 surfaceLine, Soil dikeEmbankmentMaterial, SoilbaseDB soilBaseDB, SoilList soilList, double xOffsetSoilGeometry2DOrigin)
{
SoilGeometry2DName = soilGeometry2DName;
SurfaceLine = surfaceLine;
DikeEmbankmentMaterial = dikeEmbankmentMaterial;
this.SoilList = soilList;
XOffsetSoilGeometry2DOrigin = xOffsetSoilGeometry2DOrigin;
}
public string SoilGeometry2DName { get; set; }
public SurfaceLine2 SurfaceLine { get; set; }
public Soil DikeEmbankmentMaterial { get; set; }
private SoilList SoilList { get; set; }
public double XOffsetSoilGeometry2DOrigin { get; set; }
///
/// Make section on specified x-coordinate.
/// Material above surfacelevel of geometry and below surfaceline will be specified as dikeEmbankmentMaterial
///
///
///
///
public SoilProfile1D Convert(double xCoordinate)
{
//xCoordinate = Math.Min(xCoordinate, this.SurfaceLine[CharacteristicPointType.SurfaceLevelInside].X - 0.1);
//xCoordinate = this.SurfaceLine[CharacteristicPointType.SurfaceLevelInside].X-0.25;
DAMMStabGeometry2DSectionAssembler assembler = new DAMMStabGeometry2DSectionAssembler();
var geometry2DSectionParameters = new Geometry2DSectionParameters();
geometry2DSectionParameters.SoilGeometry2DName = System.IO.Path.GetFullPath(SoilGeometry2DName);
geometry2DSectionParameters.XCoordinateSection = xCoordinate + XOffsetSoilGeometry2DOrigin;
XDocument doc = assembler.CreateDataTransferObject(geometry2DSectionParameters);
String LXMLInput = doc.ToString();
// Following file for debugging
// SaveXMLInputFile(xCoordinate, doc);
StringBuilder LXMLOutput = null;
var stabilityServiceAgent = new StabilityServiceAgent();
stabilityServiceAgent.ConvertGeometry2DTo1D(LXMLInput, ref LXMLOutput);
XDocument docOut = XDocument.Parse(LXMLOutput.ToString());
Geometry2DSectionParameters geometry2DSectionParametersOut = assembler.CreateOutputObject(docOut);
SoilProfile1D soilProfile = geometry2DSectionParametersOut.SoilProfile;
AddDikeMaterialIfSurfaceLineAboveGeometrySurface(ref soilProfile, xCoordinate);
AssignSoilsFromSoilbaseToProfile(soilProfile);
return soilProfile;
}
///
/// Saves the XML input file for debugging.
///
/// The x coordinate.
/// The document.
private void SaveXMLInputFile(double xCoordinate, XDocument doc)
{
string directoryGeometry2DSectionParameters = "Geometry2DSectionParameters";
string filenameGeometry2DSectionParameters = String.Format("Geometry2DSectionParameters_{0}_{1}.xml",
Path.GetFileNameWithoutExtension(SoilGeometry2DName), xCoordinate);
if (!Directory.Exists(directoryGeometry2DSectionParameters))
{
Directory.CreateDirectory(directoryGeometry2DSectionParameters);
}
doc.Save(Path.Combine(directoryGeometry2DSectionParameters, filenameGeometry2DSectionParameters));
}
///
/// Add toplayer made of dikeEmbankmentMaterial when the surfaceline is higher then the defined 2D-geometry
///
///
private void AddDikeMaterialIfSurfaceLineAboveGeometrySurface(ref SoilProfile1D soilProfile, double xCoordinate)
{
double surfaceLevel = this.SurfaceLine.Geometry.GetZAtUnsortedX(xCoordinate);
if (surfaceLevel > soilProfile.Layers[0].TopLevel)
{
// Add toplayer
ThrowIfNoDikeMaterialAssigned();
var topLayer = new SoilLayer1D();
topLayer.Id = soilProfile.GetNewUniqueLayerId();
topLayer.Name = DikeEmbankmentMaterial.Name;
topLayer.TopLevel = surfaceLevel;
soilProfile.Layers.Insert(0, topLayer);
}
}
///
/// Read soilparameters from soilbase and assign to soil in layers
///
///
private void AssignSoilsFromSoilbaseToProfile(SoilProfile1D soilProfile)
{
foreach (SoilLayer1D layer in soilProfile.Layers)
{
layer.Soil = SoilList.GetSoilByName(layer.Name);
if (layer.Soil == null)
{
throw new Geometry2DTo1DConverterException(String.Format("Soil material '{0}' belonging to layer '{1}' not available in soilmaterials", layer.Name, layer.Id));
}
if (SoilList.AquiferDictionary.ContainsKey(layer.Soil))
{
layer.IsAquifer = SoilList.AquiferDictionary[layer.Soil];
}
}
var aquifers = soilProfile.GetAquiferLayers();
if (aquifers.Count == 0)
{
soilProfile.Layers.Last().IsAquifer = true;
}
}
///
/// Check if dikeEmbankmentmaterial assigned
///
private void ThrowIfNoDikeMaterialAssigned()
{
if (DikeEmbankmentMaterial == null)
{
throw new Geometry2DTo1DConverterException(String.Format("No dikeEmbankmentmaterial assigned for surfaceline '{0}'", SurfaceLine.Name));
}
}
}
}