- Added port_mass_flows to Component trait and implements for core components. - Added System::check_mass_balance and integrated it into the solver. - Restored connect methods for ExpansionValve, Compressor, and Pipe to fix integration tests. - Updated Python and C bindings for validation errors. - Updated sprint status and story documentation.
179 lines
6.3 KiB
C
179 lines
6.3 KiB
C
/**
|
|
* Simple refrigeration cycle example for Entropyk C FFI.
|
|
*
|
|
* Demonstrates:
|
|
* - System lifecycle (create/free)
|
|
* - Component creation (compressor, condenser, valve, evaporator)
|
|
* - System topology (add components, add edges, finalize)
|
|
* - Solving (fallback solver)
|
|
* - Result retrieval
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include "entropyk.h"
|
|
|
|
int main() {
|
|
printf("Entropyk C FFI Example - Simple Refrigeration Cycle\n");
|
|
printf("===================================================\n\n");
|
|
|
|
/* 1. Create the system */
|
|
EntropykSystem* sys = entropyk_system_create();
|
|
if (!sys) {
|
|
printf("ERROR: Failed to create system\n");
|
|
return 1;
|
|
}
|
|
printf("Created system\n");
|
|
|
|
/* 2. Create components */
|
|
double compressor_coeffs[10] = {
|
|
0.85, /* m1: mass flow coefficient */
|
|
2.5, /* m2: mass flow exponent for suction pressure */
|
|
500.0, /* m3: mass flow coefficient for superheat */
|
|
1500.0, /* m4: power coefficient */
|
|
-2.5, /* m5: power exponent */
|
|
1.8, /* m6: power exponent */
|
|
600.0, /* m7: additional power coefficient */
|
|
1600.0, /* m8: additional power coefficient */
|
|
-3.0, /* m9: power exponent */
|
|
2.0 /* m10: power exponent */
|
|
};
|
|
|
|
EntropykComponent* comp = entropyk_compressor_create(compressor_coeffs, 10);
|
|
EntropykComponent* cond = entropyk_condenser_create(5000.0); /* 5 kW/K */
|
|
EntropykComponent* valve = entropyk_expansion_valve_create();
|
|
EntropykComponent* evap = entropyk_evaporator_create(3000.0); /* 3 kW/K */
|
|
|
|
if (!comp || !cond || !valve || !evap) {
|
|
printf("ERROR: Failed to create components\n");
|
|
entropyk_system_free(sys);
|
|
return 1;
|
|
}
|
|
printf("Created 4 components: compressor, condenser, valve, evaporator\n");
|
|
|
|
/* 3. Add components to system (transfers ownership, returns node index) */
|
|
unsigned int comp_idx = entropyk_system_add_component(sys, comp);
|
|
unsigned int cond_idx = entropyk_system_add_component(sys, cond);
|
|
unsigned int valve_idx = entropyk_system_add_component(sys, valve);
|
|
unsigned int evap_idx = entropyk_system_add_component(sys, evap);
|
|
|
|
if (comp_idx == UINT32_MAX || cond_idx == UINT32_MAX ||
|
|
valve_idx == UINT32_MAX || evap_idx == UINT32_MAX) {
|
|
printf("ERROR: Failed to add component to system\n");
|
|
entropyk_system_free(sys);
|
|
return 1;
|
|
}
|
|
|
|
printf("Added components: comp=%u, cond=%u, valve=%u, evap=%u\n",
|
|
comp_idx, cond_idx, valve_idx, evap_idx);
|
|
|
|
/* 4. Connect components (simple cycle: comp -> cond -> valve -> evap -> comp) */
|
|
EntropykErrorCode err;
|
|
|
|
err = entropyk_system_add_edge(sys, comp_idx, cond_idx);
|
|
if (err != ENTROPYK_OK) {
|
|
printf("ERROR: Failed to add edge comp->cond: %s\n", entropyk_error_string(err));
|
|
entropyk_system_free(sys);
|
|
return 1;
|
|
}
|
|
|
|
err = entropyk_system_add_edge(sys, cond_idx, valve_idx);
|
|
if (err != ENTROPYK_OK) {
|
|
printf("ERROR: Failed to add edge cond->valve: %s\n", entropyk_error_string(err));
|
|
entropyk_system_free(sys);
|
|
return 1;
|
|
}
|
|
|
|
err = entropyk_system_add_edge(sys, valve_idx, evap_idx);
|
|
if (err != ENTROPYK_OK) {
|
|
printf("ERROR: Failed to add edge valve->evap: %s\n", entropyk_error_string(err));
|
|
entropyk_system_free(sys);
|
|
return 1;
|
|
}
|
|
|
|
err = entropyk_system_add_edge(sys, evap_idx, comp_idx);
|
|
if (err != ENTROPYK_OK) {
|
|
printf("ERROR: Failed to add edge evap->comp: %s\n", entropyk_error_string(err));
|
|
entropyk_system_free(sys);
|
|
return 1;
|
|
}
|
|
|
|
printf("Connected components in cycle\n");
|
|
printf("System: %u nodes, %u edges\n",
|
|
entropyk_system_node_count(sys),
|
|
entropyk_system_edge_count(sys));
|
|
|
|
/* 5. Finalize the system */
|
|
err = entropyk_system_finalize(sys);
|
|
if (err != ENTROPYK_OK) {
|
|
printf("ERROR: Failed to finalize system: %s\n", entropyk_error_string(err));
|
|
entropyk_system_free(sys);
|
|
return 1;
|
|
}
|
|
printf("System finalized (state vector length: %u)\n",
|
|
entropyk_system_state_vector_len(sys));
|
|
|
|
/* 6. Configure and run solver */
|
|
EntropykFallbackConfig config = {
|
|
.newton = {
|
|
.max_iterations = 100,
|
|
.tolerance = 1e-6,
|
|
.line_search = false,
|
|
.timeout_ms = 0
|
|
},
|
|
.picard = {
|
|
.max_iterations = 500,
|
|
.tolerance = 1e-4,
|
|
.relaxation = 0.5
|
|
}
|
|
};
|
|
|
|
EntropykSolverResult* result = NULL;
|
|
err = entropyk_solve_fallback(sys, &config, &result);
|
|
|
|
/* 7. Check results */
|
|
if (err == ENTROPYK_OK && result != NULL) {
|
|
EntropykConvergenceStatus status = entropyk_result_get_status(result);
|
|
unsigned int iterations = entropyk_result_get_iterations(result);
|
|
double residual = entropyk_result_get_residual(result);
|
|
|
|
printf("\n=== Solver Results ===\n");
|
|
printf("Status: %s\n",
|
|
status == CONVERGED ? "CONVERGED" :
|
|
status == CONVERGED_TIMED_OUT ? "TIMED_OUT" :
|
|
status == CONVERGED_CONTROL_SATURATION ? "CONTROL_SATURATION" : "UNKNOWN");
|
|
printf("Iterations: %u\n", iterations);
|
|
printf("Final residual: %.2e\n", residual);
|
|
|
|
/* Get state vector */
|
|
unsigned int len = 0;
|
|
entropyk_result_get_state_vector(result, NULL, &len);
|
|
if (len > 0) {
|
|
double* state = (double*)malloc(len * sizeof(double));
|
|
if (state) {
|
|
entropyk_result_get_state_vector(result, state, &len);
|
|
printf("State vector[%u]: [", len);
|
|
for (unsigned int i = 0; i < (len < 6 ? len : 6); i++) {
|
|
printf("%.2f", state[i]);
|
|
if (i < len - 1) printf(", ");
|
|
}
|
|
if (len > 6) printf(", ...");
|
|
printf("]\n");
|
|
free(state);
|
|
}
|
|
}
|
|
|
|
entropyk_result_free(result);
|
|
} else {
|
|
printf("\n=== Solver Failed ===\n");
|
|
printf("Error: %s\n", entropyk_error_string(err));
|
|
}
|
|
|
|
/* 8. Cleanup */
|
|
entropyk_system_free(sys);
|
|
printf("\nCleanup complete.\n");
|
|
|
|
return (err == ENTROPYK_OK) ? 0 : 1;
|
|
}
|