//! 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;
}
예제 #5
0
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;
	}
	*/
}
예제 #8
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);
}
예제 #9
0
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;
}