00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "hdyn.h"
00030
00031
00032
00033 bool hdyn::is_perturbed_cpt()
00034 {
00035 return (!get_kepler() || !fully_unperturbed);
00036 }
00037
00038 bool hdyn::is_perturbed_cm()
00039 {
00040 return (is_parent() && get_oldest_daughter()->is_perturbed_cpt());
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #define FAST_ACCESS false
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 local int compare_ptr(const void * pi, const void * pj)
00068 {
00069 hdynptr bi = *((hdynptr*)pi);
00070 hdynptr bj = *((hdynptr*)pj);
00071
00072 if (bi > bj)
00073 return +1;
00074 else if (bi < bj)
00075 return -1;
00076 else
00077 return 0;
00078 }
00079
00080 void hdyn::reconstruct_perturbed_list()
00081 {
00082 if (!options->use_perturbed_list) return;
00083
00084 if (perturbed_list) delete [] perturbed_list;
00085
00086 perturbed_list = new hdynptr[get_root()->n_leaves()];
00087 n_perturbed = 0;
00088
00089 for_all_daughters(hdyn, get_root(), bi)
00090 if (bi->is_perturbed_cm()) {
00091
00092 perturbed_list[n_perturbed++] = bi;
00093
00094
00095
00096
00097
00098
00099 }
00100
00101 if (FAST_ACCESS) {
00102
00103
00104
00105 qsort(perturbed_list, n_perturbed, sizeof(hdynptr), compare_ptr);
00106 }
00107
00108 cerr << endl
00109 << "Rebuilt perturbed_list; n_perturbed = " << n_perturbed
00110 << endl;
00111 }
00112
00113 void hdyn::dump_perturbed_list()
00114 {
00115 if (n_perturbed <= 0) return;
00116
00117 cerr << "Perturbed_list (n_perturbed = " << n_perturbed << "):"
00118 << endl;
00119
00120 for (int i = 0; i < n_perturbed; i++)
00121 cerr << " " << i << " " << perturbed_list[i]
00122 << " " << perturbed_list[i]->format_label() << endl;
00123 }
00124
00125 int hdyn::get_index_on_perturbed_list(bool debug)
00126 {
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 if (!FAST_ACCESS) {
00138
00139
00140
00141 bool below = true;
00142 for (int i = 0; i < n_perturbed; i++) {
00143 if (perturbed_list[i] == this)
00144 return i;
00145 else if (below && perturbed_list[i] > this)
00146 below = false;
00147 }
00148
00149 if (below)
00150 return -1;
00151 else
00152 return n_perturbed;
00153
00154 } else {
00155
00156
00157
00158 if (debug)
00159 cerr << "In get_index_on_perturbed_list for " << format_label()
00160 << " at time " << system_time << endl;
00161
00162 if (this < perturbed_list[0])
00163 return -1;
00164 else if (this > perturbed_list[n_perturbed-1])
00165 return n_perturbed;
00166
00167 int ilow = 0, ihigh = n_perturbed - 1;
00168
00169 while (ilow < ihigh) {
00170
00171 int imid = (ilow + ihigh)/2;
00172
00173
00174
00175 if (imid == ilow) {
00176 if (perturbed_list[ihigh] == this)
00177 return ihigh;
00178 else
00179 return ilow;
00180 }
00181
00182 if (perturbed_list[imid] == this)
00183 return imid;
00184 else if (perturbed_list[imid] < this)
00185 ilow = imid;
00186 else
00187 ihigh = imid;
00188
00189 if (debug) {
00190 PRC(this), PRC(ilow), PRL(ihigh);
00191 PRC(perturbed_list[ilow]), PRL(perturbed_list[ihigh]);
00192 }
00193 }
00194
00195 return ilow;
00196 }
00197 }
00198
00199 bool hdyn::on_perturbed_list()
00200 {
00201 int i = get_index_on_perturbed_list();
00202 return (i >= 0 && i < n_perturbed && perturbed_list[i] == this);
00203 }
00204
00205 void hdyn::check_perturbed_list()
00206 {
00207
00208
00209
00210
00211 if (!perturbed_list) {
00212
00213 cerr << endl
00214 << "check_perturbed_list: perturbed_list = NULL!"
00215 << endl;
00216
00217 } else {
00218
00219 int i;
00220 bool reconstruct_list = false;
00221
00222
00223
00224 for_all_daughters(hdyn, get_root(), bi)
00225 if (bi->is_perturbed_cm()) {
00226 if ((i = bi->get_index_on_perturbed_list()) < 0
00227 || i >= n_perturbed
00228 || perturbed_list[i] != bi) {
00229 cerr << "check_perturbed_list: " << bi->format_label()
00230 << " not on perturbed_list" << endl;
00231 reconstruct_list = true;
00232 }
00233 }
00234
00235
00236
00237 for (i = 0; i < n_perturbed; i++) {
00238 if (!perturbed_list[i]->is_perturbed_cm()) {
00239 cerr << "check_perturbed_list: entry " << i
00240 << " " << perturbed_list[i]->format_label()
00241 << " is not perturbed" << endl;
00242 reconstruct_list = true;
00243 }
00244 }
00245
00246
00247
00248 for (i = 0; i < n_perturbed-1; i++) {
00249 if (perturbed_list[i] >= perturbed_list[i+1]) {
00250 cerr << "perturbed_list corrupted at i = " << i << endl;
00251 reconstruct_list = true;
00252 }
00253 }
00254
00255
00256
00257 if (reconstruct_list) {
00258 dump_perturbed_list();
00259 reconstruct_perturbed_list();
00260 }
00261 }
00262 }
00263
00264 void hdyn::add_to_perturbed_list(int id)
00265 {
00266 if (!options->use_perturbed_list) return;
00267
00268 if (!perturbed_list) {
00269 perturbed_list = new hdynptr[get_root()->n_leaves()];
00270 n_perturbed = 0;
00271 }
00272
00273
00274
00275
00276
00277
00278 int i = get_index_on_perturbed_list();
00279
00280 if (i >= 0 && i < n_perturbed && perturbed_list[i] == this) {
00281
00282 cerr << "***** warning: add_to_perturbed_list: node "
00283 << this << " " << format_label() << " already on list"
00284 << endl;
00285
00286 check_perturbed_list();
00287
00288 } else {
00289
00290 if (FAST_ACCESS) {
00291
00292
00293
00294
00295
00296 if (i < n_perturbed) i++;
00297
00298
00299
00300 for (int j = n_perturbed; j > i; j--)
00301 perturbed_list[j] = perturbed_list[j-1];
00302
00303 } else
00304
00305 i = n_perturbed;
00306
00307 perturbed_list[i] = this;
00308 n_perturbed++;
00309
00310 if (diag->report_adjust_perturbed_list) {
00311
00312 cerr << "added node " << this << " " << format_label()
00313 << " to perturbed_list at time " << system_time
00314 << endl
00315 << " index = " << i
00316 << " n_perturbed = " << n_perturbed;
00317
00318 if (id > 0) cerr << " (ID = " << id << ")";
00319
00320 cerr << endl;
00321 }
00322 }
00323 }
00324
00325 void hdyn::remove_from_perturbed_list(int id)
00326 {
00327 if (!options->use_perturbed_list) return;
00328
00329
00330
00331 for_all_nodes(node, get_root(), bb)
00332 if(bb!=bb->get_starbase()->get_node()) {
00333 PRC(bb->format_label());
00334 PRC(bb);PRL(bb->get_starbase()->get_node());
00335 }
00336
00337 if (!perturbed_list || n_perturbed <= 0) return;
00338
00339 int i = get_index_on_perturbed_list();
00340
00341 if (i < 0 || i >= n_perturbed || perturbed_list[i] != this) {
00342
00343 cerr << "***** warning: remove_from_perturbed_list: node "
00344 << this << " " << format_label() << " not on list"
00345 << endl;
00346
00347 check_perturbed_list();
00348
00349 } else {
00350
00351
00352
00353 for (int j = i; j < n_perturbed-1; j++)
00354 perturbed_list[j] = perturbed_list[j+1];
00355
00356 n_perturbed--;
00357
00358 if (diag->report_adjust_perturbed_list) {
00359
00360 cerr << "removed node " << this << " " << format_label()
00361 << " from perturbed_list at time " << system_time
00362 << endl
00363 << " index = " << i
00364 << " n_perturbed = " << n_perturbed;
00365
00366 if (id > 0) cerr << " (ID = " << id << ")";
00367
00368 cerr << endl;
00369 }
00370 }
00371
00372 for_all_nodes(node, get_root(), bb)
00373 if(bb!=bb->get_starbase()->get_node()) {
00374 PRC(bb->format_label());
00375 PRC(bb);PRL(bb->get_starbase()->get_node());
00376 }
00377 }