diff --git a/spec/mock_jasmine.ts b/spec/mock_jasmine.ts
index e3a0c3fa63e86f26d9002005bafe80c062d401c8..a3b051f89f5169b67274347206e00962a5a5be4f 100644
--- a/spec/mock_jasmine.ts
+++ b/spec/mock_jasmine.ts
@@ -39,9 +39,9 @@ export function xit(sTxt: string, fFun: () => void) {
 
 export function fail(m?: string) {
     let s = "Test failed";
-    if (m !== undefined)
+    if (m !== undefined) {
         s += ` (${m})`;
-
+    }
     console.error(s);
 }
 
diff --git a/spec/pab/pab_puissance.spec.ts b/spec/pab/pab_puissance.spec.ts
index a8856b4b4caf71ab6c5ae604efea3a5b06da474d..4064654d18ac0f9522d8868490d3119fe9542bee 100644
--- a/spec/pab/pab_puissance.spec.ts
+++ b/spec/pab/pab_puissance.spec.ts
@@ -12,7 +12,7 @@ function PabPuissanceTest(varTest: string) {
                 0.3,      // Chute entre bassins DH (m)
                 0.1,      // Débit Q (m3/s)
                 0.5,    // Volume V (m3)
-                588.6   // Puissance dissipée Pv (W/m3)
+                588.6   // Puissance dissipée PV (W/m3)
             );
 
             let res: number = prms[varTest].v;
@@ -33,5 +33,5 @@ describe("Class PabPuissance: ", () => {
     PabPuissanceTest("DH");
     PabPuissanceTest("Q");
     PabPuissanceTest("V");
-    PabPuissanceTest("Pv");
+    PabPuissanceTest("PV");
 });
diff --git a/spec/structure/cloisons.spec.ts b/spec/structure/cloisons.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a57206b8fbc4ec5993838ea071fab504b760a003
--- /dev/null
+++ b/spec/structure/cloisons.spec.ts
@@ -0,0 +1,89 @@
+/**
+ * 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 test_func.ts
+ */
+// import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
+
+import { Cloisons, CloisonsParams } from "../../src/structure/cloisons";
+import { CreateStructure } from "../../src/structure/factory_structure";
+import { StructureKiviParams } from "../../src/structure/structure_kivi";
+import { LoiDebit, StructureType } from "../../src/structure/structure_props";
+// tslint:disable-next-line:max-line-length
+import { RectangularStructureParams, StructureWeirSubmergedLarinier } from "../../src/structure/structure_weir_submerged_larinier";
+import { testParallelStructures } from "./functions";
+
+const cloisons: Cloisons = new Cloisons(
+    new CloisonsParams(
+        0,      // Débit total (m3/s)
+        102,    // Cote de l'eau amont (m)
+        10,     // Longueur des bassins (m)
+        1,      // Largeur des bassins (m)
+        1,      // Profondeur moyenne (m)
+        0.5     // Hauteur de chute (m)
+    ),
+    false       // debug
+);
+
+const fente: StructureWeirSubmergedLarinier = new StructureWeirSubmergedLarinier(
+    new RectangularStructureParams(
+        0,
+        101,
+        102,
+        101.5,
+        0.2,
+        0.65
+    )
+);
+
+cloisons.addStructure(fente);
+
+describe("Class Cloisons: ", () => {
+    describe("Calc(Q) Fente noyée (Larinier 1992)", () => {
+        it("vCalc should return 0.407", () => {
+            expect(cloisons.Calc("Q").vCalc).toBeCloseTo(0.407, 3);
+        });
+        it("extraResults.PV should return 199.7", () => {
+            expect(cloisons.Calc("Q").extraResults.PV).toBeCloseTo(199.7, 1);
+        });
+    });
+
+    const c2: Cloisons = new Cloisons(
+        new CloisonsParams(
+            0,      // Débit total (m3/s)
+            102,    // Cote de l'eau amont (m)
+            10,     // Longueur des bassins (m)
+            1,      // Largeur des bassins (m)
+            1,      // Profondeur moyenne (m)
+            0.5     // Hauteur de chute (m)
+        ),
+        false       // debug
+    );
+
+    // Ajout d'une structure de chaque type dans Cloisons
+    const iStTypes: StructureType[] = [
+        StructureType.Orifice,
+        StructureType.SeuilRectangulaire,
+        StructureType.SeuilRectangulaire
+    ];
+    const iLoiDebits: LoiDebit[] = [
+        LoiDebit.OrificeSubmerged,
+        LoiDebit.WeirSubmergedLarinier,
+        LoiDebit.KIVI
+    ];
+    for (let i = 0; i < 3; i++ ) {
+        c2.addStructure(CreateStructure(iStTypes[i], iLoiDebits[i], false));
+    }
+    const prmsKivi: StructureKiviParams = c2.structures[2].prms as StructureKiviParams;
+    prmsKivi.ZRAM.v = 0;
+
+    testParallelStructures(c2, iStTypes, iLoiDebits);
+
+    describe("Calcul de ZRAM de l'équation KIVI", () => {
+        it("ZRAM should be 101", () => {
+            c2.Calc("Q");
+            expect(prmsKivi.ZRAM.v).toBeCloseTo(101, 3);
+        });
+    });
+});
diff --git a/spec/structure/dever.spec.ts b/spec/structure/dever.spec.ts
index dc43499aa55727f4983a572c5ddb9b34ab4c8bec..f93eea1866868bd04ae4506ced6b6487fec0aa05 100644
--- a/spec/structure/dever.spec.ts
+++ b/spec/structure/dever.spec.ts
@@ -9,7 +9,6 @@
 import { Dever, DeverParams } from "../../src/structure/dever";
 import { CreateStructure } from "../../src/structure/factory_structure";
 import { LoiDebit, StructureType } from "../../src/structure/structure_props";
-import { Result } from "../../src/util/result";
 
 const dever: Dever = new Dever(
     new DeverParams(
diff --git a/spec/structure/functions.ts b/spec/structure/functions.ts
index 853eecc881d2d7c2c0664b6683830320e41f99d9..800641dcb128957b41bf0f1704c9369e5d651c83 100644
--- a/spec/structure/functions.ts
+++ b/spec/structure/functions.ts
@@ -5,11 +5,15 @@
  */
 // import { describe, expect, it, xdescribe } from "../mock_jasmine";
 
-import { Structure } from "../../src/structure/structure";
-import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
+import { MessageCode } from "../../src";
+import { ParamCalculability } from "../../src/param/param-definition";
+import { ParallelStructure } from "../../src/structure/parallel_structure";
+import { Structure, StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
+import { LoiDebit, StructureType } from "../../src/structure/structure_props";
 import { Describer } from "../../src/util/describer";
 import { Result } from "../../src/util/result";
 import { precDigits } from "../test_config";
+import { checkResult } from "../test_func";
 
 export function itCalcQ(
     struct: Structure, Z1: number, W: number, Q: number,
@@ -38,3 +42,114 @@ export function itCalcQ(
         });
     }
 }
+
+/**
+ * Test de calcul de tous les paramètres d'une loi de débit
+ * @param st Structure à tester
+ * @param mode Mode d'écoulement
+ * @param regime Régime d'écoulement
+ * @param bNotZDV Loi de débit ne permettant pas de calculer ZDV
+ */
+export function testStructure(
+    st: Structure,
+    mode: StructureFlowMode,
+    regime: StructureFlowRegime,
+    bNotZDV: boolean = false
+) {
+    for (const prm of st.prms) {
+        if ([ParamCalculability.DICHO, ParamCalculability.EQUATION].includes(prm.calculability)) {
+            if (prm.symbol === "W" && prm.v === Infinity) {
+                // Le calcul de l'ouverture sur les seuils doit renvoyer une exception (cas impossible)
+                it(`Calc(${prm.symbol}) should return exception`, () => {
+                    expect(
+                        () => { st.Calc(prm.symbol); }
+                    ).toThrow(new Error("Structure:Calc : Calcul de W impossible sur un seuil"));
+                });
+            } else {
+                const ref: number = prm.v;
+                const res: Result = st.Calc(prm.symbol);
+                if (bNotZDV) {
+                    // Les lois CEM88D et CUNGE80 ne font pas intervenir ZDV dans le calcul d'un orifice noyé
+                    it(`Calc(${prm.symbol}) should return an error`, () => {
+                        expect(
+                            st.Calc(prm.symbol).code
+                        ).toBe(MessageCode.ERROR_STRUCTURE_ZDV_PAS_CALCULABLE);
+                    });
+                } else {
+                    // On ne teste pas le calcul de l'ouverture sur les seuils
+                    it(`Calc(${prm.symbol}) should return ${ref}`, () => {
+                        checkResult(res, ref);
+                    });
+                }
+                prm.v = ref; // Go back to initial value for following tests
+            }
+        }
+    }
+}
+
+/**
+ * Test d'ouvrages en parallèle : calcul des débits individuels et test de tous les paramètres
+ * @param oPS objet ParallelStructure à tester
+ * @param iStTypes Liste ordonnée des types des ouvrages à tester
+ * @param iLoiDebits Liste ordonnée des lois de débit à tester
+ */
+export function testParallelStructures(oPS: ParallelStructure, iStTypes: number[], iLoiDebits: number[]) {
+    oPS.prms.Q.v = oPS.Calc("Q").vCalc;
+
+    for (let i = 0; i < oPS.structures.length; i++) {
+        const st: Structure = oPS.structures[i];
+        describe(`this.structures[${i}]: ${StructureType[iStTypes[i]]} Structure${LoiDebit[iLoiDebits[i]]}: `, () => {
+            // Tests sur les résultats complémentaires
+            it(`Calc(Q).extraResults[${i}.Q] should return ${oPS.structures[i].Calc("Q").vCalc}`, () => {
+                expect(
+                    oPS.Calc("Q").extraResults[`ouvrage[${i}].Q`]
+                ).toBe(
+                    oPS.structures[i].Calc("Q").vCalc
+                );
+            });
+
+            // Tests de calcul des paramètres des ouvrages
+            for (const prm of st.prms) {
+                if (
+                    prm.calculability === ParamCalculability.DICHO &&
+                    prm.symbol !== "Z1" && prm.symbol !== "Z2"
+                ) {
+                    const ref: number = prm.v;
+                    if (prm.symbol === "W" && prm.v === Infinity) {
+                        // Le calcul de l'ouverture sur les seuils doit renvoyer une exception (cas impossible)
+                        it(`Calc(${prm.symbol}) should return exception`, () => {
+                            expect(
+                                () => { oPS.Calc(i + "." + prm.symbol); }
+                            ).toThrow(new Error("Structure:Calc : Calcul de W impossible sur un seuil"));
+                        });
+                    } else if (
+                        iStTypes[i] === StructureType.VanneRectangulaire &&
+                        !oPS.structures[i].isZDVcalculable &&
+                        prm.symbol === "ZDV"
+                    ) {
+                        // Les lois CEM88D et CUNGE80 ne font pas intervenir ZDV dans le calcul d'un orifice noyé
+                        it(`Calc(${prm.symbol}) should return an error`, () => {
+                            expect(
+                                oPS.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(oPS.Calc(i + "." + prm.symbol), ref, 1);
+                        });
+                    } else {
+                        // Cas normal : On teste la valeur calculée
+                        it(`Calc(${prm.symbol}) should return ${ref}`, () => {
+                            checkResult(oPS.Calc(i + "." + prm.symbol), ref);
+                        });
+                    }
+                    prm.v = ref; // Go back to initial value for following tests
+                }
+            }
+        });
+    }
+}
diff --git a/spec/structure/parallel_structure.spec.ts b/spec/structure/parallel_structure.spec.ts
index d7bf22a27ade7686274e5996f6a318bc23386497..087c7f250767e1cc2d737dc36fa82b6c2696fd18 100644
--- a/spec/structure/parallel_structure.spec.ts
+++ b/spec/structure/parallel_structure.spec.ts
@@ -6,17 +6,15 @@
  */
 // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
 
-import { ParamCalculability } from "../../src/param/param-definition";
 import { CreateStructure } 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 { loiAdmissibles, LoiDebit, StructureType } from "../../src/structure/structure_props";
+import { loiAdmissibles, StructureType } from "../../src/structure/structure_props";
 import { EnumEx } from "../../src/util/enum";
-import { MessageCode } from "../../src/util/message";
 import { Result } from "../../src/util/result";
 import { precDigits } from "../test_config";
 import { checkResult } from "../test_func";
+import { testParallelStructures } from "./functions";
 import { structTest } from "./structure_test";
 
 const pstruct: ParallelStructure = new ParallelStructure(
@@ -94,63 +92,5 @@ describe("Class ParallelStructure: ", () => {
             iStTypes.push(s);
         }
     }
-
-    ps2.prms.Q.v = ps2.Calc("Q").vCalc;
-
-    for (let i = 0; i < ps2.structures.length; i++) {
-        const st: Structure = ps2.structures[i];
-        describe(`this.structures[${i}]: ${StructureType[iStTypes[i]]} Structure${LoiDebit[iLoiDebits[i]]}: `, () => {
-            // Tests sur les résultats complémentaires
-            it(`Calc(Q).extraResults[${i}.Q] should return ${ps2.structures[i].Calc("Q").vCalc}`, () => {
-                expect(
-                    ps2.Calc("Q").extraResults[`ouvrage[${i}].Q`]
-                ).toBe(
-                    ps2.structures[i].Calc("Q").vCalc
-                );
-            });
-
-            // Tests de calcul des paramètres des ouvrages
-            for (const prm of st.prms) {
-                if (
-                    prm.calculability === ParamCalculability.DICHO &&
-                    prm.symbol !== "Z1" && prm.symbol !== "Z2"
-                ) {
-                    const ref: number = prm.v;
-                    if (prm.symbol === "W" && prm.v === Infinity) {
-                        // Le calcul de l'ouverture sur les seuils doit renvoyer une exception (cas impossible)
-                        it(`Calc(${prm.symbol}) should return exception`, () => {
-                            expect(
-                                () => { ps2.Calc(i + "." + prm.symbol); }
-                            ).toThrow(new Error("Structure:Calc : Calcul de W impossible sur un seuil"));
-                        });
-                    } else if (
-                        iStTypes[i] === StructureType.VanneRectangulaire &&
-                        !ps2.structures[i].isZDVcalculable &&
-                        prm.symbol === "ZDV"
-                    ) {
-                        // Les lois CEM88D et CUNGE80 ne font pas intervenir ZDV dans le calcul d'un orifice noyé
-                        it(`Calc(${prm.symbol}) should return an error`, () => {
-                            expect(
-                                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}`, () => {
-                            checkResult(ps2.Calc(i + "." + prm.symbol), ref);
-                        });
-                    }
-                    prm.v = ref; // Go back to initial value for following tests
-                }
-            }
-        });
-    }
+    testParallelStructures(ps2, iStTypes, iLoiDebits);
 });
diff --git a/spec/structure/structure_kivi.spec.ts b/spec/structure/structure_kivi.spec.ts
index d0700be77cbc097c6ecee5709196544fddb8e800..a4fb71297aca20d60c81674b0c01557fa20aaf13 100644
--- a/spec/structure/structure_kivi.spec.ts
+++ b/spec/structure/structure_kivi.spec.ts
@@ -10,11 +10,12 @@ import { MessageCode, StructureFlowMode, StructureFlowRegime } from "../../src";
 import { CreateStructure } from "../../src/structure/factory_structure";
 import { StructureKivi } from "../../src/structure/structure_kivi";
 import { LoiDebit, StructureType } from "../../src/structure/structure_props";
-import { testStructure } from "./structure_test";
+import { testStructure } from "./functions";
 
 const structTest: StructureKivi = CreateStructure(
     StructureType.SeuilRectangulaire, LoiDebit.KIVI
 ) as StructureKivi;
+structTest.prms.ZDV.v = 101;
 
 describe("Class StructureKivi: ", () => {
     describe("Ecoulement noyé", () => {
diff --git a/spec/structure/structure_orifice_submerged.spec.ts b/spec/structure/structure_orifice_submerged.spec.ts
index d303605c006e0280ac1e8ad7acef8e8959e365a1..2eaf38fa6c221a727a94403c9e0c8ae65e2f8492 100644
--- a/spec/structure/structure_orifice_submerged.spec.ts
+++ b/spec/structure/structure_orifice_submerged.spec.ts
@@ -2,56 +2,26 @@
  * 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
+ * Faire de même avec le fichier ../structure/functions.ts
  */
 // import { describe, expect, it, xdescribe } from "../mock_jasmine";
 
-import { RectangularStructureParams } from "../../src/structure/rectangular_structure_params";
 import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
-import { StructureOrificeSubmerged } from "../../src/structure/structure_orifice_submerged";
-import { Result } from "../../src/util/result";
-import { itCalcQ } from "./functions";
+// tslint:disable-next-line:max-line-length
+import { StructureOrificeSubmerged, StructureOrificeSubmergedParams } from "../../src/structure/structure_orifice_submerged";
+import { itCalcQ } from "../structure/functions";
 
-const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0);
-const structTest: StructureOrificeSubmerged = new StructureOrificeSubmerged(structPrm, false);
+const prms: StructureOrificeSubmergedParams = new StructureOrificeSubmergedParams(0, 102, 101.5, 0.7, 0.1);
+const test: StructureOrificeSubmerged = new StructureOrificeSubmerged(prms, false);
 
 describe("Class StructureOrificeSubmerged: ", () => {
-    describe("Calcul Q avec W croissant: ", () => {
-        const W: number[] = [
-            0.000000, 0.100000, 0.200000, 0.300000, 0.400000, 0.500000, 0.600000,
-            0.700000, 0.800000, 0.900000, 1.000000, 1.100000, 1.200000, 1.300000];
-        const h1: number = 1.200000;
-        const Q: number[] = [0.000000, 0.237709, 0.475418, 0.713127, 0.950836, 1.188545,
-            1.426254, 1.663963, 1.901673, 2.139382, 2.377091, 2.614800, 2.852509, 2.852509];
-
-        for (let i = 0; i < Q.length; i++) {
-            itCalcQ(structTest, h1, W[i], Q[i]);
-        }
-    });
-    describe("Calcul Q en charge avec h1 croissant: ", () => {
-        const W: number = 0.8;
-        const h1: number[] = [1.050000, 1.300000, 1.500000];
-        const Q: number[] = [0.950836, 2.329064, 3.006808];
-        const mode: StructureFlowMode[] = [
-            StructureFlowMode.ORIFICE, StructureFlowMode.ORIFICE, StructureFlowMode.ORIFICE];
-        const regime: StructureFlowRegime[] = [
-            StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED];
-
-        for (let i = 0; i < Q.length; i++) {
-            itCalcQ(structTest, h1[i], W, Q[i], mode[i], regime[i]);
-        }
-    });
-    describe("Calcul Q a surface libre avec h1 croissant: ", () => {
-        const W: number = Infinity;
-        const h1: number[] = [1.100000, 1.500000];
-        const Q: number[] = [1.848943, 5.637766];
-        const mode: StructureFlowMode[] = [
-            StructureFlowMode.WEIR, StructureFlowMode.WEIR];
-        const regime: StructureFlowRegime[] = [
-            StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED];
-
+    describe("Calc(Q): ", () => {
+        const h1: number[] = [102];
+        const Q: number[] = [0.219];
+        const mode: StructureFlowMode = StructureFlowMode.ORIFICE;
+        const regime: StructureFlowRegime = StructureFlowRegime.SUBMERGED;
         for (let i = 0; i < Q.length; i++) {
-            itCalcQ(structTest, h1[i], W, Q[i], mode[i], regime[i]);
+            itCalcQ(test, h1[i], Infinity, Q[i], mode, regime);
         }
     });
 });
diff --git a/spec/structure/structure_orifice_free.spec.ts b/spec/structure/structure_rectangular_orifice_free.spec.ts
similarity index 91%
rename from spec/structure/structure_orifice_free.spec.ts
rename to spec/structure/structure_rectangular_orifice_free.spec.ts
index 708f8ae1a0c7e96a775ce169ed07abb72b212aa4..91fe31bdaade51dbf292bac55437799f04281636 100644
--- a/spec/structure/structure_orifice_free.spec.ts
+++ b/spec/structure/structure_rectangular_orifice_free.spec.ts
@@ -8,12 +8,11 @@
 
 import { RectangularStructureParams } from "../../src/structure/rectangular_structure_params";
 import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
-import { StructureOrificeFree } from "../../src/structure/structure_orifice_free";
-import { Result } from "../../src/util/result";
+import { StructureRectangularOrificeFree } from "../../src/structure/structure_rectangular_orifice_free";
 import { itCalcQ } from "./functions";
 
 const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0);
-const structTest: StructureOrificeFree = new StructureOrificeFree(structPrm, false);
+const structTest: StructureRectangularOrificeFree = new StructureRectangularOrificeFree(structPrm, false);
 
 describe("Class StructureOrificeFree: ", () => {
     describe("Calcul Q avec W croissant: ", () => {
diff --git a/spec/structure/structure_rectangular_orifice_submerged.spec.ts b/spec/structure/structure_rectangular_orifice_submerged.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..012e111c9924183e403c3313725eec524fc4cfc9
--- /dev/null
+++ b/spec/structure/structure_rectangular_orifice_submerged.spec.ts
@@ -0,0 +1,57 @@
+/**
+ * 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 { RectangularStructureParams } from "../../src/structure/rectangular_structure_params";
+import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
+import { StructureRectangularOrificeSubmerged } from "../../src/structure/structure_rectangular_orifice_submerged";
+import { Result } from "../../src/util/result";
+import { itCalcQ } from "./functions";
+
+const structPrm: RectangularStructureParams = new RectangularStructureParams(1, 0, 1, 1, 2, 0.6, 0);
+const structTest: StructureRectangularOrificeSubmerged = new StructureRectangularOrificeSubmerged(structPrm, false);
+
+describe("Class StructureRectangularOrificeSubmerged: ", () => {
+    describe("Calcul Q avec W croissant: ", () => {
+        const W: number[] = [
+            0.000000, 0.100000, 0.200000, 0.300000, 0.400000, 0.500000, 0.600000,
+            0.700000, 0.800000, 0.900000, 1.000000, 1.100000, 1.200000, 1.300000];
+        const h1: number = 1.200000;
+        const Q: number[] = [0.000000, 0.237709, 0.475418, 0.713127, 0.950836, 1.188545,
+            1.426254, 1.663963, 1.901673, 2.139382, 2.377091, 2.614800, 2.852509, 2.852509];
+
+        for (let i = 0; i < Q.length; i++) {
+            itCalcQ(structTest, h1, W[i], Q[i]);
+        }
+    });
+    describe("Calcul Q en charge avec h1 croissant: ", () => {
+        const W: number = 0.8;
+        const h1: number[] = [1.050000, 1.300000, 1.500000];
+        const Q: number[] = [0.950836, 2.329064, 3.006808];
+        const mode: StructureFlowMode[] = [
+            StructureFlowMode.ORIFICE, StructureFlowMode.ORIFICE, StructureFlowMode.ORIFICE];
+        const regime: StructureFlowRegime[] = [
+            StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED];
+
+        for (let i = 0; i < Q.length; i++) {
+            itCalcQ(structTest, h1[i], W, Q[i], mode[i], regime[i]);
+        }
+    });
+    describe("Calcul Q a surface libre avec h1 croissant: ", () => {
+        const W: number = Infinity;
+        const h1: number[] = [1.100000, 1.500000];
+        const Q: number[] = [1.848943, 5.637766];
+        const mode: StructureFlowMode[] = [
+            StructureFlowMode.WEIR, StructureFlowMode.WEIR];
+        const regime: StructureFlowRegime[] = [
+            StructureFlowRegime.SUBMERGED, StructureFlowRegime.SUBMERGED];
+
+        for (let i = 0; i < Q.length; i++) {
+            itCalcQ(structTest, h1[i], W, Q[i], mode[i], regime[i]);
+        }
+    });
+});
diff --git a/spec/structure/structure_test.ts b/spec/structure/structure_test.ts
index fd9a2a1b4d8fb415ae5203ba8cf0313cd861848d..5a79d9a9f6361334f9e25c4cee6a65a144e65eac 100644
--- a/spec/structure/structure_test.ts
+++ b/spec/structure/structure_test.ts
@@ -9,6 +9,7 @@
 import { MessageCode } from "../../src";
 import { ParamCalculability } from "../../src/param/param-definition";
 import { Structure, StructureFlowMode, StructureFlowRegime, StructureParams } from "../../src/structure/structure";
+import { LoiDebit, StructureType } from "../../src/structure/structure_props";
 import { Result } from "../../src/util/result";
 import { checkResult } from "../test_func";
 
@@ -59,45 +60,3 @@ class StructureTest extends Structure {
  */
 export const structTestPrm: StructureParams = new StructureParams(1, 0, 30, 15);
 export const structTest: StructureTest = new StructureTest(structTestPrm, false);
-
-/**
- * Test de calcul de tous les paramètres d'une loi de débit
- * @param st Structure à tester
- * @param bNotZDV Loi de débit ne permettant pas de calculer ZDV
- */
-export function testStructure(
-    st: Structure,
-    mode: StructureFlowMode,
-    regime: StructureFlowRegime,
-    bNotZDV: boolean = false
-) {
-    for (const prm of st.prms) {
-        if ([ParamCalculability.DICHO, ParamCalculability.EQUATION].includes(prm.calculability)) {
-            if (prm.symbol === "W" && prm.v === Infinity) {
-                // Le calcul de l'ouverture sur les seuils doit renvoyer une exception (cas impossible)
-                it(`Calc(${prm.symbol}) should return exception`, () => {
-                    expect(
-                        () => { st.Calc(prm.symbol); }
-                    ).toThrow(new Error("Structure:Calc : Calcul de W impossible sur un seuil"));
-                });
-            } else {
-                const ref: number = prm.v;
-                const res: Result = st.Calc(prm.symbol);
-                if (bNotZDV) {
-                    // Les lois CEM88D et CUNGE80 ne font pas intervenir ZDV dans le calcul d'un orifice noyé
-                    it(`Calc(${prm.symbol}) should return an error`, () => {
-                        expect(
-                            st.Calc(prm.symbol).code
-                        ).toBe(MessageCode.ERROR_STRUCTURE_ZDV_PAS_CALCULABLE);
-                    });
-                } else {
-                    // On ne teste pas le calcul de l'ouverture sur les seuils
-                    it(`Calc(${prm.symbol}) should return ${ref}`, () => {
-                        checkResult(res, ref);
-                    });
-                }
-                prm.v = ref; // Go back to initial value for following tests
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/spec/structure/structure_weir_submerged_larinier.spec.ts b/spec/structure/structure_weir_submerged_larinier.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1952ed2f26f196c7e1f6e80312025e39965534f9
--- /dev/null
+++ b/spec/structure/structure_weir_submerged_larinier.spec.ts
@@ -0,0 +1,27 @@
+/**
+ * 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 ../structure/functions.ts
+ */
+// import { describe, expect, it, xdescribe } from "../mock_jasmine";
+
+import { StructureFlowMode, StructureFlowRegime } from "../../src/structure/structure";
+// tslint:disable-next-line:max-line-length
+import { RectangularStructureParams, StructureWeirSubmergedLarinier } from "../../src/structure/structure_weir_submerged_larinier";
+import { itCalcQ } from "../structure/functions";
+
+const prms: RectangularStructureParams = new RectangularStructureParams(0, 101, 102, 101.5, 0.2, 0.65);
+const test: StructureWeirSubmergedLarinier = new StructureWeirSubmergedLarinier(prms, false);
+
+describe("Class CloisonsOrifice: ", () => {
+    describe("Calc(Q): ", () => {
+        const Z1: number[] = [102];
+        const Q: number[] = [0.407];
+        const mode: StructureFlowMode = StructureFlowMode.WEIR;
+        const regime: StructureFlowRegime = StructureFlowRegime.SUBMERGED;
+        for (let i = 0; i < Q.length; i++) {
+            itCalcQ(test, Z1[i], Infinity, Q[i], mode, regime);
+        }
+    });
+});
diff --git a/spec/test_func.ts b/spec/test_func.ts
index d19d4b41cae27dd39f35b28ffe730de4e34b9835..a3b692f0e0a38105bc3cabf8acea575a5af05600 100644
--- a/spec/test_func.ts
+++ b/spec/test_func.ts
@@ -220,8 +220,9 @@ export function compareExtraResult(
     const nre = res.resultElements.length;
     let n1 = 0;
     for (let i = 0; i < nre; i++) {
-        if (res.resultElements[i].getExtraResult(key) != undefined)
+        if (res.resultElements[i].getExtraResult(key) !== undefined) {
             n1++;
+        }
     }
 
     const n2 = Object.keys(objValid).length;
@@ -236,4 +237,4 @@ export function compareExtraResult(
         expect(b).toBeTruthy(s + " : " + i + "ieme valeur incorrecte " + v1 + ", devrait etre " + v2);
         if (!b) { return; }
     }
-}
\ No newline at end of file
+}
diff --git a/src/compute-node.ts b/src/compute-node.ts
index 6d98e09d1519e9f34f343bef92eca91cad07da8d..023de3bba04d7b5b6b9108ff007fd311fde96ff6 100644
--- a/src/compute-node.ts
+++ b/src/compute-node.ts
@@ -7,12 +7,17 @@ import { IParamDefinitionIterator, ParamsEquation } from "./param/params-equatio
  * type de calculette
  */
 export enum CalculatorType {
-    ConduiteDistributrice, LechaptCalmon, SectionParametree, RegimeUniforme, CourbeRemous,
+    ConduiteDistributrice,
+    LechaptCalmon,
+    SectionParametree,
+    RegimeUniforme,
+    CourbeRemous,
     PabDimensions,      // passe à bassin rectangulaire
     PabPuissance,       // passe à bassin : puissance dissipée
     Structure,          // ouvrages hydrauliques simples
     ParallelStructure,  // ouvrages hydrauliques en parallèle
-    Dever               // Outil Cassiopée Dever
+    Dever,              // Outil Cassiopée Dever
+    Cloisons            // Outil Cassiopée PAB Cloisons
 }
 
 /**
diff --git a/src/nub_factory.ts b/src/nub_factory.ts
index 2f4e19b6117d813b1f4ee77feb31f9298c8c66c9..e8a5458f60404b792ea11fb00241b6d4c7d015c1 100644
--- a/src/nub_factory.ts
+++ b/src/nub_factory.ts
@@ -10,6 +10,7 @@ import { PabPuissance, PabPuissanceParams } from "./pab/pab_puissance";
 import { RegimeUniforme } from "./regime_uniforme";
 import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "./remous";
 import { SectionParametree } from "./section/section_nub";
+import { Cloisons, CloisonsParams } from "./structure/cloisons";
 import { Dever, DeverParams } from "./structure/dever";
 import { ParallelStructure, ParallelStructureParams } from "./structure/parallel_structure";
 
@@ -309,7 +310,7 @@ export class NubFactory {
                         0.3,      // Chute entre bassins DH (m)
                         0.1,      // Débit Q (m3/s)
                         0.5,    // Volume V (m3)
-                        588.6   // Puissance dissipée Pv (W/m3)
+                        588.6   // Puissance dissipée PV (W/m3)
                     );
                     return new PabPuissance(prms);
                 }
@@ -338,6 +339,20 @@ export class NubFactory {
                     return new Dever(prms);
                 }
 
+            case CalculatorType.Cloisons:
+                {
+                    return new Cloisons(
+                        new CloisonsParams(
+                            0,      // Débit total (m3/s)
+                            102,    // Cote de l'eau amont (m)
+                            10,     // Longueur des bassins (m)
+                            1,      // Largeur des bassins (m)
+                            1,      // Profondeur moyenne (m)
+                            0.5     // Hauteur de chute (m)
+                        )
+                    );
+                }
+
             default:
                 throw new Error(
                     // tslint:disable-next-line:max-line-length
diff --git a/src/pab/pab_puissance.ts b/src/pab/pab_puissance.ts
index a0729bfc104157fd3ab6a91b77afc02f72a1ae97..9f4fd19c058870c545c5978934ed2dbd4ab3e52c 100644
--- a/src/pab/pab_puissance.ts
+++ b/src/pab/pab_puissance.ts
@@ -17,19 +17,19 @@ export class PabPuissanceParams extends ParamsEquation {
     private _V: ParamDefinition;
 
     /** Puissance dissipée PV */
-    private _Pv: ParamDefinition;
+    private _PV: ParamDefinition;
 
     constructor(rDH: number, rQ: number, rV: number, rPV?: number) {
         super();
         this._DH = new ParamDefinition("DH", ParamDomainValue.POS, rDH);
         this._Q = new ParamDefinition("Q", ParamDomainValue.POS, rQ);
         this._V = new ParamDefinition("V", ParamDomainValue.POS, rV);
-        this._Pv = new ParamDefinition("Pv", ParamDomainValue.POS, rPV);
+        this._PV = new ParamDefinition("PV", ParamDomainValue.POS, rPV);
 
         this.addParamDefinition(this._DH);
         this.addParamDefinition(this._Q);
         this.addParamDefinition(this._V);
-        this.addParamDefinition(this._Pv);
+        this.addParamDefinition(this._PV);
     }
 
     get DH() {
@@ -44,8 +44,8 @@ export class PabPuissanceParams extends ParamsEquation {
         return this._V;
     }
 
-    get Pv() {
-        return this._Pv;
+    get PV() {
+        return this._PV;
     }
 }
 
@@ -66,7 +66,7 @@ export class PabPuissance extends Nub {
         let v: number;
 
         switch (sVarCalc) {
-            case "Pv":
+            case "PV":
                 const ro: number = 1000;     // masse volumique de l'eau en kg/m3
                 const g: number = 9.81;     // accélération de la gravité terrestre en m/s2.
                 v = ro * g * this.prms.Q.v * this.prms.DH.v / this.prms.V.v;
@@ -86,7 +86,7 @@ export class PabPuissance extends Nub {
         this.prms.DH.calculability = ParamCalculability.DICHO;
         this.prms.Q.calculability = ParamCalculability.DICHO;
         this.prms.V.calculability = ParamCalculability.DICHO;
-        this.prms.Pv.calculability = ParamCalculability.EQUATION;
+        this.prms.PV.calculability = ParamCalculability.EQUATION;
     }
 
 }
diff --git a/src/structure/cloisons.ts b/src/structure/cloisons.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6571566f3811c4e8bd621b17b1d537155527b935
--- /dev/null
+++ b/src/structure/cloisons.ts
@@ -0,0 +1,91 @@
+import { PabPuissance, PabPuissanceParams } from "../pab/pab_puissance";
+import { ParamCalculability, ParamDefinition } from "../param/param-definition";
+import { Result } from "../util/result";
+import { CloisonsParams } from "./cloisons_params";
+import { ParallelStructure } from "./parallel_structure";
+import { StructureKiviParams } from "./structure_kivi";
+
+export { CloisonsParams };
+
+export class Cloisons extends ParallelStructure {
+    constructor(prms: CloisonsParams, dbg: boolean = false) {
+        super(prms, dbg);
+    }
+
+    /**
+     * paramètres castés au bon type
+     */
+    get prms(): CloisonsParams {
+        return this._prms as CloisonsParams;
+    }
+
+    /**
+     * 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", "DH" ou "n.X" avec "n" l'index de l'ouvrage et "X" son paramètre
+     * @param rInit Valeur initiale
+     * @param rPrec Précision attendue
+     */
+    public Calc(sVarCalc: string, rInit?: number, rPrec: number = 0.001): Result {
+        // Mise à jour de ZRAM pour Kivi à partir de Z1 - PB
+        this.updateKiviZRAM();
+
+        // Transformation DH => Z2
+        this.prms.Z2.v = this.prms.Z1.v - this.prms.DH.v;
+        let sVC: string = sVarCalc;
+        if (sVarCalc === "DH") {
+            sVC = "Z2";
+        }
+
+        const r: Result = super.Calc(sVC, rInit, rPrec);
+
+        // Transformation Z2 => DH
+        if (sVarCalc === "DH") {
+            r.vCalc = this.prms.Z1.v - r.vCalc;
+        }
+
+        // Ajout du calcul de la puissance dissipée
+        const prms = this.getcalculatedparams(sVarCalc, r);
+        const puissanceNub: PabPuissance = new PabPuissance(
+            new PabPuissanceParams(
+                prms.DH,
+                prms.Q,
+                prms.LB * prms.BB * prms.PB
+            )
+        );
+        r.extraResults.PV = puissanceNub.Calc("PV", 0).vCalc;
+
+        return r;
+    }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.LB.calculability = ParamCalculability.FREE;
+        this.prms.BB.calculability = ParamCalculability.FREE;
+        this.prms.PB.calculability = ParamCalculability.FREE;
+        this.prms.DH.calculability = ParamCalculability.DICHO;
+    }
+
+    protected getcalculatedparams(sVarCalc: string, result: Result): { [key: string]: number } {
+        const cPrms: { [key: string]: number } = {};
+        for (const p of this.parameterIterator) {
+            if (p.symbol === sVarCalc) {
+                cPrms[p.symbol] = result.vCalc;
+            } else {
+                cPrms[p.symbol] = p.v;
+            }
+        }
+        return cPrms;
+    }
+
+    private updateKiviZRAM() {
+        for (const structure of this.structures) {
+            if (structure.prms instanceof StructureKiviParams) {
+                structure.prms.ZRAM.v = this.prms.Z1.v - this.prms.PB.v;
+            }
+        }
+    }
+}
diff --git a/src/structure/cloisons_params.ts b/src/structure/cloisons_params.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ca7d27323ee4e530d0aef1e4816c191a541c063c
--- /dev/null
+++ b/src/structure/cloisons_params.ts
@@ -0,0 +1,41 @@
+import { ParamDefinition } from "../param/param-definition";
+import { ParamDomainValue } from "../param/param-domain";
+import { ParallelStructureParams } from "./parallel_structure_params";
+
+/**
+ * Common parameters of hydraulic structure equations
+ */
+export class CloisonsParams extends ParallelStructureParams {
+    /** Largeur des bassins (m) */
+    public BB: ParamDefinition;
+
+    /** Longueur des bassins (m) */
+    public LB: ParamDefinition;
+
+    /** Profondeur moyenne (m) */
+    public PB: ParamDefinition;
+
+    /** Hauteur de chute (m) */
+    public DH: ParamDefinition;
+
+    /**
+     * Paramètres communs à toutes les équations de structure
+     * @param rQ Débit total (m3/s)
+     * @param rZ1 Cote de l'eau amont (m)
+     * @param rLB Longueur des bassins (m)
+     * @param rBB Largeur des bassins (m)
+     * @param rPB Profondeur moyenne (m)
+     * @param rDH Hauteur de chute (m)
+     */
+    constructor(rQ: number, rZ1: number, rLB: number, rBB: number, rPB: number, rDH: number) {
+        super(rQ, rZ1, rZ1 - rDH);
+        this.LB = new ParamDefinition("LB", ParamDomainValue.POS, rLB);
+        this.addParamDefinition(this.LB);
+        this.BB = new ParamDefinition("BB", ParamDomainValue.POS, rBB);
+        this.addParamDefinition(this.BB);
+        this.PB = new ParamDefinition("PB", ParamDomainValue.POS, rPB);
+        this.addParamDefinition(this.PB);
+        this.DH = new ParamDefinition("DH", ParamDomainValue.POS, rDH);
+        this.addParamDefinition(this.DH);
+    }
+}
diff --git a/src/structure/dever.ts b/src/structure/dever.ts
index 2f9355881bd8ee3a03edb1bad4d63603305b0a6f..51fba3774da8c764c46020016ed8dedf89c93c4b 100644
--- a/src/structure/dever.ts
+++ b/src/structure/dever.ts
@@ -1,4 +1,3 @@
-import { Nub } from "../nub";
 import { ParamCalculability, ParamDefinition } from "../param/param-definition";
 import { Result } from "../util/result";
 import { DeverParams } from "./dever_params";
diff --git a/src/structure/factory_structure.ts b/src/structure/factory_structure.ts
index 912003139efb808efcbcdb37fe04b14a001fe4cc..d607f256536e1aa71988608708d1cec05cbb853a 100644
--- a/src/structure/factory_structure.ts
+++ b/src/structure/factory_structure.ts
@@ -1,18 +1,21 @@
+// Classes générales sur les structures
 import { RectangularStructureParams } from "./rectangular_structure_params";
 import { Structure } from "./structure";
+import { LoiDebit, StructureProperties, StructureType } from "./structure_props";
+
+// Equations de débit
 import { StructureCem88d } from "./structure_cem88d";
 import { StructureCem88v } from "./structure_cem88v";
 import { StructureCunge80 } from "./structure_cunge80";
-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 { StructureKivi, StructureKiviParams } from "./structure_kivi";
+import { StructureOrificeSubmerged, StructureOrificeSubmergedParams } from "./structure_orifice_submerged";
+import { StructureRectangularOrificeFree } from "./structure_rectangular_orifice_free";
+import { StructureRectangularOrificeSubmerged } from "./structure_rectangular_orifice_submerged";
 // tslint:disable-next-line:max-line-length
 import { StructureTriangularTruncWeirFree, TriangularTruncStructureParams } from "./structure_triangular_trunc_weir_free";
 import { StructureTriangularWeirFree, TriangularStructureParams } from "./structure_triangular_weir_free";
 import { StructureWeirFree } from "./structure_weir_free";
-
+import { StructureWeirSubmergedLarinier } from "./structure_weir_submerged_larinier";
 
 export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit, dbg: boolean = false): Structure {
     const oCd: {[s: string]: number} = {SeuilR: 0.4, VanneR: 0.6, SeuilT: 1.36};
@@ -35,6 +38,7 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit
         case StructureType.SeuilRectangulaire:
         case StructureType.SeuilTriangulaire:
         case StructureType.SeuilTriangulaireTrunc:
+        case StructureType.Orifice:
             break;
 
         default:
@@ -62,19 +66,22 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit
             rectStructPrms.Cd.v = oCd.VanneR; // Cd Cunge80 qu'on soit en seuil ou vanne
             return new StructureCunge80(rectStructPrms, dbg);
 
-        case LoiDebit.OrificeFree:
-            return new StructureOrificeFree(rectStructPrms, dbg);
+        case LoiDebit.RectangularOrificeFree:
+            return new StructureRectangularOrificeFree(rectStructPrms, dbg);
 
-        case LoiDebit.OrificeSubmerged:
-            return new StructureOrificeSubmerged(rectStructPrms, dbg);
+        case LoiDebit.RectangularOrificeSubmerged:
+            return new StructureRectangularOrificeSubmerged(rectStructPrms, dbg);
 
         case LoiDebit.WeirFree:
             return new StructureWeirFree(rectStructPrms, dbg);
 
+        case LoiDebit.WeirSubmergedLarinier:
+            return new StructureWeirSubmergedLarinier(rectStructPrms, dbg);
+
         case LoiDebit.KIVI:
             const structKiviPrm: StructureKiviParams = new StructureKiviParams(
                 8.516,      // Q
-                101,        // ZDV
+                101.5,        // ZDV
                 103,        // Z1
                 102,        // Z2
                 2,          // L
@@ -82,7 +89,7 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit
                 0.001,      // béta
                 100);       // ZRAM : cote Radier Amont
             return new StructureKivi(structKiviPrm, dbg);
-            case LoiDebit.TriangularWeirFree:
+        case LoiDebit.TriangularWeirFree:
             const structTriangPrms: TriangularStructureParams = new TriangularStructureParams(
                 0,          // Q
                 100,        // ZDV
@@ -92,7 +99,7 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit
                 // W = Infinity par défaut pour un seuil
             );
             return new StructureTriangularWeirFree(structTriangPrms, dbg);
-            case LoiDebit.TriangularTruncWeirFree:
+        case LoiDebit.TriangularTruncWeirFree:
             const structTriTruncPrms: TriangularTruncStructureParams = new TriangularTruncStructureParams(
                 0,          // Q
                 100.1,        // ZDV
@@ -103,6 +110,17 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit
                 // W = Infinity par défaut pour un seuil
             );
             return new StructureTriangularTruncWeirFree(structTriTruncPrms, dbg);
+        case LoiDebit.OrificeSubmerged:
+            return new StructureOrificeSubmerged(
+                new StructureOrificeSubmergedParams(
+                    0,      // Q
+                    102,    // Z1
+                    101.5,  // Z2
+                    0.7,    // Cd
+                    0.1     // S
+                ),
+                dbg
+            );
 
         default:
             throw new Error(`type de LoiDebit ${LoiDebit[loiDebit]} non pris en charge`);
diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts
index 1ecbc67a0febad528dab4f8d83385f012a91d838..4710780eaa5bd2b9a8083f5919b2955acacc10bb 100644
--- a/src/structure/parallel_structure.ts
+++ b/src/structure/parallel_structure.ts
@@ -230,8 +230,9 @@ export class ParallelStructure extends Nub {
                 // analyse ouvrage[n].X
                 const i: IStructureVarCalc = this.getStructureVarCalc2(desc);
                 const res = this.structures[i.index].result;
-                if (res === undefined)
+                if (res === undefined) {
                     return undefined;  // pas de résultat calculé
+                }
                 return res.getExtraResult(i.prm);
             } catch (e) {
                 // desc n'est pas de la forme ouvrage[n].X
@@ -299,7 +300,7 @@ export class ParallelStructure extends Nub {
     /**
      * Mise à jour de Z1, Z2, h1 et h2 pour tous les ouvrages
      */
-    private updateStructuresH1H2() {
+    protected updateStructuresH1H2() {
         for (const structure of this.structures) {
             structure.prms.Z1.v = this.prms.Z1.v;
             structure.prms.Z2.v = this.prms.Z2.v;
diff --git a/src/structure/structure.ts b/src/structure/structure.ts
index 8965a98e88998f5072715bb6c92c961b4df3985e..c3effee93fa0176b5226db684b896cba39fd5cfb 100644
--- a/src/structure/structure.ts
+++ b/src/structure/structure.ts
@@ -33,6 +33,18 @@ export enum StructureFlowRegime {
     NULL,
 }
 
+/**
+ * Type de jet : Sans objet (orifice), plongeant, de surface
+ */
+export enum StructureJetType {
+    /** Sans objet (orifice) */
+    SO,
+    /** Plongeant */
+    PLONGEANT,
+    /** De surface */
+    SURFACE,
+}
+
 /**
  * classe de calcul sur la conduite distributrice
  */
@@ -100,16 +112,16 @@ export abstract class Structure extends Nub {
         // Gestion du débit nul
         const flagsNull = { Mode: StructureFlowMode.NULL, Regime: StructureFlowRegime.NULL };
         if (sVarCalc === "Q") {
-            if (this.prms.h1.v === this.prms.h2.v || this.prms.W.v <= 0) {
+            if (this.prms.h1.v <= 0 || this.prms.Z1.v === this.prms.Z2.v || this.prms.W.v <= 0) {
                 return new Result(0, flagsNull);
             }
         } 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 "Z1":
-                    return new Result(this.prms.h2.v, flagsNull);
+                    return new Result(this.prms.Z2.v, flagsNull);
                 case "Z2":
-                    return new Result(this.prms.h1.v, flagsNull);
+                    return new Result(this.prms.Z1.v, flagsNull);
                 default:
                     // Est-ce toujours vrai ? Nécessitera peut-être d'étendre la méthode
                     return new Result(0, flagsNull);
@@ -212,4 +224,22 @@ export abstract class Structure extends Nub {
             return StructureFlowRegime.SUBMERGED;
         }
     }
+
+    /**
+     * Give the Jet Type for weir flow
+     * Cf. Baudoin J.M., Burgun V., Chanseau M., Larinier M., Ovidio M., SremskiW., Steinbach P. et Voegtle B., 2014.
+     * Evaluer le franchissement des obstacles par les poissons. Principes et méthodes. Onema. 200 pages
+     */
+    protected getJetType(): StructureJetType {
+        if (this.getFlowMode() === StructureFlowMode.WEIR) {
+            if (Math.abs(this.prms.h1.v - this.prms.h2.v) < 0.5 * this.prms.h1.v) {
+                return StructureJetType.SURFACE;
+            } else {
+                return StructureJetType.PLONGEANT;
+            }
+        } else {
+            return StructureJetType.SO;
+        }
+    }
+
 }
diff --git a/src/structure/structure_kivi.ts b/src/structure/structure_kivi.ts
index e1bade6082007e4557476505f40156c0785a2c0a..082bdf614540ea028445f620f879ff7663914622 100644
--- a/src/structure/structure_kivi.ts
+++ b/src/structure/structure_kivi.ts
@@ -5,6 +5,8 @@ import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
 import { StructureKiviParams } from "./structure_kivi_params";
 import { Villemonte } from "./villemonte";
 
+export { StructureKiviParams };
+
 export class StructureKivi extends Structure {
 
     constructor(prms: StructureKiviParams, dbg: boolean = false) {
diff --git a/src/structure/structure_orifice_submerged.ts b/src/structure/structure_orifice_submerged.ts
index be0dae154c58eb52a64140a5644f4425b83c516b..3350831d1ce05a352267bacee58666c7cbdbe6c9 100644
--- a/src/structure/structure_orifice_submerged.ts
+++ b/src/structure/structure_orifice_submerged.ts
@@ -1,20 +1,25 @@
+import { ParamCalculability } from "../param/param-definition";
+import { Structure, StructureFlowMode, StructureFlowRegime } from "../structure/structure";
 import { Result } from "../util/result";
-import { RectangularStructure } from "./rectangular_structure";
-import { RectangularStructureParams } from "./rectangular_structure_params";
-import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { StructureOrificeSubmergedParams } from "./structure_orifice_submerged_params";
 
-export { RectangularStructureParams };
+export { StructureOrificeSubmergedParams };
 
 /**
  * Equation classique orifice noyé
  */
-export class StructureOrificeSubmerged extends RectangularStructure {
+export class StructureOrificeSubmerged extends Structure {
 
-    constructor(prms: RectangularStructureParams, dbg: boolean = false) {
+    constructor(prms: StructureOrificeSubmergedParams, dbg: boolean = false) {
         super(prms, dbg);
-        if (prms.W.v !== Infinity) {
-            this._isZDVcalculable = false;
-        }
+        this._isZDVcalculable = false;
+    }
+
+    /**
+     * paramètres castés au bon type
+     */
+    get prms(): StructureOrificeSubmergedParams {
+        return this._prms as StructureOrificeSubmergedParams;
     }
 
     /**
@@ -25,13 +30,30 @@ export class StructureOrificeSubmerged extends RectangularStructure {
         Structure.CheckEquation(sVarCalc);
         const data = this.getResultData();
 
-        const v = this.prms.Cd.v * Math.min(this.prms.W.v, this.prms.h1.v) * this.prms.L.v
-            * Structure.R2G * Math.sqrt(this.prms.h1.v - this.prms.h2.v);
+        const v = this.prms.Cd.v * this.prms.S.v * Structure.R2G * Math.sqrt(this.prms.Z1.v - this.prms.Z2.v);
 
         return new Result(v, data);
     }
 
+    public calcA(): number {
+        return this.prms.S.v;
+    }
+
     protected getFlowRegime() {
         return StructureFlowRegime.SUBMERGED;
     }
+
+    protected getFlowMode() {
+        return StructureFlowMode.ORIFICE;
+    }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.S.calculability = ParamCalculability.DICHO;
+        this.prms.Cd.calculability = ParamCalculability.DICHO;
+        this.prms.ZDV.calculability = ParamCalculability.NONE;
+    }
 }
diff --git a/src/structure/structure_orifice_submerged_params.ts b/src/structure/structure_orifice_submerged_params.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a8f861726f24904096264fcd4d27d97d8b87279d
--- /dev/null
+++ b/src/structure/structure_orifice_submerged_params.ts
@@ -0,0 +1,40 @@
+import { ParamDefinition } from "../param/param-definition";
+import { ParamDomainValue } from "../param/param-domain";
+import { StructureParams } from "../structure/structure_params";
+
+/**
+ * Parameters for rectangular structures (common for all rectangular structure equations)
+ */
+export class StructureOrificeSubmergedParams extends StructureParams {
+
+    /** Area of the orifice (m2) */
+    public S: ParamDefinition;
+
+    /** Discharge coefficient */
+    // tslint:disable-next-line:variable-name
+    public Cd: ParamDefinition;
+
+    /**
+     * Constructeur d'une structure rectangulaire
+     * @param rQ    Débit (m3/s)
+     * @param rZ1   Cote de l'eau amont (m)
+     * @param rZ2   Cote de l'eau aval (m)
+     * @param rCd   Coefficient de débit (-)
+     * @param rS    Surface de l'orifice (m2)
+     */
+    constructor(rQ: number, rZ1: number, rZ2: number, rCd: number, rS: number) {
+        super(rQ, -Infinity, rZ1, rZ2);
+        this.S = new ParamDefinition("S", ParamDomainValue.POS_NULL, rS);
+        this.addParamDefinition(this.S);
+        this.Cd = new ParamDefinition("Cd", ParamDomainValue.POS_NULL, rCd);
+        this.addParamDefinition(this.Cd);
+    }
+
+    /**
+     * Mise à jour de h1 et h2
+     */
+    public update_h1h2() {
+        // Inutile pour cette équation qui ne fait pas intervenir ces variables
+    }
+
+}
diff --git a/src/structure/structure_params.ts b/src/structure/structure_params.ts
index 28ff720ad5f5dd5b8cd186ddbaf304f566ff9bd7..8740525ea3d4334f39b65c0c2c7f3f0ca25f8edf 100644
--- a/src/structure/structure_params.ts
+++ b/src/structure/structure_params.ts
@@ -1,7 +1,7 @@
 import { Nub } from "../nub";
-import { ParamsEquation } from "../param/params-equation";
 import { ParamDefinition } from "../param/param-definition";
 import { ParamDomainValue } from "../param/param-domain";
+import { ParamsEquation } from "../param/params-equation";
 
 /**
  * Common parameters of hydraulic structure equations
diff --git a/src/structure/structure_props.ts b/src/structure/structure_props.ts
index d7835ef44d4fed4e57e5f6bacc58b0d644eb3e78..0988e11ff4cb35812c067cf1fdba7fc05c44d896 100644
--- a/src/structure/structure_props.ts
+++ b/src/structure/structure_props.ts
@@ -1,5 +1,9 @@
 export enum StructureType {
-    SeuilRectangulaire, VanneRectangulaire, SeuilTriangulaire, SeuilTriangulaireTrunc
+    SeuilRectangulaire,
+    VanneRectangulaire,
+    Orifice,
+    SeuilTriangulaire,
+    SeuilTriangulaireTrunc
     // VanneCirculaire,
     // VanneTrapezoidale, SeuilTrapezoidal
 }
@@ -12,9 +16,9 @@ export enum LoiDebit {
     // loi de débit Cunge 1980
     Cunge80,
     // loi de débit pour vanne dénoyée
-    OrificeFree,
+    RectangularOrificeFree,
     // loi de débit pour vanne noyée
-    OrificeSubmerged,
+    RectangularOrificeSubmerged,
     // loi de débit pour seuil dénoyé
     WeirFree,
     // Loi Kindsvater-Carter et Villemonte
@@ -22,13 +26,20 @@ export enum LoiDebit {
     // Loi de débit seuil triangulaire dénoyé
     TriangularWeirFree,
     // Loi de débit seuil triangulaire tronqué
-    TriangularTruncWeirFree
+    TriangularTruncWeirFree,
+    // Loi de débit seuil noyé (Larinier 1992)
+    WeirSubmergedLarinier,
+    // Loi de débit orifice noyé
+    OrificeSubmerged
 }
 
 export const loiAdmissibles: { [key: string]: LoiDebit[] } = {
+    Orifice: [
+        LoiDebit.OrificeSubmerged
+    ],
     SeuilRectangulaire: [
         LoiDebit.Cem88d, LoiDebit.Cem88v, LoiDebit.Cunge80, LoiDebit.WeirFree,
-        LoiDebit.KIVI
+        LoiDebit.KIVI, LoiDebit.WeirSubmergedLarinier
     ],
     SeuilTriangulaire: [
         LoiDebit.TriangularWeirFree
@@ -37,8 +48,8 @@ export const loiAdmissibles: { [key: string]: LoiDebit[] } = {
         LoiDebit.TriangularTruncWeirFree
     ],
     VanneRectangulaire: [
-        LoiDebit.Cem88d, LoiDebit.Cem88v, LoiDebit.Cunge80, LoiDebit.OrificeFree,
-        LoiDebit.OrificeSubmerged
+        LoiDebit.Cem88d, LoiDebit.Cem88v, LoiDebit.Cunge80, LoiDebit.RectangularOrificeFree,
+        LoiDebit.RectangularOrificeSubmerged
     ]
 };
 
@@ -66,10 +77,20 @@ export class StructureProperties {
     }
 
     /**
-     * @return la 1ère valeur de LoiDebit compatible avec le type de structure
+     * trouve la 1ère valeur de LoiDebit compatible avec le type de structure
+     * @param struct type de structure avec laquelle la loi de débit doit être compatible
+     * @param subset si non vide, recherche la loi de débit compatible dans ce tableau; sinon prend la 1ere
      */
-    public static findCompatibleLoiDebit(struct: StructureType): LoiDebit {
+    public static findCompatibleLoiDebit(struct: StructureType, subset: LoiDebit[]): LoiDebit {
         const sst: string = StructureType[struct];
-        return loiAdmissibles[sst][0];
+
+        if (subset.length === 0)
+            return loiAdmissibles[sst][0];
+
+        for (const ld of loiAdmissibles[sst])
+            if (subset.includes(ld))
+                return ld;
+
+        return undefined;
     }
 }
diff --git a/src/structure/structure_orifice_free.ts b/src/structure/structure_rectangular_orifice_free.ts
similarity index 85%
rename from src/structure/structure_orifice_free.ts
rename to src/structure/structure_rectangular_orifice_free.ts
index 4d18544dcf38ff1823b7a8b9f9b2856bec36a744..596fa6e06fe2bedb58f80a819644d6da4eff5154 100644
--- a/src/structure/structure_orifice_free.ts
+++ b/src/structure/structure_rectangular_orifice_free.ts
@@ -1,14 +1,14 @@
 import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
-import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { Structure, StructureFlowRegime } from "./structure";
 
 export { RectangularStructureParams };
 
 /**
  * Equation classique orifice dénoyé
  */
-export class StructureOrificeFree extends RectangularStructure {
+export class StructureRectangularOrificeFree extends RectangularStructure {
     /**
      * Calcul du débit avec l'équation classique d'un orifice dénoyé
      * @param sVarCalc Variable à calculer (doit être égale à Q ici)
diff --git a/src/structure/structure_rectangular_orifice_submerged.ts b/src/structure/structure_rectangular_orifice_submerged.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5d0515911316b4d4fac312ba27f45846e69f3485
--- /dev/null
+++ b/src/structure/structure_rectangular_orifice_submerged.ts
@@ -0,0 +1,37 @@
+import { Result } from "../util/result";
+import { RectangularStructure } from "./rectangular_structure";
+import { RectangularStructureParams } from "./rectangular_structure_params";
+import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+
+export { RectangularStructureParams };
+
+/**
+ * Equation classique orifice noyé
+ */
+export class StructureRectangularOrificeSubmerged extends RectangularStructure {
+
+    constructor(prms: RectangularStructureParams, dbg: boolean = false) {
+        super(prms, dbg);
+        if (prms.W.v !== Infinity) {
+            this._isZDVcalculable = false;
+        }
+    }
+
+    /**
+     * Calcul du débit avec l'équation classique d'un orifice noyé
+     * @param sVarCalc Variable à calculer (doit être égale à Q ici)
+     */
+    public Equation(sVarCalc: string): Result {
+        Structure.CheckEquation(sVarCalc);
+        const data = this.getResultData();
+
+        const v = this.prms.Cd.v * Math.min(this.prms.W.v, this.prms.h1.v) * this.prms.L.v
+            * Structure.R2G * Math.sqrt(this.prms.h1.v - this.prms.h2.v);
+
+        return new Result(v, data);
+    }
+
+    protected getFlowRegime() {
+        return StructureFlowRegime.SUBMERGED;
+    }
+}
diff --git a/src/structure/structure_weir_submerged_larinier.ts b/src/structure/structure_weir_submerged_larinier.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f3468ac4fbeff4041c132ac789d61c267ce11b98
--- /dev/null
+++ b/src/structure/structure_weir_submerged_larinier.ts
@@ -0,0 +1,35 @@
+import { Result } from "../util/result";
+import { RectangularStructure } from "./rectangular_structure";
+import { RectangularStructureParams } from "./rectangular_structure_params";
+import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+
+export { RectangularStructureParams };
+
+/**
+ * Equation de la fente noyé
+ * d'après Larinier, M., Travade, F., Porcher, J.-P., Gosset, C., 1992.
+ * Passes à poissons : expertise et conception des ouvrages de franchissement
+ */
+export class StructureWeirSubmergedLarinier extends RectangularStructure {
+    /**
+     * 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.prms.L.v * Structure.R2G
+            * this.prms.h1.v * Math.sqrt(this.prms.h1.v - this.prms.h2.v);
+
+        return new Result(v, data);
+    }
+
+    protected getFlowRegime() {
+        return StructureFlowRegime.SUBMERGED;
+    }
+
+    protected getFlowMode() {
+        return StructureFlowMode.WEIR;
+    }
+}