From ac261833a532675e5a2df4ebc92b52835dcb146e Mon Sep 17 00:00:00 2001
From: "mathias.chouet" <mathias.chouet@irstea.fr>
Date: Wed, 20 Nov 2019 11:41:36 +0100
Subject: [PATCH] MacrorugoCompound: calculate children depths once for all in
 CalcSerie()

---
 spec/macrorugo/macrorugo_compound.spec.ts | 15 +++++++--
 src/macrorugo/macrorugo_compound.ts       | 37 ++++++++++++++++++++++-
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/spec/macrorugo/macrorugo_compound.spec.ts b/spec/macrorugo/macrorugo_compound.spec.ts
index 0c2f7fc2..813a77d7 100644
--- a/spec/macrorugo/macrorugo_compound.spec.ts
+++ b/spec/macrorugo/macrorugo_compound.spec.ts
@@ -28,7 +28,7 @@ function getMacroRugoRef(i: number = 0): MacroRugo {
 
 describe("MacroRugoCompound", () => {
     describe("Default 1 apron", () => {
-        it("should return same result as Macrorugo", () => {
+        it("should return same result as Macrorugo (1)", () => {
             const mrc = Session.getInstance().createNub(
                 new Props({ calcType: CalculatorType.MacroRugoCompound })
             ) as MacrorugoCompound;
@@ -36,7 +36,7 @@ describe("MacroRugoCompound", () => {
             const mr = getMacroRugoRef();
             expect(mrc.CalcSerie().vCalc).toBeCloseTo(mr.result.vCalc, 3);
         });
-        it("should return same result as Macrorugo", () => {
+        it("should return same result as Macrorugo (2)", () => {
             const mrc = Session.getInstance().createNub(
                 new Props({ calcType: CalculatorType.MacroRugoCompound })
             ) as MacrorugoCompound;
@@ -48,6 +48,17 @@ describe("MacroRugoCompound", () => {
             mr.CalcSerie();
             compareTwoResults(mrc.children[0].result, mr.result, 3, [ "ZF2" ]);
         });
+        it("variating Z1, children Y should not always be 0.6", () => {
+            const mrc = Session.getInstance().createNub(
+                new Props({ calcType: CalculatorType.MacroRugoCompound })
+            ) as MacrorugoCompound;
+            mrc.addDefaultChild();
+            mrc.children[0].prms.L.singleValue = 0.5;
+            mrc.prms.Z1.setValues(10, 15, 5);
+            mrc.CalcSerie();
+            const childYs = mrc.children[0].prms.Y.getInferredValuesList();
+            expect(childYs).toEqual([ 0, 2.5 ]);
+        });
     });
     describe("Default inclined but flat apron", () => {
         beforeAll(() => {
diff --git a/src/macrorugo/macrorugo_compound.ts b/src/macrorugo/macrorugo_compound.ts
index 326d1f5f..8645ee22 100644
--- a/src/macrorugo/macrorugo_compound.ts
+++ b/src/macrorugo/macrorugo_compound.ts
@@ -33,6 +33,42 @@ export class MacrorugoCompound extends MacroRugo implements Observer {
             // important to regenerate it here, at every iteration of CalcSerie()
             this.generateInclinedFishway();
         }
+        // calculate and store depths once for all
+        for (const child of this.children) {
+            // do we have a series of values ?
+            if (this.prms.Z1.hasMultipleValues || child.prms.ZF1.hasMultipleValues) {
+                let valsZ1;
+                let valsChildZF1;
+                if (this.prms.Z1.hasMultipleValues) {
+                    valsZ1 = this.prms.Z1.getInferredValuesList();
+                } else {
+                    valsZ1 = new Array(child.prms.ZF1.getInferredValuesList().length)
+                    .fill(this.prms.Z1.singleValue);
+                }
+                if (child.prms.ZF1.hasMultipleValues) {
+                    valsChildZF1 = child.prms.ZF1.getInferredValuesList();
+                } else {
+                    valsChildZF1 = new Array(this.prms.Z1.getInferredValuesList().length)
+                        .fill(child.prms.ZF1.singleValue);
+                }
+                // adjust lengths (should never happen when only one of the paramters is varying)
+                if (valsZ1.length > valsChildZF1.length) {
+                    valsChildZF1 = child.prms.ZF1.getInferredValuesList(valsZ1.length);
+                } else if (valsZ1.length < valsChildZF1.length) {
+                    valsZ1 = this.prms.Z1.getInferredValuesList(valsChildZF1.length);
+                }
+                // define calculated values list on child
+                const valsY: number[] = [];
+                for (let i = 0; i < valsZ1.length; i++) {
+                    valsY.push(Math.max(valsZ1[i] - valsChildZF1[i], 0));
+                }
+                child.prms.Y.setValues(valsY);
+            } else {
+                // or just a single value ?
+                child.prms.Y.setValue(Math.max(this.prms.Z1.singleValue - child.prms.ZF1.singleValue, 0));
+            }
+        }
+
         return super.CalcSerie(rInit);
     }
 
@@ -141,7 +177,6 @@ export class MacrorugoCompound extends MacroRugo implements Observer {
             }
             // Calculate Length and depth from other parameters
             child.prms.L.v = this.prms.DH.v / this.prms.If.v;
-            child.prms.Y.v = Math.max(this.prms.Z1.v - child.prms.ZF1.v, 0);
         }
     }
 
-- 
GitLab