Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/ipc/candidates/candidates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <ipc/distance/point_plane.hpp>
#include <ipc/distance/point_point.hpp>
#include <ipc/utils/eigen_ext.hpp>
#include <ipc/utils/profiler.hpp>
#include <ipc/utils/save_obj.hpp>

#include <igl/remove_unreferenced.h>
Expand Down Expand Up @@ -45,6 +46,8 @@ void Candidates::build(
const double inflation_radius,
BroadPhase* broad_phase)
{
IPC_TOOLKIT_PROFILE_BLOCK("Candidates::build(static)");

std::unique_ptr<BroadPhase> default_broad_phase;
if (broad_phase == nullptr) {
default_broad_phase = make_default_broad_phase();
Expand Down Expand Up @@ -130,6 +133,8 @@ void Candidates::build(
const double inflation_radius,
BroadPhase* broad_phase)
{
IPC_TOOLKIT_PROFILE_BLOCK("Candidates::build(dynamic)");

std::unique_ptr<BroadPhase> default_broad_phase;
if (broad_phase == nullptr) {
default_broad_phase = make_default_broad_phase();
Expand Down Expand Up @@ -255,6 +260,7 @@ double Candidates::compute_collision_free_stepsize(
{
assert(vertices_t0.rows() == mesh.num_vertices());
assert(vertices_t1.rows() == mesh.num_vertices());
IPC_TOOLKIT_PROFILE_BLOCK("Candidates::compute_collision_free_stepsize");

if (empty()) {
return 1; // No possible collisions, so can take full step.
Expand Down
3 changes: 3 additions & 0 deletions src/ipc/collisions/normal/normal_collisions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <ipc/collisions/normal/normal_collisions_builder.hpp>
#include <ipc/utils/local_to_global.hpp>
#include <ipc/utils/profiler.hpp>

#include <tbb/blocked_range.h>
#include <tbb/enumerable_thread_specific.h>
Expand All @@ -24,6 +25,7 @@ void NormalCollisions::build(
BroadPhase* broad_phase)
{
assert(vertices.rows() == mesh.num_vertices());
IPC_TOOLKIT_PROFILE_BLOCK("NormalCollisions::build");

const double inflation_radius = 0.5 * (dhat + dmin);

Expand All @@ -41,6 +43,7 @@ void NormalCollisions::build(
const double dmin)
{
assert(vertices.rows() == mesh.num_vertices());
IPC_TOOLKIT_PROFILE_BLOCK("NormalCollisions::build(candidates)");

clear();

Expand Down
3 changes: 3 additions & 0 deletions src/ipc/collisions/tangential/tangential_collisions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <ipc/distance/edge_edge_mollifier.hpp>
#include <ipc/friction/smooth_mu.hpp>
#include <ipc/utils/local_to_global.hpp>
#include <ipc/utils/profiler.hpp>

#include <tbb/blocked_range.h>
#include <tbb/enumerable_thread_specific.h>
Expand Down Expand Up @@ -69,6 +70,7 @@ void TangentialCollisions::build(
{
assert(mu_s.size() == vertices.rows());
assert(mu_k.size() == vertices.rows());
IPC_TOOLKIT_PROFILE_BLOCK("TangentialCollisions::build");

const Eigen::MatrixXi& edges = mesh.edges();
const Eigen::MatrixXi& faces = mesh.faces();
Expand Down Expand Up @@ -180,6 +182,7 @@ void TangentialCollisions::build(
{
assert(mu_k.size() == vertices.rows());
assert(mu_s.size() == vertices.rows());
IPC_TOOLKIT_PROFILE_BLOCK("TangentialCollisions::build(smooth)");

const Eigen::MatrixXi& edges = mesh.edges();
const Eigen::MatrixXi& faces = mesh.faces();
Expand Down
5 changes: 5 additions & 0 deletions src/ipc/ipc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <scalable_ccd/cuda/ipc_ccd_strategy.hpp>
#endif

#include <ipc/utils/profiler.hpp>

#include <igl/predicates/segment_segment_intersect.h>

namespace ipc {
Expand All @@ -25,6 +27,7 @@ bool is_step_collision_free(
{
assert(vertices_t0.rows() == mesh.num_vertices());
assert(vertices_t1.rows() == mesh.num_vertices());
IPC_TOOLKIT_PROFILE_BLOCK("is_step_collision_free");

// Broad phase
Candidates candidates;
Expand All @@ -49,6 +52,7 @@ double compute_collision_free_stepsize(
{
assert(vertices_t0.rows() == mesh.num_vertices());
assert(vertices_t1.rows() == mesh.num_vertices());
IPC_TOOLKIT_PROFILE_BLOCK("compute_collision_free_stepsize");

std::unique_ptr<BroadPhase> default_broad_phase;
if (broad_phase == nullptr) {
Expand Down Expand Up @@ -104,6 +108,7 @@ bool has_intersections(
BroadPhase* broad_phase)
{
assert(vertices.rows() == mesh.num_vertices());
IPC_TOOLKIT_PROFILE_BLOCK("has_intersections");

std::unique_ptr<BroadPhase> default_broad_phase;
if (broad_phase == nullptr) {
Expand Down
2 changes: 2 additions & 0 deletions src/ipc/potentials/barrier_potential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ class BarrierPotential : public NormalPotential {
m_barrier = barrier;
}

std::string name() const override { return "BarrierPotential"; }

using Super::operator();
using Super::gradient;
using Super::hessian;
Expand Down
2 changes: 2 additions & 0 deletions src/ipc/potentials/friction_potential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class FrictionPotential : public TangentialPotential {
m_eps_v = eps_v;
}

std::string name() const override { return "FrictionPotential"; }

protected:
/// @brief Compute the value of the ∫ μ(y) f₁(y) dy, where f₁ is the first derivative of the smooth mollifier.
/// @param x The tangential relative speed.
Expand Down
2 changes: 2 additions & 0 deletions src/ipc/potentials/normal_adhesion_potential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class NormalAdhesionPotential : public NormalPotential {
const double _Y,
const double _eps_c);

std::string name() const override { return "NormalAdhesionPotential"; }

using Super::operator();
using Super::gradient;
using Super::hessian;
Expand Down
119 changes: 76 additions & 43 deletions src/ipc/potentials/potential.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <ipc/collisions/normal/normal_collisions.hpp>
#include <ipc/collisions/tangential/tangential_collisions.hpp>
#include <ipc/utils/local_to_global.hpp>
#include <ipc/utils/profiler.hpp>

#include <tbb/blocked_range.h>
#include <tbb/combinable.h>
Expand Down Expand Up @@ -39,6 +40,7 @@ double Potential<TCollisions>::operator()(
Eigen::ConstRef<Eigen::MatrixXd> X) const
{
assert(X.rows() == mesh.num_vertices());
IPC_TOOLKIT_PROFILE_BLOCK(this->name() + "::operator()");

return tbb::parallel_reduce(
tbb::blocked_range<size_t>(size_t(0), collisions.size()), 0.0,
Expand All @@ -61,6 +63,7 @@ Eigen::VectorXd Potential<TCollisions>::gradient(
Eigen::ConstRef<Eigen::MatrixXd> X) const
{
assert(X.rows() == mesh.num_vertices());
IPC_TOOLKIT_PROFILE_BLOCK(this->name() + "::gradient()");

if (collisions.empty()) {
return Eigen::VectorXd::Zero(X.size());
Expand All @@ -70,20 +73,25 @@ Eigen::VectorXd Potential<TCollisions>::gradient(

tbb::combinable<Eigen::VectorXd> grad(Eigen::VectorXd::Zero(X.size()));

tbb::parallel_for(size_t(0), collisions.size(), [&](size_t i) {
const TCollision& collision = collisions[i];
{
IPC_TOOLKIT_PROFILE_BLOCK("compute local gradients");
tbb::parallel_for(size_t(0), collisions.size(), [&](size_t i) {
const TCollision& collision = collisions[i];

const VectorMaxNd local_grad = this->gradient(
collision, collision.dof(X, mesh.edges(), mesh.faces()));
const VectorMaxNd local_grad = this->gradient(
collision, collision.dof(X, mesh.edges(), mesh.faces()));

local_gradient_to_global_gradient(
local_grad, collision.vertex_ids(mesh.edges(), mesh.faces()), dim,
grad.local());
});
local_gradient_to_global_gradient(
local_grad, collision.vertex_ids(mesh.edges(), mesh.faces()),
dim, grad.local());
});
}

return grad.combine([](const Eigen::VectorXd& a, const Eigen::VectorXd& b) {
return a + b;
});
{
IPC_TOOLKIT_PROFILE_BLOCK("combine local gradients");
return grad.combine([](const Eigen::VectorXd& a,
const Eigen::VectorXd& b) { return a + b; });
}
}

template <class TCollisions>
Expand All @@ -94,6 +102,7 @@ Eigen::SparseMatrix<double> Potential<TCollisions>::hessian(
const PSDProjectionMethod project_hessian_to_psd) const
{
assert(X.rows() == mesh.num_vertices());
IPC_TOOLKIT_PROFILE_BLOCK(this->name() + "::hessian()");

if (collisions.empty()) {
return Eigen::SparseMatrix<double>(X.size(), X.size());
Expand All @@ -111,30 +120,43 @@ Eigen::SparseMatrix<double> Potential<TCollisions>::hessian(
tbb::enumerable_thread_specific<LocalThreadMatStorage> storage(
LocalThreadMatStorage(buffer_size, ndof, ndof));

tbb::parallel_for(size_t(0), collisions.size(), [&](size_t i) {
auto& hess_triplets = storage.local();

const TCollision& collision = collisions[i];

const MatrixMaxNd local_hess = this->hessian(
collisions[i], collisions[i].dof(X, edges, faces),
project_hessian_to_psd);

local_hessian_to_global_triplets(
local_hess, collision.vertex_ids(edges, faces), dim,
*(hess_triplets.cache), mesh.num_vertices());
});
{
IPC_TOOLKIT_PROFILE_BLOCK("compute local hessians and triplets");
tbb::parallel_for(size_t(0), collisions.size(), [&](size_t i) {
auto& hess_triplets = storage.local();

const TCollision& collision = collisions[i];

MatrixMaxNd local_hess;
{
IPC_TOOLKIT_PROFILE_BLOCK("compute local hessian");
local_hess = this->hessian(
collision, collision.dof(X, edges, faces),
project_hessian_to_psd);
}

{
IPC_TOOLKIT_PROFILE_BLOCK(
"map local hessian to global triplets");
local_hessian_to_global_triplets(
local_hess, collision.vertex_ids(edges, faces), dim,
*(hess_triplets.cache), mesh.num_vertices());
}
Comment thread
zfergus marked this conversation as resolved.
});
}
if (storage.empty()) {
return Eigen::SparseMatrix<double>();
}

// Assemble the stiffness matrix by concatenating the tuples in each local
// storage

tbb::parallel_for_each(
storage.begin(), storage.end(),
[](const auto& local_storage) { local_storage.cache->prune(); });
{
IPC_TOOLKIT_PROFILE_BLOCK("prune local storages");
tbb::parallel_for_each(
storage.begin(), storage.end(),
[](const auto& local_storage) { local_storage.cache->prune(); });
}

// Prepares for parallel concatenation
std::vector<size_t> offsets(storage.size());
Expand Down Expand Up @@ -164,26 +186,37 @@ Eigen::SparseMatrix<double> Potential<TCollisions>::hessian(
return hess;
}

triplets.resize(triplet_count);
// Allocate triplets
{
IPC_TOOLKIT_PROFILE_BLOCK("allocate triplets");
triplets.resize(triplet_count);
}

// Parallel copy into triplets
tbb::parallel_for(size_t(0), storage.size(), [&](size_t i) {
const SparseMatrixCache& cache = dynamic_cast<const SparseMatrixCache&>(
*((storage.begin() + i)->cache));
size_t offset = offsets[i];

std::copy(
cache.entries().begin(), cache.entries().end(),
triplets.begin() + offset);
offset += cache.entries().size();

if (cache.mat().nonZeros() > 0) {
set_triplets(cache.mat(), triplets, offset);
}
});
{
IPC_TOOLKIT_PROFILE_BLOCK("parallel copy into triplets");
tbb::parallel_for(size_t(0), storage.size(), [&](size_t i) {
const SparseMatrixCache& cache =
dynamic_cast<const SparseMatrixCache&>(
*((storage.begin() + i)->cache));
size_t offset = offsets[i];

std::copy(
cache.entries().begin(), cache.entries().end(),
triplets.begin() + offset);
offset += cache.entries().size();

if (cache.mat().nonZeros() > 0) {
set_triplets(cache.mat(), triplets, offset);
}
});
}

// Sort and assemble
hess.setFromTriplets(triplets.begin(), triplets.end());
{
IPC_TOOLKIT_PROFILE_BLOCK("assemble hessian from triplets");
hess.setFromTriplets(triplets.begin(), triplets.end());
}

return hess;
}
Expand Down
5 changes: 5 additions & 0 deletions src/ipc/potentials/potential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <ipc/collision_mesh.hpp>
#include <ipc/utils/eigen_ext.hpp>

#include <string>

namespace ipc {

/// @brief Base class for potentials.
Expand All @@ -19,6 +21,9 @@ template <class TCollisions> class Potential {
Potential() = default;
virtual ~Potential() = default;

/// @brief The name of this potential (used for profiling).
virtual std::string name() const = 0;

Comment thread
zfergus marked this conversation as resolved.
// -- Cumulative methods ---------------------------------------------------

/// @brief Compute the potential for a set of collisions.
Expand Down
2 changes: 2 additions & 0 deletions src/ipc/potentials/tangential_adhesion_potential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class TangentialAdhesionPotential : public TangentialPotential {
m_eps_a = eps_a;
}

std::string name() const override { return "TangentialAdhesionPotential"; }

protected:
/// @brief Compute the value of the ∫ μ(y) f₁(y) dy, where f₁ is the first derivative of the smooth mollifier.
/// @param x The tangential relative speed.
Expand Down
Loading
Loading