Esempio n. 1
0
//////////////////////////////////////////////////////////////////////
// Advect using the MacCormack method from the Selle paper
//////////////////////////////////////////////////////////////////////
void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd)
{
	const float dt0 = _dt / _dx;
	Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);

	// use force array as temp arrays
	float* t1 = _xForce;

	// advectFieldMacCormack2(dt, xVelocity, yVelocity, zVelocity, oldField, newField, tempfield, temp, res, obstacles)

	advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, _densityTemp, t1, res, _obstacles, zBegin, zEnd);
	advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, _heatTemp, t1, res, _obstacles, zBegin, zEnd);
	advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocityTemp, _xVelocity, t1, res, _obstacles, zBegin, zEnd);
	advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocityTemp, _yVelocity, t1, res, _obstacles, zBegin, zEnd);
	advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocityTemp, _zVelocity, t1, res, _obstacles, zBegin, zEnd);

	if(_domainBcLeft == 0) copyBorderX(_xVelocityTemp, res, zBegin, zEnd);
	else setZeroX(_xVelocityTemp, res, zBegin, zEnd);				

	if(_domainBcFront == 0) copyBorderY(_yVelocityTemp, res, zBegin, zEnd);
	else setZeroY(_yVelocityTemp, res, zBegin, zEnd); 

	if(_domainBcTop == 0) copyBorderZ(_zVelocityTemp, res, zBegin, zEnd);
	else setZeroZ(_zVelocityTemp, res, zBegin, zEnd);

	setZeroBorder(_density, res, zBegin, zEnd);
	setZeroBorder(_heat, res, zBegin, zEnd);


	/*int begin=zBegin * _slabSize;
	int end=begin + (zEnd - zBegin) * _slabSize;
  for (int x = begin; x < end; x++)
    _xForce[x] = _yForce[x] = 0.0f;*/
}
Esempio n. 2
0
void FLUID_3D::advectMacCormackBegin(int zBegin, int zEnd)
{
	Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);

	if(_domainBcLeft == 0) copyBorderX(_xVelocityOld, res, zBegin, zEnd);
	else setZeroX(_xVelocityOld, res, zBegin, zEnd);

	if(_domainBcFront == 0) copyBorderY(_yVelocityOld, res, zBegin, zEnd);
	else setZeroY(_yVelocityOld, res, zBegin, zEnd); 

	if(_domainBcTop == 0) copyBorderZ(_zVelocityOld, res, zBegin, zEnd);
	else setZeroZ(_zVelocityOld, res, zBegin, zEnd);
}
Esempio n. 3
0
//////////////////////////////////////////////////////////////////////
// Advect using the MacCormack method from the Selle paper
//////////////////////////////////////////////////////////////////////
void FLUID_3D::advectMacCormack()
{
	Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);

	if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
	else setZeroX(_xVelocity, res); 

	if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
	else setZeroY(_yVelocity, res); 

	if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
	else setZeroZ(_zVelocity, res);

	SWAP_POINTERS(_xVelocity, _xVelocityOld);
	SWAP_POINTERS(_yVelocity, _yVelocityOld);
	SWAP_POINTERS(_zVelocity, _zVelocityOld);
	SWAP_POINTERS(_density, _densityOld);
	SWAP_POINTERS(_heat, _heatOld);

	const float dt0 = _dt / _dx;
	// use force arrays as temp arrays
	for (int x = 0; x < _totalCells; x++)
		_xForce[x] = _yForce[x] = 0.0;

	float* t1 = _xForce;
	float* t2 = _yForce;

	advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, t1,t2, res, _obstacles);
	advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, t1,t2, res, _obstacles);
	advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, t1,t2, res, _obstacles);
	advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, t1,t2, res, _obstacles);
	advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, t1,t2, res, _obstacles);

	if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
	else setZeroX(_xVelocity, res); 

	if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
	else setZeroY(_yVelocity, res); 

	if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
	else setZeroZ(_zVelocity, res);

	setZeroBorder(_density, res);
	setZeroBorder(_heat, res);

  for (int x = 0; x < _totalCells; x++)
    t1[x] = t2[x] = 0.0;
}
Esempio n. 4
0
//////////////////////////////////////////////////////////////////////
// Advect using the MacCormack method from the Selle paper
//////////////////////////////////////////////////////////////////////
void FLUID_3D::advectMacCormackEnd1(int zBegin, int zEnd)
{
	Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);

	const float dt0 = _dt / _dx;

	int begin=zBegin * _slabSize;
	int end=begin + (zEnd - zBegin) * _slabSize;
	for (int x = begin; x < end; x++)
		_xForce[x] = 0.0;

	// advectFieldMacCormack1(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res)

	advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _densityTemp, res, zBegin, zEnd);
	advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heatTemp, res, zBegin, zEnd);
	advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, res, zBegin, zEnd);
	advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, res, zBegin, zEnd);
	advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, res, zBegin, zEnd);

	// Have to wait untill all the threads are done -> so continuing in step 3
}
Esempio n. 5
0
//////////////////////////////////////////////////////////////////////
// constructor
//////////////////////////////////////////////////////////////////////
WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, int init_fire, int init_colors)
{
	// if noise magnitude is below this threshold, its contribution
	// is negilgible, so stop evaluating new octaves
	_cullingThreshold = 1e-3;
	
	// factor by which to increase the simulation resolution
	_amplify = amplify;
	
	// manually adjust the overall amount of turbulence
	// DG - RNA-fied _strength = 2.;
	
	// add the corresponding octaves of noise
	_octaves = (int)(log((float)_amplify) / log(2.0f) + 0.5); // XXX DEBUG/ TODO: int casting correct? - dg
	
	// noise resolution
	_xResBig = _amplify * xResSm;
	_yResBig = _amplify * yResSm;
	_zResBig = _amplify * zResSm;
	_resBig = Vec3Int(_xResBig, _yResBig, _zResBig);
	_invResBig = Vec3(1./(float)_resBig[0], 1./(float)_resBig[1], 1./(float)_resBig[2]);
	_slabSizeBig = _xResBig*_yResBig;
	_totalCellsBig = _slabSizeBig * _zResBig;
	
	// original / small resolution
	_xResSm = xResSm;
	_yResSm = yResSm;
	_zResSm = zResSm;
	_resSm = Vec3Int(xResSm, yResSm, zResSm);
	_invResSm = Vec3(1./(float)_resSm[0], 1./(float)_resSm[1], 1./(float)_resSm[2] );
	_slabSizeSm = _xResSm*_yResSm;
	_totalCellsSm = _slabSizeSm * _zResSm;
	
	// allocate high resolution density field
	_totalStepsBig = 0;
	_densityBig = new float[_totalCellsBig];
	_densityBigOld = new float[_totalCellsBig];
	
	for(int i = 0; i < _totalCellsBig; i++) {
		_densityBig[i] = 
		_densityBigOld[i] = 0.;
	}

	/* fire */
	_flameBig = _fuelBig = _fuelBigOld = NULL;
	_reactBig = _reactBigOld = NULL;
	if (init_fire) {
		initFire();
	}
	/* colors */
	_color_rBig = _color_rBigOld = NULL;
	_color_gBig = _color_gBigOld = NULL;
	_color_bBig = _color_bBigOld = NULL;
	if (init_colors) {
		initColors(0.0f, 0.0f, 0.0f);
	}
	
	// allocate & init texture coordinates
	_tcU = new float[_totalCellsSm];
	_tcV = new float[_totalCellsSm];
	_tcW = new float[_totalCellsSm];
	_tcTemp = new float[_totalCellsSm];
	
	// map all 
	const float dx = 1./(float)(_resSm[0]);
	const float dy = 1./(float)(_resSm[1]);
	const float dz = 1./(float)(_resSm[2]);
	int index = 0;
	for (int z = 0; z < _zResSm; z++) 
	for (int y = 0; y < _yResSm; y++) 
		for (int x = 0; x < _xResSm; x++, index++)
		{
		_tcU[index] = x*dx;
		_tcV[index] = y*dy;
		_tcW[index] = z*dz;
		_tcTemp[index] = 0.;
		}
	
	// noise tiles
	_noiseTile = new float[noiseTileSize * noiseTileSize * noiseTileSize];
	/*
	std::string noiseTileFilename = std::string("noise.wavelets");
	generateTile_WAVELET(_noiseTile, noiseTileFilename);
	*/
	setNoise(noisetype);
	/*
	std::string noiseTileFilename = std::string("noise.fft");
	generatTile_FFT(_noiseTile, noiseTileFilename);
	*/
}
Esempio n. 6
0
FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
	_xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f), _dt(dt)
{
	// set simulation consts
	// _dt = dt; // 0.10
	
	// start point of array
	_p0[0] = p0[0];
	_p0[1] = p0[1];
	_p0[2] = p0[2];

	_iterations = 100;
	_tempAmb = 0; 
	_heatDiffusion = 1e-3;
	_vorticityEps = 2.0;
	_totalTime = 0.0f;
	_totalSteps = 0;
	_res = Vec3Int(_xRes,_yRes,_zRes);
	_maxRes = MAX3(_xRes, _yRes, _zRes);
	
	// initialize wavelet turbulence
	/*
	if(amplify)
		_wTurbulence = new WTURBULENCE(_res[0],_res[1],_res[2], amplify, noisetype);
	else
		_wTurbulence = NULL;
	*/
	
	// scale the constants according to the refinement of the grid
	_dx = 1.0f / (float)_maxRes;
	float scaling = 64.0f / _maxRes;
	scaling = (scaling < 1.0f) ? 1.0f : scaling;
	_vorticityEps /= scaling;

	// allocate arrays
	_totalCells   = _xRes * _yRes * _zRes;
	_slabSize = _xRes * _yRes;
	_xVelocity    = new float[_totalCells];
	_yVelocity    = new float[_totalCells];
	_zVelocity    = new float[_totalCells];
	_xVelocityOld = new float[_totalCells];
	_yVelocityOld = new float[_totalCells];
	_zVelocityOld = new float[_totalCells];
	_xForce       = new float[_totalCells];
	_yForce       = new float[_totalCells];
	_zForce       = new float[_totalCells];
	_density      = new float[_totalCells];
	_densityOld   = new float[_totalCells];
	_heat         = new float[_totalCells];
	_heatOld      = new float[_totalCells];
	_obstacles    = new unsigned char[_totalCells]; // set 0 at end of step

	// DG TODO: check if alloc went fine

	for (int x = 0; x < _totalCells; x++)
	{
		_density[x]      = 0.0f;
		_densityOld[x]   = 0.0f;
		_heat[x]         = 0.0f;
		_heatOld[x]      = 0.0f;
		_xVelocity[x]    = 0.0f;
		_yVelocity[x]    = 0.0f;
		_zVelocity[x]    = 0.0f;
		_xVelocityOld[x] = 0.0f;
		_yVelocityOld[x] = 0.0f;
		_zVelocityOld[x] = 0.0f;
		_xForce[x]       = 0.0f;
		_yForce[x]       = 0.0f;
		_zForce[x]       = 0.0f;
		_obstacles[x]    = false;
	}

	// set side obstacles
	int index;
	for (int y = 0; y < _yRes; y++)
	for (int x = 0; x < _xRes; x++)
	{
		// front slab
		index = x + y * _xRes;
		if(DOMAIN_BC_FRONT==1) _obstacles[index] = 1;

		// back slab
		index += _totalCells - _slabSize;
		if(DOMAIN_BC_BACK==1) _obstacles[index] = 1;
	}

	for (int z = 0; z < _zRes; z++)
	for (int x = 0; x < _xRes; x++)
	{
		// bottom slab
		index = x + z * _slabSize;
		if(DOMAIN_BC_BOTTOM==1) _obstacles[index] = 1;

		// top slab
		index += _slabSize - _xRes;
		if(DOMAIN_BC_TOP==1) _obstacles[index] = 1;
	}

	for (int z = 0; z < _zRes; z++)
	for (int y = 0; y < _yRes; y++)
	{
		// left slab
		index = y * _xRes + z * _slabSize;
		if(DOMAIN_BC_LEFT==1) _obstacles[index] = 1;

		// right slab
		index += _xRes - 1;
		if(DOMAIN_BC_RIGHT==1) _obstacles[index] = 1;
	}
}
Esempio n. 7
0
FLUID_3D::FLUID_3D(int *res, float *p0) :
	_xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f)
{
	// set simulation consts
	_dt = DT_DEFAULT;	// just in case. set in step from a RNA factor
	
	// start point of array
	_p0[0] = p0[0];
	_p0[1] = p0[1];
	_p0[2] = p0[2];

	_iterations = 100;
	_tempAmb = 0; 
	_heatDiffusion = 1e-3;
	_totalTime = 0.0f;
	_totalSteps = 0;
	_res = Vec3Int(_xRes,_yRes,_zRes);
	_maxRes = MAX3(_xRes, _yRes, _zRes);
	
	// initialize wavelet turbulence
	/*
	if(amplify)
		_wTurbulence = new WTURBULENCE(_res[0],_res[1],_res[2], amplify, noisetype);
	else
		_wTurbulence = NULL;
	*/
	
	// scale the constants according to the refinement of the grid
	_dx = 1.0f / (float)_maxRes;
	_constantScaling = 64.0f / _maxRes;
	_constantScaling = (_constantScaling < 1.0f) ? 1.0f : _constantScaling;
	_vorticityEps = 2.0f / _constantScaling; // Just in case set a default value

	// allocate arrays
	_totalCells   = _xRes * _yRes * _zRes;
	_slabSize = _xRes * _yRes;
	_xVelocity    = new float[_totalCells];
	_yVelocity    = new float[_totalCells];
	_zVelocity    = new float[_totalCells];
	_xVelocityOld = new float[_totalCells];
	_yVelocityOld = new float[_totalCells];
	_zVelocityOld = new float[_totalCells];
	_xForce       = new float[_totalCells];
	_yForce       = new float[_totalCells];
	_zForce       = new float[_totalCells];
	_density      = new float[_totalCells];
	_densityOld   = new float[_totalCells];
	_heat         = new float[_totalCells];
	_heatOld      = new float[_totalCells];
	_obstacles    = new unsigned char[_totalCells]; // set 0 at end of step

	// For threaded version:
	_xVelocityTemp = new float[_totalCells];
	_yVelocityTemp = new float[_totalCells];
	_zVelocityTemp = new float[_totalCells];
	_densityTemp   = new float[_totalCells];
	_heatTemp      = new float[_totalCells];

	// DG TODO: check if alloc went fine

	for (int x = 0; x < _totalCells; x++)
	{
		_density[x]      = 0.0f;
		_densityOld[x]   = 0.0f;
		_heat[x]         = 0.0f;
		_heatOld[x]      = 0.0f;
		_xVelocity[x]    = 0.0f;
		_yVelocity[x]    = 0.0f;
		_zVelocity[x]    = 0.0f;
		_xVelocityOld[x] = 0.0f;
		_yVelocityOld[x] = 0.0f;
		_zVelocityOld[x] = 0.0f;
		_xForce[x]       = 0.0f;
		_yForce[x]       = 0.0f;
		_zForce[x]       = 0.0f;
		_obstacles[x]    = false;
	}

	// boundary conditions of the fluid domain
	// set default values -> vertically non-colliding
	_domainBcFront = true;
	_domainBcTop = false;
	_domainBcLeft = true;
	_domainBcBack = _domainBcFront;
	_domainBcBottom = _domainBcTop;
	_domainBcRight	= _domainBcLeft;

	_colloPrev = 1;	// default value


	// set side obstacles
	int index;
	for (int y = 0; y < _yRes; y++)
	for (int x = 0; x < _xRes; x++)
	{
		// bottom slab
		index = x + y * _xRes;
		if(_domainBcBottom==1) _obstacles[index] = 1;

		// top slab
		index += _totalCells - _slabSize;
		if(_domainBcTop==1) _obstacles[index] = 1;
	}

	for (int z = 0; z < _zRes; z++)
	for (int x = 0; x < _xRes; x++)
	{
		// front slab
		index = x + z * _slabSize;
		if(_domainBcFront==1) _obstacles[index] = 1;

		// back slab
		index += _slabSize - _xRes;
		if(_domainBcBack==1) _obstacles[index] = 1;
	}

	for (int z = 0; z < _zRes; z++)
	for (int y = 0; y < _yRes; y++)
	{
		// left slab
		index = y * _xRes + z * _slabSize;
		if(_domainBcLeft==1) _obstacles[index] = 1;

		// right slab
		index += _xRes - 1;
		if(_domainBcRight==1) _obstacles[index] = 1;
	}

}