diff --git a/src/reaction_modules/asm3_class Koch.js b/src/reaction_modules/asm3_class Koch.js index e5e98b3..0742afa 100644 --- a/src/reaction_modules/asm3_class Koch.js +++ b/src/reaction_modules/asm3_class Koch.js @@ -1,4 +1,9 @@ -const math = require('mathjs') +const math = require('mathjs'); + +const ASM_CONSTANTS = { + S_O_INDEX: 0, + NUM_SPECIES: 13 +}; /** * ASM3 class for the Activated Sludge Model No. 3 (ASM3). Using Koch et al. 2000 parameters. @@ -208,4 +213,4 @@ class ASM3 { } } -module.exports = ASM3; \ No newline at end of file +module.exports = { ASM3, ASM_CONSTANTS }; \ No newline at end of file diff --git a/src/reaction_modules/asm3_class.js b/src/reaction_modules/asm3_class.js index d228619..dc519db 100644 --- a/src/reaction_modules/asm3_class.js +++ b/src/reaction_modules/asm3_class.js @@ -1,4 +1,9 @@ -const math = require('mathjs') +const math = require('mathjs'); + +const ASM_CONSTANTS = { + S_O_INDEX: 0, + NUM_SPECIES: 13 +}; /** * ASM3 class for the Activated Sludge Model No. 3 (ASM3). @@ -208,4 +213,4 @@ class ASM3 { } } -module.exports = ASM3; \ No newline at end of file +module.exports = { ASM3, ASM_CONSTANTS }; \ No newline at end of file diff --git a/src/specificClass.js b/src/specificClass.js index 18ac54a..3f368e1 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -1,4 +1,4 @@ -const ASM3 = require('./reaction_modules/asm3_class.js'); +const { ASM3, ASM_CONSTANTS } = require('./reaction_modules/asm3_class.js'); const { create, all, isArray, i } = require('mathjs'); const { assertNoNaN } = require('./utils.js'); const { childRegistrationUtils, logger, MeasurementContainer } = require('generalFunctions'); @@ -10,8 +10,6 @@ const mathConfig = { const math = create(all, mathConfig); -const S_O_INDEX = 0; -const NUM_SPECIES = 13; const BC_PADDING = 2; const DEBUG = false; const DAY2MS = 1000 * 60 * 60 * 24; @@ -39,7 +37,7 @@ class Reactor { this.volume = config.volume; // fluid volume reactor [m3] this.Fs = [0]; // fluid debits per inlet [m3 d-1] - this.Cs_in = [Array(NUM_SPECIES).fill(0)]; // composition influents + this.Cs_in = [Array(ASM_CONSTANTS.NUM_SPECIES).fill(0)]; // composition influents this.OTR = 0.0; // oxygen transfer rate [g O2 d-1 m-3] this.temperature = 20; // temperature [C] @@ -59,7 +57,7 @@ class Reactor { if (this.Fs.length <= i_in) { this.logger.debug(`Adding new inlet index ${i_in}.`); this.Fs.push(0); - this.Cs_in.push(Array(NUM_SPECIES).fill(0)); + this.Cs_in.push(Array(ASM_CONSTANTS.NUM_SPECIES).fill(0)); this.setInfluent = input; } this.Fs[i_in] = input.payload.F; @@ -243,8 +241,8 @@ class Reactor_CSTR extends Reactor { const inflow = math.multiply(math.divide([this.Fs], this.volume), this.Cs_in)[0]; const outflow = math.multiply(-1 * math.sum(this.Fs) / this.volume, this.state); const reaction = this.asm.compute_dC(this.state, this.temperature); - const transfer = Array(NUM_SPECIES).fill(0.0); - transfer[S_O_INDEX] = isNaN(this.kla) ? this.OTR : this._calcOTR(this.state[S_O_INDEX], this.temperature); // calculate OTR if kla is not NaN, otherwise use externaly calculated OTR + const transfer = Array(ASM_CONSTANTS.NUM_SPECIES).fill(0.0); + transfer[ASM_CONSTANTS.S_O_INDEX] = isNaN(this.kla) ? this.OTR : this._calcOTR(this.state[S_O_INDEX], this.temperature); // calculate OTR if kla is not NaN, otherwise use externaly calculated OTR const dC_total = math.multiply(math.add(inflow, outflow, reaction, transfer), time_step) this.state = this._arrayClip2Zero(math.add(this.state, dC_total)); // clip value element-wise to avoid negative concentrations @@ -273,7 +271,7 @@ class Reactor_PFR extends Reactor { this.alpha = config.alpha; this.state = Array.from(Array(this.n_x), () => config.initialState.slice()); - this.extendedState = Array.from(Array(this.n_x + 2*BC_PADDING), () => new Array(NUM_SPECIES).fill(0)); + this.extendedState = Array.from(Array(this.n_x + 2*BC_PADDING), () => new Array(ASM_CONSTANTS.NUM_SPECIES).fill(0)); // initialise extended state this.state.forEach((row, i) => this.extendedState[i+BC_PADDING] = row); @@ -324,15 +322,15 @@ class Reactor_PFR extends Reactor { const dispersion = math.multiply(this.D / (this.d_x*this.d_x), this.D2_op, this.extendedState); const advection = math.multiply(-1 * math.sum(this.Fs) / (this.A*this.d_x), this.D_op, this.extendedState); const reaction = this.extendedState.map((state_slice) => this.asm.compute_dC(state_slice, this.temperature)); - const transfer = Array.from(Array(this.n_x+2*BC_PADDING), () => new Array(NUM_SPECIES).fill(0)); + const transfer = Array.from(Array(this.n_x+2*BC_PADDING), () => new Array(ASM_CONSTANTS.NUM_SPECIES).fill(0)); if (isNaN(this.kla)) { // calculate OTR if kla is not NaN, otherwise use externally calculated OTR for (let i = BC_PADDING+1; i < BC_PADDING+this.n_x - 1; i++) { - transfer[i][S_O_INDEX] = this.OTR * this.n_x/(this.n_x-2); + transfer[i][ASM_CONSTANTS.S_O_INDEX] = this.OTR * this.n_x/(this.n_x-2); } } else { for (let i = BC_PADDING+1; i < BC_PADDING+this.n_x - 1; i++) { - transfer[i][S_O_INDEX] = this._calcOTR(this.extendedState[i][S_O_INDEX], this.temperature) * this.n_x/(this.n_x-2); + transfer[i][ASM_CONSTANTS.S_O_INDEX] = this._calcOTR(this.extendedState[i][ASM_CONSTANTS.S_O_INDEX], this.temperature) * this.n_x/(this.n_x-2); } } @@ -357,7 +355,7 @@ class Reactor_PFR extends Reactor { switch(measurementType) { case "quantity (oxygen)": let grid_pos = Math.round(context.distance / this.config.length * this.n_x); - this.state[grid_pos][S_O_INDEX] = value; // naive approach for reconciling measurements and simulation + this.state[grid_pos][0] = value; // naive approach for reconciling measurements and simulation break; default: super._updateMeasurement(measurementType, value, position, context);