diff --git a/src/app/calculators/parallel-structures/parallel-structures.config.json b/src/app/calculators/parallel-structures/parallel-structures.config.json
index bb302ba931b2109a6b398e452fca3b2f67bab74d..165ecec7293575eac838c0a397f6b72fccc0a45e 100644
--- a/src/app/calculators/parallel-structures/parallel-structures.config.json
+++ b/src/app/calculators/parallel-structures/parallel-structures.config.json
@@ -50,35 +50,66 @@
                 "type": "select",
                 "select": [
                     {
-                        "id": "select_loidebit1_cemagref88"
+                        "id": "select_loidebit1_cem88d"
                     },
                     {
-                        "id": "select_loidebit1_vannedenoye"
+                        "id": "select_loidebit1_cem88v"
                     },
                     {
-                        "id": "select_loidebit1_vannenoye"
+                        "id": "select_loidebit1_seuildenoye"
+                    },
+                    {
+                        "id": "select_loidebit1_cunge80"
                     }
                 ],
                 "dep_exist": [
                     {
                         "refid": "select_ouvrage",
-                        "refvalue": "select_ouvrage_vanne_rect"
+                        "refvalue": "select_ouvrage_seuil_rect"
+                    }
+                ]
+            },
+            {
+                "id": "select_loidebit2",
+                "type": "select",
+                "select": [
+                    {
+                        "id": "select_loidebit2_cem88v"
                     },
+                    {
+                        "id": "select_loidebit2_cem88d"
+                    },
+                    {
+                        "id": "select_loidebit2_vannedenoye"
+                    },
+                    {
+                        "id": "select_loidebit2_vannenoye"
+                    },
+                    {
+                        "id": "select_loidebit2_cunge80"
+                    }
+                ],
+                "dep_exist": [
                     {
                         "refid": "select_ouvrage",
-                        "refvalue": "select_ouvrage_seuil_rect"
+                        "refvalue": "select_ouvrage_vanne_rect"
                     }
                 ]
             },
             {
                 "type": "input",
-                "id": "W",
+                "id": "ZDV",
                 "unit": "m",
-                "value": 0.5,
+                "value": 0.2,
+                "nodeType": "StructureRectangle",
                 "dep_exist": [
                     {
                         "refid": "select_ouvrage",
                         "refvalue": "select_ouvrage_vanne_rect"
+                    },
+                    {
+                        "refid": "select_ouvrage",
+                        "refvalue": "select_ouvrage_seuil_rect"
                     }
                 ]
             },
@@ -99,6 +130,18 @@
                     }
                 ]
             },
+            {
+                "type": "input",
+                "id": "W",
+                "unit": "m",
+                "value": 0.5,
+                "dep_exist": [
+                    {
+                        "refid": "select_ouvrage",
+                        "refvalue": "select_ouvrage_vanne_rect"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "Cd",
diff --git a/src/app/calculators/parallel-structures/parallel-structures.fr.json b/src/app/calculators/parallel-structures/parallel-structures.fr.json
index fa436a240d6d51f7ee101b4cf43bb483a5f3a5c7..258adb9d2f577d66eb6e70e410db475c0c497c41 100644
--- a/src/app/calculators/parallel-structures/parallel-structures.fr.json
+++ b/src/app/calculators/parallel-structures/parallel-structures.fr.json
@@ -12,11 +12,16 @@
     "select_ouvrage_vanne_trap": "Vanne trapézoïdale",
     "W": "Ouverture de vanne",
     "select_loidebit1": "Loi de débit",
-    "select_loidebit1_cemagref88": "Déversoir/Orifice Cemagref 88",
-    "select_loidebit1_vannedenoye": "Vanne dénoyé",
-    "select_loidebit1_vannenoye": "Vanne noyé",
+    "select_loidebit1_seuildenoye": "Seuil dénoyé",
+    "select_loidebit1_cunge80": "Cunge 80",
+    "select_loidebit1_cem88d": "Déversoir/Orifice Cemagref 88",
+    "select_loidebit1_cem88v": "Déversoir/Vanne de fond Cemagref 88",
     "select_loidebit2": "Loi de débit",
-    "select_loidebit2_cemagref88": "Déversoir/Orifice Cemagref 88",
+    "select_loidebit2_vannedenoye": "Vanne dénoyé",
+    "select_loidebit2_vannenoye": "Vanne noyé",
+    "select_loidebit2_cunge80": "Cunge 80",
+    "select_loidebit2_cem88d": "Déversoir/Orifice Cemagref 88",
+    "select_loidebit2_cem88v": "Déversoir/Vanne de fond Cemagref 88",
     "ZDV": "Cote de la crête du déversoir ou du radier de la vanne",
     "L": "Largeur du déversoir",
     "Cd": "Coefficient de débit",
diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
index bc1699aebcafbff8f9592b21825c0dba00d5247e..ae1d2e96b712a734804e012e7d75992d2f039d16 100644
--- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts
+++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
@@ -44,16 +44,18 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
     }
 
     public resetResults() {
+        this._formResult.resetResults();
     }
 
     public doCompute() {
+        this._formCompute.doCompute();
     }
 
     public get hasResults(): boolean {
-        return false;
+        return this._formResult.hasResults;
     }
 
     public get results(): CalculatorResults[] {
-        return undefined;
+        return this._formResult.results;
     }
 }
diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index 36b59be021b21d1109f020230f900d302dc0b6e2..03393744d7c7eb0475dde22f1484afce6ada9cc4 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -23,6 +23,14 @@ export abstract class FormComputeFixedVar extends FormCompute {
         return this._formBase.getDisplayedParamFromState(ParamRadioConfig.CAL);
     }
 
+    /**
+     * retourne un identifiant du paramètre dans le formulaire
+     * surchargé dans le cas des ouvrages //
+     */
+    protected getParameterRefid(p: NgParameter) {
+        return p.symbol;
+    }
+
     /**
      * lance le calcul d'un paramètre en déterminant une valeur initiale
      */
@@ -43,10 +51,21 @@ export abstract class FormComputeFixedVar extends FormCompute {
                 init = 1e-8;
                 break;
         }
+
         if (prec == undefined)
-            return nub.Calc(p.symbol, init);
+            return nub.Calc(this.getParameterRefid(p), init);
 
-        return nub.Calc(p.symbol, init, prec);
+        return nub.Calc(this.getParameterRefid(p), init, prec);
+    }
+
+    /**
+     * fixe la valeur d'un paramètre de ComputeNode
+     * @param node ComputeNode contenant le paramètre
+     * @param p paramètre dont on fixe la valeur
+     * @param val valeur à fixer
+     */
+    protected setParameterValue(node: ComputeNode, p: NgParameter, val: number) {
+        node.getParameter(p.symbol).v = val;
     }
 
     protected compute() {
@@ -90,7 +109,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
                     let step: number = +varParam.stepValue;
 
                     for (let val = min; val <= max; val += step) {
-                        prms[varParam.symbol].v = val;
+                        this.setParameterValue(nub, varParam, val);
 
                         let res: Result = this.runNubCalc(nub, computedParam, computePrec);
                         if (res.ok) {
@@ -106,7 +125,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
                     this.formResult.graphType = GraphType.Histogram;
 
                     for (let val of varParam.valueList) {
-                        prms[varParam.symbol].v = val;
+                        this.setParameterValue(nub, varParam, val);
 
                         let res: Result = this.runNubCalc(nub, computedParam, computePrec);
                         if (res.ok) {
diff --git a/src/app/formulaire/definition/form-compute-parallel-structures.ts b/src/app/formulaire/definition/form-compute-parallel-structures.ts
index c441272a4212324ff18f9e42e66a471647c81149..02cd70390be7a83d7ffb702ce42ee6ab2748c86b 100644
--- a/src/app/formulaire/definition/form-compute-parallel-structures.ts
+++ b/src/app/formulaire/definition/form-compute-parallel-structures.ts
@@ -1,15 +1,122 @@
-import { ComputeNode, ParamsEquation } from "jalhyd";
+import { ComputeNode, ParamsEquation, ParallelStructure, ParallelStructureParams, CalculatorType, StructureParams, Structure, CreateStructure, StructureType, ComputeNodeType } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
-import { FormulaireDefinition } from "./form-definition";
 import { FormResultFixedVar } from "./form-result-fixedvar";
+import { FormulaireDefinition } from "./form-definition";
+import { SelectField } from "../select-field";
+import { FormulaireElement } from "../formulaire-element";
+import { NgParameter } from "../ngparam";
+import { FormulaireNode } from "../formulaire-node";
+import { FieldSet } from "../fieldset";
+import { FieldsetContainer } from "../fieldset-container";
 
 export class FormComputeParallelStructures extends FormComputeFixedVar {
     constructor(formBase: FormulaireDefinition, formResult: FormResultFixedVar) {
         super(formBase, formResult);
     }
 
+    /**
+     * dictionnaire des StructureType indexés par les valeurs de liste déroulante (loi de débit)
+     */
+    private static tsMap = {
+        "cem88d": StructureType.Cem88d,
+        "cem88v": StructureType.Cem88d,
+        "cunge80": StructureType.Cunge80,
+        "seuildenoye": StructureType.WeirFree,
+        "vannenoye": StructureType.OrificeSubmerged,
+        "vannedenoye": StructureType.OrificeFree
+    }
+
+    /**
+     * @return dans le cas d'un paramètre d'ouvrage, le FieldSet parent d'un paramètre,
+     * le FieldsetContainer parent du FieldSet
+     * ainsi que l'indice du FieldSet parent dans le FieldsetContainer
+     */
+    private structureParents(p: NgParameter): [FieldsetContainer, FieldSet, number] {
+        const parent1: FormulaireNode = p.getDirectParent(this._formBase);
+        if (parent1 !== undefined)
+            if (parent1 instanceof FieldSet) {
+                const parent2 = parent1.getDirectParent(this._formBase);
+                if (parent2 instanceof FieldsetContainer) {
+                    const fsIndex = parent1.indexAsKid(this._formBase);
+                    return [parent2, parent1, fsIndex];
+                }
+            }
+
+        return [undefined, undefined, -1];
+    }
+
+    /**
+     * construit un identifiant de type "n.X" avec "n" l'index de l'ouvrage auquel appartient le paramètre et "X" son symbole
+     */
+    protected getParameterRefid(p: NgParameter) {
+        const [fsc, fs, i] = this.structureParents(p);
+        if (i == -1)
+            return super.getParameterRefid(p);
+
+        return `${i}.${p.symbol}`;
+    }
+
+    protected setParameterValue(node: ComputeNode, p: NgParameter, val: number) {
+        const [fsc, fs, i] = this.structureParents(p);
+        if (i == -1)
+            super.setParameterValue(node, p, val); // paramètre "normal" (pas un paramètre d'ouvrage)
+        else {
+            const n: ParallelStructure = node as ParallelStructure;
+            const prm = n.structures[i].getParameter(p.symbol);
+            prm.v = val;
+        }
+    }
+
     public getNubAndParameters(): [ComputeNode, ParamsEquation] {
-        return undefined;
+        // paramètres communs
+
+        const Q: number = this._formBase.getParameterValue("Q"); // Débit 
+        const Z1: number = this._formBase.getParameterValue("Z1"); // Cote de l'eau amont (m)
+        const Z2: number = this._formBase.getParameterValue("Z2"); // Cote de l'eau aval (m)
+        const prms = new ParallelStructureParams(Q, Z1, Z2);
+
+        const nub: ParallelStructure = new ParallelStructure(prms);
+
+        // ouvrages
+
+        for (const fs of this._formBase.allFieldsets)
+            if (fs.calculatorType == CalculatorType.Structure) {
+                let loiDebit: string = fs.getSelectedValue("select_loidebit1");
+                if (loiDebit == undefined)
+                    loiDebit = fs.getSelectedValue("select_loidebit2");
+                if (loiDebit == undefined)
+                    throw new Error(`FormComputeParallelStructures.getNubAndParameters() : aucune loi de débit trouvée`);
+
+                const ts: StructureType = FormComputeParallelStructures.tsMap[loiDebit];
+                if (ts == undefined)
+                    throw new Error(`FormComputeParallelStructures.getNubAndParameters() :loi de débit ${loiDebit} non prise en charge`);
+
+                // cote de radier
+                const ZDV = fs.getNodeParameterValue("ZDV");
+
+                // ouverture de vanne
+                try {
+                    var W = fs.getNodeParameterValue("W");
+                } catch (e) {
+                }
+
+                // création de l'ouvrage
+                const ouvr = CreateStructure(ts);
+
+                // affectation des valeurs (en prenant garde de ne pas écraser les valeurs par défaut dans le cas d'un paramètre à calculer)
+                if (Z1 != undefined)
+                    ouvr.prms.Z1.v = Z1;
+                if (Z2 != undefined)
+                    ouvr.prms.Z2.v = Z2;
+                if (ZDV != undefined)
+                    ouvr.prms.ZDV.v = ZDV;
+                if (W != undefined)
+                    ouvr.prms.W.v = W;
+
+                nub.addStructure(ouvr);
+            }
+
+        return [nub, prms];
     }
 }
diff --git a/src/app/formulaire/form-iterator/deep-node-iterator.ts b/src/app/formulaire/form-iterator/deep-node-iterator.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ad3aa95e0f7afc538b9168293a4f5a2eaa1dba9f
--- /dev/null
+++ b/src/app/formulaire/form-iterator/deep-node-iterator.ts
@@ -0,0 +1,10 @@
+import { AbstractFormulaireNodeIterator } from "./abstract-node-iterator";
+import { FormulaireNode } from "../formulaire-node";
+
+export class DeepFormulaireNodeIterator extends AbstractFormulaireNodeIterator<FormulaireNode> implements IterableIterator<FormulaireNode> {
+    // interface IterableIterator
+
+    [Symbol.iterator](): IterableIterator<FormulaireNode> {
+        return this;
+    }
+}
\ No newline at end of file
diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts
index da01c3ecd144711abc9025c3d8edf7afdb545550..e569c7e30cb16b89e691fa242b70aa6f3ecd5ac2 100644
--- a/src/app/formulaire/formulaire-node.ts
+++ b/src/app/formulaire/formulaire-node.ts
@@ -1,6 +1,7 @@
 import { JalhydObject } from "jalhyd"
 
 import { FormulaireDefinition } from "./definition/form-definition";
+import { DeepFormulaireNodeIterator } from "./form-iterator/deep-node-iterator";
 
 /**
  * représentation sous forme d'arbre du formulaire et de ses éléments
@@ -112,6 +113,57 @@ export abstract class FormulaireNode {
         return undefined;
     }
 
+    private hasDirectKid(n: FormulaireNode): boolean {
+        for (const k of this._kids)
+            if (k._uid == n._uid)
+                return true;
+        return false;
+    }
+
+    /**
+     * retourne le parent direct de this
+     * @param root FormulaireNode racine dont on part pour rechercher le parent
+     */
+    public getDirectParent(root: FormulaireNode): FormulaireNode {
+        if (root.hasDirectKid(this))
+            return root;
+
+        const it = new DeepFormulaireNodeIterator(root);
+        for (const n of it)
+            if (n.hasDirectKid(this))
+                return n;
+        return undefined;
+    }
+
+    /**
+     * retourne l'indice d'un FormulaireNode enfant dans la liste des enfants
+     * @param kid FormulaireNode enfant dont on cherche l'indice
+     * @return -1 si non trouvé, indice commençant à 0 sinon
+     */
+    private kidIndex(kid: FormulaireNode): number {
+        let n = 0;
+        for (const k of this._kids) {
+            if (k._uid == kid._uid)
+                return n;
+            n++;
+        }
+
+        return -1;
+    }
+
+    /**
+     * retourne l'indice de this dans la liste des enfants de son parent
+     * (cad rang par rapport à ses frères)
+     * @param root FormulaireNode racine dont on part pour rechercher le parent
+     */
+    public indexAsKid(root: FormulaireNode): number {
+        // parent de this
+        const p = this.getDirectParent(root);
+
+        // indice
+        return p.kidIndex(this);
+    }
+
     /**
      * crée une nouvelle instance (appel simple du constructeur)
      */