Beispiel #1
0
//////////////////////////////////////////////////////////////////////
// step simulation once
//////////////////////////////////////////////////////////////////////
void FLUID_3D::step()
{
	// addSmokeTestCase(_density, _res);
	// addSmokeTestCase(_heat, _res);

	wipeBoundaries();

	// run the solvers
	addVorticity();
	addBuoyancy(_heat, _density);
	addForce();
	project();
	diffuseHeat();

	// advect everything
	advectMacCormack();

	// if(_wTurbulence) {
	// 	_wTurbulence->stepTurbulenceFull(_dt/_dx,
	//			_xVelocity, _yVelocity, _zVelocity, _obstacles);
		// _wTurbulence->stepTurbulenceReadable(_dt/_dx,
		//  _xVelocity, _yVelocity, _zVelocity, _obstacles);
	// }
/*
 // no file output
  float *src = _density;
	string prefix = string("./original.preview/density_fullxy_");
	writeImageSliceXY(src,_res, _res[2]/2, prefix, _totalSteps);
*/
	// artificial damping -- this is necessary because we use a
  // collated grid, and at very coarse grid resolutions, banding
  // artifacts can occur
	artificialDamping(_xVelocity);
	artificialDamping(_yVelocity);
	artificialDamping(_zVelocity);
/*
// no file output
  string pbrtPrefix = string("./pbrt/density_small_");
  IMAGE::dumpPBRT(_totalSteps, pbrtPrefix, _density, _res[0],_res[1],_res[2]);
  */
	_totalTime += _dt;
	_totalSteps++;	

	// todo xxx dg: only clear obstacles, not boundaries
	// memset(_obstacles, 0, sizeof(unsigned char)*_xRes*_yRes*_zRes);

	// wipe forces
	// for external forces we can't do it at the beginning of this function but at the end
	for (int i = 0; i < _totalCells; i++)
	{
		_xForce[i] = _yForce[i] = _zForce[i] = 0.0f;
	}
}
Beispiel #2
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;
	}

}