• Aucun résultat trouvé

Transferts latéraux de subsurface

CHAPITRE 10. TRANSFERTS LATÉRAUX DE SUBSURFACE

10.3 Transferts entre deux parcelles séparées par un fossés

10.3.3 Implémentation de la ligne d’échanges entre 2 colonnes séparées par un fossé

La ligne d’échanges est codée sous la forme de la classe ColumnDitchColumnEx- changeLine. Celle-ci hérite de la classe SubsurfaceInterface et s’initialise entre autre à partir de deux instances de la classe Column et d’une instance de la classe Ditch. La classe Column est décrite section 10.2.3 et les autres classes sont décrites ci-après :

Classe Ditch

La classe Ditch initialise une instance de fossé telle qu’on en a besoin dans la ligne d’échanges ColumnDitchColumnExchangeLine. Cette initialisation se fait à partir d’une instance de la classe Reach (voir description dans la section 9.4.2). En plus d’un construc- teur, la classe Ditch contient des méthodes d’initialisation du flux latéral algébrique entrant/sortant de l’élément (un scalaire pour le flux d’eau, un vecteur(0 :n_solute) pour les solutés). La classe Ditch contient aussi les méthodes update_waterlatflux et update_solutelatflux. Contrairement à des setters classiques qui remplacent des variables existantes par une nouvelle valeur, ces méthodes permettent de mettre à jour la variable waterlatflux (resp. solutelatflux) en incrémentant la variable existante avec un stock additionnel increment_waterflux (resp. increment_solutelatflux).

Classe ColumnDitchColumnExchangeLine

• _init_()

Cette méthode permet d’initialiser une instance de la classe ColumnDitchColumn- ExchangeLine avec les mêmes attributs que la classe SubsurfaceInterface :

— idx : un index (scalaire entier) pour repérer l’interface ; — length : une longueur [L] ;

— x,y : une longitude et une latitude [L] ; — z : une altitude [L] ;

— UpstreamInstance : une instance de la classe Column. Il s’agit de l’élément situé à l’amont de l’interface.

— DownstreamInstance : une instance de la classe Column. Il s’agit de l’élément situé à l’aval de l’interface.

— InterceptInstance : une instance de la classe Ditch qui interceptera une partie des transferts entre les colonnes amont et aval.

• update_state_variables()

Cette méthode permet la mise à jour des variables d’état des colonnes amont et aval au début de chaque pas de temps. Pour cela, elle récupère les variables PALM contenant le vecteur de pression capillaire, de volume d’eau et de concen- tration en solutés dans chaque cellule numérique et met à jour les attributs de la classe Column correspondants. La méthode get_h_table de la classe Column est également appelée pour finaliser cette mise à jour. La concentration en solutés est enfin initialisée pour l’instance de fossé interceptant une partie des transferts.

• split_watertable(ColumnInstance,limit,limit_idx)

Split_watertable est une fonction qui prend en entrée les variables suivantes : — ColumnInstance : une instance de la classe Column ;

— limit : une profondeur limite (scalar) ;

— limit_idx : l’index de la cellule au fond de laquelle la profondeur limite limit est atteinte (integer).

Cette fonction permet de modifier le dictionnaire water_table_dic pour q’il ne contienne que les nappes situées en dessous de la hauteur limit. En réalité, les autres nappes sont conservées dans le dictionnaire mais tous leurs attributs sont fixés à None. Ces nappes ainsi que leurs attributs sont par ailleurs stockés dans le dictionnaire wt_2linear_dic.

Les sorties de la fonction sont composées des dictionnaires water_table_dic et wt_2linear_dic et du vecteur sat_cl_above contenant les index des cellules situées au dessus de la limite limit.

• calculate_flux_interface()

La méthode calculate_flux_interface gère le calcul du flux latéral dans le cas d’une ligne d’échanges Colonne-Fossé-Colonne.

Dans un premier temps, on suppose qu’un fossé se comporte toujours comme un fossé qui intercepte et transfère (d de la figure 36). La ligne d’échanges correspondante fonctionne de la manière suivante :

• Le flux latéral (eau et solutés) sortant de la colonne amont (UpstreamInstance) est d’abord calculé comme s’il n’existait pas de linéaire mais simplement une colonne aval (DownstreamInstance). A partir des instances de la classe Column UpstreamInstance et DownstreamInstance, on peut initialiser une instance de la classe ColumnColumnExchangeLine.

• Si un fossé se trouve entre les deux colonnes, les écoulements latéraux provenant de cellules numériques situées au dessus du fond du fossé seront envoyés vers le fossé (écoulements interceptés). Ceux provenant de cellules numériques situées au dessous du fond du fossé seront transmises à la colonne aval comme si le fossé n’existait pas (cf fig. 37).

!

4

Il est possible de se trouver dans le cas où le fond du fossé ne correspond pas exactement à la limite entre 2 cellules numériques de la colonne de sol amont. Dans ce cas-là, la profondeur du fossé est remplacée par la profondeur de la cellule numérique la plus proche (variable dx_lin12) pour éviter de devoir répartir l’eau d’une cellule numérique entre linéaire et colonne aval.

Comme détaillé dans la partie relative à l’interface ColumnColumnExchange- Line, pour calculer les flux d’eau sortant de la colonne amont vers la colonne aval, la méthode ColumnColumnExchangeLine.calculate_flux_interface ex- plore les nappes d’eau contenues dans le dictionnaire water_table_dic afin de déterminer si elles seront à l’origine d’un flux et quelles cellules numériques de la colonne aval seront concernées.

Pour effectuer ces deux premières étapes et être capable de distinguer l’eau qui sera transmise au fossé de celle transmise à la colonne aval, on se base sur le

CHAPITRE 10. TRANSFERTS LATÉRAUX DE SUBSURFACE

Figure 37 – Répartition des flux latéraux sortant de la colonne amont avec et sans fossé.

dictionnaire water_table_dic : on déplace toutes les nappes dont le fond est situé au dessus du fond du fossé dans un second dictionnaire wt_2linear_dic. Dans le cas d’une nappe située à cheval sur un fossé (fond de la nappe inférieur au fond du fossé mais fond du fossé inférieur au haut de la nappe), elle sera coupée en 2 pour apparaître dans les 2 dictionnaires, comme illustré fig. 38. Ce découpage des nappes est assuré par la fonction split_watertable.

Dans un premier temps, on ne découpait que les nappes de la colonnes amont pour différencier l’eau qui allait entrer dans le fossé de celle qui allait entrer dans la colonne aval. Par la suite, on s’est rendu compte qu’il fallait également découper les nappes de la colonne aval afin de ne garder que celles situées plus bas que le fossé s’assurant ainsi que l’eau de la nappe amont ne "remontera" pas dans la colonne aval.

Figure 38 – Répartition des nappes dans les dictionnaires water_table_dic et wt_2linear en fonction de leur position par rapport au fossé.

!

4

Attention, dans le code, lorsque l’on manipule le dictionnaire wa-

ter_table_dic. Lorsqu’une nappe est "supprimée" du dictionnaire car le flux sortant sera dirigé vers un linéaire et non pas vers la colonne aval, les en- trées du dictionnaire correspondantes (water_table_dic[indice,bottom],

water_table_dic[indice,sat_cells], water_table_dic[indice,thick], wa-

ter_table_dic[indice,height] et water_table_dic[indice,Keq]) ne sont pas réellement supprimées mais plutôt passées à None. Ceci car, si l’on supprime ces entrées et que l’on diminue le nombre de nappes représentées dans le dictionnaire, on ne s’assure pas de passer en revue toutes les nappes existantes par la suite dans handle_water_table :

Par exemple, si l’on dispose au départ d’un dictionnaire contenant 2 nappes et que l’on efface toutes les entrées relatives à la numéro 1 tout en diminuant de 1 le nombre de nappes dans le dictionnaire, la méthode ColumnColumnExchange- Line.calculate_flux_interface va effectuer les opérations suivantes :

 Chercher le nombre de nappes à explorer = 1  Explorer la première nappe, soit la numéro 1

 Or, la nappe numéro 1 n’existe plus, c’est la numéro 2 qui existe encore dans le dictionnaire !

Ainsi, pour éviter ce problème, on garde bien les 2 nappes dans le dic- tionnaire et on rajoute un test dans la méthode ColumnColumnExchange- Line.calculate_flux_interface : une nappe ne sera étudiée que si elle contient au moins une cellule saturée.

D’un point de vue du code détaillé, l’algorithme se présente comme suit :

• Appel de la méthode split_watertable(UH,limit,limit_idx) pour séparer les nappes et modifier water_table_dic.

• Appel de la méthode ColumnColumnExchangeLine.calculate_flux_interface pour calculer les flux correspondant aux nappes qui ne seront pas redirigées vers le fossés (pointillés verts sur la fig. 38).

• Remplacement de l’attribut water_table_dic par wt_2linear (pointillés bleus sur la fig. 38) et second appel de la méthode ColumnColumnExchan- geLine.calculate_flux_interface (ainsi, on calcule séparément les flux allant vers la colonne aval ou vers le fossé ce qui devrait éviter les confusions). • Mise à jour des attributs lat_flux (eau) et sol_flux (solutés) pour les instances

UpstreamInstance, DownstreamInstance et InterceptInstance en rajoutant les différentes contributions calculées :

UpstreamInstance_lat_flux est incrémenté grâce au vecteur des flux sortants

attribués aux nappes de water_table_dic et wt_2linear. Intercept_instance_lat_flux est incrémenté à partir de l’opposé du flux sortant attribués aux nappes de

wt_2linear_dic (on ne veut qu’un scalaire). Enfin DownstreamInstance_lat_flux est incrémenté grâce au vecteur des flux entrant attribués aux nappes de water_table_dic. Le calcul de ces différentes contributions est illustré fig. 39. Le fonctionnement est le même pour le calcul des contributions aux flux de solutés.

CHAPITRE 10. TRANSFERTS LATÉRAUX DE SUBSURFACE

Figure 39 – Décomposition du calcul des vecteurs Q_UH1, Q_UH2 et du scalaire Q_lin.