Finish inp reader

This commit is contained in:
WQY\qiong
2022-11-18 21:10:01 +08:00
parent 1ee4a83d4c
commit 1e2f19e3c8

View File

@@ -28,17 +28,16 @@ from .s25_vertices import *
from .s26_labels import *
from .s27_backdrop import *
from .s28_end import *
from .command 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]]:
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']
file: dict[str, list[str]] = {}
for s in section_name:
file[s] = []
@@ -48,7 +47,11 @@ def parse_inp(inp: str) -> dict[str, list[str]]:
for line in open(inp):
line = line.strip()
if line == '':
section = ''
# skip empty line for control and rule
if section == 'CONTROLS' or section == 'RULES':
pass
else:
section = ''
continue
if line.startswith('['):
@@ -67,259 +70,125 @@ def parse_inp(inp: str) -> dict[str, list[str]]:
return file
def read_inp(project: str, inp: str):
file = parse_inp(inp)
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['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 # :)
cs = ChangeSet()
cs.merge(file_cs['PATTERNS'])
cs.merge(file_cs['CURVES'])
for s in section_name:
if s == 'PATTERNS' or s == 'CURVES':
continue
cs.merge(file_cs[s])
if is_project_open(project):
close_project(project)
if have_project(project):
delete_project(project)
create_project(project)
open_project(project)
execute_batch_command(project, cs)
def read_inp(name: str, inp: str):
if is_project_open(name):
close_project(name)
if have_project(name):
delete_project(name)
create_project(name)
open_project(name)
section = ''
file: dict[str, list[str]] = {}
_1_title : str = ''
_2_junctions : dict[str, dict[str, Any]] = {}
_3_reservoirs : dict[str, dict[str, Any]] = {}
_4_tanks : dict[str, dict[str, Any]] = {}
_5_pipes : dict[str, dict[str, Any]] = {}
_6_pumps : dict[str, dict[str, Any]] = {}
_7_valves : dict[str, dict[str, Any]] = {}
_9_demands : dict[str, list[dict[str, Any]]] = {}
_10_status : dict[str, dict[str, Any]] = {}
_11_patterns : dict[str, list[float]] = {}
_12_curves : dict[str, list[dict[str, float]]] = {}
_16_emitters : dict[str, float] = {}
_21_times : dict[str, str] = {}
_22_options : dict[str, str] = {}
for line in open(inp):
line = line.strip()
if line.startswith(';') and not line.endswith(':'):
continue
if line.endswith(';'):
line = line.removesuffix(';')
if line.startswith('[TITLE'):
section = 'title'
continue
if line.startswith('[JUNCTION'):
section = JUNCTION
continue
if line.startswith('[RESERVOIR'):
section = RESERVOIR
continue
if line.startswith('[TANK'):
section = TANK
continue
if line.startswith('[PIPE'):
section = PIPE
continue
if line.startswith('[PUMP'):
section = PUMP
continue
if line.startswith('[VALVE'):
section = VALVE
continue
if line.startswith('[DEMAND'):
section = 'demand'
continue
if line.startswith('[STATUS'):
section = 'status'
continue
if line.startswith('[PATTERN'):
section = PATTERN
continue
if line.startswith('[CURVE'):
section = CURVE
continue
if line.startswith('[EMITTER'):
section = 'emitter'
continue
if line.startswith('[TIME'):
section = 'time'
continue
if line.startswith('[OPTION'):
section = 'option'
continue
if line.startswith('[COORDINATE'):
section = 'coordinate'
continue
if line.startswith('['):
section = ''
continue
tokens = []
if section == 'time' or section == 'option':
tokens = line.upper().split()
else:
tokens = line.split()
tokens_len = len(tokens)
if tokens_len == 0:
continue
if section == 'title':
if _1_title == '':
_1_title += '\n'
_1_title += line
continue
elif section == JUNCTION:
junction_demand = float(tokens[2]) if tokens_len >= 3 else None
junction_pattern = tokens[3] if tokens_len == 4 else None
_2_junctions[tokens[0]] = {'id': tokens[0], 'elevation': tokens[1], 'demand': junction_demand, 'pattern': junction_pattern}
continue
elif section == RESERVOIR:
reservoir_pattern = tokens[2] if tokens_len == 3 else None
_3_reservoirs[tokens[0]] = {'id': tokens[0], 'head': tokens[1], 'pattern': reservoir_pattern}
continue
elif section == TANK:
tank_vol_curve = tokens[7] if tokens_len >= 8 else None
tank_overflow = tokens[8].upper() if tokens_len == 9 else None
_4_tanks[tokens[0]] = {'id': tokens[0], 'elevation': tokens[1], 'init_level': tokens[2], 'min_level': tokens[3], 'max_level': tokens[4], 'diameter': tokens[5], 'min_vol': tokens[6], 'vol_curve': tank_vol_curve, 'overflow': tank_overflow}
continue
elif section == PIPE:
# status is must-have, here fix input
pipe_status = tokens[7].upper() if tokens_len == 8 else PIPE_STATUS_OPEN
_5_pipes[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'length': tokens[3], 'diameter': tokens[4], 'roughness': tokens[5], 'minor_loss': tokens[6], 'status': pipe_status}
continue
elif section == PUMP:
_6_pumps[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2]}
for i in range(3, tokens_len, 2):
_6_pumps[tokens[0]] |= { tokens[i].lower(): tokens[i + 1] }
continue
elif section == VALVE:
_7_valves[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'diameter': tokens[3], 'v_type': tokens[4], 'setting': tokens[5], 'minor_loss': tokens[6]}
continue
elif section == 'demand':
demand_pattern = tokens[2] if tokens_len >= 3 else None
demand_category = tokens[3] if tokens_len == 4 else None
_9_demands[tokens[0]].append({'demand': tokens[1], 'pattern': demand_pattern, 'category': demand_category})
continue
elif section == 'status':
if tokens[0] not in _10_status:
_10_status[tokens[0]] = {}
setting = None
try:
setting = float(tokens[1])
except:
setting = None
if setting != None:
_10_status[tokens[0]]['setting'] = setting
else:
_10_status[tokens[0]]['status'] = tokens[1].upper()
continue
elif section == PATTERN:
if tokens[0] not in _11_patterns:
_11_patterns[tokens[0]] = []
for i in range(1, tokens_len):
_11_patterns[tokens[0]].append(float(tokens[i]))
continue
elif section == CURVE:
if tokens[0] not in _12_curves:
_12_curves[tokens[0]] = []
for i in range(1, tokens_len, 2):
_12_curves[tokens[0]].append({ 'x': float(tokens[i]), 'y': float(tokens[i + 1]) })
continue
elif section == 'emitter':
_16_emitters[tokens[0]] = float(tokens[1])
continue
elif section == 'time':
if tokens_len == 2:
_21_times[tokens[0]] = tokens[1]
elif tokens_len == 3:
_21_times[tokens[0] + ' ' + tokens[1]] = tokens[2]
elif tokens_len == 4:
_21_times[tokens[0] + ' ' + tokens[1]] = tokens[2] + ' ' + tokens[3]
continue
elif section == 'option':
if tokens[0] == 'HYDRAULICS' or tokens[0] == 'MAP':
continue
if tokens_len == 2:
_22_options[tokens[0]] = tokens[1]
elif tokens_len == 3:
if tokens[0] == 'UNBALANCED' or tokens[0] == 'QUALITY':
_22_options[tokens[0]] = tokens[1] + ' ' + tokens[2]
else:
_22_options[tokens[0] + ' ' + tokens[1]] = tokens[2]
continue
elif section == 'coordinate':
if tokens[0] in _2_junctions:
_2_junctions[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
elif tokens[0] in _3_reservoirs:
_3_reservoirs[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
elif tokens[0] in _4_tanks:
_4_tanks[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
continue
# title
set_title(name, ChangeSet({ 'value': _1_title }))
# pattern
for key, value in _11_patterns.items():
set_pattern(name, ChangeSet({'id': key, 'factors': value}))
# curve
for key, value in _12_curves.items():
set_curve(name, ChangeSet({'id': key, 'coords': value}))
# junction
for value in _2_junctions.values():
if 'x' not in value:
value['x'] = 0.0
if 'y' not in value:
value['y'] = 0.0
add_junction(name, ChangeSet(value))
# reservoir
for value in _3_reservoirs.values():
if 'x' not in value:
value['x'] = 0.0
if 'y' not in value:
value['y'] = 0.0
add_reservoir(name, ChangeSet(value))
# tank
for value in _4_tanks.values():
if 'x' not in value:
value['x'] = 0.0
if 'y' not in value:
value['y'] = 0.0
add_tank(name, ChangeSet(value))
# pipe
for value in _5_pipes.values():
add_pipe(name, ChangeSet(value))
# pump
for value in _6_pumps.values():
add_pump(name, ChangeSet(value))
# valve
for value in _7_valves.values():
add_valve(name, ChangeSet(value))
# demand
for key, value in _9_demands.items():
set_demand(name, ChangeSet({'junction': key, 'demands': value}))
# status
for key, value in _10_status.items():
set_status(name, ChangeSet({'link': key} | value))
# emitter
for key, value in _16_emitters.items():
set_emitter(name, ChangeSet({'junction': key, 'coefficient': value}))
# time
set_time(name, ChangeSet(_21_times))
# option
set_option(name, ChangeSet(_22_options))
close_project(name)
def dump_inp(name: str, inp: str):
pass