diff --git a/spec/fuzzing.spec.ts b/spec/fuzzing.spec.ts
index 060e09dcab6f3ea9098423aa5876a141276f7c79..3af87a89694738a80bdb1d376e5a32e31d9c2b17 100644
--- a/spec/fuzzing.spec.ts
+++ b/spec/fuzzing.spec.ts
@@ -1,4 +1,5 @@
 import { CalculatorType } from "../src/compute-node";
+import { MacrorugoCompound } from "../src/macrorugo/macrorugo_compound";
 import { Nub } from "../src/nub";
 import { CloisonAval } from "../src/pab/cloison_aval";
 import { Pab } from "../src/pab/pab";
@@ -110,6 +111,10 @@ function setPab(pab: Pab, nClMax = 30, nStMax = 3) {
     addRandomStructures(pab.downWall, nStMax);
 }
 
+function setMacrorugoCompound(n: MacrorugoCompound) {
+    n.properties.setPropValue("inclinedApron", Math.random() > 0.5);
+}
+
 function CreateTestNub(iCalType: number): Nub {
     const n = Session.getInstance().createNub(
         new Props({ calcType: iCalType })
@@ -129,6 +134,9 @@ function CreateTestNub(iCalType: number): Nub {
     if (iCalType === CalculatorType.Pab) {
         setPab(n as Pab, fuzzyCfg.Pab.poolMax, fuzzyCfg.Pab.structureMax);
     }
+    if (iCalType === CalculatorType.MacroRugoCompound) {
+        setMacrorugoCompound(n as MacrorugoCompound);
+    }
     for (const p of n.parameterIterator) {
         if (p.visible) {
             randomizeParameter(p);
@@ -155,6 +163,7 @@ describe("Fuzz testing", () => {
         }
     });
     for (const iCalType of calTypes) {
+        // if ([CalculatorType.MacroRugoCompound].includes(iCalType)) {
         if (!nubsNotTested.includes(iCalType)) {
             describe(CalculatorType[iCalType], () => {
                 for (let i = 0; i < fuzzyCfg.nTests; i++) {
diff --git a/spec/macrorugo/macrorugo_compound.spec.ts b/spec/macrorugo/macrorugo_compound.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..096533774ad01d008b189a9341f837750755d316
--- /dev/null
+++ b/spec/macrorugo/macrorugo_compound.spec.ts
@@ -0,0 +1,111 @@
+import { CalculatorType } from "../../src/compute-node";
+import { MacroRugo, MacrorugoParams } from "../../src/macrorugo/macrorugo";
+import { MacrorugoCompound } from "../../src/macrorugo/macrorugo_compound";
+import { Props } from "../../src/props";
+import { Session } from "../../src/session";
+import { compareTwoResults } from "../test_func";
+
+let BR: number;
+let mrc2: MacrorugoCompound;
+
+/**
+ * Return default instance of MacroRugo as reference for one apron
+ * @param i Offset of ZF1 (- 0.2 * i) and B (+ i)
+ */
+function getMacroRugoRef(i: number = 0): MacroRugo {
+    const mr = Session.getInstance().createNub(
+        new Props({ calcType: CalculatorType.MacroRugo })
+    ) as MacroRugo;
+    mr.prms.ZF1.singleValue -= 0.21 * i;
+    mr.prms.Y.singleValue += 0.21 * i;
+    mr.prms.B.singleValue += i;
+    mr.prms.L.singleValue = 3 / mr.prms.If.currentValue;
+    mr.prms.Q.setCalculated();
+    mr.CalcSerie();
+    return mr;
+}
+
+describe("MacroRugoCompound", () => {
+    describe("Default 1 apron", () => {
+        it("should return same result as Macrorugo", () => {
+            const mrc = Session.getInstance().createNub(
+                new Props({ calcType: CalculatorType.MacroRugoCompound })
+            ) as MacrorugoCompound;
+            mrc.addDefaultChild();
+            const mr = getMacroRugoRef();
+            expect(mrc.CalcSerie().vCalc).toBeCloseTo(mr.result.vCalc, 3);
+        });
+        it("should return same result as Macrorugo", () => {
+            const mrc = Session.getInstance().createNub(
+                new Props({ calcType: CalculatorType.MacroRugoCompound })
+            ) as MacrorugoCompound;
+            mrc.addDefaultChild();
+            mrc.children[0].prms.L.singleValue = 0.5;
+            mrc.CalcSerie();
+            const mr = getMacroRugoRef();
+            mr.prms.L.singleValue = mrc.children[0].prms.L.v;
+            mr.CalcSerie();
+            compareTwoResults(mrc.children[0].result, mr.result, 3);
+        });
+    });
+    describe("Default inclined but flat apron", () => {
+        beforeAll(() => {
+            BR = 0;
+        });
+        beforeEach(() => {
+            BR += 1;
+        });
+        for (let i = 1; i < 10; i += 1) {
+            it(`B = ${i} should return same result as Macrorugo`, () => {
+                const mrc = Session.getInstance().createNub(
+                    new Props({ calcType: CalculatorType.MacroRugoCompound })
+                ) as MacrorugoCompound;
+                mrc.properties.setPropValue("inclinedApron", true);
+                mrc.prms.BR.singleValue = BR;
+                const mr = getMacroRugoRef();
+                expect(mrc.CalcSerie().vCalc)
+                    .toBeCloseTo(mr.result.vCalc * mrc.prms.BR.currentValue / mr.prms.B.currentValue, 3);
+                const ax = mrc.prms.PBD.v / Math.sqrt(mrc.prms.C.v);
+                let B: number = 0;
+                for (const child of mrc.children) {
+                    expect(child.result.values.xCenter)
+                        .toBeCloseTo(B + child.prms.B.v / 2);
+                    B += child.prms.B.v;
+                    expect(child.prms.B.v).toBeGreaterThanOrEqual(ax / 4);
+                }
+                expect(B).toBeCloseTo(mrc.prms.BR.currentValue, 6);
+            });
+        }
+    });
+    describe("Multiple apron", () => {
+        beforeAll(() => {
+            mrc2 = Session.getInstance().createNub(
+                new Props({ calcType: CalculatorType.MacroRugoCompound })
+            ) as MacrorugoCompound;
+            for (let i = 0; i < 3; i++) {
+                mrc2.addChild(
+                    new MacroRugo(
+                        new MacrorugoParams(0, 100, 100, 0.5, 1, 10, 1, 1, 1, 10, 0.5)
+                    )
+                );
+                mrc2.children[i].prms.ZF1.singleValue = 12.5 - 0.21 * i;
+                mrc2.children[i].prms.B.singleValue = 1 + i;
+            }
+            mrc2.CalcSerie();
+        });
+        for (let i = 0; i < 3; i++) {
+            it(`Apron #${i} should return same parameters as Macrorugo`, () => {
+                const mr = getMacroRugoRef(i);
+                for (const p of mrc2.children[i].parameterIterator) {
+                    if (p.symbol !== "Q") {
+                        expect(p.v).toBeCloseTo(mr.getParameter(p.symbol).v, 3);
+                    }
+                }
+            });
+            it(`Apron #${i} should return same result as Macrorugo`, () => {
+                const mr = getMacroRugoRef(i);
+                compareTwoResults(mrc2.children[i].result, mr.result, 3);
+            });
+        }
+    });
+});
diff --git a/spec/test_func.ts b/spec/test_func.ts
index 0c321f7861a8103a7233d5b99eb09ca811b16b45..014b58a701db2685808c7b51ddfe6c3fda3e7e74 100644
--- a/spec/test_func.ts
+++ b/spec/test_func.ts
@@ -210,6 +210,29 @@ export function checkResult(result: Result, valRef: number, prec?: number) {
     }
 }
 
+/**
+ * Compare the content of two results objects
+ * @param rTest Result to test
+ * @param rRef Result used as reference
+ * @param prec numbers of digits of the needed precision
+ */
+export function compareTwoResults(rTest: Result, rRef: Result, prec: number = Math.max(0, precDigits - 1)) {
+    expect(rTest.ok).toEqual(rRef.ok, `ok should be $rRef.ok`);
+    if (!rTest.ok) { return; }
+    expect(rTest.resultElements.length).toEqual(rRef.resultElements.length, `resultElements.length should be $rRef.ok`);
+    if (rTest.resultElements.length !== rRef.resultElements.length) { return; }
+    for (let i = 0; i < rRef.resultElements.length; i++) {
+        for (const k of Object.keys(rRef.resultElements[i].values)) {
+            expect(rTest.resultElements[i].values[k])
+            .toBeCloseTo(
+                rRef.resultElements[i].values[k],
+                prec,
+                k
+            );
+        }
+    }
+}
+
 export function checkResultConsistency(nub: Nub, r?: Result) {
     if (r === undefined) {
         r = nub.result;
diff --git a/src/base.ts b/src/base.ts
index 4feba95707ac3a45d08a178cc56a3cc33cb4ae69..16915a29e79559433329c4c2529d784aec3d396b 100644
--- a/src/base.ts
+++ b/src/base.ts
@@ -131,3 +131,7 @@ export function formattedValue(value: number, nDigits: number) {
         return value.toFixed(nDigits);
     }
 }
+
+export function capitalize(s: string): string {
+    return s.charAt(0).toUpperCase() + s.slice(1);
+}
diff --git a/src/compute-node.ts b/src/compute-node.ts
index a7b0795f2f122ff2da6d284f49caea41920d8006..9619bdda8ec8f66eeea9aec10639c1f4a98689d1 100644
--- a/src/compute-node.ts
+++ b/src/compute-node.ts
@@ -23,7 +23,8 @@ export enum CalculatorType {
     PabNombre,
     Section,
     Pab,                // Passe à bassins;
-    CloisonAval
+    CloisonAval,
+    MacroRugoCompound   // Passe à enrochement composée
 }
 
 /**
diff --git a/src/index.ts b/src/index.ts
index 8fc065d4efe1f8a4626265a4740e15509429bfe5..243c278ee7ca6342658d4a54aa8d057b5c7af0bc 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -42,3 +42,5 @@ export * from "./pab/cloison_aval";
 export * from "./lechaptcalmon";
 export * from "./lc-material";
 export * from "./structure/dever";
+export * from "./macrorugo/macrorugo";
+export * from "./macrorugo/macrorugo_compound";
diff --git a/src/macrorugo/macrorugo.ts b/src/macrorugo/macrorugo.ts
index 2f1bb744be7f26d1ce36ebd779c7489a7ac91133..1adc516b0486cc9972da5b3cbab4c0ee7f64d94f 100644
--- a/src/macrorugo/macrorugo.ts
+++ b/src/macrorugo/macrorugo.ts
@@ -66,6 +66,8 @@ export class MacroRugo extends Nub {
         this.getParameter(sVarCalc).valueMode = ParamValueMode.CALCUL;
 
         const r: Result = super.Calc(sVarCalc, rInit);
+        this.getParameter(sVarCalc).valueMode = originalValueMode;
+
         // Ajout des résultats complémentaires
         // Cote de fond aval
         r.resultElement.values.ZF2 = this.prms.ZF1.v - this.prms.If.v * this.prms.L.v;
@@ -115,9 +117,6 @@ export class MacroRugo extends Nub {
                 Math.pow(this.prms.If.v, cV[2]) * Math.sqrt(MacroRugo.g * this.prms.PBD.v);
         }
 
-        // mode d'origine du paramètre; voir le haut de la fonction
-        this.getParameter(sVarCalc).valueMode = originalValueMode;
-
         return r;
     }
 
@@ -125,8 +124,13 @@ export class MacroRugo extends Nub {
         this.Q = this.prms.Q.v;
         const q0 = Math.sqrt(2 * MacroRugo.g * this.prms.If.v * this.prms.PBD.v * ( 1 - (this.sigma * this.prms.C.v)) /
             (this.prms.Cd0.v * this.prms.C.v)) * this.prms.Y.v * this.prms.B.v;
-        const dicho = new Dichotomie(this, "Q", false, this.resolveQ);
-        const r: Result = dicho.Dichotomie(0, this.prms.Pr.v, q0);
+        let r: Result;
+        if (q0 > 0) {
+            const dicho = new Dichotomie(this, "Q", false, this.resolveQ);
+            r = dicho.Dichotomie(0, this.prms.Pr.v, q0);
+        } else {
+            r = new Result(0);
+        }
         this.prms.Q.v = this.Q;
         return r;
 
diff --git a/src/macrorugo/macrorugo_compound.ts b/src/macrorugo/macrorugo_compound.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b91bab5eb4e2bab05441565ca4d674b20912cbaf
--- /dev/null
+++ b/src/macrorugo/macrorugo_compound.ts
@@ -0,0 +1,193 @@
+import { round } from "../base";
+import { CalculatorType } from "../compute-node";
+import { ParamCalculability } from "../param/param-definition";
+import { Props } from "../props";
+import { Session } from "../session";
+import { Observer } from "../util/observer";
+import { Result } from "../util/result";
+import { MacroRugo } from "./macrorugo";
+import { MacrorugoCompoundParams } from "./macrorugo_compound_params";
+
+export class MacrorugoCompound extends MacroRugo implements Observer {
+
+    /** enfants castés au bon type */
+    get children(): MacroRugo[] {
+        return this._children as MacroRugo[];
+    }
+
+    /** parameters cast to the right type */
+    get prms(): MacrorugoCompoundParams {
+        return this._prms as MacrorugoCompoundParams;
+    }
+
+    constructor(prms: MacrorugoCompoundParams, dbg: boolean = false) {
+        super(prms, dbg);
+        this._calcType = CalculatorType.MacroRugoCompound;
+        this._props.addObserver(this);
+        this.properties.setPropValue("inclinedApron", false);
+        this._childrenType = "MacroRugo";
+    }
+
+    public CalcSerie(rInit?: number, sDonnee?: any): Result {
+        if (this.properties.getPropValue("inclinedApron")) {
+            // important to regenerate it here, at every iteration of CalcSerie()
+            this.generateInclinedFishway();
+        }
+        return super.CalcSerie(rInit, sDonnee);
+    }
+
+    /**
+     * 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
+     * @param rInit Valeur initiale
+     */
+    public Calc(sVarCalc: string, rInit?: number): Result {
+        if (sVarCalc !== "Q") {
+            throw new Error("MacrorugoCompound.Calc() : invalid parameter " + sVarCalc);
+        }
+        this.copyPrmsToChildren();
+        this.currentResult = this.Equation(sVarCalc);
+        return this._result;
+    }
+
+    public Equation(sVarCalc: string): Result {
+        let QT: number = 0;
+        let B: number = 0;
+        for (const child of this.children) {
+            child.Calc(sVarCalc);
+            QT += child.result.vCalc;
+            child.result.values.xCenter = B + child.prms.B.v / 2;
+            B += child.prms.B.v;
+        }
+        return new Result(QT);
+    }
+
+    public addChild(child: MacroRugo, after?: number) {
+        super.addChild(child, after);
+        for (const p of child.parameterIterator) {
+            p.visible = false;
+        }
+        child.prms.ZF1.visible = true;
+        child.prms.B.visible = true;
+        child.prms.B.calculability = ParamCalculability.FREE;
+    }
+
+    public addDefaultChild(after?: number) {
+        this.addChild(
+            Session.getInstance().createNub(new Props({ calcType: CalculatorType.MacroRugo })) as MacroRugo,
+            after
+        );
+    }
+
+    // interface Observer
+
+    public update(sender: any, data: any) {
+        if (data.action === "propertyChange" && data.name === "inclinedApron") {
+            if (data.value) { // switch to inclined apron mode
+                this.prms.ZRL.visible = true;
+                this.prms.ZRR.visible = true;
+                this.prms.BR.visible = true;
+                this.prms.PBD.calculability = ParamCalculability.FIXED;
+                this.prms.C.calculability = ParamCalculability.FIXED;
+            } else { // switch to multiple aprons mode
+                this.prms.ZRL.visible = false;
+                this.prms.ZRR.visible = false;
+                this.prms.BR.visible = false;
+                this.prms.PBD.calculability = ParamCalculability.FREE;
+                this.prms.C.calculability = ParamCalculability.FREE;
+            }
+        }
+    }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        this.prms.ZF1.calculability = ParamCalculability.FREE;
+        this.prms.L.calculability = ParamCalculability.FREE;
+        this.prms.Ks.calculability = ParamCalculability.FREE;
+        this.prms.B.calculability = ParamCalculability.FREE;
+        this.prms.If.calculability = ParamCalculability.FREE;
+        this.prms.Q.calculability = ParamCalculability.EQUATION;
+        this.prms.Y.calculability = ParamCalculability.FREE;
+        this.prms.C.calculability = ParamCalculability.FREE;
+        this.prms.PBD.calculability = ParamCalculability.FREE;
+        this.prms.PBH.calculability = ParamCalculability.FREE;
+        this.prms.Cd0.calculability = ParamCalculability.FREE;
+
+        this.prms.ZRL.calculability = ParamCalculability.FIXED;
+        this.prms.ZRR.calculability = ParamCalculability.FIXED;
+        this.prms.BR.calculability = ParamCalculability.FIXED;
+    }
+
+    private copyPrmsToChildren() {
+        for (const child of this.children) {
+            // Copy common parameters with MacrorugoCompound
+            for (const v of ["Ks", "If", "C", "PBD", "PBH", "Cd0"]) {
+                child.getParameter(v).v = this.getParameter(v).v;
+            }
+            // Calculate Length and depth from other parameters
+            child.prms.L.v = this.prms.DH.v / this.prms.If.v;
+            child.prms.Y.v = Math.max(this.prms.Z1.v - child.prms.ZF1.v, 0);
+        }
+    }
+
+    /**
+     * Discrétisation d'un radier incliné en radiers horizontaux
+     * Le pas de discrétisationest fixée à D / C^0.5.
+     * Les cellules discrétisées sont centrées sur la passe, on crée
+     * les cellules manquantes aux extrémités si le reste > ax / 2
+     * sinon les cellules aux extrémités sont étendues jusqu'aux bords.
+     * La cote de radier de chaque cellule est calculée au milieu de celles-ci.
+     */
+    private generateInclinedFishway() {
+        // Calcul de la position des cellules
+        // Taille d'une cellule de calcul
+        const ax: number = this.prms.PBD.singleValue / Math.sqrt(this.prms.C.singleValue);
+        // Nombre entier de cellules et reste
+        let nCells: number = Math.floor(this.prms.BR.singleValue / ax);
+        const xRest: number = this.prms.BR.singleValue % ax;
+        const xCenters: number[] = [];
+        let lastBorder: number = 0;
+        // Position du centre de la première cellule
+        if (xRest > ax / 2) {
+            // Ajout d'une cellule à gauche
+            xCenters.push(xRest / 4);
+            nCells++;
+        } else {
+            if (nCells < 2) {
+                xCenters.push(this.prms.BR.singleValue / 2);
+            } else {
+                xCenters.push((ax + xRest / 2) / 2);
+            }
+        }
+        if (nCells > 1 || xRest > ax / 2) {
+            lastBorder = xCenters[0] * 2;
+            // Ajout des cellules centrales décalées de ax
+            for (let i = 1; i < nCells; i++) {
+                xCenters.push(lastBorder + ax / 2);
+                lastBorder += ax;
+            }
+            if (xRest > ax / 2) {
+                // Ajout de la cellule supplémentaire à droite
+                xCenters.push(this.prms.BR.singleValue - xRest / 4);
+            } else {
+                xCenters[xCenters.length - 1] = this.prms.BR.singleValue - (ax + xRest / 2) / 2;
+            }
+        }
+        // Génération des radiers
+        // Suppression des radiers existants
+        this.deleteAllChildren();
+        // Ajout des radiers et calcul de leur cote amont et de leur largeur
+        lastBorder = 0;
+        for (const xCenter of xCenters) {
+            this.addDefaultChild();
+            this.children[this.children.length - 1].prms.ZF1.singleValue = round(
+                this.prms.ZRL.singleValue + xCenter / this.prms.BR.singleValue
+                * (this.prms.ZRR.singleValue - this.prms.ZRL.singleValue)
+            , 3);
+            this.children[this.children.length - 1].prms.B.singleValue = round((xCenter - lastBorder) * 2, 3);
+            lastBorder += this.children[this.children.length - 1].prms.B.singleValue;
+        }
+    }
+}
diff --git a/src/macrorugo/macrorugo_compound_params.ts b/src/macrorugo/macrorugo_compound_params.ts
new file mode 100644
index 0000000000000000000000000000000000000000..93e55e4917b56b3ad922b15802a22e7a47902f47
--- /dev/null
+++ b/src/macrorugo/macrorugo_compound_params.ts
@@ -0,0 +1,96 @@
+import { ParamDefinition, ParamFamily } from "../param/param-definition";
+import { ParamDomain, ParamDomainValue } from "../param/param-domain";
+import { MacrorugoParams } from "./macrorugo";
+
+export class MacrorugoCompoundParams extends MacrorugoParams {
+
+    /** Upstream water elevation (m) */
+    private _Z1: ParamDefinition;
+
+    /** Water fall (m) */
+    private _DH: ParamDefinition;
+
+    /** Inclined apron: Left bank apron elevation (m) */
+    private _ZRL: ParamDefinition;
+
+    /** Inclined apron: Right bank apron elevation (m) */
+    private _ZRR: ParamDefinition;
+
+    /** Inclined apron: Apron total width (m) */
+    private _BR: ParamDefinition;
+
+    /**
+     *
+     * @param rZ1 Cote de l'eau amont (m)
+     * @param rZRL Cote de radier gauche (m) (Radier incliné seulement)
+     * @param rZRR Cote de radier droit (m) (Radier incliné seulement)
+     * @param rB Largeur (m) (Radier incliné seulement)
+     * @param rDH Chute (m)
+     * @param rIf Pente (m/m)
+     * @param rY Tirant d'eau (m)
+     * @param rRF Rugosité de fond (m)
+     * @param rCB Concentration de blocs (m)
+     * @param rPBD Paramètre de bloc : Diamètre (m)
+     * @param rPBH Paramètre de bloc : Hauteur (m)
+     * @param rCd0 Paramètre de bloc : Forme (1 pour rond, 2 pour carré)
+     */
+    constructor(
+        rZ1: number,
+        rZRL: number,
+        rZRR: number,
+        rB: number,
+        rDH: number,
+        rIf: number,
+        rRF: number,
+        rCB: number,
+        rPBD: number,
+        rPBH: number,
+        rCd0: number
+    ) {
+        super((rZRL + rZRR) / 2, 1, rDH / rIf, rIf, 1, 1, rRF, rCB, rPBD, rPBH, rCd0);
+
+        this._Z1 = new ParamDefinition(this, "Z1", ParamDomainValue.ANY, "m", rZ1, ParamFamily.ELEVATIONS);
+        this.addParamDefinition(this._Z1);
+
+        this._ZRL = new ParamDefinition(this, "ZRL", ParamDomainValue.ANY, "m", rZRL, ParamFamily.ELEVATIONS);
+        this.addParamDefinition(this.ZRL);
+
+        this._ZRR = new ParamDefinition(this, "ZRR", ParamDomainValue.ANY, "m", rZRR, ParamFamily.ELEVATIONS);
+        this.addParamDefinition(this._ZRR);
+
+        this._BR = new ParamDefinition(this, "BR",
+            new ParamDomain(ParamDomainValue.INTERVAL, 0, 100), "m", rB, ParamFamily.WIDTHS);
+        this.addParamDefinition(this._BR);
+
+        this._DH = new ParamDefinition(this, "DH",
+            new ParamDomain(ParamDomainValue.INTERVAL, 0, 100), "m", rDH, ParamFamily.ELEVATIONS);
+        this.addParamDefinition(this._DH);
+
+        // Width, water depth, and Bottom elevation are defined in Macrorugo children
+        this.B.visible = false;
+        this.ZF1.visible = false;
+        this.Y.visible = false;
+        this.Q.visible = false;
+
+    }
+
+    public get Z1(): ParamDefinition {
+        return this._Z1;
+    }
+
+    public get ZRL(): ParamDefinition {
+        return this._ZRL;
+    }
+
+    public get ZRR(): ParamDefinition {
+        return this._ZRR;
+    }
+
+    public get BR(): ParamDefinition {
+        return this._BR;
+    }
+
+    public get DH(): ParamDefinition {
+        return this._DH;
+    }
+}
diff --git a/src/macrorugo/macrorugo_params.ts b/src/macrorugo/macrorugo_params.ts
index 9c88e88b6eee8492e205adb46326569551e258dc..123d120c1c4d3d384280baac1430ce54e31a3513 100644
--- a/src/macrorugo/macrorugo_params.ts
+++ b/src/macrorugo/macrorugo_params.ts
@@ -1,5 +1,5 @@
 import { ParamDefinition, ParamFamily } from "../param/param-definition";
-import { ParamDomainValue } from "../param/param-domain";
+import { ParamDomain, ParamDomainValue } from "../param/param-domain";
 import { ParamsEquation } from "../param/params-equation";
 
 export class MacrorugoParams extends ParamsEquation {
@@ -56,7 +56,7 @@ export class MacrorugoParams extends ParamsEquation {
                 rY: number, rRF: number, rCB: number, rPBD: number, rPBH: number, rCd0: number) {
         super();
 
-        this._ZF1 = new ParamDefinition(this, "ZF1", ParamDomainValue.POS, "m", rZF1, ParamFamily.ELEVATIONS);
+        this._ZF1 = new ParamDefinition(this, "ZF1", ParamDomainValue.ANY, "m", rZF1, ParamFamily.ELEVATIONS);
         this.addParamDefinition(this._ZF1);
 
         this._L = new ParamDefinition(this, "L", ParamDomainValue.POS, "m", rL, ParamFamily.LENGTHS);
@@ -65,22 +65,23 @@ export class MacrorugoParams extends ParamsEquation {
         this._B = new ParamDefinition(this, "B", ParamDomainValue.POS, "m", rB, ParamFamily.WIDTHS);
         this.addParamDefinition(this._B);
 
-        this._If = new ParamDefinition(this, "If", ParamDomainValue.POS, "m/m", rIf, ParamFamily.SLOPES);
+        this._If = new ParamDefinition(this, "If",
+            new ParamDomain(ParamDomainValue.INTERVAL, 0, 0.5), "m/m", rIf, ParamFamily.SLOPES);
         this.addParamDefinition(this._If);
 
         this._Q = new ParamDefinition(this, "Q", ParamDomainValue.POS, "m³/s", rQ, ParamFamily.FLOWS);
         this.addParamDefinition(this._Q);
 
-        this._Y = new ParamDefinition(this, "Y", ParamDomainValue.POS, "m", rY, ParamFamily.HEIGHTS);
+        this._Y = new ParamDefinition(this, "Y", ParamDomainValue.POS_NULL, "m", rY, ParamFamily.HEIGHTS);
         this.addParamDefinition(this._Y);
 
-        this._Ks = new ParamDefinition(this, "Ks", ParamDomainValue.POS_NULL, "m", rRF);
+        this._Ks = new ParamDefinition(this, "Ks", new ParamDomain(ParamDomainValue.INTERVAL, 0, 1), "m", rRF);
         this.addParamDefinition(this._Ks);
 
-        this._C = new ParamDefinition(this, "C", ParamDomainValue.POS, "m", rCB);
+        this._C = new ParamDefinition(this, "C", new ParamDomain(ParamDomainValue.INTERVAL, 0, 1), "-", rCB);
         this.addParamDefinition(this._C);
 
-        this._PBD = new ParamDefinition(this, "PBD", ParamDomainValue.POS, "m", rPBD);
+        this._PBD = new ParamDefinition(this, "PBD", new ParamDomain(ParamDomainValue.INTERVAL, 0, 2), "m", rPBD);
         this.addParamDefinition(this._PBD);
 
         this._PBH = new ParamDefinition(this, "PBH", ParamDomainValue.POS, "m", rPBH, ParamFamily.HEIGHTS);
diff --git a/src/nub.ts b/src/nub.ts
index f82d1baa7d1c7a1029f53827b327e89909f596a9..c4cc38959b2f202b98c4d0ca764cb1f5d4192ac4 100644
--- a/src/nub.ts
+++ b/src/nub.ts
@@ -105,7 +105,6 @@ export abstract class Nub extends ComputeNode implements IObservable {
         for (const p of this.parameterIterator) {
             if (
                 p.symbol !== "Pr" &&
-                p.visible &&
                 [ParamCalculability.DICHO, ParamCalculability.EQUATION].includes(p.calculability)
             ) {
                 calcPrms.push(p);
diff --git a/src/param/param-definition.ts b/src/param/param-definition.ts
index c5adb6fb9b49823b6a6c630681317650255d1c1d..83687c884714c5fb2edf68ecede54532a1483ec2 100644
--- a/src/param/param-definition.ts
+++ b/src/param/param-definition.ts
@@ -1100,9 +1100,9 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
      */
     get V(): number {
         if (this.valueMode === ParamValueMode.CALCUL) {
-            if (this.originNub.result !== undefined) {
-                if (this.originNub.result.resultElement.ok) {
-                    return this.originNub.result.vCalc;
+            if (this.parentNub.result !== undefined) {
+                if (this.parentNub.result.resultElement.ok) {
+                    return this.parentNub.result.vCalc;
                 }
             }
         }
diff --git a/src/props.ts b/src/props.ts
index e058eebd3c77717462fe9dca34a22e52d85f141d..99f40d377583c8baea39f650cd095498d5e83602 100644
--- a/src/props.ts
+++ b/src/props.ts
@@ -71,6 +71,7 @@ export class Props implements IObservable {
      */
     public clone(): Props {
         const res = new Props();
+        // copy values
         for (const k in this._props) {
             if (this._props.hasOwnProperty(k)) {
                 res._props[k] = this._props[k];
diff --git a/src/session.ts b/src/session.ts
index 53adab86b305db40349bfe034571dacf77b0fe2c..e9c64acdc7192d6a0a3ea73101ab9d4d98126de9 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -10,6 +10,8 @@ import { config } from "./config";
 import { ConduiteDistrib, ConduiteDistribParams } from "./cond_distri";
 import { LechaptCalmon, LechaptCalmonParams } from "./lechaptcalmon";
 import { MacroRugo, MacrorugoParams } from "./macrorugo/macrorugo";
+import { MacrorugoCompound } from "./macrorugo/macrorugo_compound";
+import { MacrorugoCompoundParams } from "./macrorugo/macrorugo_compound_params";
 import { PabChute, PabChuteParams } from "./pab/pab_chute";
 import { PabDimension, PabDimensionParams } from "./pab/pab_dimension";
 import { PabNombre, PabNombreParams } from "./pab/pab_nombre";
@@ -38,7 +40,6 @@ import { Dever, DeverParams } from "./structure/dever";
 import { CreateStructure } from "./structure/factory_structure";
 import { ParallelStructure, ParallelStructureParams } from "./structure/parallel_structure";
 import { LoiDebit, StructureType } from "./structure/structure_props";
-
 export class Session {
 
     public static getInstance(): Session {
@@ -76,6 +77,7 @@ export class Session {
                         res[k] = LCMaterial[res[k]];
                         break;
                     // "varCalc" is not an enum
+                    // "inclinedApron" is not an enum
                 }
             }
         }
@@ -255,162 +257,147 @@ export class Session {
         let prms: any;
 
         switch (calcType) {
-            case CalculatorType.ConduiteDistributrice: {
-                    prms = new ConduiteDistribParams(
-                        3, // débit Q
-                        1.2, // diamètre D
-                        0.6, // perte de charge J
-                        100, // Longueur de la conduite Lg
-                        1e-6, // Viscosité dynamique Nu
-                    );
-                    nub = new ConduiteDistrib(prms, dbg);
-                    break;
-                }
+            case CalculatorType.ConduiteDistributrice:
+                prms = new ConduiteDistribParams(
+                    3, // débit Q
+                    1.2, // diamètre D
+                    0.6, // perte de charge J
+                    100, // Longueur de la conduite Lg
+                    1e-6, // Viscosité dynamique Nu
+                );
+                nub = new ConduiteDistrib(prms, dbg);
+                break;
 
-            case CalculatorType.LechaptCalmon: {
-                    prms = new LechaptCalmonParams(
-                        3, // débit
-                        1.2, // diamètre
-                        0.6, /// perte de charge
-                        100, // longueur du toyo
-                        1.863, // paramètre L du matériau
-                        2, // paramètre M du matériau
-                        5.33// paramètre N du matériau
-                    );
-                    nub = new LechaptCalmon(prms, dbg);
-                    break;
-                }
+            case CalculatorType.LechaptCalmon:
+                prms = new LechaptCalmonParams(
+                    3, // débit
+                    1.2, // diamètre
+                    0.6, /// perte de charge
+                    100, // longueur du toyo
+                    1.863, // paramètre L du matériau
+                    2, // paramètre M du matériau
+                    5.33// paramètre N du matériau
+                );
+                nub = new LechaptCalmon(prms, dbg);
+                break;
 
-            case CalculatorType.SectionParametree: {
-                    nub = new SectionParametree(undefined, dbg);
-                    break;
-                }
+            case CalculatorType.SectionParametree:
+                nub = new SectionParametree(undefined, dbg);
+                break;
 
-            case CalculatorType.RegimeUniforme: {
-                    nub = new RegimeUniforme(undefined, dbg);
-                    break;
-                }
+            case CalculatorType.RegimeUniforme:
+                nub = new RegimeUniforme(undefined, dbg);
+                break;
 
-            case CalculatorType.CourbeRemous: {
-                    prms = new CourbeRemousParams(
-                        0.15, // Yamont = tirant amont
-                        0.4, // Yaval = tirant aval
-                        100,  // Long= Longueur du bief
-                        5,  // Dx=Pas d'espace
-                    );
-                    nub = new CourbeRemous(undefined, prms, MethodeResolution.EulerExplicite, dbg);
-                    break;
-                }
+            case CalculatorType.CourbeRemous:
+                prms = new CourbeRemousParams(
+                    0.15, // Yamont = tirant amont
+                    0.4, // Yaval = tirant aval
+                    100,  // Long= Longueur du bief
+                    5,  // Dx=Pas d'espace
+                );
+                nub = new CourbeRemous(undefined, prms, MethodeResolution.EulerExplicite, dbg);
+                break;
 
-            case CalculatorType.PabDimensions: {
-                    prms = new PabDimensionParams(
-                        2,      // Longueur L
-                        1,      // Largeur W
-                        0.5,    // Tirant d'eau Y
-                        2       // Volume V
-                    );
-                    nub = new PabDimension(prms, dbg);
-                    break;
-                }
+            case CalculatorType.PabDimensions:
+                prms = new PabDimensionParams(
+                    2,      // Longueur L
+                    1,      // Largeur W
+                    0.5,    // Tirant d'eau Y
+                    2       // Volume V
+                );
+                nub = new PabDimension(prms, dbg);
+                break;
 
-            case CalculatorType.PabPuissance: {
-                    prms = new PabPuissanceParams(
-                        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)
-                    );
-                    nub = new PabPuissance(prms, dbg);
-                    break;
-                }
+            case CalculatorType.PabPuissance:
+                prms = new PabPuissanceParams(
+                    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)
+                );
+                nub = new PabPuissance(prms, dbg);
+                break;
 
-            case CalculatorType.Structure: {
-                    const loiDebit: LoiDebit = params.getPropValue("loiDebit");
-                    nub = CreateStructure(loiDebit, (parentNub as ParallelStructure));
-                    break;
-                }
+            case CalculatorType.Structure:
+                const loiDebit: LoiDebit = params.getPropValue("loiDebit");
+                nub = CreateStructure(loiDebit, (parentNub as ParallelStructure));
+                break;
 
-            case CalculatorType.ParallelStructure: {
-                    prms = new ParallelStructureParams(
-                        0.5, // Q
-                        102, // Z1
-                        101.5 // Z2
-                    );
-                    nub = new ParallelStructure(prms, dbg);
-                    break;
-                }
+            case CalculatorType.ParallelStructure:
+                prms = new ParallelStructureParams(
+                    0.5, // Q
+                    102, // Z1
+                    101.5 // Z2
+                );
+                nub = new ParallelStructure(prms, dbg);
+                break;
 
-            case CalculatorType.Dever: {
-                    const deverPrms = new DeverParams(
-                        0.5, // Q
-                        102, // Z1
-                        10,  // BR : largeur du cours d'eau
-                        99   // ZR : cote du lit du cours d'eau
-                    );
-                    nub = new Dever(deverPrms, dbg);
-                    break;
-                }
+            case CalculatorType.Dever:
+                const deverPrms = new DeverParams(
+                    0.5, // Q
+                    102, // Z1
+                    10,  // BR : largeur du cours d'eau
+                    99   // ZR : cote du lit du cours d'eau
+                );
+                nub = new Dever(deverPrms, dbg);
+                break;
 
-            case CalculatorType.Cloisons: {
-                    nub = new Cloisons(
-                        new CloisonsParams(
-                            1.5,      // 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)
-                        ), dbg
-                    );
-                    break;
-                }
+            case CalculatorType.Cloisons:
+                nub = new Cloisons(
+                    new CloisonsParams(
+                        1.5,      // 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)
+                    ), dbg
+                );
+                break;
 
-            case CalculatorType.MacroRugo: {
-                    nub = new MacroRugo(
-                        new MacrorugoParams(
-                            12.5,   // ZF1
-                            6,      // L
-                            1,      // B
-                            0.05,   // If
-                            1.57,   // Q
-                            0.6,    // h
-                            0.01,   // Ks
-                            0.05,   // C
-                            0.5,    // D
-                            0.8,    // k
-                            1.5     // Cd0
-                        ), dbg
-                    );
-                    break;
-                }
+            case CalculatorType.MacroRugo:
+                nub = new MacroRugo(
+                    new MacrorugoParams(
+                        12.5,   // ZF1
+                        6,      // L
+                        1,      // B
+                        0.05,   // If
+                        1.57,   // Q
+                        0.6,    // h
+                        0.01,   // Ks
+                        0.05,   // C
+                        0.5,    // D
+                        0.8,    // k
+                        1.5     // Cd0
+                    ), dbg
+                );
+                break;
 
-            case CalculatorType.PabChute: {
-                    nub = new PabChute(
-                        new PabChuteParams(
-                            2,      // Z1
-                            0.5,    // Z2
-                            1.5     // DH
-                        ), dbg
-                    );
-                    break;
-                }
+            case CalculatorType.PabChute:
+                nub = new PabChute(
+                    new PabChuteParams(
+                        2,      // Z1
+                        0.5,    // Z2
+                        1.5     // DH
+                    ), dbg
+                );
+                break;
 
-            case CalculatorType.PabNombre: {
-                    nub = new PabNombre(
-                        new PabNombreParams(
-                            6,     // DHT
-                            10,    // N
-                            0.6    // DH
-                        ), dbg
-                    );
-                    break;
-                }
+            case CalculatorType.PabNombre:
+                nub = new PabNombre(
+                    new PabNombreParams(
+                        6,     // DHT
+                        10,    // N
+                        0.6    // DH
+                    ), dbg
+                );
+                break;
 
-            case CalculatorType.Section: {
-                    const nodeType: ComputeNodeType = params.getPropValue("nodeType");
-                    nub = this.createSection(nodeType, dbg);
-                    break;
-                }
+            case CalculatorType.Section:
+                const nodeType: ComputeNodeType = params.getPropValue("nodeType");
+                nub = this.createSection(nodeType, dbg);
+                break;
 
             case CalculatorType.Pab:
                 nub = new Pab(
@@ -433,11 +420,28 @@ export class Session {
                     break;
                 }
 
-            default: {
-                    throw new Error(
-                        `Session.createNub() : type de module '${CalculatorType[calcType]}' non pris en charge`
-                    );
-                }
+            case CalculatorType.MacroRugoCompound:
+                nub = new MacrorugoCompound(
+                    new MacrorugoCompoundParams(
+                        13.1,   // Z1
+                        12.5,   // ZRL
+                        12.5,   // ZRR
+                        4,      // B
+                        3,      // DH
+                        0.05,   // If
+                        0.01,   // Ks
+                        0.05,   // C
+                        0.5,    // D
+                        0.8,    // k
+                        1.5     // Cd0
+                    )
+                );
+                break;
+
+            default:
+                throw new Error(
+                    `Session.createNub() : type de module '${CalculatorType[calcType]}' non pris en charge`
+                );
         }
 
         // propagate properties
@@ -512,51 +516,51 @@ export class Session {
         switch (nt) {
             case ComputeNodeType.None: // pour les paramètres communs, n'importe quelle section convient
             case ComputeNodeType.SectionTrapeze: {
-                    const prms = new ParamsSectionTrapez(2.5, // largeur de fond
-                        0.56, // fruit
-                        0.8, // tirant d'eau
-                        40, //  Ks=Strickler
-                        1.2,  //  Q=Débit
-                        0.001, //  If=pente du fond
-                        1, // YB= hauteur de berge
-                    );
+                const prms = new ParamsSectionTrapez(2.5, // largeur de fond
+                    0.56, // fruit
+                    0.8, // tirant d'eau
+                    40, //  Ks=Strickler
+                    1.2,  //  Q=Débit
+                    0.001, //  If=pente du fond
+                    1, // YB= hauteur de berge
+                );
 
-                    return new cSnTrapez(prms, dbg);
-                }
+                return new cSnTrapez(prms, dbg);
+            }
 
             case ComputeNodeType.SectionRectangle: {
-                    const prms = new ParamsSectionRectang(0.8, // tirant d'eau
-                        2.5, // largeur de fond
-                        40, //  Ks=Strickler
-                        1.2, // Q=Débit
-                        0.001, // If=pente du fond
-                        1 // YB=hauteur de berge
-                    );
-                    return new cSnRectang(prms, dbg);
-                }
+                const prms = new ParamsSectionRectang(0.8, // tirant d'eau
+                    2.5, // largeur de fond
+                    40, //  Ks=Strickler
+                    1.2, // Q=Débit
+                    0.001, // If=pente du fond
+                    1 // YB=hauteur de berge
+                );
+                return new cSnRectang(prms, dbg);
+            }
 
             case ComputeNodeType.SectionCercle: {
-                    const prms = new ParamsSectionCirc(2, // diamètre
-                        0.8, // tirant d'eau
-                        40, //  Ks=Strickler
-                        1.2,  //  Q=Débit
-                        0.001, //  If=pente du fond
-                        1, // YB= hauteur de berge
-                    );
-                    return new cSnCirc(prms, dbg);
-                }
+                const prms = new ParamsSectionCirc(2, // diamètre
+                    0.8, // tirant d'eau
+                    40, //  Ks=Strickler
+                    1.2,  //  Q=Débit
+                    0.001, //  If=pente du fond
+                    1, // YB= hauteur de berge
+                );
+                return new cSnCirc(prms, dbg);
+            }
 
             case ComputeNodeType.SectionPuissance: {
-                    const prms = new ParamsSectionPuiss(0.5, // coefficient
-                        0.8, // tirant d'eau
-                        4, // largeur de berge
-                        40, //  Ks=Strickler
-                        1.2,  //  Q=Débit
-                        0.001, //  If=pente du fond
-                        1, // YB= hauteur de berge
-                    );
-                    return new cSnPuiss(prms, dbg);
-                }
+                const prms = new ParamsSectionPuiss(0.5, // coefficient
+                    0.8, // tirant d'eau
+                    4, // largeur de berge
+                    40, //  Ks=Strickler
+                    1.2,  //  Q=Débit
+                    0.001, //  If=pente du fond
+                    1, // YB= hauteur de berge
+                );
+                return new cSnPuiss(prms, dbg);
+            }
 
             default:
                 throw new Error(`type de section ${ComputeNodeType[nt]} non pris en charge`);
diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts
index 107b5b571a63ba2f13b20e3f6f2117c9460d176a..d9c7483e5c436af4b7c82ef0c9cbc708016758d7 100644
--- a/src/structure/parallel_structure.ts
+++ b/src/structure/parallel_structure.ts
@@ -21,6 +21,7 @@ export class ParallelStructure extends Nub {
     constructor(prms: ParamsEquation, dbg: boolean = false) {
         super(prms, dbg);
         this._calcType = CalculatorType.ParallelStructure;
+        this._childrenType = "Structure";
     }
 
     /** children casting */
@@ -128,21 +129,13 @@ export class ParallelStructure extends Nub {
                 }
                 // Pour les caractéristiques des ouvrages
                 const structureIndex = this.getIndexForChild(sVarCalc.uid);
-                this.currentResult = this.CalcStructPrm(structureIndex, sVarCalc.symbol, rInit);
-                if (this.result.ok) {
-                    this._children[structureIndex].getParameter(sVarCalc.symbol).v = this.result.resultElement.vCalc;
-                }
-        }
-        if (this.result.ok) {
-            // Recalcul du débit total pour récupérer les résultats des ouvrages dans les résultats complémentaires
-            const resQtot: Result = this.CalcQ();
-            for (const extraResKey in resQtot.extraResults) {
-                if (resQtot.resultElement.values.hasOwnProperty(extraResKey)) {
-                    this.result.resultElement.addExtraResult(
-                        extraResKey, resQtot.extraResults.resultElement.values[extraResKey]
-                    );
+                const r = this.CalcStructPrm(structureIndex, sVarCalc.symbol, rInit);
+                if (r.ok) {
+                    this.result.symbol = r.symbol;
+                    this.result.vCalc = r.vCalc;
+                } else {
+                    this.currentResult = r;
                 }
-            }
         }
 
         return this.result;
@@ -205,7 +198,9 @@ export class ParallelStructure extends Nub {
         this.structures[index].prms.Q.v = this.prms.Q.v - this.CalcQ(index).vCalc;
 
         // Calcul du paramètre de la structure en calcul
-        return this.structures[index].Calc(symbol, rInit);
+        const r: Result = this.structures[index].Calc(symbol, rInit);
+        this.structures[index].result.values.Q = this.structures[index].prms.Q.v;
+        return r;
     }
 
 }
diff --git a/src/structure/structure.ts b/src/structure/structure.ts
index 01980793bd25b7caecb98d4437e8971bf6631551..75285fdc5c0d19e9c5ae176dc28afb9d70496b33 100644
--- a/src/structure/structure.ts
+++ b/src/structure/structure.ts
@@ -320,7 +320,7 @@ export abstract class Structure extends Nub {
         this.prms.Z2.calculability = ParamCalculability.DICHO;
         this.prms.h1.calculability = ParamCalculability.DICHO;
         this.prms.h2.calculability = ParamCalculability.DICHO;
-        this.prms.W.calculability = ParamCalculability.DICHO;
+        this.prms.W.calculability = ParamCalculability.FIXED;
     }
 
     /**
diff --git a/src/structure/structure_cem88d.ts b/src/structure/structure_cem88d.ts
index 08bfeb4c0f176b18dc3ae35b0997933dc417d1a4..51d820c5f311d05969f50d2d9e69be4983040851 100644
--- a/src/structure/structure_cem88d.ts
+++ b/src/structure/structure_cem88d.ts
@@ -1,3 +1,4 @@
+import { ParamCalculability } from "../param/param-definition";
 import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
@@ -65,6 +66,14 @@ export class StructureGateCem88d extends RectangularStructure {
 
         return new Result(v, this, data);
     }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.W.calculability = ParamCalculability.DICHO;
+    }
 }
 
 // tslint:disable-next-line:max-classes-per-file
@@ -81,4 +90,5 @@ export class StructureWeirCem88d extends StructureGateCem88d {
     protected getFlowMode(): StructureFlowMode {
         return StructureFlowMode.WEIR;
     }
+
 }
diff --git a/src/structure/structure_cem88v.ts b/src/structure/structure_cem88v.ts
index 8a5d9c49dc4e65fa1f17d165bad5fe3c28e7f096..dec63d4005427e6400fb2ffbe4793e3d70d0da34 100644
--- a/src/structure/structure_cem88v.ts
+++ b/src/structure/structure_cem88v.ts
@@ -1,3 +1,4 @@
+import { ParamCalculability } from "../param/param-definition";
 import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
@@ -115,6 +116,14 @@ export class StructureGateCem88v extends RectangularStructure {
         }
     }
 
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.W.calculability = ParamCalculability.DICHO;
+    }
+
     private getAlfa(h2: number): number {
         let alfa: number = 1 - 0.14 * (h2) / this.W;
         alfa = Math.min(Math.max(alfa, 0.4), 0.75);
@@ -147,4 +156,5 @@ export class StructureWeirCem88v extends StructureGateCem88v {
     protected getFlowMode(): StructureFlowMode {
         return StructureFlowMode.WEIR;
     }
+
 }
diff --git a/src/structure/structure_cunge80.ts b/src/structure/structure_cunge80.ts
index 79c2fff0fad296935982686a32f4d529251aa001..a19f4354df4cf259671c08d13d11d653697f8d51 100644
--- a/src/structure/structure_cunge80.ts
+++ b/src/structure/structure_cunge80.ts
@@ -1,3 +1,4 @@
+import { ParamCalculability } from "../param/param-definition";
 import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
@@ -80,6 +81,14 @@ export class StructureGateCunge80 extends RectangularStructure {
             }
         }
     }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.W.calculability = ParamCalculability.DICHO;
+    }
 }
 
 // tslint:disable-next-line:max-classes-per-file
@@ -94,4 +103,5 @@ export class StructureWeirCunge80 extends StructureGateCunge80 {
     protected getFlowMode(): StructureFlowMode {
         return StructureFlowMode.WEIR;
     }
+
 }
diff --git a/src/structure/structure_rectangular_orifice_free.ts b/src/structure/structure_rectangular_orifice_free.ts
index 8f0592b63d02705193da02a36847125862538040..18c2cc80128182f82fc4b37c2c37bae8dd383a0f 100644
--- a/src/structure/structure_rectangular_orifice_free.ts
+++ b/src/structure/structure_rectangular_orifice_free.ts
@@ -1,3 +1,4 @@
+import { ParamCalculability } from "../param/param-definition";
 import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
@@ -34,4 +35,12 @@ export class StructureRectangularOrificeFree extends RectangularStructure {
     protected getFlowRegime() {
         return StructureFlowRegime.FREE;
     }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.W.calculability = ParamCalculability.DICHO;
+    }
 }
diff --git a/src/structure/structure_rectangular_orifice_submerged.ts b/src/structure/structure_rectangular_orifice_submerged.ts
index 2550a70e5e02d748e56d526183728d7872ca9401..257bbd495b86d677eb85ba04ee657e9fdbaddd96 100644
--- a/src/structure/structure_rectangular_orifice_submerged.ts
+++ b/src/structure/structure_rectangular_orifice_submerged.ts
@@ -1,3 +1,4 @@
+import { ParamCalculability } from "../param/param-definition";
 import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
@@ -37,4 +38,12 @@ export class StructureRectangularOrificeSubmerged extends RectangularStructure {
     protected getFlowRegime() {
         return StructureFlowRegime.SUBMERGED;
     }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.W.calculability = ParamCalculability.DICHO;
+    }
 }