Parallel Finite Element - General geometry Ewald-like Method
Part of Continuum-particle Simulation Suite under MICCOM
point_mesh.h
Go to the documentation of this file.
1 // Parallel Finite Element-General Geometry Ewald-like Method.
2 // Copyright (C) 2015-2016 Xujun Zhao, Jiyuan Li, Xikai Jiang
3 
4 // This code is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 
10 // This code is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 
15 
16 // You should have received a copy of the GNU General Public
17 // License along with this code; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20 
21 #pragma once
22 
23 // libmesh Includes -----------------------------------
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/reference_counted_object.h"
26 #include "libmesh/parallel_object.h"
27 #include "libmesh/mesh.h"
28 #ifdef LIBMESH_HAVE_NANOFLANN
29 # include "libmesh/nanoflann.hpp"
30 #endif
31 
32 
33 // Local Includes -----------------------------------
34 #include "point_particle.h"
35 #include "polymer_chain.h"
36 #include "pm_periodic_boundary.h"
37 #include "rigid_particle.h"
38 
39 // C++ Includes -------------------------------------
40 //#include <stdio.h>
41 #include <string>
42 #include <vector>
43 
44 
45 namespace libMesh
46 {
47 
48 
49 class PointParticle;
50 
51 template <unsigned int KDDim>
52 class ParticleMesh;
53 
54 /*
55  * This template class defines point-point and point-mesh mapping relations.
56  * It takes advantage of KD Tree library nanoflann to build the neigbor list.
57  */
58 
59 template <unsigned int KDDim>
60 class PointMesh : public ReferenceCountedObject<PointMesh<KDDim> >,
61  public ParallelObject
62 {
63 protected:
64 
65 #ifdef LIBMESH_HAVE_NANOFLANN
66 
74  template <unsigned int PLDim>
75  class PointListAdaptor
76  {
77  private:
78  // use ref, which will point to the address of _particles in the parent class
79  // when _particles is modified, this ref needs not to be updated
80  const std::vector<PointParticle*> &_pts;
81 
82  public:
83  // Constructor of PointListAdaptor
84  PointListAdaptor (const std::vector<PointParticle*> &particles)
85  : _pts(particles)
86  { }
87 
91  typedef Real coord_t;
92  typedef std::size_t size_t;
93 
97  inline size_t kdtree_get_point_count() const { return _pts.size(); }
98 
103  inline coord_t kdtree_distance(const coord_t *p1, const size_t idx_p2, size_t size) const
104  {
105  libmesh_assert_equal_to (size, PLDim);
106  libmesh_assert_less (idx_p2, _pts.size());
107 
108  // retrieve the point data with index = idx_p2
109  const Point &p2( _pts[idx_p2]->point() );
110 
111  switch (size)
112  {
113  case 3:
114  {
115  const coord_t d0=p1[0] - p2(0);
116  const coord_t d1=p1[1] - p2(1);
117  const coord_t d2=p1[2] - p2(2);
118  return d0*d0 + d1*d1 + d2*d2;
119  }
120 
121  case 2:
122  {
123  const coord_t d0=p1[0] - p2(0);
124  const coord_t d1=p1[1] - p2(1);
125  return d0*d0 + d1*d1;
126  }
127 
128  case 1:
129  {
130  const coord_t d0=p1[0] - p2(0);
131  return d0*d0;
132  }
133  default:
134  libmesh_error_msg("ERROR: unknown size " << size);
135  }
136 
137  return -1.0;
138  } // end of kdtree_distance()
139 
145  inline coord_t kdtree_get_pt(const size_t idx, int dim) const
146  {
147  libmesh_assert_less (dim, (int) PLDim);
148  libmesh_assert_less (idx, _pts.size());
149  libmesh_assert_less (dim, 3);
150 
151  const Point &p(_pts[idx]->point() );
152  if (dim==0) return p(0);
153  if (dim==1) return p(1);
154  return p(2);
155  } // end of kdtree_get_pt()
156 
163  template <class BBOX>
164  bool kdtree_get_bbox(BBOX & /* bb */) const { return false; }
165 
166  }; // end of class PointListAdaptor
167 
168 
169  typedef nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<Real,PointListAdaptor<KDDim> >,
170  PointListAdaptor<KDDim>,
171  KDDim> kd_tree_t;
172 
173  /*
174  * If a data member is declared mutable, then it is legal to assign a value
175  to this data member from a const member function.
176  */
177  mutable UniquePtr<kd_tree_t> _kd_tree;
178 
179 #endif // LIBMESH_HAVE_NANOFLANN
180 
181 
185  virtual void construct_kd_tree ();
186 
187 
188 
189 
190 public:
191  /* Constructor
192  * This creates the PointMesh class using the ParticleMesh object,
193  * but does NOT change the ParticleMesh
194  */
196  const Real& search_radius_p,
197  const Real& search_radius_e);
198 
199 
200  /*
201  * Constructor
202  * This creates the PointMesh class using multiple PolymerChains
203  * FIXME: NOT used currently, and need to be modified!
204  */
205  PointMesh(MeshBase& mesh,
206  std::vector<PolymerChain>& polymer_chains,
207  const Real& search_radius_p,
208  const Real& search_radius_e);
209 
210 
211  /*
212  * Constructor
213  * This creates the PointMesh class using single PolymerChain
214  */
215  PointMesh(MeshBase& mesh,
217  const Real& search_radius_p,
218  const Real& search_radius_e);
219 
220 
221  /*
222  * Destructor
223  */
224  ~PointMesh();
225 
226 
227  /*
228  * Read points coordinate data from file
229  */
230  // void read_points_data(const std::string& filename);
231 
232 
237  // void generate_random_points(const std::size_t N,
238  // const Real bbox_XA, const Real bbox_XB,
239  // const Real bbox_YA, const Real bbox_YB,
240  // const Real bbox_ZA, const Real bbox_ZB);
241 
242 
243  // void generate_random_points(const std::size_t N,
244  // const Point& bbox_min,
245  // const Point& bbox_max);
246 
247 
248 
252  std::vector<PointParticle*> particles() const { return _particles; }
253 
254 
258  PolymerChain* polymer_chain() const { return _polymer_chain; }
259 
260 
264  std::size_t num_particles() const { return _particles.size(); }
265 
266 
267  std::size_t num_chains() const{ return _polymer_chain -> n_chains(); }
268 
272  std::size_t num_bonds() const { return _polymer_chain->n_bonds(); }
273 
274 
278  bool is_sorted() const { return _is_sorted; }
279 
280 
286  const std::map<const std::size_t, std::vector<std::size_t> >& elem_neighbor_list() const
287  { return _elem_neighbor_list; }
288 
289 
294  const std::vector<std::size_t> elem_neighbor_list(const Elem* elem)
295  {
296  const std::size_t elem_id = elem->id();
297  return _elem_neighbor_list[elem_id];
298  //return _elem_neighbor_list.at(elem_id); // not work well
299  }
300 
301 
306  const std::vector<std::size_t> local_elem_neighbor_list(const Elem* elem)
307  {
308  const std::size_t elem_id = elem->id();
309  return _local_elem_neighbor_list[elem_id];
310  }
311 
312 
317  virtual void clear_kd_tree();
318 
319 
320 
329  virtual void build_particle_neighbor_list(const Point &query_pt,
330  const bool is_sorted,
331  std::vector<std::pair<std::size_t,Real> >& IndicesDists);
332 
333 
341  virtual void build_particle_neighbor_list();
342 
343 
344 
345  /*** NOT ACTUALLY USED NOW, written only for the purpose of comparing with KD-Tree!
346  *
347  * Build the neighbor list for all the particles directly! (N^2 complexity)
348  * NOTE that the particle list constructed from this function is not sorted!
349  ***/
351 
355  virtual void reinit_neighbor_vector();
356 
366  virtual void build_elem_neighbor_list(const Elem* elem,
367  const bool is_sorted,
368  std::vector<std::size_t>& n_list);
369 
370 
377  virtual void build_elem_neighbor_list();
378 
379 
380 
381  /*
382  * Reinit the point-mesh system. This includes:
383  * (1) build the point-point neighbor list according to search radius;
384  * (2) build the element-point neighbor list according to search radius;
385  * (3) set the elem_id and proc_id for points
386  * ---- force recalculation is not reinitialized here, but in ForceField:
387  */
388  void reinit(const bool& with_hi,
389  bool& neighbor_list_update_flag);
390 
391 
392 
393  /*
394  * update the (input) particle_mesh object according to the point_mesh
395  * This function updates the input class, but doesn't change its own data
396  */
397  void update_particle_mesh(ParticleMesh<KDDim>* particle_mesh) const;
398 
399 
400  /*
401  * update the point_mesh object according to the (input) particle_mesh.
402  * This function updates the class itself only, but doesn't change the input
403  */
404  // void update_point_mesh(const ParticleMesh<KDDim>* particle_mesh);
405 
406 
410  void print_point_info() const;
411 
412 
416  void print_elem_neighbor_list(std::ostream & out = libMesh::out) const;
417 
418 
419 
423  void set_search_radius(const Real rp, const Real re)
424  {
425  _search_radius_p = rp;
426  _search_radius_e = re;
427  };
428 
429 
433  Real search_radius(const std::string & p_e) const;
434 
435 
440  { _periodic_boundary = &_periodic_bdry; }
441 
442 
447  { return _periodic_boundary; }
448 
453  void set_bead_velocity(const std::vector<Real>& vel);
454 
459  // void set_rigid_particle_velocity();
460 
461 
462 
466  const Real& maximum_bead_velocity() const {return _max_velocity_magnitude;};
467 
471  const Real& minimum_bead_velocity() const {return _min_velocity_magnitude;};
472 
476  const void write_initial_surface_node_pos() const;
477 
478 
479 private:
480 
481  // Mesh base (for simulaiton domain)
482  MeshBase& _mesh;
483 
484  // Search radius (around a particle)
485  Real _search_radius_p;
486 
487  // Search radius (around an element) whose value must be larger than hmax!
488  Real _search_radius_e;
489 
490  // A vector that store the pointers to PointParticle(save storage)
491  std::vector<PointParticle*> _particles;
492 
493  // A vector that store the pointers to RigidParticle(save storage)
494  std::vector<RigidParticle*> _rigid_particles;
495 
496  // number of point particles
497  std::size_t _num_point_particles;
498 
499  // number of rigid particles
500  std::size_t _num_rigid_particles;
501 
502  // Polymer chain
503  PolymerChain* _polymer_chain;
504 
505  // The point list adapter
506  // - interface to the nanoflann in order to construct KD-Tree
507  PointListAdaptor<KDDim> _point_list_adaptor;
508 
509  // Is the neighbor list sorted? set true defaultly (particle/elem neighbor list)
510  bool _is_sorted;
511 
512  // Element neighbor list: mapping between Elem and particle id's around it
513  // This is NOT necessary to be on all the processors in implementation,
514  // but we do this here only for test purpose. For local build
515  std::map<const std::size_t, std::vector<std::size_t> > _elem_neighbor_list;
516  std::map<const std::size_t, std::vector<std::size_t> > _local_elem_neighbor_list;
517 
518  // Pointer to the Periodic boundary condition
519  PMPeriodicBoundary* _periodic_boundary;
520 
521  // bead velocity magniture array
522  std::vector<Real> _velocity_magnitude;
523 
524  // maximum bead/surface node velocity magniture
525  Real _max_velocity_magnitude;
526 
527  // minimum bead/surface node velocity magniture
528  Real _min_velocity_magnitude;
529 }; // end of the class
530 
531 
532 } // end name space
virtual void reinit_neighbor_vector()
Definition: point_mesh.C:511
virtual void construct_kd_tree()
Definition: point_mesh.C:305
Definition: particle_mesh.h:76
void add_periodic_boundary(PMPeriodicBoundary &_periodic_bdry)
Definition: point_mesh.h:439
const Real & maximum_bead_velocity() const
Definition: point_mesh.h:466
PMPeriodicBoundary * pm_periodic_boundary()
Definition: point_mesh.h:446
const void write_initial_surface_node_pos() const
Definition: point_mesh.C:1070
PolymerChain * polymer_chain() const
Definition: point_mesh.h:258
virtual void build_particle_neighbor_list()
Definition: point_mesh.C:431
const std::vector< std::size_t > elem_neighbor_list(const Elem *elem)
Definition: point_mesh.h:294
virtual void build_particle_neighbor_list_naively()
Definition: point_mesh.C:462
std::size_t num_chains() const
Definition: point_mesh.h:267
Definition: brownian_system.h:58
Definition: pm_periodic_boundary.h:46
Real search_radius(const std::string &p_e) const
Definition: point_mesh.C:970
std::vector< PointParticle * > particles() const
Definition: point_mesh.h:252
void set_bead_velocity(const std::vector< Real > &vel)
Definition: point_mesh.C:1051
std::size_t num_bonds() const
Definition: point_mesh.h:272
std::size_t num_particles() const
Definition: point_mesh.h:264
Definition: polymer_chain.h:47
void update_particle_mesh(ParticleMesh< KDDim > *particle_mesh) const
Definition: point_mesh.C:918
void set_search_radius(const Real rp, const Real re)
Definition: point_mesh.h:423
const std::vector< std::size_t > local_elem_neighbor_list(const Elem *elem)
Definition: point_mesh.h:306
~PointMesh()
Definition: point_mesh.C:161
const Real & minimum_bead_velocity() const
Definition: point_mesh.h:471
virtual void build_elem_neighbor_list()
Definition: point_mesh.C:622
bool is_sorted() const
Definition: point_mesh.h:278
virtual void clear_kd_tree()
Definition: point_mesh.C:329
PointMesh(libMesh::ParticleMesh< KDDim > &particle_mesh, const Real &search_radius_p, const Real &search_radius_e)
Definition: point_mesh.C:47
void reinit(const bool &with_hi, bool &neighbor_list_update_flag)
Definition: point_mesh.C:830
Definition: point_particle.h:54
void print_elem_neighbor_list(std::ostream &out=libMesh::out) const
Definition: point_mesh.C:1016
const std::map< const std::size_t, std::vector< std::size_t > > & elem_neighbor_list() const
Definition: point_mesh.h:286
void print_point_info() const
Definition: point_mesh.C:989
Definition: particle_mesh.h:57