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

#30 Ajout des structures en parallèle

Showing with 294 additions and 35 deletions
+294 -35
/**
* IMPORTANT !
* Décommenter temporairement la ligne suivante (import { } from "./mock_jasmine")
* Pour exécuter ce code dans le débugger.
* Faire de même avec le fichier test_func.ts
*/
// import { describe, expect, it, xdescribe } from "../mock_jasmine";
import { ParallelStructure } from "../../src/structure/parallel_structure";
import { ParallelStructureParams } from "../../src/structure/parallel_structure_params";
import { Result } from "../../src/util/result";
import { checkResult } from "../test_func";
import { structTest } from "./structure_test";
const pstruct: ParallelStructure = new ParallelStructure(
new ParallelStructureParams(30, 30, 15), // Q = 30, Z1 = 30, Z2 = 15
false // debug
);
// Test avec deux structures test identiques
pstruct.addStructure(structTest);
pstruct.addStructure(structTest);
describe("Class ParallelStructure: ", () => {
describe("Calc()", () => {
itParallelStructure("Q", 30, 15);
itParallelStructure("Z1", 30, 15);
itParallelStructure("Z2", 15, 15);
});
});
function itParallelStructure(sVarCalc: string, rVcalc: number, Q: number) {
it(`${sVarCalc} should be ${rVcalc}`, () => {
const res: Result = pstruct.Calc(sVarCalc);
checkResult(res, rVcalc);
checkResult(res.extractResult(1), Q);
checkResult(res.extractResult(2), Q);
});
}
...@@ -47,7 +47,7 @@ describe("Class Structure: ", () => { ...@@ -47,7 +47,7 @@ describe("Class Structure: ", () => {
describe("Calc()", () => { describe("Calc()", () => {
const flagsNull = { Mode: StructureFlowMode.NULL, Regime: StructureFlowRegime.NULL }; const flagsNull = { Mode: StructureFlowMode.NULL, Regime: StructureFlowRegime.NULL };
it("h1=h2 => Q=0", () => { it("Z1=Z2 => Q=0", () => {
structTest.prms.Z2.v = structTest.prms.Z1.v; structTest.prms.Z2.v = structTest.prms.Z1.v;
checkResult(structTest.Calc("Q"), 0); checkResult(structTest.Calc("Q"), 0);
expect(structTest.Calc("Q").extraResults).toEqual(flagsNull); expect(structTest.Calc("Q").extraResults).toEqual(flagsNull);
...@@ -59,10 +59,10 @@ describe("Class Structure: ", () => { ...@@ -59,10 +59,10 @@ describe("Class Structure: ", () => {
expect(structTest.Calc("Q").extraResults).toEqual(flagsNull); expect(structTest.Calc("Q").extraResults).toEqual(flagsNull);
structTest.prms.W.v = Infinity; structTest.prms.W.v = Infinity;
}); });
it("Q=0 => h1=h2", () => { it("Q=0 => Z1=Z2", () => {
structTest.prms.Q.v = 0; structTest.prms.Q.v = 0;
checkResult(structTest.Calc("h1"), structTest.prms.h2.v); checkResult(structTest.Calc("Z1"), structTest.prms.h2.v);
expect(structTest.Calc("h1").extraResults).toEqual(flagsNull); expect(structTest.Calc("Z1").extraResults).toEqual(flagsNull);
structTest.prms.Q.v = 1; structTest.prms.Q.v = 1;
}); });
it("Q=0 => W=0", () => { it("Q=0 => W=0", () => {
......
...@@ -26,10 +26,18 @@ class StructureTest extends Structure { ...@@ -26,10 +26,18 @@ class StructureTest extends Structure {
public Equation(sVarCalc: string): Result { public Equation(sVarCalc: string): Result {
this.prms.update_h1h2(); this.prms.update_h1h2();
Structure.CheckEquation(sVarCalc); Structure.CheckEquation(sVarCalc);
return new Result(this.prms.Z1.v - this.prms.Z2.v); const data = this.getResultData();
return new Result(this.prms.Z1.v - this.prms.Z2.v, data);
} }
} }
/* Test structure with :
* - ZDV = 0
* - Z1 = 30
* - Z2 = 15
* - expected Q = 15
*/
export const structTestPrm: StructureParams = new StructureParams(1, 0, 30, 15); export const structTestPrm: StructureParams = new StructureParams(1, 0, 30, 15);
export const structTest: StructureTest = new StructureTest(structTestPrm, false); export const structTest: StructureTest = new StructureTest(structTestPrm, false);
import { Nub } from "../nub";
import { ParamCalculability } from "../param";
import { Message } from "../util/message";
import { Result } from "../util/result";
import { Structure } from "./structure";
import { ParallelStructureParams } from "./parallel_structure_params";
/**
* Calcul de une ou plusieurs structures hydrauliques en parallèles
* reliées par les cotes amont et aval et dont le débit est égal à la
* somme des débits de chaque structure.
*/
export class ParallelStructure extends Nub {
/** Tableau des structures hydrauliques en parallèle */
public structures: Structure[] = [];
/**
* paramètres castés au bon type
*/
get prms(): ParallelStructureParams {
return this._prms as ParallelStructureParams;
}
/**
* Mise à jour de Z1 pour toutes les structures en parallèle
*/
set Z1(Z1: number) {
this.prms.Z1.v = Z1;
for (const structure of this.structures) {
structure.prms.Z1.v = Z1;
structure.prms.update_h1h2();
}
}
/**
* Mise à jour de Z2 pour toutes les structures en parallèle
*/
set Z2(Z2: number) {
this.prms.Z2.v = Z2;
for (const structure of this.structures) {
structure.prms.Z2.v = Z2;
structure.prms.update_h1h2();
}
}
/**
* Ajout d'une structure en parallèle
* @param structure La structure à rajouter
*/
public addStructure(structure: Structure) {
this.structures.push(structure);
}
/**
* Supprime une structure hydraulique
* @param index numéro de la structure dans le tableau
*/
public deleteStructure(index: number) {
if (index > -1) {
this.structures.splice(index, 1);
} else {
throw new Error("ParallelStructure.deleteStructure invalid index=" + index);
}
}
/**
* Calcul du débit des structures en parallèle (sans détail pour chaque structure)
* @param sVarCalc Variable à calculer (Q uniquement)
*/
public Equation(sVarCalc: string): Result {
Structure.CheckEquation(sVarCalc);
this.Z1 = this.prms.Z1.v;
this.Z2 = this.prms.Z2.v;
return this.CalcQ();
}
/**
* Calcul de la somme des débits de chaque structure
* @param iExcept Index de la structure à ne pas additionner (optionel)
*/
public CalcQ(iExcept?: number): Result {
if (iExcept !== undefined) {
if (iExcept < 0 || iExcept >= this.structures.length) {
throw new Error(
"ParallelStructure.CalcQ iExcept not in [0;" + (this.structures.length - 1) + "]",
);
}
}
const calcRes: Result = new Result();
let qTot: number = 0;
for (let i = 0 ; i < this.structures.length; i++) {
if (i !== iExcept) {
const res: Result = this.structures[i].Calc("Q");
calcRes.addResult(res.result);
qTot += res.vCalc;
}
}
// Insert le débit total en premier résultat
calcRes.insertResult(new Result(qTot).result, 0);
return calcRes;
}
/**
* 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 = 0, rPrec: number = 0.001): Result {
switch (sVarCalc) {
case "Z1" :
case "Z2" :
case "Q" :
return super.Calc(sVarCalc, rInit, rPrec);
default:
// Pour les caractéristiques des ouvrages
return this.CalcStructPrm(sVarCalc, rInit, rPrec);
}
}
/**
* paramétrage de la calculabilité des paramètres
*/
protected setParametersCalculability() {
this.prms.Q.calculability = ParamCalculability.EQUATION;
this.prms.Z1.calculability = ParamCalculability.DICHO;
this.prms.Z2.calculability = ParamCalculability.DICHO;
}
/**
* Calcul du paramètre d'un des ouvrages en parallèle
* @param sVarCalc Nom du paramètre à calculer : "n.X" avec "n" l'index de l'ouvrage et "X" son paramètre
* @param rInit Valeur initiale
* @param rPrec Précision attendue
*/
private CalcStructPrm(sVarCalc: string, rInit: number = 0, rPrec: number = 0.001): Result {
// Détection de la structure où calculer le paramètre
let sIndex: string;
let sPrm: string;
[sIndex, sPrm] = sVarCalc.split(".");
const index = parseInt(sIndex, 10);
// Le débit restant sur la structure en calcul est :
const qTarget: number = this.prms.Q.v - this.CalcQ(index).vCalc;
// Calcul du paramètre de la structure en calcul
return this.structures[index].Calc(sPrm, rInit, rPrec);
}
}
import { Nub } from "../nub";
import { ComputeNodeType, ParamDefinition, ParamDomainValue, ParamsEquation } from "../param";
/**
* Common parameters of hydraulic structure equations
*/
export class ParallelStructureParams extends ParamsEquation {
/** Débit (m3/s) */
public Q: ParamDefinition;
/** Cote de l'eau amont (m) */
public Z1: ParamDefinition;
/** Cote de l'eau aval (m) */
public Z2: ParamDefinition;
/**
* Paramètres communs à toutes les équations de structure
* @param rQ Débit total (m3/s)
* @param rZ1 Cote de l'eau amont (m)
* @param rZ2 Cote de l'eau aval (m)
*/
constructor(rQ: number, rZ1: number, rZ2: number) {
super();
this.Q = new ParamDefinition(ComputeNodeType.CondDistri, "Q", ParamDomainValue.ANY, rQ);
this.addParamDefinition(this.Q);
this.Z1 = new ParamDefinition(ComputeNodeType.CondDistri, "Z1", ParamDomainValue.ANY, rZ1);
this.addParamDefinition(this.Z1);
this.Z2 = new ParamDefinition(ComputeNodeType.CondDistri, "Z2", ParamDomainValue.ANY, rZ2);
this.addParamDefinition(this.Z2);
}
}
...@@ -11,12 +11,12 @@ export { StructureParams }; ...@@ -11,12 +11,12 @@ export { StructureParams };
* Flow mode: weir or orifice flow * Flow mode: weir or orifice flow
*/ */
export enum StructureFlowMode { export enum StructureFlowMode {
/** Weir flow */ /** Weir flow */
WEIR, WEIR,
/** Orifice flow */ /** Orifice flow */
ORIFICE, ORIFICE,
/** Zéro flow */ /** Zéro flow */
NULL, NULL,
} }
/** /**
...@@ -31,7 +31,7 @@ export enum StructureFlowRegime { ...@@ -31,7 +31,7 @@ export enum StructureFlowRegime {
SUBMERGED, SUBMERGED,
/** Zéro flow */ /** Zéro flow */
NULL, NULL,
} }
/** /**
* classe de calcul sur la conduite distributrice * classe de calcul sur la conduite distributrice
...@@ -79,23 +79,42 @@ export abstract class Structure extends Nub { ...@@ -79,23 +79,42 @@ export abstract class Structure extends Nub {
} else if (this.prms.Q.v === 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 // Débit nul <=> tirant d'eau amont = tirant d'eau aval ou tout autre paramètre nul
switch (sVarCalc) { switch (sVarCalc) {
case "h1" : case "Z1" :
return new Result(this.prms.h2.v, flagsNull); return new Result(this.prms.h2.v, flagsNull);
case "h2" : case "Z2" :
return new Result(this.prms.h1.v, flagsNull); return new Result(this.prms.h1.v, flagsNull);
default : default :
// Est-ce toujours vrai ? Nécessitera peut-être d'étendre la méthode // Est-ce toujours vrai ? Nécessitera peut-être d'étendre la méthode
return new Result(0, flagsNull); return new Result(0, flagsNull);
} }
} else if (this.prms.W.v === 0 && sVarCalc === "h1") { } else if (this.prms.W.v === 0 && sVarCalc === "Z1") {
return new Result(Infinity, flagsNull); // Si la vanne est fermée la cote amont est infinie return new Result(Infinity, flagsNull); // Si la vanne est fermée la cote amont est infinie
} }
// Gestion du cas d'écoulement impossible Z1 > Z2 et Q <= 0
if (!(sVarCalc === "Q" || sVarCalc === "Z1" || sVarCalc === "Z2")) {
if (
(this.prms.Z1.v > this.prms.Z2.v && this.prms.Q.v <= 0) ||
(this.prms.Z1.v < this.prms.Z2.v && this.prms.Q.v >= 0)
) {
// On ferme l'ouvrage et on renvoie un code d'erreur
let rPrm: number;
switch (sVarCalc) {
case "ZDV":
rPrm = Infinity;
default:
rPrm = 0;
}
// TODO Ajouter un message d'erreur
// "Les cotes et le débit ne sont pas cohérents => fermeture de l'ouvrage
return new Result(rPrm, flagsNull);
}
}
// Gestion de l'inversion de débit : on inverse l'amont et l'aval pour le calcul // 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)) { 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 [this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion
let res: Result; const res: Result = super.Calc(sVarCalc, rInit, rPrec);
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 [this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion
return res; return res;
} }
...@@ -104,7 +123,7 @@ export abstract class Structure extends Nub { ...@@ -104,7 +123,7 @@ export abstract class Structure extends Nub {
return super.Calc(sVarCalc, rInit, rPrec); return super.Calc(sVarCalc, rInit, rPrec);
} }
protected defaultResultData() { protected getResultData() {
return { return {
Mode: this.getFlowMode(), Mode: this.getFlowMode(),
Regime: this.getFlowRegime(), Regime: this.getFlowRegime(),
......
...@@ -16,7 +16,7 @@ export class StructureCem88d extends RectangularStructure { ...@@ -16,7 +16,7 @@ export class StructureCem88d extends RectangularStructure {
*/ */
public Equation(sVarCalc: string): Result { public Equation(sVarCalc: string): Result {
Structure.CheckEquation(sVarCalc); Structure.CheckEquation(sVarCalc);
const data = super.defaultResultData(); const data = this.getResultData();
let v: number; let v: number;
const cd: number = this.prms.Cd.v * this.prms.L.v * Structure.R2G; const cd: number = this.prms.Cd.v * this.prms.L.v * Structure.R2G;
......
...@@ -16,7 +16,7 @@ export class StructureCem88v extends RectangularStructure { ...@@ -16,7 +16,7 @@ export class StructureCem88v extends RectangularStructure {
*/ */
public Equation(sVarCalc: string): Result { public Equation(sVarCalc: string): Result {
Structure.CheckEquation(sVarCalc); Structure.CheckEquation(sVarCalc);
const data = super.defaultResultData(); const data = this.getResultData();
let v: number; let v: number;
const mu0: number = 2 / 3 * this.prms.Cd.v; const mu0: number = 2 / 3 * this.prms.Cd.v;
......
...@@ -15,7 +15,7 @@ export class StructureCunge80 extends RectangularStructure { ...@@ -15,7 +15,7 @@ export class StructureCunge80 extends RectangularStructure {
*/ */
public Equation(sVarCalc: string): Result { public Equation(sVarCalc: string): Result {
Structure.CheckEquation(sVarCalc); Structure.CheckEquation(sVarCalc);
const data = super.defaultResultData(); const data = this.getResultData();
let v: number; let v: number;
switch (data.Regime) { switch (data.Regime) {
......
...@@ -15,13 +15,15 @@ export class StructureOrificeFree extends RectangularStructure { ...@@ -15,13 +15,15 @@ export class StructureOrificeFree extends RectangularStructure {
*/ */
public Equation(sVarCalc: string): Result { public Equation(sVarCalc: string): Result {
Structure.CheckEquation(sVarCalc); Structure.CheckEquation(sVarCalc);
const data = super.defaultResultData(); const data = this.getResultData();
// TODO : Warning si les conditions hydrauliques ne correspondent pas à un écoulement dénoyé
data.Regime = StructureFlowRegime.FREE;
const v = this.prms.Cd.v * Math.min(this.prms.W.v, this.prms.h1.v) * this.prms.L.v const v = this.prms.Cd.v * Math.min(this.prms.W.v, this.prms.h1.v) * this.prms.L.v
* Structure.R2G * Math.sqrt(this.prms.h1.v); * Structure.R2G * Math.sqrt(this.prms.h1.v);
return new Result(v, data); return new Result(v, data);
} }
protected getFlowRegime() {
return StructureFlowRegime.FREE;
}
} }
...@@ -15,13 +15,15 @@ export class StructureOrificeSubmerged extends RectangularStructure { ...@@ -15,13 +15,15 @@ export class StructureOrificeSubmerged extends RectangularStructure {
*/ */
public Equation(sVarCalc: string): Result { public Equation(sVarCalc: string): Result {
Structure.CheckEquation(sVarCalc); Structure.CheckEquation(sVarCalc);
const data = super.defaultResultData(); const data = this.getResultData();
// TODO : Warning si les conditions hydrauliques ne correspondent pas à un écoulement dénoyé
data.Regime = StructureFlowRegime.SUBMERGED;
const v = this.prms.Cd.v * Math.min(this.prms.W.v, this.prms.h1.v) * this.prms.L.v const v = this.prms.Cd.v * Math.min(this.prms.W.v, this.prms.h1.v) * this.prms.L.v
* Structure.R2G * Math.sqrt(this.prms.h1.v - this.prms.h2.v); * Structure.R2G * Math.sqrt(this.prms.h1.v - this.prms.h2.v);
return new Result(v, data); return new Result(v, data);
} }
protected getFlowRegime() {
return StructureFlowRegime.SUBMERGED;
}
} }
...@@ -15,13 +15,18 @@ export class StructureWeirFree extends RectangularStructure { ...@@ -15,13 +15,18 @@ export class StructureWeirFree extends RectangularStructure {
*/ */
public Equation(sVarCalc: string): Result { public Equation(sVarCalc: string): Result {
Structure.CheckEquation(sVarCalc); Structure.CheckEquation(sVarCalc);
const data = super.defaultResultData(); const data = this.getResultData();
// TODO : Warning si les conditions hydrauliques ne correspondent pas à un seuil dénoyé
data.Regime = StructureFlowRegime.FREE;
data.Mode = StructureFlowMode.WEIR;
const v = this.prms.Cd.v * this.prms.L.v * Structure.R2G * Math.pow(this.prms.h1.v, 1.5); const v = this.prms.Cd.v * this.prms.L.v * Structure.R2G * Math.pow(this.prms.h1.v, 1.5);
return new Result(v, data); return new Result(v, data);
} }
protected getFlowRegime() {
return StructureFlowRegime.FREE;
}
protected getFlowMode() {
return StructureFlowMode.WEIR;
}
} }
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