void LogResSolver3D::vel_step () { if(m_nbIter > m_nbMaxIter) return; add_source (m_u, m_uSrc); add_source (m_v, m_vSrc); add_source (m_w, m_wSrc); addVorticityConfinement(m_u,m_v,m_w); SWAP (m_uPrev, m_u); diffuse (1, m_u, m_uPrev, m_aVisc); SWAP (m_vPrev, m_v); diffuse (2, m_v, m_vPrev, m_aVisc); SWAP (m_wPrev, m_w); diffuse (3, m_w, m_wPrev, m_aVisc); m_index = 0; project (m_uPrev, m_vPrev); SWAP (m_uPrev, m_u); SWAP (m_vPrev, m_v); SWAP (m_wPrev, m_w); advect (1, m_u, m_uPrev, m_uPrev, m_vPrev, m_wPrev); advect (2, m_v, m_vPrev, m_uPrev, m_vPrev, m_wPrev); advect (3, m_w, m_wPrev, m_uPrev, m_vPrev, m_wPrev); m_index = 1; project (m_uPrev, m_vPrev); if(m_nbIter == m_nbMaxIter) cout << "Simulation over" << endl; }
//----------------------------------------------------------------------------- void StamFluidSolver::vel_step ( float * u, float * v, float * u0, float * v0, float visc, float dt ) { addSource ( u, u0, dt ); addSource ( v, v0, dt ); #if (VORTICITY_CONFINEMENT == 1) if(mUseVorticityConfinement) { // add in vorticity confinement force vorticityConfinement(u0, v0); addSource ( u, u0, dt ); addSource ( v, v0, dt ); } #endif #if 0 // add in temperature force if(mSimulateTemperature) { heatRise(v0); addSource ( v, v0, dt ); } #endif SWAP ( u0, u ); diffuse ( 1, u, u0, visc, dt ); SWAP ( v0, v ); diffuse ( 2, v, v0, visc, dt ); project ( u, v, u0, v0 ); SWAP ( u0, u ); SWAP ( v0, v ); advect ( 1, u, u0, u0, v0, dt ); advect ( 2, v, v0, u0, v0, dt ); project ( u, v, u0, v0 ); }
void vel_step ( int step , int method , int iters, int N , float* u, float* v , float* u0, float* v0 , float visc, float dt) { add_source ( N, u, u0, dt ); add_source ( N, v, v0, dt ); SWAP (u0, u); diffuse (method, iters, N, 1, u, u0, visc, dt); SWAP (v0, v); diffuse (method, iters, N, 2, v, v0, visc, dt); project (method, iters, N, u, v, u0, v0); SWAP (u0, u); SWAP (v0, v); advect (N, 1, u, u0, u0, v0, dt); advect (N, 2, v, v0, u0, v0, dt); project (method, iters, N, u, v, u0, v0); }
/* Function for setting up and running the fluid simulation kernels */ void solveFluid(struct Configuration* config) { // Jacobi settings float alpha = -1.0f; // Should use alpha -1 here, but this gives nicer results //float alpha = -(1.0f/invhalfgridscale); float rbeta = 0.25; int iterations = 100; // grid scaling. this is currently not used if(rank == 0){ float gridscale = 1.0f; float invgridscale = 1.0f/gridscale; float invhalfgridscale = 0.5f/gridscale; // Timstep value float timestep = 0.05f; // Emitter settings float amount = 2.0f; float radius = 0.5*config->N/10.0f; float emitterposx = config->N/2; float emitterposy = config->N/3; // buoyancy settings float bdiry = 1.0f; float bdirx = 0.0f; float bstrength = 0.1f; // advection settings float veldamp = 0.01f; // Velocity advection float *tmp = config->velx0; config->velx0 = config->velx; config->velx = tmp; float *tmp1 = config->vely0; config->vely0 = config->vely; config->vely = tmp1; advect(config->N, config->velx, config->velx0, config->velx0, config->vely0, timestep, veldamp, 1); advect(config->N, config->vely, config->vely0, config->velx0, config->vely0, timestep, veldamp, 2); // Density advection float *tmp2 = config->dens0; config->dens0 = config->dens; config->dens = tmp2; advect(config->N, config->dens, config->dens0, config->velx, config->vely, timestep, 0.0f, 0); // Add density and density buoyancy addDensity(config->N, config->dens, timestep, emitterposx, emitterposy, radius, amount); addDensityBuoyancy(config->N, config->velx, config->vely, config->dens, bdirx, bdiry, bstrength, timestep); // Divergence calculation divergence(config->N, config->velx, config->vely, config->div); // Pressure jacobi calculation. First set pres array to zero as initial guess setMem(config->N, config->pres); } jacobi(iterations); if(rank == 0){ // Calculate projection projection(config->N, config->velx, config->vely, config->pres); } }
/////////////////////////////////////////////////////////////////////////////// /// Calculate the velocity /// ///\param para Pointer to FFD parameters ///\param var Pointer to FFD simulation variables ///\param BINDEX Pointer to boundary index /// ///\return 0 if no error occurred /////////////////////////////////////////////////////////////////////////////// int vel_step(PARA_DATA *para, REAL **var,int **BINDEX) { REAL *u = var[VX], *v = var[VY], *w = var[VZ]; REAL *u0 = var[TMP1], *v0 = var[TMP2], *w0 = var[TMP3]; int flag = 0; flag = advect(para, var, VX, 0, u0, u, BINDEX); if(flag!=0) { ffd_log("vel_step(): Could not advect for velocity X.", FFD_ERROR); return flag; } flag = advect(para, var, VY, 0, v0, v, BINDEX); if(flag!=0) { ffd_log("vel_step(): Could not advect for velocity Y.", FFD_ERROR); return flag; } flag = advect(para, var, VZ, 0, w0, w, BINDEX); if(flag!=0) { ffd_log("vel_step(): Could not advect for velocity Z.", FFD_ERROR); return flag; } flag = diffusion(para, var, VX, 0, u, u0, BINDEX); if(flag!=0) { ffd_log("vel_step(): Could not diffuse velocity X.", FFD_ERROR); return flag; } flag = diffusion(para, var, VY, 0, v, v0, BINDEX); if(flag!=0) { ffd_log("vel_step(): Could not diffuse velocity Y.", FFD_ERROR); return flag; } flag = diffusion(para, var, VZ, 0, w, w0, BINDEX); if(flag!=0) { ffd_log("vel_step(): Could not diffuse velocity Z.", FFD_ERROR); return flag; } flag = project(para, var,BINDEX); if(flag!=0) { ffd_log("vel_step(): Could not project velocity.", FFD_ERROR); return flag; } if(para->bc->nb_outlet!=0) flag = mass_conservation(para, var,BINDEX); if(flag!=0) { ffd_log("vel_step(): Could not conduct mass conservation correction.", FFD_ERROR); return flag; } return flag; } // End of vel_step( )
void CompResAvgSolver3D::vel_step () { if(m_nbIter > m_nbMaxIter) if(m_omegaDiff < 1.9) { char file[100]; m_omegaDiff += 0.1; m_omegaProj += 0.1; sprintf(file, "logs/%2.1f/residualsAverage.log", m_omegaDiff); cout << "Processing " << file << endl; m_file.open (file, ios::out | ios::trunc); if (!m_file.is_open ()) cerr << "Can't open file " << file << endl; m_nbIter = 0; m_perturbateCount = 0; } else return; add_source (m_u, m_uSrc); add_source (m_v, m_vSrc); add_source (m_w, m_wSrc); addVorticityConfinement(m_u,m_v,m_w); SWAP (m_uPrev, m_u); diffuse (1, m_u, m_uPrev, m_aVisc); SWAP (m_vPrev, m_v); diffuse (2, m_v, m_vPrev, m_aVisc); SWAP (m_wPrev, m_w); diffuse (3, m_w, m_wPrev, m_aVisc); m_index = NB_DIFF_LOGS; project (m_uPrev, m_vPrev); SWAP (m_uPrev, m_u); SWAP (m_vPrev, m_v); SWAP (m_wPrev, m_w); advect (1, m_u, m_uPrev, m_uPrev, m_vPrev, m_wPrev); advect (2, m_v, m_vPrev, m_uPrev, m_vPrev, m_wPrev); advect (3, m_w, m_wPrev, m_uPrev, m_vPrev, m_wPrev); m_index = NB_DIFF_LOGS+1; project (m_uPrev, m_vPrev); if(m_nbIter == m_nbMaxIter){ for(uint i=0; i <= m_nbSteps; i++){ m_file << i << " "; for(uint j=0; j < (NB_PROJ_LOGS+NB_DIFF_LOGS) ; j++) m_file << m_averages[j*(m_nbSteps+1) + i] << " "; m_file << endl; } cout << "Simulation over" << endl; m_file.close (); } }
void vel_step(int width, int height, float *u, float *v, float *u0, float *v0, float visc, float dt) { add_source(width, height, u, u0, dt); add_source(width, height, v, v0, dt); SWAP(u0, u); diffuse(width, height, 1, u, u0, visc, dt); SWAP(v0, v); diffuse(width, height, 2, v, v0, visc, dt); project(width, height, u, v, u0, v0); SWAP(u0, u); SWAP(v0, v); advect(width, height, 1, u, u0, u0, v0, dt); advect(width, height, 2, v, v0, u0, v0, dt); project(width, height, u, v, u0, v0); }
void update_velocity(gaszone_type *gz, float * u, float * v, float * u0, float * v0, float visc, float dt ) { add_source (gz, u, u0, dt ); add_source (gz, v, v0, dt ); SWAP ( u0, u ); diffuse (gz, 1, u, u0, visc, dt ); SWAP ( v0, v ); diffuse (gz, 2, v, v0, visc, dt ); project (gz, u, v, u0, v0 ); SWAP ( u0, u ); SWAP ( v0, v ); advect (gz, 1, u, u0, u0, v0, dt ); advect (gz, 2, v, v0, u0, v0, dt ); project (gz, u, v, u0, v0 ); }
void update_velocity( float * u, float * v, float * u0, float * v0, float visc, float dt ) { add_source ( u, u0, dt ); add_source ( v, v0, dt ); SWAP ( u0, u ); diffuse ( 1, u, u0, visc, dt ); SWAP ( v0, v ); diffuse ( 2, v, v0, visc, dt ); project ( u, v, u0, v0 ); SWAP ( u0, u ); SWAP ( v0, v ); advect ( 1, u, u0, u0, v0, dt ); advect ( 2, v, v0, u0, v0, dt ); project ( u, v, u0, v0 ); }
/////////////////////////////////////////////////////////////////////////////// /// Calculate the contaminant concentration /// ///\param para Pointer to FFD parameters ///\param var Pointer to FFD simulation variables ///\param BINDEX Pointer to boundary index /// ///\return 0 if no error occurred /////////////////////////////////////////////////////////////////////////////// int den_step(PARA_DATA *para, REAL **var, int **BINDEX) { REAL *den, *den0 = var[TMP1]; int i, flag = 0; /**************************************************************************** | Solve the species ****************************************************************************/ for(i=0; i<para->bc->nb_Xi; i++) { if(para->outp->version==DEBUG) { sprintf(msg, "den_step(): start to solve Xi%d", i+1); ffd_log(msg, FFD_NORMAL); } den = var[Xi1+i]; flag = advect(para, var, Xi1+i, i, den0, den, BINDEX); if(flag!=0) { sprintf(msg, "den_step(): Could not advect species %d", i+1); ffd_log(msg, FFD_ERROR); return flag; } flag = diffusion(para, var, Xi1+i, i, den, den0, BINDEX); if(flag!=0) { sprintf(msg, "den_step(): Could not diffuse species %d", i+1); ffd_log(msg, FFD_ERROR); return flag; } } /**************************************************************************** | Solve the trace substances ****************************************************************************/ for(i=0; i<para->bc->nb_C; i++) { if(para->outp->version==DEBUG) { sprintf(msg, "den_step(): start to solve C%d", i+1); ffd_log(msg, FFD_NORMAL); } den = var[C1+i]; flag = advect(para, var, Xi1, i, den0, den, BINDEX); if(flag!=0) { sprintf(msg, "den_step(): Could not advect trace substance %d", i+1); ffd_log(msg, FFD_ERROR); return flag; } flag = diffusion(para, var, Xi1, i, den, den0, BINDEX); if(flag!=0) { sprintf(msg, "den_step(): Could not diffuse trace substance %d", i+1); ffd_log(msg, FFD_ERROR); return flag; } } return flag; } // End of den_step( )
void ShallowWater::computeOneStep() { Array2D<float> tempvX; Array2D<float> tempvY; m_n = advect(m_n); tempvX = advect(m_vX); tempvY = advect(m_vY); m_vX = tempvX; m_vY = tempvY; updateHeight(); plus(m_n, m_g, m_h); updateVelocities(); reflectingBoundaries(); }
void FluidField::velocityStep (float * u, float * v, float * u0, float * v0, float visc, float dt ) { add_source (u,u0, dt ); add_source (v,v0, dt ); SWAP ( u0, u ); diffuse ( 1, u, u0, visc, dt ); SWAP ( v0, v ); diffuse ( 2, v, v0, visc, dt ); project ( u, v, u0, v0 ); SWAP ( u0, u ); SWAP ( v0, v ); advect ( 1, u, u0, u0, v0, dt ); advect ( 2, v, v0, u0, v0, dt ); project ( u, v, u0, v0 ); }
//The main fluid simulation step void FluidSim::advance(float dt) { float t = 0; while(t < dt) { float substep = cfl(); if(t + substep > dt) substep = dt - t; //Passively advect particles advect_particles(substep); //Estimate the liquid signed distance compute_phi(); //Advance the velocity advect(substep); add_force(substep); apply_viscosity(substep); apply_projection(substep); //Pressure projection only produces valid velocities in faces with non-zero associated face area. //Because the advection step may interpolate from these invalid faces, //we must extrapolate velocities from the fluid domain into these zero-area faces. extrapolate(u, u_valid); extrapolate(v, v_valid); //For extrapolated velocities, replace the normal component with //that of the object. constrain_velocity(); t+=substep; } }
void MACStableFluids::step(Scalar dt) { float t=0; int count=0; while(t<dt) { float substep=cfl(); if(substep<0.000001) { std::cerr << "SUBSTEP GOING TOO LOW QUITTING\n"; return; } if(t+substep > dt) substep=dt-t; add_force(dt); advect(dt); diffuse(dt); project(dt); advect_particles(dt); ++count; t+=substep; } time += dt; }
/*************************************************************** * Solves the navier stokes equations for velocity... * i.e. satisfies: ∂u/∂t = -(div u)u + v Lap u + f ***************************************************************/ void FGS_Fluid_Solver2DS :: velocity_step(){ // Add forces from the old grid (+f) add_source(UX, OLD_UX); add_source(UY, OLD_UY); // Compute diffusion of cells' velocities based on viscosity diffuse (SET_FOR_HORIZONTAL_COMPONENT, OLD_UX, UX, viscosity); diffuse (SET_FOR_VERTICAL_COMPONENT, OLD_UY, UY, viscosity); // Compute the pressure so that the divergence in U = 0 project (OLD_UX, OLD_UY, UX, UY); advect (SET_FOR_HORIZONTAL_COMPONENT, UX, OLD_UX, OLD_UX, OLD_UY); advect (SET_FOR_VERTICAL_COMPONENT, UY, OLD_UY, OLD_UX, OLD_UY); project (UX, UY, OLD_UX, OLD_UY); }
void SWSolver::advanceTimestep(){ //std::cout << "advecting eta..." << std::endl; advect(ETA); //std::cout << "advecting velocity_x..." << std::endl; advect(VELOCITY_X); //std::cout << "advecting velocity_y..." << std::endl; advect(VELOCITY_Y); //std::cout << "updating heights..." << std::endl; updateHeight(); //std::cout << "updating velocities..." << std::endl; updateVelocity(); //std::cout << "setting boundaries..." << std::endl; setBoundary(); }
//----------------------------------------------------------------------------- void StamFluidSolver::texture_step ( float * x, float * x0, float * u, float * v, float diff, float dt ) { //addSource ( N, x, x0, dt ); SWAP ( x0, x ); diffuse ( 0, x, x0, diff, dt ); SWAP ( x0, x ); advect ( 0, x, x0, u, v, dt ); }
void FluidSimulator::simulateAndDraw(){ advect(0.01); project(); draw(); }
void FluidField::densityStep (float * x, float * x0, float * u, float * v, float diff, float dt ) { add_source ( x, x0, dt ); SWAP ( x0, x ); diffuse ( 0, x, x0, diff, dt ); SWAP ( x0, x ); advect ( 0, x, x0, u, v, dt ); }
//----------------------------------------------------------------------------- void StamFluidSolver::dens_step ( float * x, float * x0, float * u, float * v, float diff, float dt ) { addSource ( x, x0, dt ); SWAP ( x0, x ); diffuse ( 0, x, x0, diff, dt ); SWAP ( x0, x ); advect ( 0, x, x0, u, v, dt ); }
void advect(float dt, Field2f &u, Field2f &x0, Field2f &x1) { for (int y = 1; y < GRID_RES - 1; ++y) { for (int x = 1; x < GRID_RES - 1; ++x) { advect(x, y, dt, u, x0, x1); } } }
void Smoke::densityStep() { addSource( d, dOld ); swap( dOld, d ); diffuse( 0, d, dOld, diff ); swap( dOld, d ); advect( 0, d, dOld, u, v ); }
void Fluid::dens_step(float dt) { add_source(sd, d, dt); #ifdef DIFFUSE SWAPFPTR(d0, d); diffuse(0, d0, d, diffusion, dt); #endif #ifdef ADVECT SWAPFPTR(d0, d); advect(0, d0, d, u, v, w, dt); #endif }
void FluidSystem::stepDensity(Scalar dt, const DyeField &addedDensity) { density += addedDensity * dt; std::array<BoundarySetter, density.coords> boundarySetters; for (std::size_t i = 0; i < density.coords; ++i) { boundarySetters[i] = std::bind(&setContinuityBoundaries, std::placeholders::_1, dim); } std::swap(density, densityPrev); diffuse(density, densityPrev, diffusionConstant, dt, dim, boundarySetters); std::swap(density, densityPrev); advect(density, densityPrev, velocity, dt, dim, boundarySetters); }
void Smoke::velocityStep() { addSource( u, uOld ); addSource( v, vOld ); buoyancy(vOld); addSource( v, vOld ); swap( uOld, u ); diffuse( 1, u, uOld, visc ); swap( vOld, v ); diffuse( 2, v, vOld, visc ); project( uOld, vOld ); swap( uOld, u ); swap( vOld, v ); advect( 1, u, uOld, uOld, vOld ); advect( 2, v, vOld, uOld, vOld ); project( uOld, vOld ); }
static void redraw_handler(struct widget *widget, void *data) { struct smoke *smoke = data; uint32_t time = smoke->time; struct wl_callback *callback; cairo_surface_t *surface; diffuse(smoke, time / 30, smoke->b[0].u, smoke->b[1].u); diffuse(smoke, time / 30, smoke->b[0].v, smoke->b[1].v); project(smoke, time / 30, smoke->b[1].u, smoke->b[1].v, smoke->b[0].u, smoke->b[0].v); advect(smoke, time / 30, smoke->b[1].u, smoke->b[1].v, smoke->b[1].u, smoke->b[0].u); advect(smoke, time / 30, smoke->b[1].u, smoke->b[1].v, smoke->b[1].v, smoke->b[0].v); project(smoke, time / 30, smoke->b[0].u, smoke->b[0].v, smoke->b[1].u, smoke->b[1].v); diffuse(smoke, time / 30, smoke->b[0].d, smoke->b[1].d); advect(smoke, time / 30, smoke->b[0].u, smoke->b[0].v, smoke->b[1].d, smoke->b[0].d); surface = window_get_surface(smoke->window); render(smoke, surface); window_damage(smoke->window, 0, 0, smoke->width, smoke->height); cairo_surface_destroy(surface); callback = wl_surface_frame(window_get_wl_surface(smoke->window)); wl_callback_add_listener(callback, &listener, smoke); wl_surface_commit(window_get_wl_surface(smoke->window)); }
void ciMsaFluidSolver::update() { addSourceUV(); if( doVorticityConfinement ) { vorticityConfinement(uvOld); addSourceUV(); } swapUV(); diffuseUV( viscocity ); project(uv, uvOld); swapUV(); advect2d(uv, uvOld); project(uv, uvOld); if(doRGB) { addSourceRGB(); swapRGB(); if( colorDiffusion!=0. && _dt!=0. ) { diffuseRGB(0, colorDiffusion ); swapRGB(); } advectRGB(0, uv); fadeRGB(); } else { addSource(r, rOld); swapR(); if( colorDiffusion!=0. && _dt!=0. ) { diffuse(0, r, rOld, colorDiffusion ); swapRGB(); } advect(0, r, rOld, uv); fadeR(); } }
void Fluid::vel_step(float dt) { add_source(su, u, dt); add_source(sv, v, dt); add_source(sw, w, dt); add_buoyancy(dt); vorticity_confinement(dt); #ifdef DIFFUSE SWAPFPTR(u0, u); SWAPFPTR(v0, v); SWAPFPTR(w0, w); diffuse(1, u0, u, viscosity, dt); diffuse(2, v0, v, viscosity, dt); diffuse(3, w0, w, viscosity, dt); project(); #endif #ifdef ADVECT SWAPFPTR(u0, u); SWAPFPTR(v0, v); SWAPFPTR(w0, w); advect(1, u0, u, u0, v0, w0, dt); advect(2, v0, v, u0, v0, w0, dt); advect(3, w0, w, u0, v0, w0, dt); project(); #endif }
/*************************************************************** * Solves the navier stokes equations for density.. * i.e. satisfies: ∂d/∂t = -(div u)d + k Lap d + S ***************************************************************/ void FGS_Fluid_Solver2DS :: density_step(){ // Add density sources from the old grid (+S) add_source(DENSITY, OLD_DENSITY); // Compute diffusion of cells' densities into neighbours // If diffusion > 0 then densities will diffuse (+ k Lap d) diffuse (SET_FOR_NON_VELOCITY_COMPONENT, OLD_DENSITY, DENSITY, diffusion); // Advect the densities based on the velocities in the cell (-(div u)d) computing_density = true; advect (SET_FOR_NON_VELOCITY_COMPONENT, DENSITY, OLD_DENSITY, UX, UY); computing_density = false; }
static void redraw_handler(struct widget *widget, void *data) { struct smoke *smoke = data; uint32_t time = widget_get_last_time(smoke->widget); cairo_surface_t *surface; diffuse(smoke, time / 30, smoke->b[0].u, smoke->b[1].u); diffuse(smoke, time / 30, smoke->b[0].v, smoke->b[1].v); project(smoke, time / 30, smoke->b[1].u, smoke->b[1].v, smoke->b[0].u, smoke->b[0].v); advect(smoke, time / 30, smoke->b[1].u, smoke->b[1].v, smoke->b[1].u, smoke->b[0].u); advect(smoke, time / 30, smoke->b[1].u, smoke->b[1].v, smoke->b[1].v, smoke->b[0].v); project(smoke, time / 30, smoke->b[0].u, smoke->b[0].v, smoke->b[1].u, smoke->b[1].v); diffuse(smoke, time / 30, smoke->b[0].d, smoke->b[1].d); advect(smoke, time / 30, smoke->b[0].u, smoke->b[0].v, smoke->b[1].d, smoke->b[0].d); surface = window_get_surface(smoke->window); render(smoke, surface); window_damage(smoke->window, 0, 0, smoke->width, smoke->height); cairo_surface_destroy(surface); widget_schedule_redraw(smoke->widget); }