diff --git a/spec/structure/parallel_structure.spec.ts b/spec/structure/parallel_structure.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e4601e2dbbf1b0e6365f7022606fc855dac857cf
--- /dev/null
+++ b/spec/structure/parallel_structure.spec.ts
@@ -0,0 +1,39 @@
+/**
+ * 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 } from "../mock_jasmine";
+
+import { ParallelStructure } from "../../src/structure/parallel_structure";
+import { ParallelStructureParams } from "../../src/structure/parallel_structure_params";
+import { Result } from "../../src/util/result";
+import { checkResult } from "../test_func";
+import { structTest } from "./structure_test";
+
+const pstruct: ParallelStructure = new ParallelStructure(
+    new ParallelStructureParams(30, 30, 15), // Q = 30, Z1 = 30, Z2 = 15
+    false // debug
+);
+
+// Test avec deux structures test identiques
+pstruct.addStructure(structTest);
+pstruct.addStructure(structTest);
+
+describe("Class ParallelStructure: ", () => {
+    describe("Calc()", () => {
+        itParallelStructure("Q", 30, 15);
+        itParallelStructure("Z1", 30, 15);
+        itParallelStructure("Z2", 15, 15);
+    });
+});
+
+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);
+    });
+}
diff --git a/spec/structure/structure.spec.ts b/spec/structure/structure.spec.ts
index 77ae245395b81eba25dbf19109258b5bd054c1db..f1c23d0a8339db96b1e55bcffe6c0f9ee313de5e 100644
--- a/spec/structure/structure.spec.ts
+++ b/spec/structure/structure.spec.ts
@@ -47,7 +47,7 @@ describe("Class Structure: ", () => {
 
     describe("Calc()", () => {
         const flagsNull = { Mode: StructureFlowMode.NULL, Regime: StructureFlowRegime.NULL };
-        it("h1=h2 => Q=0", () => {
+        it("Z1=Z2 => Q=0", () => {
             structTest.prms.Z2.v = structTest.prms.Z1.v;
             checkResult(structTest.Calc("Q"), 0);
             expect(structTest.Calc("Q").extraResults).toEqual(flagsNull);
@@ -59,10 +59,10 @@ describe("Class Structure: ", () => {
             expect(structTest.Calc("Q").extraResults).toEqual(flagsNull);
             structTest.prms.W.v = Infinity;
         });
-        it("Q=0 => h1=h2", () => {
+        it("Q=0 => Z1=Z2", () => {
             structTest.prms.Q.v = 0;
-            checkResult(structTest.Calc("h1"), structTest.prms.h2.v);
-            expect(structTest.Calc("h1").extraResults).toEqual(flagsNull);
+            checkResult(structTest.Calc("Z1"), structTest.prms.h2.v);
+            expect(structTest.Calc("Z1").extraResults).toEqual(flagsNull);
             structTest.prms.Q.v = 1;
         });
         it("Q=0 => W=0", () => {
diff --git a/spec/structure/structure_test.ts b/spec/structure/structure_test.ts
index 20c03c7663255b53f70228fc0ce10965027d3cae..c4e582feafa5f8011717b2fe3b84eec917649034 100644
--- a/spec/structure/structure_test.ts
+++ b/spec/structure/structure_test.ts
@@ -26,10 +26,18 @@ class StructureTest extends Structure {
     public Equation(sVarCalc: string): Result {
         this.prms.update_h1h2();
         Structure.CheckEquation(sVarCalc);
-        return new Result(this.prms.Z1.v - this.prms.Z2.v);
+        const data = this.getResultData();
+
+        return new Result(this.prms.Z1.v - this.prms.Z2.v, data);
     }
 
 }
 
+/* Test structure with :
+ *  - ZDV = 0
+ *  - Z1 = 30
+ *  - Z2 = 15
+ *  - expected Q = 15
+ */
 export const structTestPrm: StructureParams = new StructureParams(1, 0, 30, 15);
 export const structTest: StructureTest = new StructureTest(structTestPrm, false);
diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c692fd4b67dc9d68cd7efa14ad3ad1f69bb20e12
--- /dev/null
+++ b/src/structure/parallel_structure.ts
@@ -0,0 +1,152 @@
+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";
+
+/**
+ * Calcul de une ou plusieurs structures hydrauliques en parallèles
+ * reliées par les cotes amont et aval et dont le débit est égal à la
+ * somme des débits de chaque structure.
+ */
+export class ParallelStructure extends Nub {
+
+    /** Tableau des structures hydrauliques en parallèle */
+    public structures: Structure[] = [];
+
+    /**
+     * paramètres castés au bon type
+     */
+    get prms(): ParallelStructureParams {
+        return this._prms as ParallelStructureParams;
+    }
+
+    /**
+     * Mise à jour de Z1 pour toutes les structures en parallèle
+     */
+    set Z1(Z1: number) {
+        this.prms.Z1.v = Z1;
+        for (const structure of this.structures) {
+            structure.prms.Z1.v = Z1;
+            structure.prms.update_h1h2();
+        }
+    }
+
+    /**
+     * Mise à jour de Z2 pour toutes les structures en parallèle
+     */
+    set Z2(Z2: number) {
+        this.prms.Z2.v = Z2;
+        for (const structure of this.structures) {
+            structure.prms.Z2.v = Z2;
+            structure.prms.update_h1h2();
+        }
+    }
+
+    /**
+     * Ajout d'une structure en parallèle
+     * @param structure La structure à rajouter
+     */
+    public addStructure(structure: Structure) {
+        this.structures.push(structure);
+    }
+
+    /**
+     * Supprime une structure hydraulique
+     * @param index numéro de la structure dans le tableau
+     */
+    public deleteStructure(index: number) {
+        if (index > -1) {
+            this.structures.splice(index, 1);
+        } else {
+            throw new Error("ParallelStructure.deleteStructure invalid index=" + index);
+        }
+    }
+
+    /**
+     * Calcul du débit des structures en parallèle (sans détail pour chaque structure)
+     * @param sVarCalc Variable à calculer (Q uniquement)
+     */
+    public Equation(sVarCalc: string): Result {
+        Structure.CheckEquation(sVarCalc);
+        this.Z1 = this.prms.Z1.v;
+        this.Z2 = this.prms.Z2.v;
+        return this.CalcQ();
+    }
+
+    /**
+     * Calcul de la somme des débits de chaque structure
+     * @param iExcept Index de la structure à ne pas additionner (optionel)
+     */
+    public CalcQ(iExcept?: number): Result {
+        if (iExcept !== undefined) {
+            if (iExcept < 0 || iExcept >= this.structures.length) {
+                throw new Error(
+                    "ParallelStructure.CalcQ iExcept not in [0;" + (this.structures.length - 1) + "]",
+                );
+            }
+        }
+        const calcRes: Result = new Result();
+        let qTot: number = 0;
+        for (let i = 0 ; i < this.structures.length; i++) {
+            if (i !== iExcept) {
+                const res: Result = this.structures[i].Calc("Q");
+                calcRes.addResult(res.result);
+                qTot += res.vCalc;
+            }
+        }
+        // Insert le débit total en premier résultat
+        calcRes.insertResult(new Result(qTot).result, 0);
+        return calcRes;
+    }
+
+    /**
+     * 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", "Z2" 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 = 0, rPrec: number = 0.001): Result {
+        switch (sVarCalc) {
+            case "Z1" :
+            case "Z2" :
+            case "Q" :
+                return super.Calc(sVarCalc, rInit, rPrec);
+            default:
+                // Pour les caractéristiques des ouvrages
+                return this.CalcStructPrm(sVarCalc, rInit, rPrec);
+        }
+    }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        this.prms.Q.calculability = ParamCalculability.EQUATION;
+        this.prms.Z1.calculability = ParamCalculability.DICHO;
+        this.prms.Z2.calculability = ParamCalculability.DICHO;
+    }
+
+    /**
+     * Calcul du paramètre d'un des ouvrages en parallèle
+     * @param sVarCalc Nom du paramètre à calculer : "n.X" avec "n" l'index de l'ouvrage et "X" son paramètre
+     * @param rInit Valeur initiale
+     * @param rPrec Précision attendue
+     */
+    private CalcStructPrm(sVarCalc: string, rInit: number = 0, rPrec: number = 0.001): Result {
+        // Détection de la structure où calculer le paramètre
+        let sIndex: string;
+        let sPrm: string;
+        [sIndex, sPrm] = sVarCalc.split(".");
+        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;
+
+        // Calcul du paramètre de la structure en calcul
+        return this.structures[index].Calc(sPrm, rInit, rPrec);
+    }
+}
diff --git a/src/structure/parallel_structure_params.ts b/src/structure/parallel_structure_params.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c7d556dbfc0eb1b920e3da8ea900491eecd8023c
--- /dev/null
+++ b/src/structure/parallel_structure_params.ts
@@ -0,0 +1,32 @@
+import { Nub } from "../nub";
+import { ComputeNodeType, ParamDefinition, ParamDomainValue, ParamsEquation } from "../param";
+
+/**
+ * Common parameters of hydraulic structure equations
+ */
+export class ParallelStructureParams extends ParamsEquation {
+    /** Débit (m3/s) */
+    public Q: ParamDefinition;
+
+    /** Cote de l'eau amont (m) */
+    public Z1: ParamDefinition;
+
+    /** Cote de l'eau aval (m) */
+    public Z2: 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 rZ2 Cote de l'eau aval (m)
+     */
+    constructor(rQ: number, rZ1: number, rZ2: number) {
+        super();
+        this.Q = new ParamDefinition(ComputeNodeType.CondDistri, "Q", ParamDomainValue.ANY, rQ);
+        this.addParamDefinition(this.Q);
+        this.Z1 = new ParamDefinition(ComputeNodeType.CondDistri, "Z1", ParamDomainValue.ANY, rZ1);
+        this.addParamDefinition(this.Z1);
+        this.Z2 = new ParamDefinition(ComputeNodeType.CondDistri, "Z2", ParamDomainValue.ANY, rZ2);
+        this.addParamDefinition(this.Z2);
+    }
+}
diff --git a/src/structure/structure.ts b/src/structure/structure.ts
index ca8abac0fe2b525da10664807698c6d4ce630407..809ab19b02c5645c081e3dbec810d14c14b6260f 100644
--- a/src/structure/structure.ts
+++ b/src/structure/structure.ts
@@ -11,12 +11,12 @@ export { StructureParams };
  * Flow mode: weir or orifice flow
  */
 export enum StructureFlowMode {
-   /** Weir flow */
-   WEIR,
-   /** Orifice flow */
-   ORIFICE,
-   /** Zéro flow */
-   NULL,
+    /** Weir flow */
+    WEIR,
+    /** Orifice flow */
+    ORIFICE,
+    /** Zéro flow */
+    NULL,
 }
 
 /**
@@ -31,7 +31,7 @@ export enum StructureFlowRegime {
     SUBMERGED,
     /** Zéro flow */
     NULL,
- }
+}
 
 /**
  * classe de calcul sur la conduite distributrice
@@ -79,23 +79,42 @@ export abstract class Structure extends Nub {
         } else if (this.prms.Q.v === 0) {
             // Débit nul <=> tirant d'eau amont = tirant d'eau aval ou tout autre paramètre nul
             switch (sVarCalc) {
-                case "h1" :
-                    return new Result(this.prms.h2.v, flagsNull);
-                case "h2" :
-                    return new Result(this.prms.h1.v, flagsNull);
+                case "Z1" :
+                return new Result(this.prms.h2.v, flagsNull);
+                case "Z2" :
+                return new Result(this.prms.h1.v, flagsNull);
                 default :
-                    // Est-ce toujours vrai ? Nécessitera peut-être d'étendre la méthode
-                    return new Result(0, flagsNull);
+                // Est-ce toujours vrai ? Nécessitera peut-être d'étendre la méthode
+                return new Result(0, flagsNull);
             }
-        } else if (this.prms.W.v === 0 && sVarCalc === "h1") {
+        } else if (this.prms.W.v === 0 && sVarCalc === "Z1") {
             return new Result(Infinity, flagsNull); // Si la vanne est fermée la cote amont est infinie
         }
 
+        // Gestion du cas d'écoulement impossible Z1 > Z2 et Q <= 0
+        if (!(sVarCalc === "Q" || sVarCalc === "Z1" || sVarCalc === "Z2")) {
+            if (
+                (this.prms.Z1.v > this.prms.Z2.v && this.prms.Q.v <= 0) ||
+                (this.prms.Z1.v < this.prms.Z2.v && this.prms.Q.v >= 0)
+            ) {
+                // On ferme l'ouvrage et on renvoie un code d'erreur
+                let rPrm: number;
+                switch (sVarCalc) {
+                    case "ZDV":
+                    rPrm = Infinity;
+                    default:
+                    rPrm = 0;
+                }
+                // TODO Ajouter un message d'erreur
+                // "Les cotes et le débit ne sont pas cohérents => fermeture de l'ouvrage
+                return new Result(rPrm, flagsNull);
+            }
+        }
+
         // Gestion de l'inversion de débit : on inverse l'amont et l'aval pour le calcul
         if ((sVarCalc === "Q" && (this.prms.h1.v < this.prms.h2.v)) || (sVarCalc !== "Q" && this.prms.Q.v < 0)) {
             [this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion
-            let res: Result;
-            res = super.Calc(sVarCalc, rInit, rPrec);
+            const res: Result = super.Calc(sVarCalc, rInit, rPrec);
             [this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion
             return res;
         }
@@ -104,7 +123,7 @@ export abstract class Structure extends Nub {
         return super.Calc(sVarCalc, rInit, rPrec);
     }
 
-    protected defaultResultData() {
+    protected getResultData() {
         return {
             Mode: this.getFlowMode(),
             Regime: this.getFlowRegime(),
diff --git a/src/structure/structure_cem88d.ts b/src/structure/structure_cem88d.ts
index 99c675de829c5c94b934cda2a0bc92d775c66738..27c2405d7bc35b16eb5633bcd088feac5ea74d3d 100644
--- a/src/structure/structure_cem88d.ts
+++ b/src/structure/structure_cem88d.ts
@@ -16,7 +16,7 @@ export class StructureCem88d extends RectangularStructure {
      */
     public Equation(sVarCalc: string): Result {
         Structure.CheckEquation(sVarCalc);
-        const data = super.defaultResultData();
+        const data = this.getResultData();
 
         let v: number;
         const cd: number = this.prms.Cd.v * this.prms.L.v * Structure.R2G;
diff --git a/src/structure/structure_cem88v.ts b/src/structure/structure_cem88v.ts
index b636fc0e55dd51ded8f86bf7309ce63c8bd21d05..c0dc94caaaef79047b945e1fd85517529441c697 100644
--- a/src/structure/structure_cem88v.ts
+++ b/src/structure/structure_cem88v.ts
@@ -16,7 +16,7 @@ export class StructureCem88v extends RectangularStructure {
      */
     public Equation(sVarCalc: string): Result {
         Structure.CheckEquation(sVarCalc);
-        const data = super.defaultResultData();
+        const data = this.getResultData();
 
         let v: number;
         const mu0: number = 2 / 3 * this.prms.Cd.v;
diff --git a/src/structure/structure_cunge80.ts b/src/structure/structure_cunge80.ts
index 38435d5546636ebdebaac7249e4cda28d4d3ed0d..155aa52ccefcc731842e9645cc77b26d3ffe6060 100644
--- a/src/structure/structure_cunge80.ts
+++ b/src/structure/structure_cunge80.ts
@@ -15,7 +15,7 @@ export class StructureCunge80 extends RectangularStructure {
      */
     public Equation(sVarCalc: string): Result {
         Structure.CheckEquation(sVarCalc);
-        const data = super.defaultResultData();
+        const data = this.getResultData();
         let v: number;
 
         switch (data.Regime) {
diff --git a/src/structure/structure_orifice_free.ts b/src/structure/structure_orifice_free.ts
index 1f4b266fc2a665fd1a18a7e6b8b7c25b6946f002..4d18544dcf38ff1823b7a8b9f9b2856bec36a744 100644
--- a/src/structure/structure_orifice_free.ts
+++ b/src/structure/structure_orifice_free.ts
@@ -15,13 +15,15 @@ export class StructureOrificeFree extends RectangularStructure {
      */
     public Equation(sVarCalc: string): Result {
         Structure.CheckEquation(sVarCalc);
-        const data = super.defaultResultData();
+        const data = this.getResultData();
 
-        // TODO : Warning si les conditions hydrauliques ne correspondent pas à un écoulement dénoyé
-        data.Regime = StructureFlowRegime.FREE;
         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);
 
         return new Result(v, data);
     }
+
+    protected getFlowRegime() {
+        return StructureFlowRegime.FREE;
+    }
 }
diff --git a/src/structure/structure_orifice_submerged.ts b/src/structure/structure_orifice_submerged.ts
index c4f42b50dc793947217a0873660bb901d0fa629e..dd91446e475f119e28d99423f07863ba4d8662df 100644
--- a/src/structure/structure_orifice_submerged.ts
+++ b/src/structure/structure_orifice_submerged.ts
@@ -15,13 +15,15 @@ export class StructureOrificeSubmerged extends RectangularStructure {
      */
     public Equation(sVarCalc: string): Result {
         Structure.CheckEquation(sVarCalc);
-        const data = super.defaultResultData();
+        const data = this.getResultData();
 
-        // TODO : Warning si les conditions hydrauliques ne correspondent pas à un écoulement dénoyé
-        data.Regime = StructureFlowRegime.SUBMERGED;
         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_free.ts b/src/structure/structure_weir_free.ts
index 57ff2f154d8911268d1125ac6854c6565a413278..444dc37259efab1ba4d2a4305cc5b7273ce756f0 100644
--- a/src/structure/structure_weir_free.ts
+++ b/src/structure/structure_weir_free.ts
@@ -15,13 +15,18 @@ export class StructureWeirFree extends RectangularStructure {
      */
     public Equation(sVarCalc: string): Result {
         Structure.CheckEquation(sVarCalc);
-        const data = super.defaultResultData();
+        const data = this.getResultData();
 
-        // TODO : Warning si les conditions hydrauliques ne correspondent pas à un seuil dénoyé
-        data.Regime = StructureFlowRegime.FREE;
-        data.Mode = StructureFlowMode.WEIR;
         const v = this.prms.Cd.v * this.prms.L.v * Structure.R2G * Math.pow(this.prms.h1.v, 1.5);
 
         return new Result(v, data);
     }
+
+    protected getFlowRegime() {
+        return StructureFlowRegime.FREE;
+    }
+
+    protected getFlowMode() {
+        return StructureFlowMode.WEIR;
+    }
 }