Commit 2ed395b9 authored by Dorchies David's avatar Dorchies David
Browse files

#6 Ajout de l'équation CEM88d avec tests OK

Showing with 188 additions and 24 deletions
+188 -24
/**
* Mock fonction describe de Jasmine
* @param sTxt Texte de la suite de test
* @param fFun Fonction de la suite de test
*/
export function describe(sTxt: string, fFun: Function) {
//console.group();
console.log(sTxt);
fFun();
//console.groupEnd();
}
/**
* Mock fonction it de jasmine
* @param sTxt Texte à afficher pour la spec
* @param fFun Function à lancer pour la spec
*/
export function it(sTxt: string, fFun: Function) {
console.log(sTxt);
fFun();
}
/**
* Mock expect et toBeCloseTo de Jasmine.
* Ne fonctionne pas à cause de this = undefined dans le contexte "use strict"
*/
export function expect(obj: Object) {
this.testResult = obj;
this.toBeCloseTo = function(expected: number, precision: number) {
var pow = Math.pow(10, precision + 1);
var delta = Math.abs(expected - this.testResult);
var maxDelta = Math.pow(10, -precision) / 2;
if (Math.round(delta * pow) / pow > maxDelta) {
console.error("Expected "+this.testResult+" to be close to "+expected+","+precision);
}
return this;
};
return this;
}
/**
* Mock de la function chainée à expect de test d'une valeur à un epsilon près
* @param actual Valeur numérique sortie du test
* @param expected Valeur numérique attendue
* @param precision Précision attendue (nombre de chiffre après la virgule)
*/
export function toBeCloseTo (actual: number, expected: number, precision: number) {
var pow = Math.pow(10, precision + 1);
var delta = Math.abs(expected - actual);
var maxDelta = Math.pow(10, -precision) / 2;
if (Math.round(delta * pow) / pow > maxDelta) {
console.error("Expected "+actual+" to be close to "+expected+","+precision);
}
return this;
};
......@@ -4,19 +4,43 @@ import { StructureCem88d, RectangularStructureParams } from "../../src/structure
import { Result } from "../../src/base";
import { precDigits } from "../nubtest";
let structPrm: RectangularStructureParams = new RectangularStructureParams(1, undefined, 1, 2, 0.6, 0);
let structTest: StructureCem88d = new StructureCem88d(structPrm, false);
let resultTesth1FnW: number[] = [Infinity, 3.603062, 1.560872, 1.323331, 1.154102, 1.073632, 1.047438, 1.035118, 1.027086, 1.021649, 1.021305];
let structPrm: RectangularStructureParams = new RectangularStructureParams(1, 1, 1, 2, 0.6, 0);
let structTest: StructureCem88d = new StructureCem88d(structPrm, true);
describe('Class StructureCem88d: ', () => {
describe('Calcul h1 avec W croissant: ', () => {
for(let iW = 0; iW <= 10; iW++ ) {
structTest.prms.W.v = iW / 10 ;
it('h1(W='+structTest.prms.W.v+') should be '+resultTesth1FnW[iW], () => {
console.log('h1(W='+structTest.prms.W.v+') should be '+resultTesth1FnW[iW]);
expect(structTest.Calc('h1').vCalc).toBeCloseTo(resultTesth1FnW[iW],precDigits);
});
function itCalcQ(structTest:StructureCem88d, h1:number, W:number, Q:number) {
it('Q(h1='+h1+',W='+W+') should be '+Q, () => {
structTest.prms.h1.v = h1;
structTest.prms.W.v = W;
expect(structTest.Calc('Q').vCalc).toBeCloseTo(Q,precDigits);
});
}
describe('Calcul Q avec W croissant: ', () => {
let W: number[] = [0.000000,0.100000,0.200000,0.300000,0.400000,0.500000,0.600000,0.700000,0.800000,0.900000,1.000000,1.100000,1.200000,1.300000];
let h1: number = 1.200000;
let Q: number[] = [0.000000,0.617586,1.235173,1.852759,2.470345,3.087931,3.705518,4.296608,4.831177,5.302464,5.700445,6.007777,6.175863,6.175863];
for(let i = 0; i < Q.length; i++ ) {
itCalcQ(structTest, h1, W[i], Q[i]);
}
});
describe('Calcul Q en charge avec h1 croissant: ', () => {
let W: number = 0.6;
let h1: number[] =[1.100000,1.300000,1.500000];
let Q: number[] =[2.620197,4.450866,5.226583];
for(let i = 0; i < Q.length; i++ ) {
itCalcQ(structTest, h1[i], W, Q[i]);
}
});
describe('Calcul Q a surface libre avec h1 croissant: ', () => {
let W: number = Infinity;
let h1: number[] =[1.100000,1.500000];
let Q: number[] =[4.366994,9.764896];
for(let i = 0; i < Q.length; i++ ) {
itCalcQ(structTest, h1[i], W, Q[i]);
}
});
});
import { StructureCem88d, RectangularStructureParams } from "../../src/structure/structure_cem88d";
import { Result } from "../../src/base";
import { precDigits } from "../nubtest";
import { describe, it, toBeCloseTo } from "../mock_jasmine"
//expect(1).toBeCloseTo(1,3);
let structPrm: RectangularStructureParams = new RectangularStructureParams(1, 1, 1, 2, 0.6, 0);
let structTest: StructureCem88d = new StructureCem88d(structPrm, true);
describe('Class StructureCem88d: ', () => {
function itCalcQ(structTest:StructureCem88d, h1:number, W:number, Q:number) {
it('Q(h1='+h1+',W='+W+') should be '+Q, () => {
structTest.prms.h1.v = h1;
structTest.prms.W.v = W;
toBeCloseTo(structTest.Calc('Q').vCalc, Q, precDigits);
});
}
describe('Calcul Q avec W croissant: ', () => {
let W: number[] = [0.000000,0.100000,0.200000,0.300000,0.400000,0.500000,0.600000,0.700000,0.800000,0.900000,1.000000,1.100000,1.200000,1.300000];
let h1: number = 1.200000;
let Q: number[] = [0.000000,0.617586,1.235173,1.852759,2.470345,3.087931,3.705518,4.296608,4.831177,5.302464,5.700445,6.007777,6.175863,6.175863];
for(let i = 0; i < Q.length; i++ ) {
itCalcQ(structTest, h1, W[i], Q[i]);
}
});
describe('Calcul Q en charge avec h1 croissant: ', () => {
let W: number = 0.6;
let h1: number[] =[1.100000,1.300000,1.500000];
let Q: number[] =[2.620197,4.450866,5.226583];
for(let i = 0; i < Q.length; i++ ) {
itCalcQ(structTest, h1[i], W, Q[i]);
}
});
describe('Calcul Q a surface libre avec h1 croissant: ', () => {
let W: number = Infinity;
let h1: number[] =[1.100000,1.500000];
let Q: number[] =[4.366994,9.764896];
for(let i = 0; i < Q.length; i++ ) {
itCalcQ(structTest, h1[i], W, Q[i]);
}
});
});
......@@ -12,9 +12,10 @@ export class Result {
private _message: Message;
constructor(v: number, e: Message = undefined) {
constructor(v: number, m: Message = undefined, e: { [key: string]: any } = {}) {
this._vCalc = v;
this._message = e;
this._message = m;
this.extraVar = e;
};
get vCalc() { return this._vCalc; }
......
......@@ -4,7 +4,7 @@
import { Result } from "../base";
import { ComputeNodeType, ParamDefinition, ParamDomain, ParamDomainValue, ParamCalculability, ParamsEquation } from "../param";
import { Nub } from "../nub";
import { Message } from "../util/message";
/**
* Common parameters of hydraulic structure equations
......@@ -98,8 +98,14 @@ export abstract class Structure extends Nub {
* Give the flow mode : weir or orifice flow
*/
protected getFlowMode(): StructureFlowMode {
if (this.prms.h1.v >= this.prms.W.v) return StructureFlowMode.ORIFICE;
return StructureFlowMode.WEIR;
if (this.prms.h1.v > this.prms.W.v) {
this.debug("Structure.getFlowRegime(h1="+this.prms.h1.v+",W="+this.prms.W.v+")=ORIFICE");
return StructureFlowMode.ORIFICE;
} else {
this.debug("Structure.getFlowRegime(h1="+this.prms.h1.v+",W="+this.prms.W.v+")=WEIR");
return StructureFlowMode.WEIR;
}
}
......@@ -111,12 +117,15 @@ export abstract class Structure extends Nub {
// Orifice have three flow regimes: free, partially submerged and (totally) submerged
if(this.prms.h2.v <= 2/3*this.prms.h1.v) {
// free flow for both weirs and orifices
this.debug("Structure.getFlowRegime(h1="+this.prms.h1.v+",h2="+this.prms.h2.v+",W="+this.prms.W.v+")=FREE");
return StructureFlowRegime.FREE;
} else if(this.prms.h1.v > this.prms.W.v && this.prms.h2.v < (2*this.prms.h1.v + this.prms.W.v)/3) {
// Partially submerged only for orifices
this.debug("Structure.getFlowRegime(h1="+this.prms.h1.v+",h2="+this.prms.h2.v+",W="+this.prms.W.v+")=PARTIAL");
return StructureFlowRegime.PARTIAL;
} else {
// (Totally) submerged for both weirs and orifices
this.debug("Structure.getFlowRegime(h1="+this.prms.h1.v+",h2="+this.prms.h2.v+",W="+this.prms.W.v+")=SUBMERGED");
return StructureFlowRegime.SUBMERGED;
}
}
......@@ -170,4 +179,20 @@ export abstract class Structure extends Nub {
if(sVarCalc!="Q") throw 'Structure.Equation() : invalid parameter name ' + sVarCalc;
}
/**
* Calcul du mode et du régime d'écoulement
*/
Equation(sVarCalc: string): Result {
this.CheckEquation(sVarCalc);
let res: Result = new Result(
undefined,
undefined,
{
"Regime": this.getFlowRegime(),
"Mode": this.getFlowMode()
}
);
return res;
}
}
\ No newline at end of file
......@@ -9,31 +9,41 @@ export { RectangularStructureParams };
export class StructureCem88d extends RectangularStructure {
Equation(sVarCalc: string): Result {
this.CheckEquation(sVarCalc);
let res: Result = super.Equation(sVarCalc);
let v : number;
let cd : number = this.prms.Cd.v * this.prms.L.v * Structure.R2G;
let b1 : number = Math.sqrt(this.prms.h1.v);
let b2 : number = Math.sqrt(this.prms.h2.v);
let cd1 : number = cd * 2.5981;
switch(this.getFlowMode()) {
let b2 : number = Math.sqrt(this.prms.h1.v-this.prms.h2.v);
let cd1 : number = cd * 2.5981; // cd * 3*sqrt(3)/2
this.debug("StructureCem88d.Equation b1="+b1+" b2="+b2+" cd1="+cd1);
switch(res.extraVar['Mode']) {
case StructureFlowMode.WEIR:
switch(this.getFlowRegime()) {
switch(res.extraVar['Regime']) {
case StructureFlowRegime.FREE:
v = cd * this.prms.h1.v * b1;
break;
case StructureFlowRegime.SUBMERGED:
v = cd1 * this.prms.h1.v * b2;
v = cd1 * this.prms.h2.v * b2;
this.debug("StructureCem88d.Equation WEIR SUBMERGED Q="+v);
break;
}
break;
case StructureFlowMode.ORIFICE:
let b3 : number = this.prms.h1.v - this.prms.W.v;
switch(this.getFlowRegime()) {
let b3 : number = Math.pow(this.prms.h1.v - this.prms.W.v, 1.5);
switch(res.extraVar['Regime']) {
case StructureFlowRegime.FREE:
v = cd * (this.prms.h1.v * b1 -b3);
break;
case StructureFlowRegime.PARTIAL:
v = cd1 * b2 * this.prms.h2.v - cd * b3;
break;
case StructureFlowRegime.SUBMERGED:
v = cd1 * b2 * this.prms.W.v;
this.debug("StructureCem88d.Equation ORIFICE SUBMERGED Q="+v);
break;
}
}
this.debug("StructureCem88d.Equation(h1="+this.prms.h1.v+",h2="+this.prms.h2.v+",W="+this.prms.W.v+") => Q="+v);
return new Result(v);
}
}
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