UNPKG

jalhyd

Version:

JaLHyd, a Javascript Library for Hydraulics

263 lines 11.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Solveur = void 0; const internal_modules_1 = require("../internal_modules"); const internal_modules_2 = require("../internal_modules"); const internal_modules_3 = require("../internal_modules"); const internal_modules_4 = require("../internal_modules"); const internal_modules_5 = require("../internal_modules"); const internal_modules_6 = require("../internal_modules"); const internal_modules_7 = require("../internal_modules"); const internal_modules_8 = require("../internal_modules"); class Solveur extends internal_modules_2.Nub { /** * Finds all parameters whose value can be searched for by dichotomy, for * a given value of calculated param of given Nub * @param nub Nub calculated by Solveur * @param addSelf if true, will also return parameters of the current Nub */ static getDependingNubsSearchableParams(nub, addSelf = false) { const searchableParams = []; if (nub !== undefined) { const upstreamNubs = nub.getRequiredNubsDeep(); if (addSelf) { upstreamNubs.push(nub); } for (const un of upstreamNubs) { for (const p of un.parameterIterator) { // only visible, non-varying, non-calculated parameters can be looked for if (p.visible && p.valueMode === internal_modules_4.ParamValueMode.SINGLE) { searchableParams.push(p); } } } } return searchableParams; } constructor(prms, dbg = false) { super(prms, dbg); this.setCalculatorType(internal_modules_1.CalculatorType.Solveur); this._props.addObserver(this); this.prms.addObserver(this); // UID of Session Nub to calculate, the result of the which must be this.prms.Ytarget.singleValue this.nubToCalculate = undefined; // symbol of extra result targetted on the Nub to calculate; if specified, then this.prms.Ytarget.singleValue // will be the expected value not for nubToCalculate.vCalc, but for nubToCalculate.values[this.targettedResult] this.targettedResult = undefined; // UID of Session Nub / symbol of source parameter to vary (the "searched" parameter) this.searchedParameter = undefined; // calculated param should always be pseudo-parameter "X" (the one whose value we're looking for) this._defaultCalculatedParam = prms.X; this.resetDefaultCalculatedParam(); } get prms() { return this._prms; } /** finds the Nub to calculate by its UID */ get nubToCalculate() { let nub; const nubUID = this._props.getPropValue("nubToCalculate"); if (nubUID !== undefined && nubUID !== "") { nub = internal_modules_5.Session.getInstance().findNubByUid(nubUID); if (nub === undefined) { // silent fail // throw new Error(`Solveur.get nubToCalculate(): cannot find Nub ${nubUID} in session`); } } return nub; } /** defines the Nub to calculate by setting property "nubToCalculate" to the UID of the given Nub */ set nubToCalculate(n) { let uid = ""; // empty value if (n !== undefined) { uid = n.uid; } this.setPropValue("nubToCalculate", uid); } get targettedResult() { return this._props.getPropValue("targettedResult"); } set targettedResult(symbol) { this._props.setPropValue("targettedResult", symbol); } /** finds the source parameter whose value we're looking for, by its Nub UID / symbol */ get searchedParameter() { let p; const nubUIDAndSymbol = this._props.getPropValue("searchedParameter"); if (nubUIDAndSymbol !== undefined && nubUIDAndSymbol !== "") { const slashPos = nubUIDAndSymbol.indexOf("/"); const nubUID = nubUIDAndSymbol.substring(0, slashPos); const paramSymbol = nubUIDAndSymbol.substring(slashPos + 1); // console.log("(i) searched param Nub UID / symbol :", nubUID, paramSymbol); if (nubUID) { const nub = internal_modules_5.Session.getInstance().findNubByUid(nubUID); if (nub !== undefined) { if (paramSymbol) { p = nub.getParameter(paramSymbol); if (p === undefined) { throw new Error(`Solveur.get searchedParameter(): cannot find Parameter ${paramSymbol} in Nub`); } } } else { // silent fail // throw new Error(`Solveur.get searchedParameter(): cannot find Nub ${nubUID} in session`); } } } return p; } /** * defines the searched parameter by setting property "searchedParameter" to the UID of the * parameter's Nub / the parameter's symbol */ set searchedParameter(p) { let sp = ""; // empty value if (p !== undefined) { sp = p.nubUid + "/" + p.symbol; } this.setPropValue("searchedParameter", sp); } /** * Looks for potential errors before calling Nub.Calc() */ Calc(sVarCalc, rInit) { const r = new internal_modules_6.Result(new internal_modules_7.ResultElement()); if (this.nubToCalculate.resultHasMultipleValues()) { r.resultElement.addMessage(new internal_modules_8.Message(internal_modules_8.MessageCode.ERROR_SOLVEUR_NO_VARIATED_PARAMS_ALLOWED)); this.currentResultElement = r; return this.result; } return super.Calc(sVarCalc, rInit); } CalcSerie(rInit) { // affect initial value of X for Dichotomie search this.prms.X.singleValue = this.prms.Xinit.currentValue; const res = super.CalcSerie(rInit); res.updateSourceNub(this); res.removeExtraResults(); // clodo trick: realculate nubToCalculate() dissociates results @see jalhyd#157 this.nubToCalculate.CalcSerie(); return res; } /** * Calculates the target "downstream" Nub, that will trigger calculation of * all linked "upstream" Nubs, including the one that contains the variating * parameter X * @param sVarCalc should always be pseudo-parameter "Y" */ Equation(sVarCalc) { if (sVarCalc !== "Y") { throw new Error(`Solveur: calculated param should always be Y (found ${sVarCalc})`); } // set the Y value we have to obtain this.prms.Y.v = this.prms.Ytarget.v; // set the current value of X, determined by Dichotomie, on the upstream Nub this.searchedParameter.singleValue = this.prms.X.v; // calculate Nubs chain const res = this.nubToCalculate.CalcSerie(); // if targetting an extraresult, replace vCalc with targetted extraresult if (this.targettedResult) { // might be undefined, or "" (when unserializing) res.vCalc = res.values[this.targettedResult]; } return res; } getFirstAnalyticalParameter() { // always use pseudo-parameter Y for Dichotomie iterations; // always update target value from input parameter this.prms.Y.v = this.prms.Ytarget.v; return this.prms.Y; } // interface Observer update(sender, data) { if (data.action === "propertyChange") { if (data.name === "nubToCalculate" || data.name === "searchedParameter" || data.name === "targettedResult") { const n = this.nubToCalculate; const t = this.targettedResult; const p = this.searchedParameter; if (n !== undefined && p !== undefined) { if (n !== p.parentNub && !n.dependsOnNubResult(p.parentNub)) { throw new Error("Solveur.update(): Nub to calculate is not linked to result of searchedParameter parent Nub"); } } if (data.name === "nubToCalculate") { if (n !== undefined) { if (n.resultHasMultipleValues()) { throw new Error("Solveur.update(): Nub to calculate must not have multiple values"); } // reset targetted result this.targettedResult = undefined; } } if (data.name === "searchedParameter") { if (p !== undefined) { if (p.valueMode !== internal_modules_4.ParamValueMode.SINGLE) { throw new Error("Solveur.update(): searched parameter X must be in SINGLE mode"); } // update pseudo-parameter X this.prms.setX(p); } } if (data.name === "targettedResult") { if (t !== undefined && t !== "") { if (n.resultsFamilies && !Object.keys(n.resultsFamilies).includes(t)) { throw new Error("Solveur.update(): targetted result T is not a declared extra result of Nub to calculate"); } } else { // empty value − is nubToCalc single ? If so, invalidate searchedParam if (Solveur.getDependingNubsSearchableParams(n).length === 0) { this.searchedParameter = undefined; } } } } } if (data.action === "XUpdated") { this._defaultCalculatedParam = this.prms.X; this.resetDefaultCalculatedParam(); } } /** * Once session is loaded, run a second pass on targetted * objects if they couldn't be set before */ fixTargets(obj) { // return value const ret = { hasErrors: false }; try { // do not use setters, to allow setting directly the string UIDs this.setPropValue("nubToCalculate", obj.props.nubToCalculate); this.setPropValue("targettedResult", obj.props.targettedResult); this.setPropValue("searchedParameter", obj.props.searchedParameter); } catch (e) { ret.hasErrors = true; } return ret; } setParametersCalculability() { if (this.prms.X !== undefined) { this.prms.X.calculability = internal_modules_3.ParamCalculability.DICHO; } this.prms.Xinit.calculability = internal_modules_3.ParamCalculability.FIXED; this.prms.Ytarget.calculability = internal_modules_3.ParamCalculability.FREE; this.prms.Y.calculability = internal_modules_3.ParamCalculability.FREE; } Solve(sVarCalc, rInit) { const res = super.Solve(sVarCalc, rInit); // if Y has log about a failure in calc chain, copy it to // a resultElement so that Nub.Calc() does not complain if (res.resultElements.length === 0) { const re = new internal_modules_7.ResultElement(); re.log.addLog(res.globalLog); res.addResultElement(re); } return res; } } exports.Solveur = Solveur; //# sourceMappingURL=solveur.js.map