From 99b9bef6f212bc8880a04eeab2a435d4bbbea336 Mon Sep 17 00:00:00 2001
From: David Dorchies <david.dorchies@irstea.fr>
Date: Fri, 9 Feb 2018 18:26:58 +0100
Subject: [PATCH] =?UTF-8?q?#38=20Ajout=20de=20la=20factory=20et=20des=20te?=
 =?UTF-8?q?sts=20sur=20toutes=20les=20=C3=A9quations.=20Il=20reste=20une?=
 =?UTF-8?q?=20erreur=20sur=20le=20calcul=20de=20ZDV=20opur=20Cunge80=20et?=
 =?UTF-8?q?=20OrificeSubmerged.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 spec/mock_jasmine.ts                      |  2 +-
 spec/structure/parallel_structure.spec.ts | 62 +++++++++++++++++++++--
 spec/structure/rectangular_structure.ts   | 17 +------
 src/dichotomie.ts                         |  2 +-
 src/nub.ts                                |  5 +-
 src/structure/factory_structure.ts        | 45 ++++++++++++++++
 src/structure/parallel_structure.ts       |  9 ++--
 src/structure/structure.ts                |  2 +-
 src/util/describer.ts                     | 15 ++++++
 src/util/result.ts                        |  7 +++
 10 files changed, 137 insertions(+), 29 deletions(-)
 create mode 100644 src/structure/factory_structure.ts
 create mode 100644 src/util/describer.ts

diff --git a/spec/mock_jasmine.ts b/spec/mock_jasmine.ts
index 2ba5f986..2a9c3fb0 100644
--- a/spec/mock_jasmine.ts
+++ b/spec/mock_jasmine.ts
@@ -50,7 +50,7 @@ class Expect {
         const delta = Math.abs(expected - this.actual);
         const maxDelta = Math.pow(10, -precision) / 2;
         if (Math.round(delta * pow) / pow > maxDelta) {
-            console.error("Expected " + this.actual + " to be close to " + expected + "," + precision);
+            console.error("Expected " + this.actual + " to be close to " + expected + " with precision " + precision);
         }
         return this;
     }
diff --git a/spec/structure/parallel_structure.spec.ts b/spec/structure/parallel_structure.spec.ts
index e4601e2d..4efe1a4e 100644
--- a/spec/structure/parallel_structure.spec.ts
+++ b/spec/structure/parallel_structure.spec.ts
@@ -6,8 +6,13 @@
  */
 // import { describe, expect, it, xdescribe } from "../mock_jasmine";
 
+import { ParamCalculability, ParamDefinition, ParamsEquation } from "../../src/param";
+import { CreateStructure, StructureType } 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 { Describer } from "../../src/util/describer";
+import { EnumEx } from "../../src/util/enum";
 import { Result } from "../../src/util/result";
 import { checkResult } from "../test_func";
 import { structTest } from "./structure_test";
@@ -17,7 +22,10 @@ const pstruct: ParallelStructure = new ParallelStructure(
     false // debug
 );
 
-// Test avec deux structures test identiques
+/*
+ * Tests avec deux structures test identiques
+ */
+
 pstruct.addStructure(structTest);
 pstruct.addStructure(structTest);
 
@@ -29,11 +37,57 @@ describe("Class ParallelStructure: ", () => {
     });
 });
 
-function itParallelStructure(sVarCalc: string, rVcalc: number, Q: number) {
+/**
+ * Test sur ParallelStructure
+ * @param sVarCalc Variable à calculer
+ * @param rVcalc Valeur de référence à retrouver
+ * @param Q Débit de chacune des structures (pour structures identiques uniquement)
+ */
+function itParallelStructure(sVarCalc: string, rVcalc: number, Q?: number) {
     it(`${sVarCalc} should be ${rVcalc}`, () => {
         const res: Result = pstruct.Calc(sVarCalc);
         checkResult(res, rVcalc);
-        checkResult(res.extractResult(1), Q);
-        checkResult(res.extractResult(2), Q);
+        if (Q !== undefined) {
+            for (let i = 1 ; i < res.nbResults ; i++) {
+                checkResult(res.extractResult(i), Q);
+            }
+        }
     });
 }
+
+/*
+ * Tests avec toutes les équations et toutes les variables (cf. jalhyd#38)
+ */
+
+const ps2: ParallelStructure = new ParallelStructure(
+    new ParallelStructureParams(0, 102, 101.5), // Q = 0, Z1 = 102, Z2 = 101.5
+    false // debug
+);
+
+// Ajout d'une structure de chaque type dans ParallelStructure
+for (const i of EnumEx.getValues(StructureType)) {
+    ps2.addStructure(CreateStructure(i));
+}
+
+ps2.prms.Q.v = ps2.Calc("Q").vCalc;
+
+// tslint:disable-next-line:prefer-for-of
+describe("Class ParallelStructure: ", () => {
+    for (let i = 0 ; i < ps2.structures.length ; i++) {
+        const st: Structure = ps2.structures[i];
+        describe(`this.structures[${i}]: Structure${StructureType[i]}: `, () => {
+            // tslint:disable-next-line:forin
+            for (const prm of st.prms) {
+                if (prm.calculability === ParamCalculability.DICHO &&
+                    prm.symbol !== "Z1" && prm.symbol !== "Z2") {
+                    const ref: number = prm.v;
+                    const res: Result = ps2.Calc(i + "." + prm.symbol);
+                    prm.v = ref; // Go back to initial value for following tests
+                    it(`Calc(${prm.symbol}) should return ${ref}`, () => {
+                        checkResult(res, ref);
+                    });
+                }
+            }
+        });
+    }
+});
diff --git a/spec/structure/rectangular_structure.ts b/spec/structure/rectangular_structure.ts
index b9b9cecd..8895e09c 100644
--- a/spec/structure/rectangular_structure.ts
+++ b/spec/structure/rectangular_structure.ts
@@ -7,25 +7,10 @@
 
 import { RectangularStructure } from "../../src/structure/rectangular_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";
 
-/**
- * Récupération du nom de la classe
- * https://www.stevefenton.co.uk/2013/04/Obtaining-A-Class-Name-At-Runtime-In-TypeScript/
- */
-export class Describer {
-    /**
-     * Récupère le nom de la classe d'un objet
-     * @param inputClass Objet à tester
-     */
-    public static getName(inputClass: any) {
-        const funcNameRegex = /function (.{1,})\(/;
-        const results = (funcNameRegex).exec((inputClass as any).constructor.toString());
-        return (results && results.length > 1) ? results[1] : "";
-    }
-}
-
 export function itCalcQ(
     struct: RectangularStructure, Z1: number, W: number, Q: number,
     mode?: StructureFlowMode, regime?: StructureFlowRegime) {
diff --git a/src/dichotomie.ts b/src/dichotomie.ts
index 3b79383e..063c301a 100644
--- a/src/dichotomie.ts
+++ b/src/dichotomie.ts
@@ -201,7 +201,7 @@ export class Dichotomie extends Debug {
      * Il faudra s'assurer que cette première variable correspond à la méthode de calcul la plus rapide
      */
     private Calcul(): Result {
-        const r: Result = this.nub.Equation(this.analyticalSymbol);
+        const r: Result = this.nub.Calc(this.analyticalSymbol);
         this.debug(
             "dicho : Calcul(vX=" + this.sVarCalc + "=" + this.vX + ") -> " +
             this.analyticalSymbol + "=" + r.vCalc);
diff --git a/src/nub.ts b/src/nub.ts
index c8815102..cb434afd 100644
--- a/src/nub.ts
+++ b/src/nub.ts
@@ -31,7 +31,10 @@ export abstract class Nub extends ComputeNode {
      * @param rInit valeur initiale de la variable à calculer dans le cas de la dichotomie
      * @param rPrec précision de calcul
      */
-    public Calc(sVarCalc: string, rInit: number = 0, rPrec: number = 0.001): Result {
+    public Calc(sVarCalc: string, rInit?: number, rPrec: number = 0.001): Result {
+        if (rInit === undefined) {
+            rInit = this._prms.map[sVarCalc].v;
+        }
         if (this._prms.map[sVarCalc].isAnalytical()) {
             return this.Equation(sVarCalc);
         }
diff --git a/src/structure/factory_structure.ts b/src/structure/factory_structure.ts
new file mode 100644
index 00000000..3acb5d4a
--- /dev/null
+++ b/src/structure/factory_structure.ts
@@ -0,0 +1,45 @@
+import { RectangularStructureParams } from "./rectangular_structure_params";
+import { Structure } from "./structure";
+import { StructureCem88d } from "./structure_cem88d";
+import { StructureCem88v } from "./structure_cem88v";
+import { StructureCunge80 } from "./structure_cunge80";
+import { StructureOrificeFree } from "./structure_orifice_free";
+import { StructureOrificeSubmerged } from "./structure_orifice_submerged";
+import { StructureWeirFree } from "./structure_weir_free";
+
+export enum StructureType {
+    Cem88d,
+    Cem88v,
+    Cunge80,
+    OrificeFree,
+    OrificeSubmerged,
+    WeirFree
+}
+
+export function CreateStructure(structureType: StructureType): Structure {
+    const structPrms: RectangularStructureParams = new RectangularStructureParams(
+        0,  // Q
+        100,        // ZDV
+        102,        // Z1
+        101.5,      // Z2
+        2,          // L
+        0.6,        // Cd
+        0.5         // W
+    );
+    switch (structureType) {
+        case StructureType.Cem88d:
+            return new StructureCem88d(structPrms);
+        case StructureType.Cem88v:
+            return new StructureCem88v(structPrms);
+        case StructureType.Cunge80:
+            return new StructureCunge80(structPrms);
+        case StructureType.OrificeFree:
+            return new StructureOrificeFree(structPrms);
+        case StructureType.OrificeSubmerged:
+            return new StructureOrificeSubmerged(structPrms);
+        case StructureType.WeirFree:
+            const st: StructureWeirFree = new StructureWeirFree(structPrms);
+            st.prms.Cd.v = 0.4;
+            return st;
+    }
+}
diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts
index c692fd4b..6489a87c 100644
--- a/src/structure/parallel_structure.ts
+++ b/src/structure/parallel_structure.ts
@@ -2,9 +2,8 @@ import { Nub } from "../nub";
 import { ParamCalculability } from "../param";
 import { Message } from "../util/message";
 import { Result } from "../util/result";
-import { Structure } from "./structure";
-
 import { ParallelStructureParams } from "./parallel_structure_params";
+import { Structure } from "./structure";
 
 /**
  * Calcul de une ou plusieurs structures hydrauliques en parallèles
@@ -109,7 +108,7 @@ export class ParallelStructure extends Nub {
      * @param rInit Valeur initiale
      * @param rPrec Précision attendue
      */
-    public Calc(sVarCalc: string, rInit: number = 0, rPrec: number = 0.001): Result {
+    public Calc(sVarCalc: string, rInit?: number, rPrec: number = 0.001): Result {
         switch (sVarCalc) {
             case "Z1" :
             case "Z2" :
@@ -136,7 +135,7 @@ export class ParallelStructure extends Nub {
      * @param rInit Valeur initiale
      * @param rPrec Précision attendue
      */
-    private CalcStructPrm(sVarCalc: string, rInit: number = 0, rPrec: number = 0.001): Result {
+    private CalcStructPrm(sVarCalc: string, rInit?: number, rPrec: number = 0.001): Result {
         // Détection de la structure où calculer le paramètre
         let sIndex: string;
         let sPrm: string;
@@ -144,7 +143,7 @@ export class ParallelStructure extends Nub {
         const index = parseInt(sIndex, 10);
 
         // Le débit restant sur la structure en calcul est :
-        const qTarget: number = this.prms.Q.v - this.CalcQ(index).vCalc;
+        this.structures[index].prms.Q.v = this.prms.Q.v - this.CalcQ(index).vCalc;
 
         // Calcul du paramètre de la structure en calcul
         return this.structures[index].Calc(sPrm, rInit, rPrec);
diff --git a/src/structure/structure.ts b/src/structure/structure.ts
index 809ab19b..0ed0b4ad 100644
--- a/src/structure/structure.ts
+++ b/src/structure/structure.ts
@@ -66,7 +66,7 @@ export abstract class Structure extends Nub {
      * @param rInit valeur initiale de la variable à calculer dans le cas de la dichotomie
      * @param rPrec précision de calcul
      */
-    public Calc(sVarCalc: string, rInit: number = 0, rPrec: number = 0.001): Result {
+    public Calc(sVarCalc: string, rInit?: number, rPrec: number = 0.001): Result {
         // Mise à jour de h1 et h2
         this.prms.update_h1h2();
 
diff --git a/src/util/describer.ts b/src/util/describer.ts
new file mode 100644
index 00000000..5786fb81
--- /dev/null
+++ b/src/util/describer.ts
@@ -0,0 +1,15 @@
+/**
+ * Récupération du nom de la classe
+ * https://www.stevefenton.co.uk/2013/04/Obtaining-A-Class-Name-At-Runtime-In-TypeScript/
+ */
+export class Describer {
+    /**
+     * Récupère le nom de la classe d'un objet
+     * @param inputClass Objet à tester
+     */
+    public static getName(inputClass: any) {
+        const funcNameRegex = /function (.{1,})\(/;
+        const results = (funcNameRegex).exec((inputClass as any).constructor.toString());
+        return (results && results.length > 1) ? results[1] : "";
+    }
+}
diff --git a/src/util/result.ts b/src/util/result.ts
index 941dea0b..22f51be5 100644
--- a/src/util/result.ts
+++ b/src/util/result.ts
@@ -101,6 +101,13 @@ export class Result {
         return new Result(this._results[i]);
     }
 
+    /**
+     * Renvoie le nombre de résultats dans le tableau de résultats
+     */
+    public get nbResults(): number {
+        return this._results.length;
+    }
+
     /**
      * Ajoute un ResultElement au tableau
      * @param r ResultElement à ajouter
-- 
GitLab