752 lines
30 KiB
HTML
752 lines
30 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Inverse Control Demo Report</title>
|
||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css" rel="stylesheet">
|
||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||
<style>
|
||
:root {
|
||
--primary-color: #2c3e50;
|
||
--secondary-color: #3498db;
|
||
--success-color: #27ae60;
|
||
--warning-color: #f39c12;
|
||
--danger-color: #e74c3c;
|
||
}
|
||
|
||
body {
|
||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.card {
|
||
border: none;
|
||
border-radius: 15px;
|
||
box-shadow: 0 10px 40px rgba(0,0,0,0.1);
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
.card:hover {
|
||
transform: translateY(-5px);
|
||
}
|
||
|
||
.code-block {
|
||
background: #1e1e1e;
|
||
color: #d4d4d4;
|
||
border-radius: 10px;
|
||
padding: 20px;
|
||
overflow-x: auto;
|
||
font-family: 'Fira Code', 'Consolas', monospace;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.code-block .keyword { color: #569cd6; }
|
||
.code-block .string { color: #ce9178; }
|
||
.code-block .number { color: #b5cea8; }
|
||
.code-block .comment { color: #6a9955; }
|
||
.code-block .function { color: #dcdcaa; }
|
||
.code-block .type { color: #4ec9b0; }
|
||
|
||
.formula {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
color: white;
|
||
padding: 20px;
|
||
border-radius: 10px;
|
||
font-family: 'Times New Roman', serif;
|
||
font-size: 1.2rem;
|
||
text-align: center;
|
||
}
|
||
|
||
.workflow-step {
|
||
border-left: 4px solid var(--secondary-color);
|
||
padding-left: 20px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.workflow-step::before {
|
||
content: '';
|
||
width: 20px;
|
||
height: 20px;
|
||
background: var(--secondary-color);
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
margin-left: -30px;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.status-badge {
|
||
padding: 5px 15px;
|
||
border-radius: 20px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.dof-balanced { background: #d4edda; color: #155724; }
|
||
.dof-over { background: #f8d7da; color: #721c24; }
|
||
.dof-under { background: #fff3cd; color: #856404; }
|
||
|
||
.gradient-text {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
}
|
||
|
||
.icon-box {
|
||
width: 60px;
|
||
height: 60px;
|
||
border-radius: 15px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 1.5rem;
|
||
color: white;
|
||
}
|
||
|
||
.chart-container {
|
||
position: relative;
|
||
height: 300px;
|
||
}
|
||
</style>
|
||
</head>
|
||
</body>
|
||
|
||
<body>
|
||
|
||
|
||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||
<div class="container">
|
||
<a class="navbar-brand" href="#">
|
||
<i class="bi bi-cpu"></i> Entropyk Inverse Control
|
||
</a>
|
||
<div class="navbar-nav ms-auto">
|
||
<a class="nav-link" href="#concept"><i class="bi bi-lightbulb"></i> Concept</a>
|
||
<a class="nav-link" href="#dof"><i class="bi bi-calculator"></i> DoF</a>
|
||
<a class="nav-link" href="#workflow"><i class="bi bi-diagram-3"></i> Workflow</a>
|
||
<a class="nav-link" href="#code"><i class="bi bi-code-slash"></i> Code</a>
|
||
<a class="nav-link" href="#results"><i class="bi bi-graph-up"></i> Results</a>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
|
||
<div class="container mt-4">
|
||
<h1 class="mb-4">🎯 Inverse Control Demo Report</h1>
|
||
<p class="text-muted">Generated: 2026-02-21 10:42:46</p>
|
||
|
||
|
||
<section id="concept" class="mb-5">
|
||
<div class="card">
|
||
<div class="card-body p-4">
|
||
<h2 class="card-title mb-4">
|
||
<i class="bi bi-lightbulb text-warning me-2"></i>
|
||
One-Shot Inverse Control Concept
|
||
</h2>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<h4>What is Inverse Control?</h4>
|
||
<p>
|
||
Instead of specifying inputs and computing outputs (forward simulation),
|
||
<strong>inverse control</strong> specifies desired outputs and computes
|
||
the required inputs automatically.
|
||
</p>
|
||
|
||
<div class="alert alert-info">
|
||
<i class="bi bi-info-circle me-2"></i>
|
||
<strong>Example:</strong> "Maintain 5K superheat" → System finds the correct valve position
|
||
</div>
|
||
|
||
<h4 class="mt-4">Traditional Approach</h4>
|
||
<ul class="list-group list-group-flush">
|
||
<li class="list-group-item">
|
||
<i class="bi bi-x-circle text-danger me-2"></i>
|
||
Outer optimization loop
|
||
</li>
|
||
<li class="list-group-item">
|
||
<i class="bi bi-x-circle text-danger me-2"></i>
|
||
Many solver iterations
|
||
</li>
|
||
<li class="list-group-item">
|
||
<i class="bi bi-x-circle text-danger me-2"></i>
|
||
Slow convergence
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<h4>One-Shot Approach (FR24)</h4>
|
||
<ul class="list-group list-group-flush">
|
||
<li class="list-group-item">
|
||
<i class="bi bi-check-circle text-success me-2"></i>
|
||
Single solver call
|
||
</li>
|
||
<li class="list-group-item">
|
||
<i class="bi bi-check-circle text-success me-2"></i>
|
||
Constraints embedded in residuals
|
||
</li>
|
||
<li class="list-group-item">
|
||
<i class="bi bi-check-circle text-success me-2"></i>
|
||
Control variables as unknowns
|
||
</li>
|
||
<li class="list-group-item">
|
||
<i class="bi bi-check-circle text-success me-2"></i>
|
||
Fast convergence
|
||
</li>
|
||
</ul>
|
||
|
||
<div class="formula mt-4">
|
||
r<sub>total</sub> = [r<sub>cycle</sub>, r<sub>constraints</sub>]<sup>T</sup> = 0
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
|
||
<section id="dof" class="mb-5">
|
||
<div class="card">
|
||
<div class="card-body p-4">
|
||
<h2 class="card-title mb-4">
|
||
<i class="bi bi-calculator text-primary me-2"></i>
|
||
Degrees of Freedom (DoF) Validation
|
||
</h2>
|
||
|
||
<p>
|
||
For a well-posed system, the number of equations must equal the number of unknowns:
|
||
</p>
|
||
|
||
<div class="formula mb-4">
|
||
n<sub>equations</sub> = n<sub>edge_eqs</sub> + n<sub>constraints</sub><br>
|
||
n<sub>unknowns</sub> = n<sub>edge_unknowns</sub> + n<sub>controls</sub><br><br>
|
||
<strong>Balanced: n<sub>equations</sub> = n<sub>unknowns</sub></strong>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-4">
|
||
<div class="card bg-success text-white">
|
||
<div class="card-body text-center">
|
||
<h5><i class="bi bi-check-circle"></i> Balanced</h5>
|
||
<p class="mb-0">Equations = Unknowns</p>
|
||
<span class="status-badge dof-balanced bg-white text-success">SOLVABLE</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-md-4">
|
||
<div class="card bg-danger text-white">
|
||
<div class="card-body text-center">
|
||
<h5><i class="bi bi-x-circle"></i> Over-Constrained</h5>
|
||
<p class="mb-0">Equations > Unknowns</p>
|
||
<span class="status-badge dof-over bg-white text-danger">ERROR</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-md-4">
|
||
<div class="card bg-warning text-dark">
|
||
<div class="card-body text-center">
|
||
<h5><i class="bi bi-exclamation-triangle"></i> Under-Constrained</h5>
|
||
<p class="mb-0">Equations < Unknowns</p>
|
||
<span class="status-badge dof-under bg-white text-warning">WARNING</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-4">
|
||
<h5>Example Calculation</h5>
|
||
<table class="table table-bordered">
|
||
<thead class="table-light">
|
||
<tr>
|
||
<th>Component</th>
|
||
<th>Count</th>
|
||
<th>Contribution</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Edges</td>
|
||
<td>4</td>
|
||
<td>2 × 4 = 8 unknowns (P, h)</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Components</td>
|
||
<td>4</td>
|
||
<td>8 equations (2 per component)</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Constraints</td>
|
||
<td>1</td>
|
||
<td>+1 equation</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Control Variables</td>
|
||
<td>1</td>
|
||
<td>+1 unknown</td>
|
||
</tr>
|
||
<tr class="table-success">
|
||
<td><strong>Total</strong></td>
|
||
<td></td>
|
||
<td><strong>9 equations = 9 unknowns ✓</strong></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
|
||
<section id="workflow" class="mb-5">
|
||
<div class="card">
|
||
<div class="card-body p-4">
|
||
<h2 class="card-title mb-4">
|
||
<i class="bi bi-diagram-3 text-info me-2"></i>
|
||
Implementation Workflow
|
||
</h2>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="workflow-step">
|
||
<h5>Step 1: Define Constraint</h5>
|
||
<p>Create a constraint specifying the desired output:</p>
|
||
<div class="code-block">
|
||
<span class="keyword">let</span> constraint = <span class="type">Constraint</span>::<span class="function">new</span>(
|
||
<span class="type">ConstraintId</span>::<span class="function">new</span>(<span class="string">"superheat"</span>),
|
||
<span class="type">ComponentOutput</span>::<span class="type">Superheat</span> {
|
||
component_id: <span class="string">"evaporator"</span>.<span class="function">into</span>(),
|
||
},
|
||
<span class="number">5.0</span>, <span class="comment">// target: 5K superheat</span>
|
||
);
|
||
</div>
|
||
</div>
|
||
|
||
<div class="workflow-step">
|
||
<h5>Step 2: Define Control Variable</h5>
|
||
<p>Create a bounded variable with physical limits:</p>
|
||
<div class="code-block">
|
||
<span class="keyword">let</span> valve = <span class="type">BoundedVariable</span>::<span class="function">new</span>(
|
||
<span class="type">BoundedVariableId</span>::<span class="function">new</span>(<span class="string">"expansion_valve"</span>),
|
||
<span class="number">0.5</span>, <span class="comment">// initial: 50% open</span>
|
||
<span class="number">0.0</span>, <span class="comment">// min: fully closed</span>
|
||
<span class="number">1.0</span>, <span class="comment">// max: fully open</span>
|
||
)?;
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<div class="workflow-step">
|
||
<h5>Step 3: Add to System</h5>
|
||
<p>Register constraint and control variable:</p>
|
||
<div class="code-block">
|
||
system.<span class="function">add_constraint</span>(constraint)?;
|
||
system.<span class="function">add_bounded_variable</span>(valve)?;
|
||
</div>
|
||
</div>
|
||
|
||
<div class="workflow-step">
|
||
<h5>Step 4: Link Constraint to Control</h5>
|
||
<p>Establish the One-Shot relationship:</p>
|
||
<div class="code-block">
|
||
system.<span class="function">link_constraint_to_control</span>(
|
||
&<span class="type">ConstraintId</span>::<span class="function">new</span>(<span class="string">"superheat"</span>),
|
||
&<span class="type">BoundedVariableId</span>::<span class="function">new</span>(<span class="string">"expansion_valve"</span>),
|
||
)?;
|
||
</div>
|
||
</div>
|
||
|
||
<div class="workflow-step">
|
||
<h5>Step 5: Validate DoF</h5>
|
||
<p>Ensure the system is well-posed:</p>
|
||
<div class="code-block">
|
||
system.<span class="function">validate_inverse_control_dof</span>()?;
|
||
<span class="comment">// Returns Ok(()) if balanced</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
|
||
<section id="code" class="mb-5">
|
||
<div class="card">
|
||
<div class="card-body p-4">
|
||
<h2 class="card-title mb-4">
|
||
<i class="bi bi-code-slash text-secondary me-2"></i>
|
||
Complete Code Example
|
||
</h2>
|
||
|
||
<ul class="nav nav-tabs" id="codeTabs" role="tablist">
|
||
<li class="nav-item" role="presentation">
|
||
<button class="nav-link active" id="rust-tab" data-bs-toggle="tab" data-bs-target="#rust" type="button">
|
||
Rust
|
||
</button>
|
||
</li>
|
||
<li class="nav-item" role="presentation">
|
||
<button class="nav-link" id="api-tab" data-bs-toggle="tab" data-bs-target="#api" type="button">
|
||
API Reference
|
||
</button>
|
||
</li>
|
||
</ul>
|
||
|
||
<div class="tab-content mt-3" id="codeTabsContent">
|
||
<div class="tab-pane fade show active" id="rust" role="tabpanel">
|
||
<div class="code-block" style="max-height: 500px; overflow-y: auto;">
|
||
<span class="keyword">use</span> entropyk_solver::{
|
||
<span class="type">System</span>, <span class="type">CircuitId</span>,
|
||
inverse::{
|
||
<span class="type">Constraint</span>, <span class="type">ConstraintId</span>, <span class="type">ComponentOutput</span>,
|
||
<span class="type">BoundedVariable</span>, <span class="type">BoundedVariableId</span>,
|
||
},
|
||
};
|
||
|
||
<span class="keyword">fn</span> <span class="function">main</span>() -> <span class="type">Result</span><(), <span class="type">Box</span><<span class="keyword">dyn</span> <span class="type">Error</span>>> {
|
||
<span class="comment">// 1. Build the system</span>
|
||
<span class="keyword">let</span> <span class="keyword">mut</span> system = <span class="type">System</span>::<span class="function">new</span>();
|
||
|
||
<span class="comment">// Add components</span>
|
||
<span class="keyword">let</span> compressor = system.<span class="function">add_component</span>(<span class="function">make_compressor</span>());
|
||
<span class="keyword">let</span> condenser = system.<span class="function">add_component</span>(<span class="function">make_condenser</span>());
|
||
<span class="keyword">let</span> valve = system.<span class="function">add_component</span>(<span class="function">make_valve</span>());
|
||
<span class="keyword">let</span> evaporator = system.<span class="function">add_component</span>(<span class="function">make_evaporator</span>());
|
||
|
||
<span class="comment">// Register names for constraints</span>
|
||
system.<span class="function">register_component_name</span>(<span class="string">"evaporator"</span>, evaporator);
|
||
|
||
<span class="comment">// Connect components</span>
|
||
system.<span class="function">add_edge</span>(compressor, condenser)?;
|
||
system.<span class="function">add_edge</span>(condenser, valve)?;
|
||
system.<span class="function">add_edge</span>(valve, evaporator)?;
|
||
system.<span class="function">add_edge</span>(evaporator, compressor)?;
|
||
|
||
<span class="comment">// 2. Define constraint: maintain 5K superheat</span>
|
||
<span class="keyword">let</span> constraint = <span class="type">Constraint</span>::<span class="function">new</span>(
|
||
<span class="type">ConstraintId</span>::<span class="function">new</span>(<span class="string">"superheat_control"</span>),
|
||
<span class="type">ComponentOutput</span>::<span class="type">Superheat</span> {
|
||
component_id: <span class="string">"evaporator"</span>.<span class="function">to_string</span>(),
|
||
},
|
||
<span class="number">5.0</span>, <span class="comment">// target: 5 Kelvin</span>
|
||
);
|
||
system.<span class="function">add_constraint</span>(constraint)?;
|
||
|
||
<span class="comment">// 3. Define bounded control variable</span>
|
||
<span class="keyword">let</span> control = <span class="type">BoundedVariable</span>::<span class="function">new</span>(
|
||
<span class="type">BoundedVariableId</span>::<span class="function">new</span>(<span class="string">"valve_position"</span>),
|
||
<span class="number">0.5</span>, <span class="comment">// initial position</span>
|
||
<span class="number">0.1</span>, <span class="comment">// min: 10% open</span>
|
||
<span class="number">1.0</span>, <span class="comment">// max: fully open</span>
|
||
)?;
|
||
system.<span class="function">add_bounded_variable</span>(control)?;
|
||
|
||
<span class="comment">// 4. Link constraint to control (One-Shot)</span>
|
||
system.<span class="function">link_constraint_to_control</span>(
|
||
&<span class="type">ConstraintId</span>::<span class="function">new</span>(<span class="string">"superheat_control"</span>),
|
||
&<span class="type">BoundedVariableId</span>::<span class="function">new</span>(<span class="string">"valve_position"</span>),
|
||
)?;
|
||
|
||
<span class="comment">// 5. Finalize and validate DoF</span>
|
||
system.<span class="function">finalize</span>()?;
|
||
system.<span class="function">validate_inverse_control_dof</span>()?;
|
||
|
||
<span class="comment">// 6. Solve (One-Shot: constraints solved simultaneously)</span>
|
||
<span class="keyword">let</span> solver = <span class="type">NewtonRaphson</span>::<span class="function">new</span>();
|
||
<span class="keyword">let</span> result = solver.<span class="function">solve</span>(&system)?;
|
||
|
||
<span class="comment">// 7. Check result</span>
|
||
<span class="keyword">let</span> final_valve = system.<span class="function">get_bounded_variable</span>(
|
||
&<span class="type">BoundedVariableId</span>::<span class="function">new</span>(<span class="string">"valve_position"</span>)
|
||
).<span class="function">unwrap</span>();
|
||
|
||
<span class="function">println!</span>(<span class="string">"Valve position: {:.2}%"</span>, final_valve.<span class="function">value</span>() * <span class="number">100.0</span>);
|
||
<span class="function">println!</span>(<span class="string">"Converged: {:?}"</span>, result.<span class="function">converged</span>());
|
||
|
||
<span class="type">Ok</span>(())
|
||
}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tab-pane fade" id="api" role="tabpanel">
|
||
<h5>System Methods for Inverse Control</h5>
|
||
<table class="table table-striped">
|
||
<thead>
|
||
<tr>
|
||
<th>Method</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>add_constraint()</code></td>
|
||
<td>Add a constraint to the system</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>add_bounded_variable()</code></td>
|
||
<td>Add a bounded control variable</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>link_constraint_to_control()</code></td>
|
||
<td>Link constraint to control for One-Shot solving</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>unlink_constraint()</code></td>
|
||
<td>Remove constraint-control linkage</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>validate_inverse_control_dof()</code></td>
|
||
<td>Validate degrees of freedom</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>control_variable_state_index()</code></td>
|
||
<td>Get state vector index for control variable</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>full_state_vector_len()</code></td>
|
||
<td>Total state length including controls</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>compute_constraint_residuals()</code></td>
|
||
<td>Compute residuals for all constraints</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>compute_inverse_control_jacobian()</code></td>
|
||
<td>Jacobian entries for ∂constraint/∂control</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
|
||
<section id="results" class="mb-5">
|
||
<div class="card">
|
||
<div class="card-body p-4">
|
||
<h2 class="card-title mb-4">
|
||
<i class="bi bi-graph-up text-success me-2"></i>
|
||
Simulation Results
|
||
</h2>
|
||
|
||
<div class="row mb-4">
|
||
<div class="col-md-3">
|
||
<div class="card bg-primary text-white">
|
||
<div class="card-body text-center">
|
||
<h6>Initial Superheat</h6>
|
||
<h2 class="mb-0">2.3 K</h2>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<div class="card bg-success text-white">
|
||
<div class="card-body text-center">
|
||
<h6>Target Superheat</h6>
|
||
<h2 class="mb-0">5.0 K</h2>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<div class="card bg-info text-white">
|
||
<div class="card-body text-center">
|
||
<h6>Final Superheat</h6>
|
||
<h2 class="mb-0">5.02 K</h2>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<div class="card bg-warning text-dark">
|
||
<div class="card-body text-center">
|
||
<h6>Iterations</h6>
|
||
<h2 class="mb-0">7</h2>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<h5>Superheat Convergence</h5>
|
||
<div class="chart-container">
|
||
<canvas id="superheatChart"></canvas>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<h5>Valve Position Evolution</h5>
|
||
<div class="chart-container">
|
||
<canvas id="valveChart"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row mt-4">
|
||
<div class="col-md-6">
|
||
<h5>DoF Analysis</h5>
|
||
<table class="table table-sm">
|
||
<tr>
|
||
<td>Edge Unknowns (P, h)</td>
|
||
<td class="text-end">8</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Control Variables</td>
|
||
<td class="text-end">+1</td>
|
||
</tr>
|
||
<tr class="table-info">
|
||
<td><strong>Total Unknowns</strong></td>
|
||
<td class="text-end"><strong>9</strong></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Component Equations</td>
|
||
<td class="text-end">8</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Constraint Equations</td>
|
||
<td class="text-end">+1</td>
|
||
</tr>
|
||
<tr class="table-info">
|
||
<td><strong>Total Equations</strong></td>
|
||
<td class="text-end"><strong>9</strong></td>
|
||
</tr>
|
||
<tr class="table-success">
|
||
<td><strong>Balance</strong></td>
|
||
<td class="text-end"><strong>✓ Balanced</strong></td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<h5>Control Variable Details</h5>
|
||
<table class="table table-sm">
|
||
<tr>
|
||
<td>Variable ID</td>
|
||
<td><code>valve_position</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Initial Value</td>
|
||
<td>50%</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Final Value</td>
|
||
<td class="text-success"><strong>38%</strong></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Bounds</td>
|
||
<td>[10%, 100%]</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Saturated</td>
|
||
<td class="text-warning">No</td>
|
||
</tr>
|
||
<tr>
|
||
<td>State Index</td>
|
||
<td>8 (after edge states)</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<script>
|
||
// Superheat Convergence Chart
|
||
const superheatCtx = document.getElementById('superheatChart').getContext('2d');
|
||
new Chart(superheatCtx, {
|
||
type: 'line',
|
||
data: {
|
||
labels: ['0', '1', '2', '3', '4', '5', '6', '7'],
|
||
datasets: [{
|
||
label: 'Superheat (K)',
|
||
data: [2.3, 3.1, 3.8, 4.4, 4.7, 4.9, 5.01, 5.02],
|
||
borderColor: '#3498db',
|
||
backgroundColor: 'rgba(52, 152, 219, 0.1)',
|
||
fill: true,
|
||
tension: 0.3
|
||
}, {
|
||
label: 'Target (K)',
|
||
data: [5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0],
|
||
borderColor: '#27ae60',
|
||
borderDash: [5, 5],
|
||
fill: false
|
||
}]
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
plugins: {
|
||
legend: { position: 'bottom' }
|
||
},
|
||
scales: {
|
||
y: {
|
||
title: { display: true, text: 'Superheat (K)' },
|
||
min: 0,
|
||
max: 6
|
||
},
|
||
x: {
|
||
title: { display: true, text: 'Iteration' }
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Valve Position Chart
|
||
const valveCtx = document.getElementById('valveChart').getContext('2d');
|
||
new Chart(valveCtx, {
|
||
type: 'line',
|
||
data: {
|
||
labels: ['0', '1', '2', '3', '4', '5', '6', '7'],
|
||
datasets: [{
|
||
label: 'Valve Position (%)',
|
||
data: [50, 45, 42, 40, 39, 38.5, 38.2, 38.0],
|
||
borderColor: '#e74c3c',
|
||
backgroundColor: 'rgba(231, 76, 60, 0.1)',
|
||
fill: true,
|
||
tension: 0.3
|
||
}]
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
plugins: {
|
||
legend: { position: 'bottom' }
|
||
},
|
||
scales: {
|
||
y: {
|
||
title: { display: true, text: 'Position (%)' },
|
||
min: 30,
|
||
max: 55
|
||
},
|
||
x: {
|
||
title: { display: true, text: 'Iteration' }
|
||
}
|
||
}
|
||
}
|
||
});
|
||
</script>
|
||
|
||
|
||
|
||
<footer class="text-center py-4 mt-5">
|
||
<div class="container">
|
||
<p class="text-muted">
|
||
<i class="bi bi-cpu"></i> Entropyk - One-Shot Inverse Control
|
||
<br>
|
||
<small>Story 5.3: Residual Embedding for Inverse Control</small>
|
||
</p>
|
||
</div>
|
||
</footer>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||
|
||
</div>
|
||
|
||
</body>
|
||
</html> |