SlowDown Algorithmic Regularization (SDAR)
Algorithmic Regularization with slowdown method for integrating few-body motions
block_time_step.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Common/Float.h"
4 
5 namespace H4{
6  // forth order Time step calculator class
7  class TimeStep4th{
8  public:
12 
13  TimeStep4th(): eta_4th(Float(-1.0)), eta_2nd(Float(-1.0)), acc0_offset_sq(Float(-1.0)) {}
14 
16 
18  bool checkParams() {
19  ASSERT(eta_4th>0.0);
20  ASSERT(eta_2nd>0.0);
21  ASSERT(acc0_offset_sq>=0.0);
22  return true;
23  }
24 
26 
31  void calcAcc0OffsetSq(const Float _mass, const Float _r, const Float _G) {
32  acc0_offset_sq = _G * _mass / (_r*_r);
34  }
35 
36 
38 
43  Float calcDt2nd(const Float* acc0,
44  const Float* acc1) const {
45  const Float s0 = acc0[0] * acc0[0] + acc0[1] * acc0[1] + acc0[2] * acc0[2] + acc0_offset_sq;
46  const Float s1 = acc1[0] * acc1[0] + acc1[1] * acc1[1] + acc1[2] * acc1[2];
47  if(s0 == acc0_offset_sq || s1 == 0.0)
48  return NUMERIC_FLOAT_MAX;
49  else
50  return eta_2nd * sqrt( s0 / s1 );
51  }
52 
54 
61  Float calcDt4th(const Float* acc0,
62  const Float* acc1,
63  const Float* acc2,
64  const Float* acc3) const {
65  const Float s0 = acc0[0] * acc0[0] + acc0[1] * acc0[1] + acc0[2] * acc0[2] + acc0_offset_sq;
66  const Float s1 = acc1[0] * acc1[0] + acc1[1] * acc1[1] + acc1[2] * acc1[2];
67  const Float s2 = acc2[0] * acc2[0] + acc2[1] * acc2[1] + acc2[2] * acc2[2];
68  const Float s3 = acc3[0] * acc3[0] + acc3[1] * acc3[1] + acc3[2] * acc3[2];
69  if(s0 == acc0_offset_sq || s1 == 0.0)
70  return NUMERIC_FLOAT_MAX;
71  else
72  return eta_4th * sqrt( (sqrt(s0*s2) + s1) / (sqrt(s1*s3) + s2) );
73  }
74 
75  void print(std::ostream & _fout) const{
76  _fout<<"eta_4th : "<<eta_4th<<std::endl
77  <<"eta_2nd : "<<eta_2nd<<std::endl;
78  }
79 
81 
85  void printColumnTitle(std::ostream & _fout, const int _width=20) {
86  _fout<<std::setw(_width)<<"Eta(4th)"
87  <<std::setw(_width)<<"Eta(2nd)";
88  }
89 
91 
95  void printColumn(std::ostream & _fout, const int _width=20){
96  _fout<<std::setw(_width)<<eta_4th
97  <<std::setw(_width)<<eta_2nd;
98  }
99 
101 
103  void writeBinary(FILE *_fp) const {
104  fwrite(this, sizeof(*this),1,_fp);
105  }
106 
108 
110  void readBinary(FILE *_fin) {
111  size_t rcount = fread(this, sizeof(*this),1,_fin);
112  if (rcount<1) {
113  std::cerr<<"Error: Data reading fails! requiring data number is 1, only obtain "<<rcount<<".\n";
114  abort();
115  }
116  }
117  };
118 
119  // Block time step class
121  private:
122  Float dt_max_; // maximum time step
123  Float dt_min_; // minimum time step
124  public:
126  BlockTimeStep4th(): TimeStep4th(), dt_max_(-1.0), dt_min_(-1.0) {}
127 
129 
133  void setDtRange(const Float _dt_max, const int _pow_index_min) {
134  dt_max_ = _dt_max;
135  dt_min_ = _dt_max;
136  for (int i=0; i<_pow_index_min; i++) {
137  dt_min_ *= Float(0.5);
138  }
139  }
140 
142 
144  Float getDtMax() const {
145  return dt_max_;
146  }
147 
149 
151  Float getDtMin() const {
152  return dt_min_;
153  }
154 
156 
160  Float calcNextDtLimit(const Float _time) {
161  ASSERT(dt_max_>dt_min_);
162  ASSERT(dt_min_>0.0);
163  // for first step, the maximum time step is OK
164  if(_time==0.0) return dt_max_;
165  else {
166  // the binary tree for current time position in block step
167  unsigned long long int bitmap = to_double(_time/dt_min_);
168  //#ifdef __GNUC__
169  // PS::S64 dts = __builtin_ctz(bitmap) ;
170  // PS::U64 c = (1<<dts);
172  //#else
173 
174  // block step multiply factor
175  unsigned long long int c=1;
176  // find the last zero in the binary tree to obtain the current block step level
177  while((bitmap&1)==0) {
178  bitmap = (bitmap>>1);
179  c = (c<<1);
180  }
181  //#endif
182 
183  // return the maximum step allown
184  return std::min(c*dt_min_,dt_max_);
185  }
186  }
187 
189 
195  Float calcBlockDt2nd(const Float* _acc0,
196  const Float* _acc1,
197  const Float _dt_limit) const{
198  ASSERT(dt_max_>dt_min_);
199  ASSERT(_dt_limit<=dt_max_);
200  ASSERT(_dt_limit>=dt_min_);
201 
202  const Float dt_ref = TimeStep4th::calcDt2nd(_acc0, _acc1);
203  Float dt = _dt_limit;
204  while(dt > dt_ref) dt *= 0.5;
205 
206  if(dt<dt_min_) {
207  std::cerr<<"Error: time step size too small: ("<<dt<<") < dt_min ("<<dt_min_<<")!"<<std::endl;
208  DATADUMP("hard_dump");
209  abort();
210  }
211  else return dt;
212  }
213 
215 
223  Float calcBlockDt4th(const Float* acc0,
224  const Float* acc1,
225  const Float* acc2,
226  const Float* acc3,
227  const Float _dt_limit) const {
228  ASSERT(dt_max_>dt_min_);
229  ASSERT(_dt_limit<=dt_max_);
230  ASSERT(_dt_limit>=dt_min_);
231 
232  const Float dt_ref = TimeStep4th::calcDt4th(acc0, acc1, acc2, acc3);
233  Float dt = _dt_limit;
234  while(dt > dt_ref) dt *= 0.5;
235 
236  if(dt<dt_min_) {
237  std::cerr<<"Error: time step size too small: ("<<dt<<") < dt_min ("<<dt_min_<<")!"<<std::endl;
238  DATADUMP("hard_dump");
239  abort();
240  }
241  else return dt;
242  }
243 
244  void print(std::ostream & _fout) const{
245  TimeStep4th::print(_fout);
246  _fout<<"dt_max: "<<dt_max_<<std::endl
247  <<"dt_min: "<<dt_min_<<std::endl;
248  }
249 
251 
255  void printColumnTitle(std::ostream & _fout, const int _width=20) {
256  TimeStep4th::printColumnTitle(_fout, _width);
257  _fout<<std::setw(_width)<<"Dt_max"
258  <<std::setw(_width)<<"Dt_min";
259  }
260 
262 
266  void printColumn(std::ostream & _fout, const int _width=20){
267  TimeStep4th::printColumn(_fout, _width);
268  _fout<<std::setw(_width)<<dt_max_
269  <<std::setw(_width)<<dt_min_;
270  }
271 
273 
275  void writeBinary(FILE *_fp) const {
276  fwrite(this, sizeof(*this),1,_fp);
277  }
278 
280 
282  void readBinary(FILE *_fin) {
283  size_t rcount = fread(this, sizeof(*this),1,_fin);
284  if (rcount<1) {
285  std::cerr<<"Error: Data reading fails! requiring data number is 1, only obtain "<<rcount<<".\n";
286  abort();
287  }
288  }
289  };
290 
291 }
H4::BlockTimeStep4th::setDtRange
void setDtRange(const Float _dt_max, const int _pow_index_min)
set dt limit (max and min)
Definition: block_time_step.h:133
H4::BlockTimeStep4th::calcBlockDt4th
Float calcBlockDt4th(const Float *acc0, const Float *acc1, const Float *acc2, const Float *acc3, const Float _dt_limit) const
Calculate 4th order block time step.
Definition: block_time_step.h:223
H4::TimeStep4th::calcDt4th
Float calcDt4th(const Float *acc0, const Float *acc1, const Float *acc2, const Float *acc3) const
calculate 4th order time step
Definition: block_time_step.h:61
Float.h
H4::TimeStep4th::readBinary
void readBinary(FILE *_fin)
read class data to file with binary format
Definition: block_time_step.h:110
H4::TimeStep4th::printColumn
void printColumn(std::ostream &_fout, const int _width=20)
print data of class members using column style
Definition: block_time_step.h:95
NUMERIC_FLOAT_MAX
const Float NUMERIC_FLOAT_MAX
Definition: Float.h:29
H4::TimeStep4th::eta_4th
Float eta_4th
Definition: block_time_step.h:9
H4::BlockTimeStep4th::calcBlockDt2nd
Float calcBlockDt2nd(const Float *_acc0, const Float *_acc1, const Float _dt_limit) const
Calculate 2nd order block time step.
Definition: block_time_step.h:195
H4::TimeStep4th::TimeStep4th
TimeStep4th()
acceleration offset to avoid too small step when weak acceleration exist
Definition: block_time_step.h:13
H4::BlockTimeStep4th::printColumnTitle
void printColumnTitle(std::ostream &_fout, const int _width=20)
print titles of class members using column style
Definition: block_time_step.h:255
H4::BlockTimeStep4th::BlockTimeStep4th
BlockTimeStep4th()
contructor
Definition: block_time_step.h:126
H4::BlockTimeStep4th::readBinary
void readBinary(FILE *_fin)
read class data to file with binary format
Definition: block_time_step.h:282
H4::BlockTimeStep4th::calcNextDtLimit
Float calcNextDtLimit(const Float _time)
calculate the maximum time step limit for next block step based on the input (current) time
Definition: block_time_step.h:160
H4::TimeStep4th::calcAcc0OffsetSq
void calcAcc0OffsetSq(const Float _mass, const Float _r, const Float _G)
calculate a0_offset_sq
Definition: block_time_step.h:31
H4::TimeStep4th::writeBinary
void writeBinary(FILE *_fp) const
write class data to file with binary format
Definition: block_time_step.h:103
H4::BlockTimeStep4th::getDtMax
Float getDtMax() const
get maximum time step
Definition: block_time_step.h:144
H4::BlockTimeStep4th::print
void print(std::ostream &_fout) const
Definition: block_time_step.h:244
H4::TimeStep4th::printColumnTitle
void printColumnTitle(std::ostream &_fout, const int _width=20)
print titles of class members using column style
Definition: block_time_step.h:85
Float
double Float
Definition: Float.h:25
H4::TimeStep4th
Definition: block_time_step.h:7
H4::TimeStep4th::print
void print(std::ostream &_fout) const
Definition: block_time_step.h:75
H4::BlockTimeStep4th::getDtMin
Float getDtMin() const
get minimum time step
Definition: block_time_step.h:151
H4::TimeStep4th::checkParams
bool checkParams()
check whether parameters values are correct
Definition: block_time_step.h:18
H4::TimeStep4th::calcDt2nd
Float calcDt2nd(const Float *acc0, const Float *acc1) const
calculate 2nd order time step
Definition: block_time_step.h:43
H4::BlockTimeStep4th
Definition: block_time_step.h:120
H4
Definition: ar_information.h:9
H4::BlockTimeStep4th::printColumn
void printColumn(std::ostream &_fout, const int _width=20)
print data of class members using column style
Definition: block_time_step.h:266
H4::TimeStep4th::eta_2nd
Float eta_2nd
time step coefficient (outside sqrt) for forth order
Definition: block_time_step.h:10
H4::TimeStep4th::acc0_offset_sq
Float acc0_offset_sq
time step coefficient (outside sqrt) for second order
Definition: block_time_step.h:11
to_double
#define to_double(x)
Definition: Float.h:27
H4::BlockTimeStep4th::writeBinary
void writeBinary(FILE *_fp) const
write class data to file with binary format
Definition: block_time_step.h:275