void MeshEdgeElementTable::calcNormalVector(int index) { if (normals == NULL) return; // Create normal const int* nodeIds = getNodeIds(index); Point3& normal = normals[index]; Point3& p1 = meshNodes[nodeIds[0]]; Point3& p2 = meshNodes[nodeIds[1]]; Point3 a; diff3(p2, p1, a); normal[0] = -a[1]; normal[1] = a[0]; normal[2] = 0.0; normalize(normal); for (int i = 0; i < 3; i++) { if ( isZero(normal[i]) ) { normal[i] = 0.0; } } }
void MeshEdgeElementTable::draw(Renderer* renderer, bool el_selected) { meshElementCode elem_code; int elem_type; for (int i = 0; i < nofElements; i++) { elem_code = getElementCode(i); elem_type = MeshElementDesc[elem_code][DESC_ELEM_TYPE]; renderer->drawMeshElement(elem_type, getNodeIds(i), NULL, meshNodes, 1, el_selected); } }
std::string EpidemicDataSet::getVariableSummaryNodeVsTime(const std::string &varName) { if(variables_.count(varName) == 0) { put_flog(LOG_ERROR, "no such variable %s", varName.c_str()); return std::string(); } // nodeIds std::vector<int> nodeIds = getNodeIds(); // generate the CSV std::stringstream out; // set maximum decimal precision for stringstream out.precision(16); // header out << "t"; // header: for each node for(unsigned int i=0; i<nodeIds.size(); i++) { out << "," << nodeIds[i]; } out << std::endl; // row for each time for(unsigned t=0; t<getNumTimes(); t++) { out << t; for(unsigned int n=0; n<nodeIds.size(); n++) { out << "," << getValue(varName, t, nodeIds[n]); } out << std::endl; } return out.str(); }
// Method finds subelement ("face") index in the parent by // comparing subelement's node-ids to that of the potential // parent. // Returns NO_INDEX if subelement doesn't belong to the parent int MeshElementTable::findSubElementIndex(int elem_index, int& direction, int& start_position, int nof_sub_nodes, const int* sub_node_ids) { static int my_sub_node_ids[64]; meshElementCode elem_code = getElementCode(elem_index); int my_nof_sub_elems = MeshElementDesc[elem_code][DESC_NOF_BNDR_ELEMS]; int nof_nodes_to_check = nof_sub_nodes; int i, my_pos, my_pos2; const int* my_node_ids = getNodeIds(elem_index); //---Loop all faces in the element and compare node ids for (int my_sub_index = 0; my_sub_index < my_nof_sub_elems; my_sub_index++) { // Collect face node ids and check if this COULD be the face for (i = 0; i < nof_sub_nodes; i++) { int local_id = MeshElementBndrNodes[elem_code][my_sub_index][i]; my_sub_node_ids[i] = my_node_ids[local_id]; } int start2; if ( !idLoopsAreMatching(nof_sub_nodes, nof_nodes_to_check, my_sub_node_ids, sub_node_ids, direction, start_position, start2) ) { continue; // Match found } else { return my_sub_index; } } // No match return (int) NO_INDEX; }
Math::RigidTransform3d Fem2DLocalization::getElementPose() { auto femRepresentation = std::static_pointer_cast<Fem2DRepresentation>(getRepresentation()); auto position = getLocalPosition(); auto femElement = femRepresentation->getFemElement(getLocalPosition().index); const auto& nodeIds = femElement->getNodeIds(); std::array<Math::Vector3d, 3> nodePositions = {femRepresentation->getCurrentState()->getPosition(nodeIds[0]), femRepresentation->getCurrentState()->getPosition(nodeIds[1]), femRepresentation->getCurrentState()->getPosition(nodeIds[2])}; Math::Vector3d edge, normal, binormal; edge = (nodePositions[1] - nodePositions[0]).normalized(); normal = (nodePositions[2] - nodePositions[0]).cross(edge).normalized(); binormal = edge.cross(normal); Math::Matrix33d rotation; rotation << edge, normal, binormal; return Math::makeRigidTransform(rotation, (nodePositions[0] + nodePositions[1] + nodePositions[2]) / 3.0); }
void MeshElementTable::calcCenter(int index) { if (centers == NULL) return; const int* nodeIds = getNodeIds(index); // Create center point Point3& center = centers[index]; centerPoint(index, center); // Calculate square of the distance of the first node // from the center Point3 r; diff3(meshNodes[nodeIds[0]], center, r); double rsquared = dot3(r, r); rSquares[index] = rsquared; }
void MeshElementTable::centerPoint(int index, Point3& center) { const int* nodeIds = getNodeIds(index); center[0] = 0; center[1] = 0; center[2] = 0; meshElementCode elem_code = getElementCode(index); short nof_nodes = MeshElementDesc[elem_code][DESC_NOF_NODES]; for (short i = 0; i < nof_nodes; i++) { Point3& p = meshNodes[nodeIds[i]]; center[0] += p[0]; center[1] += p[1]; center[2] += p[2]; } center[0] /= nof_nodes; center[1] /= nof_nodes; center[2] /= nof_nodes; }
std::string EpidemicDataSet::getVariableStratified2NodeVsTime(const std::string &varName) { if(variables_.count(varName) == 0) { put_flog(LOG_ERROR, "no such variable %s", varName.c_str()); return std::string(); } // make sure we have at least two stratifications std::vector<std::vector<std::string> > stratifications = getStratifications(); if(stratifications.size() < 2) { put_flog(LOG_ERROR, "need at least 2 stratifications"); return std::string(); } // nodeIds std::vector<int> nodeIds = getNodeIds(); // generate the CSV std::stringstream out; // set maximum decimal precision for stringstream out.precision(16); // header out << "t,group"; // header: for each node for(unsigned int i=0; i<nodeIds.size(); i++) { out << "," << nodeIds[i]; } out << std::endl; // row for each time and stratification value combination std::vector<int> stratificationValues(2, 0); for(unsigned t=0; t<getNumTimes(); t++) { for(unsigned int s1=0; s1<stratifications[0].size(); s1++) { stratificationValues[0] = s1; for(unsigned int s2=0; s2<stratifications[1].size(); s2++) { stratificationValues[1] = s2; // group name std::string groupName = stratifications[0][s1] + " " + stratifications[1][s2]; out << t << "," << groupName; for(unsigned int n=0; n<nodeIds.size(); n++) { out << "," << getValue(varName, t, nodeIds[n], stratificationValues); } out << std::endl; } } } return out.str(); }
bool MeshElementTable::isSameElement(int index, short& direction, short& start_position, int other_elem_code, int other_nof_nodes, int* other_node_ids) { meshElementCode elem_code = getElementCode(index); if (elem_code != other_elem_code) return false; int nof_nodes = other_nof_nodes; const int* my_node_ids = getNodeIds(index); int i; // First trivial sum check int my_sum = 0; int other_sum = 0; for (i = 0; i < nof_nodes; i++) { my_sum += my_node_ids[i]; other_sum += other_node_ids[i]; } if (my_sum != other_sum) return false; // Now simply compare in order if node ids matches start_position = -1; int other_start_position; for (i = 0; i < nof_nodes; i++) { for (int j = i; j < nof_nodes; j++) { if (my_node_ids[i] == other_node_ids[j]) { start_position = i; other_start_position = j; break; } } // If common node was found if (start_position != -1) break; } if (start_position == -1) return false; int my_pos, other_pos; // Find direction for my nodes my_pos = start_position + 1; if (my_pos == nof_nodes) my_pos = 0; other_pos = other_start_position + 1; if (other_pos == nof_nodes) other_pos = 0; // Try first the positive direction if ( my_node_ids[my_pos] == other_node_ids[other_pos]) { direction = 1; // Try next the negative direction } else { my_pos = start_position - 1; if (my_pos < 0) my_pos = nof_nodes - 1; if ( my_node_ids[my_pos] == other_node_ids[other_pos]) { direction = -1; // Ok, no match in either direction } else { return false; } } // Continue checking the match my_pos += direction; other_pos +=1; // Loop enough nodes the match for (i = 2; i < nof_nodes; i++) { //-check first array edges // "dropping" from left if (my_pos < 0) my_pos = nof_nodes - 1; // "dropping" from right else if (my_pos == nof_nodes) my_pos = 0; if (other_pos == nof_nodes) other_pos = 0; //-if nodes are different, we can stop if (my_node_ids[my_pos] != other_node_ids[other_pos]) { return false; } //-next check positions my_pos += direction; other_pos += 1; } return true; }
int MeshEdgeElementTable::calcLineIntersections(int elem_index, short elem_dir, Point3& lstart, Point3& ldir, Point3* isec_points) { meshElementCode elem_code = getElementCode(elem_index); if (elem_code < MEC_202 || elem_code >= 303) return 0; const int* nodeIds = getNodeIds(elem_index, elem_dir); Point3& p0 = meshNodes[nodeIds[0]]; Point3& p1 = meshNodes[nodeIds[1]]; Point3& normal = normals[elem_index]; if (elem_dir == -1) scalarmult(-1, normal, normal); // Check end-point cases if ( samepoint(p0, lstart) ){ copy3(p0, *isec_points); return 1; } if ( samepoint(p1, lstart) ){ copy3(p1, *isec_points); return 1; } Point3 edge_dir, l_delta0, tmp; // Edge direction vector (normalized) edge_dir[0] = normal[1]; edge_dir[1] = -1 * normal[0]; edge_dir[2] = 0.0; // Edge length diff3(p1, p0, tmp); double edge_len = dot3(edge_dir, tmp); // Vector l_delta0 = lstart - p0 diff3(lstart, p0, l_delta0); // Check that intersection is "within" the edge // project the intersection point to the edge double t = dot3(edge_dir, l_delta0); if ( isLess(t, 0.0) || isGreater(t, edge_len) ) return 0; // Check that intersection distance from the edge is ok // project intersection point to the edge normal double d = dot3(normal, l_delta0); if (d < 0) d *= -1; if ( isGreater(d, MeshEdgeElementTable::pickingTolerance) ) return 0; // Intersection point is: p0 + t * (p1 - p0) scalarmult(t, edge_dir, tmp); add3(p0, tmp, *isec_points); return 1; }