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

#6 Création de la classe de base des ouvrages

Showing with 274 additions and 0 deletions
+274 -0
/// <reference path="../../node_modules/@types/jasmine/index.d.ts" />
import { Structure, StructureParams, StructureFlowMode, StructureFlowRegime} from "../../src/structure/structure";
import { Result } from "../../src/base";
import { equalEpsilon } from "../nubtest";
function check(val1: Result, val2: number) {
expect(equalEpsilon(val1.vCalc, val2)).toBe(true);
}
class StructureTestParams extends StructureParams {
}
class StructureTest extends Structure {
constructor(prms: StructureTestParams, dbg: boolean = false) {
super(prms, dbg);
this.setParametersCalculability();
}
Equation(sVarCalc: string): Result {
let res: Result;
let v: number;
switch (sVarCalc) {
case "Q":
v = this.prms.h1.v-this.prms.h2.v;
break;
default:
throw 'StructureTest.Equation() : invalid parameter name ' + sVarCalc;
}
return res;
}
/**
* Test of getFlowMode
*/
public testGetFlowMode() {
return this.getFlowMode();
}
/**
* Test of getFlowRegime
*/
public testGetFlowRegime() {
return this.getFlowRegime();
}
}
let structTestPrm: StructureParams = new StructureTestParams(1, 30, 15);
let structTest: StructureTest = new StructureTest(structTestPrm, true);
describe('Class Structure: ', () => {
describe('getFlowMode()', () => {
it('Flow Mode should be WEIR', () => {
expect(structTest.testGetFlowMode()).toBe(StructureFlowMode.WEIR);
});
it('Flow Mode should be ORIFICE', () => {
structTest.prms.W.v = 10;
expect(structTest.testGetFlowMode()).toBe(StructureFlowMode.ORIFICE);
structTest.prms.W.v = Infinity;
});
});
describe('getFlowRegime()', () => {
it('Flow Regime should be FREE', () => {
expect(structTest.testGetFlowRegime()).toBe(StructureFlowRegime.FREE);
});
it('Flow Regime should be SUBMERGED (WEIR)', () => {
structTest.prms.h2.v = 21;
expect(structTest.testGetFlowRegime()).toBe(StructureFlowRegime.SUBMERGED);
});
it('Flow Regime should be PARTIAL (ORIFICE)', () => {
structTest.prms.h2.v = 21;
structTest.prms.W.v = 15;
expect(structTest.testGetFlowRegime()).toBe(StructureFlowRegime.PARTIAL);
});
it('Flow Regime should be SUBMERGED (ORIFICE)', () => {
structTest.prms.h2.v = 25;
structTest.prms.W.v = 15;
expect(structTest.testGetFlowRegime()).toBe(StructureFlowRegime.SUBMERGED);
});
structTest.prms.h2.v = 15;
structTest.prms.W.v = Infinity;
});
describe('Calc()', () => {
it('h1=h2 => Q=0', () => {
structTest.prms.h2.v = structTest.prms.h1.v;
check(structTest.Calc('Q'),0);
structTest.prms.h2.v = 15;
});
it('W=0 => Q=0', () => {
structTest.prms.W.v = 0;
check(structTest.Calc('Q'),0);
structTest.prms.W.v = Infinity;
});
it('Q=0 => h1=h2', () => {
structTest.prms.Q.v = 0;
check(structTest.Calc('h1'),structTest.prms.h2.v);
structTest.prms.Q.v = 1;
});
it('Q=0 => W=0', () => {
structTest.prms.Q.v = 0;
check(structTest.Calc('W'),0);
structTest.prms.Q.v = 1;
});
// TODO Test inversion de débit
});
});
\ No newline at end of file
/**
* @file structure/structure.ts Base classes for hydraulic structure equations
*/
import { Result } from "../base";
import { ComputeNodeType, ParamDefinition, ParamDomain, ParamDomainValue, ParamCalculability, ParamsEquation } from "../param";
import { Nub } from "../nub";
/**
* Common parameters of hydraulic structure equations
*/
export abstract class StructureParams extends ParamsEquation {
/** Débit */
Q: ParamDefinition;
/** Tirant d'eau amont */
h1: ParamDefinition;
/** Tirant d'eau aval */
h2: ParamDefinition;
/** Ouverture de la vanne
* @note Pour un seuil cette valeur vaut Infinity
*/
W: ParamDefinition;
constructor(rQ: number, rh1: number, rh2: number, rW: number = Infinity ) {
super();
this.Q = new ParamDefinition(ComputeNodeType.CondDistri, 'Q', ParamDomainValue.POS_NULL, rQ);
this.h1 = new ParamDefinition(ComputeNodeType.CondDistri, 'h1', ParamDomainValue.POS_NULL, rh1);
this.h2 = new ParamDefinition(ComputeNodeType.CondDistri, 'h2', ParamDomainValue.POS_NULL, rh2);
this.W = new ParamDefinition(ComputeNodeType.CondDistri, 'W', ParamDomainValue.POS_NULL, rW);
}
}
/**
* Flow mode: weir or orifice flow
*/
export enum StructureFlowMode {
/** Weir flow */
WEIR,
/** Orifice flow */
ORIFICE
}
/**
* Flow regime: free flow, partially submerged or submerged
*/
export enum StructureFlowRegime {
/** Free flow (unsubmerged) */
FREE,
/** Partially submerged flow */
PARTIAL,
/** Submerged flow */
SUBMERGED
}
/**
* classe de calcul sur la conduite distributrice
*/
export abstract class Structure extends Nub {
constructor(prms: StructureParams, dbg: boolean = false) {
super(prms, dbg);
}
/**
* paramètres castés au bon type
*/
get prms(): StructureParams {
return <StructureParams>this._prms;
}
/**
* paramétrage de la calculabilité des paramètres
*/
protected setParametersCalculability() {
this.prms.Q.calculability = ParamCalculability.EQUATION;
this.prms.h1.calculability = ParamCalculability.DICHO;
this.prms.h2.calculability = ParamCalculability.DICHO;
this.prms.W.calculability = ParamCalculability.DICHO;
}
/**
* 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;
}
/**
* Give the flow regime for a rectangular section : free, partially submerged or submerged flow
*/
protected getFlowRegime(): StructureFlowRegime {
// Weir have only two flow regimes: free and submerged flow
// 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
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
return StructureFlowRegime.PARTIAL;
} else {
// (Totally) submerged for both weirs and orifices
return StructureFlowRegime.SUBMERGED;
}
}
/**
* Calcul d'une équation quelque soit l'inconnue à calculer.
* Gestion du débit nul et de l'inversion de débit
* @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
*/
Calc(sVarCalc: string, rInit: number = 0, rPrec: number = 0.001): Result {
// Gestion du débit nul
if(sVarCalc == 'Q') {
if(this.prms.h1.v == this.prms.h2.v || this.prms.W.v <= 0) {
return new Result(0);
}
} else if(this.prms.Q.v == 0){
// Débit nul <=> tirant d'eau amont = tirant d'eau aval ou tout autre paramètre nul
switch(sVarCalc) {
case "h1" :
return new Result(this.prms.h2.v);
case "h2" :
return new Result(this.prms.h1.v);
default :
return new Result(0); // Est-ce toujours vrai ? Nécessitera peut-être d'étendre la méthode
}
}
// Gestion de l'inversion de débit : on inverse l'amont et l'aval pour le calcul
if((sVarCalc == 'Q' && (this.prms.h1.v < this.prms.h2.v)) || (sVarCalc != 'Q' && this.prms.Q.v < 0)) {
[this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion
let res: Result;
res = super.Calc(sVarCalc, rInit, rPrec);
[this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion
return res;
}
return super.Calc(sVarCalc, rInit, rPrec);
}
}
\ No newline at end of file
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