コード例 #1
0
ファイル: Dirichlet_basepoint.c プロジェクト: DamianHeard/orb
static void regular_constraints(
	Constraint			*constraints,
	MatrixPairList		*gen_list,
	ObjectiveFunction	objective_function,
	Boolean				*may_be_saddle_point)
{
	/*
	 *	The documentation at the top of this file shows that the image
	 *	height h corresponding to a matrix m is
	 *
	 *		h = m00 + (m01 - m10)dx + (m02 - m20)dy + (m03 - m30)dz.
	 *
	 *	Each regular constraint will say that the image height h for the
	 *	given matrix must remain greater than the image height h' of the
	 *	matrix used for the objective function.  In symbols, h >= h'.
	 *	Since a Constraint says that some quantity must remain negative,
	 *	we express the constraint as h' - h <= 0.
	 *
	 *	The Boolean *may_be_saddle_point will be set to TRUE if some
	 *	constraint suggests a saddle point.  Otherwise it gets set to FALSE.
	 */

	int			i;
	MatrixPair	*matrix_pair;
	Constraint	*constraint;
	double		h[4],
				c;

	/*
	 *	Assume we're not at a saddle point unless we encounter
	 *	evidence to the contrary.
	 */
	*may_be_saddle_point = FALSE;

	/*
	 *	Skip the identity and the MatrixPair used to define the objective
	 *	function, and begin with the next MatrixPair on the list.
	 *	Write a constraint for it and each successive MatrixPair.
	 *
	 *	Skip the first three Constraints in the constraints array.
	 *	They contain the step size constraints.
	 */

	for (	matrix_pair = gen_list->begin.next->next->next,
				constraint = constraints + 3;

			matrix_pair != &gen_list->end;

			matrix_pair = matrix_pair->next,
				constraint++)
	{
		/*
		 *	Compute h.  (As explained in set_objective_function(),
		 *	it doesn't matter which of the two matrices we use.)
		 */

		for (i = 0; i < 3; i++)
			h[i] = matrix_pair->m[0][0][i+1] - matrix_pair->m[0][i+1][0];

		h[3] = matrix_pair->m[0][0][0];

		/*
		 *	Set the constraint to h' - h.
		 *	(The objective function is h' in the above notation.)
		 */

		for (i = 0; i < 4; i++)
			(*constraint)[i] = objective_function[i] - h[i];

		/*
		 *	Does the constraint plane pass through the origin?
		 */

		if ((*constraint)[3] > - CONSTRAINT_EPSILON)
		{
			/*
			 *	Does the constraint have nonzero derivative?
			 *	If not, then h and h' must have equal but nonzero derivatives.
			 *	We know h' has nonzero derivative because we checked it
			 *	when we computed the objective function.
			 *	Its OK for h and h' to have equal but nonzero derivatives --
			 *	it simply means that as we move avoid from the closest
			 *	translate of the basepoint, we're moving away from some
			 *	other translate as well -- be we don't want to divide by
			 *	length3(*constraint).
			 */

			if (length3(*constraint) > ZERO_DERIV_EPSILON)
			{
				/*
				 *	Check whether the constraint plane is parallel
				 *	to the level sets of the objective function.
				 *
				 *	Use the formula <u,v> = |u| |v| cos(angle).
				 */

				c = inner3(objective_function, *constraint) /
						(length3(objective_function) * length3(*constraint));

				/*
				 *	If it is parallel, set *may_be_saddle_point to TRUE.
				 */

				if (fabs(c) > 1.0 - SADDLE_EPSILON)
					*may_be_saddle_point = TRUE;

				/*
				 *	If necessary we could be more sophisticated at this point,
				 *	and check whether the gradients of h and h' are parallel
				 *	or antiparallel.  Typically one expects them to be
				 *	antiparallel (the MatrixPairs are, after all, the face
				 *	pairings of a Dirichlet domain, so we don't have to worry
				 *	about squares of a matrix), but if they were parallel one
				 *	might want to ask which is longer (depending on which is
				 *	longer, you will or will not be able to move the basepoint
				 *	in that direction).
				 */
			}
		}
	}
}
コード例 #2
0
void peano::applications::faxen::lbf::mappings::RegularGrid2SwitchFromLB2NSE::handleCell(
		peano::applications::faxen::lbf::RegularGridBlockVertex* const vertices,
		peano::applications::faxen::lbf::RegularGridBlockCell&  cell,
		const peano::kernel::gridinterface::VertexEnumerator&  enumerator
) {
	logTraceInWith2Arguments( "handleCell()", enumerator.toString(), cell );

	// only for 2D implementation

	/*
	 * positions of LB cells that are used for velocities interpolation
	 * for NSE grid
	 */
	tarch::la::Vector<DIMENSIONS,double> positionU0;
	tarch::la::Vector<DIMENSIONS,double> positionU1;
	tarch::la::Vector<DIMENSIONS,double> positionU2;
	tarch::la::Vector<DIMENSIONS,double> positionU3;

	tarch::la::Vector<DIMENSIONS,double> positionV0;
	tarch::la::Vector<DIMENSIONS,double> positionV1;
	tarch::la::Vector<DIMENSIONS,double> positionV2;
	tarch::la::Vector<DIMENSIONS,double> positionV3;

	// cellSize
	tarch::la::Vector<DIMENSIONS,double> cellSize = enumerator.getCellSize();

	// cellCenter
	tarch::la::Vector<DIMENSIONS,double> cellCenter = enumerator.getCellCenter();

	// particles index
	int index;

	if(LB_BLOCKSIZE%2 == 0) {
		positionU0[0] = cellCenter[0] + cellSize[0]/2 - _dx/2;
		positionU0[1] = cellCenter[1] - _dx/2;

		positionU1[0] = cellCenter[0] + cellSize[0]/2 + _dx/2;
		positionU1[1] = cellCenter[1] - _dx/2;

		positionU2[0] = cellCenter[0] + cellSize[0]/2 - _dx/2;
		positionU2[1] = cellCenter[1] + _dx/2;

		positionU3[0] = cellCenter[0] + cellSize[0]/2 + _dx/2;
		positionU3[1] = cellCenter[1] + _dx/2;

		positionV0[0] = cellCenter[0] - _dx/2;
		positionV0[1] = cellCenter[1] + cellSize[1]/2 - _dx/2;

		positionV1[0] = cellCenter[0] + _dx/2;
		positionV1[1] = cellCenter[1] + cellSize[1]/2 - _dx/2;

		positionV2[0] = cellCenter[0] - _dx/2;
		positionV2[1] = cellCenter[1] + cellSize[1]/2 + _dx/2;

		positionV3[0] = cellCenter[0] +_dx/2;
		positionV3[1] = cellCenter[1] + cellSize[1]/2 + _dx/2;
	} else {

		positionU0[0] = cellCenter[0] + cellSize[0]/2;
		positionU0[1] = cellCenter[1] - _dx/2;

		positionU1[0] = cellCenter[0] + cellSize[0]/2;
		positionU1[1] = cellCenter[1] + _dx/2;

		positionV0[0] = cellCenter[0] - _dx/2;
		positionV0[1] = cellCenter[1] + cellSize[1]/2;

		positionV1[0] = cellCenter[0] + _dx/2;
		positionV1[1] = cellCenter[1] + cellSize[1]/2;
	}

	// load bottom left vertex
	peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().
			loadVertex(vertices[enumerator(0)].getVertexNumber());
	std::bitset<LB_BLOCK_NUMBER_OF_CELLS>& inner0(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getInner());
	tarch::la::Vector<LB_BLOCK_NUMBER_OF_CELLS,double>& density0(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getDensity());
	_p[0] = inner0[LB_BLOCK_NUMBER_OF_CELLS-1] ? density0[LB_BLOCK_NUMBER_OF_CELLS-1] : 0.0;

	// load bottom right vertex
	peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().
			loadVertex(vertices[enumerator(1)].getVertexNumber());
	std::bitset<LB_BLOCK_NUMBER_OF_CELLS>& inner1(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getInner());
	tarch::la::Vector<LB_BLOCK_NUMBER_OF_CELLS,double>& density1(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getDensity());
	_p[1] = inner1[LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE] ? density1[LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE] : 0.0;


	tarch::la::Vector<LB_BLOCK_NUMBER_OF_CELLS*DIMENSIONS,double>& velocity1(peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getVelocity());
	if(LB_BLOCKSIZE%2 == 0) {

		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionU0)) != -1 ){
			_u[0] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[0]/_dxbydt;
		} else {
			_u[0] = inner1[(2*LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE-2)/2] ? velocity1[2*LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE-2] : 0.0;
		}

		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionU1)) != -1 ){
			_u[1] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[0]/_dxbydt;
		} else {
			_u[1] = inner1[(2*LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE)/2] ? velocity1[2*LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE] : 0.0;
		}

	} else {
		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionU0)) != -1 ){
			_u[0] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[0]/_dxbydt;
		} else {
			_u[0] = inner1[(2*LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE)/2] ? velocity1[2*LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE] : 0.0;
		}
	}

	// load top left vertex
	peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().
			loadVertex(vertices[enumerator(2)].getVertexNumber());
	std::bitset<LB_BLOCK_NUMBER_OF_CELLS>& inner2(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getInner());
	tarch::la::Vector<LB_BLOCK_NUMBER_OF_CELLS,double>& density2(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getDensity());
	_p[2] = inner2[LB_BLOCKSIZE-1] ? density2[LB_BLOCKSIZE-1] : 0.0;

	tarch::la::Vector<LB_BLOCK_NUMBER_OF_CELLS*DIMENSIONS,double>& velocity2(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getVelocity());
	if(LB_BLOCKSIZE%2 == 0) {
		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionV0)) != -1 ){
			_v[0] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[1]/_dxbydt;
		} else {
			_v[0] = inner2[(LB_BLOCK_NUMBER_OF_CELLS-1)/2] ? velocity2[LB_BLOCK_NUMBER_OF_CELLS-1] : 0.0;
		}

		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionV2)) != -1 ){
			_v[2] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[1]/_dxbydt;
		} else {
			_v[2] = inner2[(LB_BLOCK_NUMBER_OF_CELLS+2*LB_BLOCKSIZE-1)/2] ? velocity2[LB_BLOCK_NUMBER_OF_CELLS+2*LB_BLOCKSIZE-1] : 0.0;
		}

	} else {
		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionV0)) != -1 ){
			_v[0] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[1]/_dxbydt;
		} else {
			_v[0] = inner2[(LB_BLOCK_NUMBER_OF_CELLS+LB_BLOCKSIZE-1)/2] ? velocity2[LB_BLOCK_NUMBER_OF_CELLS+LB_BLOCKSIZE-1] : 0.0;
		}
	}

	// load top right vertex
	peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().
			loadVertex(vertices[enumerator(3)].getVertexNumber());
	std::bitset<LB_BLOCK_NUMBER_OF_CELLS>& inner3(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getInner());
	tarch::la::Vector<LB_BLOCK_NUMBER_OF_CELLS,double>& density3(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getDensity());
	_p[3] = inner3[0] ? density3[0] : 0.0;

	tarch::la::Vector<LB_BLOCK_NUMBER_OF_CELLS*DIMENSIONS,double>& velocity3(
			peano::applications::latticeboltzmann::blocklatticeboltzmann::services::GridManagementService::getInstance().getVelocity());
	if(LB_BLOCKSIZE%2 == 0) {
		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionU2)) != -1 ){
			_u[2] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[0]/_dxbydt;
		} else {
			_u[2] = inner3[(LB_BLOCKSIZE-2)/2] ? velocity3[LB_BLOCKSIZE-2] : 0.0;
		}

		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionU3)) != -1 ){
			_u[3] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[0]/_dxbydt;
		} else {
			_u[3] = inner3[LB_BLOCKSIZE/2] ? velocity3[LB_BLOCKSIZE] : 0.0;
		}

		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionV1)) != -1 ){
			_v[1] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[1]/_dxbydt;
		} else {
			_v[1] = inner3[(LB_BLOCK_NUMBER_OF_CELLS-2*LB_BLOCKSIZE+1)/2] ? velocity3[LB_BLOCK_NUMBER_OF_CELLS-2*LB_BLOCKSIZE+1] : 0.0;
		}

		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionV3)) != -1 ){
			_v[3] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[1]/_dxbydt;
		} else {
			_v[3] = inner3[(LB_BLOCK_NUMBER_OF_CELLS+1)/2] ? velocity3[LB_BLOCK_NUMBER_OF_CELLS+1] : 0.0;
		}

	} else {
		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionU1)) != -1 ){
			_u[1] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[0]/_dxbydt;
		} else {
			_u[1] = inner3[(LB_BLOCKSIZE-1)/2] ? velocity3[LB_BLOCKSIZE-1] : 0.0;
		}

		if( (index=peano::applications::faxen::lbf::services::ParticlesService::getInstance().belongs2Particle(positionV1)) != -1 ){
			_v[1] = peano::applications::faxen::lbf::services::ParticlesService::getInstance().getParticlesVelocity(index)[1]/_dxbydt;
		} else {
			_v[1] = inner3[(LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE+1)/2] ? velocity3[LB_BLOCK_NUMBER_OF_CELLS-LB_BLOCKSIZE+1] : 0.0;
		}
	}

	double P_new = ((_p[0]+_p[1]+_p[2]+_p[3])/4)*_dxbydt*_dxbydt*_rho/3;
	double P_old = cell.getP();

	// updating cell's pressure and its averages with neighbors.
	vertices[enumerator(1)].updateP0(P_old,P_new);
	vertices[enumerator(2)].updateP1(P_old,P_new);
	vertices[enumerator(3)].updateP0(P_old,P_new);
	vertices[enumerator(3)].updateP1(P_old,P_new);
	cell.setP(P_new);

	double U_new, V_new;
	double U_old = cell.getU();
	double V_old = cell.getV();

	if(LB_BLOCKSIZE%2 == 0) {
		U_new = _dxbydt*(_u[0]+_u[1]+_u[2]+_u[3])/4;
		V_new = _dxbydt*(_v[0]+_v[1]+_v[2]+_v[3])/4;
	} else {
		U_new = _dxbydt*(_u[0]+_u[1])/2;
		V_new = _dxbydt*(_v[0]+_v[1])/2;
	}

	// updating cell's horizontal velocity and its averages with neighbors.
	vertices[enumerator(0)].updateU0(U_old,U_new);
	vertices[enumerator(1)].updateU1(U_old,U_new);
	vertices[enumerator(1)].updateU0(U_old,U_new);
	vertices[enumerator(2)].updateU2(U_old,U_new);
	vertices[enumerator(3)].updateU2(U_old,U_new);
	vertices[enumerator(2)].updateU0(U_old,U_new);
	vertices[enumerator(3)].updateU1(U_old,U_new);
	vertices[enumerator(3)].updateU0(U_old,U_new);
	cell.setU(U_new);

	// updating cell's vertical velocity and its averages with neighbors.
	vertices[enumerator(0)].updateV0(V_old,V_new);
	vertices[enumerator(1)].updateV1(V_old,V_new);
	vertices[enumerator(1)].updateV0(V_old,V_new);
	vertices[enumerator(2)].updateV2(V_old,V_new);
	vertices[enumerator(3)].updateV2(V_old,V_new);
	vertices[enumerator(2)].updateV0(V_old,V_new);
	vertices[enumerator(3)].updateV1(V_old,V_new);
	vertices[enumerator(3)].updateV0(V_old,V_new);
	cell.setV(V_new);

	logTraceOut( "handleCell()" );
}