void MacCormackClamp(FlagGrid& flags, MACGrid& vel, Grid<T>& dst, Grid<T>& orig, Grid<T>& fwd, Real dt) { if (flags.isObstacle(i,j,k)) return; if ( isNotFluid(flags,i,j,k) ) { dst(i,j,k) = fwd(i,j,k); return; } T dval = dst(i,j,k); Vec3i upperClamp = flags.getSize() - 1; // lookup forward/backward Vec3i posFwd = toVec3i( Vec3(i,j,k) - vel.getCentered(i,j,k) * dt ); Vec3i posBwd = toVec3i( Vec3(i,j,k) + vel.getCentered(i,j,k) * dt ); dval = doClampComponent<T>(upperClamp, orig, dval, posFwd ); // test if lookups point out of grid or into obstacle if (posFwd.x < 0 || posFwd.y < 0 || posFwd.z < 0 || posBwd.x < 0 || posBwd.y < 0 || posBwd.z < 0 || posFwd.x > upperClamp.x || posFwd.y > upperClamp.y || ((posFwd.z > upperClamp.z)&&flags.is3D()) || posBwd.x > upperClamp.x || posBwd.y > upperClamp.y || ((posBwd.z > upperClamp.z)&&flags.is3D()) || flags.isObstacle(posFwd) || flags.isObstacle(posBwd) ) { dval = fwd(i,j,k); } dst(i,j,k) = dval; }
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 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]); }
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); }
void MacCormackClampMAC (FlagGrid& flags, MACGrid& vel, MACGrid& dst, MACGrid& orig, MACGrid& fwd, Real dt) { if (flags.isObstacle(i,j,k)) return; if ( isNotFluidMAC(flags,i,j,k) ) { dst(i,j,k) = fwd(i,j,k); return; } Vec3 pos(i,j,k); Vec3 dval = dst(i,j,k); Vec3i upperClamp = flags.getSize() - 1; // get total fwd lookup Vec3i posFwd = toVec3i( Vec3(i,j,k) - vel.getCentered(i,j,k) * dt ); Vec3i posBwd = toVec3i( Vec3(i,j,k) + vel.getCentered(i,j,k) * dt ); // clamp individual components dval.x = doClampComponentMAC<0>(upperClamp, orig, dval.x, toVec3i( pos - vel.getAtMACX(i,j,k) * dt) ); dval.y = doClampComponentMAC<1>(upperClamp, orig, dval.y, toVec3i( pos - vel.getAtMACY(i,j,k) * dt) ); dval.z = doClampComponentMAC<2>(upperClamp, orig, dval.z, toVec3i( pos - vel.getAtMACZ(i,j,k) * dt) ); // test if lookups point out of grid or into obstacle if (posFwd.x < 0 || posFwd.y < 0 || posFwd.z < 0 || posBwd.x < 0 || posBwd.y < 0 || posBwd.z < 0 || posFwd.x > upperClamp.x || posFwd.y > upperClamp.y || ((posFwd.z > upperClamp.z)&&flags.is3D()) || posBwd.x > upperClamp.x || posBwd.y > upperClamp.y || ((posBwd.z > upperClamp.z)&&flags.is3D()) //|| flags.isObstacle(posFwd) || flags.isObstacle(posBwd) // note - this unfortunately introduces asymmetry... TODO update ) { dval = fwd(i,j,k); } // writeback dst(i,j,k) = dval; }