affiniteitswetten toevoegen #7

Open
opened 2025-11-27 08:22:55 +00:00 by renederen · 1 comment
Owner

Debiet => Q2 (nieuwdebiet) = Q1 (huidigdebiet) * (n2(nieuwRPM) / n1(oudRPM) )
Opvoerhoogte => H2= H1 * (n2/n1)*^2
Vermogen => P1 = P1 * ( n2/n1 )^3

Q = debiet
H = verschildruk
P = Power

Debiet => Q2 (nieuwdebiet) = Q1 (huidigdebiet) * (n2(nieuwRPM) / n1(oudRPM) ) Opvoerhoogte => H2= H1 * (n2/n1)*^2 Vermogen => P1 = P1 * ( n2/n1 )^3 Q = debiet H = verschildruk P = Power
renederen self-assigned this 2025-11-27 08:23:02 +00:00
Author
Owner

// =====================================================
// Hybride pompmodel met jouw cubic/monotone splines
// -------------------------------------------------
// 1) Normaliseer velddata naar q* en h*
// q* = Q / n
// h* = H / n²
// 2) Maak spline h*(q*) → baseline pompmodel
// 3) Bereken residuals r = H_meas - H_baseline(Q, n)
// 4) Maak tweede spline r(q*) → correctiemodel
// 5) Verbeterde voorspelling: H_improved = H_baseline + r_corr(q*)
//
// Gebruik: Interpolation uit jouw generalFunctions/predict
// =====================================================

// -----------------------------------------------------
// 0. Imports / requires
// PAS DIT PAD AAN NAAR JOUW PROJECTSTRUCTUUR
// -----------------------------------------------------
const Interpolation = require('./interpolation');
// voorbeeld alternatieven:
// const Interpolation = require('generalFunctions/src/predict/interpolation');
// const Interpolation = require('../predict/interpolation');

// -----------------------------------------------------
// 1. Voorbeeld meetdata (vervang door echte velddata)
// -----------------------------------------------------
const measurements = [
// { Q: m3/h, H: m, n: rpm }
{ Q: 500, H: 12.0, n: 1450 },
{ Q: 600, H: 11.3, n: 1450 },
{ Q: 700, H: 10.5, n: 1450 },
{ Q: 400, H: 8.5, n: 1160 },
{ Q: 450, H: 8.1, n: 1160 },
{ Q: 520, H: 7.6, n: 1160 },
// voeg hier al je velddata toe
];

// -----------------------------------------------------
// 2. Normaliseer naar q* en h*
// q* = Q / n
// h* = H / n²
// -----------------------------------------------------
function normalizeData(rawMeasurements) {
const valid = rawMeasurements.filter(m => m.n > 0);

const normalizedPoints = valid.map(m => {
const qStar = m.Q / m.n;
const hStar = m.H / (m.n * m.n);
return { qStar, hStar };
});

return normalizedPoints;
}

const normalizedData = normalizeData(measurements);
console.log("Genormaliseerde data (q*, h*):");
console.log(normalizedData);

// -----------------------------------------------------
// 3. Baseline-spline: h*(q*)
// -----------------------------------------------------
function buildQStarHStarSpline(normalizedData) {
if (!Array.isArray(normalizedData) || normalizedData.length < 2) {
throw new Error("Te weinig punten om baseline-spline te maken");
}

// sorteer op q* oplopend
const sorted = [...normalizedData].sort((a, b) => a.qStar - b.qStar);

const qStarArray = sorted.map(p => p.qStar);
const hStarArray = sorted.map(p => p.hStar);

const spline = new Interpolation({
type: "monotone_cubic_spline", // of "cubic_spline" als je wilt
tension: 0.5
});

// let op: in jouw code heet dit load_spline(x, y, type)
spline.load_spline(qStarArray, hStarArray, "monotone_cubic_spline");

return spline;
}

const qhSpline = buildQStarHStarSpline(normalizedData);
console.log("Baseline-spline h*(q*) opgebouwd.");

// -----------------------------------------------------
// 4. Baseline voorspelling: H(Q, n)
// H_baseline = n² * h*(Q / n)
// -----------------------------------------------------
function predictHeadBaseline(Q, n, baselineSpline) {
if (n <= 0) {
throw new Error("Ongeldig toerental (n <= 0)");
}
const qStar = Q / n;
const hStar = baselineSpline.interpolate(qStar);
const H = n * n * hStar;
return H;
}

// -----------------------------------------------------
// 5. Residuals berekenen: r = H_meas - H_baseline(Q, n)
// We projecteren de fout op q* zodat we r(q*) kunnen fitten.
// -----------------------------------------------------
function computeResidualData(measurements, baselineSpline) {
const residualData = [];

measurements.forEach(m => {
if (m.n <= 0) return;

const qStar = m.Q / m.n;
const H_meas = m.H;
const H_model = predictHeadBaseline(m.Q, m.n, baselineSpline);
const r = H_meas - H_model;

residualData.push({ qStar, r });

});

return residualData;
}

const residualData = computeResidualData(measurements, qhSpline);
console.log("Residual data (q*, r = H_meas - H_baseline):");
console.log(residualData);

// -----------------------------------------------------
// 6. Residual-spline r(q*)
// Let op: in echte toepassing wil je hier eigenlijk
// cross-validation / niet dezelfde punten 2x gebruiken,
// maar voor eenvoud nemen we alles.
// -----------------------------------------------------
function buildResidualSpline(residualData) {
if (!Array.isArray(residualData) || residualData.length < 3) {
console.warn("Te weinig punten voor residual-spline, skip.");
return null;
}

const sorted = [...residualData].sort((a, b) => a.qStar - b.qStar);

const qStarArray = sorted.map(p => p.qStar);
const rArray = sorted.map(p => p.r);

const residualSpline = new Interpolation({
type: "monotone_cubic_spline",
tension: 0.5
});

residualSpline.load_spline(qStarArray, rArray, "monotone_cubic_spline");

return residualSpline;
}

const residualSpline = buildResidualSpline(residualData);
if (residualSpline) {
console.log("Residual-spline r(q*) opgebouwd.");
} else {
console.log("Geen residual-spline opgebouwd (te weinig data).");
}

// -----------------------------------------------------
// 7. Verbeterde voorspelling: H_improved(Q, n)
// H_improved = H_baseline(Q, n) + r_corr(q*)
// -----------------------------------------------------
function predictHeadImproved(Q, n, baselineSpline, residualSpline) {
const H_baseline = predictHeadBaseline(Q, n, baselineSpline);

if (!residualSpline) {
// als we geen residual-spline hebben, val terug op baseline
return H_baseline;
}

const qStar = Q / n;
const r_corr = residualSpline.interpolate(qStar);

const H_improved = H_baseline + r_corr;
return H_improved;
}

// -----------------------------------------------------
// 8. Curves genereren voor een vast toerental
// - zowel baseline als improved
// -----------------------------------------------------
function generateCurvesForSpeed(n, Qmin, Qmax, steps, baselineSpline, residualSpline) {
const points = [];
const stepSize = (Qmax - Qmin) / (steps - 1);

for (let k = 0; k < steps; k++) {
const Q = Qmin + k * stepSize;
const H_base = predictHeadBaseline(Q, n, baselineSpline);
const H_impr = predictHeadImproved(Q, n, baselineSpline, residualSpline);
points.push({
Q,
n,
H_baseline: H_base,
H_improved: H_impr
});
}

return points;
}

// -----------------------------------------------------
// 9. Demo: één punt en een hele curve
// -----------------------------------------------------
const Qtest = 650;
const ntest = 1350;

const H_base_test = predictHeadBaseline(Qtest, ntest, qhSpline);
const H_impr_test = predictHeadImproved(Qtest, ntest, qhSpline, residualSpline);

console.log(\nVoorbeeld voorspelling op één punt: Q=${Qtest}, n=${ntest});
console.log( H_baseline ≈ ${H_base_test.toFixed(3)} m);
console.log( H_improved ≈ ${H_impr_test.toFixed(3)} m);

const curve1450 = generateCurvesForSpeed(1450, 400, 800, 10, qhSpline, residualSpline);
console.log("\nGegenereerde curve voor n = 1450 rpm (baseline vs improved):");
console.log(curve1450);

// =====================================================
// Einde script
// =====================================================

// ===================================================== // Hybride pompmodel met jouw cubic/monotone splines // ------------------------------------------------- // 1) Normaliseer velddata naar q* en h* // q* = Q / n // h* = H / n² // 2) Maak spline h*(q*) → baseline pompmodel // 3) Bereken residuals r = H_meas - H_baseline(Q, n) // 4) Maak tweede spline r(q*) → correctiemodel // 5) Verbeterde voorspelling: H_improved = H_baseline + r_corr(q*) // // Gebruik: Interpolation uit jouw generalFunctions/predict // ===================================================== // ----------------------------------------------------- // 0. Imports / requires // PAS DIT PAD AAN NAAR JOUW PROJECTSTRUCTUUR // ----------------------------------------------------- const Interpolation = require('./interpolation'); // voorbeeld alternatieven: // const Interpolation = require('generalFunctions/src/predict/interpolation'); // const Interpolation = require('../predict/interpolation'); // ----------------------------------------------------- // 1. Voorbeeld meetdata (vervang door echte velddata) // ----------------------------------------------------- const measurements = [ // { Q: m3/h, H: m, n: rpm } { Q: 500, H: 12.0, n: 1450 }, { Q: 600, H: 11.3, n: 1450 }, { Q: 700, H: 10.5, n: 1450 }, { Q: 400, H: 8.5, n: 1160 }, { Q: 450, H: 8.1, n: 1160 }, { Q: 520, H: 7.6, n: 1160 }, // voeg hier al je velddata toe ]; // ----------------------------------------------------- // 2. Normaliseer naar q* en h* // q* = Q / n // h* = H / n² // ----------------------------------------------------- function normalizeData(rawMeasurements) { const valid = rawMeasurements.filter(m => m.n > 0); const normalizedPoints = valid.map(m => { const qStar = m.Q / m.n; const hStar = m.H / (m.n * m.n); return { qStar, hStar }; }); return normalizedPoints; } const normalizedData = normalizeData(measurements); console.log("Genormaliseerde data (q*, h*):"); console.log(normalizedData); // ----------------------------------------------------- // 3. Baseline-spline: h*(q*) // ----------------------------------------------------- function buildQStarHStarSpline(normalizedData) { if (!Array.isArray(normalizedData) || normalizedData.length < 2) { throw new Error("Te weinig punten om baseline-spline te maken"); } // sorteer op q* oplopend const sorted = [...normalizedData].sort((a, b) => a.qStar - b.qStar); const qStarArray = sorted.map(p => p.qStar); const hStarArray = sorted.map(p => p.hStar); const spline = new Interpolation({ type: "monotone_cubic_spline", // of "cubic_spline" als je wilt tension: 0.5 }); // let op: in jouw code heet dit load_spline(x, y, type) spline.load_spline(qStarArray, hStarArray, "monotone_cubic_spline"); return spline; } const qhSpline = buildQStarHStarSpline(normalizedData); console.log("Baseline-spline h*(q*) opgebouwd."); // ----------------------------------------------------- // 4. Baseline voorspelling: H(Q, n) // H_baseline = n² * h*(Q / n) // ----------------------------------------------------- function predictHeadBaseline(Q, n, baselineSpline) { if (n <= 0) { throw new Error("Ongeldig toerental (n <= 0)"); } const qStar = Q / n; const hStar = baselineSpline.interpolate(qStar); const H = n * n * hStar; return H; } // ----------------------------------------------------- // 5. Residuals berekenen: r = H_meas - H_baseline(Q, n) // We projecteren de fout op q* zodat we r(q*) kunnen fitten. // ----------------------------------------------------- function computeResidualData(measurements, baselineSpline) { const residualData = []; measurements.forEach(m => { if (m.n <= 0) return; const qStar = m.Q / m.n; const H_meas = m.H; const H_model = predictHeadBaseline(m.Q, m.n, baselineSpline); const r = H_meas - H_model; residualData.push({ qStar, r }); }); return residualData; } const residualData = computeResidualData(measurements, qhSpline); console.log("Residual data (q*, r = H_meas - H_baseline):"); console.log(residualData); // ----------------------------------------------------- // 6. Residual-spline r(q*) // Let op: in echte toepassing wil je hier eigenlijk // cross-validation / niet dezelfde punten 2x gebruiken, // maar voor eenvoud nemen we alles. // ----------------------------------------------------- function buildResidualSpline(residualData) { if (!Array.isArray(residualData) || residualData.length < 3) { console.warn("Te weinig punten voor residual-spline, skip."); return null; } const sorted = [...residualData].sort((a, b) => a.qStar - b.qStar); const qStarArray = sorted.map(p => p.qStar); const rArray = sorted.map(p => p.r); const residualSpline = new Interpolation({ type: "monotone_cubic_spline", tension: 0.5 }); residualSpline.load_spline(qStarArray, rArray, "monotone_cubic_spline"); return residualSpline; } const residualSpline = buildResidualSpline(residualData); if (residualSpline) { console.log("Residual-spline r(q*) opgebouwd."); } else { console.log("Geen residual-spline opgebouwd (te weinig data)."); } // ----------------------------------------------------- // 7. Verbeterde voorspelling: H_improved(Q, n) // H_improved = H_baseline(Q, n) + r_corr(q*) // ----------------------------------------------------- function predictHeadImproved(Q, n, baselineSpline, residualSpline) { const H_baseline = predictHeadBaseline(Q, n, baselineSpline); if (!residualSpline) { // als we geen residual-spline hebben, val terug op baseline return H_baseline; } const qStar = Q / n; const r_corr = residualSpline.interpolate(qStar); const H_improved = H_baseline + r_corr; return H_improved; } // ----------------------------------------------------- // 8. Curves genereren voor een vast toerental // - zowel baseline als improved // ----------------------------------------------------- function generateCurvesForSpeed(n, Qmin, Qmax, steps, baselineSpline, residualSpline) { const points = []; const stepSize = (Qmax - Qmin) / (steps - 1); for (let k = 0; k < steps; k++) { const Q = Qmin + k * stepSize; const H_base = predictHeadBaseline(Q, n, baselineSpline); const H_impr = predictHeadImproved(Q, n, baselineSpline, residualSpline); points.push({ Q, n, H_baseline: H_base, H_improved: H_impr }); } return points; } // ----------------------------------------------------- // 9. Demo: één punt en een hele curve // ----------------------------------------------------- const Qtest = 650; const ntest = 1350; const H_base_test = predictHeadBaseline(Qtest, ntest, qhSpline); const H_impr_test = predictHeadImproved(Qtest, ntest, qhSpline, residualSpline); console.log(`\nVoorbeeld voorspelling op één punt: Q=${Qtest}, n=${ntest}`); console.log(` H_baseline ≈ ${H_base_test.toFixed(3)} m`); console.log(` H_improved ≈ ${H_impr_test.toFixed(3)} m`); const curve1450 = generateCurvesForSpeed(1450, 400, 800, 10, qhSpline, residualSpline); console.log("\nGegenereerde curve voor n = 1450 rpm (baseline vs improved):"); console.log(curve1450); // ===================================================== // Einde script // =====================================================
Sign in to join this conversation.
No description provided.