An error occurred while loading the file. Please try again.
-
Youcef Aouad authored673ae390
import { Debug } from "./base";
import { DefinedNumber } from "./util/definedvalue";
import { Interval } from "./util/interval";
import { Message, MessageCode } from "./util/message";
import { MapIterator } from "./util/iterator";
import { JalhydObject } from "./jalhyd_object";
/**
* domaine de définition du paramètre
*/
export enum ParamDomainValue {
/**
* >0, =0, <0 (-inf -> +inf)
*/
ANY,
/**
* >=0
*/
POS_NULL,
/**
* > 0
*/
POS,
/**
* <>0
*/
NOT_NULL,
/**
* intervalle
*/
INTERVAL
}
export class ParamDomain {
public static getDefaultBounds(d: ParamDomainValue): { min: number, max: number } {
switch (d) {
case ParamDomainValue.INTERVAL:
const e: Message = new Message(MessageCode.ERROR_PARAMDOMAIN_INVALID);
throw e;
case ParamDomainValue.ANY:
case ParamDomainValue.NOT_NULL:
return { min: -Infinity, max: Infinity };
case ParamDomainValue.POS:
return { min: 1e-9, max: Infinity };
case ParamDomainValue.POS_NULL:
return { min: 0, max: Infinity };
// default:
// throw "valeur de ParamDomainValue" + ParamDomainValue[d] + " non prise en charge";
}
}
private _domain: ParamDomainValue;
private _minValue: number;
private _maxValue: number;
constructor(d: ParamDomainValue, min?: number, max?: number) {
this.checkValue(d, min, max);
this._domain = d;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
switch (this._domain) {
case ParamDomainValue.INTERVAL:
this._minValue = min;
this._maxValue = max;
break;
default:
const b = ParamDomain.getDefaultBounds(this._domain);
this._minValue = b.min;
this._maxValue = b.max;
break;
}
}
get domain() {
return this._domain;
}
get minValue() {
return this._minValue;
}
get maxValue() {
return this._maxValue;
}
public get interval(): Interval {
switch (this._domain) {
case ParamDomainValue.INTERVAL:
return new Interval(this._minValue, this._maxValue);
default:
const b = ParamDomain.getDefaultBounds(this._domain);
return new Interval(b.min, b.max);
}
}
public clone(): ParamDomain {
switch (this._domain) {
case ParamDomainValue.INTERVAL:
return new ParamDomain(this._domain, this._minValue, this._maxValue);
default:
return new ParamDomain(this._domain);
}
}
private checkValue(val: number, min: number, max: number) {
switch (val) {
case ParamDomainValue.INTERVAL:
if (min === undefined || max === undefined || min > max) {
const e: Message = new Message(MessageCode.ERROR_PARAMDOMAIN_INTERVAL_BOUNDS);
e.extraVar.minValue = min;
e.extraVar.maxValue = max;
throw e;
}
break;
default:
// en dehors du cas INTERVAL, on ne doit pas fournir de valeur
if (min !== undefined || max !== undefined) {
const e: Message = new Message(MessageCode.ERROR_PARAMDOMAIN_INTERVAL_BOUNDS);
e.extraVar.minValue = min;
e.extraVar.maxValue = max;
throw e;
}
break;
}
}
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
}
/**
* calculabilité du paramètre
*/
export enum ParamCalculability {
/**
* paramètre fixé (immuable, cad non modifiable après création)
*/
NONE,
/**
* paramètre libre (modifiable)
*/
FREE,
/**
* paramètre calculable analytiquement, par méthode de Newton, ...
*/
EQUATION,
/**
* paramètre calculable par dichotomie
*/
DICHO
}
/**
* paramètre avec symbole et domaine de définition
*/
// tslint:disable-next-line:max-classes-per-file
export class BaseParam extends JalhydObject {
/**
* symbole
*/
private _symbol: string;
/**
* domaine de définition
*/
private _domain: ParamDomain;
/**
* valeur numérique (éventuellement non définie)
*/
private _value: DefinedNumber;
constructor(symb: string, d: ParamDomain | ParamDomainValue, val?: number) {
super();
this._symbol = symb;
this._value = new DefinedNumber(val);
if (d instanceof ParamDomain) {
this._domain = d;
} else {
this._domain = new ParamDomain(d as ParamDomainValue);
}
this.checkValue(val);
}
get symbol(): string {
return this._symbol;
}
public getDomain(): ParamDomain {
return this._domain;
}
public get interval(): Interval {
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
return this._domain.interval;
}
/**
* gestion de la valeur
*/
public get isDefined(): boolean {
return this._value.isDefined;
}
public getValue(): number {
if (!this._value.isDefined) {
const e = new Message(MessageCode.ERROR_PARAMDEF_VALUE_UNDEFINED);
e.extraVar.symbol = this.symbol;
throw e;
}
return this._value.value;
}
public setValue(val: number) {
this.checkValue(val);
this._value.value = val;
// console.log("setting param " + this._symbol + " id=" + this._id + " to " + val); // A VIRER
}
public get uncheckedValue(): number {
return this._value.uncheckedValue;
}
public checkValue(v: number) {
const sDomain = ParamDomainValue[this._domain.domain];
switch (this._domain.domain) {
case ParamDomainValue.ANY:
break;
case ParamDomainValue.POS:
if (v <= 0) {
const f = new Message(MessageCode.ERROR_PARAMDEF_VALUE_POS);
f.extraVar.symbol = this.symbol;
f.extraVar.value = v;
throw f;
}
break;
case ParamDomainValue.POS_NULL:
if (v < 0) {
const f = new Message(MessageCode.ERROR_PARAMDEF_VALUE_POSNULL);
f.extraVar.symbol = this.symbol;
f.extraVar.value = v;
throw f;
}
break;
case ParamDomainValue.NOT_NULL:
if (v === 0) {
const f = new Message(MessageCode.ERROR_PARAMDEF_VALUE_NULL);
f.extraVar.symbol = this.symbol;
throw f;
}
break;
case ParamDomainValue.INTERVAL:
const min = this._domain.minValue;
const max = this._domain.maxValue;
if (v < min || v > max) {
const f = new Message(MessageCode.ERROR_PARAMDEF_VALUE_INTERVAL);
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
f.extraVar.symbol = this.symbol;
f.extraVar.value = v;
f.extraVar.minValue = min;
f.extraVar.maxValue = max;
throw f;
}
break;
default:
const e = new Message(MessageCode.ERROR_PARAMDOMAIN_INVALID);
e.extraVar.symbol = this.symbol;
e.extraVar.domain = sDomain;
throw e;
}
}
}
/**
* définition d'un paramètre d'un noeud de calcul
*/
// tslint:disable-next-line:max-classes-per-file
export class ParamDefinition extends BaseParam {
/**
* calculabilité
*/
private _calc: ParamCalculability;
constructor(s: string, d: ParamDomain | ParamDomainValue, val?: number) {
super(s, d, val);
this._calc = undefined;
this.checkValue(val);
}
get v(): number {
return super.getValue();
}
set v(val: number) {
if (this.calculability === ParamCalculability.NONE) {
const e = new Message(MessageCode.ERROR_PARAMDEF_VALUE_FIXED);
e.extraVar.symbol = this.symbol;
throw e;
}
super.setValue(val);
}
/*
* méthodes de calculabilité
*/
/**
* variable calculable par l'équation ?
*/
public isAnalytical(): boolean {
return this.calculability === ParamCalculability.EQUATION;
}
get calculability(): ParamCalculability {
if (this._calc === undefined) {
// throw "value of parameter '" + this._symbol + "' calculability is not defined";
const e = new Message(MessageCode.ERROR_PARAMDEF_CALC_UNDEFINED);
e.extraVar.symbol = this.symbol;
throw e;
}
return this._calc;
}
set calculability(c: ParamCalculability) {
this._calc = c;
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
}
public clone(): ParamDefinition {
const res = new ParamDefinition(this.symbol, this.getDomain().clone(), this.uncheckedValue);
res._calc = this._calc;
return res;
}
}
/**
* liste des paramètres d'une équation
*/
// tslint:disable-next-line:max-classes-per-file
export abstract class ParamsEquation implements Iterable<ParamDefinition> {
protected _paramMap: { [key: string]: ParamDefinition } = {};
public hasParameter(name: string): boolean {
for (const ps in this._paramMap) {
const p: ParamDefinition = this._paramMap[ps];
if (p.symbol === name) {
return true;
}
}
return false;
}
public getParameter(name: string): ParamDefinition {
for (const ps in this._paramMap) {
const p: ParamDefinition = this._paramMap[ps];
if (p.symbol === name) {
return p;
}
}
throw new Error("ParamsEquation.getParameter() : invalid parameter name " + name);
}
public getFirstAnalyticalParameter(): ParamDefinition {
for (const ps in this._paramMap) {
const p: ParamDefinition = this._paramMap[ps];
if (p.isAnalytical()) {
return p;
}
}
return undefined;
}
protected addParamDefinition(p: ParamDefinition) {
if (!this.hasParameter(p.symbol)) {
this._paramMap[p.symbol] = p;
}
}
protected addParamDefinitions(ps: ParamsEquation) {
for (const pi in ps._paramMap) {
this.addParamDefinition(ps._paramMap[pi]);
}
}
public get map(): { [key: string]: ParamDefinition } {
return this._paramMap;
}
protected checkParametersCalculability() {
const res = [];
for (const ps in this._paramMap) {
const p: ParamDefinition = this._paramMap[ps];
if (p.calculability === undefined) {
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
res.push(p.symbol);
}
}
if (res.length > 0) {
throw new Error("Calculability of parameter(s) " + res.toString() + " has not been defined");
}
}
[Symbol.iterator](): Iterator<ParamDefinition> {
return this.iterator;
}
public get iterator() {
return new MapIterator(this._paramMap);
}
}
/**
* type de calculette
*/
export enum CalculatorType {
ConduiteDistributrice, LechaptCalmon, SectionParametree, RegimeUniforme, CourbeRemous,
PabDimensions, // passe à bassin rectangulaire
PabPuissance, // passe à bassin : puissance dissipée
Structure, // ouvrages hydrauliques simples
ParallelStructure // ouvrages hydrauliques en parallèle
}
/**
* type de noeud de calcul (sous type de calculette)
*/
export enum ComputeNodeType {
None,
// types de sections
SectionTrapeze, SectionRectangle, SectionCercle, SectionPuissance,
// types d'ouvrages hydrauliques
StructureRectangle,
}
/**
* noeud de calcul
*/
// tslint:disable-next-line:max-classes-per-file
export abstract class ComputeNode extends Debug {
protected _prms: ParamsEquation;
constructor(prms: ParamsEquation, dbg: boolean = false) {
super(dbg);
this._prms = prms;
this.setParametersCalculability();
}
public getParameter(name: string): ParamDefinition {
return this._prms.getParameter(name);
}
public getFirstAnalyticalParameter(): ParamDefinition {
return this._prms.getFirstAnalyticalParameter();
}
protected abstract setParametersCalculability(): void;
}