diff --git a/spec/mock_jasmine.ts b/spec/mock_jasmine.ts index e3a0c3fa63e86f26d9002005bafe80c062d401c8..a3b051f89f5169b67274347206e00962a5a5be4f 100644 --- a/spec/mock_jasmine.ts +++ b/spec/mock_jasmine.ts @@ -39,9 +39,9 @@ export function xit(sTxt: string, fFun: () => void) { export function fail(m?: string) { let s = "Test failed"; - if (m !== undefined) + if (m !== undefined) { s += ` (${m})`; - + } console.error(s); } diff --git a/spec/pab/pab_puissance.spec.ts b/spec/pab/pab_puissance.spec.ts index a8856b4b4caf71ab6c5ae604efea3a5b06da474d..4064654d18ac0f9522d8868490d3119fe9542bee 100644 --- a/spec/pab/pab_puissance.spec.ts +++ b/spec/pab/pab_puissance.spec.ts @@ -12,7 +12,7 @@ function PabPuissanceTest(varTest: string) { 0.3, // Chute entre bassins DH (m) 0.1, // Débit Q (m3/s) 0.5, // Volume V (m3) - 588.6 // Puissance dissipée Pv (W/m3) + 588.6 // Puissance dissipée PV (W/m3) ); let res: number = prms[varTest].v; @@ -33,5 +33,5 @@ describe("Class PabPuissance: ", () => { PabPuissanceTest("DH"); PabPuissanceTest("Q"); PabPuissanceTest("V"); - PabPuissanceTest("Pv"); + PabPuissanceTest("PV"); }); diff --git a/spec/structure/cloisons.spec.ts b/spec/structure/cloisons.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..a57206b8fbc4ec5993838ea071fab504b760a003 --- /dev/null +++ b/spec/structure/cloisons.spec.ts @@ -0,0 +1,89 @@ +/** + * 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 { Cloisons, CloisonsParams } from "../../src/structure/cloisons"; +import { CreateStructure } from "../../src/structure/factory_structure"; +import { StructureKiviParams } from "../../src/structure/structure_kivi"; +import { LoiDebit, StructureType } from "../../src/structure/structure_props"; +// tslint:disable-next-line:max-line-length +import { RectangularStructureParams, StructureWeirSubmergedLarinier } from "../../src/structure/structure_weir_submerged_larinier"; +import { testParallelStructures } from "./functions"; + +const cloisons: Cloisons = new Cloisons( + new CloisonsParams( + 0, // Débit total (m3/s) + 102, // Cote de l'eau amont (m) + 10, // Longueur des bassins (m) + 1, // Largeur des bassins (m) + 1, // Profondeur moyenne (m) + 0.5 // Hauteur de chute (m) + ), + false // debug +); + +const fente: StructureWeirSubmergedLarinier = new StructureWeirSubmergedLarinier( + new RectangularStructureParams( + 0, + 101, + 102, + 101.5, + 0.2, + 0.65 + ) +); + +cloisons.addStructure(fente); + +describe("Class Cloisons: ", () => { + describe("Calc(Q) Fente noyée (Larinier 1992)", () => { + it("vCalc should return 0.407", () => { + expect(cloisons.Calc("Q").vCalc).toBeCloseTo(0.407, 3); + }); + it("extraResults.PV should return 199.7", () => { + expect(cloisons.Calc("Q").extraResults.PV).toBeCloseTo(199.7, 1); + }); + }); + + const c2: Cloisons = new Cloisons( + new CloisonsParams( + 0, // Débit total (m3/s) + 102, // Cote de l'eau amont (m) + 10, // Longueur des bassins (m) + 1, // Largeur des bassins (m) + 1, // Profondeur moyenne (m) + 0.5 // Hauteur de chute (m) + ), + false // debug + ); + + // Ajout d'une structure de chaque type dans Cloisons + const iStTypes: StructureType[] = [ + StructureType.Orifice, + StructureType.SeuilRectangulaire, + StructureType.SeuilRectangulaire + ]; + const iLoiDebits: LoiDebit[] = [ + LoiDebit.OrificeSubmerged, + LoiDebit.WeirSubmergedLarinier, + LoiDebit.KIVI + ]; + for (let i = 0; i < 3; i++ ) { + c2.addStructure(CreateStructure(iStTypes[i], iLoiDebits[i], false)); + } + const prmsKivi: StructureKiviParams = c2.structures[2].prms as StructureKiviParams; + prmsKivi.ZRAM.v = 0; + + testParallelStructures(c2, iStTypes, iLoiDebits); + + describe("Calcul de ZRAM de l'équation KIVI", () => { + it("ZRAM should be 101", () => { + c2.Calc("Q"); + expect(prmsKivi.ZRAM.v).toBeCloseTo(101, 3); + }); + }); +}); diff --git a/spec/structure/dever.spec.ts b/spec/structure/dever.spec.ts index dc43499aa55727f4983a572c5ddb9b34ab4c8bec..f93eea1866868bd04ae4506ced6b6487fec0aa05 100644 --- a/spec/structure/dever.spec.ts +++ b/spec/structure/dever.spec.ts @@ -9,7 +9,6 @@ import { Dever, DeverParams } from "../../src/structure/dever"; import { CreateStructure } from "../../src/structure/factory_structure"; import { LoiDebit, StructureType } from "../../src/structure/structure_props"; -import { Result } from "../../src/util/result"; const dever: Dever = new Dever( new DeverParams( diff --git a/spec/structure/functions.ts b/spec/structure/functions.ts index 853eecc881d2d7c2c0664b6683830320e41f99d9..800641dcb128957b41bf0f1704c9369e5d651c83 100644 --- a/spec/structure/functions.ts +++ b/spec/structure/functions.ts @@ -5,11 +5,15 @@ */ // import { describe, expect, it, xdescribe } from "../mock_jasmine"; -import { Structure } from "../../src/structure/structure"; -import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure"; +import { MessageCode } from "../../src"; +import { ParamCalculability } from "../../src/param/param-definition"; +import { ParallelStructure } from "../../src/structure/parallel_structure"; +import { Structure, StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure"; +import { LoiDebit, StructureType } from "../../src/structure/structure_props"; import { Describer } from "../../src/util/describer"; import { Result } from "../../src/util/result"; import { precDigits } from "../test_config"; +import { checkResult } from "../test_func"; export function itCalcQ( struct: Structure, Z1: number, W: number, Q: number, @@ -38,3 +42,114 @@ export function itCalcQ( }); } } + +/** + * Test de calcul de tous les paramètres d'une loi de débit + * @param st Structure à tester + * @param mode Mode d'écoulement + * @param regime Régime d'écoulement + * @param bNotZDV Loi de débit ne permettant pas de calculer ZDV + */ +export function testStructure( + st: Structure, + mode: StructureFlowMode, + regime: StructureFlowRegime, + bNotZDV: boolean = false +) { + for (const prm of st.prms) { + if ([ParamCalculability.DICHO, ParamCalculability.EQUATION].includes(prm.calculability)) { + if (prm.symbol === "W" && prm.v === Infinity) { + // Le calcul de l'ouverture sur les seuils doit renvoyer une exception (cas impossible) + it(`Calc(${prm.symbol}) should return exception`, () => { + expect( + () => { st.Calc(prm.symbol); } + ).toThrow(new Error("Structure:Calc : Calcul de W impossible sur un seuil")); + }); + } else { + const ref: number = prm.v; + 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é + 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 + it(`Calc(${prm.symbol}) should return ${ref}`, () => { + checkResult(res, ref); + }); + } + prm.v = ref; // Go back to initial value for following tests + } + } + } +} + +/** + * Test d'ouvrages en parallèle : calcul des débits individuels et test de tous les paramètres + * @param oPS objet ParallelStructure à tester + * @param iStTypes Liste ordonnée des types des ouvrages à tester + * @param iLoiDebits Liste ordonnée des lois de débit à tester + */ +export function testParallelStructures(oPS: ParallelStructure, iStTypes: number[], iLoiDebits: number[]) { + oPS.prms.Q.v = oPS.Calc("Q").vCalc; + + for (let i = 0; i < oPS.structures.length; i++) { + const st: Structure = oPS.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 ${oPS.structures[i].Calc("Q").vCalc}`, () => { + expect( + oPS.Calc("Q").extraResults[`ouvrage[${i}].Q`] + ).toBe( + oPS.structures[i].Calc("Q").vCalc + ); + }); + + // Tests de calcul des paramètres des ouvrages + for (const prm of st.prms) { + if ( + prm.calculability === ParamCalculability.DICHO && + prm.symbol !== "Z1" && prm.symbol !== "Z2" + ) { + const ref: number = prm.v; + if (prm.symbol === "W" && prm.v === Infinity) { + // Le calcul de l'ouverture sur les seuils doit renvoyer une exception (cas impossible) + it(`Calc(${prm.symbol}) should return exception`, () => { + expect( + () => { oPS.Calc(i + "." + prm.symbol); } + ).toThrow(new Error("Structure:Calc : Calcul de W impossible sur un seuil")); + }); + } else if ( + iStTypes[i] === StructureType.VanneRectangulaire && + !oPS.structures[i].isZDVcalculable && + prm.symbol === "ZDV" + ) { + // Les lois CEM88D et CUNGE80 ne font pas intervenir ZDV dans le calcul d'un orifice noyé + it(`Calc(${prm.symbol}) should return an error`, () => { + expect( + oPS.Calc(i + "." + prm.symbol).code + ).toBe(MessageCode.ERROR_STRUCTURE_ZDV_PAS_CALCULABLE); + }); + } else if ( + iLoiDebits[i] === LoiDebit.TriangularWeirFree && + prm.symbol === "alpha2" + ) { + // Le calcul de l'angle de l'équation triangulaire n'est pas assez précis + it(`Calc(${prm.symbol}) should return ${ref}`, () => { + checkResult(oPS.Calc(i + "." + prm.symbol), ref, 1); + }); + } else { + // Cas normal : On teste la valeur calculée + it(`Calc(${prm.symbol}) should return ${ref}`, () => { + checkResult(oPS.Calc(i + "." + prm.symbol), ref); + }); + } + prm.v = ref; // Go back to initial value for following tests + } + } + }); + } +} diff --git a/spec/structure/parallel_structure.spec.ts b/spec/structure/parallel_structure.spec.ts index d7bf22a27ade7686274e5996f6a318bc23386497..087c7f250767e1cc2d737dc36fa82b6c2696fd18 100644 --- a/spec/structure/parallel_structure.spec.ts +++ b/spec/structure/parallel_structure.spec.ts @@ -6,17 +6,15 @@ */ // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine"; -import { ParamCalculability } from "../../src/param/param-definition"; import { CreateStructure } from "../../src/structure/factory_structure"; import { ParallelStructure } from "../../src/structure/parallel_structure"; import { ParallelStructureParams } from "../../src/structure/parallel_structure_params"; -import { Structure } from "../../src/structure/structure"; -import { loiAdmissibles, LoiDebit, StructureType } from "../../src/structure/structure_props"; +import { loiAdmissibles, StructureType } from "../../src/structure/structure_props"; import { EnumEx } from "../../src/util/enum"; -import { MessageCode } from "../../src/util/message"; import { Result } from "../../src/util/result"; import { precDigits } from "../test_config"; import { checkResult } from "../test_func"; +import { testParallelStructures } from "./functions"; import { structTest } from "./structure_test"; const pstruct: ParallelStructure = new ParallelStructure( @@ -94,63 +92,5 @@ describe("Class ParallelStructure: ", () => { iStTypes.push(s); } } - - ps2.prms.Q.v = ps2.Calc("Q").vCalc; - - 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[`ouvrage[${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 && - prm.symbol !== "Z1" && prm.symbol !== "Z2" - ) { - const ref: number = prm.v; - if (prm.symbol === "W" && prm.v === Infinity) { - // Le calcul de l'ouverture sur les seuils doit renvoyer une exception (cas impossible) - it(`Calc(${prm.symbol}) should return exception`, () => { - expect( - () => { ps2.Calc(i + "." + prm.symbol); } - ).toThrow(new Error("Structure:Calc : Calcul de W impossible sur un seuil")); - }); - } else if ( - iStTypes[i] === StructureType.VanneRectangulaire && - !ps2.structures[i].isZDVcalculable && - prm.symbol === "ZDV" - ) { - // Les lois CEM88D et CUNGE80 ne font pas intervenir ZDV dans le calcul d'un orifice noyé - it(`Calc(${prm.symbol}) should return an error`, () => { - expect( - ps2.Calc(i + "." + prm.symbol).code - ).toBe(MessageCode.ERROR_STRUCTURE_ZDV_PAS_CALCULABLE); - }); - } else if ( - iLoiDebits[i] === LoiDebit.TriangularWeirFree && - prm.symbol === "alpha2" - ) { - // Le calcul de l'angle de l'équation triangulaire n'est pas assez précis - it(`Calc(${prm.symbol}) should return ${ref}`, () => { - checkResult(ps2.Calc(i + "." + prm.symbol), ref, 1); - }); - } else { - // Cas normal : On teste la valeur calculée - it(`Calc(${prm.symbol}) should return ${ref}`, () => { - checkResult(ps2.Calc(i + "." + prm.symbol), ref); - }); - } - prm.v = ref; // Go back to initial value for following tests - } - } - }); - } + testParallelStructures(ps2, iStTypes, iLoiDebits); }); diff --git a/spec/structure/structure_kivi.spec.ts b/spec/structure/structure_kivi.spec.ts index d0700be77cbc097c6ecee5709196544fddb8e800..a4fb71297aca20d60c81674b0c01557fa20aaf13 100644 --- a/spec/structure/structure_kivi.spec.ts +++ b/spec/structure/structure_kivi.spec.ts @@ -10,11 +10,12 @@ import { MessageCode, StructureFlowMode, StructureFlowRegime } from "../../src"; import { CreateStructure } from "../../src/structure/factory_structure"; import { StructureKivi } from "../../src/structure/structure_kivi"; import { LoiDebit, StructureType } from "../../src/structure/structure_props"; -import { testStructure } from "./structure_test"; +import { testStructure } from "./functions"; const structTest: StructureKivi = CreateStructure( StructureType.SeuilRectangulaire, LoiDebit.KIVI ) as StructureKivi; +structTest.prms.ZDV.v = 101; describe("Class StructureKivi: ", () => { describe("Ecoulement noyé", () => { diff --git a/spec/structure/structure_orifice_submerged.spec.ts b/spec/structure/structure_orifice_submerged.spec.ts index d303605c006e0280ac1e8ad7acef8e8959e365a1..2eaf38fa6c221a727a94403c9e0c8ae65e2f8492 100644 --- a/spec/structure/structure_orifice_submerged.spec.ts +++ b/spec/structure/structure_orifice_submerged.spec.ts @@ -2,56 +2,26 @@ * 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 rectangular_structure.ts + * Faire de même avec le fichier ../structure/functions.ts */ // import { describe, expect, it, xdescribe } from "../mock_jasmine"; -import { RectangularStructureParams } from "../../src/structure/rectangular_structure_params"; import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure"; -import { StructureOrificeSubmerged } from "../../src/structure/structure_orifice_submerged"; -import { Result } from "../../src/util/result"; -import { itCalcQ } from "./functions"; +// tslint:disable-next-line:max-line-length +import { StructureOrificeSubmerged, StructureOrificeSubmergedParams } from "../../src/structure/structure_orifice_submerged"; +import { itCalcQ } from "../structure/functions"; -const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0); -const structTest: StructureOrificeSubmerged = new StructureOrificeSubmerged(structPrm, false); +const prms: StructureOrificeSubmergedParams = new StructureOrificeSubmergedParams(0, 102, 101.5, 0.7, 0.1); +const test: StructureOrificeSubmerged = new StructureOrificeSubmerged(prms, false); describe("Class StructureOrificeSubmerged: ", () => { - describe("Calcul Q avec W croissant: ", () => { - const W: number[] = [ - 0.000000, 0.100000, 0.200000, 0.300000, 0.400000, 0.500000, 0.600000, - 0.700000, 0.800000, 0.900000, 1.000000, 1.100000, 1.200000, 1.300000]; - const h1: number = 1.200000; - const Q: number[] = [0.000000, 0.237709, 0.475418, 0.713127, 0.950836, 1.188545, - 1.426254, 1.663963, 1.901673, 2.139382, 2.377091, 2.614800, 2.852509, 2.852509]; - - for (let i = 0; i < Q.length; i++) { - itCalcQ(structTest, h1, W[i], Q[i]); - } - }); - describe("Calcul Q en charge avec h1 croissant: ", () => { - const W: number = 0.8; - const h1: number[] = [1.050000, 1.300000, 1.500000]; - const Q: number[] = [0.950836, 2.329064, 3.006808]; - const mode: StructureFlowMode[] = [ - StructureFlowMode.ORIFICE, StructureFlowMode.ORIFICE, StructureFlowMode.ORIFICE]; - const regime: StructureFlowRegime[] = [ - StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED]; - - for (let i = 0; i < Q.length; i++) { - itCalcQ(structTest, h1[i], W, Q[i], mode[i], regime[i]); - } - }); - describe("Calcul Q a surface libre avec h1 croissant: ", () => { - const W: number = Infinity; - const h1: number[] = [1.100000, 1.500000]; - const Q: number[] = [1.848943, 5.637766]; - const mode: StructureFlowMode[] = [ - StructureFlowMode.WEIR, StructureFlowMode.WEIR]; - const regime: StructureFlowRegime[] = [ - StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED]; - + describe("Calc(Q): ", () => { + const h1: number[] = [102]; + const Q: number[] = [0.219]; + const mode: StructureFlowMode = StructureFlowMode.ORIFICE; + const regime: StructureFlowRegime = StructureFlowRegime.SUBMERGED; for (let i = 0; i < Q.length; i++) { - itCalcQ(structTest, h1[i], W, Q[i], mode[i], regime[i]); + itCalcQ(test, h1[i], Infinity, Q[i], mode, regime); } }); }); diff --git a/spec/structure/structure_orifice_free.spec.ts b/spec/structure/structure_rectangular_orifice_free.spec.ts similarity index 91% rename from spec/structure/structure_orifice_free.spec.ts rename to spec/structure/structure_rectangular_orifice_free.spec.ts index 708f8ae1a0c7e96a775ce169ed07abb72b212aa4..91fe31bdaade51dbf292bac55437799f04281636 100644 --- a/spec/structure/structure_orifice_free.spec.ts +++ b/spec/structure/structure_rectangular_orifice_free.spec.ts @@ -8,12 +8,11 @@ import { RectangularStructureParams } from "../../src/structure/rectangular_structure_params"; import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure"; -import { StructureOrificeFree } from "../../src/structure/structure_orifice_free"; -import { Result } from "../../src/util/result"; +import { StructureRectangularOrificeFree } from "../../src/structure/structure_rectangular_orifice_free"; import { itCalcQ } from "./functions"; const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0); -const structTest: StructureOrificeFree = new StructureOrificeFree(structPrm, false); +const structTest: StructureRectangularOrificeFree = new StructureRectangularOrificeFree(structPrm, false); describe("Class StructureOrificeFree: ", () => { describe("Calcul Q avec W croissant: ", () => { diff --git a/spec/structure/structure_rectangular_orifice_submerged.spec.ts b/spec/structure/structure_rectangular_orifice_submerged.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..012e111c9924183e403c3313725eec524fc4cfc9 --- /dev/null +++ b/spec/structure/structure_rectangular_orifice_submerged.spec.ts @@ -0,0 +1,57 @@ +/** + * 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 rectangular_structure.ts + */ +// import { describe, expect, it, xdescribe } from "../mock_jasmine"; + +import { RectangularStructureParams } from "../../src/structure/rectangular_structure_params"; +import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure"; +import { StructureRectangularOrificeSubmerged } from "../../src/structure/structure_rectangular_orifice_submerged"; +import { Result } from "../../src/util/result"; +import { itCalcQ } from "./functions"; + +const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0); +const structTest: StructureRectangularOrificeSubmerged = new StructureRectangularOrificeSubmerged(structPrm, false); + +describe("Class StructureRectangularOrificeSubmerged: ", () => { + describe("Calcul Q avec W croissant: ", () => { + const W: number[] = [ + 0.000000, 0.100000, 0.200000, 0.300000, 0.400000, 0.500000, 0.600000, + 0.700000, 0.800000, 0.900000, 1.000000, 1.100000, 1.200000, 1.300000]; + const h1: number = 1.200000; + const Q: number[] = [0.000000, 0.237709, 0.475418, 0.713127, 0.950836, 1.188545, + 1.426254, 1.663963, 1.901673, 2.139382, 2.377091, 2.614800, 2.852509, 2.852509]; + + for (let i = 0; i < Q.length; i++) { + itCalcQ(structTest, h1, W[i], Q[i]); + } + }); + describe("Calcul Q en charge avec h1 croissant: ", () => { + const W: number = 0.8; + const h1: number[] = [1.050000, 1.300000, 1.500000]; + const Q: number[] = [0.950836, 2.329064, 3.006808]; + const mode: StructureFlowMode[] = [ + StructureFlowMode.ORIFICE, StructureFlowMode.ORIFICE, StructureFlowMode.ORIFICE]; + const regime: StructureFlowRegime[] = [ + StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED]; + + for (let i = 0; i < Q.length; i++) { + itCalcQ(structTest, h1[i], W, Q[i], mode[i], regime[i]); + } + }); + describe("Calcul Q a surface libre avec h1 croissant: ", () => { + const W: number = Infinity; + const h1: number[] = [1.100000, 1.500000]; + const Q: number[] = [1.848943, 5.637766]; + const mode: StructureFlowMode[] = [ + StructureFlowMode.WEIR, StructureFlowMode.WEIR]; + const regime: StructureFlowRegime[] = [ + StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED]; + + for (let i = 0; i < Q.length; i++) { + itCalcQ(structTest, h1[i], W, Q[i], mode[i], regime[i]); + } + }); +}); diff --git a/spec/structure/structure_test.ts b/spec/structure/structure_test.ts index fd9a2a1b4d8fb415ae5203ba8cf0313cd861848d..5a79d9a9f6361334f9e25c4cee6a65a144e65eac 100644 --- a/spec/structure/structure_test.ts +++ b/spec/structure/structure_test.ts @@ -9,6 +9,7 @@ import { MessageCode } from "../../src"; import { ParamCalculability } from "../../src/param/param-definition"; import { Structure, StructureFlowMode, StructureFlowRegime, StructureParams } from "../../src/structure/structure"; +import { LoiDebit, StructureType } from "../../src/structure/structure_props"; import { Result } from "../../src/util/result"; import { checkResult } from "../test_func"; @@ -59,45 +60,3 @@ class StructureTest extends Structure { */ export const structTestPrm: StructureParams = new StructureParams(1, 0, 30, 15); export const structTest: StructureTest = new StructureTest(structTestPrm, false); - -/** - * Test de calcul de tous les paramètres d'une loi de débit - * @param st Structure à tester - * @param bNotZDV Loi de débit ne permettant pas de calculer ZDV - */ -export function testStructure( - st: Structure, - mode: StructureFlowMode, - regime: StructureFlowRegime, - bNotZDV: boolean = false -) { - for (const prm of st.prms) { - if ([ParamCalculability.DICHO, ParamCalculability.EQUATION].includes(prm.calculability)) { - if (prm.symbol === "W" && prm.v === Infinity) { - // Le calcul de l'ouverture sur les seuils doit renvoyer une exception (cas impossible) - it(`Calc(${prm.symbol}) should return exception`, () => { - expect( - () => { st.Calc(prm.symbol); } - ).toThrow(new Error("Structure:Calc : Calcul de W impossible sur un seuil")); - }); - } else { - const ref: number = prm.v; - 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é - 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 - it(`Calc(${prm.symbol}) should return ${ref}`, () => { - checkResult(res, ref); - }); - } - prm.v = ref; // Go back to initial value for following tests - } - } - } -} \ No newline at end of file diff --git a/spec/structure/structure_weir_submerged_larinier.spec.ts b/spec/structure/structure_weir_submerged_larinier.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..1952ed2f26f196c7e1f6e80312025e39965534f9 --- /dev/null +++ b/spec/structure/structure_weir_submerged_larinier.spec.ts @@ -0,0 +1,27 @@ +/** + * 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 ../structure/functions.ts + */ +// import { describe, expect, it, xdescribe } from "../mock_jasmine"; + +import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure"; +// tslint:disable-next-line:max-line-length +import { RectangularStructureParams, StructureWeirSubmergedLarinier } from "../../src/structure/structure_weir_submerged_larinier"; +import { itCalcQ } from "../structure/functions"; + +const prms: RectangularStructureParams = new RectangularStructureParams(0, 101, 102, 101.5, 0.2, 0.65); +const test: StructureWeirSubmergedLarinier = new StructureWeirSubmergedLarinier(prms, false); + +describe("Class CloisonsOrifice: ", () => { + describe("Calc(Q): ", () => { + const Z1: number[] = [102]; + const Q: number[] = [0.407]; + const mode: StructureFlowMode = StructureFlowMode.WEIR; + const regime: StructureFlowRegime = StructureFlowRegime.SUBMERGED; + for (let i = 0; i < Q.length; i++) { + itCalcQ(test, Z1[i], Infinity, Q[i], mode, regime); + } + }); +}); diff --git a/spec/test_func.ts b/spec/test_func.ts index d19d4b41cae27dd39f35b28ffe730de4e34b9835..a3b692f0e0a38105bc3cabf8acea575a5af05600 100644 --- a/spec/test_func.ts +++ b/spec/test_func.ts @@ -220,8 +220,9 @@ export function compareExtraResult( const nre = res.resultElements.length; let n1 = 0; for (let i = 0; i < nre; i++) { - if (res.resultElements[i].getExtraResult(key) != undefined) + if (res.resultElements[i].getExtraResult(key) !== undefined) { n1++; + } } const n2 = Object.keys(objValid).length; @@ -236,4 +237,4 @@ export function compareExtraResult( expect(b).toBeTruthy(s + " : " + i + "ieme valeur incorrecte " + v1 + ", devrait etre " + v2); if (!b) { return; } } -} \ No newline at end of file +} diff --git a/src/compute-node.ts b/src/compute-node.ts index 6d98e09d1519e9f34f343bef92eca91cad07da8d..023de3bba04d7b5b6b9108ff007fd311fde96ff6 100644 --- a/src/compute-node.ts +++ b/src/compute-node.ts @@ -7,12 +7,17 @@ import { IParamDefinitionIterator, ParamsEquation } from "./param/params-equatio * type de calculette */ export enum CalculatorType { - ConduiteDistributrice, LechaptCalmon, SectionParametree, RegimeUniforme, CourbeRemous, + ConduiteDistributrice, + LechaptCalmon, + SectionParametree, + RegimeUniforme, + CourbeRemous, PabDimensions, // passe à bassin rectangulaire PabPuissance, // passe à bassin : puissance dissipée Structure, // ouvrages hydrauliques simples ParallelStructure, // ouvrages hydrauliques en parallèle - Dever // Outil Cassiopée Dever + Dever, // Outil Cassiopée Dever + Cloisons // Outil Cassiopée PAB Cloisons } /** diff --git a/src/nub_factory.ts b/src/nub_factory.ts index 2f4e19b6117d813b1f4ee77feb31f9298c8c66c9..e8a5458f60404b792ea11fb00241b6d4c7d015c1 100644 --- a/src/nub_factory.ts +++ b/src/nub_factory.ts @@ -10,6 +10,7 @@ import { PabPuissance, PabPuissanceParams } from "./pab/pab_puissance"; import { RegimeUniforme } from "./regime_uniforme"; import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "./remous"; import { SectionParametree } from "./section/section_nub"; +import { Cloisons, CloisonsParams } from "./structure/cloisons"; import { Dever, DeverParams } from "./structure/dever"; import { ParallelStructure, ParallelStructureParams } from "./structure/parallel_structure"; @@ -309,7 +310,7 @@ export class NubFactory { 0.3, // Chute entre bassins DH (m) 0.1, // Débit Q (m3/s) 0.5, // Volume V (m3) - 588.6 // Puissance dissipée Pv (W/m3) + 588.6 // Puissance dissipée PV (W/m3) ); return new PabPuissance(prms); } @@ -338,6 +339,20 @@ export class NubFactory { return new Dever(prms); } + case CalculatorType.Cloisons: + { + return new Cloisons( + new CloisonsParams( + 0, // Débit total (m3/s) + 102, // Cote de l'eau amont (m) + 10, // Longueur des bassins (m) + 1, // Largeur des bassins (m) + 1, // Profondeur moyenne (m) + 0.5 // Hauteur de chute (m) + ) + ); + } + default: throw new Error( // tslint:disable-next-line:max-line-length diff --git a/src/pab/pab_puissance.ts b/src/pab/pab_puissance.ts index a0729bfc104157fd3ab6a91b77afc02f72a1ae97..9f4fd19c058870c545c5978934ed2dbd4ab3e52c 100644 --- a/src/pab/pab_puissance.ts +++ b/src/pab/pab_puissance.ts @@ -17,19 +17,19 @@ export class PabPuissanceParams extends ParamsEquation { private _V: ParamDefinition; /** Puissance dissipée PV */ - private _Pv: ParamDefinition; + private _PV: ParamDefinition; constructor(rDH: number, rQ: number, rV: number, rPV?: number) { super(); this._DH = new ParamDefinition("DH", ParamDomainValue.POS, rDH); this._Q = new ParamDefinition("Q", ParamDomainValue.POS, rQ); this._V = new ParamDefinition("V", ParamDomainValue.POS, rV); - this._Pv = new ParamDefinition("Pv", ParamDomainValue.POS, rPV); + this._PV = new ParamDefinition("PV", ParamDomainValue.POS, rPV); this.addParamDefinition(this._DH); this.addParamDefinition(this._Q); this.addParamDefinition(this._V); - this.addParamDefinition(this._Pv); + this.addParamDefinition(this._PV); } get DH() { @@ -44,8 +44,8 @@ export class PabPuissanceParams extends ParamsEquation { return this._V; } - get Pv() { - return this._Pv; + get PV() { + return this._PV; } } @@ -66,7 +66,7 @@ export class PabPuissance extends Nub { let v: number; switch (sVarCalc) { - case "Pv": + case "PV": const ro: number = 1000; // masse volumique de l'eau en kg/m3 const g: number = 9.81; // accélération de la gravité terrestre en m/s2. v = ro * g * this.prms.Q.v * this.prms.DH.v / this.prms.V.v; @@ -86,7 +86,7 @@ export class PabPuissance extends Nub { this.prms.DH.calculability = ParamCalculability.DICHO; this.prms.Q.calculability = ParamCalculability.DICHO; this.prms.V.calculability = ParamCalculability.DICHO; - this.prms.Pv.calculability = ParamCalculability.EQUATION; + this.prms.PV.calculability = ParamCalculability.EQUATION; } } diff --git a/src/structure/cloisons.ts b/src/structure/cloisons.ts new file mode 100644 index 0000000000000000000000000000000000000000..6571566f3811c4e8bd621b17b1d537155527b935 --- /dev/null +++ b/src/structure/cloisons.ts @@ -0,0 +1,91 @@ +import { PabPuissance, PabPuissanceParams } from "../pab/pab_puissance"; +import { ParamCalculability, ParamDefinition } from "../param/param-definition"; +import { Result } from "../util/result"; +import { CloisonsParams } from "./cloisons_params"; +import { ParallelStructure } from "./parallel_structure"; +import { StructureKiviParams } from "./structure_kivi"; + +export { CloisonsParams }; + +export class Cloisons extends ParallelStructure { + constructor(prms: CloisonsParams, dbg: boolean = false) { + super(prms, dbg); + } + + /** + * paramètres castés au bon type + */ + get prms(): CloisonsParams { + return this._prms as CloisonsParams; + } + + /** + * Calcul du débit total, de la cote amont ou aval ou d'un paramètre d'une structure + * @param sVarCalc Nom du paramètre à calculer : + * "Q", "Z1", "DH" ou "n.X" avec "n" l'index de l'ouvrage et "X" son paramètre + * @param rInit Valeur initiale + * @param rPrec Précision attendue + */ + public Calc(sVarCalc: string, rInit?: number, rPrec: number = 0.001): Result { + // Mise à jour de ZRAM pour Kivi à partir de Z1 - PB + this.updateKiviZRAM(); + + // Transformation DH => Z2 + this.prms.Z2.v = this.prms.Z1.v - this.prms.DH.v; + let sVC: string = sVarCalc; + if (sVarCalc === "DH") { + sVC = "Z2"; + } + + const r: Result = super.Calc(sVC, rInit, rPrec); + + // Transformation Z2 => DH + if (sVarCalc === "DH") { + r.vCalc = this.prms.Z1.v - r.vCalc; + } + + // Ajout du calcul de la puissance dissipée + const prms = this.getcalculatedparams(sVarCalc, r); + const puissanceNub: PabPuissance = new PabPuissance( + new PabPuissanceParams( + prms.DH, + prms.Q, + prms.LB * prms.BB * prms.PB + ) + ); + r.extraResults.PV = puissanceNub.Calc("PV", 0).vCalc; + + return r; + } + + /** + * paramétrage de la calculabilité des paramètres + */ + protected setParametersCalculability() { + super.setParametersCalculability(); + this.prms.LB.calculability = ParamCalculability.FREE; + this.prms.BB.calculability = ParamCalculability.FREE; + this.prms.PB.calculability = ParamCalculability.FREE; + this.prms.DH.calculability = ParamCalculability.DICHO; + } + + protected getcalculatedparams(sVarCalc: string, result: Result): { [key: string]: number } { + const cPrms: { [key: string]: number } = {}; + for (const p of this.parameterIterator) { + if (p.symbol === sVarCalc) { + cPrms[p.symbol] = result.vCalc; + } else { + cPrms[p.symbol] = p.v; + } + } + return cPrms; + } + + private updateKiviZRAM() { + for (const structure of this.structures) { + if (structure.prms instanceof StructureKiviParams) { + structure.prms.ZRAM.v = this.prms.Z1.v - this.prms.PB.v; + } + } + } +} diff --git a/src/structure/cloisons_params.ts b/src/structure/cloisons_params.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca7d27323ee4e530d0aef1e4816c191a541c063c --- /dev/null +++ b/src/structure/cloisons_params.ts @@ -0,0 +1,41 @@ +import { ParamDefinition } from "../param/param-definition"; +import { ParamDomainValue } from "../param/param-domain"; +import { ParallelStructureParams } from "./parallel_structure_params"; + +/** + * Common parameters of hydraulic structure equations + */ +export class CloisonsParams extends ParallelStructureParams { + /** Largeur des bassins (m) */ + public BB: ParamDefinition; + + /** Longueur des bassins (m) */ + public LB: ParamDefinition; + + /** Profondeur moyenne (m) */ + public PB: ParamDefinition; + + /** Hauteur de chute (m) */ + public DH: ParamDefinition; + + /** + * Paramètres communs à toutes les équations de structure + * @param rQ Débit total (m3/s) + * @param rZ1 Cote de l'eau amont (m) + * @param rLB Longueur des bassins (m) + * @param rBB Largeur des bassins (m) + * @param rPB Profondeur moyenne (m) + * @param rDH Hauteur de chute (m) + */ + constructor(rQ: number, rZ1: number, rLB: number, rBB: number, rPB: number, rDH: number) { + super(rQ, rZ1, rZ1 - rDH); + this.LB = new ParamDefinition("LB", ParamDomainValue.POS, rLB); + this.addParamDefinition(this.LB); + this.BB = new ParamDefinition("BB", ParamDomainValue.POS, rBB); + this.addParamDefinition(this.BB); + this.PB = new ParamDefinition("PB", ParamDomainValue.POS, rPB); + this.addParamDefinition(this.PB); + this.DH = new ParamDefinition("DH", ParamDomainValue.POS, rDH); + this.addParamDefinition(this.DH); + } +} diff --git a/src/structure/dever.ts b/src/structure/dever.ts index 2f9355881bd8ee3a03edb1bad4d63603305b0a6f..51fba3774da8c764c46020016ed8dedf89c93c4b 100644 --- a/src/structure/dever.ts +++ b/src/structure/dever.ts @@ -1,4 +1,3 @@ -import { Nub } from "../nub"; import { ParamCalculability, ParamDefinition } from "../param/param-definition"; import { Result } from "../util/result"; import { DeverParams } from "./dever_params"; diff --git a/src/structure/factory_structure.ts b/src/structure/factory_structure.ts index 912003139efb808efcbcdb37fe04b14a001fe4cc..d607f256536e1aa71988608708d1cec05cbb853a 100644 --- a/src/structure/factory_structure.ts +++ b/src/structure/factory_structure.ts @@ -1,18 +1,21 @@ +// Classes générales sur les structures import { RectangularStructureParams } from "./rectangular_structure_params"; import { Structure } from "./structure"; +import { LoiDebit, StructureProperties, StructureType } from "./structure_props"; + +// Equations de débit import { StructureCem88d } from "./structure_cem88d"; import { StructureCem88v } from "./structure_cem88v"; import { StructureCunge80 } from "./structure_cunge80"; -import { StructureKivi } from "./structure_kivi"; -import { StructureKiviParams } from "./structure_kivi_params"; -import { StructureOrificeFree } from "./structure_orifice_free"; -import { StructureOrificeSubmerged } from "./structure_orifice_submerged"; -import { LoiDebit, StructureProperties, StructureType } from "./structure_props"; +import { StructureKivi, StructureKiviParams } from "./structure_kivi"; +import { StructureOrificeSubmerged, StructureOrificeSubmergedParams } from "./structure_orifice_submerged"; +import { StructureRectangularOrificeFree } from "./structure_rectangular_orifice_free"; +import { StructureRectangularOrificeSubmerged } from "./structure_rectangular_orifice_submerged"; // tslint:disable-next-line:max-line-length import { StructureTriangularTruncWeirFree, TriangularTruncStructureParams } from "./structure_triangular_trunc_weir_free"; import { StructureTriangularWeirFree, TriangularStructureParams } from "./structure_triangular_weir_free"; import { StructureWeirFree } from "./structure_weir_free"; - +import { StructureWeirSubmergedLarinier } from "./structure_weir_submerged_larinier"; export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit, dbg: boolean = false): Structure { const oCd: {[s: string]: number} = {SeuilR: 0.4, VanneR: 0.6, SeuilT: 1.36}; @@ -35,6 +38,7 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit case StructureType.SeuilRectangulaire: case StructureType.SeuilTriangulaire: case StructureType.SeuilTriangulaireTrunc: + case StructureType.Orifice: break; default: @@ -62,19 +66,22 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit rectStructPrms.Cd.v = oCd.VanneR; // Cd Cunge80 qu'on soit en seuil ou vanne return new StructureCunge80(rectStructPrms, dbg); - case LoiDebit.OrificeFree: - return new StructureOrificeFree(rectStructPrms, dbg); + case LoiDebit.RectangularOrificeFree: + return new StructureRectangularOrificeFree(rectStructPrms, dbg); - case LoiDebit.OrificeSubmerged: - return new StructureOrificeSubmerged(rectStructPrms, dbg); + case LoiDebit.RectangularOrificeSubmerged: + return new StructureRectangularOrificeSubmerged(rectStructPrms, dbg); case LoiDebit.WeirFree: return new StructureWeirFree(rectStructPrms, dbg); + case LoiDebit.WeirSubmergedLarinier: + return new StructureWeirSubmergedLarinier(rectStructPrms, dbg); + case LoiDebit.KIVI: const structKiviPrm: StructureKiviParams = new StructureKiviParams( 8.516, // Q - 101, // ZDV + 101.5, // ZDV 103, // Z1 102, // Z2 2, // L @@ -82,7 +89,7 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit 0.001, // béta 100); // ZRAM : cote Radier Amont return new StructureKivi(structKiviPrm, dbg); - case LoiDebit.TriangularWeirFree: + case LoiDebit.TriangularWeirFree: const structTriangPrms: TriangularStructureParams = new TriangularStructureParams( 0, // Q 100, // ZDV @@ -92,7 +99,7 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit // W = Infinity par défaut pour un seuil ); return new StructureTriangularWeirFree(structTriangPrms, dbg); - case LoiDebit.TriangularTruncWeirFree: + case LoiDebit.TriangularTruncWeirFree: const structTriTruncPrms: TriangularTruncStructureParams = new TriangularTruncStructureParams( 0, // Q 100.1, // ZDV @@ -103,6 +110,17 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit // W = Infinity par défaut pour un seuil ); return new StructureTriangularTruncWeirFree(structTriTruncPrms, dbg); + case LoiDebit.OrificeSubmerged: + return new StructureOrificeSubmerged( + new StructureOrificeSubmergedParams( + 0, // Q + 102, // Z1 + 101.5, // Z2 + 0.7, // Cd + 0.1 // S + ), + dbg + ); default: throw new Error(`type de LoiDebit ${LoiDebit[loiDebit]} non pris en charge`); diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts index 1ecbc67a0febad528dab4f8d83385f012a91d838..4710780eaa5bd2b9a8083f5919b2955acacc10bb 100644 --- a/src/structure/parallel_structure.ts +++ b/src/structure/parallel_structure.ts @@ -230,8 +230,9 @@ export class ParallelStructure extends Nub { // analyse ouvrage[n].X const i: IStructureVarCalc = this.getStructureVarCalc2(desc); const res = this.structures[i.index].result; - if (res === undefined) + if (res === undefined) { return undefined; // pas de résultat calculé + } return res.getExtraResult(i.prm); } catch (e) { // desc n'est pas de la forme ouvrage[n].X @@ -299,7 +300,7 @@ export class ParallelStructure extends Nub { /** * Mise à jour de Z1, Z2, h1 et h2 pour tous les ouvrages */ - private updateStructuresH1H2() { + protected updateStructuresH1H2() { for (const structure of this.structures) { structure.prms.Z1.v = this.prms.Z1.v; structure.prms.Z2.v = this.prms.Z2.v; diff --git a/src/structure/structure.ts b/src/structure/structure.ts index 8965a98e88998f5072715bb6c92c961b4df3985e..c3effee93fa0176b5226db684b896cba39fd5cfb 100644 --- a/src/structure/structure.ts +++ b/src/structure/structure.ts @@ -33,6 +33,18 @@ export enum StructureFlowRegime { NULL, } +/** + * Type de jet : Sans objet (orifice), plongeant, de surface + */ +export enum StructureJetType { + /** Sans objet (orifice) */ + SO, + /** Plongeant */ + PLONGEANT, + /** De surface */ + SURFACE, +} + /** * classe de calcul sur la conduite distributrice */ @@ -100,16 +112,16 @@ export abstract class Structure extends Nub { // Gestion du débit nul const flagsNull = { Mode: StructureFlowMode.NULL, Regime: StructureFlowRegime.NULL }; if (sVarCalc === "Q") { - if (this.prms.h1.v === this.prms.h2.v || this.prms.W.v <= 0) { + if (this.prms.h1.v <= 0 || this.prms.Z1.v === this.prms.Z2.v || this.prms.W.v <= 0) { return new Result(0, flagsNull); } } else if (this.prms.Q.v === 0) { // Débit nul <=> tirant d'eau amont = tirant d'eau aval ou tout autre paramètre nul switch (sVarCalc) { case "Z1": - return new Result(this.prms.h2.v, flagsNull); + return new Result(this.prms.Z2.v, flagsNull); case "Z2": - return new Result(this.prms.h1.v, flagsNull); + return new Result(this.prms.Z1.v, flagsNull); default: // Est-ce toujours vrai ? Nécessitera peut-être d'étendre la méthode return new Result(0, flagsNull); @@ -212,4 +224,22 @@ export abstract class Structure extends Nub { return StructureFlowRegime.SUBMERGED; } } + + /** + * Give the Jet Type for weir flow + * Cf. Baudoin J.M., Burgun V., Chanseau M., Larinier M., Ovidio M., SremskiW., Steinbach P. et Voegtle B., 2014. + * Evaluer le franchissement des obstacles par les poissons. Principes et méthodes. Onema. 200 pages + */ + protected getJetType(): StructureJetType { + if (this.getFlowMode() === StructureFlowMode.WEIR) { + if (Math.abs(this.prms.h1.v - this.prms.h2.v) < 0.5 * this.prms.h1.v) { + return StructureJetType.SURFACE; + } else { + return StructureJetType.PLONGEANT; + } + } else { + return StructureJetType.SO; + } + } + } diff --git a/src/structure/structure_kivi.ts b/src/structure/structure_kivi.ts index e1bade6082007e4557476505f40156c0785a2c0a..082bdf614540ea028445f620f879ff7663914622 100644 --- a/src/structure/structure_kivi.ts +++ b/src/structure/structure_kivi.ts @@ -5,6 +5,8 @@ import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure"; import { StructureKiviParams } from "./structure_kivi_params"; import { Villemonte } from "./villemonte"; +export { StructureKiviParams }; + export class StructureKivi extends Structure { constructor(prms: StructureKiviParams, dbg: boolean = false) { diff --git a/src/structure/structure_orifice_submerged.ts b/src/structure/structure_orifice_submerged.ts index be0dae154c58eb52a64140a5644f4425b83c516b..3350831d1ce05a352267bacee58666c7cbdbe6c9 100644 --- a/src/structure/structure_orifice_submerged.ts +++ b/src/structure/structure_orifice_submerged.ts @@ -1,20 +1,25 @@ +import { ParamCalculability } from "../param/param-definition"; +import { Structure, StructureFlowMode, StructureFlowRegime } from "../structure/structure"; import { Result } from "../util/result"; -import { RectangularStructure } from "./rectangular_structure"; -import { RectangularStructureParams } from "./rectangular_structure_params"; -import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure"; +import { StructureOrificeSubmergedParams } from "./structure_orifice_submerged_params"; -export { RectangularStructureParams }; +export { StructureOrificeSubmergedParams }; /** * Equation classique orifice noyé */ -export class StructureOrificeSubmerged extends RectangularStructure { +export class StructureOrificeSubmerged extends Structure { - constructor(prms: RectangularStructureParams, dbg: boolean = false) { + constructor(prms: StructureOrificeSubmergedParams, dbg: boolean = false) { super(prms, dbg); - if (prms.W.v !== Infinity) { - this._isZDVcalculable = false; - } + this._isZDVcalculable = false; + } + + /** + * paramètres castés au bon type + */ + get prms(): StructureOrificeSubmergedParams { + return this._prms as StructureOrificeSubmergedParams; } /** @@ -25,13 +30,30 @@ export class StructureOrificeSubmerged extends RectangularStructure { Structure.CheckEquation(sVarCalc); const data = this.getResultData(); - const v = this.prms.Cd.v * Math.min(this.prms.W.v, this.prms.h1.v) * this.prms.L.v - * Structure.R2G * Math.sqrt(this.prms.h1.v - this.prms.h2.v); + const v = this.prms.Cd.v * this.prms.S.v * Structure.R2G * Math.sqrt(this.prms.Z1.v - this.prms.Z2.v); return new Result(v, data); } + public calcA(): number { + return this.prms.S.v; + } + protected getFlowRegime() { return StructureFlowRegime.SUBMERGED; } + + protected getFlowMode() { + return StructureFlowMode.ORIFICE; + } + + /** + * paramétrage de la calculabilité des paramètres + */ + protected setParametersCalculability() { + super.setParametersCalculability(); + this.prms.S.calculability = ParamCalculability.DICHO; + this.prms.Cd.calculability = ParamCalculability.DICHO; + this.prms.ZDV.calculability = ParamCalculability.NONE; + } } diff --git a/src/structure/structure_orifice_submerged_params.ts b/src/structure/structure_orifice_submerged_params.ts new file mode 100644 index 0000000000000000000000000000000000000000..a8f861726f24904096264fcd4d27d97d8b87279d --- /dev/null +++ b/src/structure/structure_orifice_submerged_params.ts @@ -0,0 +1,40 @@ +import { ParamDefinition } from "../param/param-definition"; +import { ParamDomainValue } from "../param/param-domain"; +import { StructureParams } from "../structure/structure_params"; + +/** + * Parameters for rectangular structures (common for all rectangular structure equations) + */ +export class StructureOrificeSubmergedParams extends StructureParams { + + /** Area of the orifice (m2) */ + public S: ParamDefinition; + + /** Discharge coefficient */ + // tslint:disable-next-line:variable-name + public Cd: ParamDefinition; + + /** + * Constructeur d'une structure rectangulaire + * @param rQ Débit (m3/s) + * @param rZ1 Cote de l'eau amont (m) + * @param rZ2 Cote de l'eau aval (m) + * @param rCd Coefficient de débit (-) + * @param rS Surface de l'orifice (m2) + */ + constructor(rQ: number, rZ1: number, rZ2: number, rCd: number, rS: number) { + super(rQ, -Infinity, rZ1, rZ2); + this.S = new ParamDefinition("S", ParamDomainValue.POS_NULL, rS); + this.addParamDefinition(this.S); + this.Cd = new ParamDefinition("Cd", ParamDomainValue.POS_NULL, rCd); + this.addParamDefinition(this.Cd); + } + + /** + * Mise à jour de h1 et h2 + */ + public update_h1h2() { + // Inutile pour cette équation qui ne fait pas intervenir ces variables + } + +} diff --git a/src/structure/structure_params.ts b/src/structure/structure_params.ts index 28ff720ad5f5dd5b8cd186ddbaf304f566ff9bd7..8740525ea3d4334f39b65c0c2c7f3f0ca25f8edf 100644 --- a/src/structure/structure_params.ts +++ b/src/structure/structure_params.ts @@ -1,7 +1,7 @@ import { Nub } from "../nub"; -import { ParamsEquation } from "../param/params-equation"; import { ParamDefinition } from "../param/param-definition"; import { ParamDomainValue } from "../param/param-domain"; +import { ParamsEquation } from "../param/params-equation"; /** * Common parameters of hydraulic structure equations diff --git a/src/structure/structure_props.ts b/src/structure/structure_props.ts index d7835ef44d4fed4e57e5f6bacc58b0d644eb3e78..0988e11ff4cb35812c067cf1fdba7fc05c44d896 100644 --- a/src/structure/structure_props.ts +++ b/src/structure/structure_props.ts @@ -1,5 +1,9 @@ export enum StructureType { - SeuilRectangulaire, VanneRectangulaire, SeuilTriangulaire, SeuilTriangulaireTrunc + SeuilRectangulaire, + VanneRectangulaire, + Orifice, + SeuilTriangulaire, + SeuilTriangulaireTrunc // VanneCirculaire, // VanneTrapezoidale, SeuilTrapezoidal } @@ -12,9 +16,9 @@ export enum LoiDebit { // loi de débit Cunge 1980 Cunge80, // loi de débit pour vanne dénoyée - OrificeFree, + RectangularOrificeFree, // loi de débit pour vanne noyée - OrificeSubmerged, + RectangularOrificeSubmerged, // loi de débit pour seuil dénoyé WeirFree, // Loi Kindsvater-Carter et Villemonte @@ -22,13 +26,20 @@ export enum LoiDebit { // Loi de débit seuil triangulaire dénoyé TriangularWeirFree, // Loi de débit seuil triangulaire tronqué - TriangularTruncWeirFree + TriangularTruncWeirFree, + // Loi de débit seuil noyé (Larinier 1992) + WeirSubmergedLarinier, + // Loi de débit orifice noyé + OrificeSubmerged } export const loiAdmissibles: { [key: string]: LoiDebit[] } = { + Orifice: [ + LoiDebit.OrificeSubmerged + ], SeuilRectangulaire: [ LoiDebit.Cem88d, LoiDebit.Cem88v, LoiDebit.Cunge80, LoiDebit.WeirFree, - LoiDebit.KIVI + LoiDebit.KIVI, LoiDebit.WeirSubmergedLarinier ], SeuilTriangulaire: [ LoiDebit.TriangularWeirFree @@ -37,8 +48,8 @@ export const loiAdmissibles: { [key: string]: LoiDebit[] } = { LoiDebit.TriangularTruncWeirFree ], VanneRectangulaire: [ - LoiDebit.Cem88d, LoiDebit.Cem88v, LoiDebit.Cunge80, LoiDebit.OrificeFree, - LoiDebit.OrificeSubmerged + LoiDebit.Cem88d, LoiDebit.Cem88v, LoiDebit.Cunge80, LoiDebit.RectangularOrificeFree, + LoiDebit.RectangularOrificeSubmerged ] }; @@ -66,10 +77,20 @@ export class StructureProperties { } /** - * @return la 1ère valeur de LoiDebit compatible avec le type de structure + * trouve la 1ère valeur de LoiDebit compatible avec le type de structure + * @param struct type de structure avec laquelle la loi de débit doit être compatible + * @param subset si non vide, recherche la loi de débit compatible dans ce tableau; sinon prend la 1ere */ - public static findCompatibleLoiDebit(struct: StructureType): LoiDebit { + public static findCompatibleLoiDebit(struct: StructureType, subset: LoiDebit[]): LoiDebit { const sst: string = StructureType[struct]; - return loiAdmissibles[sst][0]; + + if (subset.length === 0) + return loiAdmissibles[sst][0]; + + for (const ld of loiAdmissibles[sst]) + if (subset.includes(ld)) + return ld; + + return undefined; } } diff --git a/src/structure/structure_orifice_free.ts b/src/structure/structure_rectangular_orifice_free.ts similarity index 85% rename from src/structure/structure_orifice_free.ts rename to src/structure/structure_rectangular_orifice_free.ts index 4d18544dcf38ff1823b7a8b9f9b2856bec36a744..596fa6e06fe2bedb58f80a819644d6da4eff5154 100644 --- a/src/structure/structure_orifice_free.ts +++ b/src/structure/structure_rectangular_orifice_free.ts @@ -1,14 +1,14 @@ import { Result } from "../util/result"; import { RectangularStructure } from "./rectangular_structure"; import { RectangularStructureParams } from "./rectangular_structure_params"; -import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure"; +import { Structure, StructureFlowRegime } from "./structure"; export { RectangularStructureParams }; /** * Equation classique orifice dénoyé */ -export class StructureOrificeFree extends RectangularStructure { +export class StructureRectangularOrificeFree extends RectangularStructure { /** * Calcul du débit avec l'équation classique d'un orifice dénoyé * @param sVarCalc Variable à calculer (doit être égale à Q ici) diff --git a/src/structure/structure_rectangular_orifice_submerged.ts b/src/structure/structure_rectangular_orifice_submerged.ts new file mode 100644 index 0000000000000000000000000000000000000000..5d0515911316b4d4fac312ba27f45846e69f3485 --- /dev/null +++ b/src/structure/structure_rectangular_orifice_submerged.ts @@ -0,0 +1,37 @@ +import { Result } from "../util/result"; +import { RectangularStructure } from "./rectangular_structure"; +import { RectangularStructureParams } from "./rectangular_structure_params"; +import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure"; + +export { RectangularStructureParams }; + +/** + * Equation classique orifice noyé + */ +export class StructureRectangularOrificeSubmerged extends RectangularStructure { + + constructor(prms: RectangularStructureParams, dbg: boolean = false) { + super(prms, dbg); + if (prms.W.v !== Infinity) { + this._isZDVcalculable = false; + } + } + + /** + * Calcul du débit avec l'équation classique d'un orifice noyé + * @param sVarCalc Variable à calculer (doit être égale à Q ici) + */ + public Equation(sVarCalc: string): Result { + Structure.CheckEquation(sVarCalc); + const data = this.getResultData(); + + const v = this.prms.Cd.v * Math.min(this.prms.W.v, this.prms.h1.v) * this.prms.L.v + * Structure.R2G * Math.sqrt(this.prms.h1.v - this.prms.h2.v); + + return new Result(v, data); + } + + protected getFlowRegime() { + return StructureFlowRegime.SUBMERGED; + } +} diff --git a/src/structure/structure_weir_submerged_larinier.ts b/src/structure/structure_weir_submerged_larinier.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3468ac4fbeff4041c132ac789d61c267ce11b98 --- /dev/null +++ b/src/structure/structure_weir_submerged_larinier.ts @@ -0,0 +1,35 @@ +import { Result } from "../util/result"; +import { RectangularStructure } from "./rectangular_structure"; +import { RectangularStructureParams } from "./rectangular_structure_params"; +import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure"; + +export { RectangularStructureParams }; + +/** + * Equation de la fente noyé + * d'après Larinier, M., Travade, F., Porcher, J.-P., Gosset, C., 1992. + * Passes à poissons : expertise et conception des ouvrages de franchissement + */ +export class StructureWeirSubmergedLarinier extends RectangularStructure { + /** + * Calcul analytique Q = f(Cd, L, h1, h2, W) seuil dénoyé + * @param sVarCalc Variable à calculer (doit être "Q") + */ + public Equation(sVarCalc: string): Result { + Structure.CheckEquation(sVarCalc); + const data = this.getResultData(); + + const v = this.prms.Cd.v * this.prms.L.v * Structure.R2G + * this.prms.h1.v * Math.sqrt(this.prms.h1.v - this.prms.h2.v); + + return new Result(v, data); + } + + protected getFlowRegime() { + return StructureFlowRegime.SUBMERGED; + } + + protected getFlowMode() { + return StructureFlowMode.WEIR; + } +}