Skip to content
Snippets Groups Projects
Commit d28465b6 authored by Dorchies David's avatar Dorchies David
Browse files

Merge branch '298-passer-les-courbes-de-remous-en-cotes' into 'master'

Resolve "Passer les courbes de remous en cotes"

Closes #298

See merge request !63
parents 26a80dd7 7a78c70a
No related branches found
No related tags found
1 merge request!63Resolve "Passer les courbes de remous en cotes"
Pipeline #137594 passed
143-module-de-calcul-pente
146-passer-les-courbes-de-remous-en-cote
......@@ -27,8 +27,9 @@
"fields": [
"Ks",
"Long",
"If",
"YB"
"YB",
"ZF1",
"ZF2"
]
},
{
......@@ -36,8 +37,8 @@
"type": "fieldset",
"fields": [
"Q",
"Yaval",
"Yamont"
"Z1",
"Z2"
]
},
{
......
......@@ -14,17 +14,19 @@
"LargeurBerge": "Width at embankment level",
"fs_bief": "Features reach",
"Ks": "Strickler coefficient",
"Hs": "Head",
"Long": "Length of reach",
"If": "Bottom slope",
"YB": "Embankment elevation",
"fs_condlim": "Boundary conditions",
"Q": "Upstream flow",
"S": "Wet surface",
"Yaval": "Water level imposed at downstream",
"Yamont": "Water level imposed at upstream",
"fs_param_calc": "Calculation parameters",
"Dx": "Discretisation step",
"select_resolution": "Resolution method",
"Z1": "Upstream water elevation",
"Z2": "Downstream water elevation",
"ZF1": "Upstream bottom elevation",
"ZF2": "Downstream bottom elevation",
"UNIT_FLU": "m",
"UNIT_HS": "m",
......@@ -48,7 +50,7 @@
"fs_target_data": "Data to compute",
"select_target": "Choice of the data to compute",
"select_target_none": "None",
"select_target_Hs": "Specific head (m)",
"select_target_Hs": "Head (m)",
"select_target_Hsc": "Critical head (m)",
"select_target_B": "Surface width (m)",
"select_target_P": "Wetted perimeter (m)",
......
......@@ -14,16 +14,18 @@
"LargeurBerge": "Largeur de berge",
"fs_bief": "Caractéristiques du bief",
"Ks": "Coefficient de Strickler",
"Hs": "Charge",
"Long": "Longueur du bief",
"If": "Pente du fond",
"YB": "Hauteur de berge",
"fs_condlim": "Conditions aux limites",
"Q": "Débit amont",
"S": "Surface mouillée",
"Yaval": "Tirant d'eau imposé à l'aval",
"Yamont": "Tirant d'eau imposé à l'amont",
"Dx": "Pas de discrétisation",
"select_resolution": "Méthode de résolution",
"Z1": "Cote de l'eau à l'amont",
"Z2": "Cote de l'eau à l'aval",
"ZF1": "Cote du fond à l'amont",
"ZF2": "Cote du fond à l'aval",
"UNIT_FLU": "m",
"UNIT_HS": "m",
......@@ -47,7 +49,7 @@
"fs_target_data": "Donnée à calculer",
"select_target": "Choix de la donnée à calculer",
"select_target_none": "Aucune",
"select_target_Hs": "La charge spécifique (m)",
"select_target_Hs": "La charge (m)",
"select_target_Hsc": "La charge critique (m)",
"select_target_B": "La largeur au miroir (m)",
"select_target_P": "Le périmètre mouillé (m)",
......
......@@ -20,8 +20,8 @@
"Q": "Flow",
"Y": "Draft",
"fs_param_calc": "Calculation parameters",
"Hs": "Specific cahrge",
"Hsc": "Critical charge",
"Hs": "Specific head",
"Hsc": "Critical head",
"B": "Width at mirror",
"P": "Wet perimeter",
"S": "Wet surface",
......
import { Component, ViewChild, DoCheck } from "@angular/core";
import { ArrayReverseIterator, ResultElement, INumberIterator } from "jalhyd";
import { INumberIterator, CourbeRemousParams, CourbeRemous } from "jalhyd";
import { I18nService } from "../../services/internationalisation.service";
import { LogComponent } from "../../components/log/log.component";
......@@ -165,6 +165,20 @@ class ChartData {
};
}
/**
* Dessigne une ligne droite entre y0 (abscisse 0) et ymax (abscisse max),
* sans passer par les méthodes mapPoint() et mapY() utilisées dans drawLine
*/
public drawSimpleLine(y0: number, ymax: number, prof: number, color: string, lbl: string, fillColor?: string) {
const l = this.newLine(prof);
l.setPoint(0, y0);
l.setPoint(this._longBief, ymax);
l.data = {
label: lbl, fill: fillColor !== undefined, tension: 0, spanGaps: true,
borderColor: color, backgroundColor: fillColor, pointRadius: 0
};
}
public get data() {
const ds = [];
this._lines.sort((a, b) => {
......@@ -384,62 +398,26 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
private connectRessaut(lineFlu: LineData, lineTor: LineData) {
if (lineFlu !== undefined && lineTor !== undefined) {
const tX = lineFlu.tx.slice(0); // copie
tX.sort((a, b) => {
if (a > b) {
return 1;
}
if (a < b) {
return -1;
}
return 0;
});
let minXflu; // abscisse de début de la courbe fluviale
let itX = this.abscisseIterator;
for (const re of this._remousResults.result.resultElements) {
if (!itX.hasNext) {
throw new Error("RemousResultsComponent.connectRessaut() : erreur interne (itérateur sur x)");
}
const x = itX.next().value;
if (re.getValue("flu") !== undefined) {
minXflu = x;
break;
const p = this._remousResults.varResults.variatedParameters[0].paramDefinition;
const xs = p.getInferredValuesList();
// 1e passe : prolonger la torrentielle
outerloop1:
for (let i = 0; i < xs.length; i++) {
const x = xs[i];
if (lineTor.getYat(x) === null) {
lineTor.setPoint(x, lineFlu.getYat(x));
break outerloop1;
}
}
if (minXflu !== undefined && minXflu !== tX[0]) {
// la courbe fluviale ne démarre pas au début, on ajoute un point de raccord avec la ligne torrentielle
const i = tX.indexOf(minXflu);
const xflu = tX[i - 1];
const yflu = lineTor.getYat(xflu);
lineFlu.setPoint(xflu, yflu);
}
let maxXtor; // abscisse de fin de la courbe torrentielle
const itRE = new ArrayReverseIterator<ResultElement>(this._remousResults.result.resultElements);
itX = this.abscisseIterator;
for (const r of itRE) {
if (!itX.hasNext) {
throw new Error("RemousResultsComponent.connectRessaut() : erreur interne (itérateur sur x)");
}
const x = itX.next();
if (r.getValue("tor") !== undefined) {
maxXtor = x;
break;
// 2e passe : prolonger la fluviale
outerloop2:
for (let i = xs.length - 1; i >= 0; i--) {
const x = xs[i];
if (lineFlu.getYat(x) === null) {
lineFlu.setPoint(x, lineTor.getYat(x));
break outerloop2;
}
}
if (maxXtor !== undefined && maxXtor !== tX[tX.length - 1]) {
// la courbe torrentielle ne finit pas à la fin des abscisses, on ajoute un point de raccord avec la ligne fluviale
const i = tX.indexOf(maxXtor);
const xflu = tX[i + 1];
const yflu = lineFlu.getYat(xflu);
lineTor.setPoint(xflu, yflu);
}
}
}
......@@ -452,6 +430,11 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
this.varResultsComponent.results = this._remousResults.varResults;
}
const nub = this._remousResults.result.sourceNub as CourbeRemous;
const params = nub.prms as CourbeRemousParams;
const ZF1 = params.ZF1.singleValue;
const ZF2 = params.ZF2.singleValue;
const hauteurBerge = nub.section.prms.YB.singleValue;
const penteFond: number = this._remousResults.penteFond;
// abscisses
......@@ -480,29 +463,30 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
}
// ligne de fond
gr1.drawLine(0, 0, 3, "#753F00", this.uitextFond, "#753F00");
gr1.drawSimpleLine(ZF1, ZF2, 3, "#753F00", this.uitextFond, "#753F00");
// ligne de berge
if (this._remousResults.hautBerge) {
gr1.drawLine(this._remousResults.hautBerge, this._remousResults.hautBerge, 4, "#C58F50", this.uitextBerge);
if (hauteurBerge) {
gr1.drawSimpleLine(ZF1 + hauteurBerge, ZF2 + hauteurBerge, 4, "#C58F50", this.uitextBerge);
}
// hauteur normale
if (this._remousResults.hautNormale !== undefined && this._remousResults.hautNormale.ok) {
gr1.drawLine(this._remousResults.hautNormale.vCalc, this._remousResults.hautNormale.vCalc,
const Yn = this._remousResults.hautNormale.vCalc;
gr1.drawSimpleLine(Yn + ZF1, Yn + ZF2,
5, "#A4C537", this.uitextTirantNormal
);
}
// hauteur critique
if (this._remousResults.hautCritique !== undefined && this._remousResults.hautCritique.ok) {
gr1.drawLine(this._remousResults.hautCritique.vCalc, this._remousResults.hautCritique.vCalc,
const Yc = this._remousResults.hautCritique.vCalc;
gr1.drawSimpleLine(Yc + ZF1, Yc + ZF2,
6, "#FF0000", this.uitextTirantCritique
);
}
// lignes d'eau torrentielle et fluviale
let lineFlu: LineData;
if (this._remousResults.hasFluData) {
lineFlu = gr1.newLine(0);
......@@ -529,17 +513,17 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
const x = itX.next().value;
const yExtra = re.getValue(this._remousResults.extraParamSymbol);
if (yExtra !== undefined) {
lineExtra.mapPoint(x, yExtra);
lineExtra.setPoint(x, yExtra);
}
const yFlu = re.getValue("flu");
if (yFlu !== undefined) {
lineFlu.mapPoint(x, yFlu);
lineFlu.setPoint(x, yFlu);
}
const yTor = re.getValue("tor");
if (yTor !== undefined) {
lineTor.mapPoint(x, yTor);
lineTor.setPoint(x, yTor);
}
}
......@@ -558,11 +542,9 @@ export class RemousResultsComponent extends ResultsComponent implements DoCheck
}
// raccordement ligne fluviale -> torrentielle pour dessiner le ressaut
this.connectRessaut(lineFlu, lineTor);
// ajout des données au graphique
if (lineTor !== undefined) {
lineTor.data = {
label: this.uitextLigneTorrentielle,
......
......@@ -40,7 +40,8 @@ export class FormComputeCourbeRemous extends FormCompute {
this.remousResults.extraParamSymbol = this._formBase.currentNub.properties.getPropValue("varCalc");
// calcul
this.remousResults.result = cr.calculRemous(this.remousResults.extraParamSymbol);
// this.remousResults.result = cr.calculRemous(this.remousResults.extraParamSymbol);
this.remousResults.result = cr.CalcSerie();
// données du graphe
this.remousResults.hauteurNormale = this.resultYn.resultElement;
......
......@@ -36,66 +36,8 @@ export abstract class FormCompute implements Observer {
* Lance le calcul d'un paramètre en déterminant une valeur initiale.
* Si nécessaire déclenche un calcul en chaîne des modules en amont.
*/
protected runNubCalc(nub: Nub, computedParam?: ParamDefinition): Result {
let init: number;
// by default, use Nub's calculatedParam
if (computedParam === undefined) {
computedParam = nub.calculatedParam;
}
if (computedParam === undefined) {
// modules that have no calculated param (ex: Grille)
return nub.CalcSerie();
} else {
// const computedParamValue = computedParam.getValue();
const computedParamValue = computedParam.singleValue;
switch (computedParam.domain.domain) {
case ParamDomainValue.ANY:
if (computedParam && computedParam.isDefined) {
init = computedParamValue;
}
if (init === undefined) {
init = 0;
}
break;
case ParamDomainValue.POS_NULL:
if (computedParam && computedParam.isDefined) {
init = Math.max(computedParamValue, 0);
}
if (init === undefined) {
init = 0;
}
break;
case ParamDomainValue.INTERVAL:
init = (computedParam.domain.minValue + computedParam.domain.maxValue) / 2;
break;
case ParamDomainValue.NOT_NULL:
if (computedParam && computedParam.isDefined) {
init = computedParamValue;
}
if (init === undefined || init === 0) {
init = 1e-8;
}
break;
case ParamDomainValue.POS:
if (computedParam && computedParam.isDefined) {
init = Math.max(computedParamValue, 1e-8);
}
if (init === undefined) {
init = 1e-8;
}
break;
}
return nub.CalcSerie(init, this.getParameterRefid(computedParam));
}
protected runNubCalc(nub: Nub): Result {
return nub.CalcSerie();
}
protected getComputedParameter(): NgParameter {
......
......@@ -98,7 +98,7 @@ export class RemousResults extends CalculatorResults {
// série de valeurs de X
this._xValues = new ParamDefinition(p, "Abscisse", ParamDomainValue.POS_NULL);
this._xValues.paramValues.setValues(0, Long, Dx);
this._xValues.setValues(0, Long, Dx);
}
public get log() {
......
......@@ -40,6 +40,7 @@
"ERROR_PARAMDOMAIN_INTERVAL_BOUNDS": "invalid %minValue%/%maxValue% min/max boundaries for 'interval' parameter definition domain",
"ERROR_PARAMDOMAIN_INVALID": "parameter '%symbol%: non supported '%domain%' definition domain",
"ERROR_PROBLEM_LOADING_SESSION": "Session loaded, with errors",
"ERROR_REMOUS_NO_WATER_LINE": "No water line can be calculated",
"ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT": "Upstream boundary condition < Critical elevation: no possible calculation from upstream",
"ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL": "Downstream boundary condition < Critical elevation: no possible calculation from downstream",
"ERROR_REMOUS_PENTE_FORTE": "The water line slope is too steep at abscissa %x% m (the discretisation step should be reduced)",
......@@ -49,6 +50,7 @@
"ERROR_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE": "Non convergence of the calculation of the normal depth (Newton's method)",
"ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "The slope is negative or zero, the normal depth is infinite",
"ERROR_STRUCTURE_Q_TROP_ELEVE": "The flow passing through the other devices is too high: the requested parameter is not calculable.",
"ERROR_SECTION_SURFACE_NULLE": "Section : calcul impossible à cause d'une surface nulle",
"INFO_CALCULATOR_CALC_NAME": "Calculator name",
"INFO_CALCULATOR_CALCULER": "Compute",
"INFO_CALCULATOR_CLONE": "Duplicate",
......@@ -448,5 +450,9 @@
"WARNING_VANLEV_ZDV_SUP_MAX": "Regulated weir: maximum sill elevation reached",
"WARNING_GRILLE_ALPHA_GREATER_THAN_45": "Recommendation for fish guiding : α ≤ 45°",
"WARNING_GRILLE_BETA_GREATER_THAN_26": "Recommendation for fish guiding : β ≤ 26°",
"WARNING_GRILLE_VN_GREATER_THAN_05": "Recommendation to prevent fish getting stuck on grid plan (physical barrier) or prematurely passing through the grid (behavioural barrier) : VN ≤ 0.5 m/s.<br>Above average value calculated here, refer to the recommendations taken from experimental caracterisation of effective speed values."
"WARNING_GRILLE_VN_GREATER_THAN_05": "Recommendation to prevent fish getting stuck on grid plan (physical barrier) or prematurely passing through the grid (behavioural barrier) : VN ≤ 0.5 m/s.<br>Above average value calculated here, refer to the recommendations taken from experimental caracterisation of effective speed values.",
"WARNING_UPSTREAM_BOTTOM_HIGHER_THAN_WATER": "Upstream water elevation is lower or equal to bottom elevation",
"WARNING_DOWNSTREAM_BOTTOM_HIGHER_THAN_WATER": "Downstream water elevation is lower or equal to bottom elevation",
"WARNING_YN_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "Normal depth: slope is negative or zero, normal depth is infinite",
"WARNING_YN_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE": "Normal depth: non convergence of the calculation (Newton's method)"
}
......@@ -40,6 +40,7 @@
"ERROR_PARAMDOMAIN_INTERVAL_BOUNDS": "Les bornes (%minValue%/%maxValue%) de l'intervalle sont incorrectes",
"ERROR_PARAMDOMAIN_INVALID": "Paramètre '%symbol%'&nbsp;: le domaine de définition '%domain%' est incorrect",
"ERROR_PROBLEM_LOADING_SESSION": "Session chargée, avec des erreurs",
"ERROR_REMOUS_NO_WATER_LINE": "Aucune ligne d'eau ne peut être calculée",
"ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT": "Condition limite amont > Hauteur critique&nbsp;: pas de calcul possible depuis l'amont",
"ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL": "Condition limite aval < Hauteur critique&nbsp;: pas de calcul possible depuis l'aval",
"ERROR_REMOUS_PENTE_FORTE": "La pente de la ligne d'eau est trop forte à l'abscisse %x% m (il faudrait réduire le pas de discrétisation)",
......@@ -48,6 +49,7 @@
"ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCOR": "Non convergence du calcul de la hauteur correspondante (Méthode de Newton)",
"ERROR_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE": "Non convergence du calcul de la hauteur normale (Méthode de Newton)",
"ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "La pente est négative ou nulle, la hauteur normale est infinie",
"ERROR_SECTION_SURFACE_NULLE": "Section: calculation is impossible when surface is null",
"ERROR_STRUCTURE_Q_TROP_ELEVE": "Le débit passant par les autres ouvrages est trop élevé: le paramètre demandé n'est pas calculable.",
"INFO_CALCULATOR_CALC_NAME": "Nom du module de calcul",
"INFO_CALCULATOR_CALCULER": "Calculer",
......@@ -447,5 +449,9 @@
"WARNING_VANLEV_ZDV_SUP_MAX": "Seuil régulé&nbsp;: cote maximale de seuil atteinte",
"WARNING_GRILLE_ALPHA_GREATER_THAN_45": "Préconisation pour le guidage des poissons : α ≤ 45°",
"WARNING_GRILLE_BETA_GREATER_THAN_26": "Préconisation pour le guidage des poissons : β ≤ 26°",
"WARNING_GRILLE_VN_GREATER_THAN_05": "Préconisation pour éviter le placage des poissons sur le plan de grille (barrière physique) ou leur passage prématuré au travers (barrière comportementale) : VN ≤ 0.5 m/s.<br>Au-delà de la valeur moyenne calculée ici, se reporter aux préconisations tirées de la caractérisation expérimentale des valeurs effectives de vitesses."
"WARNING_GRILLE_VN_GREATER_THAN_05": "Préconisation pour éviter le placage des poissons sur le plan de grille (barrière physique) ou leur passage prématuré au travers (barrière comportementale) : VN ≤ 0.5 m/s.<br>Au-delà de la valeur moyenne calculée ici, se reporter aux préconisations tirées de la caractérisation expérimentale des valeurs effectives de vitesses.",
"WARNING_UPSTREAM_BOTTOM_HIGHER_THAN_WATER": "La cote de l'eau à l'amont est plus basse ou égale à la cote de fond",
"WARNING_DOWNSTREAM_BOTTOM_HIGHER_THAN_WATER": "La cote de l'eau à l'aval est plus basse ou égale à la cote de fond",
"WARNING_YN_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "Hauteur normale: pente négative ou nulle, hauteur normale infinie",
"WARNING_YN_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE": "Hauteur normale: non convergence du calcul (méthode de Newton)"
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment