//------------------------------------------------------------------------------ void Solver::Advance (float timeStep) { Timer t; t.Start(); updateBlendValues(); mFluidHashTable[LOW]->Fill(mFluidParticles[LOW]->ActiveIDs); mFluidHashTable[HIGH]->Fill(mFluidParticles[HIGH]->ActiveIDs); computeDensity(LOW); computeDensity(HIGH); computeAcceleration(LOW); computeAcceleration(HIGH); integrate(HIGH, timeStep/2.0f); mFluidHashTable[HIGH]->Fill(mFluidParticles[HIGH]->ActiveIDs); computeDensity(HIGH); computeAcceleration(HIGH); integrate(HIGH, timeStep/2.0f); integrate(LOW, timeStep); inject(); t.Stop(); std::cout << "#LOW " << mFluidParticles[LOW]->ActiveIDs.size() << " #HIGH " << mFluidParticles[HIGH]->ActiveIDs.size() << " #TOTAL: " << mFluidParticles[LOW]->ActiveIDs.size() + mFluidParticles[HIGH]->ActiveIDs.size() << "TIME: " << t.GetElapsed() << std::endl; }
/* Performs one step of Euler Integration as a result, updates the jello structure */ void Euler(cloth *clothItem) { int index; computeAcceleration(clothItem); for(int row = 0; row < clothItem->height; row++) { for(int col = 0; col < clothItem->width; col++) { index = FindIndexInArray(row, col, clothItem->width); if(index == 0 || index == clothItem->width-1) continue; clothItem->positions[index].x += clothItem->tStep * clothItem->velocities[index].x; clothItem->positions[index].y += clothItem->tStep * clothItem->velocities[index].y; clothItem->positions[index].z += clothItem->tStep * clothItem->velocities[index].z; clothItem->velocities[index].x += clothItem->tStep * clothItem->acceleration[index].x; clothItem->velocities[index].y += clothItem->tStep * clothItem->acceleration[index].y; clothItem->velocities[index].z += clothItem->tStep * clothItem->acceleration[index].z; } } }
// Update particle acclerations void updateAccelerations(fluid_particle *fluid_particles, boundary_particle *boundary_particles, param *params) { int num_fluid_particles = params->number_fluid_particles; int num_boundary_particles = params->number_boundary_particles; for(int i=0; i<num_fluid_particles; i++) { double ax = 0.0; double ay = 0.0; double az = -9.8; double3 p_pos = fluid_particles[i].pos; double3 p_v = fluid_particles[i].v; double p_density = fluid_particles[i].density; double p_pressure = fluid_particles[i].pressure; for(int j=0; j<num_fluid_particles; j++) { if (i!=j) { double3 q_pos = fluid_particles[j].pos; double3 q_v = fluid_particles[j].v; double q_density = fluid_particles[j].density; double q_pressure = fluid_particles[j].pressure; double3 tmp_a = computeAcceleration(p_pos, p_v, p_density, p_pressure, q_pos, q_v, q_density, q_pressure, params); ax += tmp_a.x; ay += tmp_a.y; az += tmp_a.z; } } fluid_particles[i].a.x = ax; fluid_particles[i].a.y = ay; fluid_particles[i].a.z = az; } for(int i=0; i<num_fluid_particles; i++) { double ax = fluid_particles[i].a.x; double ay = fluid_particles[i].a.y; double az = fluid_particles[i].a.z; double3 p_pos = fluid_particles[i].pos; for (int j=0; j<num_boundary_particles; j++) { double3 k_pos = boundary_particles[j].pos; double3 k_n = boundary_particles[j].n; double3 tmp_a = computeBoundaryAcceleration(p_pos,k_pos,k_n, params->smoothing_radius, params->speed_sound); ax += tmp_a.x; ay += tmp_a.y; az += tmp_a.z; } fluid_particles[i].a.x = ax; fluid_particles[i].a.y = ay; fluid_particles[i].a.z = az; } }
void CSimuVertexRingObj::computeStiffnessMatrix(void) { CSparseMatrix33 *pmat = this->getOdeIntegrator()->getSparseMatrix(); if (pmat==NULL) return; pmat->clear(); const bool needJacobian = true; computeAcceleration(1, needJacobian); }
void SPHSystem::step() { curframe++; cout << "frame " << curframe << " out of " << params.nframes << endl; if (curframe < params.nframes) { for (int i = 0; i < params.nsteps; ++i) { computeAcceleration(); leapFrog(); checkState(); } if( params.writeLog ) writeFrame(&pressure[0]); } }
/* as a result, updates the chain structure */ void Euler(struct chain * chain) { point a[chain->number]; computeAcceleration(chain, a); for (int i=1; i<=chain->number; i++) { chain->p[i].x += chain->dt * chain->v[i].x; chain->p[i].y += chain->dt * chain->v[i].y; chain->v[i].x += chain->dt * a[i-1].x; chain->v[i].y += chain->dt * a[i-1].y; } }
void SPHSystem::init() { curframe = 0; if( params.writeLog ) { logstream = ofstream(params.logfile, ios::binary); // write initial state writeHeader(); writeFrame(&pressure[0]); } // step once computeAcceleration(); leapFrogStart(); checkState(); }
void Smoke::update(float Pmass) { computeAcceleration(); float DeltaTime = ofGetLastFrameTime(); accelerate(DeltaTime); move(DeltaTime); // bounceInWindow(); if(position.distance(initalPos)>300.0f) { position=initalPos; } mass=Pmass; }
/* as a result, updates the jello structure */ void Euler(struct world * jello) { computeAcceleration(jello); /*printf("A start\n"); for (int i=0; i<particleNum; i++) { printf("a[%d].x = %f a.y = %f a.z = %f\n",i,jello->a[i][0][0].x,jello->a[i][0][0].y, jello->a[i][0][0].z); } printf("\n");*/ for (int i=1; i<particleNum; i++) { jello->v[i].x += jello->dt * jello->a[i].x; jello->v[i].y += jello->dt * jello->a[i].y; jello->p[i].x += jello->dt * jello->v[i].x; jello->p[i].y += jello->dt * jello->v[i].y; } }
/* as a result, updates the jello structure */ void Euler(struct world * jello) { int i,j,k; point a[8][8][8]; computeAcceleration(jello, a); for (i=0; i<=7; i++) for (j=0; j<=7; j++) for (k=0; k<=7; k++) { jello->p[i][j][k].x += jello->dt * jello->v[i][j][k].x; jello->p[i][j][k].y += jello->dt * jello->v[i][j][k].y; jello->p[i][j][k].z += jello->dt * jello->v[i][j][k].z; jello->v[i][j][k].x += jello->dt * a[i][j][k].x; jello->v[i][j][k].y += jello->dt * a[i][j][k].y; jello->v[i][j][k].z += jello->dt * a[i][j][k].z; } }
/* Performs one step of Euler Integration as a result, updates the jello structure */ void Euler(struct world * jello) { int i,j,k; point a[8][8][8]; memset( (void*)force, 0, sizeof(force)); memset( (void*)a, 0, sizeof(a)); computeAcceleration(jello, a); for (i=0; i<=7; i++) for (j=0; j<=7; j++) for (k=0; k<=7; k++) { jello->p[i][j][k].x += jello->dt * jello->v[i][j][k].x; jello->p[i][j][k].y += jello->dt * jello->v[i][j][k].y; jello->p[i][j][k].z += jello->dt * jello->v[i][j][k].z; jello->v[i][j][k].x += jello->dt * a[i][j][k].x; jello->v[i][j][k].y += jello->dt * a[i][j][k].y; jello->v[i][j][k].z += jello->dt * a[i][j][k].z; } }
/* as a result, updates the jello structure */ void RK4(cloth *clothItem) { int index; point *F1p, *F1v, *F2p, *F2v, *F3p, *F3v, *F4p, *F4v; F1p = (point*)calloc(clothItem->cArrayLength, sizeof(point)); F1v = (point*)calloc(clothItem->cArrayLength, sizeof(point)); F2p = (point*)calloc(clothItem->cArrayLength, sizeof(point)); F2v = (point*)calloc(clothItem->cArrayLength, sizeof(point)); F3p = (point*)calloc(clothItem->cArrayLength, sizeof(point)); F3v = (point*)calloc(clothItem->cArrayLength, sizeof(point)); F4p = (point*)calloc(clothItem->cArrayLength, sizeof(point)); F4v = (point*)calloc(clothItem->cArrayLength, sizeof(point)); cloth *buffer = (cloth*)malloc(1 * sizeof(cloth)); CopyToBuffer(buffer, clothItem); computeAcceleration(clothItem); for(int row = 0; row < clothItem->height; row++) { for(int col = 0; col < clothItem->width; col++) { index = FindIndexInArray(row, col, clothItem->width); // Pin Check if(gPin == PINNED) { if(index == 0 || index == clothItem->width-1) continue; } else if(gPin == UNPINLEFT) { if(index == clothItem->width-1) continue; } else if(gPin == UNPINRIGHT) { if(index == 0) continue; } pMULTIPLY(clothItem->velocities[index], clothItem->tStep, F1p[index]); pMULTIPLY(clothItem->acceleration[index], clothItem->tStep, F1v[index]); pMULTIPLY(F1p[index], 0.5, buffer->positions[index]); pMULTIPLY(F1v[index], 0.5, buffer->velocities[index]); pSUM(clothItem->positions[index], buffer->positions[index], buffer->positions[index]); pSUM(clothItem->velocities[index], buffer->velocities[index], buffer->velocities[index]); } } for(int i= 0; i < clothItem->cArrayLength; i++) { pCPY(clothItem->acceleration[i], buffer->acceleration[i]); } computeAcceleration(buffer); for(int row = 0; row < clothItem->height; row++) { for(int col = 0; col < clothItem->width; col++) { index = FindIndexInArray(row, col, clothItem->width); // Pin Check if(gPin == PINNED) { if(index == 0 || index == clothItem->width-1) continue; } else if(gPin == UNPINLEFT) { if(index == clothItem->width-1) continue; } else if(gPin == UNPINRIGHT) { if(index == 0) continue; } pMULTIPLY(buffer->velocities[index], clothItem->tStep, F2p[index]); pMULTIPLY(buffer->acceleration[index], clothItem->tStep, F2v[index]); pMULTIPLY(F2p[index], 0.5, buffer->positions[index]); pMULTIPLY(F2v[index], 0.5, buffer->velocities[index]); pSUM(clothItem->positions[index], buffer->positions[index], buffer->positions[index]); pSUM(clothItem->velocities[index], buffer->velocities[index], buffer->velocities[index]); } } computeAcceleration(buffer); for(int row = 0; row < clothItem->height; row++) { for(int col = 0; col < clothItem->width; col++) { index = FindIndexInArray(row, col, clothItem->width); // Pin Check if(gPin == PINNED) { if(index == 0 || index == clothItem->width-1) continue; } else if(gPin == UNPINLEFT) { if(index == clothItem->width-1) continue; } else if(gPin == UNPINRIGHT) { if(index == 0) continue; } pMULTIPLY(buffer->velocities[index], clothItem->tStep, F3p[index]); pMULTIPLY(buffer->acceleration[index], clothItem->tStep, F3v[index]); pMULTIPLY(F3p[index], 0.5, buffer->positions[index]); pMULTIPLY(F3v[index], 0.5, buffer->velocities[index]); pSUM(clothItem->positions[index], buffer->positions[index], buffer->positions[index]); pSUM(clothItem->velocities[index], buffer->velocities[index], buffer->velocities[index]); } } computeAcceleration(buffer); for(int row = 0; row < clothItem->height; row++) { for(int col = 0; col < clothItem->width; col++) { index = FindIndexInArray(row, col, clothItem->width); // Pin Check if(gPin == PINNED) { if(index == 0 || index == clothItem->width-1) continue; } else if(gPin == UNPINLEFT) { if(index == clothItem->width-1) continue; } else if(gPin == UNPINRIGHT) { if(index == 0) continue; } pMULTIPLY(buffer->velocities[index], clothItem->tStep, F4p[index]); pMULTIPLY(buffer->acceleration[index], clothItem->tStep, F4v[index]); pMULTIPLY(F2p[index], 2, buffer->positions[index]); pMULTIPLY(F3p[index], 2, buffer->velocities[index]); pSUM(buffer->positions[index], buffer->velocities[index], buffer->positions[index]); pSUM(buffer->positions[index], F1p[index], buffer->positions[index]); pSUM(buffer->positions[index], F4p[index], buffer->positions[index]); pMULTIPLY(buffer->positions[index], 1.0 / 6, buffer->positions[index]); pSUM(buffer->positions[index], clothItem->positions[index], clothItem->positions[index]); pMULTIPLY(F2v[index], 2, buffer->positions[index]); pMULTIPLY(F3v[index], 2, buffer->velocities[index]); pSUM(buffer->positions[index], buffer->velocities[index], buffer->positions[index]); pSUM(buffer->positions[index], F1v[index], buffer->positions[index]); pSUM(buffer->positions[index], F4v[index], buffer->positions[index]); pMULTIPLY(buffer->positions[index], 1.0 / 6, buffer->positions[index]); pSUM(buffer->positions[index], clothItem->velocities[index], clothItem->velocities[index]); } } for(int i= 0; i < clothItem->cArrayLength; i++) { pCPY(buffer->acceleration[i], clothItem->acceleration[i]); } for(int i= 0; i < clothItem->cArrayLength; i++) { // Pin Check if(gPin == PINNED) { if(index == 0 || index == clothItem->width-1) continue; } else if(gPin == UNPINLEFT) { if(index == clothItem->width-1) continue; } else if(gPin == UNPINRIGHT) { if(index == 0) continue; } pMULTIPLY(clothItem->velocities[i], gDelta, underWaterDamp); pSUM(clothItem->velocities[i], underWaterDamp, clothItem->velocities[i]); pSUM(clothItem->force[i], gravity, clothItem->force[i]); } free(buffer); return; }
// Update particle acclerations void updateAccelerations(fluid_particle *fluid_particles, boundary_particle *boundary_particles, param *params) { int num_fluid_particles = params->number_fluid_particles; int num_boundary_particles = params->number_boundary_particles; #pragma acc parallel loop default(present) for(int i=0; i<num_fluid_particles; i++) { double ax = 0.0; double ay = 0.0; double az = -9.8; double3 p_pos = fluid_particles[i].pos; double3 p_v = fluid_particles[i].v; double p_density = fluid_particles[i].density; double p_pressure = fluid_particles[i].pressure; for(int j=0; j<num_fluid_particles; j++) { if (i!=j) { double3 q_pos = fluid_particles[j].pos; double3 q_v = fluid_particles[j].v; double q_density = fluid_particles[j].density; double q_pressure = fluid_particles[j].pressure; double3 tmp_a; computeAcceleration(&tmp_a, p_pos, p_v, p_density, p_pressure, q_pos, q_v, q_density, q_pressure, params[0].smoothing_radius, params[0].alpha, params[0].speed_sound, params[0].mass_particle,params[0].surface_tension); ax += tmp_a.x; ay += tmp_a.y; az += tmp_a.z; } } fluid_particles[i].a.x = ax; fluid_particles[i].a.y = ay; fluid_particles[i].a.z = az; } #pragma acc parallel loop default(present) for(int i=0; i<num_fluid_particles; i++) { double ax = fluid_particles[i].a.x; double ay = fluid_particles[i].a.y; double az = fluid_particles[i].a.z; double3 p_pos = fluid_particles[i].pos; for (int j=0; j<num_boundary_particles; j++) { double3 k_pos = boundary_particles[j].pos; double3 k_n = boundary_particles[j].n; double3 tmp_a; computeBoundaryAcceleration(&tmp_a, p_pos,k_pos,k_n, params[0].smoothing_radius, params[0].speed_sound); ax += tmp_a.x; ay += tmp_a.y; az += tmp_a.z; } fluid_particles[i].a.x = ax; fluid_particles[i].a.y = ay; fluid_particles[i].a.z = az; } }
int main(int argc, char* argv[]){ // domain variables int iter = 0; int i; int file_index; int max_iter; double max_time = 1.0; double dt = .0000001; double domain_box[4] = {0.0, 0.0, 1.0, 2.0}; double domain_m_box[4] = {.10, 0.2, 0.90, 2.00}; int domain_num_cells[2] = {10, 20}; int pp_cell[2] = {2,2}; double ipart_dim[2]; int domain_num_particles[2]; double test_px, test_py; char p_filename[40]; char p_filename2[40]; char g_filename[40]; //timing variables double start_time; double end_time; // patch variables int rank = 0; int size; int num_proc[2]; double box[4]; double m_box[4]; int num_cells[2]; int halo_cells[4] = {1,1,1,1}; int num_particles[2]; int sfactor = 2; GridData grid_data; Node** grid; InitialParticleData ipart_data; Particle* particles; Particle* post_particles; Particle* particle_list; Particle* rhalo_parts[8]; Particle* shalo_parts[8]; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Request halo_req[8][2]; MPI_Status halo_stat[8][2]; max_iter = (int)(max_time/dt); if(rank == 0){ if(argc == 3){ num_proc[0] = atoi(argv[1]); num_proc[1] = atoi(argv[2]); }else if(argc == 6){ num_proc[0] = atoi(argv[1]); num_proc[1] = atoi(argv[2]); domain_num_cells[0] = atoi(argv[3]); domain_num_cells[1] = atoi(argv[4]); max_iter = atoi(argv[5]); } } MPI_Bcast(num_proc, 2, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(domain_num_cells, 2, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&max_iter, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); grid_data.gravity[0] = 0; grid_data.gravity[1] = -900.8; grid_data.cell_dim[0] = (domain_box[2] - domain_box[0])/domain_num_cells[0]; grid_data.cell_dim[1] = (domain_box[3] - domain_box[1])/domain_num_cells[1]; test_px = grid_data.cell_dim[0]/pp_cell[0]; test_py = grid_data.cell_dim[1]/pp_cell[1]; domain_num_particles[0] = (int)((domain_m_box[2] - domain_m_box[0])/test_px); domain_num_particles[1] = (int)((domain_m_box[3] - domain_m_box[1])/test_py); ipart_dim[0] = (domain_m_box[2] - domain_m_box[0])/domain_num_particles[0]; ipart_dim[1] = (domain_m_box[3] - domain_m_box[1])/domain_num_particles[1]; decomposeGrid(rank, num_proc, domain_num_cells, num_cells, domain_box, box, halo_cells, &grid_data); decomposeMaterial(box, domain_m_box, m_box, ipart_dim, num_particles); ipart_data.density = 1000; ipart_data.bulk = 3; ipart_data.shear = 4; ipart_data.E = 90000; ipart_data.poisson = .30; ipart_data.idim[0] = ipart_dim[0]; ipart_data.idim[1] = ipart_dim[1]; ipart_data.velocity[0] = 0; ipart_data.velocity[1] = 0; ipart_data.box[0] = m_box[0]; ipart_data.box[1] = m_box[1]; ipart_data.box[2] = m_box[2]; ipart_data.box[3] = m_box[3]; ipart_data.num_particles[0] = num_particles[0]; ipart_data.num_particles[1] = num_particles[1]; ipart_data.domain_num_particles[0] = domain_num_particles[0]; ipart_data.domain_num_particles[1] = domain_num_particles[1]; grid = createGrid(&grid_data, box, num_cells); particles = createMaterial(&grid_data, &ipart_data); post_particles = createMaterial(&grid_data, &ipart_data); initializeGrid(&grid_data, grid); initializeMaterial(&grid_data, &ipart_data, particles); //allocate halo particles allocateHaloParticles(&grid_data, sfactor, pp_cell, rhalo_parts, shalo_parts); file_index = 0; start_time = MPI_Wtime(); for(iter = 0; iter <= max_iter; iter++){ gatherHaloParticles(&grid_data, particles, rhalo_parts, shalo_parts); sendRecvParticles(&grid_data, rhalo_parts, shalo_parts); clearGridValues(&grid_data, grid); mapToGrid(&grid_data, grid, particles); for(i = 0; i < 8; i++){ if(grid_data.rank[i] >= 0 && rhalo_parts[i][0].particle_count > 0){ mapToGrid(&grid_data, grid, rhalo_parts[i]); } } momentumToVelocityOnGrid(&grid_data, grid); computeForces(&grid_data, grid, particles); for(i = 0; i < 8; i++){ if(grid_data.rank[i] >= 0 && rhalo_parts[i][0].particle_count > 0){ computeForces(&grid_data, grid, rhalo_parts[i]); } } computeAcceleration(&grid_data, grid); /** particle_list = gatherParticles(rank, size, domain_num_particles[0] * domain_num_particles[1], particles, post_particles); if(rank == 0){ //if(iter%100 == 0){ sprintf(p_filename, "ppart%06d.vtk", file_index); //sprintf(p_filename2, "center%06d.vtk", file_index); //sprintf(g_filename, "grid_output%06d.vtk", file_index); //writeParticlesVtkFile(&grid_data, grid, rhalo_parts[0], p_filename); writeParticlesVtkFile(&grid_data, grid, particle_list, p_filename); //writeParticlesVtkFile(&grid_data, grid, particle_list, p_filename); //writeParticlesVtkFile(&grid_data, grid, particles, p_filename); //writeGridVtkFile(&grid_data, grid, g_filename); //writeGridVtkFile(&grid_data, grid, g_filename); //free(particle_list); file_index++; //} } **/ updateNodalValues(&grid_data, grid, dt); updateStressAndStrain(&grid_data, grid, particles, dt); pUpdateParticlePosition(&grid_data, grid, particles, post_particles, shalo_parts, dt); sendRecvParticles(&grid_data, rhalo_parts, shalo_parts); updateParticleList(&grid_data, particles, rhalo_parts); /** particle_list = gatherParticles(rank, size, domain_num_particles[0] * domain_num_particles[1], particles, post_particles); if(rank == 0){ sprintf(p_filename, "particle_output%06d.vtk", file_index); file_index++; //sprintf(g_filename, "grid_output%06d.vtk", file_index); writeParticlesVtkFile(&grid_data, grid, particles, p_filename); //writeParticlesVtkFile(&grid_data, grid, particle_list, p_filename); //writeParticlesVtkFile(&grid_data, grid, particles, p_filename); //writeGridVtkFile(&grid_data, grid, g_filename); free(particle_list); } **/ MPI_Barrier(MPI_COMM_WORLD); } end_time = MPI_Wtime(); MPI_Barrier(MPI_COMM_WORLD); //particle_list = gatherParticles(rank, size, domain_num_particles[0] * domain_num_particles[1], // particles, post_particles); if(rank == 0){ printf("Parallel, np: %d, iterations: %d, time: %f\n", size, max_iter, end_time-start_time); //writeParticlesVtkFile(&grid_data, grid, particle_list, "pparts.vtk"); //free(particle_list); } freeGrid(grid, &grid_data); freeMaterial(particles); freeMaterial(post_particles); freeHaloParticles(&grid_data, rhalo_parts, shalo_parts); //MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); return 0; }
void RK4(struct world * jello) { point F1p[999], F1v[999], F2p[999], F2v[999], F3p[999], F3v[999], F4p[999], F4v[999]; struct world buffer; int i,j,k; buffer = *jello; // make a copy of jello computeAcceleration(jello); for (i=0; i<particleNum; i++){ pMULTIPLY(jello->v[i],jello->dt,F1p[i]); pMULTIPLY(jello->a[i],jello->dt,F1v[i]); pMULTIPLY(F1p[i],0.5,buffer.p[i]); pMULTIPLY(F1v[i],0.5,buffer.v[i]); pSUM(jello->p[i],buffer.p[i],buffer.p[i]); pSUM(jello->v[i],buffer.v[i],buffer.v[i]); } computeAcceleration(&buffer); for (i=0; i<particleNum; i++){ // F2p = dt * buffer.v; pMULTIPLY(buffer.v[i],jello->dt,F2p[i]); // F2v = dt * a(buffer.p,buffer.v); pMULTIPLY(buffer.a[i],jello->dt,F2v[i]); pMULTIPLY(F2p[i],0.5,buffer.p[i]); pMULTIPLY(F2v[i],0.5,buffer.v[i]); pSUM(jello->p[i],buffer.p[i],buffer.p[i]); pSUM(jello->v[i],buffer.v[i],buffer.v[i]); } computeAcceleration(&buffer); for (i=0; i<particleNum; i++) { // F3p = dt * buffer.v; pMULTIPLY(buffer.v[i],jello->dt,F3p[i]); // F3v = dt * a(buffer.p,buffer.v); pMULTIPLY(buffer.a[i],jello->dt,F3v[i]); pMULTIPLY(F3p[i],0.5,buffer.p[i]); pMULTIPLY(F3v[i],0.5,buffer.v[i]); pSUM(jello->p[i],buffer.p[i],buffer.p[i]); pSUM(jello->v[i],buffer.v[i],buffer.v[i]); } computeAcceleration(&buffer); for (i=0; i<particleNum; i++) { // F3p = dt * buffer.v; pMULTIPLY(buffer.v[i],jello->dt,F4p[i]); // F3v = dt * a(buffer.p,buffer.v); pMULTIPLY(jello->a[i],jello->dt,F4v[i]); pMULTIPLY(F2p[i],2,buffer.p[i]); pMULTIPLY(F3p[i],2,buffer.v[i]); pSUM(buffer.p[i],buffer.v[i],buffer.p[i]); pSUM(buffer.p[i],F1p[i],buffer.p[i]); pSUM(buffer.p[i],F4p[i],buffer.p[i]); pMULTIPLY(buffer.p[i],1.0 / 6,buffer.p[i]); pSUM(buffer.p[i],jello->p[i],jello->p[i]); pMULTIPLY(F2v[i],2,buffer.p[i]); pMULTIPLY(F3v[i],2,buffer.v[i]); pSUM(buffer.p[i],buffer.v[i],buffer.p[i]); pSUM(buffer.p[i],F1v[i],buffer.p[i]); pSUM(buffer.p[i],F4v[i],buffer.p[i]); pMULTIPLY(buffer.p[i],1.0 / 6,buffer.p[i]); pSUM(buffer.p[i],jello->v[i],jello->v[i]); } return; }
/* as a result, updates the chain structure */ void RK4(struct chain * chain) { point F1p[chain->number], F1v[chain->number], F2p[chain->number], F2v[chain->number], F3p[chain->number], F3v[chain->number], F4p[chain->number], F4v[chain->number]; point a[chain->number]; struct chain buffer = *chain; computeAcceleration(chain, a); for (int i=1; i<=chain->number; i++) { pMULTIPLY(chain->v[i],chain->dt,F1p[i-1]); pMULTIPLY(a[i-1],chain->dt,F1v[i-1]); pMULTIPLY(F1p[i-1],0.5,buffer.p[i]); pMULTIPLY(F1v[i-1],0.5,buffer.v[i]); pSUM(chain->p[i],buffer.p[i],buffer.p[i]); pSUM(chain->v[i],buffer.v[i],buffer.v[i]); } computeAcceleration(&buffer, a); for (int i=1; i<=chain->number; i++) { // F2p = dt * buffer.v; pMULTIPLY(buffer.v[i], chain->dt, F2p[i-1]); // F2v = dt * a(buffer.p,buffer.v); pMULTIPLY(a[i-1], chain->dt, F2v[i-1]); pMULTIPLY(F2p[i-1], 0.5, buffer.p[i]); pMULTIPLY(F2v[i-1], 0.5, buffer.v[i]); pSUM(chain->p[i], buffer.p[i], buffer.p[i]); pSUM(chain->v[i], buffer.v[i], buffer.v[i]); } computeAcceleration(&buffer, a); for (int i=1; i<=chain->number; i++) { // F3p = dt * buffer.v; pMULTIPLY(buffer.v[i], chain->dt, F3p[i-1]); // F3v = dt * a(buffer.p,buffer.v); pMULTIPLY(a[i-1], chain->dt, F3v[i-1]); pMULTIPLY(F3p[i-1], 0.5, buffer.p[i]); pMULTIPLY(F3v[i-1], 0.5, buffer.v[i]); pSUM(chain->p[i], buffer.p[i], buffer.p[i]); pSUM(chain->v[i], buffer.v[i], buffer.v[i]); } computeAcceleration(&buffer, a); for (int i=1; i<=chain->number; i++) { // F3p = dt * buffer.v; pMULTIPLY(buffer.v[i], chain->dt, F4p[i-1]); // F3v = dt * a(buffer.p,buffer.v); pMULTIPLY(a[i-1], chain->dt, F4v[i-1]); pMULTIPLY(F2p[i-1], 2, buffer.p[i]); pMULTIPLY(F3p[i-1], 2, buffer.v[i]); pSUM(buffer.p[i], buffer.v[i], buffer.p[i]); pSUM(buffer.p[i], F1p[i-1], buffer.p[i]); pSUM(buffer.p[i], F4p[i-1], buffer.p[i]); pMULTIPLY(buffer.p[i], 1.0 / 6, buffer.p[i]); pSUM(buffer.p[i], chain->p[i], chain->p[i]); pMULTIPLY(F2v[i-1], 2, buffer.p[i]); pMULTIPLY(F3v[i-1], 2, buffer.v[i]); pSUM(buffer.p[i], buffer.v[i], buffer.p[i]); pSUM(buffer.p[i], F1v[i-1], buffer.p[i]); pSUM(buffer.p[i], F4v[i-1], buffer.p[i]); pMULTIPLY(buffer.p[i], 1.0 / 6, buffer.p[i]); pSUM(buffer.p[i], chain->v[i], chain->v[i]); } return; }
/* as a result, updates the jello structure */ void RK4(struct world * jello) { point F1p[8][8][8], F1v[8][8][8], F2p[8][8][8], F2v[8][8][8], F3p[8][8][8], F3v[8][8][8], F4p[8][8][8], F4v[8][8][8]; point a[8][8][8]; struct world buffer; int i,j,k; buffer = *jello; // make a copy of jello computeAcceleration(jello, a); for (i=0; i<=7; i++) for (j=0; j<=7; j++) for (k=0; k<=7; k++) { pMULTIPLY(jello->v[i][j][k],jello->dt,F1p[i][j][k]); pMULTIPLY(a[i][j][k],jello->dt,F1v[i][j][k]); pMULTIPLY(F1p[i][j][k],0.5,buffer.p[i][j][k]); pMULTIPLY(F1v[i][j][k],0.5,buffer.v[i][j][k]); pSUM(jello->p[i][j][k],buffer.p[i][j][k],buffer.p[i][j][k]); pSUM(jello->v[i][j][k],buffer.v[i][j][k],buffer.v[i][j][k]); } computeAcceleration(&buffer, a); for (i=0; i<=7; i++) for (j=0; j<=7; j++) for (k=0; k<=7; k++) { // F2p = dt * buffer.v; pMULTIPLY(buffer.v[i][j][k],jello->dt,F2p[i][j][k]); // F2v = dt * a(buffer.p,buffer.v); pMULTIPLY(a[i][j][k],jello->dt,F2v[i][j][k]); pMULTIPLY(F2p[i][j][k],0.5,buffer.p[i][j][k]); pMULTIPLY(F2v[i][j][k],0.5,buffer.v[i][j][k]); pSUM(jello->p[i][j][k],buffer.p[i][j][k],buffer.p[i][j][k]); pSUM(jello->v[i][j][k],buffer.v[i][j][k],buffer.v[i][j][k]); } computeAcceleration(&buffer, a); for (i=0; i<=7; i++) for (j=0; j<=7; j++) for (k=0; k<=7; k++) { // F3p = dt * buffer.v; pMULTIPLY(buffer.v[i][j][k],jello->dt,F3p[i][j][k]); // F3v = dt * a(buffer.p,buffer.v); pMULTIPLY(a[i][j][k],jello->dt,F3v[i][j][k]); pMULTIPLY(F3p[i][j][k],0.5,buffer.p[i][j][k]); pMULTIPLY(F3v[i][j][k],0.5,buffer.v[i][j][k]); pSUM(jello->p[i][j][k],buffer.p[i][j][k],buffer.p[i][j][k]); pSUM(jello->v[i][j][k],buffer.v[i][j][k],buffer.v[i][j][k]); } computeAcceleration(&buffer, a); for (i=0; i<=7; i++) for (j=0; j<=7; j++) for (k=0; k<=7; k++) { // F3p = dt * buffer.v; pMULTIPLY(buffer.v[i][j][k],jello->dt,F4p[i][j][k]); // F3v = dt * a(buffer.p,buffer.v); pMULTIPLY(a[i][j][k],jello->dt,F4v[i][j][k]); pMULTIPLY(F2p[i][j][k],2,buffer.p[i][j][k]); pMULTIPLY(F3p[i][j][k],2,buffer.v[i][j][k]); pSUM(buffer.p[i][j][k],buffer.v[i][j][k],buffer.p[i][j][k]); pSUM(buffer.p[i][j][k],F1p[i][j][k],buffer.p[i][j][k]); pSUM(buffer.p[i][j][k],F4p[i][j][k],buffer.p[i][j][k]); pMULTIPLY(buffer.p[i][j][k],1.0 / 6,buffer.p[i][j][k]); pSUM(buffer.p[i][j][k],jello->p[i][j][k],jello->p[i][j][k]); pMULTIPLY(F2v[i][j][k],2,buffer.p[i][j][k]); pMULTIPLY(F3v[i][j][k],2,buffer.v[i][j][k]); pSUM(buffer.p[i][j][k],buffer.v[i][j][k],buffer.p[i][j][k]); pSUM(buffer.p[i][j][k],F1v[i][j][k],buffer.p[i][j][k]); pSUM(buffer.p[i][j][k],F4v[i][j][k],buffer.p[i][j][k]); pMULTIPLY(buffer.p[i][j][k],1.0 / 6,buffer.p[i][j][k]); pSUM(buffer.p[i][j][k],jello->v[i][j][k],jello->v[i][j][k]); } return; }