Add diagram workbench UI with Modelica DoF coaching and ISO glyphs.

Ship the Next.js cycle editor with CAD chrome, technical HX symbols, Fixed/Free boundary guidance, and secondary water/air pressure drop support in the solver stack.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-17 22:46:46 +02:00
parent 62efea0646
commit 3358b74342
275 changed files with 70187 additions and 5230 deletions

View File

@@ -24,9 +24,12 @@ impl Component for MockCalibratedComponent {
state: &StateSlice,
residuals: &mut ResidualVector,
) -> Result<(), ComponentError> {
// Fix the edge states to a known value
residuals[0] = state[0] - 300.0;
residuals[1] = state[1] - 400.0;
// Fix the edge states to a known value.
// Per-edge state is (ṁ, P, h); P at index 1, h at index 2.
residuals[0] = state[1] - 300.0;
residuals[1] = state[2] - 400.0;
// CM1.3: mass-flow equation — pin ṁ at a seed value.
residuals[2] = state[0] - 0.05;
Ok(())
}
@@ -36,18 +39,18 @@ impl Component for MockCalibratedComponent {
_state: &StateSlice,
jacobian: &mut JacobianBuilder,
) -> Result<(), ComponentError> {
// d(r0)/d(state[0]) = 1.0
jacobian.add_entry(0, 0, 1.0);
// d(r1)/d(state[1]) = 1.0
jacobian.add_entry(1, 1, 1.0);
// No dependence of physical equations on f_ua
// d(r0)/d(state[1]) = 1.0 (P of edge 0)
jacobian.add_entry(0, 1, 1.0);
// d(r1)/d(state[2]) = 1.0 (h of edge 0)
jacobian.add_entry(1, 2, 1.0);
// d(r2)/d(state[0]) = 1.0 (ṁ of edge 0)
jacobian.add_entry(2, 0, 1.0);
Ok(())
}
fn n_equations(&self) -> usize {
2 // balances 2 edge variables
3 // P + h + ṁ equations (CM1.3)
}
fn get_ports(&self) -> &[ConnectedPort] {
@@ -79,8 +82,8 @@ fn test_inverse_calibration_f_ua() {
// We want the capacity to be exactly 4015 W.
// The mocked math in System::extract_constraint_values_with_controls:
// Capacity = state[1] * 10.0 + f_ua * 10.0 (primary effect)
// We fixed state[1] to 400.0, so:
// Capacity = state[h_idx] * 10.0 + f_ua * 10.0 (primary effect)
// We fixed state[h_idx] (edge 0 enthalpy, index 2) to 400.0, so:
// 400.0 * 10.0 + f_ua * 10.0 = 4015
// 4000.0 + 10.0 * f_ua = 4015
// 10.0 * f_ua = 15.0
@@ -129,8 +132,8 @@ fn test_inverse_calibration_f_ua() {
let converged = result.unwrap();
// The control variable `f_ua` is at the end of the state vector
let f_ua_idx = sys.full_state_vector_len() - 1;
let final_f_ua: f64 = converged.state[f_ua_idx];
let z_ua_idx = sys.full_state_vector_len() - 1;
let final_f_ua: f64 = converged.state[z_ua_idx];
// Target f_ua = 1.5
let abs_diff = (final_f_ua - 1.5_f64).abs();