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/spec/structure/parallel_structure.spec.ts b/spec/structure/parallel_structure.spec.ts index edacedeea591aec9ef2c5ffc20f7ec903afbfaba..1f2d7d9b9ccbbd7204fe4e28ee0774d245b85bb1 100644 --- a/spec/structure/parallel_structure.spec.ts +++ b/spec/structure/parallel_structure.spec.ts @@ -102,6 +102,16 @@ describe("Class ParallelStructure: ", () => { for (let i = 0; i < ps2.structures.length; i++) { const st: Structure = ps2.structures[i]; describe(`this.structures[${i}]: ${StructureType[iStTypes[i]]} Structure${LoiDebit[iLoiDebits[i]]}: `, () => { + // Tests sur les résultats complémentaires + it(`Calc(Q).extraResults[${i}.Q] should return ${ps2.structures[i].Calc("Q").vCalc}`, () => { + expect( + ps2.Calc("Q").extraResults[`${i}.Q`] + ).toBe( + ps2.structures[i].Calc("Q").vCalc + ); + }); + + // Tests de calcul des paramètres des ouvrages for (const prm of st.prms) { if ( prm.calculability === ParamCalculability.DICHO && @@ -121,7 +131,6 @@ describe("Class ParallelStructure: ", () => { prm.symbol === "ZDV" ) { // Les lois CEM88D et CUNGE80 ne font pas intervenir ZDV dans le calcul d'un orifice noyé - // TODO Il faudrait générer une erreur pour dire que le résultat est indéfini it(`Calc(${prm.symbol}) should return an error`, () => { expect( ps2.Calc(i + "." + prm.symbol).code diff --git a/spec/structure/structure_test.ts b/spec/structure/structure_test.ts index 8fefd6ab17b34b7dde4ccb2600391069ef63b5b1..6ff1af5f39e0eee3857d1fca6445608079c34e18 100644 --- a/spec/structure/structure_test.ts +++ b/spec/structure/structure_test.ts @@ -6,8 +6,9 @@ */ // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine"; +import { MessageCode } from "../../src"; import { ParamCalculability } from "../../src/param/param-definition"; -import { Structure, StructureParams, StructureFlowRegime, StructureFlowMode } from "../../src/structure/structure"; +import { Structure, StructureFlowMode, StructureFlowRegime, StructureParams } from "../../src/structure/structure"; import { Result } from "../../src/util/result"; import { checkResult } from "../test_func"; @@ -77,9 +78,10 @@ export function testStructure( const res: Result = st.Calc(prm.symbol); if (bNotZDV) { // Les lois CEM88D et CUNGE80 ne font pas intervenir ZDV dans le calcul d'un orifice noyé - // TODO Il faudrait générer une erreur pour dire que le résultat est indéfini - xit(`Calc(${prm.symbol}) should return undefined`, () => { - checkResult(res, undefined); + it(`Calc(${prm.symbol}) should return an error`, () => { + expect( + st.Calc(prm.symbol).code + ).toBe(MessageCode.ERROR_STRUCTURE_ZDV_PAS_CALCULABLE); }); } else { // On ne teste pas le calcul de l'ouverture sur les seuils 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 {