Пример #1
0
RealVectorValue
CrackFrontDefinition::calculateCrackFrontDirection(const Node* crack_front_node,
                                                   const RealVectorValue& tangent_direction,
                                                   const CRACK_NODE_TYPE ntype) const
{
  RealVectorValue crack_dir;
  RealVectorValue zero_vec(0.0);

  bool calc_dir = true;
  if (_end_direction_method == END_CRACK_DIRECTION_VECTOR)
  {
    if (ntype == END_1_NODE)
    {
      crack_dir = _crack_direction_vector_end_1;
      calc_dir = false;
    }
    else if (ntype == END_2_NODE)
    {
      crack_dir = _crack_direction_vector_end_2;
      calc_dir = false;
    }
  }

  if (calc_dir)
  {
    if (_direction_method == CRACK_DIRECTION_VECTOR)
    {
      crack_dir = _crack_direction_vector;
    }
    else if (_direction_method == CRACK_MOUTH)
    {
      if (_crack_mouth_coordinates.absolute_fuzzy_equals(*crack_front_node,1.e-15))
      {
        mooseError("Crack mouth too close to crack front node");
      }
      RealVectorValue mouth_to_front = *crack_front_node - _crack_mouth_coordinates;

      RealVectorValue crack_plane_normal = mouth_to_front.cross(tangent_direction);
      if (crack_plane_normal.absolute_fuzzy_equals(zero_vec,1.e-15))
      {
        mooseError("Vector from crack mouth to crack front node is collinear with crack front segment");
      }

      crack_dir = tangent_direction.cross(crack_plane_normal);
      Real dotprod = crack_dir*mouth_to_front;
      if (dotprod < 0)
      {
        crack_dir = -crack_dir;
      }
    }
    else if (_direction_method == CURVED_CRACK_FRONT)
    {
      crack_dir = tangent_direction.cross(_crack_plane_normal);
    }
  }
  crack_dir = crack_dir.unit();

  return crack_dir;
}
Пример #2
0
OrientedBoxInterface::OrientedBoxInterface(const InputParameters & parameters) :
    _center(parameters.get<Point>("center"))
{
  const std::string & name = parameters.get<std::string>("_object_name");

  // Define the bounding box
  Real xmax = 0.5 * parameters.get<Real>("width");
  Real ymax = 0.5 * parameters.get<Real>("length");
  Real zmax = 0.5 * parameters.get<Real>("height");

  Point bottom_left(-xmax, -ymax, -zmax);
  Point top_right(xmax, ymax, zmax);

  _bounding_box = new MeshTools::BoundingBox(bottom_left, top_right);

  /*
   * now create the rotation matrix that rotates the oriented
   * box's width direction to "x", its length direction to "y"
   * and its height direction to "z"
   */
  RealVectorValue w = parameters.get<RealVectorValue>("width_direction");
  RealVectorValue l = parameters.get<RealVectorValue>("length_direction");

  /*
   * Normalize the width and length directions in readiness for
   * insertion into the rotation matrix
   */
  Real len = w.norm();
  if (len == 0.0)
    mooseError("Length of width_direction vector is zero in " << name);
  w /= len;

  len = l.norm();
  if (len == 0.0)
    mooseError("Length of length_direction vector is zero in " << name);
  l /= len;

  if (w*l > 1E-10)
    mooseError("width_direction and length_direction are not perpendicular in " << name);

  // The rotation matrix!
  _rot_matrix = new RealTensorValue(w, l, w.cross(l));

}
Пример #3
0
bool
LineSegment::intersect (const LineSegment & l, Point & intersect_p) const
{
  /**
   * First check for concurance:
   *
   *
   * | x1 y1 z1 1 |
   * | x2 y2 z2 1 | = (x3 - x1) * [(x2-x1) x (x4-x3)] = 0
   * | x3 y3 z3 1 |
   * | x4 y4 z4 1 |
   *
   *
   * Solve:
   *   x = _p0 + (_p1 - _p0)*s
   *   x = l.p0 + (l._p1 - l.p0)*t
   *
   *   where
   *   a = _p1 - _p0
   *   b = l._p1 - l._p0
   *   c = l._p0 - _p0
   *
   *   s = (c x b) * (a x b) / | a x b |^2
   */
  RealVectorValue a = _p1 - _p0;
  RealVectorValue b = l._p1 - l._p0;
  RealVectorValue c = l._p0 - _p0;

  RealVectorValue v = a.cross(b);

  // Check for parallel lines
  if (std::abs(v.norm()) < 1.e-10 && std::abs(c.cross(a).norm()) < 1.e-10)
  {
    // TODO: The lines are co-linear but more work is needed to determine and intersection point
    //       it could be the case that the line segments don't lie on the same line or overlap only
    //       a bit
    return true;
  }

  // Check that the lines are coplanar
  Real concur = c * (a.cross(b));
  if (std::abs(concur) > 1.e-10)
    return false;

  Real s = (c.cross(b) * v) / (v*v);
  Real t = (c.cross(a) * v) / (v*v);

  // if s and t are between 0 and 1 then the Line Segments intersect
  // TODO: We could handle other case of clamping to the end of Line
  //       Segements if we want to here

  if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
  {
    intersect_p = _p0 + s*a;
    return true;
  }
  return false;

  /**
   * Parameteric Equation of lines
   * _p0 + t(v0) = l._p0 + u(v1)
   *
   * Case 1: Parallel Lines
   *         v0 x v1 == 0
   *
   * Case 1a: Collinear Lines
   *         v0 x v1 == 0
   *         (l._p0 - _p0) x (_p1 - _p0) == 0
   *
   * Case 2: Intersecting Lines
   *         0 <= t <= 1
   *         0 <= u <= 1
   *
   *
   * Case 1: The lines do not intersect
   *         vleft cross vright = non-zero
   *
   * Case 2: The lines are co-linear
   *         vleft cross vright = zero
   *         vleft (Denominator) = zero
   *
   * Case 3: The line intersect at a single point
   *         vleft cross vright = zero
   *         vleft (Denominator) = non-zero
  RealVectorValue v0 = _p1 - _p0;
  RealVectorValue v1 = l._p1 - l._p0;
  RealVectorValue v2 = l._p0 - _p0;

  RealVectorValue vbot = v0.cross(v1);
  RealVectorValue vtop = v2.cross(v1);

  RealVectorValue crossed = vleft.cross(vright);

  // Case 1: No intersection
  if (std::abs(vleft.cross(vright).size()) > 1.e-10)
    return false;

  // Case 2: Co-linear (just return one of the end points)
  if (std::abs(vleft.size()) < 1.e-10)
  {
    intersect_p = _p0;
    return true;
  }

  // Case 3:

  //TODO: We could detect whether the Line Segments actually overlap
  //      instead of whether the Lines are co-linear

  Real a = vright.size()/vleft.size();
  intersect_p = _p0 + a*v0;
  return true;
     */
}