void SPHSystem::computeForce() { int i, j, s, numNei; float dij; float term1, term2; Point3f vij; Point3f pf, vf, tf, gf, cf; //#pragma omp parallel for private( j, nId, numNei, d, term1, term2, dv, pf, vf, tf, gf ) for(i=0; i<p.size(); ++i) { pf.Set(0,0,0); vf.Set(0,0,0); tf.Set(0,0,0); numNei = p[i]->pq.getSize(); for(s=1; s<=numNei; ++s) { j = p[i]->pq.queue[s]; if(i==j) continue; term1 = p[i]->p/(p[i]->d*p[i]->d); term2 = p[j]->p/(p[j]->d*p[j]->d); vij = *p[i]-*p[j]; dij = vij.Length(); // pressure force pf += (term1+term2)*p[j]->m*k->pw1(dij)*vij; // viscosity force vf += p[j]->m*k->vw2(dij)*(p[j]->v-p[i]->v); // surface tension } pf = -p[i]->d*pf; vf = (X/p[i]->d)*vf; gf = p[i]->d*Point3f(0.0f, -GR, 0.0f); if(p[i]->n.Length() < ( SIM_DIM==2 ? 0.6f : 3.0f) ) // for 2d < 0.6 , 3d < 3.0 tf.Zero(); else tf = -p[i]->lapc*p[i]->n.GetNormalized(); p[i]->tf = tf; p[i]->pf = pf; p[i]->vf = vf; p[i]->a = (pf+vf+gf+tf)/p[i]->d; } }
void SPHSystem::computeDensityPressure() { int i, j, s, numNei; float lapc, c, d; float w; float vj; // volumn float lenij; // length (i,j) Point3f n; Point3f vecij; // vector (i,j) for(i=0; i<p.size(); ++i) { p[i]->vol = p[i]->m/p[i]->d; } #pragma omp parallel for private(s, j, numNei, lapc, c, d, w, vj, lenij, n, vecij ) for(i=0; i<p.size(); ++i) { lapc = 0; c = 0; d = 0; n.Zero(); numNei = p[i]->pq.getSize(); for(s=1; s<=numNei; ++s) { j = p[i]->pq.queue[s]; vj = p[j]->vol; vecij = *p[i]-*p[j]; lenij = vecij.Length(); w = k->w(lenij); c += p[j]->c*p[j]->m*(vj)*w; n += p[j]->m*(vj)*k->w1(lenij)*(vecij); lapc += p[j]->m*(vj)*k->w2(lenij); d += p[j]->m*w; } p[i]->lapc = lapc; // laplacian of c p[i]->c = c; // color field p[i]->n = n; // inward surface normal p[i]->d = d; // density p[i]->p = (K*RHO/7.0f)*(pow((d/RHO),7.0f)-1); // pressure (Tait Equation, http://graphics.stanford.edu/~wicke/eg09-tutorial/coursenotes.pdf) if(p[i]->p < 0) // correct pressure if p<0 p[i]->p *= Z; // reduce it to a tiny number (~=0) } }