Compare commits

...
157 Commits
Author SHA1 Message Date
Theophile Terraz 9b6abadb5a debug release 2025-01-23 16:57:03 +01:00
Theophile Terraz 686b01c43a Merge branch 'master' of gitlab.com:pamhyr/pamhyr2 2025-01-23 15:17:52 +01:00
Theophile Terraz 04afbf2f84 debug CI 2025-01-23 15:16:22 +01:00
Dorian Hernandez 75f2796748 Ajout du TP AdisTS dans la release 2025-01-23 14:29:07 +01:00
Dorian Hernandez 45179bc542 Ajout du TP AdisTS 2025-01-23 14:11:11 +01:00
Theophile Terraz 67729e94bf add Tuto 2 (thanks to Celine Berni) 2025-01-23 10:03:00 +01:00
Theophile Terraz c53e82a423 debug remove sediment 2025-01-22 16:01:59 +01:00
Theophile Terraz 02ccfa9ed7 disable custom plot adists 2025-01-22 11:59:39 +01:00
Theophile Terraz fc5de2a097 pep8 2025-01-22 11:46:08 +01:00
Theophile Terraz 0753c4e1b7 debug profile geometry window 2025-01-22 11:15:07 +01:00
Theophile Terraz d8c2634a66 debug 2025-01-22 09:13:13 +01:00
Theophile Terraz 6f7a891a6d optimization + debug 2025-01-20 16:24:17 +01:00
Theophile Terraz e4224e6358 force Mage sulver type in open from file 2025-01-17 13:54:27 +01:00
Theophile Terraz aa8a9dccbf translation 2025-01-17 12:00:42 +01:00
Theophile Terraz 1732e30e58 debug 2025-01-17 09:31:37 +01:00
Theophile Terraz 9eedd1fff9 debug results 2025-01-17 09:20:01 +01:00
Theophile Terraz ac6e8a3704 debug Adis-TS files generation 2025-01-16 15:54:50 +01:00
Theophile Terraz c5f918c885 pep8 2025-01-16 15:08:24 +01:00
Theophile Terraz 230712c3ea debug Adis-TS 2025-01-16 15:03:52 +01:00
Theophile Terraz 2e2f054a4f debug Adis-TS 2025-01-16 14:16:24 +01:00
Theophile Terraz f75a25d010 debug 2025-01-15 14:26:31 +01:00
Theophile Terraz 9db90debeb translation 2024-12-20 17:13:44 +01:00
Theophile Terraz 2333ab540e debug 2024-12-20 15:54:25 +01:00
Theophile Terraz c81d65f527 rm test case 2024-12-20 15:49:30 +01:00
Theophile Terraz bf44f5c027 rm test case 2024-12-20 15:47:48 +01:00
Theophile Terraz d1400f12a6 debug 2024-12-20 15:41:19 +01:00
Theophile Terraz c610717220 pep8 2024-12-20 10:47:08 +01:00
Theophile Terraz 5edcf15072 Export Adis to csv 2024-12-20 10:05:56 +01:00
Theophile Terraz e4bffce6f4 debug node name in adis BC 2024-12-19 11:24:30 +01:00
Theophile Terraz 54fe032791 pep8 + colors + debug 2024-12-18 16:19:41 +01:00
Theophile Terraz c668dddcfd more work on adis results 2024-12-18 15:17:13 +01:00
Theophile Terraz bdc975f280 work on plot multiple lines 2024-12-17 16:22:07 +01:00
Theophile Terraz 4315fb94f3 debug last solver 2024-12-16 15:34:19 +01:00
Theophile Terraz eb1163f712 debug ci 2024-12-11 11:26:46 +01:00
Theophile Terraz 42f3c02c3e work on release 2024-12-09 17:17:28 +01:00
Theophile Terraz 31ebcf07e0 debug 2024-12-09 14:06:01 +01:00
Theophile Terraz 95612e8ce9 debug 2024-12-09 14:04:48 +01:00
Theophile Terraz e56d88937a pep8 2024-12-09 09:28:00 +01:00
Theophile Terraz 8c697a9621 debug incomplete database 2024-12-09 09:03:02 +01:00
Theophile Terraz 2d3747b3d3 add adists default path 2024-12-05 17:26:47 +01:00
Theophile Terraz b38e252746 cleaning 2024-12-05 16:50:10 +01:00
Theophile Terraz f1d6eb8990 more work on adists results 2024-12-05 16:03:40 +01:00
Theophile Terraz c2c77304d7 remove suspension BC in main window 2024-12-05 14:30:22 +01:00
Theophile Terraz 0b051ad3c6 debug adis BC 2024-12-05 13:38:22 +01:00
Theophile Terraz b72ffe03c3 more work on adis results 2024-12-04 16:09:33 +01:00
Theophile Terraz 01de0cfe93 remove empty tab 2024-12-04 12:01:46 +01:00
Theophile Terraz d6f152958f work on results adis 2024-12-04 11:59:02 +01:00
Theophile Terraz b85962bfcd work on results, type_pol 2024-12-03 14:59:38 +01:00
Theophile Terraz a1ae3f42f4 work on adis results 2024-12-02 15:07:50 +01:00
Theophile Terraz 21876586df debug read_bin 2024-12-02 13:48:57 +01:00
Theophile Terraz a317cd849f more pep8 2024-11-29 11:52:06 +01:00
Theophile Terraz 3b8a49d429 add src/View/ui/OutputRKAdisTS.ui 2024-11-29 09:31:03 +01:00
Theophile Terraz 872235e94f pep8 Model 2024-11-29 09:30:37 +01:00
Theophile Terraz da7ef60bef pep8 src/Solver/AdisTS.py 2024-11-28 14:32:45 +01:00
Theophile Terraz 824669f70f debug 2024-11-28 11:46:20 +01:00
Youcef AOUAD 19a3f3d310 mass zero results fixed 2024-11-28 08:31:40 +01:00
Youcef AOUAD 49aab685fb to fix mass zero 2024-11-27 14:50:44 +01:00
Youcef AOUAD 4383599d30 node name fixed 2024-11-12 09:01:25 +01:00
Youcef AOUAD ae6bca3033 display results from main complete 2024-11-08 09:36:03 +01:00
Theophile Terraz 1266884f93 Merge branch 'terraz_dev' into adists_release 2024-11-07 16:29:19 +01:00
Theophile Terraz f91527464d Merge branch 'master' into terraz_dev 2024-11-07 16:28:24 +01:00
Youcef AOUAD 97f8a3ccde correction of results 2024-11-07 14:20:58 +01:00
Theophile Terraz cef67540c2 debug 2024-11-06 13:40:16 +01:00
Theophile Terraz ff38571933 merge 2024-11-05 13:29:12 +01:00
Theophile Terraz 4f69553bd3 merge 2024-10-31 14:02:38 +01:00
Theophile Terraz 55da743977 Merge branch 'master' into terraz_dev 2024-10-30 10:31:23 +01:00
Youcef AOUAD e711f0fb6f results from main solver type 2024-10-24 10:40:13 +02:00
Youcef AOUAD 36fd8cdc8a display adists results from main 2024-10-22 11:35:29 +02:00
Theophile Terraz 4a24e39224 Merge branch 'adists_release' into terraz_dev 2024-10-21 14:27:14 +02:00
Youcef AOUAD 97c161fc3f correct names nodes reaches 2024-10-21 14:21:25 +02:00
Theophile Terraz 00c43d91cd Merge branch 'master' of gitlab-ssh.irstea.fr:theophile.terraz/pamhyr into terraz_dev 2024-10-21 14:18:50 +02:00
Youcef AOUAD 100cfd095e db version fixed for adists files 2024-10-17 10:36:25 +02:00
Youcef AOUAD 5047dbc85e tables load fixed 2024-10-16 11:15:27 +02:00
Theophile Terraz c7eb10884a remove solver 2024-10-14 14:46:20 +02:00
Theophile Terraz 0ec1a39328 adistslc => adistswc 2024-10-14 14:44:26 +02:00
Theophile Terraz 92c9b106e3 add time slider (results) 2024-10-11 08:57:40 +02:00
Theophile Terraz 91e780432d Merge branch 'master' of gitlab-ssh.irstea.fr:theophile.terraz/pamhyr into terraz_dev 2024-10-08 10:59:13 +02:00
Theophile Terraz 81f15208cf debug 2024-10-07 16:55:24 +02:00
Theophile Terraz c9c5bfe093 Merge branch 'master' of gitlab-ssh.irstea.fr:theophile.terraz/pamhyr into terraz_dev 2024-10-07 15:35:53 +02:00
Theophile Terraz 0483a2463b Merge branch 'master' of gitlab-ssh.irstea.fr:theophile.terraz/pamhyr into terraz_dev 2024-10-07 15:30:06 +02:00
Theophile Terraz 9364b99158 Merge branch 'master' of gitlab-ssh.irstea.fr:theophile.terraz/pamhyr into terraz_dev 2024-10-07 14:27:42 +02:00
Theophile Terraz fa2cc303cd Merge branch 'master' of gitlab-ssh.irstea.fr:theophile.terraz/pamhyr into terraz_dev 2024-10-07 14:25:58 +02:00
Theophile Terraz 2b85f221bb Merge branch 'master' of gitlab-ssh.irstea.fr:theophile.terraz/pamhyr into terraz_dev 2024-10-04 10:16:12 +02:00
Theophile Terraz 55d96a3767 Merge branch 'test_merge_master' into terraz_dev 2024-10-02 10:58:55 +02:00
Theophile Terraz 6000a91e74 Merge branch 'master' of gitlab-ssh.irstea.fr:theophile.terraz/pamhyr into terraz_dev 2024-10-02 10:57:25 +02:00
Theophile Terraz bd6e200a70 merge 2024-10-02 10:57:17 +02:00
Theophile Terraz 143f468c26 kp to rk 2024-09-25 12:03:48 +02:00
Theophile Terraz 334633f0fb replace kp with rk 2024-09-24 16:28:23 +02:00
Theophile Terraz a52e6b86f4 merge master 2024-09-24 16:04:22 +02:00
Youcef AOUAD 9ae16ca6ec delete page from ui resultsadists 2024-09-17 11:04:39 +02:00
Youcef AOUAD c7406d3bce raw data done for one timestamp 2024-09-17 10:23:41 +02:00
Youcef AOUAD cb8ecc752b raw data for adists 2024-09-16 16:33:02 +02:00
Youcef AOUAD 4c522ae050 plot tabs tot sediments done with limit effect 2024-09-13 18:21:38 +02:00
Youcef AOUAD 689d5a7592 plot tot sediments done 2024-09-13 09:40:57 +02:00
Youcef AOUAD c118d4fae8 tot sed plots 2024-09-12 15:27:52 +02:00
Youcef AOUAD 1baf2e8dd5 plot c m done 2024-09-12 11:05:19 +02:00
Youcef AOUAD 1fcdaa8b81 pollutant selection done 2024-09-11 15:14:39 +02:00
Youcef AOUAD 71729578dd reload plot H 2024-09-11 10:29:56 +02:00
Youcef AOUAD abe7bf969a delete sliders 2024-09-10 11:44:31 +02:00
Youcef AOUAD 673ae3908c var phys 2024-09-09 11:44:17 +02:00
Youcef AOUAD 1a31c9122e first plot complete 2024-09-05 12:35:16 +02:00
Youcef AOUAD c53d7d9c25 bug results fixed for data 2024-09-03 14:03:42 +02:00
Youcef AOUAD 02f14ffdf1 debug results profiles read from bin 2024-09-03 11:43:13 +02:00
Youcef AOUAD 84fd841f86 results adists pollutants table view 2024-09-02 15:12:07 +02:00
Youcef AOUAD 629b856788 data view complete pols 2024-09-02 11:42:51 +02:00
Youcef AOUAD f3007e2fe2 adists results data phys variables complete 2024-08-30 12:08:43 +02:00
Youcef AOUAD a7a1a4ddd1 adists results read bin data 2024-08-29 17:26:53 +02:00
Youcef AOUAD 0719db17ed results adists tables 2024-08-26 16:02:25 +02:00
Youcef AOUAD 018192714c windiow results adists mage 2024-08-23 14:59:28 +02:00
Theophile Terraz e1f69e41b0 pep8 2024-08-21 15:48:11 +02:00
Youcef AOUAD 501000fa6b display message run adists 2024-07-24 14:25:29 +02:00
Youcef AOUAD 75149000db rep mage select fixed 2024-07-22 15:22:55 +02:00
Youcef AOUAD 3c82148f44 select adists fixed 2024-07-17 14:24:26 +02:00
Youcef AOUAD 7f2ff9d341 time display ald fixed 2024-07-15 10:06:03 +02:00
Youcef AOUAD 57be80bcd4 cancel merge with master and update 2024-07-12 11:26:28 +02:00
Youcef AOUAD 29b5c97345 Solver adists done 2024-06-28 11:40:57 +02:00
Youcef AOUAD b171eb7d32 Solver connect 2024-06-27 15:46:27 +02:00
Youcef AOUAD 0e18d43496 Export Files 2 2024-06-26 17:04:14 +02:00
Youcef AOUAD bd4222adfa Export files 1 2024-06-26 12:55:07 +02:00
Youcef AOUAD 1e4761609d DIF Complete 2024-06-24 15:55:42 +02:00
Youcef AOUAD de72e2e96b DIF Model 2024-06-24 11:23:09 +02:00
Youcef AOUAD 95a0dabe68 d90 Complete 2024-06-21 15:46:41 +02:00
Youcef AOUAD 9f53ad685e d90 Model 2024-06-21 11:39:04 +02:00
Youcef AOUAD 02c597d109 LCS Complete 2024-06-20 11:59:57 +02:00
Youcef AOUAD 510bee115b LCS -data 2024-06-20 11:12:14 +02:00
Youcef AOUAD ed250f836d LC View Tab 2024-06-19 16:01:58 +02:00
Youcef AOUAD a47410a0f1 LC Model 2024-06-19 11:10:09 +02:00
Youcef AOUAD 704130966e BC AdisTS Complete 2024-06-18 15:40:06 +02:00
Youcef AOUAD b927aa81b3 BC AdisTS View Table 2024-06-17 16:34:41 +02:00
Youcef AOUAD d154ac96c2 BC AdisTS View1 2024-06-17 12:02:07 +02:00
Youcef AOUAD 6067ba601e BC Model 2024-06-14 14:52:29 +02:00
Youcef AOUAD 716d0af96f INI GOOD 2024-06-13 14:35:40 +02:00
Youcef AOUAD f917dd9284 INISPEC DEL 2024-06-12 16:56:05 +02:00
Youcef AOUAD cd68bebf03 INI SPEC Table 2024-06-12 15:06:28 +02:00
Youcef AOUAD 35cc348f03 INI SPEC 2024-06-11 16:22:07 +02:00
Youcef AOUAD 6f3e1e31f0 INI table db 2024-06-11 11:43:04 +02:00
Youcef AOUAD 7df0750c58 INI Default 2024-06-10 16:26:56 +02:00
Youcef AOUAD bcf825a4f7 ini view 2024-06-07 16:34:28 +02:00
Youcef AOUAD 3afd9f5025 IC model 2024-06-06 15:26:55 +02:00
Youcef AOUAD 3cb47ee5c8 ic 2024-06-06 12:00:52 +02:00
Youcef AOUAD 1535247e1b pollutants edit db 2024-06-05 11:35:41 +02:00
Youcef AOUAD 37dd4ebaef characteristics pollutant 2024-06-04 16:29:03 +02:00
Youcef AOUAD 1e8949067b pollutant characteristics 2024-06-03 16:23:39 +02:00
Youcef AOUAD 1945e94190 pollutants names 2024-06-03 12:01:41 +02:00
Youcef AOUAD 1ba971af24 adists run 2024-05-31 15:12:40 +02:00
Youcef AOUAD 0b5357d12a adisTS NUM file 1 2024-05-30 16:03:44 +02:00
Youcef AOUAD 3be361b03c adistTS NUM file 2024-05-30 16:01:13 +02:00
Youcef AOUAD 7681b5d326 adists export 2024-05-29 16:19:46 +02:00
Youcef AOUAD 0a35d387f7 adists check list 2024-05-28 16:39:11 +02:00
Youcef AOUAD b40efc2426 output kp 2024-05-27 16:48:03 +02:00
Youcef AOUAD 59aae7fd40 work 6 2024-05-24 16:07:33 +02:00
Youcef AOUAD a633e4bccf work 5 2024-05-24 15:59:25 +02:00
Youcef AOUAD b56b8099ab work 5 2024-05-23 16:48:31 +02:00
Youcef AOUAD f9fe5c9b6c work 4 2024-05-23 16:38:32 +02:00
Youcef AOUAD 13b954d580 work 3 2024-05-22 16:13:18 +02:00
Youcef AOUAD f53289ef1b output table 2024-05-21 16:29:41 +02:00
Youcef AOUAD 1b3ce91582 adding adists solver 1 2024-05-17 16:43:38 +02:00
198 changed files with 76964 additions and 377 deletions

No files matched your search

+2
View File
@@ -9,6 +9,8 @@
*.class
tmp
mage8
adists
*.tar
*.tar.*
+75 -11
View File
@@ -83,6 +83,34 @@ dl-mage8-windows:
- mage8-windows/mailleurTT.exe
- mage8-windows/libbief.dll
dl-adists-linux:
stage: downloads
tags:
- linux
rules:
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
script:
- mkdir -p adists-linux
- cd adists-linux
- curl -L -o adists https://gitlab.irstea.fr/jean-baptiste.faure/adists/-/releases/v1.0.1/downloads/executables/adists
artifacts:
paths:
- adists-linux/adists
dl-adists-windows:
stage: downloads
tags:
- linux
rules:
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
script:
- mkdir -p adists-windows
- cd adists-windows
- curl -L -o adists.exe https://gitlab.irstea.fr/jean-baptiste.faure/adists/-/releases/v1.0.1/downloads/executables/adists_win64.exe
artifacts:
paths:
- adists-windows/adists.exe
#############
# CONFIGURE #
#############
@@ -177,13 +205,32 @@ build-td:
- job: set-version
artifacts: true
script:
- cd ./doc/users/Tuto1/
- cd ./doc/users/TP_Hydraulique_Hogneau/
- ./build.sh
artifacts:
paths:
- doc/users/Tuto1/step-by-step.pdf
- doc/users/Tuto1/pas-a-pas.pdf
- doc/users/Tuto1/data/
- doc/users/TP_Hydraulique_Hogneau/step-by-step.pdf
- doc/users/TP_Hydraulique_Hogneau/pas-a-pas.pdf
- doc/users/TP_Hydraulique_Hogneau/Tuto-2-fr.pdf
- doc/users/TP_Hydraulique_Hogneau/data/
allow_failure: true
build-td-2:
stage: build
tags:
- linux
needs:
- job: set-version
artifacts: true
script:
- cd ./doc/users/TP_AdisTS_Vieux_Rhone/
- ./build.sh
artifacts:
paths:
- doc/users/TP_AdisTS_Vieux_Rhone/pas-a-pas.pdf
- doc/users/TP_AdisTS_Vieux_Rhone/data/
- doc/users/TP_AdisTS_Vieux_Rhone/Sujet.pdf
- doc/users/TP_AdisTS_Vieux_Rhone/Vieux_Rhone_TP_AdisTS.pamhyr
allow_failure: true
build-developers-doc:
@@ -224,6 +271,8 @@ build-linux:
rules:
- if: $CI_COMMIT_BRANCH == 'ci-test' || $CI_COMMIT_BRANCH == 'master' || $CI_COMMIT_TAG
needs:
- job: dl-adists-linux
artifacts: true
- job: dl-mage8-linux
artifacts: true
- job: dl-mage8-doc
@@ -238,6 +287,8 @@ build-linux:
# artifacts: true
- job: build-td
artifacts: true
- job: build-td-2
artifacts: true
script:
- mkdir -p linux
- cd linux
@@ -260,6 +311,9 @@ build-linux:
# Copy mage
- mkdir -p pamhyr/mage8
- cp -v ../mage8-linux/* pamhyr/mage8/
# Copy adists
- mkdir -p pamhyr/adists
- cp -v ../adists-linux/* pamhyr/adists/
# Copy Pamhyr
- cp -r dist/pamhyr/* pamhyr/
# Pamhyr script to force x11
@@ -294,13 +348,19 @@ build-linux:
- cp -r ../doc/dev/images/* pamhyr/doc/images
- cp -r ../doc/images/* pamhyr/doc/images
# Copy Tuto
- mkdir -p pamhyr/doc/Tuto1/
- mkdir -p pamhyr/doc/Tuto1/data
- cp ../doc/users/Tuto1/Hogneau_Engees2022.pdf pamhyr/doc/Tuto1/Hogneau_Engees2022.pdf
- cp ../doc/users/Tuto1/step-by-step.pdf pamhyr/doc/Tuto1/Tuto1-en.pdf
- cp ../doc/users/Tuto1/pas-a-pas.pdf pamhyr/doc/Tuto1/Tuto1-fr.pdf
- cp ../doc/users/Tuto1/*.pamhyr pamhyr/doc/Tuto1/
- cp ../doc/users/Tuto1/data/* pamhyr/doc/Tuto1/data/
- mkdir -p pamhyr/doc/TP_Hydraulique_Hogneau/
- mkdir -p pamhyr/doc/TP_Hydraulique_Hogneau/data
- cp ../doc/users/TP_Hydraulique_Hogneau/Hogneau_Engees2022.pdf pamhyr/doc/TP_Hydraulique_Hogneau/Hogneau_Engees2022.pdf
- cp ../doc/users/TP_Hydraulique_Hogneau/step-by-step.pdf pamhyr/doc/TP_Hydraulique_Hogneau/Tuto1-en.pdf
- cp ../doc/users/TP_Hydraulique_Hogneau/pas-a-pas.pdf pamhyr/doc/TP_Hydraulique_Hogneau/Tuto1-fr.pdf
- cp ../doc/users/TP_Hydraulique_Hogneau/Tuto-2-fr.pdf pamhyr/doc/TP_Hydraulique_Hogneau/Tuto2-fr.pdf
- cp ../doc/users/TP_Hydraulique_Hogneau/*.pamhyr pamhyr/doc/TP_Hydraulique_Hogneau/
- cp ../doc/users/TP_Hydraulique_Hogneau/data/* pamhyr/doc/TP_Hydraulique_Hogneau/data/
- mkdir -p pamhyr/doc/TP_AdisTS_Vieux_Rhone/
- mkdir -p pamhyr/doc/TP_AdisTS_Vieux_Rhone/data
- cp ../doc/users/TP_AdisTS_Vieux_Rhone/*.pdf pamhyr/doc/TP_AdisTS_Vieux_Rhone/
- cp ../doc/users/TP_AdisTS_Vieux_Rhone/data/* pamhyr/doc/TP_AdisTS_Vieux_Rhone/data/
- cp ../doc/users/TP_AdisTS_Vieux_Rhone/Vieux_Rhone_TP_AdisTS.pamhyr pamhyr/doc/TP_AdisTS_Vieux_Rhone/Vieux_Rhone_TP_AdisTS.pamhyr
# Copy TP charriage
- mkdir -p pamhyr/doc/TP_charriage/
- cp ../doc/users/TP_charriage/* pamhyr/doc/TP_charriage
@@ -317,6 +377,8 @@ build-windows:
needs:
- job: dl-mage8-windows
artifacts: true
- job: dl-adists-windows
artifacts: true
- job: dl-mage8-doc
artifacts: true
- job: set-version
@@ -329,6 +391,8 @@ build-windows:
# artifacts: true
- job: build-td
artifacts: true
- job: build-td-2
artifacts: true
script:
- mkdir windows
- cd windows
+3
View File
@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
+6
View File
@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.10 (pamhyr)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (pamhyr)" project-jdk-type="Python SDK" />
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pamhyr.iml" filepath="$PROJECT_DIR$/.idea/pamhyr.iml" />
</modules>
</component>
</project>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.10 (pamhyr)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
@@ -0,0 +1,68 @@
@article{camenen_simple_2007,
title = {Simple and {General} {Formula} for the {Settling} {Velocity} of {Particles}},
volume = {133},
language = {en},
number = {2},
urldate = {2025-01-23},
journal = {Journal of Hydraulic Engineering},
author = {Camenen, Benoit},
month = feb,
year = {2007},
pages = {229-233},
}
@article{meyer-peter_formulas_1948,
address = {Stockholm, Sweden},
title = {Formulas for bed-load transport.},
journal = {Report on Second Meeting of IAHR},
author = {Meyer-Peter, E and Mueller, R},
year = {1948},
pages = {39-64},
}
@article{elder_dispersion_1959,
title = {The dispersion of marked fluid in turbulent shear flow},
volume = {5},
issn = {0022-1120, 1469-7645},
language = {en},
number = {04},
urldate = {2025-01-23},
journal = {Journal of Fluid Mechanics},
author = {Elder, J. W.},
month = may,
year = {1959},
pages = {544},
}
@article{fischer_discussion_1975,
title = {Discussion of Simple Method for Predicting Dispersion in Streams},
volume = {101},
issn = {0090-3914, 2690-2435},
language = {en},
number = {3},
urldate = {2025-01-23},
journal = {Journal of the Environmental Engineering Division},
author = {Fischer, Hugo B},
month = mar,
year = {1975},
pages = {453-455},
}
@article{iwasa_predicting_1991,
address = {Hong Kong},
title = {Predicting longitudinal dispersion coefficient in open channel flows},
journal = {roc. Int. Symp. of Environmental Hydraulics},
author = {Iwasa, Y and Aya, S},
year = {1991},
pages = {505-510},
}
@book{soulsby_dynamics_1997,
address = {London},
edition = {Thomas Telford},
title = {Dynamics of {Marine} {Sands}: {A} {Manual} for {Practical} {Applications}},
urldate = {2025-01-23},
author = {Soulsby, Richard},
year = {1997},
}
+175
View File
@@ -0,0 +1,175 @@
%% LyX 2.0.2 created this file. For more info, see http://www.lyx.org/.
%% Do not edit unless you really know what you are doing.
\documentclass[12pt,french]{article}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
\usepackage{geometry}
\geometry{verbose,tmargin=2cm,bmargin=2cm,lmargin=2cm,rmargin=2cm,headheight=2cm,headsep=2cm,footskip=2cm}
\usepackage{textcomp}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage[frenchb]{babel}
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
\newcommand{\noun}[1]{\textsc{#1}}
%% Because html converters don't know tabularnewline
\providecommand{\tabularnewline}{\\}
\makeatother
\usepackage{babel}
\addto\extrasfrench{%
\providecommand{\og}{\leavevmode\flqq~}%
\providecommand{\fg}{\ifdim\lastskip>\z@\unskip\fi~\frqq}%
}
\begin{document}
\includegraphics[width=5cm]{img/Logo-INRAE_Transparent.png}
~
~
~
\begin{center}
TP AdisTS - Pamhyr2\\
Version : Janvier 2025
\par\end{center}
~
~
\begin{center}
\textbf{\LARGE Modélisation 1D du transport sédimentaire : } \\
\textbf{\LARGE Cas du Vieux-Rhône de Miribel-Jonage}\\
\textbf{\LARGE (Lyon, France)}
\par\end{center}{\LARGE \par}
~
\begin{center}
\includegraphics[width=17cm]{img/Garde.jpeg}
\par\end{center}
~
\begin{center}
{\large INRAE Lyon-Grenoble Auvergne-Rhône-Alpes}
\par\end{center}{\large \par}
\begin{center}
RiverLy, Hydraulique des rivières
\par\end{center}
~
\begin{center}
\begin{tabular}{lll}
Auteur : & Dorian Hernandez & dorian.hernandez@inrae.fr\tabularnewline
& Théophile Terraz & theophile.terraz@inrae.fr\tabularnewline
\end{tabular}
\par\end{center}
~
\pagebreak{}
\begin{center}
\tableofcontents{}
\par\end{center}
~
\pagebreak{}
% \section{Introduction}
%
% TODO
%
% \pagebreak{}
\section{Contexte de l'étude - le colmatage du Vieux-Rhône}
Le champ de captage de Crépieux-Charmy est un site de pompage d'eau potable alimentant 97 \% de la ville de Lyon. Situé au nord-est de la ville, il est en contact hydraulique avec trois chenaux du Rhône. Le canal de Miribel au Nord, dont les débits varient entre 89 (débit réservé) et 2400 ~$m³/s$ (Crue extrême), le canal de Jonage au sud, imposant un débit quasi constant de 600 ~$m³/s$ pour alimenter la centrale de Cusset, et un Vieux-Rhône qui traverse le site. Les fortes variations hydrauliques le long de Miribel, ainsi que le débit constant le long de Jonage mènent à un dépôt général des sédiments fins et grossiers le long du Vieux-Rhône, avec la création d'un remous important causé par Jonage.
\begin{center}
\includegraphics[width=15cm]{img/Intro.jpeg}
\par\end{center}
Eau du grand Lyon, le gérant du champ de captage, souhaite identifier les zones de dépôts de sédiments fin le long du Vieux-Rhône, cause principale de colmatage, impactant les performances de pompage de l'eau dans les nappes.
\begin{center}
\includegraphics[width=15cm]{img/Champ_captant.jpeg}
\par\end{center}
Pour cela, une campagne expérimentale visant à identifier les zones colmatés du Vieux-Rhône a été réalisée et a mis en avant une hétérogénéité du site. Notamment, une forte zone de dépôts de grossier est présente en amont. Tandis qu'une présence plus importante de fines et sables dans la zone aval (zone de remous de Jonage) a été observée, ainsi qu'un colmatage plus important.
\begin{center}
\includegraphics[width=15cm]{img/Grossier_sable.jpeg}
\par\end{center}
En parallèle, un modèle numérique hydraulique 1D a été élaboré sous Pamhyr2 afin d'analyser l'écoulement sur le site. Les résultats numériques mettent alors bien en avant le remous généré par Jonage, ainsi qu'une diminution de la vitesse de l'écoulement à partir du point kilométrique (PK) 1000, fin de la zone amont.
\begin{center}
\includegraphics[width=15cm]{img/Simu.jpeg}
\par\end{center}
\section{Objectifs de l'étude}
Le modèle numérique 1D représente actuellement la partie hydraulique du système. L'objectif du TP est alors de mettre en donnée la partie sédimentaire (fines) du modèle, afin d'effectuer des calculs à l'aide de AdisTS , et in-fine, identifier les zones de dépôt et d'érosion des sédiments fins le long du Vieux-Rhône selon différents scénarios hydraulique. Les différentes étapes seront alors :
\begin{itemize}
\item Mettre en données le modèle Pamhyr2 du Vieux-Rhône pour le solveur AdisTS.
\item Lancer des calculs Mage - AdisTS pour différents scénarios hydrauliques.
\item Interpréter et discuter les résultats obtenus (comportement hydro-sédimentaire du site, impacts des débits, impact d'une crue, limites du modèle, etc..)
\end{itemize}
\section{Données fournies}
\textbf{Le modèle numérique du Vieux-Rhône}
Fichier \textit{Vieux\_Rhone\_TP\_AdisTS.pamhyr}.\\
\textbf{Les scénarios hydrauliques}
Quatre scénarios hydrauliques sont à analyser (voir les conditions initiales hydraulique) :
\begin{itemize}
\item Le premier correspond à un débit constant de 25~$m³/s$
\item Le deuxième consiste en une faible montée en débit puis à une redescente (25 - 50 - 25~$m³/s)$.
\item Le troisième correspondant à une plus forte montée en débit (25 - 100 - 25~$m³/s)$.
\item Le dernier correspond à une crue (25 - 600 - 25~$m3/s)$.\\
\end{itemize}
\textbf{Propriétés des sédiments}
Nous considérerons 2 classes de sédiments de types sable naturel, correspondant à une classe de Fines (limon) de diamètre moyen 63 microns et une classe de Sable de 500 microns. Les deux classes auront une masse volumique de 2650~$kg/m³$, et une porosité de 0,45 pourra être choisie. Leurs concentrations constantes en amont (conditions aux limites amont) seront de 60 $mg/l$ pour les fines et 30 $mg/l$ pour les sables. Nous considérerons dans un premier temps qu'il n'y a aucun dépôt initial de ces deux classes de sédiments et que la concentration initiale en sédiments dans le bief est nulle.\\
\textbf{Documentation}
\begin{itemize}
\item Un tutoriel guidé de mise en données : Pas-a-pas.pdf.
\item Un guide utilisateur de AdisTS : adis-TS\_usage.pdf
\item Un guide de conception de AdisTS : adis-TS\_conception.pdf
\end{itemize}
\section{Bonus}
Ajouter une épaisseur initiale de sédiments \textit{Sables} au fond de 1 $cm$ et relancer un calcul avec le scénario 1.
\pagebreak{}
\end{document}
+8
View File
@@ -0,0 +1,8 @@
#! /bin/sh
pdflatex -no-shell-escape pas-a-pas.tex
bibtex pas-a-pas.aux
pdflatex -no-shell-escape pas-a-pas.tex
pdflatex -no-shell-escape pas-a-pas.tex
pdflatex -no-shell-escape Sujet.tex
pdflatex -no-shell-escape Sujet.tex
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

@@ -0,0 +1,291 @@
%% LyX 2.0.2 created this file. For more info, see http://www.lyx.org/.
%% Do not edit unless you really know what you are doing.
\documentclass[12pt,french]{article}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
\usepackage{geometry}
\geometry{verbose,tmargin=2cm,bmargin=2cm,lmargin=2cm,rmargin=2cm,headheight=2cm,headsep=2cm,footskip=2cm}
\usepackage{textcomp}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage[frenchb]{babel}
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
\newcommand{\noun}[1]{\textsc{#1}}
%% Because html converters don't know tabularnewline
\providecommand{\tabularnewline}{\\}
\makeatother
\usepackage{babel}
\addto\extrasfrench{%
\providecommand{\og}{\leavevmode\flqq~}%
\providecommand{\fg}{\ifdim\lastskip>\z@\unskip\fi~\frqq}%
}
\begin{document}
\includegraphics[width=5cm]{img/Logo-INRAE_Transparent.png}
~
~
~
\begin{center}
Tutoriel Pas-à-pas AdisTS - Pamhyr2
Version : Janvier 2025
\par\end{center}
~
~
\begin{center}
\textbf{\LARGE Modélisation 1D du transport sédimentaire : } \\
\textbf{\LARGE Cas du Vieux-Rhône de Miribel-Jonage}\\
\textbf{\LARGE (Lyon, France)}
\par\end{center}{\LARGE \par}
~
\begin{center}
\includegraphics[width=17cm]{img/Garde.jpeg}
\par\end{center}
~
\begin{center}
{\large INRAE Lyon-Grenoble Auvergne-Rhône-Alpes}
\par\end{center}{\large \par}
\begin{center}
RiverLy, Hydraulique des rivières
\par\end{center}
~
\begin{center}
\begin{tabular}{lll}
Auteurs : & Dorian Hernandez & dorian.hernandez@inrae.fr\tabularnewline
& Théophile Terraz & theophile.terraz@inrae.fr\tabularnewline
\end{tabular}
\par\end{center}
~
\pagebreak{}
\begin{center}
\tableofcontents{}
\par\end{center}
~
\pagebreak{}
% \section{Introduction}
%
% TODO
%
% \pagebreak{}
\section{Ouvrir l'étude}
Lancez Pamhyr2.
Cliquez sur le bouton \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/open.png} puis ouvrez le modèle Pamhyr2 \textit{Vieux\_Rhone\_TP\_AdisTS.pamhyr}.
Le modèle à un bief du Vieux-Rhône s'affiche sur la fenêtre graphique.
\begin{center}
\includegraphics[width=15cm]{img/Open_model.jpeg}
\par\end{center}
\section{Mise en donnée}
\subsection{Création des classes de sédiments}
Dans la fenêtre principale, cliquez sur \texttt{[AdisTS] => [Polluants]} pour créer des classes de sédiments.
\begin{center}
\includegraphics[width=15cm]{img/Model_menu_Adists.jpeg}
\par\end{center}
La fenêtre \textit{Polluants - Vieux-Rhône} s'affiche. Elle va nous permettre de définir l'ensemble des caractéristiques (type de sédiment, taille moyenne, masse volumique,..) de nos classes de sédiments, ainsi que les conditions sédimentaires initiales et aux limites du modèle.
A l'aide du bouton \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/add.png} inclure deux nouvelles classes de sédiments et les nommer \textit{Fines} et \textit{Sables}.
\begin{center}
\includegraphics[width=15cm]{img/Polluants_fenetre.jpeg}
\par\end{center}
Pensez à sauvegarder régulièrement l'étude, à l'aide du bouton \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/save.png} de la fenêtre principale.
\subsection{Caractéristiques et conditions initiales des sédiments}
Pour pouvoir attribuer des caractéristiques et des conditions initiales à une classe de sédiments, il faut d'abord la sélectionner.
Cliquez sur la classe de sédiments \textit{Fines}, puis ouvrez la fenêtre \texttt{[Caractéristiques]}.
\begin{center}
\includegraphics[width=15cm]{img/Pol_to_Caracteristique.jpeg}
\par\end{center}
La fenêtre d'édition de la classe de sédiments \textit{Fines} s'ouvre.
\begin{center}
\includegraphics[width=15cm]{img/caracteristique_fines_a_completer.jpeg}
\par\end{center}
Celle-ci contient les informations nécessaire à la résolution des termes sources (taux d'érosion et de dépôt) de l'équation de transport-dispersion. Notamment pour le calcul de la vitesse de chute selon \cite{camenen_simple_2007} et la contrainte critique de mise en mouvement via l'approximation de \cite{soulsby_dynamics_1997}.
Complétez les valeurs manquantes du tableau selon les données de l'énoncé. Puis, fermez la fenêtre des caractéristiques.
Ouvrez à présent la fenêtre de \texttt{[Conditions initiales]} (toujours pour les \textit{Fines}).
\begin{center}
\includegraphics[width=15cm]{img/CI.jpeg}
\par\end{center}
Cette fenêtre contient deux espaces permettant de définir la concentration initiale de \textit{Fines} (dans "l'eau" du bief) et l'épaisseur de dépôt de fines au fond du bief. Dans le compartiment de gauche, on définit les valeurs par défaut, appliquées à l'ensemble du bief. Le compartiment de droite permet d'imposer des conditions initiales différentes en fonction des PKs du bief.
Nous considérerons une concentration initiale nulle en sédiments fins, ainsi qu'une épaisseur nulle au fond.\\
\\
Fermez la fenêtre de conditions initiales.\\
\\
Sélectionnez la classe de sédiments \textit{Sables} et répétez les étapes précédentes en considérant cette fois-ci les caractéristiques propres aux sables selon l'énoncé.
\subsection{Conditions aux limites}
Pour les conditions aux limites il n'est pas nécessaire de mettre en surbrillance les classes de sédiments.\\
\\
Ouvrez la fenêtre de \texttt{[Conditions aux limites]} et ajouter deux conditions aux limites de type concentration au n½ud amont du bief. Il y aura alors une condition aux limites pour chaque classe de sédiments.
\begin{center}
\includegraphics[width=15cm]{img/CL.jpeg}
\par\end{center}
Éditez la condition aux limites \textit{Fines} en la mettant en surbrillance et en cliquant sur le bouton \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/edit.png}.\\
Créez une condition aux limites de type concentration constante de 60 $kg/m³$ en insérant deux lignes \textit{Temps/Concentration} à l'aide du bouton \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/add.png}.
\begin{center}
\includegraphics[width=15cm]{img/CL_edit.jpeg}
\par\end{center}
Procédez de la même façon pour la classe de sédiments \textit{Sables}, mais avec une concentration de 30 $kg/m³$.\\
\\
Fermez les fenêtres d'éditions des conditions aux limites et des polluants.
\subsection{Caractéristiques du fond fixe}
Dans la fenêtre principale, cliquez sur \texttt{[AdisTS] => [D90]}. Cette fenêtre permet de définir le diamètre des particules fixes au fond du canal, nécessaire pour le calcul du coefficient de Strickler à la manière de \cite{meyer-peter_formulas_1948}. De même que pour les conditions initiales des polluants, la fenêtre d'édition est divisée en deux parties afin d'introduire un paramètres par défaut et de laisser la possibilité d'appliquer des valeurs de $d_{90}$ variables le long du bief.
\begin{center}
\includegraphics[width=15cm]{img/D90.jpeg}
\par\end{center}
Définissez 2 coefficients différents. Une valeur de 5 cm sur la partie amont (zone principale de dépôt de grossier) et 2 cm sur la partie avale.
\subsection{Coefficient de diffusion}
Le coefficient de diffusion $D_f$ comprend une part de diffusion moléculaire prise par défaut à $D_{mol}=10^{-6}$, à laquelle s'ajoutent les diffusions turbulentes et la dispersion sous forme d'un seul terme $D_{mix}$ défini selon les formules de \cite{fischer_discussion_1975}, \cite{elder_dispersion_1959} ou \cite{iwasa_predicting_1991}. Il est aussi possible d'utiliser une forme générique de $D_{mix}$ (voir doc utilisateur) ou encore d'imposer une valeur constante. Dans le cas tu TP nous choisirons Iwasa et Aya avec $\alpha=2$.
\begin{center}
\includegraphics[width=15cm]{img/Diff.jpeg}
\par\end{center}
\section{Paramètres du solveur}
Dans la fenêtre principale, cliquez sur \texttt{[Exécuter] => [Paramètres numériques des solveurs]}.
Dans la fenêtre \textit{Paramètres du solveur}, sélectionnez l'onglet \texttt{[Adis-TS\_WC]}.
Ces paramètres pilotent le comportement du solveur numérique. On retrouve notamment les temps de début et de fin de la simulation. Le pas de temps maximal en secondes pour le calcul. Le paramètre d'implicitation du schéma numérique de Crank-Nicholson (0.5 comme valeur recommandée). Les temps d'écriture des fichiers .bin, .csv (pour l'export à la volée), et de l'affichage à l'écran. On retrouve aussi la possibilité d'appliquer une concentration initiale.
Exemple de valeurs des paramètres :
\begin{center}
\includegraphics[width=15cm]{img/Execute_param.jpeg}
\par\end{center}
Fermez la fenêtre \textit{Paramètres du solveur}.
\section{Lancer une simulation}
Avant de lancer AdisTS, il est nécessaire d'avoir une première solution hydraulique.
Vérifiez que les conditions aux limites amont et aval sélectionnées sont bien celles correspondantes à l'hydrogramme et au limnigramme du scénrio souhaité.
\begin{center}
\includegraphics[width=15cm]{img/CL_verif.jpeg}
\par\end{center}
Dans la fenêtre principale, cliquez sur \texttt{[Exécuter] => [Lancer le solveur]}.
Sélectionnez \textit{Defaut-Mage - (Mage8)} et cliquez sur le bouton \textit{Lancer}.
La fenêtre \textit{Log du solveur} s'ouvre.
Cette fenêtre affiche les sorties texte du solveur.
À partir de la fenêtre \textit{Log du solveur}, il est possible de réexécuter le calcul en cliquant sur l'icône \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/run.png}. Cliquez sur le bouton \textit{Résultats} pour ouvrir la fenêtre \textit{Résultats} de Mage.
Dans la fenêtre principale, cliquez sur \texttt{[Exécuter] => [Lancer AdisTS]}.
Sélectionnez \textit{Defaut-AdisTS - (adistswc)} et cliquez sur le bouton \textit{Lancer}.
La fenêtre \textit{Log du solveur} s'ouvre.
Cette fenêtre affiche les sorties texte du solveur. Si le calcul s'est déroulé correctement, la fenêtre log devrait ressembler à celle-ci :
\begin{center}
\includegraphics[width=15cm]{img/log.jpeg}
\par\end{center}
Cliquez sur le bouton \textit{Résultats} pour ouvrir la fenêtre \textit{Résultats} de AdisTS. Il est aussi possible de ré-ouvrir les résultats de Mage en cliquant sur le bouton \textit{Résultats Mage}.
\section{Visualisation et export de résultats}
Il est aussi possible d'ouvrir la fenêtre \textit{Résultats} si vous avez fermé la fenêtre \textit{Log du solveur}, en cliquant sur \texttt{[Résultats] => [Visualiser les derniers résultats]} à partir de la fenêtre principale. Les résultats affichés sont ceux de AdisTS.
\begin{center}
\includegraphics[width=15cm]{img/Results.jpeg}
\par\end{center}
Le panneau supérieur gauche permet de sélectionner le bief, le panneau du milieu gauche permet de sélectionner une section dans ce bief et le panneau inférieur gauche permet de sélectionner la classe de sédiments dont on veut extraire des résultats.
La fenêtre de droite possède 4 onglets. Chaque onglet présente des résultats en fonction du temps (un curseur en bas de la fenêtre permet de visualiser les résultats à différents pas de temps) :
\begin{itemize}
\item Le premier onglet correspond aux données brutes de concentration dans l'eau et de masse déposée pour chaque classe de sédiments de l'étude.
\item Le deuxième onglet est divisée en deux sous-onglets permettant de visualiser de deux façons différentes la concentration de la classe de sédiments sélectionnée : soit en fonction du PK du bief, soit en fonction du temps.
\item De même, le troisième onglet est divisé en deux sous-onglets permettant de visualiser cette fois-ci la masse linéique de sédiments s'étant déposés.
\item Enfin le dernier onglet présente l'épaisseur des sédiments déposés.
\end{itemize}
Il est possible d'exporter les résultats au format CSV en cliquant sur le bouton \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/export.png} en haut à gauche de la fenêtre.
\begin{center}
\includegraphics[width=15cm]{img/Export_res_adis.jpeg}
\par\end{center}
Répétez les étapes 4 et 5, selon différents scénarios hydrauliques.
\section{Bonus}
Ajoutez une épaisseur initiale de 1 cm de sédiments \textit{Sables} au fond et relancer un calcul avec le scénario 1.
\bibliographystyle{plainnat}
\bibliography{Biblio.bib}
\pagebreak{}
\end{document}
+263
View File
@@ -0,0 +1,263 @@
%% LyX 2.0.2 created this file. For more info, see http://www.lyx.org/.
%% Do not edit unless you really know what you are doing.
\documentclass[12pt,french]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{geometry}
\geometry{verbose,tmargin=2cm,bmargin=2cm,lmargin=2cm,rmargin=2cm,headheight=2cm,headsep=2cm,footskip=2cm}
\usepackage{textcomp}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage[frenchb]{babel}
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
\newcommand{\noun}[1]{\textsc{#1}}
\usepackage{amsthm}
\newtheorem{remark}{Q?}
%% Because html converters don't know tabularnewline
\providecommand{\tabularnewline}{\\}
\makeatother
\usepackage{babel}
\addto\extrasfrench{%
\providecommand{\og}{\leavevmode\flqq~}%
\providecommand{\fg}{\ifdim\lastskip>\z@\unskip\fi~\frqq}%
}
\begin{document}
\includegraphics[width=5cm]{img/Logo-INRAE_Transparent.png}
~
~
~
\begin{center}
Tutoriel pour Pamhyr2
- suite -
Janvier 2025
\par\end{center}
~
~
\begin{center}
\textbf{\LARGE Scénarii d'aménagement de la rivière } \\
\textbf{\LARGE Hogneau (Nord, France) avec Pamhyr2}
\par\end{center}{\LARGE \par}
~
~
\begin{center}
{\large INRAE Lyon-Grenoble Auvergne-Rhône-Alpes}
\par\end{center}{\large \par}
\begin{center}
RiverLy, Hydraulique des rivières
\par\end{center}
~
~
~
~
~
~
\begin{center}
\begin{tabular}{lll}
Auteurs : & Céline Berni & celine.berni@inrae.fr\tabularnewline
& Théophile TERRAZ & theophile.terraz@inrae.fr\tabularnewline
\end{tabular}
\par\end{center}
~
\pagebreak{}
\begin{center}
\tableofcontents{}
\par\end{center}
~
\pagebreak{}
% \section{Introduction}
%
% TODO
%
% \pagebreak{}
\section{Préambule}
Dans ce document, nous expliciterons les fonctionnalités de PamHyr utiles à la modélisation de scénarii d'aménagement de la rivière Hogneau comme décrit dans le document de TP.
Il est utile au préalable d'avoir suivi le tutoriel pour la modélisation de la rivière Hogneau fourni avec le logiciel (Tuto1-fr.pdf).
Suivre le tutoriel 1 vous permettra de construire le modèle avec le scénario de référence (la rivière avant aménagement).
Notez que l'outil PamHyr ne permet pas au stade actuel de comparer plusieurs scenarii.
Vous devrez pour ce faire exporter les vos résultats à partir de la fenêtre \textit{Résultats} qui s'ouvre en cliquant sur \texttt{[Résultats] => [Visualiser les derniers résultats]} à partir de la fenêtre principale.
Le bouton \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/export.png} vous permet d'exporter les résultats au format CSV pour une utilisation en dehors de Pamhyr2.
Vous pouvez soit vous placer en un point kilométrique (PK) donné (celui marqué en rouge sur la visualisation du profil en long ou sélectionné dans le tableau) et exporter la hauteur d'eau, le niveau d'eau le débit ou autre en fonction du temps (sélectionnez alors \texttt{Temps (s)} pour l'axe X), soit vous placer à un instant donné et exporter la grandeur de votre choix pour tous les points kilométriques de votre maillage (sélectionnez alors \texttt{Point Kilométrique (m)} pour l'axe X).
Si vous choisissez cette seconde option, cocher \texttt{envelop} vous permettra d'exporter en plus la valeur maximale au cours du temps pour la grandeur choisie.
Ainsi dans l'exemple ci-dessous, les données exportées le seront au point kilométrique 34000\,m, à l'instant $t=1$ jour et 12h.
\begin{center}
\includegraphics[width=15cm]{img/export_resultats.png}
\includegraphics[width=12cm]{img/export_resultats2.png}
\par\end{center}
\section{Premier scénario d'aménagement : abaissement du seuil}
Parmi les 3 options d'aménagement évoquées par la collectivité locale, jouer sur le contrôle aval en abaissant le seuil qui marque la jonction avec le canal de Condé-Pommeroeul peut faire baisser le niveau à l’amont.
\begin{remark}
Pourquoi jouer sur le contrôle aval peut-il avoir un effet sur le niveau d'eau en amont ?
\end{remark}
Pour modifier la hauteur du seuil, dans la fenêtre principale, cliquez sur \texttt{[Hydraulique] => [Ouvrages hydrauliques]} pour ouvrir la fenêtre des ouvrages hydrauliques.
Vous pouvez alors sélectionner le seuil Palplanche.
\begin{center}
\includegraphics[width=15cm]{img/ouvrage_seuilpalplanche.png}
\par\end{center}
Sélectionnez le seuil aval (SeuilPalplanche) et cliquez sur \includegraphics[width=0.5cm]{"../../../src/View/ui/ressources/edit.png"} pour modifier les lois de cet ouvrage.
Vous pouvez alors essayer de modifier la cote du seuil.
Lancez le calcul en exécutant le programme pour plusieurs hauteurs de seuil (dont celle initiale de référence) avec chacune des trois crues proposées en condition amont.
\begin{remark}
Exportez les données obtenues en fonction du PK pour 2 ou 3 hauteurs de seuil.
Sur quelle distance le seuil aval influence-t-il la hauteur d'eau ?
Est-ce suffisant pour limiter la hauteur d'eau au niveau du pont de l'A2 ($PK \approx 33000$\,m) ?
\end{remark}
\section{Second scénario d'aménagement : élargissement du lit moyen}
Ce scénario d'aménagement consiste à essayer d’augmenter le laminage en créant un lit moyen en rive droite entre les PKs 32 015 et 33 920\,m. Pour rappel, cette localisation est imposée pour des raisons de disponibilité des terrains et on ne peut pas envisager une largeur du lit moyen supérieure à 50 mètres.
\begin{remark}
Pourquoi élargir le lit moyen peut-il avoir un effet sur le niveau d'eau durant la crue ?
\end{remark}
Pour élargir le lit moyen, la géométrie doit être modifiée.
Il est judicieux d'enregistrer votre étude sous un autre nom avant de procéder à ces modifications (cliquez sur \texttt{[Fichier] => [Sauvegarder sous]}).
Le plus simple est de repartir de la géométrie avant maillage avant de modifier les transects.
Vous pouvez supprimer les sections interpolées en les sélectionnant dans la fenêtre \textit{Géométrie} et en appuyant sur le bouton \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/del.png}.
Cliquez sur \texttt{[Géométrie] => [Modifier la géométrie]} ou sur l'icône \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/geometry.png} pour définir la géométrie du bief.
Sélectionnez la section en travers que vous souhaitez modifier.
Vous pouvez l'éditer en cliquant sur l'icône \includegraphics[width=0.5cm]{"../../../src/View/ui/ressources/edit.png"}.
S'ouvre alors la fenêtre suivante :
\begin{center}
\includegraphics[width=15cm]{img/modif_profil_en_travers.png}
\par\end{center}
En appuyant sur \includegraphics[width=0.5cm]{"../../../src/View/ui/ressources/add.png"} vous pourrez ajouter un point sur votre profil en travers que vous pourrez ensuite placer ou vous le souhaitez sur le profil grâce aux flèches \includegraphics[width=0.5cm]{"../../../src/View/ui/ressources/up.png"} ou \includegraphics[width=0.5cm]{"../../../src/View/ui/ressources/down.png"}.
Dans le cas présent, afin d'élargir le lit moyen de 50\,m, vous pourrez ajouter un point juste après le point qui correspond à la rive droite (rd) légèrement plus haut et 50\,m plus à droite (en $Y=61.5$\,m et $Z=20.1$\,m par exemple).
Il ne restera alors plus qu'à décaler tous les points suivants de 50\,m.
Vous devriez obtenir la géométrie suivante :
\begin{center}
\includegraphics[width=15cm]{img/modif_profil_en_travers2.png}
\par\end{center}
Vous pouvez appliquer cette méthode à l'ensemble des transects à élargir et lancer le calcul pour chacune des crues proposées avec ce nouvel aménagement.
\begin{remark}
Exportez les résultats obtenus pour la hauteur d'eau en fonction du PK pour ce nouveau scénario.
Quel est l'effet de cet aménagement sur la hauteur d'eau et sur quel secteur ?
Exportez également le débit en fonction du temps en quelques sections choisies.
Quel est l'effet de cet aménagement sur l'hydrogramme de crue ?
Peut-on s'attendre à ce résultat compte tenu du volume qu'il est possible de stocker en lit moyen et du volume total de la crue ?
\end{remark}
\section{Troisième scénario d'aménagement : casier de stockage}
Ce troisième scénario consiste à faire baisser le débit dans la rivière en créant un déversement vers un casier de stockage en rive gauche juste en aval du pont de l'A2.
La surface de stockage disponible a été estimée à 42 ha pour une altitude moyenne du terrain naturel de 18\,m.
\begin{remark}
Quel volume d'eau ce réservoir peut-il stocker ?
Comment se compare-t-il au volume de la crue ?
Quel est alors l'effet attendu de cet ouvrage ?
\end{remark}
Pour modéliser ce scénario, il est nécessaire de dévier une part de l'écoulement pour le diriger vers un casier.
Il faut donc créer une difluence, soit modifier le réseau.
De nouveau, il est préférable d'enregistrer l'étude sous un autre nom avant de procéder à ces modifications.
Cliquez sur \texttt{[Réseau] => [Modifier le réseau]} ou sur l'icône \includegraphics[width=0.5cm]{img/network.png} pour modifier la structure de votre rivière.
Le réseau pour la configuration de référence ne comportait qu'un seul bief entre deux noeuds.
Pour ajouter un casier, il faut ajouter un noeud pour la diffluence, un noeud en amont du casier et un noeud en aval du casier.
Le casier ne peut en effet pas être en limite aval du modèle ni directement au niveau de la confluence.
Pour ajouter un noeud, cliquez \includegraphics[width=0.5cm]{../../../src/View/ui/ressources/add.png} pour sélectionner l'outil ``d'addition'' et cliquez ensuite dans la fenêtre grise à l'endroit ou vous souhaitez ajouter un noeud.
De la même façon vous pourrez avec cet outil ajouter un bief entre deux noeuds en cliquant successivement sur l'un puis sur l'autre.
Vous pourrez alors créer un réseau tel que celui ci-dessous où DevLat est le noeud marquant la diffluence.
\begin{center}
\includegraphics[width=12cm]{img/reseau_casier.png}
\par\end{center}
Pour chacun des nouveau biefs crées, il vous faudra créer ou adapter la géométrie.
Deux exemples vous sont proposés ci-dessous pour les biefs amont et aval du casier.
\begin{center}
\includegraphics[width=10cm]{img/geom_am_casier.png}
\includegraphics[width=10cm]{img/geom_av_casier.png}
\par\end{center}
Vous noterez la présence d'un ouvrage sur le bief amont afin de pouvoir contrôler à partir de quelle hauteur d'eau on souhaite commencer le remplissage du casier.
Pour le bief principal constitué des deux biefs Crespin->DevLat et DevLat->SeuilAval, l'un d'eux porte la géométrie complète tandis que la géométrie de l'autre n'est pas définie.
Il vous faudra supprimer les sections dans l'un que vous implémenterez dans l'autre.
L'outil d'import de géométrie pourra vous aider.
Il faudra le cas échéant réimplémenter également les ouvrages.
Lancez le calcul pour chacune des crues proposées avec ce nouvel aménagement.
\begin{remark}
Exportez les résultats obtenus pour la hauteur d'eau en fonction du PK pour ce nouveau scénario.
Quel est l'effet de cet aménagement sur la hauteur d'eau et sur quel secteur ?
Exportez également le débit en fonction du temps en quelques sections choisies.
Quel est l'effet de cet aménagement sur l'hydrogramme de crue ?
Comparer les crues centenale et décennale : comment l'ouvrage sur le bief amont impacte-t-il les hydrogrammes ?
Vos résultats sont-ils cohérent avec vos premières estimations ?
\end{remark}
\section{Conclusion}
\`A l'aide de la modélisation numérique du cours d'eau de l'Hogneau, vous avez pu comparer l'efficacité de 3 scenarii d'aménagement sur une crue historique, une crue centenale et une crue décennale.
\begin{remark}
Quel aménagement jugez-vous le plus efficace ?
Quels éléments vous ont apporté la modélisation ?
Que proposeriez-vous à la collectivité locale ?
\end{remark}
A travers cet exemple, avez pris en main l'outil PamHyr avec le code de calcul MAGE.
\pagebreak{}
\end{document}
@@ -4,3 +4,5 @@ pdflatex -no-shell-escape step-by-step.tex
pdflatex -no-shell-escape step-by-step.tex
pdflatex -no-shell-escape pas-a-pas.tex
pdflatex -no-shell-escape pas-a-pas.tex
pdflatex -no-shell-escape Tuto-2-fr.tex
pdflatex -no-shell-escape Tuto-2-fr.tex
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

File renamed without changes.
File renamed without changes.
Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+4
View File
@@ -46,6 +46,10 @@ copy /y ..\mage8-windows\mage_extraire.exe pamhyr\mage8\
copy /y ..\mage8-windows\mailleurTT.exe pamhyr\mage8\
copy /y ..\mage8-windows\libbief.dll pamhyr\mage8\
rem adists
mkdir pamhyr\adists
copy /y ..\adists-windows\adists.exe pamhyr\adists\
rem Copy tests_cases
mkdir pamhyr\tests_cases
mkdir pamhyr\tests_cases\Saar
+52
View File
@@ -0,0 +1,52 @@
# Adists.py -- Pamhyr study checkers
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import time
import logging
from functools import reduce
from PyQt5.QtCore import QCoreApplication
from Modules import Modules
from Checker.Checker import AbstractModelChecker, STATUS
_translate = QCoreApplication.translate
logger = logging.getLogger()
class AdistsOutputRKChecker(AbstractModelChecker):
def __init__(self):
super(AdistsOutputRKChecker, self).__init__()
self._name = _translate("Checker", "AdisTS output RK checker")
self._description = _translate(
"Checker", "Check output RK"
)
self._modules = Modules.OUTPUT_RK
def run(self, study):
ok = True
nerror = 0
self._summary = "ok"
self._status = STATUS.OK
if not self.basic_check(study):
return False
return ok
+1 -1
View File
@@ -395,7 +395,7 @@ class MeshingWithMageMailleurTT(AMeshingTool):
logger.info(
f"! {self._exe_path()} " +
f"{st_file} {m_file} " +
f"update_kp " +
f"update_rk " +
f"{str(step)} " +
f"{limites[0]} {limites[1]} " +
f"{directrices[0]} {directrices[1]} " +
@@ -128,7 +128,8 @@ class BoundaryCondition(SQLSubModel):
bc.node = None
if row[3] != -1:
bc.node = next(filter(lambda n: n.id == row[3], data["nodes"]))
bc.node = next(filter(lambda n: n.id == row[3], data["nodes"]),
None)
values = execute(
"SELECT ind, data0, data1 FROM boundary_condition_data " +
@@ -0,0 +1,224 @@
# BoundaryConditionsAdisTS.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from tools import (
trace, timer,
old_pamhyr_date_to_timestamp,
date_iso_to_timestamp,
date_dmy_to_timestamp,
)
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
logger = logging.getLogger()
class BoundaryConditionAdisTS(SQLSubModel):
_sub_classes = []
_id_cnt = 0
def __init__(self, id: int = -1,
pollutant: int = -1, status=None):
super(BoundaryConditionAdisTS, self).__init__()
self._status = status
if id == -1:
self.id = BoundaryConditionAdisTS._id_cnt
else:
self.id = id
self._type = ""
self._node = None
self._pollutant = pollutant
self._data = []
self._header = []
self._types = [self.time_convert, float]
BoundaryConditionAdisTS._id_cnt = max(
BoundaryConditionAdisTS._id_cnt + 1, self.id)
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE boundary_condition_adists(
id INTEGER NOT NULL PRIMARY KEY,
pollutant INTEGER NOT NULL,
type TEXT NOT NULL,
node INTEGER,
FOREIGN KEY(pollutant) REFERENCES Pollutants(id),
FOREIGN KEY(node) REFERENCES river_node(id)
)
""")
execute("""
CREATE TABLE boundary_condition_data_adists(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
data0 TEXT NOT NULL,
data1 TEXT NOT NULL,
bc INTEGER,
FOREIGN KEY(bc) REFERENCES boundary_condition_adists(id)
)
""")
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
table = execute(
"SELECT id, pollutant, type, node " +
"FROM boundary_condition_adists"
)
if table is not None:
for row in table:
bc = cls(
id=row[0],
pollutant=row[1],
status=data['status']
)
bc.type = row[2]
bc.node = None
if row[3] != -1:
tmp = next(filter(
lambda n: n.id == row[3], data["nodes"]),
None)
if tmp is not None:
bc.node = tmp.id
else:
bc.node = -1
values = execute(
"SELECT data0, data1 FROM " +
"boundary_condition_data_adists " +
f"WHERE bc = '{bc.id}'"
)
# Write data
for v in values:
data0 = bc._types[0](v[0])
data1 = bc._types[1](v[1])
# Replace data at pos ind
bc._data.append((data0, data1))
new.append(bc)
return new
def _db_save(self, execute, data=None):
execute(f"DELETE FROM boundary_condition_adists WHERE id = {self.id}")
execute(f"DELETE FROM boundary_condition_data_adists" +
f" WHERE bc = {self.id}")
node = -1
if self._node is not None:
node = self._node
sql = (
"INSERT INTO " +
"boundary_condition_adists(id, pollutant, type, node) " +
"VALUES (" +
f"{self.id}, {self._pollutant}, " +
f"'{self._db_format(self._type)}', {node}" +
")"
)
execute(sql)
for d in self._data:
data0 = self._db_format(str(d[0]))
data1 = self._db_format(str(d[1]))
sql = (
"INSERT INTO " +
"boundary_condition_data_adists(data0, data1, bc) " +
f"VALUES ('{data0}', {data1}, {self.id})"
)
execute(sql)
return True
def __len__(self):
return len(self._data)
@classmethod
def time_convert(cls, data):
if type(data) is str:
if data.count("-") == 2:
return date_iso_to_timestamp(data)
if data.count("/") == 2:
return date_dmy_to_timestamp(data)
if data.count(":") == 3:
return old_pamhyr_date_to_timestamp(data)
if data.count(":") == 2:
return old_pamhyr_date_to_timestamp("00:" + data)
if data.count(".") == 1:
return round(float(data))
return int(data)
@property
def node(self):
return self._node
@node.setter
def node(self, node):
self._node = node
self._status.modified()
@property
def header(self):
return self._header.copy()
@header.setter
def header(self, header):
self._header = header
self._status.modified()
@property
def pollutant(self):
return self._pollutant
@pollutant.setter
def pollutant(self, pollutant):
self._pollutant = pollutant
self._status.modified()
@property
def type(self):
return self._type
@type.setter
def type(self, type):
self._type = type
self._status.modified()
@property
def data(self):
return self._data.copy()
@@ -0,0 +1,67 @@
# BoundaryConditionsAdisTSList.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
from copy import copy
from tools import trace, timer
from Model.Tools.PamhyrList import PamhyrModelList
from Model.Except import NotImplementedMethodeError
from Model.BoundaryConditionsAdisTS.BoundaryConditionAdisTS \
import BoundaryConditionAdisTS
class BoundaryConditionsAdisTSList(PamhyrModelList):
_sub_classes = [
BoundaryConditionAdisTS,
]
@classmethod
def _db_load(cls, execute, data=None):
new = cls(status=data['status'])
if data is None:
data = {}
new._lst = BoundaryConditionAdisTS._db_load(
execute, data
)
return new
def _db_save(self, execute, data=None):
execute("DELETE FROM boundary_condition_adists")
execute("DELETE FROM boundary_condition_data_adists")
if data is None:
data = {}
for bc in self._lst:
bc._db_save(execute, data=data)
return True
def new(self, index, pollutant):
n = BoundaryConditionAdisTS(pollutant=pollutant, status=self._status)
self._lst.insert(index, n)
self._status.modified()
return n
@property
def BCs_AdisTS_List(self):
return self.lst
+196
View File
@@ -0,0 +1,196 @@
# D90AdisTS.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from functools import reduce
from tools import trace, timer, old_pamhyr_date_to_timestamp
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
from Model.D90AdisTS.D90AdisTSSpec import D90AdisTSSpec
logger = logging.getLogger()
class D90AdisTS(SQLSubModel):
_sub_classes = [
D90AdisTSSpec,
]
_id_cnt = 0
def __init__(self, id: int = -1, name: str = "default",
status=None):
super(D90AdisTS, self).__init__()
self._status = status
if id == -1:
self.id = D90AdisTS._id_cnt
else:
self.id = id
self._name = name
self._d90 = None
self._enabled = True
self._data = []
D90AdisTS._id_cnt = max(
D90AdisTS._id_cnt + 1,
self.id
)
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE d90_adists(
id INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
d90 REAL NOT NULL,
enabled BOOLEAN NOT NULL
)
""")
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
major, minor, release = version.strip().split(".")
if major == 0 and minor < 1:
if int(release) < 6:
cls._db_create(execute)
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
table = execute(
"SELECT id, name, d90, enabled " +
"FROM d90_adists"
)
if table is not None:
for row in table:
d90_id = row[0]
name = row[1]
d90 = row[2]
enabled = (row[3] == 1)
D90 = cls(
id=d90_id,
name=name,
status=data['status']
)
D90.d90 = d90
D90.enabled = enabled
data['d90_default_id'] = d90_id
D90._data = D90AdisTSSpec._db_load(execute, data)
new.append(D90)
return new
def _db_save(self, execute, data=None):
execute(f"DELETE FROM d90_adists WHERE id = {self.id}")
d90 = -1.
if self.d90 is not None:
d90 = self.d90
sql = (
"INSERT INTO " +
"d90_adists(" +
"id, name, d90, enabled" +
") " +
"VALUES (" +
f"{self.id}, '{self._db_format(self._name)}', " +
f"{d90}, {self._enabled}" +
")"
)
execute(sql)
data['d90_default_id'] = self.id
execute(
"DELETE FROM d90_spec " +
f"WHERE d90_default = {self.id}"
)
for d90_spec in self._data:
d90_spec._db_save(execute, data)
return True
def __len__(self):
return len(self._data)
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
self._status.modified()
@property
def d90(self):
return self._d90
@d90.setter
def d90(self, d90):
self._d90 = d90
self._status.modified()
@property
def enabled(self):
return self._enabled
@enabled.setter
def enabled(self, enabled):
self._enabled = enabled
self._status.modified()
def new(self, index):
n = D90AdisTSSpec(status=self._status)
self._data.insert(index, n)
self._status.modified()
return n
def delete(self, data):
self._data = list(
filter(
lambda x: x not in data,
self._data
)
)
self._status.modified()
def delete_i(self, indexes):
for ind in indexes:
del self._data[ind]
self._status.modified()
def insert(self, index, data):
self._data.insert(index, data)
self._status.modified()
+63
View File
@@ -0,0 +1,63 @@
# D90AdisTSList.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
from copy import copy
from tools import trace, timer
from Model.Tools.PamhyrList import PamhyrModelList
from Model.D90AdisTS.D90AdisTS import D90AdisTS
class D90AdisTSList(PamhyrModelList):
_sub_classes = [
D90AdisTS,
]
@classmethod
def _db_load(cls, execute, data=None):
new = cls(status=data['status'])
if data is None:
data = {}
new._lst = D90AdisTS._db_load(
execute, data
)
return new
def _db_save(self, execute, data=None):
execute("DELETE FROM d90_adists")
if data is None:
data = {}
for d90 in self._lst:
d90._db_save(execute, data=data)
return True
def new(self, index):
n = D90AdisTS(status=self._status)
self._lst.insert(index, n)
self._status.modified()
return n
@property
def D90_AdisTS_List(self):
return self.lst
+193
View File
@@ -0,0 +1,193 @@
# D90AdisTSSpec.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from tools import trace, timer
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
logger = logging.getLogger()
class D90AdisTSSpec(SQLSubModel):
_sub_classes = [
]
_id_cnt = 0
def __init__(self, id: int = -1, name: str = "",
status=None):
super(D90AdisTSSpec, self).__init__()
self._status = status
if id == -1:
self.id = D90AdisTSSpec._id_cnt
else:
self.id = id
self._name_section = name
self._reach = None
self._start_rk = None
self._end_rk = None
self._d90 = None
self._enabled = True
D90AdisTSSpec._id_cnt = max(D90AdisTSSpec._id_cnt + 1, self.id)
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE d90_spec(
id INTEGER NOT NULL PRIMARY KEY,
d90_default INTEGER NOT NULL,
name TEXT NOT NULL,
reach INTEGER NOT NULL,
start_rk REAL NOT NULL,
end_rk REAL NOT NULL,
d90 REAL NOT NULL,
enabled BOOLEAN NOT NULL,
FOREIGN KEY(d90_default) REFERENCES d90_adists(id),
FOREIGN KEY(reach) REFERENCES river_reach(id)
)
""")
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
major, minor, release = version.strip().split(".")
if major == 0 and minor < 1:
if int(release) < 6:
cls._db_create(execute)
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
table = execute(
"SELECT id, d90_default, name, reach, start_rk, end_rk, " +
"d90, enabled " +
"FROM d90_spec " +
f"WHERE d90_default = {data['d90_default_id']} "
)
if table is not None:
for row in table:
id = row[0]
name = row[2]
reach = row[3]
start_rk = row[4]
end_rk = row[5]
d90 = row[6]
enabled = (row[7] == 1)
new_spec = cls(
id=id,
name=name,
status=data['status']
)
new_spec.reach = reach
new_spec.start_rk = start_rk
new_spec.end_rk = end_rk
new_spec.d90 = d90
new_spec.enabled = enabled
new.append(new_spec)
return new
def _db_save(self, execute, data=None):
d90_default = data['d90_default_id']
sql = (
"INSERT INTO " +
"d90_spec(id, d90_default, name, reach, " +
"start_rk, end_rk, d90, enabled) " +
"VALUES (" +
f"{self.id}, " +
f"{d90_default}, " +
f"'{self._db_format(self._name_section)}', " +
f"{self._reach}, " +
f"{self._start_rk}, " +
f"{self._end_rk}, " +
f"{self._d90}, " +
f"{self._enabled}" +
")"
)
execute(sql)
return True
@property
def name(self):
return self._name_section
@name.setter
def name(self, name):
self._name_section = name
self._status.modified()
@property
def reach(self):
return self._reach
@reach.setter
def reach(self, reach):
self._reach = reach
self._status.modified()
@property
def start_rk(self):
return self._start_rk
@start_rk.setter
def start_rk(self, start_rk):
self._start_rk = start_rk
self._status.modified()
@property
def end_rk(self):
return self._end_rk
@end_rk.setter
def end_rk(self, end_rk):
self._end_rk = end_rk
self._status.modified()
@property
def d90(self):
return self._d90
@d90.setter
def d90(self, d90):
self._d90 = d90
self._status.modified()
@property
def enabled(self):
return self._enabled
@enabled.setter
def enabled(self, enabled):
self._enabled = enabled
self._status.modified()
+253
View File
@@ -0,0 +1,253 @@
# DIFAdisTS.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from functools import reduce
from tools import trace, timer, old_pamhyr_date_to_timestamp
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
from Model.DIFAdisTS.DIFAdisTSSpec import DIFAdisTSSpec
logger = logging.getLogger()
class DIFAdisTS(SQLSubModel):
_sub_classes = [
DIFAdisTSSpec,
]
_id_cnt = 0
def __init__(self, id: int = -1, name: str = "default",
status=None):
super(DIFAdisTS, self).__init__()
self._status = status
if id == -1:
self.id = DIFAdisTS._id_cnt
else:
self.id = id
self._name = name
self._method = None
self._dif = None
self._b = None
self._c = None
self._enabled = True
self._types = ["iwasa", "fisher", "elder", "constante", "generique"]
self._data = []
DIFAdisTS._id_cnt = max(
DIFAdisTS._id_cnt + 1,
self.id
)
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE dif_adists(
id INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
method TEXT NOT NULL,
dif REAL NOT NULL,
b REAL,
c REAL,
enabled BOOLEAN NOT NULL
)
""")
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
major, minor, release = version.strip().split(".")
if major == 0 and minor < 1:
if int(release) < 6:
cls._db_create(execute)
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
table = execute(
"SELECT id, name, method, dif, b, c, enabled " +
"FROM dif_adists"
)
if table is not None:
for row in table:
dif_id = row[0]
name = row[1]
method = row[2]
dif = row[3]
b = row[4]
c = row[5]
enabled = (row[6] == 1)
DIF = cls(
id=dif_id,
name=name,
status=data['status']
)
DIF.method = method
DIF.dif = dif
DIF.b = b
DIF.c = c
DIF.enabled = enabled
data['dif_default_id'] = dif_id
DIF._data = DIFAdisTSSpec._db_load(execute, data)
new.append(DIF)
return new
def _db_save(self, execute, data=None):
execute(f"DELETE FROM dif_adists WHERE id = {self.id}")
method = ""
if self.method is not None:
method = self.method
dif = -1.
if self.dif is not None:
dif = self.dif
b = -1.
if self.b is not None:
b = self.b
c = -1.
if self.dif is not None:
c = self.c
sql = (
"INSERT INTO " +
"dif_adists(" +
"id, name, method, dif, b, c, enabled" +
") " +
"VALUES (" +
f"{self.id}, '{self._db_format(self._name)}', " +
f"'{self._db_format(self._method)}', " +
f"{dif}, {b}, {c}, {self._enabled}" +
")"
)
execute(sql)
data['dif_default_id'] = self.id
execute(
"DELETE FROM dif_spec " +
f"WHERE dif_default = {self.id}"
)
for dif_spec in self._data:
dif_spec._db_save(execute, data)
return True
def __len__(self):
return len(self._data)
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
self._status.modified()
@property
def method(self):
return self._method
@method.setter
def method(self, method):
self._method = method
self._status.modified()
@property
def types(self):
return self._types
@property
def dif(self):
return self._dif
@dif.setter
def dif(self, dif):
self._dif = dif
self._status.modified()
@property
def b(self):
return self._b
@b.setter
def b(self, b):
self._b = b
self._status.modified()
@property
def c(self):
return self._c
@c.setter
def c(self, c):
self._c = c
self._status.modified()
@property
def enabled(self):
return self._enabled
@enabled.setter
def enabled(self, enabled):
self._enabled = enabled
self._status.modified()
def new(self, index):
n = DIFAdisTSSpec(status=self._status)
self._data.insert(index, n)
self._status.modified()
return n
def delete(self, data):
self._data = list(
filter(
lambda x: x not in data,
self._data
)
)
self._status.modified()
def delete_i(self, indexes):
for ind in indexes:
del self._data[ind]
self._status.modified()
def insert(self, index, data):
self._data.insert(index, data)
self._status.modified()
+63
View File
@@ -0,0 +1,63 @@
# DIFAdisTSList.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
from copy import copy
from tools import trace, timer
from Model.Tools.PamhyrList import PamhyrModelList
from Model.DIFAdisTS.DIFAdisTS import DIFAdisTS
class DIFAdisTSList(PamhyrModelList):
_sub_classes = [
DIFAdisTS,
]
@classmethod
def _db_load(cls, execute, data=None):
new = cls(status=data['status'])
if data is None:
data = {}
new._lst = DIFAdisTS._db_load(
execute, data
)
return new
def _db_save(self, execute, data=None):
execute("DELETE FROM dif_adists")
if data is None:
data = {}
for dif in self._lst:
dif._db_save(execute, data=data)
return True
def new(self, index):
n = DIFAdisTS(status=self._status)
self._lst.insert(index, n)
self._status.modified()
return n
@property
def DIF_AdisTS_List(self):
return self.lst
+221
View File
@@ -0,0 +1,221 @@
# DIFAdisTSSpec.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from tools import trace, timer
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
logger = logging.getLogger()
class DIFAdisTSSpec(SQLSubModel):
_sub_classes = [
]
_id_cnt = 0
def __init__(self, id: int = -1, method: str = "",
status=None):
super(DIFAdisTSSpec, self).__init__()
self._status = status
if id == -1:
self.id = DIFAdisTSSpec._id_cnt
else:
self.id = id
self._method = method
self._reach = None
self._start_rk = None
self._end_rk = None
self._dif = None
self._b = None
self._c = None
self._enabled = True
DIFAdisTSSpec._id_cnt = max(DIFAdisTSSpec._id_cnt + 1, self.id)
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE dif_spec(
id INTEGER NOT NULL PRIMARY KEY,
dif_default INTEGER NOT NULL,
method TEXT NOT NULL,
reach INTEGER NOT NULL,
start_rk REAL NOT NULL,
end_rk REAL NOT NULL,
dif REAL NOT NULL,
b REAL,
c REAL,
enabled BOOLEAN NOT NULL,
FOREIGN KEY(dif_default) REFERENCES dif_adists(id),
FOREIGN KEY(reach) REFERENCES river_reach(id)
)
""")
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
major, minor, release = version.strip().split(".")
if major == 0 and minor < 1:
if int(release) < 6:
cls._db_create(execute)
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
table = execute(
"SELECT id, dif_default, method, reach, start_rk, end_rk, " +
"dif, b, c, enabled " +
"FROM dif_spec " +
f"WHERE dif_default = {data['dif_default_id']} "
)
if table is not None:
for row in table:
id = row[0]
method = row[2]
reach = row[3]
start_rk = row[4]
end_rk = row[5]
dif = row[6]
b = row[7]
c = row[8]
enabled = (row[9] == 1)
new_spec = cls(
id=id,
method=method,
status=data['status']
)
new_spec.reach = reach
new_spec.start_rk = start_rk
new_spec.end_rk = end_rk
new_spec.dif = dif
new_spec.b = b
new_spec.c = c
new_spec.enabled = enabled
new.append(new_spec)
return new
def _db_save(self, execute, data=None):
dif_default = data['dif_default_id']
sql = (
"INSERT INTO " +
"dif_spec(id, dif_default, method, reach, " +
"start_rk, end_rk, dif, b, c, enabled) " +
"VALUES (" +
f"{self.id}, " +
f"{dif_default}, " +
f"'{self._db_format(self._method)}', " +
f"{self._reach}, " +
f"{self._start_rk}, " +
f"{self._end_rk}, " +
f"{self._dif}, " +
f"{self._b}, " +
f"{self._c}, " +
f"{self._enabled}" +
")"
)
execute(sql)
return True
@property
def method(self):
return self._method
@method.setter
def method(self, method):
self._method = method
self._status.modified()
@property
def reach(self):
return self._reach
@reach.setter
def reach(self, reach):
self._reach = reach
self._status.modified()
@property
def start_rk(self):
return self._start_rk
@start_rk.setter
def start_rk(self, start_rk):
self._start_rk = start_rk
self._status.modified()
@property
def end_rk(self):
return self._end_rk
@end_rk.setter
def end_rk(self, end_rk):
self._end_rk = end_rk
self._status.modified()
@property
def dif(self):
return self._dif
@dif.setter
def dif(self, dif):
self._dif = dif
self._status.modified()
@property
def b(self):
return self._b
@b.setter
def b(self, b):
self._b = b
self._status.modified()
@property
def c(self):
return self._c
@c.setter
def c(self, c):
self._c = c
self._status.modified()
@property
def enabled(self):
return self._enabled
@enabled.setter
def enabled(self, enabled):
self._enabled = enabled
self._status.modified()
+97 -13
View File
@@ -20,6 +20,7 @@ import logging
import numpy as np
from typing import List
from functools import reduce
from dataclasses import dataclass
from tools import timer
from shapely import geometry
@@ -33,6 +34,13 @@ from Model.Geometry.Vector_1d import Vector1d
logger = logging.getLogger()
@dataclass
class Tabulation:
z: np.array([])
A: np.array([])
L: np.array([])
class ProfileXYZ(Profile, SQLSubModel):
_sub_classes = [
PointXYZ,
@@ -70,6 +78,14 @@ class ProfileXYZ(Profile, SQLSubModel):
status=status,
)
self.tab = Tabulation([], [], [])
self.tab_up_to_date = False
self.time_z = 0.0
self.time_A = 0.0
self.time_l = 0.0
self._station = []
self.station_up_to_date = False
@classmethod
def _db_create(cls, execute):
execute("""
@@ -305,6 +321,8 @@ class ProfileXYZ(Profile, SQLSubModel):
pt = PointXYZ(*point, profile=self, status=self._status)
self.points.append(pt)
self._status.modified()
self.tab_up_to_date = False
self.station_up_to_date = False
def get_point_i(self, index: int) -> PointXYZ:
"""Get point at index.
@@ -366,6 +384,8 @@ class ProfileXYZ(Profile, SQLSubModel):
point_xyz = PointXYZ(0., 0., 0., profile=self, status=self._status)
self.points.append(point_xyz)
self._status.modified()
self.tab_up_to_date = False
self.station_up_to_date = False
def insert(self, index: int):
"""Insert a new point at index.
@@ -379,6 +399,8 @@ class ProfileXYZ(Profile, SQLSubModel):
point = PointXYZ(0., 0., 0., profile=self, status=self._status)
self.points.insert(index, point)
self._status.modified()
self.tab_up_to_date = False
self.station_up_to_date = False
return point
def filter_isnan(self, lst):
@@ -410,7 +432,7 @@ class ProfileXYZ(Profile, SQLSubModel):
return abs(rg.dist(rd))
def wet_width(self, z):
def compute_wet_width(self, z):
start, end = self.get_all_water_limits_ac(z)
if len(start) == 0:
@@ -421,6 +443,17 @@ class ProfileXYZ(Profile, SQLSubModel):
length += abs(s - e)
return length
def wet_width(self, z):
if self.tab_up_to_date:
if z > self.tab.z[-1]:
return self.tab.L[-1]
elif z < self.tab.z[0]:
return 0.0
else:
return np.interp(z, self.tab.z, self.tab.L)
else:
return self.compute_wet_width(z)
def wet_perimeter(self, z):
lines = self.wet_lines(z)
@@ -432,17 +465,46 @@ class ProfileXYZ(Profile, SQLSubModel):
length += line.length
return length
def wet_area(self, z):
lines = self.wet_lines(z)
if lines is None:
return 0
def compute_wet_area(self, z):
area = 0.0
for line in lines:
if len(line.coords) > 2:
poly = geometry.Polygon(line)
area += poly.area
if len(self.tab.L) > 0:
if z < self.tab.z[0]:
return 0.0
i = np.searchsorted([z], self.tab.z, side='right')[0]
for j in range(i-1):
area += (self.tab.L[j] + self.tab.L[j+1]) * (
self.tab.z[j+1] - self.tab.z[j]) / 2.0
area += (self.tab.L[i-1] + self.wet_width(z))
else:
lines = self.wet_lines(z)
if lines is None:
return 0.0
for line in lines:
if len(line.coords) > 2:
poly = geometry.Polygon(line)
area += poly.area
return area
def wet_area(self, z):
if self.tab_up_to_date:
if z > self.tab.z[-1]:
return self.tab.A[-1] + self.tab.L[-1] * (z - self.tab.z[-1])
elif z < self.tab.z[0]:
return 0.0
else:
return np.interp(z, self.tab.z, self.tab.A)
else:
lines = self.wet_lines(z)
if lines is None:
return 0.0
area = 0.0
for line in lines:
if len(line.coords) > 2:
poly = geometry.Polygon(line)
area += poly.area
return area
def wet_radius(self, z):
@@ -563,7 +625,7 @@ class ProfileXYZ(Profile, SQLSubModel):
return None
zz = list(map(lambda p: p.z, points))
station = self._get_station(points)
station = self.get_station()
start = []
if points[0].z <= z:
@@ -651,6 +713,19 @@ class ProfileXYZ(Profile, SQLSubModel):
return pt_left, pt_right
def compute_tabulation(self):
sorted_points = sorted(self._points, key=lambda p: p.z)
self.tab.z = np.array([p.z for p in sorted_points], np.float64)
self.tab.L = np.zeros(len(self.tab.z), np.float64)
self.tab.A = np.zeros(len(self.tab.z), np.float64)
for i in range(1, len(self.tab.z)):
self.tab.L[i] = self.compute_wet_width(self.tab.z[i])
dx = (self.tab.L[i] + self.tab.L[i-1])/2
dz = self.tab.z[i] - self.tab.z[i-1]
self.tab.A[i] = self.tab.A[i-1] + dz * dx
self.tab_up_to_date = True
def get_station(self):
"""Projection of the points of the profile on a plane.
@@ -663,7 +738,12 @@ class ProfileXYZ(Profile, SQLSubModel):
if self.nb_points < 2:
return [0.0]
else:
return self._get_station(self.points)
if self.station_up_to_date:
return self._station
else:
self._station = self._get_station(self.points)
self.station_up_to_date = True
return self._station
@timer
def _get_station(self, points):
@@ -799,3 +879,7 @@ class ProfileXYZ(Profile, SQLSubModel):
p.x = p.x + x
p.y = p.y + y
p.z = p.z + z
def modified(self):
self.tab_up_to_date = False
self.station_up_to_date = False
@@ -64,6 +64,7 @@ class HydraulicStructure(SQLSubModel):
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE hydraulic_structures(
id INTEGER NOT NULL PRIMARY KEY,
@@ -154,6 +155,7 @@ class HydraulicStructure(SQLSubModel):
return new
def _db_save(self, execute, data=None):
print("save hs unit")
execute(f"DELETE FROM hydraulic_structures WHERE id = {self.id}")
input_reach_id = -1
@@ -0,0 +1,268 @@
# InitialConditionsAdisTS.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from functools import reduce
from tools import trace, timer, old_pamhyr_date_to_timestamp
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
from Model.InitialConditionsAdisTS.InitialConditionsAdisTSSpec \
import ICAdisTSSpec
logger = logging.getLogger()
class InitialConditionsAdisTS(SQLSubModel):
_sub_classes = [
ICAdisTSSpec,
]
_id_cnt = 0
def __init__(self, id: int = -1, name: str = "default",
pollutant: int = -1, status=None):
super(InitialConditionsAdisTS, self).__init__()
self._status = status
if id == -1:
self.id = InitialConditionsAdisTS._id_cnt
else:
self.id = id
self._name = name
self._pollutant = pollutant
self._concentration = None
self._eg = None
self._em = None
self._ed = None
self._enabled = True
self._data = []
InitialConditionsAdisTS._id_cnt = max(
InitialConditionsAdisTS._id_cnt + 1,
self.id
)
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE initial_conditions_adists(
id INTEGER NOT NULL PRIMARY KEY,
pollutant INTEGER NOT NULL,
name TEXT NOT NULL,
concentration REAL NOT NULL,
eg REAL NOT NULL,
em REAL NOT NULL,
ed REAL NOT NULL,
enabled BOOLEAN NOT NULL,
FOREIGN KEY(pollutant) REFERENCES Pollutants(id)
)
""")
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
major, minor, release = version.strip().split(".")
if major == 0 and minor < 1:
if int(release) < 6:
cls._db_create(execute)
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
table = execute(
"SELECT id, pollutant, name, concentration, eg, em, ed, " +
"enabled " +
"FROM initial_conditions_adists"
)
if table is not None:
for row in table:
IC_id = row[0]
pollutant = row[1]
name = row[2]
concentration = row[3]
eg = row[4]
em = row[5]
ed = row[6]
enabled = (row[7] == 1)
IC = cls(
id=IC_id,
name=name,
status=data['status']
)
IC.pollutant = pollutant
IC.concentration = concentration
IC.eg = eg
IC.em = em
IC.ed = ed
IC.enabled = enabled
data['ic_default_id'] = IC_id
IC._data = ICAdisTSSpec._db_load(execute, data)
new.append(IC)
return new
def _db_save(self, execute, data=None):
execute(f"DELETE FROM initial_conditions_adists WHERE id = {self.id}")
pollutant = -1
if self.pollutant is not None:
pollutant = self.pollutant
concentration = -1.
if self.concentration is not None:
concentration = self.concentration
eg = -1.
if self.eg is not None:
eg = self.eg
em = -1.
if self.em is not None:
em = self.em
ed = -1.
if self.ed is not None:
ed = self.ed
sql = (
"INSERT INTO " +
"initial_conditions_adists(" +
"id, pollutant, name, concentration, " +
"eg, em, ed, enabled" +
") " +
"VALUES (" +
f"{self.id}, {pollutant}, '{self._db_format(self._name)}', " +
f"{concentration}, {eg}, {em}, {ed}, {self._enabled}" +
")"
)
execute(sql)
data['ic_default_id'] = self.id
execute(
"DELETE FROM initial_conditions_spec " +
f"WHERE ic_default = {self.id}"
)
for ic_spec in self._data:
ic_spec._db_save(execute, data)
return True
def __len__(self):
return len(self._data)
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
self._status.modified()
@property
def pollutant(self):
return self._pollutant
@pollutant.setter
def pollutant(self, pollutant):
self._pollutant = pollutant
self._status.modified()
@property
def concentration(self):
return self._concentration
@concentration.setter
def concentration(self, concentration):
self._concentration = concentration
self._status.modified()
@property
def eg(self):
return self._eg
@eg.setter
def eg(self, eg):
self._eg = eg
self._status.modified()
@property
def em(self):
return self._em
@em.setter
def em(self, em):
self._em = em
self._status.modified()
@property
def ed(self):
return self._ed
@ed.setter
def ed(self, ed):
self._ed = ed
self._status.modified()
@property
def enabled(self):
return self._enabled
@enabled.setter
def enabled(self, enabled):
self._enabled = enabled
self._status.modified()
def new(self, index):
n = ICAdisTSSpec(status=self._status)
self._data.insert(index, n)
self._status.modified()
return n
def delete(self, data):
self._data = list(
filter(
lambda x: x not in data,
self._data
)
)
self._status.modified()
def delete_i(self, indexes):
for ind in indexes:
del self._data[ind]
self._status.modified()
def insert(self, index, data):
self._data.insert(index, data)
self._status.modified()
@@ -0,0 +1,64 @@
# InitialConditionsAdisTSList.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
from copy import copy
from tools import trace, timer
from Model.Tools.PamhyrList import PamhyrModelList
from Model.InitialConditionsAdisTS.InitialConditionsAdisTS \
import InitialConditionsAdisTS
class InitialConditionsAdisTSList(PamhyrModelList):
_sub_classes = [
InitialConditionsAdisTS,
]
@classmethod
def _db_load(cls, execute, data=None):
new = cls(status=data['status'])
if data is None:
data = {}
new._lst = InitialConditionsAdisTS._db_load(
execute, data
)
return new
def _db_save(self, execute, data=None):
execute("DELETE FROM initial_conditions_adists")
if data is None:
data = {}
for ic in self._lst:
ic._db_save(execute, data=data)
return True
def new(self, index, pollutant):
n = InitialConditionsAdisTS(pollutant=pollutant, status=self._status)
self._lst.insert(index, n)
self._status.modified()
return n
@property
def Initial_Conditions_List(self):
return self.lst
@@ -0,0 +1,252 @@
# InitialConditionsAdisTSSpec.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from tools import trace, timer
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
logger = logging.getLogger()
class ICAdisTSSpec(SQLSubModel):
_sub_classes = [
]
_id_cnt = 0
def __init__(self, id: int = -1, name: str = "",
status=None):
super(ICAdisTSSpec, self).__init__()
self._status = status
if id == -1:
self.id = ICAdisTSSpec._id_cnt
else:
self.id = id
self._name_section = name
self._reach = None
self._start_rk = None
self._end_rk = None
self._concentration = None
self._eg = None
self._em = None
self._ed = None
self._rate = None
self._enabled = True
ICAdisTSSpec._id_cnt = max(ICAdisTSSpec._id_cnt + 1, self.id)
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE initial_conditions_spec(
id INTEGER NOT NULL PRIMARY KEY,
ic_default INTEGER NOT NULL,
name TEXT NOT NULL,
reach INTEGER NOT NULL,
start_rk REAL NOT NULL,
end_rk REAL NOT NULL,
concentration REAL NOT NULL,
eg REAL NOT NULL,
em REAL NOT NULL,
ed REAL NOT NULL,
rate REAL NOT NULL,
enabled BOOLEAN NOT NULL,
FOREIGN KEY(ic_default) REFERENCES initial_conditions_adists(id),
FOREIGN KEY(reach) REFERENCES river_reach(id)
)
""")
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
major, minor, release = version.strip().split(".")
if major == 0 and minor < 1:
if int(release) < 6:
cls._db_create(execute)
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
table = execute(
"SELECT id, ic_default, name, reach, start_rk, end_rk, " +
"concentration, eg, em, ed, rate, enabled " +
"FROM initial_conditions_spec " +
f"WHERE ic_default = {data['ic_default_id']} "
)
if table is not None:
for row in table:
id = row[0]
name = row[2]
reach = row[3]
start_rk = row[4]
end_rk = row[5]
concentration = row[6]
eg = row[7]
em = row[8]
ed = row[9]
rate = row[10]
enabled = (row[11] == 1)
# new_spec = [name, reach, start_rk, end_rk,
# concentration, eg, em, ed, rate, enabled]
new_spec = cls(
id=id,
name=name,
status=data['status']
)
new_spec.reach = reach
new_spec.start_rk = start_rk
new_spec.end_rk = end_rk
new_spec.concentration = concentration
new_spec.eg = eg
new_spec.em = em
new_spec.ed = ed
new_spec.rate = rate
new_spec.enabled = enabled
new.append(new_spec)
return new
def _db_save(self, execute, data=None):
ic_default = data['ic_default_id']
sql = (
"INSERT INTO " +
"initial_conditions_spec(id, ic_default, name, reach, " +
"start_rk, end_rk, concentration, eg, em, ed, rate, enabled) " +
"VALUES (" +
f"{self.id}, " +
f"{ic_default}, " +
f"'{self._db_format(self._name_section)}', " +
f"{self._reach}, " +
f"{self._start_rk}, " +
f"{self._end_rk}, " +
f"{self._concentration}, " +
f"{self._eg}, " +
f"{self._em}, " +
f"{self._ed}, " +
f"{self._rate}, " +
f"{self._enabled}" +
")"
)
execute(sql)
return True
@property
def name(self):
return self._name_section
@name.setter
def name(self, name):
self._name_section = name
self._status.modified()
@property
def reach(self):
return self._reach
@reach.setter
def reach(self, reach):
self._reach = reach
self._status.modified()
@property
def start_rk(self):
return self._start_rk
@start_rk.setter
def start_rk(self, start_rk):
self._start_rk = start_rk
self._status.modified()
@property
def end_rk(self):
return self._end_rk
@end_rk.setter
def end_rk(self, end_rk):
self._end_rk = end_rk
self._status.modified()
@property
def concentration(self):
return self._concentration
@concentration.setter
def concentration(self, concentration):
self._concentration = concentration
self._status.modified()
@property
def eg(self):
return self._eg
@eg.setter
def eg(self, eg):
self._eg = eg
self._status.modified()
@property
def em(self):
return self._em
@em.setter
def em(self, em):
self._em = em
self._status.modified()
@property
def ed(self):
return self._ed
@ed.setter
def ed(self, ed):
self._ed = ed
self._status.modified()
@property
def rate(self):
return self._rate
@rate.setter
def rate(self, rate):
self._rate = rate
self._status.modified()
@property
def enabled(self):
return self._enabled
@enabled.setter
def enabled(self, enabled):
self._enabled = enabled
self._status.modified()
@@ -0,0 +1,220 @@
# LateralContributionAdisTS.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from tools import (
trace, timer,
old_pamhyr_date_to_timestamp,
date_iso_to_timestamp,
date_dmy_to_timestamp,
)
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
logger = logging.getLogger()
class LateralContributionAdisTS(SQLSubModel):
_sub_classes = []
_id_cnt = 0
def __init__(self, id: int = -1, pollutant: int = -1,
name: str = "", status=None):
super(LateralContributionAdisTS, self).__init__()
self._status = status
if id == -1:
self.id = LateralContributionAdisTS._id_cnt
else:
self.id = id
self._pollutant = pollutant
self._edge = None
self._begin_rk = 0.0
self._end_rk = 0.0
self._data = []
self._header = ["time", "rate"]
self._types = [self.time_convert, float]
LateralContributionAdisTS._id_cnt = max(
LateralContributionAdisTS._id_cnt + 1, self.id)
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE lateral_contribution_adists(
id INTEGER NOT NULL PRIMARY KEY,
pollutant INTEGER NOT NULL,
edge INTEGER NOT NULL,
begin_rk REAL NOT NULL,
end_rk REAL NOT NULL,
FOREIGN KEY(pollutant) REFERENCES Pollutants(id),
FOREIGN KEY(edge) REFERENCES river_reach(id)
)
""")
execute("""
CREATE TABLE lateral_contribution_data_adists(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
data0 TEXT NOT NULL,
data1 TEXT NOT NULL,
lc INTEGER,
FOREIGN KEY(lc) REFERENCES lateral_contribution(id)
)
""")
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
table = execute(
"SELECT id, pollutant, edge, begin_rk, end_rk " +
"FROM lateral_contribution_adists"
)
if table is not None:
for row in table:
lc = cls(
id=row[0],
pollutant=row[1],
status=data['status']
)
lc.edge = row[2]
lc.begin_rk = row[3]
lc.end_rk = row[4]
values = execute(
"SELECT data0," +
" data1 FROM lateral_contribution_data_adists " +
f"WHERE lc = '{lc.id}'"
)
# Write data
for v in values:
data0 = lc._types[0](v[0])
data1 = lc._types[1](v[1])
# Replace data at pos ind
lc._data.append((data0, data1))
new.append(lc)
return new
def _db_save(self, execute, data=None):
execute(f"DELETE FROM lateral_contribution_adists" +
f" WHERE id = {self.id}")
execute(f"DELETE FROM lateral_contribution_data_adists" +
f" WHERE lc = {self.id}")
sql = (
"INSERT INTO " +
"lateral_contribution_adists(id, " +
"pollutant, edge, begin_rk, end_rk) " +
"VALUES (" +
f"{self.id}, {self._pollutant}, {self.edge}, " +
f"{self._begin_rk}, {self._end_rk}" +
")"
)
execute(sql)
for d in self._data:
data0 = self._db_format(str(d[0]))
data1 = self._db_format(str(d[1]))
sql = (
"INSERT INTO " +
"lateral_contribution_data_adists(data0, data1, lc) " +
f"VALUES ('{data0}', {data1}, {self.id})"
)
execute(sql)
return True
def __len__(self):
return len(self._data)
@classmethod
def time_convert(cls, data):
if type(data) is str:
if data.count("-") == 2:
return date_iso_to_timestamp(data)
if data.count("/") == 2:
return date_dmy_to_timestamp(data)
if data.count(":") == 3:
return old_pamhyr_date_to_timestamp(data)
if data.count(":") == 2:
return old_pamhyr_date_to_timestamp("00:" + data)
if data.count(".") == 1:
return round(float(data))
return int(data)
@property
def edge(self):
return self._edge
@edge.setter
def edge(self, edge):
self._edge = edge
self._status.modified()
@property
def header(self):
return self._header.copy()
@header.setter
def header(self, header):
self._header = header
self._status.modified()
@property
def pollutant(self):
return self._pollutant
@property
def data(self):
return self._data.copy()
@property
def begin_rk(self):
return self._begin_rk
@begin_rk.setter
def begin_rk(self, begin_rk):
self._begin_rk = begin_rk
self._status.modified()
@property
def end_rk(self):
return self._end_rk
@end_rk.setter
def end_rk(self, end_rk):
self._end_rk = end_rk
self._status.modified()
@@ -0,0 +1,67 @@
# LateralContributionsAdisTSList.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
from copy import copy
from tools import trace, timer
from Model.Tools.PamhyrList import PamhyrModelList
from Model.Except import NotImplementedMethodeError
from Model.LateralContributionsAdisTS.LateralContributionAdisTS \
import LateralContributionAdisTS
class LateralContributionsAdisTSList(PamhyrModelList):
_sub_classes = [
LateralContributionAdisTS,
]
@classmethod
def _db_load(cls, execute, data=None):
new = cls(status=data['status'])
if data is None:
data = {}
new._lst = LateralContributionAdisTS._db_load(
execute, data
)
return new
def _db_save(self, execute, data=None):
execute("DELETE FROM lateral_contribution_adists")
execute("DELETE FROM lateral_condition_data_adists")
if data is None:
data = {}
for lc in self._lst:
lc._db_save(execute, data=data)
return True
def new(self, index, pollutant):
n = LateralContributionAdisTS(pollutant=pollutant, status=self._status)
self._lst.insert(index, n)
self._status.modified()
return n
@property
def Lat_Cont_List(self):
return self.lst
+159
View File
@@ -0,0 +1,159 @@
# OutputRKAdists.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from tools import (
trace, timer,
old_pamhyr_date_to_timestamp,
date_iso_to_timestamp,
date_dmy_to_timestamp,
)
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
logger = logging.getLogger()
class OutputRKAdists(SQLSubModel):
_sub_classes = []
_id_cnt = 0
def __init__(self, id: int = -1, reach=None,
rk=None, title: str = "", status=None):
super(OutputRKAdists, self).__init__()
self._status = status
if id == -1:
self.id = OutputRKAdists._id_cnt
else:
self.id = id
self._reach = reach
self._rk = rk
self._title = str(title)
self._enabled = True
OutputRKAdists._id_cnt = max(
OutputRKAdists._id_cnt + 1, self.id)
@property
def reach(self):
return self._reach
@reach.setter
def reach(self, reach_id):
self._reach = reach_id
self._status.modified()
@property
def rk(self):
return self._rk
@rk.setter
def rk(self, profile_id):
self._rk = profile_id
self._status.modified()
@property
def title(self):
return self._title
@title.setter
def title(self, title):
self._title = title
self._status.modified()
@classmethod
def _db_create(cls, execute):
sql = (
"CREATE TABLE OutputRKAdists(" +
"id INTEGER NOT NULL PRIMARY KEY, " +
"reach INTEGER NOT NULL, " +
"rk REAL NOT NULL, " +
"title TEXT NOT NULL, " +
"FOREIGN KEY(reach) REFERENCES river_reach(id)" +
")"
)
execute(sql)
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
# reach = data["reach"]
# profile = data["profile"]
status = data["status"]
table = execute(
"SELECT id, reach, rk, title " +
f"FROM OutputRKAdists"
)
if table is not None:
for row in table:
id = row[0]
id_reach = row[1]
id_rk = row[2]
title = row[3]
new_output = cls(
id=id, reach=id_reach,
rk=id_rk, title=title,
status=status
)
new.append(new_output)
return new
def _db_save(self, execute, data=None):
execute(f"DELETE FROM OutputRKAdists WHERE id = {self.id}")
sql = (
"INSERT INTO " +
"OutputRKAdists(id, reach, rk, title) " +
"VALUES (" +
f"{self.id}, {self._reach}, {self._rk}, " +
f"'{self._db_format(self._title)}'" +
")"
)
execute(sql)
return True
@property
def enabled(self):
return self._enabled
@enabled.setter
def enabled(self, enabled):
self._enabled = enabled
self._status.modified()
@@ -0,0 +1,56 @@
# OutputRKListAdists.py -- Pamhyr
# Copyright (C) 2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
from tools import trace, timer
from Model.Except import NotImplementedMethodeError
from Model.Tools.PamhyrList import PamhyrModelList
from Model.OutputRKAdists.OutputRKAdists import OutputRKAdists
class OutputRKAdistsList(PamhyrModelList):
_sub_classes = [OutputRKAdists]
@classmethod
def _db_load(cls, execute, data=None):
new = cls(status=data["status"])
new._lst = OutputRKAdists._db_load(execute, data)
return new
def _db_save(self, execute, data=None):
ok = True
# Delete previous data
execute("DELETE FROM OutputRKAdists")
for sl in self._lst:
ok &= sl._db_save(execute, data)
return ok
@property
def OutputRK_List(self):
return self.lst
def new(self, lst, index):
n = OutputRKAdists(status=self._status)
self._lst.insert(index, n)
self._status.modified()
return n
+195
View File
@@ -0,0 +1,195 @@
# Pollutants.py -- Pamhyr
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import logging
from tools import (
trace, timer,
old_pamhyr_date_to_timestamp,
date_iso_to_timestamp,
date_dmy_to_timestamp,
)
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Except import NotImplementedMethodeError
logger = logging.getLogger()
class Pollutants(SQLSubModel):
_sub_classes = []
_id_cnt = 0
def __init__(self, id: int = -1, name: str = "", status=None):
super(Pollutants, self).__init__()
self._status = status
if id == -1:
self.id = Pollutants._id_cnt
else:
self.id = id
self._name = str(name)
self._enabled = True
self._data = []
Pollutants._id_cnt = max(
Pollutants._id_cnt + 1, self.id)
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
self._status.modified()
@property
def data(self):
return self._data.copy()
@classmethod
def _db_create(cls, execute):
execute("""
CREATE TABLE Pollutants(
id INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL UNIQUE
)
""")
execute("""
CREATE TABLE Pollutants_characteristics(
id INTEGER NOT NULL PRIMARY KEY,
type INTEGER NOT NULL,
diametre REAL NOT NULL,
rho REAL NOT NULL,
porosity REAL NOT NULL,
cdc_riv REAL NOT NULL,
cdc_cas REAL NOT NULL,
apd REAL NOT NULL,
ac REAL NOT NULL,
bc REAL NOT NULL,
pollutant INTEGER NOT NULL,
FOREIGN KEY(pollutant) REFERENCES Pollutants(id)
)
""")
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version):
return True
@classmethod
def _db_load(cls, execute, data=None):
new = []
status = data["status"]
table = execute(
"SELECT id, name " +
f"FROM Pollutants"
)
if table is not None:
for row in table:
id = row[0]
name = row[1]
new_pollutant = cls(
id=id, name=name,
status=status
)
new_data = []
table = execute(
"SELECT * " +
"FROM Pollutants_characteristics " +
f"WHERE pollutant = {id}"
)
if table is not None:
for t in table:
new_data = t[1:-1]
new_pollutant._data.append(new_data)
new.append(new_pollutant)
return new
def _db_save(self, execute, data=None):
execute(f"DELETE FROM Pollutants WHERE id = {self.id}")
execute(f"DELETE FROM Pollutants_characteristics" +
f" WHERE pollutant = {self.id}")
sql = (
"INSERT INTO " +
"Pollutants(id, name) " +
"VALUES (" +
f"{self.id}, " +
f"'{self._db_format(self._name)}'" +
")"
)
execute(sql)
for d in self._data:
sql = (
"INSERT INTO " +
"Pollutants_characteristics(type, diametre, rho, porosity, " +
"cdc_riv, cdc_cas, apd, ac, bc, pollutant) " +
f"VALUES ({d[0]}, {d[1]}, {d[2]},{d[3]}, {d[4]}, "
f"{d[5]}, {d[6]}, {d[7]}, {d[8]}, {self.id})"
)
execute(sql)
return True
@property
def enabled(self):
return self._enabled
@enabled.setter
def enabled(self, enabled):
self._enabled = enabled
self._status.modified()
def is_define(self):
return len(self._data) != 0
def new_from_data(self, data):
print("from_data before : ", data)
try:
new = [int(data[0])]
new += [float(d) for d in data[1:]]
except Exception as e:
logger.error(e)
new = None
print("from_data after : ", new)
return new
def __len__(self):
return len(self._data)
Loaded 100 of 198 files, more files were not shown because too many files have changed in this diff. Show more