unit DIS_DIF; interface uses WinTypes,WinProcs,Classes,SysUtils,gltype,glproc,MathObj,MVTU_TLB; function TBackDif1(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; function TBackDif2(at,adt:RealType;var time,dtime:RealType;var AU,AY:TPtrExt;var AX,ADX:array of RealType; var CU,CY : TIntArray;var Prop:TPtrArray;var Vars:Pointer;Action:Integer):Integer;export; {#######################################################################################################} IMPLEMENTATION {#######################################################################################################} type PBackDif1Rec = ^TBackDif1Rec; TBackDif1Rec = record k, T, Y0 : TExtArray; Inputs : TMultiSelect; IniFlag : ^Integer; end; {Модель апериодического звена 1-го порядка с "точным" решением на шаге интегрирования, возможностью трансляции входа и задания постоянной времени через порты } function TBackDif1Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Аналитическая апериодика 1-го порядка'; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: with PBackDif1Rec(Prop.arr)^ do begin MVTU.SetBlockProp(BlockId,'k',PChar(ConvertVector(PropStr[0])),Res); MVTU.SetBlockProp(BlockId,'T',PChar(ConvertVector(PropStr[1])),Res); MVTU.SetBlockProp(BlockId,'y0',PChar(ConvertVector(PropStr[2])),Res); MVTU.SetBlockProp(BlockId,'inputs',PChar(ConvertMultiSelect(Inputs)),Res); MVTU.ExecutePropScript(BlockId,Res,Res); MVTU.SetBlockProp(BlockId,'iniflag',PChar(IntToStr(IniFlag^)),Res); end; end; end; function TBackDif1; var i,j : Integer; x,tau : RealType; flag : Boolean; begin Result:=0; with PBackDif1Rec(Prop.arr)^ do case Action of f_GetConvertFuncAdr: Result:=integer(@TBackDif1Convert); f_EditErr : if (T.Count <> k.Count) or (Y0.Count <> k.Count) then Result:=er_Count; f_GetStateCount : Result:=2*Y0.Count; f_GetInit : if IniFlag^ = 0 then Result:=1 else Result:=0; f_GetCount : begin for i:=0 to CU.Count-1 do CU.arr^[0]:=Y0.Count; CY.arr^[0]:=Y0.Count; end; f_InitState : for i:=0 to Y0.Count-1 do begin if IniFlag^ = 0 then AY.Ptr(0).arr^[i]:=Y0.arr^[i] else AY.Ptr(0).arr^[i]:=AU.Ptr(0).arr^[i]; AX[i]:=AY.Ptr(0).arr^[i] end; f_GetState : for i:=0 to Y0.Count-1 do begin AX[i+Y0.Count]:=at; AX[i]:=AY.Ptr(0).arr^[i] end; f_RestoreOuts: for i:=0 to Y0.Count-1 do begin AY.Ptr(0).arr^[i]:=AX[i]; AX[i+Y0.Count]:=at; end; f_UpdateOuts, f_GoodStep : for i:=0 to Y0.Count-1 do begin x:=k.arr^[i]*AU.Ptr(0).arr^[i]; tau:=T.arr^[i]; flag:=false; with Inputs do for j:=0 to selected.Count-1 do case selected.arr^[j] of 0: flag:=AU.Ptr(j+1).arr^[i] > 0.5; 1: tau:=AU.Ptr(j+1).arr^[i]; end; if flag or (tau <= 0.0) then AY.Ptr(0).arr^[i]:=AU.Ptr(0).arr^[i] else AY.Ptr(0).arr^[i]:=(AX[i]-x)*exp(-(at-AX[i+Y0.Count])/tau)+x; end; end end; {Модель апериодического звена 1-го порядка решением по неявной конечно-разностной схеме, возможностью трансляции входа и задания постоянной времени через порты } function TBackDif2Convert(Action: integer; Vars: Pointer; Prop: TPtrArray; PropStr: TStringList; BlockId: integer; var MVTU: IMVTU_Server):integer; const RecName:PChar = 'Дискретная апериодика 1-го порядка'; var Res: integer; begin case Action of //Возвращаем ссылку на имя записи в базе МВТУ-4 cnv_GetRecName: Result:=integer(RecName); //Конвертируем и устанавливаем параметры при помощи интерфейса МВТУ cnv_Convert: with PBackDif1Rec(Prop.arr)^ do begin MVTU.SetBlockProp(BlockId,'k',PChar(ConvertVector(PropStr[0])),Res); MVTU.SetBlockProp(BlockId,'T',PChar(ConvertVector(PropStr[1])),Res); MVTU.SetBlockProp(BlockId,'y0',PChar(ConvertVector(PropStr[2])),Res); MVTU.SetBlockProp(BlockId,'inputs',PChar(ConvertMultiSelect(Inputs)),Res); MVTU.ExecutePropScript(BlockId,Res,Res); MVTU.SetBlockProp(BlockId,'iniflag',PChar(IntToStr(IniFlag^)),Res); end; end; end; function TBackDif2; var i,j : Integer; u,tau : RealType; flag : Boolean; begin Result:=0; with PBackDif1Rec(Prop.arr)^ do case Action of f_GetConvertFuncAdr: Result:=integer(@TBackDif2Convert); f_EditErr : if (T.Count <> k.Count) or (Y0.Count <> k.Count) then Result:=er_Count; f_GetStateCount : Result:=Y0.Count; f_GetInit : if IniFlag^ = 0 then Result:=1 else Result:=0; f_GetCount : begin for i:=0 to CU.Count-1 do CU.arr^[0]:=Y0.Count; CY.arr^[0]:=Y0.Count; end; f_InitState : for i:=0 to Y0.Count-1 do begin if IniFlag^ = 0 then AY.Ptr(0).arr^[i]:=Y0.arr^[i] else AY.Ptr(0).arr^[i]:=AU.Ptr(0).arr^[i]; AX[i]:=AY.Ptr(0).arr^[i] end; f_GetState : for i:=0 to Y0.Count-1 do AX[i]:=AY.Ptr(0).arr^[i]; f_RestoreOuts: for i:=0 to Y0.Count-1 do AY.Ptr(0).arr^[i]:=AX[i]; f_UpdateOuts, f_GoodStep : for i:=0 to Y0.Count-1 do begin u:=AU.Ptr(0).arr^[i]*k.arr^[i]; tau:=T.arr^[i]; flag:=false; with Inputs do for j:=0 to selected.Count-1 do case selected.arr^[j] of 0: flag:=AU.Ptr(j+1).arr^[i] > 0.5; 1: tau:=AU.Ptr(j+1).arr^[i]; end; if flag then AY.Ptr(0).arr^[i]:=AU.Ptr(0).arr^[i] else AY.Ptr(0).arr^[i]:=(adt*u+T.arr^[i]*AX[i])/(adt+T.arr^[i]); end; end end; end.