示例#1
0
Real
RichardsSUPGstandard::dtauSUPG_dp(RealVectorValue vel,
                                  RealVectorValue dvel_dp,
                                  Real traceperm,
                                  RealVectorValue b,
                                  Real db2_dp) const
{
  Real norm_vel = vel.norm();
  if (norm_vel == 0.0)
    return 0.0; // this deriv is not necessarily correct, but i can't see a better thing to do

  Real norm_vel_dp = dvel_dp * vel / norm_vel;

  Real norm_b = b.norm();
  if (norm_b == 0)
    return 0.0; // this deriv is not necessarily correct, but i can't see a better thing to do
  Real norm_b_dp = db2_dp / (2.0 * norm_b);

  Real h = 2.0 * norm_vel / norm_b; // h is a measure of the element length in the "a" direction
  Real h_dp = 2.0 * norm_vel_dp / norm_b - 2.0 * norm_vel * norm_b_dp / (norm_b * norm_b);

  Real alpha = 0.5 * norm_vel * h / (traceperm * _p_SUPG); // this is the Peclet number
  Real alpha_dp = 0.5 * (norm_vel_dp * h + norm_vel * h_dp) / (traceperm * _p_SUPG);

  Real xi_tilde = RichardsSUPGstandard::cosh_relation(alpha);
  Real xi_tilde_prime = RichardsSUPGstandard::cosh_relation_prime(alpha);
  Real xi_tilde_dp = xi_tilde_prime * alpha_dp;

  // Real tau = xi_tilde/norm_b;
  const Real tau_dp = xi_tilde_dp / norm_b - xi_tilde * norm_b_dp / (norm_b * norm_b);

  return tau_dp;
}
示例#2
0
RealVectorValue
RichardsSUPGstandard::dtauSUPG_dgradp(RealVectorValue vel,
                                      RealTensorValue dvel_dgradp,
                                      Real traceperm,
                                      RealVectorValue b,
                                      RealVectorValue db2_dgradp) const
{
  Real norm_vel = vel.norm();
  if (norm_vel == 0)
    return RealVectorValue();

  RealVectorValue norm_vel_dgradp(dvel_dgradp * vel / norm_vel);

  Real norm_b = b.norm();
  if (norm_b == 0)
    return RealVectorValue();
  RealVectorValue norm_b_dgradp = db2_dgradp / 2.0 / norm_b;

  Real h = 2 * norm_vel / norm_b; // h is a measure of the element length in the "a" direction
  RealVectorValue h_dgradp(2 * norm_vel_dgradp / norm_b -
                           2.0 * norm_vel * norm_b_dgradp / norm_b / norm_b);

  Real alpha = 0.5 * norm_vel * h / traceperm / _p_SUPG; // this is the Peclet number
  RealVectorValue alpha_dgradp =
      0.5 * (norm_vel_dgradp * h + norm_vel * h_dgradp) / traceperm / _p_SUPG;

  Real xi_tilde = RichardsSUPGstandard::cosh_relation(alpha);
  Real xi_tilde_prime = RichardsSUPGstandard::cosh_relation_prime(alpha);
  RealVectorValue xi_tilde_dgradp = xi_tilde_prime * alpha_dgradp;

  RealVectorValue tau_dgradp =
      xi_tilde_dgradp / norm_b - xi_tilde * norm_b_dgradp / (norm_b * norm_b);

  return tau_dgradp;
}
示例#3
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;
}
示例#4
0
void
RotationMatrixTest::rotVtoU(RealVectorValue v, RealVectorValue u)
{
  RealTensorValue ident(1,0,0,  0,1,0,  0,0,1);
  RealVectorValue vhat = v/v.size();
  RealVectorValue uhat = u/u.size();
  RealTensorValue r = RotationMatrix::rotVec1ToVec2(v, u);
  RealVectorValue rotated_v = r*vhat;
  for (unsigned i = 0 ; i < LIBMESH_DIM ; ++i)
    CPPUNIT_ASSERT_DOUBLES_EQUAL( rotated_v(i), uhat(i), 0.0001);
  CPPUNIT_ASSERT( r*r.transpose() == ident);
  CPPUNIT_ASSERT( r.transpose()*r == ident);
}
示例#5
0
Real NSEnergyInviscidBC::qpResidualHelper(Real rho, RealVectorValue u, Real /*pressure*/)
{
  // return (rho*(cv*_temperature[_qp] + 0.5*u.norm_sq()) + pressure) * (u*_normals[_qp]) * _test[_i][_qp];

  // We can also expand pressure in terms of rho... does this make a difference?
  // Then we don't use the input pressure value.
  Real cv = _R / (_gamma - 1.0);
  return rho * (_gamma * cv * _temperature[_qp] + 0.5 * u.norm_sq()) * (u * _normals[_qp]) * _test[_i][_qp];
}
示例#6
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));

}
示例#7
0
Real
RichardsSUPGstandard::tauSUPG(RealVectorValue vel, Real traceperm, RealVectorValue b) const
{
  // vel = velocity, b = bb
  Real norm_v = vel.norm();
  Real norm_b = b.norm(); // Hughes et al investigate infinity-norm and 2-norm.  i just use 2-norm
                          // here.   norm_b ~ 2|a|/ele_length_in_direction_of_a

  if (norm_b == 0)
    return 0.0; // Only way for norm_b=0 is for zero ele size, or vel=0.  Either way we don't have
                // to upwind.

  Real h = 2.0 * norm_v / norm_b; // h is a measure of the element length in the "a" direction
  Real alpha = 0.5 * norm_v * h / (traceperm * _p_SUPG); // this is the Peclet number

  const Real xi_tilde = RichardsSUPGstandard::cosh_relation(alpha);

  return xi_tilde / norm_b;
}
Real
component(const SymmTensor & symm_tensor, unsigned int index, RealVectorValue & direction)
{
    direction.zero();
    if (index < 3)
        direction(index) = 1.0;

    else if (index == 3)//xy
    {
        direction(0) = std::sqrt(0.5);
        direction(1) = direction(0);
    }
    else if (index == 4)//yz
    {
        direction(1) = std::sqrt(0.5);
        direction(2) = direction(1);
    }
    else if (index == 5)//zx
    {
        direction(0) = std::sqrt(0.5);
        direction(2) = direction(0);
    }
    return symm_tensor.component(index);
}
ContactState
FrictionalContactProblem::calculateInteractionSlip(RealVectorValue &slip,
        Real &slip_residual,
        const RealVectorValue &normal,
        const RealVectorValue &residual,
        const RealVectorValue &incremental_slip,
        const RealVectorValue &stiffness,
        const Real friction_coefficient,
        const Real slip_factor,
        const Real slip_too_far_factor,
        const int dim)
{

    ContactState state = STICKING;

    RealVectorValue normal_residual = normal * (normal * residual);
    Real normal_force = normal_residual.size();

//  _console<<"normal="<<info._normal<<std::endl;
//  _console<<"normal_force="<<normal_force<<std::endl;
//  _console<<"residual="<<residual<<std::endl;
//  _console<<"stiffness="<<stiff_vec<<std::endl;

    RealVectorValue tangential_force = normal_residual - residual ; // swap sign to make the code more manageable
    Real tangential_force_magnitude = tangential_force.size();

    Real capacity = normal_force * friction_coefficient;
    if (capacity < 0.0)
        capacity = 0.0;

    Real slip_inc = incremental_slip.size();

    slip(0)=0.0;
    slip(1)=0.0;
    slip(2)=0.0;

    if (slip_inc > 0)
    {
        state = SLIPPING;
        Real slip_dot_tang_force = incremental_slip*tangential_force / slip_inc;
        if (slip_dot_tang_force < capacity)
        {
            state = SLIPPED_TOO_FAR;
//      _console<<"STF slip_dot_force: "<<slip_dot_tang_force<<" capacity: "<<capacity<<std::endl;
        }
    }

    Real excess_force = tangential_force_magnitude - capacity;
    if (excess_force < 0.0)
        excess_force = 0;

    if (state == SLIPPED_TOO_FAR)
    {
        RealVectorValue slip_inc_direction = incremental_slip / slip_inc;
        Real tangential_force_in_slip_dir = slip_inc_direction*tangential_force;
        slip_residual = capacity - tangential_force_in_slip_dir;

        RealVectorValue force_from_unit_slip(0.0,0.0,0.0);
        for (int i=0; i<dim; ++i)
        {
            force_from_unit_slip(i) = stiffness(i) * slip_inc_direction(i);
        }
        Real stiffness_slipdir = force_from_unit_slip * slip_inc_direction; //k=f resolved to slip dir because f=kd and d is a unit vector

        Real slip_distance = slip_too_far_factor*(capacity - tangential_force_in_slip_dir) / stiffness_slipdir;
//    _console<<"STF dist: "<<slip_distance<<" inc: "<<slip_inc<<std::endl;
//    _console<<"STF  cap: "<<capacity<<" tfs: "<<tangential_force_in_slip_dir<<std::endl;
        if (slip_distance < slip_inc)
        {
//      _console<<"STF"<<std::endl;
            slip = slip_inc_direction * -slip_distance;
        }
        else
        {
//      _console<<"STF max"<<std::endl;
            slip = -incremental_slip;
        }
    }
    else if (excess_force > 0)
    {
        state = SLIPPING;
        Real tangential_force_magnitude = tangential_force.size();
        slip_residual = excess_force;

        RealVectorValue tangential_direction = tangential_force / tangential_force_magnitude;
        RealVectorValue excess_force_vector = tangential_direction * excess_force;


        for (int i=0; i<dim; ++i)
        {
            slip(i) = slip_factor * excess_force_vector(i) / stiffness(i);
        }

        //zero out component of slip in normal direction
        RealVectorValue slip_normal_dir = normal * (normal * slip);
        slip = slip - slip_normal_dir;
    }
    return state;
}
示例#10
0
文件: LineSegment.C 项目: Biyss/moose
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;
     */
}
Real
MaterialTensorCalculator::getTensorQuantity(const SymmTensor & tensor,
                                            const Point * curr_point,
                                            RealVectorValue &direction)
{
  direction.zero();
  Real value = 0.0;

  switch (_quantity)
  {
    case 0:
      value = MaterialTensorCalculatorTools::component(tensor, _index, direction);
      break;

    case 1:
      value = MaterialTensorCalculatorTools::vonMisesStress(tensor);
      break;

    case 2:
      value = MaterialTensorCalculatorTools::equivalentPlasticStrain(tensor);
      break;

    case 3:
      value = MaterialTensorCalculatorTools::hydrostatic(tensor);
      break;

    case 4:
      value = MaterialTensorCalculatorTools::directionValueTensor(tensor, _direction);
      break;

    case 5:
      value = MaterialTensorCalculatorTools::hoopStress(tensor, _p1, _p2, curr_point, direction);
      break;

    case 6:
      value = MaterialTensorCalculatorTools::radialStress(tensor, _p1, _p2, curr_point, direction);
      break;

    case 7:
      value = MaterialTensorCalculatorTools::axialStress(tensor, _p1, _p2, direction);
      break;

    case 8:
      value = MaterialTensorCalculatorTools::maxPrinciple(tensor, direction);
      break;

    case 9:
      value = MaterialTensorCalculatorTools::midPrinciple(tensor, direction);
      break;

    case 10:
      value = MaterialTensorCalculatorTools::minPrinciple(tensor, direction);
      break;

    case 11:
      value = MaterialTensorCalculatorTools::firstInvariant(tensor);
      break;

    case 12:
      value = MaterialTensorCalculatorTools::secondInvariant(tensor);
      break;

    case 13:
      value = MaterialTensorCalculatorTools::thirdInvariant(tensor);
      break;

    case 14:
      value = MaterialTensorCalculatorTools::triaxialityStress(tensor);
      break;

    case 15:
      value = MaterialTensorCalculatorTools::volumetricStrain(tensor);
      break;

    default:
    mooseError("Unknown quantity in MaterialTensorAux: " + _quantity_moose_enum.operator std::string());
  }
  return value;
}