1 /* ----------------------------------------------------------------------
2     This is the
3 
4     ██╗     ██╗ ██████╗  ██████╗  ██████╗ ██╗  ██╗████████╗███████╗
5     ██║     ██║██╔════╝ ██╔════╝ ██╔════╝ ██║  ██║╚══██╔══╝██╔════╝
6     ██║     ██║██║  ███╗██║  ███╗██║  ███╗███████║   ██║   ███████╗
7     ██║     ██║██║   ██║██║   ██║██║   ██║██╔══██║   ██║   ╚════██║
8     ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║  ██║   ██║   ███████║
9     ╚══════╝╚═╝ ╚═════╝  ╚═════╝  ╚═════╝ ╚═╝  ╚═╝   ╚═╝   ╚══════╝®
10 
11     DEM simulation engine, released by
12     DCS Computing Gmbh, Linz, Austria
13     http://www.dcs-computing.com, office@dcs-computing.com
14 
15     LIGGGHTS® is part of CFDEM®project:
16     http://www.liggghts.com | http://www.cfdem.com
17 
18     Core developer and main author:
19     Christoph Kloss, christoph.kloss@dcs-computing.com
20 
21     LIGGGHTS® is open-source, distributed under the terms of the GNU Public
22     License, version 2 or later. It is distributed in the hope that it will
23     be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
24     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have
25     received a copy of the GNU General Public License along with LIGGGHTS®.
26     If not, see http://www.gnu.org/licenses . See also top-level README
27     and LICENSE files.
28 
29     LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH,
30     the producer of the LIGGGHTS® software and the CFDEM®coupling software
31     See http://www.cfdem.com/terms-trademark-policy for details.
32 
33 -------------------------------------------------------------------------
34     Contributing author and copyright for this file:
35     (if not contributing author is listed, this file has been contributed
36     by the core developer)
37 
38     Copyright 2012-     DCS Computing GmbH, Linz
39     Copyright 2009-2012 JKU Linz
40 ------------------------------------------------------------------------- */
41 
42 #ifndef LMP_MULTISPHERE_H
43 #define LMP_MULTISPHERE_H
44 
45 #include "pointers.h"
46 #include "custom_value_tracker.h"
47 #include "mpi_liggghts.h"
48 #include "update.h"
49 #include "math_extra.h"
50 #include <vector>
51 #include <cmath>
52 
53 namespace LAMMPS_NS {
54 
55   class Multisphere : protected Pointers {
56 
57     friend class FixMultisphere;
58     friend class FixChangeSizeMultisphere;
59     friend class SetMultisphere;
60     friend class FixMoveMultisphere;
61 
62     public:
63 
64       void add_body(int nspheres, double *xcm_ins, double *xcm_to_xbound_ins,
65                     double r_bound_ins, double *v_ins, double *omega_ins,
66                     double mass_ins, double dens_ins, int atomtype_ins, int type_ins,
67                     double *inertia_ins, double *ex_space_ins, double *ey_space_ins, double *ez_space_ins,
68                     double **displace_ins,bool *fflag, bool *tflag, int start_step_ins = -1, double *v_integrate_ins = NULL);
69 
70       void grow_arrays_per_body_local(int);
71       void grow_arrays_per_body_global(int);
72 
73       void remove_body(int ilocal);
74       void copy_body(int from_local, int to_local);
75 
76       void remap_bodies(int *body);
77 
78       void clear_map();
79       void generate_map();
80       void id_extend_body_extend(int *body);
81 
82       void calc_nbody_all();
83       bool check_lost_atoms(int *body, double *atom_delflag,double *body_existflag, double *volumeweight);
84 
85       int calc_n_steps(int iatom,int body,double *p_ref,double *normalvec,double *v_normal);
86       void recalc_n_steps(double dt_ratio);
87       void release(int iatom,int body,double *v_toInsert,double *omega_toInsert);
88 
89       double max_r_bound();
90 
exchange()91       virtual void exchange() {}
92       virtual void writeRestart(FILE *);
93       virtual void restart(double *);
94 
95       void reset_forces(bool extflag);
96 
97       void* extract(const char *name, int &, int &);
98 
99       double *extract_double_scalar(const char *name);
100       double **extract_double_vector(const char *name);
101 
102       double extract_ke();
103       double extract_rke();
104       double extract_vave();
105       double extract_omega_ave();
106 
107       // inline access functions
108 
n_body()109       inline int n_body()
110       { return nbody_; }
111 
n_body_all()112       inline int n_body_all()
113       { return nbody_all_; }
114 
tag_max_body()115       inline int tag_max_body()
116       { return mapTagMax_; }
117 
map(int ibody_local)118       inline int map(int ibody_local)
119       { return mapArray_?mapArray_[ibody_local]:-1; }
120 
tag(int ibody_local)121       inline int tag(int ibody_local)
122       { return id_(ibody_local); }
123 
has_tag(int _tag)124       inline bool has_tag(int _tag)
125       { return mapArray_[_tag] == -1 ? false : true;}
126 
atomtype(int ibody_local)127       inline int atomtype(int ibody_local)
128       { return atomtype_(ibody_local); }
129 
nrigid(int ibody_local)130       inline int nrigid(int ibody_local)
131       { return nrigid_(ibody_local); }
132 
xcm(double * x_cm,int ibody_local)133       inline void xcm(double *x_cm,int ibody_local)
134       { vectorCopy3D(xcm_(ibody_local),x_cm); }
135 
vcm(double * v_cm,int ibody_local)136       inline void vcm(double *v_cm,int ibody_local)
137       { vectorCopy3D(vcm_(ibody_local),v_cm); }
138 
omega(double * const omega,const int ibody_local)139       inline void omega(double * const omega, const int ibody_local)
140       { vectorCopy3D(omega_(ibody_local), omega); }
141 
angmom(double * const angmom,const int ibody_local)142       inline void angmom(double * const angmom, const int ibody_local)
143       { vectorCopy3D(angmom_(ibody_local), angmom); }
144 
quat(double * quat,int ibody_local)145       inline void quat(double *quat,int ibody_local)
146       { vectorCopy4D(quat_(ibody_local),quat); }
147 
add_external_force(double * frc,int ibody_local)148       inline void add_external_force(double *frc,int ibody_local)
149       { vectorAdd3D(fcm_(ibody_local),frc,fcm_(ibody_local)); }
150 
x_bound(double * x_bnd,int ibody_local)151       inline void x_bound(double *x_bnd,int ibody_local)
152       {
153         vectorZeroize3D(x_bnd);
154         MathExtraLiggghts::local_coosys_to_cartesian(x_bnd,xcm_to_xbound_(ibody_local),
155                             ex_space_(ibody_local),ey_space_(ibody_local),ez_space_(ibody_local));
156         vectorAdd3D(xcm_(ibody_local),x_bnd,x_bnd);
157       }
158 
r_bound(int ibody_local)159       inline double r_bound(int ibody_local)
160       { return r_bound_(ibody_local); }
161 
mass(int ibody_local)162       inline double mass(int ibody_local)
163       { return masstotal_(ibody_local); }
164 
density(int ibody_local)165       inline double density(int ibody_local)
166       { return density_(ibody_local); }
167 
volume(int ibody_local)168       inline double volume(int ibody_local)
169       { return masstotal_(ibody_local)/density_(ibody_local); }
170 
set_v_body(int ibody_local,double * vel)171       inline void set_v_body(int ibody_local,double *vel)
172       { vcm_.set(ibody_local,vel); }
173 
set_omega_body(int ibody_local,double * omega)174       inline void set_omega_body(int ibody_local,double *omega)
175       { omega_.set(ibody_local,omega); }
176 
set_angmom_via_omega_body(int ibody_local,double * omega)177       inline void set_angmom_via_omega_body(int ibody_local,double *omega)
178       {
179         double angmom[3];
180         MathExtra::omega_to_angmom(omega, ex_space_(ibody_local), ey_space_(ibody_local), ez_space_(ibody_local), inertia_(ibody_local), angmom);
181         omega_.set(ibody_local,omega);
182         angmom_.set(ibody_local,angmom);
183       }
184 
set_angmom_body(int ibody_local,double * angmom)185       inline void set_angmom_body(int ibody_local,double *angmom)
186       { angmom_.set(ibody_local,angmom); }
187 
set_fflag(int ibody_local,bool * fflag)188       void set_fflag(int ibody_local,bool *fflag)
189       { fflag_.set(ibody_local, fflag); }
190 
set_tflag(int ibody_local,bool * tflag)191       void set_tflag(int ibody_local,bool *tflag)
192       { tflag_.set(ibody_local, tflag); }
193 
prop()194       inline class CustomValueTracker& prop()
195       { return customValues_; }
196 
tagReset(int ibody_local)197       void tagReset(int ibody_local)
198       { id_(ibody_local)=-1; }
199 
nrigidReset(int ibody_local,int resetValue)200       void nrigidReset(int ibody_local, int resetValue)
201       { nrigid_(ibody_local) = resetValue; }
202 
203     protected:
204 
205       Multisphere(LAMMPS *lmp);
206       virtual ~Multisphere();
207 
208       // class holding fields
209       CustomValueTracker &customValues_;
210 
211       // # of local rigid bodies, and global # bodies on all procs
212       int nbody_, nbody_all_;
213 
214       // global-local lookup
215       int mapTagMax_;
216       int *mapArray_;
217 
218       // ID of rigid body
219 
220       ScalarContainer<int> &id_;
221 
222       // basic body properties
223 
224       // center-of-mass coords, vels, forces, torques of each rigid body
225       // extra (external) force on center-of-mass of each
226       VectorContainer<double,3> &xcm_;
227       VectorContainer<double,3> &vcm_;
228       VectorContainer<double,3> &fcm_;
229       VectorContainer<double,3> &torquecm_;
230       VectorContainer<double,3> &dragforce_cm_;
231       VectorContainer<double,3> &hdtorque_cm_;
232 
233       // angular momentum of each in space coords
234       // angular velocity of each in space coords
235       // quaternion of each rigid body
236       VectorContainer<double,3> &angmom_;
237       VectorContainer<double,3> &omega_;
238       VectorContainer<double,4> &quat_;
239 
240       // density and total mass of each rigid body
241       // 3 principal components of inertia of each
242       // principal axes of each in space coords
243       ScalarContainer<int> &atomtype_;
244       ScalarContainer<int> &type_;
245       ScalarContainer<double> &density_;
246       ScalarContainer<double> &masstotal_;
247       VectorContainer<double,3> &inertia_;
248       VectorContainer<double,3> &ex_space_;
249       VectorContainer<double,3> &ey_space_;
250       VectorContainer<double,3> &ez_space_;
251 
252       // # of atoms in each rigid body
253       ScalarContainer<int> &nrigid_;
254 
255       // image flags of xcm of each rigid body
256       ScalarContainer<int> &imagebody_;
257       VectorContainer<int,4> &remapflag_;
258 
259       // flag for on/off of center-of-mass force, torque
260       VectorContainer<bool,3> &fflag_;
261       VectorContainer<bool,3> &tflag_;
262 
263       // step to start from for integration
264       ScalarContainer<int> &start_step_;
265       VectorContainer<double,3> &v_integrate_;
266 
267       // bounding radius for each body
268       // vector from xcm to center of bound sphere
269       ScalarContainer<double> &r_bound_;
270       VectorContainer<double,3> &xcm_to_xbound_;
271 
272       // temperature and buffer for each body
273       ScalarContainer<double> &temp_;
274       ScalarContainer<double> &temp_old_;
275   };
276 
277   // *************************************
278   #include "multisphere_I.h"
279   // *************************************
280 
281 } //Namespace
282 
283 #endif
284