Newer
Older

Grand Francois
committed
import { ParamsSection, acSection } from "./section/section_type";
import { XOR, Result, round } from "./base";
import { IParamsEquation, ParamDefinition, ParamCalculability, ComputeNodeType, ParamDomainValue } from "./param";
import { Dichotomie } from "./dichotomie";
import { Nub } from "./nub";
import { ErrorCode, ErrorMessage } from "./util/error";
import { cLog } from "./util/log";

Grand Francois
committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
export enum MethodeResolution {
Trapezes, EulerExplicite, RungeKutta4
}
/**
* paramètres pour les courbes de remous
*/
export class CourbeRemousParams implements IParamsEquation {
/**
* Débit amont
*/
// private _Qamont: ParamDefinition;
/**
* Tirant imposé à l'amont
*/
private _Yamont: ParamDefinition;
/**
* Tirant imposé à l'aval
*/
private _Yaval: ParamDefinition;
/**
* Méthode de résolution de l'équation différentielle
*/
private _methodeResolution: MethodeResolution;
// constructor(rQamont: number, rYamont: number, rYAval: number, meth: MethodeResolution) {
constructor(rYamont: number, rYAval: number, meth: MethodeResolution) {
// this._Qamont = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Qam', ParamDomainValue.POS, rQamont);
this._Yamont = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Yam', ParamDomainValue.POS, rYamont);
this._Yaval = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Yav', ParamDomainValue.POS, rYAval);
this._methodeResolution = meth;
}
// get Qamont() {
// return this._Qamont;
// }
get Yamont() {
return this._Yamont;
}
get Yaval() {
return this._Yaval;
}
get methodeResolution() {
return this._methodeResolution;
}
}
/**
* Calcul d'une courbe de remous
*/
export class CourbeRemous extends Nub {
[key: string]: any; // pour pouvoir faire this['methode]();
private _debugDicho: boolean = false;
//const DBG = false; /// Pour loguer les messages de debug de cette classe
// public $oP; /// Paramètres de la section
// public $oSect; /// Section du bief
// private $oLog; /// Journal de calcul
private _log: cLog;

Grand Francois
committed
/**
* Pas de discrétisation de l'espace (positif en partant de l'aval, négatif en partant de l'amont)
*/
// private Dx: number;
Dx: number; // TODO à remettre en privé
// private VarCal: number; /// Variable calculée Y pour la dichotomie (intégration trapèze)
private Sn: acSection;
private prmSect: ParamsSection;
private prmCR: CourbeRemousParams;
//private HautCritique: number; // Yc de la section
constructor(s: acSection, crp: CourbeRemousParams, log: cLog) {

Grand Francois
committed
super(s.prms, false);
this._log = log;

Grand Francois
committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
this.Sn = s;
this.prmSect = s.prms;
this.prmCR = crp;
//this.HautCritique = s.Calc("Yc", this.prmSect.Y.v);
this.Sn.Calc("Yc");
}
protected setParametersCalculability() {
this._prms.Y.calculability = ParamCalculability.DICHO;
}
public Equation(sVarCalc: string): Result {
if (sVarCalc == "Hs") {
// Equation de l'intégration par la méthode des trapèzes
// let res: number = this.Sn.Calc('Hs', this.VarCal) - this.Sn.Calc('J', this.VarCal) / 2 * this.Dx;
this.Sn.Reset(); // pour forcer le calcul avec la nouvelle valeur de prmSect.Y
let res: number = this.Sn.Calc('Hs') - this.Sn.Calc('J') / 2 * this.Dx;
return new Result(res);
}
throw "CourbeRemous.Equation() : paramètre " + sVarCalc + " non pris en charge";
}
/**
* Calcul de dy/dx (utilisé par Euler explicite et Runge-Kutta 4)
* @param Y Tirant d'eau initial
*/
private Calc_dYdX(Y: number): number {
// L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau
return - (this.prmSect.If.v - this.Sn.Calc('J', Y)) / (1 - Math.pow(this.Sn.Calc('Fr', Y), 2));
}
/**
* Calcul du point suivant de la courbe de remous par la méthode Euler explicite.
* @param Y Tirant d'eau initial
* @return Tirant d'eau
*/
private Calc_Y_EulerExplicite(Y: number): Result {
// L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau
let Y2 = Y + this.Dx * this.Calc_dYdX(Y);
if (XOR(this.Dx > 0, !(Y2 < this.Sn.HautCritique)))
return new Result(undefined, new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE));
return new Result(Y2);
}
/**
* Calcul du point suivant de la courbe de remous par la méthode RK4.
* @param Y Tirant d'eau initial
* @return Tirant d'eau
*/
private Calc_Y_RK4(Y: number): Result {
// L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau
//$rDx = $this ->rDx;
let Dx = this.Dx;
//$rk1 = $this ->Calc_dYdX($Y);
let k1 = this.Calc_dYdX(Y);
let hc = this.Sn.HautCritique;
//if ($this ->rDx > 0 xor !($Y + $rDx / 2 * $rk1 < $this ->oSect ->rHautCritique)) { return false; }
if (XOR(Dx > 0, !(Y + Dx / 2 * k1 < hc)))
return new Result(undefined, new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE));

Grand Francois
committed
//$rk2 = $this ->Calc_dYdX($Y + $rDx / 2 * $rk1);
let k2 = this.Calc_dYdX(Y + Dx / 2 * k1);
//if ($this ->rDx > 0 xor !($Y + $rDx / 2 * $rk2 < $this ->oSect ->rHautCritique)) { return false; }
if (XOR(Dx > 0, !(Y + Dx / 2 * k2 < hc)))
return new Result(undefined, new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE));

Grand Francois
committed
//$rk3 = $this ->Calc_dYdX($Y + $rDx / 2 * $rk2);
let k3 = this.Calc_dYdX(Y + Dx / 2 * k2);
//if ($this ->rDx > 0 xor !($Y + $rDx / 2 * $rk3 < $this ->oSect ->rHautCritique)) { return false; }
if (XOR(Dx > 0, !(Y + Dx / 2 * k3 < hc)))
return new Result(undefined, new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE));

Grand Francois
committed
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
//$rk4 = $this ->Calc_dYdX($Y + $rDx * $rk3);
let k4 = this.Calc_dYdX(Y + Dx * k3);
//$Yout = $Y + $rDx / 6 * ($rk1 + 2 * ($rk2 + $rk3) + $rk4);
let Yout = Y + Dx / 6 * (k1 + 2 * (k2 + k3) + k4);
//if ($this ->rDx > 0 xor !($Yout < $this ->oSect ->rHautCritique)) { return false; }
if (XOR(Dx > 0, !(Yout < hc)))
return new Result(undefined, new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE));
return new Result(Yout);
}
/**
* Equation de l'intégration par la méthode des trapèzes
*/
// private Calc_Y_Trapez_Fn(): number {
// // return $this ->oSect ->Calc('Hs', $this ->VarCal) - $this ->oSect ->Calc('J', $this ->VarCal) / 2 * $this ->rDx;
// return this.Sn.Calc('Hs', this.VarCal) - this.Sn.Calc('J', this.VarCal) / 2 * this.Dx;
// }
/**
* Calcul du point suivant de la courbe de remous par la méthode de l'intégration par trapèze
* @param Y Tirant d'eau initial
* @return Tirant d'eau
*/
private Calc_Y_Trapez(Y: number): Result {
//include_spip('hyd_inc/dichotomie.class');
//$this ->VarCal = &$Y;
// this.VarCal = Y;
// $oDicho = new cDichotomie($this ->oLog, $this, 'Calc_Y_Trapez_Fn', false);
let Dicho = new Dichotomie(this, "Y", this._debugDicho, "Hs");
// Calcul de H + J * \Delta x / 2
// $Trapez_Fn = $this ->oSect ->Calc('Hs', $this ->VarCal) + $this ->oSect ->Calc('J', $this ->VarCal) / 2 * $this ->rDx;
// let Trapez_Fn = this.Sn.Calc('Hs', this.VarCal) + this.Sn.Calc('J', this.VarCal) / 2 * this.Dx
let Trapez_Fn = this.Sn.Calc('Hs', Y) + this.Sn.Calc('J', Y) / 2 * this.Dx
// H est la charge totale. On se place dans le référentiel ou Zf de la section à calculer = 0
// $Trapez_Fn = $Trapez_Fn - $this ->rDx * $this ->oP ->rIf;
Trapez_Fn -= this.Dx * this.prmSect.If.v;
// list($Y2, $flag) = $oDicho ->calculer($Trapez_Fn, $this ->oP ->rPrec, $this ->oSect ->rHautCritique);
// let r: Result = Dicho.Dichotomie(Trapez_Fn, this.prmSect.Prec.v, this.Sn.HautCritique);
let r: Result = Dicho.Dichotomie(Trapez_Fn, this.prmSect.Prec.v, Y);
// if ($flag < 0) {
if (r.code != ErrorCode.ERROR_OK)
return r;
let Y2 = r.vCalc;
// } elseif($this ->rDx > 0 xor !($Y2 < $this ->oSect ->rHautCritique)) {
if (XOR(this.Dx > 0, !(Y2 < this.Sn.HautCritique)))
return new Result(undefined, new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE));
return new Result(Y2);
}
/**
* Calcul du point suivant d'une courbe de remous
* @param Y Tirant d'eau initial
* @return Tirant d'eau
*/
private Calc_Y(Y: number): Result {
// let funcCalcY = 'Calc_Y_' + Resolution;
// return this[funcCalcY](Y);
switch (this.prmCR.methodeResolution) {
case MethodeResolution.Trapezes:
return this.Calc_Y_Trapez(Y);
case MethodeResolution.RungeKutta4:
return this.Calc_Y_RK4(Y);
case MethodeResolution.EulerExplicite:
return this.Calc_Y_EulerExplicite(Y);
// default:
// throw "CourbeRemous.Calc_Y() : type de méthode de résolution " + MethodeResolution[this.prmCR.methodeResolution] + " non pris en charge";
}
}
private size(o: {}): number {
let res: number = 0;
for (let i in o)
res++;
return res;
}
private last(o: any): any {
let res: any = undefined;
for (let i in o)
res = o[i];
return res;
}
/**
* Calcul d'une courbe de remous en fluvial ou torrentiel
* @param YCL Condition limite amont (torrentiel) ou aval (fluvial)
*/
private calcul(YCL: number): { [key: number]: number } {
let trY: { [key: number]: number; } = {};
if (this.Dx > 0) {
// Calcul depuis l'aval
var Deb: number = this.prmSect.Long.v;
var Fin: number = 0;
}
else {
// Calcul depuis l'amont
Deb = 0;
Fin = this.prmSect.Long.v;
}
let dx = - this.Dx;
let lastY = YCL;
trY[round(Deb, this.prmSect.iPrec.v)] = lastY;
// Boucle de calcul de la courbe de remous
for (let x = Deb + dx; (dx > 0 && x <= Fin) || (dx < 0 && x >= Fin); x += dx) {

Grand Francois
committed
// this.debug("lastY " + lastY);

Grand Francois
committed
let rY: Result = this.Calc_Y(lastY);

Grand Francois
committed
// this.debug("calcul : x " + x + " y " + rY.vCalc);

Grand Francois
committed
// this.debug("trY ");
// this.logObject(trY);
// this.debug("end trY " + this.last(trY));

Grand Francois
committed
// this.debug("Yn " + this.Sn.HautNormale);

Grand Francois
committed
if (rY.code == ErrorCode.ERROR_OK) {
// on vérifie qu'on ne traverse pas la hauteur normale (à la précision de calcul près)
let b1: boolean = lastY - this.Sn.HautNormale > this._prms.rPrec;
let b2: boolean = rY.vCalc - this.Sn.HautNormale > this._prms.rPrec;
if (XOR(b1, b2)) {

Grand Francois
committed
this.debug("La pente de la ligne d'eau est trop forte à l'abscisse " + x + " m (Il faudrait réduire le pas de discrétisation)");
let m: ErrorMessage = new ErrorMessage(ErrorCode.ERROR_REMOUS_PENTE_FORTE);
m.extraVar["x"] = x;
this._log.add(m);

Grand Francois
committed
}
trY[round(x, this.prmSect.iPrec.v)] = rY.vCalc;
} else {
let m = new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE);
m.extraVar["x"] = x;
this._log.add(m);

Grand Francois
committed
this.debug("Arrêt du calcul : Hauteur critique atteinte à l'abscisse " + x + " m");

Grand Francois
committed
break;
}
lastY = rY.vCalc;
}
return trY;
}

Grand Francois
committed
private logArray(a: string[]) {
let s = "[";
let first = true;
for (let e of a) {
if (!first)
s += ",";
s += +e;
first = false;
}
s += "]";
this.debug(s);
}

Grand Francois
committed
private logObject(o: { [key: number]: number }) {

Grand Francois
committed
if (o == undefined)
this.debug("<undefined>");
else {
let ks: string[] = Object.keys(o);
ks.sort((a, b) => {
if (+a > +b) return 1;
if (+a < +b) return -1;
return 0;
});
for (let k of ks)
this.debug("[" + (+k).toFixed(3) + "]=" + o[+k]);
}

Grand Francois
committed
}
/**
* @param val_a_cal nom de la variable à calculer
*/
public calculRemous(val_a_cal: string): {
"flu": { [key: number]: number; },
"tor": { [key: number]: number; },
"trX": string[],
"tRes": number[]
} {
let Yc: number = this.Sn.Calc("Yc");

Grand Francois
committed
let m: ErrorMessage = new ErrorMessage(ErrorCode.ERROR_REMOUS_LARGEUR_BERGE);
m.extraVar["B"] = this.Sn.Calc("B");
this._log.add(m);

Grand Francois
committed
m = new ErrorMessage(ErrorCode.ERROR_REMOUS_H_CRITIQUE);
m.extraVar["Yc"] = Yc;
this._log.add(m);

Grand Francois
committed
m = new ErrorMessage(ErrorCode.ERROR_REMOUS_H_NORMALE);
m.extraVar["Yn"] = this.Sn.Calc("Yn");
this._log.add(m);

Grand Francois
committed
this.debug("largeur berge " + this.Sn.Calc("B"));
this.debug("hauteur critique " + Yc);
this.Sn.HautNormale = this.Sn.Calc("Yn");
this.debug("hauteur normale " + this.Sn.HautNormale);
// Calcul des courbes de remous
let crbFlu: { [key: number]: number; } = undefined;
let crbTor: { [key: number]: number; } = undefined;
//this.debug("HautCritique ", this.Sn.HautCritique);
// Calcul depuis l'aval
if (this.Sn.HautCritique <= this.prmCR.Yaval.v) {
this._log.add(new ErrorMessage(ErrorCode.ERROR_REMOUS_CALCUL_FLUVIAL));

Grand Francois
committed
this.debug("Condition limite aval (" + this.prmCR.Yaval.v + ") >= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie fluviale à partir de l'aval");
this.Dx = this.prmSect.Dx.v;
crbFlu = this.calcul(this.prmCR.Yaval.v);
}
else {
this.debug("Condition limite aval (" + this.prmCR.Yaval.v + ") < Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'aval");
this._log.add(new ErrorMessage(ErrorCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL));

Grand Francois
committed
}
this.debug("flu ");

Grand Francois
committed
// this.logObject(crbFlu);
this.debug(JSON.stringify(crbFlu));

Grand Francois
committed
// Calcul depuis l'amont
if (this.Sn.HautCritique >= this.prmCR.Yamont.v) {
this._log.add(new ErrorMessage(ErrorCode.ERROR_REMOUS_CALCUL_TORRENTIEL));

Grand Francois
committed
this.debug("Condition limite amont (" + this.prmCR.Yamont.v + ") <= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie torrentielle à partir de l'amont");
this.Dx = -this.prmSect.Dx.v;
crbTor = this.calcul(this.prmCR.Yamont.v);
}
else {
this._log.add(new ErrorMessage(ErrorCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT));

Grand Francois
committed
this.debug("Condition limite amont (" + this.prmCR.Yamont.v + ") > Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'amont");
}
this.debug("tor");

Grand Francois
committed
// this.logObject(crbTor);
this.debug(JSON.stringify(crbTor));

Grand Francois
committed
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
// Détection du ressaut hydraulique
let nFlu: number = this.size(crbFlu);
let nTor: number = this.size(crbTor);
if (nFlu != 0 && nTor != 0) {
let xMaxFlu = crbFlu[0];
let xMaxTor = this.last(crbTor);
// this.debug("end flu " + xMaxFlu);
// this.debug("end tor " + xMaxTor);
// this.debug("nFlu " + nFlu);
// this.debug("nTor " + nTor);
// this.debug("Imp flu " + this.Sn.Calc('Imp', xMaxFlu));
// this.debug("Imp tor " + this.Sn.Calc('Imp', xMaxTor));
// if (nFlu > nTor || (nFlu == nTor && this.Sn.Calc('Imp', this.last(crbFlu)) > this.Sn.Calc('Imp', this.last(crbTor)))) {
if (nFlu > nTor || (nFlu == nTor && this.Sn.Calc('Imp', xMaxFlu) > this.Sn.Calc('Imp', xMaxTor))) {
// La courbe fluviale va jusqu'au bout
var crbComplete = crbFlu; // courbe calculée sur tout le bief
var crbPartielle = crbTor; // courbe calculée sur une partie seulement du bief
var iSens = 1; // On cherche l'aval du ressaut
var sSens = "amont";
this.debug("complete=flu, partielle=tor");
// this.debug("complete(flu)");
// this.debug(crbComplete);
// this.debug("partielle(tor)");
// this.debug(crbPartielle);
} else {
// La courbe torrentielle va jusqu'au bout
crbComplete = crbTor;
crbPartielle = crbFlu;
iSens = -1; // On cherche l'amont du ressaut
sSens = "aval";
this.debug("complete=tor, partielle=flu");
// this.debug("complete(tor)");
// this.debug(crbComplete);
// this.debug("partielle(flu)");
// this.debug(crbPartielle);
}
// Parcours des sections de la ligne d'eau la plus courte

Grand Francois
committed
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
let trX: string[] = Object.keys(crbPartielle);
if (iSens == -1)
trX.sort((a, b) => {
if (+a > +b) return 1;
if (+a < +b) return -1;
return 0;
});
else
trX.sort((a, b) => {
if (+a > +b) return -1;
if (+a < +b) return 1;
return 0;
});
let trXr = trX.slice(0); // copie
trXr.reverse();
// this.debug("trX");
// this.debug(trX);
let bRessaut = false;
let Dx = this.prmSect.Dx.v;
for (let irX = 0; irX < trX.length; irX++) {
let rX: number = +trX[irX];
// this.debug("irX=" + irX);
// this.debug("rX=" + rX);
// this.debug("partielle[" + rX + "]=" + crbPartielle[rX]);

Grand Francois
committed
// Calcul de l'abscisse de la section dans l'autre régime
let Yco = this.Sn.Calc('Yco', crbPartielle[rX]); // Y conjugué

Grand Francois
committed
// this.debug("rX=" + rX + " Yco(Ypartiel=" + crbPartielle[rX] + ")=" + Yco);

Grand Francois
committed
let rLongRst = 5 * Math.abs(crbPartielle[rX] - Yco); // Longueur du ressaut

Grand Francois
committed
// this.debug("longueur ressaut=" + rLongRst);

Grand Francois
committed
let xRst = rX + Math.round(iSens * rLongRst / Dx) * Dx; // Abscisse où comparer Yconj et Y

Grand Francois
committed
// this.debug("xRst=" + xRst);

Grand Francois
committed
//let rxRst = rX + iSens * rLongRst; // Abscisse réelle du ressaut
//this.debug("xRst reel=" + (rX + iSens * rLongRst));
xRst = round(xRst, this.prmSect.iPrec.v);

Grand Francois
committed
// this.debug("xRst (arr)=" + xRst);

Grand Francois
committed
if (crbComplete[xRst] != undefined) {
// Hauteur décalée de la longueur du ressaut (il faut gérer la pente du fond)
let Ydec: number = crbComplete[xRst] + rLongRst * this.prmSect.If.v * iSens;

Grand Francois
committed
// this.debug("Ydec=" + Ydec);
// this.debug("imp(Ycomplet[xRst=" + xRst + "]=" + crbComplete[xRst] + ")=" + this.Sn.Calc('Imp', crbComplete[xRst]));
// this.debug("imp(Ypartiel[rX=" + rX + "]=" + crbPartielle[rX] + ")=" + this.Sn.Calc('Imp', crbPartielle[rX]));

Grand Francois
committed
// if (iSens == 1 ? Yco > Ydec : Yco < Ydec) {
if (Yco > Ydec) {
this.debug("Ressaut hydraulique détecté entre les abscisses " + Math.min(rX, xRst) + " et " + Math.max(rX, xRst));
m = new ErrorMessage(ErrorCode.ERROR_REMOUS_RESSAUT_HYDRO);
m.extraVar["xmin"] = Math.min(rX, xRst);
m.extraVar["xmax"] = Math.max(rX, xRst);
this._log.add(m);

Grand Francois
committed
// this.debug("rX=" + rX + " xRst=" + xRst);

Grand Francois
committed
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
// Modification de la ligne d'eau CC
for (let pi of trXr) {
let rXCC: number = +pi;
// this.debug("rXCC=" + rXCC);
if (iSens * (rXCC - rX) < 0) {
delete crbComplete[rXCC];
this.debug("Modification de la ligne d'eau complète : suppression de la valeur à rX=" + rXCC);
} else if (rXCC == rX) {
this.debug("Modification de la ligne d'eau complète : valeur " + crbComplete[rXCC] + " remplacée par " + crbPartielle[rXCC] + " à rX=" + rXCC);
crbComplete[rXCC] = crbPartielle[rXCC];
this.debug("Fin de la modification de la ligne d'eau complète");
break;
}
}
// Modification de la ligne d'eau CN
for (let xcn of trX) {
let rXCN = +xcn;
// this.debug("rXCN=" + rXCN);
if (iSens * (rXCN - xRst) > 0) {
this.debug("Modification de la ligne d'eau partielle : suppression de la valeur à rX=" + rXCN);
delete crbPartielle[rXCN];
} else if (rXCN == xRst) {
this.debug("Modification de la ligne d'eau partielle : valeur " + crbPartielle[rXCN] + " remplacée par " + crbComplete[rXCN] + " à rX=" + rXCN);
crbPartielle[rXCN] = crbComplete[rXCN];
this.debug("Fin de la modification de la ligne d'eau partielle");
break;
}
}
bRessaut = true;
break;
}
}
}
if (!bRessaut) {
// Le ressaut est en dehors du canal
let m = new ErrorMessage(ErrorCode.ERROR_REMOUS_RESSAUT_DEHORS);
m.extraVar["sens"] = sSens;
m.extraVar["x"] = +this.last(trX);
this._log.add(m);

Grand Francois
committed
this.debug("Ressaut hydraulique détecté à l'" + sSens + " de l'abscisse " + this.last(trX));
if (iSens == 1)
crbTor = {};
else
crbFlu = {};

Grand Francois
committed
crbPartielle = {}; // pour le log uniquement, à virer

Grand Francois
committed
}
}
this.debug("complete (" + (iSens == 1 ? "flu" : "tor") + ") modifiée");

Grand Francois
committed
// this.logObject(crbComplete);
this.debug(JSON.stringify(crbComplete));

Grand Francois
committed
this.debug("partielle (" + (iSens == 1 ? "tor" : "flu") + ") modifiée");

Grand Francois
committed
// this.logObject(crbPartielle);
this.debug(JSON.stringify(crbPartielle));

Grand Francois
committed
// Définition des abscisses
let trX: string[] = [];
if (nFlu != 0)
trX = Object.keys(crbFlu);
if (nTor != 0)
trX = trX.concat(Object.keys(crbTor));
// this.debug("trX=" + trX);
trX.sort((a, b) => {
if (+a > +b) return 1;
if (+a < +b) return -1;
return 0;
});
// this.debug("trX tri=" + trX);
trX = trX.filter((elem, index, array) => {
if (index > 0)
return elem != array[index - 1];
return true;
});
// this.debug("trX unique=" + trX);

Grand Francois
committed
this.debug("abscisses ");
this.logArray(trX);

Grand Francois
committed
// Calcul de la variable à calculer
let tRes: number[] = [];
if (val_a_cal != undefined && nFlu != 0 && nTor != 0) {
for (let rX of trX) {
let rY = undefined;
if (crbFlu[+rX] != undefined && crbTor[+rX] == undefined) {
rY = crbFlu[+rX];
}
if (crbTor[+rX] != undefined) {
if (crbFlu[+rX] == undefined || (crbFlu[+rX] != undefined && crbFlu[+rX] == crbTor[+rX])) {
rY = crbTor[+rX];
}
if (rY != undefined)
tRes[+rX] = this.Sn.Calc(val_a_cal, rY);
}
}
}
return { "flu": crbFlu, "tor": crbTor, "trX": trX, "tRes": tRes };
}
}