diff --git a/src/remous.ts b/src/remous.ts index ff305273c1259a3c3a02145ae9c5161cb943e736..555896085ba03f813b0e4fa977f9a8d9d68be6a6 100644 --- a/src/remous.ts +++ b/src/remous.ts @@ -1,6 +1,6 @@ import { ParamsSection, acSection } from "./section/section_type"; import { XOR, round } from "./base"; -import { Result } from "./util/result"; +import { Result, CalcResult } from "./util/result"; import { ParamsEquation, ParamDefinition, ParamCalculability, ComputeNodeType, ParamDomainValue } from "./param"; import { Dichotomie } from "./dichotomie"; import { Nub } from "./nub"; @@ -104,7 +104,7 @@ export class CourbeRemous extends Nub { /** * Journal de calcul */ - private _log: cLog; + //private _log: cLog; private prmSect: ParamsSection; @@ -115,14 +115,14 @@ export class CourbeRemous extends Nub { constructor(crp: CourbeRemousParams, dbg: boolean = false) { super(crp, dbg); - this._log = crp.Sn.log; + // this._log = crp.Sn.log; this.prmSect = crp.Sn.prms; this.Sn.Calc("Yc"); } - public get log() { - return this._log; - } + // public get log() { + // return this._log; + // } private get Sn(): acSection { return this.prms.Sn; @@ -143,9 +143,19 @@ export class CourbeRemous extends Nub { 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; + + // let res: number = this.Sn.Calc('Hs') - this.Sn.Calc('J') / 2 * this.Dx; + + const rHS = this.Sn.Calc('Hs'); + if (!rHS.ok) + return rHS; + + const rJ = this.Sn.Calc('J'); + if (!rJ.ok) + return rJ; + + const res: number = rHS.vCalc - rJ.vCalc / 2 * this.Dx; return new Result(res); } @@ -156,9 +166,20 @@ export class CourbeRemous extends Nub { * Calcul de dy/dx (utilisé par Euler explicite et Runge-Kutta 4) * @param Y Tirant d'eau initial */ - private Calc_dYdX(Y: number): number { + private Calc_dYdX(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 - return - (this.prmSect.If.v - this.Sn.Calc('J', Y)) / (1 - Math.pow(this.Sn.Calc('Fr', Y), 2)); + // return - (this.prmSect.If.v - this.Sn.Calc('J', Y)) / (1 - Math.pow(this.Sn.Calc('Fr', Y), 2)); + + const rJ = this.Sn.Calc('J', Y); + if (!rJ.ok) + return rJ; + + const rFR = this.Sn.Calc('Fr', Y); + if (!rFR.ok) + return rFR; + + const v = - (this.prmSect.If.v - rJ.vCalc) / (1 - Math.pow(rFR.vCalc, 2)); + return new Result(v); } /** @@ -167,9 +188,19 @@ export class CourbeRemous extends Nub { * @return Tirant d'eau */ private Calc_Y_EulerExplicite(Y: number): Result { + if (!this.Sn.HautCritique.ok) + return new Result(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); + // 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))) { + + const rDXDY = this.Calc_dYdX(Y); + if (!rDXDY.ok) + return rDXDY; + + // let Y2 = Y + this.Dx * this.Calc_dYdX(Y); + const Y2 = Y + this.Dx * rDXDY.vCalc; + + if (XOR(this.Dx > 0, !(Y2 < this.Sn.HautCritique.vCalc))) { return new Result(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); } @@ -182,39 +213,50 @@ export class CourbeRemous extends Nub { * @return Tirant d'eau */ private Calc_Y_RK4(Y: number): Result { + if (!this.Sn.HautCritique.ok) + return new Result(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); + // 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; + // let k1 = this.Calc_dYdX(Y); + const rDXDY: Result = this.Calc_dYdX(Y); + if (!rDXDY.ok) + return rDXDY; + const k1 = rDXDY.vCalc; + + let hc = this.Sn.HautCritique.vCalc; - //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(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); } - //$rk2 = $this ->Calc_dYdX($Y + $rDx / 2 * $rk1); - let k2 = this.Calc_dYdX(Y + Dx / 2 * k1); + // let k2 = this.Calc_dYdX(Y + Dx / 2 * k1); + const rDXDY2: Result = this.Calc_dYdX(Y + Dx / 2 * k1); + if (!rDXDY2.ok) + return rDXDY2; + const k2 = rDXDY2.vCalc; - //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(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); } - //$rk3 = $this ->Calc_dYdX($Y + $rDx / 2 * $rk2); - let k3 = this.Calc_dYdX(Y + Dx / 2 * k2); + // let k3 = this.Calc_dYdX(Y + Dx / 2 * k2); + const rDXDY3: Result = this.Calc_dYdX(Y + Dx / 2 * k2); + if (!rDXDY3.ok) + return rDXDY3; + const k3 = rDXDY3.vCalc; - //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(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); } - //$rk4 = $this ->Calc_dYdX($Y + $rDx * $rk3); - let k4 = this.Calc_dYdX(Y + Dx * k3); + // let k4 = this.Calc_dYdX(Y + Dx * k3); + const rDXDY4: Result = this.Calc_dYdX(Y + Dx * k3); + if (!rDXDY4.ok) + return rDXDY4; + const k4 = rDXDY4.vCalc; - //$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; } @@ -239,37 +281,36 @@ export class CourbeRemous extends Nub { * @return Tirant d'eau */ private Calc_Y_Trapez(Y: number): Result { - //include_spip('hyd_inc/dichotomie.class'); - //$this ->VarCal = &$Y; - // this.VarCal = Y; + if (!this.Sn.HautCritique.ok) + return new Result(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); - // $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 + // let Trapez_Fn = this.Sn.Calc('Hs', Y) + this.Sn.Calc('J', Y) / 2 * this.Dx + const rHS: Result = this.Sn.Calc('Hs', Y); + if (!rHS.ok) + return rHS; + + const rJ: Result = this.Sn.Calc('J', Y) + if (!rJ.ok) + return rJ; + + let Trapez_Fn = rHS.vCalc + rJ.vCalc / 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.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))) { + if (XOR(this.Dx > 0, !(r.vCalc < this.Sn.HautCritique.vCalc))) { return new Result(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); } - return new Result(Y2); + // return new Result(Y2); + return r; } /** @@ -317,8 +358,11 @@ export class CourbeRemous extends Nub { * 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 } { + private calcul(YCL: number): Result + // { [key: number]: number } + { let trY: { [key: number]: number; } = {}; + const res = new Result(undefined); if (this.Dx > 0) { // Calcul depuis l'aval @@ -354,21 +398,25 @@ export class CourbeRemous extends Nub { let m: Message = new Message(MessageCode.ERROR_REMOUS_PENTE_FORTE); m.extraVar["x"] = x; - this._log.add(m); + // this._log.add(m); + res.addMessage(m); } 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); + // this._log.add(m); + res.addMessage(m); this.debug("Arrêt du calcul : Hauteur critique atteinte à l'abscisse " + x + " m"); break; } lastY = rY.vCalc; } - return trY; + //return trY; + res.addExtraResult("trY", trY); + return res; } private logArray(a: string[]) { @@ -402,20 +450,26 @@ export class CourbeRemous extends Nub { /** * calcul de la ligne fluviale depuis l'aval (si possible) */ - public calculFluvial() { - let res: { [key: number]: number; } = {}; + public calculFluvial(): Result { + if (!this.Sn.HautCritique.ok) + return new Result(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); + + // let res: { [key: number]: number; } = {}; // Calcul depuis l'aval - if (this.Sn.HautCritique <= this.prms.Yaval.v) { - this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_FLUVIAL)); + if (this.Sn.HautCritique.vCalc <= 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; - res = this.calcul(this.prms.Yaval.v); + var res = this.calcul(this.prms.Yaval.v); + res.insertMessage(new Message(MessageCode.INFO_REMOUS_CALCUL_FLUVIAL)); } 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)); + // this._log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL)); + res = new Result(undefined); + res.addMessage(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL)); } return res; @@ -424,20 +478,26 @@ export class CourbeRemous extends Nub { /** * calcul de la ligne torrentielle depuis l'amont (si possible) */ - public calculTorrentiel() { - let res: { [key: number]: number; } = {}; + public calculTorrentiel(): Result { + if (!this.Sn.HautCritique.ok) + return new Result(new Message(MessageCode.ERROR_REMOUS_ARRET_CRITIQUE)); + + // let res: { [key: number]: number; } = {}; // Calcul depuis l'amont - if (this.Sn.HautCritique >= this.prms.Yamont.v) { - this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_TORRENTIEL)); + if (this.Sn.HautCritique.vCalc >= 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; - res = this.calcul(this.prms.Yamont.v); + var res = this.calcul(this.prms.Yamont.v); + res.insertMessage(new Message(MessageCode.INFO_REMOUS_CALCUL_TORRENTIEL)); } else { - this._log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT)); + // 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"); + res = new Result(undefined); + res.addMessage(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT)); } return res; @@ -446,35 +506,83 @@ export class CourbeRemous extends Nub { /** * @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": { [key: number]: number } - } { - let Yc: number = this.Sn.Calc("Yc"); - - let m: Message = new Message(MessageCode.ERROR_REMOUS_LARGEUR_BERGE); - m.extraVar["B"] = this.Sn.Calc("B", this.Sn.prms.YB.v); - this._log.add(m); - - m = new Message(MessageCode.ERROR_REMOUS_H_CRITIQUE); + public calculRemous(val_a_cal: string): + // { + // "flu": { [key: number]: number; }, + // "tor": { [key: number]: number; }, + // "trX": string[], + // "tRes": { [key: number]: number } + // } + CalcResult { + const res = new CalcResult(undefined); + + // let Yc: number = this.Sn.Calc("Yc"); + const rYC = this.Sn.Calc("Yc"); + if (!rYC.ok) { + res.addResult(rYC); + return res; + } + const Yc: number = rYC.vCalc; + + const rB: Result = this.Sn.Calc("B", this.Sn.prms.YB.v) + if (!rB.ok) { + res.addResult(rB); + return res; + } + + let m: Message = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE); + // m.extraVar["B"] = this.Sn.Calc("B", this.Sn.prms.YB.v); + m.extraVar["B"] = rB.vCalc; + // this._log.add(m); + res.addMessage(m); + + m = new Message(MessageCode.INFO_REMOUS_H_CRITIQUE); m.extraVar["Yc"] = Yc; - this._log.add(m); + // this._log.add(m); + res.addMessage(m); + + const rYN = this.Sn.Calc("Yn"); + if (!rYN.ok) { + res.addLog(rYN.log); + return res; + } - let Yn = this.Sn.Calc("Yn"); - m = new Message(MessageCode.ERROR_REMOUS_H_NORMALE); + const Yn = rYN.vCalc; + m = new Message(MessageCode.INFO_REMOUS_H_NORMALE); m.extraVar["Yn"] = Yn; - this._log.add(m); + // this._log.add(m); + res.addMessage(m); - this.debug("largeur berge " + this.Sn.Calc("B")); + // this.debug("largeur berge " + this.Sn.Calc("B")); + const rB2: Result = this.Sn.Calc("B") + this.debug("largeur berge " + rB2.vCalc); this.debug("hauteur critique " + Yc); - this.Sn.HautNormale = this.Sn.Calc("Yn"); - this.debug("hauteur normale " + this.Sn.HautNormale); + // this.Sn.HautNormale = this.Sn.Calc("Yn"); + // this.debug("hauteur normale " + this.Sn.HautNormale); + this.debug("hauteur normale " + Yn); // Calcul des courbes de remous - let crbFlu: { [key: number]: number; } = this.calculFluvial(); - let crbTor: { [key: number]: number; } = this.calculTorrentiel(); + + // let crbFlu: { [key: number]: number; } = this.calculFluvial(); + let rCourbeFlu: Result = this.calculFluvial(); + // if (!rCourbeFlu.ok) { + res.addLog(rCourbeFlu.log); + // return res; + // } + + // let crbTor: { [key: number]: number; } = this.calculTorrentiel(); + let rCourbeTor: Result = this.calculTorrentiel(); + // if (!rCourbeTor.ok) { + res.addLog(rCourbeTor.log); + // return res; + // } + + let crbFlu = rCourbeFlu.getExtraResult("trY"); + if (crbFlu == undefined) + crbFlu = {}; + let crbTor = rCourbeTor.getExtraResult("trY"); + if (crbTor == undefined) + crbTor = {}; //this.debug("HautCritique ", this.Sn.HautCritique); @@ -497,8 +605,8 @@ export class CourbeRemous extends Nub { } // Détection du ressaut hydraulique - let nFlu: number = this.size(crbFlu); - let nTor: number = this.size(crbTor); + const nFlu: number = this.size(crbFlu); + const nTor: number = this.size(crbTor); if (nFlu != 0 && nTor != 0) { let firstYFlu = crbFlu[0]; let lastYTor = this.last(crbTor); @@ -554,7 +662,7 @@ export class CourbeRemous extends Nub { // this.debug(trX); let bRessaut = false; - let Dx = this.prms.Dx.v; + const Dx = this.prms.Dx.v; for (let irX = 0; irX < trX.length; irX++) { let rX: number = +trX[irX]; @@ -563,10 +671,15 @@ export class CourbeRemous extends Nub { // this.debug("partielle[" + rX + "]=" + crbPartielle[rX]); // Calcul de l'abscisse de la section dans l'autre régime - let Yco = this.Sn.Calc('Yco', crbPartielle[rX]); // Y conjugué + const rYCO = this.Sn.Calc('Yco', crbPartielle[rX]); // Y conjugué + if (!rYCO.ok) { + res.addLog(rYCO.log); + return res; + } + const Yco = rYCO.vCalc; // this.debug("rX=" + rX + " Yco(Ypartiel=" + crbPartielle[rX] + ")=" + Yco); - let rLongRst = 5 * Math.abs(crbPartielle[rX] - Yco); // Longueur du ressaut + const rLongRst = 5 * Math.abs(crbPartielle[rX] - Yco); // Longueur du ressaut // this.debug("longueur ressaut=" + rLongRst); let xRst = rX + Math.round(iSens * rLongRst / Dx) * Dx; // Abscisse où comparer Yconj et Y @@ -579,6 +692,10 @@ export class CourbeRemous extends Nub { let impYpartielle = this.Sn.Calc('Imp', crbPartielle[rX]); // this.debug("imp(Ypartiel[rX=" + rX + "]=" + crbPartielle[rX] + ")=" + impYpartielle); + if (!impYpartielle.ok) { + res.addLog(impYpartielle.log); + return res; + } if (crbComplete[xRst] != undefined) { // Hauteur décalée de la longueur du ressaut (il faut gérer la pente du fond) @@ -586,13 +703,18 @@ export class CourbeRemous extends Nub { // this.debug("Ydec=" + Ydec); let impYcomplete = this.Sn.Calc('Imp', crbComplete[xRst]); // this.debug("imp(Ycomplet[xRst=" + xRst + "]=" + crbComplete[xRst] + ")=" + impYcomplete); + if (!impYcomplete.ok) { + res.addLog(impYcomplete.log); + return res; + } - if (impYpartielle > impYcomplete) { + if (impYpartielle.vCalc > impYcomplete.vCalc) { 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 = new Message(MessageCode.INFO_REMOUS_RESSAUT_HYDRO); m.extraVar["xmin"] = Math.min(rX, xRst); m.extraVar["xmax"] = Math.max(rX, xRst); - this._log.add(m); + // this._log.add(m); + res.addMessage(m); // this.debug("rX=" + rX + " xRst=" + xRst); // Modification de la ligne d'eau complète @@ -621,10 +743,11 @@ export class CourbeRemous extends Nub { } if (!bRessaut) { // Le ressaut est en dehors du canal - let m = new Message(MessageCode.ERROR_REMOUS_RESSAUT_DEHORS); + let m = new Message(MessageCode.INFO_REMOUS_RESSAUT_DEHORS); m.extraVar["sens"] = sSens; m.extraVar["x"] = +this.last(trX); - this._log.add(m); + // this._log.add(m); + res.addMessage(m); this.debug("Ressaut hydraulique détecté à l'" + sSens + " de l'abscisse " + this.last(trX)); if (iSens == 1) @@ -685,7 +808,13 @@ export class CourbeRemous extends Nub { rY = crbTor[+rX]; if (rY != undefined) { - tRes[+rX] = this.Sn.Calc(val_a_cal, rY); + // tRes[+rX] = this.Sn.Calc(val_a_cal, rY); + const rVar = this.Sn.Calc(val_a_cal, rY); + if (!rVar.ok) { + res.addLog(rVar.log); + return res; + } + tRes[+rX] = rVar.vCalc; this.debug('X=' + rX + ' Calc(' + val_a_cal + ', Y=' + rY + ')=' + tRes[+rX]); } } @@ -694,6 +823,23 @@ export class CourbeRemous extends Nub { this.logObject(tRes); } - return { "flu": crbFlu, "tor": crbTor, "trX": trX, "tRes": tRes }; + //return { "flu": crbFlu, "tor": crbTor, "trX": trX, "tRes": tRes }; + const rFlu = new Result(undefined); + rFlu.addExtraResult("flu", crbFlu); + res.addResult(rFlu); + + const rTor = new Result(undefined); + rTor.addExtraResult("tor", crbTor); + res.addResult(rTor); + + const rX = new Result(undefined); + rX.addExtraResult("trX", trX); + res.addResult(rX); + + const rVar = new Result(undefined); + rVar.addExtraResult("tRes", tRes); + res.addResult(rVar); + + return res; } }