Пример #1
0
local void upward_pass(kdxptr kd, int cell)
{
  kdnode *ntab = kd->ntab;

  if (ntab[cell].dim != -1) {			// not a terminal node?
    upward_pass(kd, Lower(cell));
    upward_pass(kd, Upper(cell));
    combine_nodes(&ntab[cell], &ntab[Lower(cell)], &ntab[Upper(cell)]);
  } else					// scan bodies in node
    set_bounds(&ntab[cell].bnd, kd->bptr, ntab[cell].first, ntab[cell].last);
}
Пример #2
0
void FMM2D::recalculate()
{
    if (!m_tree) {
        build_tree();
    }
    reset();
    upward_pass();
    downward_pass();
}
Пример #3
0
void FMM2D::calculate(bool precond)
{
    reset();
    m_make_prec = precond;
    build_tree();
    upward_pass();
    downward_pass();
    m_make_prec = false;
}
Пример #4
0
void build_kdtree(kdxptr kd, int nbucket)
{
    int k, n, i, d, m, j, ct;
    kdnode *ntab;

    n = kd->ngas;
    k = 1;
    while (n > nbucket) {
	n = n>>1;
	k = k<<1;
    }
    kd->nnode = k<<1;
    kd->nsplit = k;
    ntab = kd->ntab = (kdnode *) allocate(kd->nnode * sizeof(kdnode));
    ntab[KDROOT].first = 0;			/* initialize root node	    */
    ntab[KDROOT].last = kd->ngas-1;
    ntab[KDROOT].bnd = kd->bnd;
    i = KDROOT;
    ct = KDROOT;
    SetNext(ct);
    for ( ; ; ) {				/* loop splitting nodes	    */
	if (i < kd->nsplit) {
	    d = 0;				/* find longest dimension   */
	    for (j=1; j<3; ++j) {
		if (ntab[i].bnd.maxb[j]-ntab[i].bnd.minb[j] > 
		      ntab[i].bnd.maxb[d]-ntab[i].bnd.minb[d])
		    d = j;
	    }
	    m = median_index(kd->bptr, d, ntab[i].first, ntab[i].last);
	    ntab[i].dim = d;
	    ntab[i].split = Pos(kd->bptr[m])[d];
	    ntab[Lower(i)].bnd = ntab[i].bnd;
	    ntab[Lower(i)].bnd.maxb[d] = ntab[i].split;
	    ntab[Lower(i)].first = ntab[i].first;
	    ntab[Lower(i)].last = m-1;
	    ntab[Upper(i)].bnd = ntab[i].bnd;
	    ntab[Upper(i)].bnd.minb[d] = ntab[i].split;
	    ntab[Upper(i)].first = m;
	    ntab[Upper(i)].last = ntab[i].last;
	    i = Lower(i);
	} else {
	    ntab[i].dim = -1;
	    SetNext(i);
	    if (i == ct) break;
	}
    }
    upward_pass(kd, KDROOT);
}