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; }
///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; }
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; }
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; }
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; }
// 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_); } }
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; }
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; }
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; }
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; }
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); } } }
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; }
// 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; }
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; }
///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)]; }
///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)); }