mirror of
https://github.com/eddyem/eddys_snippets.git
synced 2025-12-06 02:35:12 +03:00
198 lines
8.6 KiB
Plaintext
198 lines
8.6 KiB
Plaintext
Да, конечно! Написать программу на C для этой задачи вполне возможно. Это典型的 задача инженерного расчета, которая хорошо ложится на процедурный подход языка C.
|
||
|
||
Вот пример структуры программы на C:
|
||
|
||
## Структура программы
|
||
|
||
```c
|
||
#include <stdio.h>
|
||
#include <math.h>
|
||
#include <float.h>
|
||
|
||
// Константы
|
||
#define PI 3.141592653589793
|
||
#define MU_0 (4.0 * PI * 1e-7)
|
||
#define DENSITY_CU 8900.0 // плотность меди, кг/м³
|
||
#define PRICE_CU 8.5 // цена меди, у.е./кг
|
||
#define K_FILL 0.3 // коэффициент заполнения окна
|
||
#define EFFICIENCY 0.95 // КПД трансформатора
|
||
|
||
// Структура для описания сердечника
|
||
typedef struct {
|
||
char name[20]; // название сердечника
|
||
double S_fe; // сечение магнитопровода, м²
|
||
double S_window; // площадь окна, м²
|
||
double price_fe; // стоимость сердечника, у.е.
|
||
double B_max; // максимальная индукция, Тл
|
||
double k_fe; // коэффициент формы
|
||
} Core;
|
||
|
||
// Структура для параметров трансформатора
|
||
typedef struct {
|
||
double P_out; // выходная мощность, Вт
|
||
double U_in; // входное напряжение, В
|
||
double U_out; // выходное напряжение, В
|
||
double f; // частота, Гц
|
||
double J; // плотность тока, А/мм²
|
||
} TransformerParams;
|
||
|
||
// Структура для результатов расчета
|
||
typedef struct {
|
||
Core core;
|
||
double N1, N2; // число витков
|
||
double d_wire1, d_wire2; // диаметры проводов, мм
|
||
double cost_total; // общая стоимость
|
||
double cost_cu; // стоимость меди
|
||
int is_valid; // флаг валидности расчета
|
||
} CalculationResult;
|
||
|
||
// Функция расчета одного варианта
|
||
CalculationResult calculate_transformer(const TransformerParams* params, const Core* core) {
|
||
CalculationResult result = {0};
|
||
result.core = *core;
|
||
|
||
// Расчет числа витков
|
||
result.N1 = (params->U_in * 1.05) / (4.44 * params->f * core->B_max * core->S_fe);
|
||
result.N2 = (params->U_out * 1.05) / (4.44 * params->f * core->B_max * core->S_fe);
|
||
|
||
// Расчет токов
|
||
double I1 = params->P_out / (params->U_in * EFFICIENCY);
|
||
double I2 = params->P_out / params->U_out;
|
||
|
||
// Расчет сечений проводов
|
||
double s_wire1 = I1 / (params->J * 1e6); // м²
|
||
double s_wire2 = I2 / (params->J * 1e6); // м²
|
||
|
||
result.d_wire1 = sqrt(s_wire1 * 4 / PI) * 1000; // мм
|
||
result.d_wire2 = sqrt(s_wire2 * 4 / PI) * 1000; // мм
|
||
|
||
// Проверка заполнения окна
|
||
double occupied_area = (result.N1 * s_wire1 + result.N2 * s_wire2) / K_FILL;
|
||
result.is_valid = (occupied_area <= core->S_window);
|
||
|
||
if (result.is_valid) {
|
||
// Оценка стоимости меди (упрощенно)
|
||
// Предполагаем среднюю длину витка пропорциональной корню из площади окна
|
||
double mean_length_turn = 4 * sqrt(core->S_window); // м
|
||
double length_wire1 = result.N1 * mean_length_turn;
|
||
double length_wire2 = result.N2 * mean_length_turn;
|
||
|
||
double volume_cu = length_wire1 * s_wire1 + length_wire2 * s_wire2;
|
||
double mass_cu = volume_cu * DENSITY_CU;
|
||
|
||
result.cost_cu = mass_cu * PRICE_CU;
|
||
result.cost_total = core->price_fe + result.cost_cu;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
// Основная функция оптимизации
|
||
Core find_optimal_core(const TransformerParams* params, Core* cores, int num_cores) {
|
||
CalculationResult best_result = {0};
|
||
best_result.cost_total = DBL_MAX;
|
||
int best_index = -1;
|
||
|
||
printf("Расчет трансформатора:\n");
|
||
printf("P = %.1f Вт, Uin = %.1f В, Uout = %.1f В, f = %.1f Гц\n\n",
|
||
params->P_out, params->U_in, params->U_out, params->f);
|
||
|
||
for (int i = 0; i < num_cores; i++) {
|
||
CalculationResult result = calculate_transformer(params, &cores[i]);
|
||
|
||
printf("Сердечник: %s\n", cores[i].name);
|
||
printf(" N1 = %.0f, N2 = %.0f, d1 = %.2f мм, d2 = %.2f мм\n",
|
||
result.N1, result.N2, result.d_wire1, result.d_wire2);
|
||
printf(" Стоимость: сердечник = %.2f, медь = %.2f, общая = %.2f\n",
|
||
cores[i].price_fe, result.cost_cu, result.cost_total);
|
||
printf(" Статус: %s\n\n", result.is_valid ? "ПОДХОДИТ" : "НЕ ПОДХОДИТ");
|
||
|
||
if (result.is_valid && result.cost_total < best_result.cost_total) {
|
||
best_result = result;
|
||
best_index = i;
|
||
}
|
||
}
|
||
|
||
if (best_index >= 0) {
|
||
printf("ОПТИМАЛЬНЫЙ ВАРИАНТ:\n");
|
||
printf("Сердечник: %s\n", cores[best_index].name);
|
||
printf("Общая стоимость: %.2f у.е.\n", best_result.cost_total);
|
||
return cores[best_index];
|
||
} else {
|
||
printf("НЕ УДАЛОСЬ НАЙТИ ПОДХОДЯЩИЙ СЕРДЕЧНИК!\n");
|
||
Core empty = {0};
|
||
return empty;
|
||
}
|
||
}
|
||
|
||
// Пример использования
|
||
int main() {
|
||
// Параметры трансформатора
|
||
TransformerParams params = {
|
||
.P_out = 100.0, // 100 Вт
|
||
.U_in = 220.0, // 220 В
|
||
.U_out = 12.0, // 12 В
|
||
.f = 50.0, // 50 Гц
|
||
.J = 3.0 // 3 А/мм²
|
||
};
|
||
|
||
// База данных стандартных сердечников
|
||
Core cores[] = {
|
||
{"ШЛ20х25", 5.0e-4, 4.0e-4, 15.0, 1.2, 1.2},
|
||
{"ШЛ25х32", 8.0e-4, 6.4e-4, 22.0, 1.2, 1.2},
|
||
{"ШЛ32х40", 12.8e-4, 10.0e-4, 35.0, 1.2, 1.2},
|
||
{"Тороид_40", 12.0e-4, 8.0e-4, 28.0, 1.3, 1.6},
|
||
{"Тороид_50", 15.0e-4, 12.0e-4, 42.0, 1.3, 1.6}
|
||
};
|
||
|
||
int num_cores = sizeof(cores) / sizeof(cores[0]);
|
||
|
||
// Поиск оптимального сердечника
|
||
Core optimal = find_optimal_core(¶ms, cores, num_cores);
|
||
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
## Ключевые особенности реализации:
|
||
|
||
1. **Модульная структура** - разделение на логические блоки
|
||
2. **Структуры данных** для параметров, сердечников и результатов
|
||
3. **Итерационный поиск** по базе сердечников
|
||
4. **Проверка ограничений** (заполнение окна)
|
||
5. **Критерий оптимизации** - минимальная стоимость
|
||
|
||
## Дополнительные улучшения, которые можно добавить:
|
||
|
||
```c
|
||
// Функция для итерационного подбора плотности тока
|
||
void optimize_current_density(TransformerParams* params, Core* cores, int num_cores) {
|
||
double best_J = 2.0;
|
||
double best_cost = DBL_MAX;
|
||
|
||
for (double J = 2.0; J <= 4.0; J += 0.5) {
|
||
params->J = J;
|
||
// ... расчет для каждой плотности тока
|
||
}
|
||
}
|
||
|
||
// Чтение базы сердечников из файла
|
||
int read_cores_from_file(const char* filename, Core** cores) {
|
||
// ... реализация чтения из CSV или текстового файла
|
||
}
|
||
|
||
// Расчет габаритной мощности
|
||
double calculate_gabarit_power(const Core* core, const TransformerParams* params) {
|
||
return core->S_fe * core->S_window * core->k_fe *
|
||
params->J * 1e6 * core->B_max * params->f;
|
||
}
|
||
```
|
||
|
||
Такой подход позволяет:
|
||
- Легко добавлять новые типы сердечников
|
||
- Менять критерии оптимизации
|
||
- Интегрироваться с другими системами
|
||
- Проводить параметрические исследования
|
||
|
||
Программа будет эффективно работать даже с большими базами сердечников и может быть легко расширена для дополнительных расчетов.
|