diff --git a/_unittest/example_models/T03/iron_pyaedt.amat b/_unittest/example_models/T03/iron_pyaedt.amat new file mode 100644 index 00000000000..4e88aefde9e --- /dev/null +++ b/_unittest/example_models/T03/iron_pyaedt.amat @@ -0,0 +1,98 @@ + +$begin 'iron_pyaedt' + $begin 'MaterialDef' + $begin 'iron_pyaedt' + CoordinateSystemType='Cartesian' + BulkOrSurfaceType=1 + $begin 'PhysicsTypes' + set('Electromagnetic', 'Thermal', 'Structural') + $end 'PhysicsTypes' + $begin 'AttachedData' + $begin 'MatAppearanceData' + property_data='appearance_data' + Red=74 + Green=74 + Blue=74 + $end 'MatAppearanceData' + $begin 'MatNotesData' + property_data='notes_data' + Notes='Materials data\ +Database: MaterialU\ +Table: MaterialU\ +Record name: iron_pyaedt\ +Designation: iron_pyaedt, BS EN 1561:1997 (record based on BS 1542:1990 BS grade 250)\ +GUID: 04b3107f-45c5-4e7c-bdd6-3bf3cffc2ef2' + $end 'MatNotesData' + $end 'AttachedData' + $begin 'ModifierData' + $begin 'ThermalModifierData' + modifier_data='thermal_modifier_data' + $begin 'all_thermal_modifiers' + $begin 'one_thermal_modifier' + 'Property:'='thermal_conductivity' + 'Index:'=0 + prop_modifier='thermal_modifier' + use_free_form=true + free_form_value='pwl($Thermal_conductivity_with_temperature_1,Temp)' + $end 'one_thermal_modifier' + $begin 'one_thermal_modifier' + 'Property:'='specific_heat' + 'Index:'=0 + prop_modifier='thermal_modifier' + use_free_form=true + free_form_value='pwl($Specific_heat_capacity_with_temperature_1,Temp)' + $end 'one_thermal_modifier' + $begin 'one_thermal_modifier' + 'Property:'='thermal_expansion_coefficient' + 'Index:'=0 + prop_modifier='thermal_modifier' + use_free_form=true + free_form_value='pwl($Thermal_expansion_coefficient_with_temperature_1,Temp)' + $end 'one_thermal_modifier' + $end 'all_thermal_modifiers' + $end 'ThermalModifierData' + $end 'ModifierData' + $begin 'permeability' + property_type='nonlinear' + BTypeForSingleCurve='normal' + HUnit='A_per_meter' + BUnit='tesla' + IsTemperatureDependent=false + $begin 'BHCoordinates' + DimUnits[2: '', ''] + Points[54: 0, 0, 16000, 1, 17281.6, 1.05, 18847.4, 1.1, 20865.9, 1.15, 23376, 1.2, 26469.5, 1.25, 30177.8, 1.3, 34493.5, 1.35, 39401.2, 1.4, 44861, 1.45, 50789.6, 1.5, 57260.3, 1.55, 64825.4, 1.6, 74271.5, 1.65, 86025.4, 1.7, 100233, 1.75, 117472, 1.8, 138235, 1.85, 162690, 1.9, 191556, 1.95, 224815, 2, 260282, 2.05, 295816, 2.1, 330843, 2.15, 367601, 2.2, 407000, 2.25] + $end 'BHCoordinates' + $begin 'Temperatures' + $end 'Temperatures' + $end 'permeability' + conductivity='1371180' + thermal_conductivity='43.0284' + mass_density='7199.83' + specific_heat='445.332' + youngs_modulus='1.23511e+11' + poissons_ratio='0.259952' + thermal_expansion_coefficient='8.97454e-6' + $begin 'thermal_material_type' + property_type='ChoiceProperty' + Choice='Solid' + $end 'thermal_material_type' + $end 'iron_pyaedt' + $end 'MaterialDef' + $begin 'RefDatasets' + $begin '$Thermal_conductivity_with_temperature_1' + DimUnits[2: 'cel', ''] + X('19.85', '96.99', '174.1', '251.3', '328.4', '405.6', '482.7', '559.9', '637', '714.1', '791.3', '868.4', '945.6', '1023', '1100') + Y('0.999572', '1.01491', '1.00771', '0.985861', '0.95681', '0.932872', '0.914512', '0.889413', '0.853622', '0.81086', '0.773443', '0.79831', '0.833403', '0.864778', '0.885229') + $end '$Thermal_conductivity_with_temperature_1' + $begin '$Specific_heat_capacity_with_temperature_1' + DimUnits[2: 'cel', ''] + X('19.85', '86.52', '153.2', '219.9', '286.5', '353.2', '419.9', '486.5', '553.2', '619.9') + Y('0.996785', '1.09649', '1.18024', '1.25345', '1.32171', '1.39132', '1.46789', '1.55704', '1.6646', '1.79664') + $end '$Specific_heat_capacity_with_temperature_1' + $begin '$Thermal_expansion_coefficient_with_temperature_1' + DimUnits[2: 'cel', ''] + X('19.85', '88.94', '158', '227.1', '296.2', '365.3', '434.4', '503.5', '572.6', '641.7', '710.8', '779.9') + Y('0.996931', '1.09554', '1.17332', '1.23238', '1.27806', '1.31149', '1.33712', '1.3594', '1.37946', '1.40174', '1.43406', '1.53657') + $end '$Thermal_expansion_coefficient_with_temperature_1' + $end 'RefDatasets' +$end 'iron_pyaedt' diff --git a/_unittest/example_models/T03/material_sample.amat b/_unittest/example_models/T03/material_sample.amat new file mode 100644 index 00000000000..c9461d59858 --- /dev/null +++ b/_unittest/example_models/T03/material_sample.amat @@ -0,0 +1,81 @@ +$begin '$base_index$' + $begin 'properties' + all_levels=000000000000 + time(year=000000002022, month=000000000004, day=000000000026, hour=000000000014, min=000000000052, sec=000000000029) + version=000000000000 + $end 'properties' + $begin '$base_index$' + $index$(pos=000000002021, lin=000000000072, lvl=000000000000) + $end '$base_index$' +$end '$base_index$' +$begin 'vacuum' + $begin 'AttachedData' + $begin 'MatAppearanceData' + property_data='appearance_data' + Red=230 + Green=230 + Blue=230 + Transparency=0.95 + $end 'MatAppearanceData' + $end 'AttachedData' + simple('permittivity', 1) + ModTime=1499970477 +$end 'vacuum' +$begin 'pec' + $begin 'AttachedData' + $begin 'MatAppearanceData' + property_data='appearance_data' + Red=247 + Green=242 + Blue=232 + $end 'MatAppearanceData' + $end 'AttachedData' + simple('conductivity', 1.0E30) + ModTime=1499970477 +$end 'pec' +$begin 'mat_example_1' + $begin 'AttachedData' + $begin 'MatAppearanceData' + property_data='appearance_data' + Red=176 + Green=154 + Blue=176 + $end 'MatAppearanceData' + $end 'AttachedData' + simple('conductivity', 1100000) + simple('thermal_conductivity', 13.8) + simple('mass_density', 8055) + simple('specific_heat', 480) + simple('youngs_modulus', 195000000000) + simple('poissons_ratio', 0.3) + simple('thermal_expansion_coeffcient', 1.08e-005) + ModTime=1499970477 +$end 'mat_example_1' +$begin 'mat_example_2' + $begin 'AttachedData' + $begin 'MatAppearanceData' + property_data='appearance_data' + Red=235 + Green=235 + Blue=123 + $end 'MatAppearanceData' + $end 'AttachedData' + simple('conductivity', 16700000) + simple('thermal_conductivity', 115.5) + simple('mass_density', 7140) + simple('specific_heat', 389) + simple('youngs_modulus', 115000000000) + simple('poissons_ratio', 0.33) + simple('thermal_expansion_coeffcient', 6.35e-005) + ModTime=1499970477 +$end 'mat_example_2' +$begin '$index$' + $begin '$index$' + vacuum(pos=370, lin=11, lvl=0) + pec(pos=675, lin=24, lvl=0) + mat_example_1(pos=954, lin=36, lvl=0) + mat_example_2(pos=1486, lin=54, lvl=0) + $base_index$(pos=0, lin=1, lvl=0) + $index$(pos=2021, lin=72, lvl=0) + $end '$index$' +$end '$index$' diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py index 535a8ae4e84..bd95e52a5e9 100644 --- a/_unittest/test_03_Materials.py +++ b/_unittest/test_03_Materials.py @@ -188,6 +188,20 @@ def test_08_import_materials(self): assert "al-extruded1" in self.aedtapp.materials.material_keys.keys() assert self.aedtapp.materials["al-extruded1"].thermal_conductivity.thermalmodifier + assert not self.aedtapp.materials.import_materials_from_file() + assert not self.aedtapp.materials.import_materials_from_file("mat.invented") + assert not self.aedtapp.materials.import_materials_from_file( + os.path.join(local_path, "example_models", test_subfolder, "mats.csv") + ) + + assert self.aedtapp.materials.import_materials_from_file( + os.path.join(local_path, "example_models", test_subfolder, "material_sample.amat") + ) + assert self.aedtapp.materials.import_materials_from_file( + os.path.join(local_path, "example_models", test_subfolder, "iron_pyaedt.amat") + ) + x = 1 + def test_08B_import_materials_from_excel(self): mats = self.aedtapp.materials.import_materials_from_excel( os.path.join(local_path, "example_models", test_subfolder, "mats.xlsx") diff --git a/pyaedt/generic/configurations.py b/pyaedt/generic/configurations.py index 58eec4a551f..fb0a1e87913 100644 --- a/pyaedt/generic/configurations.py +++ b/pyaedt/generic/configurations.py @@ -1114,6 +1114,7 @@ def import_config(self, config_file, *args): else: newname = el newmat = Material(self._app, el, val, material_update=True) + newmat._update_material() if newmat: self._app.materials.material_keys[newname] = newmat else: # pragma: no cover diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index d97961fa38a..776dd174e88 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -284,8 +284,12 @@ def __init__(self, material, name, val=None, thermalmodifier=None, spatialmodifi elif e == "IsTemperatureDependent": self.is_temperature_dependent = v elif e in ["BHCoordinates", "DECoordinates", "JECoordinates"]: - self.value = v["Point"] self._unit = v["DimUnits"] + if "Point" in v: + self.value = v["Point"] + elif "Points" in v: + pair_list = [v["Points"][i : i + 2] for i in range(0, len(v["Points"]), 2)] + self.value = pair_list elif e == "Temperatures": self.temperatures = v elif val is not None and isinstance(val, OrderedDict) and "Magnitude" in val.keys(): @@ -1170,18 +1174,17 @@ def _get_args(self, props=None): _dict2arg(props, arg) return arg - def _update_props(self, propname, provpavlue, update_aedt=True): + def _update_props(self, propname, propvalue, update_aedt=True): """Update properties. Parameters ---------- propname : str Name of the property. - provpavlue : + propvalue : Value of the property. update_aedt : bool, optional Whether to update the property in AEDT. The default is ``True``. - """ try: @@ -1190,9 +1193,9 @@ def _update_props(self, propname, provpavlue, update_aedt=True): except: material_props_type = None - if isinstance(provpavlue, list) and material_props_type and material_props_type in ["tensor", "anisotropic"]: + if isinstance(propvalue, list) and material_props_type and material_props_type in ["tensor", "anisotropic"]: i = 1 - for val in provpavlue: + for val in propvalue: if not self._props.get(propname, None) or not isinstance(self._props[propname], dict): if material_props_type == "tensor": self._props[propname] = OrderedDict({"property_type": "TensorProperty"}) @@ -1204,18 +1207,18 @@ def _update_props(self, propname, provpavlue, update_aedt=True): i += 1 if update_aedt: return self.update() - elif isinstance(provpavlue, (str, float, int)): - self._props[propname] = str(provpavlue) + elif isinstance(propvalue, (str, float, int)): + self._props[propname] = str(propvalue) if update_aedt: return self.update() - elif isinstance(provpavlue, OrderedDict): - self._props[propname] = provpavlue + elif isinstance(propvalue, OrderedDict): + self._props[propname] = propvalue if update_aedt: return self.update() - elif isinstance(provpavlue, list) and material_props_type and material_props_type == "nonlinear": + elif isinstance(propvalue, list) and material_props_type and material_props_type == "nonlinear": if propname == "permeability": bh = OrderedDict({"DimUnits": ["", ""]}) - for point in provpavlue: + for point in propvalue: if "Point" in bh: bh["Point"].append(point) else: @@ -1232,7 +1235,7 @@ def _update_props(self, propname, provpavlue, update_aedt=True): self._props[propname]["BHCoordinates"]["Temperatures"] = OrderedDict({}) else: bh = OrderedDict({"DimUnits": [self.__dict__["_" + propname]._unit]}) - for point in provpavlue: + for point in propvalue: if "Point" in bh: bh["Point"].append(point) else: @@ -1244,9 +1247,9 @@ def _update_props(self, propname, provpavlue, update_aedt=True): self._props[propname] = OrderedDict({"property_type": "nonlinear", pr_name: bh}) if update_aedt: return self.update() - elif isinstance(provpavlue, list) and material_props_type and material_props_type == "vector": + elif isinstance(propvalue, list) and material_props_type and material_props_type == "vector": if propname == "magnetic_coercivity": - return self.set_magnetic_coercivity(provpavlue[0], provpavlue[1], provpavlue[2], provpavlue[3]) + return self.set_magnetic_coercivity(propvalue[0], propvalue[1], propvalue[2], propvalue[3]) return False @@ -1275,6 +1278,17 @@ def __init__(self, materiallib, name, props=None, material_update=True): CommonMaterial.__init__(self, materiallib, name, props) self.thermal_material_type = "Solid" self._material_update = material_update + self._wire_type = None + self._wire_width = None + self._wire_diameter = None + self._wire_width_direction = None + self._wire_thickness_direction = None + self._wire_thickness = None + self._stacking_type = None + self._stacking_direction = None + self._stacking_factor = None + self._strand_number = None + if "thermal_material_type" in self._props: self.thermal_material_type = self._props["thermal_material_type"]["Choice"] if "PhysicsTypes" in self._props: @@ -1312,6 +1326,7 @@ def __init__(self, materiallib, name, props=None, material_update=True): if "wire_type" in self._props: self.wire_type = self._props["wire_type"]["Choice"] + def _update_material(self): for property in MatProperties.aedtname: tmods = None smods = None @@ -1344,7 +1359,6 @@ def __init__(self, materiallib, name, props=None, material_update=True): else: if modifiers[mod]["Property:"] == property: smods = modifiers[mod] - property_value = ( self._props[property] if property in self._props else MatProperties.get_defaultvalue(aedtname=property) ) diff --git a/pyaedt/modules/MaterialLib.py b/pyaedt/modules/MaterialLib.py index bc248a011c2..5a98b034037 100644 --- a/pyaedt/modules/MaterialLib.py +++ b/pyaedt/modules/MaterialLib.py @@ -6,17 +6,19 @@ import copy import fnmatch -import json import math import os import re import sys +import warnings from pyaedt import is_ironpython from pyaedt.generic.DataHandlers import _arg2dict +from pyaedt.generic.LoadAEDTFile import load_entire_aedt_file from pyaedt.generic.general_methods import generate_unique_name from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler +from pyaedt.generic.general_methods import read_json from pyaedt.generic.general_methods import write_configuration_file from pyaedt.generic.settings import settings from pyaedt.modules.Material import MatProperties @@ -318,6 +320,7 @@ def add_material(self, materialname, props=None): return self._aedmattolibrary(self._get_aedt_case_name(materialname)) else: material = Material(self, materialname, props, material_update=True) + material._update_material() if material: self.logger.info("Material has been added. Edit it to update in Desktop.") self.material_keys[materialname.lower()] = material @@ -430,6 +433,7 @@ def add_material_sweep(self, materials_list, material_name): mat_dict = self._create_mat_project_vars(matsweep) newmat = Material(self, material_name, material_update=False) + newmat._update_material() index = "$ID" + material_name newmat.is_sweep_material = True self._app[index] = 0 @@ -509,6 +513,7 @@ def duplicate_material(self, material_name, new_name=None, props=None): if not new_name: new_name = material_name + "_clone" new_material = Material(self, new_name, material._props, material_update=False) + new_material._update_material() # Parameterize material properties if these were passed. if props: @@ -672,6 +677,7 @@ def _aedmattolibrary(self, matname): value_iterator = iter(values_view) first_value = next(value_iterator) newmat = Material(self, matname, first_value, material_update=False) + newmat._update_material() newmat._material_update = True self.material_keys[matname.lower()] = newmat return self.material_keys[matname.lower()] @@ -749,25 +755,67 @@ def find_datasets(d, out_list): return write_configuration_file(json_dict, full_json_path) @pyaedt_function_handler() - def import_materials_from_file(self, full_json_path): - """Import and create materials from a JSON file. + def import_materials_from_file(self, full_path=None, **kwargs): + """Import and create materials from a JSON or AMAT file. Parameters ---------- - full_json_path : str - Full path and name for the JSON file. + full_path : str + Full path and name for the JSON or AMAT file. Returns ------- List of :class:`pyaedt.modules.Material.Material` """ + + if "full_json_path" in kwargs and kwargs["full_json_path"] is not None: # pragma: no cover + warnings.warn( + "``full_json_path`` was deprecated in 0.8.1. Use ``full_path`` instead.", + DeprecationWarning, + ) + full_path = kwargs["full_json_path"] + + if full_path is None or not os.path.exists(full_path): + self.logger.error("Incorrect path provided.") + return False + + _, file_extension = os.path.splitext(full_path) + json_flag = True + datasets = {} + if file_extension.lower() == ".json": + data = read_json(full_path) + if "datasets" in list(data.keys()): + datasets = data["datasets"] + elif file_extension.lower() == ".amat": + data = load_entire_aedt_file(full_path) + json_flag = False + new_data = {} + + for mat_name in data: + if "MaterialDef" in data[mat_name] and mat_name in data[mat_name]["MaterialDef"]: + new_data[mat_name] = data[mat_name]["MaterialDef"][mat_name] + else: + new_data[mat_name] = data[mat_name] + + if "RefDatasets" in data[mat_name]: + for dataset in data[mat_name]["RefDatasets"]: + dataset_loaded = data[mat_name]["RefDatasets"][dataset] + datasets[dataset] = {"Coordinates": {"DimUnits": [], "Points": []}} + datasets[dataset]["Coordinates"]["DimUnits"] = dataset_loaded["DimUnits"] + for point_element in range(0, len(dataset_loaded["X"]) - 1): + datasets[dataset]["Coordinates"]["Points"].append(dataset_loaded["X"][point_element]) + datasets[dataset]["Coordinates"]["Points"].append(dataset_loaded["Y"][point_element]) + if new_data: + data[mat_name] = new_data[mat_name] + else: + self.logger.error("Invalid file extension.") + return False + materials_added = [] - with open_file(full_json_path, "r") as json_file: - data = json.load(json_file) - if "datasets" in list(data.keys()): - for el, val in data["datasets"].items(): + if datasets: + for el, val in datasets.items(): numcol = len(val["Coordinates"]["DimUnits"]) xunit = val["Coordinates"]["DimUnits"][0] yunit = val["Coordinates"]["DimUnits"][1] @@ -777,26 +825,42 @@ def import_materials_from_file(self, full_json_path): val["Coordinates"]["Points"][i : i + numcol] for i in range(0, len(val["Coordinates"]["Points"]), numcol) ] - xval = new_list[0] - yval = new_list[1] + xval = [sublist[0] for sublist in new_list] + yval = [sublist[1] for sublist in new_list] zval = None if numcol > 2: zunit = val["Coordinates"]["DimUnits"][2] - zval = new_list[2] + zval = [sublist[2] for sublist in new_list] self._app.create_dataset( el[1:], xunit=xunit, yunit=yunit, zunit=zunit, xlist=xval, ylist=yval, zlist=zval ) + if json_flag: + for el, val in data["materials"].items(): + if el.lower() in list(self.material_keys.keys()): + newname = generate_unique_name(el) + self.logger.warning("Material %s already exists. Renaming to %s", el, newname) + else: + newname = el + newmat = Material(self, newname, val, material_update=True) + newmat._update_material() + # newmat.update() + self.material_keys[newname] = newmat + materials_added.append(newmat) + else: + for mat_name in data: + invalid_names = ["$base_index$", "$index$"] + if mat_name in invalid_names: + continue + if mat_name.lower() in list(self.material_keys.keys()): + newname = generate_unique_name(mat_name) + self.logger.warning("Material %s already exists. Renaming to %s", mat_name, newname) + else: + newname = mat_name - for el, val in data["materials"].items(): - if el.lower() in list(self.material_keys.keys()): - newname = generate_unique_name(el) - self.logger.warning("Material %s already exists. Renaming to %s", el, newname) - else: - newname = el - newmat = Material(self, newname, val, material_update=True) - # newmat.update() - self.material_keys[newname] = newmat - materials_added.append(newmat) + newmat = self.add_material(newname, props=data[mat_name]) + newmat._props = data[mat_name] + newmat._update_material() + materials_added.append(newmat) return materials_added @pyaedt_function_handler() @@ -847,6 +911,7 @@ def import_materials_from_excel(self, material_file): ): props[prop] = float(val[keys.index(prop)]) new_material = Material(self, newname, props, material_update=True) + new_material._update_material() # new_material.update() self.material_keys[newname] = new_material materials_added.append(new_material)