Exemplo n.º 1
0
void
CrackFrontDefinition::calculateRThetaToCrackFront(const Point qp, const unsigned int node_index, Real & r, Real & theta) const
{
  unsigned int num_nodes(_ordered_crack_front_nodes.size());
  Point p = qp;
  Point closest_node(0.0);
  RealVectorValue closest_node_to_p;

  Node & crack_tip_node = _mesh.node(_ordered_crack_front_nodes[node_index]);
  RealVectorValue crack_tip_node_rot = rotateToCrackFrontCoords(crack_tip_node,node_index);

  RealVectorValue crack_front_edge = rotateToCrackFrontCoords(_tangent_directions[node_index],node_index);

  Point p_rot = rotateToCrackFrontCoords(p,node_index);
  p_rot = p_rot - crack_tip_node_rot;

  if (_treat_as_2d)
  {
    closest_node = crack_tip_node_rot;
    closest_node_to_p = p_rot;

    //Find r, the distance between the qp and the crack front
    RealVectorValue r_vec = p_rot;
    r = r_vec.size();

  }
  else
  {
    // Loop over crack front nodes to find the one closest to the point qp
    Real min_dist = std::numeric_limits<Real>::max();
    for (unsigned int nit = 0; nit != num_nodes; ++nit)
    {
      Node & crack_front_node = _mesh.node(_ordered_crack_front_nodes[nit]);
      RealVectorValue crack_node_to_current_node = p - crack_front_node;
      Real dist = crack_node_to_current_node.size();

      if (dist < min_dist)
      {
        min_dist = dist;
        closest_node = crack_front_node;
      }
    }

    //Rotate coordinates to crack front coordinate system
    closest_node = rotateToCrackFrontCoords(closest_node,node_index);
    closest_node = closest_node - crack_tip_node_rot;

    //Find r, the distance between the qp and the crack front
    Real edge_length_sq = crack_front_edge.size_sq();
    closest_node_to_p = p_rot - closest_node;
    Real perp = crack_front_edge * closest_node_to_p;
    Real dist_along_edge = perp / edge_length_sq;
    RealVectorValue point_on_edge = closest_node + crack_front_edge * dist_along_edge;
    RealVectorValue r_vec = p_rot - point_on_edge;
    r = r_vec.size();

  }

  //Find theta, the angle between r and the crack front plane
  RealVectorValue crack_plane_normal = rotateToCrackFrontCoords(_crack_plane_normal,node_index);
  Real p_to_plane_dist = std::abs(closest_node_to_p*crack_plane_normal);

  //Determine if p is above or below the crack plane
  Real y_local = p_rot(1) - closest_node(1);

  //Determine if p is in front of or behind the crack front
  RealVectorValue p2(p_rot);
  p2(1) = 0;
  RealVectorValue p2_vec = p2 - closest_node;
  Real ahead = crack_front_edge(2) * p2_vec(0) - crack_front_edge(0) * p2_vec(2);

  Real x_local(0);
  if (ahead >= 0)
    x_local = 1;
  else
    x_local = -1;

  //Calculate theta based on in which quadrant in the crack front coordinate
  //system the qp is located
  if (x_local >= 0 && y_local >= 0)
    theta = std::asin(p_to_plane_dist/r);

  else if (x_local < 0 && y_local >= 0)
    theta = libMesh::pi - std::asin(p_to_plane_dist/r);

  else if (x_local < 0 && y_local < 0)
    theta = -(libMesh::pi - std::asin(p_to_plane_dist/r));

  else if (x_local >= 0 && y_local < 0)
    theta = -std::asin(p_to_plane_dist/r);
}
Exemplo n.º 2
0
void
CrackFrontDefinition::calculateRThetaToCrackFront(const Point qp, const unsigned int node_index, Real & r, Real & theta) const
{
  unsigned int num_nodes(_ordered_crack_front_nodes.size());
  Point p = qp;

  // Loop over nodes to find the two crack front nodes closest to the point qp
  Real mindist1(1.0e30);
  Real mindist2(1.0e30);
  Point closest_node1(0.0);
  Point closest_node2(0.0);
  for (unsigned int nit = 0; nit != num_nodes; ++nit)
  {
    Node & crack_front_node = _mesh.node(_ordered_crack_front_nodes[nit]);
    RealVectorValue crack_node_to_current_node = p - crack_front_node;
    Real dist = crack_node_to_current_node.size();

    if (dist < mindist1)
    {
      mindist2 = mindist1;
      closest_node2 = closest_node1;
      mindist1 = dist;
      closest_node1 = crack_front_node;
    }
    else if (dist < mindist2 && dist != mindist1)
    {
      mindist2 = dist;
      closest_node2 = crack_front_node;
    }

  }

  //Rotate coordinates to crack front coordinate system
  closest_node1 = rotateToCrackFrontCoords(closest_node1,node_index);
  closest_node2 = rotateToCrackFrontCoords(closest_node2,node_index);
  if (closest_node1(2) > closest_node2(2))
  {
    RealVectorValue tmp = closest_node2;
    closest_node2 = closest_node1;
    closest_node1 = tmp;
  }
  p = rotateToCrackFrontCoords(p,node_index);

  //Find r, the distance between the qp and the crack front
  RealVectorValue crack_front_edge = closest_node2 - closest_node1;
  Real edge_length_sq = crack_front_edge.size_sq();
  RealVectorValue closest_node1_to_p = p - closest_node1;
  Real perp = crack_front_edge * closest_node1_to_p;
  Real dist_along_edge = perp / edge_length_sq;
  RealVectorValue point_on_edge = closest_node1 + crack_front_edge * dist_along_edge;
  RealVectorValue r_vec = p - point_on_edge;
  r = r_vec.size();

  //Find theta, the angle between r and the crack front plane
  RealVectorValue crack_plane_normal = rotateToCrackFrontCoords(_crack_plane_normal,node_index);
  Real p_to_plane_dist = std::abs(closest_node1_to_p*crack_plane_normal);

  //Determine if p is above or below the crack plane
  Real y_local = p(1) - closest_node1(1);
  //Determine if p is in front of or behind the crack front
  RealVectorValue p2(p);
  p2(1) = 0;
  RealVectorValue p2_vec = p2 - closest_node1;
  Real ahead = crack_front_edge(2) * p2_vec(0) - crack_front_edge(0) * p2_vec(2);
  Real x_local(0);
  if (ahead >= 0)
    x_local = 1;
  else
    x_local = -1;

  //Calculate theta based on in which quadrant in the crack front coordinate
  //system the qp is located
  if (x_local >= 0 && y_local >= 0)
    theta = std::asin(p_to_plane_dist/r);

  else if (x_local < 0 && y_local >= 0)
    theta = libMesh::pi - std::asin(p_to_plane_dist/r);

  else if (x_local < 0 && y_local < 0)
    theta = -(libMesh::pi - std::asin(p_to_plane_dist/r));

  else if (x_local >= 0 && y_local < 0)
    theta = -std::asin(p_to_plane_dist/r);

}
//---------------------------------------------------------------------------//
// Hex-8 test.
TEUCHOS_UNIT_TEST( STKMeshEntityIterator, hex_8_test )
{
    // Extract the raw mpi communicator.
    Teuchos::RCP<const Teuchos::Comm<int> > comm = getDefaultComm<int>();
    Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm = 
	Teuchos::rcp_dynamic_cast< const Teuchos::MpiComm<int> >( comm );
    Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > opaque_comm = 
	mpi_comm->getRawMpiComm();
    MPI_Comm raw_comm = (*opaque_comm)();

    // Create meta data.
    int space_dim = 3;
    stk::mesh::MetaData meta_data( space_dim );

    // Make two parts.
    std::string p1_name = "part_1";
    stk::mesh::Part& part_1 = meta_data.declare_part( p1_name );
    stk::mesh::set_topology( part_1, stk::topology::HEX_8 );
    std::string p2_name = "part_2";
    stk::mesh::Part& part_2 = meta_data.declare_part( p2_name );

    // Make a coordinate field.
    stk::mesh::Field<double, stk::mesh::Cartesian3d>& coord_field =
	meta_data.declare_field<
	stk::mesh::Field<double, stk::mesh::Cartesian3d> >(
	    stk::topology::NODE_RANK, "coordinates");
    meta_data.set_coordinate_field( &coord_field );
    stk::mesh::put_field( coord_field, part_1 );
    meta_data.commit();

    // Create bulk data.
    Teuchos::RCP<stk::mesh::BulkData> bulk_data =
	Teuchos::rcp( new stk::mesh::BulkData(meta_data,raw_comm) );
    bulk_data->modification_begin();

    // Make a hex-8.
    int comm_rank = comm->getRank();
    stk::mesh::EntityId hex_id = 23 + comm_rank;
    stk::mesh::Entity hex_entity = 
	bulk_data->declare_entity( stk::topology::ELEM_RANK, hex_id, part_1 );
    int num_nodes = 8;
    Teuchos::Array<stk::mesh::EntityId> node_ids( num_nodes );
    Teuchos::Array<stk::mesh::Entity> nodes( num_nodes );
    for ( int i = 0; i < num_nodes; ++i )
    {
	node_ids[i] = num_nodes*comm_rank + i + 5;
	nodes[i] = bulk_data->declare_entity( 
	    stk::topology::NODE_RANK, node_ids[i], part_1 );
	bulk_data->declare_relation( hex_entity, nodes[i], i );
    }
    bulk_data->modification_end();

    // Create the node coordinates.
    double* node_coords = 0;
    node_coords = stk::mesh::field_data( coord_field, nodes[0] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[1] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[2] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[3] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[4] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[5] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[6] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[7] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    // Make a list of hexes.
    unsigned num_hex = 2;
    std::vector<stk::mesh::Entity> hex_entities( num_hex, hex_entity );

    // Make a range for the iterators.
    Teuchos::RCP<DataTransferKit::STKMeshEntityIteratorRange> iterator_range =
	Teuchos::rcp( new DataTransferKit::STKMeshEntityIteratorRange() );
    iterator_range->d_stk_entities = hex_entities;
    
    // Test the name predicate for part 1.
    DataTransferKit::STKPartNamePredicate part_1_name_pred( 
	Teuchos::Array<std::string>(1,p1_name), bulk_data );
    DataTransferKit::EntityIterator part_1_name_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_1_name_pred.getFunction() );
    TEST_EQUALITY( part_1_name_iterator.size(), num_hex );

    // Test the name predicate for part 2.
    DataTransferKit::STKPartNamePredicate part_2_name_pred( 
	Teuchos::Array<std::string>(2,p2_name), bulk_data );
    DataTransferKit::EntityIterator part_2_name_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_2_name_pred.getFunction() );
    TEST_EQUALITY( part_2_name_iterator.size(), 0 );

    // Test the part vector predicate for part 1.
    stk::mesh::PartVector p1_vec( 1, &part_1 );
    DataTransferKit::STKPartVectorPredicate part_1_vec_pred( p1_vec );
    DataTransferKit::EntityIterator part_1_vec_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_1_vec_pred.getFunction() );
    TEST_EQUALITY( part_1_vec_iterator.size(), num_hex );

    // Test the part vector predicate for part 2.
    stk::mesh::PartVector p2_vec( 2, &part_2 );
    DataTransferKit::STKPartVectorPredicate part_2_vec_pred( p2_vec );
    DataTransferKit::EntityIterator part_2_vec_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_2_vec_pred.getFunction() );
    TEST_EQUALITY( part_2_vec_iterator.size(), 0 );

    // Test a part vector with 2 part 1's.
    stk::mesh::PartVector p11_vec( 2, &part_1 );
    DataTransferKit::STKPartVectorPredicate part_11_vec_pred( p11_vec );
    DataTransferKit::EntityIterator part_11_vec_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_11_vec_pred.getFunction() );
    TEST_EQUALITY( part_11_vec_iterator.size(), num_hex );

    // Test a part vector with a part 1 and part 2
    stk::mesh::PartVector p12_vec( 2 );
    p12_vec[0] = &part_1;
    p12_vec[1] = &part_2;
    DataTransferKit::STKPartVectorPredicate part_12_vec_pred( p12_vec );
    DataTransferKit::EntityIterator part_12_vec_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_12_vec_pred.getFunction() );
    TEST_EQUALITY( part_12_vec_iterator.size(), 0 );

    // Test the part selector predicate for part 1.
    stk::mesh::Selector p1_sel( part_1 );
    DataTransferKit::STKSelectorPredicate part_1_sel_pred( p1_sel );
    DataTransferKit::EntityIterator part_1_sel_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_1_sel_pred.getFunction() );
    TEST_EQUALITY( part_1_sel_iterator.size(), num_hex );

    // Test the part selector predicate for part 2.
    stk::mesh::Selector p2_sel( part_2 );
    DataTransferKit::STKSelectorPredicate part_2_sel_pred( p2_sel );
    DataTransferKit::EntityIterator part_2_sel_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_2_sel_pred.getFunction() );
    TEST_EQUALITY( part_2_sel_iterator.size(), 0 );
}