summaryrefslogtreecommitdiff
path: root/Physikunit.pas
diff options
context:
space:
mode:
Diffstat (limited to 'Physikunit.pas')
-rw-r--r--Physikunit.pas327
1 files changed, 191 insertions, 136 deletions
diff --git a/Physikunit.pas b/Physikunit.pas
index 0aee452..71e6a79 100644
--- a/Physikunit.pas
+++ b/Physikunit.pas
@@ -8,7 +8,7 @@ unit Physikunit;
interface
uses
- Classes, SysUtils, Math;
+ Classes, SysUtils, Math, protokollunit, matheunit, mystringlistunit, lowlevelunit;
type
TZeitverfahren = (zfEulerVorwaerts,zfRungeKuttaVier);
@@ -21,73 +21,70 @@ type
fiGamma,fiiGamma);
TAusgabeDatei = record
- Ableitung: Boolean;
- Inhalt: TFeldInhalt;
- Datei: File;
+ ableitung: boolean;
+ inhalt: tFeldInhalt;
+ name: string;
+ datei: file;
end;
- TProtokolldatei = record
- datei: textfile;
- einrueckung: longint;
- end;
+ tFelder = class;
- { TProtokollant }
+ { tWerteGitter }
- TProtokollant = class(TObject)
- private
- sDat: ^TProtokolldatei;
- Bes: String;
- Kinder: array of TProtokollant;
- Elter: TProtokollant;
- public
- constructor create(Dateiname: string); overload;
- constructor create(Elter_: TProtokollant; Besitzer: string); overload;
- destructor destroy; override;
- procedure schreibe(s: string);
- procedure schreibe(s: string; tee: boolean);
- procedure destroyall;
+ tWerteGitter = class(tObject) // repräsentiert ein Gitter von Werten und deren Zeitableitungen
+ werte: array[boolean] of array of extended;
+ par: tFelder;
end;
- { TFeld }
+ { TFelder }
- pTFeld = ^TFeld;
- TFeld = class(TObject)
+ tFelder = class(tObject) // repräsentiert eine Simulationsbox von Feldern inklusive deren Ableitungen
public
- Groessen: array[Boolean,TFeldInhalt] of extended;
+ materieFelder: array of tWerteGitter; // Materiefelder (getrennt für verschiedene Teilchenspezies) und deren Zeitableitungen
+ elektroMagnetischeFelder: tWerteGitter; // EM-Felder und deren Zeitableitungen
// A, p[xyz]? und i?Gamma haben keine sinnvolle Ableitung hier!
dX,iDX,x,pDNMax: extended;
- lN,rN: pTFeld;
+
constructor create(deltaX,pDNMa: extended);
procedure berechneGammaUndP;
procedure berechneNAbleitung;
procedure berechneAbleitungen(dT: extended);
end;
- { TGitter }
+ { tGitter }
- TGitter = class(TObject)
+ tGitter = class(tObject)
private
groesse: longint;
- Prot: TProtokollant;
+ prot: tProtokollant;
procedure berechneAbleitungen(Felder: longint; dt: extended); overload;
procedure berechneAbleitungen(Felder: longint; dt: extended; out dTMax: extended); overload;
procedure setzeRaender(Felder: longint);
public
aktuelleFelder: longint;
- Felders: array of array of TFeld;
+ felders: array of tFelder; // mehrere komplette Simulationsboxen von Feldern, benötigt um Zwischenschritte für die Zeitentwicklung zu speichern
dTMaximum,dX,iDX,xl,xr,t,pDNMax: extended;
pDNMaxDynamisch: boolean;
Zeitverfahren: TZeitverfahren;
Al,Ar: TVerteilungsfunktion;
- constructor create(size: longint; deltaT,deltaX,pDNMa: extended; n0: TVerteilungsfunktion; ZV: TZeitverfahren; Protokollant: TProtokollant);
+ constructor create(size: longint; deltaT,deltaX,pDNMa: extended; dichten, lichter: tMyStringlist; zv: tZeitverfahren; protokollant: tProtokollant);
destructor destroy; override;
procedure iteriereSchritt(var dT: extended);
procedure macheAusgabe(AD: TAusgabedatei; sDX: extended);
function gibErhaltungsgroessen: string;
end;
-function Nullfunktion(x: extended): extended;
-function timetostr(t: extended): string;
+ { tSimulation }
+
+ tSimulation = class(tObject)
+ private
+ prot: tProtokollant;
+ gitter: tGitter;
+ kvs: tKnownValues;
+ public
+ constructor create(inName: string; Protokollant: tProtokollant);
+ destructor destroy; override;
+ end;
const
OptionNamen: array[TFeldInhalt] of string = (
@@ -98,81 +95,6 @@ const
implementation
-{ TProtokollant }
-
-constructor TProtokollant.create(Dateiname: string);
-begin
- inherited create;
- getmem(sDat,sizeof(TProtokolldatei));
- sDat^.einrueckung:=10;
- assignfile(sDat^.datei,Dateiname);
- rewrite(sDat^.datei);
- Bes:='';
- setlength(Kinder,0);
- Elter:=nil;
-end;
-
-constructor TProtokollant.create(Elter_: TProtokollant; Besitzer: string);
-begin
- inherited create;
- sDat:=Elter_.sDat;
- setlength(Elter_.Kinder,length(Elter_.Kinder)+1);
- Elter_.Kinder[length(Elter_.Kinder)-1]:=self;
- Elter:=Elter_;
- setlength(Kinder,0);
- Bes:=Elter.Bes+'.'+Besitzer;
- if pos('.',Bes)=1 then delete(Bes,1,1);
- if length(Bes)+4 > sDat^.einrueckung then
- sDat^.einrueckung:=length(Bes)+4;
-end;
-
-destructor TProtokollant.destroy;
-var i: longint;
-begin
- while length(Kinder)>0 do
- Kinder[length(Kinder)-1].free;
- if assigned(Elter) then begin
- flush(sDat^.datei);
- i:=0;
- while (i<length(Elter.Kinder)) and (Elter.Kinder[i]<>self) do
- inc(i);
- if i>=length(Elter.Kinder) then
- schreibe('destroy fehlgeschlagen, ich kann mich nicht sehen.');
- inc(i);
- while i<length(Elter.Kinder) do begin
- Elter.Kinder[i-1]:=Elter.Kinder[i];
- inc(i);
- end;
- setlength(Elter.Kinder,length(Elter.Kinder)-1);
- end
- else begin
- closefile(sDat^.datei);
- freemem(sDat,sizeof(TProtokolldatei));
- end;
- inherited destroy;
-end;
-
-procedure TProtokollant.destroyall;
-begin
- if Assigned(Elter) then Elter.destroyall
- else destroy;
-end;
-
-procedure TProtokollant.schreibe(s: string);
-begin
- schreibe(s,false);
-end;
-
-procedure TProtokollant.schreibe(s: string; tee: boolean);
-var i: longint;
-begin
- for i:=length(Bes)+1 to sDat^.einrueckung do
- s:=' '+s;
- writeln(sDat^.datei,Bes+s);
- if tee then
- writeln(Bes+s);
-end;
-
{ TFeld }
constructor TFeld.create(deltaX,pDNMa: extended);
@@ -308,12 +230,12 @@ begin
+ (Ar(t+dTMaximum)-Ar(t))/dTMaximum;
end;
-constructor TGitter.create(size: longint; deltaT,deltaX,pDNMa: extended; n0: TVerteilungsfunktion; ZV: TZeitverfahren; Protokollant: TProtokollant);
+constructor TGitter.create(size: longint; deltaT,deltaX,pDNMa: extended; dichten, lichter: tMyStringlist; zv: tZeitverfahren; protokollant: tProtokollant);
var i,j: longint;
begin
inherited create;
- Ar:=@Nullfunktion;
- Al:=@Nullfunktion;
+ Ar:=@nullfunktion;
+ Al:=@nullfunktion;
Zeitverfahren:=ZV;
groesse:=size;
Prot:=TProtokollant.create(Protokollant,'TGitter');
@@ -335,6 +257,7 @@ begin
for j:=0 to length(felders[i])-1 do begin
felders[i,j]:=TFeld.create(dX,pDNMax);
felders[i,j].x:=xl+j*dX;
+ knownValues.add('x',felders[i,j].x);
felders[i,j].Groessen[false,fiN]:=n0(felders[i,j].x);
felders[i,j].Groessen[false,fidPsiDX]:=0.0001*Cos(j/(length(felders[i])-1)*pi*15);
end;
@@ -353,9 +276,12 @@ end;
destructor TGitter.destroy;
var i,j: longint;
begin
- for i:=0 to 1 do
+ for i:=0 to length(Felders)-1 do begin
for j:=0 to length(Felders[i])-1 do
Felders[i,j].free;
+ setlength(Felders[i],0);
+ end;
+ setlength(Felders,0);
inherited destroy;
end;
@@ -574,34 +500,163 @@ begin
Pro.free;
end;
-function Nullfunktion(x: extended): extended;
+{ tSimulation }
+
+constructor tSimulation.create(inName: string; Protokollant: tProtokollant);
+var
+ ifile: tMyStringlist;
+ zeitverfahren: tZeitverfahren;
+ s,t,aSuffix,aPrefix: string;
+ deltaX,deltaT,endzeit,breite,sDT,pDNMax: extended;
+ ausgabeDateien: array of tAusgabeDatei;
+ abl: boolean;
+ fi: tFeldinhalt;
+ i,j: longint;
begin
- result:=0*x;
-end;
+ inherited create;
+ prot:=tProtokollant.create(Protokollant,'tSimulation');
+ kvs:=tKnownValues.create;
-function timetostr(t: extended): string;
-var b: boolean;
-begin
- result:='';
- b:=t>=1;
- if b then begin
- result:=result+inttostr(floor(t))+' Tage ';
- t:=t-floor(t);
+ ifile:=tMyStringlist.create(prot);
+ ifile.loadfromfile(inName);
+ if not ifile.unfoldMacros then begin
+ prot.schreibe('Fehlerhafte Macros in Parameterdatei '''+inName+'''!',true);
+ halt(1);
+ end;
+
+ // Standardeinstellungen Bereich 'allgemein'
+ zeitverfahren:=zfRungeKuttaVier;
+ deltaX:=1e-2;
+ kvs.add('λ',1/deltaX);
+ deltaT:=-1;
+ sDT:=-1;
+ endzeit:=100;
+ breite:=10.0;
+ pDNMax:=-1;
+
+ // Standardeinstellungen Bereich 'ausgaben'
+ aPrefix:=extractfilepath(paramstr(0));
+ aSuffix:='.dat';
+ setlength(ausgabeDateien,0);
+
+ while ifile.readln(s) do begin
+ if s='allgemein' then begin
+ repeat
+ if not ifile.readln(s) then begin
+ prot.schreibe('Unerwartetes Dateiende in Parameterdatei '''+inName+''' im Bereich allgemein!',true);
+ halt(1);
+ end;
+ if s='allgemeinEnde' then break;
+ if s='runge-Kutta-4' then begin
+ Zeitverfahren:=zfRungeKuttaVier;
+ continue;
+ end;
+ if s='euler-Vorwärts' then begin
+ Zeitverfahren:=zfEulerVorwaerts;
+ continue;
+ end;
+ if startetMit('ortsschritt',s) then begin
+ deltaX:=exprtofloat(false,s,kvs,nil);
+ kvs.add('λ',1/deltaX);
+ continue;
+ end;
+ if startetMit('zeitschritt',s) then begin
+ deltaT:=exprtofloat(false,s,kvs,nil);
+ kvs.add('dT',deltaT);
+ continue;
+ end;
+ if startetMit('diffusionsterm',s) then begin
+ pDNMax:=exprtofloat(false,s,kvs,nil);
+ continue;
+ end;
+ if startetMit('zeit',s) then begin
+ endzeit:=exprtofloat(false,s,kvs,nil);
+ continue;
+ end;
+ if startetMit('breite',s) then begin
+ breite:=exprtofloat(false,s,kvs,nil);
+ continue;
+ end;
+ prot.schreibe('Unbekannter Befehl '''+s+''' in Parameterdatei '''+inName+''' im Bereich allgemein!',true);
+ halt(1);
+ until false;
+ continue;
+ end;
+
+ if s='ausgaben' then begin
+ repeat
+ if not ifile.readln(s) then begin
+ prot.schreibe('Unerwartetes Dateiende in Parameterdatei '''+inName+''' im Bereich ausgaben!',true);
+ halt(1);
+ end;
+ if s='ausgabenEnde' then break;
+ if startetMit('suffix',s) then begin
+ aSuffix:=s;
+ continue;
+ end;
+ if startetMit('prefix',s) then begin
+ aPrefix:=s;
+ continue;
+ end;
+ if startetMit('zeitschritt',s) then begin
+ sDT:=exprtofloat(false,s,kvs,nil);
+ continue;
+ end;
+ if startetMit('felder',s) then begin
+ s:=s+',';
+ while s<>'' do begin
+ t:=erstesArgument(s,',');
+ for abl:=false to true do
+ for fI:=low(tFeldInhalt) to high(tFeldInhalt) do
+ if not (abl and (fI in [fiGamma,fiP])) then
+ if t=copy('d',1,byte(abl))+optionNamen[fI] then begin
+ setlength(ausgabedateien,length(ausgabedateien)+1);
+ ausgabedateien[length(ausgabedateien)-1].inhalt:=fI;
+ ausgabedateien[length(ausgabedateien)-1].ableitung:=abl;
+ ausgabedateien[length(ausgabedateien)-1].name:=aPrefix+t+aSuffix;
+ assignFile(ausgabedateien[length(ausgabedateien)-1].datei,ausgabedateien[length(ausgabedateien)-1].name);
+ end;
+ end;
+ continue;
+ end;
+ prot.schreibe('Unbekannter Befehl '''+s+''' in Parameterdatei '''+inName+''' im Bereich ausgaben!',true);
+ halt(1);
+ until false;
+ continue;
+ end;
+
+ prot.schreibe('Unbekannter Befehl '''+s+''' in Parameterdatei '''+inName+'''!',true);
+ halt(1);
end;
- t:=t*24;
- b:=b or (t>=1);
- if b then begin
- result:=result+inttostr(floor(t))+'h ';
- t:=t-floor(t);
+
+ if length(ausgabedateien)=0 then begin
+ prot.schreibe('Du solltest irgendetwas abspeichern lassen!',true);
+ halt(1);
end;
- t:=t*60;
- b:=b or (t>=1);
- if b then begin
- result:=result+inttostr(floor(t))+'min ';
- t:=t-floor(t);
+
+ if deltaT<0 then
+ deltaT:=deltaX/10;
+ if sDT<0 then
+ sDT:=deltaT;
+
+ for i:=0 to length(ausgabedateien)-1 do begin
+ rewrite(ausgabedateien[i].datei,1);
+ j:=0;
+ BlockWrite(Ausgabedateien[i].Datei,j,sizeof(longint));
+ j:=floor(Endzeit/sDT+1);
+ BlockWrite(Ausgabedateien[i].Datei,j,sizeof(longint));
end;
- t:=t*60;
- result:=result+inttostr(round(t))+'s';
+ ifile.free;
+
+ gitter:=tGitter.create(Breite,deltaT,deltaX,pDNMax,@Anfangsdichte,Zeitverfahren,Prot);
+end;
+
+destructor tSimulation.destroy;
+begin
+ gitter.free;
+ kvs.free;
+ prot.free;
+ inherited destroy;
end;
end.