Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New topology reader #61

Merged
merged 3 commits into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions controller_utils/precice_struct/PS_CouplingScheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def write_precice_xml_config(self, tag:etree, config): # config: PS_PreCICEConfi
""" write out the config XMl file """
coupling_scheme = self.write_participants_and_coupling_scheme( tag, config, "parallel-explicit" )

i = etree.SubElement(coupling_scheme, "max-time-windows", value=str(self.NrTimeStep))
i = etree.SubElement(coupling_scheme, "max-time", value=str(self.NrTimeStep))
attr = { "value": str(self.Dt)}
i = etree.SubElement(coupling_scheme, "time-window-size", attr)

Expand All @@ -155,7 +155,7 @@ def __init__(self):

self.NrTimeStep = -1
self.Dt = 1E-4
self.maxIteration = 100
self.maxIteration = 50
self.relativeConverganceEps = 1E-4
self.extrapolation_order = 2
self.postProcessing = PS_ImplicitPostPropocessing() # this is the postprocessing
Expand All @@ -180,7 +180,7 @@ def write_precice_xml_config(self, tag:etree, config): # config: PS_PreCICEConfi
""" write out the config XMl file """
coupling_scheme = self.write_participants_and_coupling_scheme( tag, config, "parallel-implicit" )

i = etree.SubElement(coupling_scheme, "max-time-windows", value = str(self.NrTimeStep))
i = etree.SubElement(coupling_scheme, "max-time", value = str(self.NrTimeStep))
attr = { "value": str(self.Dt)}
i = etree.SubElement(coupling_scheme, "time-window-size", attr)
i = etree.SubElement(coupling_scheme, "max-iterations", value=str(self.maxIteration))
Expand Down
8 changes: 4 additions & 4 deletions controller_utils/precice_struct/PS_PreCICEConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def write_precice_xml_config(self, filename:str, log:UT_PCErrorLogging, sync_mod
mystr = "vector"
pass
data_tag = etree.SubElement(precice_configuration_tag, etree.QName("data:"+mystr),
name=coupling_quantity.instance_name)
name=coupling_quantity.name)
pass

# 2 meshes
Expand All @@ -194,7 +194,7 @@ def write_precice_xml_config(self, filename:str, log:UT_PCErrorLogging, sync_mod
mesh_tag = etree.SubElement(precice_configuration_tag, "mesh", name=mesh.name, dimensions=str(dimensionality))
for quantities_name in mesh.quantities:
quant = mesh.quantities[quantities_name]
quant_tag = etree.SubElement(mesh_tag, "user-data", name=quant.instance_name)
quant_tag = etree.SubElement(mesh_tag, "use-data", name=quant.instance_name)

# 3 participants
for solver_name in self.solvers:
Expand Down Expand Up @@ -222,7 +222,7 @@ def write_precice_xml_config(self, filename:str, log:UT_PCErrorLogging, sync_mod
for q_name in solver.quantities_read:
q = solver.quantities_read[q_name]
read_tag = etree.SubElement(solver_tag,
"read-data", name=q.instance_name, mesh_name=solvers_mesh_name)
"read-data", name=q.name, mesh_name=solvers_mesh_name)
for other_solvers_name in q.list_of_solvers:
other_solver = q.list_of_solvers[other_solvers_name]
# consistent only read
Expand All @@ -245,7 +245,7 @@ def write_precice_xml_config(self, filename:str, log:UT_PCErrorLogging, sync_mod
for q_name in solver.quantities_write:
q = solver.quantities_write[q_name]
write_tag = etree.SubElement(solver_tag,
"write-data", name=q.instance_name, mesh_name=solvers_mesh_name)
"write-data", name=q.name, mesh_name=solvers_mesh_name)
for other_solvers_name in q.list_of_solvers:
other_solver = q.list_of_solvers[other_solvers_name]
# conservative only write
Expand Down
119 changes: 80 additions & 39 deletions controller_utils/ui_struct/UI_UserInput.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from controller_utils.ui_struct.UI_Participant import UI_Participant
from controller_utils.ui_struct.UI_Coupling import UI_Coupling
from controller_utils.myutils.UT_PCErrorLogging import UT_PCErrorLogging
from controller_utils.ui_struct.UI_Coupling import UI_CouplingType


class UI_UserInput(object):
"""
Expand All @@ -20,50 +22,89 @@ def __init__(self):
pass

def init_from_yaml(self, etree, mylog: UT_PCErrorLogging):
""" this method initializes all fields from a parsed YAML file
we assume that the YAML file has already has been parsed and we get
as input the root node of the file
"""
#todo catch the exceptions here
# Check if using new topology structure
if "coupling-scheme" in etree and "participants" in etree and "exchanges" in etree:
# --- Parse simulation info from 'coupling-scheme' ---
simulation_info = etree["coupling-scheme"]
self.sim_info.sync_mode = simulation_info.get("sync-mode", "on")
self.sim_info.mode = simulation_info.get("mode", "fundamental")
self.sim_info.steady = False
self.sim_info.NrTimeStep = 100 # Default or inferred value
self.sim_info.Dt = simulation_info.get("time-window-size", 1e-3)
self.sim_info.accuracy = "medium"

# --- Parse participants ---
self.participants = {}
participants_data = etree["participants"]
for participant_name, solver_info in participants_data.items():
new_participant = UI_Participant()
new_participant.name = participant_name
new_participant.solverName = solver_info
new_participant.solverType = "" # Placeholder; adjust if solver-type info available
new_participant.list_of_couplings = []
self.participants[participant_name] = new_participant

# build the simulation info
simulation_info = etree["simulation"]
# --- Parse couplings from exchanges ---
exchanges_list = etree["exchanges"]
# Group exchanges by unique participant pairs
groups = {}
for exchange in exchanges_list:
pair = tuple(sorted([exchange["from"], exchange["to"]]))
groups.setdefault(pair, []).append(exchange)

# Extract additional parameters
sync_mode = simulation_info.get("sync-mode", "on") # Default: "on"
mode = simulation_info.get("mode", "fundamental") # Default: "fundamental"
self.sim_info.sync_mode = sync_mode
self.sim_info.mode = mode
self.couplings = []
for pair, ex_list in groups.items():
coupling = UI_Coupling()
p1_name, p2_name = pair
coupling.partitcipant1 = self.participants[p1_name]
coupling.partitcipant2 = self.participants[p2_name]

self.sim_info.init_from_yaml(simulation_info, mylog)
# Determine coupling type based on exchanged data
data_names = {ex["data"] for ex in ex_list}
if "Force" in data_names and "Displacement" in data_names:
coupling.coupling_type = UI_CouplingType.fsi
elif "Force" in data_names:
coupling.coupling_type = UI_CouplingType.f2s
elif "Temperature" in data_names:
coupling.coupling_type = UI_CouplingType.cht
else:
coupling.coupling_type = UI_CouplingType.error_coupling

# build all the participants
participants_list = etree["participants"]
for participant_name in participants_list:
participant_data = participants_list[participant_name]
new_participant = UI_Participant()
new_participant.init_from_yaml(participant_data, participant_name, mylog)
# add the participant to the dictionary
self.participants[participant_name] = new_participant
pass
# Use the first exchange's patches as boundary interfaces (simple heuristic)
first_ex = ex_list[0]
coupling.boundaryC1 = first_ex.get("from-patch", "")
coupling.boundaryC2 = first_ex.get("to-patch", "")

# build the couplings
couplings_list = etree["couplings"]
for couplings in couplings_list:
# new coupling structure of the couplig section
# print("coupling name:", couplings)
# this will be only one loop always due to the YAML structure
for coupling_name in couplings:
# print("coupling type = ", coupling_name)
coupling_data = couplings[coupling_name]
# print("coupling data =",coupling_data)
new_coupling = UI_Coupling()
new_coupling.init_from_yaml(coupling_name, coupling_data, self.participants, mylog)
# add the coupling to the list of couplings
self.couplings.append(new_coupling)
self.couplings.append(coupling)
coupling.partitcipant1.list_of_couplings.append(coupling)
coupling.partitcipant2.list_of_couplings.append(coupling)

else:
# --- Fallback to original parsing logic for old YAML structures ---
try:
simulation_info = etree["simulation"]
sync_mode = simulation_info.get("sync-mode", "on")
mode = simulation_info.get("mode", "fundamental")
self.sim_info.sync_mode = sync_mode
self.sim_info.mode = mode
self.sim_info.init_from_yaml(simulation_info, mylog)

# mylog.rep_info("End building user input")
# build the list of participants
# Parse participants from the old structure
participants_list = etree["participants"]
for participant_name in participants_list:
participant_data = participants_list[participant_name]
new_participant = UI_Participant()
new_participant.init_from_yaml(participant_data, participant_name, mylog)
self.participants[participant_name] = new_participant

pass
# Parse couplings from the old structure
couplings_list = etree["couplings"]
self.couplings = []
for couplings in couplings_list:
for coupling_name in couplings:
coupling_data = couplings[coupling_name]
new_coupling = UI_Coupling()
new_coupling.init_from_yaml(coupling_name, coupling_data, self.participants, mylog)
self.couplings.append(new_coupling)
except Exception as e:
mylog.rep_error("Error during YAML initialization: " + str(e))
Loading