import { ParamsSection, acSection } from "./section/section_type"; import { XOR, Result, round } from "./base"; import { IParamsEquation, ParamDefinition, ParamCalculability, ComputeNodeType, ParamDomainValue } from "./param"; import { Dichotomie } from "./dichotomie"; import { Nub } from "./nub"; import { ErrorCode, ErrorMessage } from "./util/error"; import { } from "./util/"; export enum MethodeResolution { Trapezes, EulerExplicite, RungeKutta4 } /** * paramètres pour les courbes de remous */ export class CourbeRemousParams implements IParamsEquation { /** * Débit amont */ // private _Qamont: ParamDefinition; /** * Tirant imposé à l'amont */ private _Yamont: ParamDefinition; /** * Tirant imposé à l'aval */ private _Yaval: ParamDefinition; /** * Méthode de résolution de l'équation différentielle */ private _methodeResolution: MethodeResolution; // constructor(rQamont: number, rYamont: number, rYAval: number, meth: MethodeResolution) { constructor(rYamont: number, rYAval: number, meth: MethodeResolution) { // this._Qamont = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Qam', ParamDomainValue.POS, rQamont); this._Yamont = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Yam', ParamDomainValue.POS, rYamont); this._Yaval = new ParamDefinition(ComputeNodeType.CourbeRemous, 'Yav', ParamDomainValue.POS, rYAval); this._methodeResolution = meth; } // get Qamont() { // return this._Qamont; // } get Yamont() { return this._Yamont; } get Yaval() { return this._Yaval; } get methodeResolution() { return this._methodeResolution; } } /** * Calcul d'une courbe de remous */ export class CourbeRemous extends Nub { [key: string]: any; // pour pouvoir faire this['methode](); private _debugDicho: boolean = false; //const DBG = false; /// Pour loguer les messages de debug de cette classe // public $oP; /// Paramètres de la section // public $oSect; /// Section du bief // private $oLog; /// Journal de calcul /** * Pas de discrétisation de l'espace (positif en partant de l'aval, négatif en partant de l'amont) */ // private Dx: number; Dx: number; // TODO à remettre en privé // private VarCal: number; /// Variable calculée Y pour la dichotomie (intégration trapèze) private Sn: acSection; private prmSect: ParamsSection; private prmCR: CourbeRemousParams; //private HautCritique: number; // Yc de la section /** * dernière erreur rencontrée */ private _lastError: Result; // constructor(s: acSection, crp: CourbeRemousParams, log: cLog) { constructor(s: acSection, crp: CourbeRemousParams) { super(s.prms, false); this.Sn = s; this.prmSect = s.prms; this.prmCR = crp; //this.HautCritique = s.Calc("Yc", this.prmSect.Y.v); this.Sn.Calc("Yc"); } protected setParametersCalculability() { this._prms.Y.calculability = ParamCalculability.DICHO; } public Equation(sVarCalc: string): Result { if (sVarCalc == "Hs") { // Equation de l'intégration par la méthode des trapèzes // let res: number = this.Sn.Calc('Hs', this.VarCal) - this.Sn.Calc('J', this.VarCal) / 2 * this.Dx; this.Sn.Reset(); // pour forcer le calcul avec la nouvelle valeur de prmSect.Y let res: number = this.Sn.Calc('Hs') - this.Sn.Calc('J') / 2 * this.Dx; return new Result(res); } throw "CourbeRemous.Equation() : paramètre " + sVarCalc + " non pris en charge"; } public get lastError() { return this._lastError; } /** * Calcul de dy/dx (utilisé par Euler explicite et Runge-Kutta 4) * @param Y Tirant d'eau initial */ private Calc_dYdX(Y: number): number { // L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau return - (this.prmSect.If.v - this.Sn.Calc('J', Y)) / (1 - Math.pow(this.Sn.Calc('Fr', Y), 2)); } /** * Calcul du point suivant de la courbe de remous par la méthode Euler explicite. * @param Y Tirant d'eau initial * @return Tirant d'eau */ private Calc_Y_EulerExplicite(Y: number): Result { // L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau let Y2 = Y + this.Dx * this.Calc_dYdX(Y); if (XOR(this.Dx > 0, !(Y2 < this.Sn.HautCritique))) return new Result(undefined, new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE)); return new Result(Y2); } /** * Calcul du point suivant de la courbe de remous par la méthode RK4. * @param Y Tirant d'eau initial * @return Tirant d'eau */ private Calc_Y_RK4(Y: number): Result { // L'appel à Calc('J') avec Y en paramètre réinitialise toutes les données dépendantes de la ligne d'eau //$rDx = $this ->rDx; let Dx = this.Dx; //$rk1 = $this ->Calc_dYdX($Y); let k1 = this.Calc_dYdX(Y); let hc = this.Sn.HautCritique; //if ($this ->rDx > 0 xor !($Y + $rDx / 2 * $rk1 < $this ->oSect ->rHautCritique)) { return false; } if (XOR(Dx > 0, !(Y + Dx / 2 * k1 < hc))) return undefined; //$rk2 = $this ->Calc_dYdX($Y + $rDx / 2 * $rk1); let k2 = this.Calc_dYdX(Y + Dx / 2 * k1); //if ($this ->rDx > 0 xor !($Y + $rDx / 2 * $rk2 < $this ->oSect ->rHautCritique)) { return false; } if (XOR(Dx > 0, !(Y + Dx / 2 * k2 < hc))) return undefined; //$rk3 = $this ->Calc_dYdX($Y + $rDx / 2 * $rk2); let k3 = this.Calc_dYdX(Y + Dx / 2 * k2); //if ($this ->rDx > 0 xor !($Y + $rDx / 2 * $rk3 < $this ->oSect ->rHautCritique)) { return false; } if (XOR(Dx > 0, !(Y + Dx / 2 * k3 < hc))) return undefined; //$rk4 = $this ->Calc_dYdX($Y + $rDx * $rk3); let k4 = this.Calc_dYdX(Y + Dx * k3); //$Yout = $Y + $rDx / 6 * ($rk1 + 2 * ($rk2 + $rk3) + $rk4); let Yout = Y + Dx / 6 * (k1 + 2 * (k2 + k3) + k4); //if ($this ->rDx > 0 xor !($Yout < $this ->oSect ->rHautCritique)) { return false; } if (XOR(Dx > 0, !(Yout < hc))) return new Result(undefined, new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE)); return new Result(Yout); } /** * Equation de l'intégration par la méthode des trapèzes */ // private Calc_Y_Trapez_Fn(): number { // // return $this ->oSect ->Calc('Hs', $this ->VarCal) - $this ->oSect ->Calc('J', $this ->VarCal) / 2 * $this ->rDx; // return this.Sn.Calc('Hs', this.VarCal) - this.Sn.Calc('J', this.VarCal) / 2 * this.Dx; // } /** * Calcul du point suivant de la courbe de remous par la méthode de l'intégration par trapèze * @param Y Tirant d'eau initial * @return Tirant d'eau */ private Calc_Y_Trapez(Y: number): Result { //include_spip('hyd_inc/dichotomie.class'); //$this ->VarCal = &$Y; // this.VarCal = Y; // $oDicho = new cDichotomie($this ->oLog, $this, 'Calc_Y_Trapez_Fn', false); let Dicho = new Dichotomie(this, "Y", this._debugDicho, "Hs"); // Calcul de H + J * \Delta x / 2 // $Trapez_Fn = $this ->oSect ->Calc('Hs', $this ->VarCal) + $this ->oSect ->Calc('J', $this ->VarCal) / 2 * $this ->rDx; // let Trapez_Fn = this.Sn.Calc('Hs', this.VarCal) + this.Sn.Calc('J', this.VarCal) / 2 * this.Dx let Trapez_Fn = this.Sn.Calc('Hs', Y) + this.Sn.Calc('J', Y) / 2 * this.Dx // H est la charge totale. On se place dans le référentiel ou Zf de la section à calculer = 0 // $Trapez_Fn = $Trapez_Fn - $this ->rDx * $this ->oP ->rIf; Trapez_Fn -= this.Dx * this.prmSect.If.v; // list($Y2, $flag) = $oDicho ->calculer($Trapez_Fn, $this ->oP ->rPrec, $this ->oSect ->rHautCritique); // let r: Result = Dicho.Dichotomie(Trapez_Fn, this.prmSect.Prec.v, this.Sn.HautCritique); let r: Result = Dicho.Dichotomie(Trapez_Fn, this.prmSect.Prec.v, Y); // if ($flag < 0) { if (r.code != ErrorCode.ERROR_OK) return r; let Y2 = r.vCalc; // } elseif($this ->rDx > 0 xor !($Y2 < $this ->oSect ->rHautCritique)) { if (XOR(this.Dx > 0, !(Y2 < this.Sn.HautCritique))) return new Result(undefined, new ErrorMessage(ErrorCode.ERROR_REMOUS_ARRET_CRITIQUE)); return new Result(Y2); } /** * Calcul du point suivant d'une courbe de remous * @param Y Tirant d'eau initial * @return Tirant d'eau */ private Calc_Y(Y: number): Result { // let funcCalcY = 'Calc_Y_' + Resolution; // return this[funcCalcY](Y); switch (this.prmCR.methodeResolution) { case MethodeResolution.Trapezes: return this.Calc_Y_Trapez(Y); case MethodeResolution.RungeKutta4: return this.Calc_Y_RK4(Y); case MethodeResolution.EulerExplicite: return this.Calc_Y_EulerExplicite(Y); // default: // throw "CourbeRemous.Calc_Y() : type de méthode de résolution " + MethodeResolution[this.prmCR.methodeResolution] + " non pris en charge"; } } private size(o: {}): number { let res: number = 0; for (let i in o) res++; return res; } private last(o: any): any { let res: any = undefined; for (let i in o) res = o[i]; return res; } // private maxKey(o: { [key: number]: any }): number { // let res: number = - 1e+9; // for (let i in o) { // let v: number = +i; // if (v > res) // res = v; // } // return res; // } /** * Calcul d'une courbe de remous en fluvial ou torrentiel * @param YCL Condition limite amont (torrentiel) ou aval (fluvial) */ private calcul(YCL: number): { [key: number]: number } { // $trY = array(); let trY: { [key: number]: number; } = {}; //let n = -1; // let m: Map<number, number>; // if ($this ->rDx > 0) { if (this.Dx > 0) { // Calcul depuis l'aval var Deb: number = this.prmSect.Long.v; var Fin: number = 0; } else { // Calcul depuis l'amont Deb = 0; Fin = this.prmSect.Long.v; } // $dx = - $this ->rDx; let dx = - this.Dx; // spip_log($this, 'hydraulic', _LOG_DEBUG); // $trY[sprintf('%1.'.round($this ->oP ->iPrec).'f', $xDeb)] = (real)$rYCL; let lastY = YCL; trY[round(Deb, this.prmSect.iPrec.v)] = lastY; //n++; // Boucle de calcul de la courbe de remous // for ($x = $xDeb + $dx; ($dx > 0 && $x <= $xFin) || ($dx < 0 && $x >= $xFin); $x += $dx) { for (let x = Deb + dx; (dx > 0 && x <= Fin) || (dx < 0 && x >= Fin); x += dx) { // $rY = (real)$this->Calc_Y(end($trY), $sResolution); // this.debug("lastY", lastY); let rY: Result = this.Calc_Y(lastY); // this.debug("calcul : x " + x + " y " + rY.vCalc); // this.debug("trY "); // this.logObject(trY); // this.debug("end trY " + this.last(trY)); // this.debug("Yn " + this.Sn.HautNormale); // if ($rY) { if (rY.code == ErrorCode.ERROR_OK) { // if (end($trY) > $this ->oSect ->rHautNormale xor $rY > $this ->oSect ->rHautNormale) { if (XOR(lastY > this.Sn.HautNormale, rY.vCalc > this.Sn.HautNormale)) { // $this ->oLog ->Add(_T('hydraulic:pente_forte').' '.$x. ' m ('._T('hydraulic:reduire_pas').')', true); this.debug("La pente de la ligne d'eau est trop forte à l'abscisse " + x + " m (Il faudrait réduire le pas de discrétisation)"); } // $trY[sprintf('%1.'.round($this ->oP ->iPrec).'f', $x)] = $rY; trY[round(x, this.prmSect.iPrec.v)] = rY.vCalc; // n++; } else { // $this ->oLog ->Add(_T('hydraulic:arret_calcul').' '.$x. ' m'); this.debug("Arrêt du calcul : Hauteur critique atteinte à l'abscisse " + x + " m"); this._lastError = rY; break; } lastY = rY.vCalc; } return trY; } private logObject(o: { [key: number]: number }) { let ks: string[] = Object.keys(o); ks.sort((a, b) => { if (+a > +b) return 1; if (+a < +b) return -1; return 0; }); for (let k of ks) this.debug("[" + (+k).toFixed(3) + "]=" + o[+k]); } /** * @param val_a_cal nom de la variable à calculer */ public calculRemous(val_a_cal: string): { "flu": { [key: number]: number; }, "tor": { [key: number]: number; }, "trX": string[], "tRes": number[] } { // $this ->creer_section_param(); // On transforme les champs du tableau des données du formulaire en variables // extract($this ->data, EXTR_OVERWRITE | EXTR_REFS); // include_spip('hyd_inc/courbe_remous'); // $oLog = &$this ->oLog; this._lastError = undefined; // // On calcule les données pour créer un cache et afficher le résultat // $this ->oLog ->Add(_T('hydraulic:largeur_berge').' = '.format_nombre($this ->oSn ->rLargeurBerge, $this ->oP ->iPrec).' m'); // $this ->oLog ->Add(_T('hydraulic:h_critique').' = '.format_nombre($this ->oSn ->CalcGeo('Yc'), $this ->oP ->iPrec).' m'); // $this ->oLog ->Add(_T('hydraulic:h_normale').' = '.format_nombre($this ->oSn ->CalcGeo('Yn'), $this ->oP ->iPrec).' m'); let Yc: number = this.Sn.Calc("Yc"); this.debug("largeur berge " + this.Sn.Calc("B")); this.debug("hauteur critique " + Yc); this.Sn.HautNormale = this.Sn.Calc("Yn"); this.debug("hauteur normale " + this.Sn.HautNormale); // Calcul des courbes de remous // $aC = array(); // deux items (Flu et Tor) composé d'un vecteur avec key=X et value=Y let crbFlu: { [key: number]: number; } = undefined; let crbTor: { [key: number]: number; } = undefined; //this.debug("HautCritique ", this.Sn.HautCritique); // Calcul depuis l'aval // if ($this ->oSn ->rHautCritique <= $rYaval) { if (this.Sn.HautCritique <= this.prmCR.Yaval.v) { // $this ->oLog ->Add(_T('hydraulic:calcul_fluvial')); this.debug("Condition limite aval (" + this.prmCR.Yaval.v + ") >= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie fluviale à partir de l'aval"); // $oCRF = new cCourbeRemous($this ->oLog, $this ->oP, $this ->oSn, $rDx); // $aC['Flu'] = $oCRF ->calcul($rYaval, $rLong, $Methode); this.Dx = this.prmSect.Dx.v; crbFlu = this.calcul(this.prmCR.Yaval.v); } else { // $this ->oLog ->Add(_T('hydraulic:pas_calcul_depuis_aval'), true); this.debug("Condition limite aval (" + this.prmCR.Yaval.v + ") < Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'aval"); } this.debug("flu "); this.logObject(crbFlu); // Calcul depuis l'amont // if ($this ->oSn ->rHautCritique >= $rYamont) { if (this.Sn.HautCritique >= this.prmCR.Yamont.v) { // $this ->oLog ->Add(_T('hydraulic:calcul_torrentiel')); this.debug("Condition limite amont (" + this.prmCR.Yamont.v + ") <= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie torrentielle à partir de l'amont"); // $oCRT = new cCourbeRemous($this ->oLog, $this ->oP, $this ->oSn, -$rDx); // $aC['Tor'] = $oCRT ->calcul($rYamont, $rLong, $Methode); this.Dx = -this.prmSect.Dx.v; crbTor = this.calcul(this.prmCR.Yamont.v); } else { // $this ->oLog ->Add(_T('hydraulic:pas_calcul_depuis_amont'), true); this.debug("Condition limite amont (" + this.prmCR.Yamont.v + ") > Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'amont"); } // spip_log($aC, 'hydraulic', _LOG_DEBUG); this.debug("tor"); this.logObject(crbTor); // Détection du ressaut hydraulique let nFlu: number = this.size(crbFlu); let nTor: number = this.size(crbTor); // $bDetectRessaut = true; // if ($bDetectRessaut && isset($aC['Flu']) && isset($aC['Tor'])) { // if (crbFlu != undefined && crbTor != undefined) { if (nFlu != 0 && nTor != 0) { // if (count($aC['Flu']) > count($aC['Tor']) || (count($aC['Flu']) == count($aC['Tor']) && $this ->oSn ->Calc('Imp', end($aC['Flu'])) > $this ->oSn ->Calc('Imp', end($aC['Tor'])))) { let xMaxFlu = crbFlu[0]; let xMaxTor = this.last(crbTor); // this.debug("end flu " + xMaxFlu); // this.debug("end tor " + xMaxTor); // this.debug("nFlu " + nFlu); // this.debug("nTor " + nTor); // this.debug("Imp flu " + this.Sn.Calc('Imp', xMaxFlu)); // this.debug("Imp tor " + this.Sn.Calc('Imp', xMaxTor)); // if (nFlu > nTor || (nFlu == nTor && this.Sn.Calc('Imp', this.last(crbFlu)) > this.Sn.Calc('Imp', this.last(crbTor)))) { if (nFlu > nTor || (nFlu == nTor && this.Sn.Calc('Imp', xMaxFlu) > this.Sn.Calc('Imp', xMaxTor))) { // La courbe fluviale va jusqu'au bout // $sCC = 'Flu'; var crbComplete = crbFlu; // courbe calculée sur tout le bief // $sCN = 'Tor'; var crbPartielle = crbTor; // courbe calculée sur une partie seulement du bief var iSens = 1; // On cherche l'aval du ressaut //$sSens = _T('hydraulic:amont'); var sSens = "amont"; this.debug("complete=flu, partielle=tor"); // this.debug("complete(flu)"); // this.debug(crbComplete); // this.debug("partielle(tor)"); // this.debug(crbPartielle); } else { // La courbe torrentielle va jusqu'au bout // $sCC = 'Tor'; crbComplete = crbTor; // $sCN = 'Flu'; crbPartielle = crbFlu; iSens = -1; // On cherche l'amont du ressaut // $sSens = _T('hydraulic:aval'); sSens = "aval"; this.debug("complete=tor, partielle=flu"); // this.debug("complete(tor)"); // this.debug(crbComplete); // this.debug("partielle(flu)"); // this.debug(crbPartielle); } // $trX = array_reverse(array_keys($aC[$sCN])); // Parcours des sections de la ligne d'eau la plus courte let trX: string[] = Object.keys(crbPartielle); if (iSens == -1) trX.sort((a, b) => { if (+a > +b) return 1; if (+a < +b) return -1; return 0; }); else trX.sort((a, b) => { if (+a > +b) return -1; if (+a < +b) return 1; return 0; }); let trXr = trX.slice(0); // copie trXr.reverse(); // this.debug("trX"); // this.debug(trX); let bRessaut = false; let Dx = this.prmSect.Dx.v; // foreach($trX as $rX) { // for (let irX in trX) { // for (let irX = 0; irX < trX.length - 1; irX++) { for (let irX = 0; irX < trX.length; irX++) { let rX: number = +trX[irX]; // this.debug("irX=" + irX); // this.debug("rX=" + rX); // this.debug("partielle[" + rX + "]=" + crbPartielle[rX]); // Calcul de l'abscisse de la section dans l'autre régime // $Yco = $this ->oSn ->Calc('Yco', $aC[$sCN][$rX]); // Y conjugué let Yco = this.Sn.Calc('Yco', crbPartielle[rX]); // Y conjugué this.debug("rX=" + rX + " Yco(Ypartiel=" + crbPartielle[rX] + ")=" + Yco); // $rLongRst = 5 * abs($aC[$sCN][$rX] - $Yco); // Longueur du ressaut let rLongRst = 5 * Math.abs(crbPartielle[rX] - Yco); // Longueur du ressaut this.debug("longueur ressaut=" + rLongRst); // $xRst = $rX + round($iSens * $rLongRst / $rDx) * $rDx; // Abscisse où comparer Yconj et Y let xRst = rX + Math.round(iSens * rLongRst / Dx) * Dx; // Abscisse où comparer Yconj et Y //let rxRst = rX + iSens * rLongRst; // Abscisse réelle du ressaut //this.debug("xRst reel=" + (rX + iSens * rLongRst)); // $xRst = sprintf('%1.'.round($this ->oP ->iPrec).'f', $xRst); xRst = round(xRst, this.prmSect.iPrec.v); this.debug("xRst=" + xRst); //spip_log("\nrX=$rX xRst=$xRst Yco=$Yco",'hydraulic',_LOG_DEBUG); // if (isset($aC[$sCC][$xRst])) { if (crbComplete[xRst] != undefined) { // Hauteur décalée de la longueur du ressaut (il faut gérer la pente du fond) // $Ydec = $aC[$sCC][$xRst] + $rLongRst * $this ->oP ->rIf * $iSens; let Ydec: number = crbComplete[xRst] + rLongRst * this.prmSect.If.v * iSens; this.debug("Ydec=" + Ydec); this.debug("imp(Ycomplet[xRst=" + xRst + "]=" + crbComplete[xRst] + ")=" + this.Sn.Calc('Imp', crbComplete[xRst])); this.debug("imp(Ypartiel[rX=" + rX + "]=" + crbPartielle[rX] + ")=" + this.Sn.Calc('Imp', crbPartielle[rX])); // spip_log("\nrX=$rX xRst=$xRst Yco=$Yco Ydec=$Ydec", 'hydraulic', _LOG_DEBUG); // if (($Yco - $Ydec) > 0) { // if (iSens == 1 ? Yco > Ydec : Yco < Ydec) { if (Yco > Ydec) { // $this ->oLog ->Add(_T('hydraulic:ressaut_hydrau', array('Xmin'=>min($rX, $xRst), 'Xmax'=>max($rX, $xRst)))); this.debug("Ressaut hydraulique détecté entre les abscisses " + Math.min(rX, xRst) + " et " + Math.max(rX, xRst)); // spip_log("rX=$rX xRst=$xRst", 'hydraulic', _LOG_DEBUG); // this.debug("rX=" + rX + " xRst=" + xRst); // Modification de la ligne d'eau CC // foreach(array_keys($aC[$sCN]) as $rXCC) { // for (let pi in crbPartielle) { // for (let pi in trXr) { for (let pi of trXr) { let rXCC: number = +pi; // this.debug("rXCC=" + rXCC); // if ($iSens * ($rXCC - $rX) < 0) { if (iSens * (rXCC - rX) < 0) { // unset($aC[$sCC][$rXCC]); delete crbComplete[rXCC]; this.debug("Modification de la ligne d'eau complète : suppression de la valeur à rX=" + rXCC); // } elseif($rXCC == $rX) { } else if (rXCC == rX) { // $aC[$sCC][$rXCC] = $aC[$sCN][$rXCC]; this.debug("Modification de la ligne d'eau complète : valeur " + crbComplete[rXCC] + " remplacée par " + crbPartielle[rXCC] + " à rX=" + rXCC); crbComplete[rXCC] = crbPartielle[rXCC]; this.debug("Fin de la modification de la ligne d'eau complète"); break; } } // Modification de la ligne d'eau CN // foreach($trX as $rXCN) { for (let xcn of trX) { let rXCN = +xcn; // this.debug("rXCN=" + rXCN); // if ($iSens * ($rXCN - $xRst) > 0) { if (iSens * (rXCN - xRst) > 0) { // unset($aC[$sCN][$rXCN]); this.debug("Modification de la ligne d'eau partielle : suppression de la valeur à rX=" + rXCN); delete crbPartielle[rXCN]; // } elseif($rXCN == $xRst) { } else if (rXCN == xRst) { // $aC[$sCN][$rXCN] = $aC[$sCC][$rXCN]; this.debug("Modification de la ligne d'eau partielle : valeur " + crbPartielle[rXCN] + " remplacée par " + crbComplete[rXCN] + " à rX=" + rXCN); crbPartielle[rXCN] = crbComplete[rXCN]; this.debug("Fin de la modification de la ligne d'eau partielle"); break; } } bRessaut = true; break; } } } if (!bRessaut) { // Le ressaut est en dehors du canal // $this ->oLog ->Add(_T('hydraulic:ressaut_dehors', array('Sens' => $sSens, 'X' => end($trX)))); this.debug("Ressaut hydraulique détecté à l'" + sSens + " de l'abscisse " + this.last(trX)); // $aC[$sCN] = array(); if (iSens == 1) crbTor = {}; else crbFlu = {}; crbPartielle = {}; // pour le log uniquement, à virer } } this.debug("complete (" + (iSens == 1 ? "flu" : "tor") + ") modifiée"); this.logObject(crbComplete); this.debug("partielle (" + (iSens == 1 ? "tor" : "flu") + ") modifiée"); this.logObject(crbPartielle); // Définition des abscisses // $trX = array(); let trX: string[] = []; // if (isset($aC['Flu'])) $trX = array_merge($trX, array_keys($aC['Flu'])); // if (crbFlu != undefined) if (nFlu != 0) trX = Object.keys(crbFlu); // if (isset($aC['Tor'])) $trX = array_merge($trX, array_keys($aC['Tor'])); // if (crbTor != undefined) if (nTor != 0) trX = trX.concat(Object.keys(crbTor)); // this.debug("trX=" + trX); // $trX = array_unique($trX, SORT_NUMERIC); // sort($trX, SORT_NUMERIC); trX.sort((a, b) => { if (+a > +b) return 1; if (+a < +b) return -1; return 0; }); // this.debug("trX tri=" + trX); trX = trX.filter((elem, index, array) => { if (index > 0) return elem != array[index - 1]; return true; }); // this.debug("trX unique=" + trX); // Calcul de la variable à calculer // $this ->data['ValCal'] = $val_a_cal; // $tRes = array(); let tRes: number[] = []; // if ($val_a_cal != 'none') { // if (val_a_cal != undefined && crbFlu != undefined && crbTor != undefined) { if (val_a_cal != undefined && nFlu != 0 && nTor != 0) { // foreach($trX as $rX) { for (let rX of trX) { // $rY = false; let rY = undefined; // if (isset($aC['Flu'][$rX]) && !isset($aC['Tor'][$rX])) { if (crbFlu[+rX] != undefined && crbTor[+rX] == undefined) { // $rY = $aC['Flu'][$rX]; rY = crbFlu[+rX]; } // if (isset($aC['Tor'][$rX])) { if (crbTor[+rX] != undefined) { // if (!isset($aC['Flu'][$rX]) || (isset($aC['Flu'][$rX]) && $aC['Flu'][$rX] == $aC['Tor'][$rX])) { if (crbFlu[+rX] == undefined || (crbFlu[+rX] != undefined && crbFlu[+rX] == crbTor[+rX])) { // $rY = $aC['Tor'][$rX]; rY = crbTor[+rX]; } // if ($rY !== false) { if (rY != undefined) // if (!in_array($val_a_cal, array('Yn', 'Yc', 'Hsc'))) { // $tRes[$rX] = $this ->oSn ->Calc($val_a_cal, $rY); // } // else { // $tRes[$rX] = $this ->oSn ->CalcGeo($val_a_cal, $rY); // } // } tRes[+rX] = this.Sn.Calc(val_a_cal, rY); } } /* return array_merge( $aC, array( 'trX' => $trX, 'tRes' => $tRes ) ); /* */ } return { "flu": crbFlu, "tor": crbTor, "trX": trX, "tRes": tRes }; } }