Newer
Older

Grand Francois
committed
import { ParamsSection, acSection } from "./section/section_type";
import { XOR, Result, round } from "./base";
import { ParamsEquation, ParamDefinition, ParamCalculability, ComputeNodeType, ParamDomainValue } from "./param";

Grand Francois
committed
import { Dichotomie } from "./dichotomie";
import { Nub } from "./nub";
import { Message, MessageCode } from "./util/message";
import { cLog } from "./util/log";

Grand Francois
committed
export enum MethodeResolution {
Trapezes, EulerExplicite, RungeKutta4
}
/**
* paramètres pour les courbes de remous
*/
export class CourbeRemousParams extends ParamsEquation {
/**
* section associée
*/
private _section: acSection;

Grand Francois
committed
/**
* Débit amont
*/
// private _Qamont: ParamDefinition;
/**
* Tirant imposé à l'amont
*/
private _Yamont: ParamDefinition;
/**
* Tirant imposé à l'aval
*/
private _Yaval: ParamDefinition;
/**
* Longueur du bief
*/
private _Long: ParamDefinition;
/**
* Pas de discrétisation de l'espace (positif en partant de l'aval, négatif en partant de l'amont)
*/
private _Dx: ParamDefinition;

Grand Francois
committed
/**
* Méthode de résolution de l'équation différentielle
*/
private _methodeResolution: MethodeResolution;
// constructor(rQamont: number, rYamont: number, rYAval: number, meth: MethodeResolution) {
constructor(s: acSection, rYamont: number, rYAval: number, rLong: number, rDx: number, meth: MethodeResolution) {
super();
this._section = s;
this._Yamont = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Yamont', ParamDomainValue.POS, rYamont);
this._Yaval = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Yaval', ParamDomainValue.POS, rYAval);
this._Long = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Long', ParamDomainValue.POS, rLong);
this._Dx = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Dx', ParamDomainValue.POS, rDx);

Grand Francois
committed
this._methodeResolution = meth;
this.addParamDefinition(this._Yamont);
this.addParamDefinition(this._Yaval);
this.addParamDefinition(this._Long);
this.addParamDefinition(this._Dx);
this.addParamDefinitions(this._section.prms);

Grand Francois
committed
}
get Sn() {
return this._section;
}

Grand Francois
committed
get Yamont() {
return this._Yamont;
}
get Yaval() {
return this._Yaval;
}
get Long() {
return this._Long;
}
get Dx(): ParamDefinition {
return this._Dx;
}

Grand Francois
committed
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;
private static DBG: boolean = false; /// Pour loguer les messages de debug de cette classe

Grand Francois
committed
/**
* Journal de calcul

Grand Francois
committed
*/
private _log: cLog;

Grand Francois
committed
private prmSect: ParamsSection;
/**
* Pas de discrétisation de l'espace (positif en partant de l'aval, négatif en partant de l'amont)
*/
private Dx: number;

Grand Francois
committed

Grand Francois
committed
constructor(crp: CourbeRemousParams) {
super(crp, CourbeRemous.DBG);

Grand Francois
committed
this._log = crp.Sn.log;
this.prmSect = crp.Sn.prms;

Grand Francois
committed
this.Sn.Calc("Yc");
}

Grand Francois
committed
public get log() {
return this._log;
}
private get Sn(): acSection {
return this.prms.Sn;
}
private get prms(): CourbeRemousParams {
return <CourbeRemousParams>this._prms;
}

Grand Francois
committed
protected setParametersCalculability() {
this.prms.map.Y.calculability = ParamCalculability.DICHO;
this.prms.Long.calculability = ParamCalculability.FREE;
this.prms.map.Dx.calculability = ParamCalculability.FREE;
this.prms.map.Yamont.calculability = ParamCalculability.FREE;
this.prms.map.Yaval.calculability = ParamCalculability.FREE;

Grand Francois
committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
}
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 Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE));

Grand Francois
committed
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 Message(MessageCode.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 Message(MessageCode.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 Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE));

Grand Francois
committed
//$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 Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE));

Grand Francois
committed
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
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 != MessageCode.ERROR_OK)

Grand Francois
committed
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 Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE));

Grand Francois
committed
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.prms.methodeResolution) {

Grand Francois
committed
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.prms.methodeResolution] + " non pris en charge";

Grand Francois
committed
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
}
}
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.prms.Long.v;

Grand Francois
committed
var Fin: number = 0;
}
else {
// Calcul depuis l'amont
Deb = 0;
Fin = this.prms.Long.v;

Grand Francois
committed
}
let dx = -this.Dx;

Grand Francois
committed
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 == MessageCode.ERROR_OK) {
// on vérifie qu'on ne traverse pas la hauteur normale (à la précision de calcul près)
let prec: number = this.prms.map.Prec.v;
let b1: boolean = lastY - this.Sn.HautNormale > prec;
let b2: boolean = rY.vCalc - this.Sn.HautNormale > prec;
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: Message = new Message(MessageCode.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 Message(MessageCode.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: Message = new Message(MessageCode.ERROR_REMOUS_LARGEUR_BERGE);
m.extraVar["B"] = this.Sn.Calc("B");
this._log.add(m);

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

Grand Francois
committed
m = new Message(MessageCode.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.prms.Yaval.v) {
this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_FLUVIAL));
this.debug("Condition limite aval (" + this.prms.Yaval.v + ") >= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie fluviale à partir de l'aval");
this.Dx = this.prms.Dx.v;
crbFlu = this.calcul(this.prms.Yaval.v);

Grand Francois
committed
}
else {
this.debug("Condition limite aval (" + this.prms.Yaval.v + ") < Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'aval");
this._log.add(new Message(MessageCode.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.prms.Yamont.v) {
this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_TORRENTIEL));
this.debug("Condition limite amont (" + this.prms.Yamont.v + ") <= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie torrentielle à partir de l'amont");
this.Dx = -this.prms.Dx.v;
crbTor = this.calcul(this.prms.Yamont.v);

Grand Francois
committed
}
else {
this._log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT));
this.debug("Condition limite amont (" + this.prms.Yamont.v + ") > Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'amont");

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

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

Grand Francois
committed
464
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
492
493
494
495
496
497
498
499
500
501
// 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
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.prms.Dx.v;

Grand Francois
committed
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 Message(MessageCode.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
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
// 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 Message(MessageCode.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;
let hasFlu: boolean = crbFlu[+rX] != undefined;
let hasTor: boolean = crbTor[+rX] != undefined;

Grand Francois
committed
if (hasFlu && !hasTor)

Grand Francois
committed
rY = crbFlu[+rX];
if (hasTor)
if (!hasFlu || (hasFlu && crbFlu[+rX] == crbTor[+rX]))

Grand Francois
committed
rY = crbTor[+rX];
if (rY != undefined) {
tRes[+rX] = this.Sn.Calc(val_a_cal, rY);
this.debug('X=' + rX + ' Calc(' + val_a_cal + ', Y=' + rY + ')=' + tRes[+rX]);

Grand Francois
committed
}
}
this.debug("extra param " + val_a_cal);
this.logObject(tRes);

Grand Francois
committed
}
return { "flu": crbFlu, "tor": crbTor, "trX": trX, "tRes": tRes };
}
}