Files
machineGroupControl/test/basic/bestCombination.basic.test.js

68 lines
2.6 KiB
JavaScript
Raw Normal View History

const test = require('node:test');
const assert = require('node:assert/strict');
const { calcBestCombination } = require('../../src/optimizer/bestCombination');
function makeMachine({ id, fMin = 0, fMax = 100, NCog = 0.5, costFn } = {}) {
return {
config: { general: { id } },
NCog,
predictFlow: { currentFxyYMin: fMin, currentFxyYMax: fMax },
predictPower: { currentFxyYMin: 0, currentFxyYMax: fMax * 2 },
// Power model: caller picks the cost function so we can shape who wins.
inputFlowCalcPower: costFn ?? ((flow) => flow * 1.0),
};
}
function mkCtx(machines) {
return {
machines,
groupCurves: {
groupFlow: (m) => m.predictFlow,
groupPower: (m) => m.predictPower,
groupNCog: (m) => m.NCog ?? 0,
groupCalcPower: (m, f) => m.inputFlowCalcPower(f),
},
logger: { debug: () => {} },
};
}
test('calcBestCombination: 1 machine in combination receives Qd clamped to its range', () => {
const machines = { a: makeMachine({ id: 'a', fMin: 5, fMax: 60 }) };
const ctx = mkCtx(machines);
const res = calcBestCombination([['a']], 40, ctx);
assert.ok(res.bestCombination);
assert.equal(res.bestCombination.length, 1);
assert.equal(res.bestCombination[0].flow, 40);
// Above max — clamps to max.
const high = calcBestCombination([['a']], 200, ctx);
assert.equal(high.bestCombination[0].flow, 60);
});
test('calcBestCombination: 2 machines with equal NCog split flow evenly', () => {
const machines = {
a: makeMachine({ id: 'a', NCog: 0.5, fMin: 0, fMax: 100 }),
b: makeMachine({ id: 'b', NCog: 0.5, fMin: 0, fMax: 100 }),
};
const ctx = mkCtx(machines);
const res = calcBestCombination([['a', 'b']], 40, ctx);
const aFlow = res.bestCombination.find(e => e.machineId === 'a').flow;
const bFlow = res.bestCombination.find(e => e.machineId === 'b').flow;
assert.ok(Math.abs(aFlow - bFlow) < 1e-6, `expected even split, got a=${aFlow} b=${bFlow}`);
assert.ok(Math.abs(aFlow + bFlow - 40) < 1e-6);
});
test('calcBestCombination: returns combination with the lowest total power', () => {
// Two combinations: [a] (expensive) vs [b] (cheap). Both can deliver Qd=20.
const machines = {
a: makeMachine({ id: 'a', fMin: 0, fMax: 100, costFn: (f) => f * 10 }),
b: makeMachine({ id: 'b', fMin: 0, fMax: 100, costFn: (f) => f * 1 }),
};
const ctx = mkCtx(machines);
const res = calcBestCombination([['a'], ['b']], 20, ctx);
assert.equal(res.bestCombination[0].machineId, 'b');
assert.equal(res.bestPower, 20);
});