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

[复制链接]
查看606 | 回复1 | 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草泥马
回复

使用道具 举报

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

使用道具 举报

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

本版积分规则