From 57b2836861c12b1dee83907eb93703e9ddd004ca Mon Sep 17 00:00:00 2001 From: maksim Date: Fri, 4 Oct 2024 17:19:46 +0400 Subject: [PATCH] =?UTF-8?q?=D0=95=D0=B4=D0=B8=D0=BD=D1=82=D1=81=D0=B2?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D0=BE=D0=B5=20=D1=87=D1=82=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82=20=D1=8D=D1=82=D0=BE?= =?UTF-8?q?=20Docker.=20=D0=94=D0=B0=D0=BB=D0=B5=D0=B5=20=D1=83=20=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=8F=20=D0=BD=D0=B5=20=D0=BF=D0=BE=D0=BD=D1=8F?= =?UTF-8?q?=D1=82=D0=BD=D1=8B=D0=B5=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8?= =?UTF-8?q?=20:(?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 5 + README.md | 56 +- clickhouse_tools.py | 109 +++ config.yaml | 26 + data_models.py | 57 ++ docker-compose.yml | 30 + experiment_planner.py | 213 ++++++ insert_to_db.py | 74 ++ macros_generator.py | 1339 +++++++++++++++++++++++++++++++++++++ new_experiment_planner.py | 224 +++++++ oop_experiment_planner.py | 0 postgres_tools.py | 375 +++++++++++ requirements.txt | 8 + runner.py | 56 ++ runner_db.py | 58 ++ settings.py | 13 + test_db.py | 33 + utils.py | 7 + 18 files changed, 2681 insertions(+), 2 deletions(-) create mode 100644 .env create mode 100644 clickhouse_tools.py create mode 100644 config.yaml create mode 100644 data_models.py create mode 100644 docker-compose.yml create mode 100644 experiment_planner.py create mode 100644 insert_to_db.py create mode 100644 macros_generator.py create mode 100644 new_experiment_planner.py create mode 100644 oop_experiment_planner.py create mode 100644 postgres_tools.py create mode 100644 requirements.txt create mode 100644 runner.py create mode 100644 runner_db.py create mode 100644 settings.py create mode 100644 test_db.py create mode 100644 utils.py diff --git a/.env b/.env new file mode 100644 index 0000000..01166f6 --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +DATABASE=SuperService +POSTGRES_USER=UserSuperService +POSTGRES_PASSWORD=NotWarningWord1 +CLICKHOUSE_USER=UserMyHouse +CLICKHOUSE_PASSWORD=NotWarningWord2 \ No newline at end of file diff --git a/README.md b/README.md index f358286..f848279 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PIbd-42_SSPR +# Описание проекта Доработка автоматизированной системы планирования и выполнения численного моделирования процессов сжигания топлив в горелочных устройствах энергоустановок предназначена для оптимизации процессов проведения численных экспериментов с цифровой моделью горелочного устройства с целью поиска наиболее экономичных и низко-эмиссионных режимов работы @@ -7,4 +7,56 @@ 2. Клюшенкова Ксения 3. Базунов Андрей 4. Жимолостнова Анна -5. Цуканова Ирина \ No newline at end of file +5. Цуканова Ирина + +# Запуск проекта +## 1. Создание окружения +``` +py -m venv .venv +``` +## 2. Переход в окружение +``` +.\.venv\Scripts\activate +``` +## 3. Скачивание библиотек +``` +pip install -r .\requirements.txt +``` +## 4. Создаем .env +Необходимо создать файл и поместить в него необходимые параметры. +``` +DATABASE=SuperService +POSTGRES_USER=UserSuperService +POSTGRES_PASSWORD=NotWarningWord1 +CLICKHOUSE_USER=UserMyHouse +CLICKHOUSE_PASSWORD=NotWarningWord2 +``` + +## 5. Запускаем все контейнеры +``` +docker-compose up --build +``` +При необходимости можем закрыть контейнера +``` +docker-compose down +``` + +## 6. Запускаем проект +``` +python runner.py +``` + +## 7. Подключение к ClickHouse +Команда входа в ClickHouse +``` +docker exec -it clickhouse-db clickhouse-client -u UserMyHouse --password NotWarningWord2 --host localhost +``` +Использовать базу данных +``` +USE SuperService; +``` +## 7. Подключение к PostgreSQL +Команда входа в ClickHouse +``` +docker exec -it postgres-db psql -U UserSuperService -d SuperService +``` diff --git a/clickhouse_tools.py b/clickhouse_tools.py new file mode 100644 index 0000000..6f9c03f --- /dev/null +++ b/clickhouse_tools.py @@ -0,0 +1,109 @@ +import time +import pandas as pd +import clickhouse_connect + +class ClickHouseClient: + def __init__(self, host='localhost', port=9000, database="default", username="", password=""): + self.host = host + self.port = port + self.database = database + self.username = username + self.password = password + self.client = self.connect_clickhouse() + self.initialize_table() + + def connect_clickhouse(self): + """ + Создает подключение к базе данных ClickHouse. + """ + return clickhouse_connect.get_client(host=self.host, port=self.port, database=self.database, username=self.username, password=self.password) + + def initialize_table(self): + """ + Инициализирует таблицу в ClickHouse, если она не существует. + """ + create_table_query = """ + CREATE TABLE IF NOT EXISTS experiment_data ( + volume Float64, + nitrogen_oxide_emission Float64, + temperature Float64, + co_fraction Float64, + co2_fraction Float64, + x Float64, + y Float64, + z Float64, + file_id String + ) ENGINE = MergeTree() + ORDER BY file_id + """ + self.client.command(create_table_query) + + def get_data(self): + """ + Извлекает максимальные и взвешенные средние значения из ClickHouse, включая разницу max(x) - min(x) при температуре > 1150. + :return: DataFrame с данными из ClickHouse. + """ + query = """ + SELECT + file_id, + MAX(temperature) AS max_temperature, + MAX(nitrogen_oxide_emission) AS max_nox, + MAX(co_fraction) AS max_co, + MAX(co2_fraction) AS max_co2, + SUM(volume * temperature) / SUM(volume) AS weighted_avg_temperature, + SUM(volume * nitrogen_oxide_emission) / SUM(volume) AS weighted_avg_nox, + SUM(volume * co_fraction) / SUM(volume) AS weighted_avg_co, + SUM(volume * co2_fraction) / SUM(volume) AS weighted_avg_co2, + MAX(if(temperature > 1150, x, NULL)) - MIN(if(temperature > 1150, x, NULL)) AS x_range_high_temp, + MAX(if(temperature > 1150, y, NULL)) - MIN(if(temperature > 1150, y, NULL)) AS y_range_high_temp, + MAX(if(temperature > 1150, z, NULL)) - MIN(if(temperature > 1150, z, NULL)) AS z_range_high_temp, + SUM(if(temperature > 1150, volume, NULL)) AS flame_volume + FROM + experiment_data + GROUP BY + file_id + """ + + results = self.client.query(query) + columns = ["file_id", "max_temperature", "max_nox", "max_co", "max_co2", + "weighted_avg_temperature", "weighted_avg_nox", "weighted_avg_co", "weighted_avg_co2", + "x_range_high_temp", "y_range_high_temp", "z_range_high_temp", "flame_volume"] + + return pd.DataFrame(results.result_rows, columns=columns) + + def save_csv_to_clickhouse(self, csv_path, file_id): + """ + Загружает данные из CSV файла в ClickHouse. + :param csv_path: Путь к CSV файлу. + :param file_id: Идентификатор файла. + """ + # Чтение данных из CSV + df = pd.read_csv(csv_path, delimiter=';', decimal='.') + + # Переименовать колонки + rename_dict = { + "Volume (m^3)": "volume", + "Mass Fraction of Nitrogen Oxide Emission": "nitrogen_oxide_emission", + "Temperature (K)": "temperature", + "Mass Fraction of CO": "co_fraction", + "Mass Fraction of CO2": "co2_fraction", + "X (m)": "x", + "Y (m)": "y", + "Z (m)": "z" + } + df.rename(columns=rename_dict, inplace=True) + + df['x'] = abs(df['x']) + df['x'] = df['x'] - df['x'].min() + df['y'] = df['y'] - df['y'].min() + df['z'] = df['z'] - df['z'].min() + + # Добавление столбца идентификатора файла + df["file_id"] = file_id + + # Удаление существующих записей для данного файла + delete_query = "ALTER TABLE experiment_data DELETE WHERE file_id = %(file_id)s" + self.client.command(delete_query, parameters={'file_id': file_id}) + + # Вставка данных в ClickHouse + self.client.insert_df('experiment_data', df) \ No newline at end of file diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..ef73fa3 --- /dev/null +++ b/config.yaml @@ -0,0 +1,26 @@ +paths: + starccm: '/home/user/Siemens/19.02.009-R8/STAR-CCM+19.02.009-R8/star/bin/starccm+' + chemkin: '/media/user/Projects/burner_data/chemkin' + main: '/media/user/Data/experiment_data' + +parameters: + number_processes: 16 + mesh_base_size: 0.7 + stopping_criterion: 7000 + diameters: + d1: 1442 + d2: 1016 + d3: 640 + d4: 325 + d5: 325 + d6: 245 + default_values: + N1: 24 + L1: 70.0 + a1: 60.0 + N2: 18 + L2: 105.0 + N3: 9 + L3: 29.6 + +api_url: "http://10.6.23.120:8000/api/v1/generate_geom" \ No newline at end of file diff --git a/data_models.py b/data_models.py new file mode 100644 index 0000000..a63c47b --- /dev/null +++ b/data_models.py @@ -0,0 +1,57 @@ +import matplotlib.pyplot as mp +import pandas as pd +import seaborn as sb +from settings import settings + +from clickhouse_tools import ClickHouseClient +from postgres_tools import PostgresClient + + +class DataPreparer: + def __init__(self, clickhouse_host='localhost', postgres_host='localhost', postgres_db='your_db', + postgres_user='your_user', postgres_password='your_password'): + self.clickhouse_client = ClickHouseClient("localhost", 8123, database=settings.DATABASE, username=settings.CLICKHOUSE_USER, password=settings.CLICKHOUSE_PASSWORD) + self.postgres_client = PostgresClient( + dbname=settings.DATABASE, + user=settings.POSTGRES_USER, + password=settings.POSTGRES_PASSWORD, + host="localhost", + port="5432" + ) + + def prepare_ml_dataset(self): + """ + Подготавливает набор данных для машинного обучения, объединяя данные из ClickHouse и PostgreSQL. + :return: DataFrame с подготовленными данными. + """ + # clickhouse_data = self.clickhouse_client.get_data() + postgres_data = self.postgres_client.get_experiments() + result_data = self.postgres_client.get_data() + + # Объединение данных по file_id + ml_dataset = pd.merge(postgres_data, result_data, on='file_id') + + self.postgres_client.close() + + return ml_dataset + + +data_preparer = DataPreparer() + +# Подготовка набора данных для машинного обучения +ml_dataset = data_preparer.prepare_ml_dataset() +ml_dataset = ml_dataset.drop('file_id', axis=1) + +ml_dataset.to_csv('burner_data_pg_2.csv', index=False) + +# Находим колонки с одним уникальным значением +cols_to_drop = ml_dataset.columns[ml_dataset.nunique() == 1] + +# Удаляем эти колонки +ml_dataset = ml_dataset.drop(columns=cols_to_drop) + +fig, ax = mp.subplots(figsize=(40, 40)) +dataplot = sb.heatmap(ml_dataset.corr(), cmap="YlGnBu", annot=True) + +# displaying heatmap +mp.show() diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..28aa101 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +version: '3.8' + +services: + db: + image: postgres + container_name: postgres-db + environment: + POSTGRES_DB: ${DATABASE} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + + clickhouse: + image: clickhouse/clickhouse-server:latest + container_name: clickhouse-db + environment: + CLICKHOUSE_USER: ${CLICKHOUSE_USER} + CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD} + ports: + - "8123:8123" + - "9000:9000" + volumes: + - clickhouse_data:/var/lib/clickhouse + +volumes: + postgres_data: + clickhouse_data: diff --git a/experiment_planner.py b/experiment_planner.py new file mode 100644 index 0000000..f038920 --- /dev/null +++ b/experiment_planner.py @@ -0,0 +1,213 @@ +import requests +import os +import subprocess +import time +import psutil +import argparse +import macros_generator as mg + + +STARCCM_PATH = '/home/user/Siemens/19.02.009-R8/STAR-CCM+19.02.009-R8/star/bin/starccm+' +NUMBER_PROCESSES = 16 + + +def download_file_from_fastapi(api_url, params, full_file_name): + response = requests.post(api_url, json=params) + + if response.status_code == 200: + with open(full_file_name, "wb") as f: + f.write(response.content) + print("File downloaded successfully.") + else: + print(f"Failed to download file. Status code: {response.status_code}") + + +def terminate_process_by_name(process_name): + # Проходим по всем процессам в системе + for proc in psutil.process_iter(['pid', 'name']): + try: + # Если имя процесса совпадает с искомым + if proc.info['name'] == process_name: + # Завершаем процесс + proc.terminate() + print(f"Процесс '{process_name}' с PID {proc.pid} был завершен.") + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess) as e: + print(f"Не удалось завершить процесс '{process_name}': {e}") + + +def create_directory(path): + if not os.path.exists(path): + os.makedirs(path) + + +def delete_directory(path): + if os.path.exists(path): + os.remove(path) + + +def run_macros(macros_name, model_name=None, new_model=False, is_gpgpu=False): + + np_value = '1 -gpgpu auto' if is_gpgpu else str(NUMBER_PROCESSES) + + if new_model: + macros_command = f'{STARCCM_PATH} -np {np_value} -new -batch \'{macros_name}\'' + else: + if model_name is None: + raise ValueError("model_name must be provided if new_model is False") + macros_command = f'{STARCCM_PATH} -np {np_value} \'{model_name}\' -batch \'{macros_name}\'' + + subprocess.run( + ["bash", "-c", macros_command]) + + +def run_experiment(angle): + + chemkin_path = "/media/user/Новый том/burner_automation/burner_data/chemkin" + mesh_base_size = 0.7 + cpu_stopping_criterion = 200 + stopping_criterion = 7000 + + main_path = '/media/user/Новый том/burner_automation/experiment_data' + create_directory(main_path) + + diameters = {'d1': 1442, 'd2': 1016, 'd3': 640, 'd4': 325, 'd5': 325, 'd6': 245} + + default_values = { + "N1": 24, + "L1": 70.0, + "a1": 60.0, + "N2": 18, + "L2": 105.0, + "N3": 9, + "L3": 30.0 + } + + # number_outer_blades = [12, 24, 36, 48] + #number_outer_blades = 24.0 + # length_outer_blades = [44, 70, 86, 107.5] + #length_outer_blades = 70.0 + # angle_outer_blades = [30.0, 45.0, 60.0, 75.0] + # number_middle_blades = [9, 18, 27, 36] + #number_middle_blades = 18.0 + # load = [190, 260, 315, 400, 465] + # load_eco = [260, 315, 400, 465] + load = 450 + # recycling_eco = [0, 7, 14, 21, 28] + # recycling = [0, 5, 10, 15, 20, 25, 30] + # recycling = [0, 6, 12, 18, 24, 30] + recycling = 0 + + start_time = time.time() + + directories_list = [] + + api_url = "http://10.6.23.120:8000/api/v1/generate_geom" + params = { + "a1": angle + } + geometry_path = str(24) + '_' + str(70) + '_' + str(angle) + '_' + str(18) + geometry_path_full = os.path.join(main_path, geometry_path, 'geometry') + create_directory(geometry_path_full) + + geometry_file_name = os.path.join(geometry_path_full, 'geometry.stp') + + download_file_from_fastapi(api_url, params, geometry_file_name) + + macros_path = os.path.join(main_path, geometry_path, 'general_macros') + directories_list.append(macros_path) + + MODEL_PATH = os.path.join(main_path, geometry_path, 'model') + directories_list.append(MODEL_PATH) + + model_parameters = { + 'geometry_path': geometry_file_name, + 'chemkin_path': chemkin_path, + 'init_model_folder': MODEL_PATH, + 'bladeCount': 18, + 'mesh_base_size': mesh_base_size + } + + fuel_parameters = mg.load_calculation(load, diameters) + + recycling_parameters = mg.recycling_calculation(fuel_parameters['alpha'], fuel_parameters['gas_consumption'], + fuel_parameters['air_consumption'], recycling) + + experiments_path = os.path.join(main_path, geometry_path, 'experiments') + directories_list.append(experiments_path) + + load_path = os.path.join(experiments_path, str(load)) + directories_list.append(load_path) + + load_macros_experiment_path = os.path.join(load_path, 'macros') + directories_list.append(load_macros_experiment_path) + + load_model_experiment_path = os.path.join(load_path, 'model') + directories_list.append(load_model_experiment_path) + + recycling_experiment_path = os.path.join(load_path, str(recycling)) + directories_list.append(recycling_experiment_path) + + recycling_macros_experiment_path = os.path.join(recycling_experiment_path, 'macros') + directories_list.append(recycling_macros_experiment_path) + + solver_parameters = { + 'experiment_path': recycling_experiment_path, + 'stopping_criterion': stopping_criterion + } + + prc_macros_file = os.path.join(macros_path, 'preprocess_macro.java') + fuel_macros_file = os.path.join(load_macros_experiment_path, 'fuel_macro.java') + rec_macros_file = os.path.join(recycling_macros_experiment_path, 'recycle_macro.java') + run_macros_file = os.path.join(recycling_macros_experiment_path, 'run_macros.java') + + for directory in directories_list: + create_directory(directory) + + model_file = os.path.join(MODEL_PATH, 'init_model.sim') + + mg.preprocessor_settings(prc_macros_file, model_parameters, model_file) + + load_model_file = os.path.join(load_model_experiment_path, "load_"+str(load)+".sim") + + mg.fuel_settings(fuel_macros_file, fuel_parameters, load_model_file) + + exp_file = os.path.join(recycling_experiment_path, "recycling_"+str(recycling)+".sim") + + mg.fgm_table_settings(rec_macros_file, recycling_parameters, exp_file) + mg.setting_and_running_solver(run_macros_file, solver_parameters, exp_file) + + run_macros(prc_macros_file, new_model=True) + run_macros(fuel_macros_file, model_file) + run_macros(rec_macros_file, load_model_file) + run_macros(run_macros_file, exp_file, is_gpgpu=True) + _EXP_FILE = exp_file + "~" + delete_directory(_EXP_FILE) + + # solver_parameters['stopping_criterion'] = STOPPING_CRITERION + # mg.setting_and_running_solver(run_macros_file, solver_parameters, EXP_FILE) + # run_macros(run_macros_file, EXP_FILE, is_gpgpu=True) + # _EXP_FILE = EXP_FILE + "~" + # delete_directory(_EXP_FILE) + + # Конец замера времени + end_time = time.time() + + # Вычисление времени выполнения + execution_time = end_time - start_time + print(f"Execution time: {execution_time}") + + # time.sleep(10) + # + # processes_name = ["starccm+", "star-ccm+"] + # + # for process in processes_name: + # terminate_process_by_name(process) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Запуск экспериментов с энергетической установкой ГМУ-45") + parser.add_argument("angle", type=str, help="Угол наклона лопаток во внешнем контуре") + + args = parser.parse_args() + + run_experiment(args.angle) diff --git a/insert_to_db.py b/insert_to_db.py new file mode 100644 index 0000000..bc62a57 --- /dev/null +++ b/insert_to_db.py @@ -0,0 +1,74 @@ +from pathlib import Path +import yaml +from settings import settings + +from clickhouse_tools import ClickHouseClient +import utils +from postgres_tools import PostgresClient + +# Загрузка конфигурации из файла config.yaml +with open('config.yaml', 'r') as config_file: + config = yaml.safe_load(config_file) + +MAIN_PATH = config['paths']['main'] +main_path = Path(MAIN_PATH) + + +def add_data_to_db(experiment_parameters, load_parameters, recycling_parameters): + + geometry_path = (f"{experiment_parameters['outer_blades_count']}_{experiment_parameters['outer_blades_length']}_" + f"{experiment_parameters['outer_blades_angle']}_{experiment_parameters['middle_blades_count']}") + experiments_path = main_path / geometry_path / 'experiments' + load_path = experiments_path / str(experiment_parameters['load']) + load_parameters_path = load_path / 'parameters' + recycling_path = load_path / str(experiment_parameters['recycling']) + load_parameters_file = load_parameters_path / f"load_{experiment_parameters['load']}_parameters.yaml" + plot_csv = recycling_path / 'plot.csv' + table_csv = recycling_path / 'data_table.csv' + + file_id = utils.calculate_hash(experiment_parameters) + + clickhouse_client = ClickHouseClient("localhost", 8123, settings.DATABASE, settings.CLICKHOUSE_USER, settings.CLICKHOUSE_PASSWORD) + + # Инициализация базы данных + db = PostgresClient( + dbname=settings.DATABASE, + user=settings.POSTGRES_USER, + password=settings.POSTGRES_PASSWORD, + host="localhost", + port="5432" + ) + + try: + + if load_parameters_file.exists(): + with open(load_parameters_file, 'r') as fuel_dict_file: + fuel_parameters = yaml.safe_load(fuel_dict_file) + load_parameters['primary_air_consumption'] = fuel_parameters['primary_air_consumption'] + load_parameters['secondary_air_consumption'] = fuel_parameters['secondary_air_consumption'] + load_parameters['gas_inlet_consumption'] = fuel_parameters['gas_inlet_consumption'] + + # Вставка данных в load_parameters и получение id + load_id = db.insert_load_parameters(load_parameters) + + # Вставка данных в recycling_parameters и получение id + recycling_id = db.insert_recycling_parameters(recycling_parameters, load_id) + + # Вставка данных в experiment_parameters + db.insert_experiment_parameters(experiment_parameters, load_id, recycling_id, file_id) + + # Сохранение изменений + db.connection.commit() + + db.save_csv_to_postgres(plot_csv, file_id) + + clickhouse_client.save_csv_to_clickhouse(table_csv, file_id) + + print('Загружено: ', experiment_parameters) + + finally: + db.close() + + + + diff --git a/macros_generator.py b/macros_generator.py new file mode 100644 index 0000000..9168031 --- /dev/null +++ b/macros_generator.py @@ -0,0 +1,1339 @@ +def recycling_calculation(alpha: float, gas_consumption: float, air_consumption: float, recycling: float) -> dict: + recycling_percent = recycling / 100 + + init_concentrations = {'CO2': 1.03, 'N2': 7.67, 'H2O': 2.17, 'O2': 9.69 * (alpha - 1)} + # init_concentrations_N = 73.5 + init_concentrations_O2 = 23.15 + + amount_flue_gases = 0 + for v in init_concentrations.values(): + amount_flue_gases = amount_flue_gases + v + amount_flue_gases = amount_flue_gases * gas_consumption + + return_recirculation = amount_flue_gases * recycling_percent + + init_data_of_gases = dict() + for k, v in init_concentrations.items(): + init_data_of_gases[k] = v * gas_consumption + + gas_volume = dict() + for k, v in init_data_of_gases.items(): + gas_volume[k] = v * recycling_percent + + recycling_composition = {'CO2': gas_volume['CO2'] / air_consumption, 'H2O': gas_volume['H2O'] / air_consumption} + recycling_composition['O2'] = ((air_consumption - return_recirculation) * init_concentrations_O2 / 100 + gas_volume[ + 'O2']) / air_consumption + amount_percent_gases = 1 + for v in recycling_composition.values(): + amount_percent_gases = amount_percent_gases - v + recycling_composition['N2'] = amount_percent_gases + + return recycling_composition + + +def load_calculation(steam_consumption: float, diameters: dict, alpha=None) -> dict: + # перевод из миллиметров в метры + for key, value in diameters.items(): + diameters[key] = value / 1000 + + gas_density = 0.670723907 + if alpha is None: + alpha = (-0.0000000496 * steam_consumption ** 3 + 0.0000597347 * steam_consumption ** 2 - 0.0237830036 * + steam_consumption + 4.1600366991) + total_gas_consumption = (-0.0004574291 * steam_consumption ** 3 + 0.4767036785 * steam_consumption ** 2 - + 77.847437247 * steam_consumption + 15542.3008630679) + gas_consumption = total_gas_consumption / 8 + air_consumption = 9.69 * alpha * gas_consumption + + hydraulic_diameter_pa = diameters['d3'] - diameters['d4'] + hydraulic_diameter_sa = diameters['d1'] - diameters['d2'] + # hydraulic_diameter_g = diametrs['d5'] - diametrs['d6'] + + air_inlet_ratio_pa = hydraulic_diameter_pa / (hydraulic_diameter_pa + hydraulic_diameter_sa) + air_inlet_ratio_sa = 1 - air_inlet_ratio_pa + # print(air_inlet_ratio_pa, air_inlet_ratio_sa) + primary_air_consumption = 4 * (air_consumption / 3600 * air_inlet_ratio_sa) / ( + 3.14 * (diameters['d1'] / 2) ** 2 - 3.14 * (diameters['d2'] / 2) ** 2) + secondary_air_consumption = 4 * (air_consumption / 3600 * air_inlet_ratio_pa) / ( + 3.14 * (diameters['d3'] / 2) ** 2 - 3.14 * (diameters['d4'] / 2) ** 2) + gas_inlet_rate = gas_consumption / 3600 / (3.14 * (diameters['d5'] / 2) ** 2 - 3.14 * (diameters['d6'] / 2) ** 2) + gas_inlet_consumption = gas_consumption * gas_density / 3600 + # print(alpha, total_gas_consumption, gas_consumption, air_consumption, primary_air_consumption, secondary_air_consumption, gas_inlet_rate, gas_inlet_consumption) + outlet_data = {'alpha': alpha, 'gas_consumption': gas_consumption, 'air_consumption': air_consumption, + 'primary_air_consumption': primary_air_consumption, + 'secondary_air_consumption': secondary_air_consumption, 'gas_inlet_rate': gas_inlet_rate, + 'gas_inlet_consumption': gas_inlet_consumption} + + return outlet_data + + +def preprocessor_settings(path, model_parameters, model_path): + macros_file = open(path, 'w') + macros_file.write(""" +import java.util.*; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; + +import star.combustion.*; +import star.combustion.fgm.*; +import star.combustion.tablegenerators.*; +import star.common.*; +import star.mapping.*; +import star.base.neo.*; +import star.cadmodeler.*; +import star.dualmesher.VolumeControlDualMesherSizeOption; +import star.emissions.NoxModel; +import star.emissions.NoxSolver; +import star.emissions.NoxThreeEquationZeldovichModel; +import star.energy.StaticTemperatureProfile; +import star.flow.MassFlowRateProfile; +import star.flow.VelocityMagnitudeProfile; +import star.keturb.KEpsilonTurbulence; +import star.keturb.KeTwoLayerAllYplusWallTreatment; +import star.keturb.RkeTwoLayerTurbModel; +import star.material.MaterialDataBaseManager; +import star.material.MultiComponentGasModel; +import star.meshing.*; +import star.reactions.ReactingModel; +import star.resurfacer.VolumeControlResurfacerSizeOption; +import star.segregatedenergy.SegregatedFluidEnthalpyModel; +import star.segregatedflow.SegregatedFlowModel; +import star.turbulence.RansTurbulenceModel; +import star.turbulence.TurbulentModel; +import star.vis.*; + +public class preprocess_macro extends StarMacro { + + String geometry_path = resolvePath("%s"); + String chemkin_path = resolvePath("%s"); + String grimech30_path = chemkin_path + "/grimech30.dat"; + String thermo30_path = chemkin_path + "/thermo30.dat"; + String transport_path = chemkin_path + "/transport.dat"; + String init_model_folder = resolvePath("%s"); + + public void execute() { + + /*Simulation sim = + getActiveSimulation();*/ + + long startTime = System.currentTimeMillis(); + + importGeometry(); + createCylinderParts(); + createVolumeMeshControl(); + createBoundaries(); + generateVolumeMesh(); + settingPhysicsContinuum(); + createFgmTable(); + setInitialConditions(); + createLineSection(); + createPlaneSection(); + createScene(); + createPlot(); + createXYZTable(); + //initializeSolution(); + saveState(); + + long endTime = System.currentTimeMillis(); + + long durationInMilliseconds = endTime - startTime; + double durationInSeconds = durationInMilliseconds / 1000.0; + + String filename = init_model_folder + "/exec_time.txt"; + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) { + writer.write("Время создания модели: " + durationInSeconds + "\\n"); + } catch (IOException e) { + //sim.println("Ошибка при записи в файл: " + e.getMessage()); + } + + } + + private void importGeometry() { + + Simulation simulation = + getActiveSimulation(); + + CadModel cadModel = + simulation.get(SolidModelManager.class).createSolidModel(); + + cadModel.resetSystemOptions(); + + ImportCadFileFeature importCadFileFeature = + cadModel.importCadFile(resolvePath(geometry_path), true, false, false, false, false, false, false, true, false, true, NeoProperty.fromString("{\'NX\': 1, \'STEP\': 1, \'SE\': 1, \'CGR\': 1, \'SW\': 1, \'IFC\': 1, \'ACIS\': 1, \'JT\': 1, \'IGES\': 1, \'CATIAV5\': 1, \'CATIAV4\': 1, \'3DXML\': 1, \'CREO\': 1, \'INV\': 1}"), false, true); + + star.cadmodeler.Body cadmodelerBody = + ((star.cadmodeler.Body) importCadFileFeature.getBodyByIndex(1)); + + Face face_0 = + ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {0.01, 0.72, 0}))); + + cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_0}), "Air inlet", false); + + ArrayList coordinates = calculateCoordinatesClockwise(0.314, (int) %s); + + ArrayList faces = new ArrayList<>(); + + for (double[] coordinate : coordinates) { + faces.add((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(coordinate))); + } + + cadModel.setFaceNameAttributes(faces, "Air blades", false); + + Face face_2 = + ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {0.01, 0.153, 0}))); + + cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_2}), "CH4", false); + + Face face_3 = + ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {0.01, 0.114, 0}))); + + cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_3}), "No Gas 1", false); + + Face face_4 = + ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {0.01, 0.07, 0}))); + + cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_4}), "No Gas 2", false); + + Face face_5 = + ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {-10.667, 0.6180132, -0.6180132}))); + + cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_5}), "Outlet", false); + + cadModel.update(); + + simulation.get(SolidModelManager.class).endEditCadModel(cadModel); + + cadModel.createParts(new NeoObjectVector(new Object[] {cadmodelerBody}), new NeoObjectVector(new Object[] {}), true, false, 1, false, false, 3, "SharpEdges", 30.0, 2, true, 1.0E-5, false); + + } + + private void createCylinderParts() { + + Simulation simulation = + getActiveSimulation(); + + Units units_0 = + simulation.getUnitsManager().getPreferredUnits(Dimensions.Builder().length(1).build()); + + MeshPartFactory meshPartFactory = + simulation.get(MeshPartFactory.class); + + SimpleCylinderPart simpleCylinderPart_0 = + meshPartFactory.createNewCylinderPart(simulation.get(SimulationPartManager.class)); + + simpleCylinderPart_0.setDoNotRetessellate(true); + + LabCoordinateSystem labCoordinateSystem_0 = + simulation.getCoordinateSystemManager().getLabCoordinateSystem(); + + simpleCylinderPart_0.setCoordinateSystem(labCoordinateSystem_0); + + simpleCylinderPart_0.getStartCoordinate().setCoordinateSystem(labCoordinateSystem_0); + + simpleCylinderPart_0.getStartCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {0.01, 0.0, 0.0})); + + simpleCylinderPart_0.getEndCoordinate().setCoordinateSystem(labCoordinateSystem_0); + + simpleCylinderPart_0.getEndCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-0.667, 0.0, 0.0})); + + simpleCylinderPart_0.getRadius().setUnits(units_0); + + simpleCylinderPart_0.getRadius().setValue(0.721); + + simpleCylinderPart_0.getTessellationDensityOption().setSelected(TessellationDensityOption.Type.MEDIUM); + + simpleCylinderPart_0.rebuildSimpleShapePart(); + + simpleCylinderPart_0.setDoNotRetessellate(false); + + SimpleCylinderPart simpleCylinderPart_1 = + meshPartFactory.createNewCylinderPart(simulation.get(SimulationPartManager.class)); + + simpleCylinderPart_1.setDoNotRetessellate(true); + + simpleCylinderPart_1.setCoordinateSystem(labCoordinateSystem_0); + + simpleCylinderPart_1.getStartCoordinate().setCoordinateSystem(labCoordinateSystem_0); + + simpleCylinderPart_1.getStartCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-0.667, 0.0, 0.0})); + + simpleCylinderPart_1.getEndCoordinate().setCoordinateSystem(labCoordinateSystem_0); + + simpleCylinderPart_1.getEndCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-1.111, 0.0, 0.0})); + + simpleCylinderPart_1.getRadius().setUnits(units_0); + + simpleCylinderPart_1.getRadius().setValue(0.535); + + simpleCylinderPart_1.getTessellationDensityOption().setSelected(TessellationDensityOption.Type.MEDIUM); + + simpleCylinderPart_1.rebuildSimpleShapePart(); + + simpleCylinderPart_1.setDoNotRetessellate(false); + + SimpleCylinderPart simpleCylinderPart_2 = + meshPartFactory.createNewCylinderPart(simulation.get(SimulationPartManager.class)); + + simpleCylinderPart_2.setDoNotRetessellate(true); + + simpleCylinderPart_2.setCoordinateSystem(labCoordinateSystem_0); + + simpleCylinderPart_2.getStartCoordinate().setCoordinateSystem(labCoordinateSystem_0); + + simpleCylinderPart_2.getStartCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-1.111, 0.0, 0.0})); + + simpleCylinderPart_2.getEndCoordinate().setCoordinateSystem(labCoordinateSystem_0); + + simpleCylinderPart_2.getEndCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-10.667, 0.0, 0.0})); + + simpleCylinderPart_2.getRadius().setUnits(units_0); + + simpleCylinderPart_2.getRadius().setValue(1.5); + + simpleCylinderPart_2.getTessellationDensityOption().setSelected(TessellationDensityOption.Type.MEDIUM); + + simpleCylinderPart_2.rebuildSimpleShapePart(); + + simpleCylinderPart_2.setDoNotRetessellate(false); + + } + + private void createVolumeMeshControl(){ + + Simulation simulation = + getActiveSimulation(); + + Units units_0 = + ((Units) simulation.getUnitsManager().getObject("m")); + + SimpleCylinderPart simpleCylinderPart_0 = + ((SimpleCylinderPart) simulation.get(SimulationPartManager.class).getPart("Cylinder")); + + SimpleCylinderPart simpleCylinderPart_1 = + ((SimpleCylinderPart) simulation.get(SimulationPartManager.class).getPart("Cylinder 2")); + + SimpleCylinderPart simpleCylinderPart_2 = + ((SimpleCylinderPart) simulation.get(SimulationPartManager.class).getPart("Cylinder 3")); + + SolidModelPart solidModelPart_0 = + ((SolidModelPart) simulation.get(SimulationPartManager.class).getPart("Body 1")); + + AutoMeshOperation autoMeshOperation = + simulation.get(MeshOperationManager.class).createAutoMeshOperation(new StringVector(new String[] {}), new NeoObjectVector(new Object[] {solidModelPart_0})); + + autoMeshOperation.getMeshers().setMeshersByNames(new StringVector(new String[] {"star.resurfacer.ResurfacerAutoMesher", "star.dualmesher.DualAutoMesher"})); + + VolumeCustomMeshControl volumeCustomMeshControl_0 = + autoMeshOperation.getCustomMeshControls().createVolumeControl(); + + VolumeCustomMeshControl volumeCustomMeshControl_1 = + autoMeshOperation.getCustomMeshControls().createVolumeControl(); + + VolumeCustomMeshControl volumeCustomMeshControl_2 = + autoMeshOperation.getCustomMeshControls().createVolumeControl(); + + SurfaceCustomMeshControl surfaceCustomMeshControl_0 = + autoMeshOperation.getCustomMeshControls().createSurfaceControl(); + + volumeCustomMeshControl_0.getGeometryObjects().setQuery(null); + + volumeCustomMeshControl_0.getGeometryObjects().setObjects(simpleCylinderPart_0); + + volumeCustomMeshControl_1.getGeometryObjects().setQuery(null); + + volumeCustomMeshControl_1.getGeometryObjects().setObjects(simpleCylinderPart_1); + + volumeCustomMeshControl_2.getGeometryObjects().setQuery(null); + + volumeCustomMeshControl_2.getGeometryObjects().setObjects(simpleCylinderPart_2); + + surfaceCustomMeshControl_0.getGeometryObjects().setQuery(null); + + PartSurface partSurface_0 = + ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Default")); + + PartSurface partSurface_1 = + ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Outlet")); + + surfaceCustomMeshControl_0.getGeometryObjects().setObjects(partSurface_0, partSurface_1); + + surfaceCustomMeshControl_0.getCustomConditions().get(PartsTargetSurfaceSizeOption.class).setSelected(PartsTargetSurfaceSizeOption.Type.CUSTOM); + + PartsTargetSurfaceSize partsTargetSurfaceSize_0 = + surfaceCustomMeshControl_0.getCustomValues().get(PartsTargetSurfaceSize.class); + + Units units_1 = + ((Units) simulation.getUnitsManager().getObject("")); + + partsTargetSurfaceSize_0.getRelativeSizeScalar().setValueAndUnits(20.0, units_1); + + VolumeControlResurfacerSizeOption volumeControlResurfacerSizeOption_0 = + volumeCustomMeshControl_0.getCustomConditions().get(VolumeControlResurfacerSizeOption.class); + + volumeControlResurfacerSizeOption_0.setVolumeControlBaseSizeOption(true); + + VolumeControlDualMesherSizeOption volumeControlDualMesherSizeOption_0 = + volumeCustomMeshControl_0.getCustomConditions().get(VolumeControlDualMesherSizeOption.class); + + volumeControlDualMesherSizeOption_0.setVolumeControlBaseSizeOption(true); + + VolumeControlSize volumeControlSize_0 = + volumeCustomMeshControl_0.getCustomValues().get(VolumeControlSize.class); + + volumeControlSize_0.getRelativeSizeScalar().setValueAndUnits(2.0, units_1); + + VolumeControlResurfacerSizeOption volumeControlResurfacerSizeOption_1 = + volumeCustomMeshControl_1.getCustomConditions().get(VolumeControlResurfacerSizeOption.class); + + volumeControlResurfacerSizeOption_1.setVolumeControlBaseSizeOption(true); + + VolumeControlDualMesherSizeOption volumeControlDualMesherSizeOption_1 = + volumeCustomMeshControl_1.getCustomConditions().get(VolumeControlDualMesherSizeOption.class); + + volumeControlDualMesherSizeOption_1.setVolumeControlBaseSizeOption(true); + + VolumeControlSize volumeControlSize_1 = + volumeCustomMeshControl_1.getCustomValues().get(VolumeControlSize.class); + + volumeControlSize_1.getRelativeSizeScalar().setValueAndUnits(2.0, units_1); + + VolumeControlResurfacerSizeOption volumeControlResurfacerSizeOption_2 = + volumeCustomMeshControl_2.getCustomConditions().get(VolumeControlResurfacerSizeOption.class); + + volumeControlResurfacerSizeOption_2.setVolumeControlBaseSizeOption(true); + + VolumeControlDualMesherSizeOption volumeControlDualMesherSizeOption_2 = + volumeCustomMeshControl_2.getCustomConditions().get(VolumeControlDualMesherSizeOption.class); + + volumeControlDualMesherSizeOption_2.setVolumeControlBaseSizeOption(true); + + VolumeControlSize volumeControlSize_2 = + volumeCustomMeshControl_2.getCustomValues().get(VolumeControlSize.class); + + volumeControlSize_2.getRelativeSizeScalar().setValueAndUnits(5.0, units_1); + + autoMeshOperation.getDefaultValues().get(BaseSize.class).setValueAndUnits(%s, units_0); + + autoMeshOperation.getMesherParallelModeOption().setSelected(MesherParallelModeOption.Type.PARALLEL); + + } + + private void createBoundaries() { + + Simulation simulation = + getActiveSimulation(); + + Region region = + simulation.getRegionManager().createEmptyRegion(null); + + region.setPresentationName("Body 1"); + + SolidModelPart solidModelPart_0 = + ((SolidModelPart) simulation.get(SimulationPartManager.class).getPart("Body 1")); + + region.getPartGroup().addObjects(solidModelPart_0); + + Boundary boundary_0 = + region.getBoundaryManager().createEmptyBoundary("", null); + + boundary_0.setPresentationName("Air blades"); + + InletBoundary inletBoundary = + ((InletBoundary) simulation.get(ConditionTypeManager.class).get(InletBoundary.class)); + + boundary_0.setBoundaryType(inletBoundary); + + boundary_0.getGeometryPartEntityGroup().setQuery(null); + + PartSurface partSurface_2 = + ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Air blades")); + + boundary_0.getGeometryPartEntityGroup().setObjects(partSurface_2); + + Boundary boundary_1 = + region.getBoundaryManager().createEmptyBoundary("", null); + + boundary_1.setPresentationName("Air inlet"); + + boundary_1.getGeometryPartEntityGroup().setQuery(null); + + PartSurface partSurface_3 = + ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Air inlet")); + + boundary_1.getGeometryPartEntityGroup().setObjects(partSurface_3); + + boundary_1.setBoundaryType(inletBoundary); + + Boundary boundary_2 = + region.getBoundaryManager().createEmptyBoundary("", null); + + boundary_2.setPresentationName("CH4"); + + boundary_2.getGeometryPartEntityGroup().setQuery(null); + + PartSurface partSurface_4 = + ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("CH4")); + + boundary_2.getGeometryPartEntityGroup().setObjects(partSurface_4); + + MassFlowBoundary massFlowBoundary = + ((MassFlowBoundary) simulation.get(ConditionTypeManager.class).get(MassFlowBoundary.class)); + + boundary_2.setBoundaryType(massFlowBoundary); + + Boundary boundary_3 = + region.getBoundaryManager().createEmptyBoundary("", null); + + boundary_3.setPresentationName("No Gas 1"); + + boundary_3.getGeometryPartEntityGroup().setQuery(null); + + PartSurface partSurface_5 = + ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("No Gas 1")); + + boundary_3.getGeometryPartEntityGroup().setObjects(partSurface_5); + + Boundary boundary_4 = + region.getBoundaryManager().createEmptyBoundary("", null); + + boundary_4.setPresentationName("No Gas 2"); + + boundary_4.getGeometryPartEntityGroup().setQuery(null); + + PartSurface partSurface_6 = + ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("No Gas 2")); + + boundary_4.getGeometryPartEntityGroup().setObjects(partSurface_6); + + Boundary boundary_5 = + region.getBoundaryManager().createEmptyBoundary("", null); + + boundary_5.setPresentationName("Outlet"); + + boundary_5.getGeometryPartEntityGroup().setQuery(null); + + PartSurface partSurface_1 = + ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Outlet")); + + boundary_5.getGeometryPartEntityGroup().setObjects(partSurface_1); + + PressureBoundary pressureBoundary = + ((PressureBoundary) simulation.get(ConditionTypeManager.class).get(PressureBoundary.class)); + + boundary_5.setBoundaryType(pressureBoundary); + + } + + private void generateVolumeMesh() { + + Simulation simulation = + getActiveSimulation(); + + MeshPipelineController meshPipelineController = + simulation.get(MeshPipelineController.class); + + meshPipelineController.generateVolumeMesh(); + + } + + private void settingPhysicsContinuum() { + + Simulation simulation = + getActiveSimulation(); + + PhysicsContinuum physicsContinuum = + ((PhysicsContinuum) simulation.getContinuumManager().getContinuum("Physics 1")); + + physicsContinuum.enable(SteadyModel.class); + + physicsContinuum.enable(MultiComponentGasModel.class); + + physicsContinuum.enable(ReactingModel.class); + + physicsContinuum.enable(FlameletBasedModel.class); + + physicsContinuum.enable(FgmCombustionModel.class); + + physicsContinuum.enable(FgmReactionModel.class); + + physicsContinuum.enable(SegregatedFluidEnthalpyModel.class); + + physicsContinuum.enable(FgmIdealGasModel.class); + + physicsContinuum.enable(TurbulentModel.class); + + physicsContinuum.enable(RansTurbulenceModel.class); + + physicsContinuum.enable(SegregatedFlowModel.class); + + physicsContinuum.enable(KEpsilonTurbulence.class); + + physicsContinuum.enable(RkeTwoLayerTurbModel.class); + + physicsContinuum.enable(KeTwoLayerAllYplusWallTreatment.class); + + physicsContinuum.enable(TfcCombustionPartiallyPremixedModel.class); + + physicsContinuum.enable(SolutionInterpolationModel.class); + + physicsContinuum.enable(NoxModel.class); + + physicsContinuum.enable(NoxThreeEquationZeldovichModel.class); + + ProgressVariableIgnitor progressVariableIgnitor = + physicsContinuum.get(IgnitorManager.class).createIgnitor(ProgressVariableIgnitor.class); + + progressVariableIgnitor.getGeometryPartGroup().setQuery(null); + + SimpleCylinderPart simpleCylinderPart_0 = + ((SimpleCylinderPart) simulation.get(SimulationPartManager.class).getPart("Cylinder 3")); + + progressVariableIgnitor.getGeometryPartGroup().setObjects(simpleCylinderPart_0); + + PulseActivator pulseActivator = + ((PulseActivator) progressVariableIgnitor.getActivator()); + + Units units_0 = + ((Units) simulation.getUnitsManager().getObject("")); + + pulseActivator.getBegin().setValueAndUnits(200.0, units_0); + + pulseActivator.getEnd().setValueAndUnits(250.0, units_0); + + TfcCombustionPartiallyPremixedModel tfcCombustionPartiallyPremixedModel_0 = + physicsContinuum.getModelManager().getModel(TfcCombustionPartiallyPremixedModel.class); + + tfcCombustionPartiallyPremixedModel_0.getLaminarFlameSpeedOptions().setMethod(LaminarFlameSpeedGulderOption.class); + + } + + private void createFgmTable() { + + Simulation simulation = + getActiveSimulation(); + + PhysicsContinuum physicsContinuum = + ((PhysicsContinuum) simulation.getContinuumManager().getContinuum("Physics 1")); + + FgmTableGenerator fgmTableGenerator = + physicsContinuum.get(FgmTableGenerator.class); + + FgmTableParameters fgmTableParameters = + ((FgmTableParameters) fgmTableGenerator.getTableParameters()); + + fgmTableParameters.getTableProgressVariableDefinition().setSelected(TableProgressVariableDefinitionOption.Type.CHEMENTHALPY); + + Fgm0dIgnitionNumericalSettings fgm0dIgnitionNumericalSettings = + ((Fgm0dIgnitionNumericalSettings) fgmTableParameters.getFgm0dIgnitionNumericalSettings()); + + TableAxisParameters tableAxisParameters = + ((TableAxisParameters) fgm0dIgnitionNumericalSettings.getTableAxisParametersManager().getComponent("Heat Loss Ratio")); + + tableAxisParameters.setAdapt(true); + + FixedGridParameters fixedGridParameters = + tableAxisParameters.getFixedGridParameters(); + + IntegerValue integerValue_0 = + fixedGridParameters.getDimensionSizeValue(); + + integerValue_0.getQuantity().setValue(1.0); + + TableChemistryDefinition tableChemistryDefinition = + ((TableChemistryDefinition) fgmTableGenerator.getTableChemistryDefinition()); + + tableChemistryDefinition.importCaseFromChemkin(resolvePath(grimech30_path), resolvePath(thermo30_path), resolvePath(transport_path), "", ""); + + TableFluidStreamCollection tableFluidStreamCollection = + ((TableFluidStreamCollection) fgmTableGenerator.getTableFluidStreamCollection()); + + TableFluidStream tableFluidStream_0 = + ((TableFluidStream) tableFluidStreamCollection.getOxidizerStream()); + + Units units_1 = + ((Units) simulation.getUnitsManager().getObject("K")); + + tableFluidStream_0.getTemperature().setValueAndUnits(483.0, units_1); + + tableFluidStream_0.getFluidStreamComposition().setArray(new DoubleVector(new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.767, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.233, 0.0})); + + TableFluidStream tableFluidStream_1 = + ((TableFluidStream) tableFluidStreamCollection.getFuelStream()); + + tableFluidStream_1.getFluidStreamComposition().setArray(new DoubleVector(new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0})); + + TableSpeciesForPostProcessing tableSpeciesForPostProcessing_0 = + ((TableSpeciesForPostProcessing) fgmTableParameters.getTableSpeciesForPostProcessing()); + + ((TableSpeciesGroup) tableSpeciesForPostProcessing_0.getTableSpeciesGroup()).setQuery(null); + + star.material.MaterialDataBase materialMaterialDataBase = + simulation.get(MaterialDataBaseManager.class).getMatlDataBase("Table Generator"); + + star.material.DataBaseMaterialManager materialDataBaseMaterialManager = + materialMaterialDataBase.getFolder("Physics 1-Fgm"); + + star.material.DataBaseGas materialDataBaseGas_0 = + ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("CH4_Gas")); + + star.material.DataBaseGas materialDataBaseGas_1 = + ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("CO_Gas")); + + star.material.DataBaseGas materialDataBaseGas_2 = + ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("CO2_Gas")); + + star.material.DataBaseGas materialDataBaseGas_3 = + ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("H2O_Gas")); + + star.material.DataBaseGas materialDataBaseGas_4 = + ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("N2_Gas")); + + star.material.DataBaseGas materialDataBaseGas_5 = + ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("NO_Gas")); + + star.material.DataBaseGas materialDataBaseGas_6 = + ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("NO2_Gas")); + + star.material.DataBaseGas materialDataBaseGas_7 = + ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("O2_Gas")); + + star.material.DataBaseGas materialDataBaseGas_8 = + ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("OH_Gas")); + + ((TableSpeciesGroup) tableSpeciesForPostProcessing_0.getTableSpeciesGroup()).setObjects(materialDataBaseGas_0, materialDataBaseGas_1, materialDataBaseGas_2, materialDataBaseGas_3, materialDataBaseGas_4, materialDataBaseGas_5, materialDataBaseGas_6, materialDataBaseGas_7, materialDataBaseGas_8); + + FgmCombustionSolver fgmCombustionSolver = + ((FgmCombustionSolver) simulation.getSolverManager().getSolver(FgmCombustionSolver.class)); + + fgmCombustionSolver.setDifferentURFNumber(true); + + Units units_2 = + ((Units) simulation.getUnitsManager().getObject("")); + + fgmCombustionSolver.getUrfProgressVariableQuantity().setValueAndUnits(0.8, units_2); + + NoxSolver noxSolver = + ((NoxSolver) simulation.getSolverManager().getSolver(NoxSolver.class)); + + noxSolver.getUrfQuantity().setValueAndUnits(0.8, units_2); + + FgmTable fgmTable = + ((FgmTable) fgmTableGenerator.getFgmTable()); + + fgmTable.constructTable(); + + } + + private void setInitialConditions() { + + Simulation simulation = + getActiveSimulation(); + + Region region = + simulation.getRegionManager().getRegion("Body 1"); + + Boundary boundary = + region.getBoundaryManager().getBoundary("CH4"); + + MixtureFractionArrayProfile mixtureFractionArrayProfile = + boundary.getValues().get(MixtureFractionArrayProfile.class); + + mixtureFractionArrayProfile.getMethod(ConstantArrayProfileMethod.class).getQuantity().setArray(new DoubleVector(new double[] {1.0})); + + } + + private void createPlaneSection() { + + Simulation simulation = + getActiveSimulation(); + + PlaneSection planeSection = + (PlaneSection) simulation.getPartManager().createImplicitPart(new NeoObjectVector(new Object[] {}), new DoubleVector(new double[] {0.0, 0.0, 1.0}), new DoubleVector(new double[] {0.0, 0.0, 0.0}), 0, 1, new DoubleVector(new double[] {0.0}), null); + + planeSection.getInputParts().setQuery(null); + + Region region = + simulation.getRegionManager().getRegion("Body 1"); + + planeSection.getInputParts().setObjects(region); + + } + + private void createScene() { + + Simulation simulation = + getActiveSimulation(); + + simulation.getSceneManager().createScalarScene("Scalar Scene", "Outline", "Scalar", null); + + Scene scene = + simulation.getSceneManager().getScene("Scalar Scene 1"); + + scene.initializeAndWait(); + + ScalarDisplayer scalarDisplayer = + ((ScalarDisplayer) scene.getDisplayerManager().getObject("Scalar 1")); + + Legend legend = + scalarDisplayer.getLegend(); + + PredefinedLookupTable predefinedLookupTable = + ((PredefinedLookupTable) simulation.get(LookupTableManager.class).getObject("blue-yellow-red")); + + legend.setLookupTable(predefinedLookupTable); + + SceneUpdate sceneUpdate = + scene.getSceneUpdate(); + + HardcopyProperties hardcopyProperties = + sceneUpdate.getHardcopyProperties(); + + hardcopyProperties.setCurrentResolutionWidth(1440); + + hardcopyProperties.setCurrentResolutionHeight(720); + + scene.resetCamera(); + + scene.closeInteractive(); + + PartDisplayer partDisplayer = + ((PartDisplayer) scene.getDisplayerManager().getObject("Outline 1")); + + partDisplayer.setOutline(false); + + scalarDisplayer.getInputParts().setQuery(null); + + PlaneSection planeSection = + ((PlaneSection) simulation.getPartManager().getObject("Plane Section")); + + scalarDisplayer.getInputParts().setObjects(planeSection); + + scalarDisplayer.setFillMode(ScalarFillMode.NODE_SMOOTH); + + } + + private void createLineSection() { + + Simulation simulation = + getActiveSimulation(); + + LineSection lineSection = + simulation.getPartManager().createLineSection(new NeoObjectVector(new Object[] {}), new DoubleVector(new double[] {0.0, 0.0, 0.0}), new DoubleVector(new double[] {0.0, 0.0, 1.0}), 0, true, null); + + lineSection.getInputParts().setQuery(null); + + Region region = + simulation.getRegionManager().getRegion("Body 1"); + + lineSection.getInputParts().setObjects(region); + + LineSectionPointPoint lineSectionPointPoint = + lineSection.getPointPoint(); + + Units units_1 = + ((Units) simulation.getUnitsManager().getObject("m")); + + lineSectionPointPoint.getStartPointCoordinate().setCoordinate(units_1, units_1, units_1, new DoubleVector(new double[] {-10.666999816894531, 0.0, 0.0})); + + lineSectionPointPoint.getEndPointCoordinate().setCoordinate(units_1, units_1, units_1, new DoubleVector(new double[] {0.009999999776482582, 0.0, 0.0})); + + } + + private void createPlot() { + + Simulation simulation = + getActiveSimulation(); + + XYPlot xYPlot = + simulation.getPlotManager().create("star.common.XYPlot"); + + PlotUpdate plotUpdate = + xYPlot.getPlotUpdate(); + + HardcopyProperties hardcopyProperties = + plotUpdate.getHardcopyProperties(); + + hardcopyProperties.setCurrentResolutionWidth(1440); + + hardcopyProperties.setCurrentResolutionHeight(720); + + xYPlot.getParts().setQuery(null); + + LineSection lineSection_1 = + ((LineSection) simulation.getPartManager().getObject("Line Section")); + + xYPlot.getParts().setObjects(lineSection_1); + + YAxisType yAxisType_0 = + ((YAxisType) xYPlot.getYAxes().getAxisType("Y Type 1")); + + FieldFunctionUnits fieldFunctionUnits_0 = + yAxisType_0.getScalarFunction(); + + PrimitiveFieldFunction primitiveFieldFunction_0 = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("Temperature")); + + fieldFunctionUnits_0.setFieldFunction(primitiveFieldFunction_0); + + YAxisType yAxisType_1 = + xYPlot.getYAxes().createAxisType(); + + FieldFunctionUnits fieldFunctionUnits_1 = + yAxisType_1.getScalarFunction(); + + PrimitiveFieldFunction primitiveFieldFunction_1 = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("NitrogenOxide")); + + fieldFunctionUnits_1.setFieldFunction(primitiveFieldFunction_1); + + YAxisType yAxisType_2 = + xYPlot.getYAxes().createAxisType(); + + FieldFunctionUnits fieldFunctionUnits_2 = + yAxisType_2.getScalarFunction(); + + PrimitiveFieldFunction primitiveFieldFunction_2 = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("MassFractionCO2")); + + fieldFunctionUnits_2.setFieldFunction(primitiveFieldFunction_2); + + YAxisType yAxisType_3 = + xYPlot.getYAxes().createAxisType(); + + FieldFunctionUnits fieldFunctionUnits_3 = + yAxisType_3.getScalarFunction(); + + PrimitiveFieldFunction primitiveFieldFunction_3 = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("MassFractionCO")); + + fieldFunctionUnits_3.setFieldFunction(primitiveFieldFunction_3); + + AxisType axisType_0 = + xYPlot.getXAxisType(); + + Units units_1 = + ((Units) simulation.getUnitsManager().getObject("m")); + + axisType_0.getDirectionVector().setComponentsAndUnits(-1.0, 0.0, 0.0, units_1); + + } + + private void createXYZTable() { + + Simulation simulation = + getActiveSimulation(); + + XyzInternalTable xyzInternalTable = + simulation.getTableManager().create("star.common.XyzInternalTable"); + + PrimitiveFieldFunction primitiveFieldFunction_0 = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("NitrogenOxide")); + + PrimitiveFieldFunction primitiveFieldFunction_1 = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("Temperature")); + + PrimitiveFieldFunction primitiveFieldFunction_2 = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("MassFractionCO")); + + PrimitiveFieldFunction primitiveFieldFunction_3 = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("MassFractionCO2")); + + PrimitiveFieldFunction primitiveFieldFunction_4 = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("Volume")); + + xyzInternalTable.setFieldFunctions(new NeoObjectVector(new Object[] {primitiveFieldFunction_4, primitiveFieldFunction_0, primitiveFieldFunction_1, primitiveFieldFunction_2, primitiveFieldFunction_3})); + + xyzInternalTable.getParts().setQuery(null); + + Region region = + simulation.getRegionManager().getRegion("Body 1"); + + xyzInternalTable.getParts().setObjects(region); + + } + + private void initializeSolution() { + + Simulation simulation = + getActiveSimulation(); + + Solution solution = + simulation.getSolution(); + + solution.initializeSolution(); + + } + + private void saveState() { + + Simulation simulation = + getActiveSimulation(); + + simulation.saveState(resolvePath("%s")); + + } + + public static ArrayList calculateCoordinatesClockwise(double R, int bladeCount) { + + double stepDegrees = 360.0/bladeCount; + + ArrayList coordinates = new ArrayList<>(); + + for (double theta = 360.0; theta > 0; theta -= stepDegrees) { + double radianTheta = Math.toRadians(theta); + double x = (double) (R * Math.cos(radianTheta)); + double y = (double) (R * Math.sin(radianTheta)); + double z = 0.01; + coordinates.add(new double[] {z, x, y}); + } + return coordinates; + } + +} + """ % (model_parameters['geometry_path'], + model_parameters['chemkin_path'], + model_parameters['init_model_folder'], + str(model_parameters['bladeCount']), + str(model_parameters['mesh_base_size']), + model_path)) + macros_file.close() + + +def fuel_settings(path, fuel_parameters, model_path): + macros_file = open(path, 'w') + macros_file.write(""" +import java.util.*; + +import star.common.*; +import star.base.neo.*; +import star.flow.*; + +public class fuel_macro extends StarMacro { + + public void execute() { + + setInitialConditions(); + + } + + private void setInitialConditions() { + + Simulation simulation = getActiveSimulation(); + + Solution solution = + simulation.getSolution(); + + simulation.clearSolution(); + + Region region = + simulation.getRegionManager().getRegion("Body 1"); + + Boundary boundary_0 = + region.getBoundaryManager().getBoundary("Air blades"); + + VelocityMagnitudeProfile velocityMagnitudeProfile_0 = + boundary_0.getValues().get(VelocityMagnitudeProfile.class); + + Units units_0 = + ((Units) simulation.getUnitsManager().getObject("m/s")); + + velocityMagnitudeProfile_0.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValueAndUnits(%s, units_0); + + Boundary boundary_1 = + region.getBoundaryManager().getBoundary("Air inlet"); + + VelocityMagnitudeProfile velocityMagnitudeProfile_1 = + boundary_1.getValues().get(VelocityMagnitudeProfile.class); + + velocityMagnitudeProfile_1.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValueAndUnits(%s, units_0); + + Boundary boundary_2 = + region.getBoundaryManager().getBoundary("CH4"); + + MassFlowRateProfile massFlowRateProfile_0 = + boundary_2.getValues().get(MassFlowRateProfile.class); + + Units units_1 = + ((Units) simulation.getUnitsManager().getObject("kg/s")); + + massFlowRateProfile_0.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValueAndUnits(%s, units_1); + + simulation.saveState(resolvePath("%s")); + } +} + """ % (str(fuel_parameters['secondary_air_consumption']), + str(fuel_parameters['primary_air_consumption']), + str(fuel_parameters['gas_inlet_consumption']), + model_path)) + macros_file.close() + + +def fgm_table_settings(path, recycling_parameters, model_path): + macros_file = open(path, 'w') + macros_file.write(""" +package macro; + +import java.util.*; + +import star.common.*; +import star.base.neo.*; +import star.combustion.fgm.*; +import star.combustion.tablegenerators.*; + +public class recycle_macro extends StarMacro { + + public void execute() { + execute0(); + } + + private void execute0() { + + Simulation simulation_0 = + getActiveSimulation(); + + PhysicsContinuum physicsContinuum_0 = + ((PhysicsContinuum) simulation_0.getContinuumManager().getContinuum("Physics 1")); + + FgmTableGenerator fgmTableGenerator_0 = + physicsContinuum_0.get(FgmTableGenerator.class); + + FgmTable fgmTable_0 = + ((FgmTable) fgmTableGenerator_0.getFgmTable()); + + fgmTable_0.deleteTable(); + + TableFluidStreamCollection tableFluidStreamCollection_0 = + ((TableFluidStreamCollection) fgmTableGenerator_0.getTableFluidStreamCollection()); + + TableFluidStream tableFluidStream_0 = + ((TableFluidStream) tableFluidStreamCollection_0.getOxidizerStream()); + + tableFluidStream_0.getFluidStreamComposition().setArray(new DoubleVector(new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, %s, 0.0, 0.0, 0.0, %s, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, %s, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, %s, 0.0})); + + fgmTable_0.constructTable(); + + Solution solution_0 = + simulation_0.getSolution(); + + solution_0.initializeSolution(); + + simulation_0.saveState(resolvePath("%s")); + } +} + """ % (str(recycling_parameters['CO2']), + str(recycling_parameters['H2O']), + str(recycling_parameters['N2']), + str(recycling_parameters['O2']), + model_path)) + macros_file.close() + + +def setting_and_running_solver(path, solver_parameters, model_path): + macros_file = open(path, 'w') + macros_file.write(""" +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.*; + +import star.combustion.*; +import star.combustion.fgm.*; +import star.combustion.tablegenerators.*; +import star.common.*; +import star.mapping.*; +import star.base.neo.*; +import star.cadmodeler.*; +import star.dualmesher.VolumeControlDualMesherSizeOption; +import star.emissions.NoxModel; +import star.emissions.NoxSolver; +import star.emissions.NoxThreeEquationZeldovichModel; +import star.energy.StaticTemperatureProfile; +import star.flow.MassFlowRateProfile; +import star.flow.VelocityMagnitudeProfile; +import star.keturb.KEpsilonTurbulence; +import star.keturb.KeTwoLayerAllYplusWallTreatment; +import star.keturb.RkeTwoLayerTurbModel; +import star.material.MaterialDataBaseManager; +import star.material.MultiComponentGasModel; +import star.meshing.*; +import star.reactions.ReactingModel; +import star.resurfacer.VolumeControlResurfacerSizeOption; +import star.segregatedenergy.SegregatedFluidEnthalpyModel; +import star.segregatedflow.SegregatedFlowModel; +import star.turbulence.RansTurbulenceModel; +import star.turbulence.TurbulentModel; +import star.vis.*; + +public class run_macros extends StarMacro { + + List sceneParameters = Arrays.asList("Temperature", "NitrogenOxide", "MassFractionCO", "MassFractionCO2"); + String experiment_path = "%s"; + + public void execute() { + + Simulation sim = + getActiveSimulation(); + + long startTime = System.currentTimeMillis(); + + setStoppingCriterion(); + runSimulation(); + for (String param : sceneParameters) { + changeSceneFieldFunction(param); + String scene_path = experiment_path + System.getProperty("file.separator") + "scenes" + System.getProperty("file.separator") + param + ".png"; + saveScene(scene_path); + } + + String path_plot = experiment_path + System.getProperty("file.separator") + "plot.csv"; + savePlotData(path_plot); + + String data_table_path = experiment_path + System.getProperty("file.separator") + "data_table.csv"; + saveXYZTable(data_table_path); + + saveState(); + + long endTime = System.currentTimeMillis(); + + long durationInMilliseconds = endTime - startTime; + double durationInSeconds = durationInMilliseconds / 1000.0; + + String filename = experiment_path + "/exec_time.txt"; + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename, true))) { + writer.write("Время расчета модели: " + durationInSeconds + "\\n"); + } catch (IOException e) { + //sim.println("Ошибка при добавлении строки в файл: " + e.getMessage()); + } + + } + + private void setStoppingCriterion() { + + Simulation simulation = + getActiveSimulation(); + + StepStoppingCriterion stepStoppingCriterion = + ((StepStoppingCriterion) simulation.getSolverStoppingCriterionManager().getSolverStoppingCriterion("Maximum Steps")); + + IntegerValue integerValue = + stepStoppingCriterion.getMaximumNumberStepsObject(); + + integerValue.getQuantity().setValue(%s); + + } + + private void runSimulation() { + + Simulation simulation = + getActiveSimulation(); + + Solution solution = + simulation.getSolution(); + + solution.initializeSolution(); + + ResidualPlot residualPlot = + ((ResidualPlot) simulation.getPlotManager().getPlot("Residuals")); + + residualPlot.openInteractive(); + + simulation.getSimulationIterator().run(); + + } + + private void changeSceneFieldFunction(String FieldFunction) { + + Simulation simulation = + getActiveSimulation(); + + Scene scene = + simulation.getSceneManager().getScene("Scalar Scene 1"); + + ScalarDisplayer scalarDisplayer = + ((ScalarDisplayer) scene.getDisplayerManager().getObject("Scalar 1")); + + PrimitiveFieldFunction primitiveFieldFunction = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction(FieldFunction)); + + scalarDisplayer.getScalarDisplayQuantity().setFieldFunction(primitiveFieldFunction); + + } + + private void changePlotFieldFunction(String fieldFunction) { + + Simulation simulation = + getActiveSimulation(); + + XYPlot xYPlot = + ((XYPlot) simulation.getPlotManager().getPlot("XY Plot 1")); + + YAxisType yAxisType = + ((YAxisType) xYPlot.getYAxes().getAxisType("Y Type 1")); + + FieldFunctionUnits fieldFunctionUnits = + yAxisType.getScalarFunction(); + + PrimitiveFieldFunction primitiveFieldFunction = + ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction(fieldFunction)); + + fieldFunctionUnits.setFieldFunction(primitiveFieldFunction); + + } + + private void saveScene(String pathName) { + + Simulation simulation = + getActiveSimulation(); + + Scene scene = + simulation.getSceneManager().getScene("Scalar Scene 1"); + + scene.resetCamera(); + + scene.printAndWait(resolvePath(pathName), 1, 1920, 1080, true, false); + + } + + private void saveXYZTable(String pathName) { + + Simulation simulation = + getActiveSimulation(); + + XyzInternalTable xyzInternalTable = + ((XyzInternalTable) simulation.getTableManager().getTable("XYZ Internal Table")); + + xyzInternalTable.extract(); + + xyzInternalTable.export(resolvePath(pathName), ";"); + + } + + private void savePlotData(String save_path) { + + Simulation simulation = + getActiveSimulation(); + + XYPlot xYPlot = + ((XYPlot) simulation.getPlotManager().getPlot("XY Plot 1")); + + xYPlot.export(resolvePath(save_path), ","); + + } + + private void saveState() { + + Simulation simulation = + getActiveSimulation(); + + simulation.saveState(resolvePath("%s")); + + } + +} + """ % (solver_parameters['experiment_path'], + str(solver_parameters['stopping_criterion']), + model_path)) + macros_file.close() diff --git a/new_experiment_planner.py b/new_experiment_planner.py new file mode 100644 index 0000000..1bc1359 --- /dev/null +++ b/new_experiment_planner.py @@ -0,0 +1,224 @@ +import requests +import subprocess +import argparse +import yaml +import psutil +import time + +import macros_generator as mg +from settings import settings + +from clickhouse_tools import ClickHouseClient +import utils +from postgres_tools import PostgresClient + +from pathlib import Path +from contextlib import contextmanager + +# Загрузка конфигурации из файла config.yaml +with open('config.yaml', 'r') as config_file: + config = yaml.safe_load(config_file) + +STARCCM_PATH = config['paths']['starccm'] +CHEMKIN_PATH = config['paths']['chemkin'] +MAIN_PATH = config['paths']['main'] + +NUMBER_PROCESSES = config['parameters']['number_processes'] +MESH_BASE_SIZE = config['parameters']['mesh_base_size'] +STOPPING_CRITERION = config['parameters']['stopping_criterion'] +DIAMETERS = config['parameters']['diameters'] +DEFAULT_VALUES = config['parameters']['default_values'] + +API_URL = config['api_url'] + + +def download_file_from_fastapi(api_url, params, full_file_name): + try: + response = requests.post(api_url, json=params) + response.raise_for_status() + with open(full_file_name, "wb") as f: + f.write(response.content) + print("File downloaded successfully.") + except requests.RequestException as e: + print(f"Failed to download file: {e}") + + +def terminate_process_by_name(process_name): + for proc in psutil.process_iter(['pid', 'name']): + try: + if proc.info['name'] == process_name: + proc.terminate() + print(f"Process '{process_name}' with PID {proc.pid} was terminated.") + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess) as e: + print(f"Failed to terminate process '{process_name}': {e}") + + +def create_directory(path): + Path(path).mkdir(parents=True, exist_ok=True) + + +@contextmanager +def remove_file_on_exit(file_path): + try: + yield + finally: + if file_path.exists(): + file_path.unlink() + + +def run_macros(macros_name, model_name=None, new_model=False, is_gpgpu=False): + np_value = '1 -gpgpu auto' if is_gpgpu else str(NUMBER_PROCESSES) + + if new_model: + macros_command = f'{STARCCM_PATH} -np {np_value} -new -batch \'{macros_name}\'' + else: + if model_name is None: + raise ValueError("model_name must be provided if new_model is False") + macros_command = f'{STARCCM_PATH} -np {np_value} \'{model_name}\' -batch \'{macros_name}\'' + + subprocess.run(["bash", "-c", macros_command], check=True) + + +def run_experiment(outer_blades_count, outer_blades_length, outer_blades_angle, middle_blades_count, load, recycling): + main_path = Path(MAIN_PATH) + create_directory(main_path) + + geometry_path = f"{outer_blades_count}_{outer_blades_length}_{outer_blades_angle}_{middle_blades_count}" + geometry_path_full = main_path / geometry_path / 'geometry' + create_directory(geometry_path_full) + + geometry_file_name = geometry_path_full / 'geometry.stp' + + general_macros_path = main_path / geometry_path / 'general_macros' + create_directory(general_macros_path) + + model_path = main_path / geometry_path / 'model' + create_directory(model_path) + model_file = model_path / 'init_model.sim' + + experiments_path = main_path / geometry_path / 'experiments' + load_path = experiments_path / str(load) + load_parameters_path = load_path / 'parameters' + load_macros_path = load_path / 'macros' + load_model_path = load_path / 'model' + recycling_path = load_path / str(recycling) + recycling_macros_path = recycling_path / 'macros' + + for directory in [experiments_path, load_path, load_parameters_path, load_macros_path, load_model_path, + recycling_path, recycling_macros_path]: + create_directory(directory) + + load_parameters_file = load_parameters_path / f"load_{load}_parameters.yaml" + load_model_file = load_model_path / f"load_{load}.sim" + exp_file = recycling_path / f"recycling_{recycling}.sim" + + # Проверка наличия файла init_model.sim + if not model_file.exists(): + download_file_from_fastapi(API_URL, {"N1": outer_blades_count, + "L1": outer_blades_length, + "a1": outer_blades_angle, + "N2": middle_blades_count}, + geometry_file_name) + prc_macros_file = general_macros_path / 'preprocess_macro.java' + model_parameters = { + 'geometry_path': geometry_file_name, + 'chemkin_path': CHEMKIN_PATH, + 'init_model_folder': model_path, + 'bladeCount': middle_blades_count, + 'mesh_base_size': MESH_BASE_SIZE + } + mg.preprocessor_settings(prc_macros_file, model_parameters, model_file) + run_macros(prc_macros_file, new_model=True) + + if not load_parameters_file.exists(): + fuel_parameters = mg.load_calculation(float(load), DIAMETERS) + with open(load_parameters_file, 'w') as fuel_dict_file: + yaml.dump(fuel_parameters, fuel_dict_file, default_flow_style=False, allow_unicode=True) + else: + with open(load_parameters_file, 'r') as fuel_dict_file: + fuel_parameters = yaml.safe_load(fuel_dict_file) + + # Проверка наличия файла load_{load}.sim + if not load_model_file.exists(): + fuel_macros_file = load_macros_path / 'fuel_macro.java' + mg.fuel_settings(fuel_macros_file, fuel_parameters, load_model_file) + run_macros(fuel_macros_file, model_file) + + # Проверка наличия файла recycling_{recycling}.sim + if not exp_file.exists(): + rec_macros_file = recycling_macros_path / 'recycle_macro.java' + run_macros_file = recycling_macros_path / 'run_macros.java' + recycling_parameters = mg.recycling_calculation( + fuel_parameters['alpha'], fuel_parameters['gas_consumption'], fuel_parameters['air_consumption'], + float(recycling)) + solver_parameters = { + 'experiment_path': recycling_path, + 'stopping_criterion': STOPPING_CRITERION + } + mg.fgm_table_settings(rec_macros_file, recycling_parameters, exp_file) + mg.setting_and_running_solver(run_macros_file, solver_parameters, exp_file) + run_macros(rec_macros_file, load_model_file) + run_macros(run_macros_file, exp_file, is_gpgpu=True) + + experiment_parameters = { + 'outer_blades_count': int(float(outer_blades_count)), + 'outer_blades_length': outer_blades_length, + 'outer_blades_angle': outer_blades_angle, + 'middle_blades_count': int(float(middle_blades_count)), + 'load': float(load), + 'recycling': float(recycling), + } + + fields_to_select = ['primary_air_consumption', 'secondary_air_consumption', 'gas_inlet_consumption'] + + load_parameters = {key: fuel_parameters[key] for key in fields_to_select} + load_parameters['load'] = float(load) + + recycling_parameters['load'] = float(load) + recycling_parameters['recycling_level'] = float(recycling) + + plot_csv = recycling_path / 'plot.csv' + table_csv = recycling_path / 'data_table.csv' + + clickhouse_client = ClickHouseClient("localhost", 8123, settings.DATABASE, settings.CLICKHOUSE_USER, + settings.CLICKHOUSE_PASSWORD) + db = PostgresClient( + dbname=settings.DATABASE, + user=settings.POSTGRES_USER, + password=settings.POSTGRES_PASSWORD, + host="localhost", + port="5432" + ) + + file_id = utils.calculate_hash(experiment_parameters) + + try: + clickhouse_client.save_csv_to_clickhouse(table_csv, file_id) + print("Clickhouse saved successfully") + + load_id = db.insert_load_parameters(load_parameters) + recycling_id = db.insert_recycling_parameters(recycling_parameters, load_id) + db.insert_experiment_parameters(experiment_parameters, load_id, recycling_id, file_id) + db.connection.commit() + db.save_csv_to_postgres(plot_csv, file_id) + print("Postgres saved successfully") + finally: + db.close() + + with remove_file_on_exit(exp_file.with_suffix(".sim~")): + pass + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Запуск экспериментов с энергетической установкой ГМУ-45") + parser.add_argument("outer_blades_count", type=str, help="Количество лопаток во внешнем контуре") + parser.add_argument("outer_blades_length", type=str, help="Ширина лопаток во внешнем контуре") + parser.add_argument("outer_blades_angle", type=str, help="Угол наклона лопаток во внешнем контуре") + parser.add_argument("middle_blades_count", type=str, help="Количество лопаток в среднем контуре") + parser.add_argument("load", type=str, help="Паровая нагрузка") + parser.add_argument("recycling", type=str, help="Уровень рециркуляции уходящих газов") + + args = parser.parse_args() + + run_experiment(args.outer_blades_count, args.outer_blades_length, args.outer_blades_angle, args.middle_blades_count, + args.load, args.recycling) diff --git a/oop_experiment_planner.py b/oop_experiment_planner.py new file mode 100644 index 0000000..e69de29 diff --git a/postgres_tools.py b/postgres_tools.py new file mode 100644 index 0000000..017bfed --- /dev/null +++ b/postgres_tools.py @@ -0,0 +1,375 @@ +import psycopg +import pandas as pd + +class PostgresClient: + def __init__(self, dbname, user, password, host, port): + self.connection = psycopg.connect( + dbname=dbname, + user=user, + password=password, + host=host, + port=port + ) + self.init_db() + + def init_db(self): + with self.connection.cursor() as cur: + cur.execute(""" + CREATE TABLE IF NOT EXISTS load_parameters ( + id SERIAL PRIMARY KEY, + load NUMERIC NOT NULL UNIQUE, + primary_air_consumption NUMERIC NOT NULL, + secondary_air_consumption NUMERIC NOT NULL, + gas_inlet_consumption NUMERIC NOT NULL + ); + + CREATE TABLE IF NOT EXISTS recycling_parameters ( + id SERIAL PRIMARY KEY, + load_id INTEGER NOT NULL, + recycling_level NUMERIC NOT NULL, + CO2 NUMERIC NOT NULL, + N2 NUMERIC NOT NULL, + H2O NUMERIC NOT NULL, + O2 NUMERIC NOT NULL, + UNIQUE(load_id, recycling_level), + FOREIGN KEY (load_id) REFERENCES load_parameters(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS experiment_parameters ( + id SERIAL PRIMARY KEY, + outer_blades_count INTEGER NOT NULL, + outer_blades_length NUMERIC NOT NULL, + outer_blades_angle NUMERIC NOT NULL, + middle_blades_count INTEGER NOT NULL, + load_id INTEGER NOT NULL, + recycling_id INTEGER NOT NULL, + experiment_hash CHAR(64) NOT NULL UNIQUE, + FOREIGN KEY (load_id) REFERENCES load_parameters(id) ON DELETE CASCADE, + FOREIGN KEY (recycling_id) REFERENCES recycling_parameters(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS experiment_data ( + id BIGSERIAL PRIMARY KEY, + Direction DOUBLE PRECISION, + Temperature DOUBLE PRECISION, + NOx DOUBLE PRECISION, + CO2 DOUBLE PRECISION, + CO DOUBLE PRECISION, + file_id CHAR(64) NOT NULL + ); + """) + self.connection.commit() + + def insert_load_parameters(self, load_parameters): + with self.connection.cursor() as cur: + cur.execute("SELECT id FROM load_parameters WHERE load = %s", (load_parameters['load'],)) + load_id = cur.fetchone() + if load_id is None: + cur.execute(""" + INSERT INTO load_parameters (load, primary_air_consumption, secondary_air_consumption, gas_inlet_consumption) + VALUES (%s, %s, %s, %s) + RETURNING id; + """, (load_parameters['load'], load_parameters['primary_air_consumption'], + load_parameters['secondary_air_consumption'], load_parameters['gas_inlet_consumption'])) + load_id = cur.fetchone()[0] + else: + load_id = load_id[0] + self.connection.commit() + return load_id + + def insert_recycling_parameters(self, recycling_parameters, load_id): + with self.connection.cursor() as cur: + cur.execute("SELECT id FROM recycling_parameters WHERE load_id = %s AND recycling_level = %s", + (load_id, recycling_parameters['recycling_level'])) + recycling_id = cur.fetchone() + if recycling_id is None: + cur.execute(""" + INSERT INTO recycling_parameters (load_id, recycling_level, CO2, N2, H2O, O2) + VALUES (%s, %s, %s, %s, %s, %s) + RETURNING id; + """, (load_id, recycling_parameters['recycling_level'], recycling_parameters['CO2'], + recycling_parameters['N2'], recycling_parameters['H2O'], recycling_parameters['O2'])) + recycling_id = cur.fetchone()[0] + else: + recycling_id = recycling_id[0] + self.connection.commit() + return recycling_id + + def insert_experiment_parameters(self, experiment_parameters, load_id, recycling_id, file_id): + with self.connection.cursor() as cur: + cur.execute("SELECT id FROM experiment_parameters WHERE experiment_hash = %s", (file_id,)) + experiment_id = cur.fetchone() + if experiment_id is None: + cur.execute(""" + INSERT INTO experiment_parameters (outer_blades_count, outer_blades_length, outer_blades_angle, middle_blades_count, load_id, recycling_id, experiment_hash) + VALUES (%s, %s, %s, %s, %s, %s, %s); + """, (experiment_parameters['outer_blades_count'], experiment_parameters['outer_blades_length'], + experiment_parameters['outer_blades_angle'], experiment_parameters['middle_blades_count'], load_id, + recycling_id, file_id)) + self.connection.commit() + + def get_load_parameters(self, load): + with self.connection.cursor() as cur: + cur.execute("SELECT * FROM load_parameters WHERE load = %s", (load,)) + row = cur.fetchone() + if row: + return { + 'load': row[1], + 'primary_air_consumption': row[2], + 'secondary_air_consumption': row[3], + 'gas_inlet_consumption': row[4] + } + return None + + def get_recycling_parameters(self, load, recycling_level): + with self.connection.cursor() as cur: + cur.execute(""" + SELECT rp.* FROM recycling_parameters rp + JOIN load_parameters lp ON rp.load_id = lp.id + WHERE lp.load = %s AND rp.recycling_level = %s + """, (load, recycling_level)) + row = cur.fetchone() + if row: + return { + 'load': load, + 'recycling_level': row[2], + 'CO2': row[3], + 'N2': row[4], + 'H2O': row[5], + 'O2': row[6] + } + return None + + def get_experiment_parameters(self, experiment_hash): + with self.connection.cursor() as cur: + cur.execute("SELECT * FROM experiment_parameters WHERE experiment_hash = %s", (experiment_hash,)) + row = cur.fetchone() + if row: + load_params = self.get_load_parameters(row[5]) + recycling_params = self.get_recycling_parameters(load_params['load'], row[6]) + return { + 'outer_blades_count': row[1], + 'outer_blades_length': row[2], + 'outer_blades_angle': row[3], + 'middle_blades_count': row[4], + 'load': load_params['load'], + 'recycling': recycling_params['recycling_level'], + 'experiment_hash': row[7] + } + return None + + def get_experiments(self): + # query = """ + # SELECT + # ep.experiment_hash AS file_id, + # ep.outer_blades_count, + # ep.outer_blades_length, + # ep.outer_blades_angle, + # ep.middle_blades_count, + # lp.primary_air_consumption, + # lp.secondary_air_consumption, + # lp.gas_inlet_consumption, + # rp.n2, + # rp.o2, + # rp.h2o, + # rp.co2 + # FROM + # experiment_parameters ep + # JOIN + # load_parameters lp ON ep.load_id = lp.id + # JOIN + # recycling_parameters rp ON ep.recycling_id = rp.id + # """ + query = """ + SELECT + ep.experiment_hash AS file_id, + ep.outer_blades_count, + ep.outer_blades_length, + ep.outer_blades_angle, + ep.middle_blades_count, + lp.load, + rp.recycling_level + FROM + experiment_parameters ep + JOIN + load_parameters lp ON ep.load_id = lp.id + JOIN + recycling_parameters rp ON ep.recycling_id = rp.id + """ + with self.connection.cursor() as cursor: + cursor.execute(query) + data = cursor.fetchall() + columns = [desc[0] for desc in cursor.description] + + df = pd.DataFrame(data, columns=columns) + return df + + def save_csv_to_postgres(self, csv_path, file_id): + + try: + # Прочитать файл и добавить хэш как новую колонку + df = pd.read_csv(csv_path) + + first_col = df.columns[0] + df = df[[first_col] + [col for col in df.columns if "Line Section: Direction [-1,0,0] (m)" not in col]] + + # Переименовать колонки + rename_dict = { + "Line Section: Direction [-1,0,0] (m)": "Direction", + "Line Section: Temperature (K)": "Temperature", + "Line Section: Mass Fraction of Nitrogen Oxide Emission": "NOx", + "Line Section: Mass Fraction of CO2": "CO2", + "Line Section: Mass Fraction of CO": "CO" + } + df.rename(columns=rename_dict, inplace=True) + + df['file_id'] = file_id + + with self.connection.cursor() as cur: + cur.execute("SELECT file_id FROM experiment_data WHERE file_id = %s", (file_id,)) + row = cur.fetchone() + if row: + cur.execute("DELETE FROM experiment_data WHERE file_id = %s", (file_id,)) + self.connection.commit() + + # Вставка новых данных из DataFrame в таблицу + insert_query = ''' + INSERT INTO experiment_data (Direction, Temperature, NOx, CO2, CO, file_id) + VALUES (%s, %s, %s, %s, %s, %s) + ''' + data_to_insert = df.to_records(index=False).tolist() + cur.executemany(insert_query, data_to_insert) + self.connection.commit() + + # Закрытие соединения + cur.close() + + return "Success" + + except Exception as e: + return f"Failed: {str(e)}" + + def get_data(self): + query = """ + WITH max_temp AS ( + SELECT + file_id, + temperature AS max_temperature, + direction AS direction_for_max_temp, + ROW_NUMBER() OVER (PARTITION BY file_id ORDER BY temperature DESC) AS temp_rank + FROM + experiment_data + ), + max_co2 AS ( + SELECT + file_id, + co2 AS max_co2, + direction AS direction_for_max_co2, + ROW_NUMBER() OVER (PARTITION BY file_id ORDER BY co2 DESC) AS co2_rank + FROM + experiment_data + ), + max_co AS ( + SELECT + file_id, + co AS max_co, + direction AS direction_for_max_co, + ROW_NUMBER() OVER (PARTITION BY file_id ORDER BY co DESC) AS co_rank + FROM + experiment_data + ), + max_nox AS ( + SELECT + file_id, + nox AS max_nox, + direction AS direction_for_max_nox, + ROW_NUMBER() OVER (PARTITION BY file_id ORDER BY nox DESC) AS nox_rank + FROM + experiment_data + ) + SELECT + t.file_id, + t.direction_for_max_temp, + t.max_temperature, + cx.direction_for_max_co2, + cx.max_co2, + c.direction_for_max_co, + c.max_co, + n.direction_for_max_nox, + n.max_nox + FROM + (SELECT * FROM max_temp WHERE temp_rank = 1) t + LEFT JOIN + (SELECT * FROM max_nox WHERE nox_rank = 1) n ON t.file_id = n.file_id + LEFT JOIN + (SELECT * FROM max_co2 WHERE co2_rank = 1) cx ON t.file_id = cx.file_id + LEFT JOIN + (SELECT * FROM max_co WHERE co_rank = 1) c ON t.file_id = c.file_id; + """ + with self.connection.cursor() as cursor: + cursor.execute(query) + data = cursor.fetchall() + columns = [desc[0] for desc in cursor.description] + + df = pd.DataFrame(data, columns=columns) + return df + + def close(self): + self.connection.close() + + +# Основной скрипт +# def main(): +# # Данные +# experiment_parameters = { +# 'outer_blades_count': 24, +# 'outer_blades_length': 74.0, +# 'outer_blades_angle': 65.0, +# 'middle_blades_count': 18, +# 'load': 315.0, +# 'recycling': 8.0, +# } +# +# load_parameters = { +# 'load': 315.0, +# 'primary_air_consumption': 15.2239, +# 'secondary_air_consumption': 63.9876, +# 'gas_inlet_consumption': 0.8648 +# } +# +# recycling_parameters = { +# 'load': 315.0, +# 'recycling_level': 8.0, +# 'CO2': 0.04, +# 'N2': 0.70, +# 'H2O': 0.06, +# 'O2': 0.20 +# } +# +# # Инициализация базы данных +# db = PostgresClient( +# dbname="your_db_name", +# user="your_db_user", +# password="your_db_password", +# host="your_db_host", +# port="your_db_port" +# ) +# +# try: +# +# # Извлечение и печать данных +# retrieved_experiment = db.get_experiment_parameters(experiment_parameters['experiment_hash']) +# print("Retrieved experiment parameters:", retrieved_experiment) +# +# retrieved_load = db.get_load_parameters(load_parameters['load']) +# print("Retrieved load parameters:", retrieved_load) +# +# retrieved_recycling = db.get_recycling_parameters(recycling_parameters['load'], +# recycling_parameters['recycling_level']) +# print("Retrieved recycling parameters:", retrieved_recycling) +# finally: +# db.close() +# +# +# if __name__ == "__main__": +# main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8563e28 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +requests +psutil +PyYAML +psycopg[binary] +clickhouse-driver +pandas +pydantic-settings +clickhouse-connect \ No newline at end of file diff --git a/runner.py b/runner.py new file mode 100644 index 0000000..3788fab --- /dev/null +++ b/runner.py @@ -0,0 +1,56 @@ +import subprocess +import time + + +def run_script(): + + # outer_blades_count = [12.0, 24.0, 36.0, 48.0] + # outer_blades_count = [24.0, 36.0] + outer_blades_count = [24.0] + # outer_blades_length = [44.0, 86.0, 107.5] + outer_blades_length = [70.0] + # outer_blades_angle = [30.0, 45.0, 60.0, 75.0] + outer_blades_angle = [45.0, 60.0] + middle_blades_count = [9.0, 27.0, 36.0] + # middle_blades_count = 18.0 + # load = [190, 260, 315, 400, 465] + load = [315, 400, 465] + # load_eco = [260, 315, 400, 465] + # load = [190, 260, 465] + # recycling_eco = [0, 7, 14, 21, 28] + # recycling_full = [0, 5, 8, 10, 15, 20, 25, 30] + recycling_full = [0, 5, 10, 20] + # recycling = [0, 6, 12, 18, 24, 30] + # recycling = [0, 5, 8] + + for middle_count in middle_blades_count: + for length in outer_blades_length: + for outer_blade in outer_blades_count: + for angle in outer_blades_angle: + for current_load in load: + for current_recycling in recycling_full: + + # Начало замера времени + start_time = time.time() + + result = subprocess.run(['python', 'new_experiment_planner.py', str(outer_blade), + str(length), str(angle), str(middle_count), + str(current_load), str(current_recycling)], capture_output=True, text=True) + + # Конец замера времени + end_time = time.time() + + # Вычисление времени выполнения + execution_time = end_time - start_time + + print("Output of the script:") + print(result.stdout) + + print("Errors (if any):") + print(result.stderr) + + print("Execution time:", execution_time) + + +if __name__ == "__main__": + run_script() diff --git a/runner_db.py b/runner_db.py new file mode 100644 index 0000000..475e78f --- /dev/null +++ b/runner_db.py @@ -0,0 +1,58 @@ +from insert_to_db import add_data_to_db +import macros_generator as mg +import yaml + + +# Загрузка конфигурации из файла config.yaml +with open('config.yaml', 'r') as config_file: + config = yaml.safe_load(config_file) +DIAMETERS = config['parameters']['diameters'] + +# outer_blades_count = [12, 24, 36, 48] +outer_blades_count = 24.0 +# outer_blades_length = [44, 70, 86, 107.5] +outer_blades_length = 70.0 +outer_blades_angle = [30.0, 45.0, 60.0, 75.0] +# middle_blades_count = [9, 18, 27, 36] +middle_blades_count = 18.0 +# load = [190, 260, 315, 400, 465] +# load_eco = [260, 315, 400, 465] +load = [190, 260, 315, 400, 465] +# recycling_eco = [0, 7, 14, 21, 28] +recycling_full = [0, 5, 8, 10, 15, 20, 25, 30] +# recycling = [0, 6, 12, 18, 24, 30] +# recycling = [0, 5, 8] +for angle in outer_blades_angle: + for current_load in load: + for current_recycling in recycling_full: + + experiment_parameters = { + 'outer_blades_count': outer_blades_count, + 'outer_blades_length': outer_blades_length, + 'outer_blades_angle': angle, + 'middle_blades_count': middle_blades_count, + 'load': current_load, + 'recycling': current_recycling, + } + + _cur_diameters = DIAMETERS.copy() + + fuel_parameters = mg.load_calculation(float(current_load), _cur_diameters) + + load_parameters = { + 'load': current_load, + 'primary_air_consumption': fuel_parameters['primary_air_consumption'], + 'secondary_air_consumption': fuel_parameters['secondary_air_consumption'], + 'gas_inlet_consumption': fuel_parameters['gas_inlet_consumption'] + } + + recycling_parameters = mg.recycling_calculation( + fuel_parameters['alpha'], fuel_parameters['gas_consumption'], fuel_parameters['air_consumption'], + float(current_recycling)) + + recycling_parameters['load'] = float(current_load) + recycling_parameters['recycling_level'] = float(current_recycling) + + add_data_to_db(experiment_parameters, load_parameters, recycling_parameters) + + diff --git a/settings.py b/settings.py new file mode 100644 index 0000000..9022623 --- /dev/null +++ b/settings.py @@ -0,0 +1,13 @@ +from pydantic_settings import BaseSettings, SettingsConfigDict + +class Settings(BaseSettings): + DATABASE: str + POSTGRES_USER: str + POSTGRES_PASSWORD: str + CLICKHOUSE_USER: str + CLICKHOUSE_PASSWORD: str + + model_config = SettingsConfigDict(env_file=".env") + + +settings = Settings() diff --git a/test_db.py b/test_db.py new file mode 100644 index 0000000..749b8cf --- /dev/null +++ b/test_db.py @@ -0,0 +1,33 @@ +from clickhouse_tools import ClickHouseClient +from settings import settings +from pathlib import Path +import yaml +import utils + +experiment_parameters = { + 'outer_blades_count': 24.0, + 'outer_blades_length': 70.0, + 'outer_blades_angle': 60.0, + 'middle_blades_count': 18.0, + 'load': 400, + 'recycling': 15, + } + +with open('config.yaml', 'r') as config_file: + config = yaml.safe_load(config_file) + +MAIN_PATH = config['paths']['main'] +main_path = Path(MAIN_PATH) + +geometry_path = (f"{experiment_parameters['outer_blades_count']}_{experiment_parameters['outer_blades_length']}_" + f"{experiment_parameters['outer_blades_angle']}_{experiment_parameters['middle_blades_count']}") +experiments_path = main_path / geometry_path / 'experiments' +load_path = experiments_path / str(experiment_parameters['load']) +recycling_path = load_path / str(experiment_parameters['recycling']) +table_csv = recycling_path / 'data_table.csv' + +file_id = utils.calculate_hash(experiment_parameters) + +clickhouse_client = ClickHouseClient("localhost", 8123, 'SuperService', 'UserMyHouse', + 'NotWarningWord2') +clickhouse_client.save_csv_to_clickhouse(table_csv, file_id) \ No newline at end of file diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..c270b5c --- /dev/null +++ b/utils.py @@ -0,0 +1,7 @@ +import hashlib +import json + + +def calculate_hash(experiment_params): + params_str = json.dumps(experiment_params, sort_keys=True) + return hashlib.sha256(params_str.encode()).hexdigest() \ No newline at end of file