NDDEM
Coarsing.h
Go to the documentation of this file.
1 
28 #ifndef COARSING_H
29 #define COARSING_H
30 
31 #include <cstdlib>
32 #include <cstdio>
33 #include <vector>
34 #include "Typedefs.h"
35 #include <boost/random.hpp>
36 #include <fstream>
37 #include <boost/math/special_functions/factorials.hpp>
38 #include <boost/math/special_functions/beta.hpp>
39 #include <boost/crc.hpp>
40 #include <map>
41 #include <variant>
42 
43 #ifdef NETCDF
44 #include <netcdf.h>
45 #endif
46 
47 #ifdef NRRDIO
48 #include "../NrrdIO-1.11.0-src/NrrdIO.h"
49 #endif
50 
51 #ifdef MATLAB
52 #include "mat.h"
53 #endif
54 
55 #include "Eigen/Dense"
56 #include "Eigen/Geometry"
57 
58 
59 using namespace std ;
60 
61 double Volume (int d , double R) ;
62 
63 enum TensorOrder {NONE=-1, SCALAR=0, VECTOR=1, TENSOR=2} ;
66 enum Pass {Pass1=1, Pass2=2, Pass3=4, Pass4=8, Pass5=16,
67  VelFluct=256, RotFluct=512} ;
68 
69 inline Pass operator|(Pass a, Pass b){return static_cast<Pass>(static_cast<int>(a) | static_cast<int>(b));}
70 //inline Pass operator|=(Pass a, const Pass b){return static_cast<Pass>(static_cast<int>(a) | static_cast<int>(b));} // Not working for some reason
71 inline bool operator& (Pass a, Pass b) { return (static_cast<int>(a) & static_cast<int>(b)) ; }
72 
73 //=========================================================
75 class CGPoint
76 {
77 public :
78  CGPoint(int dd, v1d loc) {d=dd ; location=loc ; }
79 
83  //Useful things
84  vector <int> neighbors ;
85  int d ;
86 } ;
87 //-------------------------
89 struct Field {
91  string name ;
95  int datalocation = -1;
96 };
97 //-------------------------
99 struct Data {
100 public:
101  Data () : radius(nullptr), mass(nullptr), Imom(nullptr), id1(nullptr), id2(nullptr) {}
102 int N = 0 ;
103 double * radius ;
104 double * mass ;
105 double *Imom ;
106 vector <double *> pos ;
107 vector <double *> vel ;
108 vector <double *> omega ;
109 vector <double *> orient ;
110 
111 // Superquadrics
112 vector <double *> superquadric ;
113 
116 
117 int Ncf ;
118 double * id1 ;
119 double * id2 ;
120 vector <double *> pospq ;
121 vector <double *> lpq ;
122 vector <double *> fpq;
123 vector <double *> mpq;
124 vector <double *> mqp ;
125 
126 // Exta fields if needed
127 vector<double*> extra ;
128 vector<std::tuple<std::string, int, int>> extrafields ;
129 
130 // Some useful functions
131 int Nnonper=-1 ;
132 int random_test (int N, int Ncf, int d, v2d box ) ;
133 int compute_lpq (int d) ;
134 int periodic_atoms (int d, v2d bounds, int pbc, v1d Delta, bool omegainclude) ;
135 int clean_periodic_atoms () {if (Nnonper==-1) printf("ERR: must call periodic_atoms before cleaning the periodic_atoms\n") ; else N=Nnonper ; return 0 ; }
136 bool check_field_availability(string name) ;
137 int add_extra_field (int length, std::string name)
138 {
139  extrafields.push_back({name, length, extra.size()}) ;
140  extra.resize(extra.size()+length) ;
141  return std::get<2>(extrafields.back());
142 }
143 } ;
144 //------------------------------------------------------
145 #include "WindowLibrary.h"
146 
147 //=========================================================
150 class Coarsing
151 {
152 public :
153  Coarsing (int dd, v1i nnpt, v2d bbox, int T) : cT(0), flags(0)
154  {
155  d=dd ; npt=nnpt ; box=bbox ; Time=T ;
156  dx.resize(d, 0) ;
157  for (int i=0 ; i<d ; i++)
158  dx[i]=((box[1][i]-box[0][i])/double(npt[i])) ;
159  double w= (*std::min_element(dx.begin(),dx.end())*2) ; // w automatically set
160  cutoff=2.5*w ; //TODO
161  printf("Window and cutoff: %g %g \n", w, cutoff) ;
162  //for (int i=0 ; i<d ; i++)
163  // printf("%d %d %g %g %g|", d, npt[i], box[1][i], box[0][i], dx[i]) ; fflush(stdout) ;
164  grid_generate() ;
165  //grid_neighbour() ;
166  set_field_struct() ;
167  Window = new LibLucy3D( &data, w, d) ;
168  }
169  ~Coarsing() { if (Window != nullptr) delete Window ;
170  if (CGPtemp != nullptr) delete CGPtemp ; }
171 
172  int d ;
173  int Npt;
174  int Time;
175  int cT ;
176  double cutoff ;
177  vector <CGPoint> CGP ;
178  vector <CGPoint> * CGPtemp = nullptr ;
179  vector <int> npt;
180  vector <int> nptcum ;
181  v1d dx ;
182  v2d box ;
183  LibBase * Window = nullptr ;
184  std::variant<Eigen::Matrix3d, Eigen::Quaternion<double>> original_orientation = Eigen::Quaternion<double>(0,0,0,1) ;
185 
186  // Fields variable and function
187  vector <struct Field > FIELDS ;
188  unsigned int flags ;
189  vector <int> Fidx ;
190  vector <std::pair<Field *, int>> Fcols ;
191 
192  //vector <string> Fields, Fname ; ///< Flagged field names
193  //vector <TensorOrder> Ftype ; ///< Flagged field types
194  int get_id(string nm) ;
195  struct Field * get_field(string nm) ;
196  Pass set_flags (vector <string> s) ;
197 
198  // Subfield variables and functions
199  vector <struct Field> SUBFIELDS ;
200  vector <std::pair<struct Field *, uint64_t>> subflags ;
201  vector <std::pair<Field *, std::vector<std::pair<Field*, int>> >> SFcols ;
203  int grid_getsubfields() ;
204  struct Field * get_subfield(string nm) ;
205 
206  // Grid functions
207  int set_field_struct() ;
208  int add_extra_field(string name, TensorOrder order, FieldType type) ;
209  int setWindow (Windows win, double w, vector <bool> per ={}, vector<int> boxes = {}, vector<double> deltas = {}, vector<vector<double>> bounds={{}}) ;
210  template <Windows W> int setWindow () ;
211  template <Windows W> int setWindow (double w) ;
212  template <Windows W> int setWindow (vector<vector<double>> &) ;
213  template <Windows W> int setWindow (double w, vector<bool> per, vector<int> boxes, vector<double> deltas) ;
214  int grid_generate() ;
215  int grid_neighbour() ;
216  std::map<std::string, size_t> grid_setfields() ;
217  int grid_getfields() ;
218  v2d get_bounds() ;
219  CGPoint * reverseloop (string type) ;
220  int find_closest (int id) ;
221  int find_closest_pq (int id) ;
222  v1d interpolate_vel(int id, bool usetimeavg=false) { return interpolate_vel_nearest (id, usetimeavg) ; }
223  v1d interpolate_rot(int id, bool usetimeavg=false) { return interpolate_rot_nearest (id, usetimeavg) ; }
224  v1d interpolate_vel_nearest (int id, bool usetimeavg=false) ;
225  v1d interpolate_rot_nearest (int id, bool usetimeavg=false) ;
226  v1d interpolate_vel_trilinear (int id, bool usetimeavg) ;
227  template <int D> v1d interpolate_vel_multilinear (int id, bool usetimeavg);
228  template <typename T> void add_rotated_quat(double * p, double weight, Eigen::Quaternion<double> q, T original) ;
229 
230  int idx_FastFirst2SlowFirst (int n) ;
231 
232  // Windowing functions
233  //double window(double r) {Lucy(r) ; }
234  //double window_int (v1d r1, v1d lpq, v1d x) {printf("Numerical integration of wpqf not implemented\n") ; } ///< Numerical integration: not implemented
235  //double window_int(double r1, double r2) {return window_avg(r1, r2) ; } ///< Overload to avoid integration ...
236  //double window_avg (double r1, double r2) {return (0.5*(Lucy(r1)+Lucy(r2))) ; }
237  //double Lucy (double r) {static double cst=105./(16*M_PI*w*w*w) ; if (r>=w) return 0 ; else {double f=r/w ; return (cst*(-3*f*f*f*f + 8*f*f*f - 6*f*f +1)) ; }}
238  double normdiff (v1d a, v1d b) {double res=0 ; for (int i=0 ; i<d ; i++) res+=(a[i]-b[i])*(a[i]-b[i]) ; return (sqrt(res)) ; } ;
239  // Coarse graining functions
240  int pass_1 () ;
241  int pass_2 (bool usetimeavg=false) ;
242  int pass_3 () ;
243  int pass_4 () ;
244  int pass_5 () ;
245  int compute_fluc_vel (bool usetimeavg=false) ;
246  int compute_fluc_rot (bool usetimeavg=false) ;
247  bool hasvelfluct=false, hasrotfluct=false ;
248 
249  // Data handling functions
250 
251  struct Data data ;
252 
253  // Time and output handling
254  int mean_time(bool temporary=false) ;
255  int write_vtk(string sout) ;
256  int write_netCDF (string sout) ;
257  int write_NrrdIO (string path) ;
258  int write_matlab (string path, bool squeeze = false) ;
259  int write_numpy (string path, bool squeeze = false) ;
260  int write_numpy_npy (string path, bool squeeze) ;
261  std::pair<size_t, uint8_t*> write_numpy_locbuffer (bool squeeze) {return write_numpy_buffer(-2, squeeze) ; }
262  std::pair<size_t, uint8_t*> write_numpy_buffer (int id, bool squeeze) ;
263 } ;
264 
265 
266 //-------------------------------------------------------
267 template <Windows W>
269 { double w= (*std::min_element(dx.begin(),dx.end())*1) ; // w automatically set
270  setWindow<W>(w) ; return 0 ; }
271 //-------------------------------------------------------
272 template <Windows W>
273 int Coarsing::setWindow (double w)
274 {
275  static_assert(W != Windows::LucyND_Periodic) ;
276  switch (W) {
277  case Windows::Rect3D :
278  Window=new LibRect3D (&data, w, d) ;
279  break ;
281  Window=new LibSphere3DIntersect (&data, w, d) ;
282  break ;
284  Window= new LibSphere3DIntersect_MonteCarlo(&data, w, d) ;
285  break ;
287  Window=new LibSphereNDIntersect (&data, w, d) ;
288  break ;
289  case Windows::Lucy3D :
290  Window=new LibLucy3D (&data, w, d) ;
291  break ;
293  Window=new LibLucy3DFancyInt (&data, w, d) ;
294  break ;
295  case Windows::Hann3D :
296  Window=new LibHann3D (&data, w, d) ;
297  break ;
298  case Windows::RectND :
299  Window=new LibRectND (&data, w, d) ;
300  break ;
301  case Windows::LucyND :
302  Window=new LibLucyND (&data, w, d) ;
303  break ;
304  default:
305  printf("Unknown window, check Coarsing::setWindow #2") ;
306  }
307  cutoff = Window->cutoff() ;
308  printf("Window and cutoff: %g %g \n", w, cutoff) ;
309  return 0 ;
310 }
311 //-------------------------------------------------------
312 template <Windows W>
313 int Coarsing::setWindow (double w, vector<bool> per, vector<int> boxes, vector<double> deltas)
314 {
315  static_assert(W == Windows::LucyND_Periodic) ;
316  cutoff = Window->cutoff() ;
317  printf("Window and cutoff: %g %g \n", w, cutoff) ;
318 
319  int p = 0 ;
320  for (size_t i=0 ; i<per.size() ; i++)
321  if (per[i])
322  p |= (1<<i) ;
323 
324  Window = new LibLucyND_Periodic (&data,w,d,p,boxes,deltas) ;
325 return 0 ;
326 }
327 //-----------------------------------------------------------
328 template <Windows W>
329 int Coarsing::setWindow (vector<vector<double>> & bounds)
330 {
331  static_assert(W == Windows::RVE) ;
332  double scale = 1 ;
333  for (size_t i =0 ; i<bounds.size() ; i++)
334  scale /= (bounds[i][1] - bounds[i][0]) ;
335 
336  Window = new LibRVE (scale) ;
337 return 0 ;
338 }
339 
340 //-----------------------------------------------------------------------------------------
341 template <int D>
343 {
344 int pts[1<<D][D] ;
345 const static int idvel=get_id("VAVG") ;
346 
347 auto clip = [&](double a, int maxd){if (a<0.) return(0) ; else if (a>=maxd) return (maxd-1) ; else return (static_cast<int>(a)) ; } ;
348 
349 
350 // Determine the floor and ceil indices in each dimension
351 std::vector<int> i0(D), i1(D);
352 for (int dd = 0; dd < D; ++dd) {
353  double val = (data.pos[dd][id] - CGP[0].location[dd]) / dx[dd];
354  i0[dd] = clip(std::floor(val), npt[dd]);
355  i1[dd] = clip(std::ceil(val), npt[dd]);
356  if (npt[dd]==1) continue ;
357  if (i0[dd]==i1[dd])
358  {
359  if (i0[dd]==0) i1[dd]++ ;
360  else if (i0[dd]==npt[dd]-1) i0[dd]-- ;
361  else i1[dd] ++ ; // If we are exactly on a point, just push one of the corner. The weights should be 0 anyway for this point.
362  }
363 }
364 
365 // Construct all corner indices of the cube
366 int n_corners = 1<<D ;
367 for (int c = 0; c < n_corners; ++c) {
368  for (int dd = 0; dd < D; ++dd) {
369  pts[c][dd] = ((c >> dd) & 1) ? i1[dd] : i0[dd];
370  }
371 }
372 
373 // Convert multi-dim index to linear index
374 std::vector<int> lin_idx(n_corners);
375 for (int c = 0; c < n_corners; ++c) {
376  int idx = 0;
377  for (int dd = 0; dd < D; ++dd)
378  idx += nptcum[dd] * pts[c][dd];
379  lin_idx[c] = idx;
380 }
381 
382 std::vector<double> weights(n_corners, 1.0);
383 for (int i = 0; i < n_corners; ++i) {
384  for (int j = 0; j < D; ++j) {
385  double x0 = CGP[lin_idx[i]].location[j];
386  double t = (data.pos[j][id] - x0) / dx[j];
387  if (((i >> j) & 1) == 0)
388  weights[i] *= npt[j]==1?0.5:(1.0 - t);
389  else
390  weights[i] *= npt[j]==1?0.5:(1.0 + t);
391  }
392 }
393 
394 // Interpolate field
395 std::vector<double> result(D, 0.0);
396 for (int i = 0; i < n_corners; ++i)
397  for (int j = 0; j < D; ++j)
398  {
399  double val ;
400  if (usetimeavg)
401  val = (*CGPtemp)[lin_idx[i]].fields[0][idvel + j] ;
402  else
403  val = CGP[lin_idx[i]].fields[0][idvel + j];
404  result[j] += val * weights[i];
405  }
406 
407 return result ;
408 }
409 
410 
411 #endif
EIGEN_DEVICE_FUNC const FloorReturnType floor() const
Definition: ArrayCwiseUnaryOps.h:481
EIGEN_DEVICE_FUNC const CeilReturnType ceil() const
Definition: ArrayCwiseUnaryOps.h:495
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition: ArrayCwiseUnaryOps.h:187
Windows
Definition: WindowLibrary.h:2
@ Lucy3DFancyInt
@ LucyND_Periodic
@ SphereNDIntersect
@ Sphere3DIntersect_MonteCarlo
@ Sphere3DIntersect
Data computed for a single coarse graining point.
Definition: Coarsing.h:76
Main Coarse graining class.
Definition: Coarsing.h:151
The quaternion class used to represent 3D orientations and rotations.
Definition: Quaternion.h:274
A window base class that needs to be specialised to a specific CG window.
Definition: WindowLibrary.h:6
virtual double cutoff(void)
Definition: WindowLibrary.h:26
Definition: WindowLibrary.h:363
Definition: WindowLibrary.h:42
Definition: WindowLibrary.h:29
Definition: WindowLibrary.h:387
Definition: WindowLibrary.h:370
Definition: WindowLibrary.h:416
Definition: WindowLibrary.h:81
Definition: WindowLibrary.h:88
Definition: WindowLibrary.h:279
Definition: WindowLibrary.h:94
Definition: WindowLibrary.h:177
double normdiff(v1d a, v1d b)
Definition: Coarsing.h:238
vector< struct Field > SUBFIELDS
All allowed subfields.
Definition: Coarsing.h:199
vector< int > Fidx
Where the fields is referenced in the fields vector in the CGPoint. -1 if not flagged.
Definition: Coarsing.h:189
int Npt
Number of coarse graining points.
Definition: Coarsing.h:173
vector< double * > superquadric
Superquadrics information.
Definition: Coarsing.h:112
vector< double * > omega
Particle angular velocity.
Definition: Coarsing.h:108
double cutoff
CG width, and cutoff.
Definition: Coarsing.h:176
AverageType
Definition: Coarsing.h:65
Pass operator|(Pass a, Pass b)
Definition: Coarsing.h:69
double Volume(int d, double R)
Compute a sphere volume in dimension D.
Definition: Coarsing.cpp:2049
int d
Dimension.
Definition: Coarsing.h:85
vector< double * > mpq
Moment of particle 1 on 2.
Definition: Coarsing.h:123
double * radius
Particle radius.
Definition: Coarsing.h:103
TensorOrder type
Tensorial order of the field: SCALAR, VECTOR or TENSOR.
Definition: Coarsing.h:92
Pass passlevel
Identify at which moment the field gets calculated.
Definition: Coarsing.h:94
vector< double * > pospq
Location of contact point.
Definition: Coarsing.h:120
bool operator&(Pass a, Pass b)
Definition: Coarsing.h:71
void add_rotated_quat(double *p, double weight, Eigen::Quaternion< double > q, T original)
double * id2
Index of the second particle in contact.
Definition: Coarsing.h:119
vector< double * > fpq
Force at contact.
Definition: Coarsing.h:122
int Time
Total timesteps.
Definition: Coarsing.h:174
double * mass
Particle masses.
Definition: Coarsing.h:104
vector< int > neighbors
All the neighbors of the point given the window. 1st index is the point itself.
Definition: Coarsing.h:84
v2d subfields
1st dimension is time, second are subfields (ie. "TC.ev1")
Definition: Coarsing.h:81
vector< std::pair< Field *, std::vector< std::pair< Field *, int > > > > SFcols
What the subcolumns are in the CGPoint.
Definition: Coarsing.h:201
Coarsing(int dd, v1i nnpt, v2d bbox, int T)
Definition: Coarsing.h:153
vector< struct Field > FIELDS
All allowed fields (initialized in grid_getfields)
Definition: Coarsing.h:187
vector< double * > pos
Particle positions.
Definition: Coarsing.h:106
v2d box
CG point location.
Definition: Coarsing.h:182
TensorOrder
Definition: Coarsing.h:63
unsigned int flags
Flags deciding which fields to coarse-grain.
Definition: Coarsing.h:188
int clean_periodic_atoms()
Clean periodic atoms.
Definition: Coarsing.h:135
int Ncf
Number of contacts.
Definition: Coarsing.h:117
vector< double * > orient
Particle orientation (quaternions)
Definition: Coarsing.h:109
vector< double * > extra
Definition: Coarsing.h:127
int cT
Current timestep.
Definition: Coarsing.h:175
CGPoint(int dd, v1d loc)
Definition: Coarsing.h:78
int d
Number of dimensions.
Definition: Coarsing.h:172
v1d location
Location of the coarse graining point.
Definition: Coarsing.h:82
uint64_t flag
Flag for the given field.
Definition: Coarsing.h:90
double * id1
Index of first particle in contact.
Definition: Coarsing.h:118
FieldType ftype
Mainly used to identified the type of user defined fields.
Definition: Coarsing.h:93
~Coarsing()
Definition: Coarsing.h:169
v2d vel_fluc
Fluctuating velocity. Should not be externally provided but calculated, using the function Coarsing::...
Definition: Coarsing.h:114
std::pair< size_t, uint8_t * > write_numpy_locbuffer(bool squeeze)
Definition: Coarsing.h:261
vector< std::tuple< std::string, int, int > > extrafields
Definition: Coarsing.h:128
FieldType
Definition: Coarsing.h:64
double * Imom
Particle moment of inertia.
Definition: Coarsing.h:105
vector< double * > lpq
Branch vector of the contact, use compute_lpq() to populate this.
Definition: Coarsing.h:121
vector< std::pair< struct Field *, uint64_t > > subflags
Definition: Coarsing.h:200
v1d interpolate_vel_multilinear(int id, bool usetimeavg)
Definition: Coarsing.h:342
uint64_t sf_mask_eigen
Definition: Coarsing.h:202
vector< double * > mqp
Moment of particle 2 on 1.
Definition: Coarsing.h:124
string name
Name for the given field.
Definition: Coarsing.h:91
vector< std::pair< Field *, int > > Fcols
What the columns are in the CGPoint.
Definition: Coarsing.h:190
v1d interpolate_rot(int id, bool usetimeavg=false)
Interpolate the angular velocity.
Definition: Coarsing.h:223
Pass
Definition: Coarsing.h:66
v1d dx
Distances between CG points.
Definition: Coarsing.h:181
int add_extra_field(int length, std::string name)
Definition: Coarsing.h:137
v2d rot_fluc
Fluctuating angular velocity. Should not be externally provided but calculated, using the function Co...
Definition: Coarsing.h:115
v2d fields
1st dimension is time, second are fields
Definition: Coarsing.h:80
v1d interpolate_vel(int id, bool usetimeavg=false)
Interpolate the velocity.
Definition: Coarsing.h:222
vector< int > nptcum
Cumulated number of points per dimensions (usefull for quick finding of the closest CG for a grain)
Definition: Coarsing.h:180
vector< double * > vel
Particle velocity.
Definition: Coarsing.h:107
vector< int > npt
Number of points per dimension.
Definition: Coarsing.h:179
int setWindow()
Set the windowing function.
Definition: Coarsing.h:268
Data()
Definition: Coarsing.h:101
vector< CGPoint > CGP
List of Coarse Graining points.
Definition: Coarsing.h:177
@ Pre5
Definition: Coarsing.h:65
@ Final
Definition: Coarsing.h:65
@ None
Definition: Coarsing.h:65
@ IntermediateAndPre5
Definition: Coarsing.h:65
@ Both
Definition: Coarsing.h:65
@ Intermediate
Definition: Coarsing.h:65
@ VECTOR
Definition: Coarsing.h:63
@ SCALAR
Definition: Coarsing.h:63
@ NONE
Definition: Coarsing.h:63
@ TENSOR
Definition: Coarsing.h:63
@ Defined
Definition: Coarsing.h:64
@ Particle
Definition: Coarsing.h:64
@ Fluctuation
Definition: Coarsing.h:64
@ Contact
Definition: Coarsing.h:64
@ Pass1
Definition: Coarsing.h:66
@ Pass3
Definition: Coarsing.h:66
@ Pass4
Definition: Coarsing.h:66
@ Pass2
Definition: Coarsing.h:66
@ VelFluct
Definition: Coarsing.h:67
@ RotFluct
Definition: Coarsing.h:67
@ Pass5
Definition: Coarsing.h:66
vector< vector< double > > v2d
Definition: Typedefs.h:10
vector< int > v1i
Definition: Typedefs.h:18
@ Imom
Definition: Typedefs.h:19
@ id2
Definition: Typedefs.h:19
@ id1
Definition: Typedefs.h:19
@ radius
Definition: Typedefs.h:19
@ mass
Definition: Typedefs.h:19
vector< double > v1d
Definition: Typedefs.h:9
uint d
int N
int write_NrrdIO(string path, int d, vector< vector< float >> &colors)
Writer for NRRD colormaps.
Definition: io.cpp:116
type
The type the bitset is encoded with.
Definition: bitset.hpp:44
Definition: json.hpp:5678
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1181
PUGI_IMPL_FN I min_element(I begin, I end, const Pred &pred)
Definition: pugixml.cpp:7604
unsigned __int64 uint64_t
Definition: stdint.h:136
Data structure handling point data and contact data.
Definition: Coarsing.h:99
Contains Field informations.
Definition: Coarsing.h:89