Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.

Commit abe1d5c

Browse files
committed
for new experimental branch
1 parent 7185ecd commit abe1d5c

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/ipc/collisions/normal/normal_collisions.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,61 @@ double NormalCollisions::compute_minimum_distance(
361361

362362
// ============================================================================
363363

364+
// NOTE: Actually distance squared
365+
double NormalCollisions::compute_avg_distance(
366+
const CollisionMesh& mesh,
367+
Eigen::ConstRef<Eigen::MatrixXd> vertices,
368+
const double dhat) const
369+
{
370+
assert(vertices.rows() == mesh.num_vertices());
371+
if (empty()) {
372+
return std::numeric_limits<double>::infinity();
373+
}
374+
375+
const Eigen::MatrixXi& edges = mesh.edges();
376+
const Eigen::MatrixXi& faces = mesh.faces();
377+
const double dhat_sq = dhat * dhat;
378+
379+
// Thread-local storage: pair<sum_of_distances, count_of_distances>
380+
tbb::enumerable_thread_specific<std::pair<double, size_t>> storage{ {0.0, 0} };
381+
382+
tbb::parallel_for(
383+
tbb::blocked_range<size_t>(0, size()),
384+
[&](const tbb::blocked_range<size_t>& range) {
385+
auto& local = storage.local();
386+
double& sum = local.first;
387+
size_t& count = local.second;
388+
389+
for (size_t i = range.begin(); i != range.end(); ++i) {
390+
const double dist = (*this)[i].compute_distance(
391+
(*this)[i].dof(vertices, edges, faces));
392+
393+
// only accumulate those within threshold
394+
if (dist <= dhat_sq) {
395+
sum += dist;
396+
count += 1;
397+
}
398+
}
399+
}
400+
);
401+
402+
// Combine sums and counts from all threads
403+
const auto total = storage.combine(
404+
[](const std::pair<double, size_t>& a, const std::pair<double, size_t>& b) {
405+
return std::make_pair(a.first + b.first, a.second + b.second);
406+
}
407+
);
408+
409+
const double overall_sum = total.first;
410+
const size_t overall_count = total.second;
411+
412+
if (overall_count == 0) {
413+
return std::numeric_limits<double>::infinity();
414+
}
415+
return overall_sum / static_cast<double>(overall_count);
416+
}
417+
418+
// ============================================================================
364419
size_t NormalCollisions::size() const
365420
{
366421
return vv_collisions.size() + ev_collisions.size() + ee_collisions.size()

src/ipc/collisions/normal/normal_collisions.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ class NormalCollisions {
6060
const CollisionMesh& mesh,
6161
Eigen::ConstRef<Eigen::MatrixXd> vertices) const;
6262

63+
/// @returns The avg distance between any non-adjacent elements less than dhat.
64+
double compute_avg_distance(
65+
const CollisionMesh& mesh, Eigen::ConstRef<Eigen::MatrixXd> vertices, const double dhat) const;
66+
6367
// ------------------------------------------------------------------------
6468

6569
/// @brief Get the number of collisions.

0 commit comments

Comments
 (0)