From b92adbc3c35ec2494160a6c844a1e3e9439b9c96 Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Thu, 2 Nov 2017 16:17:27 +0100 Subject: [PATCH] ajout de la calculette des courbes de remous (composants CourbeRemousComponent et RemousResultsComponent) --- src/app/app.component.ts | 3 +- src/app/app.module.ts | 6 +- .../generic/calculator.component.html | 3 +- .../generic/calculator.component.ts | 148 +++++++++++- src/app/calculators/generic/formulaire.ts | 39 +++- .../calculators/remous/remous.component.html | 2 + .../calculators/remous/remous.component.ts | 8 + src/app/calculators/remous/remous.config.json | 90 ++++--- src/app/calculators/remous/remous.fr.json | 19 +- .../remous-results.component.html | 42 ++++ .../remous-results.component.ts | 221 ++++++++++++++++++ .../services/formulaire/formulaire.service.ts | 18 +- src/app/services/param/param.service.ts | 47 ++-- 13 files changed, 555 insertions(+), 91 deletions(-) create mode 100644 src/app/calculators/remous/remous.component.html create mode 100644 src/app/calculators/remous/remous.component.ts create mode 100644 src/app/components/remous-results/remous-results.component.html create mode 100644 src/app/components/remous-results/remous-results.component.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 1500b3345..4972f2dba 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -16,8 +16,9 @@ import { FormulaireService } from './services/formulaire/formulaire.service'; <option *ngFor="let l of intlService.languages" [value]=l.code>{{l.label}}</option> </select> - <regime-uniforme></regime-uniforme> + <courbe-remous></courbe-remous> <!-- + <regime-uniforme></regime-uniforme> <section-param></section-param> <lechapt-calmon></lechapt-calmon> <cond-distri></cond-distri> diff --git a/src/app/app.module.ts b/src/app/app.module.ts index e9ec127ae..b3613a86d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -16,6 +16,7 @@ import { CondDistriComponent } from './calculators/cond_distri/conddistri.compon import { LechaptCalmonComponent } from './calculators/lechapt-calmon/lechaptcalmon.component'; import { SectionParametreeComponent } from './calculators/section-param/section-param.component'; import { RegimeUniformeComponent } from './calculators/regime-uniforme/regime-uniforme.component'; +import { CourbeRemousComponent } from './calculators/remous/remous.component'; import { AlertDialog } from './components/alert-dialog/alert-dialog.component'; import { AppErrorModule } from './error.module'; import { CalculatorResultsComponent } from './components/calculator-results/calculator-results.component'; @@ -23,6 +24,7 @@ import { SectionResultsComponent } from './components/section-results/section-re import { GenericCalculatorComponent } from './calculators/generic/calculator.component'; import { CalcCanvasComponent } from './components/canvas/canvas.component'; import { SectionCanvasComponent } from './components/section-canvas/section-canvas.component'; +import { RemousResultsComponent } from './components/remous-results/remous-results.component'; @NgModule({ imports: [ @@ -40,9 +42,9 @@ import { SectionCanvasComponent } from './components/section-canvas/section-canv ParamInputComponent, FieldSetComponent, ParamFieldLineComponent, SelectFieldLineComponent, CheckFieldLineComponent, - CondDistriComponent, LechaptCalmonComponent, SectionParametreeComponent, GenericCalculatorComponent, RegimeUniformeComponent, + CondDistriComponent, LechaptCalmonComponent, SectionParametreeComponent, GenericCalculatorComponent, RegimeUniformeComponent, CourbeRemousComponent, AlertDialog, - CalculatorResultsComponent, SectionResultsComponent, + CalculatorResultsComponent, SectionResultsComponent, RemousResultsComponent, CalcCanvasComponent, SectionCanvasComponent ], entryComponents: [AlertDialog], diff --git a/src/app/calculators/generic/calculator.component.html b/src/app/calculators/generic/calculator.component.html index 3491a069c..af3fb204b 100644 --- a/src/app/calculators/generic/calculator.component.html +++ b/src/app/calculators/generic/calculator.component.html @@ -7,4 +7,5 @@ <button type="button" class="button_compute" name="Calculer" (click)="doCompute()" i18n="@@hyd_compute">Calculer</button> </div> <calc-results [style.display]="getResultsStyleDisplay()"></calc-results> -<section-results [style.display]="getSectionResultsStyleDisplay()"></section-results> \ No newline at end of file +<section-results [style.display]="getSectionResultsStyleDisplay()"></section-results> +<remous-results [style.display]="getRemousResultsStyleDisplay()"></remous-results> diff --git a/src/app/calculators/generic/calculator.component.ts b/src/app/calculators/generic/calculator.component.ts index 1291b64c5..abf9a9dc5 100644 --- a/src/app/calculators/generic/calculator.component.ts +++ b/src/app/calculators/generic/calculator.component.ts @@ -3,7 +3,7 @@ import { Response } from '@angular/http'; import { Observable } from "rxjs/Observable"; import 'rxjs/add/operator/toPromise'; -import { ComputeNode, ComputeNodeType, IParamsEquation, Nub, acSection, RegimeUniforme } from "jalhyd"; +import { ComputeNode, ComputeNodeType, ParamsEquation, Nub, acSection, RegimeUniforme, MethodeResolution, CourbeRemousParams, CourbeRemous, cLog } from "jalhyd"; import { ParamService } from '../../services/param/param.service'; import { HttpService } from '../../services/http/http.service'; @@ -13,6 +13,7 @@ import { FieldSet, InputField, SelectField, FormulaireDefinition, CalculatorType import { NgParameter, ParamRadioConfig } from './ngparam'; import { CalculatorResultsComponent } from '../../components/calculator-results/calculator-results.component'; import { SectionResultsComponent } from '../../components/section-results/section-results.component'; +import { RemousResultsComponent } from '../../components/remous-results/remous-results.component'; import { Observer } from '../../services/observer'; @Component({ @@ -54,6 +55,12 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer { @ViewChild(SectionResultsComponent) private sectionResultsComponent: SectionResultsComponent; + /** + * composant d'affichage des résultats des section paramétrées + */ + @ViewChild(RemousResultsComponent) + private remousResultsComponent: RemousResultsComponent; + /** * objet JSON chargé depuis le fichier de traduction */ @@ -71,6 +78,11 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer { */ private _showResultsSection: boolean = false; + /** + * flag d'affichage du composant de résultats du calcul des courbes de remous + */ + private _showResultsRemous: boolean = false; + constructor(private paramService: ParamService, private httpService: HttpService, private intlService: InternationalisationService, private formulaireService: FormulaireService) { this.intlService.addObserver(this); } @@ -204,6 +216,7 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer { private onRadioClick(info: string) { this._showResultsFixVar = false; this._showResultsSection = false; + this._showResultsRemous = false; let tmp: string[] = info.split("_"); let symbol: string = tmp[0]; @@ -327,11 +340,11 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer { this.resultsComponent.setVariableResultHeader(computedParam["label"]); let ssf: SelectField = <SelectField>this._formulaire.getFormulaireElementById("select_section"); - let typeSect: ComputeNodeType = FormulaireDefinition.getSectionType(ssf.getValue()); + let typeSect: ComputeNodeType = FormulaireDefinition.getComputeNodeTypeFromSection(ssf.getValue(), CalculatorType.SectionParametree); - var np: [acSection, IParamsEquation] = this.formulaireService.getSectionNubAndParameters(CalculatorType.SectionParametree, typeSect); + var np: [acSection, ParamsEquation] = this.formulaireService.getSectionNubAndParameters(CalculatorType.SectionParametree, typeSect); let sect: acSection = np[0]; - let prms: IParamsEquation = np[1]; + let prms: ParamsEquation = np[1]; let min: number = +varParam.minValue; let max: number = +varParam.maxValue; @@ -364,16 +377,16 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer { } let ssf: SelectField = <SelectField>this._formulaire.getFormulaireElementById("select_section"); - let typeSect: ComputeNodeType = FormulaireDefinition.getSectionType(ssf.getValue()); - var np: [acSection, IParamsEquation] = this.formulaireService.getSectionNubAndParameters(CalculatorType.SectionParametree, typeSect); + let typeSect: ComputeNodeType = FormulaireDefinition.getComputeNodeTypeFromSection(ssf.getValue(), CalculatorType.SectionParametree); + var np: [acSection, ParamsEquation] = this.formulaireService.getSectionNubAndParameters(CalculatorType.SectionParametree, typeSect); let sect: acSection = np[0]; - let prms: IParamsEquation = np[1]; + let prms: ParamsEquation = np[1]; let prec: number = this.getNodeParameterValue(ComputeNodeType.SectionParametree, "Pr"); // précision let nDigits = -Math.log10(prec); - let Y = prms.Y.v; // tirant d'eau original (doit être fourni à acSection.Calc() sous peine d'être modifié par les appels successifs car c'est en même temps un paramètre et une variable temporaire) + let Y = prms.map.Y.v; // tirant d'eau original (doit être fourni à acSection.Calc() sous peine d'être modifié par les appels successifs car c'est en même temps un paramètre et une variable temporaire) // charge spécifique let Hs = sect.Calc("Hs", Y); @@ -447,21 +460,106 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer { this._showResultsSection = true; } + private addRemousResult(x: string, f: number, t: number, nDigits: number) { + let flu = f == undefined ? "" : f.toFixed(nDigits); + let tor = t == undefined ? "" : f.toFixed(nDigits); + this.remousResultsComponent.addResult(x, flu, tor); + } + + private doComputeRemous() { + this.remousResultsComponent.reset(); + + let ssf: SelectField = <SelectField>this._formulaire.getFormulaireElementById("select_section"); + let typeSect: ComputeNodeType = FormulaireDefinition.getComputeNodeTypeFromSection(ssf.getValue(), CalculatorType.CourbeRemous); + var np: [acSection, ParamsEquation] = this.formulaireService.getSectionNubAndParameters(CalculatorType.CourbeRemous, typeSect, false); + + let sect: acSection = np[0]; + let prmSect: ParamsEquation = np[1]; + + let prec: number = this.getNodeParameterValue(ComputeNodeType.CourbeRemous, "Pr"); // précision + let nDigits: number = -Math.log10(prec); + + let Yamont: number = this.getNodeParameterValue(ComputeNodeType.CourbeRemous, "Yamont"); // tirant amont + let Yaval: number = this.getNodeParameterValue(ComputeNodeType.CourbeRemous, "Yaval"); // tirant aval + let Dx: number = this.getNodeParameterValue(ComputeNodeType.CourbeRemous, "Dx"); // pas de discrétisation + let Long: number = this.getNodeParameterValue(ComputeNodeType.CourbeRemous, "Long"); // longueur du bief + let If: number = this.getNodeParameterValue(ComputeNodeType.CourbeRemous, "If"); // pente du fond + let YB: number = this.getNodeParameterValue(ComputeNodeType.CourbeRemous, "YB"); // hauteur de berge + let Yn: number = sect.Calc("Yn"); // hauteur normale + let Yc: number = sect.Calc("Yc"); // hauteur critique + + // méthode de résolution + + let msf: SelectField = <SelectField>this._formulaire.getFormulaireElementById("select_resolution"); + let smeth: string = msf.getValue(); + let methRes: MethodeResolution; + if (smeth == "select_resolution_trap") + methRes = MethodeResolution.Trapezes; + else if (smeth == "select_resolution_rk4") + methRes = MethodeResolution.RungeKutta4; + else if (smeth == "select_resolution_euler") + methRes = MethodeResolution.EulerExplicite; + else + throw "GenericCalculatorComponent.doComputeRemous() : type de méthode de résolution '" + smeth + "' inconnu"; + + // calcul + + let prmCR: CourbeRemousParams = new CourbeRemousParams(sect, Yamont, Yaval, Long, Dx, methRes); + let log: cLog = new cLog(); + let cr = new CourbeRemous(prmCR, log); + let res = cr.calculRemous(undefined); + + // affichage du graphe + + this.remousResultsComponent.setPenteFond(If); + this.remousResultsComponent.setLongBief(Long); + this.remousResultsComponent.setHauteurBerge(YB); + this.remousResultsComponent.setHauteurNormale(Yn); + this.remousResultsComponent.setHauteurCritique(Yc); + + // affichage du journal + + for (let l of log.messages) + this.remousResultsComponent.addLogEntry(l.toString()); + + // affichage des resultats numériques + + let kFlu = Object.keys(res.flu); + let kTor = Object.keys(res.tor); + for (let i = 0; i < res.trX.length; i++) { + let x: string = res.trX[i]; + // let f = i < kFlu.length ? res.flu[kFlu[i]] : undefined; + // let t = i < kTor.length ? res.tor[kTor[i]] : undefined; + let f = res.flu[x]; + let t = res.tor[x]; + this.addRemousResult(x, f, t, nDigits); + } + + this.remousResultsComponent.generateGraph(); + this._showResultsRemous = true; + } + private doCompute() { this._showResultsFixVar = false; this._showResultsSection = false; + this._showResultsRemous = false; if (this._calculatorType == CalculatorType.SectionParametree) { this.doComputeSection(); return; } - let np: [Nub, IParamsEquation]; + if (this._calculatorType == CalculatorType.CourbeRemous) { + this.doComputeRemous(); + return; + } + + let np: [Nub, ParamsEquation]; let nub: Nub; - let prms: IParamsEquation; + let prms: ParamsEquation; let rg: boolean = this._calculatorType == CalculatorType.RegimeUniforme; if (rg) { - let snp: [acSection, IParamsEquation] = this.formulaireService.getSectionNubAndParameters(CalculatorType.RegimeUniforme, this._nodeType); + let snp: [acSection, ParamsEquation] = this.formulaireService.getSectionNubAndParameters(CalculatorType.RegimeUniforme, this._nodeType); nub = new RegimeUniforme(snp[0]); prms = snp[1]; } @@ -518,6 +616,10 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer { return this._showResultsSection ? "block" : "none"; } + private getRemousResultsStyleDisplay() { + return this._showResultsRemous ? "block" : "none"; + } + private getFieldsetStyleDisplay(id: string) { let isDisplayed: boolean = this._formulaire.isDisplayed(id); return isDisplayed ? "block" : "none"; @@ -579,6 +681,30 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer { this._nodeType = ComputeNodeType.RegimeUniformePuissance; break; } + break; + + case CalculatorType.CourbeRemous: + switch (type) { + case "trapez": + this._nodeType = ComputeNodeType.CourbeRemousTrapeze; + break; + + case "rect": + this._nodeType = ComputeNodeType.CourbeRemousRectangle; + break; + + case "circ": + this._nodeType = ComputeNodeType.CourbeRemousCercle; + break; + + case "puiss": + this._nodeType = ComputeNodeType.CourbeRemousPuissance; + break; + } + break; + + default: + throw "GenericCalculatorComponent.updateSectionType() : section " + val + " / type de calculette " + CalculatorType[this._calculatorType] + " non pris en charge" } } } diff --git a/src/app/calculators/generic/formulaire.ts b/src/app/calculators/generic/formulaire.ts index a67ceab36..c3004c012 100644 --- a/src/app/calculators/generic/formulaire.ts +++ b/src/app/calculators/generic/formulaire.ts @@ -6,7 +6,7 @@ import { StringMap } from '../../stringmap'; import { logObject } from '../../util'; export enum CalculatorType { - ConduiteDistributrice, LechaptCalmon, SectionParametree, RegimeUniforme + ConduiteDistributrice, LechaptCalmon, SectionParametree, RegimeUniforme, CourbeRemous } export class FormulaireDefinition { @@ -344,6 +344,7 @@ export class FormulaireDefinition { } } + // logObject(this._fieldSets, "fieldsets"); // logObject(this._dependencies, "dependences"); } @@ -405,17 +406,33 @@ export class FormulaireDefinition { console.log(d.toString()); } - public static getSectionType(s: string): ComputeNodeType { - if (s === "select_section_trapez") - return ComputeNodeType.SectionTrapeze; - if (s === "select_section_rect") - return ComputeNodeType.SectionRectangle; - if (s === "select_section_circ") - return ComputeNodeType.SectionCercle; - if (s === "select_section_puiss") - return ComputeNodeType.SectionPuissance; + public static getComputeNodeTypeFromSection(sect: string, calc: CalculatorType): ComputeNodeType { + switch (calc) { + case CalculatorType.SectionParametree: + if (sect === "select_section_trapez") + return ComputeNodeType.SectionTrapeze; + if (sect === "select_section_rect") + return ComputeNodeType.SectionRectangle; + if (sect === "select_section_circ") + return ComputeNodeType.SectionCercle; + if (sect === "select_section_puiss") + return ComputeNodeType.SectionPuissance; + throw "Formulaire.getSectionType() : type de section '" + sect + "' inconnu pour la calculette " + CalculatorType[calc]; + + case CalculatorType.CourbeRemous: + if (sect === "select_section_trapez") + return ComputeNodeType.CourbeRemousTrapeze; + if (sect === "select_section_rect") + return ComputeNodeType.CourbeRemousRectangle; + if (sect === "select_section_circ") + return ComputeNodeType.CourbeRemousCercle; + if (sect === "select_section_puiss") + return ComputeNodeType.CourbeRemousPuissance; + throw "Formulaire.getSectionType() : type de section '" + sect + "' inconnu pour la calculette " + CalculatorType[calc]; - throw "Formulaire.getSectionType() : type de section '" + s + "' inconnu" + default: + throw "Formulaire.getSectionType() : type de calculette " + CalculatorType[calc] + " non pris en charge"; + } } public isDisplayed(id: string) { diff --git a/src/app/calculators/remous/remous.component.html b/src/app/calculators/remous/remous.component.html new file mode 100644 index 000000000..add35e051 --- /dev/null +++ b/src/app/calculators/remous/remous.component.html @@ -0,0 +1,2 @@ +<h1>Courbe de remous</h1> +<hydrocalc type="CourbeRemous"></hydrocalc> \ No newline at end of file diff --git a/src/app/calculators/remous/remous.component.ts b/src/app/calculators/remous/remous.component.ts new file mode 100644 index 000000000..eed0dc6d8 --- /dev/null +++ b/src/app/calculators/remous/remous.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'courbe-remous', + templateUrl: "./remous.component.html" +}) +export class CourbeRemousComponent { +} diff --git a/src/app/calculators/remous/remous.config.json b/src/app/calculators/remous/remous.config.json index 3a14d2db1..0376b0b44 100644 --- a/src/app/calculators/remous/remous.config.json +++ b/src/app/calculators/remous/remous.config.json @@ -16,7 +16,7 @@ "id": "select_section_circ" }, { - "id": "select_section_para" + "id": "select_section_puiss" } ] } @@ -24,11 +24,12 @@ }, { "id": "fs_section_trapez", + "nodeType": "CourbeRemousTrapeze", "option": "fix", "dep_exist": [ { "refid": "select_section", - "refvalue": "select_section_para" + "refvalue": "select_section_trapez" } ], "fields": [ @@ -48,6 +49,7 @@ }, { "id": "fs_section_rect", + "nodeType": "CourbeRemousRectangle", "option": "fix", "dep_exist": [ { @@ -58,7 +60,7 @@ "fields": [ { "type": "input", - "id": "LargeurFond", + "id": "LargeurBerge", "unit": "m", "value": 2.5 } @@ -66,6 +68,7 @@ }, { "id": "fs_section_circ", + "nodeType": "CourbeRemousCercle", "option": "fix", "dep_exist": [ { @@ -83,12 +86,13 @@ ] }, { - "id": "fs_section_para", + "id": "fs_section_puiss", + "nodeType": "CourbeRemousPuissance", "option": "fix", "dep_exist": [ { "refid": "select_section", - "refvalue": "select_section_para" + "refvalue": "select_section_puiss" } ], "fields": [ @@ -100,7 +104,7 @@ }, { "type": "input", - "id": "B", + "id": "LargeurBerge", "unit": "m", "value": 2 } @@ -112,10 +116,16 @@ "fields": [ { "type": "input", - "id": "K", + "id": "Ks", "unit": "m1/3s-1", "value": 40 }, + { + "type": "input", + "id": "Long", + "unit": "m", + "value": 100 + }, { "type": "input", "id": "If", @@ -124,7 +134,7 @@ }, { "type": "input", - "id": "H", + "id": "YB", "unit": "m", "value": 1 } @@ -136,7 +146,31 @@ "fields": [ { "type": "input", - "id": "Pd", + "id": "Q", + "unit": "m³/s", + "value": 2 + }, + { + "type": "input", + "id": "Yaval", + "unit": "m", + "value": 0.4 + }, + { + "type": "input", + "id": "Yamont", + "unit": "m", + "value": 0.15 + } + ] + }, + { + "id": "fs_param_calc", + "option": "fix", + "fields": [ + { + "type": "input", + "id": "Dx", "unit": "m", "value": 5 }, @@ -157,7 +191,7 @@ "id": "select_resolution_rk4" }, { - "id": "select_resolution_trap" + "id": "select_resolution_euler" } ] } @@ -174,55 +208,55 @@ "id": "select_target_none" }, { - "id": "select_target_hs" + "id": "select_target_Hs" }, { - "id": "select_target_hsc" + "id": "select_target_Hsc" }, { - "id": "select_target_b" + "id": "select_target_B" }, { - "id": "select_target_p" + "id": "select_target_P" }, { - "id": "select_target_s" + "id": "select_target_S" }, { - "id": "select_target_r" + "id": "select_target_R" }, { - "id": "select_target_v" + "id": "select_target_V" }, { - "id": "select_target_fr" + "id": "select_target_Fr" }, { - "id": "select_target_yc" + "id": "select_target_Yc" }, { - "id": "select_target_yn" + "id": "select_target_Yn" }, { - "id": "select_target_yf" + "id": "select_target_Yf" }, { - "id": "select_target_yt" + "id": "select_target_Yt" }, { - "id": "select_target_yco" + "id": "select_target_Yco" }, { - "id": "select_target_j" + "id": "select_target_J" }, { - "id": "select_target_i_j" + "id": "select_target_I-J" }, { - "id": "select_target_imp" + "id": "select_target_Imp" }, { - "id": "select_target_tau0" + "id": "select_target_Tau0" } ] } @@ -230,6 +264,6 @@ }, { "id": "options", - "idCal": "J" + "nodeType": "CourbeRemous" } ] \ No newline at end of file diff --git a/src/app/calculators/remous/remous.fr.json b/src/app/calculators/remous/remous.fr.json index fc1192576..ad73abf68 100644 --- a/src/app/calculators/remous/remous.fr.json +++ b/src/app/calculators/remous/remous.fr.json @@ -4,26 +4,27 @@ "select_section_trapez": "Trapézoïdale", "select_section_rect": "Rectangulaire", "select_section_circ": "Circulaire", - "select_section_para": "Parabolique", + "select_section_puiss": "Parabolique", "fs_section_trapez": "Définition de la section trapézoïdale", "LargeurFond": "Largeur au fond", "Fruit": "Fruit des berges", "fs_section_rect": "Définition de la section rectangulaire", "fs_section_circ": "Définition de la section circulaire", "D": "Diamètre", - "fs_section_para": "Définition de la section parabolique", + "fs_section_puiss": "Définition de la section puissance", "k": "Coefficient", - "B": "Largeur de berge", + "LargeurBerge": "Largeur de berge", "fs_bief": "Caractéristiques du bief", - "K": "Coefficient de Strickler", + "Ks": "Coefficient de Strickler", + "Long": "Longueur du bief", "If": "Pente du fond", - "H": "Hauteur de berge", + "YB": "Hauteur de berge", "fs_condlim": "Conditions aux limites", - "Q_a": "Débit amont", - "Y_a": "Tirant d'eau imposé à l'aval", - "Y_A": "Tirant d'eau imposé à l'amont", + "Q": "Débit amont", + "Yaval": "Tirant d'eau imposé à l'aval", + "Yamont": "Tirant d'eau imposé à l'amont", "fs_param_calc": "Paramètres de calcul", - "Pd": "Pas de discrétisation", + "Dx": "Pas de discrétisation", "Pr": "Précision de calcul et d'affichage des cotes", "select_resolution": "Méthode de résolution", "select_resolution_trap": "Intégration par trapèzes", diff --git a/src/app/components/remous-results/remous-results.component.html b/src/app/components/remous-results/remous-results.component.html new file mode 100644 index 000000000..2f957c349 --- /dev/null +++ b/src/app/components/remous-results/remous-results.component.html @@ -0,0 +1,42 @@ +<div style="width:30%; height: 400px"> + <chart [type]="graph_type" [data]="graph_data" [options]="graph_options"></chart> + <!-- + <div> + <chart style="float: left" [type]="graph_type" [data]="graph_data" [options]="graph_options"></chart> +--> +</div> +<br/> +<div style="text-align:center;"> + <!-- journal --> + <table style="float: left"> + <thead> + <tr> + <th>Journal de calcul</th> + </tr> + </thead> + <tr *ngFor="let r of _logEntries"> + <td>{{r}}</td> + </tr> + </table> + <br/> + <!-- résultats numériques --> + <table style="float: left"> + <thead> + <tr> + <th></th> + <th>Ligne d'eau fluviale</th> + <th>Ligne d'eau torrentielle</th> + </tr> + <tr> + <th>Abscisse</th> + <th>Tirant d'eau (m)</th> + <th>Tirant d'eau (m)</th> + </tr> + </thead> + <tr *ngFor="let r of _results; let i=index" [class]="getResultClass(i)"> + <td>{{r.abs}}</td> + <td>{{r.flu}}</td> + <td>{{r.tor}}</td> + </tr> + </table> +</div> \ No newline at end of file diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts new file mode 100644 index 000000000..584950c68 --- /dev/null +++ b/src/app/components/remous-results/remous-results.component.ts @@ -0,0 +1,221 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'remous-results', + templateUrl: './remous-results.component.html', + styles: [` + .result_label { + text-align: right; + padding-top:10px; + padding-bottom:10px; + padding-right:10px; + } + .result_value { + text-align: center; + padding-left:30px; + padding-right:30px; + } + .result_id_0 { + background-color: #f0f0f0; + } + .result_id_2 { + font-weight: bold; + } + ` + ] +}) +export class RemousResultsComponent { + // /** + // * tirant imposé à l'amont + // */ + // private _Yamont: number; + + // /** + // * tirant imposé à l'aval + // */ + // private _Yaval: number; + + /** + * pente du fond + */ + private _penteFond: number; + + /** + * hauteur de berge + */ + private _hautBerge: number; + + /** + * hauteur normale + */ + private _hautNormale: number; + + /** + * hauteur critique + */ + private _hautCritique: number; + + /** + * longueur du bief + */ + private _longBief: number; + + /** + * journal + */ + private _logEntries: Object[] = []; + + /** + * résultats numériques + */ + private _results: Object[] = []; + + /** + * tableau de valeurs du graphe des tirants + */ + private _fluvialGraph: any = {}; + private _torrentGraph: any = {}; + + /* + * config du graphe + */ + private graph_type = 'line'; + private graph_data = {}; + private graph_options = { + responsive: true, + maintainAspectRatio: true, + animation: { + duration: 0 + }, + legend: { + display: false + }, + title: { + display: false, + text: "" + } + }; + + public reset() { + this._results = []; + this._logEntries = []; + this._fluvialGraph = {}; + this._torrentGraph = {}; + } + + /** + * transforme une cote en tenant compte du fond + * @param x abscisse où se trouve la cote à transformer + * @param y cote à transformer + */ + private mapY(x: number, y: number) { + let d: number; + if (this._penteFond >= 0) { + d = this._penteFond * (this._longBief - x); + } else { + d = -this._penteFond * x; + } + return y + d; + } + + private drawLine(y0: number, ymax: number, color: string, fillColor: string = undefined) { + let ys = []; + ys.push({ x: 0, y: this.mapY(0, y0) }); + ys.push({ x: this._longBief, y: this.mapY(this._longBief, ymax) }); + // return { data: yFond, fill: true, tension: 0, borderColor: "#753F00", backgroundColor: "#753F00", pointRadius: 0 }; + return { data: ys, fill: fillColor != undefined, tension: 0, borderColor: color, backgroundColor: fillColor, pointRadius: 0 }; + } + + public generateGraph() { + // http://www.chartjs.org/docs/latest/charts/line.html + + let ds: any = []; + + // abscisses + + let labs = []; + for (let r of this._results) + labs.push(+r["abs"]); + + // ligne de fond + ds.push(this.drawLine(0, 0, "#753F00", "#753F00")); + + // ligne de berge + ds.push(this.drawLine(this._hautBerge, this._hautBerge, "#C58F50")); + + // hauteur normale + ds.push(this.drawLine(this._hautNormale, this._hautNormale, "#A4C537")); + + // hauteur critique + ds.push(this.drawLine(this._hautCritique, this._hautCritique, "#FF0000")); + + // lignes d'eau torrentielle et fluviale + + let dataFlu = []; + let dataTor = []; + for (let r of this._results) { + let x: number = +r["abs"]; + let yFlu: string = r["flu"]; + let yTor: string = r["tor"]; + if (yFlu != undefined && yFlu != "") + dataFlu.push(this.mapY(x, +yFlu)); + if (yTor != undefined && yTor != "") + dataTor.push(this.mapY(x, +yTor)); + } + ds.push({ data: dataTor, tension: 0, borderColor: "#77A3CD", pointRadius: 5, backgroundColor: "#D1D0D4" }); + ds.push({ data: dataFlu, tension: 0, borderColor: "#0093BD", pointRadius: 5, backgroundColor: "#D1D0D4" }); + + this.graph_data = { + labels: labs, + datasets: ds + }; + } + + public addResult(x: string, f: string, t: string) { + this._results.push({ "abs": x, "flu": f, "tor": t }); + } + + public addLogEntry(s: string) { + this._logEntries.push(s); + } + + // public setYamont(v: number) { + // this._Yamont = v; + // } + + // public setYaval(v: number) { + // this._Yaval = v; + // } + + public setPenteFond(v: number) { + this._penteFond = v; + } + + public setHauteurBerge(v: number) { + this._hautBerge = v; + } + + public setHauteurNormale(v: number) { + this._hautNormale = v; + } + + public setHauteurCritique(v: number) { + this._hautCritique = v; + } + + public setLongBief(v: number) { + this._longBief = v; + } + + public addXYFluvial(x: number, y: number) { + this._fluvialGraph.push({ x: x, y: y }); + } + + public addXYTorrent(x: number, y: number) { + this._torrentGraph.push({ x: x, y: y }); + } + + private getResultClass(i: number) { + return "result_id_" + String(i & 1); + } +} diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts index f8b3d8017..373d07227 100644 --- a/src/app/services/formulaire/formulaire.service.ts +++ b/src/app/services/formulaire/formulaire.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Response } from '@angular/http'; -import { ComputeNodeType, IParamsEquation, acSection, Nub, ConduiteDistrib, ConduiteDistribParams } from "jalhyd"; +import { ComputeNodeType, ParamsEquation, acSection, Nub, ConduiteDistrib, ConduiteDistribParams } from "jalhyd"; import { LechaptCalmon, LechaptCalmonParams, ParamsSectionTrapez, cSnTrapez } from "jalhyd"; import { ParamsSectionRectang, cSnRectang, ParamsSectionCirc, cSnCirc, ParamsSectionPuiss, cSnPuiss } from "jalhyd"; @@ -90,7 +90,7 @@ export class FormulaireService { } } - public getNubAndParameters(ct: CalculatorType): [Nub, IParamsEquation] { + public getNubAndParameters(ct: CalculatorType): [Nub, ParamsEquation] { let f = this.getFormulaire(ct); switch (ct) { case CalculatorType.ConduiteDistributrice: @@ -124,7 +124,7 @@ export class FormulaireService { } } - public getSectionNubAndParameters(ct: CalculatorType, nt: ComputeNodeType): [acSection, IParamsEquation] { + public getSectionNubAndParameters(ct: CalculatorType, nt: ComputeNodeType, getY: boolean = true): [acSection, ParamsEquation] { let f: FormulaireDefinition = this.getFormulaire(ct); // bief @@ -135,7 +135,10 @@ export class FormulaireService { // caractéristiques hydro let Q: number = f.getParameterValue("Q"); // débit Q - let Y: number = f.getParameterValue("Y"); // tirant d'eau + if (getY) + var Y: number = f.getParameterValue("Y"); // tirant d'eau + else + Y = undefined; let Prec = f.getParameterValue("Pr"); // précision calcul/affichage @@ -147,6 +150,7 @@ export class FormulaireService { switch (nt) { case ComputeNodeType.SectionTrapeze: case ComputeNodeType.RegimeUniformeTrapeze: + case ComputeNodeType.CourbeRemousTrapeze: { let LargeurFond = f.getNodeParameterValue(nt, "LargeurFond"); // Largeur au fond let Fruit = f.getNodeParameterValue(nt, "Fruit"); // Fruit des berges @@ -157,6 +161,7 @@ export class FormulaireService { case ComputeNodeType.SectionRectangle: case ComputeNodeType.RegimeUniformeRectangle: + case ComputeNodeType.CourbeRemousRectangle: { let LargeurFond = f.getNodeParameterValue(nt, "LargeurBerge"); // Largeur au fond let prms = new ParamsSectionRectang(Y, LargeurFond, Ks, Q, If, Prec, YB); @@ -166,6 +171,7 @@ export class FormulaireService { case ComputeNodeType.SectionCercle: case ComputeNodeType.RegimeUniformeCercle: + case ComputeNodeType.CourbeRemousCercle: { let D = f.getNodeParameterValue(nt, "D"); // Largeur au fond let prms = new ParamsSectionCirc(D, Y, Ks, Q, If, Prec, YB); @@ -175,6 +181,7 @@ export class FormulaireService { case ComputeNodeType.SectionPuissance: case ComputeNodeType.RegimeUniformePuissance: + case ComputeNodeType.CourbeRemousPuissance: { let k = f.getNodeParameterValue(nt, "k"); // coefficient let LargeurBerge = f.getNodeParameterValue(nt, "LargeurBerge"); // Largeur au niveau des berges @@ -205,6 +212,9 @@ export class FormulaireService { case CalculatorType.RegimeUniforme: return "app/calculators/regime-uniforme/regime-uniforme."; + case CalculatorType.CourbeRemous: + return "app/calculators/remous/remous."; + default: throw "FormulaireService.getConfigPathPrefix() : valeur de CalculatorType " + ct + " non implémentée" } diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts index fce555e49..d952660c1 100644 --- a/src/app/services/param/param.service.ts +++ b/src/app/services/param/param.service.ts @@ -1,4 +1,7 @@ -import { ParamDomain, ComputeNodeType, ComputeNodeParameters, IParamsEquation, ParamsSectionRectang, ParamDefinition, ParamDomainValue, ParamCalculability } from 'jalhyd'; +import { + ParamDomain, ComputeNodeType, ComputeNodeParameters, ParamsEquation, ParamsSectionRectang, ParamDefinition, + ParamDomainValue, ParamCalculability +} from 'jalhyd'; import { NgParameter } from "../../calculators/generic/ngparam"; import { logObject } from '../../util'; @@ -20,10 +23,14 @@ export class ParamService { this.addParameters(ComputeNodeType.RegimeUniformeRectangle); this.addParameters(ComputeNodeType.RegimeUniformeCercle); this.addParameters(ComputeNodeType.RegimeUniformePuissance); + this.addParameters(ComputeNodeType.CourbeRemousCercle); + this.addParameters(ComputeNodeType.CourbeRemousPuissance); + this.addParameters(ComputeNodeType.CourbeRemousRectangle); + this.addParameters(ComputeNodeType.CourbeRemousTrapeze); // précision de calcul - let d = new ParamDomain(ParamDomainValue.POS, 1e-10, 100); + let d = new ParamDomain(ParamDomainValue.INTERVAL, 1e-10, 100); let p = new ParamDefinition(ComputeNodeType.LechaptCalmon, 'Pr', d); p.calculability = ParamCalculability.FREE; this.addParameter(p); @@ -40,6 +47,10 @@ export class ParamService { p.calculability = ParamCalculability.FREE; this.addParameter(p); + p = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Pr', d); + p.calculability = ParamCalculability.FREE; + this.addParameter(p); + // logObject(this._params); } @@ -58,28 +69,10 @@ export class ParamService { } private addParameters(nodeType: ComputeNodeType) { - let cdp: IParamsEquation = ComputeNodeParameters.getInstance().getComputeNodeParameters(nodeType); - for (let pi in cdp) { - /* - Langage de m.... ! - Ici p n'a pas de type déclaré (bien que le type (ParamDefinition) soit connu à l'exécution, - le debugger le montre), et on peut quand même l'ajouter à this._params bien que son type soit - différent (NgParam[]) ! - - let p = cdp[pi]; - if (!this.hasParameter(p.symbol)) - this._params.push(p); - */ - /* - ce code ne marche pas mais compile sans pb !! - - let p: ParamDefinition = cdp[pi]; // on peut avoir n'importe quoi dans p malgré son typage - if (!this.hasParameter(p.symbol)) - this._params.push(new NgParameter(p)); - */ - let p = cdp[pi]; // on peut écrire let p:ParamDefinition = cdp[pi]; ça ne dérange pas le compilateur - if (p instanceof ParamDefinition) // obligatoire car malgré le typage de p, p peut être = constructor ou n'importe quel autre membre - this.addParameter(p); + let cdp: ParamsEquation = ComputeNodeParameters.getInstance().getComputeNodeParameters(nodeType); + for (let pi in cdp.map) { + let p: ParamDefinition = cdp.map[pi]; + this.addParameter(p); } } @@ -101,6 +94,12 @@ export class ParamService { case ComputeNodeType.RegimeUniformeTrapeze: return this.getParameter(ComputeNodeType.RegimeUniforme, symbol); + case ComputeNodeType.CourbeRemousCercle: + case ComputeNodeType.CourbeRemousPuissance: + case ComputeNodeType.CourbeRemousRectangle: + case ComputeNodeType.CourbeRemousTrapeze: + return this.getParameter(ComputeNodeType.CourbeRemous, symbol); + default: return undefined; } -- GitLab