Refactor advanced-reactor and nodeClass for improved readability and consistency
This commit is contained in:
@@ -20,7 +20,6 @@ class nodeClass {
|
||||
this._setupClass();
|
||||
|
||||
this._attachInputHandler();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,11 +2,16 @@ const ASM3 = require('./asm3_class.js')
|
||||
const { create, all } = require('mathjs')
|
||||
|
||||
const config = {
|
||||
matrix: 'Array' // choose 'Matrix' (default) or 'Array'
|
||||
matrix: 'Array' // use Array as the matrix type
|
||||
}
|
||||
|
||||
const math = create(all, config)
|
||||
|
||||
/**
|
||||
* Assert that no NaN values are present in an array.
|
||||
* @param {Array} arr
|
||||
* @param {string} label
|
||||
*/
|
||||
function assertNoNaN(arr, label = "array") {
|
||||
if (math.isNaN(arr)) {
|
||||
throw new Error("NaN detected in ${label}!");
|
||||
@@ -133,7 +138,7 @@ class Reactor_CSTR extends Reactor {
|
||||
|
||||
const dC_total = math.multiply(math.add(dC_in, dC_out, r, t_O), 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
|
||||
return this.state;
|
||||
}
|
||||
}
|
||||
@@ -179,6 +184,24 @@ class Reactor_PFR extends Reactor {
|
||||
return { topic: "Fluent", payload: { inlet: 0, F: math.sum(this.Fs), C: this.state.at(-1) }, timestamp: this.currentTime };
|
||||
}
|
||||
|
||||
_applyBoundaryConditions(newState) {
|
||||
// apply boundary conditions
|
||||
if (math.sum(this.Fs) > 0) { // Danckwerts BC
|
||||
const BC_C_in = math.multiply(1 / math.sum(this.Fs), [this.Fs], this.Cs_in)[0];
|
||||
const BC_gradient = Array(this.n_x).fill(0.0);
|
||||
BC_gradient[0] = -1;
|
||||
BC_gradient[1] = 1;
|
||||
let Pe = this.length * math.sum(this.Fs) / (this.D * this.A)
|
||||
const BC_dispersion = math.multiply((1 - (1 + 4 * this.volume / math.sum(this.Fs) / Pe) ^ 0.5) / Pe, [BC_gradient], stateNew)[0];
|
||||
newState[0] = math.add(BC_C_in, BC_dispersion).map(val => val < 0 ? 0 : val);
|
||||
} else { // Neumann BC (no flux)
|
||||
newState[0] = newState[1];
|
||||
}
|
||||
// Neumann BC (no flux)
|
||||
newState[this.n_x - 1] = newState[this.n_x - 2]
|
||||
return newState
|
||||
}
|
||||
|
||||
/**
|
||||
* Tick the reactor state using explicit finite difference method.
|
||||
* @param {number} time_step - Time step for the simulation [d].
|
||||
@@ -201,30 +224,16 @@ class Reactor_PFR extends Reactor {
|
||||
}
|
||||
|
||||
const dC_total = math.multiply(math.add(dispersion, advection, reaction, transfer), time_step);
|
||||
const new_state = math.add(this.state, dC_total);
|
||||
let stateNew = math.add(this.state, dC_total);
|
||||
|
||||
assertNoNaN(new_state, "new state");
|
||||
assertNoNaN(stateNew, "new state");
|
||||
|
||||
// apply boundary conditions
|
||||
if (math.sum(this.Fs) > 0) { // Danckwerts BC
|
||||
const BC_C_in = math.multiply(1/math.sum(this.Fs), [this.Fs], this.Cs_in)[0];
|
||||
const BC_gradient = Array(this.n_x).fill(0.0);
|
||||
BC_gradient[0] = -1;
|
||||
BC_gradient[1] = 1;
|
||||
let Pe = this.length*math.sum(this.Fs)/(this.D*this.A)
|
||||
const BC_dispersion = math.multiply((1-(1+4*this.volume/math.sum(this.Fs)/Pe)^0.5)/Pe, [BC_gradient], new_state)[0];
|
||||
new_state[0] = math.add(BC_C_in, BC_dispersion).map(val => val < 0 ? 0 : val);
|
||||
stateNew = this._applyBoundaryConditions(stateNew);
|
||||
|
||||
} else { // Neumann BC (no flux)
|
||||
new_state[0] = new_state[1];
|
||||
}
|
||||
// Neumann BC (no flux)
|
||||
new_state[this.n_x-1] = new_state[this.n_x-2]
|
||||
assertNoNaN(stateNew, "new state post BC");
|
||||
|
||||
assertNoNaN(new_state, "new state post BC");
|
||||
|
||||
this.state = this._arrayClip2Zero(new_state);
|
||||
return new_state;
|
||||
this.state = this._arrayClip2Zero(stateNew);
|
||||
return stateNew;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user