//! add Buoyancy force based on smoke density KERNEL(bnd=1) void create_modifier_plane_horizontal(FlagGrid& flags, MACGrid& vel_modifier, Vec3 value) { if (!flags.isFluid(i,j,k)) return; if (flags.isFluid(i,j,k)) { vel_modifier(i,j,k).x = value.x; vel_modifier(i,j,k).y = value.y; vel_modifier(i,j,k).z = value.z; } }
//! add Buoyancy force based on smoke density KERNEL(bnd=1) void KnAddBuoyancy(FlagGrid& flags, Grid<Real>& density, MACGrid& vel, Vec3 strength) { if (!flags.isFluid(i,j,k)) return; if (flags.isFluid(i-1,j,k)) vel(i,j,k).x += (0.5 * strength.x) * (density(i,j,k)+density(i-1,j,k)); if (flags.isFluid(i,j-1,k)) vel(i,j,k).y += (0.5 * strength.y) * (density(i,j,k)+density(i,j-1,k)); if (vel.is3D() && flags.isFluid(i,j,k-1)) vel(i,j,k).z += (0.5 * strength.z) * (density(i,j,k)+density(i,j,k-1)); }
//! add Buoyancy force based on smoke density KERNEL(bnd=1) void modify_velocity(FlagGrid& flags, MACGrid& vel, Vec3 value) { if (!flags.isFluid(i,j,k)) return; if (flags.isFluid(i,j,k)) { vel(i,j,k).x = value.x; vel(i,j,k).y = value.y; vel(i,j,k).z = value.z; } }
//! add Forces between fl/fl and fl/em cells KERNEL(bnd=1) void KnAddForce(FlagGrid& flags, MACGrid& vel, Vec3 force) { bool curFluid = flags.isFluid(i,j,k); bool curEmpty = flags.isEmpty(i,j,k); if (!curFluid && !curEmpty) return; if (flags.isFluid(i-1,j,k) || (curFluid && flags.isEmpty(i-1,j,k))) vel(i,j,k).x += force.x; if (flags.isFluid(i,j-1,k) || (curFluid && flags.isEmpty(i,j-1,k))) vel(i,j,k).y += force.y; if (vel.is3D() && (flags.isFluid(i,j,k-1) || (curFluid && flags.isEmpty(i,j,k-1)))) vel(i,j,k).z += force.z; }
void MakeRhs (FlagGrid& flags, Grid<Real>& rhs, MACGrid& vel, Grid<Real>* perCellCorr) { if (!flags.isFluid(i,j,k)) { rhs(i,j,k) = 0; return; } // compute divergence // assumes vel at obstacle interfaces is set to zero /* Real set = 0; if (!flags.isObstacle(i-1,j,k)) set += vel(i,j,k).x; if (!flags.isObstacle(i+1,j,k)) set -= vel(i+1,j,k).x; if (!flags.isObstacle(i,j-1,k)) set += vel(i,j,k).y; if (!flags.isObstacle(i,j+1,k)) set -= vel(i,j+1,k).y; if (!flags.isObstacle(i,j,k-1)) set += vel(i,j,k).z; if (!flags.isObstacle(i,j,k+1)) set -= vel(i,j,k+1).z; */ Real set = vel(i,j,k).x - vel(i+1,j,k).x + vel(i,j,k).y - vel(i,j+1,k).y + vel(i,j,k).z - vel(i,j,k+1).z; // per cell divergence correction if(perCellCorr) set += perCellCorr->get(i,j,k); // obtain sum, cell count sum += set; cnt++; rhs(i,j,k) = set; }
void MacCormackCorrect(FlagGrid& flags, Grid<T>& dst, Grid<T>& old, Grid<T>& fwd, Grid<T>& bwd, Real strength, bool isLevelSet, bool isMAC=false ) { // note, replacement for isNotFluidMAC and isNotFluid bool skip = false; if (!flags.isFluid(idx)) skip = true; if(!isMAC) { if( (idx>=flags.getStrideX()) && (!flags.isFluid(idx-flags.getStrideX()) )) skip = true; if( (idx>=flags.getStrideY()) && (!flags.isFluid(idx-flags.getStrideY()) )) skip = true; if ( flags.is3D() ) { if( (idx>=flags.getStrideZ()) &&(!flags.isFluid(idx-flags.getStrideZ()) )) skip = true; } } if ( skip ) { dst[idx] = isLevelSet ? fwd[idx] : (T)0.0; return; } // note, strenth of correction can be modified here dst[idx] = fwd[idx] + strength * 0.5 * (old[idx] - bwd[idx]); }
//! set no-stick wall boundary condition between ob/fl and ob/ob cells KERNEL void KnSetWallBcs(FlagGrid& flags, MACGrid& vel, Vector3D<bool> lo, Vector3D<bool> up, bool admm) { bool curFluid = flags.isFluid(i,j,k); bool curObstacle = flags.isObstacle(i,j,k); if (!curFluid && !curObstacle) return; // MLE 2014-07-04 // if not admm, leave it as in orig // if openBound, don't correct anything (solid is as empty) // if admm, correct if vel is pointing outwards // if "inner" obstacle vel if(i>0 && curObstacle && !flags.isFluid(i-1,j,k)) vel(i,j,k).x = 0; if(j>0 && curObstacle && !flags.isFluid(i,j-1,k)) vel(i,j,k).y = 0; // check lo.x if(!lo.x && i>0 && curFluid && flags.isObstacle(i-1,j,k) && ((admm&&vel(i,j,k).x<0)||!admm)) vel(i,j,k).x = 0; // check up.x if(!up.x && i>0 && curObstacle && flags.isFluid(i-1,j,k) && ((admm&&vel(i,j,k).x>0)||!admm)) vel(i,j,k).x = 0; // check lo.y if(!lo.y && j>0 && curFluid && flags.isObstacle(i,j-1,k) && ((admm&&vel(i,j,k).y<0)||!admm)) vel(i,j,k).y = 0; // check up.y if(!up.y && j>0 && curObstacle && flags.isFluid(i,j-1,k) && ((admm&&vel(i,j,k).y>0)||!admm)) vel(i,j,k).y = 0; // check lo.z if(!lo.z && k>0 && curFluid && flags.isObstacle(i,j,k-1) && ((admm&&vel(i,j,k).z<0)||!admm)) vel(i,j,k).z = 0; // check up.z if(!up.z && k>0 && curObstacle && flags.isFluid(i,j,k-1) && ((admm&&vel(i,j,k).z>0)||!admm)) vel(i,j,k).z = 0; /* MLE consider later if (curFluid) { if ((i>0 && flags.isStick(i-1,j,k)) || (i<flags.getSizeX()-1 && flags.isStick(i+1,j,k))) vel(i,j,k).y = vel(i,j,k).z = 0; if ((j>0 && flags.isStick(i,j-1,k)) || (j<flags.getSizeY()-1 && flags.isStick(i,j+1,k))) vel(i,j,k).x = vel(i,j,k).z = 0; if (vel.is3D() && ((k>0 && flags.isStick(i,j,k-1)) || (k<flags.getSizeZ()-1 && flags.isStick(i,j,k+1)))) vel(i,j,k).x = vel(i,j,k).y = 0; } */ }
void ApplyGhostFluid (FlagGrid& flags, Grid<Real>& phi, Grid<Real>& A0, Real accuracy) { if (!flags.isFluid(i,j,k)) return; const Real curPhi = phi(i,j,k); if (flags.isEmpty(i-1,j,k)) A0(i,j,k) += getGhostMatrixAddition( phi(i-1,j,k), curPhi, accuracy); if (flags.isEmpty(i+1,j,k)) A0(i,j,k) += getGhostMatrixAddition( curPhi, phi(i+1,j,k), accuracy); if (flags.isEmpty(i,j-1,k)) A0(i,j,k) += getGhostMatrixAddition( phi(i,j-1,k), curPhi, accuracy); if (flags.isEmpty(i,j+1,k)) A0(i,j,k) += getGhostMatrixAddition( curPhi, phi(i,j+1,k), accuracy); if (flags.is3D() && flags.isEmpty(i,j,k-1)) A0(i,j,k) += getGhostMatrixAddition( phi(i,j,k-1), curPhi, accuracy); if (flags.is3D() && flags.isEmpty(i,j,k+1)) A0(i,j,k) += getGhostMatrixAddition( curPhi, phi(i,j,k+1), accuracy); }
void CorrectVelGhostFluid (FlagGrid& flags, MACGrid& vel, Grid<Real>& pressure) //, Grid<Real>& phi) { bool curFluid = flags.isFluid(i,j,k); if (!curFluid && !flags.isEmpty(i,j,k)) return; const Real curPress = pressure(i,j,k); //const Real curPhi = phi(i,j,k); // TODO - include ghost fluid factor NT_DEBUG // in contrast to old implementation: // make sure to add gradient for all fluid-empty or fluid-fluid combinations // of neighbors... if (!flags.isObstacle(i-1,j,k) && (curFluid || flags.isFluid(i-1,j,k))) vel(i,j,k).x -= curPress - pressure(i-1,j,k); if (!flags.isObstacle(i,j-1,k) && (curFluid || flags.isFluid(i,j-1,k))) vel(i,j,k).y -= curPress - pressure(i,j-1,k); if (flags.is3D() && (!flags.isObstacle(i,j,k-1) && (curFluid || flags.isFluid(i,j,k-1)))) vel(i,j,k).z -= curPress - pressure(i,j,k-1); }
static inline bool isNotFluidMAC(FlagGrid& flags, int i, int j, int k) { if ( flags.isFluid(i,j,k) ) return false; return true; }