diff --git a/spec/iterator/param_equation.spec.ts b/spec/iterator/param_equation.spec.ts
index 5c3af3cf0f8552b46078e38e273c7c8e2d0b034f..7798163fcc84440bd0902af73896c2546e643fbd 100644
--- a/spec/iterator/param_equation.spec.ts
+++ b/spec/iterator/param_equation.spec.ts
@@ -12,7 +12,7 @@ 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 { LoiDebit, StructureType } from "../../src/structure/structure_props";
+import { LoiDebit } from "../../src/structure/structure_props";
 
 function checkParams(pdi: IParamDefinitionIterator, symbols: string[], values: number[]) {
     let n = 0;
@@ -45,8 +45,8 @@ describe("iterator  : ", () => {
         const psp: ParallelStructureParams = new ParallelStructureParams(1, 2, 3);
         const pst = new ParallelStructure(psp);
 
-        const st: Structure = CreateStructure(StructureType.SeuilRectangulaire, LoiDebit.WeirCem88d, pst);
-        pst.addStructure(st);
+        const st: Structure = CreateStructure(LoiDebit.WeirCem88d, pst);
+        pst.addChild(st);
 
         // le 2e "Pr" est celui de la structure
         const symbs = ["Pr", "Q", "Z1", "Z2", "Pr", "Cd", "h1", "h2", "L", "Q", "W", "Z1", "Z2", "ZDV"];
diff --git a/spec/mock_jasmine.ts b/spec/mock_jasmine.ts
index 6bc77c6f3c7b877a20866fee820e802bbc65e94d..b56b3cc6bdb37633000484e58978c3142e8829b8 100644
--- a/spec/mock_jasmine.ts
+++ b/spec/mock_jasmine.ts
@@ -152,6 +152,14 @@ class Expect {
         }
     }
 
+    public toContain(expected: any) {
+        const res = Array.isArray(this.actual) && this.actual.includes(expected);
+        if (!res) {
+            console.error("Expected " + this.actual + " to contain " + expected);
+        }
+        return res;
+    }
+
     public toThrow(expected?: any) {
         let exception: Error;
         if (typeof this.actual !== "function") {
diff --git a/spec/param/param_modes.spec.ts b/spec/param/param_modes.spec.ts
index 0d7fbff3feed6384ba7dbd544726142923d52ead..28a0b250ee05b175515e65bf41bd3fac17077117 100644
--- a/spec/param/param_modes.spec.ts
+++ b/spec/param/param_modes.spec.ts
@@ -2,10 +2,11 @@ import { cSnTrapez, LinkedValue, Nub, ParallelStructure, ParallelStructureParams
          ParamsSectionTrapez, ParamValueMode, SectionParametree, Session } from "../../src/index";
 import { RegimeUniforme } from "../../src/regime_uniforme";
 import { cSnCirc, ParamsSectionCirc } from "../../src/section/section_circulaire";
-import { Cloisons, CloisonsParams } from "../../src/structure/cloisons";
+import { Cloisons } from "../../src/structure/cloisons";
+import { CloisonsParams } from "../../src/structure/cloisons_params";
 import { Dever, DeverParams } from "../../src/structure/dever";
 import { CreateStructure } from "../../src/structure/factory_structure";
-import { LoiDebit, StructureType } from "../../src/structure/structure_props";
+import { LoiDebit } from "../../src/structure/structure_props";
 
 /**
  * IMPORTANT !
@@ -38,22 +39,20 @@ function createEnv() {
     paramSect.Pr.v = 0.01;
     const sect = new cSnCirc(paramSect);
     nub1 = new RegimeUniforme(sect);
-    prm1 = nub1.prms as ParamsSectionCirc;
+    prm1 = nub1.section.prms as ParamsSectionCirc;
 
     // Nub 2 : Lois d'ouvrages
     prm2 = new ParallelStructureParams(0.5, 102, 101.5);
     prm2.Pr.v = 0.01;
     nub2 = new ParallelStructure(prm2);
-    nub2.addStructure(
+    nub2.addChild(
         CreateStructure(
-            StructureType.VanneRectangulaire,
             LoiDebit.Cunge80,
             nub2
         )
     );
-    nub2.addStructure(
+    nub2.addChild(
         CreateStructure(
-            StructureType.SeuilTriangulaire,
             LoiDebit.TriangularWeirFree,
             nub2
         )
@@ -62,16 +61,14 @@ function createEnv() {
     // Nub 3 : Passe à Bassin : Cloisons
     prm3 = new CloisonsParams(1.5, 102, 10, 1, 1, 0.5);
     nub3 = new Cloisons(prm3);
-    nub3.addStructure(
+    nub3.addChild(
         CreateStructure(
-            StructureType.Orifice,
             LoiDebit.OrificeSubmerged,
             nub3
         )
     );
-    nub3.addStructure(
+    nub3.addChild(
         CreateStructure(
-            StructureType.SeuilRectangulaire,
             LoiDebit.KIVI,
             nub3
         )
@@ -81,17 +78,15 @@ function createEnv() {
     prm4 = new DeverParams(0.5, 102, 10, 99);
     prm4.Pr.v = 0.01;
     nub4 = new Dever(prm4);
-    nub4.addStructure(
+    nub4.addChild(
         CreateStructure(
-            StructureType.SeuilRectangulaire,
             LoiDebit.WeirFree,
             nub4,
             false
         )
     );
-    nub4.addStructure(
+    nub4.addChild(
         CreateStructure(
-            StructureType.SeuilTriangulaireTrunc,
             LoiDebit.TriangularTruncWeirFree,
             nub4,
             false
@@ -102,17 +97,15 @@ function createEnv() {
     prm5 = new DeverParams(0.5, 102, 10, 99);
     prm5.Pr.v = 0.01;
     nub5 = new Dever(prm5);
-    nub5.addStructure(
+    nub5.addChild(
         CreateStructure(
-            StructureType.SeuilRectangulaire,
             LoiDebit.WeirFree,
             nub5,
             false
         )
     );
-    nub5.addStructure(
+    nub5.addChild(
         CreateStructure(
-            StructureType.SeuilTriangulaireTrunc,
             LoiDebit.TriangularTruncWeirFree,
             nub5,
             false
@@ -245,6 +238,9 @@ describe("cohérence des modes de paramètres : ", () => {
     it("varier un paramètre d'une Section Paramétrée", () => {
         createEnv();
         prm6.YB.setValues(0.5, 2, 0.075);
+        /* for (const p of nub6.parameterIterator) {
+            console.log(">>> param 2", p.symbol, ParamValueMode[p.valueMode]);
+        } */
         nub6.CalcSerie(1, "Yf");
     });
 
@@ -276,7 +272,7 @@ describe("cohérence des modes de paramètres : ", () => {
 
         // link other Nubs Q to nub1.Q
         for (const n of [ nub2, nub3, nub4 ]) {
-            n.prms.Q.defineReference(nub1, "Q");
+            n.prms.Q.defineReference(nub1.section, "Q");
             // set every parameter to MINMAX / LISTE mode
             let i = 0;
             for (const p of n.parameterIterator) {
@@ -299,11 +295,11 @@ describe("cohérence des modes de paramètres : ", () => {
         prm1.Q.setValues(0.6, 2.4, 0.09);
 
         // link nub6.Q to nub1.Q
-        prm6.Q.defineReference(nub1, "Q");
+        prm6.Q.defineReference(nub1.section, "Q");
 
         // link other Nubs Q to nub6.Q
         for (const n of [ nub2, nub3, nub4 ]) {
-            n.prms.Q.defineReference(nub6, "Q");
+            n.prms.Q.defineReference(nub6.section, "Q");
             // set every parameter to MINMAX / LISTE mode
             let i = 0;
             for (const p of n.parameterIterator) {
@@ -328,7 +324,7 @@ describe("cohérence des modes de paramètres : ", () => {
 
         // link other Nubs Q to nub1.Q
         for (const n of [ nub2, nub3, nub4 ]) {
-            n.prms.Q.defineReference(nub1, "Q");
+            n.prms.Q.defineReference(nub1.section, "Q");
             // set every parameter to MINMAX / LISTE mode
             let i = 0;
             for (const p of n.parameterIterator) {
@@ -352,11 +348,11 @@ describe("cohérence des modes de paramètres : ", () => {
         prm1.Q.setCalculated();
 
         // link nub6.Q to nub5.CvQT
-        prm6.Q.defineReference(nub1, "Q");
+        prm6.Q.defineReference(nub1.section, "Q");
 
         // link other Nubs Q to nub6.Q
         for (const n of [ nub2, nub3, nub4 ]) {
-            n.prms.Q.defineReference(nub6, "Q");
+            n.prms.Q.defineReference(nub6.section, "Q");
             // set every parameter to MINMAX / LISTE mode
             let i = 0;
             for (const p of n.parameterIterator) {
@@ -409,7 +405,7 @@ describe("cohérence des modes de paramètres : ", () => {
 
         // link other Nubs Q to nub6.Q
         for (const n of [ nub2, nub3, nub4 ]) {
-            n.prms.Q.defineReference(nub6, "Q");
+            n.prms.Q.defineReference(nub6.section, "Q");
             // set every parameter to MINMAX / LISTE mode
             let i = 0;
             for (const p of n.parameterIterator) {
diff --git a/spec/section_param/section_param_circ_fluvial.spec.ts b/spec/section_param/section_param_circ_fluvial.spec.ts
index 49d9e110c0002a30f3364c7dfcf4c118a3cdd815..425384dc16a584e7d868af4e8c5b330c425deb80 100644
--- a/spec/section_param/section_param_circ_fluvial.spec.ts
+++ b/spec/section_param/section_param_circ_fluvial.spec.ts
@@ -39,89 +39,89 @@ describe("Section paramétrée circulaire : ", () => {
     describe("fluvial / pas de débordement :", () => {
         // charge spécifique
         it("Hs should equal to 0.853", () => {
-            checkResult(sect.Calc("Hs"), 0.853);
+            checkResult(sect.CalcSection("Hs"), 0.853);
         });
 
         // charge critique
         it("Hsc should equal to 0.694", () => {
-            checkResult(sect.Calc("Hsc"), 0.694);
+            checkResult(sect.CalcSection("Hsc"), 0.694);
         });
 
         // largeur au miroir
         it("B should equal to 1.959", () => {
-            checkResult(sect.Calc("B"), 1.959);
+            checkResult(sect.CalcSection("B"), 1.959);
         });
 
         // périmètre mouillé
         it("P should equal to 2.738", () => {
-            checkResult(sect.Calc("P"), 2.738);
+            checkResult(sect.CalcSection("P"), 2.738);
         });
 
         // surface mouillée
         it("S should equal to 1.173", () => {
-            checkResult(sect.Calc("S"), 1.173);
+            checkResult(sect.CalcSection("S"), 1.173);
         });
 
         // rayon hydraulique
         it("R should equal to 0.428", () => {
-            checkResult(sect.Calc("R"), 0.428);
+            checkResult(sect.CalcSection("R"), 0.428);
         });
 
         // vitesse moyenne
         it("V should equal to 1.023", () => {
-            checkResult(sect.Calc("V"), 1.023);
+            checkResult(sect.CalcSection("V"), 1.023);
         });
 
         // nombre de Froude
         it("Fr should equal to 0.422", () => {
-            checkResult(sect.Calc("Fr"), 0.422);
+            checkResult(sect.CalcSection("Fr"), 0.422);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 0.512", () => {
-            checkResult(sect.Calc("Yc"), 0.512);
+            checkResult(sect.CalcSection("Yc"), 0.512);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 0.976", () => {
-            checkResult(sect.Calc("Yn"), 0.976);
+            checkResult(sect.CalcSection("Yn"), 0.976);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 0.8", () => {
-            checkResult(sect.Calc("Yf"), 0.8);
+            checkResult(sect.CalcSection("Yf"), 0.8);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.361", () => {
-            checkResult(sect.Calc("Yt"), 0.361);
+            checkResult(sect.CalcSection("Yt"), 0.361);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 0.307", () => {
-            checkResult(sect.Calc("Yco"), 0.307);
+            checkResult(sect.CalcSection("Yco"), 0.307);
         });
 
         // perte de charge
         it("J should equal to 0.002", () => {
             // sect = createSection(0.00001);
-            checkResult(sect.Calc("J"), 0.002);
+            checkResult(sect.CalcSection("J"), 0.002);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to -0.00102", () => {
             sect = createSection(0.00001);
-            checkResult(sect.Calc("I-J"), -0.00102);
+            checkResult(sect.CalcSection("I-J"), -0.00102);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 5076.304", () => {
-            checkResult(sect.Calc("Imp"), 5076.304);
+            checkResult(sect.CalcSection("Imp"), 5076.304);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 8.505", () => {
-            checkResult(sect.Calc("Tau0"), 8.505);
+            checkResult(sect.CalcSection("Tau0"), 8.505);
         });
     });
 });
@@ -134,89 +134,89 @@ describe("Section paramétrée circulaire : ", () => {
     describe("fluvial / débordement :", () => {
         // charge spécifique
         it("Hs should equal to 2.006", () => {
-            checkResult(sect.Calc("Hs"), 2.006);
+            checkResult(sect.CalcSection("Hs"), 2.006);
         });
 
         // charge critique
         it("Hsc should equal to 0.694", () => {
-            checkResult(sect.Calc("Hsc"), 0.694);
+            checkResult(sect.CalcSection("Hsc"), 0.694);
         });
 
         // largeur au miroir
         it("B should equal to 2", () => {
-            checkResult(sect.Calc("B"), 2);
+            checkResult(sect.CalcSection("B"), 2);
         });
 
         // périmètre mouillé
         it("P should equal to 5.142", () => {
-            checkResult(sect.Calc("P"), 5.142);
+            checkResult(sect.CalcSection("P"), 5.142);
         });
 
         // surface mouillée
         it("S should equal to 3.571", () => {
-            checkResult(sect.Calc("S"), 3.571);
+            checkResult(sect.CalcSection("S"), 3.571);
         });
 
         // rayon hydraulique
         it("R should equal to 0.694", () => {
-            checkResult(sect.Calc("R"), 0.694);
+            checkResult(sect.CalcSection("R"), 0.694);
         });
 
         // vitesse moyenne
         it("V should equal to 0.336", () => {
-            checkResult(sect.Calc("V"), 0.336);
+            checkResult(sect.CalcSection("V"), 0.336);
         });
 
         // nombre de Froude
         it("Fr should equal to 0.08", () => {
-            checkResult(sect.Calc("Fr"), 0.08);
+            checkResult(sect.CalcSection("Fr"), 0.08);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 0.512", () => {
-            checkResult(sect.Calc("Yc"), 0.512);
+            checkResult(sect.CalcSection("Yc"), 0.512);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 0.976", () => {
-            checkResult(sect.Calc("Yn"), 0.976);
+            checkResult(sect.CalcSection("Yn"), 0.976);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 2", () => {
-            checkResult(sect.Calc("Yf"), 2);
+            checkResult(sect.CalcSection("Yf"), 2);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.232", () => {
-            checkResult(sect.Calc("Yt"), 0.232);
+            checkResult(sect.CalcSection("Yt"), 0.232);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 0.24", () => {
-            checkResult(sect.Calc("Yco"), 0.24);
+            checkResult(sect.CalcSection("Yco"), 0.24);
         });
 
         // perte de charge
         it("J should equal to 0.0001", () => {
             sect = createSectionDebordement(0.00001);
-            checkResult(sect.Calc("J"), 0.0001);
+            checkResult(sect.CalcSection("J"), 0.0001);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to 0.001", () => {
             sect = createSectionDebordement(0.00001);
-            checkResult(sect.Calc("I-J"), 0.001);
+            checkResult(sect.CalcSection("I-J"), 0.001);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 6943.271", () => {
-            checkResult(sect.Calc("Imp"), 6943.271);
+            checkResult(sect.CalcSection("Imp"), 6943.271);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 0.782", () => {
-            checkResult(sect.Calc("Tau0"), 0.782);
+            checkResult(sect.CalcSection("Tau0"), 0.782);
         });
     });
 });
diff --git a/spec/section_param/section_param_circ_torrentiel.spec.ts b/spec/section_param/section_param_circ_torrentiel.spec.ts
index e867379a7f265b29c7784ffaa0dc16df3f8da263..8ae10cbb4b81b9b8c0befbcb5e18637bae524a92 100644
--- a/spec/section_param/section_param_circ_torrentiel.spec.ts
+++ b/spec/section_param/section_param_circ_torrentiel.spec.ts
@@ -26,89 +26,89 @@ describe("Section paramétrée circulaire : ", () => {
     describe("torrentiel :", () => {
         // charge spécifique
         it("Hs should equal to 4.501", () => {
-            checkResult(sect.Calc("Hs"), 4.501);
+            checkResult(sect.CalcSection("Hs"), 4.501);
         });
 
         // charge critique
         it("Hsc should equal to 2.263", () => {
-            checkResult(sect.Calc("Hsc"), 2.263);
+            checkResult(sect.CalcSection("Hsc"), 2.263);
         });
 
         // largeur au miroir
         it("B should equal to 1.960", () => {
-            checkResult(sect.Calc("B"), 1.960);
+            checkResult(sect.CalcSection("B"), 1.960);
         });
 
         // périmètre mouillé
         it("P should equal to 2.739", () => {
-            checkResult(sect.Calc("P"), 2.739);
+            checkResult(sect.CalcSection("P"), 2.739);
         });
 
         // surface mouillée
         it("S should equal to 1.173", () => {
-            checkResult(sect.Calc("S"), 1.173);
+            checkResult(sect.CalcSection("S"), 1.173);
         });
 
         // rayon hydraulique
         it("R should equal to 0.428", () => {
-            checkResult(sect.Calc("R"), 0.428);
+            checkResult(sect.CalcSection("R"), 0.428);
         });
 
         // vitesse moyenne
         it("V should equal to 8.522", () => {
-            checkResult(sect.Calc("V"), 8.522);
+            checkResult(sect.CalcSection("V"), 8.522);
         });
 
         // nombre de Froude
         it("Fr should equal to 3.516", () => {
-            checkResult(sect.Calc("Fr"), 3.516);
+            checkResult(sect.CalcSection("Fr"), 3.516);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 1.581", () => {
-            checkResult(sect.Calc("Yc"), 1.581);
+            checkResult(sect.CalcSection("Yc"), 1.581);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 4.624", () => {
-            checkResult(sect.Calc("Yn"), 4.624);
+            checkResult(sect.CalcSection("Yn"), 4.624);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 4.43", () => {
-            checkResult(sect.Calc("Yf"), 4.43);
+            checkResult(sect.CalcSection("Yf"), 4.43);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.8", () => {
-            checkResult(sect.Calc("Yt"), 0.8);
+            checkResult(sect.CalcSection("Yt"), 0.8);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 0.8", () => {
-            checkResult(sect.Calc("Yco"), 0.8);
+            checkResult(sect.CalcSection("Yco"), 0.8);
         });
 
         // perte de charge
         it("J should equal to 0.141", () => {
             // sect = createSection(0.00001);
-            checkResult(sect.Calc("J"), 0.141);
+            checkResult(sect.CalcSection("J"), 0.141);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to -0.14", () => {
             // sect = createSection(0.00001);
-            checkResult(sect.Calc("I-J"), -0.14);
+            checkResult(sect.CalcSection("I-J"), -0.14);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 89065.861", () => {
-            checkResult(sect.Calc("Imp"), 89065.861);
+            checkResult(sect.CalcSection("Imp"), 89065.861);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 590.605", () => {
-            checkResult(sect.Calc("Tau0"), 590.605);
+            checkResult(sect.CalcSection("Tau0"), 590.605);
         });
     });
 });
diff --git a/spec/section_param/section_param_puiss_fluvial.spec.ts b/spec/section_param/section_param_puiss_fluvial.spec.ts
index 8d2b931330722d830d3dc9d8a94d26d5084e7490..f2fb30ed4e672c35858f3343950991ac02ee57cf 100644
--- a/spec/section_param/section_param_puiss_fluvial.spec.ts
+++ b/spec/section_param/section_param_puiss_fluvial.spec.ts
@@ -41,89 +41,89 @@ describe("Section paramétrée puissance :", () => {
     describe("fluvial / pas de débordement :", () => {
         // charge spécifique
         it("Hs should equal to 0.82", () => {
-            checkResult(sect.Calc("Hs"), 0.82);
+            checkResult(sect.CalcSection("Hs"), 0.82);
         });
 
         // charge critique
         it("Hsc should equal to 0.559", () => {
-            checkResult(sect.Calc("Hsc"), 0.559);
+            checkResult(sect.CalcSection("Hsc"), 0.559);
         });
 
         // largeur au miroir
         it("B should equal to 3.578", () => {
-            checkResult(sect.Calc("B"), 3.578);
+            checkResult(sect.CalcSection("B"), 3.578);
         });
 
         // périmètre mouillé
         it("P should equal to 4.223", () => {
-            checkResult(sect.Calc("P"), 4.223);
+            checkResult(sect.CalcSection("P"), 4.223);
         });
 
         // surface mouillée
         it("S should equal to 1.908", () => {
-            checkResult(sect.Calc("S"), 1.908);
+            checkResult(sect.CalcSection("S"), 1.908);
         });
 
         // rayon hydraulique
         it("R should equal to 0.452", () => {
-            checkResult(sect.Calc("R"), 0.452);
+            checkResult(sect.CalcSection("R"), 0.452);
         });
 
         // vitesse moyenne
         it("V should equal to 0.629", () => {
-            checkResult(sect.Calc("V"), 0.629);
+            checkResult(sect.CalcSection("V"), 0.629);
         });
 
         // nombre de Froude
         it("Fr should equal to 0.275", () => {
-            checkResult(sect.Calc("Fr"), 0.275);
+            checkResult(sect.CalcSection("Fr"), 0.275);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 0.419", () => {
-            checkResult(sect.Calc("Yc"), 0.419);
+            checkResult(sect.CalcSection("Yc"), 0.419);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 0.742", () => {
-            checkResult(sect.Calc("Yn"), 0.742);
+            checkResult(sect.CalcSection("Yn"), 0.742);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 0.8", () => {
-            checkResult(sect.Calc("Yf"), 0.8);
+            checkResult(sect.CalcSection("Yf"), 0.8);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.265", () => {
-            checkResult(sect.Calc("Yt"), 0.265);
+            checkResult(sect.CalcSection("Yt"), 0.265);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 0.189", () => {
-            checkResult(sect.Calc("Yco"), 0.189);
+            checkResult(sect.CalcSection("Yco"), 0.189);
         });
 
         // perte de charge
         it("J should equal to 0.0007", () => {
             sect = createSection(0.00001);
-            checkResult(sect.Calc("J"), 0.0007);
+            checkResult(sect.CalcSection("J"), 0.0007);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to 0.000335", () => {
             sect = createSection(0.000001);
-            checkResult(sect.Calc("I-J"), 0.000335);
+            checkResult(sect.CalcSection("I-J"), 0.000335);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 6744.616", () => {
-            checkResult(sect.Calc("Imp"), 6744.616);
+            checkResult(sect.CalcSection("Imp"), 6744.616);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 3.16", () => {
-            checkResult(sect.Calc("Tau0"), 3.16);
+            checkResult(sect.CalcSection("Tau0"), 3.16);
         });
     });
 });
@@ -136,89 +136,89 @@ describe("Section paramétrée puissance :", () => {
     describe("fluvial / débordement :", () => {
         // charge spécifique
         it("Hs should equal to 2.001", () => {
-            checkResult(sect.Calc("Hs"), 2.001);
+            checkResult(sect.CalcSection("Hs"), 2.001);
         });
 
         // charge critique
         it("Hsc should equal to 0.559", () => {
-            checkResult(sect.Calc("Hsc"), 0.559);
+            checkResult(sect.CalcSection("Hsc"), 0.559);
         });
 
         // largeur au miroir
         it("B should equal to 4", () => {
-            checkResult(sect.Calc("B"), 4);
+            checkResult(sect.CalcSection("B"), 4);
         });
 
         // périmètre mouillé
         it("P should equal to 6.098", () => {
-            checkResult(sect.Calc("P"), 6.098);
+            checkResult(sect.CalcSection("P"), 6.098);
         });
 
         // surface mouillée
         it("S should equal to 7.542", () => {
-            checkResult(sect.Calc("S"), 7.542);
+            checkResult(sect.CalcSection("S"), 7.542);
         });
 
         // rayon hydraulique
         it("R should equal to 1.237", () => {
-            checkResult(sect.Calc("R"), 1.237);
+            checkResult(sect.CalcSection("R"), 1.237);
         });
 
         // vitesse moyenne
         it("V should equal to 0.159", () => {
-            checkResult(sect.Calc("V"), 0.159);
+            checkResult(sect.CalcSection("V"), 0.159);
         });
 
         // nombre de Froude
         it("Fr should equal to 0.037", () => {
-            checkResult(sect.Calc("Fr"), 0.037);
+            checkResult(sect.CalcSection("Fr"), 0.037);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 0.419", () => {
-            checkResult(sect.Calc("Yc"), 0.419);
+            checkResult(sect.CalcSection("Yc"), 0.419);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 0.742", () => {
-            checkResult(sect.Calc("Yn"), 0.742);
+            checkResult(sect.CalcSection("Yn"), 0.742);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 2", () => {
-            checkResult(sect.Calc("Yf"), 2);
+            checkResult(sect.CalcSection("Yf"), 2);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.178", () => {
-            checkResult(sect.Calc("Yt"), 0.178);
+            checkResult(sect.CalcSection("Yt"), 0.178);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 0.044", () => {
-            checkResult(sect.Calc("Yco"), 0.044);
+            checkResult(sect.CalcSection("Yco"), 0.044);
         });
 
         // perte de charge
         it("J should equal to 0.00059", () => {
             sect = createSection(0.00001);
-            checkResult(sect.Calc("J"), 0.00059);
+            checkResult(sect.CalcSection("J"), 0.00059);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to 0.00041", () => {
             sect = createSection(0.00001);
-            checkResult(sect.Calc("I-J"), 0.00041);
+            checkResult(sect.CalcSection("I-J"), 0.00041);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 59384.242", () => {
-            checkResult(sect.Calc("Imp"), 59384.242);
+            checkResult(sect.CalcSection("Imp"), 59384.242);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 0.145", () => {
-            checkResult(sect.Calc("Tau0"), 0.145);
+            checkResult(sect.CalcSection("Tau0"), 0.145);
         });
     });
 });
diff --git a/spec/section_param/section_param_puiss_torrentiel.spec.ts b/spec/section_param/section_param_puiss_torrentiel.spec.ts
index 58b763be12048abd4d1acba2dac285eabc49eb68..6df874ef91760be164b20de3053c15e82e9e05dc 100644
--- a/spec/section_param/section_param_puiss_torrentiel.spec.ts
+++ b/spec/section_param/section_param_puiss_torrentiel.spec.ts
@@ -27,89 +27,89 @@ describe("Section paramétrée puissance :", () => {
     describe("torrentiel / pas de débordement :", () => {
         // charge spécifique
         it("Hs should equal to 2.2", () => {
-            checkResult(sect.Calc("Hs"), 2.2);
+            checkResult(sect.CalcSection("Hs"), 2.2);
         });
 
         // charge critique
         it("Hsc should equal to 1.616", () => {
-            checkResult(sect.Calc("Hsc"), 1.616);
+            checkResult(sect.CalcSection("Hsc"), 1.616);
         });
 
         // largeur au miroir
         it("B should equal to 3.578", () => {
-            checkResult(sect.Calc("B"), 3.578);
+            checkResult(sect.CalcSection("B"), 3.578);
         });
 
         // périmètre mouillé
         it("P should equal to 4.223", () => {
-            checkResult(sect.Calc("P"), 4.223);
+            checkResult(sect.CalcSection("P"), 4.223);
         });
 
         // surface mouillée
         it("S should equal to 1.908", () => {
-            checkResult(sect.Calc("S"), 1.908);
+            checkResult(sect.CalcSection("S"), 1.908);
         });
 
         // rayon hydraulique
         it("R should equal to 0.452", () => {
-            checkResult(sect.Calc("R"), 0.452);
+            checkResult(sect.CalcSection("R"), 0.452);
         });
 
         // vitesse moyenne
         it("V should equal to 5.241", () => {
-            checkResult(sect.Calc("V"), 5.241);
+            checkResult(sect.CalcSection("V"), 5.241);
         });
 
         // nombre de Froude
         it("Fr should equal to 2.291", () => {
-            checkResult(sect.Calc("Fr"), 2.291);
+            checkResult(sect.CalcSection("Fr"), 2.291);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 1.186", () => {
-            checkResult(sect.Calc("Yc"), 1.186);
+            checkResult(sect.CalcSection("Yc"), 1.186);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 1.916", () => {
-            checkResult(sect.Calc("Yn"), 1.916);
+            checkResult(sect.CalcSection("Yn"), 1.916);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 2.126", () => {
-            checkResult(sect.Calc("Yf"), 2.126);
+            checkResult(sect.CalcSection("Yf"), 2.126);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.8", () => {
-            checkResult(sect.Calc("Yt"), 0.8);
+            checkResult(sect.CalcSection("Yt"), 0.8);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 1.746", () => {
-            checkResult(sect.Calc("Yco"), 1.746);
+            checkResult(sect.CalcSection("Yco"), 1.746);
         });
 
         // perte de charge
         it("J should equal to 0.05", () => {
             // sect = createSection(0.00001);
-            checkResult(sect.Calc("J"), 0.05);
+            checkResult(sect.CalcSection("J"), 0.05);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to -0.049", () => {
             // sect = createSection(0.00001);
-            checkResult(sect.Calc("I-J"), -0.049);
+            checkResult(sect.CalcSection("I-J"), -0.049);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 58397.786", () => {
-            checkResult(sect.Calc("Imp"), 58397.786);
+            checkResult(sect.CalcSection("Imp"), 58397.786);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 219.455", () => {
-            checkResult(sect.Calc("Tau0"), 219.455);
+            checkResult(sect.CalcSection("Tau0"), 219.455);
         });
     });
 });
diff --git a/spec/section_param/section_param_rect_conv_newton.spec.ts b/spec/section_param/section_param_rect_conv_newton.spec.ts
index 0590226921c1537a1b30c523ed247c2019ac3248..fdae2fad8ebaf7b2cf62689e135d3b57a6c3cb1a 100644
--- a/spec/section_param/section_param_rect_conv_newton.spec.ts
+++ b/spec/section_param/section_param_rect_conv_newton.spec.ts
@@ -23,13 +23,13 @@ describe("Section paramétrée rectangulaire : ", () => {
 
     describe("non convergence de la méthode de Newton :", () => {
         it("hauteur critique", () => {
-            const r: Result = sect.Calc("Yc");
+            const r: Result = sect.CalcSection("Yc");
             expect(r.log.messages.length).toEqual(1);
             expect(r.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
         });
 
         it("hauteur normale", () => {
-            const r: Result = sect.Calc("Yn");
+            const r: Result = sect.CalcSection("Yn");
             // expect(r.log.messages.length).toEqual(2);
             expect(r.ok).toBeFalsy("le calcul devrait avoir échoué");
             expect(r.log.messages.length).toEqual(1);
@@ -39,20 +39,20 @@ describe("Section paramétrée rectangulaire : ", () => {
 
         it("hauteur normale, pente nulle", () => {
             sect.prms.If.v = 0;
-            const r: Result = sect.Calc("Yn");
+            const r: Result = sect.CalcSection("Yn");
             expect(r.log.messages.length).toEqual(1);
             expect(r.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF);
         });
 
         it("hauteur normale, pente négative", () => {
             sect.prms.If.v = -0.001;
-            const r: Result = sect.Calc("Yn");
+            const r: Result = sect.CalcSection("Yn");
             expect(r.log.messages.length).toEqual(1);
             expect(r.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF);
         });
 
         it("hauteur fluviale, Y < Yc", () => {
-            const r: Result = sect.Calc("Yf");
+            const r: Result = sect.CalcSection("Yf");
             // expect(r.log.messages.length).toEqual(3);
             expect(r.ok).toBeFalsy("le calcul devrait avoir échoué");
             expect(r.log.messages.length).toEqual(1);
@@ -63,20 +63,20 @@ describe("Section paramétrée rectangulaire : ", () => {
 
         it("hauteur fluviale, Y > Yc", () => {
             sect.prms.Y.v = 2;
-            const r: Result = sect.Calc("Yf");
+            const r: Result = sect.CalcSection("Yf");
             expect(r.log.messages.length).toEqual(1);
             expect(r.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
         });
 
         it("hauteur torrentielle, Y < Yc", () => {
-            const r: Result = sect.Calc("Yt");
+            const r: Result = sect.CalcSection("Yt");
             expect(r.log.messages.length).toEqual(1);
             expect(r.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
         });
 
         it("hauteur torrentielle, Y > Yc", () => {
             sect.prms.Y.v = 2;
-            const r: Result = sect.Calc("Yt");
+            const r: Result = sect.CalcSection("Yt");
             //            expect(r.log.messages.length).toEqual(2);
             expect(r.ok).toBeFalsy("le calcul devrait avoir échoué");
             expect(r.log.messages.length).toEqual(1);
@@ -86,7 +86,7 @@ describe("Section paramétrée rectangulaire : ", () => {
 
         it("hauteur conjuguée, Froude < 1", () => {
             sect.prms.Y.v = 2;
-            const r: Result = sect.Calc("Yco");
+            const r: Result = sect.CalcSection("Yco");
             // console.log(r.log.toString());
             // expect(r.log.messages.length).toEqual(3);
             expect(r.ok).toBeFalsy("le calcul devrait avoir échoué");
@@ -97,7 +97,7 @@ describe("Section paramétrée rectangulaire : ", () => {
         });
 
         it("hauteur conjuguée, Froude > 1", () => {
-            const r: Result = sect.Calc("Yco");
+            const r: Result = sect.CalcSection("Yco");
             // expect(r.log.messages.length).toEqual(4);
             expect(r.ok).toBeFalsy("le calcul devrait avoir échoué");
             expect(r.log.messages.length).toEqual(1);
diff --git a/spec/section_param/section_param_rect_fluvial.spec.ts b/spec/section_param/section_param_rect_fluvial.spec.ts
index 0a49c235ef18b163ec25c5318aad50950552a694..9e6103ec54e33d7fd34b11942d0caafc660c1360 100644
--- a/spec/section_param/section_param_rect_fluvial.spec.ts
+++ b/spec/section_param/section_param_rect_fluvial.spec.ts
@@ -39,89 +39,89 @@ describe("Section paramétrée rectangulaire : ", () => {
     describe("fluvial / pas de débordement :", () => {
         // charge spécifique
         it("Hs should equal to 0.818", () => {
-            checkResult(sect.Calc("Hs"), 0.818);
+            checkResult(sect.CalcSection("Hs"), 0.818);
         });
 
         // charge critique
         it("Hsc should equal to 0.43", () => {
-            checkResult(sect.Calc("Hsc"), 0.43);
+            checkResult(sect.CalcSection("Hsc"), 0.43);
         });
 
         // largeur au miroir
         it("B should equal to 2.5", () => {
-            checkResult(sect.Calc("B"), 2.5);
+            checkResult(sect.CalcSection("B"), 2.5);
         });
 
         // périmètre mouillé
         it("P should equal to 4.1", () => {
-            checkResult(sect.Calc("P"), 4.1);
+            checkResult(sect.CalcSection("P"), 4.1);
         });
 
         // surface mouillée
         it("S should equal to 2", () => {
-            checkResult(sect.Calc("S"), 2);
+            checkResult(sect.CalcSection("S"), 2);
         });
 
         // rayon hydraulique
         it("R should equal to 0.488", () => {
-            checkResult(sect.Calc("R"), 0.488);
+            checkResult(sect.CalcSection("R"), 0.488);
         });
 
         // vitesse moyenne
         it("V should equal to 0.6", () => {
-            checkResult(sect.Calc("V"), 0.6);
+            checkResult(sect.CalcSection("V"), 0.6);
         });
 
         // nombre de Froude
         it("Fr should equal to 0.214", () => {
-            checkResult(sect.Calc("Fr"), 0.214);
+            checkResult(sect.CalcSection("Fr"), 0.214);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 0.286", () => {
-            checkResult(sect.Calc("Yc"), 0.286);
+            checkResult(sect.CalcSection("Yc"), 0.286);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 0.663", () => {
-            checkResult(sect.Calc("Yn"), 0.663);
+            checkResult(sect.CalcSection("Yn"), 0.663);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 0.8", () => {
-            checkResult(sect.Calc("Yf"), 0.8);
+            checkResult(sect.CalcSection("Yf"), 0.8);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.131", () => {
-            checkResult(sect.Calc("Yt"), 0.131);
+            checkResult(sect.CalcSection("Yt"), 0.131);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 0.068", () => {
-            checkResult(sect.Calc("Yco"), 0.068);
+            checkResult(sect.CalcSection("Yco"), 0.068);
         });
 
         // perte de charge
         it("J should equal to 0.00059", () => {
             sect = createSection(0.00001);
-            checkResult(sect.Calc("J"), 0.00059);
+            checkResult(sect.CalcSection("J"), 0.00059);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to 0.00041", () => {
             sect = createSection(0.00001);
-            checkResult(sect.Calc("I-J"), 0.00041);
+            checkResult(sect.CalcSection("I-J"), 0.00041);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 8568", () => {
-            checkResult(sect.Calc("Imp"), 8568);
+            checkResult(sect.CalcSection("Imp"), 8568);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 2.804", () => {
-            checkResult(sect.Calc("Tau0"), 2.804);
+            checkResult(sect.CalcSection("Tau0"), 2.804);
         });
     });
 });
@@ -134,89 +134,89 @@ describe("Section paramétrée rectangulaire : ", () => {
     describe("fluvial / débordement :", () => {
         // charge spécifique
         it("Hs should equal to 2.003", () => {
-            checkResult(sect.Calc("Hs"), 2.003);
+            checkResult(sect.CalcSection("Hs"), 2.003);
         });
 
         // charge critique
         it("Hsc should equal to 0.43", () => {
-            checkResult(sect.Calc("Hsc"), 0.43);
+            checkResult(sect.CalcSection("Hsc"), 0.43);
         });
 
         // largeur au miroir
         it("B should equal to 2.5", () => {
-            checkResult(sect.Calc("B"), 2.5);
+            checkResult(sect.CalcSection("B"), 2.5);
         });
 
         // périmètre mouillé
         it("P should equal to 6.5", () => {
-            checkResult(sect.Calc("P"), 6.5);
+            checkResult(sect.CalcSection("P"), 6.5);
         });
 
         // surface mouillée
         it("S should equal to 5", () => {
-            checkResult(sect.Calc("S"), 5);
+            checkResult(sect.CalcSection("S"), 5);
         });
 
         // rayon hydraulique
         it("R should equal to 0.769", () => {
-            checkResult(sect.Calc("R"), 0.769);
+            checkResult(sect.CalcSection("R"), 0.769);
         });
 
         // vitesse moyenne
         it("V should equal to 0.24", () => {
-            checkResult(sect.Calc("V"), 0.24);
+            checkResult(sect.CalcSection("V"), 0.24);
         });
 
         // nombre de Froude
         it("Fr should equal to 0.0542", () => {
-            checkResult(sect.Calc("Fr"), 0.0542);
+            checkResult(sect.CalcSection("Fr"), 0.0542);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 0.286", () => {
-            checkResult(sect.Calc("Yc"), 0.286);
+            checkResult(sect.CalcSection("Yc"), 0.286);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 0.663", () => {
-            checkResult(sect.Calc("Yn"), 0.663);
+            checkResult(sect.CalcSection("Yn"), 0.663);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 2", () => {
-            checkResult(sect.Calc("Yf"), 2);
+            checkResult(sect.CalcSection("Yf"), 2);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.078", () => {
-            checkResult(sect.Calc("Yt"), 0.078);
+            checkResult(sect.CalcSection("Yt"), 0.078);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 0.012", () => {
-            checkResult(sect.Calc("Yco"), 0.012);
+            checkResult(sect.CalcSection("Yco"), 0.012);
         });
 
         // perte de charge
         it("J should equal to 0.00059", () => {
             sect = createSection(0.00001);
-            checkResult(sect.Calc("J"), 0.00059);
+            checkResult(sect.CalcSection("J"), 0.00059);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to 0.0009", () => {
             sect = createSection(0.00001);
-            checkResult(sect.Calc("I-J"), 0.0009);
+            checkResult(sect.CalcSection("I-J"), 0.0009);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 49338", () => {
-            checkResult(sect.Calc("Imp"), 49338);
+            checkResult(sect.CalcSection("Imp"), 49338);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 0.385", () => {
-            checkResult(sect.Calc("Tau0"), 0.385);
+            checkResult(sect.CalcSection("Tau0"), 0.385);
         });
     });
 });
diff --git a/spec/section_param/section_param_rect_torrentiel.spec.ts b/spec/section_param/section_param_rect_torrentiel.spec.ts
index ee056c983d51334c93ce0240e4655d4b8cf43f3b..08949ad33cb680ff9034fed719e711dfeccbb3ec 100644
--- a/spec/section_param/section_param_rect_torrentiel.spec.ts
+++ b/spec/section_param/section_param_rect_torrentiel.spec.ts
@@ -22,89 +22,89 @@ describe("Section paramétrée rectangulaire : ", () => {
     describe("torrentiel :", () => {
         // charge spécifique
         it("Hs should equal to 2.074", () => {
-            checkResult(sect.Calc("Hs"), 2.074);
+            checkResult(sect.CalcSection("Hs"), 2.074);
         });
 
         // charge critique
         it("Hsc should equal to 1.766", () => {
-            checkResult(sect.Calc("Hsc"), 1.766);
+            checkResult(sect.CalcSection("Hsc"), 1.766);
         });
 
         // largeur au miroir
         it("B should equal to 2.5", () => {
-            checkResult(sect.Calc("B"), 2.5);
+            checkResult(sect.CalcSection("B"), 2.5);
         });
 
         // périmètre mouillé
         it("P should equal to 4.1", () => {
-            checkResult(sect.Calc("P"), 4.1);
+            checkResult(sect.CalcSection("P"), 4.1);
         });
 
         // surface mouillée
         it("S should equal to 2", () => {
-            checkResult(sect.Calc("S"), 2);
+            checkResult(sect.CalcSection("S"), 2);
         });
 
         // rayon hydraulique
         it("R should equal to 0.488", () => {
-            checkResult(sect.Calc("R"), 0.488);
+            checkResult(sect.CalcSection("R"), 0.488);
         });
 
         // vitesse moyenne
         it("V should equal to 5", () => {
-            checkResult(sect.Calc("V"), 5);
+            checkResult(sect.CalcSection("V"), 5);
         });
 
         // nombre de Froude
         it("Fr should equal to 1.785", () => {
-            checkResult(sect.Calc("Fr"), 1.785);
+            checkResult(sect.CalcSection("Fr"), 1.785);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 1.177", () => {
-            checkResult(sect.Calc("Yc"), 1.177);
+            checkResult(sect.CalcSection("Yc"), 1.177);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 3.364", () => {
-            checkResult(sect.Calc("Yn"), 3.364);
+            checkResult(sect.CalcSection("Yn"), 3.364);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 1.831", () => {
-            checkResult(sect.Calc("Yf"), 1.831);
+            checkResult(sect.CalcSection("Yf"), 1.831);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.8", () => {
-            checkResult(sect.Calc("Yt"), 0.8);
+            checkResult(sect.CalcSection("Yt"), 0.8);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 1.659", () => {
-            checkResult(sect.Calc("Yco"), 1.659);
+            checkResult(sect.CalcSection("Yco"), 1.659);
         });
 
         // perte de charge
         it("J should equal to 0.041", () => {
             // paramCnl.v.Prec = 0.00001;
-            checkResult(sect.Calc("J"), 0.041);
+            checkResult(sect.CalcSection("J"), 0.041);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to -0.04", () => {
             // paramCnl.v.Prec = 0.00001;
-            checkResult(sect.Calc("I-J"), -0.04);
+            checkResult(sect.CalcSection("I-J"), -0.04);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 57848", () => {
-            checkResult(sect.Calc("Imp"), 57848);
+            checkResult(sect.CalcSection("Imp"), 57848);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 194.718", () => {
-            checkResult(sect.Calc("Tau0"), 194.718);
+            checkResult(sect.CalcSection("Tau0"), 194.718);
         });
     });
 });
diff --git a/spec/section_param/section_param_trapez_fluvial.spec.ts b/spec/section_param/section_param_trapez_fluvial.spec.ts
index b5366847273458cebee998ecc3bdcd0ff521a4da..c58cbc8e823c9355951d566656540352cfffa9a5 100644
--- a/spec/section_param/section_param_trapez_fluvial.spec.ts
+++ b/spec/section_param/section_param_trapez_fluvial.spec.ts
@@ -41,88 +41,88 @@ describe("Section paramétrée trapèze : ", () => {
     describe("fluvial / pas de débordement :", () => {
         // charge spécifique
         it("Hs should equal to 0.813", () => {
-            checkResult(sect.Calc("Hs"), 0.813);
+            checkResult(sect.CalcSection("Hs"), 0.813);
         });
 
         // charge critique
         it("Hsc should equal to 0.413", () => {
-            checkResult(sect.Calc("Hsc"), 0.413);
+            checkResult(sect.CalcSection("Hsc"), 0.413);
         });
 
         // largeur au miroir
         it("B should equal to 3.396", () => {
-            checkResult(sect.Calc("B"), 3.396);
+            checkResult(sect.CalcSection("B"), 3.396);
         });
 
         // périmètre mouillé
         it("P should equal to 4.334", () => {
-            checkResult(sect.Calc("P"), 4.334);
+            checkResult(sect.CalcSection("P"), 4.334);
         });
 
         // surface mouillée
         it("S should equal to 2.358", () => {
-            checkResult(sect.Calc("S"), 2.358);
+            checkResult(sect.CalcSection("S"), 2.358);
         });
 
         // rayon hydraulique
         it("R should equal to 0.544", () => {
-            checkResult(sect.Calc("R"), 0.544);
+            checkResult(sect.CalcSection("R"), 0.544);
         });
 
         // vitesse moyenne
         it("V should equal to 0.509", () => {
-            checkResult(sect.Calc("V"), 0.509);
+            checkResult(sect.CalcSection("V"), 0.509);
         });
 
         // nombre de Froude
         it("Fr should equal to 0.195", () => {
-            checkResult(sect.Calc("Fr"), 0.195);
+            checkResult(sect.CalcSection("Fr"), 0.195);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 0.28", () => {
-            checkResult(sect.Calc("Yc"), 0.28);
+            checkResult(sect.CalcSection("Yc"), 0.28);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 0.587", () => {
-            checkResult(sect.Calc("Yn"), 0.587);
+            checkResult(sect.CalcSection("Yn"), 0.587);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 0.8", () => {
-            checkResult(sect.Calc("Yf"), 0.8);
+            checkResult(sect.CalcSection("Yf"), 0.8);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.127", () => {
-            checkResult(sect.Calc("Yt"), 0.127);
+            checkResult(sect.CalcSection("Yt"), 0.127);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 0.061", () => {
-            checkResult(sect.Calc("Yco"), 0.061);
+            checkResult(sect.CalcSection("Yco"), 0.061);
         });
 
         // perte de charge
         it("J should equal to 0.00036", () => {
             const sect2 = createSection(0.00001);
-            checkResult(sect2.Calc("J"), 0.00036);
+            checkResult(sect2.CalcSection("J"), 0.00036);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to 0.001", () => {
-            checkResult(sect.Calc("I-J"), 0.001);
+            checkResult(sect.CalcSection("I-J"), 0.001);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 9396.158", () => {
-            checkResult(sect.Calc("Imp"), 9396.158);
+            checkResult(sect.CalcSection("Imp"), 9396.158);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 1.944", () => {
-            checkResult(sect.Calc("Tau0"), 1.944);
+            checkResult(sect.CalcSection("Tau0"), 1.944);
         });
     });
 });
@@ -135,88 +135,88 @@ describe("Section paramétrée trapèze : ", () => {
     describe("fluvial / débordement :", () => {
         // charge spécifique
         it("Hs should equal to 2.002", () => {
-            checkResult(sect.Calc("Hs"), 2.002);
+            checkResult(sect.CalcSection("Hs"), 2.002);
         });
 
         // charge critique
         it("Hsc should equal to 0.413", () => {
-            checkResult(sect.Calc("Hsc"), 0.413);
+            checkResult(sect.CalcSection("Hsc"), 0.413);
         });
 
         // largeur au miroir
         it("B should equal to 3.62", () => {
-            checkResult(sect.Calc("B"), 3.62);
+            checkResult(sect.CalcSection("B"), 3.62);
         });
 
         // périmètre mouillé
         it("P should equal to 6.792", () => {
-            checkResult(sect.Calc("P"), 6.792);
+            checkResult(sect.CalcSection("P"), 6.792);
         });
 
         // surface mouillée
         it("S should equal to 6.68", () => {
-            checkResult(sect.Calc("S"), 6.68);
+            checkResult(sect.CalcSection("S"), 6.68);
         });
 
         // rayon hydraulique
         it("R should equal to 0.983", () => {
-            checkResult(sect.Calc("R"), 0.983);
+            checkResult(sect.CalcSection("R"), 0.983);
         });
 
         // vitesse moyenne
         it("V should equal to 0.18", () => {
-            checkResult(sect.Calc("V"), 0.18);
+            checkResult(sect.CalcSection("V"), 0.18);
         });
 
         // nombre de Froude
         it("Fr should equal to 0.042", () => {
-            checkResult(sect.Calc("Fr"), 0.042);
+            checkResult(sect.CalcSection("Fr"), 0.042);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 0.28", () => {
-            checkResult(sect.Calc("Yc"), 0.28);
+            checkResult(sect.CalcSection("Yc"), 0.28);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 0.587", () => {
-            checkResult(sect.Calc("Yn"), 0.587);
+            checkResult(sect.CalcSection("Yn"), 0.587);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 2", () => {
-            checkResult(sect.Calc("Yf"), 2);
+            checkResult(sect.CalcSection("Yf"), 2);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.077", () => {
-            checkResult(sect.Calc("Yt"), 0.077);
+            checkResult(sect.CalcSection("Yt"), 0.077);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 0.009", () => {
-            checkResult(sect.Calc("Yco"), 0.009);
+            checkResult(sect.CalcSection("Yco"), 0.009);
         });
 
         // perte de charge
         it("J should equal to 0.00002", () => {
             const sect2 = createSection(0.00001);
-            checkResult(sect2.Calc("J"), 0.00002);
+            checkResult(sect2.CalcSection("J"), 0.00002);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to 0.001", () => {
-            checkResult(sect.Calc("I-J"), 0.001);
+            checkResult(sect.CalcSection("I-J"), 0.001);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 63915.169", () => {
-            checkResult(sect.Calc("Imp"), 63915.169);
+            checkResult(sect.CalcSection("Imp"), 63915.169);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 0.199", () => {
-            checkResult(sect.Calc("Tau0"), 0.199);
+            checkResult(sect.CalcSection("Tau0"), 0.199);
         });
     });
 });
diff --git a/spec/section_param/section_param_trapez_torrentiel.spec.ts b/spec/section_param/section_param_trapez_torrentiel.spec.ts
index 63cd7a18f5cc472bb4d768f3be08a14590aad5ec..658f3d800d4d167921c46de3d1e8e674e3a73500 100644
--- a/spec/section_param/section_param_trapez_torrentiel.spec.ts
+++ b/spec/section_param/section_param_trapez_torrentiel.spec.ts
@@ -23,88 +23,88 @@ describe("Section paramétrée trapèze :", () => {
     describe("torrentiel :", () => {
         // charge spécifique
         it("Hs should equal to 1.716", () => {
-            checkResult(sect.Calc("Hs"), 1.716);
+            checkResult(sect.CalcSection("Hs"), 1.716);
         });
 
         // charge critique
         it("Hsc should equal to 1.534", () => {
-            checkResult(sect.Calc("Hsc"), 1.534);
+            checkResult(sect.CalcSection("Hsc"), 1.534);
         });
 
         // largeur au miroir
         it("B should equal to 3.396", () => {
-            checkResult(sect.Calc("B"), 3.396);
+            checkResult(sect.CalcSection("B"), 3.396);
         });
 
         // périmètre mouillé
         it("P should equal to 4.334", () => {
-            checkResult(sect.Calc("P"), 4.334);
+            checkResult(sect.CalcSection("P"), 4.334);
         });
 
         // surface mouillée
         it("S should equal to 2.358", () => {
-            checkResult(sect.Calc("S"), 2.358);
+            checkResult(sect.CalcSection("S"), 2.358);
         });
 
         // rayon hydraulique
         it("R should equal to 0.544", () => {
-            checkResult(sect.Calc("R"), 0.544);
+            checkResult(sect.CalcSection("R"), 0.544);
         });
 
         // vitesse moyenne
         it("V should equal to 4.24", () => {
-            checkResult(sect.Calc("V"), 4.24);
+            checkResult(sect.CalcSection("V"), 4.24);
         });
 
         // nombre de Froude
         it("Fr should equal to 1.625", () => {
-            checkResult(sect.Calc("Fr"), 1.625);
+            checkResult(sect.CalcSection("Fr"), 1.625);
         });
 
         // tirant d'eau critique
         it("Yc should equal to 1.074", () => {
-            checkResult(sect.Calc("Yc"), 1.074);
+            checkResult(sect.CalcSection("Yc"), 1.074);
         });
 
         // tirant d'eau normal
         it("Yn should equal to 2.275", () => {
-            checkResult(sect.Calc("Yn"), 2.275);
+            checkResult(sect.CalcSection("Yn"), 2.275);
         });
 
         // tirant d'eau fluvial
         it("Yf should equal to 1.502", () => {
-            checkResult(sect.Calc("Yf"), 1.502);
+            checkResult(sect.CalcSection("Yf"), 1.502);
         });
 
         // tirant d'eau torrentiel
         it("Yt should equal to 0.8", () => {
-            checkResult(sect.Calc("Yt"), 0.8);
+            checkResult(sect.CalcSection("Yt"), 0.8);
         });
 
         // tirant d'eau conjugué
         it("Yco should equal to 1.398", () => {
-            checkResult(sect.Calc("Yco"), 1.398);
+            checkResult(sect.CalcSection("Yco"), 1.398);
         });
 
         // perte de charge
         it("J should equal to 0.025", () => {
             // paramCnl.v.Prec = 0.00001;
-            checkResult(sect.Calc("J"), 0.025);
+            checkResult(sect.CalcSection("J"), 0.025);
         });
 
         // Variation linéaire de l'énergie spécifique
         it("I-J should equal to -0.024", () => {
-            checkResult(sect.Calc("I-J"), -0.024);
+            checkResult(sect.CalcSection("I-J"), -0.024);
         });
 
         // impulsion hydraulique
         it("Imp should equal to 51187.203", () => {
-            checkResult(sect.Calc("Imp"), 51187.203);
+            checkResult(sect.CalcSection("Imp"), 51187.203);
         });
 
         // force tractrice (contrainte de cisaillement)
         it("Tau0 should equal to 135.020", () => {
-            checkResult(sect.Calc("Tau0"), 135.020);
+            checkResult(sect.CalcSection("Tau0"), 135.020);
         });
     });
 });
diff --git a/spec/session/serialisation.spec.ts b/spec/session/serialisation.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e3a7df1241b01a8850efeebd4040d2aad2a70e90
--- /dev/null
+++ b/spec/session/serialisation.spec.ts
@@ -0,0 +1,194 @@
+import { ParamValueMode, SectionParametree, Session } from "../../src";
+import { ConduiteDistrib, ConduiteDistribParams } from "../../src/cond_distri";
+import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+import { cSnCirc, ParamsSectionCirc } from "../../src/section/section_circulaire";
+import { cSnTrapez, ParamsSectionTrapez } from "../../src/section/section_trapez";
+import { Cloisons } from "../../src/structure/cloisons";
+import { CloisonsParams } from "../../src/structure/cloisons_params";
+import { Dever, DeverParams } from "../../src/structure/dever";
+import { CreateStructure } from "../../src/structure/factory_structure";
+import { LoiDebit } from "../../src/structure/structure_props";
+import {
+    RectangularStructureParams,
+    StructureWeirSubmergedLarinier
+} from "../../src/structure/structure_weir_submerged_larinier";
+
+/**
+ * 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";
+
+function createEnv() {
+    // create complex session
+    const dever: Dever = new Dever(
+        new DeverParams(
+            0,     // rQ Débit total (m3/s)
+            102,   // rZ1 Cote de l'eau amont (m)
+            2,     // rBR Largeur du cours d'eau amont (m)
+            100    // rZR Cote du lit du cours d'eau amont (m)
+        ),
+        false // debug
+    );
+    dever.addChild(CreateStructure(LoiDebit.TriangularTruncWeirFree, dever, false));
+
+    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.addChild(fente);
+
+    const prmsCD = new ConduiteDistribParams(undefined, // 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
+    );
+    const conduite = new ConduiteDistrib(prmsCD);
+
+    const prmsST = new ParamsSectionTrapez(2.5, // largeur de fond
+        0.56, // fruit
+        undefined, // tirant d'eau
+        40, //  Ks=Strickler
+        2,  //  Q=Débit
+        0.001, //  If=pente du fond
+        1, // YB= hauteur de berge
+    );
+    const sect = new cSnTrapez(prmsST);
+    const prem = new CourbeRemousParams(0.15, // Yamont = tirant amont
+        0.803, // Yaval = tirant aval
+        5,  // Long= Longueur du bief
+        5,  // Dx=Pas d'espace
+    );
+    const rem = new CourbeRemous(sect, prem, MethodeResolution.Trapezes);
+
+    const paramSection = new ParamsSectionCirc(2, // diamètre
+        0.8, // tirant d'eau
+        40, //  Ks=Strickler
+        10,  //  Q=Débit
+        0.001, //  If=pente du fond
+        1, // YB= hauteur de berge
+    );
+    const section = new cSnCirc(paramSection);
+    const sp = new SectionParametree(section);
+
+    Session.getInstance().clear();
+    Session.getInstance().registerNub(dever);
+    Session.getInstance().registerNub(cloisons);
+    Session.getInstance().registerNub(conduite);
+    Session.getInstance().registerNub(rem);
+    Session.getInstance().registerNub(sp);
+}
+
+describe("serialising / deserialising session - ", () => {
+
+    it ("serialized file should contain 5 Nubs", () => {
+        createEnv();
+        const session = Session.getInstance().serialise();
+        const js = JSON.parse(session);
+        expect(Object.keys(js)).toContain("session");
+        expect(js.session.length).toBe(5);
+    });
+
+    it ("reloading serialized file should give 5 Nubs", () => {
+        createEnv();
+        const session = Session.getInstance().serialise();
+
+        Session.getInstance().clear();
+        expect(Session.getInstance().getNumberOfNubs()).toBe(0);
+
+        Session.getInstance().unserialise(session);
+        expect(Session.getInstance().getNumberOfNubs()).toBe(5);
+    });
+
+    it("when saving a SectionParametree, the edited values should be present in the file", () => {
+        // d
+        const paramSection = new ParamsSectionCirc(
+            2, // diamètre
+            0.8, // tirant d'eau
+            40, //  Ks=Strickler
+            10,  //  Q=Débit
+            0.001, //  If=pente du fond
+            1, // YB= hauteur de berge
+        );
+        const section = new cSnCirc(paramSection);
+        const sp = new SectionParametree(section);
+        sp.section.prms.Ks.v = 42;
+
+        const serialised = sp.serialise();
+        expect(serialised).toContain('{"symbol":"Ks","mode":"SINGLE","value":42}');
+    });
+
+    it ("loaded serialized RegimeUniforme should be calculable", () => {
+        const fs = require("fs");
+        Session.getInstance().clear();
+        const session = fs.readFileSync(__dirname + "/../../../spec/session/session-RU.json", { encoding: "utf8" });
+        Session.getInstance().unserialise(session);
+
+        expect(Session.getInstance().getNumberOfNubs()).toBe(1);
+
+        const RU = Session.getInstance().findNubByUid("YTEwZG");
+        expect(RU).toBeDefined();
+
+        const calculatedParam = RU.calculatedParam;
+        expect(calculatedParam.symbol).toBe("Q");
+
+        let nbCalc = 0;
+        for (const p of RU.parameterIterator) {
+            if (p.valueMode === ParamValueMode.CALCUL) {
+                nbCalc++;
+            }
+        }
+        expect(nbCalc).toBe(1);
+
+        RU.CalcSerie();
+        expect(RU.result).toBeDefined();
+    });
+
+    it ("loaded serialized Ouvrages should be calculable", () => {
+        const fs = require("fs");
+        Session.getInstance().clear();
+        const session = fs.readFileSync(__dirname + "/../../../spec/session/session-OUV.json", { encoding: "utf8" });
+        Session.getInstance().unserialise(session);
+
+        expect(Session.getInstance().getNumberOfNubs()).toBe(1);
+
+        const OUV = Session.getInstance().findNubByUid("NGVzdz");
+        expect(OUV).toBeDefined();
+
+        const calculatedParam = OUV.calculatedParam;
+        expect(calculatedParam.symbol).toBe("L");
+
+        let nbCalc = 0;
+        for (const p of OUV.parameterIterator) {
+            if (p.valueMode === ParamValueMode.CALCUL) {
+                nbCalc++;
+            }
+        }
+        expect(nbCalc).toBe(1);
+
+        OUV.CalcSerie();
+        expect(OUV.result).toBeDefined();
+        expect(OUV.result.vCalc).toBeCloseTo(1.031);
+    });
+
+});
diff --git a/spec/session/session-OUV.json b/spec/session/session-OUV.json
new file mode 100644
index 0000000000000000000000000000000000000000..52309305cf8f4b1d5775e03e170ab09e94106880
--- /dev/null
+++ b/spec/session/session-OUV.json
@@ -0,0 +1,101 @@
+{
+    "session": [
+        {
+            "uid": "NGVzdz",
+            "props": {
+                "calcType": 8,
+                "nodeType": 0
+            },
+            "meta": {
+                "title": "Ouvrages"
+            },
+            "children": [
+                {
+                    "uid": "Z2F4dz",
+                    "props": {
+                        "calcType": 7,
+                        "nodeType": 5,
+                        "structureType": 1,
+                        "loiDebit": 1
+                    },
+                    "children": [],
+                    "parameters": [
+                        {
+                            "symbol": "ZDV",
+                            "mode": "SINGLE",
+                            "value": 100
+                        },
+                        {
+                            "symbol": "W",
+                            "mode": "SINGLE",
+                            "value": 0.5
+                        },
+                        {
+                            "symbol": "L",
+                            "mode": "SINGLE",
+                            "value": 2
+                        },
+                        {
+                            "symbol": "Cd",
+                            "mode": "SINGLE",
+                            "value": 0.6
+                        }
+                    ]
+                },
+                {
+                    "uid": "ZDR4cX",
+                    "props": {
+                        "calcType": 7,
+                        "nodeType": 5,
+                        "structureType": 1,
+                        "loiDebit": 1
+                    },
+                    "children": [],
+                    "parameters": [
+                        {
+                            "symbol": "ZDV",
+                            "mode": "SINGLE",
+                            "value": 100
+                        },
+                        {
+                            "symbol": "W",
+                            "mode": "SINGLE",
+                            "value": 0.5
+                        },
+                        {
+                            "symbol": "L",
+                            "mode": "CALCUL"
+                        },
+                        {
+                            "symbol": "Cd",
+                            "mode": "SINGLE",
+                            "value": 0.6
+                        }
+                    ]
+                }
+            ],
+            "parameters": [
+                {
+                    "symbol": "Pr",
+                    "mode": "SINGLE",
+                    "value": 0.0001
+                },
+                {
+                    "symbol": "Q",
+                    "mode": "SINGLE",
+                    "value": 3.5
+                },
+                {
+                    "symbol": "Z1",
+                    "mode": "SINGLE",
+                    "value": 102
+                },
+                {
+                    "symbol": "Z2",
+                    "mode": "SINGLE",
+                    "value": 101.5
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/spec/session/session-RU.json b/spec/session/session-RU.json
new file mode 100644
index 0000000000000000000000000000000000000000..8f2c6f3d7a7a95b4bd08db79a96b10325498d6be
--- /dev/null
+++ b/spec/session/session-RU.json
@@ -0,0 +1 @@
+{"session":[{"uid":"YTEwZG","props":{"calcType":3,"nodeType":2},"meta":{"title":"R. uniforme"},"children":[{"uid":"NDcxN3","props":{"calcType":14,"nodeType":2},"children":[],"parameters":[{"symbol":"Pr","mode":"SINGLE","value":0.0001},{"symbol":"Ks","mode":"SINGLE","value":40},{"symbol":"Q","mode":"CALCUL"},{"symbol":"If","mode":"SINGLE","value":0.001},{"symbol":"YB","mode":"SINGLE","value":1},{"symbol":"Y","mode":"SINGLE","value":0.89},{"symbol":"LargeurBerge","mode":"SINGLE","value":2.5}]}],"parameters":[{"symbol":"Pr","mode":"SINGLE","value":0.0001}]}]}
\ No newline at end of file
diff --git a/spec/structure/cloisons.spec.ts b/spec/structure/cloisons.spec.ts
index 1b62e13e611591fc20b3191f0e048bf1de909909..9e52d240ce214aa388913fde50ff506922e47f1c 100644
--- a/spec/structure/cloisons.spec.ts
+++ b/spec/structure/cloisons.spec.ts
@@ -6,10 +6,11 @@
  */
 // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
 
-import { Cloisons, CloisonsParams } from "../../src/structure/cloisons";
+import { Cloisons } from "../../src/structure/cloisons";
+import { CloisonsParams } from "../../src/structure/cloisons_params";
 import { CreateStructure } from "../../src/structure/factory_structure";
 import { StructureKiviParams } from "../../src/structure/structure_kivi";
-import { LoiDebit, StructureType } from "../../src/structure/structure_props";
+import { LoiDebit } 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";
@@ -37,7 +38,7 @@ const fente: StructureWeirSubmergedLarinier = new StructureWeirSubmergedLarinier
     )
 );
 
-cloisons.addStructure(fente);
+cloisons.addChild(fente);
 
 describe("Class Cloisons: ", () => {
     describe("Calc(Q) Fente noyée (Larinier 1992)", () => {
@@ -62,23 +63,18 @@ describe("Class Cloisons: ", () => {
     );
 
     // 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], c2, false));
+        c2.addChild(CreateStructure(iLoiDebits[i], c2, false));
     }
     const prmsKivi: StructureKiviParams = c2.structures[2].prms as StructureKiviParams;
     prmsKivi.ZRAM.v = 0;
 
-    testParallelStructures(c2, iStTypes, iLoiDebits);
+    testParallelStructures(c2, iLoiDebits);
 
     describe("Calcul de ZRAM de l'équation KIVI", () => {
         it("ZRAM should be 101", () => {
diff --git a/spec/structure/dever.spec.ts b/spec/structure/dever.spec.ts
index 2a1f0bbea52ef72202350440595ab4bd1afabd12..f2bdecaff4ad6365f17cb9040872ebaa17be3c98 100644
--- a/spec/structure/dever.spec.ts
+++ b/spec/structure/dever.spec.ts
@@ -8,7 +8,7 @@
 
 import { Dever, DeverParams } from "../../src/structure/dever";
 import { CreateStructure } from "../../src/structure/factory_structure";
-import { LoiDebit, StructureType } from "../../src/structure/structure_props";
+import { LoiDebit } from "../../src/structure/structure_props";
 
 const dever: Dever = new Dever(
     new DeverParams(
@@ -20,8 +20,7 @@ const dever: Dever = new Dever(
     false // debug
 );
 
-dever.addStructure(CreateStructure(StructureType.SeuilTriangulaireTrunc,
-    LoiDebit.TriangularTruncWeirFree, dever, false));
+dever.addChild(CreateStructure(LoiDebit.TriangularTruncWeirFree, dever, false));
 
 describe("Class Dever: ", () => {
     describe("Calc(Q) Seuil Triangulaire Trunc", () => {
diff --git a/spec/structure/functions.ts b/spec/structure/functions.ts
index 6ba3666da0356f2c402725871dc06431756a3306..65863fbd5f7be392c62905cf5dd0a7b8607eb854 100644
--- a/spec/structure/functions.ts
+++ b/spec/structure/functions.ts
@@ -9,7 +9,7 @@ import { MessageCode } from "../../src/index";
 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 { loiAdmissiblesOuvrages, LoiDebit } from "../../src/structure/structure_props";
 import { Result } from "../../src/util/result";
 import { precDigits } from "../test_config";
 import { checkResult } from "../test_func";
@@ -92,12 +92,12 @@ export function testStructure(
  * @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[]) {
+export function testParallelStructures(oPS: ParallelStructure, 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]]}: `, () => {
+        describe(`this.structures[${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(
@@ -125,7 +125,7 @@ export function testParallelStructures(oPS: ParallelStructure, iStTypes: number[
                             ).toThrow(new Error("Structure:Calc : Calcul de W impossible sur un seuil"));
                         });
                     } else if (
-                        iStTypes[i] === StructureType.VanneRectangulaire &&
+                        loiAdmissiblesOuvrages.VanneRectangulaire.includes(iLoiDebits[i]) &&
                         !oPS.structures[i].isZDVcalculable &&
                         prm.symbol === "ZDV"
                     ) {
diff --git a/spec/structure/parallel_structure.spec.ts b/spec/structure/parallel_structure.spec.ts
index 4c871f409295d5842d7978a647145e3df6510180..a473e54cfed2ff39ac5cba2a01c7b619ffe90a7e 100644
--- a/spec/structure/parallel_structure.spec.ts
+++ b/spec/structure/parallel_structure.spec.ts
@@ -27,8 +27,8 @@ const pstruct: ParallelStructure = new ParallelStructure(
  * Tests avec deux structures test identiques
  */
 
-pstruct.addStructure(structTest);
-pstruct.addStructure(structTest);
+pstruct.addChild(structTest);
+pstruct.addChild(structTest);
 
 describe("Class ParallelStructure: ", () => {
     describe("Calc()", () => {
@@ -104,10 +104,10 @@ describe("Class ParallelStructure: ", () => {
     const iStTypes: number[] = [];
     for (const s of EnumEx.getValues(StructureType)) {
         for (const la of loiAdmissiblesOuvrages[StructureType[s]]) {
-            ps2.addStructure(CreateStructure(s, la, ps2, false));
+            ps2.addChild(CreateStructure(la, ps2, false));
             iLoiDebits.push(la);
             iStTypes.push(s);
         }
     }
-    testParallelStructures(ps2, iStTypes, iLoiDebits);
+    testParallelStructures(ps2, iLoiDebits);
 });
diff --git a/spec/test_func.ts b/spec/test_func.ts
index 3fea98947ee6783e1f9d06a11297bf03c78f48bd..bb980480d5cf1fd77f6de2a9c1531285b49fd747 100644
--- a/spec/test_func.ts
+++ b/spec/test_func.ts
@@ -3,7 +3,7 @@
  * décommenter la ligne suivante (import { expect } from "./mock_jasmine") dans le cas d'une fonction
  * qui utilise la fonction expect() de Jasmine mais qui doit être exécutée en dehors de tests Jasmine
  */
-// import { expect } from "./mock_jasmine";
+import { expect } from "./mock_jasmine";
 
 import { cLog } from "../src/util/log";
 import { Message, MessageCode } from "../src/util/message";
diff --git a/spec/value_ref/value_ref_indirect.spec.ts b/spec/value_ref/value_ref_indirect.spec.ts
index bd7296fd5f35942eff7300437fa24ad7168c5dc6..4df7e9abcda2fb2f2f6ed74f0b6ab8e04f098d68 100644
--- a/spec/value_ref/value_ref_indirect.spec.ts
+++ b/spec/value_ref/value_ref_indirect.spec.ts
@@ -1,5 +1,5 @@
 import { CreateStructure, cSnCirc, cSnTrapez, LoiDebit, ParamsSectionCirc,
-         ParamsSectionTrapez, Session, StructureType } from "../../src/index";
+         ParamsSectionTrapez, Session } from "../../src";
 import { PabDimension, PabDimensionParams } from "../../src/pab/pab_dimension";
 import { RegimeUniforme } from "../../src/regime_uniforme";
 import { SectionParametree } from "../../src/section/section_parametree";
@@ -32,13 +32,13 @@ function createEnv() {
     paramSect.Pr.v = 0.01;
     const sect = new cSnCirc(paramSect);
     nub1 = new RegimeUniforme(sect);
-    prm1 = nub1.prms as ParamsSectionCirc;
+    prm1 = nub1.section.prms as ParamsSectionCirc;
 
     // Nub 2 : Section Paramétrée
     const prmsS = new ParamsSectionTrapez(1, 0.5, 1, 0.01, 1, 0.01, 2);
     prmsS.Pr.v = 0.01;
     nub2 = new SectionParametree(new cSnTrapez(prmsS));
-    prm2 = nub2.prms as ParamsSectionTrapez;
+    prm2 = nub2.section.prms as ParamsSectionTrapez; // = prmsS
 
     // Nub 3 : Passe à Bassins : Dimensions
     prm3 = new PabDimensionParams(2, 1, 0.5, 2);
@@ -48,9 +48,8 @@ function createEnv() {
     prm4 = new DeverParams(0.5, 102, 10, 99);
     prm4.Pr.v = 0.01;
     nub4 = new Dever(prm4);
-    nub4.addStructure(
+    nub4.addChild(
         CreateStructure(
-            StructureType.SeuilRectangulaire,
             LoiDebit.WeirFree,
             nub4,
             false
@@ -74,8 +73,8 @@ describe("référence indirecte d'un paramètre à un autre : ", () => {
         createEnv();
 
         prm3.Y.v = 0.1;  // valeur esclave, doit être masquée par la valeur maître (cad prm1.Y)
-        prm3.Y.defineReference(nub2, "Y");
-        prm2.Y.defineReference(nub1, "Y");
+        prm3.Y.defineReference(nub2.section, "Y");
+        prm2.Y.defineReference(nub1.section, "Y");
 
         nub3.CalcSerie();
 
@@ -90,8 +89,8 @@ describe("référence indirecte d'un paramètre à un autre : ", () => {
         createEnv();
 
         prm3.Y.v = 0.1;  // valeur esclave, doit être masquée par la valeur maître (cad prm1.Y)
-        prm3.Y.defineReference(nub2, "Y");
-        prm2.Y.defineReference(nub1, "Y");
+        prm3.Y.defineReference(nub2.section, "Y");
+        prm2.Y.defineReference(nub1.section, "Y");
         prm1.Y.setValues(2, 5, 1);
 
         nub3.CalcSerie();
@@ -107,8 +106,8 @@ describe("référence indirecte d'un paramètre à un autre : ", () => {
         createEnv();
 
         prm3.Y.v = 0.1;  // valeur esclave, doit être masquée par la valeur maître (cad prm1.Y)
-        prm3.Y.defineReference(nub2, "Y");
-        prm2.Y.defineReference(nub1, "Y");
+        prm3.Y.defineReference(nub2.section, "Y");
+        prm2.Y.defineReference(nub1.section, "Y");
 
         prm1.LargeurBerge.v = 3.5; // Section Circ !
         prm1.Ks.v = 42;
@@ -127,8 +126,8 @@ describe("référence indirecte d'un paramètre à un autre : ", () => {
         createEnv();
 
         prm3.Y.v = 0.1;  // valeur esclave, doit être masquée par la valeur maître (cad prm1.Y)
-        prm3.Y.defineReference(nub2, "Y");
-        prm2.Y.defineReference(nub1, "Y");
+        prm3.Y.defineReference(nub2.section, "Y");
+        prm2.Y.defineReference(nub1.section, "Y");
 
         prm1.D.setValues(2.5, 7, 0.5);
         prm1.Ks.v = 42;
@@ -156,7 +155,7 @@ describe("référence indirecte d'un paramètre à un autre : ", () => {
         createEnv();
 
         prm1.Q.v = 0.1;  // valeur esclave, doit être masquée par la valeur maître (cad prm4.Q)
-        prm1.Q.defineReference(nub2, "Q");
+        prm1.Q.defineReference(nub2.section, "Q");
         nub1.calculatedParam = prm1.Ks;
         prm2.Q.defineReference(nub4, "CvQT");
 
@@ -175,7 +174,7 @@ describe("référence indirecte d'un paramètre à un autre : ", () => {
         createEnv();
 
         prm1.Q.v = 0.1;  // valeur esclave, doit être masquée par la valeur maître (cad prm4.Q)
-        prm1.Q.defineReference(nub2, "Q");
+        prm1.Q.defineReference(nub2.section, "Q");
         nub1.calculatedParam = prm1.Ks;
         prm2.Q.defineReference(nub4, "CvQT");
 
diff --git a/spec/value_ref/value_ref_section.spec.ts b/spec/value_ref/value_ref_section.spec.ts
index 995d00f5259212b239ceef735541851b0d2c8d65..8a9c89d31944bd18096e5db7030c93ec758ef8ff 100644
--- a/spec/value_ref/value_ref_section.spec.ts
+++ b/spec/value_ref/value_ref_section.spec.ts
@@ -1,4 +1,4 @@
-import { CreateStructure, cSnTrapez, LoiDebit, ParamsSectionTrapez, StructureType, Session } from "../../src/index";
+import { CreateStructure, cSnTrapez, LoiDebit, ParamsSectionTrapez, Session } from "../../src";
 import { SectionParametree } from "../../src/section/section_parametree";
 import { Dever, DeverParams } from "../../src/structure/dever";
 
@@ -23,9 +23,8 @@ function createEnv() {
     const prms1 = new DeverParams(0.5, 102, 10, 99);
     prms1.Pr.v = 0.01;
     nub1 = new Dever(prms1);
-    nub1.addStructure(
+    nub1.addChild(
         CreateStructure(
-            StructureType.SeuilRectangulaire,
             LoiDebit.WeirFree,
             nub1,
             false
@@ -36,7 +35,7 @@ function createEnv() {
     const prmsS = new ParamsSectionTrapez(1, 0.5, 1, 0.01, 1, 0.01, 2);
     prmsS.Pr.v = 0.01;
     nub2 = new SectionParametree(new cSnTrapez(prmsS));
-    prm2 = nub2.prms as ParamsSectionTrapez;
+    prm2 = nub2.section.prms as ParamsSectionTrapez;
 
     Session.getInstance().clear();
     Session.getInstance().registerNub(nub1);
diff --git a/spec/value_ref/value_ref_type_section.spec.ts b/spec/value_ref/value_ref_type_section.spec.ts
index 935bdf2ef0abb83fe96caf34b8a9016be0d0a91f..069626084c4b91a629f3d810c44bfe3e5f5226e1 100644
--- a/spec/value_ref/value_ref_type_section.spec.ts
+++ b/spec/value_ref/value_ref_type_section.spec.ts
@@ -1,5 +1,5 @@
 import { CreateStructure, cSnCirc, LinkedValue, LoiDebit, ParallelStructure, ParallelStructureParams,
-         ParamsSectionCirc, Session, StructureType } from "../../src/index";
+         ParamsSectionCirc, Session } from "../../src";
 import { RegimeUniforme } from "../../src/regime_uniforme";
 import { RectangularStructureParams } from "../../src/structure/structure_cem88d";
 
@@ -32,16 +32,14 @@ function createEnv() {
     prm2 = new ParallelStructureParams(0.5, 102, 101.5);
     prm2.Pr.v = 0.01;
     nub2 = new ParallelStructure(prm2);
-    nub2.addStructure(
+    nub2.addChild(
         CreateStructure(
-            StructureType.VanneRectangulaire,
             LoiDebit.Cunge80,
             nub2
         )
     );
-    nub2.addStructure(
+    nub2.addChild(
         CreateStructure(
-            StructureType.SeuilTriangulaire,
             LoiDebit.TriangularWeirFree,
             nub2
         )
diff --git a/spec/value_ref/value_ref_variable_extraresult.spec.ts b/spec/value_ref/value_ref_variable_extraresult.spec.ts
index eb6cec1b10a7d022cb039e966ea8ab84255bfaca..9ddb5aeaf32856dc70486bd70dd8c0fcb1b8c097 100644
--- a/spec/value_ref/value_ref_variable_extraresult.spec.ts
+++ b/spec/value_ref/value_ref_variable_extraresult.spec.ts
@@ -1,5 +1,5 @@
 // tslint:disable-next-line:max-line-length
-import { CreateStructure, cSnCirc, LoiDebit, ParamsSectionCirc, StructureType, Session } from "../../src/index";
+import { CreateStructure, cSnCirc, LoiDebit, ParamsSectionCirc, Session } from "../../src";
 import { RegimeUniforme } from "../../src/regime_uniforme";
 import { Dever, DeverParams } from "../../src/structure/dever";
 
@@ -20,9 +20,8 @@ describe("référence d'un paramètre à un résultat complémentaire multivalu
         const prms1 = new DeverParams(0.5, 102, 10, 99);
         prms1.Pr.v = 0.01;
         const nub1 = new Dever(prms1);
-        nub1.addStructure(
+        nub1.addChild(
             CreateStructure(
-                StructureType.SeuilRectangulaire,
                 LoiDebit.WeirFree,
                 nub1,
                 false
@@ -50,7 +49,7 @@ describe("référence d'un paramètre à un résultat complémentaire multivalu
 
         // link and calc
         nub2.calculatedParam = paramSect.Ks;
-        nub2.prms.Q.defineReference(nub1, "CvQT");
+        nub2.section.prms.Q.defineReference(nub1, "CvQT");
         nub2.CalcSerie();
 
         const refVals = [ 113.534, 321.398, 590.624, 909.467, 1271.138,
diff --git a/src/compute-node.ts b/src/compute-node.ts
index 62c0fb85e8dd5e76b022e144a828facac5755c79..93b34ea7160a4055098335d253f5680507276a32 100644
--- a/src/compute-node.ts
+++ b/src/compute-node.ts
@@ -20,7 +20,8 @@ export enum CalculatorType {
     Cloisons,            // Outil Cassiopée PAB Cloisons
     MacroRugo,       // Passe à enrochement simple (Cassan et al., 2016)
     PabChute,
-    PabNombre
+    PabNombre,
+    Section
 }
 
 /**
@@ -49,6 +50,8 @@ export abstract class ComputeNode extends JalhydObject implements IDebug {
      */
     protected _extraResultsFamilies: any;
 
+    protected _calcType: CalculatorType;
+
     private _debug: Debug;
 
     constructor(prms: ParamsEquation, dbg: boolean = false) {
@@ -98,6 +101,9 @@ export abstract class ComputeNode extends JalhydObject implements IDebug {
         return undefined;
     }
 
+    /**
+     * Returns an iterator over own parameters (this._prms)
+     */
     public get parameterIterator(): IParamDefinitionIterator {
         return this._prms.iterator;
     }
diff --git a/src/cond_distri.ts b/src/cond_distri.ts
index 0fd13ae6246ee81a03a667ed9a66592ac9cca5a4..9e19897295edb7ce3a41c7363c434e6e299393e7 100644
--- a/src/cond_distri.ts
+++ b/src/cond_distri.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "./compute-node";
 import { Nub } from "./nub";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "./param/param-definition";
 import { ParamDomainValue } from "./param/param-domain";
@@ -49,6 +50,7 @@ export class ConduiteDistrib extends Nub {
 
     constructor(prms: ConduiteDistribParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._calcType = CalculatorType.ConduiteDistributrice;
     }
 
     /**
diff --git a/src/index.ts b/src/index.ts
index 403096993d54d6829bcf371bddf48cfbef4a5b56..a8b1bd974fd57751fccf86d6025d60213bf867b7 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -33,3 +33,4 @@ export * from "./structure/structure_props";
 export * from "./linked-value";
 export * from "./jalhyd_object";
 export * from "./date_revision";
+export * from "./section/section_nub";
diff --git a/src/lechaptcalmon.ts b/src/lechaptcalmon.ts
index fba3f127b0f97962f14da3e43a7ab0bf0ad14467..a36f474b32a3aba977bb956019ad20df1dd93184 100644
--- a/src/lechaptcalmon.ts
+++ b/src/lechaptcalmon.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "./compute-node";
 import { Nub } from "./nub";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "./param/param-definition";
 import { ParamDomainValue } from "./param/param-domain";
@@ -84,6 +85,7 @@ export class LechaptCalmonParams extends ParamsEquation {
 export class LechaptCalmon extends Nub {
     constructor(prms: LechaptCalmonParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._calcType = CalculatorType.LechaptCalmon;
     }
 
     /**
diff --git a/src/linked-value.ts b/src/linked-value.ts
index 4cc05e11d192a4b36b3ffcf0c0821f0f554dfc95..9d6d66019d498c4d31e73deb2f1ca7d452ac37bf 100644
--- a/src/linked-value.ts
+++ b/src/linked-value.ts
@@ -211,7 +211,7 @@ export class LinkedValue {
      * - a result / extra result is targetted and it has more than 1 value
      */
     public hasMultipleValues(): boolean {
-        if (this.isParameter()) {
+        if (this.isParameter()) { // possibly in CALC mode, but ParamDefinition.hasMultipleValues takes care of it
             return (this.element as ParamDefinition).hasMultipleValues;
         } else if (this.isResult() || this.isExtraResult()) {
             // guess if parent Nub has any variating parameter (linked or not)
diff --git a/src/macrorugo/macrorugo.ts b/src/macrorugo/macrorugo.ts
index f2cdd0252ca2adf5fd1aaeb51e73618fde6ce0a3..e06bf61afef21a7133af3396613cfb2f46bfda97 100644
--- a/src/macrorugo/macrorugo.ts
+++ b/src/macrorugo/macrorugo.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "../compute-node";
 import { Nub } from "../nub";
 import { ParamCalculability, ParamFamily } from "../param/param-definition";
 import { ParamValueMode } from "../param/param-value-mode";
@@ -43,6 +44,7 @@ export class MacroRugo extends Nub {
     constructor(prms: MacrorugoParams, dbg: boolean = false) {
         super(prms, dbg);
         this._cache = {};
+        this._calcType = CalculatorType.MacroRugo;
     }
 
     /**
diff --git a/src/nub.ts b/src/nub.ts
index 8906f89a508ecd059dfe2691954e33b59540665e..24294817702279f4f4cd642542e0b480056d2405 100644
--- a/src/nub.ts
+++ b/src/nub.ts
@@ -1,6 +1,7 @@
-import { ParamDefinition, ParamsEquation, Session, Structure } from "./index";
-import { ComputeNode } from "./compute-node";
+import { CalculatorType, ComputeNode } from "./compute-node"; // nghyd build fails when commenting CalculatorType @WTF
 import { Dichotomie } from "./dichotomie";
+import { acSection, IParamDefinitionIterator, ParamDefinition, ParamsEquation, ParamsEquationArrayIterator,
+         Session, Structure } from "./index";
 import { LinkedValue } from "./linked-value";
 import { ParamCalculability } from "./param/param-definition";
 import { ParamValueMode } from "./param/param-value-mode";
@@ -20,6 +21,9 @@ export abstract class Nub extends ComputeNode implements IObservable {
     /** paramétrage de la dichotomie */
     public dichoStartIntervalMaxSteps: number = 100;
 
+    /** pointer to parent Nub */
+    public parent: Nub;
+
     /** parameter that is to be computed by default - to be overloaded by child classes */
     protected _defaultCalculatedParam: ParamDefinition;
 
@@ -29,7 +33,15 @@ export abstract class Nub extends ComputeNode implements IObservable {
     /** résultat de Calc()/CalcSerie() */
     protected _result: Result;
 
-    private _props: Props = new Props();
+    /**
+     * List of children Nubs; browsed by parameters iterator.
+     *  - for ParallelStructures: contains 0 or more Structures
+     *  - for SectionNub : contains exactly 1 acSection
+     */
+    protected _children: Nub[];
+
+    /** properties describing the Nub type */
+    protected _props: Props = new Props();
 
     /** implémentation par délégation de IObservable */
     private _observable: Observable;
@@ -39,6 +51,7 @@ export abstract class Nub extends ComputeNode implements IObservable {
 
     public constructor(prms: ParamsEquation, dbg: boolean = false) {
         super(prms, dbg);
+        this._children = [];
         this._observable = new Observable();
         this._defaultCalculatedParam = this.getFirstAnalyticalParameter();
         this.resetDefaultCalculatedParam();
@@ -50,6 +63,8 @@ export abstract class Nub extends ComputeNode implements IObservable {
 
     /** Returns Props object (observable set of key-values) associated to this Nub */
     public get properties(): Props {
+        // completes props with calcType if not already set
+        this._props.setPropValue("calcType", this.calcType);
         return this._props;
     }
 
@@ -57,6 +72,22 @@ export abstract class Nub extends ComputeNode implements IObservable {
         this._props = props.clone();
     }
 
+    /**
+     * Returns an iterator over :
+     *  - own parameters (this._prms)
+     *  - children parameters (this._children[*]._prms)
+     */
+    public get parameterIterator(): IParamDefinitionIterator {
+        const prms: ParamsEquation[] = [];
+        prms.push(this._prms);
+        if (this._children) { // if called within constructor, default class member value is not set yet
+            for (const child of this._children) {
+                prms.push(child.prms);
+            }
+        }
+        return new ParamsEquationArrayIterator(prms);
+    }
+
     protected get progress() {
         return this._progress;
     }
@@ -69,9 +100,8 @@ export abstract class Nub extends ComputeNode implements IObservable {
         this.notifyProgressUpdated();
     }
 
-    /** Rapid accessor for calculator type */
     public get calcType() {
-        return this._props.getPropValue("calcType");
+        return this._calcType;
     }
 
     public get calculatedParam(): ParamDefinition {
@@ -115,7 +145,7 @@ export abstract class Nub extends ComputeNode implements IObservable {
                 requirer === this._defaultCalculatedParam
                 || this._defaultCalculatedParam.valueMode !== ParamValueMode.SINGLE
             ) {
-                // first SINGLE parameter if any
+                // first SINGLE calculable parameter if any
                 const newCalculatedParam = this.findFirstSingleParameter(requirer);
                 if (newCalculatedParam) {
                     this.calculatedParam = newCalculatedParam;
@@ -139,7 +169,7 @@ export abstract class Nub extends ComputeNode implements IObservable {
     public findFirstSingleParameter(otherThan?: ParamDefinition) {
         for (const p of this.parameterIterator) {
             if (
-                p.calculability !== ParamCalculability.NONE
+                [ ParamCalculability.EQUATION, ParamCalculability.DICHO ].includes(p.calculability)
                 && p.symbol !== "Pr"
                 && p.visible
                 && p !== otherThan
@@ -371,14 +401,24 @@ export abstract class Nub extends ComputeNode implements IObservable {
         return p.v;
     }
 
-    // generic methods to ease iteration
+    public addChild(child: Nub, after?: number) {
+        if (after !== undefined) {
+            this._children.splice(after + 1, 0, child);
+        } else {
+            this._children.push(child);
+        }
+        // add reference to parent collection (this)
+        child.parent = this;
+        // propagate precision
+        child.prms.Pr.setValue(this.prms.Pr.v); // does not write to .v to bypass calculability control
+    }
 
     public getChildren(): Nub[] {
-        return [];
+        return this._children;
     }
 
     public getParent(): Nub {
-        return undefined;
+        return this.parent;
     }
 
     /**
@@ -406,7 +446,7 @@ export abstract class Nub extends ComputeNode implements IObservable {
         // Different Structures in the same parent can get linked to each other.
         if (! this.isParentOrChildOf(src.nubUid)) {
 
-            // 1. parameters
+            // 1. own parameters
             for (const p of this._prms) {
                 // if symbol and Nub type are identical, or if family is identical
                 if (
@@ -415,12 +455,16 @@ export abstract class Nub extends ComputeNode implements IObservable {
                 ) {
                     // if it is safe to link p's value to src
                     if (p.isLinkableTo(src)) {
-                        // if p is a CALC param of a Structure, other than "Q", expose its parent
+                        // if p is a CALC param of a Structure other than "Q"
                         // (structures always have Q as CALC param and cannot have another)
+                        // or a CALC param of a Section,
+                        // expose its parent
                         if (
-                            (this instanceof Structure)
+                            (
+                              (this instanceof Structure && p.symbol !== "Q")
+                              || this instanceof acSection
+                            )
                             && (p.valueMode === ParamValueMode.CALCUL)
-                            && p.symbol !== "Q"
                         ) {
                             // trick to expose p a a result of the parent Nub
                             res.push(new LinkedValue(this.parent, p, p.symbol));
@@ -640,7 +684,7 @@ export abstract class Nub extends ComputeNode implements IObservable {
      * linked or not, is variated
      */
     public resultHasMultipleValues(): boolean {
-        for (const p of this._prms) {
+        for (const p of this.parameterIterator) {
             if (p.valueMode === ParamValueMode.MINMAX || p.valueMode === ParamValueMode.LISTE) {
                 return true;
             } else if (p.valueMode === ParamValueMode.LINK && p.isReferenceDefined()) {
@@ -700,30 +744,38 @@ export abstract class Nub extends ComputeNode implements IObservable {
     public objectRepresentation(extra?: object) {
         let ret: any = {
             uid: this.uid,
-            props: this.getPropertiesData(),
+            props: this.properties.props,
         };
 
         if (extra) {
             ret =  {...ret, ...{ meta: extra } }; // merge properties
         }
-        ret = {...ret, ...{ parameters: [] } }; // extend here to make "parameters" the down-most key
+        ret = {...ret, ...{  children: [], parameters: [] } }; // extend here to make "parameters" the down-most key
 
-        // iterate over parameters
-        for (const p of this.parameterIterator) {
+        // iterate over local parameters
+        const localParametersIterator =  new ParamsEquationArrayIterator([this._prms]);
+        for (const p of localParametersIterator) {
             if (p.visible) {
                 ret.parameters.push(p.objectRepresentation());
             }
         }
 
+        // iterate over children Nubs
+        for (const child of this._children) {
+            ret.children.push(child.objectRepresentation());
+        }
+
         return ret;
     }
 
     /**
      * Fills the current Nub with parameter values, provided an object representation
      * @param obj object representation of a Nub content (parameters)
+     * @returns the calculated parameter found, if any - used by child Nub to notify
+     *          its parent of the calculated parameter to set
      */
-    public loadObjectRepresentation(obj: any) {
-        let calculatedParam;
+    public loadObjectRepresentation(obj: any): ParamDefinition {
+        let calculatedParam: ParamDefinition;
         // set parameter modes and values
         if (obj.parameters && Array.isArray(obj.parameters)) {
             for (const p of obj.parameters) {
@@ -731,48 +783,39 @@ export abstract class Nub extends ComputeNode implements IObservable {
                 if (! param) {
                     throw new Error(`session file : cannot find parameter ${p.symbol} in target Nub`);
                 }
-                // set mode
-                const mode: ParamValueMode = (ParamValueMode as any)[p.mode]; // get enum index for string value
-                param.valueMode = mode;
-                // set value(s)
-                switch (mode) {
-                    case ParamValueMode.SINGLE:
-                        param.singleValue = p.value;
-                        break;
-
-                    case ParamValueMode.MINMAX:
-                        param.min = p.min;
-                        param.max = p.max;
-                        param.step = p.step;
-                        break;
-
-                    case ParamValueMode.LISTE:
-                        param.valueList = p.values;
-                        break;
-
-                    case ParamValueMode.CALCUL:
-                        // although calculated param is set at Nub level (see below),
-                        // it is detected as "the only parameter in CALC mode"
-                        calculatedParam = param;
-                        break;
-
-                    case ParamValueMode.LINK:
-                        // formulaire dont le Nub est la cible du lien
-                        const destNub = Session.getInstance().findNubByUid(p.targetNub);
-                        if (destNub) {
-                            param.defineReference(destNub, p.targetParam);
-                        } // si la cible du lien n'existe pas, Session.fixLinks() est censé s'en occuper
-                        break;
-
-                    default:
-                        throw new Error(`session file : invalid value mode '${p.valueMode}' in param object`);
+                // load parameter
+                const iscalculated = param.loadObjectRepresentation(p, false);
+                if (iscalculated) {
+                    calculatedParam = param;
                 }
             }
             // define calculated param at Nub level
+            // @TODO except if we are a Section or Structure ?
             if (calculatedParam) {
                 this.calculatedParam = calculatedParam;
             }
         }
+
+        // iterate over children if any
+        if (obj.children && Array.isArray(obj.children)) {
+            for (const s of obj.children) {
+                // create the Nub
+                const subNub = Session.getInstance().createNub(new Props(s.props), this);
+                // try to keep the original ID
+                if (! Session.getInstance().uidAlreadyUsed(s.uid)) {
+                    subNub.setUid(s.uid);
+                }
+                const childCalculatedParam = subNub.loadObjectRepresentation(s);
+                // add Structure to parent
+                this.addChild(subNub as Structure);
+                // set calculated parameter for child ?
+                if (childCalculatedParam) {
+                    this.calculatedParam = childCalculatedParam;
+                }
+            }
+        }
+
+        return calculatedParam;
     }
 
     /**
@@ -798,15 +841,157 @@ export abstract class Nub extends ComputeNode implements IObservable {
         }
     }
 
-    // overloaded by ParallelStructure
-    public hasStructureUid(uid: string): boolean {
-        return false;
+    /**
+     * Replaces a child Nub
+     * @param index index of child in _children array
+     * @param child new child
+     * @param resetCalcParam if true, resets default calculated parameter after replacing child
+     * @param keepParametersState if true, mode and value of parameters will be kept between old and new section
+     */
+    public replaceChild(index: number, child: Nub, resetCalcParam: boolean = false,
+                        keepParametersState: boolean = true
+    ) {
+        if (index > -1 && index < this._children.length) {
+            const hasOldChild = (this._children[index] !== undefined);
+            const parametersState: any = {};
+
+            // store old parameters state
+            if (keepParametersState && hasOldChild) {
+                for (const p of this._children[index].parameterIterator) {
+                    parametersState[p.symbol] = p.objectRepresentation();
+                }
+            }
+
+            // replace child
+            this._children[index] = child;
+
+            // reapply parameters state
+            if (keepParametersState && hasOldChild) {
+                for (const p of this._children[index].parameterIterator) {
+                    if (p.symbol in parametersState) {
+                        p.loadObjectRepresentation(parametersState[p.symbol]);
+                    }
+                }
+            }
+        } else {
+            throw new Error(`${this.constructor.name}.replaceChild invalid index ${index}`
+                          + ` (children length: ${this._children.length})`);
+        }
+        if (resetCalcParam) {
+            this.resetDefaultCalculatedParam();
+        }
+        // add reference to parent collection (this)
+        child.parent = this;
+    }
+
+    /**
+     * Finds oldChild in the list, and replaces it at the same index with newChild;
+     * if the current calculated parameter belonged to the old child, resets a default one
+     * @param oldChild child to get the index for
+     * @param newChild child to set at this index
+     */
+    public replaceChildInplace(oldChild: Nub, newChild: Nub) {
+        const calcParamLost = (
+            typeof this.calculatedParamDescriptor !== "string"
+            && this.calculatedParamDescriptor.uid === oldChild.uid
+        );
+        const index = this.getIndexForChild(oldChild);
+        if (index === -1) {
+            throw new Error("old child not found");
+        }
+        this.replaceChild(index, newChild, calcParamLost);
     }
-    // overloaded by ParallelStructure
-    public hasStructure(structure: Nub): boolean {
+
+    /**
+     * Returns the current index of the given child if any,
+     * or else returns -1
+     * @param child child or child UID to look for
+     */
+    public getIndexForChild(child: Nub | string): number {
+        let index: number = -1;
+        const uid = (child instanceof Nub) ? child.uid : child;
+        for (let i = 0; i < this._children.length; i++) {
+            if (this._children[i].uid === uid) {
+                index = i;
+            }
+        }
+        return index;
+    }
+
+    /**
+     * @return true if given Nub id a child of current Nub
+     */
+    public hasChild(child: Nub): boolean {
+        return this.hasChildUid(child.uid);
+    }
+
+    /**
+     * @return true if given Nub uid id a child of current Nub
+     */
+    public hasChildUid(childUid: string): boolean {
+        for (const s of this._children) {
+            if (s.uid === childUid) {
+                return true;
+            }
+        }
         return false;
     }
 
+    /**
+     * Moves a child to first position
+     */
+    public moveChildUp(child: Nub) {
+        let i = 0;
+        for (const s of this._children) {
+            if (s.uid === child.uid && i > 0) {
+                const t = this._children[i - 1];
+                this._children[i - 1] = this._children[i];
+                this._children[i] = t;
+                return;
+            }
+            i++;
+        }
+    }
+
+    /**
+     * Moves a child to last position
+     */
+    public moveChildDown(child: Nub) {
+        let i = 0;
+        for (const s of this._children) {
+            if (s.uid === child.uid && i < this._children.length - 1) {
+                const t = this._children[i];
+                this._children[i] = this._children[i + 1];
+                this._children[i + 1] = t;
+                return;
+            }
+            i++;
+        }
+    }
+
+    /**
+     * Removes a child
+     * @param index
+     */
+    public deleteChild(index: number) {
+        if (index > -1) {
+            this._children.splice(index, 1);
+        } else {
+            throw new Error(`${this.constructor.name}.deleteChild invalid index=${index}`);
+        }
+    }
+
+    /**
+     * Returns the position or the current structure (starting at 0)
+     * in the parent Nub
+     */
+    public findPositionInParent(): number {
+        if (this.parent) {
+            return this.parent.getIndexForChild(this);
+        }
+        throw new Error(`Nub of class ${this.constructor.name} has no parent`);
+    }
+
     // interface IObservable
 
     /**
@@ -837,13 +1022,6 @@ export abstract class Nub extends ComputeNode implements IObservable {
         return Nub.prototype.Calc.call(this, sVarCalc, rInit);
     }
 
-    /**
-     * Returns inner properties dataset associated to this Nub
-     */
-    protected getPropertiesData(): object {
-        return this._props.props;
-    }
-
     /**
      * Sets the variated values and warns if there were already some
      */
diff --git a/src/pab/pab_chute.ts b/src/pab/pab_chute.ts
index 55275db5bc08764d3f1bba838a6af74d7ee92d4a..e7b41568894db60e8c52a34cdc26069c4a373145 100644
--- a/src/pab/pab_chute.ts
+++ b/src/pab/pab_chute.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "../compute-node";
 import { Nub } from "../nub";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
 import { ParamDomainValue } from "../param/param-domain";
@@ -44,6 +45,7 @@ export class PabChuteParams extends ParamsEquation {
 export class PabChute extends Nub {
     constructor(prms: PabChuteParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._calcType = CalculatorType.PabChute;
         this._defaultCalculatedParam = prms.DH;
         this.resetDefaultCalculatedParam();
     }
diff --git a/src/pab/pab_dimension.ts b/src/pab/pab_dimension.ts
index 036aa49875e794b08002ad1a6ba552ef0d31ecfa..f1dd13353de7266033a610ec1e144957f4a4cc8a 100644
--- a/src/pab/pab_dimension.ts
+++ b/src/pab/pab_dimension.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "../compute-node";
 import { Nub } from "../nub";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
 import { ParamDomainValue } from "../param/param-domain";
@@ -53,6 +54,7 @@ export class PabDimensionParams extends ParamsEquation {
 export class PabDimension extends Nub {
     constructor(prms: PabDimensionParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._calcType = CalculatorType.PabDimensions;
     }
 
     /**
diff --git a/src/pab/pab_nombre.ts b/src/pab/pab_nombre.ts
index f843c767cc257f15750298d33b49277e903acb25..a853df31ee87c3c4fcad2fc950f2f4adc8d85b23 100644
--- a/src/pab/pab_nombre.ts
+++ b/src/pab/pab_nombre.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "../compute-node";
 import { Nub } from "../nub";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
 import { ParamDomainValue } from "../param/param-domain";
@@ -44,6 +45,7 @@ export class PabNombreParams extends ParamsEquation {
 export class PabNombre extends Nub {
     constructor(prms: PabNombreParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._calcType = CalculatorType.PabNombre;
         this._defaultCalculatedParam = prms.N;
         this.resetDefaultCalculatedParam();
     }
diff --git a/src/pab/pab_puissance.ts b/src/pab/pab_puissance.ts
index cc5c9afae9b69383a1efdeb014b0578ed051dad0..44368c506f899b5fe70f8ca5148ec88d1eaabdfd 100644
--- a/src/pab/pab_puissance.ts
+++ b/src/pab/pab_puissance.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "../compute-node";
 import { Nub } from "../nub";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
 import { ParamDomainValue } from "../param/param-domain";
@@ -53,6 +54,7 @@ export class PabPuissanceParams extends ParamsEquation {
 export class PabPuissance extends Nub {
     constructor(prms: PabPuissanceParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._calcType = CalculatorType.PabPuissance;
     }
 
     /**
diff --git a/src/param/param-definition.ts b/src/param/param-definition.ts
index b26c288847447b9c3dfb59490ba62d6f8db937db..764c11bbc51e1912e5c37161c4a910b529fff53a 100644
--- a/src/param/param-definition.ts
+++ b/src/param/param-definition.ts
@@ -1,6 +1,7 @@
 import { CalculatorType, ComputeNode } from "../compute-node";
 import { LinkedValue } from "../linked-value";
 import { Nub } from "../nub";
+import { acSection } from "../section/section_type";
 import { Session } from "../session";
 import { Interval } from "../util/interval";
 import { Message, MessageCode } from "../util/message";
@@ -116,13 +117,18 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
 
     /**
      * pointer to the ComputeNode (usually Nub) that uses the ParamsEquation that
-     * uses this ParamDefinition
+     * uses this ParamDefinition; for Section params, this means the Nub enclosing
+     * the Section
      */
     public get parentComputeNode(): ComputeNode {
         let parentCN: ComputeNode;
         if (this._parent) {
             // ComputeNode utilisant le ParamsEquation
             parentCN = this._parent.parent;
+            // Section: go up to enclosing Nub ?
+            if (parentCN instanceof acSection) {
+                parentCN = parentCN.parent;
+            }
         } else {
             // fail silently (the story of my life)
             // throw new Error("ParamDefinition.parentComputeNode : parameter has no parent !");
@@ -697,6 +703,7 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
      * @param symbol
      */
     public defineReference(nub: Nub, symbol: string) {
+        // console.log(`Defining reference from ${this.nubUid}(${this.parentNub.constructor.name})/${this.symbol} to ${nub.uid}(${nub.constructor.name})/${symbol}`);
         // prevent loops - beware that all Nubs must be registered in the
         // current session or this test will always fail
         if (! this.isAcceptableReference(nub, symbol)) {
@@ -788,6 +795,60 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
         return paramRep;
     }
 
+    /**
+     * Fills the current Parameter, provided an object representation
+     * @param obj object representation of a Parameter state
+     */
+    public loadObjectRepresentation(obj: any, setCalcMode: boolean = true): boolean {
+        // set mode
+        const mode: ParamValueMode = (ParamValueMode as any)[obj.mode]; // get enum index for string value
+
+        // when loading parent Nub, setting mode to CALC would prevent ensuring
+        // consistency when setting calculatedParam afterwards
+        if (mode !== ParamValueMode.CALCUL || setCalcMode) {
+            this.valueMode = mode;
+        }
+
+        // detect if this is the calculated param - used by Nub.loadObjectRepresentation()
+        let isCalculated = false;
+
+        // set value(s)
+        switch (mode) {
+            case ParamValueMode.SINGLE:
+                this.singleValue = obj.value;
+                break;
+
+            case ParamValueMode.MINMAX:
+                this.min = obj.min;
+                this.max = obj.max;
+                this.step = obj.step;
+                break;
+
+            case ParamValueMode.LISTE:
+                this.valueList = obj.values;
+                break;
+
+            case ParamValueMode.CALCUL:
+                // although calculated param is set at Nub level (see below),
+                // it is detected as "the only parameter in CALC mode"
+                isCalculated = true;
+                break;
+
+            case ParamValueMode.LINK:
+                // formulaire dont le Nub est la cible du lien
+                const destNub = Session.getInstance().findNubByUid(obj.targetNub);
+                if (destNub) {
+                    this.defineReference(destNub, obj.targetParam);
+                } // si la cible du lien n'existe pas, Session.fixLinks() est censé s'en occuper
+                break;
+
+            default:
+                throw new Error(`session file : invalid value mode '${obj.valueMode}' in param object ${obj.symbol}`);
+        }
+
+        return isCalculated;
+    }
+
     /**
      * Returns true if both the Nub UID and the symbol are identical
      */
diff --git a/src/regime_uniforme.ts b/src/regime_uniforme.ts
index 2628d5812686a61afdc54c5b5b3719072f26eac5..446e97b3a08915f35de0ef41f212aead1c35e2c7 100644
--- a/src/regime_uniforme.ts
+++ b/src/regime_uniforme.ts
@@ -1,25 +1,29 @@
+import { CalculatorType } from "./compute-node";
 import { ParamCalculability } from "./param/param-definition";
 import { SectionNub } from "./section/section_nub";
-import { acSection, ParamsSection } from "./section/section_type";
+import { SectionParams } from "./section/section_parametree";
+import { acSection } from "./section/section_type";
 import { Result } from "./util/result";
 
 export class RegimeUniforme extends SectionNub {
 
     constructor(s: acSection, dbg: boolean = false) {
-        super(s.prms, dbg);
-        this._section = s;
-    }
-
-    get prms(): ParamsSection {
-        return this._prms as ParamsSection;
+        super(new SectionParams(), dbg);
+        this._calcType = CalculatorType.RegimeUniforme;
+        this.setSection(s);
     }
 
     public Equation(sVarCalc: string): Result {
         this.debug("RU: Equation(" + sVarCalc + ")");
 
+        if (typeof sVarCalc !== "string") {
+            // dirty hack because calculated param descriptor for section params is an object { uid: , symbol: }
+            sVarCalc = (sVarCalc as any).symbol;
+        }
+
         switch (sVarCalc) {
             case "Y":
-                return this.section.Calc("Yn");
+                return this.section.CalcSection("Yn");
 
             case "Q":
                 return this.Calc_Qn();
@@ -29,9 +33,19 @@ export class RegimeUniforme extends SectionNub {
         }
     }
 
-    protected setParametersCalculability() {
-        this.prms.Q.calculability = ParamCalculability.EQUATION;
-        this.prms.Y.calculability = ParamCalculability.EQUATION;
+    public setSection(s: acSection) {
+        super.setSection(s);
+        // had no analytical parameters before ?
+        this._defaultCalculatedParam = this.getFirstAnalyticalParameter();
+        this.resetDefaultCalculatedParam();
+    }
+
+    // tslint:disable-next-line:no-empty
+    protected setParametersCalculability() {}
+
+    protected setSectionParametersCalculability(): void {
+        this.section.prms.Q.calculability = ParamCalculability.EQUATION;
+        this.section.prms.Y.calculability = ParamCalculability.EQUATION;
     }
 
     /**
@@ -43,12 +57,12 @@ export class RegimeUniforme extends SectionNub {
             return new Result(0, this);
         }
 
-        const rR: Result = this.section.Calc("R", this.section.prms.Y.v);
+        const rR: Result = this.section.CalcSection("R", this.section.prms.Y.v);
         if (!rR) {
             return rR;
         }
 
-        const rS: Result = this.section.Calc("S", this.section.prms.Y.v);
+        const rS: Result = this.section.CalcSection("S", this.section.prms.Y.v);
         if (!rS) {
             return rS;
         }
diff --git a/src/remous.ts b/src/remous.ts
index f156e73719f09d9ea5285f3d674f8df879159008..234c1d8a7a8359cc070d0848c8e0e263ef1915cf 100644
--- a/src/remous.ts
+++ b/src/remous.ts
@@ -1,12 +1,13 @@
-import { ParamValues } from "./index";
 import { round, XOR } from "./base";
+import { CalculatorType } from "./compute-node";
 import { Dichotomie } from "./dichotomie";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "./param/param-definition";
 import { ParamDomainValue } from "./param/param-domain";
 import { ParamValueMode } from "./param/param-value-mode";
+import { ParamValues } from "./param/param-values";
 import { ParamsEquation } from "./param/params-equation";
 import { SectionNub } from "./section/section_nub";
-import { acSection, ParamsSection } from "./section/section_type";
+import { acSection } from "./section/section_type";
 import { Message, MessageCode } from "./util/message";
 import { Result } from "./util/result";
 import { ResultElement } from "./util/resultelement";
@@ -93,30 +94,14 @@ export class CourbeRemous extends SectionNub {
     // tslint:disable-next-line:variable-name
     private Dx: number;
 
-    /**
-     * Journal de calcul
-     */
-    // private _log: cLog;
-
-    private prmSect: ParamsSection;
-
     constructor(s: acSection, crp: CourbeRemousParams, method: MethodeResolution = MethodeResolution.Trapezes,
                 dbg: boolean = false
     ) {
         super(crp, dbg);
-        // this._log = crp.Sn.log;
-        this._section = s;
-        this._sectionVars.Y = this._section.prms.Y;
-        this._section.prms.Y.calculability = ParamCalculability.DICHO;
-        this.prmSect = this._section.prms;
-        this.Sn.Calc("Yc");
+        this._calcType = CalculatorType.CourbeRemous;
 
-        // merge parameters from "section" but change their parent ParamsEquation, so that the
-        // grand-parent Nub is Remous and not acSection (for linking)
-        for (const p of this._section.prms) {
-            p.parent = crp;
-            this.prms.addParamDefinition(p);
-        }
+        this.setSection(s);
+        // this.Sn.CalcSection("Yc");
 
         // should this be a ParamDefinition driven by an Enum, instead of a Prop ?
         this.properties.setPropValue("methodeResolution", method);
@@ -137,8 +122,8 @@ export class CourbeRemous extends SectionNub {
         Result {
         const res = new Result(undefined, this);
 
-        // let Yc: number = this.Sn.Calc("Yc");
-        const rYC = this.Sn.Calc("Yc");
+        // let Yc: number = this.Sn.CalcSection("Yc");
+        const rYC = this.Sn.CalcSection("Yc");
         if (!rYC.ok) {
             res.addLog(rYC.log);
             return res;
@@ -146,14 +131,14 @@ export class CourbeRemous extends SectionNub {
         // tslint:disable-next-line:variable-name
         const Yc: number = rYC.vCalc;
 
-        const rB: Result = this.Sn.Calc("B", this.Sn.prms.YB.v);
+        const rB: Result = this.Sn.CalcSection("B", this.Sn.prms.YB.v);
         if (!rB.ok) {
             res.addLog(rB.log);
             return res;
         }
 
         let m: Message = new Message(MessageCode.INFO_REMOUS_LARGEUR_BERGE);
-        // m.extraVar["B"] = this.Sn.Calc("B", this.Sn.prms.YB.v);
+        // m.extraVar["B"] = this.Sn.CalcSection("B", this.Sn.prms.YB.v);
         m.extraVar.B = rB.vCalc;
         // this._log.add(m);
         res.addMessage(m);
@@ -163,7 +148,7 @@ export class CourbeRemous extends SectionNub {
         // this._log.add(m);
         res.addMessage(m);
 
-        const rYN = this.Sn.Calc("Yn");
+        const rYN = this.Sn.CalcSection("Yn");
         if (!rYN.ok) {
             res.addLog(rYN.log);
             return res;
@@ -176,11 +161,11 @@ export class CourbeRemous extends SectionNub {
         // this._log.add(m);
         res.addMessage(m);
 
-        // this.debug("largeur berge " + this.Sn.Calc("B"));
-        // const rB2: Result = this.Sn.Calc("B")
+        // this.debug("largeur berge " + this.Sn.CalcSection("B"));
+        // const rB2: Result = this.Sn.CalcSection("B")
         // this.debug("largeur berge " + rB2.vCalc);
         // this.debug("hauteur critique " + Yc);
-        // this.Sn.HautNormale = this.Sn.Calc("Yn");
+        // this.Sn.HautNormale = this.Sn.CalcSection("Yn");
         // this.debug("hauteur normale " + this.Sn.HautNormale);
         // this.debug("hauteur normale " + Yn);
 
@@ -226,13 +211,13 @@ export class CourbeRemous extends SectionNub {
         // tslint:disable-next-line:forin
         for (const xflu in crbFlu) {
             const yflu = crbFlu[xflu];
-            // this.debug("imp x " + xflu + " flu " + this.Sn.Calc('Imp', yflu));
+            // this.debug("imp x " + xflu + " flu " + this.Sn.CalcSection('Imp', yflu));
         }
 
         // tslint:disable-next-line:forin
         for (const xtor in crbTor) {
             const ytor = crbTor[xtor];
-            // this.debug("imp x " + xtor + " tor " + this.Sn.Calc('Imp', ytor));
+            // this.debug("imp x " + xtor + " tor " + this.Sn.CalcSection('Imp', ytor));
         }
 
         // Détection du ressaut hydraulique
@@ -245,8 +230,8 @@ export class CourbeRemous extends SectionNub {
             // this.debug("end tor " + lastYTor);
             // this.debug("nFlu " + nFlu);
             // this.debug("nTor " + nTor);
-            // this.debug("Imp flu " + this.Sn.Calc('Imp', firstYFlu));
-            // this.debug("Imp tor " + this.Sn.Calc('Imp', lastYTor));
+            // this.debug("Imp flu " + this.Sn.CalcSection('Imp', firstYFlu));
+            // this.debug("Imp tor " + this.Sn.CalcSection('Imp', lastYTor));
             let crbComplete: any;
             let crbPartielle: any;
             let iSens: number;
@@ -309,7 +294,7 @@ export class CourbeRemous extends SectionNub {
                 // this.debug("partielle[" + rX + "]=" + crbPartielle[rX]);
 
                 // Calcul de l'abscisse de la section dans l'autre régime
-                const rYCO = this.Sn.Calc("Yco", crbPartielle[rX]); // Y conjugué
+                const rYCO = this.Sn.CalcSection("Yco", crbPartielle[rX]); // Y conjugué
                 if (!rYCO.ok) {
                     res.addLog(rYCO.log);
                     return res;
@@ -326,10 +311,10 @@ export class CourbeRemous extends SectionNub {
                 // let rxRst = rX + iSens * rLongRst; // Abscisse réelle du ressaut
                 // this.debug("xRst reel=" + (rX + iSens * rLongRst));
 
-                xRst = round(xRst, this.prmSect.iPrec);
+                xRst = round(xRst, this.section.prms.iPrec);
                 // this.debug("xRst (arr)=" + xRst);
 
-                const impYpartielle = this.Sn.Calc("Imp", crbPartielle[rX]);
+                const impYpartielle = this.Sn.CalcSection("Imp", crbPartielle[rX]);
                 // this.debug("imp(Ypartiel[rX=" + rX + "]=" + crbPartielle[rX] + ")=" + impYpartielle);
                 if (!impYpartielle.ok) {
                     res.addLog(impYpartielle.log);
@@ -338,9 +323,9 @@ export class CourbeRemous extends SectionNub {
 
                 if (crbComplete[xRst] !== undefined) {
                     // Hauteur décalée de la longueur du ressaut (il faut gérer la pente du fond)
-                    // const Ydec: number = crbComplete[xRst] + rLongRst * this.prmSect.If.v * iSens;
+                    // const Ydec: number = crbComplete[xRst] + rLongRst * this.section.prms.If.v * iSens;
                     // this.debug("Ydec=" + Ydec);
-                    const impYcomplete = this.Sn.Calc("Imp", crbComplete[xRst]);
+                    const impYcomplete = this.Sn.CalcSection("Imp", crbComplete[xRst]);
                     // this.debug("imp(Ycomplet[xRst=" + xRst + "]=" + crbComplete[xRst] + ")=" + impYcomplete);
                     if (!impYcomplete.ok) {
                         res.addLog(impYcomplete.log);
@@ -473,7 +458,7 @@ export class CourbeRemous extends SectionNub {
             for (const re of res.resultElements) {
                 const rY = re.vCalc;
                 if (rY !== undefined) {
-                    const rVar = this.Sn.Calc(valACal, rY);
+                    const rVar = this.Sn.CalcSection(valACal, rY);
                     if (!rVar.ok) {
                         res.addLog(rVar.log);
                     } else {
@@ -498,16 +483,16 @@ export class CourbeRemous extends SectionNub {
     public Equation(sVarCalc: string): Result {
         if (sVarCalc === "Hs") {
             // Equation de l'intégration par la méthode des trapèzes
-            this.Sn.Reset();  // pour forcer le calcul avec la nouvelle valeur de prmSect.Y
+            this.Sn.Reset();  // pour forcer le calcul avec la nouvelle valeur de section.prms.Y
 
-            // let res: number = this.Sn.Calc('Hs') - this.Sn.Calc('J') / 2 * this.Dx;
+            // let res: number = this.Sn.CalcSection('Hs') - this.Sn.CalcSection('J') / 2 * this.Dx;
 
-            const rHS = this.Sn.Calc("Hs");
+            const rHS = this.Sn.CalcSection("Hs");
             if (!rHS.ok) {
                 return rHS;
             }
 
-            const rJ = this.Sn.Calc("J");
+            const rJ = this.Sn.CalcSection("J");
             if (!rJ.ok) {
                 return rJ;
             }
@@ -520,7 +505,7 @@ export class CourbeRemous extends SectionNub {
     }
 
     public get Sn(): acSection {
-        return this._section;
+        return this.section;
     }
 
     get prms(): CourbeRemousParams {
@@ -528,11 +513,14 @@ export class CourbeRemous extends SectionNub {
     }
 
     protected setParametersCalculability() {
-        // see constructor for "Y" section parameter
-        this.prms.map.Long.calculability = ParamCalculability.FREE;
-        this.prms.map.Dx.calculability = ParamCalculability.FREE;
-        this.prms.map.Yamont.calculability = ParamCalculability.FREE;
-        this.prms.map.Yaval.calculability = ParamCalculability.FREE;
+        this.prms.Long.calculability = ParamCalculability.FREE;
+        this.prms.Dx.calculability = ParamCalculability.FREE;
+        this.prms.Yamont.calculability = ParamCalculability.FREE;
+        this.prms.Yaval.calculability = ParamCalculability.FREE;
+    }
+
+    protected setSectionParametersCalculability(): void {
+        this.section.prms.Y.calculability = ParamCalculability.DICHO;
     }
 
     /**
@@ -610,19 +598,19 @@ export class CourbeRemous extends SectionNub {
      */
     private Calc_dYdX(Y: number): Result {
         // L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau
-        // return - (this.prmSect.If.v - this.Sn.Calc('J', Y)) / (1 - Math.pow(this.Sn.Calc('Fr', Y), 2));
+        // return - (this.section.prms.If.v - this.Sn.CalcSection('J', Y)) / (1 - Math.pow(this.Sn.CalcSection('Fr', Y), 2));
 
-        const rJ = this.Sn.Calc("J", Y);
+        const rJ = this.Sn.CalcSection("J", Y);
         if (!rJ.ok) {
             return rJ;
         }
 
-        const rFR = this.Sn.Calc("Fr", Y);
+        const rFR = this.Sn.CalcSection("Fr", Y);
         if (!rFR.ok) {
             return rFR;
         }
 
-        const v = - (this.prmSect.If.v - rJ.vCalc) / (1 - Math.pow(rFR.vCalc, 2));
+        const v = - (this.section.prms.If.v - rJ.vCalc) / (1 - Math.pow(rFR.vCalc, 2));
         return new Result(v, this);
     }
 
@@ -728,13 +716,13 @@ export class CourbeRemous extends SectionNub {
         const dicho = new Dichotomie(this, "Y", this._debugDicho, "Hs");
 
         // Calcul de H + J * \Delta x / 2
-        // let Trapez_Fn = this.Sn.Calc('Hs', Y) + this.Sn.Calc('J', Y) / 2 * this.Dx
-        const rHS: Result = this.Sn.Calc("Hs", Y);
+        // let Trapez_Fn = this.Sn.CalcSection('Hs', Y) + this.Sn.CalcSection('J', Y) / 2 * this.Dx
+        const rHS: Result = this.Sn.CalcSection("Hs", Y);
         if (!rHS.ok) {
             return rHS;
         }
 
-        const rJ: Result = this.Sn.Calc("J", Y);
+        const rJ: Result = this.Sn.CalcSection("J", Y);
         if (!rJ.ok) {
             return rJ;
         }
@@ -742,9 +730,9 @@ export class CourbeRemous extends SectionNub {
         let trapezFn = rHS.vCalc + rJ.vCalc / 2 * this.Dx;
 
         // H est la charge totale. On se place dans le référentiel ou Zf de la section à calculer = 0
-        trapezFn -= this.Dx * this.prmSect.If.v;
+        trapezFn -= this.Dx * this.section.prms.If.v;
 
-        const r: Result = dicho.Dichotomie(trapezFn, this.prmSect.Pr.v, Y);
+        const r: Result = dicho.Dichotomie(trapezFn, this.section.prms.Pr.v, Y);
         if (!r.ok) {
             return r;
         }
@@ -816,7 +804,7 @@ export class CourbeRemous extends SectionNub {
         const res = new ResultElement();
 
         let lastY = YCL;
-        trY[round(varParam.next().value, this.prmSect.iPrec)] = lastY;
+        trY[round(varParam.next().value, this.section.prms.iPrec)] = lastY;
 
         // Boucle de calcul de la courbe de remous
         while (varParam.hasNext) {
@@ -846,7 +834,7 @@ export class CourbeRemous extends SectionNub {
                     res.addMessage(m);
                 }
 
-                trY[round(x, this.prmSect.iPrec)] = rY.vCalc;
+                trY[round(x, this.section.prms.iPrec)] = rY.vCalc;
             } else {
                 const m = new Message(MessageCode.WARNING_REMOUS_ARRET_CRITIQUE);
                 m.extraVar.x = x;
diff --git a/src/section/hauteur.ts b/src/section/hauteur.ts
index 680c9fc05f3156ad3f87ec9921ebf5c12338da69..c43869e406710279c3515a7d9e941a286e7b1199 100644
--- a/src/section/hauteur.ts
+++ b/src/section/hauteur.ts
@@ -1,7 +1,7 @@
 import { Message, MessageCode } from "../util/message";
 import { Result } from "../util/result";
 import { acNewton } from "./newton";
-import { acSection, cParamsCanal } from "./section_type";
+import { acSection, ParamsSection } from "./section_type";
 
 /**
  * Calcul de la hauteur critique
@@ -29,30 +29,30 @@ export class cHautCritique extends acNewton {
          * @param rX Variable dont dépend la fonction
          */
         public CalcFn(rX: number): Result {
-                const rS: Result = this.Sn.Calc("S", rX);
+                const rS: Result = this.Sn.CalcSection("S", rX);
                 if (!rS.ok) {
                         return rS;
                 }
 
                 // Calcul de la fonction
-                // if (this.Sn.Calc("S", rX) !== 0)
+                // if (this.Sn.CalcSection("S", rX) !== 0)
                 if (rS.vCalc === 0) {
                         return new Result(new Message(MessageCode.ERROR_SECTION_SURFACE_NULLE));
                 }
 
                 // tslint:disable-next-line:max-line-length
-                // return (Math.pow(this.Sn.prms.Q.v, 2) * this.Sn.Calc("B", rX) / Math.pow(this.Sn.Calc("S", rX), 3) / cParamsCanal.G - 1);
-                const rB: Result = this.Sn.Calc("B", rX);
+                // return (Math.pow(this.Sn.prms.Q.v, 2) * this.Sn.CalcSection("B", rX) / Math.pow(this.Sn.CalcSection("S", rX), 3) / ParamsSection.G - 1);
+                const rB: Result = this.Sn.CalcSection("B", rX);
                 if (!rB.ok) {
                         return rB;
                 }
 
-                const rS2: Result = this.Sn.Calc("S", rX);
+                const rS2: Result = this.Sn.CalcSection("S", rX);
                 if (!rS2.ok) {
                         return rS2;
                 }
 
-                const v = (Math.pow(this.Sn.prms.Q.v, 2) * rB.vCalc / Math.pow(rS2.vCalc, 3) / cParamsCanal.G - 1);
+                const v = (Math.pow(this.Sn.prms.Q.v, 2) * rB.vCalc / Math.pow(rS2.vCalc, 3) / ParamsSection.G - 1);
                 return new Result(v);
 
                 // return Infinity;
@@ -63,8 +63,8 @@ export class cHautCritique extends acNewton {
          * @param rX Variable dont dépend la fonction
          */
         public CalcDer(rX: number): Result {
-                // let S = this.Sn.Calc("S");
-                const rS: Result = this.Sn.Calc("S");
+                // let S = this.Sn.CalcSection("S");
+                const rS: Result = this.Sn.CalcSection("S");
                 if (!rS.ok) {
                         return rS;
                 }
@@ -74,23 +74,23 @@ export class cHautCritique extends acNewton {
                         return new Result(new Message(MessageCode.ERROR_SECTION_SURFACE_NULLE));
                 }
 
-                // let B = this.Sn.Calc("B");
-                const rB: Result = this.Sn.Calc("B");
+                // let B = this.Sn.CalcSection("B");
+                const rB: Result = this.Sn.CalcSection("B");
                 if (!rB.ok) {
                         return rB;
                 }
                 const B = rB.vCalc;
 
-                const rDB: Result = this.Sn.Calc("dB");
+                const rDB: Result = this.Sn.CalcSection("dB");
                 if (!rDB.ok) {
                         return rDB;
                 }
 
                 // L'initialisation à partir de rX a été faite lors de l'appel à CalcFn
-                // let Der = (this.Sn.Calc("dB") * S - 3 * B * B);
+                // let Der = (this.Sn.CalcSection("dB") * S - 3 * B * B);
                 // tslint:disable-next-line:variable-name
                 const Der = (rDB.vCalc * S - 3 * B * B);
-                const v = Math.pow(this.Sn.prms.Q.v, 2) / cParamsCanal.G * Der / Math.pow(S, 4);
+                const v = Math.pow(this.Sn.prms.Q.v, 2) / ParamsSection.G * Der / Math.pow(S, 4);
                 return new Result(v);
                 // }
 
@@ -146,13 +146,13 @@ export class cHautNormale extends acNewton {
         public CalcFn(rX: number): Result {
                 // Calcul de la fonction
                 // tslint:disable-next-line:max-line-length
-                // return (this.Q - this.Ks * Math.pow(this.Sn.Calc("R", rX), 2 / 3) * this.Sn.Calc("S", rX) * Math.sqrt(this.If));
-                const rR: Result = this.Sn.Calc("R", rX);
+                // return (this.Q - this.Ks * Math.pow(this.Sn.CalcSection("R", rX), 2 / 3) * this.Sn.CalcSection("S", rX) * Math.sqrt(this.If));
+                const rR: Result = this.Sn.CalcSection("R", rX);
                 if (!rR.ok) {
                         return rR;
                 }
 
-                const rS: Result = this.Sn.Calc("S", rX);
+                const rS: Result = this.Sn.CalcSection("S", rX);
                 if (!rS.ok) {
                         return rS;
                 }
@@ -166,38 +166,38 @@ export class cHautNormale extends acNewton {
          * @param rX Variable dont dépend la fonction
          */
         public CalcDer(rX: number): Result {
-                const rDR: Result = this.Sn.Calc("dR");
+                const rDR: Result = this.Sn.CalcSection("dR");
                 if (!rDR.ok) {
                         return rDR;
                 }
 
-                const rR: Result = this.Sn.Calc("R");
+                const rR: Result = this.Sn.CalcSection("R");
                 if (!rR.ok) {
                         return rR;
                 }
 
-                const rS: Result = this.Sn.Calc("S");
+                const rS: Result = this.Sn.CalcSection("S");
                 if (!rS.ok) {
                         return rS;
                 }
 
                 // L'initialisation a été faite lors de l'appel à CalcFn
 
-                // let Der = 2 / 3 * this.Sn.Calc("dR") * Math.pow(this.Sn.Calc("R"), -1 / 3) * this.Sn.Calc("S");
+                // let Der = 2 / 3 * this.Sn.CalcSection("dR") * Math.pow(this.Sn.CalcSection("R"), -1 / 3) * this.Sn.CalcSection("S");
                 // tslint:disable-next-line:variable-name
                 let Der = 2 / 3 * rDR.vCalc * Math.pow(rR.vCalc, -1 / 3) * rS.vCalc;
 
-                const rR2: Result = this.Sn.Calc("R");
+                const rR2: Result = this.Sn.CalcSection("R");
                 if (!rR2.ok) {
                         return rR2;
                 }
 
-                const rB: Result = this.Sn.Calc("B");
+                const rB: Result = this.Sn.CalcSection("B");
                 if (!rB.ok) {
                         return rB;
                 }
 
-                // Der = Der + Math.pow(this.Sn.Calc("R"), 2 / 3) * this.Sn.Calc("B");
+                // Der = Der + Math.pow(this.Sn.CalcSection("R"), 2 / 3) * this.Sn.CalcSection("B");
                 Der = Der + Math.pow(rR2.vCalc, 2 / 3) * rB.vCalc;
 
                 Der = Der * -this.Ks * Math.sqrt(this.If);
@@ -239,16 +239,16 @@ export class cHautCorrespondante extends acNewton {
         constructor(Sn: acSection, maxIter: number, dbg: boolean = false) {
                 super(Sn.prms, maxIter, dbg);
                 this.Y = Sn.prms.Y.v;
-                //                this.rS2 = Math.pow(Sn.Calc("S"), -2);
+                //                this.rS2 = Math.pow(Sn.CalcSection("S"), -2);
                 this.Sn = Sn;
                 // tslint:disable-next-line:no-unused-expression
                 this.rS2;  // pour initialiser la valeur @WTF (utilise le getter)
-                this.rQ2G = Math.pow(Sn.prms.Q.v, 2) / (2 * cParamsCanal.G);
+                this.rQ2G = Math.pow(Sn.prms.Q.v, 2) / (2 * ParamsSection.G);
         }
 
         private get rS2(): Result {
                 if (this._rS2 === undefined) {
-                        const rS = this.Sn.Calc("S");
+                        const rS = this.Sn.CalcSection("S");
                         if (rS.ok) {
                                 const v = Math.pow(rS.vCalc, -2);
                                 this._rS2 = new Result(v);
@@ -268,13 +268,13 @@ export class cHautCorrespondante extends acNewton {
                         return this.rS2;
                 }
 
-                const rS: Result = this.Sn.Calc("S", rX);
+                const rS: Result = this.Sn.CalcSection("S", rX);
                 if (!rS.ok) {
                         return rS;
                 }
 
                 // Calcul de la fonction
-                // return this.Y - rX + (this.rS2 - Math.pow(this.Sn.Calc("S", rX), -2)) * this.rQ2G;
+                // return this.Y - rX + (this.rS2 - Math.pow(this.Sn.CalcSection("S", rX), -2)) * this.rQ2G;
                 const v = this.Y - rX + (this.rS2.vCalc - Math.pow(rS.vCalc, -2)) * this.rQ2G;
                 return new Result(v);
         }
@@ -284,8 +284,8 @@ export class cHautCorrespondante extends acNewton {
          * @param rX Variable dont dépend la fonction
          */
         public CalcDer(rX: number): Result {
-                // let S = this.Sn.Calc("S");
-                const rS: Result = this.Sn.Calc("S");
+                // let S = this.Sn.CalcSection("S");
+                const rS: Result = this.Sn.CalcSection("S");
                 if (!rS.ok) {
                         return rS;
                 }
@@ -297,12 +297,12 @@ export class cHautCorrespondante extends acNewton {
                         return new Result(new Message(MessageCode.ERROR_SECTION_SURFACE_NULLE));
                 }
 
-                const rB: Result = this.Sn.Calc("B");
+                const rB: Result = this.Sn.CalcSection("B");
                 if (!rB.ok) {
                         return rB;
                 }
 
-                // return -1 + 2 * this.rQ2G * this.Sn.Calc("B") / Math.pow(S, 3);
+                // return -1 + 2 * this.rQ2G * this.Sn.CalcSection("B") / Math.pow(S, 3);
                 const v = -1 + 2 * this.rQ2G * rB.vCalc / Math.pow(S, 3);
                 return new Result(v);
 
@@ -336,8 +336,8 @@ export class cHautConjuguee extends acNewton {
                 super(oSn.prms, maxIter, dbg);
                 this.rQ2 = Math.pow(oSn.prms.Q.v, 2);
                 this.Sn = oSn;
-                this.rS = oSn.Calc("S");
-                this.rSYg = oSn.Calc("SYg");
+                this.rS = oSn.CalcSection("S");
+                this.rSYg = oSn.CalcSection("SYg");
         }
 
         /**
@@ -353,16 +353,16 @@ export class cHautConjuguee extends acNewton {
                         return this.rSYg;
                 }
 
-                const rS2: Result = this.Sn.Calc("S", rX);
+                const rS2: Result = this.Sn.CalcSection("S", rX);
                 if (!rS2.ok) {
                         return rS2;
                 }
 
-                // Réinitialisation des paramètres hydrauliques de this.Sn avec l'appel this.Sn.Calc("S',rX)
-                // if (this.rS > 0 && this.Sn.Calc("S", rX) > 0) {
+                // Réinitialisation des paramètres hydrauliques de this.Sn avec l'appel this.Sn.CalcSection("S',rX)
+                // if (this.rS > 0 && this.Sn.CalcSection("S", rX) > 0) {
                 if (this.rS.vCalc > 0 && rS2.vCalc > 0) {
-                        // let Fn = this.rQ2 * (1 / this.rS - 1 / this.Sn.Calc("S"));
-                        const rS3: Result = this.Sn.Calc("S");
+                        // let Fn = this.rQ2 * (1 / this.rS - 1 / this.Sn.CalcSection("S"));
+                        const rS3: Result = this.Sn.CalcSection("S");
                         if (!rS3.ok) {
                                 return rS3;
                         }
@@ -370,13 +370,13 @@ export class cHautConjuguee extends acNewton {
                         // tslint:disable-next-line:variable-name
                         const Fn = this.rQ2 * (1 / this.rS.vCalc - 1 / rS3.vCalc);
 
-                        const rSYg = this.Sn.Calc("SYg");
+                        const rSYg = this.Sn.CalcSection("SYg");
                         if (!rSYg.ok) {
                                 return rSYg;
                         }
 
-                        // return Fn + cParamsCanal.G * (this.rSYg - this.Sn.Calc("SYg"));
-                        const v = Fn + cParamsCanal.G * (this.rSYg.vCalc - rSYg.vCalc);
+                        // return Fn + ParamsSection.G * (this.rSYg - this.Sn.CalcSection("SYg"));
+                        const v = Fn + ParamsSection.G * (this.rSYg.vCalc - rSYg.vCalc);
                         return new Result(v);
                 }
 
@@ -393,8 +393,8 @@ export class cHautConjuguee extends acNewton {
                         return this.rS;
                 }
 
-                //                let S = this.Sn.Calc("S");
-                const rS2: Result = this.Sn.Calc("S");
+                //                let S = this.Sn.CalcSection("S");
+                const rS2: Result = this.Sn.CalcSection("S");
                 if (!rS2.ok) {
                         return rS2;
                 }
@@ -403,22 +403,22 @@ export class cHautConjuguee extends acNewton {
                 // L'initialisation a été faite lors de l'appel à CalcFn
                 // if (this.rS > 0 && S > 0) {
                 if (this.rS.vCalc > 0 && S > 0) {
-                        const rDS: Result = this.Sn.Calc("dS");
+                        const rDS: Result = this.Sn.CalcSection("dS");
                         if (!rDS.ok) {
                                 return rDS;
                         }
 
-                        // let Der = this.rQ2 * this.Sn.Calc("dS") * Math.pow(S, -2);
+                        // let Der = this.rQ2 * this.Sn.CalcSection("dS") * Math.pow(S, -2);
                         // tslint:disable-next-line:variable-name
                         const Der = this.rQ2 * rDS.vCalc * Math.pow(S, -2);
 
-                        const rDYG: Result = this.Sn.Calc("dSYg", rX);
+                        const rDYG: Result = this.Sn.CalcSection("dSYg", rX);
                         if (!rDYG.ok) {
                                 return rDYG;
                         }
 
-                        // return Der - cParamsCanal.G * this.Sn.Calc("dSYg", rX);
-                        const v = Der - cParamsCanal.G * rDYG.vCalc;
+                        // return Der - ParamsSection.G * this.Sn.CalcSection("dSYg", rX);
+                        const v = Der - ParamsSection.G * rDYG.vCalc;
                         return new Result(v);
                 }
 
diff --git a/src/section/newton.ts b/src/section/newton.ts
index 29ac3d3eee8dbdca65dcbb09978945d9c1d440f5..bc8c9c9604f4b1d495120a3d784a351e84f06da5 100644
--- a/src/section/newton.ts
+++ b/src/section/newton.ts
@@ -2,7 +2,7 @@ import { Debug, XOR } from "../base";
 import { Message, MessageCode } from "../util/message";
 import { Result } from "../util/result";
 import { ResultElement } from "../util/resultelement";
-import { cParamsCanal } from "./section_type";
+import { ParamsSection } from "./section_type";
 
 // tslint:disable-next-line:class-name
 export abstract class acNewton extends Debug {
@@ -19,7 +19,7 @@ export abstract class acNewton extends Debug {
          * Constructeur de la classe
          * @param prms Paramètres supplémentaires (Débit, précision...)
          */
-        constructor(prms: cParamsCanal, maxIter: number, dbg: boolean = false) {
+        constructor(prms: ParamsSection, maxIter: number, dbg: boolean = false) {
                 super(dbg);
                 this.rTol = prms.Pr.v;
                 this.Dx = prms.Pr.v / 10;
diff --git a/src/section/section_circulaire.ts b/src/section/section_circulaire.ts
index 7f2a1daa148d3f46b7dde1d20e6d0e73fb53e80a..4ff68af501fbcdcc70f02a0985eb0d4d341e4d1e 100644
--- a/src/section/section_circulaire.ts
+++ b/src/section/section_circulaire.ts
@@ -1,3 +1,4 @@
+import { ComputeNodeType } from "../compute-node";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
 import { ParamDomainValue } from "../param/param-domain";
 import { Message, MessageCode } from "../util/message";
@@ -38,6 +39,7 @@ export class cSnCirc extends acSection {
 
         constructor(prms: ParamsSectionCirc, dbg: boolean = false) {
                 super(prms, dbg);
+                this._nodeType = ComputeNodeType.SectionCercle;
                 // commenté car si D est la variable à déterminer, il peut valoir n'importe
                 // quoi... if (prms.YB.v > D) { prms.YB.v = D; } // On place la berge au sommet du cercle
 
diff --git a/src/section/section_nub.ts b/src/section/section_nub.ts
index f6c2a7c07acbd0ab93cff8dcb02d22c43c197893..4c52358452d879f053ebd13439bf8a2e60f84db2 100644
--- a/src/section/section_nub.ts
+++ b/src/section/section_nub.ts
@@ -1,6 +1,7 @@
 import { Nub } from "../nub";
 import { ParamDefinition } from "../param/param-definition";
 import { ParamsEquation } from "../param/params-equation";
+import { Props } from "../props";
 import { acSection } from "./section_type";
 
 /**
@@ -8,12 +9,16 @@ import { acSection } from "./section_type";
  */
 export abstract class SectionNub extends Nub {
 
-    protected _section: acSection;
-
+    /** moved from SectionParametree @TODO make sure it is used by other SectionNubs */
     protected _sectionVars: { [key: string]: ParamDefinition };
 
+    /** Section is always the first child */
     public get section(): acSection {
-        return this._section;
+        if (this._children && this._children.length > 0) {
+            return this._children[0] as acSection;
+        } else {
+            return undefined;
+        }
     }
 
     public constructor(prms: ParamsEquation, dbg: boolean = false) {
@@ -21,10 +26,27 @@ export abstract class SectionNub extends Nub {
         this._sectionVars = {};
     }
 
+    /** Returns Props object (observable set of key-values) associated to this Nub */
+    public get properties(): Props {
+        // completes props with calcType and nodeType if not already set
+        this._props.setPropValue("calcType", this.calcType);
+        // this._props.setPropValue("nodeType", this.section.nodeType);
+        return this._props;
+    }
+
+    // setter is not inherited from Nub if getter is redefined :/
+    public set properties(props: Props) {
+        this._props = props.clone();
+    }
+
     public getParameter(name: string): ParamDefinition {
+        if (typeof name !== "string") {
+            // dirty hack because calculated param descriptor for section params is an object { uid: , symbol: }
+            name = (name as any).symbol;
+        }
         let res = super.getParameter(name);
         if (res === undefined) {
-            // pas trouvé -> il s'agit peut être d'une variable dans le genre Hs, B, P, ...
+            // not found - maybe a section var ?
             res = this._sectionVars[name];
 
             if (!res) {
@@ -39,9 +61,17 @@ export abstract class SectionNub extends Nub {
     /**
      * Sets / replaces the current section
      */
-    public replaceSection(s: acSection) {
-        this._section = s;
-        s.parent = this;
+    public setSection(s: acSection) {
+        if (s) {
+            // prevent index out of bounds at first time
+            if (this._children.length === 0) {
+                this._children[0] = undefined;
+            }
+            this.replaceChild(0, s);
+            this.setSectionParametersCalculability();
+        }
     }
 
+    /** Called everytime a section is set / replaced */
+    protected abstract setSectionParametersCalculability(): void;
 }
diff --git a/src/section/section_parametree.ts b/src/section/section_parametree.ts
index add9c2228dd7c5cdeb94f8b9747542513a1cb319..874418aac3269a0ab419e75721bcf13c4a201c84 100644
--- a/src/section/section_parametree.ts
+++ b/src/section/section_parametree.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "../compute-node";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
 import { ParamDomain, ParamDomainValue } from "../param/param-domain";
 import { ParamValueMode } from "../param/param-value-mode";
@@ -17,9 +18,10 @@ export class SectionParams extends ParamsEquation {}
 // tslint:disable-next-line:max-classes-per-file
 export class SectionParametree extends SectionNub {
 
-    constructor(sect: acSection, dbg: boolean = false) {
-        super(sect.prms, dbg);
-        this._section = sect;
+    constructor(s: acSection, dbg: boolean = false) {
+        super(new SectionParams(), dbg);
+        this._calcType = CalculatorType.SectionParametree;
+        this.setSection(s);
         this.initSectionVars();
         // no calculated parameter
         this._defaultCalculatedParam = undefined;
@@ -60,7 +62,7 @@ export class SectionParametree extends SectionNub {
             case "Imp":
             case "Tau0":
             case "I-J":
-                return this._section.Calc(sVarCalc, this.getParameter("Y").v);
+                return this.section.CalcSection(sVarCalc, this.getParameter("Y").v);
 
             default:
                 throw new Error(`SectionParam.Equation() : calcul sur ${sVarCalc} non implémenté`);
@@ -101,7 +103,6 @@ export class SectionParametree extends SectionNub {
             }
         }
 
-
         if (variatedParam === undefined) {
             this.Calc(); // résultat dans this._result
         } else {
@@ -200,6 +201,9 @@ export class SectionParametree extends SectionNub {
     // tslint:disable-next-line:no-empty
     protected setParametersCalculability(): void {}
 
+    // tslint:disable-next-line:no-empty
+    protected setSectionParametersCalculability(): void {}
+
     protected setExtraResultsFamilies() {
         this._extraResultsFamilies = {
             B: ParamFamily.WIDTHS,
@@ -271,23 +275,12 @@ export class SectionParametree extends SectionNub {
         return res;
     }
 
-    private hasVariatedParameter(): boolean {
-        for (const p of this.parameterIterator) {
-            switch (p.valueMode) {
-                case ParamValueMode.LISTE:
-                case ParamValueMode.MINMAX:
-                    return true;
-            }
-        }
-        return false;
-    }
-
     /**
      * Calculates varCalc from Y, and sets the result as an
      * extraResult of the given ResultElement
      */
     private addExtraResultFromVar(varCalc: string, Y: number, re: ResultElement) {
-        const r: Result = this._section.Calc(varCalc, Y);
+        const r: Result = this.section.CalcSection(varCalc, Y);
         if (r.ok) {
             re.addExtraResult(varCalc, r.vCalc);
         } else {
diff --git a/src/section/section_puissance.ts b/src/section/section_puissance.ts
index 3b216037180b506a6b03d525e9407d8234e4bc44..900b93a5f06aa258c1189e4868bbe21564f4d482 100644
--- a/src/section/section_puissance.ts
+++ b/src/section/section_puissance.ts
@@ -1,3 +1,4 @@
+import { ComputeNodeType } from "../compute-node";
 import { ParamCalculability, ParamDefinition } from "../param/param-definition";
 import { ParamDomain, ParamDomainValue } from "../param/param-domain";
 import { Result } from "../util/result";
@@ -35,6 +36,7 @@ export class cSnPuiss extends acSection {
 
         constructor(prms: ParamsSectionPuiss, dbg: boolean = false) {
                 super(prms, dbg);
+                this._nodeType = ComputeNodeType.SectionPuissance;
         }
 
         protected setParametersCalculability() {
diff --git a/src/section/section_rectang.ts b/src/section/section_rectang.ts
index ef8da7a62964be521a79871f62b601495c2efc67..4e2d178ed49c02e4a6ab6d6aaf00564b8ddcb63c 100644
--- a/src/section/section_rectang.ts
+++ b/src/section/section_rectang.ts
@@ -1,3 +1,4 @@
+import { ComputeNodeType } from "../compute-node";
 import { Result } from "../util/result";
 import { acSection, ParamsSection } from "./section_type";
 
@@ -17,6 +18,7 @@ export class ParamsSectionRectang extends ParamsSection {
 export class cSnRectang extends acSection {
         constructor(prms: ParamsSectionRectang, dbg: boolean = false) {
                 super(prms, dbg);
+                this._nodeType = ComputeNodeType.SectionRectangle;
         }
 
         get prms(): ParamsSectionRectang {
diff --git a/src/section/section_trapez.ts b/src/section/section_trapez.ts
index 4252633025ee0fd63e5c847f572aae454f0d0dd7..b0e9ecc886ef1f2d11d7ebe2520ec8c2c728e9a8 100644
--- a/src/section/section_trapez.ts
+++ b/src/section/section_trapez.ts
@@ -1,3 +1,4 @@
+import { ComputeNodeType } from "../compute-node";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
 import { ParamDomainValue } from "../param/param-domain";
 import { Result } from "../util/result";
@@ -48,6 +49,7 @@ export class cSnTrapez extends acSection {
         }
         constructor(prms: ParamsSectionTrapez, dbg: boolean = false) {
                 super(prms, dbg);
+                this._nodeType = ComputeNodeType.SectionTrapeze;
         }
 
         protected setParametersCalculability() {
diff --git a/src/section/section_type.ts b/src/section/section_type.ts
index 9bbac4cbc1034fd2e57900a56c3603d22f87f722..0cfad6eb4158604d060ae6263d65d1a07056f83e 100644
--- a/src/section/section_type.ts
+++ b/src/section/section_type.ts
@@ -1,16 +1,16 @@
-import { ComputeNode } from "../compute-node";
+import { CalculatorType, ComputeNodeType } from "../compute-node";
+import { Nub } from "../nub";
 import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
 import { ParamDomainValue } from "../param/param-domain";
 import { ParamsEquation } from "../param/params-equation";
+import { Props } from "../props";
 import { Message, MessageCode } from "../util/message";
 import { Result } from "../util/result";
 import { cHautConjuguee, cHautCorrespondante, cHautCritique, cHautNormale } from "./hauteur";
 
-/**
- * Gestion des Paramètres du canal (hors section)
- */
-// tslint:disable-next-line:class-name
-export abstract class cParamsCanal extends ParamsEquation {
+// tslint:disable-next-line:max-classes-per-file
+export abstract class ParamsSection extends ParamsEquation {
+
         public static readonly G: number = 9.81; /// Constante de gravité
 
         private _Ks: ParamDefinition; // Strickler
@@ -18,20 +18,37 @@ export abstract class cParamsCanal extends ParamsEquation {
         private _If: ParamDefinition;  // Pente du fond
         private _YB: ParamDefinition;  // Hauteur de berge
         private _iPrec: number;  // Précision en nombre de décimales
+        private _Y: ParamDefinition;          // Tirant d'eau
+        private _LargeurBerge: ParamDefinition; // largeur au débordement
 
-        constructor(rKs: number, rQ: number, rIf: number, rYB: number) {
+        constructor(rY: number,
+                    rLargeurBerge: number,
+                    rKs: number,
+                    rQ: number,
+                    rIf: number,
+                    rYB: number
+        ) {
                 super();
                 this._Ks = new ParamDefinition(this, "Ks", ParamDomainValue.POS, rKs);
                 this._Q = new ParamDefinition(this, "Q", ParamDomainValue.POS_NULL, rQ, ParamFamily.FLOWS);
                 this._If = new ParamDefinition(this, "If", ParamDomainValue.ANY, rIf, ParamFamily.SLOPES);
                 this._YB = new ParamDefinition(this, "YB", ParamDomainValue.POS, rYB, ParamFamily.HEIGHTS);
+                this._Y = new ParamDefinition(this, "Y", ParamDomainValue.POS_NULL, rY, ParamFamily.HEIGHTS);
+                this._LargeurBerge = new ParamDefinition(
+                    this, "LargeurBerge", ParamDomainValue.POS_NULL, rLargeurBerge, ParamFamily.WIDTHS);
+
+                this._iPrec = Math.round(-Math.log(this.Pr.v) / Math.log(10));
 
                 this.addParamDefinition(this._Ks);
                 this.addParamDefinition(this._Q);
                 this.addParamDefinition(this._If);
                 this.addParamDefinition(this._YB);
+                this.addParamDefinition(this._Y);
+                this.addParamDefinition(this._LargeurBerge);
 
-                this._iPrec = Math.round(-Math.log(this.Pr.v) / Math.log(10));
+                if (rY === undefined) { // avoid undefined on Swap()
+                    this._Y.v = 1E6;
+                }
         }
 
         /**
@@ -68,32 +85,6 @@ export abstract class cParamsCanal extends ParamsEquation {
         get YB(): ParamDefinition {
                 return this._YB;
         }
-}
-
-// tslint:disable-next-line:max-classes-per-file
-export abstract class ParamsSection extends cParamsCanal {
-        private _Y: ParamDefinition;          // Tirant d'eau
-        private _LargeurBerge: ParamDefinition; // largeur au débordement
-
-        constructor(rY: number,
-                    rLargeurBerge: number,
-                    rKs: number,
-                    rQ: number,
-                    rIf: number,
-                    rYB: number
-        ) {
-                super(rKs, rQ, rIf, rYB);
-                this._Y = new ParamDefinition(this, "Y", ParamDomainValue.POS_NULL, rY, ParamFamily.HEIGHTS);
-                this._LargeurBerge = new ParamDefinition(
-                    this, "LargeurBerge", ParamDomainValue.POS_NULL, rLargeurBerge, ParamFamily.WIDTHS);
-
-                if (rY === undefined) { // avoid undefined on Swap()
-                    this._Y.v = 1E6;
-                }
-
-                this.addParamDefinition(this._Y);
-                this.addParamDefinition(this._LargeurBerge);
-        }
 
         /**
          * Tirant d'eau
@@ -115,7 +106,7 @@ export abstract class ParamsSection extends cParamsCanal {
  * Comprend les formules pour la section rectangulaire pour gérer les débordements
  */
 // tslint:disable-next-line:max-classes-per-file class-name
-export abstract class acSection extends ComputeNode {
+export abstract class acSection extends Nub {
         [key: string]: any; // pour pouvoir faire this['methode]();
 
         get prms(): ParamsSection {
@@ -136,6 +127,8 @@ export abstract class acSection extends ComputeNode {
         protected bSnFermee: boolean = false;
         protected arCalcGeo: { [key: string]: number } = {}; /// Données ne dépendant pas de la cote de l'eau
 
+        protected _nodeType: ComputeNodeType;
+
         private _hautCritique: Result;  // Tirant d'eau critique
 
         /**
@@ -176,15 +169,46 @@ export abstract class acSection extends ComputeNode {
          */
         constructor(prms: ParamsSection, dbg: boolean = false) {
                 super(prms, dbg);
+                this._calcType = CalculatorType.Section;
+                this._newtonDbg = dbg;
+        }
 
-                // this._v = oP.v;  // copie la référence au tableau
-                // this.prms.Y.v = 0;
-                // this.prms.LargeurBerge.v = 0;
+        public get nodeType() {
+                return this._nodeType;
+        }
 
-                // this.CalcGeo("B");  // à ce point, il manque des paramètres pour certaines
-                // sections (ex : fruit pour trapèze)
+        /** Returns Props object (observable set of key-values) associated to this Nub */
+        public get properties(): Props {
+            // completes props with calcType and nodeType if not already set
+            this._props.setPropValue("calcType", this.calcType);
+            this._props.setPropValue("nodeType", this.nodeType);
+            return this._props;
+        }
 
-                this._newtonDbg = dbg;
+        // setter is not inherited from Nub if getter is redefined :/
+        public set properties(props: Props) {
+            this._props = props.clone();
+        }
+
+        /**
+         * Forwards to parent, that has vsibility over
+         * all the parameters, including the Section ones
+         */
+        public get calculatedParam(): ParamDefinition {
+            if (this.parent) {
+                return this.parent.calculatedParam;
+            }
+            return undefined;
+        }
+
+        /**
+         * Forwards to parent, that has vsibility over
+         * all the parameters, including the Section ones
+         */
+        public set calculatedParam(p: ParamDefinition) {
+            if (this.parent) {
+                this.parent.calculatedParam = p;
+            }
         }
 
         public clone(): acSection {
@@ -208,6 +232,17 @@ export abstract class acSection extends ComputeNode {
                 super.debug(this.calcIndent() + m);
         }
 
+        /**
+         * The parent is the Nub that holds the parameter to calculate;
+         * ask it to perform calculation and copy its result to local
+         * result, to facilitate values reading by targetting modules
+         * (used by triggerChainCalculation)
+         */
+        public CalcSerie(rInit?: number, sDonnee?: any): Result {
+                this._result = this.parent.CalcSerie(rInit, sDonnee);
+                return this._result;
+        }
+
         /**
          * Calcul des données à la section
          * effectue un reset du cache des résultats
@@ -215,13 +250,26 @@ export abstract class acSection extends ComputeNode {
          * @param rY valeur de Y à utiliser
          * @return la donnée calculée
          */
-        public Calc(sDonnee: string, rY?: number): Result {
+        public CalcSection(sDonnee: string, rY?: number): Result {
                 this.debug(`Calc(${sDonnee},${rY})`);
                 this._indentCalc = -1;
                 this.Reset(true);
                 return this.calcFromY(sDonnee, rY);
         }
 
+        /**
+         * Proxy to parent SectionNub, to compute non-hydraulic variables
+         * @param sVarCalc
+         * @param rInit
+         */
+        public Calc(sVarCalc?: string, rInit?: number): Result {
+                return this.parent.Calc(sVarCalc, rInit);
+        }
+
+        public Equation(sVarCalc: string): Result {
+                throw new Error("acSection.Equation() : cannot be called");
+        }
+
         protected setParametersCalculability() {
                 this.prms.Ks.calculability = ParamCalculability.DICHO;
                 this.prms.Q.calculability = ParamCalculability.DICHO;
@@ -617,7 +665,7 @@ export abstract class acSection extends ComputeNode {
                         return rB;
                 }
 
-                const v = this.prms.Q.v / rS.vCalc * Math.sqrt(rB.vCalc / rS.vCalc / cParamsCanal.G);
+                const v = this.prms.Q.v / rS.vCalc * Math.sqrt(rB.vCalc / rS.vCalc / ParamsSection.G);
                 return new Result(v);
         }
 
@@ -670,7 +718,7 @@ export abstract class acSection extends ComputeNode {
                         return rV;
                 }
 
-                const v = this.prms.Y.v + Math.pow(rV.vCalc, 2) / (2 * cParamsCanal.G);
+                const v = this.prms.Y.v + Math.pow(rV.vCalc, 2) / (2 * ParamsSection.G);
                 return new Result(v);
         }
 
@@ -868,7 +916,7 @@ export abstract class acSection extends ComputeNode {
                         return rJ;
                 }
 
-                return new Result(1000 * cParamsCanal.G * rR.vCalc * rJ.vCalc);
+                return new Result(1000 * ParamsSection.G * rR.vCalc * rJ.vCalc);
         }
 
         /**
@@ -886,7 +934,7 @@ export abstract class acSection extends ComputeNode {
                         return rSYG;
                 }
 
-                const v = 1000 * (this.prms.Q.v * rV.vCalc + cParamsCanal.G * rSYG.vCalc);
+                const v = 1000 * (this.prms.Q.v * rV.vCalc + ParamsSection.G * rSYG.vCalc);
                 return new Result(v);
         }
 }
diff --git a/src/session.ts b/src/session.ts
index 9babc28dd090f68f3fface18650ac724c7dd12d7..6f9afebe1b84d74eec17cfafd1b41ec8ae0d1b5b 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -6,14 +6,13 @@ import { Props } from "./props";
 import { ConduiteDistrib, ConduiteDistribParams } from "./cond_distri";
 import { LechaptCalmon, LechaptCalmonParams } from "./lechaptcalmon";
 import { MacroRugo, MacrorugoParams } from "./macrorugo/macrorugo";
+import { PabChute, PabChuteParams } from "./pab/pab_chute";
 import { PabDimension, PabDimensionParams } from "./pab/pab_dimension";
+import { PabNombre, PabNombreParams } from "./pab/pab_nombre";
 import { PabPuissance, PabPuissanceParams } from "./pab/pab_puissance";
 import { RegimeUniforme } from "./regime_uniforme";
 import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "./remous";
 import { SectionParametree } from "./section/section_parametree";
-import { Cloisons, CloisonsParams } from "./structure/cloisons";
-import { Dever, DeverParams } from "./structure/dever";
-import { ParallelStructure, ParallelStructureParams } from "./structure/parallel_structure";
 
 // Classes relatives aux sections
 import { cSnCirc, ParamsSectionCirc } from "./section/section_circulaire";
@@ -24,12 +23,14 @@ import { acSection } from "./section/section_type";
 
 // Classes relatives aux structures
 import { LinkedValue } from "./linked-value";
-import { PabChute, PabChuteParams } from "./pab/pab_chute";
-import { PabNombre, PabNombreParams } from "./pab/pab_nombre";
 import { ParamDefinition } from "./param/param-definition";
+import { Cloisons } from "./structure/cloisons";
+import { CloisonsParams } from "./structure/cloisons_params";
+import { Dever, DeverParams } from "./structure/dever";
 import { CreateStructure } from "./structure/factory_structure";
+import { ParallelStructure, ParallelStructureParams } from "./structure/parallel_structure";
 import { Structure } from "./structure/structure";
-import { LoiDebit, StructureType } from "./structure/structure_props";
+import { LoiDebit } from "./structure/structure_props";
 
 export class Session {
 
@@ -83,37 +84,6 @@ export class Session {
         return this._nubs.length;
     }
 
-    /**
-     * Remplace un Nub par un nouveau dans la session, en conservant son UID (utile pour les Structure dans
-     * les Nub de types parallèle)
-     * @param sn Nub à remplacer
-     * @param params propriété du nouveau Nub
-     */
-    public replaceNub(sn: Nub, params: Props): Nub {
-        let i = 0;
-        const olduid: string = sn.uid;
-        for (const n of this._nubs) {
-            if (n.uid === olduid) {
-                const newNub = this.createNub(params);
-                newNub.setUid(olduid); // should never lead to any collision
-                this._nubs[i] = newNub;
-                // move structure inside parent
-                if (sn instanceof Structure) {
-                    const struct = sn as Structure;
-                    if (struct.parent) {
-                        struct.parent.replaceStructureInplace(struct, newNub as Structure);
-                    } else {
-                        throw new Error("Structure nub had no parent");
-                    }
-                }
-                return newNub;
-            }
-            i++;
-        }
-        // pas trouvé
-        return undefined;
-    }
-
     /**
      * Removes a Nub from the session; does not consider Structure nubs inside Calculator nubs
      * @param sn the Nub to remove from the session
@@ -211,7 +181,7 @@ export class Session {
      *        - nodeType: sous type de Nub
      * @param dbg activer débogage
      */
-    public createNub(params: Props, parentNub?: ParallelStructure, dbg: boolean = false): Nub {
+    public createNub(params: Props, parentNub?: Nub, dbg: boolean = false): Nub {
         const calcType: CalculatorType = params.getPropValue("calcType");
         const nodeType: ComputeNodeType = params.getPropValue("nodeType");
 
@@ -221,7 +191,8 @@ export class Session {
         switch (calcType) {
             case CalculatorType.ConduiteDistributrice:
             {
-                prms = new ConduiteDistribParams(3, // débit Q
+                prms = new ConduiteDistribParams(
+                    3, // débit Q
                     1.2, // diamètre D
                     0.6, // perte de charge J
                     100, // Longueur de la conduite Lg
@@ -233,7 +204,8 @@ export class Session {
 
             case CalculatorType.LechaptCalmon:
             {
-                prms = new LechaptCalmonParams(3, // débit
+                prms = new LechaptCalmonParams(
+                    3, // débit
                     1.2, // diamètre
                     0.6, /// perte de charge
                     100, // longueur du toyo
@@ -247,27 +219,25 @@ export class Session {
 
             case CalculatorType.SectionParametree:
             {
-                nub = new SectionParametree(this.createSection(nodeType, dbg), dbg);
+                nub = new SectionParametree(undefined, dbg);
                 break;
             }
 
             case CalculatorType.RegimeUniforme:
             {
-                const sect: acSection = this.createSection(nodeType, dbg);
-                const ru = new RegimeUniforme(sect, dbg);
-                nub = ru;
+                nub = new RegimeUniforme(undefined, dbg);
                 break;
             }
 
             case CalculatorType.CourbeRemous:
             {
-                const sectCR: acSection = this.createSection(nodeType, dbg);
-                prms = new CourbeRemousParams(0.15, // Yamont = tirant amont
+                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(sectCR, prms, MethodeResolution.EulerExplicite, dbg);
+                nub = new CourbeRemous(undefined, prms, MethodeResolution.EulerExplicite, dbg);
                 break;
             }
 
@@ -297,15 +267,15 @@ export class Session {
 
             case CalculatorType.Structure:
             {
-                const structType: StructureType = params.getPropValue("structureType");
                 const loiDebit: LoiDebit = params.getPropValue("loiDebit");
-                nub = CreateStructure(structType, loiDebit, parentNub);
+                nub = CreateStructure(loiDebit, (parentNub as ParallelStructure));
                 break;
             }
 
             case CalculatorType.ParallelStructure:
             {
-                prms = new ParallelStructureParams(0.5, // Q
+                prms = new ParallelStructureParams(
+                    0.5, // Q
                     102, // Z1
                     101.5 // Z2
                 );
@@ -315,7 +285,8 @@ export class Session {
 
             case CalculatorType.Dever:
             {
-                const deverPrms = new DeverParams(0.5, // Q
+                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
@@ -383,6 +354,12 @@ export class Session {
                 break;
             }
 
+            case CalculatorType.Section:
+            {
+                nub = this.createSection(nodeType, dbg);
+                break;
+            }
+
             default:
             {
                 throw new Error(
@@ -445,6 +422,9 @@ export class Session {
             const linkableValues = n.getLinkableValues(p);
             res = res.concat(linkableValues);
         }
+        /* console.log("LINKABLE VALUES", res.map((lv) => {
+            return `${lv.nub.uid}(${lv.nub.constructor.name})/${lv.symbol}`;
+        })); */
         return res;
     }
 
diff --git a/src/structure/cloisons.ts b/src/structure/cloisons.ts
index 0b335418ae610b8b35d20560aacb57416d0a42a9..bfc110a8e1a665d36a349fe34a86df858d7b816b 100644
--- a/src/structure/cloisons.ts
+++ b/src/structure/cloisons.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "../compute-node";
 import { PabPuissance, PabPuissanceParams } from "../pab/pab_puissance";
 import { ParamCalculability } from "../param/param-definition";
 import { Result } from "../util/result";
@@ -6,11 +7,10 @@ import { ParallelStructure } from "./parallel_structure";
 import { StructureKiviParams } from "./structure_kivi";
 import { loiAdmissiblesCloisons, LoiDebit } from "./structure_props";
 
-export { CloisonsParams };
-
 export class Cloisons extends ParallelStructure {
     constructor(prms: CloisonsParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._calcType = CalculatorType.Cloisons;
     }
 
     /**
@@ -112,7 +112,7 @@ export class Cloisons extends ParallelStructure {
     }
 
     private updateKiviZRAM() {
-        for (const structure of this._structures) {
+        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/dever.ts b/src/structure/dever.ts
index 4af0244f17285ba418d5c9b052d8595158d625e4..fedcf19599084101a75386072526d3feee0eaba2 100644
--- a/src/structure/dever.ts
+++ b/src/structure/dever.ts
@@ -1,3 +1,4 @@
+import { CalculatorType } from "../compute-node";
 import { ParamCalculability, ParamFamily } from "../param/param-definition";
 import { Result } from "../util/result";
 import { DeverParams } from "./dever_params";
@@ -9,6 +10,7 @@ export { DeverParams };
 export class Dever extends ParallelStructure {
     constructor(prms: DeverParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._calcType = CalculatorType.Dever;
     }
 
     /**
@@ -107,7 +109,7 @@ export class Dever extends ParallelStructure {
      */
     private calcA(): number {
         let A: number = 0;
-        for (const st of this._structures) {
+        for (const st of this.structures) {
             A += st.calcA();
         }
         return A;
diff --git a/src/structure/factory_structure.ts b/src/structure/factory_structure.ts
index d486982f47a052c96b99b150f967f587ae2b234e..f1f0b7c069d03772125befd1885995c09e1be794 100644
--- a/src/structure/factory_structure.ts
+++ b/src/structure/factory_structure.ts
@@ -1,10 +1,9 @@
-import { CalculatorType } from "../compute-node";
 import { ParallelStructure } from "./parallel_structure";
 
 // Classes générales sur les structures
 import { RectangularStructureParams } from "./rectangular_structure_params";
 import { Structure } from "./structure";
-import { LoiDebit, StructureProperties, StructureType } from "./structure_props";
+import { LoiDebit } from "./structure_props";
 
 // Equations de débit
 import { StructureGateCem88d, StructureWeirCem88d } from "./structure_cem88d";
@@ -20,7 +19,7 @@ import { StructureTriangularWeirFree, TriangularStructureParams } from "./struct
 import { StructureWeirFree } from "./structure_weir_free";
 import { StructureWeirSubmergedLarinier } from "./structure_weir_submerged_larinier";
 
-export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit, parentNub?: ParallelStructure,
+export function CreateStructure(loiDebit: LoiDebit, parentNub?: ParallelStructure,
                                 dbg: boolean = false): Structure {
     const oCd: {[s: string]: number} = {SeuilR: 0.4, VanneR: 0.6, SeuilT: 1.36};
     const rectStructPrms: RectangularStructureParams = new RectangularStructureParams(
@@ -34,28 +33,14 @@ export function CreateStructure(structureType: StructureType, loiDebit: LoiDebit
     );
 
     // Control of validity of structure type and definition of parameters
-    switch (structureType) {
-        case StructureType.VanneRectangulaire:
+    switch (loiDebit) {
+        case LoiDebit.GateCem88d:
+        case LoiDebit.GateCem88v:
+        case LoiDebit.Cunge80:
+        case LoiDebit.RectangularOrificeFree:
+        case LoiDebit.RectangularOrificeSubmerged:
             rectStructPrms.W.v = 0.5;
             rectStructPrms.Cd.v = oCd.VanneR; // Cd pour une vanne rectangulaire
-            break;
-        case StructureType.SeuilRectangulaire:
-        case StructureType.SeuilTriangulaire:
-        case StructureType.SeuilTriangulaireTrunc:
-        case StructureType.Orifice:
-            break;
-
-        default:
-            throw new Error(`type de structure ${StructureType[structureType]} non pris en charge`);
-    }
-
-    // Control validity of the triple Parnet Nub type / Structure Type / Discharge equation
-    if (!(StructureProperties.isCompatibleValues(structureType, loiDebit, parentNub))) {
-        const parentNubType: CalculatorType = (CalculatorType as any)[parentNub.calcType];
-        throw new Error(
-            `La loi de débit ${LoiDebit[loiDebit]} n'est pas admissible pour le type ${StructureType[structureType]}`
-            + ` dans le module ${parentNubType}`
-        );
     }
 
     // Instanciation of the equation
diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts
index 51cf032f1e7dc71b850b9ce557b59cd9336d5ce9..481df778c6f49ace03a719485867231d24a65dda 100644
--- a/src/structure/parallel_structure.ts
+++ b/src/structure/parallel_structure.ts
@@ -1,7 +1,7 @@
+import { CalculatorType } from "../compute-node";
 import { Nub } from "../nub";
 import { ParamCalculability } from "../param/param-definition";
-import { IParamDefinitionIterator, ParamsEquation, ParamsEquationArrayIterator } from "../param/params-equation";
-import { Props } from "../props";
+import { ParamsEquation } from "../param/params-equation";
 import { Session } from "../session";
 import { Result } from "../util/result";
 import { ParallelStructureParams } from "./parallel_structure_params";
@@ -17,12 +17,14 @@ export { ParallelStructureParams };
  */
 export class ParallelStructure extends Nub {
 
-    /** Tableau des structures hydrauliques en parallèle */
-    protected _structures: Structure[] = [];
+    constructor(prms: ParamsEquation, dbg: boolean = false) {
+        super(prms, dbg);
+        this._calcType = CalculatorType.ParallelStructure;
+    }
 
-    /** getter only makes it kind of readonly */
+    /** children casting */
     public get structures() {
-        return this._structures;
+        return this._children as Structure[];
     }
 
     /**
@@ -52,154 +54,6 @@ export class ParallelStructure extends Nub {
         this.updateStructuresH1H2();
     }
 
-    /**
-     * Itérateur sur tous les paramètres du Nub, plus tous les paramètres de
-     * toutes les structures en parallèle
-     */
-    public get parameterIterator(): IParamDefinitionIterator {
-        const prms: ParamsEquation[] = [];
-        prms.push(this._prms);
-        if (this._structures) { // if called within constructor, default class member value is not set yet
-            for (const st of this._structures) {
-                prms.push(st.prms);
-            }
-        }
-        return new ParamsEquationArrayIterator(prms);
-    }
-
-    /**
-     * Ajout d'une structure en parallèle
-     * @param structure La structure à rajouter
-     * @param after position après laquelle insérer la structure, à la fin sinon
-     */
-    public addStructure(structure: Structure, after?: number) {
-        if (after !== undefined) {
-            this._structures.splice(after + 1, 0, structure);
-        } else {
-            this._structures.push(structure);
-        }
-        // add reference to parent collection (this)
-        structure.parent = this;
-        // propagate precision
-        structure.prms.Pr.setValue(this.prms.Pr.v); // does not write to .v to bypass calculability control
-    }
-
-    /**
-     * remplace une structure hydraulique
-     * @param index indice de la structure dans le tableau
-     * @param structure nouvelle structure
-     * @param resetCalcParam if true, resets default calculated parameter after replacing structure
-     */
-    public replaceStructure(index: number, structure: Structure, resetCalcParam: boolean = false) {
-        if (index > -1 && index < this._structures.length) {
-            this._structures[index] = structure;
-        } else {
-            throw new Error(`ParallelStructure.replaceStructure invalid index ${index}`);
-        }
-        if (resetCalcParam) {
-            this.resetDefaultCalculatedParam();
-        }
-        // add reference to parent collection (this)
-        structure.parent = this;
-    }
-
-    /**
-     * Finds oldStructure in the list, and replaces it (at the same index) with newStructure;
-     * if the current calculated parameter belonged to the old structure, resets a default one
-     * @param oldStructure Structure to get the index for
-     * @param newStructure Structure to set at this index
-     */
-    public replaceStructureInplace(oldStructure: Structure, newStructure: Structure) {
-        const calcParamLost = (
-            typeof this.calculatedParamDescriptor !== "string"
-            && this.calculatedParamDescriptor.uid === oldStructure.uid
-        );
-        const index = this.getIndexForStructure(oldStructure);
-        if (index === -1) {
-            throw new Error("old Structure not found");
-        }
-        this.replaceStructure(index, newStructure, calcParamLost);
-    }
-
-    /**
-     * Returns the current index of the given structure if any,
-     * or else returns -1
-     * @param structure Structure or Structure UID to look for
-     */
-    public getIndexForStructure(structure: Structure | string): number {
-        let index: number = -1;
-        const uid = (structure instanceof Structure) ? structure.uid : structure;
-        for (let i = 0; i < this._structures.length; i++) {
-            if (this._structures[i].uid === uid) {
-                index = i;
-            }
-        }
-        return index;
-    }
-
-    /**
-     * @return true si la structure donnée est dans la liste
-     */
-    public hasStructure(structure: Nub): boolean {
-        return this.hasStructureUid(structure.uid);
-    }
-
-    /**
-     * @return true si la structure donnée est dans la liste
-     */
-    public hasStructureUid(structureUid: string): boolean {
-        for (const s of this._structures) {
-            if (s.uid === structureUid) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * déplace une structure d'une position vers le début de la liste
-     */
-    public moveStructureUp(structure: Structure) {
-        let i = 0;
-        for (const s of this._structures) {
-            if (s.uid === structure.uid && i > 0) {
-                const t = this._structures[i - 1];
-                this._structures[i - 1] = this._structures[i];
-                this._structures[i] = t;
-                return;
-            }
-            i++;
-        }
-    }
-
-    /**
-     * déplace une structure d'une position vers la fin de la liste
-     */
-    public moveStructureDown(structure: Structure) {
-        let i = 0;
-        for (const s of this._structures) {
-            if (s.uid === structure.uid && i < this._structures.length - 1) {
-                const t = this._structures[i];
-                this._structures[i] = this._structures[i + 1];
-                this._structures[i + 1] = t;
-                return;
-            }
-            i++;
-        }
-    }
-
-    /**
-     * 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)
@@ -216,17 +70,17 @@ export class ParallelStructure extends Nub {
      */
     public CalcQ(iExcept?: number): Result {
         if (iExcept !== undefined) {
-            if (iExcept < 0 || iExcept >= this._structures.length) {
+            if (iExcept < 0 || iExcept >= this._children.length) {
                 throw new Error(
-                    "ParallelStructure.CalcQ iExcept not in [0;" + (this._structures.length - 1) + "]",
+                    "ParallelStructure.CalcQ iExcept not in [0;" + (this._children.length - 1) + "]",
                 );
             }
         }
         const calcRes: Result = new Result(0, this);
         let qTot: number = 0;
-        for (let i = 0; i < this._structures.length; i++) {
+        for (let i = 0; i < this._children.length; i++) {
             if (i !== iExcept) {
-                const res: Result = this._structures[i].Calc("Q");
+                const res: Result = this._children[i].Calc("Q");
                 calcRes.resultElement.AddResultElementToExtra(res.resultElement, `ouvrage[${i}].Q`);
                 qTot += res.vCalc;
             }
@@ -259,12 +113,12 @@ export class ParallelStructure extends Nub {
                     throw new Error("ParallelStructures.Calc() : unknow parameter to calculate " + sVarCalc);
                 }
                 // Pour les caractéristiques des ouvrages
-                const structureIndex = this.getIndexForStructure(sVarCalc.uid);
+                const structureIndex = this.getIndexForChild(sVarCalc.uid);
                 res = this.CalcStructPrm(structureIndex, sVarCalc.symbol);
                 // Suppression des extraResults : ils sont complétés plus bas pour chaque ouvrage
                 res.resultElement.extraResults = {};
                 if (res.ok) {
-                    this._structures[structureIndex].getParameter(sVarCalc.symbol).setValue(res.vCalc);
+                    this._children[structureIndex].getParameter(sVarCalc.symbol).setValue(res.vCalc);
                 }
         }
         if (res.ok) {
@@ -280,70 +134,6 @@ export class ParallelStructure extends Nub {
         return res;
     }
 
-    public getChildren(): Nub[] {
-        return this.structures;
-    }
-
-    public getParent(): Nub {
-        return undefined;
-    }
-
-    /**
-     * Returns an object representation of the Nub's current state; compared to generic
-     * Nub::objectRepresentation(), represents the parallel structures in a specific way
-     * @param extra extra key-value pairs, for ex. calculator title in GUI
-     */
-    public objectRepresentation(extra?: object) {
-        let ret: any = {
-            uid: this.uid,
-            props: this.getPropertiesData(),
-        };
-        if (extra) {
-            ret =  {...ret, ...{ meta: extra } }; // merge properties
-        }
-        // extend here to make "structures" and "parameters" the down-most keys
-        ret = {...ret, ...{ structures: [], parameters: [] } };
-
-        // iterate over parameters
-        const localParametersIterator =  new ParamsEquationArrayIterator([this._prms]);
-        for (const p of localParametersIterator) {
-            if (p.visible) {
-                ret.parameters.push(p.objectRepresentation());
-            }
-        }
-
-        // iterate over parallel structures
-        for (const struct of this._structures) {
-            ret.structures.push(struct.objectRepresentation());
-        }
-
-        return ret;
-    }
-
-    /**
-     * Fills the current Nub with parameter values, provided an object representation
-     * @param obj object representation of a Nub content (parameters, structures)
-     */
-    public loadObjectRepresentation(obj: any) {
-        // load regular Nub contents (parameters)
-        super.loadObjectRepresentation(obj);
-
-        // iterate over structures if any
-        if (obj.structures && Array.isArray(obj.structures)) {
-            for (const s of obj.structures) {
-                // create the Nub
-                const subNub = Session.getInstance().createNub(new Props(s.props), this);
-                // try to keep the original ID
-                if (! Session.getInstance().uidAlreadyUsed(s.uid)) {
-                    subNub.setUid(s.uid);
-                }
-                subNub.loadObjectRepresentation(s);
-                // add Structure to parent
-                this.addStructure(subNub as Structure);
-            }
-        }
-    }
-
     /**
      * Once session is loaded, run a second pass on all linked parameters to
      * reset their target if needed
@@ -375,7 +165,7 @@ export class ParallelStructure extends Nub {
      * Mise à jour de Z1, Z2, h1 et h2 pour tous les ouvrages
      */
     protected updateStructuresH1H2() {
-        for (const structure of this._structures) {
+        for (const structure of this.structures) {
             structure.prms.Z1.v = this.prms.Z1.v;
             structure.prms.Z2.v = this.prms.Z2.v;
             structure.prms.update_h1h2();
@@ -389,10 +179,10 @@ export class ParallelStructure extends Nub {
      */
     protected CalcStructPrm(index: number, symbol: string, rInit?: number): Result {
         // Le débit restant sur la structure en calcul est :
-        this._structures[index].prms.Q.setValue(this.prms.Q.v - this.CalcQ(index).vCalc);
+        this.structures[index].prms.Q.setValue(this.prms.Q.v - this.CalcQ(index).vCalc);
 
         // Calcul du paramètre de la structure en calcul
-        return this._structures[index].Calc(symbol, rInit);
+        return this.structures[index].Calc(symbol, rInit);
     }
 
 }
diff --git a/src/structure/structure.ts b/src/structure/structure.ts
index dd72feb87b33924e714be3b167714802e0902b73..c92d5e381cebcb8b3c820252c6b7cf00b027ea04 100644
--- a/src/structure/structure.ts
+++ b/src/structure/structure.ts
@@ -1,10 +1,12 @@
+import { CalculatorType } from "../compute-node";
 import { Nub } from "../nub";
 import { ParamCalculability, ParamDefinition } from "../param/param-definition";
 import { ParamValueMode } from "../param/param-value-mode";
+import { Props } from "../props";
 import { Message, MessageCode } from "../util/message";
 import { Result } from "../util/result";
-import { ParallelStructure } from "./parallel_structure";
 import { StructureParams } from "./structure_params";
+import { LoiDebit } from "./structure_props";
 
 export { StructureParams };
 
@@ -61,14 +63,14 @@ export abstract class Structure extends Nub {
     /** Constante utile : Racine de 2g */
     protected static readonly R2G: number = Math.sqrt(2 * 9.81);
 
-    /** pointer to collection of structures */
-    public parent: ParallelStructure;
-
     /** Peut-on calculer ZDV ? */
     protected _isZDVcalculable: boolean;
 
+    protected _loiDebit: LoiDebit;
+
     constructor(prms: StructureParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._calcType = CalculatorType.Structure;
         this._isZDVcalculable = true;
         // Q is always the only calculated variable; setting another parameter
         // of a Structure to CALC mode makes it the calculated variable of the
@@ -76,6 +78,19 @@ export abstract class Structure extends Nub {
         this.calculatedParam = this.prms.Q;
     }
 
+    /** Returns Props object (observable set of key-values) associated to this Nub */
+    public get properties(): Props {
+        // completes props with calcType and nodeType if not already set
+        this._props.setPropValue("calcType", this.calcType);
+        this._props.setPropValue("loiDebit", this._loiDebit);
+        return this._props;
+    }
+
+    // setter is not inherited from Nub if getter is redefined :/
+    public set properties(props: Props) {
+        this._props = props.clone();
+    }
+
     get isZDVcalculable(): boolean {
         return this._isZDVcalculable;
     }
@@ -139,17 +154,6 @@ export abstract class Structure extends Nub {
         }
     }
 
-    /**
-     * Returns the position or the current structure (starting at 0) in the parent ParallelStructure
-     */
-    public findPositionInParent(): number {
-        return this.parent.getIndexForStructure(this);
-    }
-
-    public getParent(): Nub {
-        return this.parent;
-    }
-
     /**
      * Calcul de l'aire d'écoulement sur le seuil ou dans l'orifice
      */
diff --git a/src/structure/structure_cem88d.ts b/src/structure/structure_cem88d.ts
index 94079c526d81621763b27967b214ebca251dd4be..8c08a710694713d4cc809de003996e08f22f269d 100644
--- a/src/structure/structure_cem88d.ts
+++ b/src/structure/structure_cem88d.ts
@@ -2,6 +2,7 @@ import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
 import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
 
 export { RectangularStructureParams };
 
@@ -14,6 +15,7 @@ export class StructureWeirCem88d extends RectangularStructure {
 
     constructor(prms: RectangularStructureParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.WeirCem88d;
         if (prms.W.v !== Infinity) {
             this._isZDVcalculable = false;
         }
@@ -73,6 +75,7 @@ export class StructureGateCem88d extends StructureWeirCem88d {
 
     constructor(prms: RectangularStructureParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.GateCem88d;
         // afficher l'ouverture de vanne
         this.prms.W.visible = true;
     }
diff --git a/src/structure/structure_cem88v.ts b/src/structure/structure_cem88v.ts
index 886ee53dbe5bdf8b58f4e8622f0912756d276af6..f02f9f33d1ad74584231ff71ba53c300ea7dc7d0 100644
--- a/src/structure/structure_cem88v.ts
+++ b/src/structure/structure_cem88v.ts
@@ -2,6 +2,7 @@ import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
 import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
 
 export { RectangularStructureParams };
 
@@ -10,6 +11,11 @@ export { RectangularStructureParams };
  */
 export class StructureWeirCem88v extends RectangularStructure {
 
+    constructor(prms: RectangularStructureParams, dbg: boolean = false) {
+        super(prms, dbg);
+        this._loiDebit = LoiDebit.WeirCem88v;
+    }
+
     /**
      * Calcul analytique Q = f(Cd, L, h1, h2, W) CEM88V
      * @param sVarCalc Variable à calculer (doit être "Q")
@@ -133,6 +139,7 @@ export class StructureGateCem88v extends StructureWeirCem88v {
 
     constructor(prms: RectangularStructureParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.GateCem88v;
         // afficher l'ouverture de vanne
         this.prms.W.visible = true;
     }
diff --git a/src/structure/structure_cunge80.ts b/src/structure/structure_cunge80.ts
index 7da977193f6df78202d3d744dcc2ad841c7c8635..a6196e6217539d5320ae1b44749f17c2901abf48 100644
--- a/src/structure/structure_cunge80.ts
+++ b/src/structure/structure_cunge80.ts
@@ -2,6 +2,7 @@ import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
 import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
 
 export { RectangularStructureParams };
 
@@ -12,6 +13,7 @@ export class StructureCunge80 extends RectangularStructure {
 
     constructor(prms: RectangularStructureParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.Cunge80;
         if (prms.W.v !== Infinity) {
             this._isZDVcalculable = false;
         }
diff --git a/src/structure/structure_kivi.ts b/src/structure/structure_kivi.ts
index 06de167a2ff5877aaeab5e533b76ead933316fc6..7bbbaccbf369fd9a52b0ae52be69763a9595414f 100644
--- a/src/structure/structure_kivi.ts
+++ b/src/structure/structure_kivi.ts
@@ -3,6 +3,7 @@ import { Message, MessageCode } from "../util/message";
 import { Result } from "../util/result";
 import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
 import { StructureKiviParams } from "./structure_kivi_params";
+import { LoiDebit } from "./structure_props";
 import { Villemonte } from "./villemonte";
 
 export { StructureKiviParams };
@@ -11,6 +12,7 @@ export class StructureKivi extends Structure {
 
     constructor(prms: StructureKiviParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.KIVI;
     }
 
     /**
diff --git a/src/structure/structure_orifice_submerged.ts b/src/structure/structure_orifice_submerged.ts
index 67ec3d61e4723bea80341a4c0b8efaa443ac3c06..ebbd4a20acaba8e0168f067c073159bbb0aa2db0 100644
--- a/src/structure/structure_orifice_submerged.ts
+++ b/src/structure/structure_orifice_submerged.ts
@@ -2,6 +2,7 @@ import { ParamCalculability } from "../param/param-definition";
 import { Structure, StructureFlowMode, StructureFlowRegime } from "../structure/structure";
 import { Result } from "../util/result";
 import { StructureOrificeSubmergedParams } from "./structure_orifice_submerged_params";
+import { LoiDebit } from "./structure_props";
 
 export { StructureOrificeSubmergedParams };
 
@@ -12,6 +13,7 @@ export class StructureOrificeSubmerged extends Structure {
 
     constructor(prms: StructureOrificeSubmergedParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.OrificeSubmerged;
         this._isZDVcalculable = false;
     }
 
diff --git a/src/structure/structure_props.ts b/src/structure/structure_props.ts
index 9b2ab5a0c2509792d6a6ac78b9cdd41697c33d0b..5c366ecf2b05673a42c82d9b3bd1e617ea609502 100644
--- a/src/structure/structure_props.ts
+++ b/src/structure/structure_props.ts
@@ -112,12 +112,12 @@ export class StructureProperties {
      */
     public static findCompatibleLoiDebit(struct: StructureType, subset: LoiDebit[],
                                          parentNub: ParallelStructure): LoiDebit {
+
         const sst: string = StructureType[struct];
-        if (subset.length === 0) {
-            return parentNub.getLoisAdmissibles()[sst][0];
-        }
-        for (const ld of parentNub.getLoisAdmissibles()[sst]) {
-            if (subset.includes(ld)) {
+        const lois = parentNub.getLoisAdmissibles();
+
+        for (const ld of lois[sst]) {
+            if (subset.length === 0 || subset.includes(ld)) {
                 return ld;
             }
         }
diff --git a/src/structure/structure_rectangular_orifice_free.ts b/src/structure/structure_rectangular_orifice_free.ts
index 5b89e0a2c9b51e812676f443487ce58adb75dd58..22212ec0133b1bd02cf1e26b9174830e4dc21040 100644
--- a/src/structure/structure_rectangular_orifice_free.ts
+++ b/src/structure/structure_rectangular_orifice_free.ts
@@ -2,6 +2,7 @@ import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
 import { Structure, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
 
 export { RectangularStructureParams };
 
@@ -12,6 +13,7 @@ export class StructureRectangularOrificeFree extends RectangularStructure {
 
     constructor(prms: RectangularStructureParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.RectangularOrificeFree;
         this.prms.W.visible = true;
     }
 
diff --git a/src/structure/structure_rectangular_orifice_submerged.ts b/src/structure/structure_rectangular_orifice_submerged.ts
index bb71b307d9cedf55ddbc52402dd21c98f858efa8..6c278cc6d14291cca136b721d08f2863f916c1c5 100644
--- a/src/structure/structure_rectangular_orifice_submerged.ts
+++ b/src/structure/structure_rectangular_orifice_submerged.ts
@@ -2,6 +2,7 @@ import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
 import { Structure, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
 
 export { RectangularStructureParams };
 
@@ -12,6 +13,7 @@ export class StructureRectangularOrificeSubmerged extends RectangularStructure {
 
     constructor(prms: RectangularStructureParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.RectangularOrificeSubmerged;
         if (prms.W.v !== Infinity) {
             this._isZDVcalculable = false;
         }
diff --git a/src/structure/structure_triangular_trunc_weir_free.ts b/src/structure/structure_triangular_trunc_weir_free.ts
index 85fc1704d7d12bf2fb02b6dc9aafd5bed3b2f67b..dbecb29e18fef3f2f4fa7885036e52455752c60e 100644
--- a/src/structure/structure_triangular_trunc_weir_free.ts
+++ b/src/structure/structure_triangular_trunc_weir_free.ts
@@ -1,6 +1,7 @@
 import { ParamCalculability } from "../param/param-definition";
 import { Result } from "../util/result";
 import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
 import { TriangularTruncStructureParams } from "./structure_triangular_trunc_weir_free_params";
 
 export { TriangularTruncStructureParams };
@@ -12,6 +13,7 @@ export class StructureTriangularTruncWeirFree extends Structure {
 
     constructor(prms: TriangularTruncStructureParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.TriangularTruncWeirFree;
     }
 
     /**
diff --git a/src/structure/structure_triangular_weir_free.ts b/src/structure/structure_triangular_weir_free.ts
index fe1b429b8ff25b6f82584166cc14c9bcb0f48b12..0890add9d0f4924b77359c241ee1bdd8e90410db 100644
--- a/src/structure/structure_triangular_weir_free.ts
+++ b/src/structure/structure_triangular_weir_free.ts
@@ -1,6 +1,7 @@
 import { ParamCalculability } from "../param/param-definition";
 import { Result } from "../util/result";
 import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
 import { TriangularStructureParams } from "./structure_triangular_weir_free_params";
 
 export { TriangularStructureParams };
@@ -12,6 +13,7 @@ export class StructureTriangularWeirFree extends Structure {
 
     constructor(prms: TriangularStructureParams, dbg: boolean = false) {
         super(prms, dbg);
+        this._loiDebit = LoiDebit.TriangularWeirFree;
     }
 
     /**
diff --git a/src/structure/structure_weir_free.ts b/src/structure/structure_weir_free.ts
index 4346adbbb50c59be9fa41f13c33934b5fd46f88b..957791c6fe43bafc59d5d9616d6f53b67362d5b2 100644
--- a/src/structure/structure_weir_free.ts
+++ b/src/structure/structure_weir_free.ts
@@ -2,6 +2,7 @@ import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
 import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
 
 export { RectangularStructureParams };
 
@@ -9,6 +10,12 @@ export { RectangularStructureParams };
  * Equation classique seuil dénoyé
  */
 export class StructureWeirFree extends RectangularStructure {
+
+    constructor(prms: RectangularStructureParams, dbg: boolean = false) {
+        super(prms, dbg);
+        this._loiDebit = LoiDebit.WeirFree;
+    }
+
     /**
      * Calcul analytique Q = f(Cd, L, h1, h2, W) seuil dénoyé
      * @param sVarCalc Variable à calculer (doit être "Q")
diff --git a/src/structure/structure_weir_submerged_larinier.ts b/src/structure/structure_weir_submerged_larinier.ts
index afb6ec391bd47ac305b63f230575dd30644af7ac..f7d7af00872ce3886c8e72ad4a2f8c1376007459 100644
--- a/src/structure/structure_weir_submerged_larinier.ts
+++ b/src/structure/structure_weir_submerged_larinier.ts
@@ -2,6 +2,7 @@ import { Result } from "../util/result";
 import { RectangularStructure } from "./rectangular_structure";
 import { RectangularStructureParams } from "./rectangular_structure_params";
 import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { LoiDebit } from "./structure_props";
 
 export { RectangularStructureParams };
 
@@ -11,6 +12,12 @@ export { RectangularStructureParams };
  * Passes à poissons : expertise et conception des ouvrages de franchissement
  */
 export class StructureWeirSubmergedLarinier extends RectangularStructure {
+
+    constructor(prms: RectangularStructureParams, dbg: boolean = false) {
+        super(prms, dbg);
+        this._loiDebit = LoiDebit.WeirSubmergedLarinier;
+    }
+
     /**
      * Calcul analytique Q = f(Cd, L, h1, h2, W) seuil dénoyé
      * @param sVarCalc Variable à calculer (doit être "Q")