Commit de7a95a7 authored by Dorchies David's avatar Dorchies David
Browse files

#22 tests qui marchent mais résultat incorrect sur Q

Showing with 122 additions and 44 deletions
+122 -44
......@@ -6,7 +6,7 @@
*/
// import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
import { ParamCalculability } from "../../src";
import { ParamCalculability, ParamValueMode } from "../../src";
import { MacroRugo, MacrorugoParams } from "../../src/macrorugo/macrorugo";
import { checkResult } from "../test_func";
......@@ -17,7 +17,7 @@ function macroRugoInstance(): MacroRugo {
6, // L
1, // B
0.05, // If
0.5, // Q
9.418, // Q
0.6, // h
0.01, // Ks
0.05, // C
......@@ -28,15 +28,15 @@ function macroRugoInstance(): MacroRugo {
);
}
function testMacroRugo(varTest: string) {
function testMacroRugo(varTest: string, valRef: number) {
describe("Calc(): ", () => {
it("V should be 1", () => {
it(`${varTest} should be ${valRef}`, () => {
const nub = macroRugoInstance();
nub.prms.Q.v = nub.Calc("Q").vCalc;
const res: number = nub.prms[varTest].v;
nub.prms[varTest].v = undefined;
checkResult(nub.Calc(varTest, 0), res);
const p = nub.getParameter(varTest);
p.v = undefined;
p.valueMode = ParamValueMode.CALCUL;
checkResult(nub.Calc(varTest, 0.1), valRef);
});
});
}
......@@ -48,7 +48,7 @@ describe("Class MacroRugo: ", () => {
for (const prm of nub.prms) {
if ([ParamCalculability.DICHO, ParamCalculability.EQUATION].includes(prm.calculability)) {
testMacroRugo(prm.symbol);
testMacroRugo(prm.symbol, prm.v);
}
}
});
......@@ -184,7 +184,7 @@ export function compareLog(logTest: cLog, logValid: cLog) {
}
export function checkResult(val1: Result, val2: number, prec?: number) {
expect(val1.ok).toBeTruthy("Result : computation error on Result " + val1.toString());
expect(val1.ok).toBeTruthy((!val1.ok) ? "Result: ERROR code=" + MessageCode[val1.code] : "");
if (val1.ok) {
/*
* on demande une précision de vérification inférieure à la précision de calcul
......
......@@ -5,6 +5,12 @@ import { MacrorugoParams } from "./macrorugo_params";
export { MacrorugoParams };
export enum MacroRugoFlowType {
EMERGENT,
QUASI_EMERGENT,
IMMERGE
}
export class MacroRugo extends Nub {
private static readonly g = 9.81;
......@@ -16,6 +22,10 @@ export class MacroRugo extends Nub {
/** Ratio between the lenght (parallel to flow) and the width (perpendicular to flow) of a cell (-) */
private static readonly fracAyAx = 1;
/** Limit between emergent and submerged flow */
private static readonly limitSubmerg = 1.1;
/** Rugosité de fond (m) */
private ks: number;
/** Averaged velocity at the bed (m.s-1) */
......@@ -34,17 +44,84 @@ export class MacroRugo extends Nub {
return this._prms as MacrorugoParams;
}
/**
* Calcul du débit total, de la cote amont ou aval ou d'un paramètre d'une structure
* @param sVarCalc Nom du paramètre à calculer :
* "Q", "Z1", "Z2" ou "n.X" avec "n" l'index de l'ouvrage et "X" son paramètre
* @param rInit Valeur initiale
* @param rPrec Précision attendue
*/
public Calc(sVarCalc: string, rInit?: number, rPrec: number = 0.001): Result {
const r: Result = super.Calc(sVarCalc, rInit, rPrec);
// Ajout des résultats complémentaires
// Cote de fond aval
r.extraResults.ZF2 = this.prms.ZF1.v - this.prms.If.v * this.prms.L.v;
// Vitesse débitante
r.extraResults.Vdeb = this.V(this.prms.Q) / this.prms.B.v / this.prms.Y.v;
// Vitesse maximale
r.extraResults.V = r.extraResults.Vdeb * this.calc_fFr(r.extraResults.Vdeb);
// Puissance dissipée
r.extraResults.P = 1000 * MacroRugo.g * this.V(this.prms.Q) / this.prms.B.v * this.prms.If.v;
// Type d'écoulement
if (this.prms.Y.v / this.prms.PBH.v < 1) {
r.extraResults.FlowType = MacroRugoFlowType.EMERGENT;
} else if (this.prms.Y.v / this.prms.PBH.v < 1.1) {
r.extraResults.FlowType = MacroRugoFlowType.QUASI_EMERGENT;
} else {
r.extraResults.FlowType = MacroRugoFlowType.IMMERGE;
}
// Vitesse et débit du guide technique
let cQ: [number, number, number, number];
let cV: [number, number, number];
if (this.prms.Y.v / this.prms.PBH.v > 1.1) {
cQ = [0.955, 2.282, 0.466, -0.23];
} else {
if (Math.abs(this.prms.Cd0.v - 2) < 0.05) {
cQ = [0.648, 1.084, 0.56, -0.456];
cV = [3.35, 0.27, 0.53];
} else {
cQ = [0.815, 1.45, 0.557, -0.456];
cV = [4.54, 0.32, 0.56]
}
}
r.extraResults.Q2 = cQ[0] * Math.pow(this.prms.Y.v / this.prms.PBH.v, cQ[1]) *
Math.pow(this.prms.If.v, cQ[2]) * Math.pow(this.prms.C.v, cQ[3]) *
Math.sqrt(MacroRugo.g * this.prms.PBD.v) * this.prms.PBH.v * this.prms.B.v;
if (this.prms.Y.v / this.prms.PBH.v <= 1.1) {
r.extraResults.V2 = cV[0] * Math.pow(this.prms.Y.v / this.prms.PBD.v, cV[1]) *
Math.pow(this.prms.If.v, cQ[2]) * Math.sqrt(MacroRugo.g * this.prms.PBD.v);
}
return r;
}
public Equation(sVarCalc: string): Result {
const Q = uniroot(this.calcQ, this, 0, 1E7);
const Q = uniroot(this.calcQ, this, 0, 1E7) * this.prms.B.v;
return new Result(Q);
}
/**
* paramétrage de la calculabilité des paramètres
*/
protected setParametersCalculability() {
this.prms.ZF1.calculability = ParamCalculability.FREE;
this.prms.L.calculability = ParamCalculability.FREE;
this.prms.Ks.calculability = ParamCalculability.FREE;
this.prms.B.calculability = ParamCalculability.DICHO;
this.prms.If.calculability = ParamCalculability.DICHO;
this.prms.Q.calculability = ParamCalculability.EQUATION;
this.prms.Y.calculability = ParamCalculability.DICHO;
this.prms.C.calculability = ParamCalculability.DICHO;
this.prms.PBD.calculability = ParamCalculability.DICHO;
this.prms.PBH.calculability = ParamCalculability.FREE;
this.prms.Cd0.calculability = ParamCalculability.DICHO;
}
/**
* Equation from Cassan, L., Laurens, P., 2016. Design of emergent and submerged rock-ramp fish passes.
* Knowledge & Management of Aquatic Ecosystems 45.
* @param sVarCalc Variable à calculer
*/
public calcQ(this: MacroRugo, Q: number): number {
private calcQ(this: MacroRugo, Q: number): number {
// Reset cached variables depending on Q (or not...)
this._cache = {};
/** Longueur (m) */
......@@ -69,13 +146,17 @@ export class MacroRugo extends Nub {
const g = MacroRugo.g;
const kappa = 0.41; // von Karman constant
// u0 = Averaged velocity at the bed (m.s-1)
this.u0 = Q / this.prms.L.v / this.prms.Y.v;
/** Calulated average velocity */
let u: number;
if (h / k > 1.1) {
if (h / k > MacroRugo.limitSubmerg) {
// Submerged conditions
/** Velocity at the bed §2.3.2 Cassan et al., 2016 */
this.u0 = Math.sqrt(2 * g * S * D * this.R / (Cd0 * C));
/** @todo Faut-il un point fixe ici vu que Cd dépend de u0 ? */
this.u0 = Math.sqrt(2 * g * S * D * this.R / (this.calcCd(this.calc_fFr(this.u0)) * C));
/** turbulent length scale (m) within the blocks layer (alpha_t) */
const alpha = uniroot(this.calcAlpha_t, this, 0, 100);
/** averaged velocity at the top of blocks (m.s-1) */
......@@ -110,11 +191,8 @@ export class MacroRugo extends Nub {
} else {
// Emergent conditions
// u0 = Averaged velocity at the bed (m.s-1)
this.u0 = Q / this.prms.L.v / this.prms.Y.v;
// Resolve equation (4) Cassan et al., 2016
u = uniroot(this.calcU0, this, 0, 1E7);
u = uniroot(this.resolveU0, this, 0, 1E7);
}
return this.u0 - u;
}
......@@ -144,16 +222,16 @@ export class MacroRugo extends Nub {
if (this._cache.R !== undefined) {
return this._cache.R;
}
return (1 - this.sigma * this.prms.C.v) * Math.pow(1 - Math.sqrt(this.prms.C.v), 2);
return (1 - this.sigma * this.prms.C.v);
}
/**
* Bed friction coefficient Equation (3) (Cassan et al., 2016)
*/
private get Cf(): number {
private calcCf(U0: number): number {
// Between Eq (8) and (9) (Cassan et al., 2016)
// tslint:disable-next-line:variable-name
const Re = this.u0 * this.prms.Y.v / MacroRugo.nu;
const Re = U0 * this.prms.Y.v / MacroRugo.nu;
if (this.prms.Ks.v < 1E-6) {
return 0.3164 / 4. * Math.pow(Re, -0.25);
......@@ -163,23 +241,6 @@ export class MacroRugo extends Nub {
}
}
/**
* paramétrage de la calculabilité des paramètres
*/
protected setParametersCalculability() {
this.prms.ZF1.calculability = ParamCalculability.FREE;
this.prms.L.calculability = ParamCalculability.FREE;
this.prms.Ks.calculability = ParamCalculability.FREE;
this.prms.B.calculability = ParamCalculability.DICHO;
this.prms.If.calculability = ParamCalculability.DICHO;
this.prms.Q.calculability = ParamCalculability.EQUATION;
this.prms.Y.calculability = ParamCalculability.DICHO;
this.prms.C.calculability = ParamCalculability.DICHO;
this.prms.PBD.calculability = ParamCalculability.FREE;
this.prms.PBH.calculability = ParamCalculability.FREE;
this.prms.Cd0.calculability = ParamCalculability.FREE;
}
/**
* Calculation of Cd : drag coefficient of a block under the actual flow conditions
* @param Cd0
......@@ -230,17 +291,17 @@ export class MacroRugo extends Nub {
return alpha * this.calcUz(alpha) - l0 * this.ustar;
}
private calcU0(U01: number) {
private resolveU0(U0: number) {
const g = MacroRugo.g;
const alpha = 1 - (1 * this.prms.C.v);
// tslint:disable-next-line:variable-name
const Cd = this.calcCd(this.calc_fFr(U01));
const Cd = this.calcCd(this.calc_fFr(U0));
/** N from Cassan 2016 eq(2) et Cassan 2014 eq(12) */
const N = (alpha * this.Cf) / (this.prms.Y.v / this.prms.PBD.v * Cd * this.prms.C.v);
const N = (alpha * this.calcCf(U0)) / (this.prms.Y.v / this.prms.PBD.v * Cd * this.prms.C.v);
return U01 - Math.sqrt(
return U0 - Math.sqrt(
2 * MacroRugo.g * this.prms.If.v * this.prms.PBD.v *
(1 - this.sigma * this.prms.C.v) / (Cd * this.prms.C.v * (1 + N))
);
......
......@@ -110,8 +110,9 @@ export abstract class Nub extends ComputeNode implements IReferencedNub {
case ParamValueMode.LINK:
const ro = p.referencedObject;
if (ro !== undefined && ro.hasMultipleValues)
if (ro !== undefined && ro.hasMultipleValues) {
variatedValues = this.setVariatedValues(p, variatedValues);
}
break;
default:
......@@ -161,6 +162,22 @@ export abstract class Nub extends ComputeNode implements IReferencedNub {
return this._result;
}
/**
* Renvoie la valeur actuelle d'un paramètre (valeur utilisateur ou résultat)
* @param p Paramètre
*/
public V(p: ParamDefinition): number {
if (p.valueMode === ParamValueMode.CALCUL) {
if (this.result !== undefined) {
if (this.result.ok) {
return this.result.vCalc;
}
}
throw new Error(`Attempt to read the result of ${p.symbol} but none found`);
}
return p.v;
}
// interface IReferencedNub
public getReferencedParamValues(desc: string): ParamValues {
......@@ -218,7 +235,7 @@ export abstract class Nub extends ComputeNode implements IReferencedNub {
* 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)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment