diff --git a/spec/devalaison/jet.spec.ts b/spec/devalaison/jet.spec.ts index e82443f6c04220165770006d7eac6b2c6c2015fb..583aaefea2a206d712512a815c9139779eba08da 100644 --- a/spec/devalaison/jet.spec.ts +++ b/spec/devalaison/jet.spec.ts @@ -135,4 +135,27 @@ describe("Class Jet − ", () => { }); }); + it("calculate slope with empty values − ", () => { + // erase all values, as nghyd does when creating a new calc + jet.prms.D.singleValue = undefined; + jet.prms.S.singleValue = undefined; + jet.prms.V0.singleValue = undefined; + jet.prms.ZF.singleValue = undefined; + jet.prms.ZW.singleValue = undefined; + jet.prms.ZJ.singleValue = undefined; + // calculate D (DICHO) + jet.calculatedParam = jet.prms.D; + // set values for all params except D + jet.prms.S.singleValue = 0.01; + jet.prms.V0.singleValue = 1; + jet.prms.ZF.singleValue = 10; + jet.prms.ZW.singleValue = 11; + jet.prms.ZJ.singleValue = 12; + // fixed + const res = jet.CalcSerie(); + // comparison + expect(res).toBeDefined(); + expect(res.vCalc).toBeCloseTo(0.452, 3); + }); + }); diff --git a/src/nub.ts b/src/nub.ts index dd79bb536171159b3e120eb326b75e48180183e1..bf731c3fa7a2ea2b67f5ef91077a092bf318eaeb 100644 --- a/src/nub.ts +++ b/src/nub.ts @@ -332,7 +332,7 @@ export abstract class Nub extends ComputeNode implements IObservable { } if (rInit === undefined) { - rInit = computedVar.v; + rInit = computedVar.initValue; } if (computedVar.isAnalytical()) { this.currentResult = this.Equation(sVarCalc); @@ -1415,7 +1415,12 @@ export abstract class Nub extends ComputeNode implements IObservable { public variatingLength(): number { let size = 0; for (const p of this.parameterIterator) { - size = Math.max(size, p.valuesIterator.count()); + try { + const iter = p.valuesIterator; + size = Math.max(size, iter.count()); + } catch (e) { + // silent fail (when p is in SINGLE mode and its value is undefined) + } } return size; } diff --git a/src/param/param-definition.ts b/src/param/param-definition.ts index 5b8b33fe1320fee11a3b305cd49ec9a3c3708110..0b2189c70b6e8af7b03bc4174bb02cba284d99d5 100644 --- a/src/param/param-definition.ts +++ b/src/param/param-definition.ts @@ -69,6 +69,9 @@ export class ParamDefinition implements INamedIterableValues, IObservable { /** sandbox value used during calculation */ public v: number; + /** value used to initialize "DICHO" calculation, never supposed to be undefined */ + private _initValue: number; + /** extension strategy, when multiple parameters vary */ private _extensionStrategy: ExtensionStrategy; @@ -111,9 +114,10 @@ export class ParamDefinition implements INamedIterableValues, IObservable { this._observable = new Observable(); this._paramValues = new ParamValues(); - // set single value and copy it to sandbox value + // set single value and copy it to sandbox value and initValue this._paramValues.singleValue = val; this.v = val; + this.initValue = val; this._calc = ParamCalculability.FREE; this._family = family; @@ -150,6 +154,25 @@ export class ParamDefinition implements INamedIterableValues, IObservable { this._unit = u; } + public get initValue(): number { + return this._initValue; + } + + /** + * Make sure that this value is never undefined, null or NaN, so that + * there is always an initial value for "DICHO" calculations, even + * when param value was set to undefined before + */ + public set initValue(v: number) { + if (v !== undefined && ! isNaN(v) && v !== null) { + this._initValue = v; + } else { + if (this._initValue === undefined || isNaN(this._initValue) || this._initValue === null) { + this._initValue = Math.random(); + } + } + } + /** * pointer to the ComputeNode (usually Nub) that uses the ParamsEquation that * uses this ParamDefinition; for Section params, this means the Nub enclosing @@ -406,6 +429,7 @@ export class ParamDefinition implements INamedIterableValues, IObservable { public set singleValue(v: number) { this.checkValueMode([ParamValueMode.SINGLE, ParamValueMode.CALCUL, ParamValueMode.LINK]); this.paramValues.singleValue = v; + this.initValue = v; this.notifyValueModified(this); } @@ -1026,7 +1050,6 @@ export class ParamDefinition implements INamedIterableValues, IObservable { /** * Transparent proxy to own values iterator or targetted values iterator (in LINK mode) - * @TODO rewrite more simply ? */ public get valuesIterator(): INumberIterator { if (this.valueMode === ParamValueMode.LINK && this.isReferenceDefined()) {