From ec287517647c3eb8279cb3afd17b076287fce2ee Mon Sep 17 00:00:00 2001 From: David Dorchies <david.dorchies@irstea.fr> Date: Mon, 6 Nov 2017 12:24:32 +0100 Subject: [PATCH] =?UTF-8?q?#6=20Cr=C3=A9ation=20de=20la=20classe=20de=20ba?= =?UTF-8?q?se=20des=20ouvrages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/structure/structure.spec.ts | 118 +++++++++++++++++++++++ src/structure/structure.ts | 156 +++++++++++++++++++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 spec/structure/structure.spec.ts create mode 100644 src/structure/structure.ts diff --git a/spec/structure/structure.spec.ts b/spec/structure/structure.spec.ts new file mode 100644 index 00000000..ea18f087 --- /dev/null +++ b/spec/structure/structure.spec.ts @@ -0,0 +1,118 @@ +/// <reference path="../../node_modules/@types/jasmine/index.d.ts" /> + +import { Structure, StructureParams, StructureFlowMode, StructureFlowRegime} from "../../src/structure/structure"; +import { Result } from "../../src/base"; +import { equalEpsilon } from "../nubtest"; + +function check(val1: Result, val2: number) { + expect(equalEpsilon(val1.vCalc, val2)).toBe(true); +} + + +class StructureTestParams extends StructureParams { + +} + + +class StructureTest extends Structure { + + constructor(prms: StructureTestParams, dbg: boolean = false) { + super(prms, dbg); + this.setParametersCalculability(); + } + + Equation(sVarCalc: string): Result { + let res: Result; + let v: number; + + switch (sVarCalc) { + case "Q": + v = this.prms.h1.v-this.prms.h2.v; + break; + default: + throw 'StructureTest.Equation() : invalid parameter name ' + sVarCalc; + } + + return res; + } + + /** + * Test of getFlowMode + */ + public testGetFlowMode() { + return this.getFlowMode(); + } + + /** + * Test of getFlowRegime + */ + public testGetFlowRegime() { + return this.getFlowRegime(); + } + +} + + +let structTestPrm: StructureParams = new StructureTestParams(1, 30, 15); +let structTest: StructureTest = new StructureTest(structTestPrm, true); + + +describe('Class Structure: ', () => { + + describe('getFlowMode()', () => { + it('Flow Mode should be WEIR', () => { + expect(structTest.testGetFlowMode()).toBe(StructureFlowMode.WEIR); + }); + it('Flow Mode should be ORIFICE', () => { + structTest.prms.W.v = 10; + expect(structTest.testGetFlowMode()).toBe(StructureFlowMode.ORIFICE); + structTest.prms.W.v = Infinity; + }); + }); + + describe('getFlowRegime()', () => { + it('Flow Regime should be FREE', () => { + expect(structTest.testGetFlowRegime()).toBe(StructureFlowRegime.FREE); + }); + it('Flow Regime should be SUBMERGED (WEIR)', () => { + structTest.prms.h2.v = 21; + expect(structTest.testGetFlowRegime()).toBe(StructureFlowRegime.SUBMERGED); + }); + it('Flow Regime should be PARTIAL (ORIFICE)', () => { + structTest.prms.h2.v = 21; + structTest.prms.W.v = 15; + expect(structTest.testGetFlowRegime()).toBe(StructureFlowRegime.PARTIAL); + }); + it('Flow Regime should be SUBMERGED (ORIFICE)', () => { + structTest.prms.h2.v = 25; + structTest.prms.W.v = 15; + expect(structTest.testGetFlowRegime()).toBe(StructureFlowRegime.SUBMERGED); + }); + structTest.prms.h2.v = 15; + structTest.prms.W.v = Infinity; + }); + describe('Calc()', () => { + it('h1=h2 => Q=0', () => { + structTest.prms.h2.v = structTest.prms.h1.v; + check(structTest.Calc('Q'),0); + structTest.prms.h2.v = 15; + }); + it('W=0 => Q=0', () => { + structTest.prms.W.v = 0; + check(structTest.Calc('Q'),0); + structTest.prms.W.v = Infinity; + }); + it('Q=0 => h1=h2', () => { + structTest.prms.Q.v = 0; + check(structTest.Calc('h1'),structTest.prms.h2.v); + structTest.prms.Q.v = 1; + }); + it('Q=0 => W=0', () => { + structTest.prms.Q.v = 0; + check(structTest.Calc('W'),0); + structTest.prms.Q.v = 1; + }); + // TODO Test inversion de débit + + }); +}); \ No newline at end of file diff --git a/src/structure/structure.ts b/src/structure/structure.ts new file mode 100644 index 00000000..9b41135c --- /dev/null +++ b/src/structure/structure.ts @@ -0,0 +1,156 @@ +/** + * @file structure/structure.ts Base classes for hydraulic structure equations + */ +import { Result } from "../base"; +import { ComputeNodeType, ParamDefinition, ParamDomain, ParamDomainValue, ParamCalculability, ParamsEquation } from "../param"; +import { Nub } from "../nub"; + + +/** + * Common parameters of hydraulic structure equations + */ +export abstract class StructureParams extends ParamsEquation { + /** Débit */ + Q: ParamDefinition; + + /** Tirant d'eau amont */ + h1: ParamDefinition; + + /** Tirant d'eau aval */ + h2: ParamDefinition; + + /** Ouverture de la vanne + * @note Pour un seuil cette valeur vaut Infinity + */ + W: ParamDefinition; + + constructor(rQ: number, rh1: number, rh2: number, rW: number = Infinity ) { + super(); + this.Q = new ParamDefinition(ComputeNodeType.CondDistri, 'Q', ParamDomainValue.POS_NULL, rQ); + this.h1 = new ParamDefinition(ComputeNodeType.CondDistri, 'h1', ParamDomainValue.POS_NULL, rh1); + this.h2 = new ParamDefinition(ComputeNodeType.CondDistri, 'h2', ParamDomainValue.POS_NULL, rh2); + this.W = new ParamDefinition(ComputeNodeType.CondDistri, 'W', ParamDomainValue.POS_NULL, rW); + } +} + + +/** +* Flow mode: weir or orifice flow +*/ +export enum StructureFlowMode { + /** Weir flow */ + WEIR, + /** Orifice flow */ + ORIFICE +} + + +/** +* Flow regime: free flow, partially submerged or submerged +*/ +export enum StructureFlowRegime { + /** Free flow (unsubmerged) */ + FREE, + /** Partially submerged flow */ + PARTIAL, + /** Submerged flow */ + SUBMERGED + } + + +/** + * classe de calcul sur la conduite distributrice + */ +export abstract class Structure extends Nub { + constructor(prms: StructureParams, dbg: boolean = false) { + super(prms, dbg); + } + + + /** + * paramètres castés au bon type + */ + get prms(): StructureParams { + return <StructureParams>this._prms; + } + + + /** + * paramétrage de la calculabilité des paramètres + */ + protected setParametersCalculability() { + this.prms.Q.calculability = ParamCalculability.EQUATION; + this.prms.h1.calculability = ParamCalculability.DICHO; + this.prms.h2.calculability = ParamCalculability.DICHO; + this.prms.W.calculability = ParamCalculability.DICHO; + } + + + /** + * Give the flow mode : weir or orifice flow + */ + protected getFlowMode(): StructureFlowMode { + if (this.prms.h1.v >= this.prms.W.v) return StructureFlowMode.ORIFICE; + return StructureFlowMode.WEIR; + } + + + /** + * Give the flow regime for a rectangular section : free, partially submerged or submerged flow + */ + protected getFlowRegime(): StructureFlowRegime { + // Weir have only two flow regimes: free and submerged flow + // Orifice have three flow regimes: free, partially submerged and (totally) submerged + if(this.prms.h2.v <= 2/3*this.prms.h1.v) { + // free flow for both weirs and orifices + return StructureFlowRegime.FREE; + } else if(this.prms.h1.v > this.prms.W.v && this.prms.h2.v < (2*this.prms.h1.v + this.prms.W.v)/3) { + // Partially submerged only for orifices + return StructureFlowRegime.PARTIAL; + } else { + // (Totally) submerged for both weirs and orifices + return StructureFlowRegime.SUBMERGED; + } + } + + + /** + * Calcul d'une équation quelque soit l'inconnue à calculer. + * Gestion du débit nul et de l'inversion de débit + * @param sVarCalc nom de la variable à calculer + * @param rInit valeur initiale de la variable à calculer dans le cas de la dichotomie + * @param rPrec précision de calcul + */ + Calc(sVarCalc: string, rInit: number = 0, rPrec: number = 0.001): Result { + + // Gestion du débit nul + if(sVarCalc == 'Q') { + if(this.prms.h1.v == this.prms.h2.v || this.prms.W.v <= 0) { + return new Result(0); + } + } 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 "h1" : + return new Result(this.prms.h2.v); + case "h2" : + return new Result(this.prms.h1.v); + default : + return new Result(0); // Est-ce toujours vrai ? Nécessitera peut-être d'étendre la méthode + } + } + + // Gestion de l'inversion de débit : on inverse l'amont et l'aval pour le calcul + if((sVarCalc == 'Q' && (this.prms.h1.v < this.prms.h2.v)) || (sVarCalc != 'Q' && this.prms.Q.v < 0)) { + [this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion + let res: Result; + res = super.Calc(sVarCalc, rInit, rPrec); + [this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion + return res; + } + + return super.Calc(sVarCalc, rInit, rPrec); + + } + +} \ No newline at end of file -- GitLab