232 lines
9.4 KiB
Python
232 lines
9.4 KiB
Python
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__":
|
||
import argparse
|
||
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
|
||
)
|