I have developed a dynamic phasor model of a grid-connected single phase inverter. Running the open loop model of the simulation (with modulation index and initial angle constant) for a duration of 0.3 seconds with a step-size of 1e-05 takes about 45 seconds.
However, implementing a discrete PI controller with sampling rate of 1e-4 leads to a simulation duration of about 30 minutes.
My suspicion is the sample
function in my PI code. Would be glad if anyone could help with identifying the cause and a possible workaround. The controller code is below. Thanks in advance.
model LinearController_DQ_InverterSP
// reference currents
parameter Real Id_ref[3] = {0.0, 10.0, 20.0};
parameter Real Iq_ref[3] = {0.0, 5.0, 10.0};
//step times
parameter Real step_times[2] = {0.08, 0.12};
// current reference currents
Real Id_ref_curr;
Real Iq_ref_curr;
parameter Real Kp_cc = 0.0541 "Proportional term of controller";
parameter Real Ki_cc = 55.577 "Integral term of controller";
parameter Real T_sample = 1e-4 "Sampling period";
// previous time step terms
Real ud_prev(start = 0.0, fixed = true);
Real uq_prev(start = 0.0, fixed = true);
Real ed_prev(start = 0.0, fixed = true);
Real eq_prev(start = 0.0, fixed = true);
Real Vd_pcc_prev(start = 220*sqrt(2), fixed = true);
Real Vq_pcc_prev(start = 0.0, fixed = true);
// current time step terms
Real ud_curr, uq_curr;
Real ed_curr, eq_curr;
Real Vin_d, Vin_q;
Real a_const = Kp_cc + Ki_cc * T_sample / 2;
Real b_const = -Kp_cc + Ki_cc * T_sample / 2;
Modelica.Blocks.Interfaces.RealOutput Mr(start = 0.87, fixed=true); // modulation index
Modelica.Blocks.Interfaces.RealOutput th(start=0.0, fixed=true) ; // angle
Modelica.Blocks.Interfaces.RealInput Id ; // measured Id current
Modelica.Blocks.Interfaces.RealInput Iq ; // measure Iq current
Modelica.Blocks.Interfaces.RealInput Vd_pcc ; // Vd of measured grid voltage
Modelica.Blocks.Interfaces.RealInput Vq_pcc ; // Vq of measured grid voltage
algorithm
if time < step_times[1] then
Id_ref_curr := Id_ref[1];
Iq_ref_curr := Iq_ref[1];
elseif (time > step_times[1]) and (time < step_times[2]) then
Id_ref_curr := Id_ref[2];
Iq_ref_curr := Iq_ref[2];
else
Id_ref_curr := Id_ref[3];
Iq_ref_curr := Iq_ref[3];
end if;
when sample(0, T_sample) then
//Calc error
ed_curr := Id_ref_curr - Id;
eq_curr := Iq_ref_curr - Iq;
//Calc pid controller output
ud_curr := ud_prev + a_const * ed_curr + b_const * ed_prev;
uq_curr := uq_prev + a_const * eq_curr + b_const * eq_prev;
//Apply feedforward term
Vin_d := (Vd_pcc_prev + ud_prev);
Vin_q := (Vq_pcc_prev + uq_prev);
//Compute control signals
th := atan(Vin_q / Vin_d);
Mr := sqrt(Vin_d^2 + Vin_q^2) / 360;
// Update values
Vd_pcc_prev := Vd_pcc;
Vq_pcc_prev := Vq_pcc;
ed_prev := ed_curr;
eq_prev := eq_curr;
ud_prev := ud_curr;
uq_prev := uq_curr;
end when;
end LinearController_DQ_InverterSP;