Skip to content

Commit

Permalink
Monitors and datasets import/export improvements (#3917)
Browse files Browse the repository at this point in the history
* Make monitors and datasets import/export through configurations valid for json validation

* fix ut
  • Loading branch information
lorenzovecchietti authored Dec 6, 2023
1 parent 223399e commit 3664c1b
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 98 deletions.
23 changes: 23 additions & 0 deletions _unittest/test_01_configuration_files.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# standard imports
import json
import os
import time

Expand Down Expand Up @@ -208,6 +209,28 @@ def test_04a_icepak(self, icepak_a, aedtapp, add_app):
out = app.configurations.import_config(conf_file)
assert isinstance(out, dict)
assert app.configurations.results.global_import_success
# backward compatibility
with open(conf_file, "r") as f:
old_dict_format = json.load(f)
old_dict_format["monitor"] = old_dict_format.pop("monitors")
old_mon_dict = {}
for mon in old_dict_format["monitor"]:
old_mon_dict[mon["Name"]] = mon
old_mon_dict[mon["Name"]].pop("Name")
old_dict_format["monitor"] = old_mon_dict
old_dataset_dict = {}
for dat in old_dict_format["datasets"]:
old_dataset_dict[dat["Name"]] = dat
old_dataset_dict[dat["Name"]].pop("Name")
old_dict_format["datasets"] = old_dataset_dict
old_conf_file = conf_file + ".old.json"
with open(old_conf_file, "w") as f:
json.dump(old_dict_format, f)
app = add_app(application=Icepak, project_name="new_proj_Ipk_a_test2", just_open=True)
app.modeler.import_3d_cad(file_path)
out = app.configurations.import_config(old_conf_file)
assert isinstance(out, dict)
assert app.configurations.results.global_import_success
app.close_project(save_project=False)

@pytest.mark.skipif(
Expand Down
137 changes: 77 additions & 60 deletions pyaedt/generic/configurations.py
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,8 @@ def _update_parametrics(self, name, props):
return False

@pyaedt_function_handler()
def _update_datasets(self, name, data_dict):
def _update_datasets(self, data_dict):
name = data_dict["Name"]
is_project_dataset = False
if name.startswith("$"):
is_project_dataset = True
Expand Down Expand Up @@ -1088,8 +1089,14 @@ def import_config(self, config_file, *args):

if self.options.import_datasets and dict_in.get("datasets", None):
self.results.import_datasets = True
for k, v in dict_in["datasets"].items():
self._update_datasets(k, v)
if not isinstance(dict_in["datasets"], list): # backward compatibility
dataset_list = []
for k, v in dict_in["datasets"].items():
v["Name"] = k
dataset_list.append(v)
dict_in["datasets"] = dataset_list
for dataset in dict_in["datasets"]:
self._update_datasets(dataset)

if self.options.import_boundaries and dict_in.get("boundaries", None):
self.results.import_boundaries = True
Expand Down Expand Up @@ -1272,24 +1279,27 @@ def _export_mesh_operations(self, dict_out):
def _export_datasets(self, dict_out):
if self._app.project_datasets or self._app.design_datasets:
if dict_out.get("datasets", None) is None:
dict_out["datasets"] = {}
dict_out["datasets"] = []
for dataset_dict in [self._app.project_datasets, self._app.design_datasets]:
for k, obj in dataset_dict.items():
if k not in dict_out.get("material datasets", []):
dict_out["datasets"][k] = {
"v": obj.v,
"vunit": obj.vunit,
"x": obj.x,
"xunit": obj.xunit,
"y": obj.y,
"yunit": obj.yunit,
"z": obj.z,
"zunit": obj.zunit,
}
dict_out["datasets"].append(
{
"Name": k,
"v": obj.v,
"vunit": obj.vunit,
"x": obj.x,
"xunit": obj.xunit,
"y": obj.y,
"yunit": obj.yunit,
"z": obj.z,
"zunit": obj.zunit,
}
)

@pyaedt_function_handler()
def _export_monitor(self, dict_out):
dict_monitor = {}
dict_monitors = []
native_parts = [
part.name
for udc_name, udc in self._app.modeler.user_defined_components.items()
Expand All @@ -1298,33 +1308,33 @@ def _export_monitor(self, dict_out):
]
if self._app.monitor.all_monitors != {}:
for mon_name in self._app.monitor.all_monitors:
dict_monitor[mon_name] = {
dict_monitor = {
key: val
for key, val in self._app.monitor.all_monitors[mon_name].properties.items()
if key not in ["Name", "Object"]
}
if dict_monitor[mon_name]["Geometry Assignment"] in native_parts:
dict_monitor[mon_name]["Native Assignment"] = [
dict_monitor["Name"] = mon_name
if dict_monitor["Geometry Assignment"] in native_parts:
dict_monitor["Native Assignment"] = [
name
for name, dict_comp in self._app.modeler.user_defined_components.items()
if dict_monitor[mon_name]["Geometry Assignment"]
if dict_monitor["Geometry Assignment"]
in [part.name for part_id, part in dict_comp.parts.items()]
][0]
if dict_monitor[mon_name]["Type"] == "Face":
dict_monitor[mon_name]["Area Assignment"] = self._app.modeler.get_face_area(
dict_monitor[mon_name]["ID"]
)
elif dict_monitor[mon_name]["Type"] == "Surface":
dict_monitor[mon_name]["Area Assignment"] = self._app.modeler.get_face_area(
self._app.modeler.get_object_from_name(dict_monitor[mon_name]["ID"]).faces[0].id
if dict_monitor["Type"] == "Face":
dict_monitor["Area Assignment"] = self._app.modeler.get_face_area(dict_monitor["ID"])
elif dict_monitor["Type"] == "Surface":
dict_monitor["Area Assignment"] = self._app.modeler.get_face_area(
self._app.modeler.get_object_from_name(dict_monitor["ID"]).faces[0].id
)
elif dict_monitor[mon_name]["Type"] == "Object":
bb = self._app.modeler.get_object_from_name([dict_monitor[mon_name]["ID"]][0]).bounding_box
dict_monitor[mon_name]["Location"] = [(bb[i] + bb[i + 3]) / 2 for i in range(3)]
dict_monitor[mon_name]["Volume Assignment"] = self._app.modeler.get_object_from_name(
dict_monitor[mon_name]["ID"]
elif dict_monitor["Type"] == "Object":
bb = self._app.modeler.get_object_from_name([dict_monitor["ID"]][0]).bounding_box
dict_monitor["Location"] = [(bb[i] + bb[i + 3]) / 2 for i in range(3)]
dict_monitor["Volume Assignment"] = self._app.modeler.get_object_from_name(
dict_monitor["ID"]
).volume
dict_out["monitor"] = dict_monitor
dict_monitors.append(dict_monitor)
dict_out["monitors"] = dict_monitors

@pyaedt_function_handler()
def _export_materials(self, dict_out):
Expand Down Expand Up @@ -1618,58 +1628,57 @@ def update_monitor(self, m_case, m_object, m_quantity, m_name):

@pyaedt_function_handler()
def _monitor_assignment_finder(self, dict_in, monitor_obj, exclude_set):
if dict_in["monitor"][monitor_obj].get("Native Assignment", None):
idx = dict_in["monitors"].index(monitor_obj)
if monitor_obj.get("Native Assignment", None):
objects_to_check = [obj for _, obj in self._app.modeler.objects.items()]
objects_to_check = list(set(objects_to_check) - exclude_set)
if dict_in["monitor"][monitor_obj]["Type"] == "Face":
if monitor_obj["Type"] == "Face":
for obj in objects_to_check:
for f in obj.faces:
if (
GeometryOperators.v_norm(
GeometryOperators.v_sub(f.center, dict_in["monitor"][monitor_obj]["Location"])
)
GeometryOperators.v_norm(GeometryOperators.v_sub(f.center, monitor_obj["Location"]))
<= 1e-12
and abs(f.area - dict_in["monitor"][monitor_obj]["Area Assignment"]) <= 1e-12
and abs(f.area - monitor_obj["Area Assignment"]) <= 1e-12
):
dict_in["monitor"][monitor_obj]["ID"] = f.id
monitor_obj["ID"] = f.id
dict_in["monitors"][idx] = monitor_obj
return
elif dict_in["monitor"][monitor_obj]["Type"] == "Surface":
elif monitor_obj["Type"] == "Surface":
for obj in objects_to_check:
if len(obj.faces) == 1:
for f in obj.faces:
if (
GeometryOperators.v_norm(
GeometryOperators.v_sub(f.center, dict_in["monitor"][monitor_obj]["Location"])
)
GeometryOperators.v_norm(GeometryOperators.v_sub(f.center, monitor_obj["Location"]))
<= 1e-12
and abs(f.area - dict_in["monitor"][monitor_obj]["Area Assignment"]) <= 1e-12
and abs(f.area - monitor_obj["Area Assignment"]) <= 1e-12
):
dict_in["monitor"][monitor_obj]["ID"] = obj.name
monitor_obj["ID"] = obj.name
dict_in["monitors"][idx] = monitor_obj
return
elif dict_in["monitor"][monitor_obj]["Type"] == "Object":
elif monitor_obj["Type"] == "Object":
for obj in objects_to_check:
bb = obj.bounding_box
if (
GeometryOperators.v_norm(
GeometryOperators.v_sub(
[(bb[i] + bb[i + 3]) / 2 for i in range(3)], dict_in["monitor"][monitor_obj]["Location"]
[(bb[i] + bb[i + 3]) / 2 for i in range(3)], monitor_obj["Location"]
)
)
<= 1e-12
and abs(obj.volume - dict_in["monitor"][monitor_obj]["Volume Assignment"]) <= 1e-12
and abs(obj.volume - monitor_obj["Volume Assignment"]) <= 1e-12
):
dict_in["monitor"][monitor_obj]["ID"] = obj.id
monitor_obj["ID"] = obj.id
dict_in["monitors"][idx] = monitor_obj
return
elif dict_in["monitor"][monitor_obj]["Type"] == "Vertex":
elif monitor_obj["Type"] == "Vertex":
for obj in objects_to_check:
for v in obj.vertices:
if (
GeometryOperators.v_norm(
GeometryOperators.v_sub(v.position, dict_in["monitor"][monitor_obj]["Location"])
)
GeometryOperators.v_norm(GeometryOperators.v_sub(v.position, monitor_obj["Location"]))
<= 1e-12
):
dict_in["monitor"][monitor_obj]["ID"] = v.id
monitor_obj["ID"] = v.id
dict_in["monitors"][idx] = monitor_obj
return

@pyaedt_function_handler()
Expand Down Expand Up @@ -1723,16 +1732,24 @@ def import_config(self, config_file, *args):
result_native_component = False

dict_in = Configurations.import_config(self, config_file)
if self.options.import_monitor and dict_in.get("monitor", None):
if self.options.import_monitor and dict_in.get("monitor", None): # backward compatibility
dict_in["monitors"] = dict_in.pop("monitor")
if self.options.import_monitor and dict_in.get("monitors", None):
if not isinstance(dict_in["monitors"], list): # backward compatibility
mon_list = []
for k, v in dict_in["monitors"].items():
v["Name"] = k
mon_list.append(v)
dict_in["monitors"] = mon_list
self.results.import_monitor = True
for monitor_obj in dict_in["monitor"]:
for monitor_obj in dict_in["monitors"]:
self._monitor_assignment_finder(dict_in, monitor_obj, exclude_set)
m_type = dict_in["monitor"][monitor_obj]["Type"]
m_obj = dict_in["monitor"][monitor_obj]["ID"]
m_type = monitor_obj["Type"]
m_obj = monitor_obj["ID"]
if m_type == "Point":
m_obj = dict_in["monitor"][monitor_obj]["Location"]
m_obj = monitor_obj["Location"]
if not self.update_monitor(
m_type, m_obj, dict_in["monitor"][monitor_obj]["Quantity"], monitor_obj
m_type, m_obj, monitor_obj["Quantity"], monitor_obj["Name"]
): # pragma: no cover
self.results.import_monitor = False
try:
Expand Down
Loading

0 comments on commit 3664c1b

Please sign in to comment.