From dce1d1a83b8cdc7fc6a6939724284f109308989a Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Thu, 19 Oct 2023 10:20:59 +0200 Subject: [PATCH 01/26] enhance core loss electrical steel --- pyaedt/generic/DataHandlers.py | 5 + pyaedt/modules/Material.py | 197 +++++++++++++++++++++++++++------ 2 files changed, 166 insertions(+), 36 deletions(-) diff --git a/pyaedt/generic/DataHandlers.py b/pyaedt/generic/DataHandlers.py index 8b6568163de..4522cb414f7 100644 --- a/pyaedt/generic/DataHandlers.py +++ b/pyaedt/generic/DataHandlers.py @@ -101,6 +101,11 @@ def _dict2arg(d, arg_out): arg = ["NAME:" + k] _dict2arg(el, arg) arg_out.append(arg) + elif type(v) is list and len(v) > 0 and all(isinstance(n, int) for n in v): + arg = ["NAME:" + k] + for el in v: + arg.append(el) + arg_out.append(arg) else: arg_out.append(k + ":=") diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index e07e596693c..2f6d251f922 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -14,6 +14,7 @@ """ from collections import OrderedDict import copy +import itertools import warnings from pyaedt.generic.DataHandlers import _dict2arg @@ -450,8 +451,8 @@ def _add_thermal_modifier(self, formula, index): """ if ( - "ModifierData" not in self._material._props - or "ThermalModifierData" not in self._material._props["ModifierData"] + "ModifierData" not in self._material._props + or "ThermalModifierData" not in self._material._props["ModifierData"] ): tm = OrderedDict( { @@ -463,8 +464,8 @@ def _add_thermal_modifier(self, formula, index): } ) if ( - "ModifierData" in self._material._props - and "SpatialModifierData" in self._material._props["ModifierData"] + "ModifierData" in self._material._props + and "SpatialModifierData" in self._material._props["ModifierData"] ): self._material._props["ModifierData"] = OrderedDict( { @@ -492,7 +493,8 @@ def _add_thermal_modifier(self, formula, index): else: for tmname in self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"]: if isinstance( - self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname], list + self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname], + list ): found = False for tm in self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][ @@ -521,14 +523,16 @@ def _add_thermal_modifier(self, formula, index): tmname ].append(tm) elif ( - self.name - == self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ - "Property:" - ] - and index - == self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ - "Index:" - ] + self.name + == + self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ + "Property:" + ] + and index + == + self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ + "Index:" + ] ): self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ "use_free_form" @@ -639,7 +643,8 @@ def add_thermal_modifier_dataset(self, dataset_name, index=0): @pyaedt_function_handler() def add_thermal_modifier_closed_form( - self, tref=22, c1=0.0001, c2=1e-6, tl=-273.15, tu=1000, units="cel", auto_calc=True, tml=1000, tmu=1000, index=0 + self, tref=22, c1=0.0001, c2=1e-6, tl=-273.15, tu=1000, units="cel", auto_calc=True, tml=1000, tmu=1000, + index=0 ): """Add a thermal modifier to a material property using a closed-form formula. @@ -739,12 +744,12 @@ def add_thermal_modifier_closed_form( } ) if ( - "ModifierData" not in self._material._props - or "ThermalModifierData" not in self._material._props["ModifierData"] + "ModifierData" not in self._material._props + or "ThermalModifierData" not in self._material._props["ModifierData"] ): if ( - "ModifierData" in self._material._props - and "SpatialModifierData" in self._material._props["ModifierData"] + "ModifierData" in self._material._props + and "SpatialModifierData" in self._material._props["ModifierData"] ): self._material._props["ModifierData"] = OrderedDict( { @@ -912,8 +917,8 @@ def _add_spatial_modifier(self, formula, index): """ if ( - "ModifierData" not in self._material._props - or "SpatialModifierData" not in self._material._props["ModifierData"] + "ModifierData" not in self._material._props + or "SpatialModifierData" not in self._material._props["ModifierData"] ): sm = OrderedDict( { @@ -924,8 +929,8 @@ def _add_spatial_modifier(self, formula, index): } ) if ( - "ModifierData" in self._material._props - and "ThermalModifierData" in self._material._props["ModifierData"] + "ModifierData" in self._material._props + and "ThermalModifierData" in self._material._props["ModifierData"] ): self._material._props["ModifierData"] = OrderedDict( { @@ -952,7 +957,8 @@ def _add_spatial_modifier(self, formula, index): else: for smname in self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"]: if isinstance( - self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname], list + self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname], + list ): found = False for sm in self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][ @@ -975,14 +981,16 @@ def _add_spatial_modifier(self, formula, index): smname ].append(sm) elif ( - self.name - == self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ - "Property:" - ] - and index - == self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ - "Index:" - ] + self.name + == + self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ + "Property:" + ] + and index + == + self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ + "Index:" + ] ): self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ "free_form_value" @@ -1268,7 +1276,7 @@ def __init__(self, materiallib, name, props=None, material_update=True): if (materiallib._color_id) > len(vals): materiallib._color_id = 0 h = vals[materiallib._color_id].lstrip("#") - self._material_appearance = list(int(h[i : i + 2], 16) for i in (0, 2, 4)) + self._material_appearance = list(int(h[i: i + 2], 16) for i in (0, 2, 4)) materiallib._color_id += 1 self._props["AttachedData"] = OrderedDict( { @@ -1972,25 +1980,99 @@ def set_magnetic_coercivity(self, value=0, x=1, y=0, z=0): return self.update() @pyaedt_function_handler() - def set_electrical_steel_coreloss(self, kh=0, kc=0, ke=0, kdc=0, cut_depth=0.0001): + def set_electrical_steel_coreloss(self, + kh=0, + kc=0, + ke=0, + kdc=0, + cut_depth=0.001, + is_coreloss_at_freq=False, + thickness="0.5mm", + conductivity=0, + is_coreloss_vs_freq=False, + points_list_at_frequencies={}): """Set Electrical Steel Type Core Loss. Parameters ---------- kh : float + Hysteresis core loss coefficient kc : float + Eddy-current core loss coefficient ke : float + Excess core loss coefficient kdc : float + Coefficient considering the DC flux bias effects cut_depth : float + Equivalent cut depth. + The manufacturing effects on core loss computation can be considered by using this parameter. + The default value is ``1mm``. + is_coreloss_at_freq : bool + Material properties can be calculated either for ``Core Loss at One Frequency`` or ``Core Loss versus + Frequency``. + If ``True`` material properties are calculated for ``Core Loss at One Frequency``. + The default value is ``False``. + thickness : str + Thickness specified in terms of value + unit. + The default value is ``0.5mm``. + conductivity : float + Conductivity. The unit is S/m. + The default value is ``0S/m``. + is_coreloss_vs_freq : bool + Material properties can be calculated either for ``Core Loss at One Frequency`` or ``Core Loss versus + Frequency``. + If ``True`` material properties are calculated for ``Core Loss versus Frequency``. + The default value is ``False``. + points_list_at_frequencies : dict or list + If is_coreloss_at_one_freq is ``True``, points_list_at_frequencies has to be provided as a dictionary where + the key is the single frequency and the value is a list of list of points (BP curve). + If is_coreloss_vs_freq is ``True``, points_list_at_frequencies has to be provided as a dictionary + where the keys are the frequencies and values are list of list of points (BP curve) for each frequency. Returns ------- bool + ``True`` if successful or ``False`` if it fails. + + References + ---------- + + >>> oDefinitionManager.EditMaterial + + Examples + -------- + This example shows how to set a core loss model for a material in case material properties are calculated for + core losses at one frequency or core losses versus frequencies. + The first case shows how to set properties for core losses at one frequency: + + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() + >>> box = m3d.modeler.create_box([-10, -10, 0], [20, 20, 20], "box_to_split") + >>> box.material = "magnesium" + >>> m3d.materials["magnesium"].set_electrical_steel_coreloss( + ... is_coreloss_at_freq=True, + ... points_list_at_frequencies={60 : [[0,0], [1,3.5], [2,7.4]]} + ... ) + >>> m3d.release_desktop(True, True) + + The second case shows how to set properties for core losses versus frequencies: + + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() + >>> box = m3d.modeler.create_box([-10, -10, 0], [20, 20, 20], "box_to_split") + >>> box.material = "magnesium" + >>> m3d.materials["magnesium"].set_electrical_steel_coreloss( + ... is_coreloss_vs_freq=True, + ... points_list_at_frequencies=[{60 : [[0,0], [1,3.5], [2,7.4]]}, + ... {100 : [[0,0], [1,8], [2,9]]}, + ... {150 : [[0,0], [1,10], [2,19]]}] + ... ) + >>> m3d.release_desktop(True, True) + """ if "core_loss_type" not in self._props: self._props["core_loss_type"] = OrderedDict( - {"property_type": "ChoiceProperty", "Choice": "Electrical Steel"} - ) + {"property_type": "ChoiceProperty", "Choice": "Electrical Steel"}) else: self._props.pop("core_loss_cm", None) self._props.pop("core_loss_x", None) @@ -2000,6 +2082,49 @@ def set_electrical_steel_coreloss(self, kh=0, kc=0, ke=0, kdc=0, cut_depth=0.000 self._props.pop("core_loss_hkc", None) self._props.pop("core_loss_curves", None) self._props["core_loss_type"]["Choice"] = "Electrical Steel" + if is_coreloss_at_freq: + if not isinstance(points_list_at_frequencies, dict): + self.logger.error("Points list at frequency must be provided as a dictionary.") + return False + self._props["AttachedData"]["CoefficientSetupData"] = OrderedDict({}) + self._props["AttachedData"]["CoefficientSetupData"]["property_data"] = "coreloss_data" + self._props["AttachedData"]["CoefficientSetupData"]["coefficient_setup"] = "w_per_cubic_meter" + self._props["AttachedData"]["CoefficientSetupData"]["Frequency"] = "{}Hz".format( + list(points_list_at_frequencies.keys())[0]) + self._props["AttachedData"]["CoefficientSetupData"]["Thickness"] = thickness + self._props["AttachedData"]["CoefficientSetupData"]["Conductivity"] = str(conductivity) + + self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"] = ( + OrderedDict({"DimUnits": ["", ""], + "Points": list(itertools.chain(*[v for v in list(points_list_at_frequencies.values())[0]])) + } + ) + ) + #points_list = OrderedDict({"Points": list(itertools.chain(*[v for v in list(points_list_at_frequencies.values())[0]]))}) + # self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"]["Points"] = OrderedDict({}) + # points = OrderedDict({}) + # for pairs in list(points_list_at_frequencies.values())[0]: + # points[pairs[0]] = pairs[1] + # self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"]["Points"] = points + elif is_coreloss_vs_freq: + if not isinstance(points_list_at_frequencies, dict): + self.logger.error("Points list at frequencies must be provided as a list of dictionaries.") + return False + self._props["AttachedData"]["CoreLossMultiCurveData"] = OrderedDict({}) + self._props["AttachedData"]["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" + self._props["AttachedData"]["CoreLossMultiCurveData"]["coreloss_unit"] = "w_per_cubic_meter" + + self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"] = OrderedDict({}) + for freq in list(points_list_at_frequencies.keys()): + self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = OrderedDict({}) + self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"]["Frequency"] = freq + self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"][ + "Coordinates"] = OrderedDict({}) + self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"]["Coordinates"][ + "Points"] = [] + self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"]["Coordinates"][ + "Points"].append(itertools.chain(points_list_at_frequencies[freq])) + self._props["core_loss_kh"] = str(kh) self._props["core_loss_kc"] = str(kc) self._props["core_loss_ke"] = str(ke) @@ -2085,7 +2210,7 @@ def set_power_ferrite_coreloss(self, cm=0, x=0, y=0, kdc=0, cut_depth=0.0001): @pyaedt_function_handler() def set_bp_curve_coreloss( - self, point_list, kdc=0, cut_depth=0.0001, punit="kw/m^3", bunit="tesla", frequency=60, thickness="0.5mm" + self, point_list, kdc=0, cut_depth=0.0001, punit="kw/m^3", bunit="tesla", frequency=60, thickness="0.5mm" ): """Set B-P Type Core Loss. From 730bdf244d1c19022656971b1413f39b97420814 Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Mon, 30 Oct 2023 11:38:09 +0100 Subject: [PATCH 02/26] implement core losses --- pyaedt/generic/DataHandlers.py | 2 +- pyaedt/modules/Material.py | 200 +++++++++++++++++++++------------ 2 files changed, 130 insertions(+), 72 deletions(-) diff --git a/pyaedt/generic/DataHandlers.py b/pyaedt/generic/DataHandlers.py index 4522cb414f7..57498f145da 100644 --- a/pyaedt/generic/DataHandlers.py +++ b/pyaedt/generic/DataHandlers.py @@ -101,7 +101,7 @@ def _dict2arg(d, arg_out): arg = ["NAME:" + k] _dict2arg(el, arg) arg_out.append(arg) - elif type(v) is list and len(v) > 0 and all(isinstance(n, int) for n in v): + elif type(v) is list and len(v) > 0 and all(isinstance(n, int) for n in v) or all(isinstance(n, float) for n in v): arg = ["NAME:" + k] for el in v: arg.append(el) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 2f6d251f922..112b7ae5acf 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -18,9 +18,16 @@ import warnings from pyaedt.generic.DataHandlers import _dict2arg +from pyaedt import is_ironpython from pyaedt.generic.constants import CSS4_COLORS from pyaedt.generic.general_methods import pyaedt_function_handler +if not is_ironpython: + try: + import numpy as np + except ImportError: + pass + class MatProperties(object): """Contains a list of constant names for all materials with @@ -1980,53 +1987,117 @@ def set_magnetic_coercivity(self, value=0, x=1, y=0, z=0): return self.update() @pyaedt_function_handler() - def set_electrical_steel_coreloss(self, - kh=0, - kc=0, - ke=0, - kdc=0, - cut_depth=0.001, - is_coreloss_at_freq=False, - thickness="0.5mm", - conductivity=0, - is_coreloss_vs_freq=False, - points_list_at_frequencies={}): - """Set Electrical Steel Type Core Loss. + def get_core_loss_coefficients(self, + points_list_at_freq, + core_loss_model_type="Electrical Steel", + thickness="0.5mm", + conductivity=0, + coefficient_setup="w_per_cubic_meter"): + """Compute core loss coefficients from the loss characteristics (B-P Curve) at a given frequency. + + Parameters + ---------- + points_list_at_freq : dict + points_list_at_freq is a dictionary of BP values for a given frequency. + Key is the frequency and values are the list of points (BP curve). + core_loss_model_type : str, optional + Core loss model type. It can be ``Electrical Steel`` or ``Power Ferrite``. + The default value is ``Electrical Steel``. + thickness : str, optional + Thickness provided as value + unit. + The default value is ``0.5mm``. + conductivity : float, optional + Material conductivity. + The default value is ``0``. + coefficient_setup : str, optional + Core loss unit. + Possible values are: ``w_per_cubic_meter``, ``kw_per_cubic_meter``, ``w_per_lb``, ``w_per_kg``. + The default value is ``w_per_cubic_meter``. + + Returns + ------- + list + List of core loss coefficients. + Returns Kh, Kc, Ke coefficients if core loss model is ``Electrical Steel``. + Returns Cm, X, Y if core loss model is ``Power Ferrite``. + + Examples + -------- + This example shows how to get core loss coefficients for Electrical Steel core loss model. + + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() + >>> box = m3d.modeler.create_box([-10, -10, 0], [20, 20, 20], "box_to_split") + >>> box.material = "magnesium" + >>> coefficients = m3d.materials["magnesium"].get_core_loss_coefficients( + ... points_list_at_freq={60 : [[0, 0], [1, 3], [2, 7]]}, + ... thickness="0.5mm", + ... conductivity=0) + >>> print(coefficients) + >>> m3d.release_desktop(True, True) + """ + if not isinstance(points_list_at_freq, dict): + self.logger.error("Points list at frequency must be provided as a dictionary.") + return False + props = OrderedDict({}) + if len(points_list_at_freq.keys()) == 1: + props["CoefficientSetupData"] = OrderedDict({}) + props["CoefficientSetupData"]["property_data"] = "coreloss_data" + props["CoefficientSetupData"]["coefficient_setup"] = coefficient_setup + frequency = list(points_list_at_freq.keys())[0] + props["CoefficientSetupData"]["Frequency"] = "{}Hz".format(frequency) + props["CoefficientSetupData"]["Thickness"] = thickness + props["CoefficientSetupData"]["Conductivity"] = str(conductivity) + points = list(itertools.chain(*[v for v in list(points_list_at_freq.values())[0]])) + props["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], + "Points": points}) + elif len(points_list_at_freq.keys()) > 1: + props["CoreLossMultiCurveData"] = OrderedDict({}) + props["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" + props["CoreLossMultiCurveData"]["coreloss_unit"] = "w_per_cubic_meter" + + props["CoreLossMultiCurveData"]["AllCurves"] = OrderedDict({}) + props["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = [] + for freq in list(points_list_at_freq.keys()): + points = list(itertools.chain(*[v for v in points_list_at_freq[freq]])) + one_curve = OrderedDict({"Frequency": "{}Hz".format(freq), "Coordinates": OrderedDict({"DimUnits": ["", ""], "Points": points})}) + props["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"].append(one_curve) + + props = args = self._get_args(props) + props.pop(0) + coefficients = self.odefinition_manager.ComputeCoreLossCoefficients(core_loss_model_type, + self.mass_density.evaluated_value, + props[0]) + return coefficients + + @pyaedt_function_handler() + def set_electrical_steel_coreloss_at_frequency(self, + kdc=0, + cut_depth=0.001, + is_coreloss_at_freq=False, + thickness="0.5mm", + conductivity=0, + points_list_at_freq={}): + """Set Electrical Steel Core Loss Model at one single frequency or at multiple frequencies. Parameters ---------- - kh : float - Hysteresis core loss coefficient - kc : float - Eddy-current core loss coefficient - ke : float - Excess core loss coefficient kdc : float Coefficient considering the DC flux bias effects cut_depth : float Equivalent cut depth. The manufacturing effects on core loss computation can be considered by using this parameter. The default value is ``1mm``. - is_coreloss_at_freq : bool - Material properties can be calculated either for ``Core Loss at One Frequency`` or ``Core Loss versus - Frequency``. - If ``True`` material properties are calculated for ``Core Loss at One Frequency``. - The default value is ``False``. thickness : str Thickness specified in terms of value + unit. The default value is ``0.5mm``. conductivity : float Conductivity. The unit is S/m. The default value is ``0S/m``. - is_coreloss_vs_freq : bool - Material properties can be calculated either for ``Core Loss at One Frequency`` or ``Core Loss versus - Frequency``. - If ``True`` material properties are calculated for ``Core Loss versus Frequency``. - The default value is ``False``. - points_list_at_frequencies : dict or list - If is_coreloss_at_one_freq is ``True``, points_list_at_frequencies has to be provided as a dictionary where + points_list_at_freq : dict + If is_coreloss_at_one_freq is ``True``, points_list_at_freq has to be provided as a dictionary where the key is the single frequency and the value is a list of list of points (BP curve). - If is_coreloss_vs_freq is ``True``, points_list_at_frequencies has to be provided as a dictionary + If is_coreloss_vs_freq is ``True``, points_list_at_freq has to be provided as a dictionary where the keys are the frequencies and values are list of list of points (BP curve) for each frequency. Returns @@ -2050,8 +2121,8 @@ def set_electrical_steel_coreloss(self, >>> box = m3d.modeler.create_box([-10, -10, 0], [20, 20, 20], "box_to_split") >>> box.material = "magnesium" >>> m3d.materials["magnesium"].set_electrical_steel_coreloss( - ... is_coreloss_at_freq=True, - ... points_list_at_frequencies={60 : [[0,0], [1,3.5], [2,7.4]]} + ... is_coreloss_vs_freq=False, + ... points_list_at_freq={60 : [[0,0], [1,3.5], [2,7.4]]} ... ) >>> m3d.release_desktop(True, True) @@ -2063,13 +2134,16 @@ def set_electrical_steel_coreloss(self, >>> box.material = "magnesium" >>> m3d.materials["magnesium"].set_electrical_steel_coreloss( ... is_coreloss_vs_freq=True, - ... points_list_at_frequencies=[{60 : [[0,0], [1,3.5], [2,7.4]]}, - ... {100 : [[0,0], [1,8], [2,9]]}, - ... {150 : [[0,0], [1,10], [2,19]]}] + ... points_list_at_freq={60 : [[0,0], [1,3.5], [2,7.4]], + ... 100 : [[0,0], [1,8], [2,9]], + ... 150 : [[0,0], [1,10], [2,19]]} ... ) >>> m3d.release_desktop(True, True) """ + if not isinstance(points_list_at_freq, dict): + self.logger.error("Points list at frequencies must be provided as a list of dictionaries.") + return False if "core_loss_type" not in self._props: self._props["core_loss_type"] = OrderedDict( {"property_type": "ChoiceProperty", "Choice": "Electrical Steel"}) @@ -2082,52 +2156,36 @@ def set_electrical_steel_coreloss(self, self._props.pop("core_loss_hkc", None) self._props.pop("core_loss_curves", None) self._props["core_loss_type"]["Choice"] = "Electrical Steel" - if is_coreloss_at_freq: - if not isinstance(points_list_at_frequencies, dict): - self.logger.error("Points list at frequency must be provided as a dictionary.") - return False + if len(points_list_at_freq.keys()) == 1: self._props["AttachedData"]["CoefficientSetupData"] = OrderedDict({}) self._props["AttachedData"]["CoefficientSetupData"]["property_data"] = "coreloss_data" self._props["AttachedData"]["CoefficientSetupData"]["coefficient_setup"] = "w_per_cubic_meter" - self._props["AttachedData"]["CoefficientSetupData"]["Frequency"] = "{}Hz".format( - list(points_list_at_frequencies.keys())[0]) + frequency = list(points_list_at_freq.keys())[0] + self._props["AttachedData"]["CoefficientSetupData"]["Frequency"] = "{}Hz".format(frequency) self._props["AttachedData"]["CoefficientSetupData"]["Thickness"] = thickness self._props["AttachedData"]["CoefficientSetupData"]["Conductivity"] = str(conductivity) - self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"] = ( - OrderedDict({"DimUnits": ["", ""], - "Points": list(itertools.chain(*[v for v in list(points_list_at_frequencies.values())[0]])) - } - ) - ) - #points_list = OrderedDict({"Points": list(itertools.chain(*[v for v in list(points_list_at_frequencies.values())[0]]))}) - # self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"]["Points"] = OrderedDict({}) - # points = OrderedDict({}) - # for pairs in list(points_list_at_frequencies.values())[0]: - # points[pairs[0]] = pairs[1] - # self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"]["Points"] = points - elif is_coreloss_vs_freq: - if not isinstance(points_list_at_frequencies, dict): - self.logger.error("Points list at frequencies must be provided as a list of dictionaries.") - return False + points = list(itertools.chain(*[v for v in list(points_list_at_freq.values())[0]])) + self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], + "Points": points}) + elif len(points_list_at_freq.keys()) > 1: self._props["AttachedData"]["CoreLossMultiCurveData"] = OrderedDict({}) self._props["AttachedData"]["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" self._props["AttachedData"]["CoreLossMultiCurveData"]["coreloss_unit"] = "w_per_cubic_meter" self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"] = OrderedDict({}) - for freq in list(points_list_at_frequencies.keys()): - self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = OrderedDict({}) - self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"]["Frequency"] = freq - self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"][ - "Coordinates"] = OrderedDict({}) - self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"]["Coordinates"][ - "Points"] = [] - self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"]["Coordinates"][ - "Points"].append(itertools.chain(points_list_at_frequencies[freq])) - - self._props["core_loss_kh"] = str(kh) - self._props["core_loss_kc"] = str(kc) - self._props["core_loss_ke"] = str(ke) + self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = [] + for freq in list(points_list_at_freq.keys()): + points = list(itertools.chain(*[v for v in points_list_at_freq[freq]])) + one_curve = OrderedDict({"Frequency": "{}Hz".format(freq), + "Coordinates": OrderedDict({"DimUnits": ["", ""], "Points": points})}) + self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"].append(one_curve) + + coefficients = self.get_core_loss_coefficients(points_list_at_freq, thickness=thickness, + conductivity=conductivity) + self._props["core_loss_kh"] = str(coefficients[0]) + self._props["core_loss_kc"] = str(coefficients[1]) + self._props["core_loss_ke"] = str(coefficients[2]) self._props["core_loss_kdc"] = str(kdc) self._props["core_loss_equiv_cut_depth"] = "{}meter".format(cut_depth) return self.update() From 7391fa07fb50a30072f696b06f3260a51d3e9033 Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Tue, 31 Oct 2023 14:57:04 +0100 Subject: [PATCH 03/26] fix --- pyaedt/generic/DataHandlers.py | 7 ++++++- pyaedt/modules/Material.py | 29 ++++++++++++++++------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/pyaedt/generic/DataHandlers.py b/pyaedt/generic/DataHandlers.py index 57498f145da..0d266ba029c 100644 --- a/pyaedt/generic/DataHandlers.py +++ b/pyaedt/generic/DataHandlers.py @@ -101,7 +101,12 @@ def _dict2arg(d, arg_out): arg = ["NAME:" + k] _dict2arg(el, arg) arg_out.append(arg) - elif type(v) is list and len(v) > 0 and all(isinstance(n, int) for n in v) or all(isinstance(n, float) for n in v): + elif type(v) is list and len(v) > 0 and all(isinstance(n, int) for n in v): + arg = ["NAME:" + k] + for el in v: + arg.append(el) + arg_out.append(arg) + elif type(v) is list and len(v) > 0 and all(isinstance(n, float) for n in v): arg = ["NAME:" + k] for el in v: arg.append(el) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index c621b388ffd..c899c5d2578 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2085,10 +2085,11 @@ def get_core_loss_coefficients(self, @pyaedt_function_handler() def set_electrical_steel_coreloss_at_frequency(self, kdc=0, - cut_depth=0.001, - is_coreloss_at_freq=False, + cut_depth="1mm", thickness="0.5mm", conductivity=0, + coefficient_setup="w_per_cubic_meter", + core_loss_model_type="Electrical Steel", points_list_at_freq={}): """Set Electrical Steel Core Loss Model at one single frequency or at multiple frequencies. @@ -2096,7 +2097,7 @@ def set_electrical_steel_coreloss_at_frequency(self, ---------- kdc : float Coefficient considering the DC flux bias effects - cut_depth : float + cut_depth : str Equivalent cut depth. The manufacturing effects on core loss computation can be considered by using this parameter. The default value is ``1mm``. @@ -2106,11 +2107,15 @@ def set_electrical_steel_coreloss_at_frequency(self, conductivity : float Conductivity. The unit is S/m. The default value is ``0S/m``. + coefficient_setup : str, optional + Core loss unit. + Possible values are: ``w_per_cubic_meter``, ``kw_per_cubic_meter``, ``w_per_lb``, ``w_per_kg``. + The default value is ``w_per_cubic_meter``. points_list_at_freq : dict - If is_coreloss_at_one_freq is ``True``, points_list_at_freq has to be provided as a dictionary where - the key is the single frequency and the value is a list of list of points (BP curve). - If is_coreloss_vs_freq is ``True``, points_list_at_freq has to be provided as a dictionary - where the keys are the frequencies and values are list of list of points (BP curve) for each frequency. + Dictionary where keys are the frequencies (in Hz) and values are lists of points (BP curve). + If the core loss model is calculated at one frequency points_list_at_freq has to be provided as a + dictionary with one key (single frequency in Hz) and values are lists of points at + that specific freq (BP curve). Returns ------- @@ -2125,7 +2130,7 @@ def set_electrical_steel_coreloss_at_frequency(self, Examples -------- This example shows how to set a core loss model for a material in case material properties are calculated for - core losses at one frequency or core losses versus frequencies. + core losses at one frequency or core losses versus frequencies (core losses multi curve data). The first case shows how to set properties for core losses at one frequency: >>> from pyaedt import Maxwell3d @@ -2133,7 +2138,6 @@ def set_electrical_steel_coreloss_at_frequency(self, >>> box = m3d.modeler.create_box([-10, -10, 0], [20, 20, 20], "box_to_split") >>> box.material = "magnesium" >>> m3d.materials["magnesium"].set_electrical_steel_coreloss( - ... is_coreloss_vs_freq=False, ... points_list_at_freq={60 : [[0,0], [1,3.5], [2,7.4]]} ... ) >>> m3d.release_desktop(True, True) @@ -2145,7 +2149,6 @@ def set_electrical_steel_coreloss_at_frequency(self, >>> box = m3d.modeler.create_box([-10, -10, 0], [20, 20, 20], "box_to_split") >>> box.material = "magnesium" >>> m3d.materials["magnesium"].set_electrical_steel_coreloss( - ... is_coreloss_vs_freq=True, ... points_list_at_freq={60 : [[0,0], [1,3.5], [2,7.4]], ... 100 : [[0,0], [1,8], [2,9]], ... 150 : [[0,0], [1,10], [2,19]]} @@ -2167,11 +2170,11 @@ def set_electrical_steel_coreloss_at_frequency(self, self._props.pop("core_loss_br", None) self._props.pop("core_loss_hkc", None) self._props.pop("core_loss_curves", None) - self._props["core_loss_type"]["Choice"] = "Electrical Steel" + self._props["core_loss_type"]["Choice"] = core_loss_model_type if len(points_list_at_freq.keys()) == 1: self._props["AttachedData"]["CoefficientSetupData"] = OrderedDict({}) self._props["AttachedData"]["CoefficientSetupData"]["property_data"] = "coreloss_data" - self._props["AttachedData"]["CoefficientSetupData"]["coefficient_setup"] = "w_per_cubic_meter" + self._props["AttachedData"]["CoefficientSetupData"]["coefficient_setup"] = coefficient_setup frequency = list(points_list_at_freq.keys())[0] self._props["AttachedData"]["CoefficientSetupData"]["Frequency"] = "{}Hz".format(frequency) self._props["AttachedData"]["CoefficientSetupData"]["Thickness"] = thickness @@ -2199,7 +2202,7 @@ def set_electrical_steel_coreloss_at_frequency(self, self._props["core_loss_kc"] = str(coefficients[1]) self._props["core_loss_ke"] = str(coefficients[2]) self._props["core_loss_kdc"] = str(kdc) - self._props["core_loss_equiv_cut_depth"] = "{}meter".format(cut_depth) + self._props["core_loss_equiv_cut_depth"] = cut_depth return self.update() @pyaedt_function_handler() From 24d48dd6f68790e51732a89c156a9c2315ed5ad8 Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Tue, 31 Oct 2023 16:58:09 +0100 Subject: [PATCH 04/26] set_electrical_steel core losses with coefficients --- pyaedt/modules/Material.py | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index c899c5d2578..3169b93d985 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2205,6 +2205,52 @@ def set_electrical_steel_coreloss_at_frequency(self, self._props["core_loss_equiv_cut_depth"] = cut_depth return self.update() + @pyaedt_function_handler() + def set_electrical_steel_coreloss(self, kh=0, kc=0, ke=0, kdc=0, cut_depth="1mm"): + """Set Electrical Steel Core Loss. + + Parameters + ---------- + kh : float, optional + Hysteresis core loss coefficient. + The default value is ``0``. + kc : float, optional + Eddy-current core loss coefficient. + The default value is ``0``. + ke : float, optional + Excess core loss coefficient. + The default value is ``0``. + kdc : float, optional + Coefficient considering the DC flux bias effects. + The default value is ``0``. + cut_depth : str, optional + Equivalent Cut Depth considering manufacturing effects on core loss computation. + The default value is ``1mm``. + + Returns + ------- + bool + """ + if "core_loss_type" not in self._props: + self._props["core_loss_type"] = OrderedDict( + {"property_type": "ChoiceProperty", "Choice": "Electrical Steel"} + ) + else: + self._props.pop("core_loss_cm", None) + self._props.pop("core_loss_x", None) + self._props.pop("core_loss_y", None) + self._props.pop("core_loss_hci", None) + self._props.pop("core_loss_br", None) + self._props.pop("core_loss_hkc", None) + self._props.pop("core_loss_curves", None) + self._props["core_loss_type"]["Choice"] = "Electrical Steel" + self._props["core_loss_kh"] = str(kh) + self._props["core_loss_kc"] = str(kc) + self._props["core_loss_ke"] = str(ke) + self._props["core_loss_kdc"] = str(kdc) + self._props["core_loss_equiv_cut_depth"] = cut_depth + return self.update() + @pyaedt_function_handler() def set_hysteresis_coreloss(self, kdc=0, hci=0, br=0, hkc=0, cut_depth=0.0001): """Set Hysteresis Type Core Loss. From bd715fde0a6c4e7f1b5bcbb58b2e60e9940187fb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 16:00:27 +0000 Subject: [PATCH 05/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyaedt/modules/Material.py | 144 +++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 68 deletions(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index f1b30c1b890..bf55a28c7f7 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -17,8 +17,8 @@ import itertools import warnings -from pyaedt.generic.DataHandlers import _dict2arg from pyaedt import is_ironpython +from pyaedt.generic.DataHandlers import _dict2arg from pyaedt.generic.constants import CSS4_COLORS from pyaedt.generic.general_methods import pyaedt_function_handler @@ -458,8 +458,8 @@ def _add_thermal_modifier(self, formula, index): """ if ( - "ModifierData" not in self._material._props - or "ThermalModifierData" not in self._material._props["ModifierData"] + "ModifierData" not in self._material._props + or "ThermalModifierData" not in self._material._props["ModifierData"] ): tm = OrderedDict( { @@ -471,8 +471,8 @@ def _add_thermal_modifier(self, formula, index): } ) if ( - "ModifierData" in self._material._props - and "SpatialModifierData" in self._material._props["ModifierData"] + "ModifierData" in self._material._props + and "SpatialModifierData" in self._material._props["ModifierData"] ): self._material._props["ModifierData"] = OrderedDict( { @@ -500,8 +500,7 @@ def _add_thermal_modifier(self, formula, index): else: for tmname in self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"]: if isinstance( - self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname], - list + self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname], list ): found = False for tm in self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][ @@ -530,16 +529,14 @@ def _add_thermal_modifier(self, formula, index): tmname ].append(tm) elif ( - self.name - == - self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ - "Property:" - ] - and index - == - self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ - "Index:" - ] + self.name + == self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ + "Property:" + ] + and index + == self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ + "Index:" + ] ): self._material._props["ModifierData"]["ThermalModifierData"]["all_thermal_modifiers"][tmname][ "use_free_form" @@ -650,8 +647,7 @@ def add_thermal_modifier_dataset(self, dataset_name, index=0): @pyaedt_function_handler() def add_thermal_modifier_closed_form( - self, tref=22, c1=0.0001, c2=1e-6, tl=-273.15, tu=1000, units="cel", auto_calc=True, tml=1000, tmu=1000, - index=0 + self, tref=22, c1=0.0001, c2=1e-6, tl=-273.15, tu=1000, units="cel", auto_calc=True, tml=1000, tmu=1000, index=0 ): """Add a thermal modifier to a material property using a closed-form formula. @@ -751,12 +747,12 @@ def add_thermal_modifier_closed_form( } ) if ( - "ModifierData" not in self._material._props - or "ThermalModifierData" not in self._material._props["ModifierData"] + "ModifierData" not in self._material._props + or "ThermalModifierData" not in self._material._props["ModifierData"] ): if ( - "ModifierData" in self._material._props - and "SpatialModifierData" in self._material._props["ModifierData"] + "ModifierData" in self._material._props + and "SpatialModifierData" in self._material._props["ModifierData"] ): self._material._props["ModifierData"] = OrderedDict( { @@ -936,8 +932,8 @@ def _add_spatial_modifier(self, formula, index): """ if ( - "ModifierData" not in self._material._props - or "SpatialModifierData" not in self._material._props["ModifierData"] + "ModifierData" not in self._material._props + or "SpatialModifierData" not in self._material._props["ModifierData"] ): sm = OrderedDict( { @@ -948,8 +944,8 @@ def _add_spatial_modifier(self, formula, index): } ) if ( - "ModifierData" in self._material._props - and "ThermalModifierData" in self._material._props["ModifierData"] + "ModifierData" in self._material._props + and "ThermalModifierData" in self._material._props["ModifierData"] ): self._material._props["ModifierData"] = OrderedDict( { @@ -976,8 +972,7 @@ def _add_spatial_modifier(self, formula, index): else: for smname in self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"]: if isinstance( - self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname], - list + self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname], list ): found = False for sm in self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][ @@ -1000,16 +995,14 @@ def _add_spatial_modifier(self, formula, index): smname ].append(sm) elif ( - self.name - == - self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ - "Property:" - ] - and index - == - self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ - "Index:" - ] + self.name + == self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ + "Property:" + ] + and index + == self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ + "Index:" + ] ): self._material._props["ModifierData"]["SpatialModifierData"]["all_spatial_modifiers"][smname][ "free_form_value" @@ -1295,7 +1288,7 @@ def __init__(self, materiallib, name, props=None, material_update=True): if (materiallib._color_id) > len(vals): materiallib._color_id = 0 h = vals[materiallib._color_id].lstrip("#") - self._material_appearance = list(int(h[i: i + 2], 16) for i in (0, 2, 4)) + self._material_appearance = list(int(h[i : i + 2], 16) for i in (0, 2, 4)) materiallib._color_id += 1 self._props["AttachedData"] = OrderedDict( { @@ -1999,12 +1992,14 @@ def set_magnetic_coercivity(self, value=0, x=1, y=0, z=0): return self.update() @pyaedt_function_handler() - def get_core_loss_coefficients(self, - points_list_at_freq, - core_loss_model_type="Electrical Steel", - thickness="0.5mm", - conductivity=0, - coefficient_setup="w_per_cubic_meter"): + def get_core_loss_coefficients( + self, + points_list_at_freq, + core_loss_model_type="Electrical Steel", + thickness="0.5mm", + conductivity=0, + coefficient_setup="w_per_cubic_meter", + ): """Compute core loss coefficients from the loss characteristics (B-P Curve) at a given frequency. Parameters @@ -2061,8 +2056,7 @@ def get_core_loss_coefficients(self, props["CoefficientSetupData"]["Thickness"] = thickness props["CoefficientSetupData"]["Conductivity"] = str(conductivity) points = list(itertools.chain(*[v for v in list(points_list_at_freq.values())[0]])) - props["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], - "Points": points}) + props["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], "Points": points}) elif len(points_list_at_freq.keys()) > 1: props["CoreLossMultiCurveData"] = OrderedDict({}) props["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" @@ -2072,25 +2066,32 @@ def get_core_loss_coefficients(self, props["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = [] for freq in list(points_list_at_freq.keys()): points = list(itertools.chain(*[v for v in points_list_at_freq[freq]])) - one_curve = OrderedDict({"Frequency": "{}Hz".format(freq), "Coordinates": OrderedDict({"DimUnits": ["", ""], "Points": points})}) + one_curve = OrderedDict( + { + "Frequency": "{}Hz".format(freq), + "Coordinates": OrderedDict({"DimUnits": ["", ""], "Points": points}), + } + ) props["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"].append(one_curve) props = args = self._get_args(props) props.pop(0) - coefficients = self.odefinition_manager.ComputeCoreLossCoefficients(core_loss_model_type, - self.mass_density.evaluated_value, - props[0]) + coefficients = self.odefinition_manager.ComputeCoreLossCoefficients( + core_loss_model_type, self.mass_density.evaluated_value, props[0] + ) return coefficients @pyaedt_function_handler() - def set_electrical_steel_coreloss_at_frequency(self, - kdc=0, - cut_depth="1mm", - thickness="0.5mm", - conductivity=0, - coefficient_setup="w_per_cubic_meter", - core_loss_model_type="Electrical Steel", - points_list_at_freq={}): + def set_electrical_steel_coreloss_at_frequency( + self, + kdc=0, + cut_depth="1mm", + thickness="0.5mm", + conductivity=0, + coefficient_setup="w_per_cubic_meter", + core_loss_model_type="Electrical Steel", + points_list_at_freq={}, + ): """Set Electrical Steel Core Loss Model at one single frequency or at multiple frequencies. Parameters @@ -2161,7 +2162,8 @@ def set_electrical_steel_coreloss_at_frequency(self, return False if "core_loss_type" not in self._props: self._props["core_loss_type"] = OrderedDict( - {"property_type": "ChoiceProperty", "Choice": "Electrical Steel"}) + {"property_type": "ChoiceProperty", "Choice": "Electrical Steel"} + ) else: self._props.pop("core_loss_cm", None) self._props.pop("core_loss_x", None) @@ -2181,8 +2183,9 @@ def set_electrical_steel_coreloss_at_frequency(self, self._props["AttachedData"]["CoefficientSetupData"]["Conductivity"] = str(conductivity) points = list(itertools.chain(*[v for v in list(points_list_at_freq.values())[0]])) - self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], - "Points": points}) + self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"] = OrderedDict( + {"DimUnits": ["", ""], "Points": points} + ) elif len(points_list_at_freq.keys()) > 1: self._props["AttachedData"]["CoreLossMultiCurveData"] = OrderedDict({}) self._props["AttachedData"]["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" @@ -2192,12 +2195,17 @@ def set_electrical_steel_coreloss_at_frequency(self, self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = [] for freq in list(points_list_at_freq.keys()): points = list(itertools.chain(*[v for v in points_list_at_freq[freq]])) - one_curve = OrderedDict({"Frequency": "{}Hz".format(freq), - "Coordinates": OrderedDict({"DimUnits": ["", ""], "Points": points})}) + one_curve = OrderedDict( + { + "Frequency": "{}Hz".format(freq), + "Coordinates": OrderedDict({"DimUnits": ["", ""], "Points": points}), + } + ) self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"].append(one_curve) - coefficients = self.get_core_loss_coefficients(points_list_at_freq, thickness=thickness, - conductivity=conductivity) + coefficients = self.get_core_loss_coefficients( + points_list_at_freq, thickness=thickness, conductivity=conductivity + ) self._props["core_loss_kh"] = str(coefficients[0]) self._props["core_loss_kc"] = str(coefficients[1]) self._props["core_loss_ke"] = str(coefficients[2]) @@ -2329,7 +2337,7 @@ def set_power_ferrite_coreloss(self, cm=0, x=0, y=0, kdc=0, cut_depth=0.0001): @pyaedt_function_handler() def set_bp_curve_coreloss( - self, point_list, kdc=0, cut_depth=0.0001, punit="kw/m^3", bunit="tesla", frequency=60, thickness="0.5mm" + self, point_list, kdc=0, cut_depth=0.0001, punit="kw/m^3", bunit="tesla", frequency=60, thickness="0.5mm" ): """Set B-P Type Core Loss. From e55087417ace900a77677482952db919006c59aa Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Tue, 31 Oct 2023 17:01:33 +0100 Subject: [PATCH 06/26] remove imports --- pyaedt/modules/Material.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 3169b93d985..b60b357de0b 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -18,16 +18,9 @@ import warnings from pyaedt.generic.DataHandlers import _dict2arg -from pyaedt import is_ironpython from pyaedt.generic.constants import CSS4_COLORS from pyaedt.generic.general_methods import pyaedt_function_handler -if not is_ironpython: - try: - import numpy as np - except ImportError: - pass - class MatProperties(object): """Contains a list of constant names for all materials with From 5ece5f4b75d2dce6647c7cdead32de9238bee128 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 16:08:33 +0000 Subject: [PATCH 07/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyaedt/modules/Material.py | 55 ++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index c9dc3b96bb3..a9f4e91c482 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -1985,12 +1985,14 @@ def set_magnetic_coercivity(self, value=0, x=1, y=0, z=0): return self.update() @pyaedt_function_handler() - def get_core_loss_coefficients(self, - points_list_at_freq, - core_loss_model_type="Electrical Steel", - thickness="0.5mm", - conductivity=0, - coefficient_setup="w_per_cubic_meter"): + def get_core_loss_coefficients( + self, + points_list_at_freq, + core_loss_model_type="Electrical Steel", + thickness="0.5mm", + conductivity=0, + coefficient_setup="w_per_cubic_meter", + ): """Compute core loss coefficients from the loss characteristics (B-P Curve) at a given frequency. Parameters @@ -2047,8 +2049,7 @@ def get_core_loss_coefficients(self, props["CoefficientSetupData"]["Thickness"] = thickness props["CoefficientSetupData"]["Conductivity"] = str(conductivity) points = list(itertools.chain(*[v for v in list(points_list_at_freq.values())[0]])) - props["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], - "Points": points}) + props["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], "Points": points}) elif len(points_list_at_freq.keys()) > 1: props["CoreLossMultiCurveData"] = OrderedDict({}) props["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" @@ -2074,14 +2075,16 @@ def get_core_loss_coefficients(self, return coefficients @pyaedt_function_handler() - def set_electrical_steel_coreloss_at_frequency(self, - kdc=0, - cut_depth="1mm", - thickness="0.5mm", - conductivity=0, - coefficient_setup="w_per_cubic_meter", - core_loss_model_type="Electrical Steel", - points_list_at_freq={}): + def set_electrical_steel_coreloss_at_frequency( + self, + kdc=0, + cut_depth="1mm", + thickness="0.5mm", + conductivity=0, + coefficient_setup="w_per_cubic_meter", + core_loss_model_type="Electrical Steel", + points_list_at_freq={}, + ): """Set Electrical Steel Core Loss Model at one single frequency or at multiple frequencies. Parameters @@ -2173,8 +2176,9 @@ def set_electrical_steel_coreloss_at_frequency(self, self._props["AttachedData"]["CoefficientSetupData"]["Conductivity"] = str(conductivity) points = list(itertools.chain(*[v for v in list(points_list_at_freq.values())[0]])) - self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], - "Points": points}) + self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"] = OrderedDict( + {"DimUnits": ["", ""], "Points": points} + ) elif len(points_list_at_freq.keys()) > 1: self._props["AttachedData"]["CoreLossMultiCurveData"] = OrderedDict({}) self._props["AttachedData"]["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" @@ -2184,12 +2188,17 @@ def set_electrical_steel_coreloss_at_frequency(self, self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = [] for freq in list(points_list_at_freq.keys()): points = list(itertools.chain(*[v for v in points_list_at_freq[freq]])) - one_curve = OrderedDict({"Frequency": "{}Hz".format(freq), - "Coordinates": OrderedDict({"DimUnits": ["", ""], "Points": points})}) + one_curve = OrderedDict( + { + "Frequency": "{}Hz".format(freq), + "Coordinates": OrderedDict({"DimUnits": ["", ""], "Points": points}), + } + ) self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"].append(one_curve) - coefficients = self.get_core_loss_coefficients(points_list_at_freq, thickness=thickness, - conductivity=conductivity) + coefficients = self.get_core_loss_coefficients( + points_list_at_freq, thickness=thickness, conductivity=conductivity + ) self._props["core_loss_kh"] = str(coefficients[0]) self._props["core_loss_kc"] = str(coefficients[1]) self._props["core_loss_ke"] = str(coefficients[2]) @@ -2321,7 +2330,7 @@ def set_power_ferrite_coreloss(self, cm=0, x=0, y=0, kdc=0, cut_depth=0.0001): @pyaedt_function_handler() def set_bp_curve_coreloss( - self, point_list, kdc=0, cut_depth=0.0001, punit="kw/m^3", bunit="tesla", frequency=60, thickness="0.5mm" + self, point_list, kdc=0, cut_depth=0.0001, punit="kw/m^3", bunit="tesla", frequency=60, thickness="0.5mm" ): """Set B-P Type Core Loss. From b43b84e050a3c6171990d48322a5cef8323d76c9 Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Thu, 2 Nov 2023 16:15:44 +0100 Subject: [PATCH 08/26] add get coreloss coefficients test --- _unittest/test_03_Materials.py | 15 ++++++++++++- pyaedt/modules/Material.py | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py index 73f141114cf..ccb651590ee 100644 --- a/_unittest/test_03_Materials.py +++ b/_unittest/test_03_Materials.py @@ -82,7 +82,7 @@ def test_02_create_material(self): assert mat1.set_electrical_steel_coreloss(1, 2, 3, 4, 0.002) assert mat1.get_curve_coreloss_type() == "Electrical Steel" - assert mat1.get_curve_coreloss_values()["core_loss_equiv_cut_depth"] == "0.002meter" + assert mat1.get_curve_coreloss_values()["core_loss_equiv_cut_depth"] == 0.002 assert mat1.set_hysteresis_coreloss(1, 2, 3, 4, 0.002) assert mat1.get_curve_coreloss_type() == "Hysteresis Model" assert mat1.set_bp_curve_coreloss([[0, 0], [10, 10], [20, 20]]) @@ -243,3 +243,16 @@ def test_12_material_model(self): self.aedtapp["$dk"] = 3 self.aedtapp["$df"] = 0.01 assert mat.set_djordjevic_sarkar_model(dk="$dk", df="$df") + + def test_13_get_coreloss_coefficients(self): + mat = self.aedtapp.materials.add_material("mat_test") + coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients(points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}) + assert isinstance(coeff, list) + assert len(coeff) == 3 + assert all(isinstance(c, float) for c in coeff) + assert not self.aedtapp.materials["mat_test"].get_core_loss_coefficients(points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]]) + coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients(points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]], 100: [[0, 0],[1, 8],[2, 9]], 150: [[0, 0], [1, 10], [2, 19]]}) + assert isinstance(coeff, list) + assert len(coeff) == 3 + assert all(isinstance(c, float) for c in coeff) + diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index a9f4e91c482..30b60065d50 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2511,6 +2511,47 @@ def is_dielectric(self, threshold=100000): """ return not self.is_conductor(threshold) + @pyaedt_function_handler + def set_djordjevic_sarkar_model( + self, + dk=4, + df=0.02, + i_freq=1e9, + sigma_dc=1e-12, + freq_hi=159.15494e9, + ): + """Set Djordjevic-Sarkar model. + Parameters + ---------- + dk : int, float, str, optional + Dielectric constant at input frequency. + df : int, float, str, optional + Loss tangent at input frequency. + i_freq : int, float, optional. + Input frequency in Hz. + sigma_dc : int, float, optional + Conductivity at DC. + freq_hi : int, float, optional + High Frequency corner in Hz. + Returns + ------- + bool + ``True`` if successful, ``False`` otherwise. + """ + + # K = f"({dk} * {df} - {sigma_dc} / (2 * pi * {i_freq} * e0)) / atan({freq_hi} / {i_freq})" + K = "({} * {} - {} / (2 * pi * {} * e0)) / atan({} / {})".format(dk, df, sigma_dc, i_freq, freq_hi, i_freq) + epsilon_inf = "({} - {} / 2 * ln({}**2 / {}**2 + 1))".format(dk, K, freq_hi, i_freq) + freq_low = "({} / exp(10 * {} * {} / ({})))".format(freq_hi, df, epsilon_inf, K) + ds_er = "{} + {} / 2 * ln(({}**2 + Freq**2) / ({}**2 + Freq**2))".format(epsilon_inf, K, freq_hi, freq_low) + cond = "{} + 2 * pi * Freq * e0 * ({}) * (atan(Freq / ({})) - atan(Freq / {}))".format(sigma_dc, K, freq_low, freq_hi) + # ds_tande = "{} / (e0 * {} * 2 * pi * Freq)".format(cond, ds_er) + + self.conductivity = cond + self.permittivity = ds_er + + return self.update() + @pyaedt_function_handler() def update(self): """Update the material in AEDT. From c3a68b76284af8cba1c4d60fe3abe114c0d7cec5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:18:38 +0000 Subject: [PATCH 09/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- _unittest/test_03_Materials.py | 17 +++++++++++++---- pyaedt/modules/Material.py | 16 +++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py index ccb651590ee..54669c88ad0 100644 --- a/_unittest/test_03_Materials.py +++ b/_unittest/test_03_Materials.py @@ -246,13 +246,22 @@ def test_12_material_model(self): def test_13_get_coreloss_coefficients(self): mat = self.aedtapp.materials.add_material("mat_test") - coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients(points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}) + coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]} + ) assert isinstance(coeff, list) assert len(coeff) == 3 assert all(isinstance(c, float) for c in coeff) - assert not self.aedtapp.materials["mat_test"].get_core_loss_coefficients(points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]]) - coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients(points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]], 100: [[0, 0],[1, 8],[2, 9]], 150: [[0, 0], [1, 10], [2, 19]]}) + assert not self.aedtapp.materials["mat_test"].get_core_loss_coefficients( + points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]] + ) + coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( + points_list_at_freq={ + 60: [[0, 0], [1, 3.5], [2, 7.4]], + 100: [[0, 0], [1, 8], [2, 9]], + 150: [[0, 0], [1, 10], [2, 19]], + } + ) assert isinstance(coeff, list) assert len(coeff) == 3 assert all(isinstance(c, float) for c in coeff) - diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 30b60065d50..c75b680a5dc 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2513,12 +2513,12 @@ def is_dielectric(self, threshold=100000): @pyaedt_function_handler def set_djordjevic_sarkar_model( - self, - dk=4, - df=0.02, - i_freq=1e9, - sigma_dc=1e-12, - freq_hi=159.15494e9, + self, + dk=4, + df=0.02, + i_freq=1e9, + sigma_dc=1e-12, + freq_hi=159.15494e9, ): """Set Djordjevic-Sarkar model. Parameters @@ -2544,7 +2544,9 @@ def set_djordjevic_sarkar_model( epsilon_inf = "({} - {} / 2 * ln({}**2 / {}**2 + 1))".format(dk, K, freq_hi, i_freq) freq_low = "({} / exp(10 * {} * {} / ({})))".format(freq_hi, df, epsilon_inf, K) ds_er = "{} + {} / 2 * ln(({}**2 + Freq**2) / ({}**2 + Freq**2))".format(epsilon_inf, K, freq_hi, freq_low) - cond = "{} + 2 * pi * Freq * e0 * ({}) * (atan(Freq / ({})) - atan(Freq / {}))".format(sigma_dc, K, freq_low, freq_hi) + cond = "{} + 2 * pi * Freq * e0 * ({}) * (atan(Freq / ({})) - atan(Freq / {}))".format( + sigma_dc, K, freq_low, freq_hi + ) # ds_tande = "{} / (e0 * {} * 2 * pi * Freq)".format(cond, ds_er) self.conductivity = cond From 6e97530363fd8636f7d0e05a0b6a761560521a59 Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Wed, 15 Nov 2023 12:17:10 +0100 Subject: [PATCH 10/26] set core loss test implement --- _unittest/test_03_Materials.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py index 837dfcbb18d..bc2887cb23f 100644 --- a/_unittest/test_03_Materials.py +++ b/_unittest/test_03_Materials.py @@ -267,3 +267,19 @@ def test_13_get_coreloss_coefficients(self): assert isinstance(coeff, list) assert len(coeff) == 3 assert all(isinstance(c, float) for c in coeff) + + def test_14_set_core_loss(self): + mat = self.aedtapp.materials["mat_test"] + assert self.aedtapp.materials["mat_test"].set_electrical_steel_coreloss_at_frequency( + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]} + ) + assert not self.aedtapp.materials["mat_test"].set_electrical_steel_coreloss_at_frequency( + points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]] + ) + assert self.aedtapp.materials["mat_test"].set_electrical_steel_coreloss_at_frequency( + points_list_at_freq={ + 60: [[0, 0], [1, 3.5], [2, 7.4]], + 100: [[0, 0], [1, 8], [2, 9]], + 150: [[0, 0], [1, 10], [2, 19]], + } + ) \ No newline at end of file From 4c8a95c6cd6ade2787b03e161bbb2ade01c1cd3f Mon Sep 17 00:00:00 2001 From: gmalinve <103059376+gmalinve@users.noreply.github.com> Date: Wed, 15 Nov 2023 12:18:11 +0100 Subject: [PATCH 11/26] Update pyaedt/modules/Material.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- pyaedt/modules/Material.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 957704077bb..e2c11dc9f64 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2529,6 +2529,7 @@ def set_djordjevic_sarkar_model( freq_hi=159.15494e9, ): """Set Djordjevic-Sarkar model. + Parameters ---------- dk : int, float, str, optional From eb66357a3b527084d6a6e286436bd16d00aa16ad Mon Sep 17 00:00:00 2001 From: gmalinve <103059376+gmalinve@users.noreply.github.com> Date: Wed, 15 Nov 2023 12:18:52 +0100 Subject: [PATCH 12/26] Update pyaedt/modules/Material.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- pyaedt/modules/Material.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index e2c11dc9f64..12dcffeb71f 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2539,7 +2539,7 @@ def set_djordjevic_sarkar_model( i_freq : int, float, optional. Input frequency in Hz. sigma_dc : int, float, optional - Conductivity at DC. + Conductivity at DC. The default is ``1e-12``. freq_hi : int, float, optional High Frequency corner in Hz. Returns From 0a9afedf6ea82425df8dd439ff0fc334948d9eca Mon Sep 17 00:00:00 2001 From: gmalinve <103059376+gmalinve@users.noreply.github.com> Date: Wed, 15 Nov 2023 12:19:22 +0100 Subject: [PATCH 13/26] Update pyaedt/modules/Material.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- pyaedt/modules/Material.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 12dcffeb71f..9e42dea5f3d 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2541,7 +2541,8 @@ def set_djordjevic_sarkar_model( sigma_dc : int, float, optional Conductivity at DC. The default is ``1e-12``. freq_hi : int, float, optional - High Frequency corner in Hz. + High-frequency corner in Hz. The default is ``159.15494e9``. + Returns ------- bool From e06d12997952b7e63c07fd65e8c07ebfe90b48a5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:20:03 +0000 Subject: [PATCH 14/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- _unittest/test_03_Materials.py | 2 +- pyaedt/modules/Material.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py index bc2887cb23f..c55330f2f5c 100644 --- a/_unittest/test_03_Materials.py +++ b/_unittest/test_03_Materials.py @@ -282,4 +282,4 @@ def test_14_set_core_loss(self): 100: [[0, 0], [1, 8], [2, 9]], 150: [[0, 0], [1, 10], [2, 19]], } - ) \ No newline at end of file + ) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 9e42dea5f3d..a6f4a7a7e2f 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2529,7 +2529,7 @@ def set_djordjevic_sarkar_model( freq_hi=159.15494e9, ): """Set Djordjevic-Sarkar model. - + Parameters ---------- dk : int, float, str, optional From 144f522480f89c127dc0c2dead813b6e137d09e7 Mon Sep 17 00:00:00 2001 From: gmalinve <103059376+gmalinve@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:35:11 +0100 Subject: [PATCH 15/26] Apply suggestions from code review Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- pyaedt/modules/Material.py | 41 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index a6f4a7a7e2f..b32a6678908 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2001,26 +2001,27 @@ def get_core_loss_coefficients( conductivity=0, coefficient_setup="w_per_cubic_meter", ): - """Compute core loss coefficients from the loss characteristics (B-P Curve) at a given frequency. + """Compute core loss coefficients from the loss characteristics (BP curve) at a given frequency. Parameters ---------- points_list_at_freq : dict - points_list_at_freq is a dictionary of BP values for a given frequency. - Key is the frequency and values are the list of points (BP curve). + Dictionary of BP values for a given frequency. The key is the + frequency, and the values are the list of points (BP curve). core_loss_model_type : str, optional - Core loss model type. It can be ``Electrical Steel`` or ``Power Ferrite``. - The default value is ``Electrical Steel``. + Core loss model type. The default value is ``"Electrical Steel"``. + Options are ``"Electrical Steel"`` and ``"Power Ferrite"``. thickness : str, optional - Thickness provided as value + unit. - The default value is ``0.5mm``. + Thickness provided as the value plus the unit. + The default is ``0.5mm``. conductivity : float, optional Material conductivity. - The default value is ``0``. + The default is ``0``. coefficient_setup : str, optional - Core loss unit. - Possible values are: ``w_per_cubic_meter``, ``kw_per_cubic_meter``, ``w_per_lb``, ``w_per_kg``. - The default value is ``w_per_cubic_meter``. + Core loss unit. The default is ``"w_per_cubic_meter"``. + Options are ``"kw_per_cubic_meter"``, ``"w_per_cubic_meter"``, ``"w_per_kg"``, + and ``"w_per_lb"``. + Returns ------- @@ -2101,7 +2102,7 @@ def set_electrical_steel_coreloss_at_frequency( Coefficient considering the DC flux bias effects cut_depth : str Equivalent cut depth. - The manufacturing effects on core loss computation can be considered by using this parameter. + You use this parameter to consider the manufacturing effects on core loss computation. The default value is ``1mm``. thickness : str Thickness specified in terms of value + unit. @@ -2122,7 +2123,7 @@ def set_electrical_steel_coreloss_at_frequency( Returns ------- bool - ``True`` if successful or ``False`` if it fails. + ``True`` when successful, ``False`` when failed. References ---------- @@ -2216,25 +2217,25 @@ def set_electrical_steel_coreloss_at_frequency( @pyaedt_function_handler() def set_electrical_steel_coreloss(self, kh=0, kc=0, ke=0, kdc=0, cut_depth="1mm"): - """Set Electrical Steel Core Loss. + """Set electrical steel core loss. Parameters ---------- kh : float, optional Hysteresis core loss coefficient. - The default value is ``0``. + The default is ``0``. kc : float, optional Eddy-current core loss coefficient. - The default value is ``0``. + The default is ``0``. ke : float, optional Excess core loss coefficient. - The default value is ``0``. + The default is ``0``. kdc : float, optional Coefficient considering the DC flux bias effects. - The default value is ``0``. + The default is ``0``. cut_depth : str, optional - Equivalent Cut Depth considering manufacturing effects on core loss computation. - The default value is ``1mm``. + Equivalent cut depth considering manufacturing effects on core loss computation. + The default value is ``"1mm"``. Returns ------- From 3e959efcb024189a740092dc3f8bb8cddcd91e69 Mon Sep 17 00:00:00 2001 From: gmalinve <103059376+gmalinve@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:37:13 +0100 Subject: [PATCH 16/26] Update pyaedt/modules/Material.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- pyaedt/modules/Material.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index b32a6678908..53087710fd4 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2027,8 +2027,8 @@ def get_core_loss_coefficients( ------- list List of core loss coefficients. - Returns Kh, Kc, Ke coefficients if core loss model is ``Electrical Steel``. - Returns Cm, X, Y if core loss model is ``Power Ferrite``. + Returns Kh, Kc, and Ke coefficients if the core loss model is ``"Electrical Steel"``. + Returns Cm, X, and Y if the core loss model is ``"Power Ferrite"``. Examples -------- From 77a3aacb6426a5911d830df90e95030ad3eae3cc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 15:38:39 +0000 Subject: [PATCH 17/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyaedt/modules/Material.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 53087710fd4..bc5b659e461 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2543,7 +2543,7 @@ def set_djordjevic_sarkar_model( Conductivity at DC. The default is ``1e-12``. freq_hi : int, float, optional High-frequency corner in Hz. The default is ``159.15494e9``. - + Returns ------- bool From 39acaaf9c5bec336ba83ac1b5dc559476ed537c7 Mon Sep 17 00:00:00 2001 From: gmalinve <103059376+gmalinve@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:42:11 +0100 Subject: [PATCH 18/26] Update pyaedt/modules/Material.py Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- pyaedt/modules/Material.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index bc5b659e461..17322056e0a 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2103,22 +2103,22 @@ def set_electrical_steel_coreloss_at_frequency( cut_depth : str Equivalent cut depth. You use this parameter to consider the manufacturing effects on core loss computation. - The default value is ``1mm``. + The default value is ``"1mm"``. thickness : str - Thickness specified in terms of value + unit. - The default value is ``0.5mm``. + Thickness specified in terms of the value plus the unit. + The default is ``"0.5mm"``. conductivity : float Conductivity. The unit is S/m. - The default value is ``0S/m``. + The default is ``"0S/m"``. coefficient_setup : str, optional - Core loss unit. - Possible values are: ``w_per_cubic_meter``, ``kw_per_cubic_meter``, ``w_per_lb``, ``w_per_kg``. - The default value is ``w_per_cubic_meter``. + Core loss unit. The default is ``"w_per_cubic_meter"``. + Options are ``"kw_per_cubic_meter"``, ``"w_per_cubic_meter"``, ``"w_per_kg"``, + and ``"w_per_lb"``. points_list_at_freq : dict Dictionary where keys are the frequencies (in Hz) and values are lists of points (BP curve). - If the core loss model is calculated at one frequency points_list_at_freq has to be provided as a + If the core loss model is calculated at one frequency, this parameter must be provided as a dictionary with one key (single frequency in Hz) and values are lists of points at - that specific freq (BP curve). + that specific frequency (BP curve). Returns ------- From b1a83cc77d2223cb3c6dd874bb272b0c46cd499f Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Thu, 16 Nov 2023 16:43:19 +0100 Subject: [PATCH 19/26] fix comments review --- pyaedt/modules/Material.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 17322056e0a..b39cb10ab24 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2006,8 +2006,10 @@ def get_core_loss_coefficients( Parameters ---------- points_list_at_freq : dict - Dictionary of BP values for a given frequency. The key is the - frequency, and the values are the list of points (BP curve). + Dictionary where keys are the frequencies (in Hz) and values are lists of points (BP curve). + If the core loss model is calculated at one frequency, this parameter must be provided as a + dictionary with one key (single frequency in Hz) and values are lists of points at + that specific frequency (BP curve). core_loss_model_type : str, optional Core loss model type. The default value is ``"Electrical Steel"``. Options are ``"Electrical Steel"`` and ``"Power Ferrite"``. @@ -2094,7 +2096,7 @@ def set_electrical_steel_coreloss_at_frequency( core_loss_model_type="Electrical Steel", points_list_at_freq={}, ): - """Set Electrical Steel Core Loss Model at one single frequency or at multiple frequencies. + """Set electrical steel core loss model at one single frequency or at multiple frequencies. Parameters ---------- From f17f92afb19b7a63f609020084a8cf7b5c8564b5 Mon Sep 17 00:00:00 2001 From: gmalinve <103059376+gmalinve@users.noreply.github.com> Date: Tue, 21 Nov 2023 14:46:47 +0100 Subject: [PATCH 20/26] Apply suggestions from code review Co-authored-by: Maxime Rey <87315832+MaxJPRey@users.noreply.github.com> --- pyaedt/generic/DataHandlers.py | 4 ++-- pyaedt/modules/Material.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyaedt/generic/DataHandlers.py b/pyaedt/generic/DataHandlers.py index 0d266ba029c..570aaa92b6e 100644 --- a/pyaedt/generic/DataHandlers.py +++ b/pyaedt/generic/DataHandlers.py @@ -101,12 +101,12 @@ def _dict2arg(d, arg_out): arg = ["NAME:" + k] _dict2arg(el, arg) arg_out.append(arg) - elif type(v) is list and len(v) > 0 and all(isinstance(n, int) for n in v): + elif isinstance(v,list) and len(v) > 0 and all(isinstance(n, int) for n in v): arg = ["NAME:" + k] for el in v: arg.append(el) arg_out.append(arg) - elif type(v) is list and len(v) > 0 and all(isinstance(n, float) for n in v): + elif isinstance(v, list) and len(v) > 0 and all(isinstance(n, float) for n in v): arg = ["NAME:" + k] for el in v: arg.append(el) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index b39cb10ab24..60ac2599f62 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2102,16 +2102,16 @@ def set_electrical_steel_coreloss_at_frequency( ---------- kdc : float Coefficient considering the DC flux bias effects - cut_depth : str + cut_depth : str, optional Equivalent cut depth. You use this parameter to consider the manufacturing effects on core loss computation. The default value is ``"1mm"``. - thickness : str + thickness : str, optional Thickness specified in terms of the value plus the unit. The default is ``"0.5mm"``. - conductivity : float + conductivity : float, optional Conductivity. The unit is S/m. - The default is ``"0S/m"``. + The default is ``"0 S/m"``. coefficient_setup : str, optional Core loss unit. The default is ``"w_per_cubic_meter"``. Options are ``"kw_per_cubic_meter"``, ``"w_per_cubic_meter"``, ``"w_per_kg"``, From b443b0d25cc484befdd470f5c664a96a0b7519d1 Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Wed, 22 Nov 2023 08:55:09 +0100 Subject: [PATCH 21/26] fix comments review --- _unittest/test_03_Materials.py | 83 ++++++++++++++++++++++++++++--- pyaedt/modules/Material.py | 89 ++++++++++++++++++++++------------ 2 files changed, 135 insertions(+), 37 deletions(-) diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py index 0cbe56639b5..3356daee22f 100644 --- a/_unittest/test_03_Materials.py +++ b/_unittest/test_03_Materials.py @@ -277,15 +277,30 @@ def test_13_get_materials_in_project(self): def test_14_get_coreloss_coefficients(self): mat = self.aedtapp.materials.add_material("mat_test") + # Test points_list_at_freq coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]} ) assert isinstance(coeff, list) assert len(coeff) == 3 assert all(isinstance(c, float) for c in coeff) - assert not self.aedtapp.materials["mat_test"].get_core_loss_coefficients( - points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]] + coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( + points_list_at_freq={"60Hz": [[0, 0], [1, 3.5], [2, 7.4]]} ) + assert isinstance(coeff, list) + assert len(coeff) == 3 + assert all(isinstance(c, float) for c in coeff) + coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( + points_list_at_freq={"0.06kHz": [[0, 0], [1, 3.5], [2, 7.4]]} + ) + assert isinstance(coeff, list) + assert len(coeff) == 3 + assert all(isinstance(c, float) for c in coeff) + try: + self.aedtapp.materials["mat_test"].get_core_loss_coefficients(points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]]) + assert False + except TypeError: + assert True coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( points_list_at_freq={ 60: [[0, 0], [1, 3.5], [2, 7.4]], @@ -296,19 +311,75 @@ def test_14_get_coreloss_coefficients(self): assert isinstance(coeff, list) assert len(coeff) == 3 assert all(isinstance(c, float) for c in coeff) + # Test thickness + coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, + thickness="0.6mm" + ) + assert isinstance(coeff, list) + assert len(coeff) == 3 + assert all(isinstance(c, float) for c in coeff) + try: + coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, + thickness="invalid" + ) + assert False + except TypeError: + assert True + try: + coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, + thickness=50 + ) + assert False + except TypeError: + assert True def test_14_set_core_loss(self): mat = self.aedtapp.materials["mat_test"] - assert self.aedtapp.materials["mat_test"].set_electrical_steel_coreloss_at_frequency( + # Test points_list_at_freq + assert self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]} ) - assert not self.aedtapp.materials["mat_test"].set_electrical_steel_coreloss_at_frequency( - points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]] + assert self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( + points_list_at_freq={"60Hz": [[0, 0], [1, 3.5], [2, 7.4]]} ) - assert self.aedtapp.materials["mat_test"].set_electrical_steel_coreloss_at_frequency( + assert self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( + points_list_at_freq={"0.06kHz": [[0, 0], [1, 3.5], [2, 7.4]]} + ) + try: + self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( + points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]]) + assert False + except TypeError: + assert True + assert self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( points_list_at_freq={ 60: [[0, 0], [1, 3.5], [2, 7.4]], 100: [[0, 0], [1, 8], [2, 9]], 150: [[0, 0], [1, 10], [2, 19]], } ) + # Test thickness + assert self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, + thickness="0.6mm" + ) + try: + coeff = self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, + thickness="invalid" + ) + assert False + except TypeError: + assert True + try: + coeff = self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, + thickness=50 + ) + assert False + except TypeError: + assert True + diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 60ac2599f62..b3e89986ea9 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -14,12 +14,12 @@ """ from collections import OrderedDict import copy -import itertools import warnings +from pyaedt.application.Variables import decompose_variable_value from pyaedt.generic.DataHandlers import _dict2arg -from pyaedt.generic.constants import CSS4_COLORS -from pyaedt.generic.general_methods import pyaedt_function_handler +from pyaedt.generic.constants import CSS4_COLORS, unit_converter +from pyaedt.generic.general_methods import pyaedt_function_handler, is_number class MatProperties(object): @@ -2001,7 +2001,7 @@ def get_core_loss_coefficients( conductivity=0, coefficient_setup="w_per_cubic_meter", ): - """Compute core loss coefficients from the loss characteristics (BP curve) at a given frequency. + """Get electrical steel or power ferrite core loss coefficients from the loss characteristics (BP curve) at a given frequency. Parameters ---------- @@ -2048,28 +2048,44 @@ def get_core_loss_coefficients( >>> m3d.release_desktop(True, True) """ if not isinstance(points_list_at_freq, dict): - self.logger.error("Points list at frequency must be provided as a dictionary.") - return False + raise TypeError("Points list at frequency must be provided as a dictionary.") + if not isinstance(thickness, str): + raise TypeError("Thickness must be provided as a string with value and unit.") + else: + value, unit = decompose_variable_value(thickness) + if not is_number(value) and not unit: + raise TypeError("Thickness must be provided as a string with value and unit.") props = OrderedDict({}) - if len(points_list_at_freq.keys()) == 1: + freq_keys = list(points_list_at_freq.keys()) + for i in range(0, len(freq_keys)): + if isinstance(freq_keys[i], str): + value, unit = decompose_variable_value(freq_keys[i]) + if unit != "Hz": + value = unit_converter(values=value, unit_system="Freq", input_units=unit, + output_units="Hz") + points_list_at_freq[value] = points_list_at_freq[freq_keys[i]] + del points_list_at_freq[freq_keys[i]] + freq_keys = list(points_list_at_freq.keys()) + + if len(freq_keys) == 1: props["CoefficientSetupData"] = OrderedDict({}) props["CoefficientSetupData"]["property_data"] = "coreloss_data" props["CoefficientSetupData"]["coefficient_setup"] = coefficient_setup - frequency = list(points_list_at_freq.keys())[0] + frequency = freq_keys[0] props["CoefficientSetupData"]["Frequency"] = "{}Hz".format(frequency) props["CoefficientSetupData"]["Thickness"] = thickness props["CoefficientSetupData"]["Conductivity"] = str(conductivity) - points = list(itertools.chain(*[v for v in list(points_list_at_freq.values())[0]])) + points = [i for p in points_list_at_freq[frequency] for i in p] props["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], "Points": points}) - elif len(points_list_at_freq.keys()) > 1: + elif len(freq_keys) > 1: props["CoreLossMultiCurveData"] = OrderedDict({}) props["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" props["CoreLossMultiCurveData"]["coreloss_unit"] = "w_per_cubic_meter" props["CoreLossMultiCurveData"]["AllCurves"] = OrderedDict({}) props["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = [] - for freq in list(points_list_at_freq.keys()): - points = list(itertools.chain(*[v for v in points_list_at_freq[freq]])) + for freq in list(freq_keys): + points = [i for p in points_list_at_freq[freq] for i in p] one_curve = OrderedDict( { "Frequency": "{}Hz".format(freq), @@ -2078,7 +2094,7 @@ def get_core_loss_coefficients( ) props["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"].append(one_curve) - props = args = self._get_args(props) + props = self._get_args(props) props.pop(0) coefficients = self.odefinition_manager.ComputeCoreLossCoefficients( core_loss_model_type, self.mass_density.evaluated_value, props[0] @@ -2086,20 +2102,25 @@ def get_core_loss_coefficients( return coefficients @pyaedt_function_handler() - def set_electrical_steel_coreloss_at_frequency( + def set_coreloss_at_frequency( self, + points_list_at_freq, kdc=0, cut_depth="1mm", thickness="0.5mm", conductivity=0, coefficient_setup="w_per_cubic_meter", core_loss_model_type="Electrical Steel", - points_list_at_freq={}, ): - """Set electrical steel core loss model at one single frequency or at multiple frequencies. + """Set electrical steel or power ferrite core loss model at one single frequency or at multiple frequencies. Parameters ---------- + points_list_at_freq : dict + Dictionary where keys are the frequencies (in Hz) and values are lists of points (BP curve). + If the core loss model is calculated at one frequency, this parameter must be provided as a + dictionary with one key (single frequency in Hz) and values are lists of points at + that specific frequency (BP curve). kdc : float Coefficient considering the DC flux bias effects cut_depth : str, optional @@ -2116,11 +2137,9 @@ def set_electrical_steel_coreloss_at_frequency( Core loss unit. The default is ``"w_per_cubic_meter"``. Options are ``"kw_per_cubic_meter"``, ``"w_per_cubic_meter"``, ``"w_per_kg"``, and ``"w_per_lb"``. - points_list_at_freq : dict - Dictionary where keys are the frequencies (in Hz) and values are lists of points (BP curve). - If the core loss model is calculated at one frequency, this parameter must be provided as a - dictionary with one key (single frequency in Hz) and values are lists of points at - that specific frequency (BP curve). + core_loss_model_type : str, optional + Core loss model type. The default value is ``"Electrical Steel"``. + Options are ``"Electrical Steel"`` and ``"Power Ferrite"``. Returns ------- @@ -2135,7 +2154,7 @@ def set_electrical_steel_coreloss_at_frequency( Examples -------- This example shows how to set a core loss model for a material in case material properties are calculated for - core losses at one frequency or core losses versus frequencies (core losses multi curve data). + core losses at one frequency or core losses versus frequencies (core losses multicurve data). The first case shows how to set properties for core losses at one frequency: >>> from pyaedt import Maxwell3d @@ -2162,8 +2181,17 @@ def set_electrical_steel_coreloss_at_frequency( """ if not isinstance(points_list_at_freq, dict): - self.logger.error("Points list at frequencies must be provided as a list of dictionaries.") - return False + raise TypeError("Points list at frequency must be provided as a dictionary.") + freq_keys = list(points_list_at_freq.keys()) + for i in range(0, len(freq_keys)): + if isinstance(freq_keys[i], str): + value, unit = decompose_variable_value(freq_keys[i]) + if unit != "Hz": + value = unit_converter(values=value, unit_system="Freq", input_units=unit, + output_units="Hz") + points_list_at_freq[value] = points_list_at_freq[freq_keys[i]] + del points_list_at_freq[freq_keys[i]] + freq_keys = list(points_list_at_freq.keys()) if "core_loss_type" not in self._props: self._props["core_loss_type"] = OrderedDict( {"property_type": "ChoiceProperty", "Choice": "Electrical Steel"} @@ -2177,28 +2205,27 @@ def set_electrical_steel_coreloss_at_frequency( self._props.pop("core_loss_hkc", None) self._props.pop("core_loss_curves", None) self._props["core_loss_type"]["Choice"] = core_loss_model_type - if len(points_list_at_freq.keys()) == 1: + if len(freq_keys) == 1: self._props["AttachedData"]["CoefficientSetupData"] = OrderedDict({}) self._props["AttachedData"]["CoefficientSetupData"]["property_data"] = "coreloss_data" self._props["AttachedData"]["CoefficientSetupData"]["coefficient_setup"] = coefficient_setup - frequency = list(points_list_at_freq.keys())[0] + frequency = freq_keys[0] self._props["AttachedData"]["CoefficientSetupData"]["Frequency"] = "{}Hz".format(frequency) self._props["AttachedData"]["CoefficientSetupData"]["Thickness"] = thickness self._props["AttachedData"]["CoefficientSetupData"]["Conductivity"] = str(conductivity) - - points = list(itertools.chain(*[v for v in list(points_list_at_freq.values())[0]])) + points = [i for p in points_list_at_freq[frequency] for i in p] self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"] = OrderedDict( {"DimUnits": ["", ""], "Points": points} ) - elif len(points_list_at_freq.keys()) > 1: + elif len(freq_keys) > 1: self._props["AttachedData"]["CoreLossMultiCurveData"] = OrderedDict({}) self._props["AttachedData"]["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" self._props["AttachedData"]["CoreLossMultiCurveData"]["coreloss_unit"] = "w_per_cubic_meter" self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"] = OrderedDict({}) self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = [] - for freq in list(points_list_at_freq.keys()): - points = list(itertools.chain(*[v for v in points_list_at_freq[freq]])) + for freq in freq_keys: + points = [i for p in points_list_at_freq[freq] for i in p] one_curve = OrderedDict( { "Frequency": "{}Hz".format(freq), From 31c672a5ca51000566d418f04da9df827f524e71 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 22 Nov 2023 07:59:22 +0000 Subject: [PATCH 22/26] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- _unittest/test_03_Materials.py | 26 +++++++++++--------------- pyaedt/generic/DataHandlers.py | 2 +- pyaedt/modules/Material.py | 12 ++++++------ 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py index 3356daee22f..1ab01ec52f3 100644 --- a/_unittest/test_03_Materials.py +++ b/_unittest/test_03_Materials.py @@ -297,7 +297,9 @@ def test_14_get_coreloss_coefficients(self): assert len(coeff) == 3 assert all(isinstance(c, float) for c in coeff) try: - self.aedtapp.materials["mat_test"].get_core_loss_coefficients(points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]]) + self.aedtapp.materials["mat_test"].get_core_loss_coefficients( + points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]] + ) assert False except TypeError: assert True @@ -313,24 +315,21 @@ def test_14_get_coreloss_coefficients(self): assert all(isinstance(c, float) for c in coeff) # Test thickness coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( - points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, - thickness="0.6mm" + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, thickness="0.6mm" ) assert isinstance(coeff, list) assert len(coeff) == 3 assert all(isinstance(c, float) for c in coeff) try: coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( - points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, - thickness="invalid" + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, thickness="invalid" ) assert False except TypeError: assert True try: coeff = self.aedtapp.materials["mat_test"].get_core_loss_coefficients( - points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, - thickness=50 + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, thickness=50 ) assert False except TypeError: @@ -350,7 +349,8 @@ def test_14_set_core_loss(self): ) try: self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( - points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]]) + points_list_at_freq=[[0, 0], [1, 3.5], [2, 7.4]] + ) assert False except TypeError: assert True @@ -363,23 +363,19 @@ def test_14_set_core_loss(self): ) # Test thickness assert self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( - points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, - thickness="0.6mm" + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, thickness="0.6mm" ) try: coeff = self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( - points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, - thickness="invalid" + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, thickness="invalid" ) assert False except TypeError: assert True try: coeff = self.aedtapp.materials["mat_test"].set_coreloss_at_frequency( - points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, - thickness=50 + points_list_at_freq={60: [[0, 0], [1, 3.5], [2, 7.4]]}, thickness=50 ) assert False except TypeError: assert True - diff --git a/pyaedt/generic/DataHandlers.py b/pyaedt/generic/DataHandlers.py index 570aaa92b6e..d036982da25 100644 --- a/pyaedt/generic/DataHandlers.py +++ b/pyaedt/generic/DataHandlers.py @@ -101,7 +101,7 @@ def _dict2arg(d, arg_out): arg = ["NAME:" + k] _dict2arg(el, arg) arg_out.append(arg) - elif isinstance(v,list) and len(v) > 0 and all(isinstance(n, int) for n in v): + elif isinstance(v, list) and len(v) > 0 and all(isinstance(n, int) for n in v): arg = ["NAME:" + k] for el in v: arg.append(el) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index b3e89986ea9..7a8ead19756 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -18,8 +18,10 @@ from pyaedt.application.Variables import decompose_variable_value from pyaedt.generic.DataHandlers import _dict2arg -from pyaedt.generic.constants import CSS4_COLORS, unit_converter -from pyaedt.generic.general_methods import pyaedt_function_handler, is_number +from pyaedt.generic.constants import CSS4_COLORS +from pyaedt.generic.constants import unit_converter +from pyaedt.generic.general_methods import is_number +from pyaedt.generic.general_methods import pyaedt_function_handler class MatProperties(object): @@ -2061,8 +2063,7 @@ def get_core_loss_coefficients( if isinstance(freq_keys[i], str): value, unit = decompose_variable_value(freq_keys[i]) if unit != "Hz": - value = unit_converter(values=value, unit_system="Freq", input_units=unit, - output_units="Hz") + value = unit_converter(values=value, unit_system="Freq", input_units=unit, output_units="Hz") points_list_at_freq[value] = points_list_at_freq[freq_keys[i]] del points_list_at_freq[freq_keys[i]] freq_keys = list(points_list_at_freq.keys()) @@ -2187,8 +2188,7 @@ def set_coreloss_at_frequency( if isinstance(freq_keys[i], str): value, unit = decompose_variable_value(freq_keys[i]) if unit != "Hz": - value = unit_converter(values=value, unit_system="Freq", input_units=unit, - output_units="Hz") + value = unit_converter(values=value, unit_system="Freq", input_units=unit, output_units="Hz") points_list_at_freq[value] = points_list_at_freq[freq_keys[i]] del points_list_at_freq[freq_keys[i]] freq_keys = list(points_list_at_freq.keys()) From 9442f012208ba4eb6b2b90401842f3b92af3775a Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Wed, 22 Nov 2023 10:55:21 +0100 Subject: [PATCH 23/26] fix comments review --- pyaedt/modules/Material.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index b3e89986ea9..52c5497cf4d 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2065,26 +2065,25 @@ def get_core_loss_coefficients( output_units="Hz") points_list_at_freq[value] = points_list_at_freq[freq_keys[i]] del points_list_at_freq[freq_keys[i]] - freq_keys = list(points_list_at_freq.keys()) - if len(freq_keys) == 1: + if len(points_list_at_freq) == 1: props["CoefficientSetupData"] = OrderedDict({}) props["CoefficientSetupData"]["property_data"] = "coreloss_data" props["CoefficientSetupData"]["coefficient_setup"] = coefficient_setup - frequency = freq_keys[0] + frequency = list(points_list_at_freq.keys())[0] props["CoefficientSetupData"]["Frequency"] = "{}Hz".format(frequency) props["CoefficientSetupData"]["Thickness"] = thickness props["CoefficientSetupData"]["Conductivity"] = str(conductivity) points = [i for p in points_list_at_freq[frequency] for i in p] props["CoefficientSetupData"]["Coordinates"] = OrderedDict({"DimUnits": ["", ""], "Points": points}) - elif len(freq_keys) > 1: + elif len(points_list_at_freq) > 1: props["CoreLossMultiCurveData"] = OrderedDict({}) props["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" props["CoreLossMultiCurveData"]["coreloss_unit"] = "w_per_cubic_meter" props["CoreLossMultiCurveData"]["AllCurves"] = OrderedDict({}) props["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = [] - for freq in list(freq_keys): + for freq in points_list_at_freq.keys(): points = [i for p in points_list_at_freq[freq] for i in p] one_curve = OrderedDict( { @@ -2191,7 +2190,6 @@ def set_coreloss_at_frequency( output_units="Hz") points_list_at_freq[value] = points_list_at_freq[freq_keys[i]] del points_list_at_freq[freq_keys[i]] - freq_keys = list(points_list_at_freq.keys()) if "core_loss_type" not in self._props: self._props["core_loss_type"] = OrderedDict( {"property_type": "ChoiceProperty", "Choice": "Electrical Steel"} @@ -2205,11 +2203,11 @@ def set_coreloss_at_frequency( self._props.pop("core_loss_hkc", None) self._props.pop("core_loss_curves", None) self._props["core_loss_type"]["Choice"] = core_loss_model_type - if len(freq_keys) == 1: + if len(points_list_at_freq) == 1: self._props["AttachedData"]["CoefficientSetupData"] = OrderedDict({}) self._props["AttachedData"]["CoefficientSetupData"]["property_data"] = "coreloss_data" self._props["AttachedData"]["CoefficientSetupData"]["coefficient_setup"] = coefficient_setup - frequency = freq_keys[0] + frequency = list(points_list_at_freq.keys())[0] self._props["AttachedData"]["CoefficientSetupData"]["Frequency"] = "{}Hz".format(frequency) self._props["AttachedData"]["CoefficientSetupData"]["Thickness"] = thickness self._props["AttachedData"]["CoefficientSetupData"]["Conductivity"] = str(conductivity) @@ -2217,14 +2215,14 @@ def set_coreloss_at_frequency( self._props["AttachedData"]["CoefficientSetupData"]["Coordinates"] = OrderedDict( {"DimUnits": ["", ""], "Points": points} ) - elif len(freq_keys) > 1: + elif len(points_list_at_freq) > 1: self._props["AttachedData"]["CoreLossMultiCurveData"] = OrderedDict({}) self._props["AttachedData"]["CoreLossMultiCurveData"]["property_data"] = "coreloss_multi_curve_data" self._props["AttachedData"]["CoreLossMultiCurveData"]["coreloss_unit"] = "w_per_cubic_meter" self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"] = OrderedDict({}) self._props["AttachedData"]["CoreLossMultiCurveData"]["AllCurves"]["OneCurve"] = [] - for freq in freq_keys: + for freq in points_list_at_freq.keys(): points = [i for p in points_list_at_freq[freq] for i in p] one_curve = OrderedDict( { From 3039939bbee71dd3b5e758e1db846f4bb0f8e34e Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Thu, 23 Nov 2023 09:17:29 +0100 Subject: [PATCH 24/26] fix docstring --- pyaedt/modules/Material.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 8c72c562536..2d9b4d3a0d3 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2003,7 +2003,7 @@ def get_core_loss_coefficients( conductivity=0, coefficient_setup="w_per_cubic_meter", ): - """Get electrical steel or power ferrite core loss coefficients from the loss characteristics (BP curve) at a given frequency. + """Get electrical steel or power ferrite core loss coefficients at a given frequency. Parameters ---------- From 52b3e633e4c83f39cc5f629f1c5264e426b08ff5 Mon Sep 17 00:00:00 2001 From: Samuelopez-ansys Date: Thu, 23 Nov 2023 15:13:19 +0100 Subject: [PATCH 25/26] Fix return list --- pyaedt/modules/Material.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 2d9b4d3a0d3..da72124123f 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -2099,7 +2099,7 @@ def get_core_loss_coefficients( coefficients = self.odefinition_manager.ComputeCoreLossCoefficients( core_loss_model_type, self.mass_density.evaluated_value, props[0] ) - return coefficients + return list(coefficients) @pyaedt_function_handler() def set_coreloss_at_frequency( From 0baae87e0a604b2737e4407193f9c4e8ba318515 Mon Sep 17 00:00:00 2001 From: Giulia Malinverno Date: Thu, 23 Nov 2023 17:30:09 +0100 Subject: [PATCH 26/26] fix regression error --- _unittest/test_03_Materials.py | 2 +- pyaedt/generic/DataHandlers.py | 10 ---------- pyaedt/modules/Material.py | 5 ++++- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py index 1ab01ec52f3..16e15f4df48 100644 --- a/_unittest/test_03_Materials.py +++ b/_unittest/test_03_Materials.py @@ -210,7 +210,7 @@ def test_08B_import_materials_from_excel(self): assert len(mats) == 2 def test_09_non_linear_materials(self, add_app): - app = add_app(application=Maxwell3d) + app = add_app(application=Maxwell3d, solution_type="Transient") mat1 = app.materials.add_material("myMat") mat1.permeability = [[0, 0], [1, 12], [10, 30]] mat1.permittivity = [[0, 0], [2, 12], [10, 30]] diff --git a/pyaedt/generic/DataHandlers.py b/pyaedt/generic/DataHandlers.py index d036982da25..8b6568163de 100644 --- a/pyaedt/generic/DataHandlers.py +++ b/pyaedt/generic/DataHandlers.py @@ -101,16 +101,6 @@ def _dict2arg(d, arg_out): arg = ["NAME:" + k] _dict2arg(el, arg) arg_out.append(arg) - elif isinstance(v, list) and len(v) > 0 and all(isinstance(n, int) for n in v): - arg = ["NAME:" + k] - for el in v: - arg.append(el) - arg_out.append(arg) - elif isinstance(v, list) and len(v) > 0 and all(isinstance(n, float) for n in v): - arg = ["NAME:" + k] - for el in v: - arg.append(el) - arg_out.append(arg) else: arg_out.append(k + ":=") diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index da72124123f..14940bb3e18 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -1160,7 +1160,7 @@ def _get_args(self, props=None): Parameters ---------- - prop : str, optional + props : str, optional Name of the property. The default is ``None``. """ if not props: @@ -2096,6 +2096,9 @@ def get_core_loss_coefficients( props = self._get_args(props) props.pop(0) + props[0][-1][2] = "NAME:Points" + points = props[0][-1].pop(2) + props[0][-1][2].insert(0, points) coefficients = self.odefinition_manager.ComputeCoreLossCoefficients( core_loss_model_type, self.mass_density.evaluated_value, props[0] )