Commit a7809c46 authored by Grand Francois's avatar Grand Francois
Browse files
Showing with 190 additions and 8 deletions
+190 -8
......@@ -4,8 +4,10 @@
* Résultat de calcul comprenant la valeur du résultat et des calculs annexes (flag, calculs intermédiaires...)
*/
export class Result {
public varCalc: number;
public extraVar: {}; /** @todo Comment définit-on un objet dont on ne connait pas le nom des clés mais dont on connait le type ? */
/** Valeur calculée */
public vCalc: number;
/** Variables intermédiaires, flags d'erreur */
public extraVar: {};
}
/**
......@@ -27,17 +29,38 @@ export interface IParametres {
}
/**
* Gestion des messages de debogage dans la console
* @note Etendre cette classe pour toutes les classes à debugguer
* Dans le constructeur, utiliser super(true) pour debugger la classe, super(false) sinon.
*/
export abstract class Debug {
/**
* @param DBG Flag de débuggage
*/
constructor(private DBG: boolean) {}
/**
* Affiche un message dans la console si le flag this.DBG est à true
* @param s Message à afficher dans la console
*/
protected debug(s: any) {
if(this.DBG) console.log(s);
}
}
/**
* Classe abstraite de Noeud de calcul : classe de base pour tous les calculs
*/
export abstract class Nub {
export abstract class Nub extends Debug {
/// Nom des variables calculées par la méthode Equation
private _varsEq: string[];
public v: IParametres;
constructor(parametres: IParametres) {
super(false);
this.v = parametres;
}
......
import { Debug, Nub, Result } from "base";
export class Dichotomie extends Debug {
/** Pas de parcours de l'intervalle pour initialisation dichotomie */
readonly IDEFINT = 100;
/** Nombre d'itérations maximum de la dichotomie */
readonly IDICMAX = 100;
/**
* Construction de la classe.
* @param nub Noeud de calcul contenant la méthode de calcul Equation
* @param sVarCalc Nom de la variable à calculer
*/
constructor(private nub: Nub, private sVarCalc: string) {
super(false);
}
/** Valeur inconnue à rechercher */
get vX() {
return this.nub.v[this.sVarCalc];
}
/** Valeur inconnue à rechercher */
set vX(vCalc) {
this.nub.v[this.sVarCalc] = vCalc;
}
/**
* Méthode simulant l'opérateur booléen xor
* @see http://www.howtocreate.co.uk/xor.html
*/
XOR(a, b) {
return (a || b) && !(a && b);
}
/**
* Calcul de l'équation analytique.
* @note Wrapper vers this.nub.Equation pour simplifier le code.
* On utilise la première variable du tableau des variables pourvant être calculées analytiquement
* Il faudra s'assurer que cette première variable correspond à la méthode de calcul la plus rapide
*/
private Calcul() {
/**
* @note
*/
return this.nub.Equation(this.nub.sVarsEq[0]);
}
/**
* Calcul à l'ouvrage
* @param sVarCalc Nom de la variable à calculer
* @param rTarget Valeur cible
* @param rtol Précision attendue du résultat
* @param rInit Valeur initiale de l'inconnue à rechercher
*/
Dichotomie(rTarget: number, rTol: number, rInit: number): Result {
let res: Result
let XminInit = 1E-8;
this.vX = XminInit;
let v1: number = this.Calcul().vCalc;
let XmaxInit: number = Math.max(1, rInit) * 100;
this.vX = XmaxInit;
let v2 = this.Calcul().vCalc;
let DX = (XmaxInit - XminInit) / this.IDEFINT;
let nIterMax = Math.floor(Math.max(XmaxInit - rInit, rInit - XminInit) / DX + 1);
let Xmin = rInit;
let Xmax = rInit;
let X1 = rInit;
let X2 = rInit;
this.debug("rInit: " + rInit);
this.vX = rInit;
let v = this.Calcul().vCalc;
v1 = v;
v2 = v;
this.debug(nIterMax);
//** @todo : Chercher en dehors de l'intervalle en le décalant à droite ou à gauche en fonction de la valeur */
let nIter: number;
for (nIter = 1; nIter < nIterMax; nIter++) {
//Ouverture de l'intervalle des deux côtés : à droite puis à gauche
Xmax = Xmax + DX;
if (this.XOR(Xmax > XmaxInit, DX <= 0)) Xmax = XmaxInit;
this.vX = Xmax;
v = this.Calcul().vCalc;
if (this.XOR(v1 < v2, v <= v2)) {
v2 = v;
X2 = Xmax;
}
if (this.XOR(v1 < v2, v >= v1)) {
v1 = v;
X1 = Xmax;
}
Xmin = Xmin - DX;
if (this.XOR(Xmin < XminInit, DX <= 0)) {
Xmin = XminInit;
}
this.vX = Xmin;
v = this.Calcul().vCalc;
if (this.XOR(v1 < v2, v <= v2)) {
v2 = v;
X2 = Xmin;
}
if (this.XOR(v1 < v2, v >= v1)) {
v1 = v;
X1 = Xmin;
}
if (this.XOR(rTarget > v1, rTarget >= v2)) { break; }
}
if (nIter >= this.IDEFINT) {
this.debug("in if");
// Pas d'intervalle trouvé avec au moins une solution
if (v2 < rTarget && v1 < rTarget) {
// Cote de l'eau trop basse pour passer le débit il faut ouvrir un autre ouvrage
this.vX = XmaxInit;
}
else {
// Cote de l'eau trop grande il faut fermer l'ouvrage
this.vX = XminInit;
}
res = this.Calcul();
res.extraVar["flag"] = -1; // la valeur cible n'est pas dans l'intervalle de recherche
return res;
}
else {
// Dichotomie
this.debug("in dicho");
let X = rInit;
for (nIter = 1; nIter <= this.IDICMAX; nIter++) {
this.vX = X;
v = this.Calcul().vCalc;
if (rTarget != 0 && Math.abs(X1 - X2) <= rTol) { break; }
if (this.XOR(rTarget < v, v1 <= v2)) {
// rTarget < IQ et v(X1) > v(X2) ou pareil en inversant les inégalités
X1 = this.vX;
}
else {
// rTarget < IQ et v(X1) < v(X2) ou pareil en inversant les inégalités
X2 = this.vX;
}
X = (X2 + X1) * 0.5;
this.debug((X));
}
if (nIter == this.IDICMAX) {
res = this.Calcul();
res.extraVar["flag"] = -1; // la valeur cible n'est pas dans l'intervalle de recherche
return res;
}
}
res.vCalc = v
return ;
}
}
\ No newline at end of file
......@@ -36,16 +36,16 @@ class LechaptCalmon extends Nub {
switch (sVarCalc) {
case "Q":
res.varCalc = Math.pow((((this.v.J * Math.pow(this.v.D, this.v.N)) / this.v.L) * (1000 / this.v.Lg)), 1 / this.v.M);
res.vCalc = Math.pow((((this.v.J * Math.pow(this.v.D, this.v.N)) / this.v.L) * (1000 / this.v.Lg)), 1 / this.v.M);
break;
case "D":
res.varCalc = Math.pow((((this.v.L * Math.pow(this.v.Q, this.v.M)) / this.v.J) * (this.v.Lg / 1000)), 1 / this.v.N);
break;
res.vCalc = Math.pow((((this.v.L * Math.pow(this.v.Q, this.v.M)) / this.v.J) * (this.v.Lg / 1000)), 1 / this.v.N);
break
case "J":
res.varCalc = ((this.v.L * Math.pow(this.v.Q, this.v.M)) / Math.pow(this.v.D, this.v.N)) * (this.v.Lg / 1000);
res.vCalc = ((this.v.L * Math.pow(this.v.Q, this.v.M)) / Math.pow(this.v.D, this.v.N)) * (this.v.Lg / 1000);
break;
case "Lg":
res.varCalc = ((this.v.J * Math.pow(this.v.D, this.v.N)) / (this.v.L * Math.pow(this.v.Q, this.v.M))) * 1000;
res.vCalc = ((this.v.J * Math.pow(this.v.D, this.v.N)) / (this.v.L * Math.pow(this.v.Q, this.v.M))) * 1000;
}
return res;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment