From 7ea02ad0f0cd79044ed4f53ee0f9c0304d74c985 Mon Sep 17 00:00:00 2001 From: abujazar Date: Mon, 23 Oct 2023 04:58:17 +0200 Subject: [PATCH 1/6] discription of core_parts --- femmt/component.py | 52 ++++++++++++++++------------- femmt/thermal/thermal_simulation.py | 34 +++++++++++++++---- 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/femmt/component.py b/femmt/component.py index 8cc93a01..f28580a1 100644 --- a/femmt/component.py +++ b/femmt/component.py @@ -262,7 +262,7 @@ def thermal_simulation(self, thermal_conductivity_dict: Dict, boundary_temperatu # Power density for volumes W/m^3 #core_area = self.calculate_core_volume() core_area = self.calculate_core_parts_volume() - #core_area = ff.calculate_cylinder_volume() + # Set wire radii @@ -647,15 +647,18 @@ def calculate_core_volume(self) -> float: def calculate_core_parts_volume(self) -> list: - """Calculates the volume of the core excluding air. + """Calculates the volume of the part core excluding air. :return: Volume of the core. :rtype: list """ + # Extract heights from the midpoints of air gaps heights = [point[2] for point in self.air_gaps.midpoints] core_part_volume = [] + # Helper function to calculate width based on part number and stray path def get_width(part_number): + """ If there is a stray path, calculate width based on its starting index and part number""" if self.stray_path: if self.stray_path.start_index == 0: if part_number == 2: @@ -667,9 +670,11 @@ def get_width(part_number): return self.stray_path.length elif part_number == 3: return self.core.core_inner_diameter / 2 + # Default width calculation return self.core.core_inner_diameter / 2 if self.core.core_type == CoreType.Single: + # For single core type and integrated transformer component type if self.component_type == ComponentType.IntegratedTransformer: # Calculate heights dynamically @@ -688,7 +693,7 @@ def get_width(part_number): third_topmost_airgap_height = sorted_midpoints[-3][2] - + #subpart1 subpart1_1_height = bottommost_airgap_position + self.core.window_h / 2 - bottommost_airgap_height / 2 + self.core.core_inner_diameter / 4 subpart1_1_width = self.core.core_inner_diameter / 2 subpart1_1_volume = np.pi * subpart1_1_width ** 2 * subpart1_1_height @@ -708,15 +713,17 @@ def get_width(part_number): subpart1_4_width = self.core.window_w subpart1_4_volume = np.pi * subpart1_4_width ** 2 * subpart1_4_height - #subpart1_5_height = self.air_gaps.midpoints[self.stray_path.start_index+1][1] - self.air_gaps.midpoints[self.stray_path.start_index+1][2] / 2 + #subpart5 subpart1_5_height = self.core.window_h / 2 - topmost_airgap_position - topmost_airgap_height / 2 + self.core.core_inner_diameter / 4 subpart1_5_width = self.core.core_inner_diameter / 2 subpart1_5_volume = np.pi * subpart1_5_width ** 2 * subpart1_5_height + # Calculate the volume of core part 1 by summing up subpart volumes core_part_1_volume = subpart1_1_volume + subpart1_2_volume + subpart1_3_volume + subpart1_4_volume + subpart1_5_volume core_part_volume.append(core_part_1_volume) # #core_part_2 + # If there are multiple sorted midpoints, calculate the volume of core part 2 if len(sorted_midpoints) > 1: core_part_2_height = topmost_airgap_position - topmost_airgap_height / 2 - (second_topmost_airgap_position + second_topmost_airgap_height / 2) core_part_2_width = get_width(2) @@ -725,6 +732,7 @@ def get_width(part_number): core_part_volume.append(core_part_2_volume) #core_part_3 + # If there are more than two sorted midpoints, calculate the volume of core part 3 if len(sorted_midpoints) > 2: core_part_3_height = second_topmost_airgap_position - second_topmost_airgap_height / 2 - (third_topmost_airgap_position + third_topmost_airgap_height / 2) core_part_3_width = get_width(3) @@ -732,18 +740,22 @@ def get_width(part_number): core_part_3_volume = np.pi * core_part_3_width ** 2 * core_part_3_height core_part_volume.append(core_part_3_volume) - + # Return the total core part volume return core_part_volume else: + # In case of non-integrated transformer components, the core volume is calculated directly without + # considering individual core parts. It uses the 'calculate_core_volume' method to compute the total core volume. (for thermal simulation) return [self.calculate_core_volume()] elif self.core.core_type == CoreType.Stacked: + # For stacked core types, the volume is divided into different core parts, each of which is further + # divided into subparts to calculate the total volume of each core part. - # core_part_1 - # core_part_1 is divided into 3 subparts + # Core Part 1 Calculation + # Core part 1 is calculated as the sum of three different subparts # subpart_1 subpart1_1_height = self.core.window_h_bot / 2 + self.core.core_inner_diameter / 4 - heights[0] / 2 subpart1_1_width = self.core.core_inner_diameter / 2 @@ -759,6 +771,7 @@ def get_width(part_number): subpart1_3_width = self.core.r_outer - self.core.r_inner subpart1_3_volume = np.pi * subpart1_3_width ** 2 * subpart1_3_height + # Summing up the volumes of the subparts to get the total volume of core part 1 core_part_1_volume = subpart1_1_volume + subpart1_2_volume + subpart1_3_volume core_part_volume.append(core_part_1_volume) @@ -796,24 +809,13 @@ def get_width(part_number): subpart5_3_height = self.core.window_h_top + self.core.core_inner_diameter / 4 subpart5_3_width = self.core.r_outer - self.core.r_inner subpart5_3_volume = np.pi * subpart5_3_width ** 2 * subpart5_3_height - + # Summing up the volumes of the subparts to get the total volume of core_part_5 core_part_5_volume = subpart5_1_volume + subpart5_2_volume + subpart5_3_volume core_part_volume.append(core_part_5_volume) + # Returning the final list of core part volumes return core_part_volume - # if self.core.core_type == CoreType.Single: - # cylinder_height = self.core.window_h + self.core.core_inner_diameter / 2 - # elif self.core.core_type == CoreType.Stacked: - # cylinder_height = self.core.window_h_bot + self.core.window_h_top + self.core.core_inner_diameter * 3 / 4 - # cylinder_diameter = self.core.r_outer - # - # core_volumes = [] # Initialize list to store each volume - # - # for _ in self.mesh.plane_surface_core: - # volume = ff.calculate_cylinder_volume(cylinder_diameter, cylinder_height) - # core_volumes.append(volume) - # - # return core_volumes # Return the list of volumes + def calculate_core_weight(self) -> float: """ @@ -2259,6 +2261,8 @@ def calculate_and_write_log(self, sweep_number: int = 1, currents: List = None, sweep_dict["core_hyst_losses"] = self.load_result(res_name="p_hyst", last_n=sweep_number)[sweep_run] # Core Part losses + # If there are multiple core parts, calculate losses for each part individually + # the core losses are caluclated by summing the eddy and hyst losses if len(self.mesh.plane_surface_core) > 1: sweep_dict["core_parts"] = {} for i in range(0, len(self.mesh.plane_surface_core)): @@ -2272,6 +2276,7 @@ def calculate_and_write_log(self, sweep_number: int = 1, currents: List = None, hyst = sweep_dict["core_parts"][f"core_part_{i + 1}"]["hyst_losses"] sweep_dict["core_parts"][f"core_part_{i + 1}"][f"total_core_part_{i + 1}"] = eddy + hyst + # For a single core part, total losses are simply the sum of eddy and hysteresis losses else: # if I have only one core_part sweep_dict["core_parts"] = {} # parent dictionary is initialized first @@ -2320,12 +2325,13 @@ def calculate_and_write_log(self, sweep_number: int = 1, currents: List = None, # Core log_dict["total_losses"]["eddy_core"] = sum( log_dict["single_sweeps"][d]["core_eddy_losses"] for d in range(len(log_dict["single_sweeps"]))) - # setting the total for every core_part in total losses dict + # In the total losses calculation, individual core part losses are also accounted for if len(self.mesh.plane_surface_core) > 1: for i in range(len(self.mesh.plane_surface_core)): log_dict["total_losses"][f"total_core_part_{i + 1}"] = sweep_dict["core_parts"][f"core_part_{i + 1}"][ f"total_core_part_{i + 1}"] - if len(self.mesh.plane_surface_core) == 1: # core and core_part_1 will be the same + # If there is only one core part, set its total losses directly + if len(self.mesh.plane_surface_core) == 1: log_dict["total_losses"]["total_core_part_1"] = sweep_dict["core_parts"]["core_part_1"]["total_core_part_1"] diff --git a/femmt/thermal/thermal_simulation.py b/femmt/thermal/thermal_simulation.py index 0e9c3c8d..e8047978 100644 --- a/femmt/thermal/thermal_simulation.py +++ b/femmt/thermal/thermal_simulation.py @@ -67,16 +67,28 @@ def create_background(background_tag, k_air, function_pro: FunctionPro, group_pr def create_core_and_air_gaps(core_tags, k_core, core_area, core_parts_losses, air_gaps_tag, k_air_gaps, function_pro: FunctionPro, group_pro: GroupPro): - - + """ + Creates core and air gaps configurations with associated thermal properties. + + :param core_tags: Tags identifying different parts of the core. + :param k_core: Thermal conductivity of the core. + :param core_area: Areas of different core parts. + :param core_parts_losses: losses in different core parts. + :param air_gaps_tag: Tag identifying the air gaps. + :param k_air_gaps: Thermal conductivity of the air gaps. + :param function_pro: Object to manage function properties. + :param group_pro: Object to manage group properties. + """ + # Initialize dictionaries for volumetric heat flux, thermal conductivity, and region q_vol = {} # Dictionary to hold volumetric heat flux for each core part k = {} # Dictionary to hold thermal conductivity for each core part regions = {} # Dictionary to hold regions for each core part core_total_str = "{" + # Convert core tags to a list of lists for consistency core_tags = [[tag] for tag in core_tags] for index, tag in enumerate(core_tags): - #tag = tag_list[0] + # Create a unique name for each core part based on its index name = f"core_part_{index + 1}" # Create a name for the core part based on its position core_total_str += f"{name}, " @@ -89,6 +101,7 @@ def create_core_and_air_gaps(core_tags, k_core, core_area, core_parts_losses, ai # Associate the core part name with its tag regions[name] = tag[0] # as Tag is list of list + # If air gaps are defined, assign thermal conductivity and tag if air_gaps_tag is not None: k["air_gaps"] = k_air_gaps regions["air_gaps"] = air_gaps_tag @@ -148,6 +161,14 @@ def create_windings(winding_tags, k_windings, winding_losses, conductor_radii, w def create_post_operation(thermal_file_path, thermal_influx_file_path, thermal_material_file_path, sensor_points_file, core_file, insulation_file, winding_file, windings, core_parts, print_sensor_values, post_operation_pro: PostOperationPro, flag_insulation): + """ + Configures post-operation properties for a thermal simulation. + + :param ...: (Include detailed description for each parameter as needed) + :param post_operation_pro: Object to manage post-operation properties. + :param flag_insulation: Flag indicating the presence of insulation. + """ + # Add pos file generation post_operation_pro.add_on_elements_of_statement("T", "Total", thermal_file_path) post_operation_pro.add_on_elements_of_statement("influx", "Warm", thermal_influx_file_path) @@ -176,9 +197,7 @@ def create_post_operation(thermal_file_path, thermal_influx_file_path, thermal_m # Add regions #core file will be GmshParsed file as we have many core parts - # for core_index, core_part in enumerate(core_parts): # Assuming core_tags is a list of core tags - # name = f"core_part_{core_index + 1}" - # post_operation_pro.add_on_elements_of_statement("T", name, core_file, "GmshParsed", 0, name, True) + # Adding temperature post-operation statements for each core part if they are defined core_parts = [[part] for part in core_parts] core_append = False # Initialize the append flag for core parts for core_index, core_part in enumerate(core_parts): @@ -191,10 +210,11 @@ def create_post_operation(thermal_file_path, thermal_influx_file_path, thermal_m core_append = True - + # Adding temperature post-operation statement for insulation if insulation is present if flag_insulation: post_operation_pro.add_on_elements_of_statement("T", "insulation", insulation_file, "SimpleTable", 0) + # Adding temperature post-operation statements for each winding, considering the case of parallel windings append = False for winding_index, winding in enumerate(windings): if winding is not None and len(winding) > 0: From 5d294255a526bacd0b01f6764eadd50252b090d5 Mon Sep 17 00:00:00 2001 From: abujazar Date: Fri, 27 Oct 2023 03:20:40 +0200 Subject: [PATCH 2/6] fix thermal simulation for more than one airgap. It is detected now dynamically --- femmt/component.py | 132 ++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 75 deletions(-) diff --git a/femmt/component.py b/femmt/component.py index 81757b1e..ea2d59c3 100644 --- a/femmt/component.py +++ b/femmt/component.py @@ -646,109 +646,92 @@ def calculate_core_volume(self) -> float: return np.pi * (core_width ** 2 * core_height - ( inner_leg_width + winding_width) ** 2 * winding_height + inner_leg_width ** 2 * winding_height) - air_gap_volume - def calculate_core_parts_volume(self) -> list: """Calculates the volume of the part core excluding air. - :return: Volume of the core. + :return: Volume of the core part. :rtype: list """ # Extract heights from the midpoints of air gaps heights = [point[2] for point in self.air_gaps.midpoints] - core_part_volume = [] + core_parts_volumes = [] - # Helper function to calculate width based on part number and stray path def get_width(part_number): - """ If there is a stray path, calculate width based on its starting index and part number""" - if self.stray_path: - if self.stray_path.start_index == 0: - if part_number == 2: - return self.core.core_inner_diameter / 2 - elif part_number == 3: - return self.stray_path.length - elif self.stray_path.start_index == 1: - if part_number == 2: - return self.stray_path.length - elif part_number == 3: - return self.core.core_inner_diameter / 2 - # Default width calculation + """ + If there is a stray path, calculate width based on its starting index and part number. + part_number is the core_part_i+2; means that if the start_index is 0, the stray path is in core_part_2 + if the start_index is 1, the stray path is in core_part_3 and so on + + """ + + if self.stray_path and part_number == self.stray_path.start_index + 2: + return self.stray_path.length return self.core.core_inner_diameter / 2 + # if single core if self.core.core_type == CoreType.Single: - # For single core type and integrated transformer component type - if self.component_type == ComponentType.IntegratedTransformer: + # For single core type and many core_parts (due to multiple airgaps) + if len(self.mesh.plane_surface_core) > 1: - # Calculate heights dynamically + # For single core and more than one core_part, volume for every core part is calculated + # # Sorting air gaps from lower to upper sorted_midpoints = sorted(self.air_gaps.midpoints, key=lambda x: x[1]) - #finding position of first airgap + # Finding position of first airgap bottommost_airgap_position = sorted_midpoints[0][1] bottommost_airgap_height = sorted_midpoints[0][2] - #finding position of last airgap + # Finding position of last airgap topmost_airgap_position = sorted_midpoints[-1][1] topmost_airgap_height = sorted_midpoints[-1][2] - # finding position to get the distance between two airgaps - second_topmost_airgap_position = sorted_midpoints[-2][1] - second_topmost_airgap_height = sorted_midpoints[-2][2] - # finding position to get the distance between two airgaps - third_topmost_airgap_position = sorted_midpoints[-3][1] - third_topmost_airgap_height = sorted_midpoints[-3][2] - - #subpart1 + # core_part_1 is divided into subparts cores + # subpart1: bottom left subpart subpart1_1_height = bottommost_airgap_position + self.core.window_h / 2 - bottommost_airgap_height / 2 + self.core.core_inner_diameter / 4 subpart1_1_width = self.core.core_inner_diameter / 2 subpart1_1_volume = np.pi * subpart1_1_width ** 2 * subpart1_1_height - #subpart2 + # subpart2: bottom mid subpart subpart1_2_height = self.core.core_inner_diameter / 4 subpart1_2_width = self.core.window_w subpart1_2_volume = np.pi * subpart1_2_width ** 2 * subpart1_2_height - #subpart2 + # subpart3: right subpart subpart1_3_height = self.core.window_h + self.core.core_inner_diameter / 2 subpart1_3_width = self.core.r_outer - self.core.r_inner subpart1_3_volume = np.pi * subpart1_3_width ** 2 * subpart1_3_height - #subpart4 + # subpart4: top mid subpart subpart1_4_height = self.core.core_inner_diameter / 4 subpart1_4_width = self.core.window_w subpart1_4_volume = np.pi * subpart1_4_width ** 2 * subpart1_4_height - #subpart5 + # subpart5: top left subpart subpart1_5_height = self.core.window_h / 2 - topmost_airgap_position - topmost_airgap_height / 2 + self.core.core_inner_diameter / 4 subpart1_5_width = self.core.core_inner_diameter / 2 subpart1_5_volume = np.pi * subpart1_5_width ** 2 * subpart1_5_height # Calculate the volume of core part 1 by summing up subpart volumes core_part_1_volume = subpart1_1_volume + subpart1_2_volume + subpart1_3_volume + subpart1_4_volume + subpart1_5_volume - core_part_volume.append(core_part_1_volume) - - # #core_part_2 - # If there are multiple sorted midpoints, calculate the volume of core part 2 - if len(sorted_midpoints) > 1: - core_part_2_height = topmost_airgap_position - topmost_airgap_height / 2 - (second_topmost_airgap_position + second_topmost_airgap_height / 2) - core_part_2_width = get_width(2) - - core_part_2_volume = np.pi * core_part_2_width ** 2 * core_part_2_height - core_part_volume.append(core_part_2_volume) - - #core_part_3 - # If there are more than two sorted midpoints, calculate the volume of core part 3 - if len(sorted_midpoints) > 2: - core_part_3_height = second_topmost_airgap_position - second_topmost_airgap_height / 2 - (third_topmost_airgap_position + third_topmost_airgap_height / 2) - core_part_3_width = get_width(3) - - core_part_3_volume = np.pi * core_part_3_width ** 2 * core_part_3_height - core_part_volume.append(core_part_3_volume) + core_parts_volumes.append(core_part_1_volume) + + # Calculate the volumes of the core parts between the air gaps + for i in range(len(sorted_midpoints) - 1): + air_gap_1_position = sorted_midpoints[i][1] + air_gap_1_height = sorted_midpoints[i][2] + air_gap_2_position = sorted_midpoints[i + 1][1] + air_gap_2_height = sorted_midpoints[i + 1][2] + # calculate the height based on airgap positions and heights, and the width + core_part_height = air_gap_2_position - air_gap_2_height / 2 - ( + air_gap_1_position + air_gap_1_height / 2) + core_part_width = get_width(i + 2) + # calculate the volume + core_part_volume = np.pi * core_part_width ** 2 * core_part_height + core_parts_volumes.append(core_part_volume) # Return the total core part volume - return core_part_volume - - + return core_parts_volumes + # for single core and only one core part else: - # In case of non-integrated transformer components, the core volume is calculated directly without - # considering individual core parts. It uses the 'calculate_core_volume' method to compute the total core volume. (for thermal simulation) return [self.calculate_core_volume()] elif self.core.core_type == CoreType.Stacked: @@ -758,66 +741,65 @@ def get_width(part_number): # Core Part 1 Calculation # Core part 1 is calculated as the sum of three different subparts - # subpart_1 + # subpart_1: bottom left subpart subpart1_1_height = self.core.window_h_bot / 2 + self.core.core_inner_diameter / 4 - heights[0] / 2 subpart1_1_width = self.core.core_inner_diameter / 2 subpart1_1_volume = np.pi * subpart1_1_width ** 2 * subpart1_1_height - # subpart_2 + # subpart_2 : bottom mid subpart subpart1_2_height = self.core.core_inner_diameter / 4 subpart1_2_width = self.core.window_w subpart1_2_volume = np.pi * subpart1_2_width ** 2 * subpart1_2_height - # subpart 3 + # subpart_3: bottom right subpart subpart1_3_height = self.core.window_h_bot + self.core.core_inner_diameter / 4 subpart1_3_width = self.core.r_outer - self.core.r_inner subpart1_3_volume = np.pi * subpart1_3_width ** 2 * subpart1_3_height # Summing up the volumes of the subparts to get the total volume of core part 1 core_part_1_volume = subpart1_1_volume + subpart1_2_volume + subpart1_3_volume - core_part_volume.append(core_part_1_volume) + core_parts_volumes.append(core_part_1_volume) - # core_part_2 + # core_part_2 : core part between the bottom airgap and subpart_1 of core_part_1 core_part_2_height = self.core.window_h_bot / 2 - heights[0] / 2 core_part_2_width = self.core.core_inner_diameter / 2 core_part_2_volume = np.pi * core_part_2_width ** 2 * core_part_2_height - core_part_volume.append(core_part_2_volume) + core_parts_volumes.append(core_part_2_volume) - # core_part_3 + # core_part_3 : left mid core part (stacked) core_part_3_height = self.core.core_inner_diameter / 4 core_part_3_width = self.core.r_inner core_part_3_volume = np.pi * core_part_3_width ** 2 * core_part_3_height - core_part_volume.append(core_part_3_volume) + core_parts_volumes.append(core_part_3_volume) - # core_part_4 + # core_part_4: right mid core part core_part_4_height = self.core.core_inner_diameter / 4 core_part_4_width = self.core.r_outer - self.core.r_inner core_part_4_volume = np.pi * core_part_4_width ** 2 * core_part_4_height - core_part_volume.append(core_part_4_volume) + core_parts_volumes.append(core_part_4_volume) # core_part_5 # core_part_5 is divided into 3 parts - # subpart_1 + # subpart_1: top right subpart subpart5_1_height = self.core.window_h_top + self.core.core_inner_diameter / 4 - heights[1] / 2 - subpart5_1_width = self.core.r_inner - self.core.window_w + subpart5_1_width = self.core.core_inner_diameter / 2 subpart5_1_volume = np.pi * subpart5_1_width ** 2 * subpart5_1_height - # subpart_2 + # subpart_2: mid top subpart subpart5_2_height = self.core.core_inner_diameter / 4 subpart5_2_width = self.core.window_w subpart5_2_volume = np.pi * subpart5_2_width ** 2 * subpart5_2_height - # subpart 3 + # subpart 3: left top subpart subpart5_3_height = self.core.window_h_top + self.core.core_inner_diameter / 4 subpart5_3_width = self.core.r_outer - self.core.r_inner subpart5_3_volume = np.pi * subpart5_3_width ** 2 * subpart5_3_height # Summing up the volumes of the subparts to get the total volume of core_part_5 core_part_5_volume = subpart5_1_volume + subpart5_2_volume + subpart5_3_volume - core_part_volume.append(core_part_5_volume) + core_parts_volumes.append(core_part_5_volume) # Returning the final list of core part volumes - return core_part_volume - + return core_parts_volumes def calculate_core_weight(self) -> float: """ From 76ddd9470634c2f1ab75409f2d130213d025cea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikolas=20F=C3=B6rster?= Date: Fri, 27 Oct 2023 17:05:51 +0200 Subject: [PATCH 3/6] add thermal tests --- .../results/log_electro_magnetic_thermal.json | 176 ------ .../fixtures/results/results_thermal.json | 70 --- ...hermal_inductor_core_fixed_loss_angle.json | 80 +++ ...uctor_core_fixed_loss_angle_litz_wire.json | 80 +++ ...ermal_inductor_core_material_database.json | 80 +++ ...or_core_material_database_measurement.json | 80 +++ ...mal_transformer_core_fixed_loss_angle.json | 130 ++++ ...mer_interleaved_core_fixed_loss_angle.json | 170 +++++ tests/integration/test_femmt.py | 584 ++++++++++++++++-- 9 files changed, 1136 insertions(+), 314 deletions(-) delete mode 100644 tests/integration/fixtures/results/log_electro_magnetic_thermal.json delete mode 100644 tests/integration/fixtures/results/results_thermal.json create mode 100644 tests/integration/fixtures/results/thermal_inductor_core_fixed_loss_angle.json create mode 100644 tests/integration/fixtures/results/thermal_inductor_core_fixed_loss_angle_litz_wire.json create mode 100644 tests/integration/fixtures/results/thermal_inductor_core_material_database.json create mode 100644 tests/integration/fixtures/results/thermal_inductor_core_material_database_measurement.json create mode 100644 tests/integration/fixtures/results/thermal_transformer_core_fixed_loss_angle.json create mode 100644 tests/integration/fixtures/results/thermal_transformer_interleaved_core_fixed_loss_angle.json diff --git a/tests/integration/fixtures/results/log_electro_magnetic_thermal.json b/tests/integration/fixtures/results/log_electro_magnetic_thermal.json deleted file mode 100644 index 7f1de2b9..00000000 --- a/tests/integration/fixtures/results/log_electro_magnetic_thermal.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "single_sweeps": [ - { - "f": 100000, - "winding1": { - "turn_losses": [ - 0.005191803070657385, - 0.02381013923073857, - 0.06068039921019962, - 0.09263788641818624, - 0.1522932034121882, - 0.04825064671041221, - 0.02263980055268533, - 0.004988884101278411 - ], - "flux": [ - 9.134996331611467e-05, - -1.481437190952988e-06 - ], - "flux_over_current": [ - 3.0449969226243222e-05, - -4.957253860030809e-07 - ], - "V": [ - 0.9344203385191461, - 57.39683977392059 - ], - "number_turns": 8, - "I": [ - 3.0, - 0.0 - ], - "winding_losses": 0.4104927627063445, - "P": 1.401630507778719, - "Q": 86.09525966088088, - "S": 86.10666817474034 - }, - "core_eddy_losses": 0.0, - "core_hyst_losses": 0.9922305174935993, - "core_parts": { - "core_part_1": { - "total_core_part_1": 0.9922305174935993 - } - }, - "all_winding_losses": 0.4104927627063445 - } - ], - "total_losses": { - "winding1": { - "total": 0.41049276270634594, - "turns": [ - 0.005191803070657385, - 0.02381013923073857, - 0.06068039921019962, - 0.09263788641818624, - 0.1522932034121882, - 0.04825064671041221, - 0.02263980055268533, - 0.004988884101278411 - ] - }, - "all_windings": 0.4104927627063445, - "eddy_core": 0.0, - "total_core_part_1": 0.9922305174935993, - "hyst_core_fundamental_freq": 0.9922305174935993, - "core": 0.9922305174935993, - "total_losses": 1.4027232801999436 - }, - "simulation_settings": { - "simulation_name": null, - "date": "2023-10-20 15:24:30", - "component_type": "Inductor", - "working_directory": "C:\\Users\\samba\\PycharmProjects\\FEM_Magnetics_Toolbox\\tests\\integration\\temp", - "core": { - "core_inner_diameter": 0.0149, - "window_w": 0.01105, - "window_h": 0.0295, - "material": "custom", - "loss_approach": "LossAngle", - "mu_r_abs": 3100, - "phi_mu_deg": 12, - "sigma": [ - 0.0, - 0.0 - ], - "non_linear": false, - "correct_outer_leg": false, - "temperature": null, - "permeability_datasource": "custom", - "permeability_measurement_setup": null, - "permeability_datatype": null, - "permittivity_datasource": "custom", - "permittivity_measurement_setup": null, - "permittivity_datatype": null - }, - "winding_windows": [ - { - "max_bot_bound": -0.013749999999999998, - "max_top_bound": 0.013749999999999998, - "max_left_bound": 0.00945, - "max_right_bound": 0.0175, - "virtual_winding_windows": [ - { - "bot_bound": -0.013749999999999998, - "top_bound": 0.013749999999999998, - "left_bound": 0.00945, - "right_bound": 0.0175, - "winding_type": "Single", - "winding_scheme": null, - "wrap_para": null, - "windings": [ - { - "winding_number": 0, - "conductivity": "Copper", - "conductor_type": "RoundSolid", - "thickness": null, - "conductor_radius": 0.0015, - "conductor_arrangement": "Square", - "number_strands": 0, - "strand_radius": null, - "fill_factor": null - } - ], - "turns": [ - 8 - ] - } - ] - } - ], - "air_gaps": { - "method": "Center", - "air_gap_number": 1, - "air_gaps": [ - { - "leg_position": "CenterLeg", - "position_value": 0, - "height": 0.0005, - "stacked_position": null - } - ] - }, - "insulation": { - "inner_winding_insulations": [ - [ - 0.0001 - ] - ], - "core_insulations": [ - 0.001, - 0.001, - 0.002, - 0.001 - ] - } - }, - "misc": { - "core_2daxi_volume": 1.9509769078973208e-05, - "core_2daxi_total_volume": 4.61718454654407e-05, - "core_2daxi_weight": 0.0, - "wire_lengths": [ - 0.5504070329089318 - ], - "wire_volumes": [ - 3.890598054909425e-06 - ], - "wire_weight": [ - 0.03470413464979207 - ], - "core_cost": 0.0, - "winding_cost": [ - 3.589970289046465 - ], - "total_cost_incl_margin": 4.786627052061953 - } -} diff --git a/tests/integration/fixtures/results/results_thermal.json b/tests/integration/fixtures/results/results_thermal.json deleted file mode 100644 index 3452f862..00000000 --- a/tests/integration/fixtures/results/results_thermal.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "core_parts": { - "core_part_1": { - "min": 20.15928442290691, - "max": 21.23228498341263, - "mean": 20.74054867007518 - }, - "total": { - "min": 20.15928442290691, - "max": 21.23228498341263, - "mean": 20.74054867007518 - } - }, - "windings": { - "winding_0_0": { - "min": 20.77722154058429, - "max": 20.78129896378544, - "mean": 20.77882860503081 - }, - "winding_0_1": { - "min": 20.86520324787963, - "max": 20.87066742939298, - "mean": 20.867816943976056 - }, - "winding_0_2": { - "min": 20.95962314654136, - "max": 20.96455114361719, - "mean": 20.96218789580841 - }, - "winding_0_3": { - "min": 21.03203456392462, - "max": 21.03496398969962, - "mean": 21.033754905178824 - }, - "winding_0_4": { - "min": 21.05902021215361, - "max": 21.06103547095902, - "mean": 21.060253914511854 - }, - "winding_0_5": { - "min": 20.99107579068684, - "max": 20.99535703035788, - "mean": 20.9932589129064 - }, - "winding_0_6": { - "min": 20.91348883851931, - "max": 20.91790978303437, - "mean": 20.915564214338495 - }, - "winding_0_7": { - "min": 20.84399557863777, - "max": 20.84724514360274, - "mean": 20.845297194030216 - }, - "total": { - "min": 20.77722154058429, - "max": 21.06103547095902, - "mean": 20.932120323222634 - } - }, - "misc": { - "case_volume": 0.00017214993340642786, - "case_weight": -1 - }, - "insulations": { - "min": 20.24849972466502, - "max": 21.15300382780513, - "mean": 20.69871779609566 - } -} diff --git a/tests/integration/fixtures/results/thermal_inductor_core_fixed_loss_angle.json b/tests/integration/fixtures/results/thermal_inductor_core_fixed_loss_angle.json new file mode 100644 index 00000000..32eb2b24 --- /dev/null +++ b/tests/integration/fixtures/results/thermal_inductor_core_fixed_loss_angle.json @@ -0,0 +1,80 @@ +{ + "core_parts": { + "core_part_1": { + "min": 20.26398303567154, + "max": 21.10084543113022, + "mean": 20.64525688929095 + }, + "core_part_2": { + "min": 21.06550856420846, + "max": 21.33712512482574, + "mean": 21.227151075847047 + }, + "total": { + "min": 20.26398303567154, + "max": 21.33712512482574, + "mean": 20.936203982568998 + } + }, + "windings": { + "winding_0_0": { + "min": 20.86695463026816, + "max": 20.86871580858037, + "mean": 20.867896088836545 + }, + "winding_0_1": { + "min": 20.93076090173764, + "max": 20.93193470619059, + "mean": 20.93143277148465 + }, + "winding_0_2": { + "min": 20.92796487473939, + "max": 20.92914024114734, + "mean": 20.928638161977 + }, + "winding_0_3": { + "min": 20.8992827619004, + "max": 20.90048441313719, + "mean": 20.899961808911495 + }, + "winding_0_4": { + "min": 20.88550560005773, + "max": 20.88669115436789, + "mean": 20.886166558740392 + }, + "winding_0_5": { + "min": 20.90218184768714, + "max": 20.90339583559974, + "mean": 20.9028648159693 + }, + "winding_0_6": { + "min": 20.93391559700827, + "max": 20.93510050620943, + "mean": 20.93459820421602 + }, + "winding_0_7": { + "min": 20.93977610635383, + "max": 20.94094795922852, + "mean": 20.94045513789456 + }, + "winding_0_8": { + "min": 20.87838027668208, + "max": 20.88013001523136, + "mean": 20.87931628690792 + }, + "total": { + "min": 20.86695463026816, + "max": 20.94094795922852, + "mean": 20.90792553721532 + } + }, + "misc": { + "case_volume": 0.00017214993340642786, + "case_weight": -1 + }, + "insulations": { + "min": 20.40397414619924, + "max": 21.21802631813222, + "mean": 20.866048090297838 + } +} \ No newline at end of file diff --git a/tests/integration/fixtures/results/thermal_inductor_core_fixed_loss_angle_litz_wire.json b/tests/integration/fixtures/results/thermal_inductor_core_fixed_loss_angle_litz_wire.json new file mode 100644 index 00000000..2685ac78 --- /dev/null +++ b/tests/integration/fixtures/results/thermal_inductor_core_fixed_loss_angle_litz_wire.json @@ -0,0 +1,80 @@ +{ + "core_parts": { + "core_part_1": { + "min": 20.22742519111262, + "max": 20.97471307336562, + "mean": 20.546318372843864 + }, + "core_part_2": { + "min": 20.89962993837921, + "max": 21.16067709210542, + "mean": 21.05284394366213 + }, + "total": { + "min": 20.22742519111262, + "max": 21.16067709210542, + "mean": 20.799581158252998 + } + }, + "windings": { + "winding_0_0": { + "min": 20.62556545644145, + "max": 20.62628276528842, + "mean": 20.62594884380426 + }, + "winding_0_1": { + "min": 20.65737224009086, + "max": 20.65806500438718, + "mean": 20.65773463467894 + }, + "winding_0_2": { + "min": 20.67844121515095, + "max": 20.67914678579811, + "mean": 20.678805634075246 + }, + "winding_0_3": { + "min": 20.69164324498031, + "max": 20.69236973691228, + "mean": 20.692021813312888 + }, + "winding_0_4": { + "min": 20.69963446337397, + "max": 20.70037474187797, + "mean": 20.70001965259286 + }, + "winding_0_5": { + "min": 20.70354453713561, + "max": 20.70429254975538, + "mean": 20.703934441333235 + }, + "winding_0_6": { + "min": 20.70317969710283, + "max": 20.70392754750065, + "mean": 20.703570279207362 + }, + "winding_0_7": { + "min": 20.69702250787281, + "max": 20.69777281962206, + "mean": 20.697417639065595 + }, + "winding_0_8": { + "min": 20.68203250834514, + "max": 20.68285970409766, + "mean": 20.68247466301176 + }, + "total": { + "min": 20.62556545644145, + "max": 20.70429254975538, + "mean": 20.68243640012024 + } + }, + "misc": { + "case_volume": 0.00017214993340642786, + "case_weight": -1 + }, + "insulations": { + "min": 20.33053898154655, + "max": 21.03491098819614, + "mean": 20.688914622599054 + } +} \ No newline at end of file diff --git a/tests/integration/fixtures/results/thermal_inductor_core_material_database.json b/tests/integration/fixtures/results/thermal_inductor_core_material_database.json new file mode 100644 index 00000000..94a2e052 --- /dev/null +++ b/tests/integration/fixtures/results/thermal_inductor_core_material_database.json @@ -0,0 +1,80 @@ +{ + "core_parts": { + "core_part_1": { + "min": 20.1112736918566, + "max": 20.4922695086855, + "mean": 20.29718075831936 + }, + "core_part_2": { + "min": 20.51484827197675, + "max": 20.64466170428551, + "mean": 20.598006908054757 + }, + "total": { + "min": 20.1112736918566, + "max": 20.64466170428551, + "mean": 20.447593833187057 + } + }, + "windings": { + "winding_0_0": { + "min": 20.51871158662502, + "max": 20.52026710055326, + "mean": 20.519519371306014 + }, + "winding_0_1": { + "min": 20.57794001223308, + "max": 20.57864638591567, + "mean": 20.578375937206694 + }, + "winding_0_2": { + "min": 20.57065682718899, + "max": 20.5713314832966, + "mean": 20.571080951195405 + }, + "winding_0_3": { + "min": 20.5389548612267, + "max": 20.5396779280161, + "mean": 20.53937928326633 + }, + "winding_0_4": { + "min": 20.52411170117527, + "max": 20.52474486612969, + "mean": 20.52451246928034 + }, + "winding_0_5": { + "min": 20.54176625112737, + "max": 20.54251573048915, + "mean": 20.542194056472017 + }, + "winding_0_6": { + "min": 20.57642162581192, + "max": 20.57711794449588, + "mean": 20.576855349168135 + }, + "winding_0_7": { + "min": 20.58669086732031, + "max": 20.58739197188176, + "mean": 20.587132273853157 + }, + "winding_0_8": { + "min": 20.52983342512741, + "max": 20.5313774296703, + "mean": 20.5306397239592 + }, + "total": { + "min": 20.51871158662502, + "max": 20.58739197188176, + "mean": 20.552187712856366 + } + }, + "misc": { + "case_volume": 0.00017214993340642786, + "case_weight": -1 + }, + "insulations": { + "min": 20.17971198592431, + "max": 20.61583412058758, + "mean": 20.472423874704024 + } +} \ No newline at end of file diff --git a/tests/integration/fixtures/results/thermal_inductor_core_material_database_measurement.json b/tests/integration/fixtures/results/thermal_inductor_core_material_database_measurement.json new file mode 100644 index 00000000..9920d043 --- /dev/null +++ b/tests/integration/fixtures/results/thermal_inductor_core_material_database_measurement.json @@ -0,0 +1,80 @@ +{ + "core_parts": { + "core_part_1": { + "min": 20.18142888701398, + "max": 20.77196380114331, + "mean": 20.456264956441824 + }, + "core_part_2": { + "min": 20.76619094810481, + "max": 20.96225217295261, + "mean": 20.88580758470626 + }, + "total": { + "min": 20.18142888701398, + "max": 20.96225217295261, + "mean": 20.671036270574042 + } + }, + "windings": { + "winding_0_0": { + "min": 20.67167713370532, + "max": 20.67328393229362, + "mean": 20.672521916835024 + }, + "winding_0_1": { + "min": 20.73189960757356, + "max": 20.73280845384166, + "mean": 20.732438437462662 + }, + "winding_0_2": { + "min": 20.72744230373837, + "max": 20.72833297943858, + "mean": 20.727974595703735 + }, + "winding_0_3": { + "min": 20.69846812558443, + "max": 20.69938133794891, + "mean": 20.69900323670138 + }, + "winding_0_4": { + "min": 20.68471622606024, + "max": 20.6856004855603, + "mean": 20.685232614136133 + }, + "winding_0_5": { + "min": 20.70126896339646, + "max": 20.70219816833279, + "mean": 20.701807779537535 + }, + "winding_0_6": { + "min": 20.73318077978665, + "max": 20.73408135990459, + "mean": 20.73372158132328 + }, + "winding_0_7": { + "min": 20.74058493876315, + "max": 20.74149116761968, + "mean": 20.741129976673687 + }, + "winding_0_8": { + "min": 20.68267962956238, + "max": 20.68427140667179, + "mean": 20.683517098103298 + }, + "total": { + "min": 20.67167713370532, + "max": 20.74149116761968, + "mean": 20.7085941373863 + } + }, + "misc": { + "case_volume": 0.00017214993340642786, + "case_weight": -1 + }, + "insulations": { + "min": 20.28290640644805, + "max": 20.89045321030462, + "mean": 20.6492675843772 + } +} \ No newline at end of file diff --git a/tests/integration/fixtures/results/thermal_transformer_core_fixed_loss_angle.json b/tests/integration/fixtures/results/thermal_transformer_core_fixed_loss_angle.json new file mode 100644 index 00000000..5035fbfc --- /dev/null +++ b/tests/integration/fixtures/results/thermal_transformer_core_fixed_loss_angle.json @@ -0,0 +1,130 @@ +{ + "core_parts": { + "core_part_1": { + "min": 20.50214224347022, + "max": 27.53391264533138, + "mean": 23.994925705403222 + }, + "total": { + "min": 20.50214224347022, + "max": 27.53391264533138, + "mean": 23.994925705403222 + } + }, + "windings": { + "winding_0_0": { + "min": 28.71181539790021, + "max": 28.71831012964829, + "mean": 28.716025080239824 + }, + "winding_0_1": { + "min": 28.18795802911803, + "max": 28.2090051279591, + "mean": 28.19911483352939 + }, + "winding_0_2": { + "min": 27.27312373628725, + "max": 27.30124799860819, + "mean": 27.286900790249035 + }, + "winding_0_3": { + "min": 26.28496732338034, + "max": 26.31210537329982, + "mean": 26.29750146021271 + }, + "winding_0_4": { + "min": 25.44457446145334, + "max": 25.46372181165918, + "mean": 25.452118871775163 + }, + "winding_0_5": { + "min": 28.24754339282917, + "max": 28.26327666662304, + "mean": 28.254850567439007 + }, + "winding_0_6": { + "min": 27.80313564667688, + "max": 27.82240619436214, + "mean": 27.813827524213462 + }, + "winding_0_7": { + "min": 26.97491843703213, + "max": 27.00108027084997, + "mean": 26.988020506612905 + }, + "winding_0_8": { + "min": 26.04989224163797, + "max": 26.07606315423621, + "mean": 26.0624399664869 + }, + "winding_0_9": { + "min": 25.22442970909221, + "max": 25.24541254930722, + "mean": 25.233864638198973 + }, + "winding_1_0": { + "min": 24.90361178840659, + "max": 24.92647846528412, + "mean": 24.912998394220313 + }, + "winding_1_1": { + "min": 25.86564152344892, + "max": 25.89602793258035, + "mean": 25.880001541847 + }, + "winding_1_2": { + "min": 26.95579301030553, + "max": 26.98653483986232, + "mean": 26.97099745233809 + }, + "winding_1_3": { + "min": 27.95468807627188, + "max": 27.97812423354487, + "mean": 27.967048136950485 + }, + "winding_1_4": { + "min": 28.55105688218471, + "max": 28.55906936581176, + "mean": 28.556260726618152 + }, + "winding_1_5": { + "min": 24.6914230888444, + "max": 24.71570535787071, + "mean": 24.70215380582518 + }, + "winding_1_6": { + "min": 25.6382834439525, + "max": 25.66769425038234, + "mean": 25.652536233812135 + }, + "winding_1_7": { + "min": 26.66417381314561, + "max": 26.69305741296078, + "mean": 26.678903249222696 + }, + "winding_1_8": { + "min": 27.57553304085365, + "max": 27.59702550696397, + "mean": 27.587374664578288 + }, + "winding_1_9": { + "min": 28.09242604408157, + "max": 28.10801121199798, + "mean": 28.099605342225658 + }, + "total": { + "min": 24.6914230888444, + "max": 28.71831012964829, + "mean": 26.865627189329768 + } + }, + "misc": { + "case_volume": 0.00017607032966310472, + "case_weight": -1 + }, + "insulations": { + "min": 20.90290841329679, + "max": 28.69075749792995, + "mean": 24.574380034018496 + } +} \ No newline at end of file diff --git a/tests/integration/fixtures/results/thermal_transformer_interleaved_core_fixed_loss_angle.json b/tests/integration/fixtures/results/thermal_transformer_interleaved_core_fixed_loss_angle.json new file mode 100644 index 00000000..1981e188 --- /dev/null +++ b/tests/integration/fixtures/results/thermal_transformer_interleaved_core_fixed_loss_angle.json @@ -0,0 +1,170 @@ +{ + "core_parts": { + "core_part_1": { + "min": 20.34953523352948, + "max": 25.0218356450574, + "mean": 22.759999626437665 + }, + "total": { + "min": 20.34953523352948, + "max": 25.0218356450574, + "mean": 22.759999626437665 + } + }, + "windings": { + "winding_0_0": { + "min": 23.43889869847968, + "max": 23.45237393033219, + "mean": 23.44475301974073 + }, + "winding_0_1": { + "min": 23.95215802178127, + "max": 23.96749041076642, + "mean": 23.959617441929147 + }, + "winding_0_2": { + "min": 24.47335093467583, + "max": 24.4883966749889, + "mean": 24.480750732270383 + }, + "winding_0_3": { + "min": 24.97027291144472, + "max": 24.98400252013918, + "mean": 24.977097184877696 + }, + "winding_0_4": { + "min": 25.40380660767918, + "max": 25.41475492151629, + "mean": 25.409382615474396 + }, + "winding_0_5": { + "min": 25.71581993109857, + "max": 25.72190294826109, + "mean": 25.719156321925514 + }, + "winding_0_6": { + "min": 25.8191903457075, + "max": 25.82221522289126, + "mean": 25.821148706410092 + }, + "winding_0_7": { + "min": 25.54825677177177, + "max": 25.5617037812522, + "mean": 25.55582566358401 + }, + "winding_0_8": { + "min": 24.90863929248822, + "max": 24.92923655080165, + "mean": 24.91898178304087 + }, + "winding_0_9": { + "min": 24.1646646718446, + "max": 24.18564700885512, + "mean": 24.17468105739721 + }, + "winding_0_10": { + "min": 23.50334696204615, + "max": 23.51880919391166, + "mean": 23.50954376392254 + }, + "winding_0_11": { + "min": 22.83712476582853, + "max": 22.8500510075047, + "mean": 22.843418287687037 + }, + "winding_0_12": { + "min": 23.27579181647863, + "max": 23.2888128828172, + "mean": 23.282336879045253 + }, + "winding_0_13": { + "min": 23.69227966910301, + "max": 23.7044237351258, + "mean": 23.698401940864628 + }, + "winding_0_14": { + "min": 24.06616025014995, + "max": 24.07722403310746, + "mean": 24.07173124811919 + }, + "winding_0_15": { + "min": 24.36338706701889, + "max": 24.37456319992025, + "mean": 24.368840707807877 + }, + "winding_0_16": { + "min": 24.53087306873268, + "max": 24.54239022763685, + "mean": 24.536345680369056 + }, + "winding_0_17": { + "min": 24.48396623978851, + "max": 24.49653860286413, + "mean": 24.48976629711417 + }, + "winding_0_18": { + "min": 24.08096759724374, + "max": 24.09533969805735, + "mean": 24.08833001681582 + }, + "winding_0_19": { + "min": 23.55111611080951, + "max": 23.56628420972879, + "mean": 23.55833805581782 + }, + "winding_0_20": { + "min": 23.0769435675773, + "max": 23.088942616582, + "mean": 23.08227978307703 + }, + "winding_1_0": { + "min": 23.31398881131033, + "max": 23.32716653294803, + "mean": 23.319884728390594 + }, + "winding_1_1": { + "min": 23.79205128707858, + "max": 23.80626699897524, + "mean": 23.798905907928926 + }, + "winding_1_2": { + "min": 24.26871384425964, + "max": 24.28244163077514, + "mean": 24.275419716864306 + }, + "winding_1_3": { + "min": 24.71330598385453, + "max": 24.72560142402793, + "mean": 24.719442635126462 + }, + "winding_1_4": { + "min": 25.08642434909413, + "max": 25.09597397756461, + "mean": 25.091274087376526 + }, + "winding_1_5": { + "min": 25.32918570617232, + "max": 25.33821277740141, + "mean": 25.334103042093574 + }, + "winding_1_6": { + "min": 25.37300452548676, + "max": 25.38341920374809, + "mean": 25.378711860990713 + }, + "total": { + "min": 22.83712476582853, + "max": 25.82221522289126, + "mean": 24.353873898787914 + } + }, + "misc": { + "case_volume": 0.00017607032966310472, + "case_weight": -1 + }, + "insulations": { + "min": 20.66123663423358, + "max": 25.80569798551228, + "mean": 23.26874750313497 + } +} \ No newline at end of file diff --git a/tests/integration/test_femmt.py b/tests/integration/test_femmt.py index 303cb4c2..3bf776dd 100644 --- a/tests/integration/test_femmt.py +++ b/tests/integration/test_femmt.py @@ -137,28 +137,35 @@ def femmt_simulation_inductor_core_material_database(temp_folder): geo.single_simulation(freq=100000, current=[4.5], show_fem_simulation_results=False) - """ - Currently only the magnetics simulation is tested - thermal_conductivity_dict = { - "air": 0.0263, - "case": 0.3, - "core": 5, - "winding": 400, - "air_gaps": 180 + "air": 1.57, # potting epoxy resign + "case": { + "top": 1.57, + "top_right": 1.57, + "right": 1.57, + "bot_right": 1.57, + "bot": 1.57 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 1.57, + "insulation": 1.57 } - case_gap_top = 0.0015 + + case_gap_top = 0.002 case_gap_right = 0.0025 case_gap_bot = 0.002 + boundary_temperatures = { - "value_boundary_top": 293, - "value_boundary_top_right": 293, - "value_boundary_right_top": 293, - "value_boundary_right": 293, - "value_boundary_right_bottom": 293, - "value_boundary_bottom_right": 293, - "value_boundary_bottom": 293 + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 } + boundary_flags = { "flag_boundary_top": 1, "flag_boundary_top_right": 1, @@ -169,14 +176,26 @@ def femmt_simulation_inductor_core_material_database(temp_folder): "flag_boundary_bottom": 1 } - geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, case_gap_right, case_gap_bot, show_results=False) - """ + # color_scheme = fmt.colors_ba_jonas + # colors_geometry = fmt.colors_geometry_ba_jonas + color_scheme = fmt.colors_ba_jonas + colors_geometry = fmt.colors_geometry_draw_only_lines + + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, + case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, color_scheme=color_scheme, + colors_geometry=colors_geometry) + + except Exception as e: print("An error occurred while creating the femmt mesh files:", e) except KeyboardInterrupt: print("Keyboard interrupt..") - return os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result @pytest.fixture @@ -236,28 +255,35 @@ def femmt_simulation_inductor_core_material_database_measurement(temp_folder): geo.single_simulation(freq=100000, current=[4.5], show_fem_simulation_results=False) - """ - Currently only the magnetics simulation is tested - thermal_conductivity_dict = { - "air": 0.0263, - "case": 0.3, - "core": 5, - "winding": 400, - "air_gaps": 180 + "air": 1.57, # potting epoxy resign + "case": { + "top": 1.57, + "top_right": 1.57, + "right": 1.57, + "bot_right": 1.57, + "bot": 1.57 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 1.57, + "insulation": 1.57 } - case_gap_top = 0.0015 + + case_gap_top = 0.002 case_gap_right = 0.0025 case_gap_bot = 0.002 + boundary_temperatures = { - "value_boundary_top": 293, - "value_boundary_top_right": 293, - "value_boundary_right_top": 293, - "value_boundary_right": 293, - "value_boundary_right_bottom": 293, - "value_boundary_bottom_right": 293, - "value_boundary_bottom": 293 + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 } + boundary_flags = { "flag_boundary_top": 1, "flag_boundary_top_right": 1, @@ -268,14 +294,26 @@ def femmt_simulation_inductor_core_material_database_measurement(temp_folder): "flag_boundary_bottom": 1 } - geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, case_gap_right, case_gap_bot, show_results=False) - """ + # color_scheme = fmt.colors_ba_jonas + # colors_geometry = fmt.colors_geometry_ba_jonas + color_scheme = fmt.colors_ba_jonas + colors_geometry = fmt.colors_geometry_draw_only_lines + + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, + case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, color_scheme=color_scheme, + colors_geometry=colors_geometry) + + except Exception as e: print("An error occurred while creating the femmt mesh files:", e) except KeyboardInterrupt: print("Keyboard interrupt..") - return os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result @pytest.fixture @@ -329,13 +367,66 @@ def femmt_simulation_inductor_core_fixed_loss_angle(temp_folder): geo.create_model(freq=100000, pre_visualize_geometry=False, save_png=False) geo.single_simulation(freq=100000, current=[4.5], show_fem_simulation_results=False) + thermal_conductivity_dict = { + "air": 1.57, # potting epoxy resign + "case": { + "top": 1.57, + "top_right": 1.57, + "right": 1.57, + "bot_right": 1.57, + "bot": 1.57 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 1.57, + "insulation": 1.57 + } + + case_gap_top = 0.002 + case_gap_right = 0.0025 + case_gap_bot = 0.002 + + boundary_temperatures = { + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 + } + + boundary_flags = { + "flag_boundary_top": 1, + "flag_boundary_top_right": 1, + "flag_boundary_right_top": 1, + "flag_boundary_right": 1, + "flag_boundary_right_bottom": 1, + "flag_boundary_bottom_right": 1, + "flag_boundary_bottom": 1 + } + + # color_scheme = fmt.colors_ba_jonas + # colors_geometry = fmt.colors_geometry_ba_jonas + color_scheme = fmt.colors_ba_jonas + colors_geometry = fmt.colors_geometry_draw_only_lines + + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, + case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, color_scheme=color_scheme, + colors_geometry=colors_geometry) + except Exception as e: print("An error occurred while creating the femmt mesh files:", e) except KeyboardInterrupt: print("Keyboard interrupt..") - return os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result + @pytest.fixture def femmt_simulation_inductor_core_fixed_loss_angle_litz_wire(temp_folder): @@ -387,12 +478,68 @@ def femmt_simulation_inductor_core_fixed_loss_angle_litz_wire(temp_folder): geo.single_simulation(freq=100000, current=[4.5], show_fem_simulation_results=False) + thermal_conductivity_dict = { + "air": 1.57, # potting epoxy resign + "case": { + "top": 1.57, + "top_right": 1.57, + "right": 1.57, + "bot_right": 1.57, + "bot": 1.57 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 1.57, + "insulation": 1.57 + } + + case_gap_top = 0.002 + case_gap_right = 0.0025 + case_gap_bot = 0.002 + + boundary_temperatures = { + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 + } + + boundary_flags = { + "flag_boundary_top": 1, + "flag_boundary_top_right": 1, + "flag_boundary_right_top": 1, + "flag_boundary_right": 1, + "flag_boundary_right_bottom": 1, + "flag_boundary_bottom_right": 1, + "flag_boundary_bottom": 1 + } + + # color_scheme = fmt.colors_ba_jonas + # colors_geometry = fmt.colors_geometry_ba_jonas + color_scheme = fmt.colors_ba_jonas + colors_geometry = fmt.colors_geometry_draw_only_lines + + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, + case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, + color_scheme=color_scheme, + colors_geometry=colors_geometry) + + except Exception as e: print("An error occurred while creating the femmt mesh files:", e) except KeyboardInterrupt: print("Keyboard interrupt..") - return os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result + + @pytest.fixture def femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical(temp_folder): @@ -447,6 +594,55 @@ def femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical(temp_folder): geo.single_simulation(freq=100000, current=[3], show_fem_simulation_results=False) + thermal_conductivity_dict = { + "air": 1.57, # potting epoxy resign + "case": { + "top": 1.57, + "top_right": 1.57, + "right": 1.57, + "bot_right": 1.57, + "bot": 1.57 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 1.57, + "insulation": 1.57 + } + + case_gap_top = 0.002 + case_gap_right = 0.0025 + case_gap_bot = 0.002 + + boundary_temperatures = { + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 + } + + boundary_flags = { + "flag_boundary_top": 1, + "flag_boundary_top_right": 1, + "flag_boundary_right_top": 1, + "flag_boundary_right": 1, + "flag_boundary_right_bottom": 1, + "flag_boundary_bottom_right": 1, + "flag_boundary_bottom": 1 + } + + # color_scheme = fmt.colors_ba_jonas + # colors_geometry = fmt.colors_geometry_ba_jonas + color_scheme = fmt.colors_ba_jonas + colors_geometry = fmt.colors_geometry_draw_only_lines + + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, + case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, + color_scheme=color_scheme, + colors_geometry=colors_geometry) except Exception as e: @@ -454,7 +650,11 @@ def femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical(temp_folder): except KeyboardInterrupt: print("Keyboard interrupt..") - return os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result + @pytest.fixture def femmt_simulation_inductor_core_fixed_loss_angle_foil_horizontal(temp_folder): @@ -510,12 +710,66 @@ def femmt_simulation_inductor_core_fixed_loss_angle_foil_horizontal(temp_folder) geo.single_simulation(freq=100000, current=[3], show_fem_simulation_results=False) + thermal_conductivity_dict = { + "air": 1.57, # potting epoxy resign + "case": { + "top": 1.57, + "top_right": 1.57, + "right": 1.57, + "bot_right": 1.57, + "bot": 1.57 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 1.57, + "insulation": 1.57 + } + + case_gap_top = 0.002 + case_gap_right = 0.0025 + case_gap_bot = 0.002 + + boundary_temperatures = { + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 + } + + boundary_flags = { + "flag_boundary_top": 1, + "flag_boundary_top_right": 1, + "flag_boundary_right_top": 1, + "flag_boundary_right": 1, + "flag_boundary_right_bottom": 1, + "flag_boundary_bottom_right": 1, + "flag_boundary_bottom": 1 + } + + # color_scheme = fmt.colors_ba_jonas + # colors_geometry = fmt.colors_geometry_ba_jonas + color_scheme = fmt.colors_ba_jonas + colors_geometry = fmt.colors_geometry_draw_only_lines + + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, + case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, + color_scheme=color_scheme, + colors_geometry=colors_geometry) + + except Exception as e: print("An error occurred while creating the femmt mesh files:", e) except KeyboardInterrupt: print("Keyboard interrupt..") - return os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result @pytest.fixture @@ -580,12 +834,67 @@ def femmt_simulation_transformer_core_fixed_loss_angle(temp_folder): geo.create_model(freq=250000, pre_visualize_geometry=False) geo.single_simulation(freq=250000, current=[4, 4], phi_deg=[0, 178], show_fem_simulation_results=False) + thermal_conductivity_dict = { + "air": 1.57, # potting epoxy resign + "case": { + "top": 1.57, + "top_right": 1.57, + "right": 1.57, + "bot_right": 1.57, + "bot": 1.57 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 1.57, + "insulation": 1.57 + } + + case_gap_top = 0.002 + case_gap_right = 0.0025 + case_gap_bot = 0.002 + + boundary_temperatures = { + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 + } + + boundary_flags = { + "flag_boundary_top": 1, + "flag_boundary_top_right": 1, + "flag_boundary_right_top": 1, + "flag_boundary_right": 1, + "flag_boundary_right_bottom": 1, + "flag_boundary_bottom_right": 1, + "flag_boundary_bottom": 1 + } + + # color_scheme = fmt.colors_ba_jonas + # colors_geometry = fmt.colors_geometry_ba_jonas + color_scheme = fmt.colors_ba_jonas + colors_geometry = fmt.colors_geometry_draw_only_lines + + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, + case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, + color_scheme=color_scheme, + colors_geometry=colors_geometry) + + except Exception as e: print("An error occurred while creating the femmt mesh files:", e) except KeyboardInterrupt: print("Keyboard interrupt..") - return os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result + @pytest.fixture def femmt_simulation_transformer_interleaved_core_fixed_loss_angle(temp_folder): @@ -646,6 +955,55 @@ def femmt_simulation_transformer_interleaved_core_fixed_loss_angle(temp_folder): geo.create_model(freq=250000, pre_visualize_geometry=False) geo.single_simulation(freq=250000, current=[4, 12], phi_deg=[0, 180], show_fem_simulation_results=False) + thermal_conductivity_dict = { + "air": 1.57, # potting epoxy resign + "case": { + "top": 1.57, + "top_right": 1.57, + "right": 1.57, + "bot_right": 1.57, + "bot": 1.57 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 1.57, + "insulation": 1.57 + } + + case_gap_top = 0.002 + case_gap_right = 0.0025 + case_gap_bot = 0.002 + + boundary_temperatures = { + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 + } + + boundary_flags = { + "flag_boundary_top": 1, + "flag_boundary_top_right": 1, + "flag_boundary_right_top": 1, + "flag_boundary_right": 1, + "flag_boundary_right_bottom": 1, + "flag_boundary_bottom_right": 1, + "flag_boundary_bottom": 1 + } + + # color_scheme = fmt.colors_ba_jonas + # colors_geometry = fmt.colors_geometry_ba_jonas + color_scheme = fmt.colors_ba_jonas + colors_geometry = fmt.colors_geometry_draw_only_lines + + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, + case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, + color_scheme=color_scheme, + colors_geometry=colors_geometry) except Exception as e: @@ -653,7 +1011,11 @@ def femmt_simulation_transformer_interleaved_core_fixed_loss_angle(temp_folder): except KeyboardInterrupt: print("Keyboard interrupt..") - return os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result + @pytest.fixture def femmt_simulation_transformer_integrated_core_fixed_loss_angle(temp_folder): @@ -724,12 +1086,67 @@ def femmt_simulation_transformer_integrated_core_fixed_loss_angle(temp_folder): geo.create_model(freq=250000, pre_visualize_geometry=False) geo.single_simulation(freq=250000, current=[8.0, 4.0], phi_deg=[0, 175], show_fem_simulation_results=False) + thermal_conductivity_dict = { + "air": 1.57, # potting epoxy resign + "case": { + "top": 1.57, + "top_right": 1.57, + "right": 1.57, + "bot_right": 1.57, + "bot": 1.57 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 1.57, + "insulation": 1.57 + } + + case_gap_top = 0.002 + case_gap_right = 0.0025 + case_gap_bot = 0.002 + + boundary_temperatures = { + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 + } + + boundary_flags = { + "flag_boundary_top": 1, + "flag_boundary_top_right": 1, + "flag_boundary_right_top": 1, + "flag_boundary_right": 1, + "flag_boundary_right_bottom": 1, + "flag_boundary_bottom_right": 1, + "flag_boundary_bottom": 1 + } + + # color_scheme = fmt.colors_ba_jonas + # colors_geometry = fmt.colors_geometry_ba_jonas + color_scheme = fmt.colors_ba_jonas + colors_geometry = fmt.colors_geometry_draw_only_lines + + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, + case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, + color_scheme=color_scheme, + colors_geometry=colors_geometry) + + except Exception as e: print("An error occurred while creating the femmt mesh files:", e) except KeyboardInterrupt: print("Keyboard interrupt..") - return os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result + @pytest.fixture def thermal_simulation(temp_folder): @@ -855,7 +1272,7 @@ def test_inductor_core_material_database(femmt_simulation_inductor_core_material Now as an example only the result log will be checked. """ - test_result_log = femmt_simulation_inductor_core_material_database + test_result_log, thermal_result_log = femmt_simulation_inductor_core_material_database assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" @@ -863,6 +1280,11 @@ def test_inductor_core_material_database(femmt_simulation_inductor_core_material fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "log_electro_magnetic_inductor_core_material.json") compare_result_logs(test_result_log, fixture_result_log) + # check thermal simulation results + assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_inductor_core_material_database.json") + compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_inductor_core_material_database_measurement(femmt_simulation_inductor_core_material_database_measurement): """ The first idea was to compare the simulated meshes with test meshes simulated manually. @@ -873,7 +1295,7 @@ def test_inductor_core_material_database_measurement(femmt_simulation_inductor_c Now as an example only the result log will be checked. """ - test_result_log = femmt_simulation_inductor_core_material_database_measurement + test_result_log, thermal_result_log = femmt_simulation_inductor_core_material_database_measurement assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" @@ -881,8 +1303,13 @@ def test_inductor_core_material_database_measurement(femmt_simulation_inductor_c fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "log_electro_magnetic_inductor_core_material_measurement.json") compare_result_logs(test_result_log, fixture_result_log) + # check thermal simulation results + assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_inductor_core_material_database_measurement.json") + compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_inductor_core_fixed_loss_angle(femmt_simulation_inductor_core_fixed_loss_angle): - test_result_log = femmt_simulation_inductor_core_fixed_loss_angle + test_result_log, thermal_result_log = femmt_simulation_inductor_core_fixed_loss_angle assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" @@ -890,8 +1317,13 @@ def test_inductor_core_fixed_loss_angle(femmt_simulation_inductor_core_fixed_los fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "log_electro_magnetic_inductor_core_fixed_loss_angle.json") compare_result_logs(test_result_log, fixture_result_log) + # check thermal simulation results + assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_inductor_core_fixed_loss_angle.json") + compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_inductor_core_fixed_loss_angle_litz_wire(femmt_simulation_inductor_core_fixed_loss_angle_litz_wire): - test_result_log = femmt_simulation_inductor_core_fixed_loss_angle_litz_wire + test_result_log, thermal_result_log = femmt_simulation_inductor_core_fixed_loss_angle_litz_wire assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" @@ -899,8 +1331,13 @@ def test_inductor_core_fixed_loss_angle_litz_wire(femmt_simulation_inductor_core fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "log_electro_magnetic_inductor_core_fixed_loss_angle_litz_wire.json") compare_result_logs(test_result_log, fixture_result_log, significant_digits=4) + # check thermal simulation results + assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_inductor_core_fixed_loss_angle_litz_wire.json") + compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_inductor_core_fixed_loss_angle_foil_vertical(femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical): - test_result_log = femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical + test_result_log, thermal_result_log = femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" @@ -909,8 +1346,13 @@ def test_inductor_core_fixed_loss_angle_foil_vertical(femmt_simulation_inductor_ "log_electro_magnetic_inductor_core_fixed_loss_angle_foil_vertical.json") compare_result_logs(test_result_log, fixture_result_log) + # check thermal simulation results + #assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + #fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_inductor_core_fixed_loss_angle_foil_vertical.json") + #compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_inductor_core_fixed_loss_angle_foil_horizontal(femmt_simulation_inductor_core_fixed_loss_angle_foil_horizontal): - test_result_log = femmt_simulation_inductor_core_fixed_loss_angle_foil_horizontal + test_result_log, thermal_result_log = femmt_simulation_inductor_core_fixed_loss_angle_foil_horizontal assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" @@ -919,11 +1361,16 @@ def test_inductor_core_fixed_loss_angle_foil_horizontal(femmt_simulation_inducto "log_electro_magnetic_inductor_core_fixed_loss_angle_foil_horizontal.json") compare_result_logs(test_result_log, fixture_result_log) + # check thermal simulation results + #assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + #fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_inductor_core_fixed_loss_angle_foil_vertical.json") + #compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_transformer_core_fixed_loss_angle(femmt_simulation_transformer_core_fixed_loss_angle): - test_result_log = femmt_simulation_transformer_core_fixed_loss_angle + test_result_log, thermal_result_log = femmt_simulation_transformer_core_fixed_loss_angle assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" @@ -931,8 +1378,13 @@ def test_transformer_core_fixed_loss_angle(femmt_simulation_transformer_core_fix fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "log_electro_magnetic_transformer_core_fixed_loss_angle.json") compare_result_logs(test_result_log, fixture_result_log) + # check thermal simulation results + assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_transformer_core_fixed_loss_angle.json") + compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_transformer_interleaved_core_fixed_loss_angle(femmt_simulation_transformer_interleaved_core_fixed_loss_angle): - test_result_log = femmt_simulation_transformer_interleaved_core_fixed_loss_angle + test_result_log, thermal_result_log = femmt_simulation_transformer_interleaved_core_fixed_loss_angle assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" @@ -940,8 +1392,13 @@ def test_transformer_interleaved_core_fixed_loss_angle(femmt_simulation_transfor fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "log_electro_magnetic_transformer_interleaved_core_fixed_loss_angle.json") compare_result_logs(test_result_log, fixture_result_log) + # check thermal simulation results + assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_transformer_interleaved_core_fixed_loss_angle.json") + compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_transformer_integrated_core_fixed_loss_angle(femmt_simulation_transformer_integrated_core_fixed_loss_angle): - test_result_log = femmt_simulation_transformer_integrated_core_fixed_loss_angle + test_result_log, thermal_result_log = femmt_simulation_transformer_integrated_core_fixed_loss_angle assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" @@ -949,6 +1406,11 @@ def test_transformer_integrated_core_fixed_loss_angle(femmt_simulation_transform fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "log_electro_magnetic_transformer_integrated_core_fixed_loss_angle.json") compare_result_logs(test_result_log, fixture_result_log) + # check thermal simulation results + #assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + #fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_transformer_integrated_core_fixed_loss_angle.json") + #compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_load_files(temp_folder, femmt_simulation_inductor_core_material_database, femmt_simulation_inductor_core_fixed_loss_angle, femmt_simulation_inductor_core_fixed_loss_angle_litz_wire, @@ -1001,20 +1463,6 @@ def test_load_files(temp_folder, femmt_simulation_inductor_core_material_databas #compare_result_logs(test_result_log, fixture_result_log) -def test_thermal_simulation(thermal_simulation): - electromagnetoquasistatic_result_log, thermal_result_log = thermal_simulation - - # check magnetoquasistatic simulation results - assert os.path.exists(electromagnetoquasistatic_result_log), "Electro magnetic simulation did not work!" - fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "log_electro_magnetic_thermal.json") - compare_result_logs(electromagnetoquasistatic_result_log, fixture_result_log) - - # check thermal simulation results - assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" - fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "results_thermal.json") - compare_thermal_result_logs(thermal_result_log, fixture_result_log) - - ############################## # Basic example tests # These tests just run the basic examples an see if the run without error From 4642f804857b8f44f7cdf17c119d4169477b6fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikolas=20F=C3=B6rster?= Date: Tue, 31 Oct 2023 12:01:45 +0100 Subject: [PATCH 4/6] add stacked transformer to tests --- ...rmer_integrated_core_fixed_loss_angle.json | 90 ++ ...mal_transformer_stacked_center_tapped.json | 140 ++++ .../transformer_stacked_center_tapped.json | 791 ++++++++++++++++++ tests/integration/test_femmt.py | 163 +++- 4 files changed, 1180 insertions(+), 4 deletions(-) create mode 100644 tests/integration/fixtures/results/thermal_transformer_integrated_core_fixed_loss_angle.json create mode 100644 tests/integration/fixtures/results/thermal_transformer_stacked_center_tapped.json create mode 100644 tests/integration/fixtures/results/transformer_stacked_center_tapped.json diff --git a/tests/integration/fixtures/results/thermal_transformer_integrated_core_fixed_loss_angle.json b/tests/integration/fixtures/results/thermal_transformer_integrated_core_fixed_loss_angle.json new file mode 100644 index 00000000..b5800ea4 --- /dev/null +++ b/tests/integration/fixtures/results/thermal_transformer_integrated_core_fixed_loss_angle.json @@ -0,0 +1,90 @@ +{ + "core_parts": { + "core_part_1": { + "min": 20.04653861830209, + "max": 21.24758544552233, + "mean": 20.594005093085773 + }, + "core_part_2": { + "min": 20.40301047179924, + "max": 20.8330136539829, + "mean": 20.688893477317325 + }, + "total": { + "min": 20.04653861830209, + "max": 21.24758544552233, + "mean": 20.64144928520155 + } + }, + "windings": { + "winding_0_0": { + "min": 21.22334262382156, + "max": 21.22837551824961, + "mean": 21.225795862298074 + }, + "winding_0_1": { + "min": 21.37910942485433, + "max": 21.38262242055034, + "mean": 21.38105738101794 + }, + "winding_0_2": { + "min": 21.45262983304582, + "max": 21.45550943635332, + "mean": 21.454086268059573 + }, + "winding_0_3": { + "min": 20.69272787756391, + "max": 20.69399203274648, + "mean": 20.693411656603796 + }, + "winding_1_0": { + "min": 21.30774666516796, + "max": 21.31268549869332, + "mean": 21.309942013372833 + }, + "winding_1_1": { + "min": 21.47794772786948, + "max": 21.48193722187542, + "mean": 21.480038708830612 + }, + "winding_1_2": { + "min": 21.57867243012928, + "max": 21.5797184510145, + "mean": 21.579374051717608 + }, + "winding_1_3": { + "min": 21.52587701982411, + "max": 21.52896137687279, + "mean": 21.52764073709713 + }, + "winding_1_4": { + "min": 21.37153290280354, + "max": 21.37608023233968, + "mean": 21.373691593226635 + }, + "winding_1_5": { + "min": 21.22056221214933, + "max": 21.22402953045881, + "mean": 21.221917737480425 + }, + "winding_1_6": { + "min": 20.72911210392989, + "max": 20.73039555004542, + "mean": 20.72994246398273 + }, + "winding_1_7": { + "min": 20.6532240287376, + "max": 20.65519949914115, + "mean": 20.654058313033786 + }, + "total": { + "min": 20.6532240287376, + "max": 21.5797184510145, + "mean": 21.21924639889343 + } + }, + "misc": { + "case_volume": 0.00019303762679690408, + "case_weight": -1 + } +} \ No newline at end of file diff --git a/tests/integration/fixtures/results/thermal_transformer_stacked_center_tapped.json b/tests/integration/fixtures/results/thermal_transformer_stacked_center_tapped.json new file mode 100644 index 00000000..6e15de6a --- /dev/null +++ b/tests/integration/fixtures/results/thermal_transformer_stacked_center_tapped.json @@ -0,0 +1,140 @@ +{ + "core_parts": { + "core_part_1": { + "min": 20.00442178971212, + "max": 20.01215169908621, + "mean": 20.010755553443452 + }, + "core_part_2": { + "min": 20.01215676365594, + "max": 20.01277486946877, + "mean": 20.012350474163323 + }, + "core_part_3": { + "min": 20.01088209239312, + "max": 20.01308467726944, + "mean": 20.012288453167507 + }, + "core_part_4": { + "min": 20.00930557354711, + "max": 20.01187180734401, + "mean": 20.010651867151598 + }, + "core_part_5": { + "min": 20.00696146122564, + "max": 20.0131040645083, + "mean": 20.01243128947938 + }, + "total": { + "min": 20.00442178971212, + "max": 20.0131040645083, + "mean": 20.011695527481052 + } + }, + "windings": { + "winding_0_0": { + "min": 20.01307745206233, + "max": 20.01313954805585, + "mean": 20.013119985443467 + }, + "winding_0_1": { + "min": 20.01289086883742, + "max": 20.01303905630243, + "mean": 20.01296580891639 + }, + "winding_0_2": { + "min": 20.01269781903796, + "max": 20.01284594581066, + "mean": 20.012767373160322 + }, + "winding_0_3": { + "min": 20.01203090603548, + "max": 20.01208434387253, + "mean": 20.012058328342878 + }, + "winding_0_4": { + "min": 20.01199408479541, + "max": 20.01205412785553, + "mean": 20.01202534350818 + }, + "winding_0_5": { + "min": 20.01192212089257, + "max": 20.01199824749053, + "mean": 20.01196262380059 + }, + "winding_0_6": { + "min": 20.01210818413711, + "max": 20.01213756957902, + "mean": 20.01212527066642 + }, + "winding_0_7": { + "min": 20.01207890328756, + "max": 20.01211642350503, + "mean": 20.012099099246225 + }, + "winding_0_8": { + "min": 20.01202444650466, + "max": 20.01207492757923, + "mean": 20.01205081655648 + }, + "winding_0_9": { + "min": 20.01195206196783, + "max": 20.01201450707192, + "mean": 20.011984652629167 + }, + "winding_0_10": { + "min": 20.01218336185178, + "max": 20.01220374096687, + "mean": 20.012196539840705 + }, + "winding_0_11": { + "min": 20.01215094062147, + "max": 20.01218646142387, + "mean": 20.012169718122934 + }, + "winding_0_12": { + "min": 20.01209643134435, + "max": 20.01214487918894, + "mean": 20.01212130465183 + }, + "winding_0_13": { + "min": 20.01202675628716, + "max": 20.01208403801863, + "mean": 20.012054760123863 + }, + "winding_0_14": { + "min": 20.01218592137931, + "max": 20.01220184550852, + "mean": 20.012195909048305 + }, + "winding_0_15": { + "min": 20.01213965294995, + "max": 20.01217818592358, + "mean": 20.012160055100555 + }, + "winding_0_16": { + "min": 20.01207444498193, + "max": 20.01212690180343, + "mean": 20.01210036382833 + }, + "winding_1_0": { + "min": 20.01192645174038, + "max": 20.01220588751465, + "mean": 20.012093502724664 + }, + "winding_2_0": { + "min": 20.01170469612669, + "max": 20.01216671081474, + "mean": 20.012002263691592 + }, + "total": { + "min": 20.01170469612669, + "max": 20.01313954805585, + "mean": 20.012223879968577 + } + }, + "misc": { + "case_volume": 0.0001752032961426901, + "case_weight": -1 + } +} \ No newline at end of file diff --git a/tests/integration/fixtures/results/transformer_stacked_center_tapped.json b/tests/integration/fixtures/results/transformer_stacked_center_tapped.json new file mode 100644 index 00000000..60194367 --- /dev/null +++ b/tests/integration/fixtures/results/transformer_stacked_center_tapped.json @@ -0,0 +1,791 @@ +{ + "single_sweeps": [ + { + "f": 200000, + "winding1": { + "turn_losses": [ + 0.00854745442416348, + 0.003968722783214754, + 0.001391349603448017, + 0.00185307869987259, + 0.002167011038618997, + 0.002211605742967861, + 0.002605005876262636, + 0.001976774301170707, + 0.002246655032313463, + 0.002032242973961912, + 0.002603438857226084, + 0.001977321336368448, + 0.002247515317207334, + 0.002032729274984073, + 0.001852661746831253, + 0.00216659799916434, + 0.002211043510552654 + ], + "flux": [ + 9.154756491555945e-05, + -8.366501014306989e-07 + ], + "flux_over_current": [ + 9.154756491555914e-05, + -8.541145007172639e-07 + ], + "V": [ + 1.073311936311148, + 115.0420629571021 + ], + "number_turns": 17, + "I": [ + 1, + 0 + ], + "winding_losses": 0.04409120851832866, + "P": 0.536655968155574, + "Q": 57.52103147855105, + "S": 57.523534853002715 + }, + "winding2": { + "turn_losses": [ + 0.1013725974059359 + ], + "flux": [ + 6.28487714772295e-06, + -5.453894896672284e-08 + ], + "flux_over_current": [ + 0, + 0 + ], + "V": [ + 0.06833440295013014, + 7.89780535485187 + ], + "number_turns": 2, + "I": [ + 0, + 0 + ], + "winding_losses": 0.1013725974059359, + "P": 0.0, + "Q": 0.0, + "S": 0.0 + }, + "winding3": { + "turn_losses": [ + 0.1014347183973672 + ], + "flux": [ + 6.284865027561311e-06, + -5.453659383678326e-08 + ], + "flux_over_current": [ + 0, + 0 + ], + "V": [ + 0.06833142685735918, + 7.897790109083544 + ], + "number_turns": 2, + "I": [ + 0, + 0 + ], + "winding_losses": 0.1014347183973672, + "P": 0.0, + "Q": 0.0, + "S": 0.0 + }, + "core_eddy_losses": 0.04381553139991682, + "core_hyst_losses": 0.2459419134644537, + "core_parts": { + "core_part_1": { + "eddy_losses": 0.02217773207007774, + "hyst_losses": 0.1634433476425362, + "total_core_part_1": 0.18562107971261393 + }, + "core_part_2": { + "eddy_losses": 0.009786998821391217, + "hyst_losses": 0.0338852269383, + "total_core_part_2": 0.043672225759691215 + }, + "core_part_3": { + "eddy_losses": 0.01139804204581063, + "hyst_losses": 0.04120554993572245, + "total_core_part_3": 0.05260359198153308 + }, + "core_part_4": { + "eddy_losses": 0.0001593803300013477, + "hyst_losses": 0.005234210468247662, + "total_core_part_4": 0.0053935907982490105 + }, + "core_part_5": { + "eddy_losses": 0.0002933781326359427, + "hyst_losses": 0.002173578479648176, + "total_core_part_5": 0.0024669566122841186 + } + }, + "all_winding_losses": 0.24689852432163176 + }, + { + "f": 200000, + "winding1": { + "turn_losses": [ + 4.832579866245031e-09, + 3.066020340314766e-09, + 1.702383659953918e-09, + 4.557033204938074e-07, + 1.302346528548916e-07, + 1.473722895811995e-07, + 6.173547529472612e-06, + 7.448275808681261e-07, + 2.758064661750736e-07, + 1.971460188688776e-07, + 4.005535928846266e-06, + 2.141028761262491e-07, + 1.439480178954795e-07, + 1.507852422715736e-07, + 1.510149833045326e-06, + 3.900116220558879e-07, + 2.18379254644799e-07 + ], + "flux": [ + 6.284873809133666e-06, + -5.437879006479036e-08 + ], + "flux_over_current": [ + 0, + 0 + ], + "V": [ + 0.06833440295145926, + 7.897805355005286 + ], + "number_turns": 17, + "I": [ + 0, + 0 + ], + "winding_losses": 1.476715161706667e-05, + "P": 0.0, + "Q": 0.0, + "S": 0.0 + }, + "winding2": { + "turn_losses": [ + 0.0007070716750583408 + ], + "flux": [ + 4.511651791784028e-07, + -4.333651153399458e-09 + ], + "flux_over_current": [ + 4.511649824184797e-07, + -4.4029149945916566e-09 + ], + "V": [ + 0.005532866160555796, + 0.5669506377291456 + ], + "number_turns": 2, + "I": [ + 1, + 0 + ], + "winding_losses": 0.0007070716750583408, + "P": 0.002766433080277898, + "Q": 0.2834753188645728, + "S": 0.28348881734092946 + }, + "winding3": { + "turn_losses": [ + 0.0005268829822123683 + ], + "flux": [ + 4.494123773863792e-07, + -3.702944863146842e-09 + ], + "flux_over_current": [ + 0, + 0 + ], + "V": [ + 0.004639985848272382, + 0.564747909121568 + ], + "number_turns": 2, + "I": [ + 0, + 0 + ], + "winding_losses": 0.0005268829822123683, + "P": 0.0, + "Q": 0.0, + "S": 0.0 + }, + "core_eddy_losses": 0.0002142283617254341, + "core_hyst_losses": 0.001303482915047707, + "core_parts": { + "core_part_1": { + "eddy_losses": 0.0001133833790724526, + "hyst_losses": 0.0008357483060413147, + "total_core_part_1": 0.0009491316851137672 + }, + "core_part_2": { + "eddy_losses": 4.971501325056382e-05, + "hyst_losses": 0.0001746526292367056, + "total_core_part_2": 0.00022436764248726942 + }, + "core_part_3": { + "eddy_losses": 5.04223464868899e-05, + "hyst_losses": 0.0002678172823222363, + "total_core_part_3": 0.0003182396288091262 + }, + "core_part_4": { + "eddy_losses": 7.070152304523473e-07, + "hyst_losses": 2.522337907990443e-05, + "total_core_part_4": 2.5930394310356777e-05 + }, + "core_part_5": { + "eddy_losses": 6.076850750808244e-10, + "hyst_losses": 4.131836754892995e-08, + "total_core_part_5": 4.192605262401078e-08 + } + }, + "all_winding_losses": 0.0012487218088877757 + }, + { + "f": 200000, + "winding1": { + "turn_losses": [ + 4.795436323172129e-09, + 3.042325208673895e-09, + 1.689205269611696e-09, + 1.511524809751418e-06, + 3.901554082550339e-07, + 2.183849112322217e-07, + 4.01134272057779e-06, + 2.143110135187956e-07, + 1.439014049427083e-07, + 1.507435876510932e-07, + 6.166705483005869e-06, + 7.443137411848738e-07, + 2.75779363718349e-07, + 1.971642187673827e-07, + 4.549912539751239e-07, + 1.302646252596657e-07, + 1.474128360272629e-07 + ], + "flux": [ + 6.28486167693653e-06, + -5.437642176540741e-08 + ], + "flux_over_current": [ + 0, + 0 + ], + "V": [ + 0.06833142685868161, + 7.897790109236745 + ], + "number_turns": 17, + "I": [ + 0, + 0 + ], + "winding_losses": 1.476652234466901e-05, + "P": 0.0, + "Q": 0.0, + "S": 0.0 + }, + "winding2": { + "turn_losses": [ + 0.0005265874854861891 + ], + "flux": [ + 4.494123770831253e-07, + -3.702945009603913e-09 + ], + "flux_over_current": [ + 0, + 0 + ], + "V": [ + 0.004639985848271956, + 0.5647479091215482 + ], + "number_turns": 2, + "I": [ + 0, + 0 + ], + "winding_losses": 0.0005265874854861891, + "P": 0.0, + "Q": 0.0, + "S": 0.0 + }, + "winding3": { + "turn_losses": [ + 0.0007073710949399029 + ], + "flux": [ + 4.51165148360193e-07, + -4.333673353100642e-09 + ], + "flux_over_current": [ + 4.5116495128896877e-07, + -4.40293733511328e-09 + ], + "V": [ + 0.00553289423448324, + 0.5669505986106484 + ], + "number_turns": 2, + "I": [ + 1, + 0 + ], + "winding_losses": 0.0007073710949399029, + "P": 0.00276644711724162, + "Q": 0.2834752993053242, + "S": 0.28348879791959264 + }, + "core_eddy_losses": 0.0002142275065171041, + "core_hyst_losses": 0.001303494513256726, + "core_parts": { + "core_part_1": { + "eddy_losses": 0.0001138752002961412, + "hyst_losses": 0.0008383434964385632, + "total_core_part_1": 0.0009522186967347043 + }, + "core_part_2": { + "eddy_losses": 4.959665381022874e-05, + "hyst_losses": 0.0001742105734750961, + "total_core_part_2": 0.00022380722728532486 + }, + "core_part_3": { + "eddy_losses": 5.005339851558071e-05, + "hyst_losses": 0.0002658674771396305, + "total_core_part_3": 0.00031592087565521123 + }, + "core_part_4": { + "eddy_losses": 7.016507538474428e-07, + "hyst_losses": 2.503196453104246e-05, + "total_core_part_4": 2.57336152848899e-05 + }, + "core_part_5": { + "eddy_losses": 6.031413068930598e-10, + "hyst_losses": 4.100167238980393e-08, + "total_core_part_5": 4.1604813696696985e-08 + } + }, + "all_winding_losses": 0.001248725102770761 + } + ], + "total_losses": { + "winding1": { + "total": 0.04412074219229034, + "turns": [ + 0.008547464052179668, + 0.003968728891560303, + 0.0013913529950369467, + 0.0018550459280028352, + 0.002167531428680107, + 0.0022119715001686748, + 0.0026151907665126865, + 0.001977733439765094, + 0.0022470747401845807, + 0.002032590863568432, + 0.002613611098637936, + 0.001978279752985759, + 0.0022479350445889475, + 0.002033077224445112, + 0.0018546268879182735, + 0.0021671182754116557, + 0.0022114093026433263 + ] + }, + "winding2": { + "total": 0.10260625656648044, + "turns": [ + 0.10260625656648044 + ] + }, + "winding3": { + "total": 0.10266897247451948, + "turns": [ + 0.10266897247451948 + ] + }, + "all_windings": 0.2493959712332903, + "eddy_core": 0.044243987268159354, + "total_core_part_1": 0.0009522186967347043, + "total_core_part_2": 0.00022380722728532486, + "total_core_part_3": 0.00031592087565521123, + "total_core_part_4": 2.57336152848899e-05, + "total_core_part_5": 4.1604813696696985e-08, + "hyst_core_fundamental_freq": 0.2459419134644537, + "core": 0.2901859007326131, + "total_losses": 0.5395818719659033 + }, + "simulation_settings": { + "simulation_name": null, + "date": "2023-10-31 11:53:45", + "component_type": "IntegratedTransformer", + "working_directory": "/home/nikolasf/Dokumente/01_git/30_Python/FEMMT/tests/integration/temp", + "core": { + "core_inner_diameter": 0.02, + "window_w": 0.015, + "window_h_bot": 0.017, + "window_h_top": 0.005, + "material": "custom", + "loss_approach": "LossAngle", + "mu_r_abs": 3100, + "phi_mu_deg": 12, + "sigma": [ + 1.2, + 0.0 + ], + "non_linear": false, + "correct_outer_leg": false, + "temperature": null, + "permeability_datasource": "custom", + "permeability_measurement_setup": null, + "permeability_datatype": null, + "permittivity_datasource": "custom", + "permittivity_measurement_setup": null, + "permittivity_datatype": null + }, + "winding_windows": [ + { + "max_bot_bound": 0.014500000000000002, + "max_top_bound": 0.0175, + "max_left_bound": 0.012, + "max_right_bound": 0.024, + "virtual_winding_windows": [ + { + "bot_bound": 0.014500000000000002, + "top_bound": 0.0175, + "left_bound": 0.013000000000000001, + "right_bound": 0.024, + "winding_type": "Single", + "winding_scheme": null, + "wrap_para": null, + "windings": [ + { + "winding_number": 0, + "conductivity": "Copper", + "conductor_type": "RoundLitz", + "thickness": null, + "conductor_radius": 0.0011, + "conductor_arrangement": "SquareFullWidth", + "number_strands": 50, + "strand_radius": 0.00011, + "fill_factor": 0.5 + } + ], + "turns": [ + 3, + 0, + 0 + ] + } + ] + }, + { + "max_bot_bound": -0.007500000000000001, + "max_top_bound": 0.007500000000000001, + "max_left_bound": 0.012, + "max_right_bound": 0.024, + "virtual_winding_windows": [ + { + "bot_bound": -0.007500000000000001, + "top_bound": -0.006500000000000001, + "left_bound": 0.012, + "right_bound": 0.024, + "winding_type": "Single", + "winding_scheme": "FoilHorizontal", + "wrap_para": null, + "windings": [ + { + "winding_number": 2, + "conductivity": "Copper", + "conductor_type": "RectangularSolid", + "thickness": 0.001, + "conductor_radius": 1, + "conductor_arrangement": null, + "number_strands": 0, + "strand_radius": null, + "fill_factor": null + } + ], + "turns": [ + 0, + 0, + 1 + ] + }, + { + "bot_bound": -0.0061, + "top_bound": -0.0039000000000000007, + "left_bound": 0.0142, + "right_bound": 0.024, + "winding_type": "Single", + "winding_scheme": "Single", + "wrap_para": null, + "windings": [ + { + "winding_number": 0, + "conductivity": "Copper", + "conductor_type": "RoundLitz", + "thickness": null, + "conductor_radius": 0.0011, + "conductor_arrangement": "SquareFullWidth", + "number_strands": 50, + "strand_radius": 0.00011, + "fill_factor": 0.5 + } + ], + "turns": [ + 3, + 0, + 0 + ] + }, + { + "bot_bound": -0.0037000000000000006, + "top_bound": -0.0015000000000000005, + "left_bound": 0.013000000000000001, + "right_bound": 0.024, + "winding_type": "Single", + "winding_scheme": "Single", + "wrap_para": null, + "windings": [ + { + "winding_number": 0, + "conductivity": "Copper", + "conductor_type": "RoundLitz", + "thickness": null, + "conductor_radius": 0.0011, + "conductor_arrangement": "SquareFullWidth", + "number_strands": 50, + "strand_radius": 0.00011, + "fill_factor": 0.5 + } + ], + "turns": [ + 4, + 0, + 0 + ] + }, + { + "bot_bound": -0.0011000000000000003, + "top_bound": -0.00010000000000000026, + "left_bound": 0.012, + "right_bound": 0.024, + "winding_type": "Single", + "winding_scheme": "FoilHorizontal", + "wrap_para": null, + "windings": [ + { + "winding_number": 1, + "conductivity": "Copper", + "conductor_type": "RectangularSolid", + "thickness": 0.001, + "conductor_radius": 1, + "conductor_arrangement": null, + "number_strands": 0, + "strand_radius": null, + "fill_factor": null + } + ], + "turns": [ + 0, + 1, + 0 + ] + }, + { + "bot_bound": 9.99999999999994e-05, + "top_bound": 0.0010999999999999994, + "left_bound": 0.012, + "right_bound": 0.024, + "winding_type": "Single", + "winding_scheme": "FoilHorizontal", + "wrap_para": null, + "windings": [ + { + "winding_number": 2, + "conductivity": "Copper", + "conductor_type": "RectangularSolid", + "thickness": 0.001, + "conductor_radius": 1, + "conductor_arrangement": null, + "number_strands": 0, + "strand_radius": null, + "fill_factor": null + } + ], + "turns": [ + 0, + 0, + 1 + ] + }, + { + "bot_bound": 0.0014999999999999987, + "top_bound": 0.0036999999999999993, + "left_bound": 0.013000000000000001, + "right_bound": 0.024, + "winding_type": "Single", + "winding_scheme": "Single", + "wrap_para": null, + "windings": [ + { + "winding_number": 0, + "conductivity": "Copper", + "conductor_type": "RoundLitz", + "thickness": null, + "conductor_radius": 0.0011, + "conductor_arrangement": "SquareFullWidth", + "number_strands": 50, + "strand_radius": 0.00011, + "fill_factor": 0.5 + } + ], + "turns": [ + 4, + 0, + 0 + ] + }, + { + "bot_bound": 0.0039, + "top_bound": 0.0061, + "left_bound": 0.0142, + "right_bound": 0.024, + "winding_type": "Single", + "winding_scheme": "Single", + "wrap_para": null, + "windings": [ + { + "winding_number": 0, + "conductivity": "Copper", + "conductor_type": "RoundLitz", + "thickness": null, + "conductor_radius": 0.0011, + "conductor_arrangement": "SquareFullWidth", + "number_strands": 50, + "strand_radius": 0.00011, + "fill_factor": 0.5 + } + ], + "turns": [ + 3, + 0, + 0 + ] + }, + { + "bot_bound": 0.0065, + "top_bound": 0.007499999999999999, + "left_bound": 0.012, + "right_bound": 0.024, + "winding_type": "Single", + "winding_scheme": "FoilHorizontal", + "wrap_para": null, + "windings": [ + { + "winding_number": 1, + "conductivity": "Copper", + "conductor_type": "RectangularSolid", + "thickness": 0.001, + "conductor_radius": 1, + "conductor_arrangement": null, + "number_strands": 0, + "strand_radius": null, + "fill_factor": null + } + ], + "turns": [ + 0, + 1, + 0 + ] + } + ] + } + ], + "air_gaps": { + "method": "Stacked", + "air_gap_number": 2, + "air_gaps": [ + { + "leg_position": "CenterLeg", + "position_value": 0, + "height": 0.002, + "stacked_position": 1 + }, + { + "leg_position": "CenterLeg", + "position_value": 0, + "height": 0.001, + "stacked_position": 2 + } + ] + }, + "insulation": { + "inner_winding_insulations": [ + [ + 0.0002, + 0.0004, + 0.0004 + ], + [ + 0.0004, + 0.0002, + 0.0004 + ], + [ + 0.0004, + 0.0004, + 0.0002 + ] + ], + "core_insulations": [ + 0.001, + 0.001, + 0.002, + 0.001 + ] + } + }, + "misc": { + "core_2daxi_volume": 4.7045349987507137e-05, + "core_2daxi_total_volume": 8.42732229325462e-05, + "core_2daxi_weight": 0.0, + "wire_lengths": [ + 1.8679909918244912, + 0.15079644737231007, + 0.15079644737231007 + ], + "wire_volumes": [ + 7.100844800034157e-06, + 2.261946710584651e-06, + 2.261946710584651e-06 + ], + "wire_weight": [ + 0.06333953561630468, + 0.020176564658415087, + 0.020176564658415087 + ], + "core_cost": 0.0, + "winding_cost": [ + 5.390235760108246, + 5.186003198386112, + 5.186003198386112 + ], + "total_cost_incl_margin": 21.016322875840626 + } +} \ No newline at end of file diff --git a/tests/integration/test_femmt.py b/tests/integration/test_femmt.py index 3bf776dd..da35e390 100644 --- a/tests/integration/test_femmt.py +++ b/tests/integration/test_femmt.py @@ -1134,7 +1134,8 @@ def femmt_simulation_transformer_integrated_core_fixed_loss_angle(temp_folder): case_gap_right, case_gap_bot, show_thermal_simulation_results=False, pre_visualize_geometry=False, color_scheme=color_scheme, - colors_geometry=colors_geometry) + colors_geometry=colors_geometry, + flag_insulation=False) except Exception as e: @@ -1147,6 +1148,145 @@ def femmt_simulation_transformer_integrated_core_fixed_loss_angle(temp_folder): return electromagnetoquasistatic_result, thermal_result +@pytest.fixture +def femmt_simulation_transformer_stacked_center_tapped(temp_folder): + temp_folder_path, onelab_folder = temp_folder + + # Create new temp folder, build model and simulate + try: + working_directory = temp_folder_path + if not os.path.exists(working_directory): + os.mkdir(working_directory) + + # 1. chose simulation type + geo = fmt.MagneticComponent(component_type=fmt.ComponentType.IntegratedTransformer, + working_directory=working_directory, verbosity=fmt.Verbosity.Silent, + is_gui=True) + + # Set onelab path manually + geo.file_data.onelab_folder_path = onelab_folder + + core_dimensions = fmt.dtos.StackedCoreDimensions(core_inner_diameter=0.02, window_w=0.015, window_h_top=0.005, + window_h_bot=0.017) + core = fmt.Core(core_type=fmt.CoreType.Stacked, core_dimensions=core_dimensions, mu_r_abs=3100, phi_mu_deg=12, + sigma=1.2, + permeability_datasource=fmt.MaterialDataSource.Custom, + permittivity_datasource=fmt.MaterialDataSource.Custom) + geo.set_core(core) + + air_gaps = fmt.AirGaps(fmt.AirGapMethod.Stacked, core) + air_gaps.add_air_gap(fmt.AirGapLegPosition.CenterLeg, 0.002, stacked_position=fmt.StackedPosition.Top) + air_gaps.add_air_gap(fmt.AirGapLegPosition.CenterLeg, 0.001, stacked_position=fmt.StackedPosition.Bot) + geo.set_air_gaps(air_gaps) + + # set_center_tapped_windings() automatically places the condu + insulation, coil_window, transformer_window = fmt.functions_topologies.set_center_tapped_windings(core=core, + primary_turns=14, + primary_radius=1.1e-3, + primary_number_strands=50, + primary_strand_radius=0.00011, + secondary_parallel_turns=2, + secondary_thickness_foil=1e-3, + iso_top_core=0.001, + iso_bot_core=0.001, + iso_left_core=0.002, + iso_right_core=0.001, + iso_primary_to_primary=2e-4, + iso_secondary_to_secondary=2e-4, + iso_primary_to_secondary=4e-4, + interleaving_type=fmt.CenterTappedInterleavingType.TypeC, + interleaving_scheme=fmt.InterleavingSchemesFoilLitz.ter_3_4_sec_ter_4_3_sec, + primary_coil_turns=3, + primary_additional_bobbin=1e-3, + winding_temperature=100, + bobbin_coil_left=3e-3, + center_foil_additional_bobbin=0e-3) + + geo.set_insulation(insulation) + geo.set_winding_windows([coil_window, transformer_window]) + + geo.create_model(freq=200000, pre_visualize_geometry=False) + + geo.single_simulation(freq=200000, current=[20, 120, 120], phi_deg=[0, 180, 180], + show_fem_simulation_results=False) + + geo.get_inductances(I0=1, op_frequency=200000) + + # Thermal simulation: + # The losses calculated by the magnetics simulation can be used to calculate the heat distribution of the given magnetic component + # In order to use the thermal simulation, thermal conductivities for each material can be entered as well as a boundary temperature + # which will be applied on the boundary of the simulation (dirichlet boundary condition). + + # The case parameter sets the thermal conductivity for a case which will be set around the core. + # This could model some case in which the transformer is placed in together with a set potting material. + thermal_conductivity_dict = { + "air": 0.0263, + "case": { # epoxy resign + "top": 1.54, + "top_right": 1.54, + "right": 1.54, + "bot_right": 1.54, + "bot": 1.54 + }, + "core": 5, # ferrite + "winding": 400, # copper + "air_gaps": 180, # aluminiumnitride + "insulation": 0.42 # polyethylen + } + + # Here the case size can be determined + case_gap_top = 0.002 + case_gap_right = 0.0025 + case_gap_bot = 0.002 + + # Here the boundary temperatures can be set, currently it is set to 20°C (around 293°K). + # This does not change the results of the simulation (at least when every boundary is set equally) but will set the temperature offset. + boundary_temperatures = { + "value_boundary_top": 20, + "value_boundary_top_right": 20, + "value_boundary_right_top": 20, + "value_boundary_right": 20, + "value_boundary_right_bottom": 20, + "value_boundary_bottom_right": 20, + "value_boundary_bottom": 20 + } + + # In order to compare the femmt thermal simulation with a femm heat flow simulation the same boundary temperature should be applied. + # Currently only one temperature can be applied which will be set on every boundary site. + femm_boundary_temperature = 20 + + # Here the boundary sides can be turned on (1) or off (0) + # By turning off the flag a neumann boundary will be applied at this point with heat flux = 0 + boundary_flags = { + "flag_boundary_top": 0, + "flag_boundary_top_right": 0, + "flag_boundary_right_top": 1, + "flag_boundary_right": 1, + "flag_boundary_right_bottom": 1, + "flag_boundary_bottom_right": 1, + "flag_boundary_bottom": 1 + } + + # In order for the thermal simulation to work an electro_magnetic simulation has to run before. + # The em-simulation will create a file containing the losses. + # When the losses file is already created and contains the losses for the current model, it is enough to run geo.create_model in + # order for the thermal simulation to work (geo.single_simulation is not needed). + # Obviously when the model is modified and the losses can be out of date and therefore the geo.single_simulation needs to run again. + geo.thermal_simulation(thermal_conductivity_dict, boundary_temperatures, boundary_flags, case_gap_top, + case_gap_right, case_gap_bot, show_thermal_simulation_results=False, + color_scheme=fmt.colors_ba_jonas, + colors_geometry=fmt.colors_geometry_ba_jonas, + flag_insulation=False) + + except Exception as e: + print("An error occurred while creating the femmt mesh files:", e) + except KeyboardInterrupt: + print("Keyboard interrupt..") + + electromagnetoquasistatic_result = os.path.join(temp_folder_path, "results", "log_electro_magnetic.json") + thermal_result = os.path.join(temp_folder_path, "results", "results_thermal.json") + + return electromagnetoquasistatic_result, thermal_result @pytest.fixture def thermal_simulation(temp_folder): @@ -1407,9 +1547,24 @@ def test_transformer_integrated_core_fixed_loss_angle(femmt_simulation_transform compare_result_logs(test_result_log, fixture_result_log) # check thermal simulation results - #assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" - #fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_transformer_integrated_core_fixed_loss_angle.json") - #compare_thermal_result_logs(thermal_result_log, fixture_result_log) + assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_transformer_integrated_core_fixed_loss_angle.json") + compare_thermal_result_logs(thermal_result_log, fixture_result_log) + +def test_simulation_transformer_stacked_center_tapped(femmt_simulation_transformer_stacked_center_tapped): + test_result_log, thermal_result_log = femmt_simulation_transformer_stacked_center_tapped + + assert os.path.exists(test_result_log), "Electro magnetic simulation did not work!" + + # e_m mesh + fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "transformer_stacked_center_tapped.json") + compare_result_logs(test_result_log, fixture_result_log) + + # check thermal simulation results + assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" + fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_transformer_stacked_center_tapped.json") + compare_thermal_result_logs(thermal_result_log, fixture_result_log) + def test_load_files(temp_folder, femmt_simulation_inductor_core_material_database, femmt_simulation_inductor_core_fixed_loss_angle, From b2c22c90c04bba7ee976d1d8c437a616efcc0343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikolas=20F=C3=B6rster?= Date: Tue, 31 Oct 2023 12:50:15 +0100 Subject: [PATCH 5/6] reduce to 4 digits in some tests --- tests/integration/test_femmt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration/test_femmt.py b/tests/integration/test_femmt.py index da35e390..c97f07ab 100644 --- a/tests/integration/test_femmt.py +++ b/tests/integration/test_femmt.py @@ -1474,7 +1474,7 @@ def test_inductor_core_fixed_loss_angle_litz_wire(femmt_simulation_inductor_core # check thermal simulation results assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_inductor_core_fixed_loss_angle_litz_wire.json") - compare_thermal_result_logs(thermal_result_log, fixture_result_log) + compare_thermal_result_logs(thermal_result_log, fixture_result_log, significant_digits=4) def test_inductor_core_fixed_loss_angle_foil_vertical(femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical): test_result_log, thermal_result_log = femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical @@ -1558,12 +1558,12 @@ def test_simulation_transformer_stacked_center_tapped(femmt_simulation_transform # e_m mesh fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "transformer_stacked_center_tapped.json") - compare_result_logs(test_result_log, fixture_result_log) + compare_result_logs(test_result_log, fixture_result_log, significant_digits=4) # check thermal simulation results assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_transformer_stacked_center_tapped.json") - compare_thermal_result_logs(thermal_result_log, fixture_result_log) + compare_thermal_result_logs(thermal_result_log, fixture_result_log, significant_digits=4) def test_load_files(temp_folder, femmt_simulation_inductor_core_material_database, From bf9a9f4cd2a6e9a4a055414fcf5482835a41dea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikolas=20F=C3=B6rster?= Date: Fri, 3 Nov 2023 11:09:00 +0100 Subject: [PATCH 6/6] update significant digits for inductor_core_fixed_loss_angle --- tests/integration/test_femmt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_femmt.py b/tests/integration/test_femmt.py index c97f07ab..732306de 100644 --- a/tests/integration/test_femmt.py +++ b/tests/integration/test_femmt.py @@ -1469,12 +1469,12 @@ def test_inductor_core_fixed_loss_angle_litz_wire(femmt_simulation_inductor_core # e_m mesh fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "log_electro_magnetic_inductor_core_fixed_loss_angle_litz_wire.json") - compare_result_logs(test_result_log, fixture_result_log, significant_digits=4) + compare_result_logs(test_result_log, fixture_result_log, significant_digits=3) # check thermal simulation results assert os.path.exists(thermal_result_log), "Thermal simulation did not work!" fixture_result_log = os.path.join(os.path.dirname(__file__), "fixtures", "results", "thermal_inductor_core_fixed_loss_angle_litz_wire.json") - compare_thermal_result_logs(thermal_result_log, fixture_result_log, significant_digits=4) + compare_thermal_result_logs(thermal_result_log, fixture_result_log, significant_digits=3) def test_inductor_core_fixed_loss_angle_foil_vertical(femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical): test_result_log, thermal_result_log = femmt_simulation_inductor_core_fixed_loss_angle_foil_vertical