Commit 25dbe031 authored by Mathias Chouet's avatar Mathias Chouet 🍝
Browse files

Fix #224 − bug with dedicated iterators

parent ee4e564c
......@@ -11,6 +11,7 @@ import { PabNombre } from "../../src/pab/pab_nombre";
import { PabNombreParams } from "../../src/pab/pab_nombre_params";
import { PabPuissance } from "../../src/pab/pab_puissance";
import { PabPuissanceParams } from "../../src/pab/pab_puissance_params";
import { Jet } from "../../src/devalaison/jet";
describe("chained computation of linked Nubs : ", () => {
......@@ -223,4 +224,21 @@ describe("failure in calc chain", () => {
expect(res.globalLog.messages[0].code).toBe(MessageCode.ERROR_IN_CALC_CHAIN);
});
describe("iterator bugs −", () => {
it("jalhyd#224, NaN", () => {
const sess = `{"header":{"source":"jalhyd","format_version":"1.3","created":"2020-05-18T08:05:58.374Z"},"settings":{"precision":1e-7,"maxIterations":100,"displayPrecision":3},"documentation":"## Calcul la longueur d'un jet provenant d'un déversoir dénoyé### Exposé du problèmeOn cherche à savoir pour différents débits quelle est la distance parcourue par la nappe d'eau au dessus d'un déversoir au moment où la nappe atteint la crête du déversoir.On va considérer un jet horizontal représentant la surface libre de la nappe au dessus du déversoir et calculer la distance horizontale atteinte lorsque le jet atteint la cote de la crête du déversoir.### Étapes du calculLe module déversoir dénoyé permet de calculer la cote de l'eau à l'amont du déversoir pour débits. Cette cote de l'eau correspond à la cote de départ du jet.La cote de l'eau représentant le point d'impact du jet est égale à la cote de la crête du déversoir.Pour obtenir la vitesse initiale du jet, il faut passer par plusieurs calculs intermédiaires : - Calcul du tirant d'eau entre la crête du déversoir et la cote de l'eau à l'amont du déversoir.- Calcul de la surface hydraulique de l'écoulement au dessus de la crête du déversoir en multipliant le tirant d'eau par la largeur du déversoir- Calcul de la vitesse moyenne de l'écoulement en divisant le débit par la surface hydrauliqueCette vitesse est ensuite utilisée comme vitesse initiale du jet.","session":[{"uid":"eXphMG","props":{"calcType":"Jet"},"meta":{"title":"Longueur du jet"},"children":[],"parameters":[{"symbol":"V0","mode":"LINK","targetNub":"eGxvcn","targetParam":"X"},{"symbol":"S","mode":"SINGLE","value":0},{"symbol":"ZJ","mode":"LINK","targetNub":"dGVrMX","targetParam":"Z1"},{"symbol":"ZW","mode":"LINK","targetNub":"NTRjcn","targetParam":"ZDV"},{"symbol":"ZF","mode":"SINGLE","value":1},{"symbol":"D","mode":"CALCUL"}]},{"uid":"dGVrMX","props":{"calcType":"Dever"},"meta":{"title":"Déver. dénoyés"},"children":[{"uid":"NTRjcn","props":{"calcType":"Structure","structureType":"SeuilRectangulaire","loiDebit":"WeirFree"},"children":[],"parameters":[{"symbol":"ZDV","mode":"SINGLE","value":1.4},{"symbol":"L","mode":"SINGLE","value":1.75},{"symbol":"CdWR","mode":"SINGLE","value":0.4}]}],"parameters":[{"symbol":"Q","mode":"MINMAX","min":0.07,"max":0.1,"step":0.01,"extensionStrategy":0},{"symbol":"Z1","mode":"CALCUL","value":0},{"symbol":"BR","mode":"SINGLE","value":0.7},{"symbol":"ZR","mode":"SINGLE","value":0}]},{"uid":"ZDdraH","props":{"calcType":"YAXB"},"meta":{"title":"Tirant d'eau"},"children":[],"parameters":[{"symbol":"Y","mode":"LINK","targetNub":"dGVrMX","targetParam":"Z1"},{"symbol":"A","mode":"SINGLE","value":1},{"symbol":"X","mode":"CALCUL"},{"symbol":"B","mode":"LINK","targetNub":"NTRjcn","targetParam":"ZDV"}]},{"uid":"NXJzdn","props":{"calcType":"YAXB"},"meta":{"title":"Surface hydraulique"},"children":[],"parameters":[{"symbol":"Y","mode":"CALCUL"},{"symbol":"A","mode":"LINK","targetNub":"NTRjcn","targetParam":"L"},{"symbol":"X","mode":"LINK","targetNub":"ZDdraH","targetParam":"X"},{"symbol":"B","mode":"SINGLE","value":0}]},{"uid":"eGxvcn","props":{"calcType":"YAXB"},"meta":{"title":"Vitesse initiale"},"children":[],"parameters":[{"symbol":"Y","mode":"LINK","targetNub":"dGVrMX","targetParam":"Q"},{"symbol":"A","mode":"LINK","targetNub":"NXJzdn","targetParam":"Y"},{"symbol":"X","mode":"CALCUL"},{"symbol":"B","mode":"SINGLE","value":0}]}]}`;
Session.getInstance().clear();
Session.getInstance().unserialise(sess);
const jet = Session.getInstance().findNubByUid("eXphMG") as Jet;
const res = jet.CalcSerie();
for (const re of res.resultElements) {
expect(isNaN(re.values.t)).toBe(false);
expect(isNaN(re.values.Vx)).toBe(false);
expect(isNaN(re.values.Vz)).toBe(false);
expect(isNaN(re.values.Vt)).toBe(false);
}
});
});
});
......@@ -556,7 +556,7 @@ export abstract class Nub extends ComputeNode implements IObservable {
while (variated[longest].values.hasNext && l < size) {
// get next value for all variating parameters
for (const v of variated) {
const currentIteratorValue = v.iterator.next();
const currentIteratorValue = v.iterator.nextValue();
v.param.v = currentIteratorValue.value;
}
// prepare a new slot to store results
......
......@@ -74,6 +74,11 @@ export class MirrorIterator implements INumberIterator {
}
}
/** trick method - use .next() instead, unless you are explicitely in jalhyd#222 case */
public nextValue(): IteratorResult<number> {
return this.next();
}
// interface IterableIterator
public [Symbol.iterator](): IterableIterator<number> {
......
......@@ -1098,6 +1098,11 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
return this.paramValues.next();
}
/** trick method - use .next() instead, unless you are explicitely in jalhyd#222 case */
public nextValue(): IteratorResult<number> {
return this.next();
}
public [Symbol.iterator](): IterableIterator<number> {
return this.paramValues;
}
......
......@@ -24,6 +24,8 @@ export interface INumberIterator extends IterableIterator<number> {
*/
next(): IteratorResult<number>;
nextValue(): IteratorResult<number>;
count(): number;
}
......@@ -164,6 +166,19 @@ export class ParamValueIterator implements INumberIterator {
}
}
/**
* Same as next(), but sets _currentValue on attached ParamValues; to be
* used with dedicated iterators, for params having multiple links on them
* @see jalhyd#222
*/
public nextValue(): IteratorResult<number> {
const res = this.next();
if (! res.done) {
this._param.setCurrentValueFromIterator(res.value);
}
return res;
}
public next(): IteratorResult<number> {
if (this.hasNext) {
switch (this._param.valueMode) {
......
......@@ -229,6 +229,21 @@ export class ParamValues implements IterableValues {
return res;
}
/** trick method - use .next() instead, unless you are explicitely in jalhyd#222 case */
public nextValue(): IteratorResult<number> {
return this.next();
}
/**
* Trick method to explicitely set _currentValue when using a dedicated iterator, for
* params having multiple links on them @see jalhyd#222 ; usually calling .next() on
* ParamDefinition sets _currentValue, but not when a dedicated iterator is used; this
* method should only be called by ParamValueIterator.nextValue()
*/
public setCurrentValueFromIterator(v: number) {
this._currentValue = v;
}
public [Symbol.iterator](): IterableIterator<number> {
return this;
}
......
......@@ -35,6 +35,11 @@ export class NumberArrayIterator implements INumberIterator {
return res;
}
/** trick method - use .next() instead, unless you are explicitely in jalhyd#222 case */
public nextValue(): IteratorResult<number> {
return this.next();
}
public get currentValue(): number {
return this._current;
}
......
......@@ -34,6 +34,11 @@ export class NumberArrayReverseIterator extends ArrayReverseIterator<number> imp
return res;
}
/** trick method - use .next() instead, unless you are explicitely in jalhyd#222 case */
public nextValue(): IteratorResult<number> {
return this.next();
}
public get currentValue(): number {
return this._current;
}
......
Markdown is supported
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