示例#1
0
float ElementHex::GetEnery(const std::vector<Eigen::Vector3f> & X,
  const std::vector<Eigen::Vector3f> & u)
{
  std::vector<float> weights;
  std::vector<Eigen::Vector3f> points;

  GaussCube quadrature;
  quadrature.mn = X[GetNodeIndex(0)];
  quadrature.mx = X[GetNodeIndex(6)];
  quadrature.Get(weights,points);

  std::vector<float> energyDensity(points.size(), 0);

  for(size_t ii = 0; ii<points.size();ii++){
    Eigen::Matrix3f F = GetDeformationGrad(points[ii],X,u);
    energyDensity[ii] = material->GetEnergy(F);
  }

  for(size_t jj = 0;jj<forces.size();jj++) {
    forces[jj]->element = this;
    for(size_t ii = 0; ii<points.size();ii++){
      energyDensity[ii] += forces[jj]->GetEnergyDensity(points[ii]);
    }
  }

  float energy=0;
  for (size_t jj = 0; jj < points.size(); jj++) {
    energy += weights[jj] * energyDensity[jj];
  }

  return energy;
}
示例#2
0
///Add move to board
bool ConnectBoard::AddMove(const int &column, const bool& is_me){
	
	if(data_ == NULL){
		fprintf(stderr,"Cannot add move to board, data_ is NULL.");
		return false;
	}
	if(!ValidColumn(column))return false;
	
	int colCt = ColumnCount(column);
	if(colCt == height_){
		fprintf(stderr,"Cannot add more tokens to column %d, height full",column);
		return false;
	}
	int node = GetNodeIndex(colCt,column);
	if(!ValidNode(node)){
		fprintf(stderr,"Cannot add node to board %d",column);
		return false;
	}
	
	data_[node].used = true;
	data_[node].is_me = is_me;

	/*
		Using the lookup kernel noted below we make the assumption that new moves added to the board
		have possible parents where there are 1's and possible child where there are 0's.

		The 'if' statement below (in the 'for' loop) could be collapsed to a single 
		statement but it serves readability by leaving both outcomes explicitly written.
	*/
	{
		//Lookup kernel, tells new node what parents to look for first, then what child.
		int reverseKernel[] = {1, 1, 0,		//		| 1 0 0 |
							   1,-1, 0,		// ==>  | 1   0 |
							   1, 0, 0};	//		| 1 1 0 |

		for(int r = -1; r < 2; r++){
			for(int c = -1; c < 2; c++){
				int rk = (r+1)*3 + (c + 1);
				int rki = 8 - rk;
				if(reverseKernel[rk]==1){
					int parentNode = GetNodeIndex(colCt + r,column + c);
					if(ValidNode(parentNode) && data_[parentNode].is_me == is_me && data_[parentNode].used){
					//	fprintf(stderr,"Adding parentnode[%d] to child[%d]\n",parentNode,node);
						data_[node].parent[rk] = &data_[parentNode];
						data_[parentNode].child[rki] = &data_[node];
					}
				} else if(reverseKernel[rk]==0){
					int childNode = GetNodeIndex(colCt + r,column + c);
					if(ValidNode(childNode) && data_[childNode].is_me == is_me && data_[childNode].used){
					//	fprintf(stderr,"Adding childnode[%d] to parent[%d]\n",childNode,node);
						data_[node].child[rk] = &data_[childNode];
						data_[childNode].parent[rki] = &data_[node];
					}
				}
			}
		}
	}
	return true;
}
示例#3
0
Eigen::Vector3f
ElementHex::ShapeFunGrad(int ii,
    const Eigen::Vector3f & p,
    const std::vector<Eigen::Vector3f> & X)
{
  Eigen::Vector3f xx = getLocalCoord(p,X);
  //min and max node
  Eigen::Array3f X1, X2;
  X1 = X[GetNodeIndex(0)].array();
  X2 = X[GetNodeIndex(6)].array() - X1;
  X2 = -1.0/(4*X2);
  Eigen::Vector3f gradN;
  switch (ii) {
  case 0:
    gradN[0] = X2[0] * (1 - xx[1]) * (1 - xx[2]);
    gradN[1] = X2[1] * (1 - xx[0]) * (1 - xx[2]);
    gradN[2] = X2[2] * (1 - xx[0]) * (1 - xx[1]);
    break;
  case 1:
    gradN[0] = X2[0] * (1 - xx[1]) * (1 - xx[2]);
    gradN[1] = X2[1] * (1 + xx[0]) * (1 - xx[2]);
    gradN[2] = X2[2] * (1 + xx[0]) * (1 - xx[1]);
    break;
  case 2:
    gradN[0] = X2[0] * (1 + xx[1]) * (1 - xx[2]);
    gradN[1] = X2[1] * (1 + xx[0]) * (1 - xx[2]);
    gradN[2] = X2[2] * (1 + xx[0]) * (1 + xx[1]);
    break;
  case 3:
    gradN[0] = X2[0] * (1 + xx[1]) * (1 - xx[2]);
    gradN[1] = X2[1] * (1 - xx[0]) * (1 - xx[2]);
    gradN[2] = X2[2] * (1 - xx[0]) * (1 + xx[1]);
    break;

  case 4:
    gradN[0] = X2[0] * (1 - xx[1]) * (1 + xx[2]);
    gradN[1] = X2[1] * (1 - xx[0]) * (1 + xx[2]);
    gradN[2] = X2[2] * (1 - xx[0]) * (1 - xx[1]);
    break;
  case 5:
    gradN[0] = X2[0] * (1 - xx[1]) * (1 + xx[2]);
    gradN[1] = X2[1] * (1 + xx[0]) * (1 + xx[2]);
    gradN[2] = X2[2] * (1 + xx[0]) * (1 - xx[1]);
    break;
  case 6:
    gradN[0] = X2[0] * (1 + xx[1]) * (1 + xx[2]);
    gradN[1] = X2[1] * (1 + xx[0]) * (1 + xx[2]);
    gradN[2] = X2[2] * (1 + xx[0]) * (1 + xx[1]);
    break;
  case 7:
    gradN[0] = X2[0] * (1 + xx[1]) * (1 + xx[2]);
    gradN[1] = X2[1] * (1 - xx[0]) * (1 + xx[2]);
    gradN[2] = X2[2] * (1 - xx[0]) * (1 + xx[1]);
    break;
  }
  return gradN;
}
示例#4
0
Eigen::Vector3f
ElementHex::getLocalCoord(const Eigen::Vector3f & p,
    const std::vector<Eigen::Vector3f> & X)
{
  Eigen::Vector3f local;
  //min and max node
  Eigen::Vector3f N1, N2;
  N1 = X[GetNodeIndex(0)];
  N2 = X[GetNodeIndex(6)];

  local = (2 * (p-N1).array() / (N2-N1).array() - 1).matrix();
  return local;
}
示例#5
0
int CMessage::Recv( int msgId, char* msgBuf, int msgLen )
{
	int ret = -1;
	int mutexIndex     = GetMutexIndex( msgId );
	int nodeIndex     = GetNodeIndex( msgId );
    
	if ( NULL == m_Node[nodeIndex] )
    {
    	return -1;
    }    
    
	m_Mutex[mutexIndex].Lock();

	MSG_NODE* pPrev = NULL;
	MSG_NODE* pNext = m_Node[nodeIndex];

	while ( pNext )
    {
    	if ( pNext->msgId == msgId )
        {
        	if ( msgBuf == NULL ) 
            {
            	msgLen = 0;
            	ret = 0;
            }
        	if ( msgLen > pNext->msgLen )
            {
            	msgLen = pNext->msgLen;
            }
        	if ( msgLen > 0 ) 
            {
            	memcpy( msgBuf, pNext->msgBuf, msgLen );
            	ret = msgLen;
            }
        	if ( NULL == pPrev )
            {
            	m_Node[nodeIndex] = pNext->next;
            }
        	else
            {
            	pPrev->next = pNext->next;
            }
        
        	Free( pNext->msgBuf );
        	Free( pNext );

        	break;
        }

    	pPrev = pNext;
    	pNext = pNext->next;
    }

	m_Mutex[mutexIndex].Unlock();
    
	return ret;
}
示例#6
0
// If width or height change, modify the board accordingly.
void ConnectBoard::ResizeBoard(){
	Clear();	//clear the board before checking if width and height are valid.  if one of them are wrong, the whole board is invalid.
	
	if(width_ * height_ == 0)return;

	//1-D size
	size_ = width_ * height_;
	
	//1-D board slot storage
	data_ = new ConnectBoard::Node[size_];

	{	//Initialize traversal cache and nodes(will possible require traversal cache)
		for(int row = 0; row < height_; row++){
			for(int col = 0; col < width_; col++){
				int i = GetNodeIndex(row,col);
				data_[i].used = false;
				data_[i].id = i;
				data_[i].r = row;
				data_[i].c = col;

				for(int r = -1; r < 2; r++){
					for(int c = -1; c < 2; c++){
						int rk = (r+1)*3 + (c + 1);
						int nodeID = GetNodeIndex(row + r,col + c);
						data_[i].nodeID[rk] = nodeID;
						data_[i].parent[rk] = data_[i].child[rk] = NULL;
					
					}
				}
	
			}
		}
	}
	
	{	//Initial connection array
		connectSize_ = (width_ > height_)?width_+1:height_+1;
		n_Connect_ = new int[connectSize_];
		memset(n_Connect_,0,sizeof(int) * connectSize_);
	}
}
示例#7
0
ftkgnt::RAGraph ftkgnt::BuildRAG(unsigned short id)
{
	Initialize(id);
	unsigned int counter = 0; 
	boost::property_map<RAGraph, boost::vertex_name_t>::type node_name = get(boost::vertex_name, this->RAG);
	
	while (counter != num_vertices(this->RAG))
	{
		id = static_cast<unsigned long>(atoi(node_name[counter].c_str()));
		std::vector<unsigned short> RAG_cells = labelFilter->GetContactNeighbors(id);
		RAG_cells.erase (RAG_cells.begin());
		
		//Get the Source Vertex for the iteration
		int root = GetNodeIndex(id,this->RAG);
		if(RAG_cells.size()>0)
		{
			for(unsigned int i =0 ; i<RAG_cells.size() ; i++)
			{	
				int tail = GetNodeIndex(RAG_cells[i],this->RAG);
				if(tail ==-1)
				{
					node V;
					V = add_vertex(this->RAG);
					node_name[V] = convert2string(RAG_cells[i]);
					tail = num_vertices(this->RAG)-1;
				}
				bool bRet;
				Edge e;
				boost::tie(e,bRet) = edge(root,tail,this->RAG);
				if(!bRet)
				{
					add_edge(root,tail,this->RAG);
				}
			}
		}
		counter = counter + 1 ;
	} 
	return this->RAG;
}
示例#8
0
std::vector<Eigen::Vector3f>
ElementHex::GetNodalForces(
        const std::vector<Eigen::Vector3f> & X,
        const std::vector<Eigen::Vector3f> & u
    )
{
  std::vector<float> weights;
  std::vector<Eigen::Vector3f> points;

  GaussCube quadrature;
  quadrature.mn = X[GetNodeIndex(0)];
  quadrature.mx = X[GetNodeIndex(6)];
  quadrature.Get(weights,points);

  std::vector<Eigen::Vector3f> f(points.size(),
      Eigen::Vector3f::Zero());

  std::vector<Eigen::Matrix3f> P(points.size());
  for(size_t ii = 0; ii<points.size();ii++){
    Eigen::Matrix3f F = GetDeformationGrad(points[ii],X,u);
    P[ii] = material->GetPK1(F);
  }

  std::vector<Eigen::Vector3f> extForces(points.size());
  for(size_t jj = 0;jj<forces.size();jj++) {
    forces[jj]->element = this;
    for(size_t ii = 0; ii<extForces.size();ii++){
      extForces[ii] += forces[jj]->GetForce(points[ii]);
    }
  }

  for(size_t ii = 0;ii<f.size();ii++){
    for(size_t jj = 0; jj<points.size();jj++){
      Eigen::Vector3f gradN = ShapeFunGrad(ii, points[jj], X);
      f[ii] += weights[jj]* (P[jj]*gradN + extForces[jj]);
    }
  }
  return f;
}
int CHtmlHashTree_PtrArray::GetNodeIndex (const CChainElement* pNode, int iHintStartPoint)
{
	for(int i = iHintStartPoint; i < m_iSize; i++)
		if (m_aElements[i] == pNode)
			return i;

	if (iHintStartPoint!=0)
	{
		// we have missed out due to the hint point? re-start from the start
		return GetNodeIndex(pNode, 0);
	}

	return -1;
}
示例#10
0
Eigen::Matrix3f
ElementHex::GetDeformationGrad(const Eigen::Vector3f & p,
    const std::vector<Eigen::Vector3f> & X,
    const std::vector<Eigen::Vector3f> & u)
{
  Eigen::Matrix3f F = Eigen::Matrix3f::Identity();
  for(int ii = 0;ii<8;ii++){
    int idx = GetNodeIndex(ii);
    Eigen::Vector3f gradN = ShapeFunGrad(ii,p,X);
    //outer product
    F += u[idx] * gradN.transpose();
  }
  return F;
}
示例#11
0
int CMessage::Send( int msgId, char* msgBuf, int msgLen )
{
	MSG_NODE * pNode = ( MSG_NODE * )Malloc( sizeof(MSG_NODE) );
	if ( NULL == pNode ) return -1;
    
	memset( pNode, 0, sizeof(MSG_NODE) );
	pNode->msgId = msgId;
	if ( NULL == msgBuf ) msgLen = 0;
	if ( msgLen > 0 )
    {
    	pNode->msgBuf = ( char* )Malloc( msgLen );
    	if ( NULL == pNode->msgBuf )
        {
        	Free( pNode );
        	return -1;
        }
    	memcpy( pNode->msgBuf, msgBuf, msgLen );
    	pNode->msgLen = msgLen;
    }
    
	int nodeIndex = GetNodeIndex( msgId );
	int mutIndex = GetMutexIndex( msgId );

    // 上锁
	m_Mutex[mutIndex].Lock();

	if ( NULL == m_Node[nodeIndex] )
    {
    	m_Node[nodeIndex] = pNode;
    }
	else
    {
    	MSG_NODE* pNext = m_Node[nodeIndex];
    	MSG_NODE* pPrev = NULL;
    	while ( pNext )
        {
        	pPrev = pNext;
        	pNext = pNext->next;
        }
    	pPrev->next = pNode;
    }

	m_Mutex[mutIndex].Unlock();    // 解锁	
    
	return msgLen;
}
示例#12
0
void AStar::HandleFoundNode(Node *current_node, Node *target_node)
{
	unsigned int g_value = CalculGValue(current_node, target_node->pos);
	if (g_value < target_node->g)
	{
		target_node->g = g_value;
		target_node->parent = current_node;

		size_t index = 0;
		if (GetNodeIndex(target_node, index))
		{
			PercolateUp(index);
		}
		else
		{
			assert(false);
		}
	}
}
示例#13
0
bool CMessage::Find( int msgId )
{
	int index = GetNodeIndex( msgId );

	if ( NULL == m_Node[index] )
    {
    	return false;
    }

	MSG_NODE* pNext = m_Node[index];

	while ( pNext )
    {
    	if ( msgId == pNext->msgId )
        	return true;

    	pNext = pNext->next;
    }

	return false;
}
示例#14
0
// Remove a single move from the board.
bool ConnectBoard::RemoveMove(const int &column, const bool& is_me){
	if(data_ == NULL){
		fprintf(stderr,"Cannot remove move to board, data_ is NULL.");
		return false;
	}
	if(!ValidColumn(column))return false;

	int colCt = ColumnCount(column)-1;
	int node = GetNodeIndex(colCt,column);
	if(!ValidNode(node))return false;


	if(!data_[node].used){
		fprintf(stderr,"Cannot remove token from column %d, column is empty",column);
		return false;
	}
	if(data_[node].is_me != is_me){
		fprintf(stderr,"Cannot remove token from column %d, users do not match",column);
		return false;
	}
	data_[node].used = false;
	
	//Orphan this node's child and remove it from its parents.
	{
		for(int f = 0; f < 9; f++){
			int fi = 8-f;
			if(data_[node].parent[f] != NULL){
				data_[node].parent[f]->child[fi] = NULL;
			}
			if(data_[node].child[f] != NULL){
				data_[node].child[f]->parent[fi] = NULL;
			}
			data_[node].child[f] = NULL;
			data_[node].parent[f] = NULL;
		}
	}
	return true;
}
示例#15
0
ftkgnt::MTreeType ftkgnt::BuildMergeTreeDcon(ftkgnt::RAGraph R1, unsigned short id,std::vector< std::set<int> > hypothesis)
{
	//Create the Merge Tree
	ftkgnt::MTreeType mTree; 
	std::set<int> currRPS;
	std::set<int> nextRPS;	
	
	//To store the RPSs @ the current depth
	std::vector<std::set<int> > curr_depth_RPS;
	
	//To store the RPSs @ all depths
	std::vector< std::vector< std::set<int> > > depth_map;  
	
	//This vector stores the current vector of labels (in int ) 
	std::set< int > curr_members;
	
	unsigned int depth;
	
	//Add the root node to the Merge Tree
	std::string s = convert2string(id);
	ftkgnt::node_mt V;
	V = add_vertex(mTree);
	
	//Current Root Path Set 	
	currRPS.insert(id);
	
	mTree[V].label =  s;
	mTree[V].RPS = currRPS;
	curr_depth_RPS.push_back(currRPS);
	depth_map.push_back(curr_depth_RPS);
	depth = 0;
	curr_depth_RPS = depth_map[depth];
	
	//Add the root as a member and get the current volume
	curr_members.insert(static_cast<int>(id));
	
	// Adjacency Iterators will iterate through the adjacent vertex of the 
	// Region Adjacency graph1 a.k.a the Adjacency_list
	ftkgnt::AdjVertIt avi, avinext, av_end;
	std::set<int>::iterator it;
	std::set<int>::iterator RPSIterator;
	std::set<int>::iterator volIterator;
	std::set<int>::iterator nRPSIterator;
	std::set<int>::iterator RPSIterator2;
	boost::property_map<ftkgnt::RAGraph, boost::vertex_name_t>::type nodes = get(boost::vertex_name, R1);
	
	//Start the loop here
	
	// Logic: For each node in the tree go through the Root Path Set 
	// For every element in the root path set get the neighbors  
	// Add the neighbor to the tree if valid.
	// Stop when All nodes traversed and if no change in number of vertices and 
	// number of edges,return the graph1
	
	unsigned int counter = 0; 
	while (counter != num_vertices(mTree))
	{
		currRPS =  mTree[counter].RPS;
		
		ftkgnt::node_mt V2 = vertex(counter,mTree);
		for(RPSIterator = currRPS.begin(); RPSIterator != currRPS.end(); RPSIterator++)
		{	
			int vertex_index = GetNodeIndex(static_cast<unsigned short>(*RPSIterator),R1);
			ftkgnt::node v = vertex(vertex_index,R1);
			boost::tie(avi, av_end)=adjacent_vertices(v,R1); 
			
			for (avi=avi; avi < av_end ; ++avi)
			{
				nextRPS = currRPS;	   
				ftkgnt::node X = *avi;
				int neighbor = atoi(nodes[X].c_str());
				
				//if "it" points to currRPS.end(), then this node is not present in 
				// the current RPS. RPS condition in Gang's paper   
				nextRPS.insert(neighbor);	
				
				it=currRPS.find(neighbor);
				depth = nextRPS.size() - 1 ;		   	    
				bool depth_cond = true;
				
				// Check if nextRPS is present in the depthmap for the current depth
				//This is the depth condition in Gang's paper.
				if(depth <= depth_map.size()-1)    
				{
					curr_depth_RPS= depth_map[depth]; 
					depth_cond = (curr_depth_RPS.end() == find(curr_depth_RPS.begin(), curr_depth_RPS.end(), nextRPS));	
				}  
				
				if(it==currRPS.end() && depth_cond)
				{
					//This condition checks if the current node is not @  
					// a new level/depth in the tree in the tree
					if(depth <= depth_map.size()-1) 
					{
							curr_depth_RPS= depth_map[depth];
							curr_depth_RPS.push_back(nextRPS);   
							depth_map[depth] =  curr_depth_RPS;     
					}	
					
					// If it is at the new depth.. first check the minimum volume @ the max depth
					// If this value is > than the limit of the cells... return the tree	   
					// If not update the 	   
					else
					{
						bool dcon = (depth<MAX_DEPTH);
						if(dcon)
						{
								curr_depth_RPS.clear();
								curr_depth_RPS.push_back(nextRPS);   
								depth_map.push_back(curr_depth_RPS);
							}
													
						else
						{
							return mTree;
						}
						
					}
					
					//Check if this hypothesis has been checked previously i.e. if this combination of nodes occured 
					// in a previous merge tree 
					bool hypo_cond;
					hypo_cond = (hypothesis.end() == find(hypothesis.begin(), hypothesis.end(), nextRPS));
						
					double vol = 0;	
					for(volIterator = nextRPS.begin(); volIterator != nextRPS.end(); volIterator++)
					{	
						std::vector<unsigned short>::iterator posn1 = find(labelIndex.begin(), labelIndex.end(), *volIterator);
						ftk::IntrinsicFeatures  features  =	allFeat[posn1 - labelIndex.begin()];
						vol+= features.ScalarFeatures[ftk::IntrinsicFeatures::VOLUME];
					}

					
					//Check for the volume condition 
					//Prevents unnecessary extension of tree branches in clusters   
					bool vol_cond = (vol<MAX_VOL);

					if(hypo_cond && vol_cond)
					{
						ftkgnt::node_mt V;
						V = add_vertex(mTree);
						mTree[V].label = nodes[X];
						mTree[V].RPS = nextRPS;
						int tail = num_vertices(mTree)-1;
						add_edge(counter,tail,mTree);
					}
					
				}
				
				//Delete nextRPS
				nextRPS.clear();
				
			}
			
		}		
		counter = counter +1;
		
	}
	
	return mTree;
	
}
示例#16
0
///Direct node access (TODO:  Consider dropping)
ConnectBoard::Node* ConnectBoard::operator()(const int row, const int col) const{
	if(!ValidNode(row,col))return NULL;
	return &data_[GetNodeIndex(row,col)];
}
示例#17
0
///Check if node index (by row and column) is in range.
bool ConnectBoard::ValidNode(const int &row, const int &col) const{
	if(row<0 || row >= height_ || col<0 || col >= width_)return false;
	return ValidNode(GetNodeIndex(row,col));
}