Commit f875f421 authored by Grand Francois's avatar Grand Francois
Browse files

section paramétrée : ajout des messages dans le journal pour la non...

section paramétrée : ajout des messages dans le journal pour la non convergence des calculs par la méthode de Newton
Showing with 200 additions and 23 deletions
+200 -23
/// <reference path="../node_modules/@types/jasmine/index.d.ts" />
import { Result } from "../src/base";
import { precDist, equalEpsilon } from "./nubtest";
import { ParamsSectionRectang, cSnRectang } from "../src/section/section_rectang";
import { cLog } from "../src/util/log";
import { MessageCode } from "../src/util/message";
let paramSection: ParamsSectionRectang;
let sect: cSnRectang;
function check(val1: number, val2: number) {
expect(equalEpsilon(val1, val2)).toBeTruthy("expected " + val2 + ", got " + val1);
}
describe('Section paramétrée rectangulaire : ', () => {
beforeEach(() => {
paramSection = new ParamsSectionRectang(0.8, // tirant d'eau
2.5, // largeur de fond
40, // Ks=Strickler
10, // Q=Débit
0.001, // If=pente du fond
1e-10, // précision
1 // YB= hauteur de berge
);
sect = new cSnRectang(new cLog(), paramSection);
sect.newtonMaxIter = 5;
});
describe('non convergence de la méthode de Newton :', () => {
it('hauteur critique', () => {
sect.Calc("Yc");
expect(sect.log.messages.length).toEqual(1);
expect(sect.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
});
it('hauteur normale', () => {
sect.Calc("Yn");
expect(sect.log.messages.length).toEqual(2);
expect(sect.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
expect(sect.log.messages[1].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE);
});
it('hauteur normale, pente négative', () => {
sect.prms.If.v = -0.001;
sect.Calc("Yn");
expect(sect.log.messages.length).toEqual(1);
expect(sect.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF);
});
it('hauteur fluviale, Y < Yc', () => {
sect.Calc("Yf");
expect(sect.log.messages.length).toEqual(3);
expect(sect.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
expect(sect.log.messages[1].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
expect(sect.log.messages[2].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HFLU);
});
it('hauteur fluviale, Y > Yc', () => {
sect.prms.Y.v = 2;
sect.Calc("Yf");
expect(sect.log.messages.length).toEqual(1);
expect(sect.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
});
it('hauteur torrentielle, Y < Yc', () => {
sect.Calc("Yt");
expect(sect.log.messages.length).toEqual(1);
expect(sect.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
});
it('hauteur torrentielle, Y > Yc', () => {
sect.prms.Y.v = 2;
sect.Calc("Yt");
expect(sect.log.messages.length).toEqual(2);
expect(sect.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
expect(sect.log.messages[1].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HTOR);
});
it('hauteur conjuguée, Froude < 1', () => {
sect.prms.Y.v = 2;
sect.Calc("Yco");
console.log(sect.log.toString());
expect(sect.log.messages.length).toEqual(3);
expect(sect.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
expect(sect.log.messages[1].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HTOR);
expect(sect.log.messages[2].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCONJUG);
});
it('hauteur conjuguée, Froude > 1', () => {
sect.Calc("Yco");
expect(sect.log.messages.length).toEqual(4);
expect(sect.log.messages[0].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
expect(sect.log.messages[1].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
expect(sect.log.messages[2].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HFLU);
expect(sect.log.messages[3].code).toEqual(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCONJUG);
});
});
});
...@@ -15,8 +15,8 @@ export class cHautCritique extends acNewton { ...@@ -15,8 +15,8 @@ export class cHautCritique extends acNewton {
* Constructeur de la classe * Constructeur de la classe
* @param Sn Section sur laquelle on fait le calcul * @param Sn Section sur laquelle on fait le calcul
*/ */
constructor(Sn: acSection, dbg: boolean = false) { constructor(Sn: acSection, maxIter: number, dbg: boolean = false) {
super(Sn.prms, dbg); super(Sn.prms, maxIter, dbg);
this.Sn = Sn.clone(); this.Sn = Sn.clone();
} }
...@@ -77,8 +77,8 @@ export class cHautNormale extends acNewton { ...@@ -77,8 +77,8 @@ export class cHautNormale extends acNewton {
* Constructeur de la classe * Constructeur de la classe
* @param oSn Section sur laquelle on fait le calcul * @param oSn Section sur laquelle on fait le calcul
*/ */
constructor(Sn: acSection, dbg: boolean = false) { constructor(Sn: acSection, maxIter: number, dbg: boolean = false) {
super(Sn.prms, dbg); super(Sn.prms, maxIter, dbg);
this.Sn = Sn; this.Sn = Sn;
this.Q = Sn.prms.Q.v; this.Q = Sn.prms.Q.v;
this.Ks = Sn.prms.Ks.v; this.Ks = Sn.prms.Ks.v;
...@@ -135,8 +135,8 @@ export class cHautCorrespondante extends acNewton { ...@@ -135,8 +135,8 @@ export class cHautCorrespondante extends acNewton {
* Constructeur de la classe * Constructeur de la classe
* @param oSn Section sur laquelle on fait le calcul * @param oSn Section sur laquelle on fait le calcul
*/ */
constructor(Sn: acSection, dbg: boolean = false) { constructor(Sn: acSection, maxIter: number, dbg: boolean = false) {
super(Sn.prms, dbg); super(Sn.prms, maxIter, dbg);
this.Y = Sn.prms.Y.v; this.Y = Sn.prms.Y.v;
this.rS2 = Math.pow(Sn.Calc("S"), -2); this.rS2 = Math.pow(Sn.Calc("S"), -2);
this.Sn = Sn; this.Sn = Sn;
...@@ -186,8 +186,8 @@ export class cHautConjuguee extends acNewton { ...@@ -186,8 +186,8 @@ export class cHautConjuguee extends acNewton {
* Constructeur de la classe * Constructeur de la classe
* @param oSn Section sur laquelle on fait le calcul * @param oSn Section sur laquelle on fait le calcul
*/ */
constructor(oSn: acSection, dbg: boolean = false) { constructor(oSn: acSection, maxIter: number, dbg: boolean = false) {
super(oSn.prms, dbg); super(oSn.prms, maxIter, dbg);
this.rQ2 = Math.pow(oSn.prms.Q.v, 2); this.rQ2 = Math.pow(oSn.prms.Q.v, 2);
this.Sn = oSn; this.Sn = oSn;
this.rS = oSn.Calc("S"); this.rS = oSn.Calc("S");
......
...@@ -4,8 +4,8 @@ import { cParamsCanal } from "./section_type" ...@@ -4,8 +4,8 @@ import { cParamsCanal } from "./section_type"
export abstract class acNewton extends Debug { export abstract class acNewton extends Debug {
protected rTol: number; protected rTol: number;
protected Dx: number; protected Dx: number;
private iCpt = 0; private iCpt: number = 0;
private readonly iCptMax = 50; private iCptMax: number;
private rRelax = 1; /// Coefficient de relaxation private rRelax = 1; /// Coefficient de relaxation
private rFnPrec = 0; /// Mémorisation du Fn précédent pour détecter le changement de signe private rFnPrec = 0; /// Mémorisation du Fn précédent pour détecter le changement de signe
private iOscil = 0; /// Nombre de changement de signe de Delta private iOscil = 0; /// Nombre de changement de signe de Delta
...@@ -14,10 +14,11 @@ export abstract class acNewton extends Debug { ...@@ -14,10 +14,11 @@ export abstract class acNewton extends Debug {
* Constructeur de la classe * Constructeur de la classe
* @param prms Paramètres supplémentaires (Débit, précision...) * @param prms Paramètres supplémentaires (Débit, précision...)
*/ */
constructor(prms: cParamsCanal, dbg: boolean = false) { constructor(prms: cParamsCanal, maxIter: number, dbg: boolean = false) {
super(dbg); super(dbg);
this.rTol = prms.Prec.v; this.rTol = prms.Prec.v;
this.Dx = prms.Prec.v / 10; this.Dx = prms.Prec.v / 10;
this.iCptMax = maxIter;
} }
/** /**
...@@ -92,4 +93,12 @@ export abstract class acNewton extends Debug { ...@@ -92,4 +93,12 @@ export abstract class acNewton extends Debug {
// Echec de la résolution // Echec de la résolution
return undefined; return undefined;
} }
/**
* Pour savoir si le Newton a convergé
* @return true si oui, false sinon
*/
public hasConverged(): boolean {
return this.iCpt < this.iCptMax;
}
} }
\ No newline at end of file
import { XOR } from "../base"; import { XOR } from "../base";
import { cLog } from "../util/log"; import { cLog } from "../util/log";
import { MessageCode, Message } from "../util/message";
import { ComputeNodeType, ComputeNode, ParamDefinition, ParamDomainValue, ParamCalculability, ParamsEquation } from "../param"; import { ComputeNodeType, ComputeNode, ParamDefinition, ParamDomainValue, ParamCalculability, ParamsEquation } from "../param";
import { cHautCritique, cHautNormale, cHautCorrespondante, cHautConjuguee } from "./hauteur"; import { cHautCritique, cHautNormale, cHautCorrespondante, cHautConjuguee } from "./hauteur";
...@@ -149,10 +150,9 @@ export abstract class acSection extends ComputeNode { ...@@ -149,10 +150,9 @@ export abstract class acSection extends ComputeNode {
private Calc_old = {}; /// Mémorisation des données hydrauliques pour calcul intermédiaire private Calc_old = {}; /// Mémorisation des données hydrauliques pour calcul intermédiaire
/** /**
* Nombre de points nécessaires pour le dessin de la section (hors point de berge) * itérations max pour Newton
* Valeur de 1 par défaut pour les sections rectangulaires et trapézoïdales
*/ */
protected nbDessinPoints = 1; private _newtonMaxIter: number = 50;
/** /**
* Construction de la classe. * Construction de la classe.
...@@ -188,6 +188,14 @@ export abstract class acSection extends ComputeNode { ...@@ -188,6 +188,14 @@ export abstract class acSection extends ComputeNode {
return Object.create(this); return Object.create(this);
} }
public set newtonMaxIter(n: number) {
this._newtonMaxIter = n;
}
public get log(): cLog {
return this.oLog;
}
/** /**
* Efface toutes les données calculées pour forcer le recalcul * Efface toutes les données calculées pour forcer le recalcul
* @param bGeo Réinitialise les données de géométrie aussi * @param bGeo Réinitialise les données de géométrie aussi
...@@ -500,8 +508,12 @@ export abstract class acSection extends ComputeNode { ...@@ -500,8 +508,12 @@ export abstract class acSection extends ComputeNode {
* @return tirant d'eau critique * @return tirant d'eau critique
*/ */
private Calc_Yc(): number { private Calc_Yc(): number {
var hautCritique = new cHautCritique(this, this.DBG); let hautCritique = new cHautCritique(this, this._newtonMaxIter, this.DBG);
this.HautCritique = hautCritique.Newton(this.prms.YB.v); this.HautCritique = hautCritique.Newton(this.prms.YB.v);
if (this.HautCritique == undefined || !hautCritique.hasConverged()) {
let m = new Message(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE);
this.oLog.add(m);
}
return this.HautCritique; return this.HautCritique;
} }
...@@ -511,11 +523,20 @@ export abstract class acSection extends ComputeNode { ...@@ -511,11 +523,20 @@ export abstract class acSection extends ComputeNode {
*/ */
private Calc_Yn(): number { private Calc_Yn(): number {
this.debug("in calc_Yn"); this.debug("in calc_Yn");
if (this.prms.If.v <= 0) if (this.prms.If.v <= 0) {
let m = new Message(MessageCode.ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF);
this.oLog.add(m);
return undefined; return undefined;
}
let oHautNormale = new cHautNormale(this, this._newtonMaxIter, this.DBG);
let res = oHautNormale.Newton(this.CalcGeo("Yc"));
if (res == undefined || !oHautNormale.hasConverged()) {
let m = new Message(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE);
this.oLog.add(m);
}
var oHautNormale = new cHautNormale(this, this.DBG); return res;
return oHautNormale.Newton(this.CalcGeo("Yc"));
} }
/** /**
...@@ -526,8 +547,14 @@ export abstract class acSection extends ComputeNode { ...@@ -526,8 +547,14 @@ export abstract class acSection extends ComputeNode {
if (this.prms.Y.v > this.CalcGeo("Yc")) if (this.prms.Y.v > this.CalcGeo("Yc"))
return this.prms.Y.v; return this.prms.Y.v;
var oHautCorrespondante = new cHautCorrespondante(this, this.DBG); var oHautCorrespondante = new cHautCorrespondante(this, this._newtonMaxIter, this.DBG);
return oHautCorrespondante.Newton(this.Calc("Yc") * 2); let res = oHautCorrespondante.Newton(this.Calc("Yc") * 2);
if (res == undefined || !oHautCorrespondante.hasConverged()) {
let m = new Message(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HFLU);
this.oLog.add(m);
}
return res;
} }
/** /**
...@@ -538,8 +565,14 @@ export abstract class acSection extends ComputeNode { ...@@ -538,8 +565,14 @@ export abstract class acSection extends ComputeNode {
if (this.prms.Y.v < this.CalcGeo("Yc")) if (this.prms.Y.v < this.CalcGeo("Yc"))
return this.prms.Y.v; return this.prms.Y.v;
var oHautCorrespondante = new cHautCorrespondante(this, this.DBG); var oHautCorrespondante = new cHautCorrespondante(this, this._newtonMaxIter, this.DBG);
return oHautCorrespondante.Newton(this.CalcGeo("Yc") / 2); let res = oHautCorrespondante.Newton(this.CalcGeo("Yc") / 2);
if (res == undefined || !oHautCorrespondante.hasConverged()) {
let m = new Message(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HTOR);
this.oLog.add(m);
}
return res;
} }
/** /**
...@@ -548,7 +581,7 @@ export abstract class acSection extends ComputeNode { ...@@ -548,7 +581,7 @@ export abstract class acSection extends ComputeNode {
*/ */
private Calc_Yco(): number { private Calc_Yco(): number {
this.Swap(true); this.Swap(true);
var oHautConj = new cHautConjuguee(this, this.DBG); var oHautConj = new cHautConjuguee(this, this._newtonMaxIter, this.DBG);
// Choisir une valeur initiale du bon côté de la courbe // Choisir une valeur initiale du bon côté de la courbe
if (this.Calc("Fr") < 1) { if (this.Calc("Fr") < 1) {
// Ecoulement fluvial, on cherche la conjuguée à partir du tirant d'eau torrentiel // Ecoulement fluvial, on cherche la conjuguée à partir du tirant d'eau torrentiel
...@@ -559,6 +592,11 @@ export abstract class acSection extends ComputeNode { ...@@ -559,6 +592,11 @@ export abstract class acSection extends ComputeNode {
Y0 = this.Calc("Yf"); Y0 = this.Calc("Yf");
} }
let Yco = oHautConj.Newton(Y0); let Yco = oHautConj.Newton(Y0);
if (Yco == undefined || !oHautConj.hasConverged()) {
let m = new Message(MessageCode.ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCONJUG);
this.oLog.add(m);
}
this.Swap(false); this.Swap(false);
return Yco; return Yco;
} }
......
...@@ -157,6 +157,36 @@ export enum MessageCode { ...@@ -157,6 +157,36 @@ export enum MessageCode {
* courbe de remous : Condition limite amont > Hauteur critique : pas de calcul possible depuis l'amont * courbe de remous : Condition limite amont > Hauteur critique : pas de calcul possible depuis l'amont
*/ */
ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT = -510, ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT = -510,
/**
* section : Non convergence du calcul de la hauteur critique (Méthode de Newton)
*/
ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCRITIQUE = -600,
/**
* section : Non convergence du calcul de la hauteur normale (Méthode de Newton)
*/
ERROR_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE = -601,
/**
* section : Non convergence du calcul de la hauteur conjuguée (Méthode de Newton)
*/
ERROR_SECTION_NON_CONVERGENCE_NEWTON_HCONJUG = -602,
/**
* section : Non convergence du calcul de la hauteur correspondante (Méthode de Newton) pour le calcul de la hauteur fluviale
*/
ERROR_SECTION_NON_CONVERGENCE_NEWTON_HFLU = -603,
/**
* section : Non convergence du calcul de la hauteur correspondante (Méthode de Newton) pour le calcul de la hauteur torrentielle
*/
ERROR_SECTION_NON_CONVERGENCE_NEWTON_HTOR = -604,
/**
* section : La pente est négative ou nulle, la hauteur normale est infinie
*/
ERROR_SECTION_PENTE_NEG_NULLE_HNORMALE_INF = -605,
} }
/** /**
......
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