OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
particlegrid.h
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License as published by
22  * the Free Software Foundation; either version 2 of the License, or
23  * (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License
31  * along with this program; if not, write to the Free Software
32  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33  */
34 
35 
36 #ifndef particlegrid_h
37 #define particlegrid_h
38 
39 #include "floatarray.h"
40 #include "intarray.h"
41 #include "mathfem.h"
42 
43 #include <list>
44 
45 namespace oofem
46 {
47 
48 template< class Point >
50 
56 template <class Point>
57 class OOFEM_EXPORT ParticleGrid
58 {
59 public:
62 
63 protected:
66  Point *point;
68  };
69 
71  int n;
75  int total;
84 
90  int giveIndex ( const IntArray &pos ) const;
96  void givePosition ( IntArray &pos, int index ) const;
97 
104  void init ( const IntArray &res, const FloatArray &bb0, const FloatArray &bb1 );
105 
106 public:
113  ParticleGrid ( const IntArray &res, const FloatArray &bb0, const FloatArray &bb1 );
118  ParticleGrid ( const ParticleGrid *old );
120  ~ParticleGrid();
121 
124  return n;
125  }
127  int getTotal() const {
128  return this->total;
129  }
131  int getNumberOfPoints() const;
133  bool isEmpty() const;
135  iterator begin();
137  iterator beginAt ( const FloatArray &x0, const FloatArray &x1 );
138 
144  int getResolution ( int i ) {
145  return this->res ( i );
146  }
152  double getGridStep ( int i ) const {
153  return this->dx ( i );
154  }
155 
161  void getGridCoord ( FloatArray &answer, const IntArray &pos ) const;
167  void getGridCoord ( FloatArray &answer, int ind ) const;
168 
175  bool getPoint ( Point *&answer, const IntArray &pos ) const;
176  bool getPoint ( Point *&answer, int ind ) const;
177 
184  bool getSubGrid ( ParticleGrid<Point> *&subgrid, const IntArray &pos ) const;
185  bool getSubGrid ( ParticleGrid<Point> *&subgrid, int ind ) const;
186 
194  void createSubGrid ( ParticleGrid<Point> *&subgrid, const IntArray &res, const IntArray &pos );
195 
201  void setPoint ( Point *point, const IntArray &pos );
202  void setPoint ( Point *point, int ind );
203 
208  void clearPosition ( const IntArray &pos );
209  void clearPosition ( int ind );
210 
211  void getPointsWithin ( std::list<Point*> &answer, const FloatArray &x0, const FloatArray &x1 );
212  void appendAllPoints ( std::list<Point*> &answer );
213 
221  void getBoundingBox ( const FloatArray &x0, const FloatArray &x1, IntArray &ind0, IntArray &ind1 ) const;
222 
228  void getPosition ( const FloatArray &x, IntArray &pos ) const;
229 
230  std :: string errorInfo(const char *func) const { return std :: string("ParticleGrid :: ") + func; }
231 
232  friend class ParticleGridIterator<Point>;
233 };
234 
235 template <class Point>
237 {
238  this->init ( res, bb0, bb1 );
239 }
240 
241 template <class Point>
243 {
244  this->init ( old->res, old->bb0, old->bb1 );
245 }
246 
247 template <class Point>
248 void ParticleGrid<Point> :: init ( const IntArray &res, const FloatArray &bb0, const FloatArray &bb1 )
249 {
250  this->res = res;
251  this->bb0 = bb0;
252  this->bb1 = bb1;
253 
254  this->n = this->res.giveSize();
255  this->dx.resize ( this->n );
256  this->total = 1;
257  this->res_prod.resize ( this->n );
258  this->res_prod ( 0 ) = 1;
259 
260  for ( int i = 0; i < this->n; ++i ) {
261  this->dx ( i ) = ( this->bb1 ( i ) - this->bb0 ( i ) ) / ( this->res ( i )-1 );
262 
263  this->total *= this->res ( i );
264 
265  this->res_prod ( i ) = 1;
266  for ( int j = 0; j < i; ++j ) {
267  this->res_prod ( i ) *= this->res ( j );
268  }
269  }
270 
271  this->data = new RefinedParticlePoint*[this->total];
272  for ( int i = 0; i < this->total; ++i ) {
273  this->data[i] = NULL;
274  }
275 }
276 
277 template <class Point>
279 {
280  // Clear all points
281  for ( int i = 0; i < this->total; ++i ) {
282  this->clearPosition ( i );
283  }
284  delete[] this->data;
285 }
286 
287 template <class Point>
289 {
291  int c = 0;
292  for ( int i = 0; i < this->total; ++i ) {
293  p = this->data[i];
294  if ( p ) {
295  if ( p->point ) {
296  c += 1;
297  } else if ( p->subgrid ) {
298  c += p->subgrid->getNumberOfPoints();
299  }
300  }
301  }
302  return c;
303 }
304 
305 template <class Point>
307 {
309  for ( int i = 0; i < this->total; ++i ) {
310  p = this->data[i];
311  if ( p ) {
312  if ( p->point ) {
313  return false;
314  } else if ( p->subgrid ) {
315  if ( !p->subgrid->isEmpty() ) {
316  return false;
317  }
318  }
319  }
320  }
321  return true;
322 }
323 
324 template <class Point>
326 {
327  int index = 0;
328  for ( int i = 0; i < this->n; ++i ) {
329  index += this->res_prod ( i ) *pos ( i );
330  }
331  return index;
332 }
333 
334 template <class Point>
335 void ParticleGrid<Point> :: givePosition ( IntArray &pos, int index ) const
336 {
337  pos.resize ( this->n );
338  for ( int i = 0; i < this->n; ++i ) {
339  pos ( i ) = ( index/res_prod ( i ) ) % res ( i );
340  }
341 }
342 
343 template <class Point>
344 void ParticleGrid<Point> :: getGridCoord ( FloatArray &answer, const IntArray &pos ) const
345 {
346  answer.resize ( this->n );
347  for ( int i = 0; i < this->n; ++i ) {
348  answer ( i ) = pos ( i ) *this->dx ( i ) + this->bb0 ( i );
349  }
350 }
351 
352 template <class Point>
353 void ParticleGrid<Point> :: getGridCoord ( FloatArray &answer, int ind ) const
354 {
355  IntArray pos;
356  this->givePosition ( pos, ind );
357  this->getGridCoord ( answer, pos );
358 }
359 
360 template <class Point>
361 void ParticleGrid<Point> :: getBoundingBox ( const FloatArray &x0, const FloatArray &x1, IntArray &ind0, IntArray &ind1 ) const
362 {
363  ind0.resize ( this->n );
364  ind1.resize ( this->n );
365  for ( int i = 0; i < this->n; ++i ) {
366  ind0 ( i ) = max ( ( int ) floor ( ( x0 ( i ) - this->bb0 ( i ) ) /this->dx ( i ) ), 0 );
367  ind1 ( i ) = min ( ( int ) ceil ( ( x1 ( i ) - this->bb0 ( i ) ) /this->dx ( i ) ), this->res ( i ) );
368  }
369 }
370 
371 template <class Point>
373 {
374  pos.resize ( this->n );
375  for ( int i = 0; i < this->n; ++i ) {
376  //pos(i) = (int)nearest((x(i) - this->bb0(i))/this->dx(i));
377  pos ( i ) = ( int ) floor ( ( x ( i ) - this->bb0 ( i ) ) /this->dx ( i ) + 0.5 );
378  pos ( i ) = min ( max ( pos ( i ),0 ),this->res ( i )-1 );
379  }
380 }
381 
382 template <class Point>
384 {
385  iterator it ( this );
386  return it;
387 }
388 
389 template <class Point>
391 {
392  IntArray ind0, ind1;
393  this->getBoundingBox ( x0, x1, ind0, ind1 );
394  iterator it ( this, ind0, ind1 );
395  return it;
396 }
397 
398 template <class Point>
399 void ParticleGrid<Point> :: getPointsWithin ( std::list<Point*> &answer, const FloatArray &x0, const FloatArray &x1 )
400 {
401  answer.clear();
402 
403  // First find a suitable bounding box of positions (note: this isn't perfect in regards to sub grids)
404  IntArray p0, p1;
405  this->getBoundingBox ( x0, x1, p0, p1 );
406 
407  // Get all grid points in that region
408  IntArray p ( this->n );
409  if ( this->n == 2 ) {
410  for ( int x = p0 ( 0 ); x < p1 ( 0 ); x++ ) {
411  p ( 0 ) = x;
412  for ( int y = p0 ( 1 ); y < p1 ( 1 ); y++ ) {
413  p ( 1 ) = y;
414  RefinedParticlePoint *rp = this->data[this->giveIndex ( p )];
415  if ( rp ) {
416  if ( rp->subgrid ) {
417  rp->subgrid->appendAllPoints ( answer );
418  } else {
419  answer.push_front ( rp->point );
420  }
421  }
422  }
423  }
424  } else if ( this->n == 3 ) {
425  OOFEM_ERROR ( "3D grids not implemented yet" );
426  }
427 }
428 
429 template <class Point>
430 void ParticleGrid<Point> :: appendAllPoints ( std::list<Point*> &answer )
431 {
432  for ( int i = 0; i < this->total; ++i ) {
433  RefinedParticlePoint *rp = this->data[i];
434  if ( rp ) {
435  if ( rp->subgrid ) {
436  rp->subgrid->appendAllPoints ( answer );
437  } else if ( rp->point ) {
438  answer.push_front ( rp->point );
439  } else {
440  OOFEM_ERROR ( "Refined particle does not contain subgrid or point." );
441  }
442  }
443  }
444 }
445 
446 template <class Point>
447 bool ParticleGrid<Point> :: getPoint ( Point *&answer, const IntArray &pos ) const
448 {
449  return this->getPoint ( answer, this->giveIndex ( pos ) );
450 }
451 
452 template <class Point>
453 void ParticleGrid<Point> :: setPoint ( Point *point, const IntArray &pos )
454 {
455  this->setPoint ( point, this->giveIndex ( pos ) );
456 }
457 
458 template <class Point>
459 bool ParticleGrid<Point> :: getPoint ( Point *&answer, int ind ) const
460 {
461  RefinedParticlePoint *rp = this->data[ind];
462  if ( rp == NULL ) { // Not active
463  answer = NULL;
464  return false;
465  } else {
466  if ( rp->point ) { // Active and has a point
467  answer = rp->point;
468  return true;
469  } else { // Active and has a sub grid
470  answer = NULL;
471  return false;
472  }
473  }
474 }
475 
476 template <class Point>
477 void ParticleGrid<Point> :: setPoint ( Point *point, int ind )
478 {
479  this->clearPosition ( ind );
480  this->data[ind] = new RefinedParticlePoint;
481  this->data[ind]->point = point;
482  this->data[ind]->subgrid = NULL;
483 }
484 
485 template <class Point>
487 {
488  return this->clearPosition ( this->giveIndex ( pos ) );
489 }
490 
491 template <class Point>
493 {
494  RefinedParticlePoint *rp = this->data[ind];
495  if ( rp ) {
496  if ( rp->point ) {
497  delete rp->point;
498  }
499  if ( rp->subgrid ) {
500  delete rp->subgrid;
501  }
502  delete rp;
503  }
504  this->data[ind] = NULL;
505 }
506 
507 template <class Point>
509 {
510  RefinedParticlePoint *rp = this->data[ind];
511  if ( rp == NULL ) {
512  subgrid = NULL;
513  return false;
514  } else {
515  if ( rp->subgrid ) {
516  subgrid = rp->subgrid;
517  return true;
518  } else {
519  subgrid = NULL;
520  return false;
521  }
522  }
523 }
524 
525 template <class Point>
527 {
528  return this->getSubGrid ( subgrid, this->giveIndex ( pos ) );
529 }
530 
531 template <class Point>
533 {
534  // The bounding boxes for the sub domains.
535  FloatArray grid_point;
536  this->getGridCoord ( grid_point, pos );
537  FloatArray sub_bb0, sub_bb1;
538  sub_bb0 = grid_point;
539  sub_bb0.add ( -0.5, dx );
540  sub_bb1 = grid_point;
541  sub_bb1.add ( 0.5, dx );
542  subgrid = new ParticleGrid ( res, sub_bb0, sub_bb1 );
543 
544  int ind = this->giveIndex ( pos );
545  this->clearPosition ( ind );
546  this->data[ind] = new RefinedParticlePoint;
547  this->data[ind]->point = NULL;
548  this->data[ind]->subgrid = subgrid;
549 }
550 
554 template <class Point>
556 {
557 protected:
558  int index, endind;
561 
563  const IntArray ind0, ind1;
564  bool limited;
565 
566 public:
569  index ( 0 ), endind ( 0 ), sub_it ( NULL ), grid ( NULL ), ind0(), ind1(), limited ( false ) {}
572  index ( 0 ), endind ( g->total ), sub_it ( NULL ), grid ( g ), ind0(), ind1(), limited ( false ) {
573  if ( this->grid->data[this->index] && this->grid->data[this->index]->subgrid ) {
574  this->sub_it = new ParticleGridIterator<Point> ( this->grid->data[this->index]->subgrid );
575  }
576  }
579  index ( 0 ), sub_it ( NULL ), grid ( g ), ind0 ( ind0 ), ind1 ( ind1 ), limited ( true ) {
580  IntArray end = ind1;
581  end.add ( -1 );
582  this->endind = this->grid->giveIndex ( end ) + 1;
583  this->pos = ind0;
584  this->index = this->grid->giveIndex ( ind0 );
585  if ( this->grid->data[this->index] && this->grid->data[this->index]->subgrid ) {
586  this->sub_it = new ParticleGridIterator<Point> ( this->grid->data[this->index]->subgrid );
587  }
588  }
591  index ( x.index ), sub_it ( x.sub_it ), grid ( x.grid ), ind0 ( x.ind0 ), ind1 ( x.ind1 ), limited ( x.limited ) { }
594  if ( this->sub_it ) {
595  delete sub_it;
596  }
597  }
598 
599  bool end() const {
600  return this->index >= this->endind;
601  }
602 
603  Point *getPoint() {
604  if ( this->end() ) {
605  return NULL;
606  }
607  if ( this->subGridActive() ) {
608  return this->sub_it->getPoint();
609  }
610  if ( this->grid->data[this->index] != NULL ) {
611  return this->grid->data[this->index]->point;
612  }
613  return NULL;
614  }
615 
616  int getIndex() {
617  return this->index;
618  }
619 
620  void setPoint ( Point *p ) {
621  if ( this->end() ) {
622  OOFEM_ERROR ( "Can't set element in outside grid" );
623  }
624  if ( this->subGridActive() ) {
625  this->sub_it->setPoint ( p );
626  }
627  this->grid->setPoint ( p, this->index );
628  }
629 
630  bool subGridActive() const {
631  return this->sub_it != NULL;
632  }
633 
634  void getGridPoint ( FloatArray &x ) {
635  if ( this->subGridActive() ) {
636  this->sub_it->getGridPoint ( x );
637  } else {
638  this->grid->getGridCoord ( x, this->index );
639  }
640  }
641 
643  void operator++() {
644  if ( this->subGridActive() ) {
645  this->sub_it++;
646  if ( !this->sub_it->end() ) {
647  return;
648  } else {
649  delete this->sub_it;
650  this->sub_it = NULL;
651  }
652  }
653  this->index++;
654  if ( this->limited ) {
655  this->pos ( 0 ) ++;
656  for ( int i = 0; i < this->pos.giveSize() - 1; ++i ) {
657  if ( this->pos ( i ) >= this->ind1 ( i ) ) {
658  this->pos ( i ) = this->ind0 ( i );
659  this->pos ( i+1 ) ++;
660  } else {
661  break;
662  }
663  }
664  index = this->grid->giveIndex ( pos );
665  }
666  if ( !this->end() && this->grid->data[this->index] && this->grid->data[this->index]->subgrid ) {
667  this->sub_it = new ParticleGridIterator<Point> ( this->grid->data[this->index]->subgrid );
668  }
669  }
670 
671  std :: string errorInfo(const char *func) const { return std :: string("ParticleGridIterator :: ") + func; }
672 
673  friend class ParticleGrid<Point>;
674 };
675 
676 } // end namespace oofem
677 #endif // particlegrid_h
int getResolution(int i)
Returns the resolution in given dimension.
Definition: particlegrid.h:144
bool getSubGrid(ParticleGrid< Point > *&subgrid, const IntArray &pos) const
Gives the sub-grid at the position.
Definition: particlegrid.h:526
void getBoundingBox(const FloatArray &x0, const FloatArray &x1, IntArray &ind0, IntArray &ind1) const
Finds the indices [ind0, ind1) of the bounding box [x0,x1).
Definition: particlegrid.h:361
A recursive iterator for a grid with refinements.
Definition: particlegrid.h:49
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
ParticleGridIterator(ParticleGrid< Point > *g, IntArray ind0, IntArray ind1)
Constructor.
Definition: particlegrid.h:578
void getGridPoint(FloatArray &x)
Definition: particlegrid.h:634
IntArray res_prod
Helper for index <-> position, the cumulative product of res.
Definition: particlegrid.h:83
ParticleGridIterator()
Constructor.
Definition: particlegrid.h:568
FloatArray dx
Grid increments.
Definition: particlegrid.h:79
int getTotal() const
Total number potential points.
Definition: particlegrid.h:127
int getNumberOfPoints() const
Number of active points.
Definition: particlegrid.h:288
RefinedParticlePoint ** data
Particle data structure.
Definition: particlegrid.h:81
Particle grid data structure for n-D grids.
Definition: particlegrid.h:57
Class implementing an array of integers.
Definition: intarray.h:61
void appendAllPoints(std::list< Point * > &answer)
Definition: particlegrid.h:430
double getGridStep(int i) const
Returns the grid increment.
Definition: particlegrid.h:152
int giveDimensions()
Returns Number of dimensions of grid.
Definition: particlegrid.h:123
void createSubGrid(ParticleGrid< Point > *&subgrid, const IntArray &res, const IntArray &pos)
Creates a 2 by 2 sub-grid at the given position.
Definition: particlegrid.h:532
ParticleGridIterator(ParticleGrid< Point > *g)
Constructor.
Definition: particlegrid.h:571
ParticleGridIterator< Point > iterator
List iterator type.
Definition: particlegrid.h:61
int n
Number of dimensions of the grid.
Definition: particlegrid.h:71
#define OOFEM_ERROR(...)
Definition: error.h:61
ParticleGridIterator(const ParticleGridIterator< Point > &x)
Copy constructor.
Definition: particlegrid.h:590
iterator begin()
Returns an iterator over the entire grid (with subgrids)
Definition: particlegrid.h:383
Recursive data structure for.
Definition: particlegrid.h:65
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
std::string errorInfo(const char *func) const
Definition: particlegrid.h:671
void add(int val)
Adds given scalar to all values of receiver.
Definition: intarray.C:58
Class representing vector of real numbers.
Definition: floatarray.h:82
void givePosition(IntArray &pos, int index) const
Translates from total position to n-D position.
Definition: particlegrid.h:335
void operator++()
Lets the iterator step forward to the next element.
Definition: particlegrid.h:643
FloatArray bb0
Bounding boxes.
Definition: particlegrid.h:77
void getPosition(const FloatArray &x, IntArray &pos) const
Finds the position closest to coordinate x.
Definition: particlegrid.h:372
int giveIndex(const IntArray &pos) const
Translates from n-D position to total position.
Definition: particlegrid.h:325
IntArray res
Resolution in each dimension.
Definition: particlegrid.h:73
~ParticleGrid()
Destructor.
Definition: particlegrid.h:278
void setPoint(Point *point, const IntArray &pos)
Sets a point in the grid.
Definition: particlegrid.h:453
std::string errorInfo(const char *func) const
Definition: particlegrid.h:230
void getGridCoord(FloatArray &answer, const IntArray &pos) const
Gives the real coordinates for the given identifier.
Definition: particlegrid.h:344
void getPointsWithin(std::list< Point * > &answer, const FloatArray &x0, const FloatArray &x1)
Definition: particlegrid.h:399
int total
Total grid points.
Definition: particlegrid.h:75
int min(int i, int j)
Returns smaller value from two given decimals.
Definition: mathfem.h:59
void init(const IntArray &res, const FloatArray &bb0, const FloatArray &bb1)
Initiation of structure, used by constructors.
Definition: particlegrid.h:248
ParticleGrid< Point > * grid
Definition: particlegrid.h:560
int giveSize() const
Definition: intarray.h:203
the oofem namespace is to define a context or scope in which all oofem names are defined.
bool isEmpty() const
Returns true if the entire grid is empty.
Definition: particlegrid.h:306
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
bool getPoint(Point *&answer, const IntArray &pos) const
Gives the point at the position.
Definition: particlegrid.h:447
iterator beginAt(const FloatArray &x0, const FloatArray &x1)
Returns an iterator over specified region.
Definition: particlegrid.h:390
void clearPosition(const IntArray &pos)
Deletes any preexisting data at position.
Definition: particlegrid.h:486
ParticleGrid(const IntArray &res, const FloatArray &bb0, const FloatArray &bb1)
Creates a new empty particle grid.
Definition: particlegrid.h:236
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631
ParticleGridIterator< Point > * sub_it
Definition: particlegrid.h:559
~ParticleGridIterator()
Destructor.
Definition: particlegrid.h:593

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011