Index: DamClients/DamPythonInterface/trunk/src/dampythoninterface/soil.py =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/dampythoninterface/soil.py (revision 0) +++ DamClients/DamPythonInterface/trunk/src/dampythoninterface/soil.py (revision 3484) @@ -0,0 +1,111 @@ +# Copyright (C) Stichting Deltares 2021. All rights reserved. +# +# This file is part of the Dam Python Interface. +# +# The Dam Python Interface 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. + +from .base_class import BaseDataClass + +from typing import Optional +from enum import Enum +import lxml.etree as et + + +class ShearStrengthModelType(Enum): + """Enum class that contains different shear strength models of D-Stability.""" + + NONE = "None" + CPhi = "CPhi" + StressTable = "StressTable" + PseudoValues = "PseudoValues" + SuMeasured = "SuMeasured" + SuCalculated = "SuCalculated" + SuGradient = "SuGradient" + SuCalculatedWithYield = "SuCalculatedWithYield" + CPhiOrSuCalculated = "CPhiOrSuCalculated" + + +class DilatancyTypeModel(Enum): + """ """ + + Phi = "Phi" + Zero = "Zero" + MinusPhi = "MinusPhi" + + +class Soil(BaseDataClass): + """ + Dataclass that contains geometry information for a profile + + :param Name: Name of the soil + :param BeddingAngle: bedding angle + :param DiameterD70: 70%-fractile of the aquifer’s grain size distribution + :param PermeabKx: Permeability of soil + :param WhitesConstant: White’s constant + :param DiameterD90: 90%-fractile of the aquifer’s grain size distribution + :param AbovePhreaticLevel: unit weight above phreatic line + :param BelowPhreaticLevel: unit weight below phreatic line + :param DryUnitWeight: dry unit weight of soil + :param ShearStrengthModel: shear strength model of the soil for D-Stability calculation + :param UseDefaultShearStrengthModel: + :param Cohesion: cohesion of the soil + :param FrictionAngle: friction angle + :param Ocr: Overconsolidation ratio + :param SlopeRestProfile: + :param DilatancyType: + :param RRatio: + :param StrengthIncreaseExponent: + :param RatioCuPc: + """ + + Name: str + BeddingAngle: Optional[float] = 37 + DiameterD70: Optional[float] = 208 + PermeabKx: Optional[float] = None + WhitesConstant: Optional[float] = 0.25 + DiameterD90: Optional[float] = None + AbovePhreaticLevel: Optional[float] = None + BelowPhreaticLevel: Optional[float] = None + DryUnitWeight: Optional[float] = None + ShearStrengthModel: Optional[ShearStrengthModelType] = ShearStrengthModelType.NONE + UseDefaultShearStrengthModel: Optional[bool] = False + Cohesion: Optional[float] = None + FrictionAngle: Optional[float] = None + Ocr: Optional[float] = None + SlopeRestProfile: Optional[float] = None + DilatancyType: Optional[DilatancyTypeModel] = DilatancyTypeModel.Zero + RRatio: Optional[float] = None + StrengthIncreaseExponent: Optional[float] = None + RatioCuPc: Optional[float] = None + + def serialize(self): + """ + Function that serializes the Soil class. + """ + soil_root = et.Element("Soil") + dictionary_of_values = self.dict() + for field, value in dictionary_of_values.items(): + if value is None: + soil_root.set(field, str(1)) + elif isinstance(value, Enum): + soil_root.set(field, value.value) + elif isinstance(value, bool): + soil_root.set(field, str(value).lower()) + else: + soil_root.set(field, str(value)) + return soil_root Index: DamClients/DamPythonInterface/trunk/src/tests/test_output/test_full_output.xml =================================================================== diff -u -r3474 -r3484 --- DamClients/DamPythonInterface/trunk/src/tests/test_output/test_full_output.xml (.../test_full_output.xml) (revision 3474) +++ DamClients/DamPythonInterface/trunk/src/tests/test_output/test_full_output.xml (.../test_full_output.xml) (revision 3484) @@ -21,4 +21,8 @@ + + + + Index: DamClients/DamPythonInterface/trunk/src/tests/test_soil.py =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_soil.py (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_soil.py (revision 3484) @@ -0,0 +1,77 @@ +# Copyright (C) Stichting Deltares 2021. All rights reserved. +# +# This file is part of the Dam Python Interface. +# +# The Dam Python Interface 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. + + +from dampythoninterface.soil import ShearStrengthModelType, Soil, DilatancyTypeModel +from .utils import TestUtils + +import pytest +from pathlib import Path +from lxml import etree + + +class TestSoil: + @pytest.mark.unittest + def test_soil_can_be_initialized(self): + # initialize the soil model class + test_soil = Soil(Name="new soil", AbovePhreaticLevel=18, BelowPhreaticLevel=20) + # check expectations + assert test_soil.Name == "new soil" + assert test_soil.AbovePhreaticLevel == 18 + assert test_soil.BelowPhreaticLevel == 20 + + @pytest.mark.unittest + def test_serialize(self): + # initialize the soil model class + test_soil = Soil( + Name="Dijkmateriaal", + BeddingAngle=37, + DiameterD70=0.0002, + PermeabKx=0.0004, + WhitesConstant=0.25, + AbovePhreaticLevel=17, + BelowPhreaticLevel=17, + DryUnitWeight=0.01, + ShearStrengthModel=ShearStrengthModelType.CPhi, + UseDefaultShearStrengthModel=False, + Cohesion=0.5, + FrictionAngle=22, + DilatancyType=DilatancyTypeModel.Phi, + RRatio=1, + StrengthIncreaseExponent=0.7, + RatioCuPc=0.22, + ) + # run test + root = test_soil.serialize() + # test output + xml_output = Path( + TestUtils.get_output_test_data_dir(""), "test_serialize_soil.xml" + ) + tree = etree.ElementTree(root) + tree.write(str(xml_output), pretty_print=True) + # get template file + xml_test_data = Path( + TestUtils.get_test_data_dir("", "test_data"), + "test_soil.xml", + ) + # Line by line comparison + for output_file, test_file in zip(open(xml_output), open(xml_test_data)): + assert output_file.strip() == test_file.strip() Index: DamClients/DamPythonInterface/trunk/src/dampythoninterface/input.py =================================================================== diff -u -r3479 -r3484 --- DamClients/DamPythonInterface/trunk/src/dampythoninterface/input.py (.../input.py) (revision 3479) +++ DamClients/DamPythonInterface/trunk/src/dampythoninterface/input.py (.../input.py) (revision 3484) @@ -25,6 +25,7 @@ import lxml.etree as et from .surface_line import SurfaceLine +from .soil import Soil from .base_class import BaseDataClass @@ -37,16 +38,24 @@ """ SurfaceLines: List[SurfaceLine] = [] + Soils: List[Soil] = [] def ExportToXml(self, xml_file: Path) -> None: """ Function that export the DamInput dataclass to an xml that can be used as input of the DAMengine. """ input_root = et.Element("Input") + # create surface line element SurfaceLines_root = et.Element("SurfaceLines") for surface_line in self.SurfaceLines: SurfaceLines_root.append(surface_line.serialize()) input_root.append(SurfaceLines_root) + # create soils element + soils_root = et.Element("Soils") + for soil in self.Soils: + soils_root.append(soil.serialize()) + input_root.append(soils_root) + # Construct the whole input tree tree = et.ElementTree(input_root) tree.write(str(xml_file), pretty_print=True) Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/test_soil.xml =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_data/test_soil.xml (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_data/test_soil.xml (revision 3484) @@ -0,0 +1 @@ + Index: DamClients/DamPythonInterface/trunk/doc/source/dev/input.rst =================================================================== diff -u -r3475 -r3484 --- DamClients/DamPythonInterface/trunk/doc/source/dev/input.rst (.../input.rst) (revision 3475) +++ DamClients/DamPythonInterface/trunk/doc/source/dev/input.rst (.../input.rst) (revision 3484) @@ -17,4 +17,13 @@ .. automodule:: dampythoninterface.surface_line :members: + :undoc-members: + + +Soil +---- + + +.. automodule:: dampythoninterface.soil + :members: :undoc-members: \ No newline at end of file Index: DamClients/DamPythonInterface/trunk/src/tests/test_input.py =================================================================== diff -u -r3479 -r3484 --- DamClients/DamPythonInterface/trunk/src/tests/test_input.py (.../test_input.py) (revision 3479) +++ DamClients/DamPythonInterface/trunk/src/tests/test_input.py (.../test_input.py) (revision 3484) @@ -26,6 +26,7 @@ from dampythoninterface.input import DamInput from dampythoninterface.surface_line import SurfaceLine, PointTypeEnum, Point +from dampythoninterface.soil import Soil from .utils import TestUtils @@ -51,8 +52,21 @@ assert surfaceline_1.Name == "Surface line 1" assert surfaceline_2.Name == "Surface line 2" list_of_surface_lines = [surfaceline_1, surfaceline_2] + # create soil class + soil_1 = Soil( + Name="soil 1", + AbovePhreaticLevel=17, + BelowPhreaticLevel=17, + ) + soil_2 = Soil( + Name="soil 2", + AbovePhreaticLevel=20, + BelowPhreaticLevel=20, + ) + soils = [soil_1, soil_2] + # Make input class - model = DamInput(SurfaceLines=list_of_surface_lines) + model = DamInput(SurfaceLines=list_of_surface_lines, Soils=soils) assert model # run test xml_output = Path(