Esempio n. 1
0
//////////////////////////////////////////////////////////////////////
// handle texture coordinates (advection, reset, eigenvalues), 
// Beware -- uses big density maccormack as temporary arrays
////////////////////////////////////////////////////////////////////// 
void WTURBULENCE::advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel, float *tempBig1, float *tempBig2) {

  // advection
  SWAP_POINTERS(_tcTemp, _tcU);
  FLUID_3D::copyBorderX(_tcTemp, _resSm, 0 , _resSm[2]);
  FLUID_3D::copyBorderY(_tcTemp, _resSm, 0 , _resSm[2]);
  FLUID_3D::copyBorderZ(_tcTemp, _resSm, 0 , _resSm[2]);
  FLUID_3D::advectFieldMacCormack1(dtOrg, xvel, yvel, zvel, 
      _tcTemp, tempBig1, _resSm, 0 , _resSm[2]);
  FLUID_3D::advectFieldMacCormack2(dtOrg, xvel, yvel, zvel, 
      _tcTemp, _tcU, tempBig1, tempBig2, _resSm, NULL, 0 , _resSm[2]);

  SWAP_POINTERS(_tcTemp, _tcV);
  FLUID_3D::copyBorderX(_tcTemp, _resSm, 0 , _resSm[2]);
  FLUID_3D::copyBorderY(_tcTemp, _resSm, 0 , _resSm[2]);
  FLUID_3D::copyBorderZ(_tcTemp, _resSm, 0 , _resSm[2]);
  FLUID_3D::advectFieldMacCormack1(dtOrg, xvel, yvel, zvel, 
      _tcTemp, tempBig1, _resSm, 0 , _resSm[2]);
  FLUID_3D::advectFieldMacCormack2(dtOrg, xvel, yvel, zvel, 
      _tcTemp, _tcV, tempBig1, tempBig2, _resSm, NULL, 0 , _resSm[2]);

  SWAP_POINTERS(_tcTemp, _tcW);
  FLUID_3D::copyBorderX(_tcTemp, _resSm, 0 , _resSm[2]);
  FLUID_3D::copyBorderY(_tcTemp, _resSm, 0 , _resSm[2]);
  FLUID_3D::copyBorderZ(_tcTemp, _resSm, 0 , _resSm[2]);
  FLUID_3D::advectFieldMacCormack1(dtOrg, xvel, yvel, zvel, 
      _tcTemp, tempBig1, _resSm, 0 , _resSm[2]);
  FLUID_3D::advectFieldMacCormack2(dtOrg, xvel, yvel, zvel, 
      _tcTemp, _tcW, tempBig1, tempBig2, _resSm, NULL, 0 , _resSm[2]);
}
Esempio n. 2
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. 3
0
//////////////////////////////////////////////////////////////////////
// diffuse heat
//////////////////////////////////////////////////////////////////////
void FLUID_3D::diffuseHeat()
{
	SWAP_POINTERS(_heat, _heatOld);

	copyBorderAll(_heatOld);
	solveHeat(_heat, _heatOld, _obstacles);

	// zero out inside obstacles
	for (int x = 0; x < _totalCells; x++)
		if (_obstacles[x])
			_heat[x] = 0.0f;
}
Esempio n. 4
0
//////////////////////////////////////////////////////////////////////
// step simulation once
//////////////////////////////////////////////////////////////////////
void FLUID_3D::step(float dt)
{
	// If border rules have been changed
	if (_colloPrev != *_borderColli) {
		setBorderCollisions();
	}


	// set delta time by dt_factor
	_dt = (*_dtFactor) * dt;
	// set vorticity from RNA value
	_vorticityEps = (*_vorticityRNA)/_constantScaling;


#if PARALLEL==1
	int threadval = 1;
	threadval = omp_get_max_threads();

	int stepParts = 1;
	float partSize = _zRes;

	stepParts = threadval*2;	// Dividing parallelized sections into numOfThreads * 2 sections
	partSize = (float)_zRes/stepParts;	// Size of one part;

  if (partSize < 4) {stepParts = threadval;					// If the slice gets too low (might actually slow things down, change it to larger
					partSize = (float)_zRes/stepParts;}
  if (partSize < 4) {stepParts = (int)(ceil((float)_zRes/4.0f));	// If it's still too low (only possible on future systems with +24 cores), change it to 4
					partSize = (float)_zRes/stepParts;}
#else
	int zBegin=0;
	int zEnd=_zRes;
#endif


#if PARALLEL==1
	#pragma omp parallel
	{
	#pragma omp for schedule(static,1)
	for (int i=0; i<stepParts; i++)
	{
		int zBegin = (int)((float)i*partSize + 0.5f);
		int zEnd = (int)((float)(i+1)*partSize + 0.5f);
#endif

		wipeBoundariesSL(zBegin, zEnd);
		addVorticity(zBegin, zEnd);
		addBuoyancy(_heat, _density, zBegin, zEnd);
		addForce(zBegin, zEnd);

#if PARALLEL==1
	}	// end of parallel
	#pragma omp barrier

	#pragma omp single
	{
#endif
	/*
	* addForce() changed Temp values to preserve thread safety
	* (previous functions in per thread loop still needed
	*  original velocity data)
	*
	* So swap temp values to velocity
	*/
	SWAP_POINTERS(_xVelocity, _xVelocityTemp);
	SWAP_POINTERS(_yVelocity, _yVelocityTemp);
	SWAP_POINTERS(_zVelocity, _zVelocityTemp);
#if PARALLEL==1
	}	// end of single

	#pragma omp barrier

	#pragma omp for
	for (int i=0; i<2; i++)
	{
		if (i==0)
		{
#endif
		project();
#if PARALLEL==1
		}
		else
		{
#endif
		diffuseHeat();
#if PARALLEL==1
		}
	}

	#pragma omp barrier

	#pragma omp single
	{
#endif
	/*
	* For thread safety use "Old" to read
	* "current" values but still allow changing values.
	*/
	SWAP_POINTERS(_xVelocity, _xVelocityOld);
	SWAP_POINTERS(_yVelocity, _yVelocityOld);
	SWAP_POINTERS(_zVelocity, _zVelocityOld);
	SWAP_POINTERS(_density, _densityOld);
	SWAP_POINTERS(_heat, _heatOld);

	advectMacCormackBegin(0, _zRes);

#if PARALLEL==1
	}	// end of single

	#pragma omp barrier


	#pragma omp for schedule(static,1)
	for (int i=0; i<stepParts; i++)
	{

		int zBegin = (int)((float)i*partSize + 0.5f);
		int zEnd = (int)((float)(i+1)*partSize + 0.5f);
#endif

	advectMacCormackEnd1(zBegin, zEnd);

#if PARALLEL==1
	}	// end of parallel

	#pragma omp barrier

	#pragma omp for schedule(static,1)
	for (int i=0; i<stepParts; i++)
	{

		int zBegin = (int)((float)i*partSize + 0.5f);
		int zEnd = (int)((float)(i+1)*partSize + 0.5f);
#endif

		advectMacCormackEnd2(zBegin, zEnd);

		artificialDampingSL(zBegin, zEnd);

		// Using forces as temp arrays

#if PARALLEL==1
	}
	}



	for (int i=1; i<stepParts; i++)
	{
		int zPos=(int)((float)i*partSize + 0.5f);
		
		artificialDampingExactSL(zPos);

	}
#endif

	/*
	* swap final velocity back to Velocity array
	* from temp xForce storage
	*/
	SWAP_POINTERS(_xVelocity, _xForce);
	SWAP_POINTERS(_yVelocity, _yForce);
	SWAP_POINTERS(_zVelocity, _zForce);




	_totalTime += _dt;
	_totalSteps++;		

	for (int i = 0; i < _totalCells; i++)
	{
		_xForce[i] = _yForce[i] = _zForce[i] = 0.0f;
	}

}