<br />
<b>Warning</b>:  Undefined array key "HTTP_REFERER" in <b>/var/www/vhosts/web61970.ssd-space.de/phi.pf-control.de/uni/download.php</b> on line <b>13</b><br />
#include <iostream>
#include <cstdio>
#include <time.h>

#include <fstream> 
#include <sstream>
#include <vector>
#include <algorithm>

#include <stdlib.h> 
#include <cmath>

using namespace std;
 
/*Dieses Programm simuliert Teilchenkollisionen über Runge Kutta 4. Ordnung.
Dabei werden mehrere Teilchen mit definierter Masse zunächst in einem Gitter angeordnet und in den Grundzustand fallen gelassen.
Die so entstandene Datei kann wieder eingelesen werden, um die Teilchen weiter abklingen zu lassen oder
um die Teilchen 2 Mal einzufügen und aufeinander zu schießen.
Stoßparameter, Anfangsimpulse und Temperatur sind dabei anpassbar.
Ausgegeben wird der Endzustand der Teilchen bzw. Wahlweise eine Animation der Teilchenbewegung mit aktueller Uhrzeit als Datum.
Benötigt wird gnuplot und microsoft visual studio c++ 2010 express o.Ä.
*/
//Neue Blockgröße
int anzahl=4*4*4*2; //2 4*4*4-Blöcke aufeinander
int kantenlang=4; //Kantenlänge der Blöcke für neue Blöcke. pow(4*4*4,1/3.0) ist hier zu ungenau...
int	tstart=0; //nur proforma, braucht nicht geändert werden. Erweiterbar: falls zeitabhängigkeit in Rungekutta erwünscht!
long schritte=10000;//=>0.005ps
double tende=0.05,//ns
	inabst1=4.3, //Rasterabstand Angström Block1 (bei neuen Dateien)
	temp=300; //Temperatur (K) über Monte-Carlo (bis 10000K). Restliche Parameter
//restliche Parameter: Stoßparameter, Anfangsimpuls, Datei einlesen oder neue erzeugen siehe in letzter Routine "main"!

double const masse=0.0028;//28u, alle Teilchen gleiche Masse, 1u =1.036426866d-4 eV ps^2/A^2

//Parameter für Potential
const double a=5, 
	b=0.27, 
	sigma1=1.3, 
	sigma2=3.0, 
	gamma=10, //Reibung für Grundzustand
	kb=0.000086173324, //Boltzmann
	pi=3.14159265359,
	c=299792458;


//Zwischenvariabeln für Drehimpuls/Drehtransfos.
vector<double>mitte(3,0),drehimp(3,0),vektor(3,0),winkelg(3,0),l(anzahl*6,0),r0(anzahl*6,0),r01(anzahl*6,0),schwerp(3,0),winkelg1(3,0);
vector<vector<double>>traeg(3,vector<double>(3,0));
vector<vector<double>>temp1(3,vector<double>(4,0)),temp2(3,vector<double>(4,0));
double rw,phiw,thetaw;


//Berechnet Drehimpuls und Winkelgeschwindigkeit (über Gauß).
//Dadurch lässt sich der Grundzustand so drehen, dass die Abweichung leichter ablesbar wird.
void Drehimpuls(vector<double> &y){
	int i,j;

	for(i=0;i<anzahl;i++){ //Schwerpunkt
	  mitte[0] += y[6*i+1]/anzahl;
	  mitte[1] += y[6*i+2]/anzahl;
	  mitte[2] += y[6*i+3]/anzahl;
	}
	for(i=0;i<3;i++)
		std::cout<<"m:"<<mitte[i]<<" ";

	for(i=0;i<anzahl;i++){ //Relativkoordinaten zum Schwerpunkt
	  y[6*i] -=mitte[0];
	  y[6*i+1] -=mitte[1];
	  y[6*i+2] -=mitte[2];
	}
	for(i=0;i<anzahl;i++){ //Drehimpuls rel. z. SP.
	  drehimp[0] +=y[6*i+1]*y[6*i+5]-y[6*i+2]*y[6*i+4];
	  drehimp[1] +=y[6*i+2]*y[6*i+3]-y[6*i+0]*y[6*i+5];
	  drehimp[2] +=y[6*i+0]*y[6*i+4]-y[6*i+1]*y[6*i+3];
	}
	for(i=0;i<3;i++)
		std::cout<<"d:"<<drehimp[i]<<" ";

	for(i=0;i<anzahl;i++){ //Trägheitstensor
		traeg[0][0]+=masse*(pow(y[6*i+1],2)+pow(y[6*i+2],2));
		traeg[1][1]+=masse*(pow(y[6*i],2)+pow(y[6*i+2],2));
		traeg[2][2]+=masse*(pow(y[6*i],2)+pow(y[6*i+1],2));
		traeg[0][1]-=masse*y[6*i]*y[6*i+1];
		traeg[0][2]-=masse*y[6*i]*y[6*i+2];
		traeg[1][2]-=masse*y[6*i+1]*y[6*i+2];
	}
	traeg[1][0]=traeg[0][1];
	traeg[2][0]=traeg[0][2];
	traeg[2][1]=traeg[1][2];

	for(int i=0;i<3;i++){ //Gauß
		for(int j=0;j<3;j++){
			temp1[i][j] = traeg[i][j];
			temp1[i][3] = drehimp[i];
		}
	}
	temp2 = temp1;
	for(int i=0;i<4;i++){
		temp1[2][i]-=temp2[2][0]/temp2[1][0] *temp2[1][i];
		temp1[1][i]-=temp2[1][0]/temp2[0][0] *temp2[0][i];
	}
	temp2 = temp1;
	for(int i=0;i<4;i++){
		temp1[2][i]=temp2[2][i] -temp2[2][1]/temp2[1][1] *temp2[1][i];
	}

	//winkelgeschwindigkeit
	winkelg[2] = temp1[2][3]/temp1[2][2];
	winkelg[1] = (temp1[1][3]- winkelg[2]*temp1[1][2])/temp1[1][1];
	winkelg[0]= (temp1[0][3]- winkelg[2]*temp1[0][2]- winkelg[1]*temp1[0][1])/temp1[0][0];

	for(i=0;i<3;i++)
		std::cout<<"d:"<<drehimp[i]<<" ";

	//Bahndrehimpuls erhalten? 
	for(i=0;i<3;i++){
		for(j=0;j<3;j++){
			vektor[i]+=traeg[i][j]*winkelg[j];
		}}
}
void winkelanpassung(vector<double> &y){
	double energie;
	int i=0;
	for(i=0;i<anzahl;i++){
		energie +=(pow(y[6*i+3],2)+pow(y[6*i+4],2)+pow(y[6*i+5],2))/(2.0*masse);
	}
	double e0 = 3.0/2.0 *kb*temp; //Schwerpunktsimpuls
	cout<<(energie/(e0*anzahl));
	for(i=0;i<anzahl;i++){
		schwerp[0]+=y[6*i+3]/anzahl;
		schwerp[1]+=y[6*i+4]/anzahl;
		schwerp[2]+=y[6*i+5]/anzahl;
	}
	for(i=0;i<anzahl;i++){ //Transfo ins SP-impuls-System
		y[6*i+3]-=schwerp[0];
		y[6*i+4]-=schwerp[1];
		y[6*i+5]-=schwerp[2];
	}
	for(i=0;i<anzahl;i++){ //Massenmittelpunkt
		mitte[0]+=y[6*i]/anzahl;
		mitte[1]+=y[6*i+1]/anzahl;
		mitte[2]+=y[6*i+2]/anzahl;
	}
	for(i=0;i<anzahl;i++){//Relativkoordinaten!
		r0[6*i]-=mitte[0];
		r0[6*i+1]-=mitte[1];
		r0[6*i+2]-=mitte[2];
	}
	Drehimpuls(y);
	//Kugelkoordinaten d. Winkelgeschw.
	rw=sqrt(pow(winkelg[0],2)+pow(winkelg[1],2)+pow(winkelg[2],2));
	phiw=atan2(winkelg[1],winkelg[0]);
	thetaw=acos(winkelg[2]/rw);	

	//Drehmatrizen in entspr. Richtung
	vector<vector<double>>drehz(3,vector<double>(3,0));
	drehz[0][0]=cos(-phiw);
	drehz[0][1]=sin(-phiw);
	drehz[0][2]=0;
	drehz[1][0]=-sin(-phiw);
	drehz[1][1]=cos(-phiw);
	drehz[1][2]=0;
	drehz[2][0]=0;
	drehz[2][1]=0;
	drehz[2][2]=1;
	vector<vector<double>>drehy(3,vector<double>(3,0));
	drehy[0][0]=cos(-thetaw);
	drehy[0][1]=0;
	drehy[0][2]=-sin(-thetaw);
	drehy[1][0]=0;
	drehy[1][1]=1;
	drehy[1][2]=0;
	drehy[2][0]=sin(-thetaw);
	drehy[2][1]=0;
	drehy[2][2]=cos(-thetaw);
	
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			winkelg1[i]+=drehz[i][j]*winkelg[j];
	}}
	for(int i=0;i<3;i++)
		cout<<"winkelg1"<<winkelg1[i]; //Hier Test: x=y=0, z=w !

	winkelg = vector<double>(3,0);
	
	for(int i=0;i<3;i++){		
		for(int j=0;j<3;j++){
			winkelg[i]+=drehy[i][j]*winkelg1[j];
		}
	}
		
	for(int i=0;i<3;i++)
		cout<<"Winkelgeschwindigkeit transformiert"<<winkelg[i]<<endl;
	
	for(int i=0;i<anzahl;i++){		
		for(int j=0;j<3;j++){
			for(int k=0;k<3;k++){
				r01[6*i+j]+=drehz[j][k]*r0[6*i+k];
			}}}
	//Nun Transfo von y:
	r0 = vector<double>(anzahl*6,0);
	for(int i=0;i<anzahl;i++){		
		for(int j=0;j<3;j++){
			for(int k=0;k<3;k++){
				r0[6*i+j]+=drehy[j][k]*r01[6*i+k];
			}}}
	r01 = vector<double>(anzahl*6,0); 
	for(int i=0;i<anzahl;i++){		
		for(int j=0;j<3;j++){
			for(int k=0;k<3;k++){
				r01[6*i+j]+=drehz[j][k]*y[6*i+k];
				r01[6*i+j+3]+=drehz[j][k]*y[6*i+k+3];
			}}}
	y = vector<double>(anzahl*6,0);
	for(int i=0;i<anzahl;i++){		
		for(int j=0;j<3;j++){
			for(int k=0;k<3;k++){
				y[6*i+j]+=drehy[j][k]*r01[6*i+k];
				y[6*i+j+3]+=drehy[j][k]*r01[6*i+k+3];
			}}}
	//Kugelkoordinaten des Grundzustandes.
	//da w in r-Richtung: phi+=rw*(schritte/anzahl) !
	for(int i=0;i<anzahl;i++){		
		l[3*i] = sqrt(pow(r0[6*i],2) +pow(r0[6*i+1],2) +pow(r0[6*i+2],2));
		l[3*i+1] = atan2(r0[6*i+1],r0[6*i]);
		l[3*i+2] = acos(r0[6*i+2]/l[3*i]);
	}
}

//Maxwell Boltzmann Verteilung mit Monte Carlo Methode
void montecarlo(vector<double> &y){
	//vertmax: Funktion für Maxima der Verteilung (über Mathematica)
	double vertmax = 181.69723638904276- 49036.1596250/(temp*temp) + 
		12007.293973803038/temp - 0.2326018089098843 *temp +
 		0.00020143492718019792 *temp*temp - 9.889627385975435*pow(10.0,-8)*pow(temp,3)+
 		2.8465004602038517*pow(10.0,-11) *pow(temp,4) - 4.898019128141887*pow(10.0,-15) *pow(temp,5) + 
 		4.950284303906514*pow(10.0,-19) *pow(temp,6) - 2.7071514724946854*pow(10.0,-23) *pow(temp,7) + 
 		6.176463667836648*pow(10.0,-28) *pow(temp,8);				
	double betragmax = 0.0017642832638790238+ 0.0012577681693344063*sqrt(temp)+0.002; //Verteilung hätte hier 10^-5
	double betrag,test,vert,theta,phi;
	srand(time(NULL));
	int j=0;
	for(int i=0;i<anzahl;i++){
		for(j=0;j<2000000;j++){
			vert = ((double)rand()/RAND_MAX)*vertmax;	//zufällige maxwell-boltzmann  // rand()/RAND_MAX generiert eine Zufallszahl aus dem Intervall (0,1]
			theta = pi*((double)rand()/RAND_MAX);
			phi = 2*pi*((double)rand()/RAND_MAX);
			betrag = betragmax*((double)rand()/RAND_MAX);
			test = betrag*betrag/(2*masse*kb*temp);
			if(test<=397 && !(vert>pow(2*kb*temp*masse*pi,-3/2) *4*pi*betrag*betrag*exp(-test))){
				break;
			}
		}
		if(j==2000000){cout<<"Mehr als 2d6 Überschreitungen!";}
		y[6*i+3] = betrag*sin(theta)*cos(phi);	
		y[6*i+4] = betrag*sin(theta)*sin(phi);
		y[6*i+5] = betrag*cos(theta);
	}
}

//Runge Kutta Algorithmus 4. Dimension übernommen aus numerical recipies, jedoch angepasst auf double und vector.
void rk4(vector<double> y, vector<double> dydx, double n, double x, double h, vector<double> &yout,
void (*derivs)(double, vector<double>,  vector<double>&)){ //derives sit Gleichungssystem
	int i;
	double xh,hh,h6;
	vector<double> dym(n,1);      
	vector<double> dyt(n,1);      
	vector<double> yt(n,1);      
	hh=h*0.5;
	h6=h/6.0;
	xh=x+hh; 
	for (i=0;i<n;i++) yt[i]=y[i]+hh*dydx[i]; //dydx=k1
	(*derivs)(xh,yt,dyt);					 //dyt=k2
	for (i=0;i<n;i++) yt[i]=y[i]+hh*dyt[i];
	(*derivs)(xh,yt,dym);					 //dym=k3
	for (i=0;i<n;i++) {
		yt[i]=y[i]+h*dym[i];
		dym[i] += dyt[i];					 //dym=k2+k3
	}
	(*derivs)(x+h,yt,dyt);					 //dyt=k4
	for (i=0;i<n;i++)
		yout[i]=y[i]+h6*(dydx[i]+dyt[i]+2.0*dym[i]); //ausgabe= y+ h/6 *(k1+k4+2(k2+k3))
	dym.clear();
	dyt.clear();
	yt.clear();
	
}

//Aufruf/Schnittstelle zu Runge Kutta. Hier wird auch E-Erhaltung überprüft etc.
void rkdumb(vector<double> vstart, double nvar, double x1, double x2, double nstep,vector<vector<double> > &yy,vector<double> &xx,
void (*derivs)(double, vector<double>,vector<double>&))
{
	int i,k;
	double x,h,betr;
	vector<double> v(nvar,1); //v ist im jeweiligen Schritt der aktuelle Satz an Orts/Impulskoordinaten  
	vector<double> vout(nvar,1);      
	vector<double> dv(nvar,1);      
	for (i=0;i<nvar;i++) { //Load starting values.
		v[i]=vstart[i];
		yy[i][0]=v[i]; //y speichert alle Werte jedes Schrittes ab. 0. Schritt sollen Startwerte sein.
	}
	xx[0]=x1; //Zeit. Wird nicht weiter benutzt, aber zur Erweiterung des Runge Kutta mit zeitabhängigen Potential benutzbar
	x=x1;
	h=(x2-x1)/nstep;
	cout<<"\r000%"; //Fortschritt anzeigen.
	double kngesenergie,pngesenergie; //aktuelle kin und pot energie
	double gesenergie=0; //anfängliche energie
	for (k=0;k<nstep;k++) { //Take nstep steps.
		(*derivs)(x,v,dv); 
		rk4(v,dv,nvar,x,h,vout,derivs); //Runge Kutta anwenden. derivs definiert wirkende Potentiale, v ist Ausgabe
		x += h;
		xx[k+1]=x; //Store intermediate steps.

		for (i=0;i<nvar;i++) {
			v[i]=vout[i];
			yy[i][k+1]=v[i]; //Lösung aktuellen Schritt abspeichern.
		}
		//Korrektur Drehimpuls
		for(int j=0;j<anzahl;j++)
			l[3*j+1] += rw*(tende/schritte);
		for(int j=0;j<anzahl;j++){ //in karth. Koord.
			r0[6*j+0] = l[3*j]*sin(l[3*j+2])*cos(l[3*j+1]);
			r0[6*j+1] = l[3*j]*sin(l[3*j+2])*sin(l[3*j+1]);
			r0[6*j+2] = l[3*j]*cos(l[3*j+2]);
		}
		
		//Test ob SP-Impuls=0.
		schwerp = vector<double>(3,0);		
		for(int j=0;j<anzahl;j++){
			schwerp[0]+=v[6*j+3];
			schwerp[1]+=v[6*j+4];
			schwerp[2]+=v[6*j+5];
		}
		
		//Alle 100 Schritte überprüfen...
		if(k%100==1 && (schwerp[0]+schwerp[1]+schwerp[2])/anzahl<0.000001)cout<<"sp weg\n";
		drehimp = vector<double>(3,0);
		for(int j=0;j<anzahl;j++){
			drehimp[0]+=v[6*j+1]*v[6*j+5]-v[6*j+2]*v[6*j+4];
			drehimp[1]+=v[6*j+2]*v[6*j+3]-v[6*j]*v[6*j+5];
			drehimp[2]+=v[6*j]*v[6*j+4]-v[6*j+1]*v[6*j+3];
		}
		//Test ob Dreh-Impuls=0.
		//Alle 100 Schritte überprüfen...
		if(k%100==1&&(drehimp[0]+drehimp[1]+drehimp[2])/anzahl<0.000001)cout<<"dp weg\n";
		
		pngesenergie=0;//potentielle Energie
		kngesenergie=0;//kinetische Energie
		for(int i=0;i<anzahl-1;i++){	
				for(int j=i+1;j<anzahl;j++){
				betr=sqrt(pow(v[i*6]-v[j*6],2)+pow(v[i*6+1]-v[j*6+1],2)+pow(v[i*6+2]-v[j*6+2],2));
				pngesenergie+=a*exp(-0.5*pow(betr/sigma1,2)) - b*exp(-0.5*pow(betr/sigma2,2));//potentielle Energie
			}
			kngesenergie+=(pow(v[6*i+3],2)+pow(v[6*i+4],2)+pow(v[6*i+5],2))/(2.0*masse);//kinetische Energie
		}
		kngesenergie+=(pow(v[6*(anzahl-1)+3],2)+pow(v[6*(anzahl-1)+4],2)+pow(v[6*(anzahl-1)+5],2))/(2.0*masse);//kinetische Energie

		//Energieerhaltung überprüfen.
		//Immer ausgeben: kin und pot.
		if(gesenergie==0)gesenergie=kngesenergie+pngesenergie;
		if(k%100==1)cout<<"          k"<<kngesenergie<<" - p"<<pngesenergie; 
		if(k%100==1&&abs(kngesenergie+pngesenergie)<abs(gesenergie*0.9))
			cout<<"\nEnergieerhaltung verletzt: Schrittweite verringern: "<<kngesenergie+pngesenergie<<" - "<<gesenergie; 
		if(k%100==1&&abs(kngesenergie+pngesenergie)>abs(gesenergie*1.1))
			cout<<"\nEnergieerhaltung verletzt: Schrittweite verringern: "<<kngesenergie+pngesenergie<<" - "<<gesenergie; 
			
		if(k%100==1)cout<<"\r    "<<"\r"<<(k/nstep)*100<<"%"; //Fortschritt anzeigen.
		}
	v.clear();vout.clear();dv.clear();
	cout<<"\r     "<<"\r100%\n";
}

//Potential definieren
void myderiv(double x, vector<double> y, vector<double> &dxdy){
	double betr=0;
	double temp=0;

	for(int i=0;i<anzahl;i++){
		dxdy[i*6] = y[6*i+3]/masse; //dx/dt = p/m
		dxdy[i*6+1] = y[6*i+4]/masse;
		dxdy[i*6+2] = y[6*i+5]/masse;

		for(int j=i+1;j<anzahl;j++){
			betr=sqrt(pow(y[i*6]-y[j*6],2)+pow(y[i*6+1]-y[j*6+1],2)+pow(y[i*6+2]-y[j*6+2],2)); //Abstand Teilchen voneinander
			
			//dp/dt= F
			temp=a/(sigma1*sigma1)*exp(-0.5/(sigma1*sigma1)*betr*betr)-b/(sigma2*sigma2) *exp(-0.5/(sigma2*sigma2)*(betr)*(betr)); 

			dxdy[i*6+3]+=temp*(y[6*i]-y[6*j]);
			dxdy[i*6+4]+=temp*(y[6*i+1]-y[6*j+1]);
			dxdy[i*6+5]+=temp*(y[6*i+2]-y[6*j+2]);
			dxdy[j*6+3]-=temp*(y[6*i]-y[6*j]);
			dxdy[j*6+4]-=temp*(y[6*i+1]-y[6*j+1]);
			dxdy[j*6+5]-=temp*(y[6*i+2]-y[6*j+2]);
		}

		/*dxdy[i*6+3] -= gamma*y[6*i+3]; //Reibung, für Grundzustand
		dxdy[i*6+4] -= gamma*y[6*i+4];
		dxdy[i*6+5] -= gamma*y[6*i+5];*/
	}	
} 
//string to double
template<class T> T fromString(const std::string& s) 
{
     std::istringstream stream (s);
     T t;
     stream >> t;
     return t;
}
//aktuelle Uhrzeit für Dateiausgabe von Animationen
char* currentDateTime() {
    time_t     now = time(0);
    struct tm  tstruct;
    char       buf[80];
    tstruct = *localtime(&now);
    strftime(buf, sizeof(buf), "%Y_%m_%d_%H_%M", &tstruct);

    return buf;
}
int main(){ 
	cout<<"hello!"<<endl;  //Begrüßung
	vector<double>t(schritte+1,0); //Zeitschritte, hier nicht benutzt, aber möglich für Zeitabhängigkeit
	ifstream readfile;
	vector<double>y(anzahl*6,0); //die Teilchen!
	vector<double>y1(anzahl/2*6,0); //doppeltes einlesen vom Grundzustand sodass Teilchen gegeneinander geschossen werden können
	//x1 y1 z1 px1 py1 pz1 , x0 y0 z0 px0 py0 pz0
	
	//Dieser Bereich belegt ein Gitter der Kantenlänge "kantenlang" im Abstand von inabst1 mit Teilchen.
	/*
	for(int i=0;i<anzahl;i++){
		y[i*6]=inabst1*(i%kantenlang);//+ausabst/2;		//Gitter, inabst1 A° Abstand intern, ausabst A° Abstand von anderen Gitter
		y[i*6+1]=inabst1*((i/kantenlang)%kantenlang);	
		y[i*6+2]=inabst1*((i/(kantenlang*kantenlang))%kantenlang);
		//px= A° eV/ns =0.1 eV * m/s = 3.3356*10^-10 eV/c 
	}*/


	//Dieser Bereich lädt die datei grundzustand2.temp.
	//das Format ist dabei 
	/*
	x
	y
	z
	px
	py
	pz
	x
	...
	*/
	//geladen wird in y1, sodass die Daten 2 mal mit Abstand und gespiegelt eingefügt werden können
	readfile.open("grundzustand2.temp");	
	std::string line;
	int z=0;
	for(int i=0;i<anzahl*6/2;i++){
		getline(readfile,line);
		y1[i]=fromString<double>(line);
	}
	readfile.close();
	
	//Wie vorheriger Bereich, Unterschied: hier werden Daten direkt eingelesen
	//Reichen die bisherigen Schritte/Zeit nicht aus, kann hier alles erneut geladen und weiter gerechnet werden
	
	/*readfile.open("endzustand.temp");	
	std::string line;
	int z=0;
	for(int i=0;i<anzahl*6;i++){
		getline(readfile,line);
		y[i]=fromString<double>(line);
	}
	readfile.close();*/

	//Test für das erstellen von 2 Gittern, die man aufeinander schießen könnte
	//Achtung: keine Grundzustände hier!
	/*
	for(int i=0;i<anzahl/2;i++){
		y1[i*6]=inabst1*(i%kantenlang);//+ausabst/2;		//Gitter, inabst1 A° Abstand intern, ausabst A° Abstand von anderen Gitter
		y1[i*6+1]=inabst1*((i/kantenlang)%kantenlang);	
		y1[i*6+2]=inabst1*((i/(kantenlang*kantenlang))%kantenlang);
	}
	for(int i=anzahl/2;i<anzahl;i++){
		y[i*6]=inabst2*(i%kantenlang)-ausabst/2;		//gitter, inabst2 a° abstand intern, ausabst a° abstand von anderen gitter
		y[i*6+1]=inabst2*((i/kantenlang)%kantenlang);	
		y[i*6+2]=inabst2*((i/(kantenlang*kantenlang))%kantenlang);
		y[i*6+3]=50;
	}
	*/

	anzahl/=2; // verechnen eines Blockes dieser wird dann verschoben 2 mal eingefügt zur Kollision.
	r0=y1;	
	montecarlo(y1);//Verteilen der Impulse des Grundzustandes
	winkelanpassung(y1);//Schwerpunktsystem und Drehimpulse

	//2 mal einfügen von einem Paket
	for(int i=0;i<anzahl*6;i++){ //Achtung: hier ist anzahl noch halbiert!
		y[i]=y1[i]; //1. Block einfügen
		if(i%6==1) //
			y[i+anzahl*6]=-y1[i];//2. Block an y-Achse spiegeln
		else 
			y[i+anzahl*6]=y1[i]; //ansonsten 2. Block wie erster Block

		if(i%6==4){y[i]+=0.5;y[i+anzahl*6]-=0.5;}//y-impuls (A° eV/ns ~ 0.1 eV * m/s ~ 3.3356*10^-10 eV/c)
		if(i%6==1){y[i]-=20;y[i+anzahl*6]+=20;}//y-achse => abstand
		if(i%6==0){y[i]+=15;}//x-achse => stoßparam
	}
	anzahl*=2; //tatsächliche Anzahl wieder herstellen

	vector<vector<double> > yy(anzahl*6,vector<double>(schritte+1,0)); //Ergebnis: y[index][schritt]
	vector<double>dxdy(anzahl*6,0);
	vector<double>tout(anzahl*6,0);
	
	//Runge Kutta-Schnittstelle
	rkdumb(y,anzahl*6,tstart,tende,schritte,yy,t,myderiv); 

	wofstream file;	
	file.open("endzustand.temp");	//Ausgabe-Datei des letzten Schrittes! jede Zeile eine Zahl: x y z px py pz x ...
	for(int i=0;i<anzahl*6;i++){		
		file<<yy[i][schritte-1]<<endl;
	}
	file.close();

	//zwecks Testzwecken: Zustand am Anfang wie endzustand in Datei ausgeben.
	file.open("anfangszustand.temp"); 
	for(int i=0;i<anzahl*6;i++){	
		file<<yy[i][0]<<endl;
	}
	file.close();
	
	//Plot-Datei für gnuplot!

	file.open("bewegung.temp");	 	

	//Dieser Bereich erstellt Trajektorien aller Teilchen. 
	//Grundsätzlich sinnvoll, aber nicht flüssig rotierbar und leicht unübersichtlich

	/*file<<"unset key\nsplot '-' with lines";
	for(int j=0;j<anzahl-1;j++){
		file<<", '-' with lines";
	}
	file<<"\n";
	for(int i=0;i<anzahl;i++){		
		for(int j=0;j<schritte;j+=25){
			file<<yy[i*6][j]<<" "<<yy[i*6+1][j]<<" "<<yy[i*6+2][j]<<"\n";
		}
		file<<"e\n";
	}
	*/

	//animierte gif-Datei der Teilchen ausgeben. Ergebnis wird nicht angezeigt!
	//Achtung: warte bis zum Beenden aufgefordert wird!
	
	file<<"unset key\nset term gif animate\nset output \"animate_"<<currentDateTime()<<".gif\"\n";
	
	//direkte ausgabe auf dem Bildschirm. schwer zu exportieren. 
	//über den Befehl unten in system() lässt sich bewegung.temp aber erneut aufrufen.
	
	//file<<"unset key\n";
	
	for(int j=0;j<schritte;j+=schritte/500){
		file<<"splot '-' w p ls 1";
		for(int i=0;i<anzahl-1;i++){
			file<<", '-' w p ls "<<i+2;
		}
		file<<"\n";
		for(int i=0;i<anzahl;i++){		
			file<<yy[i*6][j]<<" "<<yy[i*6+1][j]<<" "<<yy[i*6+2][j]<<"\n";
			file<<"e\n";
		}
		//für direkte Ausgabe: Zeit in Sekunden zwischen den Plots.
		//in gif-Animation wird immer 100ms benutzt.
		//file<<"pause 0.05\n";
	}
	
	file.close();
	
	//für direkte Ausgabe
	//system("wgnuplot bewegung.temp -persistent");

	//für Animation
	system("wgnuplot bewegung.temp");

	system("pause");
}
