from typing import Any import os from .project import * from .s1_title import * from .s2_junctions import * from .s3_reservoirs import * from .s4_tanks import * from .s5_pipes import * from .s6_pumps import * from .s7_valves import * from .s8_tags import * from .s9_demands import * from .s10_status import * from .s11_patterns import * from .s12_curves import * from .s13_controls import * from .s14_rules import * from .s15_energy import * from .s16_emitters import * from .s17_quality import * from .s18_sources import * from .s19_reactions import * from .s20_mixing import * from .s21_times import * from .s22_report import * from .s23_options import * from .s24_coordinates import * from .s25_vertices import * from .s26_labels import * from .s27_backdrop import * from .s28_end import * from .batch_cmds import * section_name = ['TITLE', 'JUNCTIONS', 'RESERVOIRS', 'TANKS', 'PIPES', 'PUMPS', 'VALVES', 'TAGS', 'DEMANDS', 'STATUS', 'PATTERNS', 'CURVES', 'CONTROLS', 'RULES', 'ENERGY', 'EMITTERS', 'QUALITY', 'SOURCES', 'REACTIONS', 'MIXING', 'TIMES', 'REPORT', 'OPTIONS', 'COORDINATES', 'VERTICES', 'LABELS', 'BACKDROP', 'END'] def _parse_inp(inp: str) -> dict[str, list[str]]: file: dict[str, list[str]] = {} for s in section_name: file[s] = [] section = '' for line in open(inp): line = line.strip() if line == '': # skip empty line for control and rule if section == 'CONTROLS' or section == 'RULES': pass else: section = '' continue if line.startswith('['): is_section = False for s in section_name: if line.startswith(f'[{s}'): section = s is_section = True break if is_section: continue if section != '': file[section].append(line) return file def _parse_cs(cs: ChangeSet) -> dict[str, list[str]]: file: dict[str, list[str]] = {} for s in section_name: file[s] = [] section = '' for line in str(cs.operations[0]['inp']).split('\n'): line = line.strip() if line == '': # skip empty line for control and rule if section == 'CONTROLS' or section == 'RULES': pass else: section = '' continue if line.startswith('['): is_section = False for s in section_name: if line.startswith(f'[{s}'): section = s is_section = True break if is_section: continue if section != '': file[section].append(line) return file def _read_inp(file: dict[str, list[str]]) -> ChangeSet: file_cs: dict[str, ChangeSet] = {} for s in section_name: file_cs[s] = ChangeSet() for name, section in file.items(): if name == 'TITLE': file_cs[name].merge(inp_in_title(section)) elif name == 'JUNCTIONS': # + coords file_cs[name].merge(inp_in_junction(section)) elif name == 'RESERVOIRS': # + coords file_cs[name].merge(inp_in_reservoir(section)) elif name == 'TANKS': # + coords file_cs[name].merge(inp_in_tank(section)) elif name == 'PIPES': file_cs[name].merge(inp_in_pipe(section)) elif name == 'PUMPS': file_cs[name].merge(inp_in_pump(section)) elif name == 'VALVES': file_cs[name].merge(inp_in_valve(section)) elif name == 'TAGS': file_cs[name].merge(inp_in_tag(section)) elif name == 'DEMANDS': file_cs[name].merge(inp_in_demand(section)) elif name == 'STATUS': file_cs[name].merge(inp_in_status(section)) elif name == 'PATTERNS': file_cs[name].merge(inp_in_pattern(section)) elif name == 'CURVES': file_cs[name].merge(inp_in_curve(section)) elif name == 'CONTROLS': file_cs[name].merge(inp_in_control(section)) elif name == 'RULES': file_cs[name].merge(inp_in_rule(section)) elif name == 'ENERGY': file_cs[name].merge(inp_in_energy(section)) elif name == 'EMITTERS': file_cs[name].merge(inp_in_emitter(section)) elif name == 'QUALITY': file_cs[name].merge(inp_in_quality(section)) elif name == 'SOURCES': file_cs[name].merge(inp_in_source(section)) elif name == 'REACTIONS': file_cs[name].merge(inp_in_reaction(section)) elif name == 'MIXING': file_cs[name].merge(inp_in_mixing(section)) elif name == 'TIMES': file_cs[name].merge(inp_in_time(section)) elif name == 'REPORT': pass # ignore now, for simulation, always report all elif name == 'OPTIONS': file_cs[name].merge(inp_in_option(section)) elif name == 'COORDINATES': coords = inp_in_coord(section) for s in ['JUNCTIONS', 'RESERVOIRS', 'TANKS']: for node in file_cs[s].operations: if node['type'] == 'demand': continue if node['id'] in coords: coord = coords[node['id']] node |= { 'x' : coord['x'], 'y' : coord['y'] } else: print(f"WARNING: [{s}] {node['id']} has no coordinate, set it at origin!") node |= { 'x' : 0.0, 'y' : 0.0 } elif name == 'VERTICES': file_cs[name].merge(inp_in_vertex(section)) elif name == 'LABELS': file_cs[name].merge(inp_in_label(section)) elif name == 'BACKDROP': file_cs[name].merge(inp_in_backdrop(section)) elif name == 'END': pass # :) # release file file = {} cs = ChangeSet() priorities = [ 'PATTERNS', 'CURVES', 'JUNCTIONS', 'RESERVOIRS', 'TANKS', 'COORDINATES', 'PIPES', 'PUMPS', 'VALVES', 'DEMANDS', 'STATUS', 'OPTIONS', 'TIMES', 'EMITTERS', 'QUALITY', 'SOURCES', 'REACTIONS', 'MIXING', 'ENERGY', 'REPORT', 'VERTICES', 'CONTROLS', 'RULES', 'TITLE', 'TAGS', 'LABELS', 'BACKDROP', 'END', ] for s in priorities: cs.merge(file_cs[s]) return cs def read_inp(project: str, inp: str): if is_project_open(project): close_project(project) if have_project(project): delete_project(project) create_project(project) open_project(project) file = _parse_inp(inp) cs = _read_inp(file) execute_batch_commands(project, cs) op = get_current_operation(project) set_restore_operation(project, op) close_project(project) def import_inp(project: str, cs: ChangeSet) -> ChangeSet: if is_project_open(project): close_project(project) if have_project(project): delete_project(project) create_project(project) open_project(project) file = _parse_cs(cs) new_cs = _read_inp(file) success_cs = execute_batch_commands(project, new_cs) op = get_current_operation(project) set_restore_operation(project, op) close_project(project) # return ? return success_cs def dump_inp(project: str, inp: str): if not have_project(project): return if not is_project_open(project): open_project(project) dir = os.getcwd() path = os.path.join(dir, inp) if os.path.exists(path): os.remove(path) file = open(path, mode='w') for name in section_name: if name == 'TITLE': file.write(f'[{name}]\n') else: file.write(f'\n[{name}]\n') if name == 'TITLE': file.write('\n'.join(inp_out_title(project))) elif name == 'JUNCTIONS': # + coords file.write('\n'.join(inp_out_junction(project))) elif name == 'RESERVOIRS': # + coords file.write('\n'.join(inp_out_reservoir(project))) elif name == 'TANKS': # + coords file.write('\n'.join(inp_out_tank(project))) elif name == 'PIPES': file.write('\n'.join(inp_out_pipe(project))) elif name == 'PUMPS': file.write('\n'.join(inp_out_pump(project))) elif name == 'VALVES': file.write('\n'.join(inp_out_valve(project))) elif name == 'TAGS': file.write('\n'.join(inp_out_tag(project))) elif name == 'DEMANDS': file.write('\n'.join(inp_out_demand(project))) elif name == 'STATUS': file.write('\n'.join(inp_out_status(project))) elif name == 'PATTERNS': file.write('\n'.join(inp_out_pattern(project))) elif name == 'CURVES': file.write('\n'.join(inp_out_curve(project))) elif name == 'CONTROLS': file.write('\n'.join(inp_out_control(project))) elif name == 'RULES': file.write('\n'.join(inp_out_rule(project))) elif name == 'ENERGY': file.write('\n'.join(inp_out_energy(project))) elif name == 'EMITTERS': file.write('\n'.join(inp_out_emitter(project))) elif name == 'QUALITY': file.write('\n'.join(inp_out_quality(project))) elif name == 'SOURCES': file.write('\n'.join(inp_out_source(project))) elif name == 'REACTIONS': file.write('\n'.join(inp_out_reaction(project))) elif name == 'MIXING': file.write('\n'.join(inp_out_mixing(project))) elif name == 'TIMES': file.write('\n'.join(inp_out_time(project))) elif name == 'REPORT': file.write('\n'.join(inp_out_report(project))) elif name == 'OPTIONS': file.write('\n'.join(inp_out_option(project))) elif name == 'COORDINATES': file.write('\n'.join(inp_out_coord(project))) elif name == 'VERTICES': file.write('\n'.join(inp_out_vertex(project))) elif name == 'LABELS': file.write('\n'.join(inp_out_label(project))) elif name == 'BACKDROP': file.write('\n'.join(inp_out_backdrop(project))) elif name == 'END': pass # :) file.write('\n') file.close() close_project(project) def export_inp(project: str) -> ChangeSet: if not have_project(project): return ChangeSet() project_open = is_project_open(project) if not project_open: open_project(project) inp = '' for name in section_name: if name == 'TITLE': inp += f'[{name}]\n' else: inp += f'\n[{name}]\n' if name == 'TITLE': inp += '\n'.join(inp_out_title(project)) elif name == 'JUNCTIONS': # + coords inp += '\n'.join(inp_out_junction(project)) elif name == 'RESERVOIRS': # + coords inp += '\n'.join(inp_out_reservoir(project)) elif name == 'TANKS': # + coords inp += '\n'.join(inp_out_tank(project)) elif name == 'PIPES': inp += '\n'.join(inp_out_pipe(project)) elif name == 'PUMPS': inp += '\n'.join(inp_out_pump(project)) elif name == 'VALVES': inp += '\n'.join(inp_out_valve(project)) elif name == 'TAGS': inp += '\n'.join(inp_out_tag(project)) elif name == 'DEMANDS': inp += '\n'.join(inp_out_demand(project)) elif name == 'STATUS': inp += '\n'.join(inp_out_status(project)) elif name == 'PATTERNS': inp += '\n'.join(inp_out_pattern(project)) elif name == 'CURVES': inp += '\n'.join(inp_out_curve(project)) elif name == 'CONTROLS': inp += '\n'.join(inp_out_control(project)) elif name == 'RULES': inp += '\n'.join(inp_out_rule(project)) elif name == 'ENERGY': inp += '\n'.join(inp_out_energy(project)) elif name == 'EMITTERS': inp += '\n'.join(inp_out_emitter(project)) elif name == 'QUALITY': inp += '\n'.join(inp_out_quality(project)) elif name == 'SOURCES': inp += '\n'.join(inp_out_source(project)) elif name == 'REACTIONS': inp += '\n'.join(inp_out_reaction(project)) elif name == 'MIXING': inp += '\n'.join(inp_out_mixing(project)) elif name == 'TIMES': inp += '\n'.join(inp_out_time(project)) elif name == 'REPORT': inp += '\n'.join(inp_out_report(project)) elif name == 'OPTIONS': inp += '\n'.join(inp_out_option(project)) elif name == 'COORDINATES': inp += '\n'.join(inp_out_coord(project)) elif name == 'VERTICES': inp += '\n'.join(inp_out_vertex(project)) elif name == 'LABELS': inp += '\n'.join(inp_out_label(project)) elif name == 'BACKDROP': inp += '\n'.join(inp_out_backdrop(project)) elif name == 'END': pass # :) inp += '\n' if not project_open: close_project(project) return ChangeSet({'operation': 'export', 'inp': inp})