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

📄 spbound.cpp

📁 pic 模拟程序!面向对象
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//--------------------------------------------------------------------//// File:	spbound.cpp//// Purpose:	Implementation of the SpatialRegionBoundary - a boundary//		between two spatial regions.  Has methods for passing//		data between regions.//// Version:	$Id: spbound.cpp,v 1.40 2004/10/08 22:32:36 yew Exp $////--------------------------------------------------------------------/*====================================================================Revision HistoryCary (23 Jan 00) Added header, implementation of recvParticles, which	is like emit, except that one does not further weighting of	the particles.  Did some indentation for readability.CVS1.27.2.4 (Cary 26 Jan 00) Reorganized to put constructor first.	Not necessary, I see now, but made sure that j indexing	was increasing.  Implemented sendStripe and recvStripe.	Still not checked as we have no way of looking at MPI runs.(PeterM 1/15/01) Deeper look, allowing Enode/Bnode continuity.====================================================================*//* These are template defines.  Make it easier not to screw things up.  *//*The following advance the E field components 1 2 and 3 one timestep. "down" means lower index k.  "here" means same index.  "right" means higher index j.	"left" means lower index j "up" means higher index k*/#define NEW_E1(iC,iLhere,iLdown,Bhere,Bdown,Ihere) ( (iC).e1() * ( (Bhere).e3()*(iLhere).e3() \		- (Bdown).e3()*(iLdown).e3() -(Ihere).e1()))#define NEW_E2(iC,iLhere,iLleft,Bhere,Bleft,Ihere) ( (iC).e2() * ( -(Bhere).e3()*(iLhere).e3() \	+ (Bleft).e3()*(iLleft).e3() - (Ihere).e2()))#define NEW_E3(iC,iLhere,iLdown,iLleft,Bhere,Bdown,Bleft,Ihere)  ( (iC).e3() * ( (Bdown).e1()*(iLdown).e1()\	- (Bhere).e1()*(iLhere).e1()\	+ (Bhere).e2()*(iLhere).e2()\	- (Bleft).e2()*(iLleft).e2() - (Ihere).e3()))/* The following advance the B field components 1 2 and 3 one timestep:  directions are as above. */#define NEW_B1(Ehere,Eup)        ( (Eup).e3() - (Ehere).e3())#define NEW_B2(Ehere,Eright)     ( (Ehere).e3() - (Eright).e3())#define NEW_B3(Ehere,Eright,Eup)  ( (Ehere).e1() - (Eup).e1() + (Eright).e2() - (Ehere).e2())#include "spbound.h"#include "fields.h"#include "mapNGDs.h"#ifdef _MSC_VERusing std::cout;using std::cerr;using std::endl;#endifSpatialRegionBoundary::SpatialRegionBoundary(oopicList <LineSegment> *segments) throw (Oops) :  Boundary(segments)    {	 if(segments->nItems() > 1) {     stringstream ss (stringstream::in | stringstream::out);     ss << "SpatialRegionBoundary::SpatialRegionBoundary: Error: \n"<<      "Spatial region boundaries CANNOT have multiple segments.\n";		std::string msg;    ss >> msg;    Oops oops(msg);    throw oops;    // exit() SpatialRegionGroup::constructBoundaryParams:      /*"SpatialRegionGroup::makeSRB:     SpatialRegionBoundaryParams::CreateCounterPart: */	 }	 	 if(j1!=j2 && k1!=k2) {     stringstream ss (stringstream::in | stringstream::out);     ss << "SpatialRegionBoundary::SpatialRegionBoundary: Error: \n"<<		    "Spatial region boundaries MUST be either horizontal or vertical.\n";		      std::string msg;     ss >> msg;     Oops oops(msg);     throw oops;    // exit() SpatialRegionGroup::constructBoundaryParams:    /*"SpatialRegionGroup::makeSRB:     SpatialRegionBoundaryParams::CreateCounterPart: */	 }	 int length = MAX(abs(k1-k2),abs(j1-j2));	 // memory allocation is 1 larger to allow guard cells for a	 // simpler field solve.	 lJa = new Vector3[length+1];  // closest guard layer	 lJb = new Vector3[length+1];  // next closest guard layer	 lJc = new Vector3[length+1];  // furthest guard layer	 lEa = new Vector3[length+1];  // closest guard layer	 lEb = new Vector3[length+1];  // next closest guard layer	 lEc = new Vector3[length+1];  // furthest guard layer	 lBa = new Vector3[length+1];  // closest guard layer	 lBb = new Vector3[length+1];  // next closest guard layer	 lBc = new Vector3[length+1];  // furthest guard layer	 liLa = new Vector3[length+1];  // closest guard layer	 liLb = new Vector3[length+1];  // next closest guard layer	 liLc = new Vector3[length+1];  // furthest guard layer	 /* leave the old variables so it will compile */	 lJ = new Vector3[length+1];  // soon obsolete	 lE = new Vector3[length+1];  // soon obsolete	 lB = new Vector3[length+1];  // soon obsolete	 liL = new Vector3[length+1]; // soon obsolete	 // Sending 3 layers for simplicity	 lJsend = new Vector3[3*length+4];	 lEsend = new Vector3[3*length+4];	 lBsend = new Vector3[3*length+4];         //         // the following buffers are needed for the communication of         // the neutral gas density (in NGD objects) data strucures         // across boundaries; memory for them will be allocated only          // if there are NGDs; dad 05/16/01         //          numElementsNGDbuf = 0;          lNGDbuf = 0;         lNGDbufSend = 0;         	 //zero the memory	 memset(lJa,0,(length+1) * sizeof(Vector3));	 memset(lEa,0,(length+1) * sizeof(Vector3));	 memset(lBa,0,(length+1) * sizeof(Vector3));	 memset(liLa,0,(length+1) * sizeof(Vector3));	 memset(lJb,0,(length+1) * sizeof(Vector3));	 memset(lEb,0,(length+1) * sizeof(Vector3));	 memset(lBb,0,(length+1) * sizeof(Vector3));	 memset(liLb,0,(length+1) * sizeof(Vector3));	 memset(lJc,0,(length+1) * sizeof(Vector3));	 memset(lEc,0,(length+1) * sizeof(Vector3));	 memset(lBc,0,(length+1) * sizeof(Vector3));	 memset(liLc,0,(length+1) * sizeof(Vector3));	 memset(lJ,0,(length+1) * sizeof(Vector3));	 memset(lE,0,(length+1) * sizeof(Vector3));	 memset(lB,0,(length+1) * sizeof(Vector3));	 memset(liL,0,(length+1) * sizeof(Vector3));	 memset(lJsend,0,(3*length+4) * sizeof(Vector3));	 memset(lEsend,0,(3*length+4) * sizeof(Vector3));	 memset(lBsend,0,(3*length+4) * sizeof(Vector3));	 theLink = 0;	 BCType=SPATIAL_REGION_BOUNDARY;	 ptclPassArraySize=100;	 ptclPassArray = new particlePassDat[ptclPassArraySize];	 number_Particles_passing=0;	 }// We need to set up a special iC for the Fields:: so it doesn't interfere// with the special field solve we do for E2 and E3 on the boundary.void SpatialRegionBoundary::setPassives() {  int j,k;  if(j1==j2) // vertical boundary, set iC2 and iC3 to zero	 {		for(k=k1;k<=k2;k++) {		  fields->set_iL1(j1,k,2*fields->getiL()[j1][k].e1());  // fix iL: default is wrong.		  fields->set_iC2(j1,k,0);		  fields->set_iC3(j1,k,0);		}	 }  else  // horizontal boundary, set iC1 and iC3 to zero	 {		for(j=j1;j<=j2;j++) {		  fields->set_iL2(j,k1,2*fields->getiL()[j][k1].e2());  // fix iL: default is wrong.		  fields->set_iC1(j,k1,0);		  fields->set_iC3(j,k1,0);		}	 }}		  //  This is the function which will assemble and send the currents//  and fields necessary for the other boundary to solve for its//  fields.  By convention for this boundary, normal points INvoid SpatialRegionBoundary::putCharge_and_Current(Scalar t) {  Vector3 **intBdS = fields->getIntBdS();  Vector3 **intEdl = fields->getIntEdl();  Vector3 **I = fields->getI();  // Vector3 **iC = fields->getiC();  // Vector3 **iL = fields->getiL();// For indexing  int kl = MIN(k1,k2);  int kh = MAX(k1,k2);  int jl = MIN(j1,j2);  int jh = MAX(j1,j2);  int length;// Begin the request  if(!theLink) return;  theLink->askFields();  length = MAX(abs(k2-k1),abs(j2-j1));// Horizontal boundary data send  if(k1==k2) for(int j=jl;j<jh;j++) {      if(normal==-1) {// Real region below      lBsend[j-jl]=Vector3(intBdS[j][k1-1].e1(),0,intBdS[j][k1-1].e3());      lEsend[j-jl]=intEdl[j][k1-1];      lJsend[j-jl]=Vector3(I[j][k1].e1(),I[j][k1-1].e2(),I[j][k1].e3());    }    else {// Real region above      lBsend[j-jl]=Vector3(intBdS[j][k1].e1(), 0, intBdS[j][k1].e3());      lEsend[j-jl]=Vector3(intEdl[j][k1].e1(), intEdl[j][k1+1].e2(),		intEdl[j][k1+1].e3());      lJsend[j-jl]=Vector3(I[j][k1].e1(), I[j][k1].e2(), I[j][k1].e3());    }  }// Vertical boundary data send  else for(int k=kl;k<=kh;k++) {	  int kk = k - kl;// Real region left    if(normal==-1) {/*      lBsend[k-kl]=Vector3(0,intBdS[j1-1][k].e2(),intBdS[j1-1][k].e3());      lEsend[k-kl]=intEdl[j1-1][k];      lJsend[k-kl]=Vector3(I[j1-1][k].e1(),I[j1][k].e2(),I[j1][k].e3()); */		 //New way of doing this, send 3 full layers		 // closest layer first		 lBsend[kk] = intBdS[j1][k];		 lBsend[length + 1 + kk] = intBdS[j1-1][k];		 lBsend[2*length +2 + kk] = intBdS[j1-2][k];		 lEsend[kk] = intEdl[j1][k];		 lEsend[length + 1 + kk] = intEdl[j1-1][k];		 lEsend[2*length +2 + kk] = intEdl[j1-2][k];		 lJsend[k-kl] = I[j1][k];		 lJsend[length + 1 + kk] = I[j1-1][k];		 lJsend[2*length +2 + kk] = I[j1-2][k];		     }// Real region right    else {      /*lBsend[k-kl]=Vector3(0,intBdS[j1][k].e2(),intBdS[j1][k].e3());      lEsend[k-kl]=Vector3(intEdl[j1][k].e1(), intEdl[j1+1][k].e2(),		intEdl[j1+1][k].e3());      lJsend[k-kl]=I[j1][k]; */		 lBsend[kk] = intBdS[j1][k];		 lBsend[length + 1 + kk] = intBdS[j1+1][k];		 lBsend[2*length +2 + kk] = intBdS[j1+2][k];		 lEsend[kk] = intEdl[j1][k];		 lEsend[length + 1 + kk] = intEdl[j1+1][k];		 lEsend[2*length +2 + kk] = intEdl[j1+2][k];		 lJsend[kk] = I[j1][k];		 lJsend[length + 1 + kk] = I[j1+1][k];		 lJsend[2*length +2 + kk] = I[j1+2][k];    }  }/*#ifdef MPI_VERSION  cout << "putCharge_and_Current sending fields:" << endl;  cout << "E1 =";  for(int kk=0; kk<=k2-k1; kk++) cout << " " << lEsend[kk].e1();  cout << endl;  cout << "E2 =";  for(int kk=0; kk<=k2-k1; kk++) cout << " " << lEsend[kk].e2();  cout << endl;  cout << "E3 =";  for(int kk=0; kk<=k2-k1; kk++) cout << " " << lEsend[kk].e3();  cout << endl;  cout << "B1 =";  for(int kk=0; kk<=k2-k1; kk++) cout << " " << lBsend[kk].e1();  cout << endl;  cout << "B2 =";  for(int kk=0; kk<=k2-k1; kk++) cout << " " << lBsend[kk].e2();  cout << endl;  cout << "B3 =";  for(int kk=0; kk<=k2-k1; kk++) cout << " " << lBsend[kk].e3();  cout << endl;#endif*/// Send the fields through the link  theLink->sendFields(lEsend,lBsend,lJsend);}                  // This is the function which does the fieldsolve.// It does it in such a way that toNodes will be wrong,// and it does it in such a way that serial operation is// possible.// By convention for this boundary, normal points INvoid SpatialRegionBoundary::applyFields(Scalar t,Scalar dt) {  Scalar dt2 = dt/2;  Vector3 **intBdS = fields->getIntBdS();  Vector3 **intEdl = fields->getIntEdl();  Vector3 **I = fields->getI();  Vector3 **iC = fields->getiC();  Vector3 **iL = fields->getiL();   int kl = MIN(k1,k2);  int kh = MAX(k1,k2);  int jl = MIN(j1,j2);  int jh = MAX(j1,j2);  int K = fields->getK();  int J = fields->getJ();  if(!theLink) return;  // old version  //theLink->waitFields();  //  do a synchronize  theLink->waitFields(lEa,lEb,lEc,lBa,lBb,lBc,lJa,lJb,lJc);  // Advance B 1/2 step  if(dt > 0) {     SRBadvanceB(t,dt);     // Advance E 1 step     SRBadvanceE(t,dt);       // Advance B 1/2 step is now NECESSARY for weighting to the nodes properly.          SRBadvanceB(t,dt);  }}//  This function sends the iL's the paired boundary will need to//  complete the field solve.void SpatialRegionBoundary::send_liL() {  int j,k;  Vector3 **iL = fields->getiL();  if(k1==k2) {	 for(j=j1;j<j2;j++) {		if(normal==1)  //send the iL's from above		  lBsend[j-j1] = iL[j][k1+1];		else //send the iL's from below		  lBsend[j-j1] = iL[j][k1-1];	 }  }  else {	 for(k=k1;k<k2;k++) {		if(normal==1)  //send the iL's from right		  lBsend[k-k1] = iL[j1+1][k];		else //send the iL's from left		  lBsend[k-k1] = iL[j1-1][k];	 }  }  //  Actually send the data over.  theLink->askFields();  //initialize the transfer  theLink->sendFields(lEsend,lBsend,lJsend); // do our send  theLink->waitFields();  //synchronize}//  This function initializes the passives across the SRB's.void SpatialRegionBoundary::initialize_passives() {  int j,k;  Vector3 **iL = fields->getiL();  if(k1==k2) {	 for(j=j1;j<=j2;j++) {		if(normal==1)  //send the iL's from below		  lBsend[j-j1] = iL[j][k1+1];		else //send the iL's from above		  lBsend[j-j1] = iL[j][k1-1];	 }  }  else {	 for(k=k1;k<=k2;k++) {		if(normal==1)  //send the iL's from right		  lBsend[k-k1] = iL[j1+1][k];		else //send the iL's from left		  lBsend[k-k1] = iL[j1-1][k];	 }  }  //  Actually send the data over.  theLink->askFields();  //initialize the transfer  theLink->sendFields(lEsend,lBsend,lJsend); // do our send  theLink->waitFields();  //synchronize  get_liL();}//  This function sends the iL's the paired boundary will need to//  complete the field solve.void SpatialRegionBoundary::get_liL() {  int j,k;    if(k1==k2) {	 for(j=j1;j<=j2;j++) {		if(normal==1) {		  liL[j-j1] = lB[j-j1];		  lB[j-j1]=0;		}		else {		  liL[j-j1] = lB[j-j1];		  lB[j-j1]=0;		}	 }  }  else {	 for(k=k1;k<k2+1;k++) {		if(normal==1) { 		  liL[k-k1] = lB[k-k1];		  lB[k-k1]=0;		}		else {		  liL[k-k1] = lB[k-k1];		  lB[k-k1]=0;		}	 }  }}void SpatialRegionBoundary::toNodes(){  oopicListIter <LineSegment> lsI(*segments);  for(lsI.restart();!lsI.Done();lsI++) {     int j1,j2,k1,k2,normal,*points;  //local copies of above     j1=(int)lsI()->A.e1();     k1=(int)lsI()->A.e2();     j2=(int)lsI()->B.e1();     k2=(int)lsI()->B.e2();     normal = lsI()->normal;     points=lsI()->points; 	      int j, k,K;     Scalar w1m=0.5, w1p=0.5;     Vector3** ENode = fields->getENode();     Vector3** BNode = fields->getBNode();     Vector3** intEdl = fields->getIntEdl();     Vector3** intBdS = fields->getIntBdS();     Grid* grid = fields->get_grid();     K = grid->getK();     BNode[j1][0] = 0;  // unbounded edges     if(j1==j2 && k1==k2) return;  // don't do toNodes on one-point boundaries.     if (j1==j2)            // vertical boundary	{	   for (j=j1, k=k1; k<=k2; k++) {	      int kk = k - k1;	      if(normal == 1) {		 // ASSUME:  Uniform mesh		 Scalar w2m = grid->dl2(j,k) / (grid->dl2(j,k) + grid->dl2(j,MAX(0,k-1)));		 Scalar w2p = 1-w2m;		 Scalar w1m = 0.5;  // uniform mesh assumption		 Scalar w1p = 0.5;  // uniform mesh assumption

⌨️ 快捷键说明

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