⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ptclgrp.cpp

📁 pic 模拟程序!面向对象
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*====================================================================File:		ptclgrp.cppPurpose:	Implementation of a ParticleGroup.Version:	$Id: ptclgrp.cpp,v 1.32 2005/07/27 11:47:16 rmtrines Exp $Revision History0.99	(JohnV 01-07-94) Separate from pic.h.0.991	(JohnV 03-23-94) Streamline includes, remove pic.h.0.992	(JohnV, KC 05-02-94) Fix Brilloiun beam problem (was neglecting      centrifugal force).0.993	(JohnV 09-13-94) Add variable np2c support.0.994 (PeterM 09-04-95) Added a method to reduce #particles, increase      the weight of particles.2.001 (JohnV 11-10) Improve increaseWeight(), handle odd n. 2.02  (JohnV 12-12-97) Modified increaseParticleWeight() to retain temporal      order of particles within groups -> handles default.inp properly.2.03  (KC 1-9)  Added Kinetic Energy diagnostic to advance.2.04  (Bruhwiler 9/29/99) set bool synchRadiationOn=FALSE in constructor2.05  (Bruhwiler 11/08/99) now moving window only checks for particles      leaving the left boundary of the simulation2.0?  (Cary 23 Jan 99) Noted in a comment that this coding is only for	right moving windows.CVS-1.16.2.20 (JohnV 15 Mar 00) Fixed bug in np2cFactor (getting ignored)2.1   (JohnV 10Jul2003) fixed recomputation of gamma before x update====================================================================*/#include "ptclgrp.h"#include "particle.h"#include "fields.h"#include "dump.h"#include <txc_streams.h>using namespace std;ParticleGroup::ParticleGroup(int _maxN, Species* s, Scalar _np2c0, 	BOOL vary_np2c){	maxN = _maxN;	if (vary_np2c)		qArray = new Scalar[maxN];	else qArray = 0;		np2c0 = _np2c0;	species = s;	q_over_m = species->get_q_over_m();	q = np2c0*species->get_q();//	speciesSub = species->get_speciesSub();	x = new Vector2[maxN];	u = new Vector3[maxN];	n = 0;   synchRadiationOn = FALSE;  // by default, synchrotron radiation is off}ParticleGroup::~ParticleGroup(){	n = maxN = 0;								// deallocate memory	delete[] x;	delete[] u;	if (qArray)	  delete[] qArray;}//--------------------------------------------------------------------//	This add uses nominal np2c0, q, q_over_mBOOL ParticleGroup::addMKS(Vector2 _x, Vector3 _v){	if (n < maxN)	{		x[n] = _x;		Vector3	beta = iSPEED_OF_LIGHT*_v;		u[n] = _v/sqrt(1 - beta*beta);	//	u = gamma*v		if (qArray) qArray[n] = q;		n++;		return TRUE;	}	return FALSE;}//--------------------------------------------------------------------//	Add a group of particles.  Not well tested yet.BOOL ParticleGroup::add(ParticleGroup& p){	if (p.q_over_m == q_over_m && p.np2c0 == np2c0)		while (--p.n >= 0)		{		  if (p.qArray){			 if (!add(x[p.n], u[p.n], p.get_np2c(p.n)))				break;		  }		  else if (p.get_q(p.n) == q){			 if (!add(x[p.n], u[p.n]))	//	did add fail?				break;						//	bail out		  }		}	p.n++;										//	restore proper value	if (p.n) return FALSE;	else return TRUE;     					//	caller responsible for destructor?}//-------------------------------------------------------------------// duplicates particles in group N times, dividing the particle weight appropriately/*ParticleGroup**     ParticleGroup::duplicateParticles(int N){  int i, j, ntemp;  BOOL varweight;  Vector2 xN;  Vector3 uN;  Scalar np2cfactor;  Scalar Nfactor;  ParticleGroup **pg;  ParticleGroup *p;  if(N < 1) { return NULL; }  Nfactor = 1.0/((Scalar)(N+1));  ntemp = n;  varweight = isVariableWeight();  //  fprintf(stderr,   //	  "\nduplicateParticles %d times, Nfactor=%g\n", N, Nfactor);  //  cerr << "\nVariable weight: " << varweight << ", np2c0 =" << np2c0;  pg = new ParticleGroup*[N];  if(ntemp > 0)    {      if(varweight)	{	  np2cfactor = np2c0;	}      else	{	  np2cfactor = np2c0*Nfactor;	}    }  else    {      return NULL;    }  //  fprintf(stderr, "\nnp2cfactor=%g", np2cfactor);  for(i=0; i < N; i++)    {      pg[i] = new ParticleGroup(maxN, species, np2cfactor, isVariableWeight());    }    for(j=0; j < ntemp; j++)    {      xN = x[j];      uN = u[j];      np2cfactor = get_np2c(j)*Nfactor;      if(varweight) 	{ 	  qArray[j] = q*np2cfactor/np2c0;	}            for(i=0; i < N; i++)	{	  p = pg[i];	  if(varweight)	    {	      if(!p->add(xN, uN, np2cfactor)) 		{ 		  fprintf(stderr, "\nduplicateParticles: error adding particles");		  return NULL; 		}	    }	  else	    {	      if(!p->add(xN, uN, -1.)) 		{ 		  fprintf(stderr, "\nduplicateParticles: error adding particles");		  return NULL; 		}	    }	  	}    }  if(!varweight)    {      np2c0 *= Nfactor;      q = np2c0*species->get_q();      //      fprintf(stderr, "\nSetting base particle weight to %g\n", np2c0);    }  return pg;}*/ParticleGroup**     ParticleGroup::duplicateParticles(int N){  int i, j, ntemp;  BOOL varweight;  Vector2 xN;  Vector3 uN;  Scalar np2cfactor;  Scalar Nfactor;  ParticleGroup **pg;  ParticleGroup *p;  if(N < 1) { return NULL; }  Nfactor = 1.0/((Scalar)(N+1));  ntemp = n;  varweight = isVariableWeight();  //  fprintf(stderr,   //	  "\nduplicateParticles %d times, Nfactor=%g\n", N, Nfactor);  //  cerr << "\nVariable weight: " << varweight << ", np2c0 =" << np2c0;  pg = new ParticleGroup*[N];  if(ntemp > 0)    {      np2cfactor = np2c0;    }  else    {      return NULL;    }  //  fprintf(stderr, "\nnp2cfactor=%g", np2cfactor);  for(i=0; i < N; i++)    {      pg[i] = new ParticleGroup(maxN, species, np2cfactor, isVariableWeight());    }    for(j=0; j < ntemp; j++)    {      xN = x[j];      uN = u[j];      np2cfactor = get_np2c(j);      if(varweight) 	{ 	  qArray[j] = q*np2cfactor/np2c0;	}      else	{	  np2cfactor = -1.;	}            for(i=0; i < N; i++)	{	  p = pg[i];	  if(!p->add(xN, uN, -1.)) 	    { 	      fprintf(stderr, "\nduplicateParticles: error adding particles");	      return NULL; 	    }	}    }  return pg;}//--------------------------------------------------------------------//	Add a new particle to this group, possibly of variable weight.//	Note that uNew is gamma*v, and xNew is in grid coords.BOOL ParticleGroup::add(const Vector2& xNew, const Vector3& uNew, Scalar np2cNew){	if (n < maxN)	{		if (np2cNew > 0)			if (qArray)	qArray[n] = q*np2cNew/np2c0;			else return FALSE;		x[n] = xNew;		u[n] = uNew;		n++;		return TRUE;	}	return FALSE;}//--------------------------------------------------------------------//	Add a Particle to this group.BOOL ParticleGroup::add(Particle* p){//	if (p->get_q_over_m() == q_over_m)	if (p->get_speciesID() == get_speciesID() && n < maxN)		if (qArray && p->isVariableWeight())			//		if (qArray)			return add(p->get_x(), p->get_u(), p->get_np2c());		else if (p->get_np2c() == np2c0)			return add(p->get_x(), p->get_u());	return FALSE;}//// we need to be able to remove particles from the particle group (in the// tunneling ionization of multi electron atoms). Note the implementation// of this function: a particle with index particleIndex is deleted and// the last particle in the group is placed at its index.    // Returns TRUE if the particle group becomes empty (at deletion of // the last particle in the group), otherwise it resturns FALSE. dad 06/29/01.//BOOL ParticleGroup::remove(int particleIndex) {  //  // is particleIndex in the allowable range  //   if ( particleIndex < 0 || particleIndex > (n-1) ) {    cerr << endl << endl << endl         << "An out of range particleIndex = " << particleIndex << endl         << "passed to BOOL ParticleGroup::remove(int particleIndex)." << endl         << "This index must be in [0, " << n-1 << "]" << endl         << "Exiting to the system..." << endl << endl << endl;  }    if ( n == 1 ) {    //     // we are deleting the only macroparticle in the group    // => return false to prompt the deletion of the group    //     n--;    return TRUE;  } else if ( particleIndex == (n-1) ) {    //    // deleting the last macroparticle in a group with more    // than one macroparticles => need only to decrement the    // number of macroparticles in the group    //      n--;    return FALSE;  } else {    //     // deleting any other particle but the last one    //     x[particleIndex] = x[n-1];    u[particleIndex] = u[n-1];    if ( qArray )       qArray[particleIndex] = qArray[n-1];    n--;    return FALSE;  } }//--------------------------------------------------------------------//	Advance particle equations of motion one timestep.  This includes//	weighting fields to the particle, solving the equation of motion,//	and accumulating the particle current on the grid.  Boris mover//	with u = gamma*v, v in MKS units; see B&L for variables.void ParticleGroup::advance(Fields& fields, Scalar dt){	Scalar	f = 0.5*dt*q_over_m;	Scalar	q_dt = q/dt;	Vector3	uPrime;	Vector3	a;	Vector3	t;	Vector3	s;	Vector2*	x = ParticleGroup::x;	Vector3*	u = ParticleGroup::u;	Vector3	dxMKS;	Boundary*	bPtr;	Grid&	grid = *fields.get_grid();	Scalar igamma;	Scalar localEnergy = 0;	for (int i=0; i<n; i++, x++, u++)	{		if (qArray) q_dt = qArray[i]/dt;	//	variable weighted particles		a = f*fields.E(*x);//		*u += a; // half acceleration		igamma = 1/ParticleGroup::gamma(*u);		t = (f*igamma)*fields.B(*x);		uPrime = *u + u->cross(t);		s = 2*t/(1 + t*t);		*u += uPrime.cross(s); // rotation		*u += a; // half acceleration		igamma = 1/ParticleGroup::gamma(*u); // must recompute gamma		dxMKS = grid.differentialMove(fields.getMKS(*x), *u*igamma, *u, dt);		if ((bPtr = fields.translateAccumulate(*x, dxMKS, q_dt)))		{			//	send this particle to boundary			bPtr->collect(*(new Particle(*x, *u, species, get_np2c(i),				(BOOL)(qArray!=0))), dxMKS);			//	Move last particle into this slot and advance it.			n--;			if (i == n) break;				//	last particle in array?			*x = ParticleGroup::x[n];		//	move last particle into open slot			*u = ParticleGroup::u[n];			if (qArray) qArray[i] = qArray[n];			i--;									//	Set index to do i again.			x--;									//	Setup to redo the array element			u--;                          // it gets inc in for loop		}		else{			if (qArray)				localEnergy += qArray[i]*(1/igamma-1);			else				localEnergy += 1/igamma-1;		}#ifdef DEBUG		if(strncmp(HOSTTYPE, "alpha", 5) != 0)		  {		    if(((*x).e1()==grid.getJ() || (*x).e1()==0 || (*x).e2()==grid.getK()			|| (*x).e2()==0)&&!bPtr) {		      printf("Particle escaped.\n");		      int *crash = 0;			      *crash = 10;		    }		  }#endif //DEBUG	}	if (qArray)		species->addKineticEnergy(SPEED_OF_LIGHT_SQ*localEnergy/q_over_m);	else		species->addKineticEnergy(SPEED_OF_LIGHT_SQ*localEnergy*get_m());}// this function combs the particles, doubling weights// and killing every second particle. Note that the particles must// remain time-ordered so that multiple packings do not leave gaps.void ParticleGroup::increaseParticleWeight(){	int new_n = (int) (n*0.5 + frand()); // keep odd particles 50% time	Scalar ratio = 2; // = ((Scalar) n)/new_n;	if (qArray) qArray[0] *= ratio;	for (int i = 1; i < new_n; i++)	{		x[i]=x[2*i];		u[i]=u[2*i];		if(qArray) qArray[i] = qArray[2*i]*ratio;	}	n = new_n;	// halve the num of particles	np2c0 *= ratio;	// double the weights	q *= ratio;		// double the charge}void ParticleGroup::fill(int index){	n--;	if (index == n) return;				//	last particle in array?	x[index] = x[n];		//	move last particle into open slot	u[index] = u[n];	if (qArray) qArray[index] = qArray[n];}#ifdef HAVE_HDF5int ParticleGroup::dumpH5(dumpHDF5 &dumpObj, Grid *grid,string groupName) {  //cerr << "entering ptclgrp::dumpH5(dumpObj)\n";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -