nub_factory.ts 13.9 KB
Newer Older
import { ComputeNodeType, CalculatorType } from "./compute-node"
import { Nub } from "./nub"
import { SessionNub, Props } from "./session_nub"
import { ConduiteDistribParams, ConduiteDistrib } from "./cond_distri";
import { LechaptCalmonParams, LechaptCalmon } from "./lechaptcalmon";

import { acSection } from "./section/section_type";
import { ParamsSectionTrapez, cSnTrapez } from "./section/section_trapez";
import { ParamsSectionRectang, cSnRectang } from "./section/section_rectang";
import { ParamsSectionCirc, cSnCirc } from "./section/section_circulaire";
import { ParamsSectionPuiss, cSnPuiss } from "./section/section_puissance";
import { SectionParametree } from "./section/section_nub";
import { RegimeUniforme } from "./regime_uniforme";
import { CourbeRemousParams, MethodeResolution, CourbeRemous } from "./remous";
import { PabDimensionParams, PabDimension } from "./pab/pab_dimension";
import { PabPuissance, PabPuissanceParams } from "./pab/pab_puissance";
import { CreateStructure } from "./structure/factory_structure";
import { StructureType, LoiDebit } from "./structure/structure_props";
import { Structure } from "./structure/structure";
import { ParallelStructure } from "./structure/parallel_structure";
import { ParallelStructureParams } from "./structure/parallel_structure_params";
import { RectangularStructureParams } from "./structure/structure_cem88d";

export class NubFactory {
    private _defaultPrecision: number = 0.001;

    private static _instance: NubFactory; // instance pour le pattern singleton

    private _session: SessionNub[];

    private constructor() {
        this._session = [];
    }

    public static getInstance() {
        if (NubFactory._instance == undefined)
            NubFactory._instance = new NubFactory();
        return NubFactory._instance;
    }

    public setDefaultPrecision(p: number) {
        this._defaultPrecision = p;
    }

    private newSessionNub(p: Props | {}): SessionNub {
        const params = p instanceof Props ? p : new Props(p);
        const nub = this.createNub(params);
        return new SessionNub(nub, params);
    }

    /**
     * créé un Nub et l'ajoute à la session
     */
    public createSessionNub(p: Props | {}): SessionNub {
        this._session.push(res);
        return res;
    }

    public findSessionNub(params: Props | {}): SessionNub {
        for (const n of this._session)
            if (n.hasProperties(params))
                return n;
        return undefined;
    }

    private replaceStructureNub(oldNub: Nub, newNub: Nub) {
        const b1 = oldNub instanceof Structure;
        const b2 = newNub instanceof Structure;
        if ((b1 && !b2) || (!b1 && b2))
            throw new Error(`NubFactory.replaceStructureNub() : arguments incorrects (${typeof (oldNub)}/${typeof (newNub)}`);
        if (b1 && b2) {
            for (const sn of this._session)
                if (sn.nub instanceof ParallelStructure) {
                    const psn = sn.nub as ParallelStructure;
                    let i = 0;
                    for (const st of psn.structures) {
                        if (st.uid == oldNub.uid) {
                            psn.replaceStructure(i, newNub as Structure);
                            return;
                        }
                        i++;
                    }
                }
            throw new Error(`NubFactory.replaceStructureNub() : la structure (uid ${oldNub.uid}) à remplacer n'a pas été trouvée`);
        }
    }

    private deleteStructureNub(n: Nub) {
        if (n instanceof Structure) {
            for (const sn of this._session)
                if (sn.nub instanceof ParallelStructure) {
                    const psn = sn.nub as ParallelStructure;
                    let i = 0;
                    for (const st of psn.structures) {
                        if (st.uid == n.uid) {
                            psn.deleteStructure(i);
                            return;
                        }
                        i++;
                    }
                }
            throw new Error(`NubFactory.deleteStructureNub() : la structure (uid ${n.uid}) à supprimer n'a pas été trouvée`);
        }
    }

    /**
     * remplace un SessionNub par un nouveau
     * @param sn SessionNub à remplacer
     * @param params propriété du nouveau SessionNub
     */
    public replaceSessionNub(sn: SessionNub, params: Props): SessionNub {
        let i = 0;
        for (const n of this._session) {
            if (n.uid == sn.uid) {
                const newNub = this.newSessionNub(params);
                this._session[i] = newNub;
                this.replaceStructureNub(sn.nub, newNub.nub);
                return newNub;
            }
            i++;
        }

        // pas trouvé
        return undefined;
    }

     *  recherche du nub ouvrages parallèles possédant l'ouvrage donné
        for (const s of this._session)
            if (s.nub instanceof ParallelStructure) {
                const res = s.nub as ParallelStructure;
                if (res.hasStructure(n))
                    return res;
        return undefined;
    }

    /**
     * déplace un SessionNub associé à un nub Structure d'une position vers le début de la liste de structures
     * @param sn SessionNub à remplacer
     * @param params propriété du nouveau SessionNub
     */
    public moveStructureNubUp(sn: SessionNub) {
        const psn = this.findParallelStructureWithNub(sn.nub);

        // déplacement
        if (psn) {
            let i = 0;
            for (const n of this._session) {
                if (n.uid == sn.uid && i > 0) {
                    const n = this._session[i - 1];
                    this._session[i - 1] = this._session[i];
                    this._session[i] = n;
                    psn.moveStructureUp(sn.nub as Structure);
                    return;
                }
                i++;
            }
        }

        throw new Error(`NubFactory.moveStructureNubUp() : la structure (uid ${sn.uid}) à déplacer n'a pas été trouvée`);
    }

    /**
     * déplace un SessionNub associé à un nub Structure d'une position vers la fin de la liste de structures
     * @param sn SessionNub à remplacer
     * @param params propriété du nouveau SessionNub
     */
    public moveStructureNubDown(sn: SessionNub) {
        const psn = this.findParallelStructureWithNub(sn.nub);

        // déplacement
        if (psn) {
            let i = 0;
            for (const n of this._session) {
                if (n.uid == sn.uid && i < this._session.length - 1) {
                    const n = this._session[i];
                    this._session[i] = this._session[i + 1];
                    this._session[i + 1] = n;
                    psn.moveStructureDown(sn.nub as Structure);
                    return;
                }
                i++;
            }
        }

        throw new Error(`NubFactory.moveStructureNubDown() : la structure (uid ${sn.uid}) à déplacer n'a pas été trouvée`);
    }

    /**
     * créé un Nub
     * @param calcType type de Nub
     * @param nodeType sous type de Nub
     * @param params paramètres supplémentaires spécifiques
     */
    private createNub(params: Props): Nub {
        const calcType: CalculatorType = params.getPropValue("calcType");
        const nodeType: ComputeNodeType = params.getPropValue("nodeType");

        switch (calcType) {
            case CalculatorType.ConduiteDistributrice:
                {
                    const prms = new ConduiteDistribParams(3, // débit Q
                        1.2, // diamètre D
                        0.6, // perte de charge J
                        100, // Longueur de la conduite Lg
                        1e-6, // Viscosité dynamique Nu
                    );

                    return new ConduiteDistrib(prms);
                }

            case CalculatorType.LechaptCalmon:
                {
                    const prms = new LechaptCalmonParams(3, // débit
                        1.2, // diamètre
                        0.6, /// perte de charge
                        100, // longueur du toyo
                        1.863, // paramètre L du matériau
                        2, // paramètre M du matériau
                        5.33// paramètre N du matériau
                    );
                    return new LechaptCalmon(prms);
                }

            case CalculatorType.SectionParametree:
                return new SectionParametree(this.createSection(nodeType));

            case CalculatorType.RegimeUniforme:
                const sect: acSection = this.createSection(nodeType);
                const ru = new RegimeUniforme(sect);
                return ru;


            case CalculatorType.CourbeRemous:
                {
                    const sect: acSection = this.createSection(nodeType);
                    const prms = new CourbeRemousParams(sect, 0.15, // Yamont = tirant amont
                        0.4, // Yaval = tirant aval
                        100,  // Long= Longueur du bief
                        5,  // Dx=Pas d'espace
                        MethodeResolution.EulerExplicite
                    );
                    return new CourbeRemous(prms);
                }

            case CalculatorType.PabDimensions:
                {
                    const prms = new PabDimensionParams(
                        2,      // Longueur L
                        1,      // Largeur W
                        0.5,    // Tirant d'eau Y
                        2       // Volume V
                    );
                    return new PabDimension(prms);
                }

            case CalculatorType.PabPuissance:
                {
                    const prms = new PabPuissanceParams(
                        0.3,      // Chute entre bassins DH (m)
                        0.1,      // Débit Q (m3/s)
                        0.5,    // Volume V (m3)
                        588.6   // Puissance dissipée Pv (W/m3)
                    );
                    return new PabPuissance(prms);
                }

            case CalculatorType.Structure:
                const structType: StructureType = params.getPropValue("structureType");
                const loiDebit: LoiDebit = params.getPropValue("loiDebit");
                return CreateStructure(structType, loiDebit);

            case CalculatorType.ParallelStructure:
                {
                    const prms = new ParallelStructureParams(0.5, // Q
                        102, // Z1
                        101.5 // Z2 
                    );
                    return new ParallelStructure(prms);
                }

            default:
                throw new Error(`NubFactory.createNub() : calculatrice '${CalculatorType[calcType]}' / noeud de calcul '${ComputeNodeType[nodeType]}' non pris en charge`);
        }
    }

    public deleteSessionNub(sn: SessionNub) {
        let i = 0;
        for (const n of this._session) {
            if (n.uid == sn.uid) {
                this._session.splice(i, 1);
                this.deleteStructureNub(sn.nub);
                return;
            }
            i++;
        }
        throw new Error(`NubFactory.deleteSessionNub() : le SessionNub (uid ${sn.uid}) à supprimer n'a pas été trouvé`);
    }

    private createSection(nt: ComputeNodeType): acSection {
        switch (nt) {
            case ComputeNodeType.None: // pour les paramètres communs, n'importe quelle section convient
            case ComputeNodeType.SectionTrapeze:
                {
                    const prms = new ParamsSectionTrapez(2.5, // largeur de fond
                        0.56, // fruit
                        0.8, // tirant d'eau
                        40, //  Ks=Strickler
                        1.2,  //  Q=Débit
                        0.001, //  If=pente du fond
                        this._defaultPrecision, // précision
                        1, // YB= hauteur de berge
                    );

                    return new cSnTrapez(prms);
                }


            case ComputeNodeType.SectionRectangle:
                {
                    const prms = new ParamsSectionRectang(0.8, // tirant d'eau
                        2.5, // largeur de fond
                        40, //  Ks=Strickler
                        1.2, // Q=Débit
                        0.001, // If=pente du fond
                        this._defaultPrecision, // précision
                        1 // YB=hauteur de berge
                    );
                    return new cSnRectang(prms);
                }

            case ComputeNodeType.SectionCercle:
                {
                    const prms = new ParamsSectionCirc(2, // diamètre
                        0.8, // tirant d'eau
                        40, //  Ks=Strickler
                        1.2,  //  Q=Débit
                        0.001, //  If=pente du fond
                        this._defaultPrecision, // précision
                        1, // YB= hauteur de berge
                    );
                    return new cSnCirc(prms);
                }

            case ComputeNodeType.SectionPuissance:
                {
                    const prms = new ParamsSectionPuiss(0.5, // coefficient
                        0.8, // tirant d'eau
                        4, // largeur de berge
                        40, //  Ks=Strickler
                        1.2,  //  Q=Débit
                        0.001, //  If=pente du fond
                        this._defaultPrecision, // précision
                        1, // YB= hauteur de berge
                    );
                    return new cSnPuiss(prms);
                }

            default:
                throw new Error(`type de section ${ComputeNodeType[nt]} non pris en charge`);
        }
    }

    // public get sessionNubIterator(): IterableIterator<SessionNub> {
    //     return this._session[Symbol.iterator](); // crée un itérateur à partir d'un tableau
    // }