/* * Evaluate the potential (i.e. the stream function psi) at a particular target location (xt, yt), * given an array of nodes and their expansions */ void evaluate(const Node* nodes, const int node_id, const double *xdata, const double *ydata, const double *mdata, const double thetasquared, double * const result, const double xt, const double yt) { // INPUT // nodes array of nodes for the tree of data we're working with // node_id index indicating the node we am considering now (used for recursive call) inside the array of nodes // expansions array of expansions for these nodes (not needed, we're actually implementing expansion as an attribute of node) // xdata array of x-coordinates of the source-particles (all of them, not just the ones contained in the node. Needed for passing this array down in the recursion) // ydata ........ y-coordinates ....................... // mdata ........ source-values ....................... (vorticities) // thetasquared . // xt x-coordinate of the location of the target // yt y-coordinate ............................. // OUTPUT // result potential at target location (xt, yt) const Node* const node = nodes + node_id; // create a pointer to the node we're considering if(node->r > -0.5){ // if this node isn't empty, go on with the evaluation if(node->r == 0){ // if the node contains only 1 particle const int n_s = node->part_start; // compute the p2p expansion *result += p2p(xdata + n_s, ydata + n_s, mdata + n_s, 1, xt, yt); return; } // if the node contains strictly more than one particle, compute the distance between the target and the center of mass of the node double distsquared = ( (node->xcom - xt)*(node->xcom - xt) + (node->ycom - yt)*(node->ycom -yt) ) ; // square of the distance between the target location and the center of mass of the node // recursive algorithm for the evaluation of the potential // pseudo-code, cf lecture 4, slide 24 if( (node->r * node->r) < (distsquared * thetasquared) ){ // if the target and the node are sufficiently far away from each other // return the expansion to particle expression as a potential *result += e2p(xt - node->xcom, yt - node->ycom, node->mass, exp_order, node->rxps, node->ixps); return; // and terminate the call to "evaluate" } else if(node->child_id == -1){ // if they're not sufficiently far away from each other // and if this node is a leaf, // then we cannot descend deeper into the tree // return the particle-to-particle expansion const int n_s = node->part_start; const int n_e = node->part_end; *result += p2p(xdata + n_s, ydata + n_s, mdata + n_s, n_e - n_s + 1, xt, yt); return; } else { // in any other case, // i.e., they are not sufficiently far away from each other, and this node isn't a leaf // continue the descent of the tree evaluate(nodes, node->child_id , xdata, ydata, mdata, thetasquared, result, xt, yt) ; evaluate(nodes, node->child_id+1, xdata, ydata, mdata, thetasquared, result, xt, yt) ; evaluate(nodes, node->child_id+2, xdata, ydata, mdata, thetasquared, result, xt, yt) ; evaluate(nodes, node->child_id+3, xdata, ydata, mdata, thetasquared, result, xt, yt) ; } } }
static uint16_type e2p( uint16_type e, uint16_type p ) { return e2p( e,p,boost::mpl::int_<( Order>3 )?1:Order>() ); }