parallel_structure.ts 8.41 KiB
import { Nub } from "../nub";
import { ParamCalculability } from "../param/param-definition";
import { Message } from "../util/message";
import { Result } from "../util/result";
import { ParallelStructureParams } from "./parallel_structure_params";
import { Structure } from "./structure";
import { IParamDefinitionIterator, ParamsEquation, ParamsEquationArrayIterator } from "../param/params-equation";
/**
 * Interface pour mémoriser le n° d'ouvrage et le paramètre à calculer
interface IStructureVarCalc {
    index: number;
    prm: string;
/**
 * 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;
        this.updateStructuresH1H2();
    /**
     * Mise à jour de Z2 pour toutes les structures en parallèle
    set Z2(Z2: number) {
        this.prms.Z2.v = Z2;
        this.updateStructuresH1H2();
    public get parameterIterator(): IParamDefinitionIterator {
        const prms: ParamsEquation[] = [];
        prms.push(this._prms);
        for (const st of this.structures)
            prms.push(st.parameters);
        return new ParamsEquationArrayIterator(prms);
    /**
     * Ajout d'une structure en parallèle
     * @param structure La structure à rajouter
     * @param after position après laquelle insérer la structure, à la fin sinon
    public addStructure(structure: Structure, after?: number) {
        if (after !== undefined)
            this.structures.splice(after + 1, 0, structure);
        else
            this.structures.push(structure);
    /**
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
* remplace une structure hydraulique * @param index indice de la structure dans le tableau * @param structure nouvelle structure */ public replaceStructure(index: number, structure: Structure) { if (index > -1 && index < this.structures.length) { this.structures[index] = structure; } else { throw new Error(`ParallelStructure.replaceStructure invalid index ${index}`); } } /** * @return true si la structure donnée est dans la liste */ public hasStructure(structure: Nub): boolean { for (const s of this.structures) if (s.uid == structure.uid) return true; return false; } /** * déplace une structure d'une position vers le début de la liste */ public moveStructureUp(structure: Structure) { let i = 0; for (const s of this.structures) { if (s.uid == structure.uid && i > 0) { const t = this.structures[i - 1]; this.structures[i - 1] = this.structures[i]; this.structures[i] = t; return; } i++; } } /** * 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.updateStructuresH1H2(); 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) + "]", );
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
} } const calcRes: Result = new Result(0); 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.resultElement.AddResultElementToExtra(res.resultElement, `${i}.Q`); qTot += res.vCalc; } } // 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 "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, rPrec: number = 0.001): Result { let res: Result; switch (sVarCalc) { case "Z1": case "Z2": case "Q": res = super.Calc(sVarCalc, rInit, rPrec); if (res.ok) { this.getParameter(sVarCalc).setValue(res.vCalc); } break; default: // Pour les caractéristiques des ouvrages const sVC = this.getStructureVarCalc(sVarCalc); res = this.CalcStructPrm(sVC, rInit, rPrec); if (res.ok) { this.structures[sVC.index].getParameter(sVC.prm).setValue(res.vCalc); } } if (res.ok) { // Recalcul du débit total pour récupérer les résultats des ouvrages dans les résultats complémentaires const resQtot: Result = this.CalcQ(); for (const extraResKey in resQtot.extraResults) { if (resQtot.extraResults.hasOwnProperty(extraResKey)) { res.resultElement.addExtraResult(extraResKey, resQtot.extraResults[extraResKey]); } } } this._result = res; return res; } /** * 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 */ private updateStructuresH1H2() { for (const structure of this.structures) { structure.prms.Z1.v = this.prms.Z1.v;
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
structure.prms.Z2.v = this.prms.Z2.v; structure.prms.update_h1h2(); } } /** * Renvoie le n° de structure et le paramètre à calculer * @param sVarCalc Nom du paramètre à calculer : "n.X" avec "n" l'index de l'ouvrage et "X" son paramètre */ private getStructureVarCalc(sVarCalc: string): IStructureVarCalc { let sIndex: string; let sPrm: string; if (sVarCalc.indexOf(".") == -1) throw new Error(`getStructureVarCalc() : erreur d'analyse de ${sVarCalc}, (pas de la forme n.X)`); [sIndex, sPrm] = sVarCalc.split("."); const i = parseInt(sIndex, 10); if (i === NaN) throw new Error(`getStructureVarCalc() : erreur d'analyse de ${sVarCalc} (${sIndex} n'est pas un nombre)`); return { index: i, prm: sPrm }; } /** * 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 * @param rPrec Précision attendue */ private CalcStructPrm(sVC: IStructureVarCalc, rInit?: number, rPrec: number = 0.001): Result { // Le débit restant sur la structure en calcul est : this.structures[sVC.index].prms.Q.setValue(this.prms.Q.v - this.CalcQ(sVC.index).vCalc); // Calcul du paramètre de la structure en calcul return this.structures[sVC.index].Calc(sVC.prm, rInit, rPrec); } }