62#include <siscone/siscone_error.h>
63#include <siscone/circulator.h>
64#include "protocones.h"
69namespace siscone_spherical{
108 if (
hc!=NULL)
delete hc;
124 multiple_centre_done.clear();
160 for (p_idx=0;p_idx<
n_part;p_idx++){
173#ifdef DEBUG_STABLE_CONES
174 cout << endl << endl;
175 cout <<
"plot 'particles.dat' u 2:1 pt 1 ps 3" << endl;
187 }
while (!update_cone());
190 return proceed_with_stability();
208int CSphstable_cones::init_cone(){
216 prepare_cocircular_lists();
226 centre_idx = first_cone;
231 compute_cone_contents();
243int CSphstable_cones::test_cone(){
285 cone_candidate = cone;
291 cone_candidate += *
parent;
294 cone_candidate = cone;
295 cone_candidate += *child;
299 cone_candidate += *
parent;
315int CSphstable_cones::update_cone(){
316#ifdef DEBUG_STABLE_CONES
317 cout <<
"call 'circles_plot.gp' '" << centre->
centre.
px <<
"' '"
319 <<
"pause -1 '(" << centre->
angle <<
" " << (centre->
side ?
'+' :
'-') <<
")";
326 if (centre_idx==first_cone)
334#ifdef DEBUG_STABLE_CONES
335 cout <<
" old_enter";
344 dpt += fabs(child->
px)+fabs(child->
py)+fabs(child->
pz);
356 if (cocircular_check()){
357#ifdef DEBUG_STABLE_CONES
358 cout <<
" Co-circular case detected" << endl;
360 return update_cone();
368#ifdef DEBUG_STABLE_CONES
379 dpt += fabs(child->
px)+fabs(child->
py)+fabs(child->
pz);
388 recompute_cone_contents();
391 cone = CSphmomentum();
395#ifdef DEBUG_STABLE_CONES
408int CSphstable_cones::proceed_with_stability(){
410 sph_hash_element *elm;
412 for (i=0;i<=
hc->
mask;i++){
421#ifdef USE_QUADTREE_FOR_STABILITY_TEST
423 if (quadtree->circle_intersect(elm->eta, elm->phi,
R2)==elm->ref)
426 if (circle_intersect(elm->centre)==elm->centre.
ref)
428 protocones.push_back(CSphmomentum(elm->centre,1.0));
439#ifdef DEBUG_STABLE_CONES
441 nb_hash_occupied =
hc->n_occupied_cells;
474void CSphstable_cones::prepare_cocircular_lists() {
482 CSphvicinity_elm* here_pntr = *here();
483 search.set_position(here);
489 if ( siscone::abs_dphi((*search())->angle, here_pntr->angle) <
490 here_pntr->cocircular_range
491 && search() != here()) {
492 (*search())->cocircular.push_back(here_pntr);
499 search.set_position(here);
502 if ( siscone::abs_dphi((*search())->angle, here_pntr->angle) <
503 here_pntr->cocircular_range
504 && search() != here()) {
505 (*search())->cocircular.push_back(here_pntr);
512 }
while (here() !=
vicinity.begin());
522void CSphstable_cones::test_cone_cocircular(CSphmomentum & borderless_cone,
523 list<CSphmomentum *> & border_list) {
527 CSph3vector angl_dir1, angl_dir2;
529 angl_dir1/=angl_dir1._norm;
530 angl_dir2/=angl_dir2._norm;
533 vector<CSphborder_store> border_vect;
534 border_vect.reserve(border_list.size());
535 for (list<CSphmomentum *>::iterator it = border_list.begin();
536 it != border_list.end(); it++) {
537 border_vect.push_back(CSphborder_store(*it, centre->
centre, angl_dir1, angl_dir2));
541 sort(border_vect.begin(), border_vect.end());
546 start(border_vect.begin(), border_vect.begin(),border_vect.end());
550 CSphmomentum candidate = borderless_cone;
552 if (candidate.ref.not_empty())
553 test_stability(candidate, border_vect);
559 mid()->is_in =
false;
560 }
while (++mid != start);
563 candidate = borderless_cone;
564 while (++mid != start) {
567 candidate += *(mid()->mom);
568 test_stability(candidate, border_vect);
571 }
while (++start != end);
576 candidate += *(mid()->mom);
577 test_stability(candidate, border_vect);
587void CSphstable_cones::test_stability(CSphmomentum & candidate,
const vector<CSphborder_store> & border_vect) {
593 for (
unsigned i = 0; i < border_vect.size(); i++) {
594 if (is_closer(&candidate, border_vect[i].mom,
tan2R) ^ (border_vect[i].is_in)) {
610bool CSphstable_cones::cocircular_check(){
629 dpt += fabs(child->
px)+fabs(child->
py)+fabs(child->
pz);
636 list<siscone::Cvicinity_inclusion *> removed_from_cone;
637 list<siscone::Cvicinity_inclusion *> put_in_border;
638 list<CSphmomentum *> border_list;
640 CSphmomentum cone_removal;
641 CSphmomentum border = *
parent;
642 border_list.push_back(
parent);
649 for(list<CSphvicinity_elm *>::iterator it = centre->
cocircular.begin();
652 if ((*it)->is_inside->cone) {
653 cone_removal += *((*it)->v);
654 (*it)->is_inside->cone =
false;
655 removed_from_cone.push_back((*it)->is_inside);
662 if (!(*it)->is_inside->cocirc) {
663 border += *((*it)->v);
664 (*it)->is_inside->cocirc =
true;
665 put_in_border.push_back((*it)->is_inside);
666 border_list.push_back((*it)->v);
673 CSphmomentum borderless_cone = cone;
674 borderless_cone -= cone_removal;
675 bool consider =
true;
676 for (
unsigned int i=0;i<multiple_centre_done.size();i++){
677 if ((multiple_centre_done[i].first ==borderless_cone.ref) &&
678 (multiple_centre_done[i].second==border.ref))
685 multiple_centre_done.push_back(pair<siscone::Creference,siscone::Creference>(borderless_cone.ref,
689 double local_dpt = fabs(cone_removal.px) + fabs(cone_removal.py);
690 double total_dpt = dpt + local_dpt;
692 recompute_cone_contents_if_needed(borderless_cone, total_dpt);
693 if (total_dpt == 0) {
696 cone = borderless_cone + cone_removal;
700 test_cone_cocircular(borderless_cone, border_list);
705 for(list<siscone::Cvicinity_inclusion *>::iterator is_in = removed_from_cone.begin();
706 is_in != removed_from_cone.end(); is_in++) {
707 (*is_in)->cone =
true;
711 for(list<siscone::Cvicinity_inclusion *>::iterator is_in = put_in_border.begin();
712 is_in != put_in_border.end(); is_in++) {
713 (*is_in)->cocirc =
false;
737void CSphstable_cones::compute_cone_contents() {
753 if (!(*here())->side) ((*here())->is_inside->cone) = 1;
759 if ((*here())->side) ((*here())->is_inside->cone) = 0;
760 }
while (here != start);
765 recompute_cone_contents();
776void CSphstable_cones::recompute_cone_contents(){
780 cone = CSphmomentum();
804void CSphstable_cones::recompute_cone_contents_if_needed(CSphmomentum & this_cone,
807 if (this_dpt >
PT_TSHOLD*(fabs(this_cone.px)+fabs(this_cone.py))) {
809 this_cone = CSphmomentum();
812 this_cone = CSphmomentum();
855 if (is_closer(&cone_centre, &(
plist[i]),
tan2R))
856 intersection+=
plist[i].ref;
references used for checksums.
bool is_empty()
test emptyness
bool not_empty()
test non-emptyness
unsigned int ref[3]
actual data for the reference
bool cone
flag for particle inclusion in the cone
a circulator that is foreseen to take as template member either a pointer or an iterator;
void get_angular_directions(CSph3vector &angular_dir1, CSph3vector &angular_dir2)
for this direction, compute the two reference directions used to measure angles
double _theta
particle theta angle (available ONLY after a call to build_thetaphi)
double _phi
particle phi angle (available ONLY after a call to build_thetaphi)
siscone::Creference ref
reference number for the vector
void init(std::vector< CSphmomentum > &_particle_list)
initialisation
int get_stable_cones(double _radius)
compute stable cones.
double tan2R
squared tangent of the cone radius
CSphstable_cones()
default ctor
sph_hash_cones * hc
list of candidates
~CSphstable_cones()
default dtor
double R2
cone radius SQUARED
int nb_tot
total number of tested cones
std::vector< CSphmomentum > protocones
list of stable cones
bool side
true if angle on the positive side, false otherwise
CSph3vector centre
direction of the centre
std::list< CSphvicinity_elm * > cocircular
list of elements co-circular with this one NB: empty list uses less mem than vector
double angle
angle with parent
CSphmomentum * v
pointer to the second borderline particle
siscone::Cvicinity_inclusion * is_inside
variable to tell if the particle is inside or outside the cone
list of element in the vicinity of a parent.
std::vector< CSphmomentum > plist
the list of particles
CSphmomentum * parent
parent vector
std::vector< CSphvicinity_elm * > vicinity
list of points in parent's vicinity
void set_particle_list(std::vector< CSphmomentum > &_particle_list)
set the particle_list
int n_part
number of particles
unsigned int vicinity_size
number of elements in vicinity
void build(CSphmomentum *_parent, double _VR)
build the vicinity list from the list of points.
list of cones candidates.
sph_hash_element ** hash_array
the cone data itself
int mask
number of occupied cells
int insert(CSphmomentum *v, CSphmomentum *parent, CSphmomentum *child, bool p_io, bool c_io)
insert a new candidate into the hash.
int n_cones
number of elements
#define PT_TSHOLD
program name