From 638bb28dab44d9228d25d77d7248341f734498ca Mon Sep 17 00:00:00 2001
From: "mathias.chouet" <mathias.chouet@irstea.fr>
Date: Thu, 31 Oct 2019 13:58:44 +0100
Subject: [PATCH] Fix #165 - new discharge law WeirSubmerged

---
 spec/iterator/param_equation.spec.ts          |  2 +-
 .../structure_weir_submerged.spec.ts          | 44 +++++++++++++
 src/structure/factory_structure.ts            |  6 ++
 src/structure/rectangular_structure.ts        |  1 +
 src/structure/rectangular_structure_params.ts |  4 ++
 src/structure/structure_props.ts              |  2 +
 src/structure/structure_weir_submerged.ts     | 63 +++++++++++++++++++
 src/util/message.ts                           |  5 ++
 8 files changed, 126 insertions(+), 1 deletion(-)
 create mode 100644 spec/structure/structure_weir_submerged.spec.ts
 create mode 100644 src/structure/structure_weir_submerged.ts

diff --git a/spec/iterator/param_equation.spec.ts b/spec/iterator/param_equation.spec.ts
index 3424d7cc..2cf32785 100644
--- a/spec/iterator/param_equation.spec.ts
+++ b/spec/iterator/param_equation.spec.ts
@@ -39,7 +39,7 @@ describe("iterator  : ", () => {
         pst.addChild(st);
 
         const symbs = [
-            "Q", "Z1", "Z2", "CdWR", "CdGR", "CdWSL", "h1", "h2", "L", "Q", "W", "Z1", "Z2", "ZDV"
+            "Q", "Z1", "Z2", "CdWR", "CdGR", "CdWSL", "CdWS", "h1", "h2", "L", "Q", "W", "Z1", "Z2", "ZDV"
         ];
         const vals = [1, 2, 3];
         checkParams(pst.parameterIterator, symbs, vals);
diff --git a/spec/structure/structure_weir_submerged.spec.ts b/spec/structure/structure_weir_submerged.spec.ts
new file mode 100644
index 00000000..77e08f3b
--- /dev/null
+++ b/spec/structure/structure_weir_submerged.spec.ts
@@ -0,0 +1,44 @@
+import { RectangularStructureParams } from "../../src/structure/rectangular_structure_params";
+import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
+import { StructureWeirSubmerged } from "../../src/structure/structure_weir_submerged";
+import { MessageCode } from "../../src/util/message";
+import { itCalcQ } from "../structure/functions";
+import { precDigits } from "../test_config";
+
+function getStructTest(): StructureWeirSubmerged {
+    return  new StructureWeirSubmerged(new RectangularStructureParams(0, 101, 102, 101.5, 0.2, 0.9), false);
+}
+
+describe("Class StructureWeirSubmerged: ", () => {
+    describe("Calc(Q): ", () => {
+        const Z1: number[] = [102];
+        const Q: number[] = [0.282];
+        const mode: StructureFlowMode = StructureFlowMode.WEIR;
+        const regime: StructureFlowRegime = StructureFlowRegime.SUBMERGED;
+        for (let i = 0; i < Q.length; i++) {
+            itCalcQ(getStructTest(), Z1[i], Infinity, Q[i], mode, regime);
+        }
+    });
+    describe("Calc(Z1): ", () => {
+        it("Z1(Q=0.780) should be 75.234", () => {
+            const testZ1 = new StructureWeirSubmerged(
+                new RectangularStructureParams(0.780, 73.665, 75.301, 75.077, 0.35, 0.9),
+                false);
+            testZ1.prms.Z1.v = 100; // Test with initial condition far from solution
+            expect(testZ1.Calc("Z1").vCalc).toBeCloseTo(75.234, precDigits);
+        });
+    });
+    describe("Calcul avec h2/h1 < 0.8 (=0.5) : ", () => {
+        it("le log devrait contenir 1 message", () => {
+            const structTest = getStructTest();
+            structTest.prms.Z1.singleValue = 110;
+            structTest.prms.Z2.singleValue = 105;
+            structTest.prms.ZDV.singleValue = 100;
+            const res = structTest.CalcSerie().resultElement;
+            expect(res.log.messages.length).toBe(1);
+            expect(
+                res.log.messages[0].code
+            ).toBe(MessageCode.WARNING_WEIR_SUBMERSION_LOWER_THAN_08);
+        });
+    });
+});
diff --git a/src/structure/factory_structure.ts b/src/structure/factory_structure.ts
index c1a3ff9c..4d45b653 100755
--- a/src/structure/factory_structure.ts
+++ b/src/structure/factory_structure.ts
@@ -28,6 +28,7 @@ import { StructureWeirCem88d } from "./structure_weir_cem88d";
 import { StructureWeirCem88v } from "./structure_weir_cem88v";
 import { StructureWeirCunge80 } from "./structure_weir_cunge80";
 import { StructureWeirFree } from "./structure_weir_free";
+import { StructureWeirSubmerged } from "./structure_weir_submerged";
 import { StructureWeirSubmergedLarinier } from "./structure_weir_submerged_larinier";
 import { StructureWeirVillemonte } from "./structure_weir_villemonte";
 
@@ -105,6 +106,11 @@ export function CreateStructure(loiDebit: LoiDebit, parentNub?: ParallelStructur
             ret = new StructureWeirSubmergedLarinier(rectStructPrms, dbg);
             break;
 
+        case LoiDebit.WeirSubmerged:
+            rectStructPrms.CdWS.singleValue = 0.9;
+            ret = new StructureWeirSubmerged(rectStructPrms, dbg);
+            break;
+
         case LoiDebit.KIVI:
             const structKiviPrm: StructureKiviParams = new StructureKiviParams(
                 8.516,      // Q
diff --git a/src/structure/rectangular_structure.ts b/src/structure/rectangular_structure.ts
index b5834c3d..366124d1 100644
--- a/src/structure/rectangular_structure.ts
+++ b/src/structure/rectangular_structure.ts
@@ -11,6 +11,7 @@ export abstract class RectangularStructure extends Structure {
         super(prms, dbg);
         this.prms.CdGR.visible = false;
         this.prms.CdWR.visible = false;
+        this.prms.CdWS.visible = false;
         this.prms.CdWSL.visible = false;
     }
 
diff --git a/src/structure/rectangular_structure_params.ts b/src/structure/rectangular_structure_params.ts
index f87d4885..10e16075 100644
--- a/src/structure/rectangular_structure_params.ts
+++ b/src/structure/rectangular_structure_params.ts
@@ -19,6 +19,8 @@ export class RectangularStructureParams extends StructureParams {
     public CdWR: ParamDefinition;
     // tslint:disable-next-line:variable-name
     public CdWSL: ParamDefinition;
+    // tslint:disable-next-line:variable-name
+    public CdWS: ParamDefinition;
 
     /**
      * Constructeur d'une structure rectangulaire
@@ -41,5 +43,7 @@ export class RectangularStructureParams extends StructureParams {
         this.addParamDefinition(this.CdWR);
         this.CdWSL = new ParamDefinition(this, "CdWSL", domainCd, undefined, rCd);
         this.addParamDefinition(this.CdWSL);
+        this.CdWS = new ParamDefinition(this, "CdWS", domainCd, undefined, rCd);
+        this.addParamDefinition(this.CdWS);
     }
 }
diff --git a/src/structure/structure_props.ts b/src/structure/structure_props.ts
index 60141db9..3e345bad 100644
--- a/src/structure/structure_props.ts
+++ b/src/structure/structure_props.ts
@@ -35,6 +35,8 @@ export enum LoiDebit {
     TriangularTruncWeirFree,
     // Loi de débit fente noyée (Larinier 1992)
     WeirSubmergedLarinier,
+    // Loi de débit fente noyée (Rajaratnam & Muralidhar 1969)
+    WeirSubmerged,
     // Loi de débit orifice noyé
     OrificeSubmerged,
     // Loi de débit orifice dénoyé
diff --git a/src/structure/structure_weir_submerged.ts b/src/structure/structure_weir_submerged.ts
new file mode 100644
index 00000000..3a9320d5
--- /dev/null
+++ b/src/structure/structure_weir_submerged.ts
@@ -0,0 +1,63 @@
+import { Message, MessageCode, ParamCalculability } from "../index";
+import { Result } from "../util/result";
+import { RectangularStructure } from "./rectangular_structure";
+import { RectangularStructureParams } from "./rectangular_structure_params";
+import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
+
+/**
+ * Equation de la fente noyée
+ * d'après Rajaratnam, N., et D. Muralidhar.
+ * « Flow below deeply submerged rectangular weirs ».
+ * Journal of Hydraulic Research 7, nᵒ 3 (1969): 355–374.
+ */
+export class StructureWeirSubmerged extends RectangularStructure {
+
+    constructor(prms: RectangularStructureParams, dbg: boolean = false) {
+        super(prms, dbg);
+        this._loiDebit = LoiDebit.WeirSubmerged;
+        this.prms.CdWS.visible = true;
+    }
+
+    public Calc(sVarCalc: string, rInit?: number): Result {
+        this.currentResult = super.Calc(sVarCalc, rInit);
+        const h2h1ratio = this.prms.h2.v / this.prms.h1.v;
+        if (h2h1ratio < 0.8) {
+            this._result.resultElement.addMessage(new Message(
+                MessageCode.WARNING_WEIR_SUBMERSION_LOWER_THAN_08,
+                { h1: this.prms.h1.v, h2: this.prms.h2.v }
+            ));
+        }
+        return this._result;
+    }
+
+    /**
+     * Calcul analytique Q
+     * @param sVarCalc Variable à calculer (doit être "Q")
+     */
+    public CalcQ(): Result {
+        const data = this.getResultData();
+
+        const v = this.prms.CdWS.v * this.prms.L.v * Structure.R2G
+            * this.prms.h2.v * Math.sqrt(this.prms.h1.v - this.prms.h2.v);
+
+        return new Result(v, this, data);
+    }
+
+    protected getFlowRegime() {
+        return StructureFlowRegime.SUBMERGED;
+    }
+
+    protected getFlowMode() {
+        return StructureFlowMode.WEIR;
+    }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.L.calculability = ParamCalculability.DICHO;
+        this.prms.CdWS.calculability = ParamCalculability.DICHO;
+    }
+}
diff --git a/src/util/message.ts b/src/util/message.ts
index 85b16c79..ae2dc255 100644
--- a/src/util/message.ts
+++ b/src/util/message.ts
@@ -352,6 +352,11 @@ export enum MessageCode {
      */
     WARNING_SLOT_SUBMERSION_NOT_BETWEEN_07_AND_09,
 
+    /**
+     * La formule du seuil noyé n'est pas conseillé pour un ennoiement inférieur à 0.8
+     */
+    WARNING_WEIR_SUBMERSION_LOWER_THAN_08,
+
     /**
      * Vanne levante : ZDV > ZDV max
      */
-- 
GitLab