modelica-3rdparty / PowerSystems

Free (standard conform) library that is intended to model electrical power systems at different levels of detail both in transient and steady-state mode.
65 stars 36 forks source link

PVIMeter improvement proposal(s) #26

Closed ceraolo closed 7 years ago

ceraolo commented 7 years ago

_In PVImeter, it the user chooses "phasor=true" v_norm, i_norm, alpha_v, alpha_i are computed and can be plotted. Is phasor=false v_norm and i_norm are not computed, but alpha_v and alpha_i are computed and set to zero. The following code makes a correction in such a way that also alpha_v and alphai are not computed (and not available for plotting) when they have no meaning, i.e. when phasor=false. Moreover, the info text is enhanced.

model PVImeter "Power-voltage-current meter, 3-phase dq0"
  extends Partials.Meter2Base;

  parameter Boolean av=false "time average power"
    annotation (Evaluate=true, Dialog(group="Options"));
  parameter SI.Time tcst(min=1e-9) = 1 "average time-constant"
    annotation (Evaluate=true, Dialog(group="Options", enable=av));

  function v2vpp_abc
    input SIpu.Voltage[3] v_abc;
    output SIpu.Voltage[3] vpp_abc;
  algorithm 
    vpp_abc := {v_abc[2],v_abc[3],v_abc[1]} - {v_abc[3],v_abc[1],v_abc[2]};
  end v2vpp_abc;

  output SIpu.Power[3] p(each stateSelect=StateSelect.never);
  output SIpu.Power[3] p_av=pav if av;
  output SIpu.Voltage[3] v(each stateSelect=StateSelect.never);
  output SIpu.Voltage[2] vpp(each stateSelect=StateSelect.never);
  output SIpu.Current[3] i(each stateSelect=StateSelect.never);

  output SIpu.Voltage[3] v_abc(each stateSelect=StateSelect.never)=
    transpose(Park)*v if abc;
  output SIpu.Voltage[3] vpp_abc(each stateSelect=StateSelect.never)=
    v2vpp_abc(transpose(Park)*v) if abc;
  output SIpu.Current[3] i_abc(each stateSelect=StateSelect.never)=
    transpose(Park)*i if abc;

  output SIpu.Voltage v_norm(stateSelect=StateSelect.never) = sqrt(v*v) if 
    phasor;
  output SI.Angle alpha_v(stateSelect=StateSelect.never)=atan2(Rot_dq[:, 2]*v[1:2],
     Rot_dq[:, 1]*v[1:2]) if phasor;
  output SIpu.Current i_norm(stateSelect=StateSelect.never) = sqrt(i*i) if 
    phasor;
  output SI.Angle alpha_i(stateSelect=StateSelect.never)=atan2(Rot_dq[:, 2]*i[1:2],
                    Rot_dq[:, 1]*i[1:2]) if phasor;
  output Real cos_phi(stateSelect=StateSelect.never) = cos(alpha_v - alpha_i) if 
       phasor;
protected 
  outer Utilities.System system;
  final parameter PS.Voltage V_base=Utilities.Precalculation.baseV(puUnits,
      V_nom);
  final parameter PS.Current I_base=Utilities.Precalculation.baseI(
        puUnits,
        V_nom,
        S_nom);
  SIpu.Power[3] pav;

initial equation 
  if av then
    pav = p;
  end if;

equation 
  v = term_p.v/V_base;
  vpp = sqrt(3)*{v[2],-v[1]};
  i = term_p.i/I_base;
  p = {v[1:2]*i[1:2],-j_dq0(v[1:2])*i[1:2],v[3]*i[3]};
  if av then
    der(pav) = (p - pav)/tcst;
  else
    pav = zeros(3);
  end if;
/*  
  if phasor then
    alpha_v = atan2(Rot_dq[:, 2]*v[1:2], Rot_dq[:, 1]*v[1:2]);
    alpha_i = atan2(Rot_dq[:, 2]*i[1:2], Rot_dq[:, 1]*i[1:2]);
  else
    alpha_v = 0;
    alpha_i = 0;
    end if;
 */
  annotation (
    defaultComponentName="PVImeter1",
    Icon(coordinateSystem(
        preserveAspectRatio=false,
        extent={{-100,-100},{100,100}},
        grid={2,2}), graphics={
        Rectangle(
          extent={{-20,24},{20,20}},
          lineColor={135,135,135},
          fillColor={175,175,175},
          fillPattern=FillPattern.Solid),
        Ellipse(
          extent={{-8,8},{8,-8}},
          lineColor={135,135,135},
          fillColor={175,175,175},
          fillPattern=FillPattern.Solid),
        Line(
          points={{0,0},{20,0}},
          color={0,100,100},
          thickness=0.5),
        Line(points={{-15,50},{15,64}}, color={135,135,135}),
        Line(points={{-15,40},{15,54}}, color={135,135,135}),
        Line(points={{-15,30},{15,44}}, color={135,135,135})}),
    Documentation(info="<html>
<p>&apos;Meters&apos; are intended as diagnostic instruments. They allow displaying signals in alternative representations, either in SI-units or in &apos;pu&apos;.</p>
<p>As they use time-dependent coordinate transforms, use them only when and where needed. Otherwise use &apos;Sensors&apos;.</p>
<p>Output variables in the chosen reference system:</p>
<pre>  p         {AC active, AC reactive, DC} power term_p to term_n
  v          voltage phase-to-ground dq0
  vpp        voltage phase-to-phase dq
  i          current dq0, term_p to term_n</pre>
<p>Optional output variables:</p>
<pre>  p_av       power term_p to term_n, time tau average of p (only if av=true)
  v_abc      voltage phase-to-ground,  abc-inertial system (only if abc=true)
  vpp_abc    voltage phase-to-phase,   abc-inertial system (only if abc=true)
  i_abc      current term_p to term_n, abc-inertial system (only if abc=true)
  v_norm     norm(v) (only if phasor=true)
  i_norm     norm(i) (only if phasor=true)
  alpha_v    phase(v)(only if phasor=true)
  alpha_i    phase(i)(only if phasor=true)
  cos_phi    cos(alpha_v - alpha_i) (only if phasor=true)</pre>
<p><i>Comment on the sign-definition of reactive power see</i> ACdq0.Sensors. </p>
</html>"));
end PVImeter;

Moreover I wonder whether the following row:

  output SI.Angle alpha_v(stateSelect=StateSelect.never)=atan2(Rot_dq[:, 2]*v[1:2],
     Rot_dq[:, 1]*v[1:2]) if phasor;

can be changed into the simpler (and equally correct?):

  output SI.Angle alpha_vMod(stateSelect=StateSelect.never)=atan2(v[2], v[1]) if 
    phasor;
rfranke commented 7 years ago

The Rot_dq is needed in the case of Inertial reference frame.

Made alpha_v and alpha_i conditional with 508248d07ae8c8d3be644ba0904a965448efc8fb.

Thank's for the hint!