diff --git a/spec/fuzzing.spec.ts b/spec/fuzzing.spec.ts index bccbb93e1e42419f99d2692b37360606844b3522..060e09dcab6f3ea9098423aa5876a141276f7c79 100644 --- a/spec/fuzzing.spec.ts +++ b/spec/fuzzing.spec.ts @@ -1,4 +1,3 @@ -import { isNumeric } from "../src/base"; import { CalculatorType } from "../src/compute-node"; import { Nub } from "../src/nub"; import { CloisonAval } from "../src/pab/cloison_aval"; @@ -9,7 +8,7 @@ import { SectionNub } from "../src/section/section_nub"; import { Session } from "../src/session"; import { CreateStructure } from "../src/structure/factory_structure"; import { ParallelStructure } from "../src/structure/parallel_structure"; -import { SetJasmineCurrentSpec } from "./test_func"; +import { checkResultConsistency, isFiniteNumber, SetJasmineCurrentSpec } from "./test_func"; /** * Fuzzing or fuzz testing is an automated software testing technique that involves providing invalid, @@ -29,7 +28,7 @@ const fuzzyCfg = { structureMax: 3 // Maximum number of structures in each cloison }, ParallelStructure: { - structureMax: 10 // Maximum number of structure in ParallelStructure and its derivated + structureMax: 1 // Maximum number of structure in ParallelStructure and its derivated } }; @@ -111,10 +110,6 @@ function setPab(pab: Pab, nClMax = 30, nStMax = 3) { addRandomStructures(pab.downWall, nStMax); } -function isFiniteNumber(x: any) { - return isNumeric(x) && isFinite(x); -} - function CreateTestNub(iCalType: number): Nub { const n = Session.getInstance().createNub( new Props({ calcType: iCalType }) @@ -200,27 +195,7 @@ describe("Fuzz testing", () => { }); it(printPrms(nubs[iNub]), () => { const r = nubs[iNub].CalcSerie(); - if (r.ok) { - if (nubs[iNub].calcType !== CalculatorType.SectionParametree) { - // Pas de vCalc sur les sections paramétrées - expect(isFiniteNumber(r.vCalc)) - .toBe(true, `vCalc = ${r.vCalc} isn't a finite number`); - } - if (r.resultElement.hasExtraResults) { - for (const key in r.resultElement.extraResults) { - if (r.resultElement.extraResults.hasOwnProperty(key)) { - const er = r.resultElement.extraResults[key]; - expect(isFiniteNumber(er)) - .toBe( - true, - `extraResult[${key}] = ${er} isn't a finite number` - ); - } - } - } - } else { - expect(r.hasErrorMessages).toBe(true, "Result KO and no error message"); - } + checkResultConsistency(nubs[iNub], r); }); }); } diff --git a/spec/structure/dever_jalhyd123.spec.ts b/spec/structure/dever_jalhyd123.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..1a4bf63063f5a832ce1e6a9bb1807a99a447242f --- /dev/null +++ b/spec/structure/dever_jalhyd123.spec.ts @@ -0,0 +1,23 @@ +import { Session } from "../../src/session"; +import { checkResultConsistency, isFiniteNumber } from "../test_func"; + +describe("Dever", () => { + describe("jalhyd#123", () => { + it("1-CalcSerie() should return consistent result with no NaN or Infinity", () => { + // tslint:disable-next-line:max-line-length + const sessionJson = `{"header":{"source":"jalhyd","format_version":"1.1","created":"2019-08-02T13:08:02.502Z"},"session":[{"uid":"ZTVndH","props":{"calcType":"Dever"},"children":[{"uid":"YWdpdz","props":{"calcType":"Structure","loiDebit":"TriangularTruncWeirFree"},"children":[],"parameters":[{"symbol":"ZDV","mode":"SINGLE","value":435224.52874659264},{"symbol":"BT","mode":"SINGLE","value":834000.9388248117},{"symbol":"ZT","mode":"SINGLE","value":122035.3210189593},{"symbol":"CdT","mode":"SINGLE","value":373098.1230344667}]}],"parameters":[{"symbol":"Q","mode":"CALCUL"},{"symbol":"Z1","mode":"SINGLE", "value": 435224.52874657186},{"symbol":"BR","mode":"SINGLE","value":377590.4669003834},{"symbol":"ZR","mode":"SINGLE","value":1783112.6327096}]}]}`; + Session.getInstance().unserialise(sessionJson); + const nub = Session.getInstance().findNubByUid("ZTVndH"); + nub.CalcSerie(); + checkResultConsistency(nub); + }); + it("2-CalcSerie() should return consistent result with no NaN or Infinity", () => { + // tslint:disable-next-line:max-line-length + const sessionJson = `{"header":{"source":"jalhyd","format_version":"1.1","created":"2019-08-02T13:50:05.186Z"},"session":[{"uid":"MnFiMX","props":{"calcType":"Dever"},"children":[{"uid":"ZHY4cn","props":{"calcType":"Structure","loiDebit":"TriangularTruncWeirFree"},"children":[],"parameters":[{"symbol":"ZDV","mode":"SINGLE","value":689767.6903101245},{"symbol":"BT","mode":"SINGLE","value":173652.02957055828},{"symbol":"ZT","mode":"SINGLE","value":681292.3529449722},{"symbol":"CdT","mode":"SINGLE","value":2.4436229141892696}]}],"parameters":[{"symbol":"Q","mode":"CALCUL"},{"symbol":"Z1","mode":"SINGLE","value":694070.3903202948},{"symbol":"BR","mode":"SINGLE","value":598136.6807876453},{"symbol":"ZR","mode":"SINGLE","value":1413511.597493809}]}]}`; + Session.getInstance().unserialise(sessionJson); + const nub = Session.getInstance().findNubByUid("MnFiMX"); + nub.CalcSerie(); + checkResultConsistency(nub); + }); + }); +}); diff --git a/spec/test_func.ts b/spec/test_func.ts index 514cfa49641a2205e748b8298f7911bb9bb41aea..e074ee3f0bbbf7e3b700edf404a5d0e037068de3 100644 --- a/spec/test_func.ts +++ b/spec/test_func.ts @@ -4,7 +4,9 @@ * qui utilise la fonction expect() de Jasmine mais qui doit être exécutée en dehors de tests Jasmine */ // import { expect } from "./mock_jasmine"; - +import { isNumeric } from "../src/base"; +import { CalculatorType } from "../src/compute-node"; +import { Nub } from "../src/nub"; import { cLog } from "../src/util/log"; import { Message, MessageCode } from "../src/util/message"; import { Result } from "../src/util/result"; @@ -208,6 +210,33 @@ export function checkResult(result: Result, valRef: number, prec?: number) { } } +export function checkResultConsistency(nub: Nub, r?: Result) { + if (r === undefined) { + r = nub.result; + } + if (r.ok) { + if (nub.calcType !== CalculatorType.SectionParametree) { + // Pas de vCalc sur les sections paramétrées + expect(isFiniteNumber(r.vCalc)) + .toBe(true, `vCalc = ${r.vCalc} isn't a finite number`); + } + if (r.resultElement.hasExtraResults) { + for (const key in r.resultElement.extraResults) { + if (r.resultElement.extraResults.hasOwnProperty(key)) { + const er = r.resultElement.extraResults[key]; + expect(isFiniteNumber(er)) + .toBe( + true, + `extraResult[${key}] = ${er} isn't a finite number` + ); + } + } + } + } else { + expect(r.hasErrorMessages).toBe(true, "Result KO and no error message"); + } +} + /** * compare un résultat complémentaire et un tableau * @param s message @@ -259,3 +288,11 @@ export function SetJasmineCurrentSpec() { } }); } + +/** + * Test if the variable is numeric and finite + * @param x the variable to test + */ +export function isFiniteNumber(x: any) { + return isNumeric(x) && isFinite(x); +} diff --git a/src/structure/dever.ts b/src/structure/dever.ts index b2dc0e011a49f9b224d8c557041118c474dab6d4..d9aecfb5d78ef03b8d38cbf071d40782c9ba6b2f 100644 --- a/src/structure/dever.ts +++ b/src/structure/dever.ts @@ -1,5 +1,6 @@ import { CalculatorType } from "../compute-node"; import { ParamCalculability, ParamFamily } from "../param/param-definition"; +import { Message, MessageCode } from "../util/message"; import { Result } from "../util/result"; import { DeverParams } from "./dever_params"; import { ParallelStructure } from "./parallel_structure"; @@ -25,12 +26,14 @@ export class Dever extends ParallelStructure { } /** - * Calcul pour tous les paramètres - * @param sVarCalc Paramètre à calculer - * @returns Résultat avec résultats complémentaires et message + * 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", "Z2" + * ou { uid: "abcdef", symbol: "X" } avec "abcdef" l'index de l'ouvrage et "X" son paramètre + * @param rInit Valeur initiale */ - public Equation(sVarCalc: string): Result { - const r: Result = super.Equation(sVarCalc); + public Calc(sVarCalc: string | any, rInit?: number): Result { + const r = super.Calc(sVarCalc, rInit); let QT: number; if (sVarCalc === "Q") { QT = r.vCalc; @@ -38,15 +41,34 @@ export class Dever extends ParallelStructure { QT = this.prms.Q.v; } // Vitesse dans le cours d'eau amont - r.extraResults.V = QT / (this.prms.BR.v * Math.max(0, this.prms.Z1.v - this.prms.ZR.v)); - // Energie cinétique dans le cours d'eau amont - r.extraResults.Ec = r.extraResults.V * r.extraResults.V / (2 * 9.81); + if (QT !== 0 && this.prms.Z1.v > this.prms.ZR.v) { + r.extraResults.V = QT / (this.prms.BR.v * Math.max(0, this.prms.Z1.v - this.prms.ZR.v)); + } else { + r.extraResults.V = 0; + } // Calcul du rapport des aires sur les seuils et de l'aire du cours d'eau amont - const rA: number = this.calcA() / (this.prms.BR.v * Math.max(0, this.prms.Z1.v - this.prms.ZR.v)); - // Calcul de Cv - r.extraResults.Cv = this.calcCv(rA); - // Calcul de CV.QT - r.extraResults.CvQT = r.extraResults.Cv * QT; + if (this.prms.Z1.v > this.prms.ZR.v) { + // Energie cinétique dans le cours d'eau amont + r.extraResults.Ec = r.extraResults.V * r.extraResults.V / (2 * 9.81); + const rA: number = this.calcA() / (this.prms.BR.v * Math.max(0, this.prms.Z1.v - this.prms.ZR.v)); + // Calcul de Cv + r.extraResults.Cv = this.calcCv(rA); + // Calcul de CV.QT + r.extraResults.CvQT = r.extraResults.Cv * QT; + } else { + r.resultElement.addMessage(new Message(MessageCode.ERROR_DEVER_ZR_SUP_Z1)); + } + return r; + } + + /** + * Calcul pour tous les paramètres + * @param sVarCalc Paramètre à calculer + * @returns Résultat avec résultats complémentaires et message + */ + public Equation(sVarCalc: string): Result { + const r: Result = super.Equation(sVarCalc); + return r; } diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts index 7fb2fd268d43995b685a7af49c954facf10d8759..bac6ffb80e450e4e44b5ad54c74a41a7c4444d40 100644 --- a/src/structure/parallel_structure.ts +++ b/src/structure/parallel_structure.ts @@ -127,7 +127,7 @@ export class ParallelStructure extends Nub { } // Pour les caractéristiques des ouvrages const structureIndex = this.getIndexForChild(sVarCalc.uid); - this.currentResult = this.CalcStructPrm(structureIndex, sVarCalc.symbol); + this.currentResult = this.CalcStructPrm(structureIndex, sVarCalc.symbol, rInit); if (this.result.ok) { // Suppression des extraResults : ils sont complétés plus bas pour chaque ouvrage this.result.resultElement.extraResults = {}; diff --git a/src/structure/rectangular_structure_params.ts b/src/structure/rectangular_structure_params.ts index ce1f454bbabbc7518cdbb3d0f123bf666214b441..f87d48855f4441ca71d79ee585409a4e51a80115 100644 --- a/src/structure/rectangular_structure_params.ts +++ b/src/structure/rectangular_structure_params.ts @@ -1,5 +1,5 @@ import { ParamDefinition, ParamFamily } from "../param/param-definition"; -import { ParamDomainValue } from "../param/param-domain"; +import { ParamDomain, ParamDomainValue } from "../param/param-domain"; import { StructureParams } from "./structure_params"; /** @@ -34,11 +34,12 @@ export class RectangularStructureParams extends StructureParams { super(rQ, rZDV, rZ1, rZ2, rW); this.L = new ParamDefinition(this, "L", ParamDomainValue.POS, "m", rL, ParamFamily.WIDTHS); this.addParamDefinition(this.L); - this.CdGR = new ParamDefinition(this, "CdGR", ParamDomainValue.POS, undefined, rCd); + const domainCd = new ParamDomain(ParamDomainValue.INTERVAL, 0, 10); + this.CdGR = new ParamDefinition(this, "CdGR", domainCd, undefined, rCd); this.addParamDefinition(this.CdGR); - this.CdWR = new ParamDefinition(this, "CdWR", ParamDomainValue.POS, undefined, rCd); + this.CdWR = new ParamDefinition(this, "CdWR", domainCd, undefined, rCd); this.addParamDefinition(this.CdWR); - this.CdWSL = new ParamDefinition(this, "CdWSL", ParamDomainValue.POS, undefined, rCd); + this.CdWSL = new ParamDefinition(this, "CdWSL", domainCd, undefined, rCd); this.addParamDefinition(this.CdWSL); } } diff --git a/src/structure/structure_orifice_submerged_params.ts b/src/structure/structure_orifice_submerged_params.ts index e11832e0ce49add6d9348abb901f48f83238f468..f98349c6c8ef9623b930054aecc8f74e566045b4 100644 --- a/src/structure/structure_orifice_submerged_params.ts +++ b/src/structure/structure_orifice_submerged_params.ts @@ -1,5 +1,5 @@ import { ParamDefinition, ParamFamily } from "../param/param-definition"; -import { ParamDomainValue } from "../param/param-domain"; +import { ParamDomain, ParamDomainValue } from "../param/param-domain"; import { StructureParams } from "../structure/structure_params"; /** @@ -26,7 +26,7 @@ export class StructureOrificeSubmergedParams extends StructureParams { super(rQ, 100, rZ1, rZ2); this.S = new ParamDefinition(this, "S", ParamDomainValue.POS_NULL, "m²", rS); this.addParamDefinition(this.S); - this.CdO = new ParamDefinition(this, "CdO", ParamDomainValue.POS_NULL, undefined, rCd); + this.CdO = new ParamDefinition(this, "CdO", new ParamDomain(ParamDomainValue.INTERVAL, 0, 10), undefined, rCd); this.addParamDefinition(this.CdO); // hide params this.ZDV.visible = false; diff --git a/src/structure/structure_triangular_trunc_weir_params.ts b/src/structure/structure_triangular_trunc_weir_params.ts index fdf2a0f539fbf2186bcfeb446f0925f1da23dbfb..b41071a2840b1b9e05e246206b3341945fc1b0af 100644 --- a/src/structure/structure_triangular_trunc_weir_params.ts +++ b/src/structure/structure_triangular_trunc_weir_params.ts @@ -1,5 +1,5 @@ import { ParamDefinition, ParamFamily } from "../param/param-definition"; -import { ParamDomainValue } from "../param/param-domain"; +import { ParamDomain, ParamDomainValue } from "../param/param-domain"; import { StructureParams } from "./structure_params"; /** @@ -36,7 +36,7 @@ export class TriangularTruncStructureParams extends StructureParams { this.addParamDefinition(this.BT); this.ZT = new ParamDefinition(this, "ZT", ParamDomainValue.POS, "m", rZT, ParamFamily.ELEVATIONS); this.addParamDefinition(this.ZT); - this.CdT = new ParamDefinition(this, "CdT", ParamDomainValue.POS, undefined, rCd); + this.CdT = new ParamDefinition(this, "CdT", new ParamDomain(ParamDomainValue.INTERVAL, 0, 10), undefined, rCd); this.addParamDefinition(this.CdT); } } diff --git a/src/structure/structure_triangular_weir_params.ts b/src/structure/structure_triangular_weir_params.ts index 1c03b749f2e22ac0d6be661687422e088438e749..3e9022973814226c5fac4dea290e64f6009a1e78 100644 --- a/src/structure/structure_triangular_weir_params.ts +++ b/src/structure/structure_triangular_weir_params.ts @@ -1,5 +1,5 @@ import { ParamDefinition, ParamFamily } from "../param/param-definition"; -import { ParamDomainValue } from "../param/param-domain"; +import { ParamDomain, ParamDomainValue } from "../param/param-domain"; import { StructureParams } from "./structure_params"; /** @@ -30,7 +30,7 @@ export class TriangularStructureParams extends StructureParams { super(rQ, rZDV, rZ1, rZ2, rW); this.alpha2 = new ParamDefinition(this, "alpha2", ParamDomainValue.POS, "°", rAlpha2); this.addParamDefinition(this.alpha2); - this.CdT = new ParamDefinition(this, "CdT", ParamDomainValue.POS, undefined, rCd); + this.CdT = new ParamDefinition(this, "CdT", new ParamDomain(ParamDomainValue.INTERVAL, 0, 10), undefined, rCd); this.addParamDefinition(this.CdT); } } diff --git a/src/util/message.ts b/src/util/message.ts index d9f8d210e1a127f3936909c1dd02f91c7d4bf415..a08100a50335de7884e0039d7ab55a8d14a9b6e3 100644 --- a/src/util/message.ts +++ b/src/util/message.ts @@ -133,6 +133,11 @@ export enum MessageCode { */ ERROR_PAB_CALC_Z1_CLOISON, + /** + * Dever : La cote du lit de la rivière ne peut pas être supérieure à la cote de l'eau + */ + ERROR_DEVER_ZR_SUP_Z1, + /** * internationalisation : langue non prise en charge */