diff --git a/.vscode/launch.json b/.vscode/launch.json
index be37e2d1bdf7fef954f0e29a3c64ca397f7415a1..b627ca869d60e1b451d619ebfe96d0d68513cff5 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -4,6 +4,7 @@
     // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
     "version": "0.2.0",
     "configurations": [
+
         {
             "name": "Launch Program",
             "type": "node",
@@ -14,7 +15,7 @@
                 "${workspaceRoot}/build/**/*.js"
             ],
             "cwd": "${workspaceRoot}",
-            // "preLaunchTask": "buildspec"
+            "preLaunchTask": "buildspec"
         }
     ]
 }
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 8379e3ff2087b7446cabec75434a16916aae6722..0f4734d17fd2ea08611521470cb5f04c24acd7f8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "jalhyd",
-  "version": "1.0.2",
+  "version": "1.0.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/spec/mock_jasmine.ts b/spec/mock_jasmine.ts
index 2baf17136e0af0f3d14d27c2a7a5d47d49aa5395..e3a0c3fa63e86f26d9002005bafe80c062d401c8 100644
--- a/spec/mock_jasmine.ts
+++ b/spec/mock_jasmine.ts
@@ -161,8 +161,7 @@ class Expect {
                 if (exception.message !== expected.message) {
                     console.error(`Function throws '${exception.message}' but '${expected.message}' was expected`);
                 }
-            }
-            else if (exception.message) {
+            } else if (exception.message) {
                 console.error(`Function throws '${exception.message}' but no message was expected`);
             }
         }
diff --git a/spec/nubtest.ts b/spec/nubtest.ts
index 5d8c6bedcf7da95be4270fea7f9768ed8ba7ff9a..710e3526b5b170efe7c10bc27bbe3c7ebe54f61f 100644
--- a/spec/nubtest.ts
+++ b/spec/nubtest.ts
@@ -1,7 +1,7 @@
-import { Result } from "../src/util/result";
+import { ParamCalculability, ParamDefinition, ParamDomainValue } from "../src";
 import { Nub } from "../src/nub";
 import { ParamsEquation } from "../src/param/params-equation";
-import { ParamDefinition, ParamDomainValue, ParamCalculability } from "../src";
+import { Result } from "../src/util/result";
 
 export class NubTestParams extends ParamsEquation {
     private _A: ParamDefinition;
@@ -32,11 +32,17 @@ export class NubTestParams extends ParamsEquation {
     }
 }
 
+// tslint:disable-next-line:max-classes-per-file
 export class NubTest extends Nub {
     constructor(prms: NubTestParams, dbg: boolean = false) {
         super(prms, dbg);
     }
 
+    public Equation(): Result {
+        // C = A+B
+        return new Result(this.prms.A.v + this.prms.B.v);
+    }
+
     protected setParametersCalculability() {
         this.getParameter("A").calculability = ParamCalculability.DICHO;
         this.getParameter("B").calculability = ParamCalculability.DICHO;
@@ -47,10 +53,6 @@ export class NubTest extends Nub {
         return this._prms as NubTestParams;
     }
 
-    Equation(): Result {
-        // C = A+B
-        return new Result(this.prms.A.v + this.prms.B.v);
-    }
 }
 
 export let nub = new NubTest(new NubTestParams());
diff --git a/spec/value_ref/value_ref.spec.ts b/spec/value_ref/value_ref.spec.ts
index 82ed531ea7af2861f4a8d7cb79e7880a30f29053..b442a245774cff8b8651132d141c950efacb9f25 100644
--- a/spec/value_ref/value_ref.spec.ts
+++ b/spec/value_ref/value_ref.spec.ts
@@ -6,10 +6,10 @@
  */
 // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
 
+import { Result } from "../../src";
+import { ParamValueMode } from "../../src/param/param-value-mode";
 import { NubTest, NubTestParams } from "../nubtest";
 import { precDigits } from "../test_config";
-import { ParamValueMode } from "../../src/param/param-value-mode";
-import { Result } from "../../src";
 
 let nub1: NubTest;
 let nub2: NubTest;
@@ -181,7 +181,7 @@ describe("référence d'un paramètre à un autre : ", () => {
         it('test 3', () => {
             // cas de figure :
             // nub2.A est lié à nub1.A (valeur variée)
-            // lecture de nub2.A 
+            // lecture de nub2.A
 
             createEnv();
 
diff --git a/spec/value_ref/value_ref_variable.spec.ts b/spec/value_ref/value_ref_variable.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..21fc66aad4cbbbef32bf9c65011dad53ee6530b6
--- /dev/null
+++ b/spec/value_ref/value_ref_variable.spec.ts
@@ -0,0 +1,54 @@
+import { ParamValueMode } from "../../src";
+import { ConduiteDistrib, ConduiteDistribParams } from "../../src/cond_distri";
+import { Result } from "../../src/util/result";
+
+/**
+ * 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";
+
+let nub1: ConduiteDistrib;
+let nub2: ConduiteDistrib;
+let prm1: ConduiteDistribParams;
+let prm2: ConduiteDistribParams;
+
+/**
+ * crée l'environnement de test.
+ * répété à chaque test car il manque un mock de beforeEach
+ */
+function createEnv() {
+    // Nub maître
+    nub1 = new ConduiteDistrib(new ConduiteDistribParams(3, 1.2, 0.6, 100, 0.000001));
+    prm1 = nub1.parameters as ConduiteDistribParams;
+
+    // Nub esclave
+    nub2 = new ConduiteDistrib(new ConduiteDistribParams(3, 1.2, 0.6, 100, 0.000001));
+    prm2 = nub2.parameters as ConduiteDistribParams;
+}
+
+describe("Référence d'un paramètre à un paramètre varié : ", () => {
+    it("ConduiteDistri Q varie sur nub1, nub2.Q => nub1.Q, calcul et comparaison de J pour les deux", () => {
+        // cas de figure :
+        // nub2.Q est lié au résultat J de nub1
+        // lecture de nub2.Q
+
+        createEnv();
+
+        prm1.Q.paramValues.valueMode = ParamValueMode.MINMAX;
+        prm1.Q.paramValues.min = 1.5;
+        prm1.Q.paramValues.max = 6;
+        prm1.Q.paramValues.step = 0.5;
+        const res1: Result = nub1.CalcSerie(0.001, 0.6, "J");
+
+        prm2.Q.defineReference(nub1, "Q");
+        const res2 = nub2.CalcSerie(0.001, 0.6, "J");
+
+        for (let i = 0; i < res1.resultElements.length; i++) {
+            expect(res1.resultElements[i].vCalc).toEqual(res2.resultElements[i].vCalc);
+        }
+
+    });
+});
diff --git a/spec/value_ref/value_ref_variable_result.spec.ts b/spec/value_ref/value_ref_variable_result.spec.ts
index 9eff1a2bbaccef2f7902459bf49b06a320188cff..7b74fa2a3ce293e70667173918b8bdec9d8966e2 100644
--- a/spec/value_ref/value_ref_variable_result.spec.ts
+++ b/spec/value_ref/value_ref_variable_result.spec.ts
@@ -1,6 +1,6 @@
-import { ConduiteDistrib } from "../../src/cond_distri";
-import { ConduiteDistribParams } from "../../src/cond_distri";
 import { ParamValueMode } from "../../src";
+import { ConduiteDistrib, ConduiteDistribParams } from "../../src/cond_distri";
+import { Result } from "../../src/util/result";
 
 /**
  * IMPORTANT !
@@ -29,8 +29,28 @@ function createEnv() {
     prm2 = nub2.parameters as ConduiteDistribParams;
 }
 
-describe("référence d'un paramètre à un résultat multivalué : ", () => {
-    it("test 1", () => {
+describe("référence d'un paramètre à un résultat : ", () => {
+    it("ConduiteDistri Q fixe => Calc(J) => Importe(J) => Calc(Q)", () => {
+        // cas de figure :
+        // nub2.Q est lié au résultat J de nub1
+        // lecture de nub2.Q
+
+        createEnv();
+
+        prm1.Q.v = 2;
+        prm1.J.paramValues.valueMode = ParamValueMode.CALCUL;
+        const res1: Result = nub1.CalcSerie(0.001, 0.6, "J");
+
+        expect(res1.resultElements.length).toEqual(1); // nombre de valeurs du Result
+
+        prm2.J.defineReference(nub1, "J.");
+        const res2 = nub2.CalcSerie(0.001, 0.6, "Q");
+        expect(res2.resultElements.length).toEqual(1);  // nombre de valeurs du Result
+
+        expect(res2.vCalc).toBeCloseTo(prm1.Q.v, 3);
+    });
+
+    it("ConduiteDistri Q varie => Calc(J) => Importe(J) => Calc(Q)", () => {
         // cas de figure :
         // nub2.Q est lié au résultat J de nub1
         // lecture de nub2.Q
@@ -41,28 +61,20 @@ describe("référence d'un paramètre à un résultat multivalué : ", () => {
         prm1.Q.paramValues.min = 1.5;
         prm1.Q.paramValues.max = 6;
         prm1.Q.paramValues.step = 0.5;
-        prm2.Q.defineReference(nub1, "J.");
+        prm1.J.paramValues.valueMode = ParamValueMode.CALCUL;
+        const res1: Result = nub1.CalcSerie(0.001, 0.6, "J");
 
-        const expectedJ: number[] = [0.024202971271651448, 0.04004160474685753, 0.059170330781816, 0.08140876712328136, 0.10661739314398751, 0.1346833675705545, 0.16551253143900968, 0.19902447617522237, 0.23514929908544743, 0.273825361776767];
+        prm2.J.defineReference(nub1, "J.");
+        const res2 = nub2.CalcSerie(0.001, 0.6, "Q");
 
-        const res = nub1.CalcSerie(0.001, 0.6, "J");
-        let i = 0;
-        for (const re of res.resultElements)
-            // console.log(re.vCalc);
-            expect(re.vCalc).toEqual(expectedJ[i++]);
+        expect(res1.resultElements.length).toEqual(10);  // nombre de valeurs du Result
+        expect(res2.resultElements.length).toEqual(10);
 
-        i = 0;
-        for (const v of res.valuesIterator)
-            expect(v).toEqual(expectedJ[i++]);
-        expect(i).toEqual(expectedJ.length);
-
-        // i = 0;
-        // for (const v of prm1.J.valuesIterator)
-        //     expect(v).toEqual(expectedJ[i++]); // échoue car le valueMode de J (SINGLE) n'est pas modifié par CalcSerie()
-
-        i = 0;
-        for (const v of prm2.Q.valuesIterator)
-            expect(v).toEqual(expectedJ[i++]);
-        expect(i).toEqual(expectedJ.length);
+        let QREF = prm1.Q.paramValues.min;
+        for (const re of res2.resultElements) {
+            // console.log(re.vCalc);
+            expect(re.vCalc).toBeCloseTo(QREF, 0.001);
+            QREF += prm1.Q.paramValues.step;
+        }
     });
 });
diff --git a/src/nub.ts b/src/nub.ts
index 68ae8e3cadee30d7f285008c7a2d449965956e98..99e2c66a4b7016ba2870259cca89a9b92d5f34ab 100644
--- a/src/nub.ts
+++ b/src/nub.ts
@@ -1,24 +1,25 @@
+import { ParamDefinition } from ".";
 import { Debug } from "./base";
-import { Dichotomie } from "./dichotomie";
 import { ComputeNode } from "./compute-node";
-import { Result } from "./util/result";
-import { ParamValues } from "./param/param-values";
+import { Dichotomie } from "./dichotomie";
+import { NamedIterableValues, NumberIterator, IterableValues } from "./param/param-value-iterator";
 import { ParamValueMode } from "./param/param-value-mode";
-import { ParamDefinition } from ".";
+import { ParamValues } from "./param/param-values";
+import { Result } from "./util/result";
 import { IReferencedNub } from "./value_ref/object_ref";
-import { NamedIterableValues, NumberIterator } from "./param/param-value-iterator";
 
 /**
  * Classe abstraite de Noeud de calcul : classe de base pour tous les calculs
  */
 export abstract class Nub extends ComputeNode implements IReferencedNub {
-    private _dichoStartIntervalMaxSteps: number = 100;
 
     /**
      * résultat de Calc()/CalcSerie()
      */
     protected _result: Result;
 
+    private _dichoStartIntervalMaxSteps: number = 100;
+
     /*
      * paramétrage de la dichotomie
      */
@@ -75,87 +76,72 @@ export abstract class Nub extends ComputeNode implements IReferencedNub {
      * @param sDonnee éventuel symbole du paramètre à calculer
      */
     public CalcSerie(rPrec: number = 0.001, rInit?: number, sDonnee?: string): Result {
-        let variatedParam: ParamDefinition;
         let computedParam: ParamDefinition;
-        let prmValue: ParamValues; // instance de ParamValues utilisée pour le paramètre varié (qui peut être un paramètre référencé (importé))
+        // instance de ParamValues utilisée pour le paramètre varié (qui peut être un paramètre référencé (importé))
+        let variatedValues: IterableValues;
 
         for (const p of this.parameterIterator) {
+            if (p.valueMode === ParamValueMode.CALCUL) {
+                if (sDonnee === undefined) {
+                    if (computedParam === undefined) {
+                        computedParam = p;
+                    } else {
+                        // tslint:disable-next-line:max-line-length
+                        throw new Error(`CalcSerie() : il y plusieurs paramètres à calculer (au moins ${computedParam.symbol} et ${p.symbol})`);
+                    }
+                }
+            }
+
             switch (p.valueMode) {
                 case ParamValueMode.SINGLE:
                     break;
 
                 case ParamValueMode.LISTE:
                 case ParamValueMode.MINMAX:
-                    if (variatedParam == undefined) {
-                        variatedParam = p;
-                        prmValue = p.paramValues;
-                    }
-                    else
-                        throw new Error(`CalcSerie() : il y plusieurs paramètres à varier (au moins ${variatedParam.symbol} et ${p.symbol})`);
+                    variatedValues = this.setVariatedValues(p, variatedValues);
                     break;
 
                 case ParamValueMode.CALCUL:
-                    if (sDonnee == undefined) {
-                        if (computedParam == undefined)
-                            computedParam = p;
-                        else
-                            throw new Error(`CalcSerie() : il y plusieurs paramètres à calculer (au moins ${computedParam.symbol} et ${p.symbol})`);
+                    // Le paramètre lié est un résultat de calcul
+                    if (p.isReferenceDefined && p.referencedResult.nbResultElements > 1) {
+                        variatedValues = this.setVariatedValues(p, variatedValues);
                     }
                     break;
 
                 case ParamValueMode.LINK:
-                    if (p.referencedParamValues !== undefined)
-                        switch (p.referencedParamValues.valueMode) {
-                            case ParamValueMode.SINGLE:
-                                break;
-
-                            case ParamValueMode.LISTE:
-                            case ParamValueMode.MINMAX:
-                                if (variatedParam == undefined) {
-                                    variatedParam = p;
-                                    prmValue = p.referencedParamValues;
-                                }
-                                else
-                                    throw new Error(`CalcSerie() : il y plusieurs paramètres à varier (au moins ${variatedParam.symbol} et ${p.symbol})`);
-                                break;
-
-                            case ParamValueMode.CALCUL:
-                                if (sDonnee == undefined) {
-                                    if (computedParam == undefined)
-                                        computedParam = p;
-                                    else
-                                        throw new Error(`CalcSerie() : il y plusieurs paramètres à calculer (au moins ${computedParam.symbol} et ${p.symbol})`);
-                                }
-                                break;
-
-                            default:
-                                throw new Error(`CalcSerie() : valeur référencée de ParamValueMode ${ParamValueMode[p.referencedParamValues.valueMode]} non prise en charge`);
-                        }
+                    const ro = p.referencedObject;
+                    if (ro !== undefined && ro.hasMultipleValues)
+                        variatedValues = this.setVariatedValues(p, variatedValues);
                     break;
 
                 default:
+                    // tslint:disable-next-line:max-line-length
                     throw new Error(`CalcSerie() : valeur de ParamValueMode ${ParamValueMode[p.valueMode]} non prise en charge`);
             }
         }
 
-        if (sDonnee)
-            var computedSymbol: string = sDonnee;
-        else {
-            if (computedParam == undefined)
+        let computedSymbol: string;
+        if (sDonnee) {
+            computedSymbol = sDonnee;
+        } else {
+            if (computedParam === undefined) {
                 throw new Error(`CalcSerie() : aucun paramètre à calculer`);
+            }
             computedSymbol = computedParam.symbol;
         }
 
-        if (rInit === undefined)
+        if (rInit === undefined) {
             rInit = computedParam.v;
+        }
 
-        if (variatedParam == undefined)
+        if (variatedValues === undefined) {
             this._result = this.Calc(computedSymbol, rInit, rPrec); // résultat dans this._result
-        else {
+        } else {
             const res = new Result();
-            prmValue.initIterator();
-            while (prmValue.hasNext) {
-                prmValue.next;
+            variatedValues.initValuesIterator(false);
+            while (variatedValues.hasNext) {
+                // tslint:disable-next-line:no-unused-expression
+                variatedValues.next();
                 this.Calc(computedSymbol, rInit, rPrec);  // résultat dans this._result
                 if (this._result.ok) {
                     res.addResultElement(this._result.resultElement);
@@ -171,19 +157,6 @@ export abstract class Nub extends ComputeNode implements IReferencedNub {
         return this._result;
     }
 
-    /**
-     * Résoud l'équation par une méthode numérique
-     * @param sVarCalc nom de la variable à calculer
-     * @param rInit valeur initiale de la variable à calculer dans le cas de la dichotomie
-     * @param rPrec précision de calcul
-     */
-    private Solve(sVarCalc: string, rInit: number, rPrec: number): Result {
-        const dicho: Dichotomie = new Dichotomie(this, sVarCalc, this.DBG);
-        dicho.startIntervalMaxSteps = this._dichoStartIntervalMaxSteps;
-        const target = this.getFirstAnalyticalParameter();
-        return dicho.Dichotomie(target.v, rPrec, rInit);
-    }
-
     public get result(): Result {
         return this._result;
     }
@@ -192,16 +165,20 @@ export abstract class Nub extends ComputeNode implements IReferencedNub {
 
     public getReferencedParamValues(desc: string): ParamValues {
         const prm = this.getParameter(desc);
-        if (prm !== undefined)
+        if (prm !== undefined) {
             return prm.paramValues;
+        }
         return undefined;
     }
 
     public getReferencedResult(desc?: string): Result {
-        if (desc === undefined || (this._result !== undefined && this._result.name === desc))
+        if (desc === undefined || (this._result !== undefined && this._result.name === desc)) {
             return this._result;
+        }
 
-        return this.CalcSerie(0.001, 0.1, desc); // il y a des valeurs par défaut pour la précision et la valeur initiale, mais il faudra prévoir un mécanisme pour les transmettre
+        // il y a des valeurs par défaut pour la précision et la valeur initiale,
+        // mais il faudra prévoir un mécanisme pour les transmettre
+        return this.CalcSerie(0.001, 0.1, desc);
     }
 
     public getReferencedExtraResult(desc: string): any {
@@ -218,26 +195,41 @@ export abstract class Nub extends ComputeNode implements IReferencedNub {
     public getReferencedObject(desc: string): NamedIterableValues {
         const tmp = desc.split(".");
 
-        if (tmp.length == 1) // paramètre (ex "Q")
+        if (tmp.length === 1) {
+            // paramètre (ex "Q")
             return this.getParameter(desc);
+        }
 
-        if (tmp[1] === "") // résultat (ex "Q.")
-            if (this._result !== undefined)
+        if (tmp[1] === "") {
+            // résultat (ex "Q.")
+            if (this._result !== undefined) {
                 return this._result;
+            }
+        }
 
         // les autres objets référençables n'implémentant pas IJalhydObject...
         return undefined;
     }
 
-    private addPrefix(str: string, prefix: string) {
-        return prefix === undefined ? str : `${prefix}${str}`;
-    }
-
     /**
      * liste des valeurs (paramètre, résultat, résultat complémentaire) liables à un paramètre
      * @param src objet qui sert de clé de recherche des paramètres liables, de type INamedObject | string
-     * @param excludeResult true si on veut exclure des valeurs retournées le résultat/résultat complémentaire correspondant à la clé de recherche
-     * @returns tableau d'objets de la forme { "name":string, "value":NamedIterableValues, "nub":Nub}, nub=Nub d'origine de la "value"
+     * @param excludeResult true si on veut exclure des valeurs retournées le résultat/résultat complémentaire
+     *                      correspondant à la clé de recherche
+     * @returns tableau d'objets de la forme { "name":string, "value":NamedIterableValues, "nub":Nub},
+     *   nub=Nub d'origine de la "value"
+     * 
+     *   l'étiquette "name" (cf. INubReference.defineReference) est de la forme <n | ouvrage[n] | N1>[.[N2]]
+     *     n : indice de de l'ouvrage dans le cas des ouvrages parallèles
+     *     N1 : un nom de paramètre/résultat (dans le cas d'un résultat, il est suivi d'un point)
+     *     N2 : nom de résultat complémentaire (optionnel)
+     *     ex :
+     *       Q, Z1 (paramètres)
+     *       J. (résultat)
+     *       .Yf (résultat complémentaire du résultat courant)
+     *       Q.Yf (résultat complémentaire du résultat nommé "Q")
+     *       0.Q : paramètre Q du 1er ouvrage (ouvrages parallèles)
+     *       ouvrage[1].Q_Mode : résultat complémentaire du 2ème ouvrage (ouvrages parallèles)
      */
     public getLinkableValues(src: any, prefix?: string, excludeResult: boolean = false): any[] {
         const res: any[] = [];
@@ -249,8 +241,9 @@ export abstract class Nub extends ComputeNode implements IReferencedNub {
         // paramètres
 
         for (const p of this._prms) {
-            const cond = hasUid ? p.uid !== src.uid : true; // pour éviter d'ajouter le paramètre d'entrée dans le tableau résultat
-            if (cond)
+            // pour éviter d'ajouter le paramètre d'entrée dans le tableau résultat
+            const cond = hasUid ? p.uid !== src.uid : true;
+            if (cond) {
                 switch (p.valueMode) {
                     case ParamValueMode.SINGLE:
                     case ParamValueMode.MINMAX:
@@ -258,29 +251,60 @@ export abstract class Nub extends ComputeNode implements IReferencedNub {
                         switch (name) {
                             case "Z1":
                             case "Z2":
-                                if (p.symbol === "Z1" || p.symbol === "Z2")
-                                    res.push({ "name": this.addPrefix(p.symbol, prefix), "value": p, "nub": this });
+                                if (p.symbol === "Z1" || p.symbol === "Z2") {
+                                    res.push({ name: this.addPrefix(p.symbol, prefix), value: p, nub: this });
+                                }
                                 break;
 
                             default:
-                                if (p.symbol === name)
-                                    res.push({ "name": this.addPrefix(p.symbol, prefix), "value": p, "nub": this });
+                                if (p.symbol === name) {
+                                    res.push({ name: this.addPrefix(p.symbol, prefix), value: p, nub: this });
+                                }
                         }
                 }
+            }
         }
 
         // résultat
         if (this._result !== undefined && !excludeResult) {
-            if (this._result.name === name)
-                res.push({ "name": this.addPrefix(`${name}.`, prefix), "value": this._result, "nub": this });
+            if (this._result.name === name) {
+                res.push({ name: this.addPrefix(`${name}.`, prefix), value: this._result, nub: this });
+            }
 
             // résultats complémentaires
 
-            const erIter = this._result.getIterableExtraResults(name)
-            if (erIter !== undefined)
-                res.push({ "name": this.addPrefix(`${this._result.name}.${name}`, prefix), "value": erIter, "nub": this });
+            const erIter = this._result.getIterableExtraResults(name);
+            if (erIter !== undefined) {
+                res.push({ name: this.addPrefix(`${this._result.name}.${name}`, prefix), value: erIter, nub: this });
+            }
         }
 
         return res;
     }
+
+    /**
+     * Résoud l'équation par une méthode numérique
+     * @param sVarCalc nom de la variable à calculer
+     * @param rInit valeur initiale de la variable à calculer dans le cas de la dichotomie
+     * @param rPrec précision de calcul
+     */
+    private Solve(sVarCalc: string, rInit: number, rPrec: number): Result {
+        const dicho: Dichotomie = new Dichotomie(this, sVarCalc, this.DBG);
+        dicho.startIntervalMaxSteps = this._dichoStartIntervalMaxSteps;
+        const target = this.getFirstAnalyticalParameter();
+        return dicho.Dichotomie(target.v, rPrec, rInit);
+    }
+
+    private addPrefix(str: string, prefix: string) {
+        return prefix === undefined ? str : `${prefix}${str}`;
+    }
+
+    private setVariatedValues(newValues: NamedIterableValues, oldValues: IterableValues) {
+        if (oldValues === undefined) {
+            return newValues;
+        } else {
+            // tslint:disable-next-line:max-line-length
+            throw new Error(`CalcSerie() : Paramètres à varier redondant : ${newValues.name}`);
+        }
+    }
 }
diff --git a/src/param/param-base.ts b/src/param/param-base.ts
index 2d8ff743bbbde4813228a2cc495dd75fc4df46d8..b4b6024457e97110d34af5e379531ce4ab80565f 100644
--- a/src/param/param-base.ts
+++ b/src/param/param-base.ts
@@ -1,14 +1,14 @@
 import { Interval } from "../util/interval";
 import { Message, MessageCode } from "../util/message";
 
-import { JalhydObject, IJalhydObject } from "../jalhyd_object"
-import { ParamDomain, ParamDomainValue } from "./param-domain";
-import { ParamValues } from "./param-values";
-import { ParamValueMode } from "./param-value-mode";
-import { IReferencedNub, INubReference } from "../value_ref/object_ref";
+import { IJalhydObject, JalhydObject } from "../jalhyd_object";
+import { IObservable, Observable, Observer } from "../util/observer";
 import { Result } from "../util/result";
+import { INubReference, IReferencedNub } from "../value_ref/object_ref";
+import { ParamDomain, ParamDomainValue } from "./param-domain";
 import { NamedIterableValues, NumberIterator } from "./param-value-iterator";
-import { IObservable, Observable, Observer } from "../util/observer";
+import { ParamValueMode } from "./param-value-mode";
+import { ParamValues } from "./param-values";
 
 /**
  * paramètre avec symbole et domaine de définition
@@ -39,7 +39,7 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
         super();
         this._symbol = symb;
 
-        this._observable = new Observable()
+        this._observable = new Observable();
 
         this._paramValues = new ParamValues();
         this._paramValues.setSingleValue(val);
@@ -66,8 +66,9 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
     }
 
     public get paramValues(): ParamValues {
-        if (this.isReferenceDefined)
+        if (this.isReferenceDefined) {
             return this.referencedParamValues;
+        }
         return this._paramValues;
     }
 
@@ -89,15 +90,8 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
         return this._paramValues.currentValue;
     }
 
-    /**
-     * notification envoyée après la modification de la valeur du paramètre
-     */
-    private notifyValueModified(sender: any) {
-        this.notifyObservers(
-            {
-                "action": "baseparamAfterValue",
-            }, sender
-        );
+    public get currentValue(): number {
+        return this.getValue();
     }
 
     public setValue(val: number, sender?: any) {
@@ -164,24 +158,6 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
         }
     }
 
-    /**
-     * vérifie si un min/max est valide par rapport au domaine de définition
-     */
-    private isMinMaxDomainValid(v: number): boolean {
-        if (v == undefined)
-            return false;
-
-        if (this._paramValues.valueMode == ParamValueMode.MINMAX)
-            try {
-                this.checkValue(v);
-            }
-            catch (e) {
-                return false;
-            }
-
-        return true;
-    }
-
     public checkMin(min: number): boolean {
         return this.isMinMaxDomainValid(min) && (min < this._paramValues.max);
     }
@@ -190,41 +166,22 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
         return this.isMinMaxDomainValid(max) && (this._paramValues.min < max);
     }
 
-    private checkMinMax(min: number, max: number): boolean {
-        return this.isMinMaxDomainValid(min) && this.isMinMaxDomainValid(max) && (min < max);
-    }
-
-    public get isMinMaxValid(): boolean {
-        return this.checkMinMax(this._paramValues.min, this._paramValues.max);
-    }
-
     public checkStep(step: number): boolean {
         return this.isMinMaxValid && this._paramValues.stepRefValue.intervalHasValue(step);
     }
 
-    public get isValueValid(): boolean {
+    get isValueValid(): boolean {
         try {
             const v = this.getValue();
             this.checkValue(v);
             return true;
-        }
-        catch (e) {
+        } catch (e) {
             return false;
         }
     }
 
-    private get isListValid(): boolean {
-        if (this._paramValues.valueList == undefined)
-            return false;
-
-        for (let v of this._paramValues.valueList)
-            try {
-                this.checkValue(v);
-            }
-            catch (e) {
-                return false;
-            }
-        return true;
+    get isMinMaxValid(): boolean {
+        return this.checkMinMax(this._paramValues.min, this._paramValues.max);
     }
 
     public get isRangeValid(): boolean {
@@ -236,6 +193,7 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
                 return this.checkStep(this._paramValues.step);
         }
 
+        // tslint:disable-next-line:max-line-length
         throw new Error(`"BaseParam.isRangeValid() : valeur ${ParamValueMode[this._paramValues.valueMode]} de ParamValueMode non prise en compte`);
     }
 
@@ -252,20 +210,24 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
                 return true;
 
             case ParamValueMode.LINK:
-                if (!this.isReferenceDefined)
+                if (!this.isReferenceDefined) {
                     return false;
+                }
 
                 try {
-                    for (const v of this.valuesIterator)
+                    for (const v of this.valuesIterator) {
                         this.checkValue(v);
-                    return true
-                }
-                catch (e) {
+                    }
+                    return true;
+                } catch (e) {
                     return false;
                 }
         }
 
-        throw new Error(`"BaseParam.isValid() : valeur de ParamValueMode '${ParamValueMode[this._paramValues.valueMode]}' non prise en charge`);
+        throw new Error(
+            // tslint:disable-next-line:max-line-length
+            `BaseParam.isValid() : valeur de ParamValueMode '${ParamValueMode[this._paramValues.valueMode]}' non prise en charge`
+        );
     }
 
     public get valueMode() {
@@ -278,36 +240,13 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
 
     // interface INubReference
 
-    /**
-     * vérifie l'absence de référence circulaire
-     * @param seenUids liste des uids déjà vérifiés
-     * @param o objet à tester (son uid est il déjà dans la liste ?)
-     */
-    private checkReferenceCircularity(o: any, seenUids: number[]) {
-        if ("uid" in o) {
-            // if (o.uid in seenUids)
-            if (seenUids.indexOf(o.uid) !== -1)
-                throw new Error(`références circulaires détectées (uids : ${seenUids})`);
-
-            seenUids.push(o.uid);
-
-            if ("referencedObject" in o) {
-                const curr = o as INubReference;
-                const next = curr.referencedObject;
-                if (next !== undefined)
-                    this.checkReferenceCircularity(next as IJalhydObject, seenUids);
-            }
-        }
-    }
-
     public defineReference(target: IReferencedNub, desc: string) {
         const oldDef = this._paramValues.referenceDefinition;
         const oldTarget = this._paramValues.referencedNub;
         try {
             this._paramValues.defineReference(target, desc);
             this.checkReferenceCircularity(this, []);
-        }
-        catch (e) {
+        } catch (e) {
             this._paramValues.defineReference(oldTarget, oldDef);
             throw e;
         }
@@ -317,43 +256,44 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
         this._paramValues.undefineReference();
     }
 
-    public get referenceDefinition(): string {
+    get referenceDefinition(): string {
         return this._paramValues.referenceDefinition;
     }
 
-    public get referencedNub(): IReferencedNub {
+    get referencedNub(): IReferencedNub {
         return this._paramValues.referencedNub;
     }
 
-    public get isReferenceDefined(): boolean {
+    get isReferenceDefined(): boolean {
         return this._paramValues.isReferenceDefined;
     }
 
-    public get referencedParamValues(): ParamValues {
+    get referencedParamValues(): ParamValues {
         return this._paramValues.referencedParamValues;
     }
 
-    public get referencedResult(): Result {
+    get referencedResult(): Result {
         return this._paramValues.referencedResult;
     }
 
-    public get referencedExtraResult(): any {
+    get referencedExtraResult(): any {
         return this._paramValues.referencedExtraResult;
     }
 
-    public get referencedValuesIterator(): NumberIterator {
+    get referencedValuesIterator(): NumberIterator {
         return this._paramValues.referencedValuesIterator;
     }
 
-    public get referencedObject(): NamedIterableValues {
+    get referencedObject(): NamedIterableValues {
         return this._paramValues.referencedObject;
     }
 
     // interface NamedIterableValues
 
     public get valuesIterator(): NumberIterator {
-        if (this.isReferenceDefined)
+        if (this.isReferenceDefined) {
             return this.referencedValuesIterator;
+        }
         return this._paramValues.valuesIterator;
     }
 
@@ -365,6 +305,22 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
         return this._symbol;
     }
 
+    public initValuesIterator(reverse: boolean = false): NumberIterator {
+        return this._paramValues.initValuesIterator(reverse);
+    }
+
+    public get hasNext(): boolean {
+        return this._paramValues.hasNext;
+    }
+
+    public next(): IteratorResult<number> {
+        return this._paramValues.next();
+    }
+
+    public [Symbol.iterator](): IterableIterator<number> {
+        return this._paramValues;
+    }
+
     // interface IObservable
 
     /**
@@ -384,7 +340,81 @@ export class BaseParam extends JalhydObject implements INubReference, NamedItera
     /**
      * notifie un événement aux observateurs
      */
-    notifyObservers(data: any, sender?: any) {
+    public notifyObservers(data: any, sender?: any) {
         this._observable.notifyObservers(data, sender);
     }
+
+    /**
+     * notification envoyée après la modification de la valeur du paramètre
+     */
+    private notifyValueModified(sender: any) {
+        this.notifyObservers(
+            {
+                action: "baseparamAfterValue",
+            }, sender
+        );
+    }
+
+    /**
+     * vérifie si un min/max est valide par rapport au domaine de définition
+     */
+    private isMinMaxDomainValid(v: number): boolean {
+        if (v === undefined) {
+            return false;
+        }
+
+        if (this._paramValues.valueMode === ParamValueMode.MINMAX) {
+            try {
+                this.checkValue(v);
+            } catch (e) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private checkMinMax(min: number, max: number): boolean {
+        return this.isMinMaxDomainValid(min) && this.isMinMaxDomainValid(max) && (min < max);
+    }
+
+    private get isListValid(): boolean {
+        if (this._paramValues.valueList === undefined) {
+            return false;
+        }
+
+        for (const v of this._paramValues.valueList) {
+            try {
+                this.checkValue(v);
+            } catch (e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * vérifie l'absence de référence circulaire
+     * @param seenUids liste des uids déjà vérifiés
+     * @param o objet à tester (son uid est il déjà dans la liste ?)
+     */
+    private checkReferenceCircularity(o: any, seenUids: number[]) {
+        if ("uid" in o) {
+            // if (o.uid in seenUids)
+            if (seenUids.indexOf(o.uid) !== -1) {
+                throw new Error(`références circulaires détectées (uids : ${seenUids})`);
+            }
+
+            seenUids.push(o.uid);
+
+            if ("referencedObject" in o) {
+                const curr = o as INubReference;
+                const next = curr.referencedObject;
+                if (next !== undefined) {
+                    this.checkReferenceCircularity(next as IJalhydObject, seenUids);
+                }
+            }
+        }
+    }
+
 }
diff --git a/src/param/param-definition.ts b/src/param/param-definition.ts
index 3cfde12f879738e1fbab0aa38e8a6b2167ff893f..43997761ffc4edf10e310ad740f1379b5ce47b0a 100644
--- a/src/param/param-definition.ts
+++ b/src/param/param-definition.ts
@@ -1,9 +1,8 @@
 import { Message, MessageCode } from "../util/message";
-
+import { Result } from "../util/result";
 import { BaseParam } from "./param-base";
 import { ParamDomain, ParamDomainValue } from "./param-domain";
 import { ParamValueMode } from "./param-value-mode";
-import { Result } from "../util/result";
 
 /**
  * calculabilité du paramètre
@@ -53,16 +52,17 @@ export class ParamDefinition extends BaseParam {
                 switch (this.referencedParamValues.valueMode) {
                     case ParamValueMode.CALCUL:
                         const r = this.referencedResult;
-                        if (r.nbResultElements == 1)
+                        if (r.nbResultElements === 1) {
                             return r.resultElement.vCalc;
+                        }
                         throw new Error(`il n'y a pas exactement un ResultElement dans le Result "${r.name}"`);
 
                     default:
                         return this.referencedParamValues.currentValue;
                 }
+            } else if (ro instanceof Result) {
+                return ro.currentValue;
             }
-            else if (ro instanceof Result)
-                return ro.vCalc;
 
             return this.referencedExtraResult;
         }
diff --git a/src/param/param-value-iterator.ts b/src/param/param-value-iterator.ts
index c5f05fcbf12acf15c3e56c4129a5823c4fe7578d..459cf1585089410f03ee865cc1c28835278ceafd 100644
--- a/src/param/param-value-iterator.ts
+++ b/src/param/param-value-iterator.ts
@@ -1,6 +1,7 @@
-import { ParamValues } from "./param-values";
-import { ParamValueMode } from "./param-value-mode";
 import { INamedObject } from "../jalhyd_object";
+import { ParamValueMode } from "./param-value-mode";
+import { ParamValues } from "./param-values";
+import { ArrayReverseIterator } from "../util/iterator";
 
 /**
  * itérateur sur des nombres
@@ -15,14 +16,20 @@ export interface NumberIterator extends IterableIterator<number> {
      * prochaine valeur
      */
     next(): IteratorResult<number>;
+
+    /**
+     * valeur courante cad résultat du précédent appel à next().
+     * contrairement à next(), on peut l'appeler plusieurs fois sans modifier l'état de l'itérateur
+     */
+    readonly currentValue: number;
 }
 
 /**
- * interface implémentée par les objets pouvant renvoyer un itérateur sur une série de valeurs numériques
+ * interface implémentée par les objets pouvant posséder/renvoyer un itérateur sur une série de valeurs numériques
  */
-export interface IterableValues {
+export interface IterableValues extends NumberIterator {
     /**
-     * itérateur sur les valeurs
+     * crée un nouvel itérateur sur les valeurs
      */
     readonly valuesIterator: NumberIterator;
 
@@ -30,6 +37,11 @@ export interface IterableValues {
      * true si la série de valeurs a plus d'une valeur
      */
     readonly hasMultipleValues: boolean;
+
+    /**
+     * initialise un itérateur interne sur les valeurs implicitement utilisé par hasNext() et next()
+     */
+    initValuesIterator(reverse: boolean): NumberIterator;
 }
 
 /**
@@ -52,6 +64,11 @@ export class ParamValueIterator implements NumberIterator {
      */
     private _reverse: boolean;
 
+    /**
+     * valeur courante
+     */
+    private _current: number;
+
     private _index: number;
 
     /**
@@ -65,7 +82,7 @@ export class ParamValueIterator implements NumberIterator {
     constructor(prm: ParamValues, reverse: boolean = false) {
         prm.check();
         this._param = prm;
-        this.reset(reverse)
+        this.reset(reverse);
     }
 
     public reset(reverse: boolean) {
@@ -79,10 +96,11 @@ export class ParamValueIterator implements NumberIterator {
 
             case ParamValueMode.MINMAX:
                 this._config = 1;
-                if (reverse)
+                if (reverse) {
                     this._index = this._param.max;
-                else
+                } else {
                     this._index = this._param.min;
+                }
                 break;
 
             case ParamValueMode.LISTE:
@@ -99,7 +117,7 @@ export class ParamValueIterator implements NumberIterator {
         switch (this._config) {
             // valeur fixée
             case 0:
-                return this._index == 0;
+                return this._index === 0;
 
             // min/max
             case 1:
@@ -120,29 +138,31 @@ export class ParamValueIterator implements NumberIterator {
             // valeur fixée
             case 0:
                 if (this.hasNext) {
+                    this._current = this._param.singleValue;
                     this._index++;
                     return {
                         done: false,
-                        value: this._param.singleValue
+                        value: this._current
                     };
-                }
-                else
+                } else {
                     return {
                         done: true,
                         value: undefined
                     };
+                }
 
             // min/max
             case 1:
-                const res = this._index;
+                this._current = this._index;
                 if (this.hasNext) {
-                    if (this._reverse)
+                    if (this._reverse) {
                         this._index -= this._param.step;
-                    else
+                    } else {
                         this._index += this._param.step;
+                    }
                     return {
                         done: false,
-                        value: res
+                        value: this._current
                     };
                 } else {
                     return {
@@ -155,10 +175,10 @@ export class ParamValueIterator implements NumberIterator {
             case 2:
                 const i = this._index;
                 if (this.hasNext) {
-                    const res = this._param.valueList[this._index++];
+                    this._current = this._param.valueList[this._index++];
                     return {
                         done: false,
-                        value: res
+                        value: this._current
                     };
                 } else {
                     return {
@@ -172,11 +192,89 @@ export class ParamValueIterator implements NumberIterator {
         }
     }
 
-    // public get current(): number {
-    //     if (this._config == 1)
-    //         return this._index;
-    //     throw new Error(`appel ParamValueIterator.current() invalide`)
-    // }
+    public get currentValue(): number {
+        return this._current;
+    }
+
+    // interface IterableIterator
+
+    public [Symbol.iterator](): IterableIterator<number> {
+        return this;
+    }
+}
+
+/**
+ * itérateur sur les valeurs prises par un tableau
+ */
+export class NumberArrayIterator implements NumberIterator {
+    private _it: IterableIterator<number>;
+
+    private _index: number;
+
+    /**
+     * valeur courante
+     */
+    private _current: number;
+
+    constructor(private _arr: number[]) {
+        this._it = this._arr[Symbol.iterator](); // crée un itérateur à partir d'un tableau
+        this._index = 0;
+    }
+
+    public get hasNext(): boolean {
+        return this._index < this._arr.length;
+    }
+
+    public next(): IteratorResult<number> {
+        this._index++;
+        const res = this._it.next();
+        if (!res.done)
+            this._current = res.value;
+        return res;
+    }
+
+    public get currentValue(): number {
+        return this._current;
+    }
+
+    // interface IterableIterator
+
+    public [Symbol.iterator](): IterableIterator<number> {
+        return this;
+    }
+}
+
+/**
+ * itérateur sur les valeurs prises par un tableau (parcourues depuis la fin)
+ */
+export class NumberArrayReverseIterator extends ArrayReverseIterator<number> implements NumberIterator {
+    private _count: number;
+
+    /**
+     * valeur courante
+     */
+    private _current: number;
+
+    constructor(arr: number[]) {
+        super(arr);
+        this._count = 0;
+    }
+
+    public get hasNext(): boolean {
+        return this._count < super._arr.length;
+    }
+
+    public next(): IteratorResult<number> {
+        this._count++;
+        const res = super.next();
+        if (!res.done)
+            this._current = res.value;
+        return res;
+    }
+
+    public get currentValue(): number {
+        return this._current;
+    }
 
     // interface IterableIterator
 
diff --git a/src/param/param-values.ts b/src/param/param-values.ts
index f30e70d5b2b9ae6e0dcfdb62f57e96ff3459fe00..dea1db9d04ea3f282f7fae570d5ca27489234532 100644
--- a/src/param/param-values.ts
+++ b/src/param/param-values.ts
@@ -1,9 +1,9 @@
-import { Pair } from "../util/pair"
-import { DefinedNumber } from "../util/definedvalue";
-import { IReferencedNub, INubReference, NubReference } from "../value_ref/object_ref";
 import { Result } from "..";
+import { DefinedNumber } from "../util/definedvalue";
+import { Pair } from "../util/pair";
+import { INubReference, IReferencedNub, NubReference } from "../value_ref/object_ref";
+import { IterableValues, NamedIterableValues, NumberIterator, ParamValueIterator } from "./param-value-iterator";
 import { ParamValueMode } from "./param-value-mode";
-import { ParamValueIterator, IterableValues, NamedIterableValues, NumberIterator } from "./param-value-iterator";
 
 export class ParamValues implements INubReference, IterableValues {
     /**
@@ -59,7 +59,7 @@ export class ParamValues implements INubReference, IterableValues {
 
     public setValues(o: number | any, max?: number, step?: number) {
         if (typeof (o) === "number") {
-            if (max == undefined) {
+            if (max === undefined) {
                 this._valueMode = ParamValueMode.SINGLE;
                 this._singleValue.value = o as number;
                 this._currentValue.value = o as number;
@@ -70,14 +70,13 @@ export class ParamValues implements INubReference, IterableValues {
                 this._stepValue = step;
                 this._currentValue.undefine();
             }
-        }
-        else if (Array.isArray(o)) {
+        } else if (Array.isArray(o)) {
             this._valueMode = ParamValueMode.LISTE;
             this._valueList = o;
             this._currentValue.undefine();
-        }
-        else
+        } else {
             throw new Error(`ParamValues.setValues() :  appel invalide`);
+        }
     }
 
     public get valueMode() {
@@ -88,32 +87,33 @@ export class ParamValues implements INubReference, IterableValues {
         this._valueMode = m;
     }
 
-    private checkValueMode(expected: ParamValueMode) {
-        if (this._valueMode != expected)
-            throw new Error(`ParamValues : mode de valeurs ${ParamValueMode[expected]} incorrect`);
-    }
-
     public check() {
         switch (this._valueMode) {
             case ParamValueMode.SINGLE:
-                if (!this._singleValue.isDefined)
+                if (!this._singleValue.isDefined) {
                     throw new Error(`ParamValues : valeur fixe non définie`);
+                }
                 break;
 
             case ParamValueMode.MINMAX:
-                if (this._minValue == undefined)
+                if (this._minValue === undefined) {
                     throw new Error(`ParamValues : valeur min non définie`);
-                if (this._maxValue == undefined)
+                }
+                if (this._maxValue === undefined) {
                     throw new Error(`ParamValues : valeur max non définie`);
-                if (this._stepValue == undefined)
+                }
+                if (this._stepValue === undefined) {
                     throw new Error(`ParamValues : valeur du pas non définie`);
-                if (this._minValue > this._maxValue)
+                }
+                if (this._minValue > this._maxValue) {
                     throw new Error(`ParamValues : min > max`);
+                }
                 break;
 
             case ParamValueMode.LISTE:
-                if (this._valueList == undefined)
+                if (this._valueList === undefined) {
                     throw new Error(`ParamValues : liste de valeurs non définie`);
+                }
                 break;
 
             case ParamValueMode.LINK:
@@ -129,8 +129,9 @@ export class ParamValues implements INubReference, IterableValues {
      * valeur courante
      */
     public get currentValue(): number {
-        if (this.isReferenceDefined)
-            return this._nubRef.referencedParamValues.currentValue;
+        if (this.isReferenceDefined) {
+            return this._nubRef.referencedObject.currentValue;
+        }
         return this._currentValue.value;
     }
 
@@ -142,8 +143,9 @@ export class ParamValues implements INubReference, IterableValues {
      * valeur dans le mode SINGLE
      */
     public get singleValue(): number {
-        if (this.isReferenceDefined)
+        if (this.isReferenceDefined) {
             return this._nubRef.referencedParamValues.singleValue;
+        }
         return this._singleValue.value;
     }
 
@@ -161,6 +163,12 @@ export class ParamValues implements INubReference, IterableValues {
         return this._currentValue.isDefined;
     }
 
+    private checkValueMode(expected: ParamValueMode) {
+        if (this._valueMode !== expected) {
+            throw new Error(`ParamValues : mode de valeurs ${ParamValueMode[expected]} incorrect`);
+        }
+    }
+
     public get min() {
         switch (this._valueMode) {
             case ParamValueMode.MINMAX:
@@ -241,42 +249,6 @@ export class ParamValues implements INubReference, IterableValues {
         return new ParamValueIterator(this, reverse);
     }
 
-    /**
-     * 
-     * @param reverse prépare un itérateur pour parcourir les valeurs
-     */
-    public initIterator(reverse: boolean = false) {
-        switch (this._valueMode) {
-            case ParamValueMode.LISTE:
-            case ParamValueMode.MINMAX:
-                this._iterator = this.getValuesIterator(reverse);
-                break;
-
-            case ParamValueMode.LINK:
-                this._iterator = this._nubRef.referencedParamValues.getValuesIterator(reverse);
-                break;
-
-            default:
-                throw new Error(`ParamValues : mode de valeurs ${ParamValueMode[this._valueMode]} incorrect`);
-        }
-    }
-
-    /**
-     * @return true si il reste des valeurs à parcourir par l'itérateur courant
-     */
-    public get hasNext(): boolean {
-        return this._iterator.hasNext;
-    }
-
-    /**
-     * fixe la valeur courante à la prochaine valeur à parcourir par l'itérateur courant
-     * @return prochaine valeur à parcourir par l'itérateur courant
-     */
-    public get next(): number {
-        this._currentValue.value = this._iterator.next().value;
-        return this._currentValue.value;
-    }
-
     // interface INubReference
 
     public defineReference(target: IReferencedNub, desc: string) {
@@ -317,8 +289,9 @@ export class ParamValues implements INubReference, IterableValues {
     }
 
     public get referencedObject(): NamedIterableValues {
-        if (this.isReferenceDefined)
+        if (this.isReferenceDefined) {
             return this._nubRef.referencedObject;
+        }
         return undefined;
     }
 
@@ -329,23 +302,71 @@ export class ParamValues implements INubReference, IterableValues {
     }
 
     public get hasMultipleValues(): boolean {
-        if (this.isReferenceDefined)
-            var it = this.referencedValuesIterator;
-        else {
+        let it;
+        if (this.isReferenceDefined) {
+            it = this.referencedValuesIterator;
+        } else {
             // dans certains cas (mode LINK mais aucune valeur liable compatible), on ne peut avoir d'itérateur
-            if (this._valueMode !== ParamValueMode.LINK)
+            if (this._valueMode !== ParamValueMode.LINK) {
                 it = this.getValuesIterator();
+            }
         }
 
-        if (it === undefined)
+        if (it === undefined) {
             return false;
+        }
 
         let n = 0;
         for (const v of it) {
             n++;
-            if (n > 1)
+            if (n > 1) {
                 break;
+            }
         }
         return n > 1;
     }
+
+    public initValuesIterator(reverse: boolean = false): NumberIterator {
+        switch (this._valueMode) {
+            case ParamValueMode.LISTE:
+            case ParamValueMode.MINMAX:
+                this._iterator = this.getValuesIterator(reverse);
+                break;
+
+            case ParamValueMode.LINK:
+                this._iterator = this.referencedObject.initValuesIterator(reverse);
+                break;
+
+            default:
+                throw new Error(`ParamValues : mode de valeurs ${ParamValueMode[this._valueMode]} incorrect`);
+        }
+
+        return this._iterator;
+    }
+
+    /**
+     * @return true si il reste des valeurs à parcourir par l'itérateur courant
+     */
+    public get hasNext(): boolean {
+        return this._iterator.hasNext;
+    }
+
+    /**
+     * fixe la valeur courante à la prochaine valeur à parcourir par l'itérateur courant
+     * @return prochaine valeur à parcourir par l'itérateur courant
+     */
+    public next(): IteratorResult<number> {
+        if (this.isReferenceDefined)
+            var res = this.referencedObject.next();
+        else {
+            res = this._iterator.next();
+            if (!res.done)
+                this._currentValue.value = res.value;
+        }
+        return res;
+    }
+
+    public [Symbol.iterator](): IterableIterator<number> {
+        return this;
+    }
 }
diff --git a/src/remous.ts b/src/remous.ts
index ac0ee931a6983c133609d9ecef2170307fcd39fa..f23ac606f0f6244be9fd523c3fef1e8e42141ecc 100644
--- a/src/remous.ts
+++ b/src/remous.ts
@@ -543,7 +543,7 @@ export class CourbeRemous extends Nub {
                 `Condition limite aval (${this.prms.Yaval.v}) >= ` +
                 `Hauteur critique (${this.Sn.HautCritique}) : calcul de la partie fluviale à partir de l'aval`);
             this.Dx = this.prms.Dx.v;
-            xValues.initIterator(true);
+            xValues.initValuesIterator(true);
             res = this.calcul(this.prms.Yaval.v, xValues);
             res.insertMessage(new Message(MessageCode.INFO_REMOUS_CALCUL_FLUVIAL));
         } else {
@@ -578,7 +578,7 @@ export class CourbeRemous extends Nub {
                 ") <= Hauteur critique (" + this.Sn.HautCritique +
                 ") : calcul de la partie torrentielle à partir de l'amont");
             this.Dx = -this.prms.Dx.v;
-            xValues.initIterator(false);
+            xValues.initValuesIterator(false);
             res = this.calcul(this.prms.Yamont.v, xValues);
             res.insertMessage(new Message(MessageCode.INFO_REMOUS_CALCUL_TORRENTIEL));
         } else {
@@ -802,11 +802,11 @@ export class CourbeRemous extends Nub {
         const res = new ResultElement();
 
         let lastY = YCL;
-        trY[round(varParam.next, this.prmSect.iPrec.v)] = lastY;
+        trY[round(varParam.next().value, this.prmSect.iPrec.v)] = lastY;
 
         // Boucle de calcul de la courbe de remous
         while (varParam.hasNext) {
-            const x = varParam.next;
+            const x = varParam.next().value;
             // this.debug("lastY " + lastY);
             const rY: Result = this.Calc_Y(lastY);
             // this.debug("calcul : x " + x + " y " + rY.vCalc);
diff --git a/src/session_nub.ts b/src/session_nub.ts
index 4a80ed6d6c84bcdb0d56487f0e3e798a1ba16bda..4313fab85a35e73b884dbf09cc58fb83453c7101 100644
--- a/src/session_nub.ts
+++ b/src/session_nub.ts
@@ -222,7 +222,18 @@ export class SessionNub {
     /**
      * liste des valeurs(paramètre, résultat, résultat complémentaire) liables à un paramètre
      * @param src objet qui sert de clé de recherche des paramètres liables, de type INamedObject | string
-     * @returns tableau d'objets de la forme { "value":NamedIterableValues, "nub":Nub}, nub=Nub d'origine de la "value"
+     * @returns tableau d'objets de la forme { "value":NamedIterableValues, "nub":Nub},
+     *   nub=Nub d'origine de la "value"
+     * 
+     *   l'étiquette "name" est de la forme <n|N1>[.[N2]]
+     *     n : indice de de l'ouvrage dans le cas des ouvrages parallèles
+     *     N1 : un nom de paramètre/résultat (dans le cas d'un résultat, il est suivi d'un point)
+     *     N2 : nom de résultat complémentaire (optionnel)
+     *     ex :
+     *       Q, Z1 (paramètres)
+     *       J. (résultat)
+     *       .Yf (résultat complémentaire du résultat courant)
+     *       Q.Yf (résultat complémentaire du résultat nommé "Q")
      */
     public getLinkableValues(src: any, excludeResult: boolean = false): any[] {
         return this._nub.getLinkableValues(src, undefined, excludeResult);
diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts
index 60299bc80d0f0b9872c038f3185b0d8a52820dfd..1ecbc67a0febad528dab4f8d83385f012a91d838 100644
--- a/src/structure/parallel_structure.ts
+++ b/src/structure/parallel_structure.ts
@@ -225,12 +225,16 @@ export class ParallelStructure extends Nub {
             const i: IStructureVarCalc = this.getStructureVarCalc(desc);
             return this.structures[i.index].getParameter(i.prm);
         } catch (e) {
+            // desc n'est pas de la forme n.X
             try {
                 // analyse ouvrage[n].X
                 const i: IStructureVarCalc = this.getStructureVarCalc2(desc);
-                return this.structures[i.index].result.getExtraResult(i.prm);
+                const res = this.structures[i.index].result;
+                if (res === undefined)
+                    return undefined;  // pas de résultat calculé
+                return res.getExtraResult(i.prm);
             } catch (e) {
-                // ???
+                // desc n'est pas de la forme ouvrage[n].X
             }
         }
         // pas de la forme n.X ou ouvrage[n].X ou erreur sur n ou X
diff --git a/src/util/iterator.ts b/src/util/iterator.ts
index 190813773fb9fe94a8acd78edd9221ddf80a50a9..b33d36b9461241e2f116d8c4e016d123557642a8 100644
--- a/src/util/iterator.ts
+++ b/src/util/iterator.ts
@@ -10,7 +10,7 @@
 export class ArrayReverseIterator<T> implements IterableIterator<T> {
     private _index: number;
 
-    constructor(private _arr: any[]) {
+    constructor(protected _arr: any[]) {
         this._index = this._arr === undefined ? 0 : this._arr.length - 1;
     }
 
diff --git a/src/util/result.ts b/src/util/result.ts
index 6c4ac03d06b95d66e157aa39a5b004242b653ba0..0998f141445eb78331682947b42ad45d284278e4 100644
--- a/src/util/result.ts
+++ b/src/util/result.ts
@@ -1,8 +1,8 @@
+import { JalhydObject } from "../jalhyd_object";
+import { NamedIterableValues, NumberIterator, NumberArrayReverseIterator, NumberArrayIterator } from "../param/param-value-iterator";
 import { cLog } from "./log";
 import { Message, MessageCode, MessageSeverity } from "./message";
 import { ResultElement } from "./resultelement";
-import { JalhydObject } from "../jalhyd_object";
-import { NamedIterableValues, NumberIterator } from "../param/param-value-iterator";
 
 /**
  * Résultat global d'un calcul
@@ -22,6 +22,11 @@ export class Result extends JalhydObject implements NamedIterableValues {
      */
     private _name: string;
 
+    /**
+     * itérateur sur les valeurs des ResultElements
+     */
+    private _iterator: NumberIterator;
+
     constructor(v?: number | Message | ResultElement, d?: any) {
         super();
         this._globalLog = new cLog();
@@ -296,6 +301,38 @@ export class Result extends JalhydObject implements NamedIterableValues {
 
         return undefined;
     }
+
+    public initValuesIterator(reverse: boolean = false): NumberIterator {
+        const vals: number[] = [];
+        for (const r of this._resultElements) {
+            vals.push(r.vCalc);
+        }
+
+        if (reverse)
+            this._iterator = new NumberArrayReverseIterator(vals);
+        else
+            this._iterator = new NumberArrayIterator(vals);
+
+        return this._iterator;
+    }
+
+    public get hasNext(): boolean {
+        return this._iterator.hasNext;
+    }
+
+    public next(): IteratorResult<number> {
+        return this._iterator.next();
+    }
+
+    public get currentValue(): number {
+        if (this._iterator === undefined)
+            return this.vCalc;
+        return this._iterator.currentValue;
+    }
+
+    public [Symbol.iterator](): IterableIterator<number> {
+        return this;
+    }
 }
 
 /**
@@ -306,6 +343,11 @@ export class ExtraResults extends JalhydObject implements NamedIterableValues {
 
     private _values: number[];
 
+    /**
+     * itérateur courant
+     */
+    private _iterator: NumberIterator;
+
     constructor(n: string) {
         super();
         this._name = n;
@@ -329,4 +371,29 @@ export class ExtraResults extends JalhydObject implements NamedIterableValues {
     public get name(): string {
         return this._name;
     }
+
+    public initValuesIterator(reverse: boolean = false): NumberIterator {
+        if (reverse)
+            this._iterator = new NumberArrayReverseIterator(this._values);
+        else
+            this._iterator = new NumberArrayIterator(this._values);
+
+        return this._iterator;
+    }
+
+    public get hasNext(): boolean {
+        return this._iterator.hasNext;
+    }
+
+    public next(): IteratorResult<number> {
+        return this._iterator.next();
+    }
+
+    public get currentValue(): number {
+        return this._iterator.currentValue;
+    }
+
+    public [Symbol.iterator](): IterableIterator<number> {
+        return this;
+    }
 }
diff --git a/src/value_ref/object_ref.ts b/src/value_ref/object_ref.ts
index b321604faacda0da1060ddf9d13a545697286afa..7670eaaaaca224f4f3b985c6ac42bacecd42cc7d 100644
--- a/src/value_ref/object_ref.ts
+++ b/src/value_ref/object_ref.ts
@@ -1,13 +1,30 @@
-import { ParamValues } from "../param/param-values";
-import { Result } from "..";
-import { IJalhydObject } from "../jalhyd_object";
+import { Nub } from "../nub";
 import { NamedIterableValues, NumberIterator } from "../param/param-value-iterator";
+import { ParamValues } from "../param/param-values";
+import { Result } from "../util/result";
+
+/*
+ * gestion de la valeur d'un paramètre par référence à une autre valeur (paramètre, résultat, résultat complémentaire)
+ * 
+ * la référence (cf. INubReference.defineReference) (cf. INubReference.defineReference) est de la forme <n | ouvrage[n] | N1>[.[N2]]
+ *     n : indice de de l'ouvrage dans le cas des ouvrages parallèles
+ *     N1 : un nom de paramètre/résultat (dans le cas d'un résultat, il est suivi d'un point)
+ *     N2 : nom de résultat complémentaire (optionnel)
+ *     ex :
+ *       Q, Z1 (paramètres)
+ *       J. (résultat)
+ *       .Yf (résultat complémentaire du résultat courant)
+ *       Q.Yf (résultat complémentaire du résultat nommé "Q")
+ *       0.Q : paramètre Q du 1er ouvrage (ouvrages parallèles)
+ *       ouvrage[1].Q_Mode : résultat complémentaire du 2ème ouvrage (ouvrages parallèles)
+ */
 
 /**
  * Nub dont certaines valeurs sont référençables pour réutilisation
  * (d'une calculette sur une autre par ex)
  */
 export interface IReferencedNub {
+
     /**
      * getter des valeurs
      * @param desc : description sous forme symbolique
@@ -132,8 +149,9 @@ export class NubReference implements INubReference {
      * instance de ParamValues référencée
      */
     public get referencedParamValues(): ParamValues {
-        if (!this.isReferenceDefined)
+        if (!this.isReferenceDefined) {
             return undefined;
+        }
         return this._referencedNub.getReferencedParamValues(this._refDefinition);
     }
 
@@ -141,8 +159,9 @@ export class NubReference implements INubReference {
      * instance de Result référencée
      */
     public get referencedResult(): Result {
-        if (!this.isReferenceDefined)
+        if (!this.isReferenceDefined) {
             return undefined;
+        }
         return this._referencedNub.getReferencedResult(this._refDefinition);
     }
 
@@ -150,8 +169,9 @@ export class NubReference implements INubReference {
      * instance de résultat complémentaire référencée
      */
     public get referencedExtraResult(): any {
-        if (!this.isReferenceDefined)
+        if (!this.isReferenceDefined) {
             return undefined;
+        }
         return this._referencedNub.getReferencedExtraResult(this._refDefinition);
     }