307void WakekNNnewForCollaps(
const std::vector<Vortex2D>& vtx,
const size_t k, std::vector<std::vector<std::pair<double, size_t>>>& initdist,
308 double cSP,
double cRBP,
double maxG,
double epsCol,
int type)
312 double preTime = -omp_get_wtime();
314 const size_t n = vtx.size();
317 auto xx = std::minmax_element(vtx.begin(), vtx.end(), [](
const Vortex2D& P1,
const Vortex2D& P2) {return P1.r()[0] < P2.r()[0]; });
318 auto yy = std::minmax_element(vtx.begin(), vtx.end(), [](
const Vortex2D& P1,
const Vortex2D& P2) {return P1.r()[1] < P2.r()[1]; });
320 double scale = std::max(xx.second->r()[0] - xx.first->r()[0], yy.second->r()[1] - yy.first->r()[1]);
323 std::vector<unsigned int> s(256 * omp_get_max_threads());
325 std::vector<TParticleCode> mcdata(vtx.size());
326 std::vector<TParticleCode> mcdata_temp(vtx.size());
331 const int nSdvig = 5;
332 double tStart[nSdvig], tFinish[nSdvig];
333 double tm[nSdvig][5];
335 preTime += omp_get_wtime();
337 std::pair<double, size_t> zeroPair = std::make_pair<double, size_t>(0.0, 0);
338 std::pair<double, size_t> minusOnePair = std::make_pair<double, size_t>(-1.0, 0);
340 std::vector<std::pair<double, size_t>> dist(2 * k, { -1.0, 0 });
341 std::vector<size_t> loc(2 * k);
342 std::vector<size_t> counter(2 * k, 0);
343 std::vector<size_t> offset(2 * k, 0);
344 std::vector<size_t> counterScan(2 * k, 0);
345 std::vector<std::pair<double, size_t>> dstKeys1(2 * k, zeroPair);
347 std::vector<std::pair<double, size_t>> updateNN(k, zeroPair);
348 std::vector<std::pair<double, size_t>> dstKeys(k, zeroPair);
351 for (
size_t sdvig = 0; sdvig < nSdvig ; ++sdvig)
353 tStart[sdvig] = omp_get_wtime();
355 const Point2D& lowLeft = { xx.first->r()[0], yy.first->r()[1] };
356 double* time = tm[sdvig];
360 time[0] = omp_get_wtime();
361#pragma omp parallel for
362 for (
int i = 0; i < vtx.size(); ++i)
364 Point2D sh = (vtx[i].r() - lowLeft) * (0.75 / scale) + sdvig *
Point2D{ 0.05, 0.05 };
365 mcdata[i].key = Morton2D(sh);
366 mcdata[i].originNumber = i;
369 time[1] = omp_get_wtime();
372 RSort_Parallel(mcdata.data(), mcdata_temp.data(), (
int)mcdata.size(), s.data());
374 time[2] = omp_get_wtime();
376 for (
size_t idx = 0; idx < 2 * k; ++idx)
378 dist[idx] = minusOnePair;
379 dstKeys1[idx] = zeroPair;
380 loc[idx] = counter[idx] = offset[idx] = counterScan[idx] = 0;
383 for (
size_t idx = 0; idx < k; ++idx)
384 updateNN[idx] = dstKeys[idx] = zeroPair;
386 time[3] = omp_get_wtime();
388#pragma omp parallel for firstprivate(dist, loc, counter, offset, counterScan, updateNN, dstKeys, dstKeys1)
389 for (
int i = 0; i < initdist.size(); ++i)
391 const Vortex2D& vtxi = vtx[mcdata[i].originNumber];
395 std::vector<std::pair<double, size_t>>& fillPosition = ((sdvig == 0) ? initdist[mcdata[i].originNumber] : dist);
397 while ((cntr < k) && (search >= 0))
399 const Vortex2D& vtxk = vtx[mcdata[search].originNumber];
400 bool flagExit, check;
402 std::tie(flagExit, check) = calcCheck(vtxi, vtxk, maxG, cSP, cRBP, epsCol, type, d2);
407 if ((mcdata[search].originNumber > mcdata[i].originNumber) && check)
408 fillPosition[cntr++] = { d2, mcdata[search].originNumber };
413 for (
int w = cntr; w < k; ++w)
414 fillPosition[cntr++] = { 100000000.0, 0 };
418 while ((cntr < 2 * k) && (search < mcdata.size()))
420 const Vortex2D& vtxk = vtx[mcdata[search].originNumber];
421 bool flagExit, check;
423 std::tie(flagExit, check) = calcCheck(vtxi, vtxk, maxG, cSP, cRBP, epsCol, type, d2);
428 if ((mcdata[search].originNumber > mcdata[i].originNumber) && check)
429 fillPosition[cntr++] = { d2, mcdata[search].originNumber };
433 for (
int w = cntr; w < 2 * k; ++w)
434 fillPosition[cntr++] = { 100000000.0, 0 };
438 newSort(initdist[mcdata[i].originNumber], dstKeys1);
439 initdist[mcdata[i].originNumber].resize(k);
443 newSort(dist, dstKeys1);
444 newMerge(mcdata[i].originNumber, initdist[mcdata[i].originNumber], dist, loc, counter, offset, counterScan, updateNN);
445 newSort(initdist[mcdata[i].originNumber], dstKeys);
449 time[4] = omp_get_wtime();
451 tFinish[sdvig] = omp_get_wtime();
458void WakekNNnewForEpsast(
const std::vector<BH::PointsCopy>& vtx,
const size_t k, std::vector<std::vector<std::pair<double, size_t>>>& initdist)
462 double preTime = -omp_get_wtime();
464 const size_t n = vtx.size();
467 auto xx = std::minmax_element(vtx.begin(), vtx.end(), [](
const Vortex2D& P1,
const Vortex2D& P2) {return P1.r()[0] < P2.r()[0]; });
468 auto yy = std::minmax_element(vtx.begin(), vtx.end(), [](
const Vortex2D& P1,
const Vortex2D& P2) {return P1.r()[1] < P2.r()[1]; });
470 double scale = std::max(xx.second->r()[0] - xx.first->r()[0], yy.second->r()[1] - yy.first->r()[1]);
473 std::vector<unsigned int> s(256 * omp_get_max_threads());
475 std::vector<TParticleCode> mcdata(vtx.size());
476 std::vector<TParticleCode> mcdata_temp(vtx.size());
481 const int nSdvig = 5;
482 double tStart[nSdvig], tFinish[nSdvig];
483 double tm[nSdvig][5];
485 preTime += omp_get_wtime();
487 std::pair<double, size_t> zeroPair = std::make_pair<double, size_t>(0.0, 0);
488 std::pair<double, size_t> minusOnePair = std::make_pair<double, size_t>(-1.0, 0);
490 std::vector<std::pair<double, size_t>> dist(2 * k, { -1.0, 0 });
491 std::vector<size_t> loc(2 * k);
492 std::vector<size_t> counter(2 * k, 0);
493 std::vector<size_t> offset(2 * k, 0);
494 std::vector<size_t> counterScan(2 * k, 0);
495 std::vector<std::pair<double, size_t>> dstKeys1(2 * k, zeroPair);
497 std::vector<std::pair<double, size_t>> updateNN(k, zeroPair);
498 std::vector<std::pair<double, size_t>> dstKeys(k, zeroPair);
501 for (
size_t sdvig = 0; sdvig < nSdvig ; ++sdvig)
503 tStart[sdvig] = omp_get_wtime();
505 const Point2D& lowLeft = { xx.first->r()[0], yy.first->r()[1] };
506 double* time = tm[sdvig];
510 time[0] = omp_get_wtime();
511#pragma omp parallel for
512 for (
int i = 0; i < vtx.size(); ++i)
514 Point2D sh = (vtx[i].r() - lowLeft) * (0.75 / scale) + sdvig *
Point2D{ 0.05, 0.05 };
515 mcdata[i].key = Morton2D(sh);
516 mcdata[i].originNumber = i;
519 time[1] = omp_get_wtime();
522 RSort_Parallel(mcdata.data(), mcdata_temp.data(), (
int)mcdata.size(), s.data());
524 time[2] = omp_get_wtime();
526 for (
size_t idx = 0; idx < 2 * k; ++idx)
528 dist[idx] = minusOnePair;
529 dstKeys1[idx] = zeroPair;
530 loc[idx] = counter[idx] = offset[idx] = counterScan[idx] = 0;
533 for (
size_t idx = 0; idx < k; ++idx)
534 updateNN[idx] = dstKeys[idx] = zeroPair;
536 time[3] = omp_get_wtime();
538#pragma omp parallel for firstprivate(dist, loc, counter, offset, counterScan, updateNN, dstKeys, dstKeys1)
539 for (
int i = 0; i < initdist.size(); ++i)
541 const Vortex2D& vtxi = vtx[mcdata[i].originNumber];
545 std::vector<std::pair<double, size_t>>& fillPosition = ((sdvig == 0) ? initdist[mcdata[i].originNumber] : dist);
547 while ((cntr < k) && (search >= 0))
549 const Vortex2D& vtxk = vtx[mcdata[search].originNumber];
550 double d2 = (vtxi.
r()-vtxk.
r()).length2();
551 fillPosition[cntr++] = { d2, mcdata[search].originNumber };
555 for (
int w = cntr; w < k; ++w)
556 fillPosition[cntr++] = { 100000000.0, 0 };
560 while ((cntr < 2 * k) && (search < mcdata.size()))
562 const Vortex2D& vtxk = vtx[mcdata[search].originNumber];
563 double d2 = (vtxi.
r() - vtxk.
r()).length2();
564 fillPosition[cntr++] = { d2, mcdata[search].originNumber };
567 for (
int w = cntr; w < 2 * k; ++w)
568 fillPosition[cntr++] = { 100000000.0, 0 };
572 newSort(initdist[mcdata[i].originNumber], dstKeys1);
573 initdist[mcdata[i].originNumber].resize(k);
577 newSort(dist, dstKeys1);
578 newMerge(mcdata[i].originNumber, initdist[mcdata[i].originNumber], dist, loc, counter, offset, counterScan, updateNN);
579 newSort(initdist[mcdata[i].originNumber], dstKeys);
583 time[4] = omp_get_wtime();
585 tFinish[sdvig] = omp_get_wtime();