Единтсвенное что работает это Docker. Далее у меня не понятные ошибки :(
This commit is contained in:
parent
b08617960e
commit
57b2836861
5
.env
Normal file
5
.env
Normal file
@ -0,0 +1,5 @@
|
||||
DATABASE=SuperService
|
||||
POSTGRES_USER=UserSuperService
|
||||
POSTGRES_PASSWORD=NotWarningWord1
|
||||
CLICKHOUSE_USER=UserMyHouse
|
||||
CLICKHOUSE_PASSWORD=NotWarningWord2
|
56
README.md
56
README.md
@ -1,4 +1,4 @@
|
||||
# PIbd-42_SSPR
|
||||
# Описание проекта
|
||||
|
||||
Доработка автоматизированной системы планирования и выполнения численного моделирования процессов сжигания топлив в горелочных устройствах энергоустановок предназначена для оптимизации процессов проведения численных экспериментов с цифровой моделью горелочного устройства с целью поиска наиболее экономичных и низко-эмиссионных режимов работы
|
||||
|
||||
@ -7,4 +7,56 @@
|
||||
2. Клюшенкова Ксения
|
||||
3. Базунов Андрей
|
||||
4. Жимолостнова Анна
|
||||
5. Цуканова Ирина
|
||||
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
|
||||
```
|
||||
|
109
clickhouse_tools.py
Normal file
109
clickhouse_tools.py
Normal file
@ -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)
|
26
config.yaml
Normal file
26
config.yaml
Normal file
@ -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"
|
57
data_models.py
Normal file
57
data_models.py
Normal file
@ -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()
|
30
docker-compose.yml
Normal file
30
docker-compose.yml
Normal file
@ -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:
|
213
experiment_planner.py
Normal file
213
experiment_planner.py
Normal file
@ -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)
|
74
insert_to_db.py
Normal file
74
insert_to_db.py
Normal file
@ -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()
|
||||
|
||||
|
||||
|
||||
|
1339
macros_generator.py
Normal file
1339
macros_generator.py
Normal file
File diff suppressed because it is too large
Load Diff
224
new_experiment_planner.py
Normal file
224
new_experiment_planner.py
Normal file
@ -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)
|
0
oop_experiment_planner.py
Normal file
0
oop_experiment_planner.py
Normal file
375
postgres_tools.py
Normal file
375
postgres_tools.py
Normal file
@ -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()
|
8
requirements.txt
Normal file
8
requirements.txt
Normal file
@ -0,0 +1,8 @@
|
||||
requests
|
||||
psutil
|
||||
PyYAML
|
||||
psycopg[binary]
|
||||
clickhouse-driver
|
||||
pandas
|
||||
pydantic-settings
|
||||
clickhouse-connect
|
56
runner.py
Normal file
56
runner.py
Normal file
@ -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()
|
58
runner_db.py
Normal file
58
runner_db.py
Normal file
@ -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)
|
||||
|
||||
|
13
settings.py
Normal file
13
settings.py
Normal file
@ -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()
|
33
test_db.py
Normal file
33
test_db.py
Normal file
@ -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)
|
Loading…
Reference in New Issue
Block a user