import { CalculatorType } from "../compute-node"; import { Session } from "../index"; import { Nub } from "../nub"; import { ParamCalculability } from "../param/param-definition"; import { ParamsEquation } from "../param/params-equation"; import { Result } from "../util/result"; import { ParallelStructureParams } from "./parallel_structure_params"; import { Structure } from "./structure"; import { loiAdmissiblesOuvrages, LoiDebit } from "./structure_props"; /** * 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 { constructor(prms: ParamsEquation, dbg: boolean = false) { super(prms, dbg); this._calcType = CalculatorType.ParallelStructure; this._childrenType = "Structure"; } /** children casting */ public get structures() { return this._children as Structure[]; } public set structures(structures: Structure[]) { this._children = structures; this._children.forEach((s) => { s.parent = this; }); } /** * paramètres castés au bon type */ get prms(): ParallelStructureParams { return this._prms as ParallelStructureParams; } /** Returns admissible LoiDebit grouped by StructureType */ public getLoisAdmissibles(): { [key: string]: LoiDebit[]; } { return loiAdmissiblesOuvrages; } /** Returns a flat array of all admissible LoiDebit */ public getLoisAdmissiblesArray(): LoiDebit[] { let loisAdm: LoiDebit[] = []; const lois = this.getLoisAdmissibles(); // tslint:disable-next-line:forin for (const k in lois) { loisAdm = loisAdm.concat(lois[k]); } return loisAdm; } /** Returns the 1st deep item from LoisAdmissibles */ public getDefaultLoiDebit(): LoiDebit { const lois = this.getLoisAdmissibles(); return lois[Object.keys(lois)[0]][0]; } /** * 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); 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._children.length) { throw new Error( "ParallelStructure.CalcQ iExcept not in [0;" + (this._children.length - 1) + "]", ); } } this.updateStructuresH1H2(); const calcRes: Result = new Result(0, this); let qTot: number = 0; for (let i = 0; i < this._children.length; i++) { if (i !== iExcept) { const res: Result = this._children[i].Calc("Q"); qTot += res.vCalc; // merge logs calcRes.resultElement.log.addLog(res.log); } } // Assigne le débit total dans le résultat calcRes.resultElement.vCalc = qTot; 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 { uid: "abcdef", symbol: "X" } avec "abcdef" l'index de l'ouvrage et "X" son paramètre * @param rInit Valeur initiale */ public Calc(sVarCalc: string | any, rInit?: number): Result { // if Calc() is called outside of CalcSerie(), _result might not be initialized if (! this.result) { this.initNewResultElement(); } switch (sVarCalc) { case "Z1": case "Z2": case "Q": this.currentResult = super.Calc(sVarCalc, rInit); if (this.result.ok) { this.getParameter(sVarCalc).v = this.result.resultElement.vCalc; } break; default: if (typeof sVarCalc === "string") { throw new Error("ParallelStructures.Calc() : unknow parameter to calculate " + sVarCalc); } // Pour les caractéristiques des ouvrages const structureIndex = this.getIndexForChild(sVarCalc.uid); const r = this.CalcStructPrm(structureIndex, sVarCalc.symbol, rInit); // whether r is .ok() or not, just copy vCalc and logs to avoid // this._result being polluted by structure.flagsNull this.result.symbol = r.symbol; this.result.vCalc = r.vCalc; // merge logs this.result.log.addLog(r.log); this.result.globalLog.addLog(r.globalLog); } return this.result; } /** * Once session is loaded, run a second pass on all linked parameters to * reset their target if needed */ public fixLinks(obj: any): { hasErrors: boolean } { // return value const ret = { hasErrors: false }; // iterate over parameters super.fixLinks(obj); // iterate over children if any if (obj.children && Array.isArray(obj.children)) { for (const s of obj.children) { // get the Nub const subNub = Session.getInstance().findNubByUid(s.uid); const res = subNub.fixLinks(s); // forward errors if (res.hasErrors) { ret.hasErrors = true; } } } return ret; } /** * 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; } /** * Mise à jour de Z1, Z2, h1 et h2 pour tous les ouvrages */ protected updateStructuresH1H2() { for (const structure of this.structures) { structure.prms.Z1.v = this.prms.Z1.v; structure.prms.Z2.v = this.prms.Z2.v; structure.prms.update_h1h2(); } } /** * Calcul du paramètre d'un des ouvrages en parallèle * @param sVC Index de l'ouvrage et paramètre à calculer * @param rInit Valeur initiale */ protected CalcStructPrm(index: number, symbol: string, rInit?: number): Result { // Le débit restant sur la structure en calcul est : this.structures[index].prms.Q.v = this.prms.Q.v - this.CalcQ(index).vCalc; // Calcul du paramètre de la structure en calcul const r: Result = this.structures[index].Calc(symbol, rInit); this.structures[index].result.values.Q = this.structures[index].prms.Q.v; return r; } }