diff --git a/doc/scilab_tests/macrorugo_find_Q_nat.sci b/doc/scilab_tests/macrorugo_find_Q_nat.sci index b54926333caa69b9b766d65229bf579cceed3a68..a449029bfea118f39b63086cfe0e575daa42774a 100644 --- a/doc/scilab_tests/macrorugo_find_Q_nat.sci +++ b/doc/scilab_tests/macrorugo_find_Q_nat.sci @@ -34,9 +34,6 @@ function [res]=find_Q_nat(Q,ks,D,h,Cd0,S,L,pf,C,sigma,bDbg) if(bDbg) then print_r("fFr"); end; - alpha=1-(1.*C).^0.5-1/2*sigma.*C; - Cd=Cd0.*(1+1./(pf./D).^2).*fFr; - //Cd=Cd0.*(0.8-2*C).*(1+0.4./(pf./D).^2).*fFr; R=(1-sigma*C);//%.*(1-C.^0.5).^2; @@ -96,21 +93,27 @@ function [res]=find_Q_nat(Q,ks,D,h,Cd0,S,L,pf,C,sigma,bDbg) else + alpha=1-(1.*C).^0.5-1/2*sigma.*C; + if bDbg then print_r('alpha'); end; + Cd=Cd0.*(1+1./(pf./D).^2).*fFr; + if bDbg then print_r('Cd'); end; + hstar=pf/D; Re=U0.*pf/1e-6; + if bDbg then print_r('Re'); end; if ks==0 Cf=0.3164/4.*Re.^(-0.25); else Cf=2/(5.1*log10(pf/ks-1)+6)^2; end + if bDbg then print_r('Cf'); end; N= (alpha.*Cf)./(pf./D.*Cd.*C); + if bDbg then print_r('N'); end; res=abs(U0-(2*g.*S.*D.*(R)./(Cd.*C.*(1+N))).^0.5); - - end endfunction diff --git a/doc/scilab_tests/macrorugo_find_U0_R0.sci b/doc/scilab_tests/macrorugo_find_U0_R0.sci deleted file mode 100644 index 0023a65645f276ea19293868dcd906a093c50f49..0000000000000000000000000000000000000000 --- a/doc/scilab_tests/macrorugo_find_U0_R0.sci +++ /dev/null @@ -1,25 +0,0 @@ -function [res]=find_U0_R0(U01,h,C,D,sigma,Cd0,cfmean,r,S) -g=9.81; -Frexp=U01./(1-(1.*C).^0.5)./(9.81*h)^0.5; -//Frexp=U01./(9.81*h)^0.5; - - fFr=(min(r./(1-(Frexp.^2)/4),Frexp.^(-2/3))).^2; - - - -if Frexp>1.3 -fFr=(Frexp.^(-2/3)).^2; -end - -alpha=1-(1.*C); - -Cd=Cd0.*(1+0.4./(h./D).^2).*fFr; -//Cd=Cd0.*1.*(1+1./(h./D).^2).*fFr; - N= (alpha.*cfmean)./(h./D.*Cd.*C); - -hstar=h/D; - -//res=(U01-(2*g.*S.*D.*(1-(sigma*C))./(Cd.*C.*(1+N))).^0.5); -res=abs(U01-(2*g.*S.*D*(1-sigma.*C)./(Cd.*C.*(1+N))).^0.5); - -endfunction diff --git a/doc/scilab_tests/macrorugo_resultats_complementaires.sci b/doc/scilab_tests/macrorugo_resultats_complementaires.sci index b9b277538910dd8be6509f4445e7f9ba299e45f2..bf0a9c7c8402628121b21d46f6043d387ac30c71 100644 --- a/doc/scilab_tests/macrorugo_resultats_complementaires.sci +++ b/doc/scilab_tests/macrorugo_resultats_complementaires.sci @@ -17,7 +17,7 @@ function macrorugo_resultComp(z_amont, S, long, Q, L, pf, C, Cd, h, D) if pf/h<1 flowcond = 'emergent' - elseif pf/h<1.1 && pf/h>=1 + elseif pf/h<1.1 & pf/h>=1 flowcond = 'quasi emergent' else flowcond = 'immerge' @@ -31,12 +31,11 @@ function macrorugo_resultComp(z_amont, S, long, Q, L, pf, C, Cd, h, D) if Cd==2 q_technique= 0.648*(pf/D)^1.084*S^0.56*C^(-0.456)*(9.81*D)^0.5.*D*L; V_technique=3.35*(pf/D)^0.27*S^0.53*(9.81*D)^0.5; - Vmax=Vg.*(min(coeff_contraction/(1-(Fr.^2)/4),Fr.^(-2/3))); else q_technique=0.815*(pf/D)^1.45*S^0.557*C^(-0.456)*(9.81*D)^0.5.*D*L; V_technique=4.54*(pf/D)^0.32*S^0.56*(9.81*D)^0.5; - Vmax=Vg.*(min(coeff_contraction/(1-(Fr.^2)/4),Fr.^(-2/3))); end + Vmax=Vg.*(min(coeff_contraction/(1-(Fr.^2)/4),Fr.^(-2/3))); print_r("Vmax"); print_r("V_technique"); end diff --git a/doc/scilab_tests/macrorugo_searchQ.sci b/doc/scilab_tests/macrorugo_searchQ.sci index e9c3656c5de0835e675ba7e194a3fe69d92ba906..912638a281ad4c8ea4397e57dc88907b0739eacc 100644 --- a/doc/scilab_tests/macrorugo_searchQ.sci +++ b/doc/scilab_tests/macrorugo_searchQ.sci @@ -20,6 +20,8 @@ function macrorugo_searchQ(ks, D, k, Cd0, S, B, h, C, z_amont, long, bDbg) g=9.81 N=0; q0=(2*g.*S.*D.*(1-(sigma*C))/(Cd0.*C.*(1+N))).^0.5*h*B; + fVal = find_Q_nat(q0,ks,D,k,Cd0,S,B,h,C,sigma,%t); + printf("find_Q_nat(%f)=%f\n",q0,fVal); [Q fVal, exitflag, outputs] = fminsearch(list(find_Q_nat, ks,D,k,Cd0,S,B,h,C,sigma,bDbg), q0, opt); printf("Q=%f fVal=%f\n",Q, fVal); macrorugo_resultComp(z_amont, S, long, Q, B, h, C, Cd0, k, D) diff --git a/spec/macrorugo/macrorugo.spec.ts b/spec/macrorugo/macrorugo.spec.ts index fe48196121e02214b42f96362b04b4370ea97949..6dbc417848d94d471b02ef28ec840b2e053aa906 100644 --- a/spec/macrorugo/macrorugo.spec.ts +++ b/spec/macrorugo/macrorugo.spec.ts @@ -10,110 +10,185 @@ import { ParamCalculability, ParamValueMode } from "../../src"; import { MacroRugo, MacroRugoFlowType, MacrorugoParams } from "../../src/macrorugo/macrorugo"; import { checkPercent, checkResult } from "../test_func"; -function macroRugoInstanceEmergent(): MacroRugo { +/* +*** Emergent conditions Cd=1.5*** +ks=0.010000 +D=0.500000 +k=0.700000 +Cd0=1.500000 +S=0.050000 +B=1.000000 +h=0.600000 +C=0.130000 +Q=0.493722 fVal=0.000000 +cote_bas = 12.200000 +Vdeb = 0.822870 +Fr = 0.530417 +P = 242.170537 +flowcond = emergent +Vmax = 1.799472 +V_technique = 1.991299 +q_technique = 0.561860 + */ + +function macroRugoInstanceEmergentCd15(): MacroRugo { return new MacroRugo( new MacrorugoParams( 12.5, // ZF1 6, // L 1, // B 0.05, // If - 1.57, // Q + 0.493722, // Q 0.6, // h 0.01, // Ks - 0.05, // C + 0.13, // C 0.5, // D - 0.8, // k + 0.7, // k 1.5 // Cd0 ) ); } +const macroRugoExtraResultEmergentCd15: { [key: string]: number|MacroRugoFlowType } = { + ENUM_MacroRugoFlowType: MacroRugoFlowType.EMERGENT, + Fr: 0.530417, + PV: 242.170537, + Q_GuideTech: 0.561860, + V_GuideTech: 1.991299, + Vdeb: 0.822870, + Vmax: 1.799472, + ZF2: 12.2 +}; + +/* +*** Emergent conditions Cd=2*** +ks=0.010000 +D=0.500000 +k=0.700000 +Cd0=2.000000 +S=0.050000 +B=1.000000 +h=0.600000 +C=0.130000 +Q=0.376808 fVal=0.000000 +cote_bas = 12.200000 +Vdeb = 0.628013 +Fr = 0.404814 +P = 184.824088 +flowcond = emergent +Vmax = 1.536115 +V_technique = 1.592932 +q_technique = 0.414154 + */ + +function macroRugoInstanceEmergentCd2(): MacroRugo { + const nub: MacroRugo = macroRugoInstanceEmergentCd15(); + nub.prms.Cd0.v = 2; + nub.prms.Q.v = 0.376808; + return nub; +} + +const macroRugoExtraResultEmergentCd2: { [key: string]: number|MacroRugoFlowType } = { + ENUM_MacroRugoFlowType: MacroRugoFlowType.EMERGENT, + Fr: 0.404814, + PV: 184.824088, + Q_GuideTech: 0.414154, + V_GuideTech: 1.592932, + Vdeb: 0.628013, + Vmax: 1.536115, + ZF2: 12.2 +}; + +/* +*** Submerged conditions *** +ks=0.010000 +D=0.500000 +k=0.700000 +Cd0=1.500000 +S=0.050000 +B=1.000000 +h=0.800000 +C=0.130000 +Q=0.908068 fVal=0.000000 +cote_bas = 12.200000 +Vdeb = 1.135085 +Fr = 0.633645 +P = 445.407266 +flowcond = immerge +q_technique = 0.940450 + */ + function macroRugoInstanceSubmerged(): MacroRugo { - const nub: MacroRugo = macroRugoInstanceEmergent(); + const nub: MacroRugo = macroRugoInstanceEmergentCd15(); nub.prms.Y.v = 0.8; - nub.prms.PBH.v = 0.6; - nub.prms.Q.v = 4.737; + nub.prms.Q.v = 0.908068; return nub; } -function testMacroRugo(nubFactory: () => MacroRugo, varTest: string, valRef: number) { - describe("Calc(): ", () => { - it(`${varTest} should be ${valRef}`, () => { - const nub = nubFactory(); +const macroRugoExtraResultSubmerged: { [key: string]: number|MacroRugoFlowType } = { + ENUM_MacroRugoFlowType: MacroRugoFlowType.SUBMERGED, + Fr: 0.633645, + PV: 445.407266, + Q_GuideTech: 0.940450, + Vdeb: 1.135085, + ZF2: 12.2 +}; + +function MacroRugoFactory(sInstance: string): MacroRugo { + switch (sInstance) { + case "EmergentCd15": { + return macroRugoInstanceEmergentCd15(); + } + case "EmergentCd2": { + return macroRugoInstanceEmergentCd2(); + } + case "Submerged": { + return macroRugoInstanceSubmerged(); + } + default: { + throw new Error("Instance name error"); + } + } +} + +function testMacroRugo(sInstance: string, varTest: string, valRef: number) { + it(`Calc(${varTest}) should be ${valRef}`, () => { + const nub = MacroRugoFactory(sInstance); nub.prms.Q.v = nub.Calc("Q").vCalc; const p = nub.getParameter(varTest); p.v = undefined; p.valueMode = ParamValueMode.CALCUL; checkResult(nub.Calc(varTest, 0.1), valRef); }); - }); } -describe("Class MacroRugo: ", () => { - - describe("Emerged conditions", () => { - it(`resolveU0(2.58) should be around 0`, () => { - const nubit = macroRugoInstanceEmergent(); +function testMacroRugoConfig(sInstance: string, Q0: number, fVal0: number, mrExtraRes: { [key: string]: number }) { + describe(`Conditions: ${sInstance}` , () => { + it(`resolveQ(${Q0}) should be ${fVal0}`, () => { + const nubit = MacroRugoFactory(sInstance); // tslint:disable-next-line:no-string-literal - expect(nubit["resolveU0"](2.58)).toBeCloseTo(0, 1); - }); - - it(`resolveQ(1.547827) should be around 0`, () => { - const nubit = macroRugoInstanceEmergent(); - // tslint:disable-next-line:no-string-literal - expect(nubit["resolveQ"](1.547827)).toBeCloseTo(0, 1); - }); - - it(`Calc("Q") should be around 1.548`, () => { - checkResult(macroRugoInstanceEmergent().Calc("Q", 0.1), 1.548, 1); - }); - - it(`Calc("Q", 0.1).extraResults.ZF2 should be around 12.2`, () => { - expect(macroRugoInstanceEmergent().Calc("Q", 0.1).extraResults.ZF2).toBeCloseTo(12.2, 3); - }); - - it(`Calc("Q", 0.1).extraResults.Vdeb should be around 2.579818`, () => { - checkPercent(macroRugoInstanceEmergent().Calc("Q", 0.1).extraResults.Vdeb, 2.579818, 0.03); - }); - - it(`Calc("Q", 0.1).extraResults.V should be around 2.694279`, () => { - checkPercent(macroRugoInstanceEmergent().Calc("Q", 0.1).extraResults.V, 2.694279, 0.03); - }); - - it(`Calc("Q", 0.1).extraResults.Fr should be around 1.369611`, () => { - checkPercent(macroRugoInstanceEmergent().Calc("Q", 0.1).extraResults.Fr, 1.369611, 0.03); - }); - - it(`Calc("Q", 0.1).extraResults.P should be around 759.240352`, () => { - checkPercent(macroRugoInstanceEmergent().Calc("Q", 0.1).extraResults.PV, 759.240352, 0.03); - }); - - it(`Calc("Q", 0.1).extraResults.FlowType should be MacroRugoFlowType.EMERGENT`, () => { - expect(macroRugoInstanceEmergent().Calc("Q", 0.1).extraResults.ENUM_MacroRugoFlowType) - .toBe(MacroRugoFlowType.EMERGENT); - }); - - it(`Calc("Q", 0.1).extraResults.Q2 should be around 0.868672`, () => { - checkPercent(macroRugoInstanceEmergent().Calc("Q", 0.1).extraResults.Q_GuideTech, 0.868672, 0.03); - }); - - it(`Calc("Q", 0.1).extraResults.V2 should be around 1.991299`, () => { - checkPercent(macroRugoInstanceEmergent().Calc("Q", 0.1).extraResults.V_GuideTech, 1.991299, 0.03); + expect(nubit["resolveQ"](Q0)).toBeCloseTo(fVal0, 5); }); - - const nub = macroRugoInstanceEmergent(); + const nub = MacroRugoFactory(sInstance); for (const prm of nub.prms) { if ([ParamCalculability.DICHO, ParamCalculability.EQUATION].includes(prm.calculability)) { - testMacroRugo(macroRugoInstanceEmergent, prm.symbol, prm.v); + testMacroRugo(sInstance, prm.symbol, prm.v); + } + } + for (const sExtraRes in mrExtraRes) { + if (mrExtraRes.hasOwnProperty(sExtraRes)) { + it(`${sExtraRes} should be ${mrExtraRes[sExtraRes]}`, () => { + expect(MacroRugoFactory(sInstance).Calc("Q").extraResults[sExtraRes]) + .toBeCloseTo(mrExtraRes[sExtraRes], 5); + }); } } }); - describe("Submerged conditions", () => { - it(`resolveQ(4.737) should be around 0`, () => { - const nubit = macroRugoInstanceSubmerged(); - // tslint:disable-next-line:no-string-literal - expect(nubit["resolveQ"](4.737)).toBeCloseTo(0, 1); - }); +} - }); +describe("Class MacroRugo: ", () => { + + testMacroRugoConfig("EmergentCd15", 0.901710, 0.379574, macroRugoExtraResultEmergentCd15); + testMacroRugoConfig("EmergentCd2", 0.768677, 0.418044, macroRugoExtraResultEmergentCd2); + testMacroRugoConfig("Submerged", 1.202280, 0.145051, macroRugoExtraResultSubmerged); }); diff --git a/src/macrorugo/macrorugo.ts b/src/macrorugo/macrorugo.ts index 30fdf729924c96fd66999d6a08045bc165ad6cab..66db51de68322d1b07988dbd3c6ad5bf51f1886b 100644 --- a/src/macrorugo/macrorugo.ts +++ b/src/macrorugo/macrorugo.ts @@ -9,7 +9,7 @@ export { MacrorugoParams }; export enum MacroRugoFlowType { EMERGENT, QUASI_EMERGENT, - IMMERGE + SUBMERGED } export class MacroRugo extends Nub { @@ -52,8 +52,7 @@ export class MacroRugo extends Nub { /** * 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 sVarCalc Nom du paramètre à calculer * @param rInit Valeur initiale * @param rPrec Précision attendue */ @@ -67,10 +66,14 @@ export class MacroRugo extends Nub { // Vitesse débitante r.extraResults.Vdeb = this.V(this.prms.Q) / this.prms.B.v / this.prms.Y.v; // Froude - r.extraResults.Fr = r.extraResults.Vdeb / (1 - Math.sqrt(MacroRugo.fracAxAy * this.prms.C.v)) - / Math.sqrt(MacroRugo.g * this.prms.Y.v); + const vg: number = r.extraResults.Vdeb / (1 - Math.sqrt(MacroRugo.fracAxAy * this.prms.C.v)); + r.extraResults.Fr = vg / Math.sqrt(MacroRugo.g * this.prms.Y.v); // Vitesse maximale - r.extraResults.V = r.extraResults.Vdeb * this.calc_fFr(r.extraResults.Vdeb); + const cc = 0.4 * this.prms.Cd0.v + 0.7; + r.extraResults.Vmax = vg * Math.min( + cc / (1 - Math.pow(r.extraResults.Fr, 2) / 4), + Math.pow(r.extraResults.Fr, -2 / 3) + ); // Puissance dissipée r.extraResults.PV = 1000 * MacroRugo.g * this.V(this.prms.Q) / this.prms.B.v * this.prms.If.v; // Type d'écoulement @@ -79,13 +82,13 @@ export class MacroRugo extends Nub { } else if (this.prms.Y.v / this.prms.PBH.v < MacroRugo.limitSubmerg) { r.extraResults.ENUM_MacroRugoFlowType = MacroRugoFlowType.QUASI_EMERGENT; } else { - r.extraResults.ENUM_MacroRugoFlowType = MacroRugoFlowType.IMMERGE; + r.extraResults.ENUM_MacroRugoFlowType = MacroRugoFlowType.SUBMERGED; } // Vitesse et débit du guide technique let cQ: [number, number, number, number]; let cV: [number, number, number]; let hdk: number; - if (this.prms.Y.v / this.prms.PBH.v > MacroRugo.limitSubmerg) { + if (r.extraResults.ENUM_MacroRugoFlowType === MacroRugoFlowType.SUBMERGED) { cQ = [0.955, 2.282, 0.466, -0.23]; hdk = this.prms.PBH.v; } else { @@ -101,9 +104,9 @@ export class MacroRugo extends Nub { r.extraResults.Q_GuideTech = cQ[0] * Math.pow(this.prms.Y.v / hdk, cQ[1]) * Math.pow(this.prms.If.v, cQ[2]) * Math.pow(this.prms.C.v, cQ[3]) * Math.sqrt(MacroRugo.g * hdk) * hdk * this.prms.B.v; - if (this.prms.Y.v / this.prms.PBH.v <= MacroRugo.limitSubmerg) { + if (r.extraResults.ENUM_MacroRugoFlowType !== MacroRugoFlowType.SUBMERGED) { r.extraResults.V_GuideTech = 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); + Math.pow(this.prms.If.v, cV[2]) * Math.sqrt(MacroRugo.g * this.prms.PBD.v); } return r; } @@ -201,11 +204,11 @@ export class MacroRugo extends Nub { // Calcul de u moyen uMoy = (Qinf + Qsup) / k; - } else { + } else { // Emergent conditions // Resolve equation (4) Cassan et al., 2016 - uMoy = uniroot(this.resolveU0, this, 0, 1E7); + return this.resolveEmergent(); } return this.U0 - uMoy; } @@ -241,11 +244,11 @@ export class MacroRugo extends Nub { /** * Bed friction coefficient Equation (3) (Cassan et al., 2016) */ - private calcCf(U0: number): number { + private calcCf(): number { - if (this.prms.Ks.v < 1E-6) { + if (this.prms.Ks.v < 1E-9) { // Between Eq (8) and (9) (Cassan et al., 2016) - const reynolds = U0 * this.prms.Y.v / MacroRugo.nu; + const reynolds = this.U0 * this.prms.Y.v / MacroRugo.nu; return 0.3164 / 4. * Math.pow(reynolds, -0.25); } else { // Equation (3) (Cassan et al., 2016) @@ -292,7 +295,7 @@ export class MacroRugo extends Nub { private resolveAlpha_t(alpha: number): number { /** s: minimum distance between blocks */ - const s = this.prms.PBD.v * ( 1 / Math.sqrt(this.prms.C.v) - 1); + const s = this.prms.PBD.v * (1 / Math.sqrt(this.prms.C.v) - 1); /** Equation(11) Cassan et al., 2016 */ const l0 = Math.min(s, 0.15 * this.prms.PBH.v); @@ -300,17 +303,17 @@ export class MacroRugo extends Nub { return alpha * this.calcUz(alpha) - l0 * this.ustar; } - private resolveU0(U0: number): number { + private resolveEmergent(): number { const g = MacroRugo.g; - const alpha = 1 - (1 / MacroRugo.fracAxAy * this.prms.C.v); + const alpha = 1 - Math.pow(1 * this.prms.C.v, 0.5) - 0.5 * this.sigma * this.prms.C.v; // tslint:disable-next-line:variable-name - const Cd = this.calcCd(this.calc_fFr(U0)); + const Cd = this.prms.Cd0.v * (1 + 1 / Math.pow(this.prms.Y.v / this.prms.PBD.v, 2)) * this.calc_fFr(this.U0); /** N from Cassan 2016 eq(2) et Cassan 2014 eq(12) */ - const N = (alpha * this.calcCf(U0)) / (this.prms.Y.v / this.prms.PBD.v * Cd * this.prms.C.v); + const N = (alpha * this.calcCf()) / (this.prms.Y.v / this.prms.PBD.v * Cd * this.prms.C.v); - return U0 - Math.sqrt( + return this.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)) );