message: Adds support for domains with empty object meshes to DistributedClosestPoint
diff: @@ -963,6 +963,16 @@ public:
  using axom::primal::squared_distance;
  using int32 = axom::int32;
  + const bool hasObjectPoints = m_points.size() > 0;
  +
  + // Check for early return
  + // Note: There is some additional computation the first time this function
  + // is called, even if the local object mesh is empty
  + if(!hasObjectPoints && !is_first)
  + {
  + return;
  + }
  +
  // Check dimension and extract the number of points
  const int dim = xfer_node.fetch_existing("dim").value();
  SLIC_ASSERT(dim == NDIMS);
  @@ -1026,12 +1036,15 @@ public:
  PointArray execPoints(queryPts, m_allocatorID);
  auto query_pts = execPoints.view();
  + if(hasObjectPoints)
  + {
  // Get a device-useable iterator
  auto it = bvh->getTraverser();
  const int rank = m_rank;
  double* sqDistThresh =
  - axom::allocate<double>(1, axom::execution_space<ExecSpace>::allocatorID());
  + axom::allocate<double>(1,
  + axom::execution_space<ExecSpace>::allocatorID());
  *sqDistThresh = m_sqDistanceThreshold;
  auto pointsView = m_points.view();
  @@ -1087,6 +1100,8 @@ public:
  }
  }
  }););
  + axom::deallocate(sqDistThresh);
  + }
  axom::copy(cpIndexes.data(),
  query_inds.data(),
  @@ -1105,7 +1120,6 @@ public:
  query_min_dist.data(),
  minDist.size() * sizeof(double));
  }
  - axom::deallocate(sqDistThresh);
  }
  private:
  @@ -1245,27 +1259,40 @@ public:
  * \param [in] mesh_node Conduit node for the object mesh
  * \param [in] coordset The name of the coordset for the object mesh's coordinates
  *
  - * \pre \a mesh_node must follow the mesh blueprint convention
  + * \pre \a mesh_node must follow the mesh blueprint convention. If this node
  + * is empty, the rank has no data
  * \pre Dimension of the mesh must be 2D or 3D
  */
  void setObjectMesh(const conduit::Node& mesh_node, const std::string& coordset)
  {
  // Perform some simple error checking
  SLIC_ASSERT(this->isValidBlueprint(mesh_node));
  -
  - // Extract the dimension and number of points from the coordinate values group
  auto valuesPath = fmt::format("coordsets/{}/values", coordset);
  +
  + const bool rankIsEmpty = mesh_node.dtype().is_empty();
  +
  + // Extract the dimension from the coordinate values group
  + // use allreduce since some ranks might be empty
  + {
  + int localDim = -1;
  + if(!rankIsEmpty)
  + {
  SLIC_ASSERT(mesh_node.has_path(valuesPath));
  auto& values = mesh_node[valuesPath];
  -
  - const int dim = internal::extractDimension(values);
  + localDim = internal::extractDimension(values);
  + }
  + int dim = -1;
  + MPI_Allreduce(&localDim, &dim, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
  setDimension(dim);
  + }
  allocateQueryInstance();
  + // dispatch mesh import to dimension-specific implementation class
  + if(!rankIsEmpty)
  + {
  + auto& values = mesh_node[valuesPath];
  const int N = internal::extractSize(values);
  -
  - // dispatch to implementation class over dimension
  switch(m_dimension)
  {
  case 2:
  @@ -1276,6 +1303,7 @@ public:
  break;
  }
  }
  + }
  /**
  * \brief Generates a BVH tree over the object mesh using the runtime execution policy
  