# 🎯 Entropyk — Contrôle Inverse One-Shot

Superheat control avec valve d'expansion — Story 5.3: Residual Embedding

Constraint
BoundedVariable
Lien One-Shot
Résultat

## Concept — One-Shot Inverse Control

FR24: Inverse Control solved simultaneously with cycle equations
❌ Approche Traditionnelle
1. Fixer valve → Simuler
2. Mesurer superheat
3. Ajuster valve
4. Répéter (optimisation externe)
→ Lent, coûteux, non garanti
✅ Approche One-Shot (Entropyk)
1. Définir contrainte: superheat = 5K
2. Lier à variable: valve position
3. Valve devient inconnue du solveur
4. Résolution simultanée (1 appel)
→ Rapide, garanti, élégant
Vecteur de résidus étendu
rtotal = [ rcycle, rconstraint ]T = 0
rconstraint = superheatmesuré − superheatcible

## Mapping — Contrainte → Variable de Contrôle

📐 Constraint
superheat_control
target: 5.0 K
link_constraint_to_control()
🎚 BoundedVar
valve_position
[0.1, 1.0]
state[idx]
✓ Résolu
valve = 38%
SH = 5.02 K

## Validation des Degrés de Liberté (DoF)

Équations
9
composants: 8
contraintes: +1
=
Inconnues
9
états bords: 8
contrôles: +1
✓ Système bien posé — validate_inverse_control_dof() = Ok
Équilibré
n_eqs == n_unknowns
Résolvable
Sur-contraint
n_eqs > n_unknowns
Erreur
Sous-contraint
n_eqs < n_unknowns
Warning

## Équations du système étendu

📦 Équations du cycle (8 éq.)

Composant | Équation | État
--- | --- | ---
Compresseur | r₁(P,h) = 0 | 2 éq.
Condenseur | r₂(P,h) = 0 | 2 éq.
EXV | r₃(P,h) = 0 | 2 éq.
Évaporateur | r₄(P,h) = 0 | 2 éq.

📐 Équations de contrainte (+1 éq.)

Type | Équation | Valeur
--- | --- | ---
Superheat | r_c = SH − 5.0 | 5.02 − 5.0
Jacobian | ∂r_c/∂valve | ≈ 1.0
State idx | 2·edges + i | idx = 8

## Convergence — Newton-Raphson

### Superheat (K)

i=0
2.30
i=1
3.12
i=2
3.89
i=3
4.41
i=4
4.73
i=5
4.91
i=6
5.01
i=7
5.02

### Valve Position (%)

i=0
50.0
i=1
46.2
i=2
43.5
i=3
41.3
i=4
39.8
i=5
38.9
i=6
38.3
i=7
38.0

## Valeurs au point de fonctionnement

### Contrainte Superheat

IDsuperheat_control
OutputSuperheat(evaporator)
Target5.0 K
Mesuré5.02 K
Résidu0.02 K
Satisfait✓

### Variable de Contrôle

IDvalve_position
Initial50.0%
Final38.0%
Bounds[10%, 100%]
SaturéNon
State idx8

### Solveur Newton-Raphson

Itérations7
Tolérance1e-8
‖r‖ final3.2e-9
MéthodeOne-Shot
Temps12 ms

### DoF Validation

Edges4 (×2 = 8)
Controls+1
Total unknowns9
Components4 (×2 = 8)
Constraints+1
Total equations9
Balance9 = 9 ✓

## API Rust — Utilisation

    // ══════════════════════════════════════════════════════════════════════
    // Story 5.3: Residual Embedding for Inverse Control
    // ══════════════════════════════════════════════════════════════════════

    use entropyk_solver::inverse::{
        Constraint, ConstraintId, ComponentOutput,
        BoundedVariable, BoundedVariableId,
    };

    // 1. Définir la contrainte: superheat = 5K
    let constraint = Constraint::new(
        ConstraintId::new("superheat_control"),
        ComponentOutput::Superheat { component_id: "evaporator".into() },
        5.0,  // target: 5 Kelvin
    );
    system.add_constraint(constraint)?;

    // 2. Définir la variable de contrôle bornée
    let control = BoundedVariable::new(
        BoundedVariableId::new("valve_position"),
        0.5, 0.1, 1.0,  // init, min, max
    )?;
    system.add_bounded_variable(control)?;

    // 3. Lier contrainte → contrôle (One-Shot!)
    system.link_constraint_to_control(
        &ConstraintId::new("superheat_control"),
        &BoundedVariableId::new("valve_position"),
    )?;

    // 4. Valider DoF + Finalize
    system.validate_inverse_control_dof()?;
    system.finalize()?;

    // 5. Résoudre (One-Shot)
    let result = NewtonRaphson::new().solve(&system)?;

    // 6. Résultat
    let valve = system.get_bounded_variable(&BoundedVariableId::new("valve_position")).unwrap();
    println!("Valve: {:.1}%  SH: {:.2} K", valve.value()*100.0, sh);

## API — Méthodes System

Méthode | Description | Retour
--- | --- | ---
add_constraint(c) | Ajoute une contrainte | Result<(), ConstraintError>
add_bounded_variable(v) | Ajoute variable bornée | Result<(), BoundedVariableError>
link_constraint_to_control(cid, vid) | Lie contrainte → contrôle | Result<(), DoFError>
unlink_constraint(cid) | Supprime le lien | Option<BoundedVariableId>
validate_inverse_control_dof() | Valide éq == inconnues | Result<(), DoFError>
control_variable_state_index(id) | Index vecteur d'état | Option<usize>
full_state_vector_len() | Longueur totale | usize
compute_constraint_residuals(...) | Calcule résidus contraintes | usize
compute_inverse_control_jacobian(...) | Jacobian ∂r/∂control | Vec<(row,col,val)>