diff options
Diffstat (limited to 'Physikunit.pas')
-rw-r--r-- | Physikunit.pas | 327 |
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. |