diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2025-04-26 17:32:00 -0400 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2025-04-26 17:32:00 -0400 |
| commit | f45e9a8d37a384ccea33158a4d3062d633720c93 (patch) | |
| tree | 59315423a519128d37bfd6b94fb52df92a70ca18 | |
| parent | 546e29a6f439146338f320240cab9b3b760eecb7 (diff) | |
| download | volute-f45e9a8d37a384ccea33158a4d3062d633720c93.zip | |
parse flow rate unit in compressor toml files
| -rw-r--r-- | compressor.c | 67 | ||||
| -rw-r--r-- | ui.c | 77 | ||||
| -rw-r--r-- | unit.c | 46 | ||||
| -rw-r--r-- | unit.h | 25 |
4 files changed, 158 insertions, 57 deletions
diff --git a/compressor.c b/compressor.c index 11f2d84..ba4cd8c 100644 --- a/compressor.c +++ b/compressor.c @@ -8,6 +8,7 @@ #include "cwalk.h" #include "toml.h" +#include "util.h" #include "unit.h" #include "compressor.h" #include "eprintf.h" @@ -19,7 +20,12 @@ static const char ROOT[NAME_MAX+1] = "compressor_maps"; static int load_compressor(const char *path, Compressor *comp); static int load_point(const toml_table_t *tbl, const char *key, const char *flowunit, Point *pt); +static int parse_flow(double val, const char *unit, Flow *flow); +static int parse_mass_flow(double val, const char *unit, Flow *flow); +static int parse_volume_flow(double val, const char *unit, Flow *flow); +static int index(const void *key, const void *base, size_t n, size_t size, int (*cmp)(const void *keyval, const void *datum)); static int toml_filter(const struct dirent *de); +static int cmp_flow_unit(const void *key, const void *datum); static void free_arr(void **arr, int n); @@ -200,6 +206,67 @@ load_point(const toml_table_t *tbl, const char *key, const char *flowunit, Point } static int +parse_flow(double val, const char *unit, Flow *flow) { + if (parse_mass_flow(val, unit, flow) == 0) { + return 0; + } + if (parse_volume_flow(val, unit, flow) == 0) { + return 0; + } + return 1; +} + +static int +parse_mass_flow(double val, const char *unit, Flow *flow) { + int i; + + i = index(unit, mass_flow_rate_units, n_mass_flow_rate_units, sizeof(mass_flow_rate_units[0]), cmp_flow_unit); + if (i >= 0) { + flow->u.mfr = mass_flow_rate_makers[i](val); + flow->t = MASS_FLOW; + return 0; + } + + return 1; +} + +static int +parse_volume_flow(double val, const char *unit, Flow *flow) { + int i; + + i = index(unit, volume_flow_rate_units, n_volume_flow_rate_units, sizeof(volume_flow_rate_units[0]), cmp_flow_unit); + if (i >= 0) { + flow->u.vfr = volume_flow_rate_makers[i](val); + flow->t = VOLUME_FLOW; + return 0; + } + + return 1; +} + +/* index linearly searches base[0]...base[n-1] for an item that matches *key. + * The function cmp must return zero if its first argument (the search key) + * equals its second (a table entry), non-zero if not equal. + * Returns the index of the first occurrence of key in base, or -1 if not present. */ +static int +index(const void *key, const void *base, size_t n, size_t size, int (*cmp)(const void *keyval, const void *datum)) { + int i; + + for (i = 0; i < n; i++) { + if (cmp(key, base) == 0) { + return i; + } + base += size; + } + return -1; +} + +static int +cmp_flow_unit(const void *key, const void *datum) { + return strcmp((char *) key, (char *) datum); +} + +static int toml_filter(const struct dirent *de) { const char *extension; size_t length, n; @@ -8,8 +8,6 @@ #include "ui.h" -#define nelem(arr) (sizeof(arr)/sizeof(arr[0])) - #define DEFAULT_DISPLACEMENT (litre(1.5)) #define DEFAULT_AMBIENT_TEMPERATURE (celsius(20)) #define DEFAULT_AMBIENT_PRESSURE (millibar(1013)) @@ -21,41 +19,6 @@ #define DEFAULT_INTERCOOLER_DELTAP (psi(0.2)) -static const char *const volume_units[] = {"cc", "l", "ci"}; -static const VolumeMaker volume_makers[nelem(volume_units)] = { - cubic_centimetre, litre, cubic_inch, -}; -static const VolumeReader volume_readers[nelem(volume_units)] = { - as_cubic_centimetre, as_litre, as_cubic_inch, -}; - -static const char *const temperature_units[] = {"°C", "K", "°F", "°R"}; -static const TemperatureMaker temperature_makers[nelem(temperature_units)] = { - celsius, kelvin, fahrenheit, rankine, -}; -static const TemperatureReader temperature_readers[nelem(temperature_units)] = { - as_celsius, as_kelvin, as_fahrenheit, as_rankine, -}; - -static const char *const pressure_units[] = {"mbar", "kPa", "bar", "psi", "inHG"}; -static const PressureMaker pressure_makers[nelem(pressure_units)] = { - millibar, kilopascal, bar, psi, inch_mercury, -}; -static const PressureReader pressure_readers[nelem(pressure_units)] = { - as_millibar, as_kilopascal, as_bar, as_psi, as_inch_mercury, -}; - -static const char *const volume_flow_rate_units[] = {"m³/s", "CFM"}; -static const VolumeFlowRateReader volume_flow_rate_readers[nelem(volume_flow_rate_units)] = { - as_cubic_metre_per_sec, as_cubic_foot_per_min, -}; - -static const char *const mass_flow_rate_units[] = {"kg/s", "lb/min"}; -static const MassFlowRateReader mass_flow_rate_readers[nelem(volume_flow_rate_units)] = { - as_kilo_per_sec, as_pound_per_min, -}; - - static void init_displacement(UI *ui); static void init_ambient_temperature(UI *ui); static void init_ambient_pressure(UI *ui); @@ -111,7 +74,7 @@ init_displacement(UI *ui) { double v; w_init_field(&ui->displacement); - w_init_select(&ui->displacement_unit, nelem(volume_units), volume_units); + w_init_select(&ui->displacement_unit, n_volume_units, volume_units); i = ui->displacement_unit.idx; v = volume_readers[i](DEFAULT_DISPLACEMENT); w_set_field(&ui->displacement, v); @@ -125,7 +88,7 @@ init_ambient_temperature(UI *ui) { double v; w_init_field(&ui->ambient_temperature); - w_init_select(&ui->ambient_temperature_unit, nelem(temperature_units), temperature_units); + w_init_select(&ui->ambient_temperature_unit, n_temperature_units, temperature_units); i = ui->ambient_temperature_unit.idx; v = temperature_readers[i](DEFAULT_AMBIENT_TEMPERATURE); w_set_field(&ui->ambient_temperature, v); @@ -139,7 +102,7 @@ init_ambient_pressure(UI *ui) { double v; w_init_field(&ui->ambient_pressure); - w_init_select(&ui->ambient_pressure_unit, nelem(pressure_units), pressure_units); + w_init_select(&ui->ambient_pressure_unit, n_pressure_units, pressure_units); i = ui->ambient_pressure_unit.idx; v = pressure_readers[i](DEFAULT_AMBIENT_PRESSURE); w_set_field(&ui->ambient_pressure, v); @@ -161,7 +124,7 @@ init_map(UI *ui) { double v; w_init_field(&ui->map[0]); - w_init_select(&ui->map_unit, nelem(pressure_units), pressure_units); + w_init_select(&ui->map_unit, n_pressure_units, pressure_units); i = ui->map_unit.idx; v = pressure_readers[i](DEFAULT_MAP); w_set_field(&ui->map[0], v); @@ -199,7 +162,7 @@ init_intercooler_deltap(UI *ui) { double v; w_init_field(&ui->intercooler_deltap[0]); - w_init_select(&ui->intercooler_deltap_unit, nelem(pressure_units), pressure_units); + w_init_select(&ui->intercooler_deltap_unit, n_pressure_units, pressure_units); i = ui->intercooler_deltap_unit.idx; v = pressure_readers[i](DEFAULT_INTERCOOLER_DELTAP); w_set_field(&ui->intercooler_deltap[0], v); @@ -215,30 +178,30 @@ init_pressure_ratio(UI *ui) { static void init_comp_outlet_temperature(UI *ui) { w_init_number(ui->comp_outlet_temperature[0]); - w_init_select(&ui->comp_outlet_temperature_unit, nelem(temperature_units), temperature_units); + w_init_select(&ui->comp_outlet_temperature_unit, n_temperature_units, temperature_units); } static void init_manifold_temperature(UI *ui) { w_init_number(ui->manifold_temperature[0]); - w_init_select(&ui->manifold_temperature_unit, nelem(temperature_units), temperature_units); + w_init_select(&ui->manifold_temperature_unit, n_temperature_units, temperature_units); } static void init_volume_flow_rate(UI *ui) { - w_init_select(&ui->volume_flow_rate_unit, nelem(volume_flow_rate_units), volume_flow_rate_units); + w_init_select(&ui->volume_flow_rate_unit, n_volume_flow_rate_units, volume_flow_rate_units); w_init_number(ui->volume_flow_rate[0]); } static void init_mass_flow_rate(UI *ui) { - w_init_select(&ui->mass_flow_rate_unit, nelem(mass_flow_rate_units), mass_flow_rate_units); + w_init_select(&ui->mass_flow_rate_unit, n_mass_flow_rate_units, mass_flow_rate_units); w_init_number(ui->mass_flow_rate[0]); } static void init_mass_flow_rate_corrected(UI *ui) { - w_init_select(&ui->mass_flow_rate_corrected_unit, nelem(mass_flow_rate_units), mass_flow_rate_units); + w_init_select(&ui->mass_flow_rate_corrected_unit, n_mass_flow_rate_units, mass_flow_rate_units); w_init_number(ui->mass_flow_rate_corrected[0]); } @@ -249,7 +212,7 @@ set_displacement(UI *ui) { Volume disp; idx = ui->displacement_unit.idx; - assert(idx >= 0 && (long unsigned int) idx < nelem(volume_units)); + assert(idx >= 0 && (size_t) idx < n_volume_units); convert = volume_makers[idx]; disp = convert(ui->displacement.value); @@ -278,7 +241,7 @@ set_ambient_temperature(UI *ui) { Temperature t; idx = ui->ambient_temperature_unit.idx; - assert(idx >= 0 && (long unsigned int) idx < nelem(temperature_units)); + assert(idx >= 0 && (size_t) idx < n_temperature_units); convert = temperature_makers[idx]; t = convert(ui->ambient_temperature.value); @@ -307,7 +270,7 @@ set_ambient_pressure(UI *ui) { Pressure p; idx = ui->ambient_pressure_unit.idx; - assert(idx >= 0 && (long unsigned int) idx < nelem(pressure_units)); + assert(idx >= 0 && (size_t) idx < n_pressure_units); convert = pressure_makers[idx]; p = convert(ui->ambient_pressure.value); @@ -341,7 +304,7 @@ set_map(UI *ui, int idx) { Pressure p; unit_idx = ui->map_unit.idx; - assert(unit_idx >= 0 && (long unsigned int) unit_idx < nelem(pressure_units)); + assert(unit_idx >= 0 && (size_t) unit_idx < n_pressure_units); convert = pressure_makers[unit_idx]; p = convert(ui->map[idx].value); @@ -385,7 +348,7 @@ set_intercooler_deltap(UI *ui, int idx) { Pressure p; unit_idx = ui->intercooler_deltap_unit.idx; - assert(unit_idx >= 0 && (long unsigned int) unit_idx < nelem(pressure_units)); + assert(unit_idx >= 0 && (size_t) unit_idx < n_pressure_units); convert = pressure_makers[unit_idx]; p = convert(ui->intercooler_deltap[idx].value); @@ -441,7 +404,7 @@ compute_comp_outlet_temperature(UI *ui, int idx) { double v; unit_idx = ui->comp_outlet_temperature_unit.idx; - assert(unit_idx >= 0 && (long unsigned int) unit_idx < nelem(temperature_units)); + assert(unit_idx >= 0 && (size_t) unit_idx < n_temperature_units); convert = temperature_readers[unit_idx]; v = convert(comp_outlet_temperature(&ui->points[idx])); @@ -455,7 +418,7 @@ compute_manifold_temperature(UI *ui, int idx) { double v; unit_idx = ui->manifold_temperature_unit.idx; - assert(unit_idx >= 0 && (long unsigned int) unit_idx < nelem(temperature_units)); + assert(unit_idx >= 0 && (size_t) unit_idx < n_temperature_units); convert = temperature_readers[unit_idx]; v = convert(manifold_temperature(&ui->points[idx])); @@ -469,7 +432,7 @@ compute_volume_flow_rate(UI *ui, int idx) { double v; unit_idx = ui->volume_flow_rate_unit.idx; - assert(unit_idx >= 0 && (long unsigned int) unit_idx < nelem(volume_flow_rate_units)); + assert(unit_idx >= 0 && (size_t) unit_idx < n_volume_flow_rate_units); convert = volume_flow_rate_readers[unit_idx]; v = convert(volume_flow_rate(&ui->points[idx])); @@ -483,7 +446,7 @@ compute_mass_flow_rate(UI *ui, int idx) { double v; unit_idx = ui->mass_flow_rate_unit.idx; - assert(unit_idx >= 0 && (long unsigned int) unit_idx < nelem(mass_flow_rate_units)); + assert(unit_idx >= 0 && (size_t) unit_idx < n_mass_flow_rate_units); convert = mass_flow_rate_readers[unit_idx]; v = convert(mass_flow_rate(&ui->points[idx])); @@ -497,7 +460,7 @@ compute_mass_flow_rate_corrected(UI *ui, int idx) { double v; unit_idx = ui->mass_flow_rate_corrected_unit.idx; - assert(unit_idx >= 0 && (long unsigned int) unit_idx < nelem(mass_flow_rate_units)); + assert(unit_idx >= 0 && (size_t) unit_idx < n_mass_flow_rate_units); convert = mass_flow_rate_readers[unit_idx]; v = convert(mass_flow_rate_corrected(&ui->points[idx])); @@ -1,6 +1,8 @@ #include <math.h> +#include <stddef.h> #include "unit.h" +#include "util.h" /* Kilograms per pound. */ @@ -21,6 +23,50 @@ /* Zero Celsius in Kelvin. */ #define ZERO_C 273.15 +const char *const pressure_units[] = {"mbar", "kPa", "bar", "psi", "inHG"}; +const PressureMaker pressure_makers[nelem(pressure_units)] = { + millibar, kilopascal, bar, psi, inch_mercury, +}; +const PressureReader pressure_readers[nelem(pressure_units)] = { + as_millibar, as_kilopascal, as_bar, as_psi, as_inch_mercury, +}; +const size_t n_pressure_units = nelem(pressure_units); + +const char *const temperature_units[] = {"°C", "K", "°F", "°R"}; +const TemperatureMaker temperature_makers[nelem(temperature_units)] = { + celsius, kelvin, fahrenheit, rankine, +}; +const TemperatureReader temperature_readers[nelem(temperature_units)] = { + as_celsius, as_kelvin, as_fahrenheit, as_rankine, +}; +const size_t n_temperature_units = nelem(temperature_units); + +const char *const volume_units[] = {"cc", "l", "ci"}; +const VolumeMaker volume_makers[nelem(volume_units)] = { + cubic_centimetre, litre, cubic_inch, +}; +const VolumeReader volume_readers[nelem(volume_units)] = { + as_cubic_centimetre, as_litre, as_cubic_inch, +}; +const size_t n_volume_units = nelem(volume_units); + +const char *const volume_flow_rate_units[] = {"m³/s", "CFM"}; +const VolumeFlowRateMaker volume_flow_rate_makers[nelem(volume_flow_rate_units)] = { + cubic_metre_per_sec, cubic_foot_per_min, +}; +const VolumeFlowRateReader volume_flow_rate_readers[nelem(volume_flow_rate_units)] = { + as_cubic_metre_per_sec, as_cubic_foot_per_min, +}; +const size_t n_volume_flow_rate_units = nelem(volume_flow_rate_units); + +const char *const mass_flow_rate_units[] = {"kg/s", "lb/min"}; +const MassFlowRateMaker mass_flow_rate_makers[nelem(mass_flow_rate_units)] = { + kilo_per_sec, pound_per_min, +}; +const MassFlowRateReader mass_flow_rate_readers[nelem(mass_flow_rate_units)] = { + as_kilo_per_sec, as_pound_per_min, +}; +const size_t n_mass_flow_rate_units = nelem(mass_flow_rate_units); AngularSpeed rad_per_sec(double x) { @@ -39,6 +39,11 @@ double as_bar(Pressure x); double as_psi(Pressure x); double as_inch_mercury(Pressure x); +extern const size_t n_pressure_units; +extern const char *const pressure_units[]; +extern const PressureMaker pressure_makers[]; +extern const PressureReader pressure_readers[]; + typedef double Temperature; typedef Temperature (*TemperatureMaker)(double); @@ -53,6 +58,11 @@ double as_celsius(Temperature t); double as_fahrenheit(Temperature t); double as_rankine(Temperature t); +extern const size_t n_temperature_units; +extern const char *const temperature_units[]; +extern const TemperatureMaker temperature_makers[]; +extern const TemperatureReader temperature_readers[]; + typedef double Volume; typedef Volume (*VolumeMaker)(double); @@ -67,6 +77,11 @@ double as_litre(Volume x); double as_cubic_metre(double x); double as_cubic_inch(double x); +extern const size_t n_volume_units; +extern const char *const volume_units[]; +extern const VolumeMaker volume_makers[]; +extern const VolumeReader volume_readers[]; + typedef double VolumeFlowRate; typedef VolumeFlowRate (*VolumeFlowRateMaker)(double); @@ -79,6 +94,11 @@ double as_cubic_metre_per_sec(VolumeFlowRate x); double as_cubic_metre_per_min(VolumeFlowRate x); double as_cubic_foot_per_min(VolumeFlowRate x); +extern const size_t n_volume_flow_rate_units; +extern const char *const volume_flow_rate_units[]; +extern const VolumeFlowRateMaker volume_flow_rate_makers[]; +extern const VolumeFlowRateReader volume_flow_rate_readers[]; + typedef double MassFlowRate; typedef MassFlowRate (*MassFlowRateMaker)(double); @@ -88,3 +108,8 @@ MassFlowRate kilo_per_sec(double x); MassFlowRate pound_per_min(double x); double as_kilo_per_sec(MassFlowRate m); double as_pound_per_min(MassFlowRate m); + +extern const size_t n_mass_flow_rate_units; +extern const char *const mass_flow_rate_units[]; +extern const MassFlowRateMaker mass_flow_rate_makers[]; +extern const MassFlowRateReader mass_flow_rate_readers[]; |