From 519ed295642b5861d2a697c87a0c0d80b480abfc Mon Sep 17 00:00:00 2001 From: Thomas Guillod Date: Mon, 1 Jun 2020 19:51:03 +0200 Subject: [PATCH] Minor bugfixes and indent correction Small changes for a release --- run_8_plot_single.m | 4 +-- .../+design_compute/CoreData.m | 18 +++++------ .../+design_compute/InductorCompute.m | 24 +++++++-------- .../+design_compute/WindingData.m | 10 +++---- .../+design_display/InductorDisplay.m | 10 +++---- .../+fem_ann/get_extend_inp.m | 6 ++-- source_inductor/utils/get_sweep.m | 4 +-- source_input/get_design_data_plot_all.m | 30 +++++++------------ source_input/get_fem_ann_data_fem.m | 2 +- source_input/get_fem_ann_data_train.m | 2 +- 10 files changed, 50 insertions(+), 60 deletions(-) diff --git a/run_8_plot_single.m b/run_8_plot_single.m index 206348d..2ce63fc 100644 --- a/run_8_plot_single.m +++ b/run_8_plot_single.m @@ -14,10 +14,10 @@ function run_8_plot_single() run_sub('ann') % run model with analytical approximation -% run_sub('approx') +run_sub('approx') % run model with FEM simulation -% run_sub('fem') +run_sub('fem') end diff --git a/source_inductor/inductor_design/+design_compute/CoreData.m b/source_inductor/inductor_design/+design_compute/CoreData.m index 87477f8..b07d3f9 100644 --- a/source_inductor/inductor_design/+design_compute/CoreData.m +++ b/source_inductor/inductor_design/+design_compute/CoreData.m @@ -125,7 +125,7 @@ % The input should have the size of the number of samples. % Minor loops are supported with the iGSE. % The amplitudes of the loops should be given (not computed by this code). - % For the loops, the peak to peak amplitude is considered. + % For the loops, the peak to peak amplitude is considered. % % The time signals are given as matrices: % - the columns represents the different samples @@ -146,7 +146,7 @@ % parse waveform, get the frequency and the AC peak value [f, B_ac_peak] = self.get_param_waveform(t_vec, B_time_vec); - + % interpolate the loss map, get the IGSE parameters [is_valid_interp, k, alpha, beta] = compute_steinmetz(self, f, B_ac_peak, B_dc, T); @@ -156,7 +156,7 @@ % check the validity of the obtained losses B_peak_tot = max(abs(B_time_vec+B_dc), [], 1); is_valid_value = self.parse_losses(P, B_peak_tot); - + % from loss densities to losses P = self.volume.*P; @@ -239,14 +239,14 @@ function parse_data(self, id_vec, id, param_tmp) % Returns: % f (vector): operating frequency % B_ac_peak (vector): AC peak flux density - + % frequency f = 1./(max(t_vec, [], 1)-min(t_vec, [], 1)); % AC peak flux density B_ac_peak = (max(B_time_vec, [], 1)-min(B_time_vec, [], 1))./2; end - + function [is_valid, k, alpha, beta] = compute_steinmetz(self, f, B_ac_peak, B_dc, T) % Compute the losses with the Steinmetz parameters from the loss map. % @@ -297,7 +297,7 @@ function parse_data(self, id_vec, id, param_tmp) is_valid = is_valid&is_valid_tmp; [is_valid_tmp, P_B_ac_peak_2] = self.get_interp(f, B_ac_peak_2, B_dc, T); is_valid = is_valid&is_valid_tmp; - + % with the gradients and the losses, compute the Steinmetz parameters alpha = log(P_f_1./P_f_2)./log(f_1./f_2); beta = log(P_B_ac_peak_1./P_B_ac_peak_2)./log(B_ac_peak_1./B_ac_peak_2); @@ -320,14 +320,14 @@ function parse_data(self, id_vec, id, param_tmp) % get the parameter from the Steinmetz parameters ki = self.compute_steinmetz_ki(k, alpha, beta); - + % find the time intervals t_vec_diff = t_vec(2:end,:)-t_vec(1:end-1,:); - + % find the flux variations B_time_vec_diff = B_time_vec(2:end,:)-B_time_vec(1:end-1,:); B_loop_vec_diff = (B_loop_vec(2:end,:)+B_loop_vec(1:end-1,:))./2; - + % get the frequency f = 1./(max(t_vec, [], 1)-min(t_vec, [], 1)); diff --git a/source_inductor/inductor_design/+design_compute/InductorCompute.m b/source_inductor/inductor_design/+design_compute/InductorCompute.m index 48f7442..80819d9 100644 --- a/source_inductor/inductor_design/+design_compute/InductorCompute.m +++ b/source_inductor/inductor_design/+design_compute/InductorCompute.m @@ -125,13 +125,13 @@ function init_geom_material(self) self.fom.geom.r_curve = geom.r_curve; self.fom.geom.n_turn = geom.n_turn; self.fom.geom.fill_pack = geom.fill_pack; - + % set the area self.fom.area.A_iso = geom.A_iso; self.fom.area.A_core = geom.A_core; self.fom.area.A_winding = geom.A_winding; self.fom.area.A_box = geom.A_box; - + % set the volume (scaling and offset for the global value) V_offset = self.data_vec.fom_data.V_offset; V_scale = self.data_vec.fom_data.V_scale; @@ -227,14 +227,14 @@ function init_thermal_loss_waveform(self) % Get the different functions describing the loss and thermal models. % Create the thermal/loss object. % Create the waveform model object. - + % thermal/loss iteration fct.get_thermal = @(operating) self.get_thermal(operating); fct.get_losses = @(operating) self.get_losses(operating); fct.get_thermal_vec = @(operating) self.get_thermal_vec(operating); fct.get_losses_vec = @(operating) self.get_losses_vec(operating); self.thermal_losses_iter_obj = design_compute.ThermalLossIter(self.data_const.iter, fct); - + % waveform model self.waveform_model_obj = design_compute.WaveformModel(self.n_sol, self.data_const.signal); end @@ -298,7 +298,7 @@ function init_thermal_loss_waveform(self) % % Returns: % operating (struct): struct with the operating point data - + % set the waveform self.waveform_model_obj.set_excitation(excitation); @@ -330,14 +330,14 @@ function init_thermal_loss_waveform(self) % get the ambient condition thermal.T_ambient = excitation.T_ambient; thermal.h_convection = excitation.h_convection; - + % the temperature is constant and is an initial guess thermal.T_core_max = self.data_vec.other.T_core_init; thermal.T_core_avg = self.data_vec.other.T_core_init; thermal.T_winding_max = self.data_vec.other.T_winding_init; thermal.T_winding_avg = self.data_vec.other.T_winding_init; thermal.T_iso_max = (self.data_vec.other.T_core_init+self.data_vec.other.T_winding_init)./2; - + % add the utilization and check the bounds [thermal, is_valid_thermal] = self.check_thermal_limit(thermal, true); @@ -363,7 +363,7 @@ function init_thermal_loss_waveform(self) h_convection = operating.thermal.h_convection; P_core = operating.losses.P_core; P_winding = operating.losses.P_winding; - + % get the thermal simulation results from the ANN/regression object excitation_tmp = struct('h_convection', h_convection, 'P_winding', P_winding, 'P_core', P_core, 'T_ambient', T_ambient); [is_valid_thermal, fom_tmp] = self.ann_fem_obj.get_ht(excitation_tmp); @@ -415,7 +415,7 @@ function init_thermal_loss_waveform(self) % assign the maximum temperature thermal.T_max = max([T_core ; T_winding ; T_iso], [], 1); - % check the thermal utilization (temperature elevation compared to the limit) + % check the thermal utilization (temperature elevation compared to the limit) thermal.stress_core = (T_core-T_ambient)./(T_core_max-T_ambient); thermal.stress_winding = (T_winding-T_ambient)./(T_winding_max-T_ambient); thermal.stress_iso = (T_iso-T_ambient)./(T_iso_max-T_ambient); @@ -469,7 +469,7 @@ function init_thermal_loss_waveform(self) % get the applied temperatures T_core_avg = operating.thermal.T_core_avg; T_winding_avg = operating.thermal.T_winding_avg; - + % get the stress applied to the core (time domain) [t_vec, B_time_vec, B_loop_vec, B_dc] = self.waveform_model_obj.get_core(B_norm); @@ -481,7 +481,7 @@ function init_thermal_loss_waveform(self) % compute the winding losses [is_valid_winding, P_winding, P_dc, P_ac_lf, P_ac_hf] = self.winding_obj.get_losses(f_vec, J_freq_vec, H_freq_vec, J_dc, T_winding_avg); - + % get the total losses (scaling and offset) P_scale = self.data_vec.fom_data.P_scale; P_offset = self.data_vec.fom_data.P_offset; @@ -496,7 +496,7 @@ function init_thermal_loss_waveform(self) operating.losses.P_winding_ac_hf = P_ac_hf; operating.losses.P_add = P_add; operating.losses.P_tot = P_tot; - + % assign relative figures of merits (ratios) operating.losses.core_losses = P_core./P_tot; operating.losses.winding_losses = P_winding./P_tot; diff --git a/source_inductor/inductor_design/+design_compute/WindingData.m b/source_inductor/inductor_design/+design_compute/WindingData.m index dd8b6f7..92f8539 100644 --- a/source_inductor/inductor_design/+design_compute/WindingData.m +++ b/source_inductor/inductor_design/+design_compute/WindingData.m @@ -105,7 +105,7 @@ % % Returns: % J_rms_max (vector): maximum current density of the different samples - + J_rms_max = self.param.J_rms_max; end @@ -224,7 +224,7 @@ function parse_data(self, id_vec, id, param_tmp) % get the equivalent operating frequency for the proximity losses prox_factor = sqrt(sum(f_vec.^2.*H_freq_vec.^2, 1))./sqrt(2); - f = prox_factor./H_ac_rms; + f = prox_factor./H_ac_rms; end function [P, P_dc, P_ac_lf, P_ac_hf] = get_losses_sub(self, f, J_ac_rms, H_ac_rms, J_dc, sigma) @@ -242,7 +242,7 @@ function parse_data(self, id_vec, id, param_tmp) % P_dc (vector): DC losses (density multiplied with volume) % P_ac_lf (vector): AC LF losses (density multiplied with volume) % P_ac_hf (vector): AC HF losses (density multiplied with volume) - + % compute the skin depth delta = self.get_delta(sigma, f); @@ -250,7 +250,7 @@ function parse_data(self, id_vec, id, param_tmp) J_dc = abs(J_dc); J_ac_rms = abs(J_ac_rms); H_ac_rms = abs(H_ac_rms); - + % get the different loss components (DC, AC LF, and AC HF) P_dc = self.compute_lf_losses(sigma, J_dc); P_ac_lf = self.compute_lf_losses(sigma, J_ac_rms); @@ -340,7 +340,7 @@ function parse_data(self, id_vec, id, param_tmp) % compute the losses P = fact_tmp.*(H_rms.^2); end - + function [is_valid, sigma] = get_interp(self, T) % Interpolate electrical conductivities for the different materials. % diff --git a/source_inductor/inductor_design/+design_display/InductorDisplay.m b/source_inductor/inductor_design/+design_display/InductorDisplay.m index ba4a776..89055c2 100644 --- a/source_inductor/inductor_design/+design_display/InductorDisplay.m +++ b/source_inductor/inductor_design/+design_display/InductorDisplay.m @@ -108,7 +108,7 @@ text{end+1} = sprintf('fill_pack = %.2f %%', 1e2.*fom_tmp.geom.fill_pack); text{end+1} = sprintf('n_turn = %d', fom_tmp.geom.n_turn); text_data{end+1} = struct('title', 'geom', 'text', {text}); - + % material data text = {}; text{end+1} = sprintf('core_id = %s', get_map_int_to_str(fom_tmp.material.core_id)); @@ -139,7 +139,7 @@ text{end+1} = sprintf('m_tot = %.2f g', 1e3.*fom_tmp.mass.m_tot); text{end+1} = sprintf('c_tot = %.2f $', fom_tmp.cost.c_tot); text_data{end+1} = struct('title', 'mass / cost', 'text', {text}); - + % magnetic data text = {}; text{end+1} = sprintf('L = %.2f uH', 1e6.*fom_tmp.circuit.L); @@ -175,7 +175,7 @@ text{end+1} = sprintf('is_valid_core = %d', operating_pts.is_valid_core); text{end+1} = sprintf('is_valid_winding = %d', operating_pts.is_valid_winding); text_data{end+1} = struct('title', 'is_valid', 'text', {text}); - + % applied excitation text = {}; text{end+1} = sprintf('type_id = %s', get_map_int_to_str(operating_pts.waveform.type_id)); @@ -190,7 +190,7 @@ text{end+1} = sprintf('fact_sat = %.2f %%', 1e2.*operating_pts.waveform.fact_sat); text{end+1} = sprintf('fact_rms = %.2f %%', 1e2.*operating_pts.waveform.fact_rms); text_data{end+1} = struct('title', 'waveform', 'text', {text}); - + % physical fields text = {}; text{end+1} = sprintf('J_dc = %.2f A/mm2', 1e-6.*operating_pts.field.J_dc); @@ -200,7 +200,7 @@ text{end+1} = sprintf('B_dc = %.2f mT', 1e3.*operating_pts.field.B_dc); text{end+1} = sprintf('B_peak_peak = %.2f mT', 1e3.*operating_pts.field.B_peak_peak); text_data{end+1} = struct('title', 'field', 'text', {text}); - + % temperatures text = {}; text{end+1} = sprintf('h_convection = %.2f W/Km2', operating_pts.thermal.h_convection); diff --git a/source_inductor/inductor_fem_ann/+fem_ann/get_extend_inp.m b/source_inductor/inductor_fem_ann/+fem_ann/get_extend_inp.m index 9c11d03..9273964 100644 --- a/source_inductor/inductor_fem_ann/+fem_ann/get_extend_inp.m +++ b/source_inductor/inductor_fem_ann/+fem_ann/get_extend_inp.m @@ -254,7 +254,7 @@ % compute the normalized inductance mu0 = 4.*pi.*1e-7; inp.L_norm = (mu0.*inp.A_core)./(2.*inp.d_gap); - + % compute the saturation current inp.I_sat = (inp.B_sat_core.*inp.A_core)./inp.L_norm; @@ -262,9 +262,9 @@ % - 'rel': the ratio with the saturation current is given, the current is calculated % - 'abs': the current is used, the ratio with the saturation current is calculated switch excitation_type - case 'rel' + case 'rel' inp.I_winding = inp.r_sat.*inp.I_sat; - case 'abs' + case 'abs' inp.r_sat = inp.I_winding./inp.I_sat; otherwise error('invalid physics excitation') diff --git a/source_inductor/utils/get_sweep.m b/source_inductor/utils/get_sweep.m index 264045f..b1a6bea 100644 --- a/source_inductor/utils/get_sweep.m +++ b/source_inductor/utils/get_sweep.m @@ -7,9 +7,9 @@ % % Three different methods are available for generating the variable samples: % - Given fixed vector -% - Randompicks (with a given length) from a given discrete set +% - Randompicks (with a given length) from a given discrete set % - Regularly spaced span -% - Variables can be float or integer +% - Variables can be float or integer % - Variable transformations (e.g., logarithmic, quadratic) are available % % Parameters: diff --git a/source_input/get_design_data_plot_all.m b/source_input/get_design_data_plot_all.m index 4c0d866..f8cfaa6 100644 --- a/source_input/get_design_data_plot_all.m +++ b/source_input/get_design_data_plot_all.m @@ -29,9 +29,8 @@ % - title: title of the block in the text field % - var: cell of variables in the block, chosen from the data created by the extraction function text_param{1} = struct('title', 'fom', 'var', {{'V_box', 'A_box', 'm_tot', 'c_tot'}}); -text_param{2} = struct('title', 'circuit', 'var', {{'L', 'f', 'I_sat', 'I_rms'}}); -text_param{3} = struct('title', 'operating', 'var', {{'P_fl', 'P_pl', 'P_mix', 'T_max'}}); -text_param{4} = struct('title', 'utilization', 'var', {{'I_peak_tot', 'I_rms_tot', 'r_peak_peak', 'fact_sat', 'fact_rms'}}); +text_param{2} = struct('title', 'circuit', 'var', {{'L', 'I_sat', 'I_rms', 'V_t_sat_sat'}}); +text_param{3} = struct('title', 'operating', 'var', {{'f', 'P_mix', 'P_fl', 'P_pl', 'T_fl', 'T_pl'}}); end @@ -104,34 +103,25 @@ L = fom.circuit.L; I_sat = fom.circuit.I_sat; I_rms = fom.circuit.I_rms; -f_fl = operating.full_load.excitation.f; -f_pl = operating.partial_load.excitation.f; +V_t_sat_sat = fom.circuit.V_t_sat_sat; data_fom.L = struct('value', L, 'name', 'L', 'scale', 1e6, 'unit', 'uH'); -data_fom.f = struct('value', (f_fl+f_pl)./2, 'name', 'f', 'scale', 1e-3, 'unit', 'kHz'); data_fom.I_sat = struct('value', I_sat, 'name', 'I_sat', 'scale', 1.0, 'unit', 'A'); data_fom.I_rms = struct('value', I_rms, 'name', 'I_rms', 'scale', 1.0, 'unit', 'A'); - -% utilization data -I_peak_tot = fom.utilization.I_peak_tot; -I_rms_tot = fom.utilization.I_rms_tot; -r_peak_peak = fom.utilization.r_peak_peak; -fact_sat = fom.utilization.fact_sat; -fact_rms = fom.utilization.fact_rms; -data_fom.I_peak_tot = struct('value', I_peak_tot, 'name', 'I_peak_tot', 'scale', 1.0, 'unit', 'A'); -data_fom.I_rms_tot = struct('value', I_rms_tot, 'name', 'I_rms_tot', 'scale', 1.0, 'unit', 'A'); -data_fom.r_peak_peak = struct('value', r_peak_peak, 'name', 'r_peak_peak', 'scale', 1e2, 'unit', '%'); -data_fom.fact_sat = struct('value', fact_sat, 'name', 'fact_sat', 'scale', 1e2, 'unit', '%'); -data_fom.fact_rms = struct('value', fact_rms, 'name', 'fact_rms', 'scale', 1e2, 'unit', '%'); +data_fom.V_t_sat_sat = struct('value', V_t_sat_sat, 'name', 'V_t_sat_sat', 'scale', 1e3, 'unit', 'Vms'); % operating conditions P_fl = operating.full_load.losses.P_tot; T_fl = operating.full_load.thermal.T_max; P_pl = operating.partial_load.losses.P_tot; T_pl = operating.partial_load.thermal.T_max; +f_fl = operating.full_load.waveform.f; +f_pl = operating.partial_load.waveform.f; +data_fom.f = struct('value', (f_fl+f_pl)./2, 'name', 'f', 'scale', 1e-3, 'unit', 'kHz'); +data_fom.P_mix = struct('value', (P_fl+P_pl)./2, 'name', 'P_mix', 'scale', 1.0, 'unit', 'W'); data_fom.P_fl = struct('value', P_fl, 'name', 'P_fl', 'scale', 1.0, 'unit', 'W'); data_fom.P_pl = struct('value', P_pl, 'name', 'P_pl', 'scale', 1.0, 'unit', 'W'); -data_fom.P_mix = struct('value', (P_fl+P_pl)./2, 'name', 'P_tot', 'scale', 1.0, 'unit', 'W'); -data_fom.T_max = struct('value', max(T_fl, T_pl), 'name', 'T_max', 'scale', 1.0, 'unit', 'C'); +data_fom.T_fl = struct('value', T_fl, 'name', 'T_fl', 'scale', 1.0, 'unit', 'C'); +data_fom.T_pl = struct('value', T_pl, 'name', 'T_pl', 'scale', 1.0, 'unit', 'C'); % extract the validity information is_valid_fom = fom.is_valid; diff --git a/source_input/get_fem_ann_data_fem.m b/source_input/get_fem_ann_data_fem.m index 23979e5..a9c0dfb 100644 --- a/source_input/get_fem_ann_data_fem.m +++ b/source_input/get_fem_ann_data_fem.m @@ -119,7 +119,7 @@ % convection coefficient reference value sweep.var.h_convection = struct('type', 'span', 'var_trf', 'none', 'var_type', 'float', 'span', span, 'lb', 15.0, 'ub', 30.0, 'n', n); - + % ambient temperature sweep.var.T_ambient = struct('type', 'span', 'var_trf', 'none', 'var_type', 'float', 'span', span, 'lb', 25.0, 'ub', 65.0, 'n', n); end diff --git a/source_input/get_fem_ann_data_train.m b/source_input/get_fem_ann_data_train.m index 524ef6e..1c57b8c 100644 --- a/source_input/get_fem_ann_data_train.m +++ b/source_input/get_fem_ann_data_train.m @@ -69,7 +69,7 @@ % convection coefficient reference value var_inp{end+1} = struct('name', 'h_convection', 'var_trf', 'none', 'var_norm', 'min_max', 'min', 0.99.*15.0, 'max', 1.01.*30.0); - + % ambient temperature var_inp{end+1} = struct('name', 'T_ambient', 'var_trf', 'none', 'var_norm', 'min_max', 'min', 0.99.*25.0, 'max', 1.01.*65.0); end