jalhyd
Version:
JaLHyd, a Javascript Library for Hydraulics
383 lines • 15.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Pab = 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");
const internal_modules_9 = require("../internal_modules");
const internal_modules_10 = require("../internal_modules");
const internal_modules_11 = require("../internal_modules");
const internal_modules_12 = require("../internal_modules");
const internal_modules_13 = require("../internal_modules");
class Pab extends internal_modules_13.FishPass {
constructor(prms, downWall, dbg = false) {
super(prms, dbg);
this.downWall = downWall;
this.setCalculatorType(internal_modules_1.CalculatorType.Pab);
}
/**
* paramètres castés au bon type
*/
get prms() {
return this._prms;
}
/**
* enfants castés au bon type
*/
get children() {
return this._children;
}
/**
* @returns iterator on all child nubs (may include extra nubs, see Pab nub)
* @see Nub.directChildNubIterator()
*/
directChildNubIterator() {
// clone children array
const arr = Object.assign([], this.children);
// append wall at downstream
arr.push(this._downWall);
// iterator
return arr[Symbol.iterator]();
}
get downWall() {
return this._downWall;
}
set downWall(dw) {
this._downWall = dw;
if (dw) { // might be undefined
dw.setParent(this); // important
// postprocessing
this.adjustDownwallParameters(this.downWall);
}
}
/**
* Add Cloisons to the PAB from a cloison model
* @param cloisonModel Cloison model parametrised as first upstream basin
* @param n Number of walls (or falls) of the PAB (Number of basin = n - 1)
*/
addCloisonsFromModel(cloisonModel, n) {
// Fix some parameters of the upstream cloison (= Wall + basin)
const DH = cloisonModel.prms.DH.currentValue;
const ZRMB = this.prms.Z1.currentValue - cloisonModel.prms.PB.currentValue - DH;
const ZRAM = ZRMB + DH / 2;
// Generate an image of the object for multiplication
// Use 2nd param as a trick to break links and copy values
const serialisedCloisonModel = cloisonModel.serialise(undefined, [cloisonModel.uid]);
for (let i = 0; i < n; i++) {
const cl = internal_modules_2.Session.getInstance().unserialiseSingleNub(serialisedCloisonModel, false).nub;
cl.setUid(internal_modules_2.JalhydObject.nextUID); // prevent all Cloisons having the same UID
const p = cl.prms;
// Copy calculated param to the new Cloison #130
cl.calculatedParam.singleValue = cloisonModel.calculatedParam.V;
p.ZRMB.singleValue = ZRMB - i * DH;
p.ZRAM.singleValue = ZRAM - i * DH;
p.QA.singleValue = 0; // set QA (attraction flow) to 0 (jalhyd #317)
// Set Structure ZDVs
for (const st of cl.structures) {
if (st.isZDVcalculable) {
st.prms.ZDV.singleValue = (this.prms.Z1.currentValue - st.prms.h1.currentValue) - i * DH;
if (st.getParameter("ZT") !== undefined) {
const stTT = st;
stTT.prms.ZT.singleValue = stTT.prms.ZT.currentValue - i * DH;
}
}
}
if (i !== n - 1) {
// Add wall + basin = cloison
this.addChild(cl);
}
else {
// The last wall is a CloisonAval (= Wall only, without basin)
const zram = this.children[this.children.length - 1].prms.ZRMB.singleValue
- this.children[this.children.length - 1].prms.DH.singleValue / 2;
const dw = new internal_modules_11.CloisonAval(new internal_modules_12.CloisonsAvalParams(0, 0, 0, zram));
dw.structures = cl.structures;
this.downWall = dw;
}
}
}
CalcSerie(rInit) {
if (!this.downWall.checkVanneLevante()) {
this._result = new internal_modules_9.Result(undefined, this);
this._result.globalLog.insert(new internal_modules_8.Message(internal_modules_8.MessageCode.ERROR_CLOISON_AVAL_UN_OUVRAGE_REGULE));
return this._result;
}
return super.CalcSerie(rInit);
}
/**
* @param sVarCalc Calcul
*/
Calc(sVarCalc, rInit) {
const r = new internal_modules_9.Result(new internal_modules_10.ResultElement());
if (!this.downWall.checkVanneLevante()) {
r.resultElement.addMessage(new internal_modules_8.Message(internal_modules_8.MessageCode.ERROR_CLOISON_AVAL_UN_OUVRAGE_REGULE));
}
if (sVarCalc === "Q") {
if (this.prms.Z1.v < this.prms.Z2.v) {
r.resultElement.addMessage(new internal_modules_8.Message(internal_modules_8.MessageCode.ERROR_PAB_Z1_LOWER_THAN_Z2));
}
this.children[0].prms.Z1.v = this.prms.Z1.v;
this.children[0].prms.Z2.v = -Infinity;
if (this.children[0].CalcQ().vCalc < 1E-7) {
r.resultElement.addMessage(new internal_modules_8.Message(internal_modules_8.MessageCode.ERROR_PAB_Z1_LOWER_THAN_UPSTREAM_WALL));
}
}
if (r.hasErrorMessages()) {
this.currentResultElement = r;
return this.result;
}
return super.Calc(sVarCalc, rInit);
}
/**
* add upstream/downstream head and submergence extra results to a parallel structure result
* (except for orifices)
*/
addWallResults(cl) {
for (const st of cl.structures) {
if (!st.isOrifice) {
const re = st.result.resultElement;
const h1 = st.prms.h1.v;
re.addExtraResult("H1", h1);
const h2 = st.prms.h2.v;
re.addExtraResult("H2", h2);
const subm = st.result.values.SUBMERGENCE;
re.addExtraResult("SUBMERGENCE", subm);
}
}
}
/**
* Calcul analytique
* @warning Should be called by this.Calc only for parameter initialisations
* @param sVarCalc Variable à calculer (Z1 uniquement)
*/
Equation(sVarCalc) {
const r = new internal_modules_9.Result(0, this);
// Up to down course : discharge distribution and bottom elevation
if (this.children.length > 0) {
this.children[0].prms.Q.v = this.prms.Q.v;
}
let l = 0; // Length of the fishway and wall abscissae
for (let i = 0; i < this.children.length; i++) {
let wall;
if (i !== this.children.length - 1) {
wall = this.children[i + 1];
}
else {
wall = this.downWall;
}
l += this.children[i].prms.LB.v;
// Set discharge for the next wall from the current basin
wall.prms.Q.v = this.children[i].prms.Q.v + this.children[i].prms.QA.v;
}
// Down to up course : water surface calculation
let Z = this.prms.Z2.v;
Z = this.calcCloisonZ1(this.downWall, Z);
if (!this.downWall.result.ok) {
return new internal_modules_9.Result(new internal_modules_8.Message(internal_modules_8.MessageCode.ERROR_PAB_CALC_Z1_CLOISON_DW), this);
}
this.downWall.result.resultElement.values.Q = this.downWall.prms.Q.v;
this.downWall.result.resultElement.values.x = l;
this.debug("Downstream wall");
this.dbgWall(this.downWall);
for (let i = this.children.length - 1; i >= 0; i--) {
// Initialisations for current cloison
const cl = this.children[i];
// Calculation of upstream water elevation
cl.prms.PB.v = Z - cl.prms.ZRMB.v;
Z = this.calcCloisonZ1(cl, Z);
if (!cl.result.ok) {
const m = new internal_modules_8.Message(internal_modules_8.MessageCode.ERROR_PAB_CALC_Z1_CLOISON);
m.extraVar.n = String(cl.findPositionInParent() + 1);
return new internal_modules_9.Result(m, this);
}
// Add extraresults: mean depth in pool and discharge
cl.result.resultElement.values.YMOY = cl.prms.PB.v;
cl.result.resultElement.values.Q = cl.prms.Q.v;
cl.result.resultElement.values.QA = cl.prms.QA.v;
l -= cl.prms.LB.v;
cl.result.resultElement.values.x = l;
// Add h1, h2 and submergence to results
this.addWallResults(cl);
this.debug("Bassin n°" + i);
this.dbgWall(cl);
}
// Add h1, h2 and submergence to results for downstream wall
this.addWallResults(this._downWall);
r.vCalc = Z;
return r;
}
get calculableParameters() {
const calcPrms = super.calculableParameters.filter((p) => p.nubCalcType === internal_modules_1.CalculatorType.Pab);
return calcPrms;
}
/**
* Returns an iterator over :
* - own parameters (this._prms)
* - children parameters (this._children[*]._prms)
* Special treatment for PAB's downwall
*/
get parameterIterator() {
const prms = [];
prms.push(this._prms);
if (this._children) {
internal_modules_4.Nub.concatPrms(prms, this.childrenPrms);
}
if (this.downWall) {
internal_modules_4.Nub.concatPrms(prms, this.downWall.childrenPrms);
}
return new internal_modules_6.ParamsEquationArrayIterator(prms);
}
/**
* Returns an object representation of the Nub's current state
* @param extra extra key-value pairs, for ex. calculator title in GUI
*/
objectRepresentation(extra) {
// regular serialization
const ret = super.objectRepresentation(extra, []);
// downwall
ret.downWall = this.downWall.objectRepresentation(undefined, []);
return ret;
}
/**
* Fills the current Nub with parameter values, provided an object representation
* @param obj object representation of a Nub content (parameters)
* @returns the calculated parameter found, if any - used by child Nub to notify
* its parent of the calculated parameter to set
*/
loadObjectRepresentation(obj) {
// return value
const ret = super.loadObjectRepresentation(obj);
// load downwall if any
if (obj.downWall) {
// decode properties
const props = internal_modules_7.Props.invertEnumKeysAndValuesInProperties(obj.downWall.props, true);
// create the Nub
const dw = internal_modules_2.Session.getInstance().createNub(new internal_modules_7.Props(props), this);
// try to keep the original ID
if (!internal_modules_2.Session.getInstance().uidAlreadyUsed(obj.downWall.uid)) {
dw.setUid(obj.downWall.uid);
}
const childRet = dw.loadObjectRepresentation(obj.downWall);
// add downWall to parent
this.downWall = dw;
// forward errors
if (childRet.hasErrors) {
ret.hasErrors = true;
}
}
return ret;
}
/**
* Adds a new empty resultElement to the current Result object, so that
* computation result is stored into it, via set currentResult(); does
* the same for all children and downWall
*/
initNewResultElement() {
super.initNewResultElement();
this.downWall.initNewResultElement();
}
/**
* Sets this._result to a new empty Result, before starting a new CalcSerie();
* does the same for all children and downWall
*/
reinitResult() {
super.reinitResult();
this.downWall.reinitResult();
}
/**
* Only Q and Z1 are calculable (see #108)
*/
findFirstCalculableParameter(otherThan) {
for (const p of [this.prms.Q, this.prms.Z1]) {
if (p !== otherThan
&& p.valueMode !== internal_modules_3.ParamValueMode.CALCUL // event LINK might be reset here
) {
return p;
}
}
throw new Error(`PAB : no calculable parameter found other than ${otherThan ? otherThan.symbol : "undefined"}`);
}
/**
* paramétrage de la calculabilité des paramètres
*/
setParametersCalculability() {
this.prms.Z1.calculability = internal_modules_5.ParamCalculability.EQUATION;
this.prms.Z2.calculability = internal_modules_5.ParamCalculability.FREE;
this.prms.Q.calculability = internal_modules_5.ParamCalculability.DICHO;
}
/**
* Remove Calculability of DH for not updating Z2 during calculation; adjust
* visibility for PAB display and serialisation
* @param child Cloison newly added to the PAB
*/
adjustChildParameters(child) {
child.prms.QA.visible = true;
child.prms.ZRAM.visible = true;
child.prms.ZRMB.visible = true;
child.prms.Q.visible = false;
child.prms.Z1.visible = false;
child.prms.PB.visible = false;
child.prms.DH.visible = false;
for (const st of child.structures) {
if (st.prms.h1.visible) {
// Set parameter visibility for ZDV and h1 in PAB context
st.prms.ZDV.visible = true;
st.prms.h1.visible = false;
}
}
}
/**
* Remove visibility of downwall hydraulic parameters, for serialisation
* @param dw
*/
adjustDownwallParameters(dw) {
dw.prms.Q.visible = false;
dw.prms.Z1.visible = false;
dw.prms.Z2.visible = false;
for (const st of dw.structures) {
if (st.prms.h1.visible) {
// Set parameter visibility for ZDV and h1 in PAB context
st.prms.ZDV.visible = true;
st.prms.h1.visible = false;
}
}
}
calcCloisonZ1(cl, Z) {
// Initialisations for current cloison
cl.prms.Z2.v = Z;
// Calculation of upstream water elevation
cl.Calc("Z1", Z + 0.1);
// Fall on this wall
cl.result.resultElement.values.DH = cl.result.vCalc - cl.prms.Z2.v;
// Return Update elevation for next pool
return cl.result.vCalc;
}
dbgWall(cl) {
if (!this.DBG) {
return;
}
let s = "";
for (const p of cl.prms) {
s += p.symbol + " = " + p.v + "; ";
}
this.debug(s);
for (const c of cl.getChildren()) {
this.debug("Ouvrage");
s = "";
for (const p of c.prms) {
if (p.visible) {
s += "*";
}
s += p.symbol + " = " + p.v + "; ";
}
this.debug(s);
}
}
}
exports.Pab = Pab;
//# sourceMappingURL=pab.js.map