我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 585|回复: 1

电力系统线路元件建模方法

[复制链接]

该用户从未签到

4

主题

2

回帖

1

积分

一级逆天

c草泥马

积分
1

社区居民

QQ
发表于 2015-11-15 14:33:29 | 显示全部楼层 |阅读模式
   FreqMultiplier     ouble;
   XgMod              ouble;
   LengthMultiplier   ouble;

   i,j, k, Norder     :Integer;

Begin
    FreqMultiplier := 1.0;
    LengthMultiplier := 1.0;

    IF SymComponentsChanged  THEN RecalcElementData;

    ClearYPrim;


    // Build Series YPrim
    WITH YPrim_Series DO Begin

         {Build Zmatrix}
         If GeometrySpecified Then Begin

             FMakeZFromGeometry(ActiveCircuit.Solution.Frequency); // Includes length in proper units
             if SolutionAbort then  Exit;

         End Else If SpacingSpecified Then Begin

             FMakeZFromSpacing(ActiveCircuit.Solution.Frequency);
             if SolutionAbort then  Exit;

         End Else Begin  // Z is from line code or specified in line data

             LengthMultiplier := Len / FUnitsConvert;   // convert to per unit length
             FYprimFreq       := ActiveCircuit.Solution.Frequency ;
             FreqMultiplier   := FYprimFreq/BaseFrequency;

             { Put in Series RL }
             ZValues    := Z.GetValuesArrayPtr(Norder);
             ZinvValues := Zinv.GetValuesArrayPtr(Norder);
             // Correct the impedances for length and frequency
             // Rg increases with frequency
             // Xg modified by ln of sqrt(1/f)
             if Xg <> 0.0 Then Xgmod :=  0.5 * KXg * ln(FreqMultiplier)
                          Else Xgmod := 0.0;

             FOR i := 1 to Norder*Norder Do
                ZinvValues^ := Cmplx((ZValues^.re + Rg * (FreqMultiplier - 1.0) )*LengthMultiplier, (ZValues^.im - Xgmod)* LengthMultiplier * FreqMultiplier);

         End;

         Zinv.Invert;  {Invert in place}
         If Zinv.Inverterror>0 Then  Begin
                 {If error, put in tiny series conductance}
            DoErrorMsg('TLineObj.CalcYPrim', 'Matrix Inversion Error for Line "' + Name + '"',
                       'Invalid impedance specified. Replaced with tiny conductance.', 183);
            Zinv.Clear;
            For i := 1 to Fnphases Do Zinv.SetElement(i, i, Cmplx(epsilon, 0.0));
          End
         Else
           { Now, Put in Yprim_Series matrix }
           FOR i := 1 to Fnphases Do Begin
               FOR j := 1 to Fnphases Do Begin
                   Value := Zinv.GetElement(i,j);
                   SetElement(i,j,Value);
                   SetElement(i+Fnphases,j+Fnphases,Value);
                   Value := cnegate(Value);
                   SetElemSym(i, j+Fnphases, Value);
               End;
           End;

           
     End;

     YPrim.Copyfrom(Yprim_Series);      // Initialize YPrim for series impedances

     // 10/3/2006 moved this to after the copy to Yprim so it doesn't affect normal line model capacitance
        // 3-30-04  ----- Rev 2-4-09 to include both sides of line
        // Increase diagonal elements of both sides of line so that we will avoid isolated bus problem
        // add equivalent of 10 kvar capacitive at 345 kV
     With Yprim_Series Do For i := 1 to Yorder Do AddElement(i,i, CAP_EPSILON);

     // Now Build the Shunt admittances and add into YPrim
     WITH YPrim_Shunt Do  Begin

         {Put half the Shunt Capacitive Admittance at each end}
         YValues := Yc.GetValuesArrayPtr(Norder);

         If GeometrySpecified Or SpacingSpecified Then Begin

            {Values are already compensated for length and frequency}
             k := 0;
             FOR j := 1 to Fnphases Do
               FOR i := 1 to Fnphases DO Begin
                  Inc(k);    // Assume matrix in col order (1,1  2,1  3,1 ...)
                  Value := CDivReal(YValues^[k], 2.0);  // half at each end ...
                  AddElement(i, j, Value);
                  AddElement(i+Fnphases, j+Fnphases, Value);
               End;

         End Else Begin
             {Regular line model - values computed per unit length at base frequency}
             k := 0;
             FOR j := 1 to Fnphases Do
             FOR i := 1 to Fnphases DO Begin
                  Inc(k);    // Assume matrix in col order (1,1  2,1  3,1 ...)
                  Value := Cmplx(0.0, YValues^[k].im*LengthMultiplier * FreqMultiplier/2.0);
                  AddElement(i,j,Value);
                  AddElement(i+Fnphases, j+Fnphases, Value);
             End;

         End;

         {Now Account for Open Conductors}
         {For any conductor that is open, zero out row and column}

      End; {With YPRIM}

    YPrim.AddFrom(Yprim_Shunt);
    Inherited CalcYPrim;
    YprimInvalid := False;

End;

PROCEDURE TLineObj.DumpProperties(Var F:TextFile; Complete:Boolean);

VAR
   i,j :Integer;

Begin
    Inherited DumpProperties(F, Complete);


    WITH ParentClass Do
    Begin
        Writeln(F,'~ ',PropertyName^[1],'=',firstbus);
        Writeln(F,'~ ',PropertyName^[2],'=',nextbus);

        Writeln(F,'~ ',PropertyName^[3],'=',CondCode);
        Writeln(F,'~ ',PropertyName^[4],'=',len:0:3);
        Writeln(F,'~ ',PropertyName^[5],'=',Fnphases:0);
        Writeln(F,'~ ',PropertyName^[6],'=',R1:0:5);
        Writeln(F,'~ ',PropertyName^[7],'=',X1:0:5);
        Writeln(F,'~ ',PropertyName^[8],'=',R0:0:5);
        Writeln(F,'~ ',PropertyName^[9],'=',X0:0:5);
        Writeln(F,'~ ',PropertyName^[10],'=',C1 * 1.0e9:0:5);
        Writeln(F,'~ ',PropertyName^[11],'=',C0 * 1.0e9:0:5);
        Write(F,'~ ',PropertyName^[12],'=','"');
           FOR i := 1 to Fnphases DO Begin
             FOR j := 1 to Fnphases DO Begin
                 Write(F, Z.GetElement(i,j).re:0:5,' ');
             End;
             Write(F,'|');
           End;
           Writeln(F,'"');
        Write(F,'~ ',PropertyName^[13],'=','"');
           FOR i := 1 to Fnphases DO Begin
             FOR j := 1 to Fnphases DO Begin
                 Write(F, Z.GetElement(i,j).im:0:5,' ');
             End;
             Write(F,'|');
           End;
           Writeln(F,'"');
        Write(F,'~ ',PropertyName^[14],'=','"');
           FOR i := 1 to Fnphases DO Begin
             FOR j := 1 to Fnphases DO Begin
                 Write(F, (Yc.GetElement(i,j).im/TwoPi/BaseFrequency * 1.e9):0:2,' ');
             End;
             Write(F,'|');
           End;
           Writeln(F,'"');

         Write(F,'~ ',PropertyName^[14],'=');
         If IsSwitch Then Writeln(F, 'true') else writeln(F, 'false');

         {Dump the rest by default}
         For i := 15 to NumProperties Do
         Begin
            Writeln(F,'~ ',PropertyName^,'=',PropertyValue);
         End;
    End;

End;


{*********** Placeholder for Line module No Load Loss procedure *********}
procedure TLineObj.GetLosses(var TotalLosses, LoadLosses,  NoLoadLosses: Complex);
begin

  {For Now, we'll just do the default behavior until we implement shunt losses}

  inherited;

end;

FUNCTION TLineObj.GetPropertyValue(Index: Integer): String;
VAR
   i, j: Integer;
   Factor: double;
begin


        Case Index of
          12..14: Result := '[';

        Else
            Result := '';
        End;
       {Report Impedance values in ohms per unit length of present length units}
        CASE Index of
            1: Result := GetBus(1);
            2: Result := GetBus(2);
            5: Result := Format('%d', [FNphases]);
            6: If SymComponentsModel Then Result := Format('%-.7g', [R1/FUnitsConvert]) else Result := '----';
            7: If SymComponentsModel Then Result := Format('%-.7g', [X1/FUnitsConvert]) else Result := '----';
            8: If SymComponentsModel Then Result := Format('%-.7g', [R0/FUnitsConvert]) else Result := '----';
            9: If SymComponentsModel Then Result := Format('%-.7g', [X0/FUnitsConvert]) else Result := '----';
           10: If SymComponentsModel Then Result := Format('%-.7g', [C1*1.0e9/FUnitsConvert]) else Result := '----';
           11: If SymComponentsModel Then Result := Format('%-.7g', [C0*1.0e9/FUnitsConvert]) else Result := '----';

           12: FOR i := 1 to FNconds Do   // R matrix
               Begin
                   For j := 1 to i Do
                   Begin  // report in per unit Length in length units
                       If GeometrySpecified Or SpacingSpecified Then  Result := Result + Format('%-.7g',[Z.GetElement(i,j).re/len]) + ' '
                       Else Result := Result + Format('%-.7g',[Z.GetElement(i,j).re/FUnitsConvert]) + ' ';
                   End;
                   IF i < FNconds Then Result := Result + '|';
               End;

           13: FOR i := 1 to FNconds Do      // X matrix
               Begin
                   For j := 1 to i Do
                   Begin
                       If GeometrySpecified Or SpacingSpecified Then  Result := Result + Format('%-.7g',[Z.GetElement(i,j).im/Len]) + ' '
                       Else Result := Result + Format('%-.7g',[Z.GetElement(i,j).im/FUnitsConvert]) + ' ';
                   End;
                   IF i < FNconds Then Result := Result + '|';
               End;

           14: Begin  // CMatrix  nf
                 Factor  := TwoPi * BaseFrequency  * 1.0e-9;
                 FOR i := 1 to FNconds Do
                 Begin
                     For j := 1 to i Do
                     Begin
                         If GeometrySpecified Or SpacingSpecified Then Result := Result + Format('%-.7g',[YC.GetElement(i,j).im/Factor/Len]) + ' '
                         Else Result := Result + Format('%-.7g',[YC.GetElement(i,j).im/Factor/FUnitsConvert]) + ' ';
                     End;
                     IF i < FNconds Then Result := Result + '|';
                 End;
               End;
           15: If IsSwitch Then Result := 'True' else Result := 'False';
           16: Result := Format('%-g', [Rg]);
           17: Result := Format('%-g', [Xg]);
           18: Result := Format('%-g', [Rho]);
        ELSE
           Result := Inherited GetPropertyValue(index);
        END;

        Case Index of
          12..14: Result := Result + ']';

        Else
        End;


end;

procedure TLineObj.GetSeqLosses(var PosSeqLosses, NegSeqLosses, ZeroSeqLosses: complex);

{ Only consider 3-phase branches with Pos seq >> Neg seq
  Otherwise, we don't know whether it is a 3-phase line or just a line with 3 phases
}

Var
   i,j, k :Integer;
   Vph,
   V012,
   I012   :Array[0..2] of Complex;

begin

    PosSeqLosses  := CZERO;
    NegSeqLosses  := CZERO;
    ZeroSeqLosses := CZERO;

    {Method: sum seq powers going into each terminal
    }

    If Fnphases=3 then Begin   {3-phase lines only}
       ComputeIterminal;
       For i := 1 to 2 do Begin
         k := (i-1)*Fnphases + 1;
         For j := 0 to 2 DO  Vph[j] := ActiveCircuit.Solution.NodeV^[NodeRef^[k+j]] ;
         Phase2SymComp(@Vph, @V012);
         Phase2SymComp(@Iterminal^[k], @I012);
         Caccum(PosSeqLosses,  Cmul(V012[1], Conjg(I012[1])));
         Caccum(NegSeqLosses,  Cmul(V012[2], Conjg(I012[2]))); // accumulate both line modes
         Caccum(ZeroSeqLosses, Cmul(V012[0], Conjg(I012[0])));
       End;
       cmulrealaccum(PosSeqLosses,  3.0);
       cmulrealaccum(NegSeqLosses,  3.0);
       cmulrealaccum(ZeroSeqLosses, 3.0);
    End;

end;

procedure TLineObj.InitPropertyValues(ArrayOffset: Integer);
begin

     PropertyValue[1] := Getbus(1);
     PropertyValue[2] := Getbus(2);
     PropertyValue[3] := '';
     PropertyValue[4] := '1.0';  // '5.28'; Changed 2/17/00
     PropertyValue[5] := '3';
     PropertyValue[6] := '.058';
     PropertyValue[7] := '.1206';
     PropertyValue[8] := '.1784';
     PropertyValue[9] := '.4047';
     PropertyValue[10] := '3.4';
     PropertyValue[11] := '1.6';
     PropertyValue[12] := '';
     PropertyValue[13] := '';
     PropertyValue[14] := '';
     PropertyValue[15] := 'false';
     PropertyValue[16] := '0.01805';
     PropertyValue[17] := '0.155081';
     PropertyValue[18] := '100';
     PropertyValue[19] := '';
     PropertyValue[20] := 'NONE';

    inherited InitPropertyValues(NumPropsThisClass);

      // Override Inherited properties  just in case
     PropertyValue[NumPropsThisClass + 1] := '400';  //Normamps
     PropertyValue[NumPropsThisClass + 2] := '600';  //emergamps
     PropertyValue[NumPropsThisClass + 3] := '0.1';  //Fault rate
     PropertyValue[NumPropsThisClass + 4] := '20';   // Pct Perm
     PropertyValue[NumPropsThisClass + 5] := '3';    // Hrs to repair

     ClearPropSeqArray;
end;

procedure TLineObj.MakePosSequence;
Var
  S:String;
  C1_new, Cs, Cmouble;
  Z1, ZS, Zm:Complex;
  i,j:Integer;
begin
// set to single phase and make sure R1, X1, C1 set.
// If already single phase, let alone
  If FnPhases>1 Then Begin
    // Kill certain propertyvalue elements to get a cleaner looking save
    PrpSequence^[3] := 0;
    For i := 6 to 14 Do PrpSequence^ := 0;

    If IsSwitch then begin
      S := ' R1=1 X1=1 C1=1.1 Phases=1 Len=0.001'
    end else begin
      if SymComponentsModel then begin  // keep the same Z1 and C1
        Z1.re := R1;
        Z1.im := X1;
        C1_new := C1 * 1.0e9; // convert to nF
      end else begin // matrix was input directly, or built from physical data
        // average the diagonal and off-dialgonal elements
        Zs := CZERO;
        For i := 1 to FnPhases  Do Caccum(Zs, Z.GetElement(i,i));
        Zs := CdivReal(Zs, Fnphases);
        Zm := CZERO;
        For i := 1 to FnPhases-1 Do  // Corrected 6-21-04
        For j := i+1 to FnPhases Do  Caccum(Zm, Z.GetElement(i,j));
        Zm := CdivReal(Zm, (Fnphases*(FnPhases-1.0)/2.0));
        Z1 := CSub(Zs, Zm);

        // Do same for Capacitances
        Cs := 0.0;
        For i := 1 to FnPhases  Do Cs := Cs + Yc.GetElement(i,i).im;
        Cm := 0.0;
        For i := 2 to FnPhases Do
        For j := i+1 to FnPhases Do  Cm := Cm + Yc.GetElement(i,j).im;
        C1_new := (Cs - Cm)/TwoPi/BaseFrequency/(Fnphases*(FnPhases-1.0)/2.0) * 1.0e9; // nanofarads
      end;
      S := Format(' R1=%-.5g  %-.5g  C1=%-.5g Phases=1',[Z1.re, Z1.im, C1_new]);
    end;
    // Conductor Current Ratings
    S := S + Format(' Normamps=%-.5g  %-.5g',[NormAmps, EmergAmps]);
    Parser.CmdString := S;
    Edit;
  End;

  Inherited MakePosSequence;
end;

function TLineObj.MergeWith(var OtherLine: TLineObj; Series:Boolean): Boolean;

// Merge this line with another line and disble the other line.
Var
    Values1, Values2 : pComplexArray;
    Order1, Order2, i, j,
    Common1, Common2:Integer;
    TotalLen, wnanoouble;
    S, NewName:String;
    TestBusNum:Integer;
    LenUnitsSaved:Integer;
    NewZ:Complex;
    LenSelf, LenOther ouble;

begin
   Result := FALSE;
   IF OtherLine <> Nil THEN
   Begin
      IF Fnphases <> OtherLine.Fnphases THEN  Exit;  // Can't merge

      LenUnitsSaved := LengthUnits;

      YPrimInvalid := True;

      // Redefine property values to make it appear that line was defined this way originally using matrices

      IF Series then TotalLen := Len + Otherline.Len * ConvertLineUnits(OtherLine.LengthUnits, LengthUnits) Else TotalLen := 1.0;

      If Series Then
      Begin
           { redefine the bus connections}

           // Find bus in common between the two lines
           Common1 := 0;
           Common2 := 0;
           i := 1;
           While (Common1=0) and (i<=2) Do
            Begin
              TestBusNum := ActiveCircuit.MapNodeToBus^[NodeRef^[1+(i-1)*Fnconds]].BusRef;
              For j := 1 to 2 Do
              Begin
                 If ActiveCircuit.MapNodeToBus^[OtherLine.NodeRef^[1+(j-1)*OtherLine.Nconds]].BusRef  = TestBusNum Then
                 Begin
                    Common1 := i;
                    Common2 := j;
                    Break;
                 End;
              End;
              inc(i);
            End;

           If Common1=0 Then Exit;  // There's been an error; didn't find anything in common

           {Redefine the bus connections}
           Case Common1 of
             1: Case Common2 of
                  1: S := 'Bus1="'+OtherLine.GetBus(2)+'"';
                  2: S := 'Bus1="'+OtherLine.GetBus(1)+'"';
                End;
             2: Case Common2 of
                  1: S := 'Bus2="'+OtherLine.GetBus(2)+'"';
                  2: S := 'Bus2="'+OtherLine.GetBus(1)+'"';
                End;
           End;

           Parser.cmdstring := S;
           Edit;

      End; {If Series}

      {Rename the line}
       If Series Then NewName := StripExtension(GetBus(1)) + '~'  + StripExtension(GetBus(2))
                 Else NewName := StripExtension(GetBus(1)) + '||' + StripExtension(GetBus(2));

       {Update ControlElement Connections to This Line}
       UpdateControlElements('line.'+NewName, 'line.'+Name);
       UpdateControlElements('line.'+NewName, 'line.'+OtherLine.Name);
       Name := NewName;

       If Series Then IsSwitch := FALSE; // not allowed on series merge.

       {Now Do the impedances}

       LenSelf := Len/FunitsConvert;  // in units of R X Data
       LenOther := OtherLine.Len/OtherLine.FunitsConvert;

       If SymComponentsModel Then
       Begin   {------------------------- Sym Component Model ----------------------------------}
         If Series Then
         Begin
              S := ' R1='+ Format('%-g',[(R1*LenSelf + OtherLine.R1*LenOther)/TotalLen]);     // Ohms per unit length of this line length units
              S := S + Format(' %-g',[(X1*LenSelf + OtherLine.X1*LenOther)/TotalLen]);
              S := S + Format(' %-g',[(R0*LenSelf + OtherLine.R0*LenOther)/TotalLen]);
              S := S + Format(' %-g',[(X0*LenSelf + OtherLine.X0*LenOther)/TotalLen]);
              S := S + Format(' %-g',[(C1*LenSelf + OtherLine.C1*LenOther)/TotalLen*1.0e9]);
              S := S + Format(' %-g',[(C0*LenSelf + OtherLine.C0*LenOther)/TotalLen*1.0e9]);
         End
         Else   {parallel}
         Begin
             If IsSwitch Then S := ''   {Leave as is if switch; just dummy z anyway}
             Else If OtherLine.IsSwitch Then S := ' switch=yes'   {This will take care of setting Z's}
             Else Begin
{********* Will This work with Length multiplier?  did it ever work? *************************}
              NewZ := ParallelZ(Cmplx(R1*Len ,X1*Len ), Cmplx(OtherLine.R1*OtherLine.Len,OtherLine.X1*OtherLine.Len));
              S := ' R1='+ Format('%-g %-g ',[NewZ.Re, NewZ.im]);
              NewZ := ParallelZ(Cmplx(R0*Len ,X0*Len ), Cmplx(OtherLine.R0*OtherLine.Len,OtherLine.X0*OtherLine.Len));
              S := ' R0='+ Format('%-g %-g ',[NewZ.Re, NewZ.im]);
              S := S + Format(' %-g',[(C1*Len + OtherLine.C1*OtherLine.Len)/TotalLen*1.0e9]);
              S := S + Format(' %-g',[(C0*Len + OtherLine.C0*OtherLine.Len)/TotalLen*1.0e9]);
             End;
         End;
          Parser.cmdstring := S;   // This reset the length units
          Edit;
       End
       Else  {------------------------- Matrix Model ----------------------------------}
           If Not Series Then  TotalLen := Len /2.0 {We'll assume lines are equal for now}
           Else
             Begin  {Matrices were defined}

               // Merge Z matrices
               Values1 := Z.GetValuesArrayPtr(Order1);
               Values2 := OtherLine.Z.GetValuesArrayPtr(Order2);

               If Order1 <> Order2 Then Exit;  // OOps.  Lines not same size for some reason

               // Z <= (Z1 + Z2 )/TotalLen   to get equiv ohms per unit length
               For i := 1 to Order1*Order1 Do
                 Values1^ := CDivReal(Cadd(CmulReal(Values1^, LenSelf), CmulReal(Values2^, LenOther)), TotalLen);

               // Merge Yc matrices
               Values1 := Yc.GetValuesArrayPtr(Order1);
               Values2 := OtherLine.Yc.GetValuesArrayPtr(Order2);

               If Order1 <> Order2 Then Exit;  // OOps.  Lines not same size for some reason

               For i := 1 to Order1*Order1 Do
                 Values1^ := CDivReal(Cadd( CmulReal(Values1^, LenSelf) , CmulReal(Values2^, LenOther) ), TotalLen);

               {R Matrix}
               S := 'Rmatrix=[';
               For i := 1 to 3 Do
               Begin
                For j := 1 to i Do
                  S := S + Format(' %-g',[Z.GetElement(i,j).Re]);
                S := S + ' | ';
               End;
               S := S + '] Xmatrix=[';
               {X Matrix}
               For i := 1 to 3 Do
               Begin
                For j := 1 to i Do
                  S := S + Format(' %-g',[Z.GetElement(i,j).im]);
                S := S + ' | ';
               End;
               S := S + ']';
               Parser.cmdstring := S;
               Edit;

               {C Matrix}
               wnano := TwoPi * BaseFrequency/1.0e9;
               S := 'Cmatrix=[';
               For i := 1 to 3 Do
               Begin
                For j := 1 to i Do
                  S := S + Format(' %-g',[(Yc.GetElement(i,j).im/wnano)]);   // convert from mhos to nanofs
                S := S + ' | ';
               End;
               S := S + '] ';
               Parser.cmdstring := S;
               Edit;
           End;  {Matrix definition}

       Parser.cmdstring := Format(' Length=%-g  Units=%s',[TotalLen, LineUnitsStr(LenUnitsSaved)]);
       Edit;

       OtherLine.Enabled := FALSE;  // Disable the Other Line
       Result := TRUE;
   End
   ELSE  DoSimpleMsg('Error in Line Merge: Attempt to merge with invalid (nil) line object found.', 184);


end;

procedure TLineObj.UpdateControlElements(const NewName, OldName: String);

Var
   pControlElem:TControlElem;
begin

     pControlElem := ActiveCircuit.DSSControls.First;
     While pControlElem <> Nil Do Begin
         If CompareText(OldName, pControlElem.ElementName)=0 Then Begin
             Parser.cmdstring := ' Element=' + NewName;  // Change name of the property
             pControlElem.Edit;
         End;
         pControlElem := ActiveCircuit.DSSControls.Next;
     End;
end;

procedure TLineObj.FetchLineSpacing(const Code: string);
begin
  if LineSpacingClass.SetActive(Code) then begin
    FLineSpacingObj := LineSpacingClass.GetActiveObj;
    FLineCodeSpecified := False;
    KillGeometrySpecified;
    SpacingCode := LowerCase(Code);

    // need to establish Yorder before FMakeZFromSpacing
    NPhases       := FLineSpacingObj.NPhases;
    Nconds        := FNPhases;  // Force Reallocation of terminal info
    Yorder        := Fnconds * Fnterms;
    YPrimInvalid  := True;       // Force Rebuild of Y matrix

  end else
    DoSimpleMsg ('Line Spacing object ' + Code + ' not found.', 181);
end;

procedure TLineObj.FetchWireList(const Code: string);
var
  i: Integer;
begin
  FLineCodeSpecified := False;
  KillGeometrySpecified;
  if not assigned (FLineSpacingObj) then
    DoSimpleMsg ('Must assign the LineSpacing before wires.', 181);

  FWireData := Allocmem(Sizeof(FWireData^[1]) * FLineSpacingObj.NWires);
  AuxParser.CmdString := Code;
  for i := 1 to FLineSpacingObj.NWires do begin
    AuxParser.NextParam; // ignore any parameter name  not expecting any
    WireDataClass.code := AuxParser.StrValue;
    if Assigned(ActiveWireDataObj) then
      FWireData^ := ActiveWireDataObj
    else
      DoSimpleMsg ('Wire ' + AuxParser.StrValue + ' was not defined first.', 181);
  end;
end;

procedure TLineObj.FetchGeometryCode(const Code: String);

Begin
   IF LineGeometryClass=Nil THEN LineGeometryClass := DSSClassList.Get(ClassNames.Find('LineGeometry'));

   IF LineGeometryClass.SetActive(Code) THEN
   Begin
       FLineCodeSpecified := FALSE;  // Cancel this flag
       SpacingSpecified := False;

       FLineGeometryObj := LineGeometryClass.GetActiveObj;
       FZFrequency      := -1.0;  // Init to signify not computed

       GeometryCode     := LowerCase(Code);

       If FrhoSpecified Then FlineGeometryObj.rhoearth := rho;

       NormAmps      := FLineGeometryObj.NormAmps;
       EmergAmps     := FLineGeometryObj.EmergAmps;
       UpdatePDProperties;

       NPhases       := FLineGeometryObj.Nconds;
       Nconds        := FNPhases;  // Force Reallocation of terminal info
       Yorder        := Fnconds * Fnterms;
       YPrimInvalid  := True;       // Force Rebuild of Y matrix

   End
   ELSE
      DoSimpleMsg('Line Geometry Object:' + Code + ' not found.', 181);

end;

Procedure TLineObj.FMakeZFromGeometry(fouble); // make new Z, Zinv, Yc, etc
Begin
     If f = FZFrequency Then exit;  // Already Done for this frequency, no need to do anything

     IF Assigned(FLineGeometryObj) Then Begin
       {This will make a New Z; Throw away present allocations}

        IF assigned(Z)    THEN Begin Z.Free;    Z    := nil; End;
        IF assigned(Zinv) THEN Begin Zinv.Free; Zinv := nil; End;
        IF assigned(Yc)   THEN Begin Yc.Free;   Yc   := nil; End;

        Z    := FLineGeometryObj.Zmatrix[ f, len, LengthUnits];
        Yc   := FLineGeometryObj.YCmatrix[f, len, LengthUnits];
        {Init Zinv}
        if Assigned(Z) then  Begin
            Zinv := TCMatrix.CreateMatrix(Z.order);  // Either no. phases or no. conductors
            Zinv.CopyFrom(Z);
        End;

        // Z and YC are actual total impedance for the line;

        FZFrequency := f;
     End;
End;

Procedure TLineObj.FMakeZFromSpacing(fouble); // make new Z, Zinv, Yc, etc
Var
  pGeo   : TLineGeometryObj;
Begin
  If f = FZFrequency Then exit;  // Already Done for this frequency, no need to do anything

  IF assigned(Z)    THEN Begin Z.Free;    Z    := nil; End;
  IF assigned(Zinv) THEN Begin Zinv.Free; Zinv := nil; End;
  IF assigned(Yc)   THEN Begin Yc.Free;   Yc   := nil; End;

  // make a temporary LineGeometry to calculate line constants
  IF LineGeometryClass=Nil THEN LineGeometryClass := DSSClassList.Get(ClassNames.Find('LineGeometry'));
  pGeo := TLineGeometryObj.Create(LineGeometryClass, '==');
  pGeo.LoadSpacingAndWires (FLineSpacingObj, FWireData);

  If FrhoSpecified Then pGeo.rhoearth := rho;
  NormAmps      := pGeo.NormAmps;
  EmergAmps     := pGeo.EmergAmps;
  UpdatePDProperties;

  Z    := pGeo.Zmatrix[ f, len, LengthUnits];
  Yc   := pGeo.YCmatrix[f, len, LengthUnits];
  if Assigned(Z) then begin
    Zinv := TCMatrix.CreateMatrix(Z.order);  // Either no. phases or no. conductors
    Zinv.CopyFrom(Z);
  end;
  pGeo.Free;

  FZFrequency := f;
End;

procedure TLineObj.KillGeometrySpecified;
begin
{Indicate No Line Geometry specification if this is called}
      If GeometrySpecified Then Begin
          FLineGeometryObj  := Nil;
          FZFrequency       := -1.0;
          GeometrySpecified := FALSE;
      End;
end;

procedure TLineObj.KillSpacingSpecified;
begin
      If SpacingSpecified Then Begin
          FLineSpacingObj := Nil;
          Reallocmem (FWireData, 0);
          FZFrequency       := -1.0;
          SpacingSpecified := FALSE;
      End;
end;

procedure TLineObj.ClearYPrim;
begin
// Line Object needs both Series and Shunt YPrims built
    IF YPrimInvalid THEN Begin // Reallocate YPrim if something has invalidated old allocation
       IF YPrim_Series <> nil THEN  YPrim_Series.Free;
       IF YPrim_Shunt  <> nil THEN  YPrim_Shunt.Free;
       IF YPrim        <> nil THEN  YPrim.Free;

       YPrim_Series := TcMatrix.CreateMatrix(Yorder);
       YPrim_Shunt  := TcMatrix.CreateMatrix(Yorder);
       YPrim        := TcMatrix.CreateMatrix(Yorder);
    End
    ELSE Begin
        YPrim_Series.Clear;   // zero out YPrim Series
        YPrim_Shunt.Clear;    // zero out YPrim Shunt
        YPrim.Clear;          // zero out YPrim
    End;
end;

procedure TLineObj.ResetLengthUnits;
{If specify the impedances always assume the length units match}
begin
      FUnitsConvert := 1.0;
      LengthUnits   := UNITS_NONE;
end;

initialization

   CAP_EPSILON := cmplx(0.0, 4.2e-8);  // 5 kvar of capacitive reactance at 345 kV to avoid open line problem

End.
c草泥马
回复

使用道具 举报

该用户从未签到

16

主题

639

回帖

230

积分

二级逆天

积分
230

社区居民忠实会员社区劳模最爱沙发社区明星终身成就奖宣传大使奖

QQ
发表于 2015-11-16 08:31:00 | 显示全部楼层
不错,源码直接分享出来了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

论坛开启做任务可以
额外奖励金币快速赚
积分升级了


Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

平平安安
TOP
快速回复 返回顶部 返回列表