| 89 | } |
| 90 | |
| 91 | void FluidModel::initModel(const unsigned int nFluidParticles, Vector3r* fluidParticles, const unsigned int nBoundaryParticles, Vector3r* boundaryParticles) |
| 92 | { |
| 93 | releaseFluidParticles(); |
| 94 | resizeFluidParticles(nFluidParticles); |
| 95 | |
| 96 | // init kernel |
| 97 | CubicKernel::setRadius(m_supportRadius); |
| 98 | |
| 99 | // copy fluid positions |
| 100 | #pragma omp parallel default(shared) |
| 101 | { |
| 102 | #pragma omp for schedule(static) |
| 103 | for (int i = 0; i < (int)nFluidParticles; i++) |
| 104 | { |
| 105 | m_particles.getPosition0(i) = fluidParticles[i]; |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | m_boundaryX.resize(nBoundaryParticles); |
| 110 | m_boundaryPsi.resize(nBoundaryParticles); |
| 111 | |
| 112 | // copy boundary positions |
| 113 | #pragma omp parallel default(shared) |
| 114 | { |
| 115 | #pragma omp for schedule(static) |
| 116 | for (int i = 0; i < (int)nBoundaryParticles; i++) |
| 117 | { |
| 118 | m_boundaryX[i] = boundaryParticles[i]; |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | // initialize masses |
| 123 | initMasses(); |
| 124 | |
| 125 | ////////////////////////////////////////////////////////////////////////// |
| 126 | // Compute value psi for boundary particles (boundary handling) |
| 127 | // (see Akinci et al. "Versatile rigid - fluid coupling for incompressible SPH", Siggraph 2012 |
| 128 | ////////////////////////////////////////////////////////////////////////// |
| 129 | |
| 130 | // Search boundary neighborhood |
| 131 | NeighborhoodSearchSpatialHashing neighborhoodSearchSH(nBoundaryParticles, m_supportRadius); |
| 132 | neighborhoodSearchSH.neighborhoodSearch(&m_boundaryX[0]); |
| 133 | |
| 134 | unsigned int **neighbors = neighborhoodSearchSH.getNeighbors(); |
| 135 | unsigned int *numNeighbors = neighborhoodSearchSH.getNumNeighbors(); |
| 136 | |
| 137 | #pragma omp parallel default(shared) |
| 138 | { |
| 139 | #pragma omp for schedule(static) |
| 140 | for (int i = 0; i < (int) nBoundaryParticles; i++) |
| 141 | { |
| 142 | Real delta = CubicKernel::W_zero(); |
| 143 | for (unsigned int j = 0; j < numNeighbors[i]; j++) |
| 144 | { |
| 145 | const unsigned int neighborIndex = neighbors[i][j]; |
| 146 | delta += CubicKernel::W(m_boundaryX[i] - m_boundaryX[neighborIndex]); |
| 147 | } |
| 148 | const Real volume = static_cast<Real>(1.0) / delta; |
no test coverage detected