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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user