00001
00002
00003
00004
00005 #include <math.h>
00006 #include <cstdlib>
00007 #include <iostream>
00008 using namespace std;
00009 #include "def.h"
00010 #include "run.h"
00011 #include "list.h"
00012 #include "collection.h"
00013 #include "species.h"
00014 #include "grid.h"
00015 #include "container.h"
00016 #include "model.h"
00017
00018 namespace GridContainer {
00019 REAL xmin[DIM],xmax[DIM];
00020 REAL cellsize;
00021 int ncells[DIM+1],
00022 mcells=0,mcells1=0;
00023 Container<Molecule> *nodes;
00024 Pool<Molecule> *pool;
00025 void init(
00026 REAL ymin[], REAL ymax[],
00027 REAL radius,
00028 Pool<Molecule> *newpool
00029 ) {
00030 REAL margin=radius;
00031 pool=newpool;
00032 cellsize=radius;
00033 mcells=1;
00034 for(int i=0;i<DIM;i++) {
00035 REAL
00036 x0=ymin[i]-margin,
00037 x1=ymax[i]+margin;
00038 int n=((int)((x1-x0)/cellsize))+1;
00039 ncells[i]=n;
00040 mcells*=n;
00041 xmin[i]=x0;
00042 xmax[i]=x1;
00043 }
00044 ncells[DIM]=1;
00045 nodes=new Container<Molecule>[mcells];
00046 if(nodes==NULL) {
00047 cout<<"Grid::init: Can't allocate nodes\n";cout.flush();
00048 exit(1);
00049 }
00050 mcells1=mcells/ncells[0];
00051 if(Run::option.debug||Run::option.verbose) {
00052 cout<<"Grid::init:cellsize:"<<cellsize<<"\n\txmin:";
00053 for(int i=0;i<DIM;i++) cout<<' '<<xmin[i];
00054 cout<<"\n\txmax:";
00055 for(int i=0;i<DIM;i++) cout<<' '<<xmax[i];
00056 cout<<"\n\tncells:";
00057 for(int i=0;i<DIM;i++) cout<<' '<<ncells[i];
00058 cout<<endl;cout.flush();
00059 }
00060 }
00061 int index(int ind[]) {
00062 int n=0;
00063 for(int i=0;i<DIM;i++) {
00064 n=n*ncells[i]+ind[i];
00065 }
00066 return n;
00067 }
00068 void index(int n, int ind[]) {
00069 if(n<0) {
00070 for(int i=0;i<DIM;i++) ind[i]=-1;
00071 return;
00072 }
00073 int m=mcells1;
00074 for(int i=0;i<DIM;i++) {
00075 ind[i]=n/m;
00076 n%=m;
00077 m/=ncells[i+1];
00078 }
00079 }
00080 #ifdef LOCAL
00081 void put(Molecule *node) {
00082 REAL
00083 *x=node->Coordinates(),
00084 *v=node->Velocity();
00085
00086 int icell=node->GridCell(),
00087 cellind[DIM],newind[DIM];
00088 bool moved=false;
00089 index(icell,cellind);
00090 for(int i=0;i<DIM;i++) {
00091 int j=(int)((x[i]-xmin[i])/cellsize);
00092 if(j>=ncells[i]||j<0) {
00093 cerr<<"Molecule "<<Species::species[node->Type()].Id()<<" at"
00094 << " x: ("<<x[0]<<','<<x[1]<<','<<x[2]<<")"
00095 << " v: ("<<v[0]<<','<<v[1]<<','<<v[2]<<")"
00096 <<" time="<<node->Time()<<" dt="<<node->TimeStep()<<" dtmax="<<Run::time.step
00097 <<" is outside of the grid: index: 0<"<<j<<"<="<<ncells[i]<<" erased\n";
00098 Ptr<Molecule> *pointer=node->getPtr();
00099 if(pointer!=NULL) {
00100 nodes[icell].remove(pointer);
00101 node->putPtr(NULL);
00102 }
00103 node->Type(Species::VOIDSPECIE);
00104 #ifdef DEBUG
00105 exit(1);
00106 #else
00107 return;
00108 #endif
00109 }
00110 if(j!=cellind[i]) moved=true;
00111 newind[i]=j;
00112 }
00113 if(moved) {
00114 Ptr<Molecule> *pointer=node->getPtr();
00115 if(pointer!=NULL) {
00116 nodes[icell].unlink0(pointer);
00117 icell=index(newind);
00118 nodes[icell].link0(pointer);
00119 } else {
00120 icell=index(newind);
00121 nodes[icell].insert(node);
00122 node->putPtr(nodes[icell].getPtr());
00123 }
00124 node->GridCell(icell);
00125 }
00126 }
00127 #ifdef OMP
00128 void put(Molecule *node, int icounter) {
00129 REAL *x=node->Coordinates();
00130 int icell=node->GridCell(),
00131 cellind[DIM],newind[DIM];
00132 bool moved=false;
00133 index(icell,cellind);
00134 for(int i=0;i<DIM;i++) {
00135 int j=(int)((x[i]-xmin[i])/cellsize);
00136 if(j>=ncells[i]||j<0) {
00137 cerr<<"Molecule ("<<x[0]<<','<<x[1]<<','<<x[2]<<") is outside of the grid: index: 0<"<<j<<"<="<<ncells[i]<<" erased\n";
00138 Ptr<Molecule> *pointer=node->getPtr();
00139 if(pointer!=NULL) {
00140 nodes[icell].remove(pointer,icounter);
00141 node->putPtr(NULL);
00142 }
00143 node->Type(Species::VOIDSPECIE);
00144 #ifdef DEBUG
00145 exit(1);
00146 #else
00147 return;
00148 #endif
00149 }
00150 if(j!=cellind[i]) moved=true;
00151 newind[i]=j;
00152 }
00153 if(moved) {
00154 Ptr<Molecule> *pointer=node->getPtr();
00155 if(pointer!=NULL) {
00156 int jcell=index(newind);
00157 while(nodes[jcell].islocked()); nodes[jcell].lock();
00158
00159 while(nodes[icell].islocked()); nodes[icell].lock();
00160 nodes[icell].unlink0(pointer);
00161 nodes[icell].unlock();
00162 nodes[jcell].link0(pointer);
00163 nodes[jcell].unlock();
00164 icell=jcell;
00165 } else {
00166 icell=index(newind);
00167
00168
00169
00170 pointer=nodes[icell].append1(node,icounter);
00171 node->putPtr(pointer);
00172 }
00173 node->GridCell(icell);
00174 }
00175 }
00176 #endif //END OMP
00177 #endif //END LOCAL INTERACTIONS
00178 Container<Molecule> *get(int ind[]) {
00179 return nodes+index(ind);
00180 }
00181 int *dimensions() { return ncells; }
00182 }
00183