3 #include "Common/Float.h"
25 void print(std::ostream & _fout)
const{
26 _fout<<
"eps_sq: "<<
eps_sq<<std::endl
36 template<
class Tpi,
class Tpj>
39 const Float dr[3] = {_pj.pos[0]-_pi.pos[0],
40 _pj.pos[1]-_pi.pos[1],
41 _pj.pos[2]-_pi.pos[2]};
42 Float dr2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2];
53 template<
class Tpi,
class Tpj>
57 const Float dr[3] = {_pj.pos[0]-_pi.pos[0],
58 _pj.pos[1]-_pi.pos[1],
59 _pj.pos[2]-_pi.pos[2]};
60 Float dr2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2];
61 Float dr2_eps = dr2 +
eps_sq;
62 const Float dv[3] = {_pj.vel[0] - _pi.vel[0],
63 _pj.vel[1] - _pi.vel[1],
64 _pj.vel[2] - _pi.vel[2]};
65 const Float drdv = dr[0]*dv[0] + dr[1]*dv[1] + dr[2]*dv[2];
66 const Float r = sqrt(dr2_eps);
68 const Float rinv = 1.0/r;
69 const Float drdot = drdv*rinv;
74 const Float rinv2 = rinv*rinv;
77 const Float gmor3 = gmor*rinv2;
78 const Float gmor3k = gmor3*k;
79 const Float gmor3kd = gmor3*kdot;
80 const Float acc0[3] = {gmor3k*dr[0], gmor3k*dr[1], gmor3k*dr[2]};
81 const Float acc1[3] = {gmor3k*dv[0] - 3.0*drdv*rinv2*acc0[0] + gmor3kd*dr[0],
82 gmor3k*dv[1] - 3.0*drdv*rinv2*acc0[1] + gmor3kd*dr[1],
83 gmor3k*dv[2] - 3.0*drdv*rinv2*acc0[2] + gmor3kd*dr[2]};
84 _fi.acc0[0] += acc0[0];
85 _fi.acc0[1] += acc0[1];
86 _fi.acc0[2] += acc0[2];
88 _fi.acc1[0] += acc1[0];
89 _fi.acc1[1] += acc1[1];
90 _fi.acc1[2] += acc1[2];
104 template<
class Tpi,
class Tgroup>
108 const int n_member = _gj.particles.getSize();
109 auto* member_adr = _gj.particles.getOriginAddressArray();
110 Float r2_min = NUMERIC_FLOAT_MAX;
111 for (
int i=0; i<n_member; i++) {
112 const auto& pj = *member_adr[i];
114 const Float dr[3] = {pj.pos[0]-_pi.pos[0],
115 pj.pos[1]-_pi.pos[1],
116 pj.pos[2]-_pi.pos[2]};
117 Float dr2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2];
118 Float dr2_eps = dr2 +
eps_sq;
119 const Float dv[3] = {pj.vel[0] - _pi.vel[0],
120 pj.vel[1] - _pi.vel[1],
121 pj.vel[2] - _pi.vel[2]};
122 const Float drdv = dr[0]*dv[0] + dr[1]*dv[1] + dr[2]*dv[2];
123 const Float r = sqrt(dr2_eps);
125 const Float rinv = 1.0/r;
126 const Float drdot = drdv*rinv;
131 const Float rinv2 = rinv*rinv;
134 const Float gmor3 = gmor*rinv2;
135 const Float gmor3k = gmor3*k;
136 const Float gmor3kd = gmor3*kdot;
137 const Float acc0[3] = {gmor3k*dr[0], gmor3k*dr[1], gmor3k*dr[2]};
138 const Float acc1[3] = {gmor3k*dv[0] - 3.0*drdv*rinv2*acc0[0] + gmor3kd*dr[0],
139 gmor3k*dv[1] - 3.0*drdv*rinv2*acc0[1] + gmor3kd*dr[1],
140 gmor3k*dv[2] - 3.0*drdv*rinv2*acc0[2] + gmor3kd*dr[2]};
141 _fi.acc0[0] += acc0[0];
142 _fi.acc0[1] += acc0[1];
143 _fi.acc0[2] += acc0[2];
145 _fi.acc1[0] += acc1[0];
146 _fi.acc1[1] += acc1[1];
147 _fi.acc1[2] += acc1[2];
149 _fi.pot += - gmor*kp;
164 template<
class Tpi,
class Tgroup,
class Tpcmj>
169 const Float dr[3] = {_pj.pos[0]-_pi.pos[0],
170 _pj.pos[1]-_pi.pos[1],
171 _pj.pos[2]-_pi.pos[2]};
172 Float dr2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2];
173 Float dr2_eps = dr2 +
eps_sq;
174 const Float dv[3] = {_pj.vel[0] - _pi.vel[0],
175 _pj.vel[1] - _pi.vel[1],
176 _pj.vel[2] - _pi.vel[2]};
177 const Float drdv = dr[0]*dv[0] + dr[1]*dv[1] + dr[2]*dv[2];
178 const Float r = sqrt(dr2_eps);
180 const Float rinv = 1.0/r;
181 const Float drdot = drdv*rinv;
186 auto* ptcl_mem = _gj.particles.getDataAddress();
187 ASSERT(_gj.particles.cm.mass==_pj.mass);
188 for (
int i=0; i<_gj.particles.getSize(); i++) {
193 const Float rinv2 = rinv*rinv;
194 const Float rinv3 = rinv2*rinv;
198 const Float acc0[3] = {gmor3k*dr[0], gmor3k*dr[1], gmor3k*dr[2]};
199 const Float acc1[3] = {gmor3k*dv[0] - 3.0*drdv*rinv2*acc0[0] + gmor3kd*dr[0],
200 gmor3k*dv[1] - 3.0*drdv*rinv2*acc0[1] + gmor3kd*dr[1],
201 gmor3k*dv[2] - 3.0*drdv*rinv2*acc0[2] + gmor3kd*dr[2]};
202 _fi.acc0[0] += acc0[0];
203 _fi.acc0[1] += acc0[1];
204 _fi.acc0[2] += acc0[2];
206 _fi.acc1[0] += acc1[0];
207 _fi.acc1[1] += acc1[1];
208 _fi.acc1[2] += acc1[2];
223 template<
class Tgroup,
class Tpcmi,
class Tpj>
228 const Float dr[3] = {_pj.pos[0]-_pi.pos[0],
229 _pj.pos[1]-_pi.pos[1],
230 _pj.pos[2]-_pi.pos[2]};
231 Float dr2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2];
232 Float dr2_eps = dr2 +
eps_sq;
233 const Float dv[3] = {_pj.vel[0] - _pi.vel[0],
234 _pj.vel[1] - _pi.vel[1],
235 _pj.vel[2] - _pi.vel[2]};
236 const Float drdv = dr[0]*dv[0] + dr[1]*dv[1] + dr[2]*dv[2];
237 const Float r = sqrt(dr2_eps);
239 const Float rinv = 1.0/r;
240 const Float drdot = drdv*rinv;
245 auto* ptcl_mem = _gi.particles.getDataAddress();
246 ASSERT(_gi.particles.cm.mass==_pi.mass);
247 for (
int i=0; i<_gi.particles.getSize(); i++) {
256 const Float rinv2 = rinv*rinv;
259 const Float gmor3 = gmor*rinv2;
260 const Float gmor3k = gmor3*k;
261 const Float gmor3kd = gmor3*kdot;
262 const Float acc0[3] = {gmor3k*dr[0], gmor3k*dr[1], gmor3k*dr[2]};
263 const Float acc1[3] = {gmor3k*dv[0] - 3.0*drdv*rinv2*acc0[0] + gmor3kd*dr[0],
264 gmor3k*dv[1] - 3.0*drdv*rinv2*acc0[1] + gmor3kd*dr[1],
265 gmor3k*dv[2] - 3.0*drdv*rinv2*acc0[2] + gmor3kd*dr[2]};
266 _fi.acc0[0] += acc0[0];
267 _fi.acc0[1] += acc0[1];
268 _fi.acc0[2] += acc0[2];
270 _fi.acc1[0] += acc1[0];
271 _fi.acc1[1] += acc1[1];
272 _fi.acc1[2] += acc1[2];
274 _fi.pot += - gmor*kp;
288 template<
class Tpi,
class Tgroup>
293 const int n_member = _gj.particles.getSize();
294 auto* member_adr = _gj.particles.getOriginAddressArray();
295 Float r2_min = NUMERIC_FLOAT_MAX;
296 ASSERT(_gi.particles.cm.mass==_pi.mass);
297 for (
int i=0; i<n_member; i++) {
298 const auto& pj = *member_adr[i];
300 const Float dr[3] = {pj.pos[0]-_pi.pos[0],
301 pj.pos[1]-_pi.pos[1],
302 pj.pos[2]-_pi.pos[2]};
303 Float dr2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2];
304 Float dr2_eps = dr2 +
eps_sq;
305 const Float dv[3] = {pj.vel[0] - _pi.vel[0],
306 pj.vel[1] - _pi.vel[1],
307 pj.vel[2] - _pi.vel[2]};
308 const Float drdv = dr[0]*dv[0] + dr[1]*dv[1] + dr[2]*dv[2];
309 const Float r = sqrt(dr2_eps);
311 const Float rinv = 1.0/r;
312 const Float drdot = drdv*rinv;
317 auto* ptcl_mem = _gi.particles.getDataAddress();
318 for (
int i=0; i<_gi.particles.getSize(); i++) {
327 const Float rinv2 = rinv*rinv;
330 const Float gmor3 = gmor*rinv2;
331 const Float gmor3k = gmor3*k;
332 const Float gmor3kd = gmor3*kdot;
333 const Float acc0[3] = {gmor3k*dr[0], gmor3k*dr[1], gmor3k*dr[2]};
334 const Float acc1[3] = {gmor3k*dv[0] - 3.0*drdv*rinv2*acc0[0] + gmor3kd*dr[0],
335 gmor3k*dv[1] - 3.0*drdv*rinv2*acc0[1] + gmor3kd*dr[1],
336 gmor3k*dv[2] - 3.0*drdv*rinv2*acc0[2] + gmor3kd*dr[2]};
337 _fi.acc0[0] += acc0[0];
338 _fi.acc0[1] += acc0[1];
339 _fi.acc0[2] += acc0[2];
341 _fi.acc1[0] += acc1[0];
342 _fi.acc1[1] += acc1[1];
343 _fi.acc1[2] += acc1[2];
345 _fi.pot += - gmor*kp;
361 template<
class Tpcmi,
class Tgroup,
class Tpcmj>
367 const Float dr[3] = {_pj.pos[0]-_pi.pos[0],
368 _pj.pos[1]-_pi.pos[1],
369 _pj.pos[2]-_pi.pos[2]};
370 Float dr2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2];
371 Float dr2_eps = dr2 +
eps_sq;
372 const Float dv[3] = {_pj.vel[0] - _pi.vel[0],
373 _pj.vel[1] - _pi.vel[1],
374 _pj.vel[2] - _pi.vel[2]};
375 const Float drdv = dr[0]*dv[0] + dr[1]*dv[1] + dr[2]*dv[2];
376 const Float r = sqrt(dr2_eps);
378 const Float rinv = 1.0/r;
379 const Float drdot = drdv*rinv;
385 auto* ptcl_mem_i = _gi.particles.getDataAddress();
386 auto* ptcl_mem_j = _gj.particles.getDataAddress();
387 for (
int i=0; i<_gi.particles.getSize(); i++) {
391 for (
int j=0; j<_gj.particles.getSize(); j++) {
394 mkdotj += ptcl_mem_j[j].mass *
ChangeOver::calcAcc1WTwo(ptcl_mem_i[i].changeover, ptcl_mem_j[j].changeover, r, drdot);
396 mkp += ptcl_mem_i[i].mass * mkpj;
397 mk += ptcl_mem_i[i].mass * mkj;
398 mkdot += ptcl_mem_i[i].mass * mkdotj;
404 const Float rinv2 = rinv*rinv;
405 const Float rinv3 = rinv2*rinv;
409 const Float acc0[3] = {gmor3k*dr[0], gmor3k*dr[1], gmor3k*dr[2]};
410 const Float acc1[3] = {gmor3k*dv[0] - 3.0*drdv*rinv2*acc0[0] + gmor3kd*dr[0],
411 gmor3k*dv[1] - 3.0*drdv*rinv2*acc0[1] + gmor3kd*dr[1],
412 gmor3k*dv[2] - 3.0*drdv*rinv2*acc0[2] + gmor3kd*dr[2]};
413 _fi.acc0[0] += acc0[0];
414 _fi.acc0[1] += acc0[1];
415 _fi.acc0[2] += acc0[2];
417 _fi.acc1[0] += acc1[0];
418 _fi.acc1[1] += acc1[1];
419 _fi.acc1[2] += acc1[2];
427 template<
class Tpi,
class Tpj>
429 const Float dr[3] = {pj.pos[0] - pi.pos[0],
430 pj.pos[1] - pi.pos[1],
431 pj.pos[2] - pi.pos[2]};
432 Float dr2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2];
433 Float dr2_eps = dr2 +
eps_sq;
434 const Float r = sqrt(dr2_eps);
436 const Float rinv = 1.0/r;
447 template<
class Tgroup,
class Tpert>
451 if (_group.perturber.soft_pert!=NULL) {
452 auto* pert = _group.perturber.soft_pert;
453 const int n_member = _group.particles.getSize();
454 for (
int j=0; j<n_member; j++) {
455 epert += _group.particles[j].mass*pert->evalPot(_group.particles[j].pos);
472 template<
class Tp,
class Tgroup,
class Tpert>
473 inline void calcEnergy(H4::HermiteEnergy& _energy,
const Tp* _particles,
const int _n_particle,
const Tgroup* _groups,
const int* _group_index,
const int _n_group,
const Tpert& _perturber) {
474 _energy.ekin = _energy.epot = _energy.epert = 0.0;
475 for (
int i=0; i<_n_particle; i++) {
476 auto& pi = _particles[i];
477 if (pi.mass==0.0)
continue;
478 _energy.ekin += pi.mass* (pi.vel[0]*pi.vel[0] + pi.vel[1]*pi.vel[1] + pi.vel[2]*pi.vel[2]);
480 for (
int j=0; j<i; j++) {
482 auto& pj = _particles[j];
483 if (pj.mass==0.0)
continue;
484 const Float dr[3] = {pj.pos[0] - pi.pos[0],
485 pj.pos[1] - pi.pos[1],
486 pj.pos[2] - pi.pos[2]};
487 Float dr2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2];
488 Float dr2_eps = dr2 +
eps_sq;
489 const Float r = sqrt(dr2_eps);
491 const Float rinv = 1.0/r;
494 poti += -pj.mass*rinv*k;
501 for (
int k=0; k<_n_group; k++) {
502 const int i = _group_index[k];
504 auto& bink = _groups[i].info.getBinaryTreeRoot();
505 auto& pcm = _groups[i].particles.cm;
507 auto& vbin = bink.vel;
508 auto& vbin_bk = _groups[i].info.vcm_record;
510 Float dvbin[3] = {vbin[0] - vbin_bk[0], vbin[1] - vbin_bk[1], vbin[2] - vbin_bk[2]};
511 Float de_kin = bink.mass*(dvbin[0]*vcm[0]+dvbin[1]*vcm[1]+dvbin[2]*vcm[2]);
512 _energy.epert -= de_kin;
523 fwrite(
this,
sizeof(*
this),1,_fp);
530 size_t rcount = fread(
this,
sizeof(*
this), 1, _fin);
532 std::cerr<<
"Error: Data reading fails! requiring data number is 1, only obtain "<<rcount<<
".\n";