Failed to fetch fork details. Try again later.
-
Delaigue Olivier authored60219b28
Forked from
HYCAR-Hydro / airGR
Source project has a limited visibility.
import { CalculatorType } from "../compute-node";
import { Nub } from "../nub";
import { ParamCalculability, ParamDefinition } from "../param/param-definition";
import { ParamValueMode } from "../param/param-value-mode";
import { Props } from "../props";
import { Message, MessageCode } from "../util/message";
import { Result } from "../util/result";
import { StructureParams } from "./structure_params";
import { LoiDebit } from "./structure_props";
export { StructureParams };
/**
* Flow mode: weir or orifice flow
*/
export enum StructureFlowMode {
/** Weir flow */
WEIR,
/** Orifice flow */
ORIFICE,
/** Zéro flow */
NULL
}
/**
* Flow regime: free flow, partially submerged or submerged
*/
export enum StructureFlowRegime {
/** Free flow (unsubmerged) */
FREE,
/** Partially submerged flow */
PARTIAL,
/** Submerged flow */
SUBMERGED,
/** Zéro flow */
NULL
}
/**
* Type de jet : Sans objet (orifice), plongeant, de surface
*/
export enum StructureJetType {
/** Sans objet (orifice) */
SO,
/** Plongeant */
PLONGEANT,
/** De surface */
SURFACE
}
/**
* classe de calcul sur la conduite distributrice
*/
export abstract class Structure extends Nub {
/**
* Test générique si VarCalc="Q" pour l'utilisation de Equation
*/
public static CheckEquation(sVarCalc: string) {
if (sVarCalc !== "Q") { throw new Error("Structure.Equation() : invalid parameter name " + sVarCalc); }
}
/** Constante utile : Racine de 2g */
protected static readonly R2G: number = Math.sqrt(2 * 9.81);
/** Peut-on calculer ZDV ? */
protected _isZDVcalculable: boolean;
protected _loiDebit: LoiDebit;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
constructor(prms: StructureParams, dbg: boolean = false) {
super(prms, dbg);
this._calcType = CalculatorType.Structure;
this._isZDVcalculable = true;
// Q is always the only calculated variable; setting another parameter
// of a Structure to CALC mode makes it the calculated variable of the
// *parent* ParallelStructures
this.calculatedParam = this.prms.Q;
}
/** Returns Props object (observable set of key-values) associated to this Nub */
public get properties(): Props {
// completes props with calcType and nodeType if not already set
this._props.setPropValue("calcType", this.calcType);
this._props.setPropValue("loiDebit", this._loiDebit);
return this._props;
}
// setter is not inherited from Nub if getter is redefined :/
public set properties(props: Props) {
this._props = props.clone();
}
get isZDVcalculable(): boolean {
return this._isZDVcalculable;
}
/**
* paramètres castés au bon type
*/
get prms(): StructureParams {
return this._prms as StructureParams;
}
/**
* Forwards to parent, that has vsibility over
* all the parameters, including the Structure ones
*/
public unsetCalculatedParam(except: ParamDefinition) {
if (this.parent) {
this.parent.unsetCalculatedParam(except);
}
}
/**
* Forwards to parent, that has vsibility over
* all the parameters, including the Structure ones
*/
public get calculatedParam(): ParamDefinition {
if (this.parent) {
return this.parent.calculatedParam;
}
return undefined;
}
/**
* Forwards to parent, that has vsibility over
* all the parameters, including the Structure ones
*/
public set calculatedParam(p: ParamDefinition) {
if (this.parent) {
this.parent.calculatedParam = p;
}
}
/**
* Forwards to parent, that has vsibility over
* all the parameters, including the Structure ones
*/
public findFirstSingleParameter(otherThan?: ParamDefinition) {
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
if (this.parent) {
return this.parent.findFirstSingleParameter(otherThan);
}
return undefined;
}
/**
* Forwards to parent, that has visibility over
* all the parameters, including the Structure ones
*/
public resetDefaultCalculatedParam(requirer?: ParamDefinition) {
if (this.parent) {
this.parent.resetDefaultCalculatedParam(requirer);
}
}
/**
* Calcul de l'aire d'écoulement sur le seuil ou dans l'orifice
*/
public abstract calcA(): number;
/**
* Calcul d'une équation quelle que 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
*/
public Calc(sVarCalc: string, rInit?: number): Result {
// Gestion de l'exception de calcul de W sur les seuils
if (rInit === undefined) {
rInit = this.getParameter(sVarCalc).v;
}
if (sVarCalc === "W" && rInit === Infinity) {
throw new Error("Structure:Calc : Calcul de W impossible sur un seuil");
}
// Gestion de l'erreur de calcul de ZDV quand il n'est pas calculable
if (sVarCalc === "ZDV" && !this.isZDVcalculable) {
return new Result(
new Message(MessageCode.ERROR_STRUCTURE_ZDV_PAS_CALCULABLE)
);
}
// Gestion du débit nul
const flagsNull = { ENUM_StructureFlowMode: StructureFlowMode.NULL,
ENUM_StructureFlowRegime: StructureFlowRegime.NULL };
if (sVarCalc === "Q") {
if (this.prms.Z1.v <= this.prms.ZDV.v || this.prms.Z1.v === this.prms.Z2.v || this.prms.W.v <= 0) {
return new Result(0, this, flagsNull);
}
} 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 "Z1":
return new Result(this.prms.Z2.v, this, flagsNull);
case "Z2":
return new Result(this.prms.Z1.v, this, flagsNull);
default:
// Est-ce toujours vrai ? Nécessitera peut-être d'étendre la méthode
return new Result(0, this, flagsNull);
}
} else if (this.prms.W.v === 0 && sVarCalc === "Z1") {
return new Result(Infinity, this, 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)
) {
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
// On ferme l'ouvrage et on renvoie un code d'erreur
let rPrm: number;
switch (sVarCalc) {
case "ZDV":
rPrm = Infinity;
break;
default:
rPrm = 0;
}
const res: Result = new Result(new Message(MessageCode.ERROR_STRUCTURE_Q_TROP_ELEVE), this, flagsNull);
res.vCalc = rPrm;
// "Les cotes et le débit ne sont pas cohérents => fermeture de l'ouvrage
return res;
}
}
// Gestion de l'inversion de débit : on inverse l'amont et l'aval pour le calcul
if (sVarCalc !== "Q" && this.prms.Q.v < 0) {
[this.prms.Z1.v, this.prms.Z2.v] = [this.prms.Z2.v, this.prms.Z1.v]; // Swap ES6 fashion
const res: Result = super.Calc(sVarCalc, rInit);
[this.prms.Z1.v, this.prms.Z2.v] = [this.prms.Z2.v, this.prms.Z1.v]; // Swap ES6 fashion
return res;
}
// Calcul normal hors débit nul
return super.Calc(sVarCalc, rInit);
}
/**
* Equation preprocessing
* @return true if inverted discharge
*/
public Equation(sVarCalc: string): Result {
Structure.CheckEquation(sVarCalc);
this.prms.update_h1h2();
let res: Result;
if (this.prms.h1.v < this.prms.h2.v) {
[this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion
res = this.CalcQ();
if (sVarCalc === "Q") {
res.vCalc = -res.vCalc;
}
[this.prms.h1.v, this.prms.h2.v] = [this.prms.h2.v, this.prms.h1.v]; // Swap ES6 fashion
} else {
res = this.CalcQ();
}
return res;
}
/**
* Function to implement for the stage discharge equation of hydraulic structure
*/
protected abstract CalcQ(): Result;
protected getResultData() {
return {
ENUM_StructureFlowMode: this.getFlowMode(),
ENUM_StructureFlowRegime: this.getFlowRegime(),
};
}
/**
* paramétrage de la calculabilité des paramètres
*/
protected setParametersCalculability() {
this.prms.Q.calculability = ParamCalculability.EQUATION;
this.prms.ZDV.calculability = ParamCalculability.DICHO;
this.prms.Z1.calculability = ParamCalculability.FREE;
this.prms.Z2.calculability = ParamCalculability.FREE;
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
this.prms.h1.calculability = ParamCalculability.FREE;
this.prms.h2.calculability = ParamCalculability.FREE;
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) {
this.debug("Structure.getFlowMode(h1=" + this.prms.h1.v + ",W=" + this.prms.W.v + ")=ORIFICE");
return StructureFlowMode.ORIFICE;
} else {
this.debug("Structure.getFlowMode(h1=" + this.prms.h1.v + ",W=" + this.prms.W.v + ")=WEIR");
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
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;
}
}
/**
* Give the Jet Type for weir flow
* Cf. Baudoin J.M., Burgun V., Chanseau M., Larinier M., Ovidio M., SremskiW., Steinbach P. et Voegtle B., 2014.
* Evaluer le franchissement des obstacles par les poissons. Principes et méthodes. Onema. 200 pages
*/
protected getJetType(): StructureJetType {
if (this.getFlowMode() === StructureFlowMode.WEIR) {
if (Math.abs(this.prms.h1.v - this.prms.h2.v) < 0.5 * this.prms.h1.v) {
return StructureJetType.SURFACE;
} else {
return StructureJetType.PLONGEANT;
}
} else {
return StructureJetType.SO;
}
}
}