Exemplo n.º 1
0
VEC3I fluid_detection::cellPos(VEC3D& pos)
{
	if (sph->dimension() == DIM2){
		return VEC3I(
			(int)floor((pos.x - gMin.x) * cSize_inv),
			(int)floor((pos.y - gMin.y) * cSize_inv),
			(int)0);
	}
	return VEC3I(
		(int)floor((pos.x - gMin.x) * cSize_inv),
		(int)floor((pos.y - gMin.y) * cSize_inv),
		(int)floor((pos.z - gMin.z) * cSize_inv));
}
Exemplo n.º 2
0
//////////////////////////////////////////////////////////////////////
// Advect using the semi-Lagrangian method of Stam
//////////////////////////////////////////////////////////////////////
void FLUID_3D_MIC::advectStam()
{
  TIMER functionTimer(__FUNCTION__);
	VEC3I res = VEC3I(_xRes,_yRes,_zRes);

	if(_domainBcLeft == 0) 
    _velocity.copyBorderX();
	else 
    _velocity.setZeroX();

	if(_domainBcTop == 0) 
    _velocity.copyBorderY();
	else 
    _velocity.setZeroY();

	if(_domainBcFront == 0) 
    _velocity.copyBorderZ();
	else 
    _velocity.setZeroZ();

  _preadvection = _velocity;

  _velocity.swapPointers(_velocityOld);
	_density.swapPointers(_densityOld);
	_heat.swapPointers(_heatOld);

	const Real dt0 = _dt / _dx;
  VECTOR3_FIELD_3D::advect(dt0, _velocityOld, _densityOld, _density);
  VECTOR3_FIELD_3D::advect(dt0, _velocityOld, _heatOld, _heat);
  VECTOR3_FIELD_3D::advect(dt0, _velocityOld, _velocityOld, _velocity);

  _cachedQuadratic = _velocity - _velocityOld;
  _postadvection = _velocity;

  // this seems to fix things relative to explicit advection --
  // otherwise new values appear at the boundaries
  _velocity.setZeroBorder();

	if(_domainBcLeft == 0) 
    _velocity.copyBorderX();
	else 
    _velocity.setZeroX();

	if(_domainBcTop == 0)
    _velocity.copyBorderY();
  else
    _velocity.setZeroY();

	if(_domainBcFront == 0) 
    _velocity.copyBorderZ();
	else 
    _velocity.setZeroZ();

	_density.setZeroBorder();
	_heat.setZeroBorder();
}
Exemplo n.º 3
0
FLUID_3D_MIC::FLUID_3D_MIC(int xRes, int yRes, int zRes, int amplify, unsigned int* boundaries) :
	_xRes(xRes), _yRes(yRes), _zRes(zRes), _res(0.)
{
	// set simulation consts
  _dt = 0.10; 

  _iterations = 1000;
  _buoyancy = 0.1f;
  _heatDiffusion = 1e-3;
  _vorticityEps = 2.0;
	_totalTime = 0.0f;
	_totalSteps = 0;
	_res = VEC3I(_xRes,_yRes,_zRes);
	_maxRes = _res.maxElement();

  // scale the constants according to the refinement of the grid
	_dx = 1.0f / (Real)_maxRes;
	Real scaling = 64.0f / _maxRes;
	scaling = (scaling < 1.0f) ? 1.0f : scaling;
	_vorticityEps /= scaling;

  // precision of the CG solver
  _solverEps = 1e-10;

  _center = VEC3F(0,0,0);
  _lengths = VEC3F(_dx * _xRes, _dx * _yRes, _dx * _zRes);

  _density    = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _densityOld = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _heat    = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _heatOld = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _pressure = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _divergence = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _residual = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _direction = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _q = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);

  _dudt0 = VECTOR3_FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _dudt1 = VECTOR3_FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);

  _velocity = VECTOR3_FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _velocityOld = VECTOR3_FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);

  _force = VECTOR3_FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
  _vorticity = VECTOR3_FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);

	_precon = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	_z      = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	_Adiag  = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	_Aplusi = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	_Aplusj = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	_Aplusk = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	_Aminui = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	_Aminuj = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	_Aminuk = FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	
	// allocate arrays
	_totalCells   = _xRes * _yRes * _zRes;
	_slabSize = _xRes * _yRes;
	_xs = 1; _ys = _xRes; _zs = _slabSize;
	_obstacles    = new unsigned char[_totalCells];
	_dirichletObstacleField = new bool[_totalCells];
	_neumannObstacleField = new bool[_totalCells];

  _neumannVelocityField = VECTOR3_FIELD_3D(_xRes, _yRes, _zRes, _center, _lengths);
	
	for (int x = 0; x < _totalCells; x++)
  {
		_obstacles[x]    = false;
    _dirichletObstacleField[x] = false;
    _neumannObstacleField[x] = false;
  }
  
  // set up the boundary conditions
  if (boundaries != NULL)
  {
    _domainBcFront  = boundaries[0];
    _domainBcBack   = boundaries[1];
    _domainBcLeft   = boundaries[2];
    _domainBcRight  = boundaries[3];
    _domainBcTop    = boundaries[4];
    _domainBcBottom = boundaries[5];
  }
  else
  {
    _domainBcFront  = 1; 
    _domainBcBack   = 1;
    _domainBcLeft   = 1;
    _domainBcRight  = 1;
    _domainBcTop    = 0;
    _domainBcBottom = 0;
  }

	// 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(_domainBcFront==1) _obstacles[index] = 1;

      // back slab
      index += _totalCells - _slabSize;
      if(_domainBcBack==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(_domainBcBottom==1) _obstacles[index] = 1;

      // top slab
      index += _slabSize - _xRes;
      if(_domainBcTop==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;
    }
}
Exemplo n.º 4
0
bool fluid_detection::initGrid()
{
	cells = 0;
// 	VEC3D fMax = sph->particle(0)->position();
// 	VEC3D fMin = fMax;
// 	if (sph->getPeriodicDirection() == PERI_X)
// 	{
// 		for (unsigned int i = 0; i < sph->nParticleByType(FLUID); i++)
// 		{
// 			VEC3D p = sph->particle(i)->position();
// 			if (fMax <= p)
// 				fMax = p;
// 			if (fMin >= p)
// 				fMin = p;
// 		}		
// 	}
	gMin = gMin - VEC3D(gcSize);
	gMax = gMax + VEC3D(gcSize);
	gSize = gMax - gMin;

	gcCount.x = static_cast<int>(ceil(gSize.x / gcSize));
	gcCount.y = static_cast<int>(ceil(gSize.y / gcSize));
	cells = gcCount.x * gcCount.y;
	if (sph->dimension() == DIM3){
		gcCount.z = static_cast<int>(ceil(gSize.z / gcSize));
		cells *= gcCount.z;
	}

	if (!gcCount.x || !gcCount.y){
		std::cout << "You need to correctly set simulation boundaries" << std::endl;
		return false;
	}

	cellCount_1 = gcCount - VEC3I(1);
	cSize_inv = 1.0 / gcSize;

	size_t np = sph->nParticle();
	if (sph->getPeriodicParticles())
	{
		np += sph->getPeriodicParticles()->nParticle();
	}
	hashes = new VEC2UI[np];
	cell_id = new size_t[np];		memset(cell_id, 0, sizeof(size_t)*np);
	cell_start = new size_t[cells];	memset(cell_start, 0, sizeof(size_t)*cells);

// 	if (sph->getPeriodicDirection() == PERI_X)
// 	{
// 		VEC3I _cmax = cellPos(fMax);
// 		peri_maxCI.x = _cmax.x;
// 		VEC3I _cmin = cellPos(fMin);
// 		peri_minCI.x = _cmin.x;
// 	}
	
// 	if (sph->Device() == GPU){
// 		checkCudaErrors(cudaMalloc((void**)&d_hashes, sizeof(int2) * np));
// 		checkCudaErrors(cudaMalloc((void**)&d_cell_id, sizeof(uint) * np));
// 		checkCudaErrors(cudaMalloc((void**)&d_cell_start, sizeof(uint) * cells));
// 	}

	return true;
}