UNPKG

ccs-sim

Version:
145 lines (144 loc) 7.27 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fluid_1 = require("./fluid"); const element_1 = require("./element"); const transport_1 = __importDefault(require("./transport")); const physical_quantities_1 = require("physical-quantities"); class Splitter extends transport_1.default { constructor(name, physical, source) { super(name, physical, 'Splitter'); this.destinations = []; this.source = source; this.source.setDestination(this); } addDestination(dest) { if (dest.physical.elevation !== this.physical.elevation) throw new Error('Destination elevation does not match splitter elevation'); this.destinations.push(dest); dest.source = this; } setDestinations(destinations) { destinations.forEach((d) => this.addDestination(d)); } applyFlowrate(branch, flowrate) { return __awaiter(this, void 0, void 0, function* () { if (!this.fluid) { throw new Error('Splitter has no fluid - unable to calculate end pressure'); } const newFluid = yield fluid_1.defaultFluidConstructor(this.fluid.pressure, this.fluid.temperature, flowrate); return this.destinations[branch].process(newFluid); }); } searchBranchFlowrate(branch, fluid) { return __awaiter(this, void 0, void 0, function* () { if (!fluid) { throw new Error('Splitter has no fluid - unable to calculate end pressure'); } let low = 0; let high = fluid.flowrate.kgps; let mid = 0; const calculatedPressureBoundaries = { highFlowrate: (yield this.applyFlowrate(branch, fluid.flowrate)).pressure .bara, lowFlowrate: (yield this.applyFlowrate(branch, new physical_quantities_1.Flowrate(0, physical_quantities_1.FlowrateUnits.Kgps))).pressure.bara, }; const target = yield this.getBranchTarget(branch, fluid); if (!target) { throw new Error(`Unable to find target pressure for branch ${branch}`); } let guesses = 0; const maxGuesses = 25; let pressureSolution = element_1.PressureSolution.Low; while (pressureSolution !== element_1.PressureSolution.Ok) { if (guesses++ > maxGuesses - 1) { break; } mid = low + ((high - low) / (calculatedPressureBoundaries.highFlowrate - calculatedPressureBoundaries.lowFlowrate)) * (target.target.bara - calculatedPressureBoundaries.lowFlowrate); if (mid >= fluid.flowrate.kgps * 0.9) { return { flowrate: mid, pressureSolution }; } if (mid <= new physical_quantities_1.Flowrate(0.001, physical_quantities_1.FlowrateUnits.Kgps).kgps) { return { flowrate: mid, pressureSolution: element_1.PressureSolution.Low }; } pressureSolution = (yield this.applyFlowrate(branch, new physical_quantities_1.Flowrate(mid, physical_quantities_1.FlowrateUnits.Kgps))).pressureSolution; if (pressureSolution === element_1.PressureSolution.Low) { high = mid; } else if (pressureSolution === element_1.PressureSolution.High) { low = mid; } } return { flowrate: mid, pressureSolution }; }); } getBranchTarget(branchNum, fluid) { return __awaiter(this, void 0, void 0, function* () { let low = 0; let high = fluid.flowrate.kgps; let mid = 0; let pressureSolution = element_1.PressureSolution.Low; let guesses = 0; const maxGuesses = 25; while (pressureSolution !== element_1.PressureSolution.Ok) { if (guesses++ > maxGuesses - 1) { break; } const { pressureSolution: pSol, pressure, target, } = yield this.applyFlowrate(branchNum, new physical_quantities_1.Flowrate(mid, physical_quantities_1.FlowrateUnits.Kgps)); if (target) return { pressureSolution: pSol, pressure, target }; mid = (low + high) / 2; pressureSolution = pSol; if (pressureSolution === element_1.PressureSolution.Low) { high = mid; } else if (pressureSolution === element_1.PressureSolution.High) { low = mid; } } }); } process(fluid) { return __awaiter(this, void 0, void 0, function* () { this.fluid = fluid; const lowPressureLimit = new physical_quantities_1.Pressure(1000, physical_quantities_1.PressureUnits.Pascal).pascal; if (this.fluid.pressure.pascal < lowPressureLimit) return { pressureSolution: element_1.PressureSolution.Low, pressure: this.fluid.pressure, target: null, }; const newFluid = yield fluid_1.defaultFluidConstructor(this.fluid.pressure, this.fluid.temperature, this.fluid.flowrate); for (let i = 0; i < this.destinations.length - 1; i++) { const { flowrate, pressureSolution } = yield this.searchBranchFlowrate(i, newFluid); if (pressureSolution !== element_1.PressureSolution.Ok) { return { pressureSolution, pressure: this.fluid.pressure, target: null, }; } newFluid.flowrate = new physical_quantities_1.Flowrate(newFluid.flowrate.kgps - flowrate, physical_quantities_1.FlowrateUnits.Kgps); } const lastSearchResult = yield this.applyFlowrate(this.destinations.length - 1, newFluid.flowrate); return lastSearchResult; }); } } exports.default = Splitter;