diff --git a/materialdatabase/__init__.py b/materialdatabase/__init__.py index 15d1206..4e818db 100644 --- a/materialdatabase/__init__.py +++ b/materialdatabase/__init__.py @@ -1,3 +1,4 @@ +"""init.py.""" from materialdatabase.material_data_base_functions import * from materialdatabase.material_data_base_classes import * from materialdatabase.enumerations import * diff --git a/materialdatabase/constants.py b/materialdatabase/constants.py index bd0c66e..ded7afb 100644 --- a/materialdatabase/constants.py +++ b/materialdatabase/constants.py @@ -1,3 +1,4 @@ +"""Constants.""" import numpy as np # vacuum permeability diff --git a/materialdatabase/dtos.py b/materialdatabase/dtos.py index 55eb01e..f3066ee 100644 --- a/materialdatabase/dtos.py +++ b/materialdatabase/dtos.py @@ -1,3 +1,4 @@ +"""Dataclass for storing material curves.""" from dataclasses import dataclass import numpy as np @@ -10,6 +11,7 @@ class MaterialCurve: This dataclass can be loaded into a calculation, by only choosing the material. All other parameters are bound to this material. """ + material_name: str material_mu_r_abs: float material_flux_density_vec: np.ndarray diff --git a/materialdatabase/enumerations.py b/materialdatabase/enumerations.py index 46e965f..b5a75df 100644 --- a/materialdatabase/enumerations.py +++ b/materialdatabase/enumerations.py @@ -1,26 +1,27 @@ +"""Enumerations for easier usage.""" from enum import Enum # Following Enums must always be consistent with the FEM Magnetics Toolbox (FEMMT) class MaterialDataSource(str, Enum): - """Sets the source from where data is taken. - """ + """Sets the source from where data is taken.""" + Custom = "custom" Measurement = "measurements" ManufacturerDatasheet = "manufacturer_datasheet" class MeasurementSetup(str, Enum): - """Sets the source from where data is taken. - """ + """Sets the setup of the measurement.""" + LEA_MTB = "LEA_MTB" LEA_MTB_small_signal = "LEA_MTB_small_signal" LEA_LK = "LEA_LK" class MeasurementMethod(str, Enum): - """Sets the source from where data is taken. - """ + """Sets the method of the measurement.""" + ImpedanceAnalyzer = "Impedance Analyzer" Calorimetric = "Calorimetric" Electric = "Electric" @@ -29,14 +30,14 @@ class MeasurementMethod(str, Enum): class Company(str, Enum): - """Sets the source from where data is taken. - """ + """Sets the name of the company.""" + UPB = "Paderborn University" class Manufacturer(str, Enum): - """Sets the source from where data is taken. - """ + """Sets the name of the manufacturer.""" + TDK = "TDK" Ferroxcube = "Ferroxcube" DMEGC = "DMEGC" @@ -44,24 +45,23 @@ class Manufacturer(str, Enum): class MeasurementDataType(str, Enum): - """Sets the type of measurement data. - """ + """Sets the type of the measurement data.""" + ComplexPermeability = "complex_permeability" ComplexPermittivity = "complex_permittivity" Steinmetz = "Steinmetz" class MeasurementDevice(str, Enum): - """Sets the type of Measurement Device - """ + """Sets the type of the measurement device.""" + lecroy = "LeCroy_HDO4104" wayne_kerr = "Wayne_Kerr_6500B" zimmer = "ZES_Zimmer_LMG640" class PlotLabels(str, Enum): - """Labels for possible plots - """ + """Labels for axes of possible plots.""" time = "time in s" time_ms = "time in ms" @@ -71,16 +71,20 @@ class PlotLabels(str, Enum): frequency_kHz = "frequency in kHz" frequency_MHz = "frequency in MHz" - powerloss_density = r"powerloss density in mW/cm^3" + powerloss_density_mW = r"powerloss density in mW/cm^3" + powerloss_density_kW = r"powerloss density in kW/m^3" h_field = "magnetic field strength in A/m" b_field = "magnetic flux density in T" e_field = "electric field strength in V/m" d_field = r"electric flux density in As/m^2" - current = "voltage in V" - voltage = "current in A" - power = "power in W" + current_A = "voltage in A" + current_mA = "voltage in mA" + voltage_V = "current in V" + voltage_mV = "current in mV" + power_W = "power in W" + power_mW = "power in mW" mu_ampl = r"rel. permeability amplitude $\mu_\mathrm{r}}$" mu_angle = r"rel. permeability angle $\mu_\mathrm{r}}$ in degree" @@ -89,8 +93,8 @@ class PlotLabels(str, Enum): class CuboidCodeNames(str, Enum): - """Probe Codes of Permittivity Measurement Probe - """ + """Probe-Codes of permittivity measurement probes.""" + # 3F46 D966 = "C25,16x2,04x15,55" T227 = "C25,05x4,05x15,78" @@ -113,12 +117,13 @@ class CuboidCodeNames(str, Enum): @classmethod def has_member_key(cls, key): + """Check if key is part of class.""" return key in cls.__members__ class ToroidCodeNames(str, Enum): - """Probe Codes of Permeability Measurement Probe - """ + """Probe-Codes of permeability measurement probes.""" + # 3F46 A461 = "R36x32x16" C293 = "R24x18x15" @@ -137,12 +142,12 @@ class ToroidCodeNames(str, Enum): @classmethod def has_member_key(cls, key): + """Check if key is part of class.""" return key in cls.__members__ class Material(str, Enum): - """Sets the name of the core material as enums. - """ + """Sets the name of the core material as enums.""" TEST = "TEST" # FOR TESTING STUFF _3F46 = "3F46" @@ -158,20 +163,24 @@ class Material(str, Enum): class ToroidDirectoryName(str, Enum): - """Sets the type of Permeability Measurement Probe + """ + Sets the type of Permeability Measurement Probe. + d_out: outer diameter of toroid in mm d_in: innter diameter of toroid in mm h: height of toroid in mm N1: primary turns number N2: secondary turns number """ + N87_1 = "R24,6x20,25x20,5_A00" DMR96A_1 = '???' DMR96A_2 = 'R_25.0x21.0x15.0x4x4' class CuboidDirectoryName(str, Enum): - """Sets the type of Permittivity Measurement Probe + """ + Sets the type of Permittivity Measurement Probe. string with: a x b x c @@ -182,14 +191,17 @@ class CuboidDirectoryName(str, Enum): (a and b can be exchanged, because A = a*b) """ + _3F46_thin = "C_25.16x2.04x15.55" DMR96A_2 = "C_25x2x15" # DMR96A_2 = 'R_25.0x21.0x15.0x4x4' class HeaderMeasurementData(str, Enum): - """Names for the header of the dataframes for the post-processing data - e.g. data of the permeability angle gets the header "permeability angle" + """ + Names for the header of the dataframes for the post-processing files(Magnetic-TestBench). + + e.g. data of the permeability angle gets the header "permeability angle" """ frequency = "frequency" @@ -210,17 +222,29 @@ class HeaderMeasurementData(str, Enum): permittivity_angle = "permittivity angle" self_inductance = "self inductance" - prim_leakage_inductance = "primary leakage inductance" - sec_leakage_inductance = "secondary leakage inductance" + prim_leak_inductance = "primary leakage inductance" + sec_leak_inductance = "secondary leakage inductance" voltage = "voltage" current = "current" power = "power" + impedance_ampl = "impedance amplitude" + impedance_angle = "impedance angle" + + impedance_ampl_prim_open = "primary open impedance amplitude" + impedance_angle_prim_open = "primary open impedance angle" + + impedance_ampl_prim_short = "primary short impedance amplitude" + impedance_angle_prim_short = "primary short impedance angle" + + impedance_ampl_sec_open = "secondary open impedance amplitude" + impedance_angle_sec_open = "secondary open impedance angle" + class ProbeDimensions(str, Enum): - """Sets the name for the dimensions of a probe - """ + """Sets the name for the dimensions of a probe.""" + height = "height" cross_section = "cross section" volume = "volume" @@ -234,4 +258,4 @@ class ProbeDimensions(str, Enum): prim_winding = "primary winding" sec_winding = "secondary winding" - l_mag = "l_mag" + l_mag = "lmag" diff --git a/materialdatabase/helper_functions/get_permeability_data_from_LEA_LK.py b/materialdatabase/helper_functions/get_permeability_data_from_LEA_LK.py index 08f43b0..abe65e3 100644 --- a/materialdatabase/helper_functions/get_permeability_data_from_LEA_LK.py +++ b/materialdatabase/helper_functions/get_permeability_data_from_LEA_LK.py @@ -1,3 +1,4 @@ +"""Script to get permeability data by LEA_LK.""" from materialdatabase.material_data_base_functions import * location = "C:/Users/tpiepe/sciebo/Exchange_FEMMT/05_Materials/data/2022_10_10_Ferrite_mu_eps_Data_Keuck/" @@ -9,5 +10,4 @@ b_ref, mu_r, mu_phi_deg = get_permeability_data_from_lea_lk(location, f, T, "N49") - b_ref, mu_r, mu_phi_deg = process_permeability_data(b_ref, mu_r, mu_phi_deg, - smooth_data=True, crop_data=False, plot_data=True) + b_ref, mu_r, mu_phi_deg = process_permeability_data(b_ref, mu_r, mu_phi_deg, smooth_data=True, crop_data=False, plot_data=True) diff --git a/materialdatabase/helper_functions/get_property_from_LEA_LK.py b/materialdatabase/helper_functions/get_property_from_LEA_LK.py index 1d41f3c..a96084b 100644 --- a/materialdatabase/helper_functions/get_property_from_LEA_LK.py +++ b/materialdatabase/helper_functions/get_property_from_LEA_LK.py @@ -1,3 +1,4 @@ +"""Script to get the property from LEA_LK.""" from materialdatabase.material_data_base_functions import * from matplotlib import pyplot as plt from scipy.signal import savgol_filter as savgol @@ -8,10 +9,10 @@ print(filename) for f in [200000, 300000]: - b_hys, p_hys = get_permeability_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="Core_Loss", - quantity="p_hys", frequency=f, material_name="N49", temperature=30) - b_phi, mu_phi_deg = get_permeability_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="mu_phi_Plot", - quantity="mu_phi", frequency=f, material_name="N49", temperature=30) + b_hys, p_hys = get_permeability_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="Core_Loss", quantity="p_hys", frequency=f, + material_name="N49", temperature=30) + b_phi, mu_phi_deg = get_permeability_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="mu_phi_Plot", quantity="mu_phi", frequency=f, + material_name="N49", temperature=30) if len(b_phi) != len(b_hys): print("invalid") break diff --git a/materialdatabase/material_data_base_classes.py b/materialdatabase/material_data_base_classes.py index 57cb628..e347ff4 100644 --- a/materialdatabase/material_data_base_classes.py +++ b/materialdatabase/material_data_base_classes.py @@ -1,3 +1,4 @@ +"""Class of the material database.""" # Python integrated libraries import logging @@ -13,6 +14,7 @@ class MaterialDatabase: """ This class manages the data stored in the material database. + It has the possibility to export for example soft magnetic materials' loss data in certain format, so that it can easily be interfaced by tools like the FEM Magnetic Toolbox. """ @@ -20,9 +22,14 @@ class MaterialDatabase: silent: bool = False def __init__(self, is_silent: bool = False, logging_file: str = ""): - """Constructor for MaterialDatabase. If is_silent is true nothing will be printet. If a logging_file is set the prints are written to a file. """ + Construct MaterialDatabase. + + Constructor for MaterialDatabase. If is_silent is true nothing will be printet. If a logging_file is set the prints are written to a file. + :param is_silent: enable/disable of plotting + :param logging_file: path to save the plots + """ self.database_file_directory = 'data/' self.database_file_name = 'material_data_base.json' self.data_folder_path = os.path.join(os.path.dirname(__file__), self.database_file_directory) @@ -43,23 +50,22 @@ def __init__(self, is_silent: bool = False, logging_file: str = ""): self.mdb_print("The material database is now initialized") def mdb_print(self, text: str, end='\n') -> None: - """ - Print function what checks the silent-mode-flag. + r""" + Print function that checks the silent-mode-flag. + Print only in case of no-silent-mode. :param text: Text to print :type text: str :param end: command for end of line, e.g. '\n' or '\t' :type end: str - """ if not self.silent: self.logger.info(f"{text}{end}") - def material_data_interpolation_to_dto(self, material_name: str, fundamental_frequency: float, - temperature: float) -> MaterialCurve: + def material_data_interpolation_to_dto(self, material_name: str, fundamental_frequency: float, temperature: float) -> MaterialCurve: """ - Returns interpolated material data packed into a single DTO for a certain operating point. + Return interpolated material data packed into a single DTO for a certain operating point. :param material_name: material name, e.g. "N95" :type material_name: str @@ -67,31 +73,25 @@ def material_data_interpolation_to_dto(self, material_name: str, fundamental_fre :type fundamental_frequency: float :param temperature: temperature in °C :type temperature: float - """ material_flux_density_vec, material_mu_r_imag_vec, material_mu_r_real_vec = self.permeability_data_to_pro_file( - temperature, fundamental_frequency, material_name, - datasource=MaterialDataSource.ManufacturerDatasheet, - datatype='permeability_data', plot_interpolation=False) - material_mu_r_initial = self.get_material_attribute(material_name=material_name, - attribute="initial_permeability") + temperature, fundamental_frequency, material_name, datasource=MaterialDataSource.ManufacturerDatasheet, datatype='permeability_data', + plot_interpolation=False) + material_mu_r_initial = self.get_material_attribute(material_name=material_name, attribute="initial_permeability") saturation_flux_density = self.get_saturation_flux_density(material_name=material_name) - return MaterialCurve(material_name, material_mu_r_initial, material_flux_density_vec, material_mu_r_imag_vec, - material_mu_r_real_vec, - saturation_flux_density, boundary_frequency=fundamental_frequency, - boundary_temperature=temperature) + return MaterialCurve(material_name, material_mu_r_initial, material_flux_density_vec, material_mu_r_imag_vec, material_mu_r_real_vec, + saturation_flux_density, boundary_frequency=fundamental_frequency, boundary_temperature=temperature) - def permeability_data_to_pro_file(self, temperature: float, frequency: float, material_name: str, - datatype: MeasurementDataType, - datasource: MaterialDataSource = None, measurement_setup: str = None, - parent_directory: str = "", + def permeability_data_to_pro_file(self, temperature: float, frequency: float, material_name: str, datatype: MeasurementDataType, + datasource: MaterialDataSource = None, measurement_setup: str = None, parent_directory: str = "", plot_interpolation: bool = False): """ - Method is used to read permeability data from the material database. + Read permeability data from the material database. + :param plot_interpolation: - :param temperature: temperature - :param frequency: Frequency + :param temperature: temperature in degree + :param frequency: Frequency in Hz :param material_name: "N95","N87".... :param datasource: "measurements" or "manufacturer_datasheet" :param datatype: "complex_permeability", "complex_permittivity" or "Steinmetz" @@ -105,15 +105,13 @@ def permeability_data_to_pro_file(self, temperature: float, frequency: float, ma >>> material_name = "N95", datatype = "complex_permeability", >>> datasource = mdb.MaterialDataSource.ManufacturerDatasheet, parent_directory = "") """ - check_input_permeability_data(datasource, material_name, temperature, frequency) if datasource == MaterialDataSource.Measurement: self.mdb_print(f"{material_name = }\n") self.mdb_print(f"{datatype = }\n") self.mdb_print(f"{measurement_setup = }\n") - permeability_data = self.data[f"{material_name.value}"]["measurements"][f"{datatype.value}"][f"{measurement_setup.value}"][ - "measurement_data"] + permeability_data = self.data[f"{material_name.value}"]["measurements"][f"{datatype.value}"][f"{measurement_setup.value}"]["measurement_data"] # mdb_print(f"{permeability_data = }") # mdb_print(f"{len(permeability_data[1]['b']), len(permeability_data[0]['mu_r']) = }") @@ -123,56 +121,28 @@ def permeability_data_to_pro_file(self, temperature: float, frequency: float, ma # mdb_print(f"{len(nbh['T_low_f_low']['b']), len(nbh['T_low_f_low']['mu_r']) = }") b_ref, mu_r = interpolate_b_dependent_quantity_in_temperature_and_frequency(temperature, frequency, - nbh["T_low_f_low"][ - "temperature"], - nbh["T_high_f_low"][ - "temperature"], - nbh["T_low_f_low"]["frequency"], - nbh["T_low_f_high"][ - "frequency"], - nbh["T_low_f_low"][ - "flux_density"], - nbh["T_low_f_low"]["mu_r_abs"], - nbh["T_high_f_low"][ - "flux_density"], - nbh["T_high_f_low"]["mu_r_abs"], - nbh["T_low_f_high"][ - "flux_density"], - nbh["T_low_f_high"]["mu_r_abs"], - nbh["T_high_f_high"][ - "flux_density"], - nbh["T_high_f_high"][ - "mu_r_abs"], - y_label="rel. amplitude permeability", - plot=plot_interpolation) + nbh["T_low_f_low"]["temperature"], nbh["T_high_f_low"]["temperature"], + nbh["T_low_f_low"]["frequency"], nbh["T_low_f_high"]["frequency"], + nbh["T_low_f_low"]["flux_density"], nbh["T_low_f_low"]["mu_r_abs"], + nbh["T_high_f_low"]["flux_density"], nbh["T_high_f_low"]["mu_r_abs"], + nbh["T_low_f_high"]["flux_density"], nbh["T_low_f_high"]["mu_r_abs"], + nbh["T_high_f_high"]["flux_density"], nbh["T_high_f_high"]["mu_r_abs"], + y_label="rel. amplitude permeability", plot=plot_interpolation) b_ref, mu_phi_deg = interpolate_b_dependent_quantity_in_temperature_and_frequency(temperature, frequency, - nbh["T_low_f_low"][ - "temperature"], - nbh["T_high_f_low"][ - "temperature"], - nbh["T_low_f_low"][ - "frequency"], - nbh["T_low_f_high"][ - "frequency"], - nbh["T_low_f_low"][ - "flux_density"], - nbh["T_low_f_low"][ - "mu_phi_deg"], - nbh["T_high_f_low"][ - "flux_density"], - nbh["T_high_f_low"][ - "mu_phi_deg"], - nbh["T_low_f_high"][ - "flux_density"], - nbh["T_low_f_high"][ - "mu_phi_deg"], - nbh["T_high_f_high"][ - "flux_density"], - nbh["T_high_f_high"][ - "mu_phi_deg"], - y_label="hyst. loss angle in deg", - plot=plot_interpolation) + nbh["T_low_f_low"]["temperature"], + nbh["T_high_f_low"]["temperature"], + nbh["T_low_f_low"]["frequency"], + nbh["T_low_f_high"]["frequency"], + nbh["T_low_f_low"]["flux_density"], + nbh["T_low_f_low"]["mu_phi_deg"], + nbh["T_high_f_low"]["flux_density"], + nbh["T_high_f_low"]["mu_phi_deg"], + nbh["T_low_f_high"]["flux_density"], + nbh["T_low_f_high"]["mu_phi_deg"], + nbh["T_high_f_high"]["flux_density"], + nbh["T_high_f_high"]["mu_phi_deg"], + y_label="hyst. loss angle in deg", plot=plot_interpolation) # mdb_print(f"{b_ref, mu_r, mu_phi_deg = }") @@ -194,64 +164,38 @@ def permeability_data_to_pro_file(self, temperature: float, frequency: float, ma # mdb_print(f"{nbh = }") b_ref, mu_r_real = interpolate_b_dependent_quantity_in_temperature_and_frequency(temperature, frequency, - nbh["T_low_f_low"][ - "temperature"], - nbh["T_high_f_low"][ - "temperature"], - nbh["T_low_f_low"][ - "frequency"], - nbh["T_low_f_high"][ - "frequency"], - nbh["T_low_f_low"][ - "flux_density"], - nbh["T_low_f_low"][ - "mu_r_real"], - nbh["T_high_f_low"][ - "flux_density"], - nbh["T_high_f_low"][ - "mu_r_real"], - nbh["T_low_f_high"][ - "flux_density"], - nbh["T_low_f_high"][ - "mu_r_real"], - nbh["T_high_f_high"][ - "flux_density"], - nbh["T_high_f_high"][ - "mu_r_real"], - plot=plot_interpolation) + nbh["T_low_f_low"]["temperature"], + nbh["T_high_f_low"]["temperature"], + nbh["T_low_f_low"]["frequency"], + nbh["T_low_f_high"]["frequency"], + nbh["T_low_f_low"]["flux_density"], + nbh["T_low_f_low"]["mu_r_real"], + nbh["T_high_f_low"]["flux_density"], + nbh["T_high_f_low"]["mu_r_real"], + nbh["T_low_f_high"]["flux_density"], + nbh["T_low_f_high"]["mu_r_real"], + nbh["T_high_f_high"]["flux_density"], + nbh["T_high_f_high"]["mu_r_real"], plot=plot_interpolation) b_ref, mu_r_imag = interpolate_b_dependent_quantity_in_temperature_and_frequency(temperature, frequency, - nbh["T_low_f_low"][ - "temperature"], - nbh["T_high_f_low"][ - "temperature"], - nbh["T_low_f_low"][ - "frequency"], - nbh["T_low_f_high"][ - "frequency"], - nbh["T_low_f_low"][ - "flux_density"], - nbh["T_low_f_low"][ - "mu_r_imag"], - nbh["T_high_f_low"][ - "flux_density"], - nbh["T_high_f_low"][ - "mu_r_imag"], - nbh["T_low_f_high"][ - "flux_density"], - nbh["T_low_f_high"][ - "mu_r_imag"], - nbh["T_high_f_high"][ - "flux_density"], - nbh["T_high_f_high"][ - "mu_r_imag"], - plot=plot_interpolation) + nbh["T_low_f_low"]["temperature"], + nbh["T_high_f_low"]["temperature"], + nbh["T_low_f_low"]["frequency"], + nbh["T_low_f_high"]["frequency"], + nbh["T_low_f_low"]["flux_density"], + nbh["T_low_f_low"]["mu_r_imag"], + nbh["T_high_f_low"]["flux_density"], + nbh["T_high_f_low"]["mu_r_imag"], + nbh["T_low_f_high"]["flux_density"], + nbh["T_low_f_high"]["mu_r_imag"], + nbh["T_high_f_high"]["flux_density"], + nbh["T_high_f_high"]["mu_r_imag"], plot=plot_interpolation) self.mdb_print(f"{b_ref, mu_r_real, mu_r_imag = }") # Write the .pro-file - export_data(parent_directory=parent_directory, file_format="pro", b_ref_vec=list(b_ref), - mu_r_real_vec=list(mu_r_real), mu_r_imag_vec=list(mu_r_imag), silent=self.silent) + export_data(parent_directory=parent_directory, file_format="pro", b_ref_vec=list(b_ref), mu_r_real_vec=list(mu_r_real), mu_r_imag_vec=list(mu_r_imag), + silent=self.silent) self.mdb_print(f"Material properties of {material_name.value} are loaded at {temperature} °C and {frequency} Hz.") @@ -260,7 +204,8 @@ def permeability_data_to_pro_file(self, temperature: float, frequency: float, ma # --------to get different material property from database file--------- def get_material_attribute(self, material_name: str, attribute: str): """ - Returns a dict of the manufacturer datasheet. + Return a dict of the manufacturer datasheet. + All dicts can be accessed under 'manufacturer_datasheet'. See example below. :param material_name: str: N95,N87..... @@ -271,13 +216,12 @@ def get_material_attribute(self, material_name: str, attribute: str): >>> material_db = mdb.MaterialDatabase(is_silent=True) >>> initial_u_r = material_db.get_material_attribute(material_name="N95", attribute="initial_permeability") """ - value = self.data[f"{material_name.value}"]["manufacturer_datasheet"][f"{attribute}"] return value def get_saturation_flux_density(self, material_name: str): """ - get the saturation flux density for 'material' from datasheet. + Get the saturation flux density for 'material' from datasheet. Function description: * searches for the maximium given temperature in b-h-curve @@ -295,8 +239,7 @@ def get_saturation_flux_density(self, material_name: str): b_h_curve_list = self.get_material_attribute(material_name=material_name, attribute="b_h_curve") b_h_curve_max_temperature = max([b_h_curve["temperature"] for b_h_curve in b_h_curve_list]) - [saturation_flux_density] = [max(b_h_curve["flux_density"]) for b_h_curve in b_h_curve_list if - b_h_curve["temperature"] == b_h_curve_max_temperature] + [saturation_flux_density] = [max(b_h_curve["flux_density"]) for b_h_curve in b_h_curve_list if b_h_curve["temperature"] == b_h_curve_max_temperature] # subtract 10% from saturation flux density saturation_flux_density = 0.9 * saturation_flux_density @@ -306,6 +249,8 @@ def get_saturation_flux_density(self, material_name: str): # ----------to get steinmetz data from database file----------------------- def get_steinmetz_data(self, material_name: str, loss_type: str, datasource: str): """ + Get the coefficients of the Steinmetz-Formula of the database. + :param material_name: material name, e.g. "N95" :param datasource: measurement or datasheet :param loss_type: steinmetz or generalized steinmetz @@ -316,31 +261,34 @@ def get_steinmetz_data(self, material_name: str, loss_type: str, datasource: str if s_data[i]["data_type"] == "steinmetz_data": coefficient = dict(s_data[i]["data"]) else: - raise Exception( - "Error in selecting loss data. 'type' must be 'Steinmetz' or others (will be implemented in future).") + raise Exception("Error in selecting loss data. 'type' must be 'Steinmetz' or others (will be implemented in future).") # elif type == "Generalized_Steinmetz": # coefficient = dict(s_data[f"{material_name.value}"]["generalized_steinmetz_data"]) # mdb_print(coefficient) return coefficient def load_database(self): + """ + Load the database. + + :return: database + """ with open(self.data_file_path, 'r') as database: return json.load(database) - def drop_down_list(self, material_name: str, comparison_type: str, datatype: str, measurement_name: str, - temperature: bool = False, flux_density: bool = False, - frequency: bool = False): - """ - This function return a list temp, freq and flux to GUI from database to used as dropdown list - @param frequency: to get freq list - @param material_name: material name, e.g. "N95" - @param temperature: boolean to get temp list - @param temperature: boolean to get temp list - @param flux_density: boolean to get flux list - @param datatype: needed for load measurement readings - @param measurement_name: test setup name, of which data is to be plotted - @param comparison_type: datasheet vs datasheet ="dvd", measurement vs measurement = "mvm", datasheet vs measurement = "dvm" - @return: temp_list or freq_list or flux_list + def drop_down_list(self, material_name: str, comparison_type: str, datatype: str, measurement_name: str, temperature: bool = False, + flux_density: bool = False, frequency: bool = False): + """ + Return a list temp, freq and flux to GUI from database to used as dropdown list. + + :param material_name: material name, e.g. "N95" + :param temperature: boolean to get temp list + :param flux_density: boolean to get flux list + :param frequency: boolean to get freq list + :param datatype: needed for load measurement readings + :param measurement_name: test setup name, of which data is to be plotted + :param comparison_type: datasheet vs datasheet ="dvd", measurement vs measurement = "mvm", datasheet vs measurement = "dvm" + :return: temp_list or freq_list or flux_list """ global temp_list, flux_list, freq_list_new, temp_list_new, flux_list_new @@ -368,8 +316,7 @@ def drop_down_list(self, material_name: str, comparison_type: str, datatype: str # ------- measurement vs measurement------ if comparison_type == "mvm": - curve_data_material = self.data[f"{material_name}"]["measurements"][datatype][measurement_name][ - "measurement_data"] + curve_data_material = self.data[f"{material_name}"]["measurements"][datatype][measurement_name]["measurement_data"] temp_list = [] freq_list = [] for _ in range(len(curve_data_material)): @@ -392,7 +339,9 @@ def drop_down_list(self, material_name: str, comparison_type: str, datatype: str def material_list_in_database(self): """ - @return: list of materials present in database in form of list to GUI. + Return a list with all the different material present in the database. + + :return: list of materials present in database in form of list to GUI. """ materials = [] for i in self.data: @@ -400,21 +349,20 @@ def material_list_in_database(self): materials.remove('custom_material') return materials - def compare_core_loss_flux_density_data(self, matplotlib_widget, material_list: list, - temperature_list: list = None): + def compare_core_loss_flux_density_data(self, matplotlib_widget, material_list: list, temperature_list: list = None): """ - Method is used to compare material properties from datasheet. - @param matplotlib_widget: plotting parameter for GUI - @param material_list:[material1, material2, .....] - @param temperature_list: [temp1, temp2,..] - @return: return plotting data in two list, power_loss and flux + Compare the core loss of a material at different temperatures over the magnetic flux density from datasheet. + + :param matplotlib_widget: plotting parameter for GUI + :param material_list:[material1, material2, .....] + :param temperature_list: [temp1, temp2,..] + :return: return plotting data in two list, power_loss and flux """ color_list = ['red', 'blue', 'green', 'yellow', 'orange'] # mdb_print(material_list) for i in range(len(material_list)): - curve_data_material = self.data[f"{material_list[i]}"]["manufacturer_datasheet"][ - "relative_core_loss_flux_density"] + curve_data_material = self.data[f"{material_list[i]}"]["manufacturer_datasheet"]["relative_core_loss_flux_density"] material = material_list[i] temperature = temperature_list[i] b = [] @@ -430,13 +378,11 @@ def compare_core_loss_flux_density_data(self, matplotlib_widget, material_list: line_style = [(0, (5, 1)), (0, (1, 1)), (0, (3, 1, 1, 1, 1, 1)), (0, (3, 5, 1, 5)), (0, (5, 10)), (0, ()), (0, (3, 10, 1, 10, 1, 10)), (0, (5, 5)), (0, (1, 10)), (0, (3, 10, 1, 10))] label = f"{material}", f"F={frequency[j]}Hz", f"T={temperature}°C" - lines = matplotlib_widget.axis.plot(b[j], power_loss[j], label=label, color=color, - linestyle=line_style[j]) + lines = matplotlib_widget.axis.plot(b[j], power_loss[j], label=label, color=color, linestyle=line_style[j]) mplcursors.cursor(lines) # plt.plot(b[j], power_loss[j], label=label, color=color, linestyle=line_style[j]) # plt.legend() - matplotlib_widget.axis.set(xlabel="B in T", ylabel="Relative power loss in W/m\u00b3", yscale='log', - xscale='log') + matplotlib_widget.axis.set(xlabel="B in T", ylabel="Relative power loss in W/m\u00b3", yscale='log', xscale='log') # plt.yscale('log') # plt.xscale('log') # plt.xlabel("B in T") @@ -448,18 +394,18 @@ def compare_core_loss_flux_density_data(self, matplotlib_widget, material_list: def compare_core_loss_temperature(self, matplotlib_widget, material_list: list, flux_density_list: list = None): """ - Method is used to compare material properties from datasheet. - @param matplotlib_widget: plot parameter for GUI - @param material_list:[material1, material2, ....] - @param flux_density_list: [flux1, flux2,..] - @return: return plotting data in two list, power_loss and temperature - """ + Compare the core loss of a material at different magnetic flux densities over the temperature from datasheet. + + :param matplotlib_widget: plot parameter for GUI + :param material_list:[material1, material2, ....] + :param flux_density_list: [flux1, flux2,..] + :return: return plotting data in two list, power_loss and temperature + """ color_list = ['red', 'blue', 'green', 'yellow', 'orange'] # mdb_print(material_list) for i in range(len(material_list)): - curve_data_material = self.data[f"{material_list[i]}"]["manufacturer_datasheet"][ - "relative_core_loss_temperature"] + curve_data_material = self.data[f"{material_list[i]}"]["manufacturer_datasheet"]["relative_core_loss_temperature"] material = material_list[i] flux = flux_density_list[i] temperature = [] @@ -475,8 +421,7 @@ def compare_core_loss_temperature(self, matplotlib_widget, material_list: list, line_style = [(0, (5, 1)), (0, (1, 1)), (0, (3, 1, 1, 1, 1, 1)), (0, (3, 5, 1, 5)), (0, (5, 10)), (0, ()), (0, (3, 10, 1, 10, 1, 10)), (0, (5, 5)), (0, (1, 10)), (0, (3, 10, 1, 10))] label = f"{material}", f"F={frequency[j]}Hz", f"B= {flux}T" - lines = matplotlib_widget.axis.plot(temperature[j], power_loss[j], label=label, color=color, - linestyle=line_style[j]) + lines = matplotlib_widget.axis.plot(temperature[j], power_loss[j], label=label, color=color, linestyle=line_style[j]) mplcursors.cursor(lines) # plt.plot(temperature[j], power_loss[j], label=label, color=color, linestyle=line_style[j]) # plt.legend() @@ -488,21 +433,20 @@ def compare_core_loss_temperature(self, matplotlib_widget, material_list: list, # plt.show() self.mdb_print(f"Material properties of {material_list} are compared.") - def compare_core_loss_frequency(self, matplotlib_widget, material_list: list, temperature_list: list = None, - flux_density_list: list = None): + def compare_core_loss_frequency(self, matplotlib_widget, material_list: list, temperature_list: list = None, flux_density_list: list = None): + """ + Compare the core loss of a material at different temperatures over the frequency from datasheet. + + :param matplotlib_widget: plot parameter for GUI + :param material_list:[material1, material2, ....] + :param flux_density_list: [flux1, flux2, ....] + :param temperature_list: [temp1, temp2, ....] + :return: return plotting data in two list, power_loss and frequency """ - Method is used to compare material properties from datasheet. - @param matplotlib_widget: plot parameter for GUI - @param material_list:[material1, material2, ....] - @param flux_density_list: [flux1, flux2, ....] - @param temperature_list: [temp1, temp2, ....] - @return: return plotting data in two list, power_loss and frequency - """ color_list = ['red', 'blue', 'green', 'yellow', 'orange'] for i in range(len(material_list)): - curve_data_material = self.data[f"{material_list[i]}"]["manufacturer_datasheet"][ - "relative_core_loss_frequency"] + curve_data_material = self.data[f"{material_list[i]}"]["manufacturer_datasheet"]["relative_core_loss_frequency"] material = material_list[i] temperature = temperature_list[i] flux = flux_density_list[i] @@ -518,31 +462,29 @@ def compare_core_loss_frequency(self, matplotlib_widget, material_list: list, te line_style = [(0, (5, 1)), (0, (1, 1)), (0, (3, 1, 1, 1, 1, 1)), (0, (3, 5, 1, 5)), (0, (5, 10)), (0, ()), (0, (3, 10, 1, 10, 1, 10)), (0, (5, 5)), (0, (1, 10)), (0, (3, 10, 1, 10))] label = f"{material}", f"B= {flux}T", f"T= {temperature}°C" - lines = matplotlib_widget.axis.plot(frequency[j], power_loss[j], color=color, label=label, - linestyle=line_style[j]) + lines = matplotlib_widget.axis.plot(frequency[j], power_loss[j], color=color, label=label, linestyle=line_style[j]) mplcursors.cursor(lines) # plt.plot(frequency[j], power_loss[j], color=color, label=label, linestyle=line_style[j]) # plt.legend() - matplotlib_widget.axis.set(xlabel="Frequency in Hz", ylabel="Relative power loss in W/m\u00b3", yscale='log', - xscale='log') + matplotlib_widget.axis.set(xlabel="Frequency in Hz", ylabel="Relative power loss in W/m\u00b3", yscale='log', xscale='log') # plt.grid() # plt.show() self.mdb_print(f"Material properties of {material_list} are compared.") def compare_b_h_curve(self, matplotlib_widget, material_list: list, temperature_list: list = None): """ - Method to compare B-H curve of different materials from datasheet - @param matplotlib_widget: plot parameter for GUI - @param material_list: [material1, material2, ...] - @param temperature_list: [temp1, temp2, ...] - @return plotting data two vector,B and H + Compare the B-H curve of a material at different temperatures from datasheet. + + :param matplotlib_widget: plot parameter for GUI + :param material_list: [material1, material2, ...] + :param temperature_list: [temp1, temp2, ...] + :return plotting data two vector,B and H """ # -------B_H Curve------- color_list = ['red', 'blue', 'green', 'yellow', 'orange'] for i in range(len(material_list)): - curve_data_material = self.data[f"{material_list[i]}"]["manufacturer_datasheet"][ - "b_h_curve"] + curve_data_material = self.data[f"{material_list[i]}"]["manufacturer_datasheet"]["b_h_curve"] b = [] h = [] color = color_list[i] @@ -568,27 +510,26 @@ def compare_b_h_curve(self, matplotlib_widget, material_list: list, temperature_ # plt.show() self.mdb_print(f"Material properties of {material_list} are compared.") - def compare_permeability_measurement_data(self, matplotlib_widget, material_list: list, measurement_name: list, - frequency_list: list = None, + def compare_permeability_measurement_data(self, matplotlib_widget, material_list: list, measurement_name: list, frequency_list: list = None, temperature_list: list = None, plot_real_part: bool = False): """ - Method is used to compare material properties from measurement data. - @param matplotlib_widget: plotting parameter for GUI - @param material_list:[material1, material2, .....] - @param plot_real_part: True for plot real part of mu/ False for plots imaginary part of mu - @type temperature_list: [temp1, temp2, ...] - @param measurement_name: Name from database - @param frequency_list: [freq1, freq2, ...] - :return: Plotting data list for GUI - """ + Compare the permeability data of a material at different temperatures and frequencies from datasheet. + + :param matplotlib_widget: plotting parameter for GUI + :param material_list:[material1, material2, .....] + :param plot_real_part: True for plot real part of mu/ False for plots imaginary part of mu + :type temperature_list: [temp1, temp2, ...] + :param measurement_name: Name from database + :param frequency_list: [freq1, freq2, ...] + :return: Plotting data list for GUI + """ color_list = ['red', 'blue', 'green', 'yellow', 'orange'] # fig, axs = plt.subplots(1, 2) # axs[0].grid() # axs[1].grid() for i in range(len(material_list)): - curve_data_material = \ - self.data[f"{material_list[i]}"]["measurements"]["complex_permeability"][measurement_name[i]]["measurement_data"] + curve_data_material = self.data[f"{material_list[i]}"]["measurements"]["complex_permeability"][measurement_name[i]]["measurement_data"] material = material_list[i] temperature = temperature_list[i] frequency = frequency_list[i] @@ -609,56 +550,48 @@ def compare_permeability_measurement_data(self, matplotlib_widget, material_list for k in range(len(b)): if plot_real_part: - line_style = [(0, (5, 1)), (0, (1, 1)), (0, (3, 1, 1, 1, 1, 1)), (0, (3, 5, 1, 5)), - (0, (5, 10)), - (0, ()), (0, (3, 10, 1, 10, 1, 10)), (0, (5, 5)), (0, (1, 10)), - (0, (3, 10, 1, 10))] + line_style = [(0, (5, 1)), (0, (1, 1)), (0, (3, 1, 1, 1, 1, 1)), (0, (3, 5, 1, 5)), (0, (5, 10)), + (0, ()), (0, (3, 10, 1, 10, 1, 10)), (0, (5, 5)), (0, (1, 10)), (0, (3, 10, 1, 10))] label = f"{material}", f"T={temperature}°C" # plt.plot(b[k], mu_r[k], label=label, color=color, linestyle=line_style[k]) # plt.xlabel(r"B in T") # plt.ylabel(r"$\mu_\mathrm{r} / \mu_0$") # plt.legend() - lines = matplotlib_widget.axis.plot(b[k], mu_r[k], label=label, color=color, - linestyle=line_style[k]) + lines = matplotlib_widget.axis.plot(b[k], mu_r[k], label=label, color=color, linestyle=line_style[k]) mplcursors.cursor(lines) matplotlib_widget.axis.set(xlabel=r"B in T", ylabel=r"$\mu_\mathrm{r} / \mu_0$") else: - line_style = [(0, (5, 1)), (0, (1, 1)), (0, (3, 1, 1, 1, 1, 1)), (0, (3, 5, 1, 5)), - (0, (5, 10)), - (0, ()), (0, (3, 10, 1, 10, 1, 10)), (0, (5, 5)), (0, (1, 10)), - (0, (3, 10, 1, 10))] + line_style = [(0, (5, 1)), (0, (1, 1)), (0, (3, 1, 1, 1, 1, 1)), (0, (3, 5, 1, 5)), (0, (5, 10)), + (0, ()), (0, (3, 10, 1, 10, 1, 10)), (0, (5, 5)), (0, (1, 10)), (0, (3, 10, 1, 10))] label = f"{material}", f"T={temperature}°C" # plt.plot(b[k], mu_phi[k], label=label, color=color, linestyle=line_style[k]) # plt.xlabel(r"B in T") # plt.ylabel(r"$\zeta_\mathrm{\mu}$") # plt.legend() - lines = matplotlib_widget.axis.plot(b[k], mu_phi[k], label=label, color=color, - linestyle=line_style[k]) + lines = matplotlib_widget.axis.plot(b[k], mu_phi[k], label=label, color=color, linestyle=line_style[k]) mplcursors.cursor(lines) matplotlib_widget.axis.set(xlabel=r"B in T", ylabel=r"$\mu_\mathrm{r} / \mu_0$") # plt.show() self.mdb_print(f"Material properties of {material_list} are compared.") - def compare_core_loss_flux_datasheet_measurement(self, matplotlib_widget, material: str, measurement_name: list, - temperature_list: list = None): + def compare_core_loss_flux_datasheet_measurement(self, matplotlib_widget, material: str, measurement_name: list, temperature_list: list = None): """ - Method is used to compare material properties between datasheet and measurement. - @param matplotlib_widget: For GUI plot - @param material: [material1, material2, ...] - @param measurement_name: Name from database - @param temperature_list: - @return: Plotting data for GUI + Compare the core loss of a material at different temperatures between the datasheet and measurement. + + :param matplotlib_widget: For GUI plot + :param material: [material1, material2, ...] + :param measurement_name: Name from database + :param temperature_list: [temp1, temp2, ...] + :return: Plotting data for GUI """ color_list = ['red', 'blue', 'green', 'yellow', 'orange'] line_style = [(0, (5, 1)), (0, (1, 1)), (0, (3, 1, 1, 1, 1, 1)), (0, (3, 5, 1, 5)), (0, (5, 10)), (0, ()), (0, (3, 10, 1, 10, 1, 10)), (0, (5, 5)), (0, (1, 10)), (0, (3, 10, 1, 10))] - curve_data_material_datasheet = self.data[f"{material}"]["manufacturer_datasheet"][ - "relative_core_loss_flux_density"] - curve_data_material = self.data[f"{material}"]["measurements"]["complex_permeability"][measurement_name][ - "measurement_data"] + curve_data_material_datasheet = self.data[f"{material}"]["manufacturer_datasheet"]["relative_core_loss_flux_density"] + curve_data_material = self.data[f"{material}"]["measurements"]["complex_permeability"][measurement_name]["measurement_data"] temperature_datasheet = temperature_list[0] temperature_measurement = temperature_list[1] b_d = [] @@ -675,8 +608,7 @@ def compare_core_loss_flux_datasheet_measurement(self, matplotlib_widget, materi power_loss_d.append(curve_data_material_datasheet[j]["power_loss"]) for j in range(len(b_d)): label = f"{material}", f"F={frequency_d[j]}Hz", f"T={temperature_datasheet}°C", "Datasheet" - lines = matplotlib_widget.axis.plot(b_d[j], power_loss_d[j], label=label, color=color_list[0], - linestyle=line_style[0]) + lines = matplotlib_widget.axis.plot(b_d[j], power_loss_d[j], label=label, color=color_list[0], linestyle=line_style[0]) mplcursors.cursor(lines) # plt.plot(b_d[j], power_loss_d[j], label=label, color=color_list[0], linestyle=line_style[0]) # plt.legend() @@ -686,19 +618,14 @@ def compare_core_loss_flux_datasheet_measurement(self, matplotlib_widget, materi b_m.append(list_item["flux_density"]) frequency_m.append(list_item["frequency"]) power_loss_m.append( - p_hyst__from_mu_r_and_mu_phi_deg(list_item["frequency"], - list_item["flux_density"], - list_item["mu_r_abs"], - list_item["mu_phi_deg"])) + p_hyst__from_mu_r_and_mu_phi_deg(list_item["frequency"], list_item["flux_density"], list_item["mu_r_abs"], list_item["mu_phi_deg"])) for j in range(len(b_m)): label = f"{material}", f"F={frequency_m[j]}Hz", f"T={temperature_measurement}°C", "Measurements" - lines = matplotlib_widget.axis.plot(b_m[j], power_loss_m[j], label=label, color=color_list[1], - linestyle=line_style[1]) + lines = matplotlib_widget.axis.plot(b_m[j], power_loss_m[j], label=label, color=color_list[1], linestyle=line_style[1]) mplcursors.cursor(lines) # plt.plot(b_m[j], power_loss_m[j], label=label, color=color_list[1], linestyle=line_style[1]) # plt.legend() - matplotlib_widget.axis.set(xlabel="B in T", ylabel="Relative power loss in W/m\u00b3", yscale='log', - xscale='log') + matplotlib_widget.axis.set(xlabel="B in T", ylabel="Relative power loss in W/m\u00b3", yscale='log', xscale='log') # plt.yscale('log') # plt.xscale('log') # plt.xlabel("B in T") @@ -709,12 +636,12 @@ def compare_core_loss_flux_datasheet_measurement(self, matplotlib_widget, materi # Permittivity Data def load_permittivity_measurement(self, material_name: str, datasource: str = "measurements", - datatype: MeasurementDataType = MeasurementDataType.ComplexPermittivity, - measurement_setup: str = None): + datatype: MeasurementDataType = MeasurementDataType.ComplexPermittivity, measurement_setup: str = None): """ - Method to load permittivity data + Load permittivity data. + :param material_name: name of material of which data to be loaded - :param datasource: "measurement" + :param datasource: "measurements" :param datatype: MeasurementDataType :param measurement_setup: "complex_permittivity" :return: dictionary of required data @@ -730,13 +657,11 @@ def load_permittivity_measurement(self, material_name: str, datasource: str = "m except Exception as err: raise ValueError("Requested measurement data not available.") from err - def get_permittivity(self, temperature: float, frequency: float, material_name: str, - datasource: str = "measurements", - datatype: MeasurementDataType = MeasurementDataType.ComplexPermittivity, - measurement_setup: str = None, + def get_permittivity(self, temperature: float, frequency: float, material_name: str, datasource: str = "measurements", + datatype: MeasurementDataType = MeasurementDataType.ComplexPermittivity, measurement_setup: str = None, interpolation_type: str = "linear"): """ - Returns the complex permittivity for a certain operation point defined by temperature and frequency. + Return the complex permittivity for a certain operation point defined by temperature and frequency. :param measurement_setup: Name of the test-setup, e.g. "LEA_LK" :type measurement_setup: str @@ -745,13 +670,13 @@ def get_permittivity(self, temperature: float, frequency: float, material_name: :param interpolation_type: "linear" (as of now, this is the only supported type) :param datasource: datasource, e.g. "measurements" :type datasource: str - :param temperature: temperature + :param temperature: temperature in degree :type temperature: float - :param frequency: frequency + :param frequency: frequency in Hz :type frequency: float :param material_name: material name, e.g. "N95" :type material_name: str - :return: complex + :return: amplitude of the permittivity, angle of the permittivity :Example: >>> import materialdatabase as mdb @@ -761,34 +686,32 @@ def get_permittivity(self, temperature: float, frequency: float, material_name: """ # Load the chosen permittivity data from the database - list_of_permittivity_dicts = self.load_permittivity_measurement(material_name, datasource, datatype, - measurement_setup) + list_of_permittivity_dicts = self.load_permittivity_measurement(material_name, datasource, datatype, measurement_setup) # Find the data, that is closest to the given operation point (T, f) - neighbourhood = create_permittivity_neighbourhood(temperature=temperature, frequency=frequency, - list_of_permittivity_dicts=list_of_permittivity_dicts) + neighbourhood = create_permittivity_neighbourhood(temperature=temperature, frequency=frequency, list_of_permittivity_dicts=list_of_permittivity_dicts) # Interpolate/Extrapolate the permittivity according to the given operation point if interpolation_type == "linear": - epsilon_r, epsilon_phi_deg = interpolate_neighbours_linear(temperature=temperature, frequency=frequency, - neighbours=neighbourhood) + epsilon_r, epsilon_phi_deg = interpolate_neighbours_linear(temperature=temperature, frequency=frequency, neighbours=neighbourhood) else: raise NotImplementedError return epsilon_r, epsilon_phi_deg def get_steinmetz(self, temperature: float, material_name: str, datasource: str = "measurements", - datatype: MeasurementDataType = MeasurementDataType.Steinmetz, measurement_setup: str = None, - interpolation_type: str = "linear"): - """ - Returns the complex permittivity for a certain operation point defined by temperature and frequency. - :param temperature: - :param material_name: - :param datasource: - :param datatype: - :param measurement_setup: - :param interpolation_type: - :return: + datatype: MeasurementDataType = MeasurementDataType.Steinmetz, measurement_setup: str = None, interpolation_type: str = "linear"): + """ + Return the complex permittivity for a certain operation point defined by temperature and frequency. + + :param temperature: temperature value + :param material_name: name of the material + :param datasource: datasource, e.g. "measurements" + :param datatype: e.g. MeasurementDataType.ComplexPermittivity + :param measurement_setup: Name of the test-setup, e.g. "LEA_LK" + :param interpolation_type: "linear" (as of now, this is the only supported type) + :return: steinmetz parameter (alpha, beta, k) + :Example: >>> import materialdatabase as mdb >>> material_db = mdb.MaterialDatabase() @@ -802,9 +725,7 @@ def get_steinmetz(self, temperature: float, material_name: str, datasource: str neighbourhood = create_steinmetz_neighbourhood(temperature=temperature, list_of_steinmetz_dicts=list_of_steinmetz_dicts) # Interpolate/Extrapolate the permittivity according to the given operation point if interpolation_type == "linear": - """ - A linear interpolation in fact is not really a good ideal for a non-linear function like Steinmetz equation! - """ + """A linear interpolation in fact is not really a good ideal for a non-linear function like Steinmetz equation!""" # TODO: Find a better interpolation method t_low = neighbourhood["T_low"]["temperature"]["value"] t_index_low = neighbourhood["T_low"]["temperature"]["index"] @@ -823,10 +744,11 @@ def get_steinmetz(self, temperature: float, material_name: str, datasource: str def find_measurement_names(self, material_name: str, datatype: str): """ - Method to make a list of available measurements in database - @param material_name: "N95" - @param datatype: complex_permittivity or complex_permeability - return: Names of measurement in database + Make a list of available measurements in database. + + :param material_name: "N95" + :param datatype: complex_permittivity or complex_permeability + :return: Names of measurement in database """ names = [] for i in self.data[material_name]["measurements"][datatype]: diff --git a/materialdatabase/material_data_base_functions.py b/materialdatabase/material_data_base_functions.py index 0345ef2..4196598 100644 --- a/materialdatabase/material_data_base_functions.py +++ b/materialdatabase/material_data_base_functions.py @@ -1,7 +1,7 @@ +"""Functions of the material database.""" # all static functions shall be inserted in this file # Python integrated libraries - import json # 3rd party libraries import os @@ -20,16 +20,17 @@ relative_path_to_db = "../data/material_data_base.json" -# --- -# Auxiliary functions +# Auxiliary functions ------------------------------------------------------------------------------------------------------------------------------------------ j = complex(0, 1) + def remove(arr, n): """ - Remove Duplicate from array - :param arr: - :param n: - :return: + Remove duplicates from array. + + :param arr: array with duplicates + :param n: has no effect of the functionality + :return: array without duplicates """ mp = {i: 0 for i in arr} for i in range(n): @@ -39,12 +40,32 @@ def remove(arr, n): def crop_data_fixed(x, pre_cropped_values: int = 0, post_cropped_values: int = 0): + """ + Crop an array based on the given indices. + + IMPORTANT! THE SECOND INDEX IS COUNTED BACKWARDS(NEGATIVE)! + + :param x: array to get cropped + :param pre_cropped_values: start value + :param post_cropped_values: end value, but counted backwards + :return: cropped data + """ if post_cropped_values == 0: post_cropped_values = -len(x) return x[pre_cropped_values:-post_cropped_values] def crop_3_with_1(x, y, z, xa, xb): + """ + Crop three arrays based on one array. + + :param x: array crop is based on + :param y: first array to get cropped + :param z: second array to get cropped + :param xa: start value of crop + :param xb: end value of crop + :return: the three cropped arrays + """ x_copy = np.array(x) y_copy = np.array(y) z_copy = np.array(z) @@ -61,8 +82,9 @@ def crop_3_with_1(x, y, z, xa, xb): def store_data(material_name: str, data_to_be_stored: dict) -> None: """ - Method is used to store data from measurement/datasheet into the material database. - :param material_name: Material name + Store data from measurement/datasheet into the material database. + + :param material_name: name of the material :type material_name: str :param data_to_be_stored: data to be stored :type data_to_be_stored: dict @@ -76,11 +98,10 @@ def store_data(material_name: str, data_to_be_stored: dict) -> None: def load_material_from_db(material_name: str) -> None: """ - Method is used to load data from material database. - :param material_name: Material name + Load data from material database. + + :param material_name: name of material :type material_name: str - :param data_to_be_stored: data to be stored - :type data_to_be_stored: dict :return: None :rtype: None """ @@ -92,10 +113,11 @@ def load_material_from_db(material_name: str) -> None: def find_nearest(array, value): """ - find nearby frequency n Temp - :param array: - :param value: - :return: + Find the nearest value in an array. + + :param array: array to search + :param value: desired value + :return: two values of the array with the wanted value in between """ array = np.asarray(array) array.sort() @@ -111,14 +133,13 @@ def find_nearest(array, value): def rect(radius_or_amplitude: float, theta_deg: float): """ - converts polar coordinates [degree] cartesian coordinates - theta in degrees + Convert polar coordinates [radius, angle] into cartesian coordinates [abscissa_x,ordinate_y]. + :param radius_or_amplitude: radius or amplitude :type radius_or_amplitude: float :param theta_deg: angle in degree :type theta_deg: float - - :returns: tuple; (float, float); (abscissa_x,ordinate_y) + :return: tuple; (float, float); (abscissa_x,ordinate_y) """ abscissa_x = radius_or_amplitude * np.cos(np.radians(theta_deg)) ordinate_y = radius_or_amplitude * np.sin(np.radians(theta_deg)) @@ -126,18 +147,28 @@ def rect(radius_or_amplitude: float, theta_deg: float): def sort_data(a, b, c): - """sorts three lists according to a + """ + Sort three arrays according to array a. - :param a: - :param b: - :param c: - :return: + :param a: array that is the base of the sorting + :param b: array that gets sorted based on a + :param c: array that gets sorted based on a + :return: the three arrays sorted according to a """ sorted_list_of_lists = [list(x) for x in list(zip(*sorted(zip(a, b, c), key=lambda a: a)))] return np.array(sorted_list_of_lists[0]), np.array(sorted_list_of_lists[1]), np.array(sorted_list_of_lists[2]) def interpolate_a_b_c(a, b, c, no_interpolation_values=20): + """ + Interpolation between three arrays based on the first array. + + :param a: array that is the base of the interpolation + :param b: array that gets interpolated based on the values of array a + :param c: array that gets interpolated based on the values of array a + :param no_interpolation_values: number of interpolation values + :return: the three interpolated arrays + """ # Find the border of the common magnetic flux density values b_min = min(a) b_max = max(a) @@ -151,11 +182,14 @@ def interpolate_a_b_c(a, b, c, no_interpolation_values=20): b_interpol_common = f_b_interpol(a_reduced) c_interpol_common = f_c_interpol(a_reduced) return a_reduced, b_interpol_common, c_interpol_common +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- +# Load Permeability -------------------------------------------------------------------------------------------------------------------------------------------- def updates_x_ticks_for_graph(x_data: list, y_data: list, x_new: list): """ - updates the x-values of the given (x_data,y_data)-dataset and returns y_new based on x_new + Update the x-values of the given (x_data,y_data)-dataset and returns y_new based on x_new. + :param x_data: x-data given :param y_data: y-data given :param x_new: new x-values @@ -165,12 +199,10 @@ def updates_x_ticks_for_graph(x_data: list, y_data: list, x_new: list): return f_linear(x_new) -# --- -# Load Permeability - def check_input_permeability_data(datasource: str, material_name: str, temperature: float, frequency: float) -> None: """ - Checks input permeability data for correct input parameters. + Check input permeability data for correct input parameters. + * datasource must be 'measurements' or 'manufacturer_datasheet' * material_name, T, f must be different from None @@ -182,7 +214,7 @@ def check_input_permeability_data(datasource: str, material_name: str, temperatu :type temperature: float :param frequency: frequency in Hz :type frequency: float - :returns: None + :return: None :rtype: None """ if datasource != MaterialDataSource.Measurement and datasource != MaterialDataSource.ManufacturerDatasheet: @@ -194,7 +226,16 @@ def check_input_permeability_data(datasource: str, material_name: str, temperatu def getdata_datasheet(permeability, variable, frequency, temperature_1, temperature_2): """ - interpolation function + Interpolation of permeability data between two temperatures at a constant frequency. + + Linear Interpolation between temperature_1 and temperature_2 to get a value for the temperature "variable". + + :param permeability: permeability data + :param variable: desired temperature value in degree + :param frequency: frequency value in Hz + :param temperature_1: first temperature value in degree + :param temperature_2: second temperature value + :return: magnetic flux density, real part of permeability and imaginary part of permeability """ for k in range(len(permeability)): if permeability[k]["frequency"] == frequency and permeability[k]["temperature"] == temperature_1: @@ -215,20 +256,19 @@ def getdata_datasheet(permeability, variable, frequency, temperature_1, temperat mu_r = [] for y in range(len(b_1)): - mu_r.append(t_mu_real_1(b_1[y]) + (t_mu_real_2(b_1[y]) - t_mu_real_1(b_1[y])) / ( - temperature_2 - temperature_1) * (variable - temperature_1)) - mu_i.append(t_mu_imag_1(b_1[y]) + (t_mu_imag_2(b_1[y]) - t_mu_imag_1(b_1[y])) / ( - temperature_2 - temperature_1) * (variable - temperature_1)) + mu_r.append(t_mu_real_1(b_1[y]) + (t_mu_real_2(b_1[y]) - t_mu_real_1(b_1[y])) / (temperature_2 - temperature_1) * (variable - temperature_1)) + mu_i.append(t_mu_imag_1(b_1[y]) + (t_mu_imag_2(b_1[y]) - t_mu_imag_1(b_1[y])) / (temperature_2 - temperature_1) * (variable - temperature_1)) return b_1, mu_r, mu_i def create_permeability_neighbourhood_datasheet(temperature, frequency, list_of_permeability_dicts): """ + Create a neighbourhood for permeability data of a datasheet. - :param temperature: - :param frequency: - :param list_of_permeability_dicts: - :return: + :param temperature: temperature value in degree + :param frequency: frequency value in Hz + :param list_of_permeability_dicts: list of permeability data dicts + :return: neighbourhood """ # Initialize dicts for the certain operation point its neighbourhood nbh = { @@ -310,11 +350,12 @@ def create_permeability_neighbourhood_datasheet(temperature, frequency, list_of_ def create_permeability_neighbourhood_measurement(temperature, frequency, list_of_permeability_dicts): """ + Create a neighbourhood for permeability data of a measurement. - :param temperature: - :param frequency: - :param list_of_permeability_dicts: - :return: + :param temperature: temperature value in degree + :param frequency: frequency value in Hz + :param list_of_permeability_dicts: list of permeability dicts + :return: neighbourhood """ # Initialize dicts for the certain operation point its neighbourhood nbh = { @@ -395,6 +436,14 @@ def create_permeability_neighbourhood_measurement(temperature, frequency, list_o def find_nearest_neighbour_values_permeability(permeability_data, temperature, frequency): + """ + Find the nearest temperature and frequency values for a given neighbourhood of permeability data. + + :param permeability_data: permeability data + :param temperature: temperature value in degree + :param frequency: frequency value in Hz + :return: lower temperature value in degree, higher temperature value in degree, lower frequency value in Hz, higher frequency value in Hz + """ temperatures = [] frequencies = [] for permeability_set in permeability_data: @@ -412,32 +461,30 @@ def find_nearest_neighbour_values_permeability(permeability_data, temperature, f def interpolate_b_dependent_quantity_in_temperature_and_frequency(temperature, frequency, temperature_low, temperature_high, frequency_low, frequency_high, - b_t_low_f_low, f_b_T_low_f_low, - b_T_high_f_low, f_b_T_high_f_low, - b_T_low_f_high, f_b_T_low_f_high, - b_T_high_f_high, f_b_T_high_f_high, - no_interpolation_values: int = 8, - y_label: str = None, plot: bool = False): - """ - - :param y_label: - :param temperature: - :param frequency:b_ref_vec - :param temperature_low: - :param temperature_high: - :param frequency_low: - :param frequency_high: - :param b_t_low_f_low: - :param f_b_T_low_f_low: - :param b_T_high_f_low: - :param f_b_T_high_f_low: - :param b_T_low_f_high: - :param f_b_T_low_f_high: - :param b_T_high_f_high: - :param f_b_T_high_f_high: - :param no_interpolation_values: - :param plot: - :return: + b_t_low_f_low, f_b_T_low_f_low, b_T_high_f_low, f_b_T_high_f_low, + b_T_low_f_high, f_b_T_low_f_high, b_T_high_f_high, f_b_T_high_f_high, + no_interpolation_values: int = 8, y_label: str = None, plot: bool = False): + """ + Interpolate a magnet flux density dependent quantity in temperature and frequency. + + :param temperature: desired temperature in degree + :param frequency: desired frequency in Hz + :param temperature_low: lower temperature value in degree + :param temperature_high: higher temperature value in degree + :param frequency_low: lower frequency value in Hz + :param frequency_high: higher frequency value in Hz + :param b_t_low_f_low: magnetic flux density at the lower temperature in degree and the lower frequency value in Hz + :param f_b_T_low_f_low: function dependent of b at the lower temperature in degree and the lower frequency value in Hz + :param b_T_high_f_low: magnetic flux density at the higher temperature in degree and the lower frequency value in Hz + :param f_b_T_high_f_low: function dependent of b at the higher temperature in degree and the lower frequency value in Hz + :param b_T_low_f_high: magnetic flux density at the lower temperature in degree and the higher frequency value in Hz + :param f_b_T_low_f_high: function dependent of b at the lower temperature in degree and the higher frequency value in Hz + :param b_T_high_f_high: magnetic flux density at the higher temperature in degree and the higher frequency value in Hz + :param f_b_T_high_f_high: function dependent of b at the higher temperature in degree and the higher frequency value in Hz + :param no_interpolation_values: number of interpolation values + :param y_label: label of y-axes + :param plot: enable/disable plotting of data + :return: array of magnetic flux density, arrays of function dependent of b """ if len(b_t_low_f_low) != len(f_b_T_low_f_low): raise ValueError(f"b_T_low_f_low and f_b_T_low_f_low must have the same lengths: \n" @@ -516,12 +563,13 @@ def interpolate_b_dependent_quantity_in_temperature_and_frequency(temperature, f def mu_r__from_p_hyst_and_mu_phi_deg(mu_phi_deg, frequency, b_peak, p_hyst): """ + Calculate the amplitude of the permeability given the peak value of the magnetic flux density, the hysteresis loss and the phase angle of the permeability. - :param mu_phi_deg: - :param frequency: frequency - :param b_peak: peak flux density - :param p_hyst: hysteresis losses - :return: + :param mu_phi_deg: phase angle of the permeability in degree + :param frequency: frequency in Hz + :param b_peak: peak flux density in T + :param p_hyst: hysteresis losses in W/m^3 + :return: amplitude of the permeability """ b_peak = np.array(b_peak) return b_peak ** 2 * np.pi * frequency * np.sin(np.deg2rad(mu_phi_deg)) / p_hyst / mu_0 @@ -529,12 +577,13 @@ def mu_r__from_p_hyst_and_mu_phi_deg(mu_phi_deg, frequency, b_peak, p_hyst): def p_hyst__from_mu_r_and_mu_phi_deg(frequency, b_peak, mu_r, mu_phi_deg): """ + Calculate the hysteresis losses given the peak value of the magnetic flux density, the amplitude and phase angle of the permeability. - :param mu_phi_deg: - :param frequency: frequency - :param b_peak: peak flux density - :param p_hyst: hysteresis losses - :return: + :param frequency: frequency in Hz + :param b_peak: peak flux density in T + :param mu_r: amplitude of the permeability in unitless + :param mu_phi_deg: phase angle of the permeability in degree + :return: hysteresis losses in W/m^3 """ b_peak = np.array(b_peak) return np.pi * frequency * np.sin(np.deg2rad(mu_phi_deg)) * mu_0 * mu_r * (b_peak / mu_0 / mu_r) ** 2 @@ -542,34 +591,37 @@ def p_hyst__from_mu_r_and_mu_phi_deg(frequency, b_peak, mu_r, mu_phi_deg): def mu_phi_deg__from_mu_r_and_p_hyst(frequency, b_peak, mu_r, p_hyst): """ + Calculate the phase angle of the permeability given the peak value of the magnetic flux density, the hysteresis loss and the amplitude of permeability. - :param mu_phi_deg: - :param frequency: frequency - :param b_peak: peak flux density - :param p_hyst: hysteresis losses - :return: + :param frequency: frequency in Hz + :param b_peak: peak flux density in T + :param mu_r: amplitude of the permeability in unitless + :param p_hyst: hysteresis losses in W/m^3 + :return: phase angle of the permeability in degree """ b_peak = np.array(b_peak) return np.rad2deg(np.arcsin(p_hyst * mu_r * mu_0 / (np.pi * frequency * b_peak ** 2))) -def process_permeability_data(b_ref_raw, mu_r_raw, mu_phi_deg_raw, b_min: float = 0.05, b_max: float = 0.3, - smooth_data: bool = False, crop_data: bool = False, +def process_permeability_data(b_ref_raw, mu_r_raw, mu_phi_deg_raw, b_min: float = 0.05, b_max: float = 0.3, smooth_data: bool = False, crop_data: bool = False, plot_data: bool = False, ax=None, f=None, T=None): """ - - :param T: - :param f: - :param ax: - :param b_max: - :param b_min: - :param b_ref_raw: - :param mu_r_raw: - :param mu_phi_deg_raw: - :param smooth_data: - :param crop_data: - :param plot_data: - :return: + Post-Processing of raw data of the permeability. + + Function can smooth, crop and plot the permeability data. + + :param T: temperature value in degree + :param f: frequency value in Hz + :param ax: matplotlib axes for plotting + :param b_max: max value of the magnetic flux density for cropping + :param b_min: min value of the magnetic flux density for cropping + :param b_ref_raw: raw data of the magnetic flux density + :param mu_r_raw: raw data of the amplitude of the permeability + :param mu_phi_deg_raw: raw data of the angle of the permeability + :param smooth_data: enable/disable smoothing of data (savgol-filter) + :param crop_data: enable/disable cropping of data + :param plot_data: enable/disable plotting of data + :return: magnetic flux density and amplitude and angle of permeability """ if crop_data: b_ref, mu_r, mu_phi_deg = crop_3_with_1(b_ref_raw, mu_r_raw, mu_phi_deg_raw, b_min, b_max) @@ -622,14 +674,15 @@ def process_permeability_data(b_ref_raw, mu_r_raw, mu_phi_deg_raw, b_min: float # plt.show() return b_ref, mu_r, mu_phi_deg +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- -# --- -# Load Permittivity - +# Load Permittivity -------------------------------------------------------------------------------------------------------------------------------------------- def find_nearest_neighbours(value, list_to_search_in): """ - only works for sorted lists (small to big) + Return the two values with the wanted value in between and additional the indices of the corresponding values. + + Only works for sorted lists (small to big). Case 0: if len(list_to_search_in) == 1: return duplicated Case 1: if value == any(list_to_search_in): return duplicated @@ -638,9 +691,9 @@ def find_nearest_neighbours(value, list_to_search_in): a) if value smaller than data: return smallest two b) if value is bigger than data: return biggest two - :param value: - :param list_to_search_in: - :return: + :param value: desired value + :param list_to_search_in: array to search for value + :return: lower index, lower value, higher index, higher value """ if isinstance(value, str): raise TypeError("value must be int or float or list") @@ -678,11 +731,12 @@ def find_nearest_neighbours(value, list_to_search_in): def create_permittivity_neighbourhood(temperature, frequency, list_of_permittivity_dicts): """ + Create neighbourhood for permittivity data. - :param temperature: - :param frequency: - :param list_of_permittivity_dicts: - :return: + :param temperature: temperature value in degree + :param frequency: frequency value in Hz + :param list_of_permittivity_dicts: list of permittivity data dicts + :return: neighbourhood """ # Initialize dicts for the certain operation point its neighbourhood nbh = { @@ -739,14 +793,12 @@ def create_permittivity_neighbourhood(temperature, frequency, list_of_permittivi "epsilon_phi_deg": None }, } - # In permittivity data: # find two temperatures at which were measured that are closest to given T temperatures = [] for permittivity_dict in list_of_permittivity_dicts: temperatures.append(permittivity_dict["temperature"]) # store them in a list - index_T_low_neighbour, value_T_low_neighbour, index_T_high_neighbour, value_T_high_neighbour = \ - find_nearest_neighbours(temperature, temperatures) + index_T_low_neighbour, value_T_low_neighbour, index_T_high_neighbour, value_T_high_neighbour = find_nearest_neighbours(temperature, temperatures) nbh["T_low_f_low"]["temperature"]["value"], nbh["T_low_f_high"]["temperature"]["value"] = value_T_low_neighbour, value_T_low_neighbour nbh["T_low_f_low"]["temperature"]["index"], nbh["T_low_f_high"]["temperature"]["index"] = index_T_low_neighbour, index_T_low_neighbour @@ -786,10 +838,11 @@ def create_permittivity_neighbourhood(temperature, frequency, list_of_permittivi def create_steinmetz_neighbourhood(temperature, list_of_steinmetz_dicts): """ + Create neighbourhood for steinmetz data. - :param temperature: - :param list_of_steinmetz_dicts: - :return: + :param temperature: temperature value in degree + :param list_of_steinmetz_dicts: list of steinmetz data dicts + :return: neighbourhood """ # Initialize dicts for the certain operation point its neighbourhood nbh = { @@ -820,8 +873,7 @@ def create_steinmetz_neighbourhood(temperature, list_of_steinmetz_dicts): temperatures = [] for steinmetz_dict in list_of_steinmetz_dicts: temperatures.append(steinmetz_dict["temperature"]) # store them in a list - index_T_low_neighbour, value_T_low_neighbour, index_T_high_neighbour, value_T_high_neighbour = \ - find_nearest_neighbours(temperature, temperatures) + index_T_low_neighbour, value_T_low_neighbour, index_T_high_neighbour, value_T_high_neighbour = find_nearest_neighbours(temperature, temperatures) nbh["T_low"]["temperature"]["value"], nbh["T_low"]["temperature"]["index"] = value_T_low_neighbour, index_T_low_neighbour nbh["T_high"]["temperature"]["value"], nbh["T_high"]["temperature"]["index"] = value_T_high_neighbour, index_T_high_neighbour @@ -831,9 +883,10 @@ def create_steinmetz_neighbourhood(temperature, list_of_steinmetz_dicts): def my_interpolate_linear(a, b, f_a, f_b, x): """ - interpolates linear between to points 'a' and 'b'. + Interpolates linear between to points 'a' and 'b'. + The return value is f_x in dependence of x - Tt applies: a < x < b. + It applies: a < x < b. :param a: input x-value for point a :param b: input x-value for point b @@ -849,7 +902,7 @@ def my_interpolate_linear(a, b, f_a, f_b, x): def my_polate_linear(a, b, f_a, f_b, x): """ - interpolates or extrapolates linear for ab + Interpolates or extrapolates linear for ab. :param a: input x-value for point a :param b: input x-value for point b @@ -868,21 +921,20 @@ def my_polate_linear(a, b, f_a, f_b, x): def interpolate_neighbours_linear(temperature, frequency, neighbours): """ + Linear interpolation of frequency and temperature between neighbours. - :param temperature: - :param frequency: - :param neighbours: - :return: + :param temperature: desired temperature value in degree + :param frequency: desired frequency value in Hz + :param neighbours: neighbours + :return: amplitude of the permittivity, angle of the permittivity """ # Interpolation of Amplitude # in temperature at f_low epsilon_r_at_T_f_low = my_polate_linear(a=neighbours["T_low_f_low"]["temperature"]["value"], b=neighbours["T_high_f_low"]["temperature"]["value"], - f_a=neighbours["T_low_f_low"]["epsilon_r"], f_b=neighbours["T_high_f_low"]["epsilon_r"], - x=temperature) + f_a=neighbours["T_low_f_low"]["epsilon_r"], f_b=neighbours["T_high_f_low"]["epsilon_r"], x=temperature) # in temperature at f_high epsilon_r_at_T_f_high = my_polate_linear(a=neighbours["T_low_f_high"]["temperature"]["value"], b=neighbours["T_high_f_high"]["temperature"]["value"], - f_a=neighbours["T_low_f_high"]["epsilon_r"], f_b=neighbours["T_high_f_high"]["epsilon_r"], - x=temperature) + f_a=neighbours["T_low_f_high"]["epsilon_r"], f_b=neighbours["T_high_f_high"]["epsilon_r"], x=temperature) # between f_low and f_high epsilon_r = my_polate_linear(a=neighbours["T_low_f_low"]["frequency"]["value"], b=neighbours["T_low_f_high"]["frequency"]["value"], f_a=epsilon_r_at_T_f_low, f_b=epsilon_r_at_T_f_high, x=frequency) @@ -901,15 +953,29 @@ def interpolate_neighbours_linear(temperature, frequency, neighbours): f_a=epsilon_phi_deg_at_T_f_low, f_b=epsilon_phi_deg_at_T_f_high, x=frequency) return epsilon_r, epsilon_phi_deg +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- -# --- # Add and remove data in Database -# General -# Permeability -def create_permeability_measurement_in_database(material_name, measurement_setup, company="", date="", test_setup_name="", - toroid_dimensions="", measurement_method="", equipment_names="", comment=""): + +# General Permeability ----------------------------------------------------------------------------------------------------------------------------------------- +def create_permeability_measurement_in_database(material_name, measurement_setup, company="", date="", test_setup_name="", toroid_dimensions="", + measurement_method="", equipment_names="", comment=""): + """ + Create a new permeability section in the database for a material. + + :param material_name: name of the material + :param measurement_setup: name of the measurement setup + :param company: name of the company + :param date: date of measurement + :param test_setup_name: information of the test setup + :param toroid_dimensions: dimensions of the probe + :param measurement_method: name of the measurement method + :param equipment_names: name of the measurement equipment + :param comment: comment regarding the measurement + :return: None + """ with open(relative_path_to_db, "r") as jsonFile: data = json.load(jsonFile) @@ -941,10 +1007,11 @@ def create_permeability_measurement_in_database(material_name, measurement_setup def clear_permeability_measurement_data_in_database(material_name, measurement_setup): """ + Clear the permeability data in the database given a material and measurement setup. - :param material_name: - :param measurement_setup: - :return: + :param material_name: name of the material + :param measurement_setup: name of the measurement setup + :return: None """ with open(relative_path_to_db, "r") as jsonFile: data = json.load(jsonFile) @@ -957,17 +1024,19 @@ def clear_permeability_measurement_data_in_database(material_name, measurement_s def write_permeability_data_into_database(frequency, temperature, b_ref, mu_r_abs, mu_phi_deg, material_name, measurement_setup, overwrite=False): """ - CAUTION: This method only adds the given measurement series to the permeability data - without checking duplicates! - :param temperature: - :param frequency: - :param measurement_setup: - :param b_ref: - :param mu_r_abs: - :param mu_phi_deg: - :param material_name: - :param overwrite: - :return: + Write permeability data into the material database. + + CAUTION: This method only adds the given measurement series to the permeability data without checking duplicates. + + :param temperature: temperature value in degree + :param frequency: frequency value in Hz + :param measurement_setup: name of the measurement setup + :param b_ref: magnetic flux density value + :param mu_r_abs: amplitude of the permeability + :param mu_phi_deg: angle of the permeability + :param material_name: name of the material + :param overwrite: enable/disable overwritting of data + :return: None """ with open(relative_path_to_db, "r") as jsonFile: data = json.load(jsonFile) @@ -995,22 +1064,23 @@ def write_permeability_data_into_database(frequency, temperature, b_ref, mu_r_ab with open(relative_path_to_db, "w") as jsonFile: json.dump(data, jsonFile, indent=2) +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- -# General -# Steinmetz +# General Steinmetz -------------------------------------------------------------------------------------------------------------------------------------------- def write_steinmetz_data_into_database(temperature, k, beta, alpha, material_name, measurement_setup): """ - CAUTION: This method only adds the given measurement series to the steinmetz data - without checking duplicates! + Write steinmetz data into the material database. + + CAUTION: This method only adds the given measurement series to the steinmetz data without checking duplicates. - :param temperature: - :param k: - :param beta: - :param alpha: - :param material_name: - :param measurement_setup: - :return: + :param temperature: temperature value in degree + :param k: k value of steinmetz parameters + :param beta: beta value of the steinmetz parameters + :param alpha: alpha value of the steinmetz parameters + :param material_name: name of the material + :param measurement_setup: name of the measurement setup + :return: None """ with open(relative_path_to_db, "r") as jsonFile: data = json.load(jsonFile) @@ -1036,7 +1106,13 @@ def write_steinmetz_data_into_database(temperature, k, beta, alpha, material_nam def create_empty_material(material_name: Material, manufacturer: Manufacturer): + """ + Create an empty material slot in the database. + :param material_name: name of the material + :param manufacturer: name of the manufacturer + :return: None + """ with open(relative_path_to_db, "r") as jsonFile: data = json.load(jsonFile) @@ -1051,12 +1127,26 @@ def create_empty_material(material_name: Material, manufacturer: Manufacturer): with open(relative_path_to_db, "w") as jsonFile: json.dump(data, jsonFile, indent=2) +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- -# General -# Permittivity -def create_permittivity_measurement_in_database(material_name, measurement_setup, company="", date="", test_setup_name="", - probe_dimensions="", measurement_method="", equipment_names="", comment=""): +# General Permittivity ----------------------------------------------------------------------------------------------------------------------------------------- +def create_permittivity_measurement_in_database(material_name, measurement_setup, company="", date="", test_setup_name="", probe_dimensions="", + measurement_method="", equipment_names="", comment=""): + """ + Create a new permittvity section in the database for a material. + + :param material_name: name of the material + :param measurement_setup: name of the measurement setup + :param company: name of the company + :param date: date of measurement + :param test_setup_name: information of the test setup + :param probe_dimensions: dimensions of the probe + :param measurement_method: name of the measurement method + :param equipment_names: name of the measurement equipment + :param comment: comment regarding the measurement + :return: None + """ with open(relative_path_to_db, "r") as jsonFile: data = json.load(jsonFile) @@ -1087,10 +1177,11 @@ def create_permittivity_measurement_in_database(material_name, measurement_setup def clear_permittivity_measurement_data_in_database(material_name, measurement_setup): """ + Clear the permittivity data in the database for a specific material. - :param material_name: - :param measurement_setup: - :return: + :param material_name: name of material + :param measurement_setup: name of measurement setup + :return: None """ with open(relative_path_to_db, "r") as jsonFile: data = json.load(jsonFile) @@ -1102,6 +1193,17 @@ def clear_permittivity_measurement_data_in_database(material_name, measurement_s def write_permittivity_data_into_database(temperature, frequencies, epsilon_r, epsilon_phi_deg, material_name, measurement_setup): + """ + Write permittivity data into the material database. + + :param temperature: measurement point of the temperature in degree + :param frequencies: measurement points of the frequency in Hz + :param epsilon_r: amplitude of the permittivity + :param epsilon_phi_deg: angle of the permittivity + :param material_name: name of material + :param measurement_setup: name of measurement setup + :return: None + """ # load data # mean of data @@ -1128,15 +1230,25 @@ def write_permittivity_data_into_database(temperature, frequencies, epsilon_r, e with open(relative_path_to_db, "w") as jsonFile: json.dump(data, jsonFile, indent=2) +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- -# LEA_LK -# Permeability +# LEA_LK Permeability ------------------------------------------------------------------------------------------------------------------------------------------ def get_permeability_data_from_lea_lk(location: str, frequency, temperature, material_name, no_interpolation_values: int = 20): - b_hys, p_hys = get_permeability_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="Core_Loss", - quantity="p_hys", frequency=frequency, material_name=material_name, temperature=temperature) - b_phi, mu_phi_deg = get_permeability_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="mu_phi_Plot", - quantity="mu_phi", frequency=frequency, material_name=material_name, temperature=temperature) + """ + Get the permeability data from LEA_LK. + + :param location: location of the permeability data + :param frequency: frequency value in Hz + :param temperature: temperature value in degree + :param material_name: name of the material + :param no_interpolation_values: number of interpolation values + :return: magnetic flux density, amplitude of the permeability, angle of the permeability + """ + b_hys, p_hys = get_permeability_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="Core_Loss", quantity="p_hys", frequency=frequency, + material_name=material_name, temperature=temperature) + b_phi, mu_phi_deg = get_permeability_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="mu_phi_Plot", quantity="mu_phi", + frequency=frequency, material_name=material_name, temperature=temperature) # Find the border of the common magnetic flux density values b_max_min = max(min(b_hys), min(b_phi), min(b_hys), min(b_phi)) @@ -1156,11 +1268,31 @@ def get_permeability_data_from_lea_lk(location: str, frequency, temperature, mat def create_permeability_file_name_lea_lk(quantity: str = "p_hys", frequency: int = 100000, material_name: str = "N49", temperature: int = 30): + """ + Create the file name for permeability data of LEA_LK. + + :param quantity: measured quantiy (e.g. p_hys) + :param frequency: frequency value in Hz + :param material_name: name of the material + :param temperature: temperature value in degree + :return: correct file name for LEA_LK + """ return "_".join([quantity, f"{int(frequency / 1000)}kHz", material_name, f"{temperature}C.txt"]) -def get_permeability_property_from_lea_lk(path_to_parent_folder, quantity: str, frequency: int, - material_name: str, temperature: int, sub_folder_name: str = "Core_Loss"): +def get_permeability_property_from_lea_lk(path_to_parent_folder, quantity: str, frequency: int, material_name: str, temperature: int, + sub_folder_name: str = "Core_Loss"): + """ + Get the proberty of the permeability from LEA_LK. + + :param path_to_parent_folder: path to permeability data + :param quantity: name of the measured quantity + :param frequency: frequency value in Hz + :param material_name: name of the material + :param temperature: temperature value in degree + :param sub_folder_name: name of the sub folder + :return: amplitude of the permeability, angle of the permeability + """ filename = create_permeability_file_name_lea_lk(quantity, frequency, material_name, temperature) complete_path = os.path.join(path_to_parent_folder, sub_folder_name, filename) # mdb_print(complete_path) @@ -1168,27 +1300,55 @@ def get_permeability_property_from_lea_lk(path_to_parent_folder, quantity: str, data = np.loadtxt(complete_path) # mdb_print(data) return data[:, 0], data[:, 1] +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- -# Permittivity +# Permittivity ------------------------------------------------------------------------------------------------------------------------------------------------- def get_permittivity_data_from_lea_lk(location, temperature, frequency, material_name): - e_amplitude, epsilon_r_tilde = get_permittivity_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="eps_r_Plot", - quantity="eps_r_tilde", frequency=frequency, - material_name=material_name, temperature=temperature) + """ + Get the permittivity data from LEA_LK. + + :param location: location of the permittivity data + :param temperature: temperature value + :param frequency: frequency value in Hz + :param material_name: name of the material + :return: amplitude of the permittivity, angle of the permittivity + """ + e_amplitude, epsilon_r_tilde = get_permittivity_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="eps_r_Plot", quantity="eps_r_tilde", + frequency=frequency, material_name=material_name, temperature=temperature) - e_phi, epsilon_phi_deg = get_permittivity_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="eps_phi_Plot", - quantity="eps_phi_tilde", frequency=frequency, - material_name=material_name, temperature=temperature) + e_phi, epsilon_phi_deg = get_permittivity_property_from_lea_lk(path_to_parent_folder=location, sub_folder_name="eps_phi_Plot", quantity="eps_phi_tilde", + frequency=frequency, material_name=material_name, temperature=temperature) return epsilon_r_tilde, epsilon_phi_deg def create_permittivity_file_name_lea_lk(quantity: str = "p_hys", frequency: int = 100000, material_name: str = "N49", temperature: int = 30): + """ + Create the file name for permittivity data of LEA_LK. + + :param quantity: measured quantiy (e.g. p_hys) + :param frequency: frequency value in Hz + :param material_name: name of the material + :param temperature: temperature value in degree + :return: correct file name for LEA_LK + """ return "_".join([quantity, material_name, f"{temperature}C", f"{int(frequency / 1000)}kHz.txt"]) -def get_permittivity_property_from_lea_lk(path_to_parent_folder, quantity: str, frequency: int, - material_name: str, temperature: int, sub_folder_name: str = "Core_Loss"): +def get_permittivity_property_from_lea_lk(path_to_parent_folder, quantity: str, frequency: int, material_name: str, temperature: int, + sub_folder_name: str = "Core_Loss"): + """ + Get the proberty of the permittivity from LEA_LK. + + :param path_to_parent_folder: path to permittivity data + :param quantity: name of the measured quantity + :param frequency: frequency value in Hz + :param material_name: name of the material + :param temperature: temperature value in degree + :param sub_folder_name: name of the sub folder + :return: amplitude of the permittivity, angle of the permittivity + """ filename = create_permittivity_file_name_lea_lk(quantity, frequency, material_name, temperature) complete_path = os.path.join(path_to_parent_folder, sub_folder_name, filename) # mdb_print(complete_path) @@ -1196,10 +1356,17 @@ def get_permittivity_property_from_lea_lk(path_to_parent_folder, quantity: str, data = np.loadtxt(complete_path) # mdb_print(data) return data[:, 0], data[:, 1] +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- -# LEA_MTB +# LEA_MTB ------------------------------------------------------------------------------------------------------------------------------------------------------ def get_permeability_property_from_lea_mtb(path_to_parent_folder): + """ + Get the proberty of the permeability from the material test bench. + + :param path_to_parent_folder: path to permeability data + :return: magnetic flux density, amplitude of the permeability, angle of the permeability + """ # hardcode: select the first file available in the directory # TODO: find a better solution new_list = [lis for lis in os.listdir(path_to_parent_folder) if '.csv' in lis] @@ -1207,13 +1374,25 @@ def get_permeability_property_from_lea_mtb(path_to_parent_folder): return data[:, 4], abs(data[:, 2]), abs(data[:, 3]) -def get_permeability_data_from_lea_mtb(location: str, no_interpolation_values: int = 20): +def get_permeability_data_from_lea_mtb(location: str): # TODO: IS THIS FUNCTION NECESSARY, ONLY CALLS THE UPPER FUNCTION WITHOUT ADDITIONAL FUNCTIONALTY + """ + Get the permeability data from the material test bench. + + :param location: location of the permability data + :return: magnetic flux density, amplitude of the permeability, angle of the permeability + """ b_hys, mu_r_abs, mu_phi_deg = get_permeability_property_from_lea_mtb(path_to_parent_folder=location) return b_hys, mu_r_abs, mu_phi_deg def get_all_frequencies_for_material(material_path): + """ + Get all the frequency values for a given material. + + :param material_path: path to the material + :return: all frequency values in Hz of the given material + """ frequencies_str = os.listdir(material_path) print(frequencies_str) frequencies = [] @@ -1225,6 +1404,12 @@ def get_all_frequencies_for_material(material_path): def get_all_temperatures_for_directory(toroid_path): + """ + Get all the temperature values for a given toroid probe. + + :param toroid_path: path of the toroid probe + :return: all temperature values in degree of the specific toroid probe + """ temperatures_str = os.listdir(toroid_path) temperatures = [] for f_str in temperatures_str: @@ -1236,15 +1421,28 @@ def get_all_temperatures_for_directory(toroid_path): def sigma_from_permittivity(amplitude_relative_equivalent_permittivity, phi_deg_relative_equivalent_permittivity, frequency): - return 2 * np.pi * frequency * amplitude_relative_equivalent_permittivity * \ - (np.cos(np.deg2rad(phi_deg_relative_equivalent_permittivity)) + \ - complex(0, 1) * np.sin(np.deg2rad(phi_deg_relative_equivalent_permittivity))) * epsilon_0 * complex(0, 1) + """ + Calculate the conductivity based on the data of the permittivity. + :param amplitude_relative_equivalent_permittivity: amplitude of the permittivity + :param phi_deg_relative_equivalent_permittivity: angle of the permittivity + :param frequency: frequency value in Hz + :return: conductivity + """ + return 2 * np.pi * frequency * amplitude_relative_equivalent_permittivity * epsilon_0 * j * \ + (np.cos(np.deg2rad(phi_deg_relative_equivalent_permittivity)) + j * np.sin(np.deg2rad(phi_deg_relative_equivalent_permittivity))) +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- -# --- -# unused or externally used +# unused or externally used ------------------------------------------------------------------------------------------------------------------------------------ def find_nearest_frequencies(permeability, frequency): + """ + Find the nearest frequency value for permeability data. + + :param permeability: permeability data + :param frequency: desired frequency value in Hz + :return: two frequency values in Hz with the desired value in between + """ freq_list = [] # mdb_print(f"{freq_list = }") for j in range(len(permeability)): @@ -1260,6 +1458,15 @@ def find_nearest_frequencies(permeability, frequency): def find_nearest_temperatures(permeability, f_l, f_h, temperature): + """ + Find the nearest temperature value between two frequency points. + + :param permeability: permeability data + :param f_l: lower frequency value in Hz + :param f_h: higher frequency value in Hz + :param temperature: desired temperature value in degree + :return: two temperature values in degree with the desired value in between + """ # ------find nearby temperature------ temp_list_l = [] temp_list_h = [] @@ -1275,6 +1482,17 @@ def find_nearest_temperatures(permeability, f_l, f_h, temperature): def getdata_measurements(permeability, variable, frequency, temperature_1, temperature_2, b_t): + """ + Linear interpolation of the permeability data between two temperatures at a constant frequency. + + :param permeability: permeability data + :param variable: desired temperature variable in degree + :param frequency: frequency value in Hz + :param temperature_1: temperature value under the desired value in degree + :param temperature_2: temperature value above the desired value in degree + :param b_t: magnetic flux density + :return: amplitude of the permeability, angle of the permeability + """ for k in range(len(permeability)): if permeability[k]["frequency"] == frequency and permeability[k]["temperature"] == temperature_1: t_mu_phi_1 = interp1d(permeability[k]["flux_density"], permeability[k]["mu_phi_deg"]) @@ -1293,15 +1511,17 @@ def getdata_measurements(permeability, variable, frequency, temperature_1, tempe return mu_r, mu_phi -def export_data(parent_directory: str = "", file_format: str = None, - b_ref_vec: list = None, mu_r_real_vec: list = None, mu_r_imag_vec: list = None, silent: bool = False): +def export_data(parent_directory: str = "", file_format: str = None, b_ref_vec: list = None, mu_r_real_vec: list = None, mu_r_imag_vec: list = None, + silent: bool = False): """ - Method is used to export data from the material database in a certain file format. + Export data from the material database in a certain file format. + :param parent_directory: :param b_ref_vec: reference vector for mu_r_real and mu_r_imag :param mu_r_imag_vec: imaginary part of mu_r_abs as a vector :param mu_r_real_vec: real part of mu_r_abs as a vector :param file_format: export format, e.g. 'pro' to export a .pro-file + :param silent: enables/disables print :parent_directory: """ if file_format == "pro": @@ -1325,14 +1545,17 @@ def export_data(parent_directory: str = "", file_format: str = None, print(f"Data is exported to {parent_directory} in a {file_format}-file.") -def plot_data(material_name: str = None, properties: str = None, - b_ref: list = None, mu_r_real=None, mu_r_imag: list = None): +def plot_data(material_name: str = None, properties: str = None, b_ref: list = None, mu_r_real=None, mu_r_imag: list = None): """ - Method is used to plot certain material properties of materials. - :param b_ref: TODO: parameter is new and will probably cause problems when plotting data, but previous implementation was very static... - :param properties: - :param material_name: - :return: + Plot certain material properties of materials. + + TODO: parameter is new and will probably cause problems when plotting data, but previous implementation was very static... + :param b_ref: magnetic flux density value + :param properties: name of the material properties + :param material_name: name of the material + :param mu_r_real: real part of the permeability + :param mu_r_imag: imaginary part of the permeability + :return: None """ if properties == "mu_r_real": plt.plot(b_ref, mu_r_real) @@ -1348,3 +1571,4 @@ def plot_data(material_name: str = None, properties: str = None, plt.show() print(f"Material properties {properties} of {material_name} are plotted.") +# -------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/materialdatabase/paths_example.py b/materialdatabase/paths_example.py index a871690..187f667 100644 --- a/materialdatabase/paths_example.py +++ b/materialdatabase/paths_example.py @@ -1,4 +1,4 @@ - +"""Instruction on how to create the paths.py.""" # For some tasks/scripts paths to specific folders are needed. These paths are located in the paths.py file. # Every user needs to create their own paths.py in their local repository of the materialdatabase. # First step is to create a new .py-file with the name paths.py. The file needs to be located in the same folder as this example-file. diff --git a/materialdatabase/scripts/write_LEA_LK_permeability_data_into_database.py b/materialdatabase/scripts/write_LEA_LK_permeability_data_into_database.py index e8b0d5c..abd9ae3 100644 --- a/materialdatabase/scripts/write_LEA_LK_permeability_data_into_database.py +++ b/materialdatabase/scripts/write_LEA_LK_permeability_data_into_database.py @@ -1,3 +1,4 @@ +"""Script to write permeability data by LEA_LK into the material database.""" from materialdatabase.material_data_base_functions import * from materialdatabase.material_data_base_classes import * from materialdatabase.paths import my_LEA_LK_measurement_path diff --git a/materialdatabase/scripts/write_LEA_LK_permittivity_data_into_database.py b/materialdatabase/scripts/write_LEA_LK_permittivity_data_into_database.py index f369804..fc93097 100644 --- a/materialdatabase/scripts/write_LEA_LK_permittivity_data_into_database.py +++ b/materialdatabase/scripts/write_LEA_LK_permittivity_data_into_database.py @@ -1,3 +1,4 @@ +"""Script to write permittivity data by LEA_LK into the material database.""" import numpy as np from materialdatabase.material_data_base_functions import * diff --git a/materialdatabase/scripts/write_LEA_MTB_data_into_database.py b/materialdatabase/scripts/write_LEA_MTB_data_into_database.py index 76cc8a7..b1a6e56 100644 --- a/materialdatabase/scripts/write_LEA_MTB_data_into_database.py +++ b/materialdatabase/scripts/write_LEA_MTB_data_into_database.py @@ -1,3 +1,4 @@ +"""Script to write data by Magnetics-TestBench into the material database.""" from materialdatabase.material_data_base_classes import * from materialdatabase.paths import my_MTB_measurements_path from datetime import date @@ -11,9 +12,8 @@ material_name = Material.DMR96A2 toroid_name = ToroidDirectoryName.DMR96A_2 create_permeability_measurement_in_database(Material.DMR96A2, MeasurementSetup.LEA_MTB, company=Company.UPB, date=str(date.today()), - test_setup_name=MeasurementSetup.LEA_MTB, - toroid_dimensions=toroid_name, measurement_method=MeasurementMethod.Electric, - equipment_names=MeasurementDevice.zimmer) + test_setup_name=MeasurementSetup.LEA_MTB, toroid_dimensions=toroid_name, + measurement_method=MeasurementMethod.Electric, equipment_names=MeasurementDevice.ZESZimmer) # General Path to measurements destination mtb_post_pro_path = os.path.join(my_MTB_measurements_path, "post_processing_data_17_08_2023") diff --git a/materialdatabase/scripts/write_MagNet_permeability_into_database.py b/materialdatabase/scripts/write_MagNet_permeability_into_database.py index a9806eb..e481fa2 100644 --- a/materialdatabase/scripts/write_MagNet_permeability_into_database.py +++ b/materialdatabase/scripts/write_MagNet_permeability_into_database.py @@ -1,3 +1,4 @@ +"""Script to write permeability data by MagNet into the material database.""" from materialdatabase.material_data_base_classes import * import pandas as pd import os @@ -18,8 +19,7 @@ fig, ax = plt.subplots(3) for frequency in f_sine_lim_clustered_set: if len(df[df["frequency"] == frequency]["b"]) > min_number_of_measurements: - b_ref, mu_r, mu_phi_deg = np.array(df[df["frequency"] == frequency]["b"]), \ - np.array(df[df["frequency"] == frequency]["mu_r_abs"]), \ + b_ref, mu_r, mu_phi_deg = np.array(df[df["frequency"] == frequency]["b"]), np.array(df[df["frequency"] == frequency]["mu_r_abs"]), \ np.array(df[df["frequency"] == frequency]["mu_phi_deg"]) b_ref, mu_r, mu_phi_deg = sort_data(b_ref, mu_r, mu_phi_deg) diff --git a/materialdatabase/scripts/write_datasheet_permeability_data_into_database.py b/materialdatabase/scripts/write_datasheet_permeability_data_into_database.py index fe6835b..918ed65 100644 --- a/materialdatabase/scripts/write_datasheet_permeability_data_into_database.py +++ b/materialdatabase/scripts/write_datasheet_permeability_data_into_database.py @@ -1,3 +1,4 @@ +"""Write permeability data of datasheets into the database.""" from materialdatabase.material_data_base_classes import * import materialdatabase.paths as paths import datetime diff --git a/materialdatabase/scripts/write_wayne_kerr_permeability_data_into_database.py b/materialdatabase/scripts/write_wayne_kerr_permeability_data_into_database.py index 360c164..ad90b22 100644 --- a/materialdatabase/scripts/write_wayne_kerr_permeability_data_into_database.py +++ b/materialdatabase/scripts/write_wayne_kerr_permeability_data_into_database.py @@ -1,3 +1,4 @@ +"""Script to write permeability data by the impedance analyzer into the material database.""" import matplotlib.pyplot as plt from scipy import constants from materialdatabase.utils import L_from_Z, get_closest @@ -131,21 +132,13 @@ flag_overwrite = True create_empty_material(material_name, manufacturer) - create_permeability_measurement_in_database(material_name, measurement_setup=MeasurementSetup.LEA_MTB_small_signal, - company=Company.UPB, date=str(date.today()), - test_setup_name=MeasurementSetup.LEA_MTB_small_signal, - toroid_dimensions=core_name, - measurement_method=MeasurementMethod.ImpedanceAnalyzer, - equipment_names=MeasurementDevice.wayne_kerr, comment="") + create_permeability_measurement_in_database(material_name, measurement_setup=MeasurementSetup.LEA_MTB_small_signal, company=Company.UPB, + date=str(date.today()), test_setup_name=MeasurementSetup.LEA_MTB_small_signal, toroid_dimensions=core_name, + measurement_method=MeasurementMethod.ImpedanceAnalyzer, equipment_names=MeasurementDevice.WayneKerr, comment="") for i, frequency in enumerate(f[indices]): - write_permeability_data_into_database(frequency=frequency, - temperature=temperature_db, - b_ref=b_ref, - mu_r_abs=[db_mu_r_abs[i], db_mu_r_abs[i]], - mu_phi_deg=[db_mu_phi_deg[i], db_mu_phi_deg[i]], - material_name=material_name, - measurement_setup=MeasurementSetup.LEA_MTB_small_signal, - overwrite=flag_overwrite) + write_permeability_data_into_database(frequency=frequency, temperature=temperature_db, b_ref=b_ref, mu_r_abs=[db_mu_r_abs[i], db_mu_r_abs[i]], + mu_phi_deg=[db_mu_phi_deg[i], db_mu_phi_deg[i]], material_name=material_name, + measurement_setup=MeasurementSetup.LEA_MTB_small_signal, overwrite=flag_overwrite) flag_overwrite = False diff --git a/materialdatabase/scripts/write_wayne_kerr_permittivity_data_into_database.py b/materialdatabase/scripts/write_wayne_kerr_permittivity_data_into_database.py index efe9bbb..6b24a44 100644 --- a/materialdatabase/scripts/write_wayne_kerr_permittivity_data_into_database.py +++ b/materialdatabase/scripts/write_wayne_kerr_permittivity_data_into_database.py @@ -1,3 +1,4 @@ +"""Script to write permittivity data measured with the impedance analyzer into the database.""" from scipy import constants from materialdatabase.utils import get_closest, Z_from_amplitude_and_angle from materialdatabase.material_data_base_classes import * @@ -62,12 +63,10 @@ if write_data: create_empty_material(material_name, manufacturer) - create_permittivity_measurement_in_database(material_name, measurement_setup=MeasurementSetup.LEA_MTB_small_signal, - company=Company.UPB, date=str(date.today()), - test_setup_name=MeasurementSetup.LEA_MTB_small_signal, - probe_dimensions=core_name, - measurement_method=MeasurementMethod.ImpedanceAnalyzer, - equipment_names=MeasurementDevice.wayne_kerr, comment="") + create_permittivity_measurement_in_database(material_name, measurement_setup=MeasurementSetup.LEA_MTB_small_signal, company=Company.UPB, + date=str(date.today()), test_setup_name=MeasurementSetup.LEA_MTB_small_signal, probe_dimensions=core_name, + measurement_method=MeasurementMethod.ImpedanceAnalyzer, equipment_names=MeasurementDevice.WayneKerr, + comment="") write_permittivity_data_into_database(temperature_db, list(f[indices]), list(db_eps_tilde_amplitude), list(db_eps_tilde_angle), material_name=material_name, measurement_setup=MeasurementSetup.LEA_MTB_small_signal) diff --git a/materialdatabase/trial_database.py b/materialdatabase/trial_database.py index 959b4ed..399044f 100644 --- a/materialdatabase/trial_database.py +++ b/materialdatabase/trial_database.py @@ -1,3 +1,4 @@ +"""Examples of differtent functions for the material database.""" import material_data_base_classes as mdb database = mdb.MaterialDatabase() diff --git a/materialdatabase/utils.py b/materialdatabase/utils.py index 368ecd6..3d104c8 100644 --- a/materialdatabase/utils.py +++ b/materialdatabase/utils.py @@ -1,11 +1,20 @@ +"""Collection of smaller functions.""" import copy import numpy as np import ntpath j = complex(0, 1) + def crop(x_full, y_full, xa, xb): - """Crops two 1D arrays for the interval [a, b] according to x wothout changing the inputs. + """ + Crops two 1D arrays for the interval [a, b] according to x without changing the inputs. + + :param x_full: array of the uncropped x-data + :param y_full: array of the uncropped y-data + :param xa: lower boundary of the interval + :param xb: upper boundary of the interval + :return: croped arrays of x_full and y_full """ x = copy.deepcopy(x_full) y = copy.deepcopy(y_full) @@ -15,14 +24,38 @@ def crop(x_full, y_full, xa, xb): x = x[xa <= x] return x, y + def path_leaf(path): + """ + Return the tail of the path. + + :param path: path + :return: tail of path + """ head, tail = ntpath.split(path) return tail or ntpath.basename(head) + def L_from_Z(Z, phi_deg, f): + """ + Calculate the inductance L based on amplitude and phase angle of the impedance Z. + + :param Z: measured impedance Z in Ω + :param phi_deg: measured phase angle phi in degree + :param f: measured frequency f in Hz + :return: calculated inductance in H based on given data + """ return Z * np.array(np.sin(np.deg2rad(phi_deg)) - j * np.cos(np.deg2rad(phi_deg))) / (2*np.pi*f) + def get_closest(to_search, x): + """ + Search an array for specific values and return the closest values. + + :param to_search: array with values to search for + :param x: array to search for the values + :return: list with the closest values to the wanted values + """ neighbours = [] for element in to_search: index = 0 @@ -35,5 +68,13 @@ def get_closest(to_search, x): break return neighbours + def Z_from_amplitude_and_angle(amplitude, angle_deg): + """ + Calculate the complex impedance given the amplitude and phase angle of the impedance. + + :param amplitude: amplitude of the impedance in Ω + :param angle_deg: phase angle of the impedance in degree + :return: complex impedance in Ω + """ return amplitude * np.array(np.cos(np.deg2rad(angle_deg)) + j * np.sin(np.deg2rad(angle_deg))) diff --git a/ruff.toml b/ruff.toml index 18a619d..b91a9cd 100644 --- a/ruff.toml +++ b/ruff.toml @@ -11,7 +11,7 @@ indent-width = 4 target-version = "py39" [lint] -select = ["E4", "E7", "E9", "F", "B"] +select = ["E4", "E7", "E9", "F", "B", "D"] # extend-select = ["D417"] deactivated by default in case of pep257 codestyle. # see also: https://docs.astral.sh/ruff/rules/undocumented-param/ ignore = ["B008", "D107", "D203", "D212", "D213", "D402", "D413", "D415", "D416", "E722", "E731", "F403", "F405", "F841",] diff --git a/tests/material_data_base_classes_test.py b/tests/material_data_base_classes_test.py index d2bec72..d8218fe 100644 --- a/tests/material_data_base_classes_test.py +++ b/tests/material_data_base_classes_test.py @@ -1,9 +1,19 @@ +"""Provides some functions to test/check classes.""" import pytest import materialdatabase as mdb import os def compare_pro_files(first_pro_filepath, second_pro_filepath, significant_digits=6): + """ + Compare two files of possible differences. + + If differences exist -> function raises AssertionError + :param first_pro_filepath: path of first file + :param second_pro_filepath: path of second file + :param significant_digits: number of significant digits + :return: None + """ difference = [] with open(first_pro_filepath, "r") as fd: @@ -22,8 +32,14 @@ def compare_pro_files(first_pro_filepath, second_pro_filepath, significant_digit assert difference == [] + @pytest.fixture def temp_folder(): + """ + Create a folder with name temp in same path as this file. + + :return: None + """ # Setup temp folder temp_folder_path = os.path.join(os.path.dirname(__file__), "temp") @@ -33,7 +49,14 @@ def temp_folder(): # Test yield temp_folder_path + def test(temp_folder): + """ + Tests the path of the created temporary folder. + + :param temp_folder: path to folder temp + :return: None + """ database = mdb.MaterialDatabase(is_silent=False) T = 100 @@ -43,9 +66,8 @@ def test(temp_folder): parent_directory = temp_folder pro_filepath = os.path.join(temp_folder, "core_materials_temp.pro") pro_verification_filepath = os.path.join(os.path.dirname(__file__), "fixtures", "core_materials_temp_n95_100000Hz_100deg.pro") - b_ref, mu_r_imag, mu_r_real = database.permeability_data_to_pro_file(temperature=T, frequency=f, material_name=material_name, - datasource=datasource, datatype="complex_permeability", - parent_directory=parent_directory) + b_ref, mu_r_imag, mu_r_real = database.permeability_data_to_pro_file(temperature=T, frequency=f, material_name=material_name, datasource=datasource, + datatype="complex_permeability", parent_directory=parent_directory) print(f"{ b_ref = }") print(f"{mu_r_imag = }") print(f"{mu_r_real = }") diff --git a/tests/mdb_functions_test.py b/tests/mdb_functions_test.py index a3013c9..7b32ada 100644 --- a/tests/mdb_functions_test.py +++ b/tests/mdb_functions_test.py @@ -1,3 +1,4 @@ +"""Provides some functions to test/check other functions.""" import pytest import materialdatabase as mdb import numpy as np @@ -5,8 +6,13 @@ mdb_instance = mdb.MaterialDatabase() + def test_get_material_property(): + """ + Tests the functionality to get the material properties of a ferrite of the material database. + :return: None + """ initial_mu_r_abs = mdb_instance.get_material_attribute(material_name=mdb.Material.N95, attribute="initial_permeability") assert initial_mu_r_abs == pytest.approx(3000, rel=1e-3) @@ -15,8 +21,7 @@ def test_get_material_property(): b_ref, mu_r_real, mu_r_imag = mdb_instance.permeability_data_to_pro_file(temperature=25, frequency=150000, material_name=mdb.Material.N95, datatype=mdb.MeasurementDataType.ComplexPermeability, - datasource=mdb.MaterialDataSource.ManufacturerDatasheet, - parent_directory="") + datasource=mdb.MaterialDataSource.ManufacturerDatasheet, parent_directory="") b_ref = np.array(b_ref) @@ -29,15 +34,19 @@ def test_get_material_property(): assert mu_r_real == pytest.approx(mu_r_real_test_ref, rel=1e-3) assert mu_r_imag == pytest.approx(mu_r_imag_test_ref, rel=1e-3) - epsilon_r, epsilon_phi_deg = mdb_instance.get_permittivity(temperature=25, frequency=150000, material_name=mdb.Material.N95, - datasource=mdb.MaterialDataSource.Measurement, - datatype=mdb.MeasurementDataType.ComplexPermittivity, + epsilon_r, epsilon_phi_deg = mdb_instance.get_permittivity(temperature=25, frequency=150000, datasource=mdb.MaterialDataSource.Measurement, + material_name=mdb.Material.N95, datatype=mdb.MeasurementDataType.ComplexPermittivity, measurement_setup=mdb.MeasurementSetup.LEA_LK, interpolation_type="linear") assert epsilon_r == pytest.approx(89591, rel=1e-3) assert epsilon_phi_deg == pytest.approx(19.6, rel=1e-3) def test_interpolation(): + """ + Tests the function interpolate_b_dependent_quantity_in_temperature_and_frequency(). + + :return: None + """ temperature = 45 frequency = 140000 T_low = 25 @@ -58,10 +67,8 @@ def test_interpolation(): mu_T_high_f_high = [2300, 2500, 3000, 3200] (result) = mdb.interpolate_b_dependent_quantity_in_temperature_and_frequency(temperature, frequency, T_low, T_high, f_low, f_high, - b_T_low_f_low, mu_T_low_f_low, - b_T_high_f_low, mu_T_high_f_low, - b_T_low_f_high, mu_T_low_f_high, - b_T_high_f_high, mu_T_high_f_high) + b_T_low_f_low, mu_T_low_f_low, b_T_high_f_low, mu_T_high_f_low, + b_T_low_f_high, mu_T_low_f_high, b_T_high_f_high, mu_T_high_f_high) result = np.array(result) correct_result = [[2.0, 2.28571429, 2.57142857, 2.85714286, 3.14285714, 3.42857143, 3.71428571, 4.0], @@ -69,25 +76,28 @@ def test_interpolation(): assert result[0] == pytest.approx(correct_result[0], rel=1e-3) assert result[1] == pytest.approx(correct_result[1], rel=1e-3) + def test_neighbourhood(): - correct_result_neighbourhood = { - 'T_low_f_low': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 300000, 'index': 2}, - 'epsilon_r': 40993.333333333336, 'epsilon_phi_deg': 24.637}, - 'T_low_f_high': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 400000, 'index': 3}, - 'epsilon_r': 38544.333333333336, 'epsilon_phi_deg': 22.727}, - 'T_high_f_low': {'temperature': {'value': 100, 'index': 1}, 'frequency': {'value': 300000, 'index': 2}, - 'epsilon_r': 45899.333333333336, 'epsilon_phi_deg': 28.648}, - 'T_high_f_high': {'temperature': {'value': 100, 'index': 1}, 'frequency': {'value': 400000, 'index': 3}, - 'epsilon_r': 42960.666666666664, 'epsilon_phi_deg': 27.502}} - - list_of_permittivity_dicts = mdb_instance.load_permittivity_measurement(material_name="N49", datasource="measurements", - measurement_setup="LEA_LK") + """ + Tests the class neighbourhood. + + :return: None + """ + correct_result_neighbourhood = {'T_low_f_low': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 300000, 'index': 2}, + 'epsilon_r': 40993.333333333336, 'epsilon_phi_deg': 24.637}, + 'T_low_f_high': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 400000, 'index': 3}, + 'epsilon_r': 38544.333333333336, 'epsilon_phi_deg': 22.727}, + 'T_high_f_low': {'temperature': {'value': 100, 'index': 1}, 'frequency': {'value': 300000, 'index': 2}, + 'epsilon_r': 45899.333333333336, 'epsilon_phi_deg': 28.648}, + 'T_high_f_high': {'temperature': {'value': 100, 'index': 1}, 'frequency': {'value': 400000, 'index': 3}, + 'epsilon_r': 42960.666666666664, 'epsilon_phi_deg': 27.502}} + + list_of_permittivity_dicts = mdb_instance.load_permittivity_measurement(material_name="N49", datasource="measurements", measurement_setup="LEA_LK") T = 64 f = 450000 - neighbourhood = mdb.create_permittivity_neighbourhood(temperature=T, frequency=f, - list_of_permittivity_dicts=list_of_permittivity_dicts) + neighbourhood = mdb.create_permittivity_neighbourhood(temperature=T, frequency=f, list_of_permittivity_dicts=list_of_permittivity_dicts) difference = deepdiff.DeepDiff(neighbourhood, correct_result_neighbourhood, ignore_order=True, significant_digits=3) print(f"{difference = }") @@ -96,26 +106,33 @@ def test_neighbourhood(): def test_load_permittivity_measurement(): - load_permittivity_measurement_result = \ - {'T_low_f_low': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 100000.0, 'index': 0}, - 'epsilon_r': 61294.333333333336, 'epsilon_phi_deg': 36.85999999999999}, - 'T_low_f_high': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 100000.0, 'index': 0}, - 'epsilon_r': 61294.333333333336, 'epsilon_phi_deg': 36.85999999999999}, - 'T_high_f_low': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 100000.0, 'index': 0}, - 'epsilon_r': 61294.333333333336, 'epsilon_phi_deg': 36.85999999999999}, - 'T_high_f_high': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 100000.0, 'index': 0}, - 'epsilon_r': 61294.333333333336, 'epsilon_phi_deg': 36.85999999999999}} - - list_of_permittivity_dicts = mdb_instance.load_permittivity_measurement(material_name="N49", datasource="measurements", - measurement_setup="LEA_LK") - - create_dict = mdb.create_permittivity_neighbourhood(temperature=60, frequency=1e5, - list_of_permittivity_dicts=list_of_permittivity_dicts) + """ + Tests the function load_permittivity_measurement(). + + :return: None + """ + load_permittivity_measurement_result = {'T_low_f_low': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 100000.0, 'index': 0}, + 'epsilon_r': 61294.333333333336, 'epsilon_phi_deg': 36.85999999999999}, + 'T_low_f_high': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 100000.0, 'index': 0}, + 'epsilon_r': 61294.333333333336, 'epsilon_phi_deg': 36.85999999999999}, + 'T_high_f_low': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 100000.0, 'index': 0}, + 'epsilon_r': 61294.333333333336, 'epsilon_phi_deg': 36.85999999999999}, + 'T_high_f_high': {'temperature': {'value': 60, 'index': 0}, 'frequency': {'value': 100000.0, 'index': 0}, + 'epsilon_r': 61294.333333333336, 'epsilon_phi_deg': 36.85999999999999}} + + list_of_permittivity_dicts = mdb_instance.load_permittivity_measurement(material_name="N49", datasource="measurements", measurement_setup="LEA_LK") + + create_dict = mdb.create_permittivity_neighbourhood(temperature=60, frequency=1e5, list_of_permittivity_dicts=list_of_permittivity_dicts) assert not deepdiff.DeepDiff(load_permittivity_measurement_result, create_dict, ignore_order=True, significant_digits=3) def test_mypolate(): + """ + Tests the function my_polate_linear(). + + :return: None + """ a = 10 b = 20 f_a = 100 @@ -163,6 +180,11 @@ def test_mypolate(): def test_find_nearest_neighbours(): + """ + Tests the function find_nearest_neighbours(). + + :return: None + """ list_to_search_in = [10] print("Case 0")