/**
 * Used to output the results of a relation vector in human
 * readable form.  This function cannot be used as the default
 * output of an IdentProcRelation since it is using knowledge that
 * what is really being stored in the IdentProc is stk::mesh
 * entity keys.
 */
void print_stk_mesh_relation_map(stk::diag::Writer &writer,
                                 IdentProcRelation relation)
{
  static std::vector<std::string> entity_names = stk::mesh::fem_entity_rank_names();
  if (writer.shouldPrint()) {
    size_t size = relation.size();
    writer << "relation  [size " << size << "]\n";
    for (size_t i=0; i < size; i++) {
      IdentProc domain = relation[i].first;
      IdentProc range  = relation[i].second;

//       stk::mesh::EntityKey domain_entity_key;
//       stk::mesh::EntityKey range_entity_key;
//       domain_entity_key.value(domain.ident);
//       range_entity_key.value(range.ident);

      stk::mesh::EntityKey domain_entity_key(domain.ident);
      stk::mesh::EntityKey range_entity_key(range.ident);

      writer << "[" << i << "] ("
             << entity_names[stk::mesh::entity_rank(domain_entity_key)] << " "
             << stk::mesh::entity_id(domain_entity_key)
             << ", proc " << domain.proc
             << "    ->    "
             << entity_names[stk::mesh::entity_rank(range_entity_key)] << " "
             << stk::mesh::entity_id(range_entity_key)
             << ", proc " << range.proc
             << ")\n";
    }
  }
}
void
use_case_4_driver(stk::ParallelMachine  comm,
		  const std::string &working_directory,
		  const std::string &range_mesh_filename,
		  const std::string &range_mesh_type,
		  const std::string &range_entity,
		  const std::string &domain_mesh_filename,
		  const std::string &domain_mesh_type,
		  const std::string &domain_entity)
{
  stk::diag::WriterThrowSafe _write_throw_safe(dw());

  dw().m(LOG_SEARCH) << "Use case 4" << stk::diag::push << stk::diag::dendl;

  // ========================================================================
  // Initialize IO system.  Registers all element types and storage
  // types and the exodusII default database type.
  Ioss::Init::Initializer init_db;

  // Define range mesh...
  stk::mesh::fem::FEMMetaData range_meta_data( spatial_dimension );
  stk::io::MeshData range_mesh_data;
  std::string filename = working_directory + range_mesh_filename;
  stk::io::create_input_mesh(range_mesh_type, filename, comm,
			     range_meta_data, range_mesh_data);
  range_meta_data.commit();

  stk::mesh::BulkData range_bulk_data(range_meta_data.get_meta_data(range_meta_data) , comm);
  stk::io::populate_bulk_data(range_bulk_data, range_mesh_data);


  // Define domain mesh...
  stk::mesh::fem::FEMMetaData domain_meta_data( spatial_dimension );
  stk::io::MeshData domain_mesh_data;
  filename = working_directory + domain_mesh_filename;
  stk::io::create_input_mesh(domain_mesh_type, domain_mesh_filename, comm,
			     domain_meta_data, domain_mesh_data);
  domain_meta_data.commit();

  stk::mesh::BulkData domain_bulk_data(domain_meta_data.get_meta_data(domain_meta_data) , comm);
  stk::io::populate_bulk_data(domain_bulk_data, domain_mesh_data);

  // ========================================================================
  // For this use case, the domain consists of an axis-aligned
  // bounding box for each 'domain_entity' in the mesh.  The range is also an
  // axis-aligned bounding box of each 'range_entity'.

  VectorField *range_coord_field = range_meta_data.get_field<VectorField>("coordinates");
  std::vector<AxisAlignedBoundingBox3D> range_vector;
  stk::search_util::build_axis_aligned_bbox(range_bulk_data,
                                            range_meta_data.entity_rank(range_entity),
                                            range_coord_field, range_vector);

  VectorField *domain_coord_field = domain_meta_data.get_field<VectorField>("coordinates");
  std::vector<AxisAlignedBoundingBox3D> domain_vector;
  stk::search_util::build_axis_aligned_bbox(domain_bulk_data,
					domain_meta_data.entity_rank(domain_entity),
					domain_coord_field, domain_vector);

  if (range_vector.size() <= 100)
     dw().m(LOG_SEARCH) << "range  " << range_vector << dendl;
  else
    dw().m(LOG_SEARCH) << "range vector size  = " << range_vector.size() << dendl;

  if (domain_vector.size() <= 100)
    dw().m(LOG_SEARCH) << "domain " << domain_vector << dendl;
  else
    dw().m(LOG_SEARCH) << "domain vector size = " << domain_vector.size() << dendl;

  FactoryOrder order;
  order.m_communicator = comm;
  //order.m_algorithm = FactoryOrder::BIHTREE;

  dw() << "Search algorithm " << order.m_algorithm << dendl;
//  dw().m(LOG_SEARCH) << "Search tree " << *range_search << dendl;

  IdentProcRelation relation;

  stk::search::coarse_search(relation, range_vector, domain_vector,order);

  if (relation.size() <= 100)
    dw().m(LOG_SEARCH) << "relation " << relation << dendl;
  else
    dw().m(LOG_SEARCH) << "relation size = " << relation.size() << dendl;

  dw().m(LOG_SEARCH) << stk::diag::pop;
}
Beispiel #3
0
    const stk_classic::mesh::Entity *
    STKSearcher<SpatialDim>::findElement(MDArray& input_phy_points, MDArray& found_parametric_coordinates,
                                         unsigned& found_it, const mesh::Entity *hint_element )
    {
      //return 0;
      mesh::fem::FEMMetaData& metaData = stk_classic::mesh::fem::FEMMetaData::get(*m_bulk);
      mesh::BulkData& bulkData = *m_bulk;

      //VectorFieldType *coords_field = metaData.get_field<VectorFieldType >("coordinates");

      PerceptMesh meshUtil(&metaData, &bulkData);

      double pts[SpatialDim];
      for (unsigned iDim = 0; iDim < SpatialDim; iDim++)
        {
          pts[iDim] = input_phy_points(0, iDim);
        }
      BPoint pointBoundingBox;
      pointBoundingBox.key.ident = 123;  // FIXME for multiple points
      pointBoundingBox.set_center(pts);
      std::vector<BPoint> points(1, pointBoundingBox);

      stk_classic::search::FactoryOrder order;
      order.m_communicator = bulkData.parallel();
      order.m_algorithm = stk_classic::search::FactoryOrder::BIHTREE;

      if (0 || EXTRA_PRINT)
        {
          bool box_p = m_boxes[0].intersect(pointBoundingBox);
          bool p_box = pointBoundingBox.intersect(m_boxes[0]);

          std::cout << "STKSearcher::findElement: m_boxes[0]=  " << m_boxes[0] << std::endl;
          std::cout << "STKSearcher::findElement: pointBoundingBox=  " << pointBoundingBox << std::endl;
          std::cout << "STKSearcher::findElement: box_p=  " << box_p << std::endl;
          std::cout << "STKSearcher::findElement: p_box=  " << p_box << std::endl;
        }

      if (0 || EXTRA_PRINT) std::cout << "STKSearcher::findElement: nboxes=  " << m_boxes.size()  << std::endl;

      IdentProcRelation relation;
      stk_classic::search::coarse_search(relation,  m_boxes, points, order);
      //stk_classic::search::coarse_search(relation,   points, m_boxes, order);

      if (0 || EXTRA_PRINT) std::cout << "STKSearcher::findElement: found  " << relation.size() << " containing bboxes"  << std::endl;

      if (relation.size())
        {
          IsInElement isIn(input_phy_points, found_parametric_coordinates);

          for (unsigned i = 0; i < relation.size(); i++)
            {
              if (0 || EXTRA_PRINT)
                std::cout << "relation[ " << i << "]= {" << relation[i].first << "} --> { " << relation[i].second << "}" << std::endl;
              mesh::Entity *element = bulkData.get_entity(metaData.element_rank(), relation[i].second.ident);
              //bool loop_break = ... intentionally ignoring return value
              isIn(*element, bulkData);
              if (0 || EXTRA_PRINT) std::cout << "STKSearcher::findElement: found it= " << isIn.m_found_it << std::endl;
              if (isIn.m_found_it)
                {
                  found_it = 1;
                  return isIn.m_foundElement;
                }
              else
                {
                  found_it = 0;
                  return 0;
                }
            }
        }

      return 0;
    }