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

📄 sptlrgn.cpp

📁 pic 模拟程序!面向对象
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*====================================================================SPTLRGN.CPPPurpose:	functions of the SpatialRegion class.  The SpatialRegion		is the fundamental building block of the PlasmaDevice to be		simulated.Revision/Author/Date0.1	(JohnV, 03-15-93)	Proto code.0.9	(JohnV, 04-30-93)	Initial draft with particles.0.91	(NTG, JohnV, 05-05-93) Add EmittingBoundary, ActiveBoundary, class		library use for list management and iterators, KinematicalObject.0.93	(JohnV, NTG 05-12-93) Fix Windows large model Gen. Prot. Fault due		to reading outside arrays.0.95	(JohnV, 06-29-93) Add Boundary::setPassives() to set up passive		boundary conditions (Fields::iC and ::iL), add Fields::set_iCx()		to support above.0.96	(JohnV 08-23-93) Add new Boundary subtypes: BeamEmitter,		CylindricalAxis, FieldEmitter, Port.  Modifications to		Maxwellian: stores all parameters in MKS.0.961	(PeterM, JohnV, 08-24-93) Replace Borland list containers with		vanilla C++ template lists in oopiclist.h0.963	(JohnV, 09-24-93)	Add Particle object for moving particle quantities		around (emission, collection, etc.)0.964	(JohnV, 11-22-93) Make agreed-upon changes in names: Vector->Vector3,		Boundaries->BoundaryList, Particles->ParticleList, ParticleGroups		->ParticleGroupList0.965	(JohnV, 02-01-94) Move magnetic field advance to Fields::advanceB(),		move boundary code, particle code to respective files.0.966	(JohnV, 02-07-94)	Fixed striation in vr vs. z phase space seen		for beam spreading in a simple cylinder.  Problem was weighting		error in Grid::interpolateBilinear().0.967	(JohnV 03-03-94) added Fields::setBz0() and ::epsilonR.0.968	(JohnV 03-11-94) Fix divide by zero for non-translating particles		with finite spin in Fields::translateAccumulate().  Also ensure all		particles that touch boundaries get collected in Grid::translate()		by changing </> to <=/>= for check conditions.0.969	(JohnV 03-23-94) Restructure Grid, Fields, and SpatialRegion to		an association rather than inheritance.0.970	(GMU 11-16-94) Added TaskYield() call.0.971 (JohnV 01-26-95) Add code to handle ParticleGroup array and Species.0.98  (KeithC 08-25-95) Lack of precision caused Bz0 to 'leak` into Etheta       and Br.  Added BNodeStatic to separate the Static part from the B		fields that that Fields  updates.  Changed Fields::setBz0() to 		Fields::setBNodeStatic.0.981 (PeterM 09-04-95) Added a method to reduce #particles, increase      the weight of particles.1.0	(JohnV 01-18-96) Added subcycling stuff from CooperD; rewrote advance().1.1   (JohnV 01-21-97) Added supercycling.1.11  (JohnV 10-01-97) Improved supercycling to work with mcc package.2.01  (JohnV 11-10-97) CountParticles() deletes empty ParticleGroup's.2.02  (JohnV 12-12-97) Modified increaseParticleWeight().2.03  (JohnV 03-31-98) Implement caching scheme for nParticles2.04  (Bruhwiler 10-08-99) Added getSynchRadiationFlag() check to addParticleList()2.0?  (Cary 22 Jan 00) Added methods for setting the shift delay time and	streamlined the shifting code.CVS-1.53.2.7 (Cary, 22 Jan 00) reorganized calls for shifting in	anticipation of making MPI work.CVS-1.53.2.8 (Cary, 22 Jan 00) Added code to determine which boundary is	involved.  The if is a SPATIAL_REGION_BOUNDARY, call passParticles().	Similar coding needed for receiving the shifted particles and fields.	I am not sure that this works except for right and down shifting	windows.CVS-1.53.2.12 (Cary 27 Jan 00) ShiftRegion changed to shiftRegion.CVS-1.53.2.13 (kgl  28 Jan 00) xgmini.h is not needed, only theDumpFile decl.)CVS-1.53.2.14 (JohnV 15 Mar 00) Fixed bug in np2cFactor (getting ignored)CVS-1.57      (kgl  4  Aug 00) dropfile size (50) is too small, increased                               to 80.  Caused coredump for long dir.                               Changed to 180 by kgl and dad to accomodate                               long file names. 04/08/02.====================================================================*///I/O stuff#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <txc_streams.h>using namespace std;// Standard includes#include <cassert>// MPI stuff#ifdef MPI_VERSION#include <unistd.h>#include <mpi.h>extern int MPI_RANK;#ifdef MPI_DEBUGextern std::ofstream dfout;#endif  // MPI_DEBUG#endif  // MPI_VERSION#include "sptlrgn.h"#include "ptclgrp.h"#include "ptclgpes.h"#include "ptclgpsr.h"#include "ptclgpnr.h"#include "ptclgpib.h"#include "mcc.h"#include "periodic.h"#include "load.h"// #include "xgmini.h"#ifdef OOPICPRO#if defined(_MSC_VER)extern "C" char theDumpFile[180];#elseextern char theDumpFile[180];#endif#else#if defined(_MSC_VER)extern "C" char* const volatile theDumpFile;#elseextern char* const volatile theDumpFile;#endif#endif// for dumping diagnostics#include "diagn.h"extern oopicList<Diagnostics> *theDiagnostics;//--------------------------------------------------------------------//	Build SpatialRegion, along with inherited Fields objectextern void taskYield();    //Yield execution to concurrent processesSpatialRegion::SpatialRegion(Fields* f, BoundaryList* b, 	ParticleGroupList** p, SpeciesList* s, MCC* _mcc,                              MCTI* _mcti, Scalar _dt) {  fields = f;  grid = fields->get_grid();  boundaryList = b;  particleGroupList = p;   speciesList = s;  nSpecies = speciesList->nItems();  speciesArray = new Species*[nSpecies];  nParticles = new long int[nSpecies];  nParticleFlag = FALSE;  theLoads = new oopicList<Load>;    mcc  = _mcc;  mcti = _mcti;  dt   = _dt;  // Set defaults for moving window  shift = 0;  shiftDir = 0;  shiftDelayTime = ( get_grid()->getX()[(95*getJ())/100][0].e1()                      - get_grid()->getX()[0][0].e1() ) * iSPEED_OF_LIGHT;  next_shift_time = -1.;  shiftNum = 0;  shift_dt = (  get_grid()->getX()[2][0].e1()                - get_grid()->getX()[1][0].e1() ) * iSPEED_OF_LIGHT;#if defined(MPI_DEBUG) && defined(MPI_VERSION)  dfout << "MPI_RANK = " << MPI_RANK << "; shift_dt = " << shift_dt        << "\niSPEED_OF_LIGHT = " << iSPEED_OF_LIGHT        << "\nx2 = " << get_grid()->getX()[2][0].e1()        << "\nx1 = " << get_grid()->getX()[1][0].e1()        << "\ndeltaX = " << (  get_grid()->getX()[2][0].e1()                             - get_grid()->getX()[1][0].e1() )	<< "\n";#endif /* defined(MPI_DEBUG) && defined(MPI_VERSION) */  // cout << "Default shift delay time = " << shiftDelayTime << endl;  // cout << "Shift delta-t = " << shift_dt << endl;  oopicListIter<ParticleGroup>	pg(*particleGroupList[0]);  pg.restart();  if (!pg.Done()) maxN = pg()->get_maxN();  else maxN = 500; //	choose a default size  t = 0.0;  // otherwise simulation time won't be initialized  // distribute particle group information to boundaries.  ApplyToList(setSpeciesArray(speciesArray),*boundaryList,Boundary);  oopicListIter<Species> spiter(*speciesList);  for(spiter.restart();!spiter.Done();spiter++)    speciesArray[spiter()->getID()]=spiter();  // set the ptrNGD and the ptrMapNGDs to zero as initial values  ptrNGD = 0;  ptrMapNGDs = 0;}SpatialRegion::~SpatialRegion(){  oopicListIter<Boundary> bIter(*boundaryList);  for (bIter.restart(); !bIter.Done();	bIter++)    bIter.deleteCurrent();  delete boundaryList;  boundaryList = NULL;  for (int i=0; i<nSpecies; i++)    {      oopicListIter<ParticleGroup> pgIter(*particleGroupList[i]);      for (pgIter.restart(); !pgIter.Done();	pgIter++)        pgIter.deleteCurrent();    }  delete[] nParticles;  delete[] particleGroupList;  particleGroupList = NULL;  delete fields;  delete grid;  fields = NULL;  grid = NULL;  // delete mcc;  // delete the list of NGD's  NGDList.deleteAll(); // delete the list elements and data for the NGDs}NGD* SpatialRegion::initNGD(const ostring& _gasType, const ostring& _analyticF,                             const Scalar& _gasDensity,                             const Vector2& _p1Grid, const Vector2& _p2Grid,                             const int& discardDumpFileNGDDataFlag)  throw(Oops){  // check first if the list is empty:  if( NGDList.isEmpty() ) {    try{      ptrNGD = new NGD(grid, _gasType, _analyticF, _gasDensity,                       _p1Grid, _p2Grid, discardDumpFileNGDDataFlag);    }    catch(Oops& oops2){      oops2.prepend("SpatialRegion::initNGD: Error: \n");//ok      throw oops2;    }    NGDList.add(ptrNGD);    return ptrNGD;   }    oopicListIter<NGD> NGDIter(NGDList);  for ( NGDIter.restart(); !NGDIter.Done(); NGDIter++ ){    if ( (NGDIter.current())->getGasType() == _gasType ) {      // this gas density already exists => return a pointer to it.      return NGDIter.current();     }  }  // the GasType was not found in the list, proceed to create it  try{    ptrNGD = new NGD(grid, _gasType, _analyticF, _gasDensity,                     _p1Grid, _p2Grid, discardDumpFileNGDDataFlag);  }  catch(Oops& oops2){    oops2.prepend("SpatialRegion::initNGD: Error: \n");//OK    throw oops2;  }  NGDList.add(ptrNGD);  return ptrNGD; }/** * A function to give a pointer to the NGDList to the Boundary * objects and set the number of NGDs initialized in the  * initialized MapNGDs object.  */void SpatialRegion::setNGDListPtrs() {  //   // instantiate an object to handle the NGD mappings   // across boundaries.  //   ptrMapNGDs = new MapNGDs(&NGDList, this);  ptrMapNGDs->setNumNGDs();  //   // allow each Boundary object to point to the MapNGDs object  //   oopicListIter<Boundary>	nextb(*boundaryList);  for(nextb.restart(); !nextb.Done(); nextb++)    nextb.current()->setPtrMapNGDs(ptrMapNGDs);}#ifdef undef//--------------------------------------------------------------------//	Compute the number of particles in this SpatialRegion, return the// total number, save the number for each specieslong SpatialRegion::nParticles(Scalar* nPtcl){  long nTotal = 0;  for (int i=0; i<nSpecies; i++)    {      long n = 0;      n = CountParticles(i);      if (nPtcl != NULL) nPtcl[i] = n;      nTotal += n;    }  return nTotal;}#endiflong SpatialRegion::CountParticles(int i){  if (nParticleFlag) return nParticles[i]; // caching scheme  long nTotal = 0;  long n = 0;  oopicListIter<ParticleGroup> pgIter(*particleGroupList[i]);  for (pgIter.restart(); !pgIter.Done(); pgIter++){    if (pgIter()->get_n()) n += pgIter()->get_n();    else pgIter.deleteCurrent();  }  nTotal += n;  nParticles[i] = nTotal;  return nTotal;}void SpatialRegion::globalParticleLimit(){  long nTotal = 0;  for (int i=0; i<nSpecies; i++) nTotal += CountParticles(i);  if (nTotal > particleLimit) increaseParticleWeight();}void SpatialRegion::advance()   throw(Oops){#if defined(MPI_DEBUG) && defined(MPI_VERSION)  dfout << "MPI_RANK = " << MPI_RANK << "; shift_dt = " << shift_dt	<< endl;  dfout << "Begin SpatialRegion::advance(): MPI_RANK = " << MPI_RANK         << "t = " << t << endl; #endif /* defined(MPI_DEBUG) && defined(MPI_VERSION) */  // Remove the particles that drop below threshold  if (getBoltzmannFlag()){      oopicListIter<Species> siter(*speciesList);    for (siter.restart(); !siter.Done(); siter++)      if (siter()->get_collisionModel()==test){        int i = siter()->getID();        addParticleList(fields->testParticleList(*particleGroupList[i]));      }  }  // Advance the particles  try{    particleAdvance();  }  catch(Oops& oops3){    oops3.prepend("SpatialRegion::advance: Error: \n"); //done    throw oops3;  }  // Advance the fields  if (fields->get_freezeFields()) t += dt*getFieldSubFlag();  else fieldsAdvance();#ifdef MPI_VERSION  extern MPI_Comm XOOPIC_COMM;#endif  // Shift the region  if ( next_shift_time < 0.0 ) {    if ( shiftDelayTime <= t ) next_shift_time = t + shift_dt;    else                       next_shift_time = shiftDelayTime;  }  /************  cout.precision(15);  cout << "shift_dt        = " << shift_dt << endl       << "shiftDelayTime  = " << shiftDelayTime << endl       << "next_shift_time = " << next_shift_time << endl       << "dt              = " << dt << endl;  *************/#if defined(MPI_DEBUG) && defined(MPI_VERSION)  cout << "MPI_RANK = " << MPI_RANK << "; shift_dt = " << shift_dt << endl;  cout << "Begin SpatialRegion::advance(): MPI_RANK = " << MPI_RANK        << "; t = " << t << endl; #endif /* defined(MPI_DEBUG) && defined(MPI_VERSION) */  if( shiftDir != 0 && (t >= next_shift_time) ) {#if defined(MPI_DEBUG) && defined(MPI_VERSION)    cout << "MPI_RANK = " << MPI_RANK << "  t = " << t << "." << endl         << "next_shift_time = " << next_shift_time << endl         << "MPI_RANK = " << MPI_RANK << ": shifting region." << endl;#endif    try{      shiftRegion();    }    catch(Oops& oops2){      oops2.prepend("SpatialRegion::advance: Error: \n");//done      throw oops2;    }  }}//--------------------------------------------------------------------//	Advance particles in spatial region in time by dt, including all its//void SpatialRegion::particleAdvance()  throw(Oops){  nParticleFlag = FALSE;  fields->clearI();     oopicListIter<Species> siter(*speciesList);  for (siter.restart(); !siter.Done(); siter++){    Species* species = siter.current();    int i = species->getID();    if (species->cycleNow()){			// this species gets pushed now      if (!fields->get_freezeFields()) {        fields->clearI(i);        fields->setAccumulator(i);      }      oopicListIter<ParticleGroup> nextpg(*particleGroupList[i]);      Scalar species_dt = species->get_subcycleIndex()*getFieldSubFlag()*dt;      species_dt /= species->get_supercycleIndex();      for (int super=0; super < species->get_supercycleIndex(); super++){        if (CountParticles(i)>(species->get_particleLimit()))          increaseParticleWeight(i);	  			        species->zeroKineticEnergy();        for (nextpg.restart(); !nextpg.Done(); nextpg++)          nextpg()->advance(*fields, species_dt);      // need to pass particles across SRB's        ApplyToList(passParticles(),*boundaryList,Boundary);              try{          emit(species); // don't move this without moving the ApplyToList above.        }        catch(Oops& oops2){          oops2.prepend("SpatialRegion::particleAdvance: Error: \n");//done          throw oops2;        }              if (mcc) {          try{            addParticleList(mcc->collide(*particleGroupList[i]));          }          catch(Oops& oops3){            oops3.prepend("SpatialRegion::particleAdvance: Error: \n");//done            throw oops3;          }        }      }      species->resetSubcycleCount();    }    else {      species->incSubcycleCount();      if (!fields->get_freezeFields()) fields->addtoI(i);    }  }  /**   * Do the tunneling ionization if the mcti was instantiated.    * Note that this call has different logic than the corresponding   * call for the mcc class given in the species loop above.    * The reason is that we need to control the order in which   * we ionize the different ion species. For this reason we   * pass directly the pointer to the array of particle group    * lists and do the work in derived classes for the different   * elements for which the tunneling ionization was implemented. 

⌨️ 快捷键说明

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