1- function [magnitude , freqVec ] = plotLLCResonantTankImpedanceCurve(LLCDesign ,options )
1+ function [magnitude , freqVec ] = plotLLCResonantTankImpedanceCurve(LLCDesign ,options )
22% This function plots the impedance magnitude and phase curves of an LLC resonant tank
33% using the GainCurveLLCConverter Simulink model at specified load conditions.
44% The function linearizes the model at each frequency point and load resistance,
3232%
3333% Copyright 2025-2026 The MathWorks, Inc.
3434
35- arguments
36- LLCDesign struct
37- options.RloadVec = simscape.Value(100 ," Ohm" ); % Load resistance
38- options.FrequencyVec = simscape.Value((linspace(0.1 * ...
39- LLCDesign.resonantFreq ,2*LLCDesign.resonantFreq ,100)),"Hz "); % Frequency Hz
40- end
41-
42- % Initialize the output parameter size
43- numPlots = length(options .RloadVec.value);
44- magnitude = zeros(numPlots ,length(options .FrequencyVec.value));
45- phaseAngle = zeros(numPlots ,length(options .FrequencyVec.value));
46- Rload = zeros(1 ,numPlots );
47- legendInfo = cell(1 ,numPlots );
48- % Model workspace
49- mdlWks = get_param(GainCurveLLCConverter ,' ModelWorkspace' );
50- freqVec = options .FrequencyVec.value;
51- % Port assignment
52- inputBlock = " GainCurveLLCConverter/Vin" ;
53- inputPort = 1 ;
54- inputType = ' input' ;
55-
56- outputBlock = " GainCurveLLCConverter/Iin" ;
57- outputPort = 1 ;
58- outputType = ' output' ;
59-
60- % Creating linearization points
61- io(1 ) = linio(inputBlock ,inputPort ,inputType );
62- io(2 ) = linio(outputBlock ,outputPort ,outputType );
63-
64- % Setting the linearization points into the model
65- setlinio(' GainCurveLLCConverter' ,io );
66- count = 0 ;
67- Parameters = struct(" Name" ," " ," Value" ,0 );
68-
69- h = figure(' Name' ,' LLCResonantConverterFullBridgeGain' );
70- % Plot the gain range
71- for i = 1 : length(options .RloadVec.value)
72-
73- count = count + 1 ;
74- Reffective = 8 * options .RloadVec(i ).value/(pi ^ 2 );
75- set_param(" GainCurveLLCConverter/Rload" , " R" , num2str(Reffective ));
76- assignin(mdlWks ,' LLCDesign' ,LLCDesign );
77-
78- Parameters(1 ).Name = ' LLCDesign.L' ;
79- Parameters(1 ).Value = LLCDesign .L;
80- Parameters(2 ).Name = ' LLCDesign.Llk1' ;
81- Parameters(2 ).Value = LLCDesign .Llk1;
82- Parameters(3 ).Name = ' LLCDesign.Llk2' ;
83- Parameters(3 ).Value = LLCDesign .Llk2;
84- Parameters(4 ).Name = ' LLCDesign.Lm' ;
85- Parameters(4 ).Value = LLCDesign .Lm;
86- Parameters(5 ).Name = ' LLCDesign.C' ;
87- Parameters(5 ).Value = LLCDesign .C;
88-
89- Rload(count ) = options .RloadVec(i ).value;
90-
91-
92- % Linearizing the model
93- % linearizeOptions('AreParamsTunable',false);
94- systemModel = linearize(' GainCurveLLCConverter' ,io ,Parameters ); % Finding open loop system statespace model
95-
96- [mag ,phase ] = bode(systemModel ,2 * pi * freqVec );
97- magnitude(count ,: ) = 1 ./ reshape(mag ,[1 ,length(mag )]);
98- phaseAngle(count ,: ) = - 1 * reshape(phase ,[1 ,length(phase )]);
99- figure(h );
100- subplot(2 ,1 ,1 );
101- loglog(freqVec ,magnitude(count ,: ),' LineWidth' ,2 );
102- hold on ;
103- subplot(2 ,1 ,2 );
104- semilogx(freqVec ,phaseAngle(count ,: ),' LineWidth' ,2 );
105- hold on
106- legendInfo{i }=sprintf(" R_L = %3.2f Ohm " ,Rload(i ));
107- end
108-
109- hold on ;
110- figure(h )
111- hold on ;
35+ arguments
36+ LLCDesign struct
37+ options.RloadVec = simscape.Value(100 ," Ohm" ); % Load resistance
38+ options.FrequencyVec = simscape.Value((linspace(0.1 * ...
39+ LLCDesign.resonantFreq ,2*LLCDesign.resonantFreq ,100)),"Hz "); % Frequency Hz
40+ end
41+
42+ % Initialize the output parameter size
43+ numPlots = length(options .RloadVec.value);
44+ magnitude = zeros(numPlots ,length(options .FrequencyVec.value));
45+ phaseAngle = zeros(numPlots ,length(options .FrequencyVec.value));
46+ Rload = zeros(1 ,numPlots );
47+ legendInfo = cell(1 ,numPlots );
48+ % Model workspace
49+ mdlWks = get_param(GainCurveLLCConverter ,' ModelWorkspace' );
50+ freqVec = options .FrequencyVec.value;
51+ % Port assignment
52+ inputBlock = " GainCurveLLCConverter/Vin" ;
53+ inputPort = 1 ;
54+ inputType = ' input' ;
55+
56+ outputBlock = " GainCurveLLCConverter/Iin" ;
57+ outputPort = 1 ;
58+ outputType = ' output' ;
59+
60+ % Creating linearization points
61+ io(1 ) = linio(inputBlock ,inputPort ,inputType );
62+ io(2 ) = linio(outputBlock ,outputPort ,outputType );
63+
64+ % Setting the linearization points into the model
65+ setlinio(' GainCurveLLCConverter' ,io );
66+ count = 0 ;
67+ Parameters = struct(" Name" ," " ," Value" ,0 );
68+
69+ h = figure(' Name' ,' LLCResonantConverterFullBridgeGain' );
70+ % Plot the gain range
71+ for i = 1 : length(options .RloadVec.value)
72+
73+ count = count + 1 ;
74+ Reffective = 8 * options .RloadVec(i ).value/(pi ^ 2 );
75+ set_param(" GainCurveLLCConverter/Rload" , " R" , num2str(Reffective ));
76+ assignin(mdlWks ,' LLCDesign' ,LLCDesign );
77+
78+ Parameters(1 ).Name = ' LLCDesign.L' ;
79+ Parameters(1 ).Value = LLCDesign .L;
80+ Parameters(2 ).Name = ' LLCDesign.Llk1' ;
81+ Parameters(2 ).Value = LLCDesign .Llk1;
82+ Parameters(3 ).Name = ' LLCDesign.Llk2' ;
83+ Parameters(3 ).Value = LLCDesign .Llk2;
84+ Parameters(4 ).Name = ' LLCDesign.Lm' ;
85+ Parameters(4 ).Value = LLCDesign .Lm;
86+ Parameters(5 ).Name = ' LLCDesign.C' ;
87+ Parameters(5 ).Value = LLCDesign .C;
88+
89+ Rload(count ) = options .RloadVec(i ).value;
90+
91+
92+ % Linearizing the model
93+ % linearizeOptions('AreParamsTunable',false);
94+ systemModel = linearize(' GainCurveLLCConverter' ,io ,Parameters ); % Finding open loop system statespace model
95+
96+ [mag ,phase ] = bode(systemModel ,2 * pi * freqVec );
97+ magnitude(count ,: ) = 1 ./ reshape(mag ,[1 ,length(mag )]);
98+ phaseAngle(count ,: ) = - 1 * reshape(phase ,[1 ,length(phase )]);
99+ figure(h );
112100 subplot(2 ,1 ,1 );
113- legend(legendInfo );
114- xlabel(' Frequency (Hz)' ,' FontSize' ,12 );
115- ylabel(' Magnitude (Ohm)' ,' FontSize' ,12 );
116- title(" Magnitude" ,' FontSize' ,13 );
101+ loglog(freqVec ,magnitude(count ,: ),' LineWidth' ,2 );
102+ hold on ;
103+ subplot(2 ,1 ,2 );
104+ semilogx(freqVec ,phaseAngle(count ,: ),' LineWidth' ,2 );
105+ hold on
106+ legendInfo{i }=sprintf(" R_L = %3.2f Ohm " ,Rload(i ));
107+ end
108+
109+ hold on ;
110+ figure(h )
111+ hold on ;
112+ subplot(2 ,1 ,1 );
113+ legend(legendInfo );
114+ xlabel(' Frequency (Hz)' ,' FontSize' ,12 );
115+ ylabel(' Magnitude (Ohm)' ,' FontSize' ,12 );
116+ title(" Magnitude" ,' FontSize' ,13 );
117+ grid on
118+ box on
119+
120+ if isscalar(Rload )
121+ [~ ,idx ] = max(Rload );
122+ xZeroCrossing = find(phaseAngle(idx ,: )>=0 ,1 );
123+ if xZeroCrossing < length(phaseAngle(idx ,: )) && xZeroCrossing > 1
124+ positiveAngle = phaseAngle(idx ,xZeroCrossing + 1 : end )>0;
125+ if positiveAngle
126+ slope = (phaseAngle(idx ,xZeroCrossing )-phaseAngle(idx ,xZeroCrossing - 1 ))/(freqVec(idx ,xZeroCrossing )-freqVec(idx ,xZeroCrossing - 1 ));
127+ delFreq = - phaseAngle(idx ,xZeroCrossing - 1 )/slope ;
128+ freqZeroCrossing = freqVec(idx ,xZeroCrossing - 1 )+delFreq ;
129+ end
130+ end
131+ if exist(' freqZeroCrossing' ,' var' )
132+ yaxisImp = [min(min(magnitude ))*0.8 ,max(max(magnitude ))*1.2 ,...
133+ max(max(magnitude ))*1.2 ,min(min(magnitude ))*0.8 ];
134+ xaxisImp = [freqZeroCrossing ,freqZeroCrossing ,freqVec(end ),...
135+ freqVec(end )];
136+ fhandle = fill(xaxisImp ,yaxisImp ,' g' , ' HandleVisibility' ,' off' );
137+ fhandle.FaceAlpha = 0.1 ;
138+ end
139+ if exist(' freqZeroCrossing' ,' var' )
140+ yaxisImp = [min(min(magnitude ))*0.8 ,max(max(magnitude ))*1.2 ,...
141+ max(max(magnitude ))*1.2 ,min(min(magnitude ))*0.8 ];
142+ xaxisImp = [freqZeroCrossing ,freqZeroCrossing ,freqVec(1 ),...
143+ freqVec(1 )];
144+ fhandle = fill(xaxisImp ,yaxisImp ,' y' , ' HandleVisibility' ,' off' );
145+ fhandle.FaceAlpha = 0.1 ;
146+ end
147+ ylim([min(min(magnitude ))*0.8 ,max(max(magnitude ))*1.2 ]);
117148 grid on
118- box on
149+ end
119150
120- subplot(2 ,1 ,2 );
121- legend(legendInfo );
122- legend(legendInfo ," Location" ," southeast" );
123- xlabel(' Frequency (Hz)' ,' FontSize' ,12 );
124- ylabel(' Phase (deg)' ,' FontSize' ,12 );
125- title(" Phase" ,' FontSize' ,13 );
151+ subplot(2 ,1 ,2 );
152+ legend(legendInfo );
153+ legend(legendInfo ," Location" ," southeast" );
154+ xlabel(' Frequency (Hz)' ,' FontSize' ,12 );
155+ ylabel(' Phase (deg)' ,' FontSize' ,12 );
156+ title(" Phase" ,' FontSize' ,13 );
157+ grid on
158+ box on
159+ set(gcf , ' Position' , [400 , 300 , 600 , 600 ]);
160+
161+ if isscalar(Rload )
162+ if exist(' freqZeroCrossing' ,' var' )
163+ yaxisImp = [min(min(phaseAngle ))*1.2 ,max(max(phaseAngle ))*1.2 ,...
164+ max(max(phaseAngle ))*1.2 ,min(min(phaseAngle ))*1.2 ];
165+ xaxisImp = [freqZeroCrossing ,freqZeroCrossing ,freqVec(end ),...
166+ freqVec(end )];
167+ fhandle = fill(xaxisImp ,yaxisImp ,' g' ,' HandleVisibility' ,' off' );
168+ fhandle.FaceAlpha = 0.1 ;
169+ end
170+ if exist(' freqZeroCrossing' ,' var' )
171+ yaxisImp = [min(min(phaseAngle ))*1.2 ,max(max(phaseAngle ))*1.2 ,...
172+ max(max(phaseAngle ))*1.2 ,min(min(phaseAngle ))*1.2 ];
173+ xaxisImp = [freqZeroCrossing ,freqZeroCrossing ,freqVec(1 ),...
174+ freqVec(1 )];
175+ fhandle = fill(xaxisImp ,yaxisImp ,' y' ,' HandleVisibility' ,' off' );
176+ fhandle.FaceAlpha = 0.1 ;
177+ end
178+ ylim([min(min(phaseAngle ))*1.2 ,max(max(phaseAngle ))*1.2 ]);
126179 grid on
127- box on
180+ sgtitle(" Impedance Curve (Yellow=Capacitive Region, Green=Inductive Region)" ,' FontSize' ,13 );
181+ else
128182 sgtitle(" Impedance Curve" ,' FontSize' ,13 );
129- set(gcf , ' Position' , [400 , 300 , 600 , 600 ]);
130-
131- end
183+ end
184+ end
0 commit comments