added toroid simulator
This commit is contained in:
@@ -535,6 +535,29 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Operating Point -->
|
||||
<div class="card">
|
||||
<div class="card-header">Operating Point</div>
|
||||
<div class="card-body">
|
||||
<div class="form-row">
|
||||
<label class="field"><span>Primary tap</span><input type="number" id="op-ptap" value="1" min="1" step="1"></label>
|
||||
<label class="field"><span>Secondary tap</span><input type="number" id="op-stap" value="1" min="1" step="1"></label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label class="field"><span>Vp RMS (V)</span><input type="number" id="op-vp" value="12" min="0.01" step="0.1"></label>
|
||||
<label class="field"><span>Frequency (Hz)</span><input type="number" id="op-freq" value="1000" min="1" step="1"></label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label class="field"><span>Load R (Ω)</span><input type="number" id="op-rload" value="100" min="0" step="1"></label>
|
||||
<label class="field"><span>Load X (Ω)</span><input type="number" id="op-xload" value="0" step="1"></label>
|
||||
</div>
|
||||
<div class="btn-row">
|
||||
<button class="btn btn-primary" id="btn-op" onclick="runOperatingPoint()">Simulate</button>
|
||||
</div>
|
||||
<div id="op-msg" class="msg" style="margin-top:8px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /left-col -->
|
||||
|
||||
|
||||
@@ -552,6 +575,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Operating Point Results -->
|
||||
<div class="card" id="op-results-card" style="display:none">
|
||||
<div class="card-header">Operating Point Results</div>
|
||||
<div class="card-body" style="padding:12px">
|
||||
<div id="op-violations" style="display:none;margin-bottom:10px;padding:8px 12px;background:#fef2f2;border:1px solid #fca5a5;border-radius:6px;color:#b91c1c;font-size:12px"></div>
|
||||
<table class="design-table" style="width:100%">
|
||||
<tbody id="op-results-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Plots -->
|
||||
<div class="card" id="plots-card" style="display:none">
|
||||
<div class="card-header">Simulation Results</div>
|
||||
@@ -834,6 +868,93 @@ function parseLoads() {
|
||||
}).filter(p => p[0] > 0 || p[1] !== 0);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Operating Point
|
||||
// ============================================================
|
||||
async function runOperatingPoint() {
|
||||
const btn = document.getElementById('btn-op');
|
||||
const msg = document.getElementById('op-msg');
|
||||
const card = document.getElementById('op-results-card');
|
||||
|
||||
btn.disabled = true;
|
||||
setMsg(msg, 'info', 'Simulating…');
|
||||
|
||||
try {
|
||||
const payload = Object.assign({}, buildPayload(), {
|
||||
primary_tap: parseInt(document.getElementById('op-ptap').value),
|
||||
secondary_tap: parseInt(document.getElementById('op-stap').value),
|
||||
Vp_rms: parseFloat(document.getElementById('op-vp').value),
|
||||
freq_hz: parseFloat(document.getElementById('op-freq').value),
|
||||
R_load: parseFloat(document.getElementById('op-rload').value) || 0,
|
||||
X_load: parseFloat(document.getElementById('op-xload').value) || 0,
|
||||
constraints: collectConstraints(),
|
||||
});
|
||||
|
||||
const resp = await fetch('/api/simulate', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
const data = await resp.json();
|
||||
|
||||
if (!data.success) {
|
||||
setMsg(msg, 'error', 'Error: ' + data.error);
|
||||
return;
|
||||
}
|
||||
|
||||
setMsg(msg, 'ok', 'Done.');
|
||||
card.style.display = '';
|
||||
|
||||
// Violations banner
|
||||
const vdiv = document.getElementById('op-violations');
|
||||
if (data.violations && data.violations.length) {
|
||||
vdiv.style.display = '';
|
||||
vdiv.textContent = 'Violations: ' + data.violations.join(', ');
|
||||
} else {
|
||||
vdiv.style.display = 'none';
|
||||
}
|
||||
|
||||
const rows = [
|
||||
['Turns (Np / Ns)', `${data.Np_eff} / ${data.Ns_eff}`],
|
||||
['Turns ratio (Np:Ns)', data.turns_ratio != null ? data.turns_ratio.toFixed(4) : '—'],
|
||||
['Peak flux density', data.B_peak_T != null ? data.B_peak_T.toFixed(4) + ' T' : '—'],
|
||||
['Primary voltage (Vp)', data.Vp_rms != null ? data.Vp_rms.toFixed(3) + ' V' : '—'],
|
||||
['Secondary voltage (Vs)', data.Vs_rms != null ? data.Vs_rms.toFixed(3) + ' V' : '—'],
|
||||
['Primary current (Ip)', data.Ip_rms != null ? data.Ip_rms.toFixed(4) + ' A' : '—'],
|
||||
['Secondary current (Is)', data.Is_rms != null ? data.Is_rms.toFixed(4) + ' A' : '—'],
|
||||
['Output power', data.P_out_W != null ? data.P_out_W.toFixed(3) + ' W' : '—'],
|
||||
['Copper loss (primary)', data.P_cu_primary_W != null ? data.P_cu_primary_W.toFixed(3) + ' W' : '—'],
|
||||
['Copper loss (secondary)', data.P_cu_secondary_W != null ? data.P_cu_secondary_W.toFixed(3) + ' W' : '—'],
|
||||
['Total copper loss', data.P_cu_W != null ? data.P_cu_W.toFixed(3) + ' W' : '—'],
|
||||
['Core loss', data.P_core_W != null ? data.P_core_W.toFixed(3) + ' W' : '—'],
|
||||
['Input power', data.P_in_W != null ? data.P_in_W.toFixed(3) + ' W' : '—'],
|
||||
['Efficiency', data.efficiency_pct != null ? data.efficiency_pct.toFixed(2) + ' %' : '—'],
|
||||
];
|
||||
|
||||
const tbody = document.getElementById('op-results-body');
|
||||
tbody.innerHTML = rows.map(([label, val]) =>
|
||||
`<tr><td style="font-weight:500;color:#444;width:55%">${label}</td><td>${val}</td></tr>`
|
||||
).join('');
|
||||
|
||||
} catch (err) {
|
||||
setMsg(msg, 'error', 'Error: ' + err.message);
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper: collect constraints object from UI
|
||||
function collectConstraints() {
|
||||
return {
|
||||
B_max_T: parseFloat(document.getElementById('con-B').value) || 0.3,
|
||||
Vp_max: parseFloat(document.getElementById('con-Vp').value) || 1e9,
|
||||
Vs_max: parseFloat(document.getElementById('con-Vs').value) || 1e9,
|
||||
Ip_max: parseFloat(document.getElementById('con-Ip').value) || 1e9,
|
||||
Is_max: parseFloat(document.getElementById('con-Is').value) || 1e9,
|
||||
P_out_max_W:parseFloat(document.getElementById('con-Pout').value) || 1e9,
|
||||
};
|
||||
}
|
||||
|
||||
async function runSweep() {
|
||||
const btn = document.getElementById('btn-sim');
|
||||
const msg = document.getElementById('sim-msg');
|
||||
|
||||
Reference in New Issue
Block a user