diff --git a/spec/remous/remous_rect_euler_penteforte.spec.ts b/spec/remous/remous_rect_euler_penteforte.spec.ts index 5339ca9221eb43a92bbed58e5197076b9c0bfaaa..99b8ddd04218179860147c75b56ab881a1f4fd2a 100644 --- a/spec/remous/remous_rect_euler_penteforte.spec.ts +++ b/spec/remous/remous_rect_euler_penteforte.spec.ts @@ -22,7 +22,7 @@ import { precDist } from "../test_config"; describe("Class Remous / section rectangulaire :", () => { describe("méthode Euler explicite :", () => { // désactivé suite au changement de format de résultat - xit("forte pente, ressaut avant l'amont", () => { + it("forte pente, ressaut avant l'amont", () => { const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond 40, // Ks=Strickler @@ -83,7 +83,7 @@ describe("Class Remous / section rectangulaire :", () => { }); // désactivé suite au changement de format de résultat - xit("forte pente, ressaut après l'aval", () => { + it("forte pente, ressaut après l'aval", () => { // TODO algo à reprendre const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond @@ -286,7 +286,7 @@ describe("Class Remous / section rectangulaire :", () => { }); // désactivé suite au changement de format de résultat - xit("forte pente, pas de ressaut, Yaval < Yc, Yamont < Yn", () => { + it("forte pente, pas de ressaut, Yaval < Yc, Yamont < Yn", () => { const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond 40, // Ks=Strickler diff --git a/spec/remous/remous_rect_rk4_penteforte.spec.ts b/spec/remous/remous_rect_rk4_penteforte.spec.ts index 0ea5402aeea547cf210c29a11e69983330d9c365..619ff15ba312fdea1ad83f260b91dd7afa933f1a 100644 --- a/spec/remous/remous_rect_rk4_penteforte.spec.ts +++ b/spec/remous/remous_rect_rk4_penteforte.spec.ts @@ -24,7 +24,7 @@ import { precDist } from "../test_config"; describe("Class Remous / section rectangulaire :", () => { describe("méthode Runge-Kutta ordre 4 :", () => { // désactivé suite au changement de format de résultat - xit("forte pente, ressaut avant l'amont", () => { + it("forte pente, ressaut avant l'amont", () => { const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond 40, // Ks=Strickler @@ -85,7 +85,7 @@ describe("Class Remous / section rectangulaire :", () => { }); // désactivé suite au changement de format de résultat - xit("forte pente, ressaut après l'aval", () => { + it("forte pente, ressaut après l'aval", () => { // TODO algo à reprendre const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond @@ -282,7 +282,7 @@ describe("Class Remous / section rectangulaire :", () => { }); // désactivé suite au changement de format de résultat - xit("forte pente, pas de ressaut, Yaval < Yc, Yamont < Yn", () => { + it("forte pente, pas de ressaut, Yaval < Yc, Yamont < Yn", () => { const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond 40, // Ks=Strickler diff --git a/spec/remous/remous_rect_trapezes_pentefaible.spec.ts b/spec/remous/remous_rect_trapezes_pentefaible.spec.ts index 0e42fe7444063e0b7dfcadd54d8e00d051ce4655..11ef5943cec37654e81ae48c436782f7239b634b 100644 --- a/spec/remous/remous_rect_trapezes_pentefaible.spec.ts +++ b/spec/remous/remous_rect_trapezes_pentefaible.spec.ts @@ -399,7 +399,7 @@ describe("Class Remous / section rectangulaire :", () => { }); // désactivé suite au changement de format de résultat - xit("faible pente, pas de fluvial, torrentiel tronqué, calcul Hs", () => { + it("faible pente, pas de fluvial, torrentiel tronqué, calcul Hs", () => { const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond 40, // Ks=Strickler diff --git a/spec/remous/remous_rect_trapezes_penteforte.spec.ts b/spec/remous/remous_rect_trapezes_penteforte.spec.ts index b897a89dc3fb6da429a61daf066623bff9651e85..79e234d4be84c7b93e02c1650da0c4821907dcb3 100644 --- a/spec/remous/remous_rect_trapezes_penteforte.spec.ts +++ b/spec/remous/remous_rect_trapezes_penteforte.spec.ts @@ -24,7 +24,7 @@ import { precDist } from "../test_config"; describe("Class Remous / section rectangulaire :", () => { describe("méthode trapèzes :", () => { // désactivé suite au changement de format de résultat - xit("forte pente, ressaut avant l'amont", () => { + it("forte pente, ressaut avant l'amont", () => { const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond 40, // Ks=Strickler @@ -85,7 +85,7 @@ describe("Class Remous / section rectangulaire :", () => { }); // désactivé suite au changement de format de résultat - xit("forte pente, ressaut après l'aval", () => { + it("forte pente, ressaut après l'aval", () => { // TODO algo à reprendre const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond @@ -283,7 +283,7 @@ describe("Class Remous / section rectangulaire :", () => { }); // désactivé suite au changement de format de résultat - xit("forte pente, pas de ressaut, Yaval < Yc, Yamont < Yn", () => { + it("forte pente, pas de ressaut, Yaval < Yc, Yamont < Yn", () => { const prms = new ParamsSectionRectang(undefined, // tirant d'eau 2.5, // largeur de fond 40, // Ks=Strickler diff --git a/spec/remous/remous_trapez.spec.ts b/spec/remous/remous_trapez.spec.ts index be41cc116c24c69486b6ea012d2e239d3ce10136..b90111075b99454a0803cef8149d93d86a46d04d 100644 --- a/spec/remous/remous_trapez.spec.ts +++ b/spec/remous/remous_trapez.spec.ts @@ -1,8 +1,16 @@ +/** + * IMPORTANT ! + * Décommenter temporairement la ligne suivante (import { } from "./mock_jasmine") + * Pour exécuter ce code dans le débugger. + * Faire de même avec le fichier test_func.ts + */ +// import { describe, expect, it, xdescribe, xit } from "../mock_jasmine"; + import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous"; import { cSnTrapez, ParamsSectionTrapez } from "../../src/section/section_trapez"; import { cLog } from "../../src/util/log"; -import { equalEpsilon, compareExtraResult } from "../test_func"; import { precDist } from "../test_config"; +import { compareExtraResult, equalEpsilon } from "../test_func"; /* Certaines valeurs de ligne d'eau torrentielle étaient auparavant remplacées par une valeur fluviale @@ -13,7 +21,37 @@ import { precDist } from "../test_config"; describe("Class Remous / section trapèze :", () => { describe("méthode trapèzes :", () => { - xit("pente faible, ressaut dans le bief sur plusieurs points", () => { // désactivé car échoue depuis les modifs apportées depuis la version PHP (calcul du ressaut hydraulique) + xit("pente faible, fluvial hauteur normale, ", () => { + const prms = new ParamsSectionTrapez(2.5, // largeur de fond + 0.56, // fruit + undefined, // tirant d'eau + 40, // Ks=Strickler + 2, // Q=Débit + 0.001, // If=pente du fond + precDist, // précision + 1, // YB= hauteur de berge + ); + + const sect = new cSnTrapez(prms); + + const prem = new CourbeRemousParams(sect, 0.15, // Yamont = tirant amont + 0.803, // Yaval = tirant aval + 5, // Long= Longueur du bief + 5, // Dx=Pas d'espace + MethodeResolution.Trapezes, + ); + + const rem = new CourbeRemous(prem); + + const res = rem.calculRemous(undefined); + + const t = { 0: 0.15 }; + compareExtraResult("YTorrentiel", res, "tor", t, 0.001); + const f = { 5: 0.803 }; + compareExtraResult("Yfluvial", res, "flu", f, 0.001); + }); + xit("pente faible, ressaut dans le bief sur plusieurs points", () => { + // désactivé car échoue depuis les modifs apportées depuis la version PHP (calcul du ressaut hydraulique) const prms = new ParamsSectionTrapez(2.5, // largeur de fond 0.56, // fruit undefined, // tirant d'eau @@ -88,7 +126,7 @@ describe("Class Remous / section trapèze :", () => { describe("paramètre à calculer :", () => { // désactivé suite au changement de format de résultat - xit("Hs (test 1)", () => { + it("Hs (test 1)", () => { const prms = new ParamsSectionTrapez( 2.5, // largeur de fond 0.56, // fruit diff --git a/src/remous.ts b/src/remous.ts index d5ce39b99fb8f02c3129367766502faf33ae8621..45070fadac9e71a1cbec3912a644aa88c6b962da 100644 --- a/src/remous.ts +++ b/src/remous.ts @@ -105,6 +105,8 @@ export class CourbeRemous extends Nub { private _debugDicho: boolean = false; + private Dx: number; + /** * Journal de calcul */ @@ -119,78 +121,6 @@ export class CourbeRemous extends Nub { this.Sn.Calc("Yc"); } - /** - * Pas de discrétisation de l'espace (positif en partant de l'aval, négatif en partant de l'amont) - */ - private get Dx(): number { - return this.prms.Dx.v; - } - - /** - * calcul de la ligne fluviale depuis l'aval (si possible) - */ - private calculFluvial(xValues: ParamValues): ResultElement { - if (!this.Sn.HautCritique.ok) { - return new ResultElement(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE)); - } - - let res: ResultElement; - - // Calcul depuis l'aval - 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`); - res = this.calcul(this.prms.Yaval.v, xValues.getValuesIterator(true)); - 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)); - res = new ResultElement(); - res.addMessage(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL)); - } - - return res; - } - - /** - * calcul de la ligne torrentielle depuis l'amont (si possible) - */ - private calculTorrentiel(xValues: ParamValues): ResultElement { - if (!this.Sn.HautCritique.ok) { - return new ResultElement(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE)); - } - - let res: ResultElement; - - // Calcul depuis l'amont - 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"); - res = this.calcul(this.prms.Yamont.v, xValues.getValuesIterator(false)); - res.insertMessage(new Message(MessageCode.INFO_REMOUS_CALCUL_TORRENTIEL)); - } 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"); - res = new ResultElement(); - res.addMessage(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT)); - } - - return res; - } - /** * @param val_a_cal nom de la variable à calculer */ @@ -252,7 +182,7 @@ export class CourbeRemous extends Nub { // Calcul des courbes de remous const xValues = new ParamValues(); - xValues.setValues(0, this.prms.Long.v, this.Dx) + xValues.setValues(0, this.prms.Long.v, this.prms.Dx.v) // let crbFlu: { [key: number]: number; } = this.calculFluvial(); const rCourbeFlu: ResultElement = this.calculFluvial(xValues); @@ -541,22 +471,26 @@ export class CourbeRemous extends Nub { for (const x of trX) { let ligneDeau; - if (crbFlu[x] == undefined) + if (crbFlu[x] === undefined) { ligneDeau = crbTor[x]; - else if (crbTor[x] == undefined) + } else if (crbTor[x] === undefined) { ligneDeau = crbFlu[x]; - else + } else { ligneDeau = Math.max(crbFlu[x], crbTor[x]); + } const re = new ResultElement(ligneDeau); - if (crbFlu[x]) + if (crbFlu[x]) { re.addExtraResult("flu", crbFlu[x]); + } - if (crbTor[x]) + if (crbTor[x]) { re.addExtraResult("tor", crbTor[x]); + } - if (hasRes && tRes[x]) + if (hasRes && tRes[x]) { re.addExtraResult("tRes", tRes[x]); + } res.addResultElement(re); } @@ -611,6 +545,73 @@ export class CourbeRemous extends Nub { this.prms.map.Yaval.calculability = ParamCalculability.FREE; } + /** + * calcul de la ligne fluviale depuis l'aval (si possible) + */ + private calculFluvial(xValues: ParamValues): ResultElement { + if (!this.Sn.HautCritique.ok) { + return new ResultElement(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE)); + } + + let res: ResultElement; + + // Calcul depuis l'aval + 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, xValues.getValuesIterator(true)); + 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)); + res = new ResultElement(); + res.addMessage(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL)); + } + + return res; + } + + /** + * calcul de la ligne torrentielle depuis l'amont (si possible) + */ + private calculTorrentiel(xValues: ParamValues): ResultElement { + if (!this.Sn.HautCritique.ok) { + return new ResultElement(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE)); + } + + let res: ResultElement; + + // Calcul depuis l'amont + 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, xValues.getValuesIterator(false)); + res.insertMessage(new Message(MessageCode.INFO_REMOUS_CALCUL_TORRENTIEL)); + } 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"); + res = new ResultElement(); + res.addMessage(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT)); + } + + return res; + } + /** * Calcul de dy/dx (utilisé par Euler explicite et Runge-Kutta 4) * @param Y Tirant d'eau initial @@ -653,10 +654,6 @@ export class CourbeRemous extends Nub { // 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.WARNING_REMOUS_ARRET_CRITIQUE)); - } - return new Result(Y2); } @@ -759,10 +756,6 @@ export class CourbeRemous extends Nub { return r; } - if (XOR(this.Dx > 0, !(r.vCalc < this.Sn.HautCritique.vCalc))) { - return new Result(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE)); - } - // return new Result(Y2); return r; } @@ -775,20 +768,27 @@ export class CourbeRemous extends Nub { private Calc_Y(Y: number): Result { // let funcCalcY = 'Calc_Y_' + Resolution; // return this[funcCalcY](Y); + let res: Result; switch (this.prms.methodeResolution) { case MethodeResolution.Trapezes: - return this.Calc_Y_Trapez(Y); - + res = this.Calc_Y_Trapez(Y); + break; case MethodeResolution.RungeKutta4: - return this.Calc_Y_RK4(Y); - + res = this.Calc_Y_RK4(Y); + break; case MethodeResolution.EulerExplicite: - return this.Calc_Y_EulerExplicite(Y); + res = this.Calc_Y_EulerExplicite(Y); + break; + default: + throw new Error("CourbeRemous.Calc_Y() : type de méthode de résolution " + + MethodeResolution[this.prms.methodeResolution] + " non pris en charge"); + } - // default: - // throw new Error("CourbeRemous.Calc_Y() : type de méthode de résolution " + - // MethodeResolution[this.prms.methodeResolution] + " non pris en charge"; + if (!res.ok || XOR(this.Dx > 0, !(res.vCalc < this.Sn.HautCritique.vCalc))) { + return new Result(new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE)); } + + return res; } private size(o: {}): number {