inline void update_forces(particle_t* pi, particle_t* pj, float h2, float rho0, float C0, float Cp, float Cv, float* pia, float* pja) { float dx[3]; vec3_diff(dx, pi->x, pj->x); float r2 = vec3_len2(dx); if (r2 < h2) { const float rhoi = pi->rho; const float rhoj = pj->rho; float q = sqrt(r2 / h2); float u = 1 - q; float w0 = C0 * u / rhoi / rhoj; float wp = w0 * Cp * (rhoi + rhoj - 2 * rho0) * u / q; float wv = w0 * Cv; float dv[3]; vec3_diff(dv, pi->v, pj->v); // Equal and opposite pressure forces vec3_saxpy(pia, wp, dx); vec3_saxpy(pja, -wp, dx); // Equal and opposite viscosity forces vec3_saxpy(pia, wv, dv); vec3_saxpy(pja, -wv, dv); } }
union vec3 *vec3_normalize(union vec3 *vo, const union vec3 *vi) { float len = sqrt(vec3_len2(vi)); vo->v.x = vi->v.x / len; vo->v.y = vi->v.y / len; vo->v.z = vi->v.z / len; return vo; }
int nearest_faction(union vec3 v) { int i; double len; int winner = 0; union vec3 distv; for (i = 0; i < nfactions(); i++) { double dist; vec3_sub(&distv, &v, &fact[i].center); dist = vec3_len2(&distv); if (i == 0 || dist < len) { len = dist; winner = i; } } return winner; }
static void add_subdivided_triangle( triangle trg, float edge_length_limit2, triangle** output, size_t* count, size_t* allocated ) { if(edge_length_limit2 > 0.0f) { // If the longest edge of the triangle has length larger than the limit, // then we split that edge. float maxval = -1.0f; int maxval_i = 0; for(int i = 0; i < 3; ++i) { int j = (i + 1) % 3; float val = vec3_len2(vec3_sub(trg.corners[i], trg.corners[j])); if(val > maxval) { maxval = val; maxval_i = i; } } if(maxval > edge_length_limit2) { triangle trg1 = trg; triangle trg2 = trg; int i = maxval_i; int j = (i + 1) % 3; int k = (j + 1) % 3; // We don't split exactly at the center to have some nice randomness // in the triangles. double t = 0.4f + 0.2f * (double)rand() / (double)RAND_MAX; vec3 split = vec3_add( vec3_mul(trg.corners[i], 1.0f - t), vec3_mul(trg.corners[j], t) ); trg1.corners[0] = split; trg1.corners[1] = trg.corners[k]; trg1.corners[2] = trg.corners[i]; trg2.corners[0] = split; trg2.corners[1] = trg.corners[j]; trg2.corners[2] = trg.corners[k]; add_subdivided_triangle( trg1, edge_length_limit2, output, count, allocated ); add_subdivided_triangle( trg2, edge_length_limit2, output, count, allocated ); return; } } ++(*count); while((*count) > (*allocated)) { (*allocated) *= 2; *output = checked_realloc2(*output, *allocated, sizeof(triangle)); } (*output)[(*count) - 1] = trg; }