马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
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, Cm ouble;
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, wnano ouble;
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(f ouble); // 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(f ouble); // 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. |