Refactor ASM3 module to export ASM_CONSTANTS and update references in Reactor classes
This commit is contained in:
@@ -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.
|
* 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;
|
module.exports = { ASM3, ASM_CONSTANTS };
|
||||||
@@ -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).
|
* ASM3 class for the Activated Sludge Model No. 3 (ASM3).
|
||||||
@@ -208,4 +213,4 @@ class ASM3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ASM3;
|
module.exports = { ASM3, ASM_CONSTANTS };
|
||||||
@@ -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 { create, all, isArray, i } = require('mathjs');
|
||||||
const { assertNoNaN } = require('./utils.js');
|
const { assertNoNaN } = require('./utils.js');
|
||||||
const { childRegistrationUtils, logger, MeasurementContainer } = require('generalFunctions');
|
const { childRegistrationUtils, logger, MeasurementContainer } = require('generalFunctions');
|
||||||
@@ -10,8 +10,6 @@ const mathConfig = {
|
|||||||
|
|
||||||
const math = create(all, mathConfig);
|
const math = create(all, mathConfig);
|
||||||
|
|
||||||
const S_O_INDEX = 0;
|
|
||||||
const NUM_SPECIES = 13;
|
|
||||||
const BC_PADDING = 2;
|
const BC_PADDING = 2;
|
||||||
const DEBUG = false;
|
const DEBUG = false;
|
||||||
const DAY2MS = 1000 * 60 * 60 * 24;
|
const DAY2MS = 1000 * 60 * 60 * 24;
|
||||||
@@ -39,7 +37,7 @@ class Reactor {
|
|||||||
this.volume = config.volume; // fluid volume reactor [m3]
|
this.volume = config.volume; // fluid volume reactor [m3]
|
||||||
|
|
||||||
this.Fs = [0]; // fluid debits per inlet [m3 d-1]
|
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.OTR = 0.0; // oxygen transfer rate [g O2 d-1 m-3]
|
||||||
this.temperature = 20; // temperature [C]
|
this.temperature = 20; // temperature [C]
|
||||||
|
|
||||||
@@ -59,7 +57,7 @@ class Reactor {
|
|||||||
if (this.Fs.length <= i_in) {
|
if (this.Fs.length <= i_in) {
|
||||||
this.logger.debug(`Adding new inlet index ${i_in}.`);
|
this.logger.debug(`Adding new inlet index ${i_in}.`);
|
||||||
this.Fs.push(0);
|
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.setInfluent = input;
|
||||||
}
|
}
|
||||||
this.Fs[i_in] = input.payload.F;
|
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 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 outflow = math.multiply(-1 * math.sum(this.Fs) / this.volume, this.state);
|
||||||
const reaction = this.asm.compute_dC(this.state, this.temperature);
|
const reaction = this.asm.compute_dC(this.state, this.temperature);
|
||||||
const transfer = Array(NUM_SPECIES).fill(0.0);
|
const transfer = Array(ASM_CONSTANTS.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
|
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)
|
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
|
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.alpha = config.alpha;
|
||||||
|
|
||||||
this.state = Array.from(Array(this.n_x), () => config.initialState.slice());
|
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
|
// initialise extended state
|
||||||
this.state.forEach((row, i) => this.extendedState[i+BC_PADDING] = row);
|
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 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 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 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
|
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++) {
|
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 {
|
} else {
|
||||||
for (let i = BC_PADDING+1; i < BC_PADDING+this.n_x - 1; i++) {
|
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) {
|
switch(measurementType) {
|
||||||
case "quantity (oxygen)":
|
case "quantity (oxygen)":
|
||||||
let grid_pos = Math.round(context.distance / this.config.length * this.n_x);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
super._updateMeasurement(measurementType, value, position, context);
|
super._updateMeasurement(measurementType, value, position, context);
|
||||||
|
|||||||
Reference in New Issue
Block a user