14 typedef std::array<Float,2> CDPair;
24 int cd_pair_array_size_;
26 CumSumCkIndex* sorted_cumsum_ck_index_;
38 void recursiveSymplecticCofficientsSplit(
Float* _ck,
const int _n) {
46 recursiveSymplecticCofficientsSplit(_ck, _n-1);
49 const int n_size=std::pow(3, _n-1);
52 Float ck_last[n_size];
53 for (
int i=0; i<n_size; i++) ck_last[i] = _ck[i];
56 Float ap = pow(2.0, 1.0/(2*_n-1));
63 for (
int i=0; i<3; i++) {
64 for (
int j=0; j<n_size; j++) {
65 _ck[i*n_size+j] = w[i]*ck_last[j];
70 std::cerr<<
"Error: integrator order should be positive, given value "<<_n<<std::endl;
88 void symplecticCofficientsGenerator(CDPair _cd_pair[], CumSumCkIndex _sorted_cumsum_ck_index[],
const int _n,
const int _cd_pair_size) {
90 const int n_size = std::pow(3,_n);
91 Float coff_array[n_size];
93 recursiveSymplecticCofficientsSplit(coff_array, _n);
96 const int n_group= n_size/3;
99 const int k = n_group+1;
101 if(k>_cd_pair_size) {
102 std::cerr<<
"Error: _cd_pair array size "<<_cd_pair_size<<
" not big enough for order "<<_n<<
", required size "<<k<<std::endl;
106 _cd_pair[0][0] = coff_array[0];
107 _sorted_cumsum_ck_index[0].cck = coff_array[0];
108 _sorted_cumsum_ck_index[0].index = 0;
109 for (
int i=0; i<n_group-1; i++) {
110 _cd_pair[i ][1] = coff_array[3*i+1];
111 _cd_pair[i+1][0] = coff_array[3*i+2]+coff_array[3*i+3];
112 _sorted_cumsum_ck_index[i+1].cck = _sorted_cumsum_ck_index[i].cck + _cd_pair[i+1][0];
113 _sorted_cumsum_ck_index[i+1].index = i+1;
115 _cd_pair[k-2][1] = coff_array[n_size-2];
116 _cd_pair[k-1][0] = coff_array[n_size-1];
117 _cd_pair[k-1][1] =
Float(0.0);
118 _sorted_cumsum_ck_index[k-1].cck = _sorted_cumsum_ck_index[k-2].cck + _cd_pair[k-1][0];
119 _sorted_cumsum_ck_index[k-1].index = k-1;
121 std::sort(_sorted_cumsum_ck_index, _sorted_cumsum_ck_index+k, [](
const CumSumCkIndex &a,
const CumSumCkIndex &b){
return a.cck<b.cck;} );
125 if(_cd_pair_size<8) {
126 std::cerr<<
"Error: _cd_pair array size "<<_cd_pair_size<<
" not big enough for order "<<_n<<
", required size "<<8<<std::endl;
130 _cd_pair[0][0] = 0.3922568052387800;
131 _cd_pair[0][1] = 0.7845136104775600;
132 _cd_pair[1][0] = 0.5100434119184585;
133 _cd_pair[1][1] = 0.2355732133593570;
134 _cd_pair[2][0] = -0.4710533854097566;
135 _cd_pair[2][1] = -1.1776799841788701;
136 _cd_pair[3][0] = 0.0687531682525181;
137 _cd_pair[3][1] = 1.3151863206839063;
138 _cd_pair[4][0] = 0.0687531682525181;
139 _cd_pair[4][1] = -1.1776799841788701;
140 _cd_pair[5][0] = -0.4710533854097566;
141 _cd_pair[5][1] = 0.2355732133593570;
142 _cd_pair[6][0] = 0.5100434119184585;
143 _cd_pair[6][1] = 0.7845136104775600;
144 _cd_pair[7][0] = 0.3922568052387800;
145 _cd_pair[7][1] = 0.0000000000000000;
146 _sorted_cumsum_ck_index[0].cck = 0.0976997828427615;
147 _sorted_cumsum_ck_index[0].index = 5;
148 _sorted_cumsum_ck_index[1].cck = 0.3922568052387800;
149 _sorted_cumsum_ck_index[1].index = 0;
150 _sorted_cumsum_ck_index[2].cck = 0.4312468317474820;
151 _sorted_cumsum_ck_index[2].index = 2;
152 _sorted_cumsum_ck_index[3].cck = 0.5000000000000000;
153 _sorted_cumsum_ck_index[3].index = 3;
154 _sorted_cumsum_ck_index[4].cck = 0.5687531682525181;
155 _sorted_cumsum_ck_index[4].index = 4;
156 _sorted_cumsum_ck_index[5].cck = 0.6077431947612200;
157 _sorted_cumsum_ck_index[5].index = 6;
158 _sorted_cumsum_ck_index[6].cck = 0.9023002171572385;
159 _sorted_cumsum_ck_index[6].index = 1;
160 _sorted_cumsum_ck_index[7].cck = 1.0000000000000000;
161 _sorted_cumsum_ck_index[7].index = 7;
164 if(_cd_pair_size<16) {
165 std::cerr<<
"Error: _cd_pair array size "<<_cd_pair_size<<
" not big enough for order "<<_n<<
", required size "<<16<<std::endl;
169 _cd_pair[0][0] = 0.4574221231148700;
170 _cd_pair[0][1] = 0.9148442462297400;
171 _cd_pair[1][0] = 0.5842687913979845;
172 _cd_pair[1][1] = 0.2536933365662290;
173 _cd_pair[2][0] = -0.5955794501471254;
174 _cd_pair[2][1] = -1.4448522368604799;
175 _cd_pair[3][0] = -0.8015464361143615;
176 _cd_pair[3][1] = -0.1582406353682430;
177 _cd_pair[4][0] = 0.8899492511272584;
178 _cd_pair[4][1] = 1.9381391376227599;
179 _cd_pair[5][0] = -0.0112355476763650;
180 _cd_pair[5][1] = -1.9606102329754900;
181 _cd_pair[6][0] = -0.9289051917917525;
182 _cd_pair[6][1] = 0.1027998493919850;
183 _cd_pair[7][0] = 0.9056264600894914;
184 _cd_pair[7][1] = 1.7084530707869978;
185 _cd_pair[8][0] = 0.9056264600894914;
186 _cd_pair[8][1] = 0.1027998493919850;
187 _cd_pair[9][0] = -0.9289051917917525;
188 _cd_pair[9][1] = -1.9606102329754900;
189 _cd_pair[10][0] = -0.0112355476763650;
190 _cd_pair[10][1] = 1.9381391376227599;
191 _cd_pair[11][0] = 0.8899492511272584;
192 _cd_pair[11][1] = -0.1582406353682430;
193 _cd_pair[12][0] = -0.8015464361143615;
194 _cd_pair[12][1] = -1.4448522368604799;
195 _cd_pair[13][0] = -0.5955794501471254;
196 _cd_pair[13][1] = 0.2536933365662290;
197 _cd_pair[14][0] = 0.5842687913979845;
198 _cd_pair[14][1] = 0.9148442462297400;
199 _cd_pair[15][0] = 0.4574221231148700;
200 _cd_pair[15][1] = 0.0000000000000000;
201 _sorted_cumsum_ck_index[0].cck = -0.4056264600894914;
202 _sorted_cumsum_ck_index[0].index = 6;
203 _sorted_cumsum_ck_index[1].cck = -0.3554349717486324;
204 _sorted_cumsum_ck_index[1].index = 3;
205 _sorted_cumsum_ck_index[2].cck = -0.0416909145128544;
206 _sorted_cumsum_ck_index[2].index = 13;
207 _sorted_cumsum_ck_index[3].cck = 0.4461114643657291;
208 _sorted_cumsum_ck_index[3].index = 2;
209 _sorted_cumsum_ck_index[4].cck = 0.4574221231148700;
210 _sorted_cumsum_ck_index[4].index = 0;
211 _sorted_cumsum_ck_index[5].cck = 0.4654857206213739;
212 _sorted_cumsum_ck_index[5].index = 10;
213 _sorted_cumsum_ck_index[6].cck = 0.4767212682977390;
214 _sorted_cumsum_ck_index[6].index = 9;
215 _sorted_cumsum_ck_index[7].cck = 0.5000000000000000;
216 _sorted_cumsum_ck_index[7].index = 7;
217 _sorted_cumsum_ck_index[8].cck = 0.5232787317022610;
218 _sorted_cumsum_ck_index[8].index = 5;
219 _sorted_cumsum_ck_index[9].cck = 0.5345142793786261;
220 _sorted_cumsum_ck_index[9].index = 4;
221 _sorted_cumsum_ck_index[10].cck = 0.5425778768851300;
222 _sorted_cumsum_ck_index[10].index = 14;
223 _sorted_cumsum_ck_index[11].cck = 0.5538885356342710;
224 _sorted_cumsum_ck_index[11].index = 12;
225 _sorted_cumsum_ck_index[12].cck = 1.0000000000000000;
226 _sorted_cumsum_ck_index[12].index = 15;
227 _sorted_cumsum_ck_index[13].cck = 1.0416909145128546;
228 _sorted_cumsum_ck_index[13].index = 1;
229 _sorted_cumsum_ck_index[14].cck = 1.3554349717486325;
230 _sorted_cumsum_ck_index[14].index = 11;
231 _sorted_cumsum_ck_index[15].cck = 1.4056264600894914;
232 _sorted_cumsum_ck_index[15].index = 8;
238 SymplecticStep(): sym_order_(0), sym_type_(0), cd_pair_array_size_(0), cd_pair_(NULL), sorted_cumsum_ck_index_(NULL) {}
242 if (cd_pair_array_size_>0) {
243 ASSERT(cd_pair_!=NULL);
246 ASSERT(sorted_cumsum_ck_index_!=NULL);
247 delete [] sorted_cumsum_ck_index_;
248 sorted_cumsum_ck_index_ = NULL;
249 cd_pair_array_size_ = 0;
261 if(cd_pair_array_size_>0)
clear();
265 if (_n>0) cd_pair_array_size_ = std::pow(3,k-1)+1;
266 else if(_n==-6) cd_pair_array_size_ = 8;
267 else if(_n==-8) cd_pair_array_size_ = 16;
269 std::cerr<<
"Error: input order "<<_n<<
" cannot be generated !\n";
274 cd_pair_ =
new CDPair[cd_pair_array_size_];
275 sorted_cumsum_ck_index_ =
new CumSumCkIndex[cd_pair_array_size_];
277 symplecticCofficientsGenerator(cd_pair_, sorted_cumsum_ck_index_, k, cd_pair_array_size_);
280 sym_order_ = _n<0?-_n:_n;
283 sym_type_ = _n<0?2:1;
288 ASSERT(_k<cd_pair_array_size_);
289 return cd_pair_[_k][0];
294 ASSERT(_k<cd_pair_array_size_);
295 return cd_pair_[_k][1];
300 return cd_pair_array_size_;
305 return sorted_cumsum_ck_index_[_k].index;
310 return sorted_cumsum_ck_index_[_k].cck;
318 return pow(_error_new_over_old,
Float(1.0/sym_order_));
326 return pow(_step_new_over_old,
Float(sym_order_));
338 fwrite(
this,
sizeof(*
this),1,_fout);
345 size_t rcount = fread(
this,
sizeof(*
this), 1, _fin);
347 std::cerr<<
"Error: Data reading fails! requiring data number is 1, only obtain "<<rcount<<
".\n";
351 ASSERT(sym_type_==1||sym_type_==2);
352 ASSERT(sym_order_>=0);
353 cd_pair_array_size_ = 0;
355 int sym_n = (sym_type_==2)?-sym_order_:sym_order_;
360 void print(std::ostream & _fout)
const{
361 _fout<<
"sym_order : "<<sym_order_<<std::endl
362 <<
"sym_type : "<<(sym_type_==1?
"Yoshida method 1":
"Yoshida method 2")<<std::endl
363 <<
"CD_pair_size : "<<cd_pair_array_size_<<std::endl;