void SemiLagrangeMAC(FlagGrid& flags, MACGrid& vel, MACGrid& dst, MACGrid& src, Real dt) 
{
	if (flags.isObstacle(i,j,k)) {
		dst(i,j,k) = 0;
		return;
	}
//	std::cout << " Don't worry, I MADE IT till here " << std::endl ;
	if ( isNotFluidMAC(flags,i,j,k) ) {
		dst(i,j,k) = src(i,j,k);
		return;
	}
	
//	std::cout << " Don't worry, I REACHED till here " << std::endl ;

	// get currect velocity at MAC position
	// no need to shift xpos etc. as lookup field is also shifted
	Vec3 xpos = Vec3(i+0.5f,j+0.5f,k+0.5f) - vel.getAtMACX(i,j,k) * dt;
	Real vx = src.getInterpolatedComponent<0>(xpos);
	Vec3 ypos = Vec3(i+0.5f,j+0.5f,k+0.5f) - vel.getAtMACY(i,j,k) * dt;
	Real vy = src.getInterpolatedComponent<1>(ypos);
	Vec3 zpos = Vec3(i+0.5f,j+0.5f,k+0.5f) - vel.getAtMACZ(i,j,k) * dt;
	Real vz = src.getInterpolatedComponent<2>(zpos);
	
//	std::cout << " Don't worry, I CAN till here " << std::endl ;

	dst(i,j,k) = Vec3(vx,vy,vz);

//	std::cout << " Don't worry, I COULD till here " << std::endl ;

}
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;
}