1
/////////////////////////////////////////////////////////////
3
// Copyright (c) 2007-2011 by The University of Queensland //
4
// Earth Systems Science Computational Centre (ESSCC) //
5
// http://www.uq.edu.au/esscc //
7
// Primary Business: Brisbane, Queensland, Australia //
8
// Licensed under the Open Software License version 3.0 //
9
// http://www.opensource.org/licenses/osl-3.0.php //
11
/////////////////////////////////////////////////////////////
13
#include "CircMNTable2D.h"
15
// --- System includes ---
18
// --- IO includes ---
25
CircMNTable2D::CircMNTable2D()
29
Construct CircMNTable2D.
31
\param MinPt minimum point (z component ignored)
32
\param MaxPt maximum point (z component ignored)
33
\param cd cell dimension
34
\param ngroups initial number of particle groups
36
CircMNTable2D::CircMNTable2D(const Vector3& MinPt,const Vector3& MaxPt,double cd,unsigned int ngroups):
37
MNTable2D(MinPt, MaxPt, cd, ngroups)
40
// check if grid spacing fits size in circular direction:
41
double nx=(MaxPt-MinPt).X()/m_celldim;
42
// error message if not
44
std::cerr << "WARNING! grid spacing " << m_celldim << " doesn't fit periodic x-dimension " << (MaxPt-MinPt).X() << std::endl;
46
double shift_x=(m_nx-2)*m_celldim;
47
m_shift_vec_x=Vector3(shift_x,0.0,0.0);
51
Destruct CircMNTable2D. Just calls MNTable2D destructor.
53
CircMNTable2D::~CircMNTable2D()
57
set circularity of x-dimension to 1
59
void CircMNTable2D::set_x_circ()
64
int CircMNTable2D::getXIndex(const Vector3& Pos) const
66
return int(floor((Pos.x()-m_x0)/m_celldim));
69
int CircMNTable2D::getYIndex(const Vector3& Pos) const
71
return int(floor((Pos.y()-m_y0)/m_celldim));
75
int CircMNTable2D::getFullIndex(const Vector3& Pos) const
77
int ix=int(floor((Pos.x()-m_x0)/m_celldim));
78
int iy=int(floor((Pos.y()-m_y0)/m_celldim));
84
get the cell index for a given position
86
\param Pos the position
87
\return the cell index if Pos is inside the table, -1 otherwise
89
int CircMNTable2D::getIndex(const Vector3& Pos) const
93
int ix=int(floor((Pos.x()-m_x0)/m_celldim));
94
int iy=int(floor((Pos.y()-m_y0)/m_celldim));
96
// check if pos is in table excl. padding
97
if((ix>=0) && (ix<=m_nx-1) && (iy>0) && (iy<m_ny-1)){
107
Insert sphere. Insert clone into other side of Table.
110
\param gid the group id
112
bool CircMNTable2D::insert(const Sphere& S,unsigned int gid)
116
int id=getIndex(S.Center());
117
int idx=getXIndex(S.Center());
119
if((id!=-1) && (idx!=0) && (idx!=m_nx-1) && (gid<m_ngroups)){ // valid index
121
m_data[id].insert(S,gid);
123
int xidx=getXIndex(S.Center());
127
SClone.shift(m_shift_vec_x);
128
int clone_id=getFullIndex(SClone.Center());
129
m_data[clone_id].insert(SClone,gid);
130
} else if (xidx==m_nx-2){
132
SClone.shift(-1.0*m_shift_vec_x);
133
int clone_id=getFullIndex(SClone.Center());
134
m_data[clone_id].insert(SClone,gid);
144
Insert sphere if it doesn't collide with other spheres. Insert clone into other side of Table.
147
\param gid the group id
149
bool CircMNTable2D::insertChecked(const Sphere& S,unsigned int gid,double tol)
152
int id=getIndex(S.Center());
153
int idx=getXIndex(S.Center());
155
// std::cerr << "CircMNTable2D::insertChecked(" << S << ") id=" << id << " idx= " << idx << std::endl;
158
if((id!=-1) && (idx!=0) && (idx!=m_nx-1) && (gid<m_ngroups)){
160
multimap<double,const Sphere*> close_spheres=getSpheresFromGroupNear(S.Center(),S.Radius()-tol,gid);
161
if(close_spheres.size()==0){
162
m_data[id].insert(S,gid);
165
int xidx=getXIndex(S.Center());
169
SClone.shift(m_shift_vec_x);
170
multimap<double,const Sphere*> close_spheres=getSpheresFromGroupNear(SClone.Center(),SClone.Radius()-tol,gid);
171
if(close_spheres.size()==0){
172
int clone_id=getFullIndex(SClone.Center());
173
m_data[clone_id].insert(SClone,gid);
175
} else if (xidx==m_nx-2){
177
SClone.shift(-1.0*m_shift_vec_x);
178
multimap<double,const Sphere*> close_spheres=getSpheresFromGroupNear(SClone.Center(),SClone.Radius()-tol,gid);
179
if(close_spheres.size()==0){
180
int clone_id=getFullIndex(SClone.Center());
181
m_data[clone_id].insert(SClone,gid);
192
insert sphere if it doesn't collide with other spheres
195
\param gid the group id
197
bool CircMNTable2D::checkInsertable(const Sphere& S,unsigned int gid)
201
int id=getIndex(S.Center());
202
int idx=getXIndex(S.Center());
204
if((id!=-1) && (idx!=0) && (idx!=m_nx-1) && (gid<m_ngroups)){
205
multimap<double,const Sphere*> close_spheres=getSpheresFromGroupNear(S.Center(),S.Radius()-s_small_value,gid);
206
if(close_spheres.size()==0){
218
Generate bonds between particles of a group. Takes cloned particles into account.
220
\param gid the group ID
221
\param tol max. difference between bond length and equilibrium dist.
224
void CircMNTable2D::generateBonds(int gid,double tol,int btag)
226
std::cerr << "CircMNTable2D::generateBonds( " << gid << " , " << tol << " , " << btag << " )" << std::endl;
227
// loop over all cells
228
for(int i=0;i<m_nx-1;i++){
229
for(int j=1;j<m_ny-1;j++){
231
// loop over "upper" neighbors of each cell
232
for(int ii=-1;ii<=1;ii++){
233
for(int jj=-1;jj<=1;jj++){
234
int id2=idx(i+ii,j+jj);
235
vector<pair<int,int> > bonds;
236
if((id2==id) && (i!=0)){ // intra-cell, not for boundary
237
//std::cerr << id << " - " << id << std::endl;
238
bonds=m_data[id].getBonds(gid,tol);
239
} else if(id2>id){ // inter-cell
240
//std::cerr << id << " - " << id2 << std::endl;
241
bonds=m_data[id].getBonds(gid,tol,m_data[id2]);
243
for(vector<pair<int,int> >::iterator iter=bonds.begin();
246
//std::cerr << iter->first << " | " << iter->second << " ";
247
m_bonds[btag].insert(*iter);
249
//std::cerr << std::endl;
252
//std::cerr << std::endl;
258
Generate bonds between particles of a group with identical particle tag. Takes cloned particles into account.
260
\param gid the group ID
261
\param tol max. difference between bond length and equilibrium dist.
263
\param ptag the particle tag
264
\param mask the mask for the particle tag
266
void CircMNTable2D::generateBondsWithMask(int gid,double tol,int btag, int ptag, int mask)
268
std::cerr << "CircMNTable2D::generateBondsWithMask( " << gid << " , " << tol << " , " << btag << " "
269
<< ptag <<" " << mask<<" )" << std::endl;
270
// loop over all cells
271
for(int i=0;i<m_nx-1;i++){
272
for(int j=1;j<m_ny-1;j++){
274
// loop over "upper" neighbors of each cell
275
for(int ii=-1;ii<=1;ii++){
276
for(int jj=-1;jj<=1;jj++){
277
int id2=idx(i+ii,j+jj);
278
vector<pair<int,int> > bonds;
279
if((id2==id) && (i!=0)){ // intra-cell, not for boundary
280
//std::cerr << id << " - " << id << std::endl;
281
bonds=m_data[id].getBonds(gid,tol,ptag,mask);
282
} else if(id2>id){ // inter-cell
283
//std::cerr << id << " - " << id2 << std::endl;
284
bonds=m_data[id].getBonds(gid,tol,m_data[id2],ptag,mask);
286
for(vector<pair<int,int> >::iterator iter=bonds.begin();
289
//std::cerr << iter->first << " | " << iter->second << " ";
290
m_bonds[btag].insert(*iter);
292
//std::cerr << std::endl;
295
//std::cerr << std::endl;
301
Output the content of a MNTable2D to an ostream. The output format depends on the value of MNTable2D::s_output_style (see MNTable2D::SetOutputStyle). If it is set to 0, output suitable for debugging is generated, if it is set to 1 output in the esys .geo format is generated. If MNTable2D::s_output_style is set to 2, the output format is VTK-XML.
303
\param ost the output stream
306
ostream& operator << (ostream& ost,const CircMNTable2D& T)
308
if(CircMNTable2D::s_output_style==0){ // debug style
309
// don't print padding
310
MNTCell::SetOutputStyle(0);
311
for(int i=0;i<T.m_nx;i++){
312
for(int j=1;j<T.m_ny-1;j++){
313
ost << "=== Cell " << i << " , " << j << " === " << endl;
314
ost << T.m_data[T.idx(i,j)];
317
} else if (CircMNTable2D::s_output_style==1){ // geo style
319
for(int i=1;i<T.m_nx-1;i++){
320
for(int j=1;j<T.m_ny-1;j++){
321
nparts+=T.m_data[T.idx(i,j)].NParts();
325
ost << "LSMGeometry 1.2" << endl;
326
ost << "BoundingBox " << T.m_x0+T.m_celldim << " " << T.m_y0+T.m_celldim << " 0.0 " << T.m_x0+double(T.m_nx-1)*T.m_celldim << " " << T.m_y0+double(T.m_ny-1)*T.m_celldim << " 0.0 " << endl;
327
ost << "PeriodicBoundaries " << T.m_x_periodic << " 0 0" << endl;
328
ost << "Dimension 2D" << endl;
330
ost << "BeginParticles" << endl;
331
ost << "Simple" << endl;
332
ost << nparts << endl;
333
MNTCell::SetOutputStyle(1);
334
for(int i=1;i<T.m_nx-1;i++){
335
for(int j=1;j<T.m_ny-1;j++){
336
ost << T.m_data[T.idx(i,j)];
339
ost << "EndParticles" << endl;
341
ost << "BeginConnect" << endl;
344
for(map<int,set<pair<int,int> > >::const_iterator iter=T.m_bonds.begin();
345
iter!=T.m_bonds.end();
347
nbonds+=iter->second.size();
349
ost << nbonds << endl;
350
for(map<int,set<pair<int,int> > >::const_iterator iter=T.m_bonds.begin();
351
iter!=T.m_bonds.end();
353
for(set<pair<int,int> >::const_iterator v_iter=iter->second.begin();
354
v_iter!=iter->second.end();
356
ost << v_iter->first << " " << v_iter->second << " " << iter->first << endl;
359
ost << "EndConnect" << endl;
360
} else if (CircMNTable2D::s_output_style==2){ // vtk-xml
361
T.WriteAsVtkXml(ost);