summaryrefslogtreecommitdiff
path: root/Physikunit.pas
diff options
context:
space:
mode:
Diffstat (limited to 'Physikunit.pas')
-rw-r--r--Physikunit.pas71
1 files changed, 55 insertions, 16 deletions
diff --git a/Physikunit.pas b/Physikunit.pas
index f95dc32..b4b1456 100644
--- a/Physikunit.pas
+++ b/Physikunit.pas
@@ -106,8 +106,9 @@ type
_aX,_aP: longint;
_dX,_dP,iDX: double;
ffts: array of array[0..1,boolean] of fftw_plan_double; // fft-Algorithmen
- fftTmp: Pcomplex_double; // Zwischenspeicher für ffts
+ fftTmp,lFftTmp: Pcomplex_double; // Zwischenspeicher für ffts
procedure initialisiereDichte(ort,tlc: longint; breite,n: double); inline;
+ procedure pruefeArrayEnden(fehler: string);
public
emFelder: array[tEMFeldGroesze,boolean] of pDouble; // EM-Felder und deren Zeitableitungen
// dPhiDX und B[xyz] haben keine sinnvolle Ableitung hier!
@@ -585,8 +586,9 @@ begin
setlength(impulsRaumGradient,length(teilchen));
for i:=0 to length(impulsRaumGradient)-1 do
for j:=0 to length(impulsRaumGradient[i])-1 do begin
- fftw_getmem(impulsRaumGradient[i,j],aP*aX*sizeof(double));
+ fftw_getmem(impulsRaumGradient[i,j],(aP*aX+1)*sizeof(double));
fillchar(impulsRaumGradient[i,j]^,aP*aX*sizeof(double),#0);
+ (impulsRaumGradient[i,j]+aP*aX)^:=pi;
end;
fillchar(iMGamma,sizeof(iMGamma),#0);
setlength(iMGamma,length(teilchen));
@@ -639,8 +641,13 @@ begin
lichters[true].grep('^rechts .*');
lichters[true].subst('^rechts *','');
- fftw_getmem(fftTmp,(aP+1)*(aX+1)*sizeof(complex_double));
- fillchar(fftTmp^,(aP+1)*(aX+1)*sizeof(complex_double),#0);
+ i:=max((aP div 2 + 1)*aX,(aX div 2 + 1)*aP);
+ fftw_getmem(fftTmp,(i+1)*sizeof(complex_double));
+ fillchar(fftTmp^,(i+1)*sizeof(complex_double),#0);
+ lFftTmp:=fftTmp+i;
+
+ lFftTmp^.re:=pi;
+ lFftTmp^.im:=sqr(pi);
fillchar(ffts,sizeof(ffts),#0);
setlength(ffts,length(teilchen));
@@ -651,11 +658,14 @@ begin
fftw_plan_many_dft_c2r(1,@_aX,aP,fftTmp,nil,aP,1,impulsRaumGradient[i,0],nil,aP,1,[fftw_measure]);
ffts[i,1,false]:= // Planung der Hintransformationen über p
- fftw_plan_many_dft_r2c(1,@_aP,aX,impulsraum[i,false],nil,1,aP,fftTmp,nil,1,aP,[fftw_preserve_input,fftw_measure]);
+ fftw_plan_many_dft_r2c(1,@_aP,aX,impulsraum[i,false],nil,1,aP,fftTmp,nil,1,aP div 2 + 1,[fftw_preserve_input,fftw_measure]);
ffts[i,1,true]:= // Planung der Rücktransformationen über p
- fftw_plan_many_dft_c2r(1,@_aP,aX,fftTmp,nil,1,aP,impulsRaumGradient[i,1],nil,1,aP,[fftw_measure]);
+ fftw_plan_many_dft_c2r(1,@_aP,aX,fftTmp,nil,1,aP div 2 + 1,impulsRaumGradient[i,1],nil,1,aP,[fftw_measure]);
end;
- (*
+
+ pruefeArrayEnden('FFT schreibt beim Planen über das Ende hinaus!');
+
+ (*
fftw_plan_many_dft_r2c(int rank, const int *n, int howmany,
double *in, const int *inembed,
int istride, int idist,
@@ -729,6 +739,26 @@ begin
(impulsraum[tlc,false]+i+ort*aP)^:=(impulsraum[tlc,false]+i+ort*aP)^ * ges;
end;
+procedure tFelder.pruefeArrayEnden(fehler: string);
+var
+ i,j: longint;
+begin
+ if (abs(lFftTmp^.re-pi)>1e-10) or (abs(lFftTmp^.im-sqr(pi))>1e-10) then begin
+ gitter.prot.schreibe(fehler);
+ gitter.prot.schreibe(floattostr(lFftTmp^.re)+' vs. '+floattostr(pi)+' und '+floattostr(lFftTmp^.im)+' vs. '+floattostr(sqr(pi)));
+ gitter.prot.destroyall;
+ halt(1);
+ end;
+ for i:=0 to length(impulsRaumGradient)-1 do
+ for j:=0 to 1 do
+ if abs((impulsRaumGradient[i,j]+aP*aX)^-pi)>1e-10 then begin
+ gitter.prot.schreibe(fehler);
+ gitter.prot.schreibe(floattostr((impulsRaumGradient[i,j]+aP*aX)^)+' vs. '+floattostr(pi));
+ gitter.prot.destroyall;
+ halt(1);
+ end;
+end;
+
procedure tFelder.berechneAbleitungen;
var
i,j,k: longint;
@@ -829,26 +859,35 @@ begin
// Gradienten der Phasenraumbesetzungsdichte berechnen
+ pruefeArrayEnden('Jemand hat das FFT-Array überschrieben!');
+
for i:=0 to length(ffts)-1 do begin
- fftw_execute(ffts[i,0,false]);
- for j:=0 to aX-1 do
+ fftw_execute(ffts[i,0,false]); // FFT in x
+ pruefeArrayEnden('Vorwärts-FFT ('+inttostr(i)+',0) schreibt beim Ausführen über das Ende hinaus!');
+
+ for j:=0 to aX div 2 do
for k:=0 to aP-1 do begin // *i*k*2*pi;
- tmp:=(fftTmp+j+k*aX)^.re;
- (fftTmp+j+k*aX)^.re:=- 2*pi/dX/aX * j * (fftTmp+j+k*aX)^.im/aX;
- (fftTmp+j+k*aX)^.im:= 2*pi/dX/aX * j * tmp/aX;
+ tmp:=(fftTmp+j+k*(aX div 2 + 1))^.re;
+ (fftTmp+j+k*(aX div 2 + 1))^.re:=- 2*pi/dX/aX * j * (fftTmp+j+k*(aX div 2 + 1))^.im/aX * byte(2*j<ax);
+ (fftTmp+j+k*(aX div 2 + 1))^.im:= 2*pi/dX/aX * j * tmp/aX * byte(2*j<ax);
end;
fftw_execute(ffts[i,0,true]);
- fftw_execute(ffts[i,1,false]);
+ pruefeArrayEnden('Rückwärts-FFT ('+inttostr(i)+',0) schreibt beim Ausführen über das Ende hinaus!');
+
+ fftw_execute(ffts[i,1,false]); // FFT in p
+ pruefeArrayEnden('Vorwärts-FFT ('+inttostr(i)+',1) schreibt beim Ausführen über das Ende hinaus!');
for j:=0 to aX-1 do
- for k:=0 to aP-1 do begin // *i*k*2*pi;
+ for k:=0 to aP div 2 do begin // *i*k*2*pi;
tmp:=(fftTmp+j+k*aX)^.re;
- (fftTmp+j+k*aX)^.re:=- 2*pi/dP/aP * k * (fftTmp+j+k*aX)^.im/aP;
- (fftTmp+j+k*aX)^.im:= 2*pi/dP/aP * k * tmp/aP;
+ (fftTmp+j+k*aX)^.re:=- 2*pi/dP/aP * k * (fftTmp+j+k*aX)^.im/aP * byte(2*k < aP);
+ (fftTmp+j+k*aX)^.im:= 2*pi/dP/aP * k * tmp/aP * byte(2*k < aP);
end;
fftw_execute(ffts[i,1,true]);
+ pruefeArrayEnden('Rückwärts-FFT ('+inttostr(i)+',1) schreibt beim Ausführen über das Ende hinaus!');
+
end;
// Zeitableitung der Phasenraumbesetzungsdichte berechnen