diff --git a/README.md b/README.md index 2d563f6..c17e98c 100644 --- a/README.md +++ b/README.md @@ -134,13 +134,13 @@ The releases are available at GitHub and contains: ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- -MATLAB 101 1648 4806 4539 +MATLAB 102 1724 5017 4703 Python 8 365 451 450 -Markdown 4 75 0 281 +Markdown 4 76 0 284 DOS Batch 3 9 0 34 Bourne Shell 3 9 9 21 ------------------------------------------------------------------------------- -SUM: 119 2106 5266 5325 +SUM: 120 2183 5477 5492 ------------------------------------------------------------------------------- ``` diff --git a/resources/material/run_core.m b/resources/material/run_core.m index aa9d59a..b35fbae 100644 --- a/resources/material/run_core.m +++ b/resources/material/run_core.m @@ -91,7 +91,7 @@ function run_core() % assign param material.param.mu = mu; % material permeability -material.param.beta = beta; % beta of the material (Steinmetz paramter) +material.param.beta = beta; % beta of the material (Steinmetz parameter) material.param.rho = rho; % volumetric density material.param.kappa = kappa; % cost per mass diff --git a/run_6_compute_single.m b/run_6_compute_single.m index 4ba74db..5672235 100644 --- a/run_6_compute_single.m +++ b/run_6_compute_single.m @@ -24,7 +24,7 @@ function run_6_compute_single() 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 2b0c32d..87477f8 100644 --- a/source_inductor/inductor_design/+design_compute/CoreData.m +++ b/source_inductor/inductor_design/+design_compute/CoreData.m @@ -3,8 +3,7 @@ % % Map the different unique id with the corresponding data. % Get constant properties (mass, cost, saturation, etc.). - % Get the losses for sinus flux (lossmap, with DC biais). - % Get the losses for triangular flux (IGGE, lossmap, with DC biais). + % Get the losses for arbitrary current waveforms (iGSE, lossmap, with DC biais). % The code is completely vectorized. % % The input data required by this class require a defined format: @@ -124,25 +123,28 @@ % - details: R. Burkart, "Advanced Modeling and Multi-Objective Optimization of Power Electronic Converter Systems", 2016 % % The input should have the size of the number of samples. - % The signal should be periodic (first point is equal to last point). - % Minor loops are supported. + % 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. % - % The signals are given as matrices: + % The time signals are given as matrices: % - the columns represents the different samples % - the rows represents the time sampling + % - the first point and last points are t=0 and t=1/f + % - the signal should be periodic (first point is equal to last point) % % Parameters: % t_vec (matrix): matrix with the times % B_time_vec (matrix): matrix with the time domain flux densities % B_loop_vec (matrix): matrix with the major/minor loop flux densities - % B_dc (matrix): vector with the DC flux densities + % B_dc (vector): DC flux densities % T (vector): operating temperature % % Returns: % is_valid (vector): if the operating points are valid (or not) % P (vector): losses of each sample (density multiplied with volume) - % parse waveform + % 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 @@ -227,13 +229,15 @@ function parse_data(self, id_vec, id, param_tmp) function [f, B_ac_peak] = get_param_waveform(self, t_vec, B_time_vec) % Extract the parameters from the time domain waveform. % + % The frequency is extracted from the time sampling. + % The AC peak value is the peak to peak value over two. + % % Parameters: % t_vec (matrix): matrix with the times - % B_time_vec (matrix): matrix with the flux densities + % B_time_vec (matrix): matrix with the time domain flux densities % % Returns: % f (vector): operating frequency - % B_dc (vector): DC flux density % B_ac_peak (vector): AC peak flux density % frequency @@ -246,15 +250,15 @@ function parse_data(self, id_vec, id, param_tmp) 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. % - % The Steinmetz paramters are extracted with the following methods: + % The Steinmetz parameters are extracted with the following methods: % - The losses are computed for: B_ac_peak*(1+eps) and B_ac_peak/(1+eps) % - The losses are computed for: f*(1+eps) and f/(1+eps) % - Then, alpha and represents the gradients (in log scale) % - Finally, k is set in order to get the right absolute value of the losses % % Parameters: - % f (vector): frequency excitation vector - % B_ac_peak (vector): peak AC flux density + % f (vector): operating frequency + % B_ac_peak (vector): AC peak flux density % B_dc (vector): DC flux density % T (vector): operating temperature % @@ -324,10 +328,10 @@ function parse_data(self, id_vec, id, param_tmp) 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; - % frequency + % get the frequency f = 1./(max(t_vec, [], 1)-min(t_vec, [], 1)); - % apply the iGSE + % apply the iGSE (time dependent losses) v_int = ki.*(abs(B_loop_vec_diff).^(beta-alpha)).*(abs(B_time_vec_diff./t_vec_diff).^alpha); % integrate the losses diff --git a/source_inductor/inductor_design/+design_compute/InductorCompute.m b/source_inductor/inductor_design/+design_compute/InductorCompute.m index e967b8b..48f7442 100644 --- a/source_inductor/inductor_design/+design_compute/InductorCompute.m +++ b/source_inductor/inductor_design/+design_compute/InductorCompute.m @@ -8,7 +8,7 @@ % - check the validity of the design % - compute many operating points % - core loss map (DC bias) and winding losses (proximity losses) - % - sinus or PWM excitation + % - sinus or triangular current excitation % - thermal/loss coupling % % Both the magnetic and the thermal model are powered by a ANN data-driven model. @@ -177,7 +177,7 @@ function init_magnetic(self) self.fom.circuit.H_norm = self.fom.geom.n_turn.*fom_mf.H_norm; self.fom.circuit.L = self.fom.geom.n_turn.^2.*fom_mf.L_norm; - % set the saturation and RMS current properties + % set the saturation, RMS current, and voltage time area properties B_sat_max = self.core_obj.get_flux_density(); J_rms_max = self.winding_obj.get_current_density(); self.fom.circuit.I_sat = B_sat_max./self.fom.circuit.B_norm; @@ -192,7 +192,7 @@ function init_limit(self) % This function does not compute losses, it is just a rough filter. % check if the figures of merit are in the right range - is_valid_limit = true(1, self.n_sol); + is_valid_limit = true; is_valid_limit = is_valid_limit&self.init_is_valid_check(self.fom.volume.V_box, self.data_vec.fom_limit.V_box); is_valid_limit = is_valid_limit&self.init_is_valid_check(self.fom.cost.c_tot, self.data_vec.fom_limit.c_tot); is_valid_limit = is_valid_limit&self.init_is_valid_check(self.fom.mass.m_tot, self.data_vec.fom_limit.m_tot); @@ -236,7 +236,7 @@ function init_thermal_loss_waveform(self) self.thermal_losses_iter_obj = design_compute.ThermalLossIter(self.data_const.iter, fct); % waveform model - self.waveform_model_obj = design_compute.WaveformModel(self.data_const.signal, self.n_sol); + self.waveform_model_obj = design_compute.WaveformModel(self.n_sol, self.data_const.signal); end end @@ -255,7 +255,7 @@ function init_thermal_loss_waveform(self) % make sure that all the samples have the right dimension excitation = get_struct_size(excitation, self.n_sol); - % init, compute data which are independent of the iterations + % init, compute the data which are independent of the iterations operating = self.get_operating_init(excitation); % compute the coupled loss and thermal models @@ -275,6 +275,9 @@ function init_thermal_loss_waveform(self) function operating = get_operating_init(self, excitation) % Initialize an operating point with the data which are independent of the iterations. % + % Compute the waveforms and the associated figures of merit. + % Initialize the thermal data for the first thermal loss iteration. + % % Parameters: % excitation (struct): struct containing the operating point excitation % @@ -282,15 +285,24 @@ function init_thermal_loss_waveform(self) % operating (struct): struct with the operating point data operating = struct(); - operating = self.get_thermal_init(operating, excitation.thermal); operating = self.get_waveform_init(operating, excitation.waveform); + operating = self.get_thermal_init(operating, excitation.thermal); end function operating = get_waveform_init(self, operating, excitation) + % Compute the waveforms and the associated figures of merit. + % + % Parameters: + % operating (struct): struct with the operating point data + % excitation (struct): struct containing the waveform parameters + % + % Returns: + % operating (struct): struct with the operating point data + % set the waveform self.waveform_model_obj.set_excitation(excitation); - % get component circuit parameters + % get the inductor circuit and field parameters B_norm = self.fom.circuit.B_norm; J_norm = self.fom.circuit.J_norm; H_norm = self.fom.circuit.H_norm; @@ -298,12 +310,13 @@ function init_thermal_loss_waveform(self) I_sat = self.fom.circuit.I_sat; I_rms = self.fom.circuit.I_rms; - % get the waveform + % get the current waveform parameters operating.waveform = self.waveform_model_obj.get_waveform(L, I_sat, I_rms); + + % get the inductor field values operating.field = self.waveform_model_obj.get_field(J_norm, H_norm, B_norm); end - function operating = get_thermal_init(self, operating, excitation) % Init the thermal model for the starting the thermal/loss iterations. % @@ -314,7 +327,7 @@ function init_thermal_loss_waveform(self) % Returns: % operating (struct): struct with the operating point data - % set the excitation + % get the ambient condition thermal.T_ambient = excitation.T_ambient; thermal.h_convection = excitation.h_convection; @@ -345,7 +358,7 @@ function init_thermal_loss_waveform(self) % Returns: % operating (struct): struct with the operating point data - % get operating condition + % get the ambient condition and the losses T_ambient = operating.thermal.T_ambient; h_convection = operating.thermal.h_convection; P_core = operating.losses.P_core; @@ -373,12 +386,14 @@ function init_thermal_loss_waveform(self) end function [thermal, is_valid_thermal] = check_thermal_limit(self, thermal, is_valid_thermal) - % Check the validity of the temperatures. + % Compute the thermal stress and check the validity of the temperatures. % % Parameters: % thermal (struct): struct with the thermal data + % is_valid_thermal (vector): if the temperatures are valid (or not) % % Returns: + % thermal (struct): struct with the thermal data % is_valid_thermal (vector): if the temperatures are valid (or not) % get the limits @@ -386,7 +401,7 @@ function init_thermal_loss_waveform(self) T_winding_max = self.winding_obj.get_temperature(); T_iso_max = self.iso_obj.get_temperature(); - % compute max + % extract the differemt temperatures T_ambient = thermal.T_ambient; T_core = max(thermal.T_core_max, thermal.T_core_avg); T_winding = max(thermal.T_winding_max, thermal.T_winding_avg); @@ -397,8 +412,10 @@ function init_thermal_loss_waveform(self) is_valid_winding = T_winding<=T_winding_max; is_valid_iso = T_iso<=T_iso_max; - % check the thermal utilization + % 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) 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); @@ -437,7 +454,6 @@ function init_thermal_loss_waveform(self) % % Core losses with the core data manager. % Winding losses with the winding data manager. - % Compute different figures of merit. % % Parameters: % operating (struct): struct with the operating point data @@ -445,22 +461,22 @@ function init_thermal_loss_waveform(self) % Returns: % operating (struct): struct with the operating point data - % get component circuit parameters + % get inductor field parameters B_norm = self.fom.circuit.B_norm; J_norm = self.fom.circuit.J_norm; H_norm = self.fom.circuit.H_norm; - % get the applied stress + % get the applied temperatures T_core_avg = operating.thermal.T_core_avg; T_winding_avg = operating.thermal.T_winding_avg; - % get the time domain waveform + % 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); % compute the core losses [is_valid_core, P_core] = self.core_obj.get_losses(t_vec, B_time_vec, B_loop_vec, B_dc, T_core_avg); - % get the Fourier coefficient of the waveform + % get the stress applied to the winding (Fourier harmonics) [f_vec, J_freq_vec, H_freq_vec, J_dc] = self.waveform_model_obj.get_winding(J_norm, H_norm); % compute the winding losses diff --git a/source_inductor/inductor_design/+design_compute/WaveformModel.m b/source_inductor/inductor_design/+design_compute/WaveformModel.m index 6a3a865..2ca9033 100644 --- a/source_inductor/inductor_design/+design_compute/WaveformModel.m +++ b/source_inductor/inductor_design/+design_compute/WaveformModel.m @@ -2,20 +2,19 @@ % Class for generating AC waveforms for the operating points. % % Generate the following parameters: - % - factor between peak and RMS - % - harmonics for the winding losses + % - parameters of the waveform + % - harmonics (Fourier) for the winding losses % - time domain for the core losses % % The code is completely vectorized. - % All the generated waveforms should not feature DC components. - % DC components are added separetely. + % The class can handle sinusoidal and triangular waveforms (with DC bias). % % (c) 2019-2020, ETH Zurich, Power Electronic Systems Laboratory, T. Guillod %% properties properties (SetAccess = private, GetAccess = public) - signal % struct: contains the control parameters n_sol % int: number of designs or samples + signal % struct: contains the control parameters is_set % logical: if the waveform has been set (or not) type_id % vector: id defining the waveform shape param % struct: waveform parameters (RMS, peak, dc, etc.) @@ -25,10 +24,11 @@ %% public methods (Access = public) - function self = WaveformModel(signal, n_sol) + function self = WaveformModel(n_sol, signal) % Constructor. % % Parameters: + % n_sol (int): number of designs or samples % signal (struct): contains the control parameters % assign data @@ -46,27 +46,40 @@ end function set_excitation(self, excitation) + % Set the waveform from given parameters. + % + % Compute the parameters, harmonics, and time domain data. + % Handle different waveform shapes. + % Transform the shapes into a standardized representation. + % + % Parameters: + % excitation (struct): waveform parameters + % find the type self.type_id = excitation.type_id; - % set the waveform + % set the waveform for the different unique type type_id_tmp = unique(self.type_id); assert(length(type_id_tmp)==1, 'invalid waveform type') switch type_id_tmp case get_map_str_to_int('tri') + % triangular waveform data f = excitation.f; d_c = excitation.d_c; I_dc = excitation.I_dc; I_peak_peak = excitation.I_peak_peak; + % compute and assign self.param = self.get_param_tri(f, I_dc, I_peak_peak); self.freq = self.get_freq_tri(f, d_c, I_peak_peak); self.time = self.get_time_tri(f, d_c, I_peak_peak); case get_map_str_to_int('sin') + % sinusoidal waveform data f = excitation.f; I_dc = excitation.I_dc; I_peak_peak = excitation.I_peak_peak; + % compute and assign self.param = self.get_param_sin(f, I_dc, I_peak_peak); self.freq = self.get_freq_sin(f, I_peak_peak); self.time = self.get_time_sin(f, I_peak_peak); @@ -79,7 +92,20 @@ case get_map_str_to_int('sin') end function waveform = get_waveform(self, L, I_sat, I_rms) - % copy the id + % Get the figures of merit of the inductor current. + % + % Parameters: + % L (vector): inductor value + % I_sat (vector): inductor saturation current + % I_rms (vector): inductor maximum RMS current + % + % Returns: + % waveform (struct): computed waveform parameters + + % check that a waveform has been set + assert(self.is_set==true, 'invalid state: no waveform is set') + + % copy the waveform shape id waveform.type_id = self.type_id; % copy basic parameters @@ -90,7 +116,7 @@ case get_map_str_to_int('sin') waveform.I_all_peak = self.param.I_all_peak; waveform.I_all_rms = self.param.I_all_rms; - % compute utilization factor + % compute utilization factor (with respect to the inductor parameters) waveform.r_peak_peak = self.param.I_peak_peak./self.param.I_dc; waveform.fact_sat = self.param.I_all_peak./I_sat; waveform.fact_rms = self.param.I_all_rms./I_rms; @@ -98,6 +124,19 @@ case get_map_str_to_int('sin') end function field = get_field(self, J_norm, H_norm, B_norm) + % Get the field values inside the inductor. + % + % Parameters: + % J_norm (vector): normalized (per ampere) current density (winding) + % H_norm (vector): normalized (per ampere) magnetic field (winding) + % B_norm (vector): normalized (per ampere) flux density (core) + % + % Returns: + % field (struct): computed field values + + % check that a waveform has been set + assert(self.is_set==true, 'invalid state: no waveform is set') + % compute the different DC field values field.J_dc = J_norm.*self.param.I_dc; field.B_dc = B_norm.*self.param.I_dc; @@ -110,22 +149,68 @@ case get_map_str_to_int('sin') end function [t_vec, B_time_vec, B_loop_vec, B_dc] = get_core(self, B_norm) + % Get the stress applied to the inductor core (iGSE, time domain). + % + % For the hysteresis loops: + % - for the loops, the peak to peak amplitude is considered + % - details: K. Venkatachalam, "Accurate Prediction of Ferrite Core Loss with Nonsinusoidal Waveforms Using Only Steinmetz Parameters", 2002 + % + % The time signals are given as matrices: + % - the columns represents the different samples + % - the rows represents the time sampling + % - the first point and last points are t=0 and t=1/f + % - the signal should be periodic (first point is equal to last point) + % + % Parameters: + % B_norm (vector): normalized (per ampere) flux density (core) + % + % Returns: + % t_vec (matrix): matrix with the times + % B_time_vec (matrix): matrix with the time domain flux densities + % B_loop_vec (matrix): matrix with the major/minor loop flux densities + % B_dc (vector): DC flux densities + + % check that a waveform has been set + assert(self.is_set==true, 'invalid state: no waveform is set') + % expand the vector into a matrix B_norm_vec = repmat(B_norm, [self.signal.n_time 1]); - % compute the applied core excitation in time domain - t_vec = self.time.t_vec; + % scale the time domain current into a flux density + t_vec = self.time.t_vec; B_time_vec = self.time.I_time_vec.*B_norm_vec; B_loop_vec = self.time.I_loop_vec.*B_norm_vec; B_dc = self.param.I_dc.*B_norm; end function [f_vec, J_freq_vec, H_freq_vec, J_dc] = get_winding(self, J_norm, H_norm) + % Get the stress applied to the inductor winding (Fourier harmonics). + % + % Peak values are used for the Fourier harmonics (only AC, no DC component). + % + % The Fourier signals are given as matrices: + % - the columns represents the different samples + % - the rows represents the frequency sampling + % - The Fourier coefficients are only AC (no DC component) + % + % Parameters: + % J_norm (vector): normalized (per ampere) current density (winding) + % H_norm (vector): normalized (per ampere) magnetic field (winding) + % + % Returns: + % f_vec (matrix): matrix with the frequencies + % J_freq_vec (matrix): matrix with the current density peak harmonics + % H_freq_vec (matrix): matrix with the magnetic field peak harmonics + % J_dc (vector): DC current density + + % check that a waveform has been set + assert(self.is_set==true, 'invalid state: no waveform is set') + % expand the vector into a matrix J_norm_vec = repmat(J_norm, [self.signal.n_freq 1]); H_norm_vec = repmat(H_norm, [self.signal.n_freq 1]); - - % compute the applied winding excitation in frequency domain + + % scale the frequency domain current into a current density and magnetic field f_vec = self.freq.f_vec; J_freq_vec = self.freq.I_freq_vec.*J_norm_vec; H_freq_vec = self.freq.I_freq_vec.*H_norm_vec; @@ -136,12 +221,22 @@ case get_map_str_to_int('sin') %% private methods (Access = private) function param = get_param_tri(self, f, I_dc, I_peak_peak) - % compute param + % Get the parameters of a triangular waveform (with DC bias). + % + % Parameters: + % f (vector): operating frequency + % I_dc (vector): DC current + % I_peak_peak (vector): peak to peak current + % + % Returns: + % param (struct): struct with the parameters + + % compute the different parameters I_ac_rms = I_peak_peak./(2.*sqrt(3)); I_all_peak = I_dc+(I_peak_peak./2); I_all_rms = hypot(I_dc, I_ac_rms); - % assign param + % assign values param.f = f; param.I_dc = I_dc; param.I_peak_peak = I_peak_peak; @@ -151,12 +246,22 @@ case get_map_str_to_int('sin') end function param = get_param_sin(self, f, I_dc, I_peak_peak) - % compute param + % Get the parameters of a sinusoidal waveform (with DC bias). + % + % Parameters: + % f (vector): operating frequency + % I_dc (vector): DC current + % I_peak_peak (vector): peak to peak current + % + % Returns: + % param (struct): struct with the parameters + + % compute the different parameters I_ac_rms = I_peak_peak./(2.*sqrt(2)); I_all_peak = I_dc+(I_peak_peak./2); I_all_rms = hypot(I_dc, I_ac_rms); - % assign param + % assign values param.f = f; param.I_dc = I_dc; param.I_peak_peak = I_peak_peak; @@ -166,6 +271,16 @@ case get_map_str_to_int('sin') end function freq = get_freq_tri(self, f, d_c, I_peak_peak) + % Get the frequency harmonics of a triangular waveform (without DC bias). + % + % Parameters: + % f (vector): operating frequency + % d_c (vector): duty cycle + % I_peak_peak (vector): peak to peak current + % + % Returns: + % freq (struct): struct with the Fourier harmonics (peak values) + % get the frequency vector [n_vec, f_vec] = self.get_frequency(f); @@ -178,12 +293,21 @@ case get_map_str_to_int('sin') % scale the values I_freq_vec = I_freq_vec.*(I_peak_peak./2); - % assign freq + % assign values freq.f_vec = f_vec; freq.I_freq_vec = I_freq_vec; end function freq = get_freq_sin(self, f, I_peak_peak) + % Get the frequency harmonics of a sinusoidal waveform (without DC bias). + % + % Parameters: + % f (vector): operating frequency + % I_peak_peak (vector): peak to peak current + % + % Returns: + % freq (struct): struct with the Fourier harmonics (peak values) + % get the frequency vector [n_vec, f_vec] = self.get_frequency(f); @@ -195,18 +319,28 @@ case get_map_str_to_int('sin') % scale the values I_freq_vec = I_freq_vec.*(I_peak_peak./2); - % assign freq + % assign values freq.f_vec = f_vec; freq.I_freq_vec = I_freq_vec; end function time = get_time_tri(self, f, d_c, I_peak_peak) + % Get the time domain representation of a triangular waveform (without DC bias). + % + % Parameters: + % f (vector): operating frequency + % d_c (vector): duty cycle + % I_peak_peak (vector): peak to peak current + % + % Returns: + % time (struct): struct with the time domain representation + % get the time vector [d_vec, t_vec] = self.get_time(f); % the duty cycle matrix d_c_vec = repmat(d_c, [self.signal.n_time 1]); - + % compute the rise and fall parts I_rise_vec = -1+2.*d_vec./d_c_vec; I_fall_vec = +1-2.*(d_vec-d_c_vec)./(1-d_c_vec); @@ -215,7 +349,7 @@ case get_map_str_to_int('sin') idx_rise = d_vec<=d_c_vec; idx_fall = d_vec>=d_c_vec; - % assign the values + % compute the values I_time_vec = NaN(self.signal.n_time, self.n_sol); I_loop_vec = 2.*ones(self.signal.n_time, self.n_sol); I_time_vec(idx_rise) = I_rise_vec(idx_rise); @@ -224,32 +358,50 @@ case get_map_str_to_int('sin') % scale the values I_time_vec = I_time_vec.*(I_peak_peak./2); I_loop_vec = I_loop_vec.*(I_peak_peak./2); - - % assign freq + + % assign values time.t_vec = t_vec; time.I_time_vec = I_time_vec; time.I_loop_vec = I_loop_vec; end function time = get_time_sin(self, f, I_peak_peak) + % Get the time domain representation of a sinusoidal waveform (without DC bias). + % + % Parameters: + % f (vector): operating frequency + % I_peak_peak (vector): peak to peak current + % + % Returns: + % time (struct): struct with the time domain representation + % get the time vector [d_vec, t_vec] = self.get_time(f); - - % assign the values + + % compute the values I_time_vec = sin(2.*pi.*d_vec); I_loop_vec = 2.*ones(self.signal.n_time, self.n_sol); % scale the values I_time_vec = I_time_vec.*(I_peak_peak./2); I_loop_vec = I_loop_vec.*(I_peak_peak./2); - - % assign freq + + % assign values time.t_vec = t_vec; time.I_time_vec = I_time_vec; time.I_loop_vec = I_loop_vec; end function [n_vec, f_vec] = get_frequency(self, f) + % Get the frequency sampling (without DC component). + % + % Parameters: + % f (vector): operating frequency + % + % Returns: + % n_vec (matrix): matrix with the harmonic numbers + % f_vec (matrix): matrix with the harmonic frequencies + % harmonics (normalized) n = 1:self.signal.n_freq; @@ -261,6 +413,15 @@ case get_map_str_to_int('sin') end function [d_vec, t_vec] = get_time(self, f) + % Get the time domain sampling. + % + % Parameters: + % f (vector): operating frequency + % + % Returns: + % d_vec (matrix): matrix with the normalized sampling + % t_vec (matrix): matrix with the time sampling + % time (normalized) d = linspace(0, 1, self.signal.n_time); diff --git a/source_inductor/inductor_design/+design_compute/WindingData.m b/source_inductor/inductor_design/+design_compute/WindingData.m index d2d93e0..dd8b6f7 100644 --- a/source_inductor/inductor_design/+design_compute/WindingData.m +++ b/source_inductor/inductor_design/+design_compute/WindingData.m @@ -3,8 +3,7 @@ % % Map the different unique id with the corresponding data. % Get constant properties (mass, cost, current density, etc.). - % Get the losses for sinus current (HF losses, with DC biais). - % Get the losses for triangular current (HF losses, with DC biais). + % Get the losses for arbitrary current waveforms (HF losses, with DC biais). % The code is completely vectorized. % % The input data required by this class require a defined format: @@ -111,7 +110,7 @@ end function [is_valid, P, P_dc, P_ac_lf, P_ac_hf] = get_losses(self, f_vec, J_freq_vec, H_freq_vec, J_dc, T) - % Compute the losses with an arbitrary excitation (Fourier). + % Compute the losses with an arbitrary excitation (using Fourier series). % % The following effects are considered. % - temperature dependence of the conductivity @@ -120,11 +119,12 @@ % - details: M. Leibl, "Three-Phase PFC Rectifier and High-Voltage Generator", 2017 % % The input should have the size of the number of samples. - % Peak values are used for the Fourier harmonics. + % Peak values are used for the Fourier harmonics (only AC, no DC component). % - % The signals are given as matrices: + % The Fourier signals are given as matrices: % - the columns represents the different samples % - the rows represents the frequency sampling + % - The Fourier coefficients are only AC (no DC component) % % Parameters: % f_vec (matrix): matrix with the frequencies @@ -140,7 +140,7 @@ % P_ac_lf (vector): AC LF losses (density multiplied with volume) % P_ac_hf (vector): AC HF losses (density multiplied with volume) - % parse waveform + % parse waveform, get the equivelent frequency and the RMS values [f, J_ac_rms, H_ac_rms] = self.get_param_waveform(f_vec, J_freq_vec, H_freq_vec); % get the conductivity @@ -204,6 +204,10 @@ function parse_data(self, id_vec, id, param_tmp) function [f, J_ac_rms, H_ac_rms] = get_param_waveform(self, f_vec, J_freq_vec, H_freq_vec) % Extract the parameters from the frequency domain waveform. % + % RMS values are computed for both the current density and the magnetic field. + % The equivalent frequency is computed from the magnetic field harmonics. + % The equivalent frequency is computed with a square frequency dependency of the HF losses. + % % Parameters: % f_vec (matrix): matrix with the frequencies % J_freq_vec (matrix): matrix with the current density peak harmonics @@ -227,14 +231,13 @@ function parse_data(self, id_vec, id, param_tmp) % Compute the losses with a a given waveform. % % Parameters: - % f (vector): frequency excitation vector + % f (vector): equivalent operating frequency % J_ac_rms (vector): AC RMS current density % H_ac_rms (vector): AC RMS magnetic field % J_dc (vector): DC current density % sigma (vector): electrical conductivity % % Returns: - % is_valid (vector): if the operating points are valid (or not) % P (vector): losses of each sample (density multiplied with volume) % P_dc (vector): DC losses (density multiplied with volume) % P_ac_lf (vector): AC LF losses (density multiplied with volume) @@ -263,7 +266,7 @@ function parse_data(self, id_vec, id, param_tmp) % Parameters: % P (vector): loss density % J_rms_tot (vector): RMS current density (AC and DC) - % delta (vector): skin depth + % f (vector): equivalent operating frequency % % Returns: % is_valid (vector): if the operating points are valid (with the additional checks) @@ -295,7 +298,7 @@ function parse_data(self, id_vec, id, param_tmp) end function P = compute_lf_losses(self, sigma, J_rms) - % Compute the LF losses. + % Compute the LF losses (Ohm's law). % % Parameters: % sigma (vector): electrical conductivity @@ -315,7 +318,7 @@ function parse_data(self, id_vec, id, param_tmp) end function P = compute_hf_losses(self, sigma, delta, H_rms) - % Compute the HF losses (litz wire proximity effect). + % Compute the HF losses (litz wire proximity effect, asymptotic aproox.). % % Parameters: % sigma (vector): electrical conductivity diff --git a/source_inductor/inductor_fem_ann/+fem_ann/get_fem_file.m b/source_inductor/inductor_fem_ann/+fem_ann/get_fem_file.m index b57d7aa..28141b0 100644 --- a/source_inductor/inductor_fem_ann/+fem_ann/get_fem_file.m +++ b/source_inductor/inductor_fem_ann/+fem_ann/get_fem_file.m @@ -4,7 +4,7 @@ function get_fem_file(filename, file_model, model, model_type, var_type, inp, co % Parameters: % filename (str): path of the file to be created with the results % file_model (str): path of the COMSOL file -% model (model): COMSOL model containg the physics +% model (model): COMSOL model containing the physics % model_type (str): name of the physics to be solved % var_type (struct): type of the different variables used in the solver % inp (struct): struct of scalars with the selected input combination diff --git a/source_inductor/inductor_fem_ann/+fem_ann/get_out_fem.m b/source_inductor/inductor_fem_ann/+fem_ann/get_out_fem.m index ec0803a..1cc4826 100644 --- a/source_inductor/inductor_fem_ann/+fem_ann/get_out_fem.m +++ b/source_inductor/inductor_fem_ann/+fem_ann/get_out_fem.m @@ -2,7 +2,7 @@ % Make a FEM simulation for given parameters, extract the results. % % Parameters: -% model (model): COMSOL model containg the physics +% model (model): COMSOL model containing the physics % model_type (str): name of the physics to be solved % inp (struct): struct of scalars with the parameters % diff --git a/source_input/design/get_design_data_vec.m b/source_input/design/get_design_data_vec.m index d786060..07a14bd 100644 --- a/source_input/design/get_design_data_vec.m +++ b/source_input/design/get_design_data_vec.m @@ -46,7 +46,7 @@ % bounds for the circuit figures of merit % - L: inductance -% - V_t_sat_sat: saturation voltage time product +% - V_t_sat_sat: saturation voltage time product (complete hysteresis loop) % - I_sat: maximum saturation current % - I_rms: maximum RMS current fom_limit.L = struct('min', 0.0, 'max', Inf); diff --git a/source_input/design/get_design_excitation.m b/source_input/design/get_design_excitation.m index ddcbe34..cca41f9 100644 --- a/source_input/design/get_design_excitation.m +++ b/source_input/design/get_design_excitation.m @@ -11,17 +11,17 @@ % % (c) 2019-2020, ETH Zurich, Power Electronic Systems Laboratory, T. Guillod -% thermal paramters +% thermal parameters % - h_convection: convection coefficient reference value % - T_ambient: ambient temperature excitation.thermal.h_convection = 20.0; excitation.thermal.T_ambient = 40.0; -% circuit parameters +% current excitation parameters % - f: operating frequency % - I_dc: DC current -% - I_ac_peak: AC peak current -% - d_c: duty cycle +% - I_peak_peak: peak to peak current +% - d_c: duty cycle (only for triangular waveform, not for sinus) % - type_id: id of the waveform shape ('sin' or 'tri') excitation.waveform.f = f; excitation.waveform.I_dc = load.*10.0;