diff --git a/index.js b/index.js index 6039c02..20d5764 100644 --- a/index.js +++ b/index.js @@ -26,6 +26,7 @@ const predict = require('./src/predict/predict_class.js'); const interpolation = require('./src/predict/interpolation.js'); const childRegistrationUtils = require('./src/helper/childRegistrationUtils.js'); const { loadCurve } = require('./datasets/assetData/curves/index.js'); +const { POSITIONS, POSITION_VALUES, isValidPosition } = require('./src/constants/positions.js'); const Fysics = require('./src/convert/fysics.js'); // Gravity helper (used by rotatingMachine for efficiency calculations) @@ -52,5 +53,8 @@ module.exports = { MenuManager, childRegistrationUtils, loadCurve, - gravity + gravity, + POSITIONS, + POSITION_VALUES, + isValidPosition }; diff --git a/src/configs/reactor.json b/src/configs/reactor.json new file mode 100644 index 0000000..879a4cf --- /dev/null +++ b/src/configs/reactor.json @@ -0,0 +1,202 @@ +{ + "general": { + "name": { + "default": "Reactor", + "rules": { + "type": "string", + "description": "A human-readable name for this reactor." + } + }, + "id": { + "default": null, + "rules": { + "type": "string", + "nullable": true, + "description": "Unique identifier for this reactor node." + } + }, + "unit": { + "default": null, + "rules": { + "type": "string", + "nullable": true, + "description": "Default measurement unit." + } + }, + "logging": { + "logLevel": { + "default": "info", + "rules": { + "type": "enum", + "values": [ + { "value": "debug", "description": "Verbose diagnostic messages." }, + { "value": "info", "description": "General informational messages." }, + { "value": "warn", "description": "Warning messages." }, + { "value": "error", "description": "Error level messages only." } + ] + } + }, + "enabled": { + "default": true, + "rules": { + "type": "boolean", + "description": "Enable or disable logging." + } + } + } + }, + "functionality": { + "softwareType": { + "default": "reactor", + "rules": { + "type": "string", + "description": "Software type identifier for parent-child registration." + } + }, + "role": { + "default": "Biological reactor for wastewater treatment", + "rules": { + "type": "string", + "description": "Describes the functional role of this node." + } + }, + "positionVsParent": { + "default": "atEquipment", + "rules": { + "type": "enum", + "values": [ + { "value": "upstream", "description": "Upstream of parent equipment." }, + { "value": "atEquipment", "description": "At equipment level." }, + { "value": "downstream", "description": "Downstream of parent equipment." } + ] + } + } + }, + "reactor": { + "reactor_type": { + "default": "CSTR", + "rules": { + "type": "enum", + "values": [ + { "value": "CSTR", "description": "Continuous Stirred Tank Reactor - fully mixed." }, + { "value": "PFR", "description": "Plug Flow Reactor - spatial gradient along length." } + ] + } + }, + "volume": { + "default": 1000, + "rules": { + "type": "number", + "min": 0, + "unit": "m3", + "description": "Reactor volume in cubic meters." + } + }, + "length": { + "default": 10, + "rules": { + "type": "number", + "min": 0, + "unit": "m", + "description": "Reactor length (relevant for PFR spatial discretization)." + } + }, + "resolution_L": { + "default": 10, + "rules": { + "type": "integer", + "min": 1, + "description": "Number of spatial segments for PFR discretization." + } + }, + "alpha": { + "default": 0.5, + "rules": { + "type": "number", + "min": 0, + "max": 1, + "description": "Dispersion coefficient alpha (0 = plug flow, 1 = fully mixed)." + } + }, + "n_inlets": { + "default": 1, + "rules": { + "type": "integer", + "min": 1, + "description": "Number of inlet points along the reactor." + } + }, + "kla": { + "default": 0, + "rules": { + "type": "number", + "min": 0, + "unit": "1/h", + "description": "Oxygen mass transfer coefficient (KLa)." + } + }, + "timeStep": { + "default": 0.001, + "rules": { + "type": "number", + "min": 0.0001, + "unit": "h", + "description": "Integration time step for the reactor model." + } + } + }, + "initialState": { + "S_O": { + "default": 0, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial dissolved oxygen concentration." } + }, + "S_I": { + "default": 30, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial inert soluble COD." } + }, + "S_S": { + "default": 70, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial readily biodegradable substrate." } + }, + "S_NH": { + "default": 25, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial ammonium nitrogen." } + }, + "S_N2": { + "default": 0, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial dinitrogen (N2)." } + }, + "S_NO": { + "default": 0, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial nitrate and nitrite nitrogen." } + }, + "S_HCO": { + "default": 5, + "rules": { "type": "number", "unit": "mmol/L", "description": "Initial alkalinity (bicarbonate)." } + }, + "X_I": { + "default": 1000, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial inert particulate COD." } + }, + "X_S": { + "default": 100, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial slowly biodegradable substrate." } + }, + "X_H": { + "default": 2000, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial heterotrophic biomass." } + }, + "X_STO": { + "default": 0, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial stored COD in biomass." } + }, + "X_A": { + "default": 200, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial autotrophic biomass." } + }, + "X_TS": { + "default": 3500, + "rules": { "type": "number", "unit": "mg/L", "description": "Initial total suspended solids." } + } + } + } diff --git a/src/configs/settler.json b/src/configs/settler.json new file mode 100644 index 0000000..1da85d5 --- /dev/null +++ b/src/configs/settler.json @@ -0,0 +1,75 @@ +{ + "general": { + "name": { + "default": "Settler", + "rules": { + "type": "string", + "description": "A human-readable name for this settler." + } + }, + "id": { + "default": null, + "rules": { + "type": "string", + "nullable": true, + "description": "Unique identifier for this settler node." + } + }, + "unit": { + "default": null, + "rules": { + "type": "string", + "nullable": true, + "description": "Default measurement unit." + } + }, + "logging": { + "logLevel": { + "default": "info", + "rules": { + "type": "enum", + "values": [ + { "value": "debug", "description": "Verbose diagnostic messages." }, + { "value": "info", "description": "General informational messages." }, + { "value": "warn", "description": "Warning messages." }, + { "value": "error", "description": "Error level messages only." } + ] + } + }, + "enabled": { + "default": true, + "rules": { + "type": "boolean", + "description": "Enable or disable logging." + } + } + } + }, + "functionality": { + "softwareType": { + "default": "settler", + "rules": { + "type": "string", + "description": "Software type identifier for parent-child registration." + } + }, + "role": { + "default": "Secondary settler for sludge separation", + "rules": { + "type": "string", + "description": "Describes the functional role of this node." + } + }, + "positionVsParent": { + "default": "downstream", + "rules": { + "type": "enum", + "values": [ + { "value": "upstream", "description": "Upstream of parent equipment." }, + { "value": "atEquipment", "description": "At equipment level." }, + { "value": "downstream", "description": "Downstream of parent equipment." } + ] + } + } + } + } diff --git a/src/constants/positions.js b/src/constants/positions.js new file mode 100644 index 0000000..d448007 --- /dev/null +++ b/src/constants/positions.js @@ -0,0 +1,18 @@ +/** + * Canonical position constants for parent-child relationships. + * Use these instead of hardcoded strings throughout the codebase. + */ +const POSITIONS = Object.freeze({ + UPSTREAM: 'upstream', + DOWNSTREAM: 'downstream', + AT_EQUIPMENT: 'atEquipment', + DELTA: 'delta', +}); + +const POSITION_VALUES = Object.freeze(Object.values(POSITIONS)); + +function isValidPosition(pos) { + return POSITION_VALUES.includes(pos); +} + +module.exports = { POSITIONS, POSITION_VALUES, isValidPosition };