예제 #1
0
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;
    }
  }
}
예제 #2
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();
}
예제 #4
0
// 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;
}
예제 #5
0
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);
}
예제 #6
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;
}
예제 #7
0
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();
}
예제 #9
0
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;
}
예제 #10
0
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;
}