160 lines
5.2 KiB
HTML
160 lines
5.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Entropyk WASM Demo</title>
|
|
<style>
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|
|
max-width: 800px;
|
|
margin: 50px auto;
|
|
padding: 0 20px;
|
|
line-height: 1.6;
|
|
}
|
|
.card {
|
|
background: #f5f5f5;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
margin: 20px 0;
|
|
}
|
|
button {
|
|
background: #007bff;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
}
|
|
button:hover {
|
|
background: #0056b3;
|
|
}
|
|
pre {
|
|
background: #2d2d2d;
|
|
color: #f8f8f2;
|
|
padding: 15px;
|
|
border-radius: 4px;
|
|
overflow-x: auto;
|
|
}
|
|
.loading { color: #666; }
|
|
.error { color: #dc3545; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Entropyk WebAssembly Demo</h1>
|
|
<p>Thermodynamic cycle simulation running entirely in your browser!</p>
|
|
|
|
<div class="card">
|
|
<h2>System Information</h2>
|
|
<div id="info" class="loading">Loading WASM module...</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Run Simulation</h2>
|
|
<button id="runBtn" disabled>Run Simple Cycle</button>
|
|
<div id="result" style="margin-top: 20px;"></div>
|
|
</div>
|
|
|
|
<script type="module">
|
|
import init, {
|
|
version,
|
|
list_available_fluids,
|
|
WasmSystem,
|
|
WasmCompressor,
|
|
WasmCondenser,
|
|
WasmEvaporator,
|
|
WasmExpansionValve,
|
|
WasmFallbackConfig
|
|
} from './pkg/entropyk_wasm.js';
|
|
|
|
let initialized = false;
|
|
|
|
async function setup() {
|
|
try {
|
|
await init();
|
|
initialized = true;
|
|
|
|
const infoDiv = document.getElementById('info');
|
|
const runBtn = document.getElementById('runBtn');
|
|
|
|
infoDiv.innerHTML = `
|
|
<p><strong>Version:</strong> ${version()}</p>
|
|
<p><strong>Available Fluids:</strong> ${list_available_fluids().join(', ')}</p>
|
|
<p style="color: green;">WASM module loaded successfully</p>
|
|
`;
|
|
|
|
runBtn.disabled = false;
|
|
runBtn.onclick = runSimulation;
|
|
|
|
} catch (err) {
|
|
document.getElementById('info').innerHTML = `
|
|
<p class="error">Failed to load WASM: ${err.message}</p>
|
|
`;
|
|
}
|
|
}
|
|
|
|
function runSimulation() {
|
|
const resultDiv = document.getElementById('result');
|
|
resultDiv.innerHTML = '<p class="loading">Running simulation...</p>';
|
|
|
|
try {
|
|
const startTime = performance.now();
|
|
|
|
const system = new WasmSystem();
|
|
|
|
// Create components
|
|
const compressor = new WasmCompressor(
|
|
"R134a", 2900.0, 0.0001, 0.85,
|
|
0.85, 2.5, 500.0, 1500.0, -2.5,
|
|
1.8, 600.0, 1600.0, -3.0, 2.0
|
|
).into_component();
|
|
const condenser = new WasmCondenser(5000.0).into_component();
|
|
const evaporator = new WasmEvaporator(3000.0).into_component();
|
|
const valve = new WasmExpansionValve("R134a", 0.0).into_component();
|
|
|
|
// Add to system
|
|
const c = system.add_component(compressor);
|
|
const cd = system.add_component(condenser);
|
|
const e = system.add_component(evaporator);
|
|
const v = system.add_component(valve);
|
|
|
|
// Connect cycle
|
|
system.add_edge(c, cd);
|
|
system.add_edge(cd, v);
|
|
system.add_edge(v, e);
|
|
system.add_edge(e, c);
|
|
system.finalize();
|
|
|
|
// Solve
|
|
const config = new WasmFallbackConfig();
|
|
const state = system.solve(config);
|
|
const endTime = performance.now();
|
|
|
|
let nodeInfo = '';
|
|
if (state.converged) {
|
|
const nodeState = system.get_node_result(0);
|
|
nodeInfo = `<h3>Node 0 State:</h3><pre>${nodeState.toJson()}</pre>`;
|
|
}
|
|
|
|
resultDiv.innerHTML = `
|
|
<p><strong>Converged:</strong> ${state.converged ? 'Yes' : 'No'}</p>
|
|
<p><strong>Status:</strong> ${state.status}</p>
|
|
<p><strong>Iterations:</strong> ${state.iterations}</p>
|
|
<p><strong>Final Residual:</strong> ${state.final_residual.toExponential(2)}</p>
|
|
<p><strong>Solve Time:</strong> ${(endTime - startTime).toFixed(2)} ms</p>
|
|
<h3>Result JSON:</h3>
|
|
<pre>${state.toJson()}</pre>
|
|
${nodeInfo}
|
|
`;
|
|
|
|
} catch (err) {
|
|
resultDiv.innerHTML = `<p class="error">Error: ${err.message}</p>`;
|
|
}
|
|
}
|
|
|
|
setup();
|
|
</script>
|
|
</body>
|
|
</html>
|