@@ -390,7 +390,7 @@ def start_proceed_study(config: InductorOptimizationDTO, number_trials: int | No
390390 # simulation for a given number of target trials
391391 if len (study_in_storage .trials ) < target_number_trials :
392392 study_in_memory = optuna .create_study (directions = ['minimize' , 'minimize' ], study_name = config .inductor_study_name , sampler = sampler )
393- print (f"Sampler is { study_in_memory .sampler .__class__ .__name__ } " )
393+ logger . info (f"Sampler is { study_in_memory .sampler .__class__ .__name__ } " )
394394 study_in_memory .add_trials (study_in_storage .trials )
395395 number_trials = target_number_trials - len (study_in_memory .trials )
396396 study_in_memory .optimize (func , n_trials = number_trials , show_progress_bar = True )
@@ -597,6 +597,75 @@ def df_from_trial_numbers(df: pd.DataFrame, trial_number_list: list[int]) -> pd.
597597
598598 return df_trial_numbers
599599
600+ @staticmethod
601+ def full_simulation (df_geometry : pd .DataFrame , current_waveform : list , inductor_config_filepath : str ) -> tuple :
602+ """
603+ Reluctance model (hysteresis losses, winding losses) for geometries from df_geometry.
604+
605+ :param df_geometry: Pandas dataframe with geometries
606+ :type df_geometry: pd.DataFrame
607+ :param current_waveform: Current waveform to simulate
608+ :type current_waveform: list
609+ :param inductor_config_filepath: Filepath of the inductor optimization configuration file
610+ :type inductor_config_filepath: str
611+ :return: volume, loss
612+ :rtype: tuple
613+ """
614+ for index , _ in df_geometry .iterrows ():
615+
616+ local_config = InductorOptimization .ReluctanceModel .load_config (inductor_config_filepath )
617+
618+ if local_config .core_name_list is not None :
619+ # using fixed core sizes from the database with flexible height.
620+ core_name = df_geometry ['params_core_name' ][index ]
621+ core = ff .core_database ()[core_name ]
622+ core_inner_diameter = core ["core_inner_diameter" ]
623+ window_w = core ["window_w" ]
624+ else :
625+ core_inner_diameter = df_geometry ['params_core_inner_diameter' ][index ]
626+ window_w = df_geometry ['params_window_w' ][index ]
627+
628+ # overwrite the old time-current vector with the new one
629+ local_config .time_current_vec = current_waveform
630+ target_and_fix_parameters = InductorOptimization .ReluctanceModel .calculate_fix_parameters (local_config )
631+
632+ litz_wire = ff .litz_database ()[df_geometry ['params_litz_wire_name' ][index ]]
633+ litz_wire_diameter = 2 * litz_wire ["conductor_radii" ]
634+
635+ # material properties
636+ material_db = mdb .MaterialDatabase (is_silent = True )
637+
638+ material_dto : mdb .MaterialCurve = material_db .material_data_interpolation_to_dto (
639+ df_geometry ['params_material_name' ][index ], target_and_fix_parameters .fundamental_frequency , local_config .temperature )
640+ # instantiate material-specific model
641+ magnet_material_model : mh .loss .LossModel = mh .loss .LossModel (material = df_geometry ['params_material_name' ][index ], team = "paderborn" )
642+
643+ reluctance_model_input = ReluctanceModelInput (
644+ core_inner_diameter = core_inner_diameter ,
645+ window_w = window_w ,
646+ window_h = df_geometry ["params_window_h" ][index ],
647+ turns = int (df_geometry ['params_turns' ][index ].item ()),
648+ target_inductance = local_config .target_inductance ,
649+ litz_wire_name = df_geometry ['params_litz_wire_name' ][index ],
650+ litz_wire_diameter = litz_wire_diameter ,
651+
652+ insulations = local_config .insulations ,
653+ material_dto = material_dto ,
654+ magnet_material_model = magnet_material_model ,
655+
656+ temperature = local_config .temperature ,
657+ current_extracted_vec = target_and_fix_parameters .current_extracted_vec ,
658+ fundamental_frequency = target_and_fix_parameters .fundamental_frequency ,
659+ fft_frequency_list = target_and_fix_parameters .fft_frequency_list ,
660+ fft_amplitude_list = target_and_fix_parameters .fft_amplitude_list ,
661+ fft_phases_list = target_and_fix_parameters .fft_phases_list
662+ )
663+
664+ reluctance_output : ReluctanceModelOutput = InductorOptimization .ReluctanceModel .single_reluctance_model_simulation (reluctance_model_input )
665+
666+ p_total = reluctance_output .p_loss_total
667+ return reluctance_output .volume , p_total , reluctance_output .area_to_heat_sink
668+
600669 class FemSimulation :
601670 """Contains methods to perform FEM simulations or process their results."""
602671
@@ -854,6 +923,26 @@ def single_fem_simulation(fem_input: FemInput, show_visual_outputs: bool = False
854923 )
855924 return fem_output
856925
926+ @staticmethod
927+ def filter_combined_loss_list_df (df : pd .DataFrame , factor_min_dc_losses : float = 1.2 , factor_max_dc_losses : float = 10 ) -> pd .DataFrame :
928+ """
929+ Remove designs with too high losses compared to the minimum losses.
930+
931+ :param df: pandas dataframe with study results
932+ :type df: pd.DataFrame
933+ :param factor_min_dc_losses: filter factor for the minimum dc losses
934+ :type factor_min_dc_losses: float
935+ :param factor_max_dc_losses: dc_max_loss = factor_max_dc_losses * min_available_dc_losses_in_pareto_front
936+ :type factor_max_dc_losses: float
937+ :returns: pandas dataframe with Pareto front near points
938+ :rtype: pd.DataFrame
939+ """
940+ df = df .drop (df [df ["combined_losses" ].isna ()].index )
941+ filtered_df = InductorOptimization .filter_df (df , x = "values_0" , y = "combined_losses" , factor_min_dc_losses = factor_min_dc_losses ,
942+ factor_max_dc_losses = factor_max_dc_losses )
943+
944+ return filtered_df
945+
857946 @staticmethod
858947 def full_simulation (df_geometry : pd .DataFrame , current_waveform : list , inductor_config_filepath : str , process_number : int = 1 ,
859948 print_derivations : bool = False ) -> tuple :
@@ -897,33 +986,33 @@ def full_simulation(df_geometry: pd.DataFrame, current_waveform: list, inductor_
897986 working_directory = os .path .join (
898987 target_and_fix_parameters .working_directories .fem_working_directory , f"process_{ process_number } " )
899988
900- # fem_input = FemInput(
901- # # general parameters
902- # working_directory=working_directory,
903- # simulation_name='xx',
904-
905- # # material and geometry parameters
906- # material_name=df_geometry['params_material_name'][index],
907- # litz_wire_name=df_geometry['params_litz_wire_name'][index],
908- # core_inner_diameter=core_inner_diameter,
909- # window_w=window_w,
910- # window_h=df_geometry["params_window_h"][index],
911- # air_gap_length=df_geometry['user_attrs_l_air_gap'][index],
912- # turns=int(df_geometry['params_turns'][index].item()),
913- # insulations=local_config.insulations,
914-
915- # # data sources
916- # material_data_sources=local_config.material_data_sources,
917-
918- # # operating point conditions
919- # temperature=local_config.temperature,
920- # fundamental_frequency=target_and_fix_parameters.fundamental_frequency,
921- # fft_frequency_list=target_and_fix_parameters.fft_frequency_list,
922- # fft_amplitude_list=target_and_fix_parameters.fft_amplitude_list,
923- # fft_phases_list=target_and_fix_parameters.fft_phases_list
924- # )
925-
926- # fem_output = InductorOptimization.FemSimulation.single_fem_simulation(fem_input, False)
989+ fem_input = FemInput (
990+ # general parameters
991+ working_directory = working_directory ,
992+ simulation_name = 'xx' ,
993+
994+ # material and geometry parameters
995+ material_name = df_geometry ['params_material_name' ][index ],
996+ litz_wire_name = df_geometry ['params_litz_wire_name' ][index ],
997+ core_inner_diameter = core_inner_diameter ,
998+ window_w = window_w ,
999+ window_h = df_geometry ["params_window_h" ][index ],
1000+ air_gap_length = df_geometry ['user_attrs_l_air_gap' ][index ],
1001+ turns = int (df_geometry ['params_turns' ][index ].item ()),
1002+ insulations = local_config .insulations ,
1003+
1004+ # data sources
1005+ material_data_sources = local_config .material_data_sources ,
1006+
1007+ # operating point conditions
1008+ temperature = local_config .temperature ,
1009+ fundamental_frequency = target_and_fix_parameters .fundamental_frequency ,
1010+ fft_frequency_list = target_and_fix_parameters .fft_frequency_list ,
1011+ fft_amplitude_list = target_and_fix_parameters .fft_amplitude_list ,
1012+ fft_phases_list = target_and_fix_parameters .fft_phases_list
1013+ )
1014+
1015+ fem_output = InductorOptimization .FemSimulation .single_fem_simulation (fem_input , False )
9271016
9281017 litz_wire = ff .litz_database ()[df_geometry ['params_litz_wire_name' ][index ]]
9291018 litz_wire_diameter = 2 * litz_wire ["conductor_radii" ]
@@ -959,42 +1048,21 @@ def full_simulation(df_geometry: pd.DataFrame, current_waveform: list, inductor_
9591048
9601049 reluctance_output : ReluctanceModelOutput = InductorOptimization .ReluctanceModel .single_reluctance_model_simulation (reluctance_model_input )
9611050
962- # p_total = reluctance_output.p_hyst + fem_output.fem_eddy_core + fem_output.fem_p_loss_winding
963- # workaround
964- p_total = reluctance_output .p_loss_total
965-
966- # if print_derivations:
967- # print(f"Inductance reluctance: {local_config.target_inductance}")
968- # print(f"Inductance FEM: {fem_output.fem_inductance}")
969- # print(f"Inductance derivation: {(fem_output.fem_inductance - local_config.target_inductance) / local_config.target_inductance * 100} %")
970- # print(f"Volume reluctance: {reluctance_output.volume}")
971- # print(f"Volume FEM: {fem_output.volume}")
972- # print(f"Volume derivation: {(reluctance_output.volume - fem_output.volume) / reluctance_output.volume * 100} %")
973- # print(f"P_winding reluctance: {reluctance_output.p_winding}")
974- # print(f"P_winding FEM: {fem_output.fem_p_loss_winding}")
975- # print(f"P_winding derivation: {(fem_output.fem_p_loss_winding - reluctance_output.p_winding) / fem_output.fem_p_loss_winding * 100}")
976- # print(f"P_hyst reluctance: {reluctance_output.p_hyst}")
977- # print(f"P_hyst FEM: {fem_output.fem_core_total}")
978- # print(f"P_hyst derivation: {(reluctance_output.p_hyst - fem_output.fem_core_total) / reluctance_output.p_hyst * 100}")
1051+ p_total = reluctance_output .p_hyst + fem_output .fem_eddy_core + fem_output .fem_p_loss_winding
1052+
1053+ if print_derivations :
1054+ logger .info (f"Inductance reluctance: { local_config .target_inductance } " )
1055+ logger .info (f"Inductance FEM: { fem_output .fem_inductance } " )
1056+ logger .info (f"Inductance derivation: "
1057+ f"{ (fem_output .fem_inductance - local_config .target_inductance ) / local_config .target_inductance * 100 } %" )
1058+ logger .info (f"Volume reluctance: { reluctance_output .volume } " )
1059+ logger .info (f"Volume FEM: { fem_output .volume } " )
1060+ logger .info (f"Volume derivation: { (reluctance_output .volume - fem_output .volume ) / reluctance_output .volume * 100 } %" )
1061+ logger .info (f"P_winding reluctance: { reluctance_output .p_winding } " )
1062+ logger .info (f"P_winding FEM: { fem_output .fem_p_loss_winding } " )
1063+ logger .info (f"P_winding derivation: { (fem_output .fem_p_loss_winding - reluctance_output .p_winding ) / fem_output .fem_p_loss_winding * 100 } " )
1064+ logger .info (f"P_hyst reluctance: { reluctance_output .p_hyst } " )
1065+ logger .info (f"P_hyst FEM: { fem_output .fem_core_total } " )
1066+ logger .info (f"P_hyst derivation: { (reluctance_output .p_hyst - fem_output .fem_core_total ) / reluctance_output .p_hyst * 100 } " )
9791067
9801068 return reluctance_output .volume , p_total , reluctance_output .area_to_heat_sink
981-
982- @staticmethod
983- def filter_combined_loss_list_df (df : pd .DataFrame , factor_min_dc_losses : float = 1.2 , factor_max_dc_losses : float = 10 ) -> pd .DataFrame :
984- """
985- Remove designs with too high losses compared to the minimum losses.
986-
987- :param df: pandas dataframe with study results
988- :type df: pd.DataFrame
989- :param factor_min_dc_losses: filter factor for the minimum dc losses
990- :type factor_min_dc_losses: float
991- :param factor_max_dc_losses: dc_max_loss = factor_max_dc_losses * min_available_dc_losses_in_pareto_front
992- :type factor_max_dc_losses: float
993- :returns: pandas dataframe with Pareto front near points
994- :rtype: pd.DataFrame
995- """
996- df = df .drop (df [df ["combined_losses" ].isna ()].index )
997- filtered_df = InductorOptimization .filter_df (df , x = "values_0" , y = "combined_losses" , factor_min_dc_losses = factor_min_dc_losses ,
998- factor_max_dc_losses = factor_max_dc_losses )
999-
1000- return filtered_df
0 commit comments