Compare commits
5 Commits
3aea0e55c4
...
boundary-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f44bac9aab | ||
| 1dc9cd0031 | |||
| 2a520be33b | |||
| baecf2f599 | |||
| cd3a19e66f |
@@ -46,7 +46,7 @@ class Reactor {
|
|||||||
|
|
||||||
this.currentTime = Date.now(); // milliseconds since epoch [ms]
|
this.currentTime = Date.now(); // milliseconds since epoch [ms]
|
||||||
this.timeStep = 1 / (24*60*60) * this.config.timeStep; // time step in seconds, converted to days.
|
this.timeStep = 1 / (24*60*60) * this.config.timeStep; // time step in seconds, converted to days.
|
||||||
this.speedUpFactor = 60; // speed up factor for simulation, 60 means 1 minute per simulated second
|
this.speedUpFactor = 100; // speed up factor for simulation, 60 means 1 minute per simulated second
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,12 +124,7 @@ class Reactor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let position;
|
const position = measurementChild.config.functionality.positionVsParent;
|
||||||
if (measurementChild.config.functionality.distance !== 'undefined') {
|
|
||||||
position = measurementChild.config.functionality.distance;
|
|
||||||
} else {
|
|
||||||
position = measurementChild.config.functionality.positionVsParent;
|
|
||||||
}
|
|
||||||
const measurementType = measurementChild.config.asset.type;
|
const measurementType = measurementChild.config.asset.type;
|
||||||
const eventName = `${measurementType}.measured.${position}`;
|
const eventName = `${measurementType}.measured.${position}`;
|
||||||
|
|
||||||
@@ -155,6 +150,14 @@ class Reactor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reactorChild.functionality.positionVsParent != "upstream") {
|
||||||
|
this.logger.warn("Reactor children of reactors should always be upstream.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (math.abs(reactorChild.d_x - this.d_x) / this.d_x < 0.025) {
|
||||||
|
this.logger.warn("Significant grid sizing discrepancies between adjacent reactors! Change resolutions to match reactors grid step, or implement boundary value interpolation.");
|
||||||
|
}
|
||||||
|
|
||||||
this.upstreamReactor = reactorChild;
|
this.upstreamReactor = reactorChild;
|
||||||
reactorChild.downstreamReactor = this;
|
reactorChild.downstreamReactor = this;
|
||||||
|
|
||||||
@@ -271,15 +274,16 @@ class Reactor_PFR extends Reactor {
|
|||||||
* @param {object} input - Input object (msg) containing payload with dispersion value [m2 d-1].
|
* @param {object} input - Input object (msg) containing payload with dispersion value [m2 d-1].
|
||||||
*/
|
*/
|
||||||
set setDispersion(input) {
|
set setDispersion(input) {
|
||||||
this.D = input.payload;
|
this.D = this._constrainDispersion(input.payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(newTime) {
|
updateState(newTime) {
|
||||||
super.updateState(newTime);
|
super.updateState(newTime);
|
||||||
let Pe_local = this.d_x*math.sum(this.Fs)/(this.D*this.A)
|
// let Pe_local = this.d_x*math.sum(this.Fs)/(this.D*this.A)
|
||||||
|
this.D = this._constrainDispersion(this.D);
|
||||||
let Co_D = this.D*this.timeStep/(this.d_x*this.d_x);
|
let Co_D = this.D*this.timeStep/(this.d_x*this.d_x);
|
||||||
|
|
||||||
(Pe_local >= 2) && this.logger.warn(`Local Péclet number (${Pe_local}) is too high! Increase reactor resolution.`);
|
// (Pe_local >= 2) && this.logger.warn(`Local Péclet number (${Pe_local}) is too high! Increase reactor resolution.`);
|
||||||
(Co_D >= 0.5) && this.logger.warn(`Courant number (${Co_D}) is too high! Reduce time step size.`);
|
(Co_D >= 0.5) && this.logger.warn(`Courant number (${Co_D}) is too high! Reduce time step size.`);
|
||||||
|
|
||||||
if(DEBUG) {
|
if(DEBUG) {
|
||||||
@@ -301,7 +305,7 @@ 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.temperrature));
|
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(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
|
||||||
@@ -310,7 +314,7 @@ class Reactor_PFR extends Reactor {
|
|||||||
}
|
}
|
||||||
} 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.state[i][S_O_INDEX], this.temperature) * this.n_x/(this.n_x-2);
|
transfer[i][S_O_INDEX] = this._calcOTR(this.extendedState[i][S_O_INDEX], this.temperature) * this.n_x/(this.n_x-2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,13 +331,14 @@ class Reactor_PFR extends Reactor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.state = this._arrayClip2Zero(stateNew);
|
this.state = this._arrayClip2Zero(stateNew);
|
||||||
|
this.state.forEach((row, i) => this.extendedState[i+BC_PADDING] = row);
|
||||||
return stateNew;
|
return stateNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateMeasurement(measurementType, value, position, context) {
|
_updateMeasurement(measurementType, value, position, context) {
|
||||||
switch(measurementType) {
|
switch(measurementType) {
|
||||||
case "quantity (oxygen)":
|
case "quantity (oxygen)":
|
||||||
let grid_pos = Math.round(position / 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][S_O_INDEX] = value; // naive approach for reconciling measurements and simulation
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -356,8 +361,11 @@ class Reactor_PFR extends Reactor {
|
|||||||
const BC_C_in = math.multiply(1 / math.sum(this.Fs), [this.Fs], this.Cs_in)[0];
|
const BC_C_in = math.multiply(1 / math.sum(this.Fs), [this.Fs], this.Cs_in)[0];
|
||||||
const BC_dispersion_term = (1-this.alpha)*this.D*this.A/(math.sum(this.Fs)*this.d_x);
|
const BC_dispersion_term = (1-this.alpha)*this.D*this.A/(math.sum(this.Fs)*this.d_x);
|
||||||
this.extendedState[BC_PADDING] = math.multiply(1/(1+BC_dispersion_term), math.add(BC_C_in, math.multiply(BC_dispersion_term, this.extendedState[BC_PADDING+1])));
|
this.extendedState[BC_PADDING] = math.multiply(1/(1+BC_dispersion_term), math.add(BC_C_in, math.multiply(BC_dispersion_term, this.extendedState[BC_PADDING+1])));
|
||||||
|
this.extendedState[BC_PADDING-1] = math.add(math.multiply(2, this.extendedState[BC_PADDING]), math.multiply(-2, this.extendedState[BC_PADDING+2]), this.extendedState[BC_PADDING+3]);
|
||||||
} else {
|
} else {
|
||||||
this.extendedState[BC_PADDING] = this.extendedState[BC_PADDING+1];
|
for (let i = 0; i < BC_PADDING; i++) {
|
||||||
|
this.extendedState[i] = this.extendedState[BC_PADDING];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,8 +379,6 @@ class Reactor_PFR extends Reactor {
|
|||||||
this.extendedState[BC_PADDING+this.n_x+i] = this.extendedState.at(-1-BC_PADDING);
|
this.extendedState[BC_PADDING+this.n_x+i] = this.extendedState.at(-1-BC_PADDING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state.forEach((row, i) => this.extendedState[i+BC_PADDING] = row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -405,6 +411,15 @@ class Reactor_PFR extends Reactor {
|
|||||||
D2.forEach((row, i) => i < BC_PADDING || i >= this.n_x+BC_PADDING ? row.fill(0) : row);
|
D2.forEach((row, i) => i < BC_PADDING || i >= this.n_x+BC_PADDING ? row.fill(0) : row);
|
||||||
return D2;
|
return D2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_constrainDispersion(D) {
|
||||||
|
const Dmin = math.sum(this.Fs) * this.d_x / (1.999 * this.A);
|
||||||
|
if (D < Dmin) {
|
||||||
|
this.logger.warn(`Local Péclet number too high! Constraining given dispersion (${D}) to minimal value (${Dmin}).`);
|
||||||
|
return Dmin;
|
||||||
|
}
|
||||||
|
return D;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { Reactor_CSTR, Reactor_PFR };
|
module.exports = { Reactor_CSTR, Reactor_PFR };
|
||||||
|
|||||||
Reference in New Issue
Block a user