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;
}
예제 #2
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 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]);
}
예제 #4
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);
}
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;
}