From 7872c66f1f9a9ad8beb21b1a314cbae89fa46dcc Mon Sep 17 00:00:00 2001
From: David Dorchies <david.dorchies@irstea.fr>
Date: Tue, 19 Jun 2018 14:05:37 +0200
Subject: [PATCH] =?UTF-8?q?#29=20Ajout=20de=20l'=C3=A9quation=20du=20seuil?=
 =?UTF-8?q?=20triangulaire=20d=C3=A9noy=C3=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...{rectangular_structure.ts => functions.ts} |  9 ++--
 spec/structure/parallel_structure.spec.ts     | 11 ++++-
 spec/structure/structure_cem88d.spec.ts       |  2 +-
 spec/structure/structure_cem88v.spec.ts       |  2 +-
 spec/structure/structure_cunge80.spec.ts      |  2 +-
 spec/structure/structure_kivi.spec.ts         |  5 +--
 spec/structure/structure_orifice_free.spec.ts |  2 +-
 .../structure_orifice_submerged.spec.ts       |  2 +-
 .../structure_triangular_weir_free.spec.ts    | 28 +++++++++++++
 spec/structure/structure_weir_free.spec.ts    |  2 +-
 src/structure/factory_structure.ts            | 31 +++++++++-----
 src/structure/rectangular_structure_params.ts |  1 -
 src/structure/structure_props.ts              |  9 +++-
 .../structure_triangular_weir_free.ts         | 41 +++++++++++++++++++
 src/structure/triangular_structure.ts         | 32 +++++++++++++++
 src/structure/triangular_structure_params.ts  | 36 ++++++++++++++++
 16 files changed, 186 insertions(+), 29 deletions(-)
 rename spec/structure/{rectangular_structure.ts => functions.ts} (78%)
 create mode 100644 spec/structure/structure_triangular_weir_free.spec.ts
 create mode 100644 src/structure/structure_triangular_weir_free.ts
 create mode 100644 src/structure/triangular_structure.ts
 create mode 100644 src/structure/triangular_structure_params.ts

diff --git a/spec/structure/rectangular_structure.ts b/spec/structure/functions.ts
similarity index 78%
rename from spec/structure/rectangular_structure.ts
rename to spec/structure/functions.ts
index 8895e09c..853eecc8 100644
--- a/spec/structure/rectangular_structure.ts
+++ b/spec/structure/functions.ts
@@ -5,15 +5,15 @@
  */
 // import { describe, expect, it, xdescribe } from "../mock_jasmine";
 
-import { RectangularStructure } from "../../src/structure/rectangular_structure";
+import { Structure } from "../../src/structure/structure";
 import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
 import { Describer } from "../../src/util/describer";
 import { Result } from "../../src/util/result";
 import { precDigits } from "../test_config";
 
 export function itCalcQ(
-    struct: RectangularStructure, Z1: number, W: number, Q: number,
-    mode?: StructureFlowMode, regime?: StructureFlowRegime) {
+    struct: Structure, Z1: number, W: number, Q: number,
+    mode?: StructureFlowMode, regime?: StructureFlowRegime, precDigits2?: number) {
 
     struct.debug("itCalQ " + Describer.getName(struct) + " Z1=" + Z1 + " W=" + W + " Q=" + Q);
 
@@ -23,8 +23,9 @@ export function itCalcQ(
     struct.debug("struct.Calc(Q)=" + res.vCalc);
 
     it("Q(Z1=" + Z1 + ",W=" + W + ") should be " + Q, () => {
+        if (precDigits2 === undefined) { precDigits2 = precDigits; }
         struct.debug("struct.Calc(Q)=" + res.vCalc);
-        expect(res.vCalc).toBeCloseTo(Q, precDigits);
+        expect(res.vCalc).toBeCloseTo(Q, precDigits2);
     });
     if (mode !== undefined) {
         it("Q(Z1=" + Z1 + ",W=" + W + ") Mode should be " + mode, () => {
diff --git a/spec/structure/parallel_structure.spec.ts b/spec/structure/parallel_structure.spec.ts
index b7b9f988..8a4d442f 100644
--- a/spec/structure/parallel_structure.spec.ts
+++ b/spec/structure/parallel_structure.spec.ts
@@ -8,11 +8,10 @@
 
 import { ParamCalculability } from "../../src/param/param-definition";
 import { CreateStructure } from "../../src/structure/factory_structure";
-import { LoiDebit, StructureType, loiAdmissibles } from "../../src/structure/structure_props";
 import { ParallelStructure } from "../../src/structure/parallel_structure";
 import { ParallelStructureParams } from "../../src/structure/parallel_structure_params";
 import { Structure } from "../../src/structure/structure";
-import { Describer } from "../../src/util/describer";
+import { loiAdmissibles, LoiDebit, StructureType } from "../../src/structure/structure_props";
 import { EnumEx } from "../../src/util/enum";
 import { MessageCode } from "../../src/util/message";
 import { Result } from "../../src/util/result";
@@ -136,6 +135,14 @@ describe("Class ParallelStructure: ", () => {
                                 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}`, () => {
diff --git a/spec/structure/structure_cem88d.spec.ts b/spec/structure/structure_cem88d.spec.ts
index 42521b8d..f44d486f 100644
--- a/spec/structure/structure_cem88d.spec.ts
+++ b/spec/structure/structure_cem88d.spec.ts
@@ -10,7 +10,7 @@ import { RectangularStructureParams } from "../../src/structure/rectangular_stru
 import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
 import { StructureCem88d } from "../../src/structure/structure_cem88d";
 import { Result } from "../../src/util/result";
-import { itCalcQ } from "./rectangular_structure";
+import { itCalcQ } from "./functions";
 
 const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0);
 const structTest: StructureCem88d = new StructureCem88d(structPrm, false);
diff --git a/spec/structure/structure_cem88v.spec.ts b/spec/structure/structure_cem88v.spec.ts
index fe40920c..5927b9fc 100644
--- a/spec/structure/structure_cem88v.spec.ts
+++ b/spec/structure/structure_cem88v.spec.ts
@@ -10,7 +10,7 @@ import { RectangularStructureParams } from "../../src/structure/rectangular_stru
 import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
 import { StructureCem88v } from "../../src/structure/structure_cem88v";
 import { Result } from "../../src/util/result";
-import { itCalcQ } from "./rectangular_structure";
+import { itCalcQ } from "./functions";
 
 const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0);
 const structTest: StructureCem88v = new StructureCem88v(structPrm, false);
diff --git a/spec/structure/structure_cunge80.spec.ts b/spec/structure/structure_cunge80.spec.ts
index 0940fce5..45ee33c6 100644
--- a/spec/structure/structure_cunge80.spec.ts
+++ b/spec/structure/structure_cunge80.spec.ts
@@ -10,7 +10,7 @@ import { RectangularStructureParams } from "../../src/structure/rectangular_stru
 import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
 import { StructureCunge80 } from "../../src/structure/structure_cunge80";
 import { Result } from "../../src/util/result";
-import { itCalcQ } from "./rectangular_structure";
+import { itCalcQ } from "./functions";
 
 const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0);
 const structTest: StructureCunge80 = new StructureCunge80(structPrm, false);
diff --git a/spec/structure/structure_kivi.spec.ts b/spec/structure/structure_kivi.spec.ts
index 1286b02b..d0700be7 100644
--- a/spec/structure/structure_kivi.spec.ts
+++ b/spec/structure/structure_kivi.spec.ts
@@ -6,11 +6,10 @@
  */
 // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
 
-import { StructureFlowMode, StructureFlowRegime, MessageCode } from "../../src";
+import { MessageCode, StructureFlowMode, StructureFlowRegime } from "../../src";
 import { CreateStructure } from "../../src/structure/factory_structure";
-import { LoiDebit, StructureType } from "../../src/structure/structure_props";
 import { StructureKivi } from "../../src/structure/structure_kivi";
-import { StructureKiviParams } from "../../src/structure/structure_kivi_params";
+import { LoiDebit, StructureType } from "../../src/structure/structure_props";
 import { testStructure } from "./structure_test";
 
 const structTest: StructureKivi = CreateStructure(
diff --git a/spec/structure/structure_orifice_free.spec.ts b/spec/structure/structure_orifice_free.spec.ts
index 0cefcda1..708f8ae1 100644
--- a/spec/structure/structure_orifice_free.spec.ts
+++ b/spec/structure/structure_orifice_free.spec.ts
@@ -10,7 +10,7 @@ import { RectangularStructureParams } from "../../src/structure/rectangular_stru
 import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
 import { StructureOrificeFree } from "../../src/structure/structure_orifice_free";
 import { Result } from "../../src/util/result";
-import { itCalcQ } from "./rectangular_structure";
+import { itCalcQ } from "./functions";
 
 const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0);
 const structTest: StructureOrificeFree = new StructureOrificeFree(structPrm, false);
diff --git a/spec/structure/structure_orifice_submerged.spec.ts b/spec/structure/structure_orifice_submerged.spec.ts
index 37537f16..d303605c 100644
--- a/spec/structure/structure_orifice_submerged.spec.ts
+++ b/spec/structure/structure_orifice_submerged.spec.ts
@@ -10,7 +10,7 @@ import { RectangularStructureParams } from "../../src/structure/rectangular_stru
 import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
 import { StructureOrificeSubmerged } from "../../src/structure/structure_orifice_submerged";
 import { Result } from "../../src/util/result";
-import { itCalcQ } from "./rectangular_structure";
+import { itCalcQ } from "./functions";
 
 const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0);
 const structTest: StructureOrificeSubmerged = new StructureOrificeSubmerged(structPrm, false);
diff --git a/spec/structure/structure_triangular_weir_free.spec.ts b/spec/structure/structure_triangular_weir_free.spec.ts
new file mode 100644
index 00000000..b550f075
--- /dev/null
+++ b/spec/structure/structure_triangular_weir_free.spec.ts
@@ -0,0 +1,28 @@
+/**
+ * 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 { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
+import { StructureTriangularWeirFree } from "../../src/structure/structure_triangular_weir_free";
+import { TriangularStructureParams } from "../../src/structure/triangular_structure_params";
+import { itCalcQ } from "./functions";
+
+const structPrm: TriangularStructureParams = new TriangularStructureParams(0, 100.1, 100.1, 100, 45, 1.36);
+const structTest: StructureTriangularWeirFree = new StructureTriangularWeirFree(structPrm, false);
+
+describe("Class StructureWeirFree: ", () => {
+    describe("Calcul Q a surface libre avec h1 croissant: ", () => {
+        const h1: number[] = [100.1, 100.2, 100.3, 100.4, 100.5, 100.6, 100.7, 100.8, 100.9, 101, 102];
+        const Q: number[] = [0., 0.004, 0.024, 0.067, 0.138, 0.240, 0.379, 0.558, 0.778, 1.045, 6.767];
+        const mode: StructureFlowMode = StructureFlowMode.WEIR;
+        const regime: StructureFlowRegime = StructureFlowRegime.FREE;
+        itCalcQ(structTest, h1[0], Infinity, Q[0], StructureFlowMode.NULL, StructureFlowRegime.NULL);
+        for (let i = 1; i < Q.length; i++) {
+            itCalcQ(structTest, h1[i], Infinity, Q[i], mode, regime);
+        }
+    });
+});
diff --git a/spec/structure/structure_weir_free.spec.ts b/spec/structure/structure_weir_free.spec.ts
index 6b04ce6a..a6f0f01f 100644
--- a/spec/structure/structure_weir_free.spec.ts
+++ b/spec/structure/structure_weir_free.spec.ts
@@ -10,7 +10,7 @@ import { RectangularStructureParams } from "../../src/structure/rectangular_stru
 import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
 import { StructureWeirFree } from "../../src/structure/structure_weir_free";
 import { Result } from "../../src/util/result";
-import { itCalcQ } from "./rectangular_structure";
+import { itCalcQ } from "./functions";
 
 const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0);
 const structTest: StructureWeirFree = new StructureWeirFree(structPrm, false);
diff --git a/src/structure/factory_structure.ts b/src/structure/factory_structure.ts
index abda575b..cb7846e5 100644
--- a/src/structure/factory_structure.ts
+++ b/src/structure/factory_structure.ts
@@ -7,8 +7,9 @@ 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 { StructureTriangularWeirFree, TriangularStructureParams } from "./structure_triangular_weir_free";
 import { StructureWeirFree } from "./structure_weir_free";
-import { StructureType, LoiDebit, StructureProperties } from "./structure_props";
 
 export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit, dbg: boolean = false): Structure {
     const rectStructPrms: RectangularStructureParams = new RectangularStructureParams(
@@ -20,27 +21,24 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit
         0.4        // Cd pour un seuil rectangulaire
         // W = Infinity par défaut pour un seuil
     );
+
     switch (structureType) {
         case StructureType.VanneRectangulaire:
             rectStructPrms.W.v = 0.5;
             rectStructPrms.Cd.v = 0.6; // Cd pour une vanne rectangulaire
-            if (!(StructureProperties.isCompatibleValues(StructureType.VanneRectangulaire, loiDebit))) {
-                throw new Error(
-                    `la loi de débit ${LoiDebit[loiDebit]} n'est pas admissible pour les vannes rectangulaires`
-                );
-            }
             break;
         case StructureType.SeuilRectangulaire:
-            if (!(StructureProperties.isCompatibleValues(StructureType.SeuilRectangulaire, loiDebit))) {
-                throw new Error(
-                    `la loi de débit ${LoiDebit[loiDebit]} n'est pas admissible pour les seuils rectangulaires`
-                );
-            }
+        case StructureType.SeuilTriangulaire:
             break;
 
         default:
             throw new Error(`type de structure ${StructureType[structureType]} non pris en charge`);
     }
+    if (!(StructureProperties.isCompatibleValues(structureType, loiDebit))) {
+        throw new Error(
+            `La loi de débit ${LoiDebit[loiDebit]} n'est pas admissible pour le type ${StructureType[structureType]}`
+        );
+    }
 
     switch (loiDebit) {
         case LoiDebit.Cem88d:
@@ -75,6 +73,17 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit
                 0.001,  // béta
                 100);    // ZRAM : cote Radier Amont
             return new StructureKivi(structKiviPrm, dbg);
+        case LoiDebit.TriangularWeirFree:
+            const triangStructPrms: TriangularStructureParams = new TriangularStructureParams(
+                0,  // Q
+                100,        // ZDV
+                102,        // Z1
+                101.5,      // Z2
+                45,          // Alpha2
+                1.36        // Cd pour un seuil triangulaire
+                // W = Infinity par défaut pour un seuil
+            );
+            return new StructureTriangularWeirFree(triangStructPrms, dbg);
 
         default:
             throw new Error(`type de LoiDebit ${LoiDebit[loiDebit]} non pris en charge`);
diff --git a/src/structure/rectangular_structure_params.ts b/src/structure/rectangular_structure_params.ts
index 5a2df407..0f157d44 100644
--- a/src/structure/rectangular_structure_params.ts
+++ b/src/structure/rectangular_structure_params.ts
@@ -1,6 +1,5 @@
 import { ParamDefinition } from "../param/param-definition";
 import { ParamDomainValue } from "../param/param-domain";
-import { Structure } from "./structure";
 import { StructureParams } from "./structure_params";
 
 /**
diff --git a/src/structure/structure_props.ts b/src/structure/structure_props.ts
index 7c7d63a4..aa0b73f1 100644
--- a/src/structure/structure_props.ts
+++ b/src/structure/structure_props.ts
@@ -1,5 +1,5 @@
 export enum StructureType {
-    SeuilRectangulaire, VanneRectangulaire
+    SeuilRectangulaire, VanneRectangulaire, SeuilTriangulaire
     // VanneCirculaire,
     // VanneTrapezoidale, SeuilTrapezoidal
 }
@@ -18,7 +18,9 @@ export enum LoiDebit {
     // loi de débit pour seuil dénoyé
     WeirFree,
     // Loi Kindsvater-Carter et Villemonte
-    KIVI
+    KIVI,
+    // Loi de débit seuil triangulaire dénoyé
+    TriangularWeirFree
 }
 
 export const loiAdmissibles: { [key: string]: LoiDebit[] } = {
@@ -26,6 +28,9 @@ export const loiAdmissibles: { [key: string]: LoiDebit[] } = {
         LoiDebit.Cem88d, LoiDebit.Cem88v, LoiDebit.Cunge80, LoiDebit.WeirFree,
         LoiDebit.KIVI
     ],
+    SeuilTriangulaire: [
+        LoiDebit.TriangularWeirFree
+    ],
     VanneRectangulaire: [
         LoiDebit.Cem88d, LoiDebit.Cem88v, LoiDebit.Cunge80, LoiDebit.OrificeFree,
         LoiDebit.OrificeSubmerged
diff --git a/src/structure/structure_triangular_weir_free.ts b/src/structure/structure_triangular_weir_free.ts
new file mode 100644
index 00000000..fc87d58a
--- /dev/null
+++ b/src/structure/structure_triangular_weir_free.ts
@@ -0,0 +1,41 @@
+import { Result } from "../util/result";
+import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { TriangularStructure } from "./triangular_structure";
+import { TriangularStructureParams } from "./triangular_structure_params";
+
+export { TriangularStructureParams };
+
+/**
+ * Equation classique seuil triangulaire dénoyé
+ */
+export class StructureTriangularWeirFree extends TriangularStructure {
+    /**
+     * 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.getTanFromDegrees(this.prms.alpha2.v)
+            * Math.pow(this.prms.h1.v, 2.5);
+
+        return new Result(v, data);
+    }
+
+    protected getFlowRegime() {
+        return StructureFlowRegime.FREE;
+    }
+
+    protected getFlowMode() {
+        return StructureFlowMode.WEIR;
+    }
+
+    /**
+     * Compute Tangent with angle in degrees
+     * @param degrees Angle (degrees)
+     */
+    protected getTanFromDegrees(degrees: number) {
+        return Math.tan(degrees * Math.PI / 180);
+      }
+}
diff --git a/src/structure/triangular_structure.ts b/src/structure/triangular_structure.ts
new file mode 100644
index 00000000..3ff33cb7
--- /dev/null
+++ b/src/structure/triangular_structure.ts
@@ -0,0 +1,32 @@
+import { ParamCalculability } from "../param/param-definition";
+import { Structure } from "./structure";
+import { TriangularStructureParams } from "./triangular_structure_params";
+
+export { TriangularStructureParams };
+
+/**
+ * Classe mère pour toutes les structures ayant une base rectangulaire (vannes, seuils)
+ */
+export abstract class TriangularStructure extends Structure {
+
+    constructor(prms: TriangularStructureParams, dbg: boolean = false) {
+        super(prms, dbg);
+    }
+
+    /**
+     * paramètres castés au bon type
+     */
+    get prms(): TriangularStructureParams {
+        return this._prms as TriangularStructureParams;
+    }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.alpha2.calculability = ParamCalculability.DICHO;
+        this.prms.Cd.calculability = ParamCalculability.DICHO;
+    }
+
+}
diff --git a/src/structure/triangular_structure_params.ts b/src/structure/triangular_structure_params.ts
new file mode 100644
index 00000000..306b94ac
--- /dev/null
+++ b/src/structure/triangular_structure_params.ts
@@ -0,0 +1,36 @@
+import { ParamDefinition } from "../param/param-definition";
+import { ParamDomainValue } from "../param/param-domain";
+import { StructureParams } from "./structure_params";
+
+/**
+ * Parameters for rectangular structures (common for all rectangular structure equations)
+ */
+export class TriangularStructureParams extends StructureParams {
+    /** half angle of the triangle top (degrees) */
+    public alpha2: ParamDefinition;
+
+    /** Discharge coefficient */
+    // tslint:disable-next-line:variable-name
+    public Cd: ParamDefinition;
+
+    /**
+     * Constructeur d'une structure rectangulaire
+     * @param rQ    Débit (m3/s)
+     * @param rZDV  Cote de la crête du déversoir ou du radier de la vanne (m)
+     * @param rZ1   Cote de l'eau amont (m)
+     * @param rZ2   Cote de l'eau aval (m)
+     * @param rAlpha2    Demi-angle au sommet du triangle (degrés)
+     * @param rCd   Coefficient de débit (-)
+     * @param rW    Ouverture de la vanne (m) (Valeur par défaut +infinity pour les déversoirs)
+     */
+    constructor(
+        rQ: number, rZDV: number, rZ1: number, rZ2: number,
+        rAlpha2: number, rCd: number, rW: number = Infinity
+    ) {
+        super(rQ, rZDV, rZ1, rZ2, rW);
+        this.alpha2 = new ParamDefinition("alpha2", ParamDomainValue.POS, rAlpha2);
+        this.addParamDefinition(this.alpha2);
+        this.Cd = new ParamDefinition("Cd", ParamDomainValue.POS, rCd);
+        this.addParamDefinition(this.Cd);
+    }
+}
-- 
GitLab