Skip to content
Snippets Groups Projects
Commit ecaa60e0 authored by mathias.chouet's avatar mathias.chouet
Browse files

[WIP] Passes à Ralentisseurs - calage

parent 330a416d
No related branches found
No related tags found
No related merge requests found
......@@ -382,9 +382,7 @@ public update(sender: any, data: any) {
}
```
@TODO
Fournir l'association propriété-enum dans `src/app/formulaire/elements/select-field.ts` (exemple pour l'opération, dans le module Trigo)
Update property-enum associations list in `src/app/formulaire/elements/select-field.ts` (example for operation property in Trigo module)
```typescript
public static enumFromProperty = {
......
......@@ -54,7 +54,7 @@ module.exports = function (config) {
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
// logLevel: config.LOG_INFO,
logLevel: config.LOG_DEBUG,
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
......
This diff is collapsed.
......@@ -35,7 +35,8 @@ export enum CalculatorType {
Trigo, // Fonctions trigonométriques
SPP, // Somme et produit de puissances
YAXN, // Y = A.X^N
ConcentrationBlocs
ConcentrationBlocs,
Par // Passe à ralentisseurs
}
/** types de sections */
......
......@@ -81,4 +81,6 @@ export * from "./math/yaxn_params";
export * from "./child_nub";
export * from "./macrorugo/concentration_blocs";
export * from "./macrorugo/concentration_blocs_params";
export * from "./variated-details";
\ No newline at end of file
export * from "./variated-details";
export * from "./par/par";
export * from "./par/par_params";
import { CalculatorType } from "../compute-node";
import { Nub } from "../nub";
import { ParamCalculability } from "../param/param-definition";
import { Observer } from "../util/observer";
import { Result } from "../util/result";
import { ParParams } from "./par_params";
import { ParTypeAbstract } from "./par_type";
import { ParTypePlane } from "./par_type_plane";
import { ParTypeFatou } from "./par_type_fatou";
import { ParTypeSuperactive } from "./par_type_superactive";
import { ParTypeChevron } from "./par_type_chevron";
import { Message, MessageCode } from "../util/message";
import { ResultElement } from "../util/resultelement";
/** Type de Passe à Ralentisseurs */
export enum ParType {
PLANE,
FATOU,
SUPERACTIVE,
CHEVRON
}
export class Par extends Nub implements Observer {
protected parCalc: ParTypeAbstract;
constructor(prms: ParParams, dbg: boolean = false) {
super(prms, dbg);
this._calcType = CalculatorType.Par;
this._defaultCalculatedParam = prms.Q;
this.resetDefaultCalculatedParam();
this._props.addObserver(this);
this.parType = ParType.PLANE;
}
get prms(): ParParams {
return this._prms as ParParams;
}
public get parType(): ParType {
return this.properties.getPropValue("parType");
}
public set parType(e: ParType) {
this.properties.setPropValue("parType", e);
}
public Calc(sVarCalc: string, rInit?: number): Result {
// if P is given and L is not calculated, check P value
if (this.calculatedParam !== this.prms.L && this.prms.P.v !== undefined) {
const standardP = this.parCalc.CalcP();
const minP = standardP * 0.9;
const maxP = standardP * 1.05;
if (this.prms.P.v < minP || this.prms.P.v > maxP) {
const r: Result = new Result(new ResultElement());
const m = new Message(MessageCode.ERROR_PAR_P_DEVIATES_MORE_THAN_10_5_PCT);
m.extraVar.stdP = standardP;
r.resultElement.addMessage(m);
this.currentResult = r;
return this.result;
}
}
// Check admissible values for S, L, N, a, M
const status: { fatal: boolean, messages: Message[] } = this.parCalc.checkInput();
if (status.fatal) {
const r: Result = new Result(new ResultElement());
for (const m of status.messages) {
r.resultElement.addMessage(m);
}
this.currentResult = r;
return this.result;
}
// Check that input data is in the range given by abacuses
if ([ this.prms.Z1, this.prms.ZD1 ].includes(this.calculatedParam)) {
// check qStar
const qStar = this.parCalc.CalcQStar();
if (qStar < this.parCalc.minQstar || qStar > this.parCalc.maxQstar) {
const r: Result = new Result(new ResultElement());
const m = new Message(MessageCode.ERROR_PAR_QSTAR_OUT_OF_RANGE);
m.extraVar.val = qStar;
m.extraVar.min = this.parCalc.minQstar;
m.extraVar.max = this.parCalc.maxQstar;
r.resultElement.addMessage(m);
this.currentResult = r;
return this.result;
}
} else if (this.calculatedParam === this.prms.Q) {
const m = this.checkHaAbacus();
if (m !== undefined) {
const r: Result = new Result(new ResultElement());
r.resultElement.addMessage(m);
this.currentResult = r;
return this.result;
}
}
super.Calc(sVarCalc, rInit);
// add checkInput()'s non fatal warnings to current result
if (! status.fatal) {
for (const m of status.messages) {
this.result.resultElement.addMessage(m);
}
}
// if L is calculated
if (this.calculatedParam === this.prms.L) {
// if P is given, inform that given P is ignored
if (this.prms.P.v !== undefined) {
this.result.resultElement.addMessage(new Message(MessageCode.WARNING_PAR_P_WAS_IGNORED));
}
// check L values
if (this.result.resultElement.values.L < 0.3 || this.result.resultElement.values.L > 1.3) {
// pseudo-fatal error converted to warning so that results are shown
const m = new Message(MessageCode.WARNING_ERROR_PAR_L);
m.extraVar.min = 0.3;
m.extraVar.max = 1.3;
this.result.resultElement.addMessage(m);
} else if (this.result.resultElement.values.L > 1) {
const m = new Message(MessageCode.WARNING_PAR_L);
m.extraVar.max = 1;
this.result.resultElement.addMessage(m);
}
// re-check ha after L is calculated
/* const mHa = this.checkHaAbacus();
if (mHa !== undefined) {
this.result.resultElement.addMessage(mHa);
} */
}
// extra results
this.parCalc.addExtraResults(this.result);
// pass type independent extra results
if (this.prms.Z2.v !== undefined) {
const P = this.result.resultElement.values.P; // calculated by addExtraResults()
const ZR1 = this.result.resultElement.values.ZR1; // calculated by addExtraResults()
// nombre de ralentisseurs
// tslint:disable-next-line:variable-name
const Nb = this.parCalc.CalcNb();
this.result.resultElement.values.Nb = Nb;
// cote de déversement à l'aval de la passe
const ZD2 = this.prms.ZD1.V - (Nb - 1) * P * this.prms.S.v;
this.result.resultElement.values.ZD2 = ZD2; // DEBUG
// cote de radier de l'aval de la passe
this.result.resultElement.values.ZR2 = ZR1 - (Nb - 1) * P * this.prms.S.v;
// longueur de la passe en suivant la pente
const LPI = (this.prms.ZD1.V - ZD2) / this.prms.S.v;
this.result.resultElement.values.LPI = LPI;
// longueur de la passe en projection horizontale
this.result.resultElement.values.LPH = Math.sqrt(Math.pow(LPI, 2) - Math.pow((this.prms.ZD1.V - ZD2), 2));
}
return this.result;
}
protected checkHaAbacus(): Message {
let m: Message;
if (this.parCalc.ha < this.parCalc.minHa || this.parCalc.ha > this.parCalc.maxHa) {
m = new Message(MessageCode.ERROR_PAR_HA_OUT_OF_RANGE);
m.extraVar.val = this.parCalc.ha;
m.extraVar.min = this.parCalc.minHa;
m.extraVar.max = this.parCalc.maxHa;
}
return m;
}
public Equation(sVarCalc: string): Result {
let v: number;
let ha: number;
switch (sVarCalc) {
case "Q":
v = this.parCalc.CalcQFromHa();
break;
case "Z1":
ha = this.parCalc.CalcHa();
v = this.prms.ZD1.v + ha;
break;
case "ZD1":
ha = this.parCalc.CalcHa();
v = this.prms.Z1.v - ha;
break;
default:
throw new Error("Par.Equation() : invalid variable name " + sVarCalc);
}
return new Result(v, this);
}
public getFirstAnalyticalParameter() {
// use Z1 in dicho, when calculating L, to rpevent negative sqrt() in doCalcQYFromHa()
return this.prms.Z1;
}
public update(sender: any, data: any) {
if (data.action === "propertyChange") {
if (data.name === "parType") {
switch (data.value) {
case ParType.PLANE:
this.parCalc = new ParTypePlane(this.prms);
break;
case ParType.FATOU:
this.parCalc = new ParTypeFatou(this.prms);
break;
case ParType.SUPERACTIVE:
this.parCalc = new ParTypeSuperactive(this.prms);
this.setCalcOtherThanL();
break;
case ParType.CHEVRON:
this.parCalc = new ParTypeChevron(this.prms);
this.setCalcOtherThanL();
break;
default:
throw new Error("Par.update() : invalid Par Type name " + data.value);
}
this.updateParamsVisibility();
}
}
}
/**
* If the calculated parameter is L, change it to another one (Q)
*/
protected setCalcOtherThanL() {
if (this.calculatedParam === this.prms.L) {
this.calculatedParam = this.prms.Q;
}
}
protected updateParamsVisibility() {
this.prms.L.visible = ([ ParType.PLANE, ParType.FATOU ].includes(this.parType));
this.prms.a.visible = ([ ParType.SUPERACTIVE, ParType.CHEVRON ].includes(this.parType));
this.prms.N.visible = ([ ParType.SUPERACTIVE, ParType.CHEVRON ].includes(this.parType));
this.prms.M.visible = (this.parType === ParType.CHEVRON);
}
protected setParametersCalculability() {
this.prms.Q.calculability = ParamCalculability.EQUATION;
this.prms.Z1.calculability = ParamCalculability.EQUATION;
this.prms.ZD1.calculability = ParamCalculability.EQUATION;
this.prms.L.calculability = ParamCalculability.DICHO;
}
protected exposeResults() {
this._resultsFamilies = {
h: undefined,
ha: undefined,
qStar: undefined,
V: undefined,
Nb: undefined,
ZR1: undefined,
ZD2: undefined,
ZR2: undefined,
ZM: undefined,
LPI: undefined,
LPH: undefined,
L: undefined
}
}
}
import { ParamDefinition, ParamFamily } from "../param/param-definition";
import { ParamDomainValue } from "../param/param-domain";
import { ParamsEquation } from "../param/params-equation";
export class ParParams extends ParamsEquation {
/** Débit dans la passe (m3/s) */
private _Q: ParamDefinition;
/** Cote de l'eau à l'amont de la passe (m) */
private _Z1: ParamDefinition;
/** Cote de l'eau à l'aval de la passe (m) [facultatif] */
private _Z2: ParamDefinition;
/** Cote de déversement à l'amont de la passe (m) */
private _ZD1: ParamDefinition;
/** Pente (m/m) */
private _S: ParamDefinition;
/** Espacement entre les ralentisseurs (m) [facultatif] */
private _P: ParamDefinition;
/** Largeur de la passe (PLANE et FATOU) (m) */
private _L: ParamDefinition;
/** Hauteur des ralentisseurs (SUPERACTIVE) ou des chevrons (CHEVRON) (m) */
private _a: ParamDefinition;
/** Nombre de motifs (SUPERACTIVE) ou de chevrons (CHEVRON) */
private _N: ParamDefinition;
/** Nombre de bandes longitudinales (CHEVRON) */
private _M: ParamDefinition;
constructor(rQ: number, rZ1: number, rZ2: number, rZD1: number, rS: number, rP?: number, rL?: number, ra?: number, rN?: number, rM?: number) {
super();
// paramètres hydrauliques
this._Q = new ParamDefinition(this, "Q", ParamDomainValue.POS_NULL, "m³/s", rQ, ParamFamily.FLOWS);
this.addParamDefinition(this.Q);
this._Z1 = new ParamDefinition(this, "Z1", ParamDomainValue.ANY, "m", rZ1, ParamFamily.ELEVATIONS);
this.addParamDefinition(this.Z1);
this._Z2 = new ParamDefinition(this, "Z2", ParamDomainValue.ANY, "m", rZ2, ParamFamily.ELEVATIONS);
this.addParamDefinition(this.Z2);
// géométrie de la passe
this._ZD1 = new ParamDefinition(this, "ZD1", ParamDomainValue.ANY, "m", rZD1, ParamFamily.ELEVATIONS);
this.addParamDefinition(this.ZD1);
this._S = new ParamDefinition(this, "S", ParamDomainValue.POS_NULL, "m/m", rS, ParamFamily.SLOPES);
this.addParamDefinition(this.S);
this._P = new ParamDefinition(this, "P", ParamDomainValue.POS_NULL, "m", rP, ParamFamily.WIDTHS);
this.addParamDefinition(this.P);
// paramètres dépendants du type de passe
this._L = new ParamDefinition(this, "L", ParamDomainValue.POS, "m", rL, ParamFamily.WIDTHS, false);
this.addParamDefinition(this.L);
this._a = new ParamDefinition(this, "a", ParamDomainValue.POS, "m", ra, ParamFamily.HEIGHTS, false);
this.addParamDefinition(this.a);
this._N = new ParamDefinition(this, "N", ParamDomainValue.POS_NULL, "", rN, undefined, false);
this.addParamDefinition(this.N);
this._M = new ParamDefinition(this, "M", ParamDomainValue.POS_NULL, "", rM, undefined, false);
this.addParamDefinition(this.M);
}
public get Q() {
return this._Q;
}
public get Z1() {
return this._Z1;
}
public get Z2() {
return this._Z2;
}
public get ZD1() {
return this._ZD1;
}
public get S() {
return this._S;
}
public get P() {
return this._P;
}
public get L() {
return this._L;
}
public get a() {
return this._a;
}
public get N() {
return this._N;
}
public get M() {
return this._M;
}
}
import { ParParams } from "./par_params";
import { Result } from "../util/result";
import { ParamValueMode } from "../param/param-value-mode";
import { ParType } from "./par";
import { Message } from "../util/message";
export abstract class ParTypeAbstract {
protected prms: ParParams;
/** type of the current PAR calculation class */
protected type: ParType;
/** gravity acceleration */
protected g = 9.81;
/** coefficients for calculating c(0|1|2)ha? @see getCoeff */
public static coeff: {
[key:number]: {
[key:string]: {
[key:string]: number[]
}
}
} = {};
public constructor(prms: ParParams) {
this.prms = prms;
ParTypeAbstract.coeff[ParType.PLANE] = {
"h": {
"c0": [ 16.7218, -6.09624, 0.834851 ],
"c1": [ -139.382, 47.2186, 0.0547598 ],
"c2": [ 347.368, -130.698, 8.14521 ]
},
"ha": {
"c0": [ 15.2115, -5.22606, 0.633654 ],
"c1": [ -184.043, 59.7073, -0.530737 ],
"c2": [ 315.110, -115.164, 6.85371 ]
}
};
ParTypeAbstract.coeff[ParType.FATOU] = {
"h": {
"c0": [ -3.56494, 0.450262, 0.0407576 ],
"c1": [ 42.4113, -24.4941, 8.84146 ],
"c2": [ -73.4829, 54.6733, -14.0622 ]
},
"ha": {
"c0": [ 15.8096, -5.19282, 0.465827 ],
"c1": [ 302.623, -106.203, 13.2957 ],
"c2": [ -783.592, 269.991, -25.2637 ]
}
};
ParTypeAbstract.coeff[ParType.SUPERACTIVE] = {
"h": {
"c0": [ 0, -2.62712, 0.601348 ],
"c1": [ 0, 1.15807, 1.07554 ],
"c2": [ 0, -0.559218, 0.000504060 ]
},
"ha": {
"c0": [ 0, -2.22434, 0.596682 ],
"c1": [ 0, 0.514953, 1.25460 ],
"c2": [ 0, -0.354624, -0.0153156 ]
}
};
/* ParTypeAbstract.coeff[ParType.CHEVRON] = {
"h": {
"c0": [ 0, -5.97224, 1.40500 ],
"c1": [ 0, 0.211514, 0.658130 ],
"c2": [ 0, -0.0880599, -0.00693098 ]
},
"ha": {
"c0": [ 0, 6.02566, 0.609006 ],
"c1": [ 0, -2.97598, 1.30323 ],
"c2": [ 0, 0.225989, -0.0465125 ]
}
}; */
ParTypeAbstract.coeff[ParType.CHEVRON] = {
"h": {
"c0": [ 0, -4.97686, 1.30546 ],
"c1": [ 0, 0.176261, 0.661656 ],
"c2": [ 0, -0.0733832, -0.00839864 ]
},
"ha": {
"c0": [ 0, 5.02138, 0.709434 ],
"c1": [ 0, -2.47998, 1.25363 ],
"c2": [ 0, 0.188324, -0.0427461 ]
}
};
}
public abstract checkInput(): { fatal: boolean, messages: Message[] };
public abstract CalcH(): number;
// used to calculate Z1 and ZD1
public abstract CalcHa(qStar?: number): number;
// used by CalcH and CalcHa
public abstract CalcQStar(): number;
/** minimum value of Q* according to abacuses */
public abstract get minQstar(): number;
/** maximum value of Q* according to abacuses */
public abstract get maxQstar(): number;
public abstract CalcAw(): number;
public abstract CalcZR1(): number;
public abstract CalcZM(): number;
public abstract CalcP(): number;
public abstract CalcQFromHa(): number;
public addExtraResults(res: Result): void {
// hauteur d'eau dans la passe
res.resultElement.values.h = this.CalcH();
// hauteur d'eau (charge) à l'amont
res.resultElement.values.ha = this.ha;
// débit adimensionnel
res.resultElement.values.qStar = this.CalcQStar();
// vitesse débitante
res.resultElement.values.V = this.CalcVDeb();
// cote d'arase minimale des murs latéraux à l'amont
res.resultElement.values.ZM = this.CalcZM();
// cote de radier à l'amont de la passe
res.resultElement.values.ZR1 = this.CalcZR1();
// espacement entre les ralentisseurs
res.resultElement.values.P = this.P;
}
public CalcVDeb(): number {
const aw = this.CalcAw();
// .V uses calculated value if any
return this.prms.Q.V / aw;
}
public get ha(): number {
// when Q or L is calculated, ha is given by elevations, do not trigger a calc loop
if (this.prms.Z1.valueMode !== ParamValueMode.CALCUL && this.prms.ZD1.valueMode !== ParamValueMode.CALCUL) {
return this.prms.Z1.V - this.prms.ZD1.V;
} else {
return this.CalcHa();
}
}
/** returns the given input P if any, or the standard P calculated by CalcP() */
public get P(): number {
if (this.prms.P.v !== undefined) {
return this.prms.P.v;
} else {
return this.CalcP();
}
}
/** minimum value of ha according to abacuses */
public get minHa(): number {
return this.CalcHa(this.minQstar);
}
/** maximum value of ha according to abacuses */
public get maxHa(): number {
return this.CalcHa(this.maxQstar);
}
/** calculates the number of baffles Nb based on the baffles spacing P */
public CalcNb(): number {
const P = this.P;
return 1 + Math.ceil(
(this.prms.Z1.V - this.prms.Z2.v) / (P * Math.sin(Math.atan(this.prms.S.v)))
);
}
// return y part of CalcQFromHa
protected doCalcQYFromHa(x: number): number {
return (Math.sqrt(Math.pow(this.c1ha, 2) - 4 * this.c2ha * (this.c0ha - x)) - this.c1ha) / (2 * this.c2ha);
}
/**
* get c0, c1 or c2 coefficient for h or ha, for the current pass type
* @param hOrHa "h" or "ha" :)
* @param ci "c0", "c1" or "c2"
*/
protected getCoeff(hOrHa: string, ci: string): number {
const a = ParTypeAbstract.coeff[this.type][hOrHa][ci][0];
const b = ParTypeAbstract.coeff[this.type][hOrHa][ci][1];
const c = ParTypeAbstract.coeff[this.type][hOrHa][ci][2];
return a * Math.pow(this.prms.S.v, 2) + b * this.prms.S.v + c;
}
protected get c0h(): number {
return this.getCoeff("h", "c0");
}
protected get c1h(): number {
return this.getCoeff("h", "c1");
}
protected get c2h(): number {
return this.getCoeff("h", "c2");
}
protected get c0ha(): number {
return this.getCoeff("ha", "c0");
}
protected get c1ha(): number {
return this.getCoeff("ha", "c1");
}
protected get c2ha(): number {
return this.getCoeff("ha", "c2");
}
}
import { Result } from "../util/result";
import { ParTypeSC } from "./par_type_sc";
import { ParParams } from "./par_params";
import { ParType } from "./par";
import { Message, MessageCode } from "../util/message";
export class ParTypeChevron extends ParTypeSC {
public constructor(prms: ParParams) {
super(prms);
this.type = ParType.CHEVRON;
}
public CalcZR1(): number {
return this.prms.ZD1.V - this.prms.a.v + (3 * this.prms.a.v * this.prms.S.v);
}
public CalcZM(): number {
// @TODO
return 0;
}
public CalcP(): number {
return 4 * this.prms.a.v;
}
public get minQstar(): number {
return 0.7;
}
public get maxQstar(): number {
return 8.1;
}
public addExtraResults(res: Result): void {
super.addExtraResults(res);
res.resultElement.values.B = this.CalcB();
}
public checkInput(): { fatal: boolean, messages: Message[] } {
const status = super.checkInput();
// M, round to 1
if (this.prms.M.v % 1 > 0.001 && this.prms.M.v % 1 < 0.999) {
const m = new Message(MessageCode.WARNING_PAR_M_ROUNDED_TO_1);
this.prms.M.v = Math.round(this.prms.M.v);
m.extraVar.val = this.prms.M.v;
status.messages.push(m);
}
// M, max. 2*N
if (this.prms.M.v > this.prms.N.v * 2) {
status.fatal = true;
const m = new Message(MessageCode.ERROR_PAR_M_GREATER_THAN_2_N);
m.extraVar.max = this.prms.N.v * 2;
status.messages.push(m);
}
return status;
}
protected CalcB(): number {
return 6 * this.prms.a.v * this.prms.N.v + 0.5 * this.prms.a.v * this.prms.M.v;
}
}
import { Result } from "../util/result";
import { ParTypePF } from "./par_type_pf";
import { ParType } from "./par";
import { ParParams } from "./par_params";
import { Message, MessageCode } from "../util/message";
export class ParTypeFatou extends ParTypePF {
public constructor(prms: ParParams) {
super(prms);
this.type = ParType.FATOU;
}
public CalcAw(): number {
return 0.6 * this.CalcH() * this.prms.L.v;
}
public CalcZR1(): number {
return this.prms.ZD1.V
- (Math.sqrt(2) * this.CalcA() * Math.sin(45 * Math.PI / 180 + Math.atan(this.prms.S.v)))
+ this.prms.L.V * 0.5 * this.prms.S.v;
}
public CalcZM(): number {
const H = 1.333 * this.prms.L.v;
return this.CalcZR1() + H * Math.cos(Math.atan(this.prms.S.v));
}
public CalcP(): number {
return 0.5 * this.prms.L.V;
}
public addExtraResults(res: Result): void {
super.addExtraResults(res);
res.resultElement.values.B = 0.6 * this.prms.L.V;
res.resultElement.values.a = this.CalcA();
res.resultElement.values.H = 1.333 * this.prms.L.V;
}
public checkInput(): { fatal: boolean, messages: Message[] } {
const status = super.checkInput();
// S
if (this.prms.S.v < 0.08 || this.prms.S.v > 0.22) {
status.fatal = true;
const m = new Message(MessageCode.ERROR_PAR_S);
m.extraVar.min = 0.08;
m.extraVar.max = 0.22;
status.messages.push(m);
} else if (this.prms.S.v > 0.2) {
const m = new Message(MessageCode.WARNING_PAR_S);
m.extraVar.min = 0;
m.extraVar.max = 0.2;
status.messages.push(m);
}
return status;
}
protected CalcA(): number {
return 0.2 * this.prms.L.V;
}
}
import { ParTypeAbstract } from "./par_type";
import { Message, MessageCode } from "../util/message";
import { ParamValueMode } from "../param/param-value-mode";
/**
* Intermediate class for common stuff between PLANE and FATOU pass types
*/
export abstract class ParTypePF extends ParTypeAbstract {
public CalcH() {
const qStar = this.CalcQStar();
return this.prms.L.v * (this.c2h * Math.pow(qStar, 2) + this.c1h * qStar + this.c0h);
}
public CalcHa(qStar?: number) {
if (qStar === undefined) {
qStar = this.CalcQStar();
}
// @TODO L.V (grand V) pour la vérification de ha p/r aux abaques ? Fait foirer le calcul de L …
return this.prms.L.v * (this.c2ha * Math.pow(qStar, 2) + this.c1ha * qStar + this.c0ha);
}
public CalcQStar(): number {
return this.prms.Q.V / (Math.sqrt(this.g) * Math.pow(this.prms.L.v, 2.5));
}
public get minQstar(): number {
return 0.0065;
}
public get maxQstar(): number {
return 0.35;
}
public CalcQFromHa(): number {
const x = this.ha / this.prms.L.v;
const y = this.doCalcQYFromHa(x);
return y * Math.sqrt(this.g) * Math.pow(this.prms.L.v, 2.5); // inverse of CalcQStar()
}
public checkInput(): { fatal: boolean, messages: Message[] } {
let fatal = false;
const messages: Message[] = [];
// L; when calculated, see Par.Calc()
if (this.prms.L.valueMode !== ParamValueMode.CALCUL) {
if (this.prms.L.v < 0.3 || this.prms.L.v > 1.3) {
fatal = true;
const m = new Message(MessageCode.ERROR_PAR_L);
m.extraVar.min = 0.3;
m.extraVar.max = 1.3;
messages.push(m);
} else if (this.prms.L.v > 1) {
const m = new Message(MessageCode.WARNING_PAR_L);
m.extraVar.max = 1;
messages.push(m);
}
}
return { fatal, messages };
}
}
import { Result } from "../util/result";
import { ParTypePF } from "./par_type_pf";
import { ParType } from "./par";
import { ParParams } from "./par_params";
import { Message, MessageCode } from "../util/message";
export class ParTypePlane extends ParTypePF {
public constructor(prms: ParParams) {
super(prms);
this.type = ParType.PLANE;
}
public CalcAw(): number {
const h = this.CalcH();
return this.prms.L.v * (0.583 * h - 0.146 * this.prms.L.v);
}
public CalcZR1(): number {
return this.prms.ZD1.V - (0.236 * this.prms.L.v * Math.sin(45 * Math.PI / 180 + Math.atan(this.prms.S.v)));
}
public CalcZM(): number {
// tslint:disable-next-line:variable-name
const Hmin = this.CalcHmin();
return this.CalcZR1() + Hmin * Math.sin(45 * Math.PI / 180 + Math.atan(this.prms.S.v));
}
public CalcP(): number {
return (2/3) * this.prms.L.V;
}
public addExtraResults(res: Result): void {
super.addExtraResults(res);
res.resultElement.values.B = 0.583 * this.prms.L.v;
res.resultElement.values.C = 0.472 * this.prms.L.v;
res.resultElement.values.D = 0.236 * this.prms.L.v;
res.resultElement.values.Hmin = this.CalcHmin();
res.resultElement.values.Hmax = 2.2 * this.prms.L.v;
}
public checkInput(): { fatal: boolean, messages: Message[] } {
const status = super.checkInput();
// S
if (this.prms.S.v < 0.06 || this.prms.S.v > 0.22) {
status.fatal = true;
const m = new Message(MessageCode.ERROR_PAR_S);
m.extraVar.min = 0.06;
m.extraVar.max = 0.22;
status.messages.push(m);
} else if (this.prms.S.v < 0.08 || this.prms.S.v > 0.2) {
const m = new Message(MessageCode.WARNING_PAR_S);
m.extraVar.min = 0.08;
m.extraVar.max = 0.2;
status.messages.push(m);
}
return status;
}
protected CalcHmin(): number {
return 1.85 * this.prms.L.v;
}
}
import { ParTypeAbstract } from "./par_type";
import { Message, MessageCode } from "../util/message";
import { ParamValueMode } from "../param/param-value-mode";
/**
* Intermediate class for common stuff between SUPERACTIVE and CHEVRON pass types
*/
export abstract class ParTypeSC extends ParTypeAbstract {
public CalcH() {
const qStar = this.CalcQStar();
return this.prms.a.v * (this.c2h * Math.pow(qStar, 2) + this.c1h * qStar + this.c0h);
}
public CalcHa(qStar?: number) {
if (qStar === undefined) {
qStar = this.CalcQStar();
}
return this.prms.a.v * (this.c2ha * Math.pow(qStar, 2) + this.c1ha * qStar + this.c0ha);
}
public CalcQStar(): number {
return (this.prms.Q.V / this.CalcB()) / (Math.sqrt(2 * this.g) * Math.pow(this.prms.a.v, 1.5));
}
public CalcQFromHa(): number {
const x = this.ha / this.prms.a.v;
const y = this.doCalcQYFromHa(x);
return y * Math.sqrt(2 * this.g) * Math.pow(this.prms.a.v, 1.5) * this.CalcB(); // inverse of CalcQStar()
}
public CalcAw(): number {
return this.CalcH() * this.CalcB();
}
public checkInput(): { fatal: boolean, messages: Message[] } {
let fatal = false;
const messages: Message[] = [];
// S
if (this.prms.S.v < 0.1 || this.prms.S.v > 0.18) {
fatal = true;
const m = new Message(MessageCode.ERROR_PAR_S);
m.extraVar.min = 0.1;
m.extraVar.max = 0.18;
messages.push(m);
} else if (this.prms.S.v > 0.16) {
const m = new Message(MessageCode.WARNING_PAR_S);
m.extraVar.max = 0.16;
messages.push(m);
}
// N
if (this.prms.N.v % 0.5 > 0.001 && this.prms.N.v % 0.5 < 0.499) {
const m = new Message(MessageCode.WARNING_PAR_N_ROUNDED_TO_05);
this.prms.N.v = Math.round(this.prms.N.v * 2) / 2;
m.extraVar.val = this.prms.N.v;
messages.push(m);
}
// a
if (this.prms.a.v < 0.05 || this.prms.a.v > 0.25) {
fatal = true;
const m = new Message(MessageCode.ERROR_PAR_A);
m.extraVar.min = 0.05;
m.extraVar.max = 0.25;
messages.push(m);
} else if (this.prms.a.v > 0.2) {
const m = new Message(MessageCode.WARNING_PAR_A);
m.extraVar.max = 0.2;
messages.push(m);
}
return { fatal, messages };
}
protected abstract CalcB(): number;
}
import { Result } from "../util/result";
import { ParTypeSC } from "./par_type_sc";
import { ParType } from "./par";
import { ParParams } from "./par_params";
import { Message, MessageCode } from "../util/message";
export class ParTypeSuperactive extends ParTypeSC {
public constructor(prms: ParParams) {
super(prms);
this.type = ParType.SUPERACTIVE;
}
public CalcZR1(): number {
return this.prms.ZD1.V - this.prms.a.v + (2.6 * this.prms.a.v * this.prms.S.v);
}
public CalcZM(): number {
// @TODO
return 0;
}
public CalcP(): number {
return 2.6 * this.prms.a.v;
}
public get minQstar(): number {
return 0.4;
}
public get maxQstar(): number {
return 5.3;
}
public addExtraResults(res: Result): void {
super.addExtraResults(res);
res.resultElement.values.B = this.CalcB();
res.resultElement.values.L = this.CalcB() / this.prms.N.v;
}
protected CalcB(): number {
return 6 * this.prms.a.v * this.prms.N.v;
}
}
......@@ -72,6 +72,8 @@ import { CreateStructure } from "./structure/factory_structure";
import { ParallelStructure } from "./structure/parallel_structure";
import { ParallelStructureParams } from "./structure/parallel_structure_params";
import { LoiDebit, StructureType } from "./structure/structure_props";
import { Par, ParType } from "./par/par";
import { ParParams } from "./par/par_params";
export class Session {
......@@ -89,7 +91,8 @@ export class Session {
nodeType: SectionType,
calcType: CalculatorType,
structureType: StructureType,
inclinedApron: MRCInclination
inclinedApron: MRCInclination,
parType: ParType
};
public static getInstance(): Session {
......@@ -647,6 +650,23 @@ export class Session {
);
break;
case CalculatorType.Par:
nub = new Par(
new ParParams(
0.25, // Q
10, // Z1
9, // Z2
9.36, // ZD1
0.2, // S
0.4, // P
0.6, // L
0.1, // a
1, // N
1 // M
)
);
break;
default:
throw new Error(
`Session.createNub() : type de module '${CalculatorType[calcType]}' non pris en charge`
......
......@@ -73,6 +73,18 @@ export enum MessageCode {
/** Jet submergé, pente trop faible: pas de solution pour calculer l'abscisse de l'impact */
ERROR_JET_SUBMERGED_NO_SOLUTION,
/**
* Passe à ralentisseurs: la valeur donnée de P est plus de 10% plus petite / plus de 5%
* plus grande que la valeur standard %stdP%
*/
ERROR_PAR_P_DEVIATES_MORE_THAN_10_5_PCT,
/** La valeur %val% de Q* sort de l'intervalle de validité [ %min%, %max% ] donné par les abaques */
ERROR_PAR_QSTAR_OUT_OF_RANGE,
/** La valeur %val% de ha sort de l'intervalle de validité [ %min%, %max% ] donné par les abaques */
ERROR_PAR_HA_OUT_OF_RANGE,
/**
* Something failed in certain steps (but not all), when calculating upstream Nubs with varying parameter
*/
......@@ -410,6 +422,39 @@ export enum MessageCode {
*/
WARNING_SLOT_SUBMERSION_NOT_BETWEEN_07_AND_09,
/** PAR : la largeur est plus grande que la valeur d'alerte %max% */
WARNING_PAR_L,
/** PAR : la largeur est en dehors des valeurs admissibles %min% et %max% (comme ERROR_PAR_L), mais pas d'erreur fatale */
WARNING_ERROR_PAR_L,
/** PAR: calcul de L, le P fourni est ignoré */
WARNING_PAR_P_WAS_IGNORED,
/** PAR : la pente est en dehors des valeurs standard (%min%, facultatif) et %max% */
WARNING_PAR_S,
/** PAR : la largeur est en dehors des valeurs admissibles %min% et %max% */
ERROR_PAR_L,
/** PAR : la pente est en dehors des valeurs admissibles %min% et %max% */
ERROR_PAR_S,
/** PAR superactive / chevrons : la hauteur est en dehors des valeurs admissibles %min% et %max% */
ERROR_PAR_A,
/** PAR superactive / chevrons : la hauteur dépasse la valeur d'alerte %max% */
WARNING_PAR_A,
/** PAR superactive / chevrons : le nombre de motifs a été arrondi à 0.5 près, à la valeur %val% */
WARNING_PAR_N_ROUNDED_TO_05,
/** PAR chevrons : le nombre de bandes dépasse deux fois le nombre de motifs %max% */
ERROR_PAR_M_GREATER_THAN_2_N,
/** PAR chevrons : le nombre de bandes a été arrondi à 1 près, à la valeur %val% */
WARNING_PAR_M_ROUNDED_TO_1,
/**
* La formule du seuil noyé n'est pas conseillé pour un ennoiement inférieur à 0.8
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment