... | ... | @@ -61,6 +61,47 @@ L'enjeu du couplage est de pouvoir intervenir sur le système à tout moment de |
|
|
|
|
|
Pour communiquer avec les modules, voir la page sur le [protocole de communication](protocole_j2k).
|
|
|
|
|
|
## CouplingCommunication
|
|
|
|
|
|
C'est le module qui gère la communication avec l'extérieur du modèle. On peut dire que c'est le module principal, c'est celui qui permet effectivement le couplage. Il comprend le protocole (on dit qu'il "implémente" le protocole) que nous avons défini et dont nous parlons dans la [page dédiée](protocole_j2k).
|
|
|
|
|
|
Ce module bloque l'exécution du modèle en début de pas de temps et attend des commandes.
|
|
|
|
|
|
* On a une commande pour le débloquer pendant un ou plusieurs pas de temps.
|
|
|
* On a des commandes pour définir les valeurs d'irrigation, de prélèvement/rejet, d'infiltration par les canaux.
|
|
|
* Une commande pour tout arrêter
|
|
|
* Des commandes pour récupérer des valeurs associées aux reachs et aux HRUs
|
|
|
|
|
|
Les commandes sont aussi détaillées dans la page sur le protocole.
|
|
|
|
|
|
### Architecture du module de communication
|
|
|
|
|
|
Ce module de communication exécute ses deux tâches en parallèle (multithread).
|
|
|
* L'ordonnancement : le contrôle de l'exécution du modèle
|
|
|
* La communication : l'écoute sur le réseau pour recevoir et répondre aux commandes venant de l'extérieur
|
|
|
|
|
|
Cela signifie qu'il peut recevoir une commande même quand ce n'est pas à son tour de s'exécuter dans le modèle.
|
|
|
|
|
|
### Ordonnancement
|
|
|
|
|
|
L'ordonnancement est géré dans la méthode principale présente dans tous les modules J2K : la méthode `run()`. C'est celle qui est appelée par JAMS pour dire à un module de s'exécuter.
|
|
|
|
|
|
On utilise ici des [sémaphores](https://fr.wikipedia.org/wiki/S%C3%A9maphore_(informatique)) pour bloquer et ensuite libérer l'exécution. Les sémaphores sont des sortes de verrous logiciels. C'est avec ceux-ci que l'on gère habituellement la synchronisation ou l'ordonnancement entre les exécutions parallèles d'un programme (programmation concurrente).
|
|
|
|
|
|
### Communication
|
|
|
|
|
|
En informatique, les communications sur les réseaux respectent l'architecture "client-serveur". Le serveur est en permanence en attente de connexion. c'est le client qui initie la communication en se connectant au serveur. Dans notre cas, le modèle J2K est le serveur, l'entité extérieure qui pilote le modèle J2K joue le rôle de client.
|
|
|
|
|
|
La gestion de la communication est très basique. Le module crée un socket (partie serveur) qui se met en attente d'une connexion (requête HTTP). Lorsqu'une requête est reçue, le message qu'elle contient est analysé et en fonction de la commande qu'elle contient, le module de communication va :
|
|
|
* effectuer une action (débloquer le modèle, stopper le modèle, renvoyer des informations sur l'état du modèle, etc...)
|
|
|
* ou bien stocker des informations (les valeurs d'irrigation que l'on veut modifier par exemple)
|
|
|
|
|
|
Le stockage d'information est effectué dans des attributs statiques (des dictionnaires) pour faciliter leur accès depuis les autres modules. On fournit aussi des méthodes statiques pour simplifier ces accès et les rendre plus lisibles.
|
|
|
|
|
|
### Interaction avec les autres modules
|
|
|
|
|
|
Quand les autres modules de couplage s'exécutent (Aspersion, Drip, BuechReachInOut etc...), ils accèdent aux informations stockées par le module de communication pour connaitre les valeurs qui viennent de l'extérieur. On peut dire qu'ils "demandent" au module de communication ce qu'ils doivent faire.
|
|
|
|
|
|
## CouplingVariableChanger
|
|
|
|
|
|
Les modules **CouplingHruVariableChanger** et **CouplingReachVariableChanger** peuvent être insérés n'importe où dans la HRU loop ou la REACH loop. On leur donne un **nom** et on fait le lien avec un attribut (une variable J2K propre à chaque HRU/REACH). On choisit si on veut forcer la valeur de l'attribut ou juste y ajouter une valeur avec le paramètre **setOrAdd**.
|
... | ... | @@ -69,27 +110,40 @@ Pour communiquer les valeurs à ces modules, on envoie la commande "set" au modu |
|
|
|
|
|
Par exemple, si on veut influer sur l'attribut "precip" des HRU, disons qu'on veut ajouter des précipitations, on ajoute **où on veut** une instance du module CouplingHruVariableChanger dans le modèle J2K (avec juice), on définit son nom en mettant l'attribut **moduleName** à "couplingPrecip" (par exemple) et on met la valeur de l'attribut **setOrAdd** à 1. On fait le lien entre l'attribut **attribute** du module avec l'attribut de notre choix, ici c'est **precip**.
|
|
|
|
|
|
Ensuite, dans le programme de couplage (Rcoupler pour nous), on appelle la fonction j2kSet en lui disant qu'on veut ajouter 10, 20 et 30 de précip pour les HRU 1, 2 et 3 :
|
|
|
Ensuite, dans le programme de pilotage du couplage (`Rcoupler.R` pour nous), on appelle la fonction `j2kSet()` en lui disant qu'on veut ajouter 10, 20 et 30 de précip pour les HRU 1, 2 et 3 :
|
|
|
```
|
|
|
j2kSet('couplingPrecip', c(1, 2, 3), c(10, 20, 30))
|
|
|
```
|
|
|
|
|
|
Donc, à l'intérieur du modèle J2K, lorsque c'est au tour du module `CouplingVariableChanger` nommé "couplingPrecip" de s'exécuter, ce dernier va demander au module de communication quelles entités il doit modifier et quelles valeurs il doit définir pour chacun d'entre elles. Cela est possible avec un simple appel à une méthode statique :
|
|
|
``` java
|
|
|
Double extValue = CouplingCommunication.getTableValue(moduleName, String.valueOf(HruId));
|
|
|
```
|
|
|
Cette ligne signifie : Je suis le module `moduleName` (qui vaut "couplingPrecip" dans notre exemple) et je veux savoir quelle valeur je dois mettre dans l'attribut dont je suis responsable pour la HRU dont l'identifiant est "HruId". Dans ce contexte, on connait l'identifiant de la HRU puisqu'on est dans la boucle spatiale (HRU loop).
|
|
|
|
|
|
**!! ATTENTION !!** Il faut bien faire attention aux unités. Dans notre exemple, on modifie precip qui est en MM. Comme ces modules sont génériques, ils ne peuvent pas faire de conversion comme les autres modules. Ces modules génériques ne savent pas ce qu'ils manipulent.
|
|
|
|
|
|
## Aspersion
|
|
|
|
|
|
Ce module est très spécifique, il permet d'ajouter de l'irrigation par aspersion depuis l'extérieur. Il doit être placé au bon endroit dans le modèle car il faut que les modifications qu'il apportent aient un effet sur les calculs impliquant les précipitations.
|
|
|
|
|
|
Pseudo code de l'irrigation par aspersion :
|
|
|
```
|
|
|
precip = precip + aspersionIrrig
|
|
|
irrigationTotal = irrigationTotal + aspersionIrrig
|
|
|
```
|
|
|
|
|
|
Très simple, ajoute de l'eau dans les précipitations.
|
|
|
`precip` est la variable interne (attribut des HRUs) contenant la quantité de précipitations du pas de temps.
|
|
|
|
|
|
Son fonctionnement est très simple, il ajoute de l'eau dans les précipitations.
|
|
|
|
|
|
Met aussi à jour une variable contenant la quantité totale d'irrigation du pas de temps.
|
|
|
Il met aussi à jour une variable contenant la quantité totale d'irrigation du pas de temps.
|
|
|
|
|
|
## Drip
|
|
|
|
|
|
Pseudo code de l'irrigation par drip:
|
|
|
Ce module ajoute de l'irrigation au goutte à goutte.
|
|
|
|
|
|
Pseudo code de l'irrigation par drip :
|
|
|
```
|
|
|
actDrip = min(maxMPS - actMPS, dripIrrig)
|
|
|
actMPS = actMPS + actDrip
|
... | ... | @@ -97,11 +151,14 @@ remainingAfterDrip = drip - actDrip |
|
|
irrigationTotal = irrigationTotal + actDrip
|
|
|
```
|
|
|
|
|
|
Ce qui reste de drip sera considéré comme de l'irrigation de surface.
|
|
|
Ce qui reste de drip, une fois qu'on a excédé la capacité d'absorption du sol, sera considéré comme de l'irrigation de surface.
|
|
|
On met aussi à jour l'irrigation totale dans ce module.
|
|
|
|
|
|
## Surface
|
|
|
|
|
|
Ce module ajoute de l'irrigation de surface.
|
|
|
|
|
|
Pseudo code de l'irrigation de surface :
|
|
|
```
|
|
|
surfaceIrrig = surfaceIrrig + remainingAfterDrip
|
|
|
netRain = netRain + surfaceIrrig
|
... | ... | @@ -112,22 +169,15 @@ On ajoute l'irrigation de surface dans la pluie (pas les précipitations). |
|
|
|
|
|
## Soil infiltration (J2KProcessLumpedSoilWater_cowat)
|
|
|
|
|
|
Application de l'infiltration par les canaux.
|
|
|
Ce module applique l'infiltration par les canaux. Sont effet est de rajouter de l'eau dans un des réservoirs des HRUs. La quantité d'infiltration n'est pas calculée dans ce module, elle provient de l'extérieur donc potentiellement d'une autre modèle qui prend en compte les canaux et connait la quantité d'eau qui s'infiltre dans les HRUs.
|
|
|
|
|
|
On part du module J2KProcessLumpedSoilWater et on l'adapte à notre cas de figure.
|
|
|
Ce module est assez complexe, son pseudo code serait trop long. on peut expliquer son fonctionnement en disant qu'on est parti du module J2KProcessLumpedSoilWater (disponible dans les modules J2K_Irstea) et qu'on l'a adapté à notre cas de figure.
|
|
|
|
|
|
## BuechReachInOut
|
|
|
Il a une influence sur l'attribut `actLPS` des HRUs.
|
|
|
|
|
|
On applique simplement les prélèvements et rejets dans les reachs. On prélève et rejette dans RD1 (variable actRD1).
|
|
|
|
|
|
## CouplingCommunication
|
|
|
|
|
|
Ce module bloque l'exécution du modèle en début de pas de temps et attend des commandes.
|
|
|
## BuechReachInOut
|
|
|
|
|
|
* On a une commande pour le débloquer pendant un ou plusieurs pas de temps.
|
|
|
* On a des commandes pour définir les valeurs d'irrigation, de prélèvement/rejet, d'infiltration par les canaux.
|
|
|
* Une commande pour tout arrêter
|
|
|
* Des commandes pour récupérer des valeurs associées aux reachs et aux HRUs
|
|
|
Ce module applique simplement les prélèvements et rejets dans les reachs. On prélève et rejette dans RD1 (attribut `actRD1` des reachs).
|
|
|
|
|
|
# Unités
|
|
|
|
... | ... | @@ -142,4 +192,4 @@ Pour l'infiltration, c'est aussi en **litres**. |
|
|
Pour les prélèvements et rejets, c'est en **litres**.
|
|
|
* ça modifie actRD1 (L)
|
|
|
|
|
|
Tout est en litres pour les modules spécifiques (tous sauf **CouplingHruVariableChanger** et **CouplingReachVariableChanger**). |
|
|
\ No newline at end of file |
|
|
Tout est en litres pour les modules spécifiques (donc tous les modules sauf **CouplingHruVariableChanger** et **CouplingReachVariableChanger**). |
|
|
\ No newline at end of file |