262 |
|
} |
263 |
|
} |
264 |
|
|
265 |
– |
/* Advect and allocate new RBF along edge */ |
266 |
– |
static RBFNODE * |
267 |
– |
e_advect_rbf(const MIGRATION *mig, const FVECT invec, int lobe_lim) |
268 |
– |
{ |
269 |
– |
double cthresh = FTINY; |
270 |
– |
RBFNODE *rbf; |
271 |
– |
int n, i, j; |
272 |
– |
double t, full_dist; |
273 |
– |
/* get relative position */ |
274 |
– |
t = Acos(DOT(invec, mig->rbfv[0]->invec)); |
275 |
– |
if (t < M_PI/grid_res) { /* near first DSF */ |
276 |
– |
n = sizeof(RBFNODE) + sizeof(RBFVAL)*(mig->rbfv[0]->nrbf-1); |
277 |
– |
rbf = (RBFNODE *)malloc(n); |
278 |
– |
if (rbf == NULL) |
279 |
– |
goto memerr; |
280 |
– |
memcpy(rbf, mig->rbfv[0], n); /* just duplicate */ |
281 |
– |
rbf->next = NULL; rbf->ejl = NULL; |
282 |
– |
return(rbf); |
283 |
– |
} |
284 |
– |
full_dist = acos(DOT(mig->rbfv[0]->invec, mig->rbfv[1]->invec)); |
285 |
– |
if (t > full_dist-M_PI/grid_res) { /* near second DSF */ |
286 |
– |
n = sizeof(RBFNODE) + sizeof(RBFVAL)*(mig->rbfv[1]->nrbf-1); |
287 |
– |
rbf = (RBFNODE *)malloc(n); |
288 |
– |
if (rbf == NULL) |
289 |
– |
goto memerr; |
290 |
– |
memcpy(rbf, mig->rbfv[1], n); /* just duplicate */ |
291 |
– |
rbf->next = NULL; rbf->ejl = NULL; |
292 |
– |
return(rbf); |
293 |
– |
} |
294 |
– |
t /= full_dist; |
295 |
– |
tryagain: |
296 |
– |
n = 0; /* count migrating particles */ |
297 |
– |
for (i = 0; i < mtx_nrows(mig); i++) |
298 |
– |
for (j = 0; j < mtx_ncols(mig); j++) |
299 |
– |
n += (mtx_coef(mig,i,j) > cthresh); |
300 |
– |
/* are we over our limit? */ |
301 |
– |
if ((lobe_lim > 0) & (n > lobe_lim)) { |
302 |
– |
cthresh = cthresh*2. + 10.*FTINY; |
303 |
– |
goto tryagain; |
304 |
– |
} |
305 |
– |
#ifdef DEBUG |
306 |
– |
fprintf(stderr, "Input RBFs have %d, %d nodes -> output has %d\n", |
307 |
– |
mig->rbfv[0]->nrbf, mig->rbfv[1]->nrbf, n); |
308 |
– |
#endif |
309 |
– |
rbf = (RBFNODE *)malloc(sizeof(RBFNODE) + sizeof(RBFVAL)*(n-1)); |
310 |
– |
if (rbf == NULL) |
311 |
– |
goto memerr; |
312 |
– |
rbf->next = NULL; rbf->ejl = NULL; |
313 |
– |
VCOPY(rbf->invec, invec); |
314 |
– |
rbf->nrbf = n; |
315 |
– |
rbf->vtotal = 1.-t + t*mig->rbfv[1]->vtotal/mig->rbfv[0]->vtotal; |
316 |
– |
n = 0; /* advect RBF lobes */ |
317 |
– |
for (i = 0; i < mtx_nrows(mig); i++) { |
318 |
– |
const RBFVAL *rbf0i = &mig->rbfv[0]->rbfa[i]; |
319 |
– |
const float peak0 = rbf0i->peak; |
320 |
– |
const double rad0 = R2ANG(rbf0i->crad); |
321 |
– |
FVECT v0; |
322 |
– |
float mv; |
323 |
– |
ovec_from_pos(v0, rbf0i->gx, rbf0i->gy); |
324 |
– |
for (j = 0; j < mtx_ncols(mig); j++) |
325 |
– |
if ((mv = mtx_coef(mig,i,j)) > cthresh) { |
326 |
– |
const RBFVAL *rbf1j = &mig->rbfv[1]->rbfa[j]; |
327 |
– |
double rad2; |
328 |
– |
FVECT v; |
329 |
– |
int pos[2]; |
330 |
– |
rad2 = R2ANG(rbf1j->crad); |
331 |
– |
rad2 = rad0*rad0*(1.-t) + rad2*rad2*t; |
332 |
– |
rbf->rbfa[n].peak = peak0 * mv * rbf->vtotal * |
333 |
– |
rad0*rad0/rad2; |
334 |
– |
rbf->rbfa[n].crad = ANG2R(sqrt(rad2)); |
335 |
– |
ovec_from_pos(v, rbf1j->gx, rbf1j->gy); |
336 |
– |
geodesic(v, v0, v, t, GEOD_REL); |
337 |
– |
pos_from_vec(pos, v); |
338 |
– |
rbf->rbfa[n].gx = pos[0]; |
339 |
– |
rbf->rbfa[n].gy = pos[1]; |
340 |
– |
++n; |
341 |
– |
} |
342 |
– |
} |
343 |
– |
rbf->vtotal *= mig->rbfv[0]->vtotal; /* turn ratio into actual */ |
344 |
– |
return(rbf); |
345 |
– |
memerr: |
346 |
– |
fprintf(stderr, "%s: Out of memory in e_advect_rbf()\n", progname); |
347 |
– |
exit(1); |
348 |
– |
return(NULL); /* pro forma return */ |
349 |
– |
} |
350 |
– |
|
265 |
|
/* Advect between recorded incident angles and allocate new RBF */ |
266 |
|
RBFNODE * |
267 |
|
advect_rbf(const FVECT invec, int lobe_lim) |