pydra-core 0.0.1__py2.py3-none-any.whl → 0.0.3__py2.py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- pydra_core/__init__.py +32 -32
- pydra_core/common/common.py +98 -98
- pydra_core/common/enum.py +63 -63
- pydra_core/common/interpolate.py +345 -345
- pydra_core/common/probability.py +293 -293
- pydra_core/core/calculation.py +51 -51
- pydra_core/core/datamodels/frequency_line.py +60 -60
- pydra_core/core/exceedance_frequency_line.py +224 -224
- pydra_core/core/exceedance_frequency_line_experimental.py +163 -163
- pydra_core/core/hbn.py +226 -226
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_2017.txt +36 -36
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_2017_metOnzHeid.txt +45 -45
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2015_metOnzHeid_v02.txt +50 -50
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2015_v02.txt +42 -42
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2050_metOnzHeid_v02.txt +56 -56
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2050_v02.txt +48 -48
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2100_metOnzHeid_v02.txt +56 -56
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_G_2100_v02.txt +48 -48
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2015_metOnzHeid_v02.txt +50 -50
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2015_v02.txt +42 -42
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2050_metOnzHeid_v02.txt +56 -56
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2050_v02.txt +48 -48
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2100_metOnzHeid_v02.txt +51 -51
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_OI2014_W_2100_v02.txt +44 -44
- pydra_core/data/statistics/Afvoer/Borgharen/Ovkans_Borgharen_piekafvoer_Ref.txt +27 -27
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_2017.txt +30 -30
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_2017_metOnzHeid.txt +32 -32
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2015.txt +44 -44
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2015_metOnzHeid.txt +33 -33
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2050.txt +44 -44
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2050_metOnzHeid.txt +33 -33
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2100.txt +44 -44
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_G_2100_metOnzHeid.txt +38 -38
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2015.txt +44 -44
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2015_metOnzHeid.txt +33 -33
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2050.txt +44 -44
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2050_metOnzHeid.txt +33 -33
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2100.txt +44 -44
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_OI2014_W_2100_metOnzHeid.txt +33 -33
- pydra_core/data/statistics/Afvoer/Dalfsen/Ovkans_Dalfsen_piekafvoer_Ref.txt +13 -13
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_2017.txt +47 -47
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_2017_metOnzHeid.txt +47 -47
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2015.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2015_metOnzHeid.txt +58 -58
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2050.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2050_metOnzHeid.txt +58 -58
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2100.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_G_2100_metOnzHeid.txt +58 -58
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2015.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2015_metOnzHeid.txt +58 -58
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2050.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2050_metOnzHeid.txt +58 -58
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2100.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_OI2014_W_2100_metOnzHeid.txt +58 -58
- pydra_core/data/statistics/Afvoer/Lith/Ovkans_Lith_piekafvoer_Ref.txt +20 -20
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_2017.txt +33 -33
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_2017_metOnzHeid.txt +59 -59
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2015.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2015_BenedenRijn.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2015_metOnzHeid.txt +62 -62
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2015_metOnzHeid_BenedenRijn.txt +65 -65
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2050.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2050_BenedenRijn.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2050_metOnzHeid.txt +62 -62
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2050_metOnzHeid_BenedenRijn.txt +64 -64
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2100.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2100_BenedenRijn.txt +49 -49
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2100_metOnzHeid.txt +62 -62
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_G_2100_metOnzHeid_BenedenRijn.txt +64 -64
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2015.txt +50 -50
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2015_BenedenRijn.txt +50 -50
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2015_metOnzHeid.txt +62 -62
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2015_metOnzHeid_BenedenRijn.txt +64 -64
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2050.txt +50 -50
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2050_BenedenRijn.txt +50 -50
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2050_metOnzHeid.txt +62 -62
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2050_metOnzHeid_BenedenRijn.txt +64 -64
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2100.txt +50 -50
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2100_BenedenRijn.txt +50 -50
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2100_metOnzHeid.txt +62 -62
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_OI2014_W_2100_metOnzHeid_BenedenRijn.txt +65 -65
- pydra_core/data/statistics/Afvoer/Lobith/Ovkans_Lobith_piekafvoer_Ref.txt +22 -22
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_2017.txt +55 -55
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_2017_metOnzHeid.txt +55 -55
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2015.txt +46 -46
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2015_metOnzHeid.txt +64 -64
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2050.txt +46 -46
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2050_metOnzHeid.txt +64 -64
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2100.txt +46 -46
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_G_2100_metOnzHeid.txt +64 -64
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2015.txt +47 -47
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2015_metOnzHeid.txt +64 -64
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2050.txt +47 -47
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2050_metOnzHeid.txt +64 -64
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2100.txt +47 -47
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_OI2014_W_2100_metOnzHeid.txt +64 -64
- pydra_core/data/statistics/Afvoer/Olst/Ovkans_Olst_piekafvoer_Ref.txt +14 -14
- pydra_core/data/statistics/Golfvorm/Borgharen/Golfvormen_Borgharen.txt +76 -76
- pydra_core/data/statistics/Golfvorm/Dalfsen/Golfvormen_Dalfsen.txt +83 -83
- pydra_core/data/statistics/Golfvorm/Grevelingenmeer/Golfvormen_Grevelingenmeer.txt +33 -33
- pydra_core/data/statistics/Golfvorm/IJsselmeer/Golfvormen_IJsselmeer.txt +83 -83
- pydra_core/data/statistics/Golfvorm/Lith/Golfvormen_Lith.txt +76 -76
- pydra_core/data/statistics/Golfvorm/Lobith/Golfvormen_Lobith.txt +76 -76
- pydra_core/data/statistics/Golfvorm/Markermeer/Golfvormen_Markermeer.txt +139 -139
- pydra_core/data/statistics/Golfvorm/Olst/Golfvormen_Olst.txt +83 -83
- pydra_core/data/statistics/Golfvorm/Veerse Meer/Golfvormen_Veersemeer.txt +53 -53
- pydra_core/data/statistics/Golfvorm/Veluwerandmeer/Golfvormen_Veluwerandmeer.txt +139 -139
- pydra_core/data/statistics/Golfvorm/Volkerak-Zoommeer/Golfvormen_Volkerakzoommeer.txt +73 -73
- pydra_core/data/statistics/Meerpeil/Grevelingenmeer/Ovkans_Grevelingenmeer_piekmeerpeil_2017.txt +12 -12
- pydra_core/data/statistics/Meerpeil/Grevelingenmeer/Ovkans_Grevelingenmeer_piekmeerpeil_2017_metOnzHeid.txt +24 -24
- pydra_core/data/statistics/Meerpeil/Grevelingenmeer/Ovkans_Grevelingenmeer_piekmeerpeil_v01.txt +12 -12
- pydra_core/data/statistics/Meerpeil/IJsselmeer/Ovkans_IJsselmeer_piekmeerpeil_2017.txt +25 -25
- pydra_core/data/statistics/Meerpeil/IJsselmeer/Ovkans_IJsselmeer_piekmeerpeil_2017_metOnzHeid.txt +39 -39
- pydra_core/data/statistics/Meerpeil/IJsselmeer/Ovkans_IJsselmeer_piekmeerpeil_v01.txt +14 -14
- pydra_core/data/statistics/Meerpeil/Markermeer/Ovkans_Markermeer_piekmeerpeil_2017.txt +18 -18
- pydra_core/data/statistics/Meerpeil/Markermeer/Ovkans_Markermeer_piekmeerpeil_2017_metOnzHeid.txt +37 -37
- pydra_core/data/statistics/Meerpeil/Markermeer/Ovkans_Markermeer_piekmeerpeil_v01.txt +10 -10
- pydra_core/data/statistics/Meerpeil/Veerse Meer/Ovkans_Veersemeer_piekmeerpeil_excl_peilverhoging.txt +13 -13
- pydra_core/data/statistics/Meerpeil/Veerse Meer/Ovkans_Veersemeer_piekmeerpeil_v01.txt +15 -15
- pydra_core/data/statistics/Meerpeil/Veluwerandmeer/Ovkans_Veluwerandmeer_piekmeerpeil_2017.txt +13 -13
- pydra_core/data/statistics/Meerpeil/Veluwerandmeer/Ovkans_Veluwerandmeer_piekmeerpeil_2017_metOnzHeid.txt +36 -36
- pydra_core/data/statistics/Meerpeil/Veluwerandmeer/Ovkans_Veluwerandmeer_piekmeerpeil_v01.txt +13 -13
- pydra_core/data/statistics/Meerpeil/Volkerak-Zoommeer/Ovkans_VZM_piekmeerpeil_BER-VZM.txt +17 -17
- pydra_core/data/statistics/Meerpeil/Volkerak-Zoommeer/Ovkans_VZM_piekmeerpeil_BER-VZM_metOnzHeid.txt +42 -42
- pydra_core/data/statistics/Restant/Oosterschelde/BesliskansenOSKering.txt +524 -524
- pydra_core/data/statistics/Restant/Oosterschelde/KansenFaseverschil_2023.txt +7 -7
- pydra_core/data/statistics/Restant/Oosterschelde/KansenFaseverschil_OS.txt +13 -13
- pydra_core/data/statistics/Restant/Oosterschelde/KansenStormduur_OS.txt +14 -14
- pydra_core/data/statistics/Restant/Oosterschelde/KansenStormduur_OS_40_60_80uur_2023.txt +16 -16
- pydra_core/data/statistics/Restant/Oosterschelde/ScenariokansenOSKering_2008.txt +23 -23
- pydra_core/data/statistics/Restant/Oosterschelde/ScenariokansenOSKering_2013.txt +18 -18
- pydra_core/data/statistics/Restant/Oosterschelde/ScenariokansenOSKering_2017.txt +18 -18
- pydra_core/data/statistics/Restant/Oosterschelde/ScenariokansenOSKering_2023.txt +13 -13
- pydra_core/data/statistics/Restant/Up2U/Up2U10.dat +59 -59
- pydra_core/data/statistics/Restant/Up2U/Up2Up.dat +59 -59
- pydra_core/data/statistics/Restant/Up2U/Up2Ustar.dat +59 -59
- pydra_core/data/statistics/Restant/hulpdijken.txt +59 -59
- pydra_core/data/statistics/Restant/hulpgolfhoogtes.txt +23 -23
- pydra_core/data/statistics/Restant/hulpgolfperiodes.txt +38 -38
- pydra_core/data/statistics/Restant/kansstormduur.txt +8 -8
- pydra_core/data/statistics/Restant/pwind_west.txt +33 -33
- pydra_core/data/statistics/Restant/pwind_west_met_Volkerfactor.txt +33 -33
- pydra_core/data/statistics/Restant/pwind_west_zonder_Volkerfactor.txt +33 -33
- pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Midden/VS_sigmafunctie_Kust_Midden.txt +18 -18
- pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Midden/VS_sigmafunctie_Kust_Midden_2017.txt +22 -22
- pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Noord/VS_sigmafunctie_Kust_Noord.txt +18 -18
- pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Noord/VS_sigmafunctie_Kust_Noord_2017.txt +22 -22
- pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Zuid/VS_sigmafunctie_Kust_Zuid.txt +18 -18
- pydra_core/data/statistics/Sigmafunctie/Hollandse Kust Zuid/VS_sigmafunctie_Kust_Zuid_2017.txt +22 -22
- pydra_core/data/statistics/Sigmafunctie/Oosterschelde/VS_sigmafunctie_OS.txt +21 -21
- pydra_core/data/statistics/Sigmafunctie/Oosterschelde/VS_sigmafunctie_OS_16sectoren_2023.txt +23 -23
- pydra_core/data/statistics/Sigmafunctie/Oosterschelde/VS_sigmafunctie_OS_2017.txt +21 -21
- pydra_core/data/statistics/Sigmafunctie/Waddenzee Oost/VS_sigmafunctie_WZ_oost.txt +18 -18
- pydra_core/data/statistics/Sigmafunctie/Waddenzee Oost/VS_sigmafunctie_WZ_oost_2017.txt +22 -22
- pydra_core/data/statistics/Sigmafunctie/Waddenzee West/VS_sigmafunctie_WZ_west.txt +18 -18
- pydra_core/data/statistics/Sigmafunctie/Waddenzee West/VS_sigmafunctie_WZ_west_2017.txt +22 -22
- pydra_core/data/statistics/Sigmafunctie/Westerschelde/VS_sigmafunctie_WS.txt +18 -18
- pydra_core/data/statistics/Sigmafunctie/Westerschelde/VS_sigmafunctie_WS_2017.txt +22 -22
- pydra_core/data/statistics/Sluitpeilen/Sluitfunctie Europoortkering Maas 2017.csv +630 -630
- pydra_core/data/statistics/Sluitpeilen/Sluitfunctie Europoortkering Rijn 2017.csv +630 -630
- pydra_core/data/statistics/Sluitpeilen/Sluitfunctie Hollandsche IJsselkering.csv +757 -757
- pydra_core/data/statistics/Sluitpeilen/Sluitfunctie Oosterscheldekering 2017.csv +55080 -55080
- pydra_core/data/statistics/Topduur/Borgharen/Topduur_Borgharen_2017.txt +18 -18
- pydra_core/data/statistics/Topduur/Borgharen/Topduur_Borgharen_v00.txt +14 -14
- pydra_core/data/statistics/Topduur/Dalfsen/Topduur_Dalfsen_2017.txt +19 -19
- pydra_core/data/statistics/Topduur/Dalfsen/Topduur_Dalfsen_v01.txt +15 -15
- pydra_core/data/statistics/Topduur/Grevelingenmeer/Topduur_Grevelingenmeer_2017.txt +13 -13
- pydra_core/data/statistics/Topduur/Grevelingenmeer/Topduur_Grevelingenmeer_v01.txt +13 -13
- pydra_core/data/statistics/Topduur/IJsselmeer/Topduur_IJsselmeer_2017.txt +19 -19
- pydra_core/data/statistics/Topduur/IJsselmeer/Topduur_IJsselmeer_v01.txt +14 -14
- pydra_core/data/statistics/Topduur/Lith/Topduur_Lith_2017.txt +18 -18
- pydra_core/data/statistics/Topduur/Lith/Topduur_Lith_v01.txt +17 -17
- pydra_core/data/statistics/Topduur/Lobith/Topduur_Lobith_2017.txt +18 -18
- pydra_core/data/statistics/Topduur/Lobith/Topduur_Lobith_v01.txt +16 -16
- pydra_core/data/statistics/Topduur/Markermeer/Topduur_Markermeer_2017.txt +19 -19
- pydra_core/data/statistics/Topduur/Markermeer/Topduur_Markermeer_v01.txt +11 -11
- pydra_core/data/statistics/Topduur/Olst/Topduur_Olst_2017.txt +19 -19
- pydra_core/data/statistics/Topduur/Olst/Topduur_Olst_v01.txt +15 -15
- pydra_core/data/statistics/Topduur/Veerse Meer/Topduur_Veersemeer_excl_peilverhoging.txt +12 -12
- pydra_core/data/statistics/Topduur/Veerse Meer/Topduur_Veersemeer_v01.txt +15 -15
- pydra_core/data/statistics/Topduur/Veluwerandmeer/Topduur_Veluwerandmeer_2017.txt +11 -11
- pydra_core/data/statistics/Topduur/Veluwerandmeer/Topduur_Veluwerandmeer_v01.txt +11 -11
- pydra_core/data/statistics/Topduur/Volkerak-Zoommeer/Topduur_Volkerakzoommeer_BER-VZM.txt +17 -17
- pydra_core/data/statistics/Windrichting/Deelen/Richtingskansen_Deelen_2017.txt +27 -27
- pydra_core/data/statistics/Windrichting/Hollandse Kust/KansenWindrichting_Kust.txt +16 -16
- pydra_core/data/statistics/Windrichting/Hollandse Kust/KansenWindrichting_Kust_2017.txt +23 -23
- pydra_core/data/statistics/Windrichting/Oosterschelde/KansenWindrichting_16sectoren_OS_2023.txt +30 -30
- pydra_core/data/statistics/Windrichting/Oosterschelde/KansenWindrichting_OS.txt +19 -19
- pydra_core/data/statistics/Windrichting/Oosterschelde/KansenWindrichting_OS_2017.txt +23 -23
- pydra_core/data/statistics/Windrichting/Schiphol/Richtingskansen_Schiphol_12sectoren.txt +19 -19
- pydra_core/data/statistics/Windrichting/Schiphol/Richtingskansen_Schiphol_12sectoren_2017.txt +19 -19
- pydra_core/data/statistics/Windrichting/Schiphol/Richtingskansen_Schiphol_2017.txt +27 -27
- pydra_core/data/statistics/Windrichting/Schiphol/kanswindrichting_v01.txt +28 -28
- pydra_core/data/statistics/Windrichting/Waddenzee/KansenWindrichting_WZ.txt +16 -16
- pydra_core/data/statistics/Windrichting/Waddenzee/KansenWindrichting_WZ_2017.txt +23 -23
- pydra_core/data/statistics/Windrichting/Westerschelde/KansenWindrichting_WS.txt +16 -16
- pydra_core/data/statistics/Windrichting/Westerschelde/KansenWindrichting_WS_2017.txt +23 -23
- pydra_core/data/statistics/Windsnelheid/De Kooy/OvkansWindsnelheid_Texel.txt +69 -69
- pydra_core/data/statistics/Windsnelheid/De Kooy/Ovkanswind_de Kooy_2017.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/De Kooy/Ovkanswind_de Kooy_2017_metOnzHeid.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/Deelen/Ovkanswind_Deelen_2017.txt +90 -90
- pydra_core/data/statistics/Windsnelheid/Deelen/Ovkanswind_Deelen_2017_metOnzHeid.txt +90 -90
- pydra_core/data/statistics/Windsnelheid/Hoek van Holland/OvkansWindsnelheid_Hoek van Holland.txt +69 -69
- pydra_core/data/statistics/Windsnelheid/Hoek van Holland/Ovkanswind_Hoek van Holland_2017.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/Hoek van Holland/Ovkanswind_Hoek van Holland_2017_metOnzHeid.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/IJmuiden/OvkansWindsnelheid_IJmuiden.txt +69 -69
- pydra_core/data/statistics/Windsnelheid/IJmuiden/Ovkanswind_IJmuiden_2017.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/IJmuiden/Ovkanswind_IJmuiden_2017_metOnzHeid.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren.txt +50 -50
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren_2017.txt +90 -90
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren_2017_metOnzHeid.txt +90 -90
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren_2017_metWindDrag.txt +96 -96
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_12sectoren_2017_metWindDrag_metOnzHeid.txt +96 -96
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_16sectoren_2017_metWindDrag.txt +96 -96
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_16sectoren_2017_metWindDrag_metOnzHeid.txt +96 -96
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_2017.txt +90 -90
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_2017_metOnzHeid.txt +90 -90
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_met_Volkerfactor_2017.txt +90 -90
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_Schiphol_met_Volkerfactor_2017_metOnzHeid.txt +90 -90
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_schiphol.txt +57 -57
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_schiphol_10%.txt +63 -63
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_schiphol_5%.txt +61 -61
- pydra_core/data/statistics/Windsnelheid/Schiphol/Ovkanswind_schiphol_B_met volker.txt +59 -59
- pydra_core/data/statistics/Windsnelheid/Vlissingen/OvkansWindsnelheid_OS.txt +66 -66
- pydra_core/data/statistics/Windsnelheid/Vlissingen/OvkansWindsnelheid_Vlissingen.txt +69 -69
- pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_16sectoren_2023.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_16sectoren_2023_metOnzHeid.txt +90 -90
- pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_2017.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_2017_metOnzHeid.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_2017_metWindDrag.txt +96 -96
- pydra_core/data/statistics/Windsnelheid/Vlissingen/Ovkanswind_Vlissingen_2017_metWindDrag_metOnzHeid.txt +96 -96
- pydra_core/data/statistics/Windsnelheid/West-Terschelling/OvkansWindsnelheid_West-Tersch.txt +69 -69
- pydra_core/data/statistics/Windsnelheid/West-Terschelling/Ovkanswind_West Terschelling_2017.txt +91 -91
- pydra_core/data/statistics/Windsnelheid/West-Terschelling/Ovkanswind_West Terschelling_2017_metOnzHeid.txt +91 -91
- pydra_core/data/statistics/Zeewaterstand/Delfzijl/CondPovDelfzijl_12u_zichtjaar1985_2017.txt +81 -81
- pydra_core/data/statistics/Zeewaterstand/Delfzijl/CondPovDelfzijl_12u_zichtjaar1985_2017_metOnzHeid.txt +81 -81
- pydra_core/data/statistics/Zeewaterstand/Delfzijl/CondPovDelfzijl_12u_zichtjaar2017.txt +81 -81
- pydra_core/data/statistics/Zeewaterstand/Delfzijl/CondPovDelfzijl_12u_zichtjaar2017_metOnzHeid.txt +81 -81
- pydra_core/data/statistics/Zeewaterstand/Delfzijl/OvkansZee_Delfzijl.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Den Helder/CondPovDenHelder_12u_zichtjaar1985_2017.txt +89 -89
- pydra_core/data/statistics/Zeewaterstand/Den Helder/CondPovDenHelder_12u_zichtjaar1985_2017_metOnzHeid.txt +89 -89
- pydra_core/data/statistics/Zeewaterstand/Den Helder/CondPovDenHelder_12u_zichtjaar2017.txt +88 -88
- pydra_core/data/statistics/Zeewaterstand/Den Helder/CondPovDenHelder_12u_zichtjaar2017_metOnzHeid.txt +88 -88
- pydra_core/data/statistics/Zeewaterstand/Den Helder/OvkansZee_Den Helder.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Den Oever/CondPovDenOeverBuiten_12u_zichtjaar1985_2017.txt +88 -88
- pydra_core/data/statistics/Zeewaterstand/Den Oever/CondPovDenOeverBuiten_12u_zichtjaar1985_2017_metOnzHeid.txt +88 -88
- pydra_core/data/statistics/Zeewaterstand/Den Oever/CondPovDenOeverBuiten_12u_zichtjaar2017.txt +87 -87
- pydra_core/data/statistics/Zeewaterstand/Den Oever/CondPovDenOeverBuiten_12u_zichtjaar2017_metOnzHeid.txt +87 -87
- pydra_core/data/statistics/Zeewaterstand/Den Oever/OvkansZee_Den Oever.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Hansweert/CondPovHansweert_12u_zichtjaar1985_2017.txt +71 -71
- pydra_core/data/statistics/Zeewaterstand/Hansweert/CondPovHansweert_12u_zichtjaar1985_2017_metOnzHeid.txt +71 -71
- pydra_core/data/statistics/Zeewaterstand/Hansweert/CondPovHansweert_12u_zichtjaar2017.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Hansweert/CondPovHansweert_12u_zichtjaar2017_metOnzHeid.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Hansweert/OvkansZee_Hansweert.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Harlingen/CondPovHarlingen_12u_zichtjaar1985_2017.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/Harlingen/CondPovHarlingen_12u_zichtjaar1985_2017_metOnzHeid.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/Harlingen/CondPovHarlingen_12u_zichtjaar2017.txt +84 -84
- pydra_core/data/statistics/Zeewaterstand/Harlingen/CondPovHarlingen_12u_zichtjaar2017_metOnzHeid.txt +84 -84
- pydra_core/data/statistics/Zeewaterstand/Harlingen/OvkansZee_Harlingen.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/CondPovHoekvanHolland_12u_zichtjaar1985_2017.txt +84 -84
- pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/CondPovHoekvanHolland_12u_zichtjaar1985_2017_metOnzHeid.txt +84 -84
- pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/CondPovHoekvanHolland_12u_zichtjaar2017.txt +83 -83
- pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/CondPovHoekvanHolland_12u_zichtjaar2017_metOnzHeid.txt +83 -83
- pydra_core/data/statistics/Zeewaterstand/Hoek van Holland/OvkansZee_Hoek van Holland.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Huibertgat/CondPovHuibertgat_12u_zichtjaar1985_2017.txt +86 -86
- pydra_core/data/statistics/Zeewaterstand/Huibertgat/CondPovHuibertgat_12u_zichtjaar1985_2017_metOnzHeid.txt +86 -86
- pydra_core/data/statistics/Zeewaterstand/Huibertgat/CondPovHuibertgat_12u_zichtjaar2017.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/Huibertgat/CondPovHuibertgat_12u_zichtjaar2017_metOnzHeid.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/Huibertgat/OvkansZee_Huibertgat.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/IJmuiden/CondPovIJmuiden_12u_zichtjaar1985_2017.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/IJmuiden/CondPovIJmuiden_12u_zichtjaar1985_2017_metOnzHeid.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/IJmuiden/CondPovIJmuiden_12u_zichtjaar2017.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/IJmuiden/CondPovIJmuiden_12u_zichtjaar2017_metOnzHeid.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/IJmuiden/OvkansZee_IJmuiden.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/CondPovIJmuiden-Additional_12u_zichtjaar1985_2017.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/CondPovIJmuiden-Additional_12u_zichtjaar1985_2017_metOnzHeid.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/CondPovIJmuiden-Additional_12u_zichtjaar2017.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/CondPovIJmuiden-Additional_12u_zichtjaar2017_metOnzHeid.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/IJmuiden virtueel/OvkansZee_IJmuiden_virtueel.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Lauwersoog/CondPovLauwersoog_12u_zichtjaar1985_2017.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/Lauwersoog/CondPovLauwersoog_12u_zichtjaar1985_2017_metOnzHeid.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/Lauwersoog/CondPovLauwersoog_12u_zichtjaar2017.txt +84 -84
- pydra_core/data/statistics/Zeewaterstand/Lauwersoog/CondPovLauwersoog_12u_zichtjaar2017_metOnzHeid.txt +84 -84
- pydra_core/data/statistics/Zeewaterstand/Lauwersoog/OvkansZee_Lauwersoog.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar1985_2011.txt +88 -88
- pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar1985_2017.txt +88 -88
- pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar1985_2017_metOnzheid.txt +92 -92
- pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar2017.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/Maasmond/CondPovMaasmond_12u_zichtjaar2017_metOnzheid.txt +85 -85
- pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_12u_zichtjaar1985_2017.txt +79 -79
- pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_12u_zichtjaar1985_2017_metOnzHeid.txt +79 -79
- pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_12u_zichtjaar2017.txt +79 -79
- pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_12u_zichtjaar2017_metOnzHeid.txt +79 -79
- pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_16sectoren_12u_2023.txt +74 -74
- pydra_core/data/statistics/Zeewaterstand/Oosterschelde/CondPovOS11_16sectoren_12u_2023_metOnzHeid.txt +73 -73
- pydra_core/data/statistics/Zeewaterstand/Oosterschelde/OvkansZee_OS11.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Oosterschelde/OvkansZeewaterstand_OS.txt +71 -71
- pydra_core/data/statistics/Zeewaterstand/Vlissingen/CondPovVlissingen_12u_zichtjaar1985_2017.txt +74 -74
- pydra_core/data/statistics/Zeewaterstand/Vlissingen/CondPovVlissingen_12u_zichtjaar1985_2017_metOnzHeid.txt +74 -74
- pydra_core/data/statistics/Zeewaterstand/Vlissingen/CondPovVlissingen_12u_zichtjaar2017.txt +74 -74
- pydra_core/data/statistics/Zeewaterstand/Vlissingen/CondPovVlissingen_12u_zichtjaar2017_metOnzHeid.txt +74 -74
- pydra_core/data/statistics/Zeewaterstand/Vlissingen/OvkansZee_Vlissingen.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/CondPovVlissingen-Additional_12u_zichtjaar1985_2017.txt +74 -74
- pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/CondPovVlissingen-Additional_12u_zichtjaar1985_2017_metOnzHeid.txt +74 -74
- pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/CondPovVlissingen-Additional_12u_zichtjaar2017.txt +74 -74
- pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/CondPovVlissingen-Additional_12u_zichtjaar2017_metOnzHeid.txt +74 -74
- pydra_core/data/statistics/Zeewaterstand/Vlissingen virtueel/OvkansZee_Vlissingen_virtueel.txt +70 -70
- pydra_core/data/statistics/Zeewaterstand/West-Terschelling/CondPovWestTerschelling_12u_zichtjaar1985_2017.txt +87 -87
- pydra_core/data/statistics/Zeewaterstand/West-Terschelling/CondPovWestTerschelling_12u_zichtjaar1985_2017_metOnzHeid.txt +87 -87
- pydra_core/data/statistics/Zeewaterstand/West-Terschelling/CondPovWestTerschelling_12u_zichtjaar2017.txt +86 -86
- pydra_core/data/statistics/Zeewaterstand/West-Terschelling/CondPovWestTerschelling_12u_zichtjaar2017_metOnzHeid.txt +86 -86
- pydra_core/data/statistics/Zeewaterstand/West-Terschelling/OvkansZee_West-Terschelling.txt +70 -70
- pydra_core/hrdatabase/hrdatabase.py +177 -177
- pydra_core/io/database_hr.py +598 -598
- pydra_core/io/database_settings.py +183 -183
- pydra_core/io/file_hydranl.py +92 -92
- pydra_core/location/location.py +115 -115
- pydra_core/location/model/base_model.py +270 -270
- pydra_core/location/model/loading/loading.py +368 -368
- pydra_core/location/model/loading/loading_factory.py +89 -89
- pydra_core/location/model/loading/loading_model/loading_model.py +324 -324
- pydra_core/location/model/loading/other_systems/loading_wave_overtopping.py +122 -122
- pydra_core/location/model/loading/water_systems/loading_coast.py +54 -54
- pydra_core/location/model/loading/water_systems/loading_eastern_scheldt.py +169 -169
- pydra_core/location/model/loading/water_systems/loading_ijssel_vechtdelta.py +55 -55
- pydra_core/location/model/loading/water_systems/loading_lake.py +55 -55
- pydra_core/location/model/loading/water_systems/loading_lower_rivier.py +68 -68
- pydra_core/location/model/loading/water_systems/loading_upper_river.py +55 -55
- pydra_core/location/model/statistics/other_systems/statistics_wave_overtopping.py +72 -72
- pydra_core/location/model/statistics/statistics.py +171 -171
- pydra_core/location/model/statistics/statistics_factory.py +89 -89
- pydra_core/location/model/statistics/stochastics/barrier/barrier.py +43 -43
- pydra_core/location/model/statistics/stochastics/barrier/barrier_easternscheldt.py +147 -147
- pydra_core/location/model/statistics/stochastics/barrier/barrier_europoort.py +209 -209
- pydra_core/location/model/statistics/stochastics/barrier/barrier_ramspol.py +41 -41
- pydra_core/location/model/statistics/stochastics/barrier/no_barrier.py +21 -21
- pydra_core/location/model/statistics/stochastics/discharge.py +108 -108
- pydra_core/location/model/statistics/stochastics/discrete_probability.py +55 -55
- pydra_core/location/model/statistics/stochastics/lake_level.py +158 -158
- pydra_core/location/model/statistics/stochastics/model_uncertainty.py +358 -358
- pydra_core/location/model/statistics/stochastics/sea_level/sea_level.py +53 -53
- pydra_core/location/model/statistics/stochastics/sea_level/sea_level_lower_river.py +93 -93
- pydra_core/location/model/statistics/stochastics/sea_level/sea_level_point.py +65 -65
- pydra_core/location/model/statistics/stochastics/sea_level/sea_level_triangular.py +158 -158
- pydra_core/location/model/statistics/stochastics/sigma_function.py +24 -24
- pydra_core/location/model/statistics/stochastics/wave_shape.py +624 -624
- pydra_core/location/model/statistics/stochastics/wind_speed.py +196 -196
- pydra_core/location/model/statistics/water_systems/statistics_coast.py +153 -153
- pydra_core/location/model/statistics/water_systems/statistics_eastern_scheldt.py +177 -177
- pydra_core/location/model/statistics/water_systems/statistics_ijssel_vechtdelta.py +229 -229
- pydra_core/location/model/statistics/water_systems/statistics_lake.py +86 -86
- pydra_core/location/model/statistics/water_systems/statistics_lower_river.py +321 -321
- pydra_core/location/model/statistics/water_systems/statistics_upper_river.py +86 -86
- pydra_core/location/model/water_system.py +249 -249
- pydra_core/location/model/wave_overtopping.py +25 -25
- pydra_core/location/profile/foreland.py +246 -246
- pydra_core/location/profile/lib/CombOverloopOverslag64.dll +0 -0
- pydra_core/location/profile/lib/DynamicLib-DaF.dll +0 -0
- pydra_core/location/profile/lib/README.MD +10 -10
- pydra_core/location/profile/lib/dllDikesOvertopping.dll +0 -0
- pydra_core/location/profile/lib/feedbackDLL.dll +0 -0
- pydra_core/location/profile/profile.py +971 -971
- pydra_core/location/profile/profile_loading.py +473 -473
- pydra_core/location/settings/settings.py +387 -387
- {pydra_core-0.0.1.dist-info → pydra_core-0.0.3.dist-info}/METADATA +25 -5
- pydra_core-0.0.3.dist-info/RECORD +393 -0
- pydra_core-0.0.1.dist-info/RECORD +0 -389
- {pydra_core-0.0.1.dist-info → pydra_core-0.0.3.dist-info}/WHEEL +0 -0
@@ -1,971 +1,971 @@
|
|
1
|
-
import ast
|
2
|
-
import matplotlib.pyplot as plt
|
3
|
-
import numpy as np
|
4
|
-
import os
|
5
|
-
|
6
|
-
from typing import Tuple, Union
|
7
|
-
|
8
|
-
from .foreland import Foreland
|
9
|
-
from .profile_loading import ProfileLoading
|
10
|
-
from ...common.enum import Breakwater
|
11
|
-
from ...common.interpolate import Interpolate
|
12
|
-
|
13
|
-
|
14
|
-
class Profile:
|
15
|
-
"""
|
16
|
-
Profile class
|
17
|
-
|
18
|
-
TODO: Implement support for sheet piles
|
19
|
-
"""
|
20
|
-
|
21
|
-
# Profile name
|
22
|
-
profile_name = None
|
23
|
-
|
24
|
-
# Breakwater
|
25
|
-
breakwater_type = Breakwater.NO_BREAKWATER
|
26
|
-
breakwater_level = 0.0
|
27
|
-
|
28
|
-
# Foreland
|
29
|
-
foreland_x_coordinates: None | list = None
|
30
|
-
foreland_y_coordinates: None | list = None
|
31
|
-
|
32
|
-
# Dike schematisation
|
33
|
-
dike_orientation: None | float = None
|
34
|
-
dike_crest_level: None | float = None
|
35
|
-
dike_x_coordinates: None | list = None
|
36
|
-
dike_y_coordinates: None | list = None
|
37
|
-
dike_roughness: None | list = None
|
38
|
-
|
39
|
-
def __init__(self, profile_name: str = "Profile"):
|
40
|
-
"""
|
41
|
-
Create a new profile
|
42
|
-
|
43
|
-
Parameters
|
44
|
-
----------
|
45
|
-
profile_name: str
|
46
|
-
Name of the profile (default: 'Profile')
|
47
|
-
"""
|
48
|
-
# Save the profile name
|
49
|
-
self.profile_name = profile_name
|
50
|
-
|
51
|
-
def validate_profile(self) -> bool:
|
52
|
-
"""
|
53
|
-
Function to validate the profile.
|
54
|
-
|
55
|
-
Returns
|
56
|
-
-------
|
57
|
-
bool
|
58
|
-
True if the profile is OK
|
59
|
-
"""
|
60
|
-
# TODO: Improve validation
|
61
|
-
# Check necessary components
|
62
|
-
# Orientation
|
63
|
-
if self.dike_orientation is None:
|
64
|
-
return False
|
65
|
-
|
66
|
-
# Crest height
|
67
|
-
if self.dike_crest_level is None:
|
68
|
-
return False
|
69
|
-
|
70
|
-
# Geometry
|
71
|
-
if (
|
72
|
-
(self.dike_x_coordinates is None)
|
73
|
-
or (self.dike_y_coordinates is None)
|
74
|
-
or (self.dike_roughness is None)
|
75
|
-
):
|
76
|
-
return False
|
77
|
-
|
78
|
-
return True
|
79
|
-
|
80
|
-
def set_dike_orientation(self, dike_orientation: float):
|
81
|
-
"""
|
82
|
-
Change the dike orientation
|
83
|
-
|
84
|
-
Parameters
|
85
|
-
----------
|
86
|
-
dike_orientation : float
|
87
|
-
The dike orientation
|
88
|
-
"""
|
89
|
-
self.dike_orientation = dike_orientation
|
90
|
-
|
91
|
-
def set_dike_crest_level(self, dike_crest_level: float):
|
92
|
-
"""
|
93
|
-
Change the crest level
|
94
|
-
|
95
|
-
Parameters
|
96
|
-
----------
|
97
|
-
dike_crest_level : float
|
98
|
-
The crest level of the dike
|
99
|
-
"""
|
100
|
-
self.dike_crest_level = dike_crest_level
|
101
|
-
|
102
|
-
def set_dike_geometry(
|
103
|
-
self,
|
104
|
-
dike_x_coordinates: list,
|
105
|
-
dike_y_coordinates: list,
|
106
|
-
dike_roughness: list = None,
|
107
|
-
):
|
108
|
-
"""
|
109
|
-
Change the geometry of the outer slope of the dike
|
110
|
-
|
111
|
-
Parameters
|
112
|
-
----------
|
113
|
-
dike_x_coordinates : list
|
114
|
-
A list with the x coordinates of the profile
|
115
|
-
dike_y_coordinates : list
|
116
|
-
A list with the y coordinates of the profile
|
117
|
-
dike_roughness : list, optional
|
118
|
-
A list with the roughness of the profile (default : all parts 1.0)
|
119
|
-
"""
|
120
|
-
# Make sure the dike geometry starts at (x = 0)
|
121
|
-
min_x = np.min(dike_x_coordinates)
|
122
|
-
|
123
|
-
# If dike roughness is None, the roughness of every part is 1.0
|
124
|
-
if dike_roughness is None:
|
125
|
-
dike_roughness = [1.0] * len(dike_x_coordinates)
|
126
|
-
|
127
|
-
# Save the dike geometry coordinates
|
128
|
-
self.dike_x_coordinates = dike_x_coordinates - min_x
|
129
|
-
self.dike_y_coordinates = dike_y_coordinates
|
130
|
-
self.dike_roughness = dike_roughness
|
131
|
-
|
132
|
-
def has_foreland(self) -> bool:
|
133
|
-
"""
|
134
|
-
Returns whether the profile has a foreland or breakwater
|
135
|
-
|
136
|
-
Returns
|
137
|
-
-------
|
138
|
-
bool
|
139
|
-
True if the profile has a foreland or breakwater
|
140
|
-
"""
|
141
|
-
# Check for a breakwater
|
142
|
-
if self.breakwater_type != Breakwater.NO_BREAKWATER:
|
143
|
-
return True
|
144
|
-
|
145
|
-
# Check for a foreland
|
146
|
-
if self.foreland_x_coordinates is not None:
|
147
|
-
return True
|
148
|
-
|
149
|
-
# No foreland or breakwater
|
150
|
-
return False
|
151
|
-
|
152
|
-
def set_foreland_geometry(
|
153
|
-
self, foreland_x_coordinates: list = None, foreland_y_coordinates: list = None
|
154
|
-
):
|
155
|
-
"""
|
156
|
-
Change the geometry of the foreland
|
157
|
-
Setting the foreland x and y coordinates to None will remove the foreland.
|
158
|
-
|
159
|
-
Parameters
|
160
|
-
----------
|
161
|
-
foreland_x_coordinates : list
|
162
|
-
A list with the x coordinates of the foreland (default: None)
|
163
|
-
foreland_y_coordinates : list
|
164
|
-
A list with the y coordinates of the foreland (default: None)
|
165
|
-
"""
|
166
|
-
# Add foreland
|
167
|
-
if foreland_x_coordinates is not None:
|
168
|
-
# Make sure the foreland ends at (x = 0)
|
169
|
-
max_x = np.max(foreland_x_coordinates)
|
170
|
-
|
171
|
-
# Save the foreland coordinates
|
172
|
-
self.foreland_x_coordinates = foreland_x_coordinates - max_x
|
173
|
-
self.foreland_y_coordinates = foreland_y_coordinates
|
174
|
-
|
175
|
-
# Delete foreland
|
176
|
-
else:
|
177
|
-
self.foreland_x_coordinates = None
|
178
|
-
self.foreland_y_coordinates = None
|
179
|
-
|
180
|
-
def remove_foreland(self) -> None:
|
181
|
-
"""
|
182
|
-
Remove the foreland
|
183
|
-
Wrapper for set_foreland_geometry()
|
184
|
-
"""
|
185
|
-
self.set_foreland_geometry(
|
186
|
-
foreland_x_coordinates=None, foreland_y_coordinates=None
|
187
|
-
)
|
188
|
-
|
189
|
-
def set_breakwater(
|
190
|
-
self, breakwater_type: Breakwater = None, breakwater_level: float = 0.0
|
191
|
-
):
|
192
|
-
"""
|
193
|
-
Change the breakwater
|
194
|
-
"""
|
195
|
-
# None equals no breakwater
|
196
|
-
if breakwater_type is None:
|
197
|
-
breakwater_type = Breakwater.NO_BREAKWATER
|
198
|
-
|
199
|
-
# If there is no breakwater, the height will be set to None
|
200
|
-
if breakwater_type == Breakwater.NO_BREAKWATER:
|
201
|
-
breakwater_level = 0.0
|
202
|
-
|
203
|
-
# Apply settings
|
204
|
-
self.breakwater_type = breakwater_type
|
205
|
-
self.breakwater_level = breakwater_level
|
206
|
-
|
207
|
-
def remove_breakwater(self) -> None:
|
208
|
-
"""
|
209
|
-
Remove the breakwater
|
210
|
-
Wrapper for set_breakwater()
|
211
|
-
"""
|
212
|
-
self.set_breakwater(
|
213
|
-
breakwater_type=Breakwater.NO_BREAKWATER, breakwater_level=0.0
|
214
|
-
)
|
215
|
-
|
216
|
-
def calculate_overtopping(
|
217
|
-
self,
|
218
|
-
water_level: Union[float, list],
|
219
|
-
significant_wave_height: Union[float, list],
|
220
|
-
spectral_wave_period: Union[float, list],
|
221
|
-
wave_direction: Union[float, list],
|
222
|
-
tp_tspec: float = 1.1,
|
223
|
-
dll_settings: dict = None,
|
224
|
-
) -> Union[float, list]:
|
225
|
-
"""
|
226
|
-
Calculate the overtopping discharge
|
227
|
-
|
228
|
-
Parameters
|
229
|
-
----------
|
230
|
-
water_level : Union[float, list]
|
231
|
-
List or float with the water level
|
232
|
-
significant_wave_height : Union[float, list]
|
233
|
-
List or float with the significant wave height
|
234
|
-
spectral_wave_period : Union[float, list]
|
235
|
-
List or float with the spectral wave period
|
236
|
-
wave_direction : Union[float, list]
|
237
|
-
List or float with the wave direction
|
238
|
-
tp_tspec : float, optional
|
239
|
-
Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
|
240
|
-
|
241
|
-
Returns
|
242
|
-
-------
|
243
|
-
Union[float, list]
|
244
|
-
List or float with the overtopping discharge
|
245
|
-
"""
|
246
|
-
# Transform wave conditions
|
247
|
-
water_level, significant_wave_height, spectral_wave_period, wave_direction = (
|
248
|
-
self.transform_wave_conditions(
|
249
|
-
water_level,
|
250
|
-
significant_wave_height,
|
251
|
-
spectral_wave_period,
|
252
|
-
wave_direction,
|
253
|
-
tp_tspec,
|
254
|
-
force_array=True,
|
255
|
-
)
|
256
|
-
)
|
257
|
-
|
258
|
-
# Create profile loading
|
259
|
-
profile_loading = ProfileLoading(self, dll_settings)
|
260
|
-
|
261
|
-
# Calculate
|
262
|
-
qov = []
|
263
|
-
for _h, _hs, _tspec, _dir in zip(
|
264
|
-
water_level, significant_wave_height, spectral_wave_period, wave_direction
|
265
|
-
):
|
266
|
-
qov.append(profile_loading.calculate_discharge(_h, _hs, _tspec, _dir))
|
267
|
-
|
268
|
-
# Return
|
269
|
-
return qov[0] if len(qov) == 1 else qov
|
270
|
-
|
271
|
-
def calculate_runup(
|
272
|
-
self,
|
273
|
-
water_level: Union[float, list],
|
274
|
-
significant_wave_height: Union[float, list],
|
275
|
-
spectral_wave_period: Union[float, list],
|
276
|
-
wave_direction: Union[float, list],
|
277
|
-
tp_tspec: float = 1.1,
|
278
|
-
dll_settings: dict = None,
|
279
|
-
) -> Union[float, list]:
|
280
|
-
"""
|
281
|
-
Calculate the runup height
|
282
|
-
|
283
|
-
Parameters
|
284
|
-
----------
|
285
|
-
water_level : Union[float, list]
|
286
|
-
List or float with the water level
|
287
|
-
significant_wave_height : Union[float, list]
|
288
|
-
List or float with the significant wave height
|
289
|
-
spectral_wave_period : Union[float, list]
|
290
|
-
List or float with the spectral wave period
|
291
|
-
wave_direction : Union[float, list]
|
292
|
-
List or float with the wave direction
|
293
|
-
tp_tspec : float, optional
|
294
|
-
Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
|
295
|
-
|
296
|
-
Returns
|
297
|
-
-------
|
298
|
-
Union[float, list]
|
299
|
-
List or float with the runup height
|
300
|
-
"""
|
301
|
-
# Transform wave conditions
|
302
|
-
water_level, significant_wave_height, spectral_wave_period, wave_direction = (
|
303
|
-
self.transform_wave_conditions(
|
304
|
-
water_level,
|
305
|
-
significant_wave_height,
|
306
|
-
spectral_wave_period,
|
307
|
-
wave_direction,
|
308
|
-
tp_tspec,
|
309
|
-
force_array=True,
|
310
|
-
)
|
311
|
-
)
|
312
|
-
|
313
|
-
# Create profile loading
|
314
|
-
profile_loading = ProfileLoading(self, dll_settings)
|
315
|
-
|
316
|
-
# Calculate
|
317
|
-
ru2p = []
|
318
|
-
for _h, _hs, _tspec, _dir in zip(
|
319
|
-
water_level, significant_wave_height, spectral_wave_period, wave_direction
|
320
|
-
):
|
321
|
-
ru2p.append(profile_loading.calculate_runup(_h, _hs, _tspec, _dir))
|
322
|
-
|
323
|
-
# Return
|
324
|
-
return ru2p[0] if len(ru2p) == 1 else ru2p
|
325
|
-
|
326
|
-
def calculate_crest_level(
|
327
|
-
self,
|
328
|
-
q_overtopping: float,
|
329
|
-
water_level: Union[float, list],
|
330
|
-
significant_wave_height: Union[float, list],
|
331
|
-
spectral_wave_period: Union[float, list],
|
332
|
-
wave_direction: Union[float, list],
|
333
|
-
tp_tspec: float = 1.1,
|
334
|
-
dll_settings: dict = None,
|
335
|
-
) -> Union[float, list]:
|
336
|
-
"""
|
337
|
-
Calculate the crest level for a given overtopping discharge
|
338
|
-
|
339
|
-
Parameters
|
340
|
-
----------
|
341
|
-
q_overtopping : float
|
342
|
-
Critical overtopping discharge
|
343
|
-
water_level : Union[float, list]
|
344
|
-
List or float with the water level
|
345
|
-
significant_wave_height : Union[float, list]
|
346
|
-
List or float with the significant wave height
|
347
|
-
spectral_wave_period : Union[float, list]
|
348
|
-
List or float with the spectral wave period
|
349
|
-
wave_direction : Union[float, list]
|
350
|
-
List or float with the wave direction
|
351
|
-
tp_tspec : float, optional
|
352
|
-
Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
|
353
|
-
|
354
|
-
Returns
|
355
|
-
-------
|
356
|
-
Union[float, list]
|
357
|
-
List or float with the crest level
|
358
|
-
"""
|
359
|
-
# Transform wave conditions
|
360
|
-
water_level, significant_wave_height, spectral_wave_period, wave_direction = (
|
361
|
-
self.transform_wave_conditions(
|
362
|
-
water_level,
|
363
|
-
significant_wave_height,
|
364
|
-
spectral_wave_period,
|
365
|
-
wave_direction,
|
366
|
-
tp_tspec,
|
367
|
-
force_array=True,
|
368
|
-
)
|
369
|
-
)
|
370
|
-
|
371
|
-
# Length of the list
|
372
|
-
n_q = 1 if isinstance(q_overtopping, (float, int)) else len(q_overtopping)
|
373
|
-
|
374
|
-
# If q_overtopping is an int or float
|
375
|
-
if isinstance(q_overtopping, (float, int)):
|
376
|
-
q_overtopping = [q_overtopping] * len(water_level)
|
377
|
-
|
378
|
-
# If q_overtopping is a list and water_level has length 1
|
379
|
-
elif n_q > 1 and len(water_level) == 1:
|
380
|
-
water_level = [water_level] * n_q
|
381
|
-
significant_wave_height = [significant_wave_height] * n_q
|
382
|
-
spectral_wave_period = [spectral_wave_period] * n_q
|
383
|
-
wave_direction = [wave_direction] * n_q
|
384
|
-
|
385
|
-
# Uneven length of arrays
|
386
|
-
else:
|
387
|
-
raise ValueError("[ERROR] Uneven length of arrays")
|
388
|
-
|
389
|
-
# To numpy
|
390
|
-
q_overtopping = np.array(q_overtopping)
|
391
|
-
water_level = np.array(water_level)
|
392
|
-
significant_wave_height = np.array(significant_wave_height)
|
393
|
-
spectral_wave_period = np.array(spectral_wave_period)
|
394
|
-
wave_direction = np.array(wave_direction)
|
395
|
-
|
396
|
-
# Create profile loading
|
397
|
-
profile_loading = ProfileLoading(self, dll_settings)
|
398
|
-
|
399
|
-
# Calculate crest level
|
400
|
-
hbn = []
|
401
|
-
for _q, _h, _hs, _tspec, _dir in zip(
|
402
|
-
q_overtopping,
|
403
|
-
water_level,
|
404
|
-
significant_wave_height,
|
405
|
-
spectral_wave_period,
|
406
|
-
wave_direction,
|
407
|
-
):
|
408
|
-
hbn.append(profile_loading.calculate_crest_level(_q, _h, _hs, _tspec, _dir))
|
409
|
-
|
410
|
-
# Return
|
411
|
-
return hbn[0] if len(hbn) == 1 else hbn
|
412
|
-
|
413
|
-
def transform_wave_conditions(
|
414
|
-
self,
|
415
|
-
water_level: Union[float, list],
|
416
|
-
significant_wave_height: Union[float, list],
|
417
|
-
spectral_wave_period: Union[float, list],
|
418
|
-
wave_direction: Union[float, list],
|
419
|
-
tp_tspec: float = 1.1,
|
420
|
-
force_array: bool = False,
|
421
|
-
) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
422
|
-
"""
|
423
|
-
Transform the wave conditions for the schematized foreland
|
424
|
-
|
425
|
-
Parameters
|
426
|
-
----------
|
427
|
-
water_level : Union[float, list]
|
428
|
-
Water level
|
429
|
-
significant_wave_height : Union[float, list]
|
430
|
-
Significant wave height
|
431
|
-
spectral_wave_period : Union[float, list]
|
432
|
-
Spectral wave period
|
433
|
-
wave_direction : Union[float, list]
|
434
|
-
Wave direction
|
435
|
-
tp_tspec : float, optional
|
436
|
-
Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
|
437
|
-
force_array : bool, optional
|
438
|
-
Always force to return an array
|
439
|
-
|
440
|
-
Returns
|
441
|
-
-------
|
442
|
-
Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]
|
443
|
-
Water level and transformed wave conditions (h, hs, tp, dir)
|
444
|
-
"""
|
445
|
-
# Length of the lists
|
446
|
-
n_h = 1 if isinstance(water_level, (float, int)) else len(water_level)
|
447
|
-
n_hs = (
|
448
|
-
1
|
449
|
-
if isinstance(significant_wave_height, (float, int))
|
450
|
-
else len(significant_wave_height)
|
451
|
-
)
|
452
|
-
n_tspec = (
|
453
|
-
1
|
454
|
-
if isinstance(spectral_wave_period, (float, int))
|
455
|
-
else len(spectral_wave_period)
|
456
|
-
)
|
457
|
-
n_dir = 1 if isinstance(wave_direction, (float, int)) else len(wave_direction)
|
458
|
-
n_max = np.max([n_h, n_hs, n_tspec, n_dir])
|
459
|
-
|
460
|
-
# Make lists
|
461
|
-
if isinstance(water_level, (float, int)):
|
462
|
-
water_level = [water_level] * n_max
|
463
|
-
elif len(water_level) != n_max:
|
464
|
-
raise ValueError("[ERROR] Uneven length of arrays")
|
465
|
-
|
466
|
-
if isinstance(significant_wave_height, (float, int)):
|
467
|
-
significant_wave_height = [significant_wave_height] * n_max
|
468
|
-
elif len(significant_wave_height) != n_max:
|
469
|
-
raise ValueError("[ERROR] Uneven length of arrays")
|
470
|
-
|
471
|
-
if isinstance(spectral_wave_period, (float, int)):
|
472
|
-
spectral_wave_period = [spectral_wave_period] * n_max
|
473
|
-
elif len(spectral_wave_period) != n_max:
|
474
|
-
raise ValueError("[ERROR] Uneven length of arrays")
|
475
|
-
|
476
|
-
if isinstance(wave_direction, (float, int)):
|
477
|
-
wave_direction = [wave_direction] * n_max
|
478
|
-
elif len(wave_direction) != n_max:
|
479
|
-
raise ValueError("[ERROR] Uneven length of arrays")
|
480
|
-
|
481
|
-
# To numpy
|
482
|
-
water_level = np.array(water_level)
|
483
|
-
significant_wave_height = np.array(significant_wave_height)
|
484
|
-
spectral_wave_period = np.array(spectral_wave_period)
|
485
|
-
wave_direction = np.array(wave_direction)
|
486
|
-
|
487
|
-
# Correct for foreland
|
488
|
-
if self.has_foreland():
|
489
|
-
fl = Foreland(self)
|
490
|
-
water_level, significant_wave_height, peak_wave_period, wave_direction = (
|
491
|
-
fl.transform_wave_conditions(
|
492
|
-
water_level,
|
493
|
-
significant_wave_height,
|
494
|
-
spectral_wave_period * tp_tspec,
|
495
|
-
wave_direction,
|
496
|
-
)
|
497
|
-
)
|
498
|
-
spectral_wave_period = peak_wave_period / tp_tspec
|
499
|
-
|
500
|
-
# Return array or floats?
|
501
|
-
if len(water_level.ravel()) == 1 and not force_array:
|
502
|
-
return (
|
503
|
-
water_level.ravel()[0],
|
504
|
-
significant_wave_height.ravel()[0],
|
505
|
-
spectral_wave_period.ravel()[0],
|
506
|
-
wave_direction.ravel()[0],
|
507
|
-
)
|
508
|
-
else:
|
509
|
-
return (
|
510
|
-
water_level,
|
511
|
-
significant_wave_height,
|
512
|
-
spectral_wave_period,
|
513
|
-
wave_direction,
|
514
|
-
)
|
515
|
-
|
516
|
-
def to_prfl(
|
517
|
-
self, export_path: str, id: str = "Onbekend000", memo: str = ""
|
518
|
-
) -> None:
|
519
|
-
"""
|
520
|
-
Export to a prfl file
|
521
|
-
|
522
|
-
export_path : str
|
523
|
-
Path to where the profile has to be exported
|
524
|
-
id : str
|
525
|
-
Id used in RisKeer
|
526
|
-
memo : str
|
527
|
-
Memo to be added to the prfl file
|
528
|
-
"""
|
529
|
-
# Check required info
|
530
|
-
if (
|
531
|
-
(self.dike_x_coordinates is None)
|
532
|
-
or (self.dike_crest_level is None)
|
533
|
-
or (self.dike_orientation is None)
|
534
|
-
):
|
535
|
-
raise ValueError(
|
536
|
-
f"[ERROR] Cannot generate .prfl for profile '{self.profile_name}', geometry, crest level or orientation is missing."
|
537
|
-
)
|
538
|
-
|
539
|
-
# Version
|
540
|
-
breakwater_level = (
|
541
|
-
self.breakwater_level if self.breakwater_level is not None else 0.0
|
542
|
-
)
|
543
|
-
n_foreland = (
|
544
|
-
len(self.foreland_x_coordinates)
|
545
|
-
if self.foreland_x_coordinates is not None
|
546
|
-
else 0
|
547
|
-
)
|
548
|
-
n_dike = (
|
549
|
-
len(self.dike_x_coordinates) if self.dike_x_coordinates is not None else 0
|
550
|
-
)
|
551
|
-
export = f"VERSIE 4.0\nID {id}\n\nRICHTING {self.dike_orientation}\n\nDAM {int(self.breakwater_type.value)}\nDAMHOOGTE {breakwater_level}\n\nVOORLAND {n_foreland}\n[FORELAND]\nDAMWAND 0\nKRUINHOOGTE {self.dike_crest_level}\nDIJK {n_dike}\n[DIKE]\nMEMO\nGenerated with Pydra for profile '{self.profile_name}'\n{memo}\n"
|
552
|
-
|
553
|
-
# Foreland
|
554
|
-
foreland = ""
|
555
|
-
if n_foreland > 0:
|
556
|
-
for foreland_x, foreland_y in zip(
|
557
|
-
self.foreland_x_coordinates, self.foreland_y_coordinates
|
558
|
-
):
|
559
|
-
foreland = (
|
560
|
-
foreland
|
561
|
-
+ f"{round(foreland_x,3):.3f}\t{round(foreland_y,3):.3f}\t1.000\n"
|
562
|
-
)
|
563
|
-
export = export.replace("[FORELAND]", foreland)
|
564
|
-
|
565
|
-
# Dike
|
566
|
-
dike = ""
|
567
|
-
if n_dike > 0:
|
568
|
-
for dike_x, dike_y, dike_r in zip(
|
569
|
-
self.dike_x_coordinates, self.dike_y_coordinates, self.dike_roughness
|
570
|
-
):
|
571
|
-
dike = (
|
572
|
-
dike
|
573
|
-
+ f"{round(dike_x,3):.3f}\t{round(dike_y,3):.3f}\t{round(dike_r,3):.3f}\n"
|
574
|
-
)
|
575
|
-
export = export.replace("[DIKE]", dike)
|
576
|
-
|
577
|
-
# Export .prfl
|
578
|
-
if not export_path.lower().endswith(".prfl"):
|
579
|
-
export_path = export_path + ".prfl"
|
580
|
-
prfl_file = open(export_path, "w")
|
581
|
-
prfl_file.write(export)
|
582
|
-
prfl_file.close()
|
583
|
-
|
584
|
-
def to_dict(self) -> dict:
|
585
|
-
"""
|
586
|
-
Export Profile to dictionary
|
587
|
-
|
588
|
-
Returns
|
589
|
-
-------
|
590
|
-
dictionary
|
591
|
-
Dictionary with all profile settings
|
592
|
-
"""
|
593
|
-
# Create an empty dictionary
|
594
|
-
profile = {}
|
595
|
-
|
596
|
-
# Add all settings to the dictionary
|
597
|
-
for setting in dir(self):
|
598
|
-
if not str(setting).startswith("__") and not callable(
|
599
|
-
getattr(self, setting)
|
600
|
-
):
|
601
|
-
profile[setting] = getattr(self, setting)
|
602
|
-
|
603
|
-
return profile
|
604
|
-
|
605
|
-
def draw_profile(self) -> None:
|
606
|
-
"""
|
607
|
-
Draw a cross-section of the profile
|
608
|
-
"""
|
609
|
-
# Init plot
|
610
|
-
plt.figure(figsize=[8, 5])
|
611
|
-
|
612
|
-
# Foreland
|
613
|
-
if self.foreland_x_coordinates is not None:
|
614
|
-
plt.plot(
|
615
|
-
self.foreland_x_coordinates,
|
616
|
-
self.foreland_y_coordinates,
|
617
|
-
color="orange",
|
618
|
-
label="Foreland",
|
619
|
-
zorder=1,
|
620
|
-
)
|
621
|
-
|
622
|
-
# Geometry
|
623
|
-
for i in range(len(self.dike_x_coordinates) - 1):
|
624
|
-
r = self.dike_roughness[i]
|
625
|
-
plt.plot(
|
626
|
-
self.dike_x_coordinates[i : i + 2],
|
627
|
-
self.dike_y_coordinates[i : i + 2],
|
628
|
-
color="black" if r != 1.0 else "green",
|
629
|
-
label=f"Roughness: {r}",
|
630
|
-
zorder=1,
|
631
|
-
)
|
632
|
-
|
633
|
-
# Breakwater
|
634
|
-
if isinstance(self.breakwater_type, Breakwater):
|
635
|
-
# Where should we draw the breakwater?
|
636
|
-
if self.foreland_x_coordinates is not None:
|
637
|
-
x_orig, y_orig = (
|
638
|
-
self.foreland_x_coordinates[0],
|
639
|
-
self.foreland_y_coordinates[0],
|
640
|
-
)
|
641
|
-
else:
|
642
|
-
x_orig, y_orig = self.dike_x_coordinates[0], self.dike_y_coordinates[0]
|
643
|
-
|
644
|
-
# Draw
|
645
|
-
bw_height = self.breakwater_level
|
646
|
-
if self.breakwater_type == Breakwater.CAISSON:
|
647
|
-
plt.fill_between(
|
648
|
-
[x_orig - 10, x_orig],
|
649
|
-
[bw_height, bw_height],
|
650
|
-
[y_orig, y_orig],
|
651
|
-
color="dimgrey",
|
652
|
-
label="Caisson",
|
653
|
-
zorder=2,
|
654
|
-
)
|
655
|
-
elif self.breakwater_type == Breakwater.VERTICAL_WALL:
|
656
|
-
plt.plot(
|
657
|
-
[x_orig, x_orig],
|
658
|
-
[y_orig, bw_height],
|
659
|
-
color="black",
|
660
|
-
lw=3,
|
661
|
-
label="Vertical wall",
|
662
|
-
zorder=2,
|
663
|
-
)
|
664
|
-
elif self.breakwater_type == Breakwater.RUBBLE_MOUND:
|
665
|
-
diff = bw_height - y_orig
|
666
|
-
plt.fill_between(
|
667
|
-
[
|
668
|
-
x_orig - (3 * diff) - 2,
|
669
|
-
x_orig - (1.5 * diff) - 2,
|
670
|
-
x_orig - (1.5 * diff),
|
671
|
-
x_orig,
|
672
|
-
],
|
673
|
-
[y_orig, bw_height, bw_height, y_orig],
|
674
|
-
[y_orig, y_orig, y_orig, y_orig],
|
675
|
-
color="grey",
|
676
|
-
label="Rubble mound",
|
677
|
-
zorder=2,
|
678
|
-
)
|
679
|
-
|
680
|
-
# Crest height
|
681
|
-
plt.axhline(
|
682
|
-
self.dike_crest_level,
|
683
|
-
linestyle=":",
|
684
|
-
color="grey",
|
685
|
-
label="Crest height",
|
686
|
-
zorder=1,
|
687
|
-
)
|
688
|
-
|
689
|
-
# Legend, labels, etc
|
690
|
-
handles, labels = plt.gca().get_legend_handles_labels()
|
691
|
-
by_label = dict(zip(labels, handles))
|
692
|
-
plt.legend(by_label.values(), by_label.keys(), loc="upper left")
|
693
|
-
plt.title(f"{self.profile_name} ({self.dike_orientation}°)", fontweight="bold")
|
694
|
-
plt.xlabel("Distance [m]")
|
695
|
-
plt.ylabel("Level [NAP+m]")
|
696
|
-
plt.show()
|
697
|
-
|
698
|
-
@classmethod
|
699
|
-
def from_prfl(cls, prfl_path: str, profile_name: str = "Profile"):
|
700
|
-
"""
|
701
|
-
Import a profile from a .prfl file
|
702
|
-
|
703
|
-
Parameters
|
704
|
-
----------
|
705
|
-
prfl_path : str
|
706
|
-
Path to the '.prfl' file
|
707
|
-
profile_name : str
|
708
|
-
Name of the profile (default: 'Profile')
|
709
|
-
|
710
|
-
Returns
|
711
|
-
-------
|
712
|
-
Profile
|
713
|
-
Profile object
|
714
|
-
"""
|
715
|
-
# Check if the file extension if .prfl
|
716
|
-
if not prfl_path.lower().endswith(".prfl"):
|
717
|
-
raise FileNotFoundError(
|
718
|
-
f"[ERROR] Input file: {prfl_path} should be a .prfl file."
|
719
|
-
)
|
720
|
-
|
721
|
-
# Check if the provided path exists
|
722
|
-
if not os.path.exists(prfl_path):
|
723
|
-
raise FileNotFoundError(f"[ERROR] Input file: {prfl_path} not found.")
|
724
|
-
|
725
|
-
# Read the file
|
726
|
-
with open(prfl_path, "r") as file:
|
727
|
-
prfl = file.read()
|
728
|
-
prfl = prfl.replace("\t", " ")
|
729
|
-
|
730
|
-
# Split the SQL commands by a line break (\n) and remove empty lines, stop before 'memo'
|
731
|
-
prfl = [entry.lower().strip() for entry in prfl.split("\n") if entry.strip()]
|
732
|
-
prfl = prfl[: prfl.index("memo")]
|
733
|
-
|
734
|
-
# Create a new profile
|
735
|
-
profile = cls(profile_name)
|
736
|
-
|
737
|
-
# Version
|
738
|
-
version = float([entry for entry in prfl if "versie" in entry][0].split(" ")[1])
|
739
|
-
if version != 4.0:
|
740
|
-
raise NotImplementedError(
|
741
|
-
f"[ERROR] Prfl version {version} is not supported."
|
742
|
-
)
|
743
|
-
|
744
|
-
# Sheet pile
|
745
|
-
sheetpile = (
|
746
|
-
True
|
747
|
-
if float([entry for entry in prfl if "damwand" in entry][0].split(" ")[1])
|
748
|
-
== 1.0
|
749
|
-
else False
|
750
|
-
)
|
751
|
-
if sheetpile:
|
752
|
-
raise NotImplementedError("[ERROR] Sheet piles are not implemented.")
|
753
|
-
|
754
|
-
# Breakwater
|
755
|
-
breakwater = Breakwater(
|
756
|
-
int([entry for entry in prfl if "dam" in entry][0].split(" ")[1])
|
757
|
-
)
|
758
|
-
breakwater_level = float(
|
759
|
-
[entry for entry in prfl if "damhoogte" in entry][0].split(" ")[1]
|
760
|
-
)
|
761
|
-
profile.set_breakwater(breakwater, breakwater_level)
|
762
|
-
|
763
|
-
# Foreland
|
764
|
-
n_foreland = int(
|
765
|
-
[entry for entry in prfl if "voorland" in entry][0].split(" ")[1]
|
766
|
-
)
|
767
|
-
idx_foreland = prfl.index(f"voorland {n_foreland}") + 1
|
768
|
-
foreland_x = []
|
769
|
-
foreland_y = []
|
770
|
-
for row in range(idx_foreland, idx_foreland + n_foreland):
|
771
|
-
foreland_x.extend([float(prfl[row].split(" ")[0])])
|
772
|
-
foreland_y.extend([float(prfl[row].split(" ")[1])])
|
773
|
-
if n_foreland > 0:
|
774
|
-
profile.set_foreland_geometry(foreland_x, foreland_y)
|
775
|
-
|
776
|
-
# Dike
|
777
|
-
n_dike = int([entry for entry in prfl if "dijk" in entry][0].split(" ")[1])
|
778
|
-
idx_dike = prfl.index(f"dijk {n_dike}") + 1
|
779
|
-
dike_x = []
|
780
|
-
dike_y = []
|
781
|
-
dike_r = []
|
782
|
-
for row in range(idx_dike, idx_dike + n_dike):
|
783
|
-
dike_x.extend([float(prfl[row].split(" ")[0])])
|
784
|
-
dike_y.extend([float(prfl[row].split(" ")[1])])
|
785
|
-
dike_r.extend([float(prfl[row].split(" ")[2])])
|
786
|
-
profile.set_dike_geometry(dike_x, dike_y, dike_r)
|
787
|
-
|
788
|
-
# Crest height
|
789
|
-
dike_crest_level = float(
|
790
|
-
[entry for entry in prfl if "kruinhoogte" in entry][0].split(" ")[1]
|
791
|
-
)
|
792
|
-
profile.set_dike_crest_level(dike_crest_level)
|
793
|
-
|
794
|
-
# Dike orientation
|
795
|
-
dike_orientation = float(
|
796
|
-
[entry for entry in prfl if "richting" in entry][0].split(" ")[1]
|
797
|
-
)
|
798
|
-
profile.set_dike_orientation(dike_orientation)
|
799
|
-
|
800
|
-
# Return the class
|
801
|
-
return profile
|
802
|
-
|
803
|
-
@classmethod
|
804
|
-
def from_dictionary(cls, dictionary: dict):
|
805
|
-
"""
|
806
|
-
Create a profile from a dictionary
|
807
|
-
|
808
|
-
Parameters
|
809
|
-
----------
|
810
|
-
dictionary: dict
|
811
|
-
Dictionary with all profile settings
|
812
|
-
"""
|
813
|
-
# Create a new profile
|
814
|
-
profile = cls(dictionary["profile_name"])
|
815
|
-
|
816
|
-
# Add settings from dictionary to profile
|
817
|
-
for setting in dictionary.keys():
|
818
|
-
setattr(profile, setting, dictionary[setting])
|
819
|
-
|
820
|
-
# Validate
|
821
|
-
profile.validate_profile()
|
822
|
-
|
823
|
-
return profile
|
824
|
-
|
825
|
-
@classmethod
|
826
|
-
def from_gebugekb_tool(
|
827
|
-
cls, sql_path: str, profile_name: str = "Profile", berm_slope: float = 1 / 100
|
828
|
-
):
|
829
|
-
"""
|
830
|
-
Import a profile from the GEBUGEKB plugin.
|
831
|
-
|
832
|
-
Parameters
|
833
|
-
----------
|
834
|
-
sql_path : str
|
835
|
-
Path to the '1.sql' file
|
836
|
-
profile_name : str
|
837
|
-
Name of the profile (default: 'Profile')
|
838
|
-
berm_slope : float
|
839
|
-
If applicable: slope of the berm (default : 1/100)
|
840
|
-
|
841
|
-
Returns
|
842
|
-
-------
|
843
|
-
Profile
|
844
|
-
Profile object
|
845
|
-
"""
|
846
|
-
# Check if the file extension if .prfl
|
847
|
-
if not sql_path.lower().endswith(".sql"):
|
848
|
-
raise FileNotFoundError(
|
849
|
-
f"[ERROR] Input file: {sql_path} should be a .sql file."
|
850
|
-
)
|
851
|
-
|
852
|
-
# Check if the provided path exists
|
853
|
-
if not os.path.exists(sql_path):
|
854
|
-
raise FileNotFoundError(f"[ERROR] Input file: {sql_path} not found.")
|
855
|
-
|
856
|
-
# Check if the berm slope is not too steep or shallow
|
857
|
-
if berm_slope < 1 / 100 or berm_slope > 1 / 15:
|
858
|
-
raise ValueError(
|
859
|
-
f"[ERROR] The slope of the berm cannot be steeper than 1/15 or shallower than 1/100 (Given: 1/{1/berm_slope})."
|
860
|
-
)
|
861
|
-
|
862
|
-
# Read the file
|
863
|
-
with open(sql_path, "r") as file:
|
864
|
-
sql_commands = file.read()
|
865
|
-
|
866
|
-
# Split the SQL commands by a line break (\n)
|
867
|
-
commands = sql_commands.split("\n")
|
868
|
-
|
869
|
-
# Remove all lines starting with 'DELETE FROM', '--' or is empty. Remove comments (by splitting at the semicolumn)
|
870
|
-
commands = [
|
871
|
-
entry.split(";")[0]
|
872
|
-
for entry in commands
|
873
|
-
if not entry.startswith("DELETE FROM")
|
874
|
-
and not entry.startswith("--")
|
875
|
-
and not entry == ""
|
876
|
-
]
|
877
|
-
|
878
|
-
# Create a new profile
|
879
|
-
profile = cls(profile_name)
|
880
|
-
|
881
|
-
# Breakwater
|
882
|
-
breakwater = [entry for entry in commands if "Breakwaters" in entry]
|
883
|
-
breakwater = np.array(
|
884
|
-
[ast.literal_eval(entry.split("VALUES ")[-1]) for entry in breakwater]
|
885
|
-
)
|
886
|
-
if len(breakwater) > 1:
|
887
|
-
raise ValueError(
|
888
|
-
"[ERROR] Multiple breakwaters are defined. Only one can be defined at a time."
|
889
|
-
)
|
890
|
-
elif len(breakwater) == 1:
|
891
|
-
profile.set_breakwater(Breakwater(int(breakwater[0][1])), breakwater[0][2])
|
892
|
-
|
893
|
-
# Foreland
|
894
|
-
foreland = [entry for entry in commands if "Forelands" in entry]
|
895
|
-
foreland = np.array(
|
896
|
-
[ast.literal_eval(entry.split("VALUES ")[-1]) for entry in foreland]
|
897
|
-
)
|
898
|
-
if len(foreland) > 0:
|
899
|
-
profile.set_foreland_geometry(foreland[:, 2], foreland[:, 3])
|
900
|
-
|
901
|
-
# Dike geometry
|
902
|
-
dike = [
|
903
|
-
entry.replace("NULL", "-999")
|
904
|
-
for entry in commands
|
905
|
-
if "VariableDatas" in entry
|
906
|
-
]
|
907
|
-
dike = np.array(
|
908
|
-
[ast.literal_eval(entry.split("VALUES ")[-1]) for entry in dike]
|
909
|
-
)[:, 4:]
|
910
|
-
|
911
|
-
# Dike geometry
|
912
|
-
slope_lower = dike[dike[:, 0] == 10][0][1]
|
913
|
-
slope_upper = dike[dike[:, 0] == 11][0][1]
|
914
|
-
toe_level = dike[dike[:, 0] == 12][0][1]
|
915
|
-
berm_level = dike[dike[:, 0] == 13][0][1]
|
916
|
-
berm_length = dike[dike[:, 0] == 14][0][1]
|
917
|
-
crest_level = dike[dike[:, 0] == 15][0][1]
|
918
|
-
dike_orientation = dike[dike[:, 0] == 16][0][1]
|
919
|
-
roughness = dike[dike[:, 0] == 17][0][1]
|
920
|
-
zone_roughness = dike[dike[:, 0] == 50][0][1]
|
921
|
-
zone_ymin = dike[dike[:, 0] == 51][0][1]
|
922
|
-
zone_ymax = dike[dike[:, 0] == 52][0][1]
|
923
|
-
|
924
|
-
# Calculate coordinates
|
925
|
-
dike_x = [0]
|
926
|
-
dike_y = [toe_level]
|
927
|
-
|
928
|
-
# If there is no berm
|
929
|
-
if berm_length <= 0:
|
930
|
-
dike_x.extend([(berm_level - toe_level) / slope_lower])
|
931
|
-
dike_y.extend([berm_level])
|
932
|
-
else:
|
933
|
-
berm_difference = berm_slope * berm_length
|
934
|
-
dike_x.extend(
|
935
|
-
[(berm_level - 0.5 * berm_difference - toe_level) / slope_lower]
|
936
|
-
)
|
937
|
-
dike_y.extend([berm_level - 0.5 * berm_difference])
|
938
|
-
dike_x.extend([dike_x[-1] + berm_length])
|
939
|
-
dike_y.extend([berm_level + 0.5 * berm_difference])
|
940
|
-
|
941
|
-
# Crest
|
942
|
-
dike_x.extend([dike_x[-1] + (crest_level - dike_y[-1]) / slope_upper])
|
943
|
-
dike_y.extend([crest_level])
|
944
|
-
|
945
|
-
# Roughness
|
946
|
-
dike_r = np.ones([len(dike_x)]) * roughness
|
947
|
-
dike_r[(dike_y >= zone_ymin) & (dike_y < zone_ymax)] = zone_roughness
|
948
|
-
|
949
|
-
# Do we need to add an extra point for zone_ymin?
|
950
|
-
if (zone_ymin >= np.min(dike_y)) and (zone_ymin not in dike_y):
|
951
|
-
x_int = Interpolate.inextrp1d(zone_ymin, dike_y, dike_x)
|
952
|
-
idx = np.searchsorted(dike_x, x_int)
|
953
|
-
dike_x = np.insert(dike_x, idx, x_int)
|
954
|
-
dike_y = np.insert(dike_y, idx, zone_ymin)
|
955
|
-
dike_r = np.insert(dike_r, idx, zone_roughness)
|
956
|
-
|
957
|
-
# Do we need to add an extra point for zone_ymax?
|
958
|
-
if (zone_ymax <= np.max(dike_y)) and (zone_ymax not in dike_y):
|
959
|
-
x_int = Interpolate.inextrp1d(zone_ymax, dike_y, dike_x)
|
960
|
-
idx = np.searchsorted(dike_x, x_int)
|
961
|
-
dike_x = np.insert(dike_x, idx, x_int)
|
962
|
-
dike_y = np.insert(dike_y, idx, zone_ymax)
|
963
|
-
dike_r = np.insert(dike_r, idx, roughness)
|
964
|
-
|
965
|
-
# Dike orientation, crest and geometry
|
966
|
-
profile.set_dike_orientation(dike_orientation)
|
967
|
-
profile.set_dike_geometry(dike_x, dike_y, dike_r)
|
968
|
-
profile.set_dike_crest_level(crest_level)
|
969
|
-
|
970
|
-
# Return the class
|
971
|
-
return profile
|
1
|
+
import ast
|
2
|
+
import matplotlib.pyplot as plt
|
3
|
+
import numpy as np
|
4
|
+
import os
|
5
|
+
|
6
|
+
from typing import Tuple, Union
|
7
|
+
|
8
|
+
from .foreland import Foreland
|
9
|
+
from .profile_loading import ProfileLoading
|
10
|
+
from ...common.enum import Breakwater
|
11
|
+
from ...common.interpolate import Interpolate
|
12
|
+
|
13
|
+
|
14
|
+
class Profile:
|
15
|
+
"""
|
16
|
+
Profile class
|
17
|
+
|
18
|
+
TODO: Implement support for sheet piles
|
19
|
+
"""
|
20
|
+
|
21
|
+
# Profile name
|
22
|
+
profile_name = None
|
23
|
+
|
24
|
+
# Breakwater
|
25
|
+
breakwater_type = Breakwater.NO_BREAKWATER
|
26
|
+
breakwater_level = 0.0
|
27
|
+
|
28
|
+
# Foreland
|
29
|
+
foreland_x_coordinates: None | list = None
|
30
|
+
foreland_y_coordinates: None | list = None
|
31
|
+
|
32
|
+
# Dike schematisation
|
33
|
+
dike_orientation: None | float = None
|
34
|
+
dike_crest_level: None | float = None
|
35
|
+
dike_x_coordinates: None | list = None
|
36
|
+
dike_y_coordinates: None | list = None
|
37
|
+
dike_roughness: None | list = None
|
38
|
+
|
39
|
+
def __init__(self, profile_name: str = "Profile"):
|
40
|
+
"""
|
41
|
+
Create a new profile
|
42
|
+
|
43
|
+
Parameters
|
44
|
+
----------
|
45
|
+
profile_name: str
|
46
|
+
Name of the profile (default: 'Profile')
|
47
|
+
"""
|
48
|
+
# Save the profile name
|
49
|
+
self.profile_name = profile_name
|
50
|
+
|
51
|
+
def validate_profile(self) -> bool:
|
52
|
+
"""
|
53
|
+
Function to validate the profile.
|
54
|
+
|
55
|
+
Returns
|
56
|
+
-------
|
57
|
+
bool
|
58
|
+
True if the profile is OK
|
59
|
+
"""
|
60
|
+
# TODO: Improve validation
|
61
|
+
# Check necessary components
|
62
|
+
# Orientation
|
63
|
+
if self.dike_orientation is None:
|
64
|
+
return False
|
65
|
+
|
66
|
+
# Crest height
|
67
|
+
if self.dike_crest_level is None:
|
68
|
+
return False
|
69
|
+
|
70
|
+
# Geometry
|
71
|
+
if (
|
72
|
+
(self.dike_x_coordinates is None)
|
73
|
+
or (self.dike_y_coordinates is None)
|
74
|
+
or (self.dike_roughness is None)
|
75
|
+
):
|
76
|
+
return False
|
77
|
+
|
78
|
+
return True
|
79
|
+
|
80
|
+
def set_dike_orientation(self, dike_orientation: float):
|
81
|
+
"""
|
82
|
+
Change the dike orientation
|
83
|
+
|
84
|
+
Parameters
|
85
|
+
----------
|
86
|
+
dike_orientation : float
|
87
|
+
The dike orientation
|
88
|
+
"""
|
89
|
+
self.dike_orientation = dike_orientation
|
90
|
+
|
91
|
+
def set_dike_crest_level(self, dike_crest_level: float):
|
92
|
+
"""
|
93
|
+
Change the crest level
|
94
|
+
|
95
|
+
Parameters
|
96
|
+
----------
|
97
|
+
dike_crest_level : float
|
98
|
+
The crest level of the dike
|
99
|
+
"""
|
100
|
+
self.dike_crest_level = dike_crest_level
|
101
|
+
|
102
|
+
def set_dike_geometry(
|
103
|
+
self,
|
104
|
+
dike_x_coordinates: list,
|
105
|
+
dike_y_coordinates: list,
|
106
|
+
dike_roughness: list = None,
|
107
|
+
):
|
108
|
+
"""
|
109
|
+
Change the geometry of the outer slope of the dike
|
110
|
+
|
111
|
+
Parameters
|
112
|
+
----------
|
113
|
+
dike_x_coordinates : list
|
114
|
+
A list with the x coordinates of the profile
|
115
|
+
dike_y_coordinates : list
|
116
|
+
A list with the y coordinates of the profile
|
117
|
+
dike_roughness : list, optional
|
118
|
+
A list with the roughness of the profile (default : all parts 1.0)
|
119
|
+
"""
|
120
|
+
# Make sure the dike geometry starts at (x = 0)
|
121
|
+
min_x = np.min(dike_x_coordinates)
|
122
|
+
|
123
|
+
# If dike roughness is None, the roughness of every part is 1.0
|
124
|
+
if dike_roughness is None:
|
125
|
+
dike_roughness = [1.0] * len(dike_x_coordinates)
|
126
|
+
|
127
|
+
# Save the dike geometry coordinates
|
128
|
+
self.dike_x_coordinates = dike_x_coordinates - min_x
|
129
|
+
self.dike_y_coordinates = dike_y_coordinates
|
130
|
+
self.dike_roughness = dike_roughness
|
131
|
+
|
132
|
+
def has_foreland(self) -> bool:
|
133
|
+
"""
|
134
|
+
Returns whether the profile has a foreland or breakwater
|
135
|
+
|
136
|
+
Returns
|
137
|
+
-------
|
138
|
+
bool
|
139
|
+
True if the profile has a foreland or breakwater
|
140
|
+
"""
|
141
|
+
# Check for a breakwater
|
142
|
+
if self.breakwater_type != Breakwater.NO_BREAKWATER:
|
143
|
+
return True
|
144
|
+
|
145
|
+
# Check for a foreland
|
146
|
+
if self.foreland_x_coordinates is not None:
|
147
|
+
return True
|
148
|
+
|
149
|
+
# No foreland or breakwater
|
150
|
+
return False
|
151
|
+
|
152
|
+
def set_foreland_geometry(
|
153
|
+
self, foreland_x_coordinates: list = None, foreland_y_coordinates: list = None
|
154
|
+
):
|
155
|
+
"""
|
156
|
+
Change the geometry of the foreland
|
157
|
+
Setting the foreland x and y coordinates to None will remove the foreland.
|
158
|
+
|
159
|
+
Parameters
|
160
|
+
----------
|
161
|
+
foreland_x_coordinates : list
|
162
|
+
A list with the x coordinates of the foreland (default: None)
|
163
|
+
foreland_y_coordinates : list
|
164
|
+
A list with the y coordinates of the foreland (default: None)
|
165
|
+
"""
|
166
|
+
# Add foreland
|
167
|
+
if foreland_x_coordinates is not None:
|
168
|
+
# Make sure the foreland ends at (x = 0)
|
169
|
+
max_x = np.max(foreland_x_coordinates)
|
170
|
+
|
171
|
+
# Save the foreland coordinates
|
172
|
+
self.foreland_x_coordinates = foreland_x_coordinates - max_x
|
173
|
+
self.foreland_y_coordinates = foreland_y_coordinates
|
174
|
+
|
175
|
+
# Delete foreland
|
176
|
+
else:
|
177
|
+
self.foreland_x_coordinates = None
|
178
|
+
self.foreland_y_coordinates = None
|
179
|
+
|
180
|
+
def remove_foreland(self) -> None:
|
181
|
+
"""
|
182
|
+
Remove the foreland
|
183
|
+
Wrapper for set_foreland_geometry()
|
184
|
+
"""
|
185
|
+
self.set_foreland_geometry(
|
186
|
+
foreland_x_coordinates=None, foreland_y_coordinates=None
|
187
|
+
)
|
188
|
+
|
189
|
+
def set_breakwater(
|
190
|
+
self, breakwater_type: Breakwater = None, breakwater_level: float = 0.0
|
191
|
+
):
|
192
|
+
"""
|
193
|
+
Change the breakwater
|
194
|
+
"""
|
195
|
+
# None equals no breakwater
|
196
|
+
if breakwater_type is None:
|
197
|
+
breakwater_type = Breakwater.NO_BREAKWATER
|
198
|
+
|
199
|
+
# If there is no breakwater, the height will be set to None
|
200
|
+
if breakwater_type == Breakwater.NO_BREAKWATER:
|
201
|
+
breakwater_level = 0.0
|
202
|
+
|
203
|
+
# Apply settings
|
204
|
+
self.breakwater_type = breakwater_type
|
205
|
+
self.breakwater_level = breakwater_level
|
206
|
+
|
207
|
+
def remove_breakwater(self) -> None:
|
208
|
+
"""
|
209
|
+
Remove the breakwater
|
210
|
+
Wrapper for set_breakwater()
|
211
|
+
"""
|
212
|
+
self.set_breakwater(
|
213
|
+
breakwater_type=Breakwater.NO_BREAKWATER, breakwater_level=0.0
|
214
|
+
)
|
215
|
+
|
216
|
+
def calculate_overtopping(
|
217
|
+
self,
|
218
|
+
water_level: Union[float, list],
|
219
|
+
significant_wave_height: Union[float, list],
|
220
|
+
spectral_wave_period: Union[float, list],
|
221
|
+
wave_direction: Union[float, list],
|
222
|
+
tp_tspec: float = 1.1,
|
223
|
+
dll_settings: dict = None,
|
224
|
+
) -> Union[float, list]:
|
225
|
+
"""
|
226
|
+
Calculate the overtopping discharge
|
227
|
+
|
228
|
+
Parameters
|
229
|
+
----------
|
230
|
+
water_level : Union[float, list]
|
231
|
+
List or float with the water level
|
232
|
+
significant_wave_height : Union[float, list]
|
233
|
+
List or float with the significant wave height
|
234
|
+
spectral_wave_period : Union[float, list]
|
235
|
+
List or float with the spectral wave period
|
236
|
+
wave_direction : Union[float, list]
|
237
|
+
List or float with the wave direction
|
238
|
+
tp_tspec : float, optional
|
239
|
+
Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
|
240
|
+
|
241
|
+
Returns
|
242
|
+
-------
|
243
|
+
Union[float, list]
|
244
|
+
List or float with the overtopping discharge
|
245
|
+
"""
|
246
|
+
# Transform wave conditions
|
247
|
+
water_level, significant_wave_height, spectral_wave_period, wave_direction = (
|
248
|
+
self.transform_wave_conditions(
|
249
|
+
water_level,
|
250
|
+
significant_wave_height,
|
251
|
+
spectral_wave_period,
|
252
|
+
wave_direction,
|
253
|
+
tp_tspec,
|
254
|
+
force_array=True,
|
255
|
+
)
|
256
|
+
)
|
257
|
+
|
258
|
+
# Create profile loading
|
259
|
+
profile_loading = ProfileLoading(self, dll_settings)
|
260
|
+
|
261
|
+
# Calculate
|
262
|
+
qov = []
|
263
|
+
for _h, _hs, _tspec, _dir in zip(
|
264
|
+
water_level, significant_wave_height, spectral_wave_period, wave_direction
|
265
|
+
):
|
266
|
+
qov.append(profile_loading.calculate_discharge(_h, _hs, _tspec, _dir))
|
267
|
+
|
268
|
+
# Return
|
269
|
+
return qov[0] if len(qov) == 1 else qov
|
270
|
+
|
271
|
+
def calculate_runup(
|
272
|
+
self,
|
273
|
+
water_level: Union[float, list],
|
274
|
+
significant_wave_height: Union[float, list],
|
275
|
+
spectral_wave_period: Union[float, list],
|
276
|
+
wave_direction: Union[float, list],
|
277
|
+
tp_tspec: float = 1.1,
|
278
|
+
dll_settings: dict = None,
|
279
|
+
) -> Union[float, list]:
|
280
|
+
"""
|
281
|
+
Calculate the runup height
|
282
|
+
|
283
|
+
Parameters
|
284
|
+
----------
|
285
|
+
water_level : Union[float, list]
|
286
|
+
List or float with the water level
|
287
|
+
significant_wave_height : Union[float, list]
|
288
|
+
List or float with the significant wave height
|
289
|
+
spectral_wave_period : Union[float, list]
|
290
|
+
List or float with the spectral wave period
|
291
|
+
wave_direction : Union[float, list]
|
292
|
+
List or float with the wave direction
|
293
|
+
tp_tspec : float, optional
|
294
|
+
Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
|
295
|
+
|
296
|
+
Returns
|
297
|
+
-------
|
298
|
+
Union[float, list]
|
299
|
+
List or float with the runup height
|
300
|
+
"""
|
301
|
+
# Transform wave conditions
|
302
|
+
water_level, significant_wave_height, spectral_wave_period, wave_direction = (
|
303
|
+
self.transform_wave_conditions(
|
304
|
+
water_level,
|
305
|
+
significant_wave_height,
|
306
|
+
spectral_wave_period,
|
307
|
+
wave_direction,
|
308
|
+
tp_tspec,
|
309
|
+
force_array=True,
|
310
|
+
)
|
311
|
+
)
|
312
|
+
|
313
|
+
# Create profile loading
|
314
|
+
profile_loading = ProfileLoading(self, dll_settings)
|
315
|
+
|
316
|
+
# Calculate
|
317
|
+
ru2p = []
|
318
|
+
for _h, _hs, _tspec, _dir in zip(
|
319
|
+
water_level, significant_wave_height, spectral_wave_period, wave_direction
|
320
|
+
):
|
321
|
+
ru2p.append(profile_loading.calculate_runup(_h, _hs, _tspec, _dir))
|
322
|
+
|
323
|
+
# Return
|
324
|
+
return ru2p[0] if len(ru2p) == 1 else ru2p
|
325
|
+
|
326
|
+
def calculate_crest_level(
|
327
|
+
self,
|
328
|
+
q_overtopping: float,
|
329
|
+
water_level: Union[float, list],
|
330
|
+
significant_wave_height: Union[float, list],
|
331
|
+
spectral_wave_period: Union[float, list],
|
332
|
+
wave_direction: Union[float, list],
|
333
|
+
tp_tspec: float = 1.1,
|
334
|
+
dll_settings: dict = None,
|
335
|
+
) -> Union[float, list]:
|
336
|
+
"""
|
337
|
+
Calculate the crest level for a given overtopping discharge
|
338
|
+
|
339
|
+
Parameters
|
340
|
+
----------
|
341
|
+
q_overtopping : float
|
342
|
+
Critical overtopping discharge
|
343
|
+
water_level : Union[float, list]
|
344
|
+
List or float with the water level
|
345
|
+
significant_wave_height : Union[float, list]
|
346
|
+
List or float with the significant wave height
|
347
|
+
spectral_wave_period : Union[float, list]
|
348
|
+
List or float with the spectral wave period
|
349
|
+
wave_direction : Union[float, list]
|
350
|
+
List or float with the wave direction
|
351
|
+
tp_tspec : float, optional
|
352
|
+
Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
|
353
|
+
|
354
|
+
Returns
|
355
|
+
-------
|
356
|
+
Union[float, list]
|
357
|
+
List or float with the crest level
|
358
|
+
"""
|
359
|
+
# Transform wave conditions
|
360
|
+
water_level, significant_wave_height, spectral_wave_period, wave_direction = (
|
361
|
+
self.transform_wave_conditions(
|
362
|
+
water_level,
|
363
|
+
significant_wave_height,
|
364
|
+
spectral_wave_period,
|
365
|
+
wave_direction,
|
366
|
+
tp_tspec,
|
367
|
+
force_array=True,
|
368
|
+
)
|
369
|
+
)
|
370
|
+
|
371
|
+
# Length of the list
|
372
|
+
n_q = 1 if isinstance(q_overtopping, (float, int)) else len(q_overtopping)
|
373
|
+
|
374
|
+
# If q_overtopping is an int or float
|
375
|
+
if isinstance(q_overtopping, (float, int)):
|
376
|
+
q_overtopping = [q_overtopping] * len(water_level)
|
377
|
+
|
378
|
+
# If q_overtopping is a list and water_level has length 1
|
379
|
+
elif n_q > 1 and len(water_level) == 1:
|
380
|
+
water_level = [water_level] * n_q
|
381
|
+
significant_wave_height = [significant_wave_height] * n_q
|
382
|
+
spectral_wave_period = [spectral_wave_period] * n_q
|
383
|
+
wave_direction = [wave_direction] * n_q
|
384
|
+
|
385
|
+
# Uneven length of arrays
|
386
|
+
else:
|
387
|
+
raise ValueError("[ERROR] Uneven length of arrays")
|
388
|
+
|
389
|
+
# To numpy
|
390
|
+
q_overtopping = np.array(q_overtopping)
|
391
|
+
water_level = np.array(water_level)
|
392
|
+
significant_wave_height = np.array(significant_wave_height)
|
393
|
+
spectral_wave_period = np.array(spectral_wave_period)
|
394
|
+
wave_direction = np.array(wave_direction)
|
395
|
+
|
396
|
+
# Create profile loading
|
397
|
+
profile_loading = ProfileLoading(self, dll_settings)
|
398
|
+
|
399
|
+
# Calculate crest level
|
400
|
+
hbn = []
|
401
|
+
for _q, _h, _hs, _tspec, _dir in zip(
|
402
|
+
q_overtopping,
|
403
|
+
water_level,
|
404
|
+
significant_wave_height,
|
405
|
+
spectral_wave_period,
|
406
|
+
wave_direction,
|
407
|
+
):
|
408
|
+
hbn.append(profile_loading.calculate_crest_level(_q, _h, _hs, _tspec, _dir))
|
409
|
+
|
410
|
+
# Return
|
411
|
+
return hbn[0] if len(hbn) == 1 else hbn
|
412
|
+
|
413
|
+
def transform_wave_conditions(
|
414
|
+
self,
|
415
|
+
water_level: Union[float, list],
|
416
|
+
significant_wave_height: Union[float, list],
|
417
|
+
spectral_wave_period: Union[float, list],
|
418
|
+
wave_direction: Union[float, list],
|
419
|
+
tp_tspec: float = 1.1,
|
420
|
+
force_array: bool = False,
|
421
|
+
) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
422
|
+
"""
|
423
|
+
Transform the wave conditions for the schematized foreland
|
424
|
+
|
425
|
+
Parameters
|
426
|
+
----------
|
427
|
+
water_level : Union[float, list]
|
428
|
+
Water level
|
429
|
+
significant_wave_height : Union[float, list]
|
430
|
+
Significant wave height
|
431
|
+
spectral_wave_period : Union[float, list]
|
432
|
+
Spectral wave period
|
433
|
+
wave_direction : Union[float, list]
|
434
|
+
Wave direction
|
435
|
+
tp_tspec : float, optional
|
436
|
+
Ratio between Tp and Tspec, only used for dam and foreland (default : 1.1)
|
437
|
+
force_array : bool, optional
|
438
|
+
Always force to return an array
|
439
|
+
|
440
|
+
Returns
|
441
|
+
-------
|
442
|
+
Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]
|
443
|
+
Water level and transformed wave conditions (h, hs, tp, dir)
|
444
|
+
"""
|
445
|
+
# Length of the lists
|
446
|
+
n_h = 1 if isinstance(water_level, (float, int)) else len(water_level)
|
447
|
+
n_hs = (
|
448
|
+
1
|
449
|
+
if isinstance(significant_wave_height, (float, int))
|
450
|
+
else len(significant_wave_height)
|
451
|
+
)
|
452
|
+
n_tspec = (
|
453
|
+
1
|
454
|
+
if isinstance(spectral_wave_period, (float, int))
|
455
|
+
else len(spectral_wave_period)
|
456
|
+
)
|
457
|
+
n_dir = 1 if isinstance(wave_direction, (float, int)) else len(wave_direction)
|
458
|
+
n_max = np.max([n_h, n_hs, n_tspec, n_dir])
|
459
|
+
|
460
|
+
# Make lists
|
461
|
+
if isinstance(water_level, (float, int)):
|
462
|
+
water_level = [water_level] * n_max
|
463
|
+
elif len(water_level) != n_max:
|
464
|
+
raise ValueError("[ERROR] Uneven length of arrays")
|
465
|
+
|
466
|
+
if isinstance(significant_wave_height, (float, int)):
|
467
|
+
significant_wave_height = [significant_wave_height] * n_max
|
468
|
+
elif len(significant_wave_height) != n_max:
|
469
|
+
raise ValueError("[ERROR] Uneven length of arrays")
|
470
|
+
|
471
|
+
if isinstance(spectral_wave_period, (float, int)):
|
472
|
+
spectral_wave_period = [spectral_wave_period] * n_max
|
473
|
+
elif len(spectral_wave_period) != n_max:
|
474
|
+
raise ValueError("[ERROR] Uneven length of arrays")
|
475
|
+
|
476
|
+
if isinstance(wave_direction, (float, int)):
|
477
|
+
wave_direction = [wave_direction] * n_max
|
478
|
+
elif len(wave_direction) != n_max:
|
479
|
+
raise ValueError("[ERROR] Uneven length of arrays")
|
480
|
+
|
481
|
+
# To numpy
|
482
|
+
water_level = np.array(water_level)
|
483
|
+
significant_wave_height = np.array(significant_wave_height)
|
484
|
+
spectral_wave_period = np.array(spectral_wave_period)
|
485
|
+
wave_direction = np.array(wave_direction)
|
486
|
+
|
487
|
+
# Correct for foreland
|
488
|
+
if self.has_foreland():
|
489
|
+
fl = Foreland(self)
|
490
|
+
water_level, significant_wave_height, peak_wave_period, wave_direction = (
|
491
|
+
fl.transform_wave_conditions(
|
492
|
+
water_level,
|
493
|
+
significant_wave_height,
|
494
|
+
spectral_wave_period * tp_tspec,
|
495
|
+
wave_direction,
|
496
|
+
)
|
497
|
+
)
|
498
|
+
spectral_wave_period = peak_wave_period / tp_tspec
|
499
|
+
|
500
|
+
# Return array or floats?
|
501
|
+
if len(water_level.ravel()) == 1 and not force_array:
|
502
|
+
return (
|
503
|
+
water_level.ravel()[0],
|
504
|
+
significant_wave_height.ravel()[0],
|
505
|
+
spectral_wave_period.ravel()[0],
|
506
|
+
wave_direction.ravel()[0],
|
507
|
+
)
|
508
|
+
else:
|
509
|
+
return (
|
510
|
+
water_level,
|
511
|
+
significant_wave_height,
|
512
|
+
spectral_wave_period,
|
513
|
+
wave_direction,
|
514
|
+
)
|
515
|
+
|
516
|
+
def to_prfl(
|
517
|
+
self, export_path: str, id: str = "Onbekend000", memo: str = ""
|
518
|
+
) -> None:
|
519
|
+
"""
|
520
|
+
Export to a prfl file
|
521
|
+
|
522
|
+
export_path : str
|
523
|
+
Path to where the profile has to be exported
|
524
|
+
id : str
|
525
|
+
Id used in RisKeer
|
526
|
+
memo : str
|
527
|
+
Memo to be added to the prfl file
|
528
|
+
"""
|
529
|
+
# Check required info
|
530
|
+
if (
|
531
|
+
(self.dike_x_coordinates is None)
|
532
|
+
or (self.dike_crest_level is None)
|
533
|
+
or (self.dike_orientation is None)
|
534
|
+
):
|
535
|
+
raise ValueError(
|
536
|
+
f"[ERROR] Cannot generate .prfl for profile '{self.profile_name}', geometry, crest level or orientation is missing."
|
537
|
+
)
|
538
|
+
|
539
|
+
# Version
|
540
|
+
breakwater_level = (
|
541
|
+
self.breakwater_level if self.breakwater_level is not None else 0.0
|
542
|
+
)
|
543
|
+
n_foreland = (
|
544
|
+
len(self.foreland_x_coordinates)
|
545
|
+
if self.foreland_x_coordinates is not None
|
546
|
+
else 0
|
547
|
+
)
|
548
|
+
n_dike = (
|
549
|
+
len(self.dike_x_coordinates) if self.dike_x_coordinates is not None else 0
|
550
|
+
)
|
551
|
+
export = f"VERSIE 4.0\nID {id}\n\nRICHTING {self.dike_orientation}\n\nDAM {int(self.breakwater_type.value)}\nDAMHOOGTE {breakwater_level}\n\nVOORLAND {n_foreland}\n[FORELAND]\nDAMWAND 0\nKRUINHOOGTE {self.dike_crest_level}\nDIJK {n_dike}\n[DIKE]\nMEMO\nGenerated with Pydra for profile '{self.profile_name}'\n{memo}\n"
|
552
|
+
|
553
|
+
# Foreland
|
554
|
+
foreland = ""
|
555
|
+
if n_foreland > 0:
|
556
|
+
for foreland_x, foreland_y in zip(
|
557
|
+
self.foreland_x_coordinates, self.foreland_y_coordinates
|
558
|
+
):
|
559
|
+
foreland = (
|
560
|
+
foreland
|
561
|
+
+ f"{round(foreland_x,3):.3f}\t{round(foreland_y,3):.3f}\t1.000\n"
|
562
|
+
)
|
563
|
+
export = export.replace("[FORELAND]", foreland)
|
564
|
+
|
565
|
+
# Dike
|
566
|
+
dike = ""
|
567
|
+
if n_dike > 0:
|
568
|
+
for dike_x, dike_y, dike_r in zip(
|
569
|
+
self.dike_x_coordinates, self.dike_y_coordinates, self.dike_roughness
|
570
|
+
):
|
571
|
+
dike = (
|
572
|
+
dike
|
573
|
+
+ f"{round(dike_x,3):.3f}\t{round(dike_y,3):.3f}\t{round(dike_r,3):.3f}\n"
|
574
|
+
)
|
575
|
+
export = export.replace("[DIKE]", dike)
|
576
|
+
|
577
|
+
# Export .prfl
|
578
|
+
if not export_path.lower().endswith(".prfl"):
|
579
|
+
export_path = export_path + ".prfl"
|
580
|
+
prfl_file = open(export_path, "w")
|
581
|
+
prfl_file.write(export)
|
582
|
+
prfl_file.close()
|
583
|
+
|
584
|
+
def to_dict(self) -> dict:
|
585
|
+
"""
|
586
|
+
Export Profile to dictionary
|
587
|
+
|
588
|
+
Returns
|
589
|
+
-------
|
590
|
+
dictionary
|
591
|
+
Dictionary with all profile settings
|
592
|
+
"""
|
593
|
+
# Create an empty dictionary
|
594
|
+
profile = {}
|
595
|
+
|
596
|
+
# Add all settings to the dictionary
|
597
|
+
for setting in dir(self):
|
598
|
+
if not str(setting).startswith("__") and not callable(
|
599
|
+
getattr(self, setting)
|
600
|
+
):
|
601
|
+
profile[setting] = getattr(self, setting)
|
602
|
+
|
603
|
+
return profile
|
604
|
+
|
605
|
+
def draw_profile(self) -> None:
|
606
|
+
"""
|
607
|
+
Draw a cross-section of the profile
|
608
|
+
"""
|
609
|
+
# Init plot
|
610
|
+
plt.figure(figsize=[8, 5])
|
611
|
+
|
612
|
+
# Foreland
|
613
|
+
if self.foreland_x_coordinates is not None:
|
614
|
+
plt.plot(
|
615
|
+
self.foreland_x_coordinates,
|
616
|
+
self.foreland_y_coordinates,
|
617
|
+
color="orange",
|
618
|
+
label="Foreland",
|
619
|
+
zorder=1,
|
620
|
+
)
|
621
|
+
|
622
|
+
# Geometry
|
623
|
+
for i in range(len(self.dike_x_coordinates) - 1):
|
624
|
+
r = self.dike_roughness[i]
|
625
|
+
plt.plot(
|
626
|
+
self.dike_x_coordinates[i : i + 2],
|
627
|
+
self.dike_y_coordinates[i : i + 2],
|
628
|
+
color="black" if r != 1.0 else "green",
|
629
|
+
label=f"Roughness: {r}",
|
630
|
+
zorder=1,
|
631
|
+
)
|
632
|
+
|
633
|
+
# Breakwater
|
634
|
+
if isinstance(self.breakwater_type, Breakwater):
|
635
|
+
# Where should we draw the breakwater?
|
636
|
+
if self.foreland_x_coordinates is not None:
|
637
|
+
x_orig, y_orig = (
|
638
|
+
self.foreland_x_coordinates[0],
|
639
|
+
self.foreland_y_coordinates[0],
|
640
|
+
)
|
641
|
+
else:
|
642
|
+
x_orig, y_orig = self.dike_x_coordinates[0], self.dike_y_coordinates[0]
|
643
|
+
|
644
|
+
# Draw
|
645
|
+
bw_height = self.breakwater_level
|
646
|
+
if self.breakwater_type == Breakwater.CAISSON:
|
647
|
+
plt.fill_between(
|
648
|
+
[x_orig - 10, x_orig],
|
649
|
+
[bw_height, bw_height],
|
650
|
+
[y_orig, y_orig],
|
651
|
+
color="dimgrey",
|
652
|
+
label="Caisson",
|
653
|
+
zorder=2,
|
654
|
+
)
|
655
|
+
elif self.breakwater_type == Breakwater.VERTICAL_WALL:
|
656
|
+
plt.plot(
|
657
|
+
[x_orig, x_orig],
|
658
|
+
[y_orig, bw_height],
|
659
|
+
color="black",
|
660
|
+
lw=3,
|
661
|
+
label="Vertical wall",
|
662
|
+
zorder=2,
|
663
|
+
)
|
664
|
+
elif self.breakwater_type == Breakwater.RUBBLE_MOUND:
|
665
|
+
diff = bw_height - y_orig
|
666
|
+
plt.fill_between(
|
667
|
+
[
|
668
|
+
x_orig - (3 * diff) - 2,
|
669
|
+
x_orig - (1.5 * diff) - 2,
|
670
|
+
x_orig - (1.5 * diff),
|
671
|
+
x_orig,
|
672
|
+
],
|
673
|
+
[y_orig, bw_height, bw_height, y_orig],
|
674
|
+
[y_orig, y_orig, y_orig, y_orig],
|
675
|
+
color="grey",
|
676
|
+
label="Rubble mound",
|
677
|
+
zorder=2,
|
678
|
+
)
|
679
|
+
|
680
|
+
# Crest height
|
681
|
+
plt.axhline(
|
682
|
+
self.dike_crest_level,
|
683
|
+
linestyle=":",
|
684
|
+
color="grey",
|
685
|
+
label="Crest height",
|
686
|
+
zorder=1,
|
687
|
+
)
|
688
|
+
|
689
|
+
# Legend, labels, etc
|
690
|
+
handles, labels = plt.gca().get_legend_handles_labels()
|
691
|
+
by_label = dict(zip(labels, handles))
|
692
|
+
plt.legend(by_label.values(), by_label.keys(), loc="upper left")
|
693
|
+
plt.title(f"{self.profile_name} ({self.dike_orientation}°)", fontweight="bold")
|
694
|
+
plt.xlabel("Distance [m]")
|
695
|
+
plt.ylabel("Level [NAP+m]")
|
696
|
+
plt.show()
|
697
|
+
|
698
|
+
@classmethod
|
699
|
+
def from_prfl(cls, prfl_path: str, profile_name: str = "Profile"):
|
700
|
+
"""
|
701
|
+
Import a profile from a .prfl file
|
702
|
+
|
703
|
+
Parameters
|
704
|
+
----------
|
705
|
+
prfl_path : str
|
706
|
+
Path to the '.prfl' file
|
707
|
+
profile_name : str
|
708
|
+
Name of the profile (default: 'Profile')
|
709
|
+
|
710
|
+
Returns
|
711
|
+
-------
|
712
|
+
Profile
|
713
|
+
Profile object
|
714
|
+
"""
|
715
|
+
# Check if the file extension if .prfl
|
716
|
+
if not prfl_path.lower().endswith(".prfl"):
|
717
|
+
raise FileNotFoundError(
|
718
|
+
f"[ERROR] Input file: {prfl_path} should be a .prfl file."
|
719
|
+
)
|
720
|
+
|
721
|
+
# Check if the provided path exists
|
722
|
+
if not os.path.exists(prfl_path):
|
723
|
+
raise FileNotFoundError(f"[ERROR] Input file: {prfl_path} not found.")
|
724
|
+
|
725
|
+
# Read the file
|
726
|
+
with open(prfl_path, "r") as file:
|
727
|
+
prfl = file.read()
|
728
|
+
prfl = prfl.replace("\t", " ")
|
729
|
+
|
730
|
+
# Split the SQL commands by a line break (\n) and remove empty lines, stop before 'memo'
|
731
|
+
prfl = [entry.lower().strip() for entry in prfl.split("\n") if entry.strip()]
|
732
|
+
prfl = prfl[: prfl.index("memo")]
|
733
|
+
|
734
|
+
# Create a new profile
|
735
|
+
profile = cls(profile_name)
|
736
|
+
|
737
|
+
# Version
|
738
|
+
version = float([entry for entry in prfl if "versie" in entry][0].split(" ")[1])
|
739
|
+
if version != 4.0:
|
740
|
+
raise NotImplementedError(
|
741
|
+
f"[ERROR] Prfl version {version} is not supported."
|
742
|
+
)
|
743
|
+
|
744
|
+
# Sheet pile
|
745
|
+
sheetpile = (
|
746
|
+
True
|
747
|
+
if float([entry for entry in prfl if "damwand" in entry][0].split(" ")[1])
|
748
|
+
== 1.0
|
749
|
+
else False
|
750
|
+
)
|
751
|
+
if sheetpile:
|
752
|
+
raise NotImplementedError("[ERROR] Sheet piles are not implemented.")
|
753
|
+
|
754
|
+
# Breakwater
|
755
|
+
breakwater = Breakwater(
|
756
|
+
int([entry for entry in prfl if "dam" in entry][0].split(" ")[1])
|
757
|
+
)
|
758
|
+
breakwater_level = float(
|
759
|
+
[entry for entry in prfl if "damhoogte" in entry][0].split(" ")[1]
|
760
|
+
)
|
761
|
+
profile.set_breakwater(breakwater, breakwater_level)
|
762
|
+
|
763
|
+
# Foreland
|
764
|
+
n_foreland = int(
|
765
|
+
[entry for entry in prfl if "voorland" in entry][0].split(" ")[1]
|
766
|
+
)
|
767
|
+
idx_foreland = prfl.index(f"voorland {n_foreland}") + 1
|
768
|
+
foreland_x = []
|
769
|
+
foreland_y = []
|
770
|
+
for row in range(idx_foreland, idx_foreland + n_foreland):
|
771
|
+
foreland_x.extend([float(prfl[row].split(" ")[0])])
|
772
|
+
foreland_y.extend([float(prfl[row].split(" ")[1])])
|
773
|
+
if n_foreland > 0:
|
774
|
+
profile.set_foreland_geometry(foreland_x, foreland_y)
|
775
|
+
|
776
|
+
# Dike
|
777
|
+
n_dike = int([entry for entry in prfl if "dijk" in entry][0].split(" ")[1])
|
778
|
+
idx_dike = prfl.index(f"dijk {n_dike}") + 1
|
779
|
+
dike_x = []
|
780
|
+
dike_y = []
|
781
|
+
dike_r = []
|
782
|
+
for row in range(idx_dike, idx_dike + n_dike):
|
783
|
+
dike_x.extend([float(prfl[row].split(" ")[0])])
|
784
|
+
dike_y.extend([float(prfl[row].split(" ")[1])])
|
785
|
+
dike_r.extend([float(prfl[row].split(" ")[2])])
|
786
|
+
profile.set_dike_geometry(dike_x, dike_y, dike_r)
|
787
|
+
|
788
|
+
# Crest height
|
789
|
+
dike_crest_level = float(
|
790
|
+
[entry for entry in prfl if "kruinhoogte" in entry][0].split(" ")[1]
|
791
|
+
)
|
792
|
+
profile.set_dike_crest_level(dike_crest_level)
|
793
|
+
|
794
|
+
# Dike orientation
|
795
|
+
dike_orientation = float(
|
796
|
+
[entry for entry in prfl if "richting" in entry][0].split(" ")[1]
|
797
|
+
)
|
798
|
+
profile.set_dike_orientation(dike_orientation)
|
799
|
+
|
800
|
+
# Return the class
|
801
|
+
return profile
|
802
|
+
|
803
|
+
@classmethod
|
804
|
+
def from_dictionary(cls, dictionary: dict):
|
805
|
+
"""
|
806
|
+
Create a profile from a dictionary
|
807
|
+
|
808
|
+
Parameters
|
809
|
+
----------
|
810
|
+
dictionary: dict
|
811
|
+
Dictionary with all profile settings
|
812
|
+
"""
|
813
|
+
# Create a new profile
|
814
|
+
profile = cls(dictionary["profile_name"])
|
815
|
+
|
816
|
+
# Add settings from dictionary to profile
|
817
|
+
for setting in dictionary.keys():
|
818
|
+
setattr(profile, setting, dictionary[setting])
|
819
|
+
|
820
|
+
# Validate
|
821
|
+
profile.validate_profile()
|
822
|
+
|
823
|
+
return profile
|
824
|
+
|
825
|
+
@classmethod
|
826
|
+
def from_gebugekb_tool(
|
827
|
+
cls, sql_path: str, profile_name: str = "Profile", berm_slope: float = 1 / 100
|
828
|
+
):
|
829
|
+
"""
|
830
|
+
Import a profile from the GEBUGEKB plugin.
|
831
|
+
|
832
|
+
Parameters
|
833
|
+
----------
|
834
|
+
sql_path : str
|
835
|
+
Path to the '1.sql' file
|
836
|
+
profile_name : str
|
837
|
+
Name of the profile (default: 'Profile')
|
838
|
+
berm_slope : float
|
839
|
+
If applicable: slope of the berm (default : 1/100)
|
840
|
+
|
841
|
+
Returns
|
842
|
+
-------
|
843
|
+
Profile
|
844
|
+
Profile object
|
845
|
+
"""
|
846
|
+
# Check if the file extension if .prfl
|
847
|
+
if not sql_path.lower().endswith(".sql"):
|
848
|
+
raise FileNotFoundError(
|
849
|
+
f"[ERROR] Input file: {sql_path} should be a .sql file."
|
850
|
+
)
|
851
|
+
|
852
|
+
# Check if the provided path exists
|
853
|
+
if not os.path.exists(sql_path):
|
854
|
+
raise FileNotFoundError(f"[ERROR] Input file: {sql_path} not found.")
|
855
|
+
|
856
|
+
# Check if the berm slope is not too steep or shallow
|
857
|
+
if berm_slope < 1 / 100 or berm_slope > 1 / 15:
|
858
|
+
raise ValueError(
|
859
|
+
f"[ERROR] The slope of the berm cannot be steeper than 1/15 or shallower than 1/100 (Given: 1/{1/berm_slope})."
|
860
|
+
)
|
861
|
+
|
862
|
+
# Read the file
|
863
|
+
with open(sql_path, "r") as file:
|
864
|
+
sql_commands = file.read()
|
865
|
+
|
866
|
+
# Split the SQL commands by a line break (\n)
|
867
|
+
commands = sql_commands.split("\n")
|
868
|
+
|
869
|
+
# Remove all lines starting with 'DELETE FROM', '--' or is empty. Remove comments (by splitting at the semicolumn)
|
870
|
+
commands = [
|
871
|
+
entry.split(";")[0]
|
872
|
+
for entry in commands
|
873
|
+
if not entry.startswith("DELETE FROM")
|
874
|
+
and not entry.startswith("--")
|
875
|
+
and not entry == ""
|
876
|
+
]
|
877
|
+
|
878
|
+
# Create a new profile
|
879
|
+
profile = cls(profile_name)
|
880
|
+
|
881
|
+
# Breakwater
|
882
|
+
breakwater = [entry for entry in commands if "Breakwaters" in entry]
|
883
|
+
breakwater = np.array(
|
884
|
+
[ast.literal_eval(entry.split("VALUES ")[-1]) for entry in breakwater]
|
885
|
+
)
|
886
|
+
if len(breakwater) > 1:
|
887
|
+
raise ValueError(
|
888
|
+
"[ERROR] Multiple breakwaters are defined. Only one can be defined at a time."
|
889
|
+
)
|
890
|
+
elif len(breakwater) == 1:
|
891
|
+
profile.set_breakwater(Breakwater(int(breakwater[0][1])), breakwater[0][2])
|
892
|
+
|
893
|
+
# Foreland
|
894
|
+
foreland = [entry for entry in commands if "Forelands" in entry]
|
895
|
+
foreland = np.array(
|
896
|
+
[ast.literal_eval(entry.split("VALUES ")[-1]) for entry in foreland]
|
897
|
+
)
|
898
|
+
if len(foreland) > 0:
|
899
|
+
profile.set_foreland_geometry(foreland[:, 2], foreland[:, 3])
|
900
|
+
|
901
|
+
# Dike geometry
|
902
|
+
dike = [
|
903
|
+
entry.replace("NULL", "-999")
|
904
|
+
for entry in commands
|
905
|
+
if "VariableDatas" in entry
|
906
|
+
]
|
907
|
+
dike = np.array(
|
908
|
+
[ast.literal_eval(entry.split("VALUES ")[-1]) for entry in dike]
|
909
|
+
)[:, 4:]
|
910
|
+
|
911
|
+
# Dike geometry
|
912
|
+
slope_lower = dike[dike[:, 0] == 10][0][1]
|
913
|
+
slope_upper = dike[dike[:, 0] == 11][0][1]
|
914
|
+
toe_level = dike[dike[:, 0] == 12][0][1]
|
915
|
+
berm_level = dike[dike[:, 0] == 13][0][1]
|
916
|
+
berm_length = dike[dike[:, 0] == 14][0][1]
|
917
|
+
crest_level = dike[dike[:, 0] == 15][0][1]
|
918
|
+
dike_orientation = dike[dike[:, 0] == 16][0][1]
|
919
|
+
roughness = dike[dike[:, 0] == 17][0][1]
|
920
|
+
zone_roughness = dike[dike[:, 0] == 50][0][1]
|
921
|
+
zone_ymin = dike[dike[:, 0] == 51][0][1]
|
922
|
+
zone_ymax = dike[dike[:, 0] == 52][0][1]
|
923
|
+
|
924
|
+
# Calculate coordinates
|
925
|
+
dike_x = [0]
|
926
|
+
dike_y = [toe_level]
|
927
|
+
|
928
|
+
# If there is no berm
|
929
|
+
if berm_length <= 0:
|
930
|
+
dike_x.extend([(berm_level - toe_level) / slope_lower])
|
931
|
+
dike_y.extend([berm_level])
|
932
|
+
else:
|
933
|
+
berm_difference = berm_slope * berm_length
|
934
|
+
dike_x.extend(
|
935
|
+
[(berm_level - 0.5 * berm_difference - toe_level) / slope_lower]
|
936
|
+
)
|
937
|
+
dike_y.extend([berm_level - 0.5 * berm_difference])
|
938
|
+
dike_x.extend([dike_x[-1] + berm_length])
|
939
|
+
dike_y.extend([berm_level + 0.5 * berm_difference])
|
940
|
+
|
941
|
+
# Crest
|
942
|
+
dike_x.extend([dike_x[-1] + (crest_level - dike_y[-1]) / slope_upper])
|
943
|
+
dike_y.extend([crest_level])
|
944
|
+
|
945
|
+
# Roughness
|
946
|
+
dike_r = np.ones([len(dike_x)]) * roughness
|
947
|
+
dike_r[(dike_y >= zone_ymin) & (dike_y < zone_ymax)] = zone_roughness
|
948
|
+
|
949
|
+
# Do we need to add an extra point for zone_ymin?
|
950
|
+
if (zone_ymin >= np.min(dike_y)) and (zone_ymin not in dike_y):
|
951
|
+
x_int = Interpolate.inextrp1d(zone_ymin, dike_y, dike_x)
|
952
|
+
idx = np.searchsorted(dike_x, x_int)
|
953
|
+
dike_x = np.insert(dike_x, idx, x_int)
|
954
|
+
dike_y = np.insert(dike_y, idx, zone_ymin)
|
955
|
+
dike_r = np.insert(dike_r, idx, zone_roughness)
|
956
|
+
|
957
|
+
# Do we need to add an extra point for zone_ymax?
|
958
|
+
if (zone_ymax <= np.max(dike_y)) and (zone_ymax not in dike_y):
|
959
|
+
x_int = Interpolate.inextrp1d(zone_ymax, dike_y, dike_x)
|
960
|
+
idx = np.searchsorted(dike_x, x_int)
|
961
|
+
dike_x = np.insert(dike_x, idx, x_int)
|
962
|
+
dike_y = np.insert(dike_y, idx, zone_ymax)
|
963
|
+
dike_r = np.insert(dike_r, idx, roughness)
|
964
|
+
|
965
|
+
# Dike orientation, crest and geometry
|
966
|
+
profile.set_dike_orientation(dike_orientation)
|
967
|
+
profile.set_dike_geometry(dike_x, dike_y, dike_r)
|
968
|
+
profile.set_dike_crest_level(crest_level)
|
969
|
+
|
970
|
+
# Return the class
|
971
|
+
return profile
|