| 475 | #ifdef USE_PERFORMANCE_OPTIMIZATION |
| 476 | |
| 477 | void TimeStep::precomputeValues() |
| 478 | { |
| 479 | Simulation* sim = Simulation::getCurrent(); |
| 480 | const unsigned int nFluids = sim->numberOfFluidModels(); |
| 481 | |
| 482 | for (unsigned int fluidModelIndex = 0; fluidModelIndex < nFluids; fluidModelIndex++) |
| 483 | { |
| 484 | FluidModel* model = sim->getFluidModel(fluidModelIndex); |
| 485 | model->get_precomputed_indices().clear(); |
| 486 | model->get_precomputed_indices_same_phase().clear(); |
| 487 | model->get_precomputed_V_gradW().clear(); |
| 488 | const int numParticles = (int)model->numActiveParticles(); |
| 489 | |
| 490 | auto& precomputed_indices = model->get_precomputed_indices(); |
| 491 | auto& precomputed_indices_same_phase = model->get_precomputed_indices_same_phase(); |
| 492 | auto& precomputed_V_gradW = model->get_precomputed_V_gradW(); |
| 493 | precomputed_indices.reserve(numParticles+1); |
| 494 | precomputed_indices.push_back(0); |
| 495 | |
| 496 | precomputed_indices_same_phase.reserve(numParticles); |
| 497 | |
| 498 | unsigned int sumNeighborParticles = 0; |
| 499 | unsigned int sumNeighborParticlesSamePhase = 0; |
| 500 | for (int i = 0; i < numParticles; i++) |
| 501 | { |
| 502 | for (unsigned int pid = 0; pid < nFluids; pid++) |
| 503 | { |
| 504 | const unsigned int maxN = sim->numberOfNeighbors(fluidModelIndex, pid, i); |
| 505 | |
| 506 | // same phase |
| 507 | if (pid == fluidModelIndex) |
| 508 | precomputed_indices_same_phase.push_back(sumNeighborParticles); |
| 509 | |
| 510 | // steps of 8 values due to avx |
| 511 | sumNeighborParticles += maxN / 8; |
| 512 | if (maxN % 8 != 0) |
| 513 | sumNeighborParticles++; |
| 514 | } |
| 515 | precomputed_indices.push_back(sumNeighborParticles); |
| 516 | } |
| 517 | |
| 518 | if (sumNeighborParticles > precomputed_V_gradW.capacity()) |
| 519 | precomputed_V_gradW.reserve(static_cast<int>(1.5 * sumNeighborParticles)); |
| 520 | precomputed_V_gradW.resize(sumNeighborParticles); |
| 521 | |
| 522 | #pragma omp parallel default(shared) |
| 523 | { |
| 524 | #pragma omp for schedule(static) |
| 525 | for (int i = 0; i < (int)numParticles; i++) |
| 526 | { |
| 527 | const Vector3r& xi = model->getPosition(i); |
| 528 | const Vector3f8 xi_avx(xi); |
| 529 | const unsigned int base = precomputed_indices[i]; |
| 530 | unsigned int idx = 0; |
| 531 | forall_fluid_neighbors_avx( |
| 532 | const Scalarf8 Vj_avx = convert_zero(fm_neighbor->getVolume(0), count); |
| 533 | precomputed_V_gradW[base + idx] = CubicKernel_AVX::gradW(xi_avx - xj_avx) * Vj_avx; |
| 534 | idx++; |
nothing calls this directly
no test coverage detected