diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index f6499c5cd..8f1f97706 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -2,16 +2,16 @@ name: PyPi Release on: workflow_dispatch: - release: - types: [published] - push: - branches: - - pypi - - main - - python - pull_request: - branches: - - main + # release: + # types: [published] + # push: + # branches: + # - pypi + # - main + # - python + # pull_request: + # branches: + # - main jobs: build_wheels: diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 30b1a5afa..0c8643212 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -307,7 +307,7 @@ Added Changed ^^^^^^^ -* Changed CMake target name to :cmake:`ipc::toolkit` +* Changed CMake target name to ``ipc::toolkit`` 2021-07-26 (`1479aae `__) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -317,7 +317,7 @@ Changed Changed ^^^^^^^ -* Updated the CMake system to use modern :cpp:`FetchContent` to download externals +* Updated the CMake system to use modern ``FetchContent`` to download externals 2021-07-22 (`e24c76d `__) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -414,7 +414,7 @@ Changed ^^^^^^^ * :cpp:`ignore_codimensional_vertices` to :cpp:`false` by default -* CMake option :cmake:`TIGHT_INCLUSION_WITH_NO_ZERO_TOI=ON` as default +* CMake option ``TIGHT_INCLUSION_WITH_NO_ZERO_TOI=ON`` as default 2021-06-18 (`aa59aeb `__) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/conf.py b/docs/source/conf.py index 2bc86127b..4a1fb69ad 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -21,7 +21,10 @@ # -- Project information ----------------------------------------------------- from datetime import datetime -import ipctk + +import sys +sys.path.append(str(pathlib.Path(__file__).parents[2] / "python")) +from _find_ipctk import ipctk # noqa project = "IPC Toolkit" copyright = f'2020-{datetime.now().year}, IPC-Sim Organization; MIT License' diff --git a/docs/source/cpp-api/barrier.rst b/docs/source/cpp-api/barrier.rst index ebebc2851..99dadc633 100644 --- a/docs/source/cpp-api/barrier.rst +++ b/docs/source/cpp-api/barrier.rst @@ -20,7 +20,7 @@ Adaptive Barrier Stiffness Semi-Implicit Stiffness ~~~~~~~~~~~~~~~~~~~~~~~ -.. doxygenfunction:: ipc::semi_implicit_stiffness(const CollisionMesh&, const Eigen::MatrixXd&, const StencilsT&, const Eigen::VectorXd&, const Eigen::SparseMatrix&, const double) +.. doxygenfunction:: ipc::semi_implicit_stiffness(const CollisionMesh&, Eigen::ConstRef, const StencilsT&, Eigen::ConstRef, const Eigen::SparseMatrix&, const double) Barrier Class ------------- @@ -34,10 +34,10 @@ Clamped Log Barrier .. doxygenclass:: ipc::ClampedLogBarrier :allow-dot-graphs: -Normalized Clamped Log Barrier -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Normalized Barrier +~~~~~~~~~~~~~~~~~~ -.. doxygenclass:: ipc::NormalizedClampedLogBarrier +.. doxygenclass:: ipc::NormalizedBarrier :allow-dot-graphs: Clamped Log Squared Barrier diff --git a/docs/source/cpp-api/distance.rst b/docs/source/cpp-api/distance.rst index debbb70d7..381a00dac 100644 --- a/docs/source/cpp-api/distance.rst +++ b/docs/source/cpp-api/distance.rst @@ -19,11 +19,11 @@ Edge-Edge Mollifier .. doxygenfunction:: edge_edge_cross_squarednorm .. doxygenfunction:: ipc::edge_edge_cross_squarednorm_gradient .. doxygenfunction:: ipc::edge_edge_cross_squarednorm_hessian -.. doxygenfunction:: edge_edge_mollifier(const Eigen::Ref& ea0, const Eigen::Ref& ea1, const Eigen::Ref& eb0, const Eigen::Ref& eb1, const double eps_x) +.. doxygenfunction:: edge_edge_mollifier(Eigen::ConstRef ea0, Eigen::ConstRef ea1, Eigen::ConstRef eb0, Eigen::ConstRef eb1, const double eps_x) .. doxygenfunction:: edge_edge_mollifier(const double x, const double eps_x) -.. doxygenfunction:: edge_edge_mollifier_gradient(const Eigen::Ref& ea0, const Eigen::Ref& ea1, const Eigen::Ref& eb0, const Eigen::Ref& eb1, const double eps_x) +.. doxygenfunction:: edge_edge_mollifier_gradient(Eigen::ConstRef ea0, Eigen::ConstRef ea1, Eigen::ConstRef eb0, Eigen::ConstRef eb1, const double eps_x) .. doxygenfunction:: edge_edge_mollifier_gradient(const double x, const double eps_x) -.. doxygenfunction:: edge_edge_mollifier_hessian(const Eigen::Ref& ea0, const Eigen::Ref& ea1, const Eigen::Ref& eb0, const Eigen::Ref& eb1, const double eps_x) +.. doxygenfunction:: edge_edge_mollifier_hessian(Eigen::ConstRef ea0, Eigen::ConstRef ea1, Eigen::ConstRef eb0, Eigen::ConstRef eb1, const double eps_x) .. doxygenfunction:: edge_edge_mollifier_hessian(const double x, const double eps_x) Edge-Edge @@ -57,12 +57,12 @@ Point-Line Point-Plane ----------- -.. doxygenfunction:: point_plane_distance(const Eigen::Ref& p, const Eigen::Ref& origin, const Eigen::Ref& normal) -.. doxygenfunction:: point_plane_distance(const Eigen::Ref& p, const Eigen::Ref& t0, const Eigen::Ref& t1, const Eigen::Ref& t2) -.. doxygenfunction:: point_plane_distance_gradient(const Eigen::Ref& p, const Eigen::Ref& origin, const Eigen::Ref& normal) -.. doxygenfunction:: point_plane_distance_gradient(const Eigen::Ref& p, const Eigen::Ref& t0, const Eigen::Ref& t1, const Eigen::Ref& t2) -.. doxygenfunction:: point_plane_distance_hessian(const Eigen::Ref& p, const Eigen::Ref& origin, const Eigen::Ref& normal) -.. doxygenfunction:: point_plane_distance_hessian(const Eigen::Ref& p, const Eigen::Ref& t0, const Eigen::Ref& t1, const Eigen::Ref& t2) +.. doxygenfunction:: point_plane_distance(Eigen::ConstRef p, Eigen::ConstRef origin, Eigen::ConstRef normal) +.. doxygenfunction:: point_plane_distance(Eigen::ConstRef p, Eigen::ConstRef t0, Eigen::ConstRef t1, Eigen::ConstRef t2) +.. doxygenfunction:: point_plane_distance_gradient(Eigen::ConstRef p, Eigen::ConstRef origin, Eigen::ConstRef normal) +.. doxygenfunction:: point_plane_distance_gradient(Eigen::ConstRef p, Eigen::ConstRef t0, Eigen::ConstRef t1, Eigen::ConstRef t2) +.. doxygenfunction:: point_plane_distance_hessian(Eigen::ConstRef p, Eigen::ConstRef origin, Eigen::ConstRef normal) +.. doxygenfunction:: point_plane_distance_hessian(Eigen::ConstRef p, Eigen::ConstRef t0, Eigen::ConstRef t1, Eigen::ConstRef t2) Point-Point ----------- diff --git a/docs/source/cpp.rst b/docs/source/cpp.rst index 1c6ab6331..74b5b2bf1 100644 --- a/docs/source/cpp.rst +++ b/docs/source/cpp.rst @@ -24,7 +24,7 @@ C++ :end-before: .. tip:: - If your :cmake:`IPC_TOOLKIT_GIT_TAG` is a tag (e.g. ``v1.3.1``), then you can use the :cmake:`FetchContent_Declare` argument :cmake:`GIT_SHALLOW TRUE` to download only a single commit. Otherwise, you should use the default :cmake:`GIT_SHALLOW FALSE`. + If your ``IPC_TOOLKIT_GIT_TAG`` is a tag (e.g. ``v1.3.1``), then you can use the ``FetchContent_Declare`` argument ``GIT_SHALLOW TRUE`` to download only a single commit. Otherwise, you should use the default ``GIT_SHALLOW FALSE``. .. include:: ../../README.md :parser: myst_parser.sphinx_ @@ -34,7 +34,7 @@ C++ .. _filib_dependency_note: .. warning:: - ``filib`` is licensed under `LGPL-2.1 `_ and as such it is required to be dynamically linked. Doing so automatically is a challenge, so by default we use static linkage. Enabling dynaic linkage requires copying the ``.so``/``.dylib``/``.dll`` file to the binary directory or system path. To enable this, set the CMake option :cmake:`FILIB_BUILD_SHARED_LIBS` to :cmake:`ON` and add this CMake code to copy the shared libaray object to the binary directory: + ``filib`` is licensed under `LGPL-2.1 `_ and as such it is required to be dynamically linked. Doing so automatically is a challenge, so by default we use static linkage. Enabling dynaic linkage requires copying the ``.so``/``.dylib``/``.dll`` file to the binary directory or system path. To enable this, set the CMake option ``FILIB_BUILD_SHARED_LIBS`` to ``ON`` and add this CMake code to copy the shared libaray object to the binary directory: .. code-block:: cmake @@ -47,7 +47,7 @@ C++ where ``${MY_EXE_TARGET}`` is the name of your executable target. If you know a better way to handle this, please `let us know `_! - If you would rather avoid LGPL code entirely, you can disable filib by setting :cmake:`IPC_TOOLKIT_WITH_FILIB` to :cmake:`OFF`. With this option disabled, CMake will not download or use any of filib's code. + If you would rather avoid LGPL code entirely, you can disable filib by setting ``IPC_TOOLKIT_WITH_FILIB`` to ``OFF``. With this option disabled, CMake will not download or use any of filib's code. .. include:: ../../README.md :parser: myst_parser.sphinx_ diff --git a/docs/source/tutorial/faq.rst b/docs/source/tutorial/faq.rst index 07a8ecb99..0878103da 100644 --- a/docs/source/tutorial/faq.rst +++ b/docs/source/tutorial/faq.rst @@ -13,7 +13,7 @@ Frequently Asked Questions How do I include IPC Toolkit in my project? ------------------------------------------- -If you are using CMake, the public include directory is added to the :cmake:`ipc::toolkit` cmake target which means that any lib/bin that includes :cmake:`ipc::toolkit` as a dependency also adds those include directories too. +If you are using CMake, the public include directory is added to the `ipc::toolkit` cmake target which means that any lib/bin that includes `ipc::toolkit` as a dependency also adds those include directories too. If you are not using CMake, the include path is ``src``. diff --git a/docs/source/tutorial/nonlinear_ccd.rst b/docs/source/tutorial/nonlinear_ccd.rst index 93d69be93..1fc150100 100644 --- a/docs/source/tutorial/nonlinear_ccd.rst +++ b/docs/source/tutorial/nonlinear_ccd.rst @@ -57,7 +57,8 @@ Let's dive deeper by breaking down the implementation of ``Rigid2DTrajectory``. .. literalinclude:: ../../../tests/src/tests/ccd/test_nonlinear_ccd.cpp :language: c++ - :lines: 127-134 + :start-after: // BEGIN_RIGID_2D_CALL + :end-before: // END_RIGID_2D_CALL :dedent: 4 @@ -65,7 +66,8 @@ Let's dive deeper by breaking down the implementation of ``Rigid2DTrajectory``. .. literalinclude:: ../../../python/tests/test_ccd.py :language: python - :lines: 90-94 + :start-after: # BEGIN_RIGID_2D_CALL + :end-before: # END_RIGID_2D_CALL :dedent: 8 This function computes the position of the point at a time :math:`t \in [0, 1]`. This defines the trajectory of the point. In this case, we have a rigid body with a center of mass (COM) at the origin. The trajectory of the point is given by: @@ -87,14 +89,16 @@ The second function we need to implement is ``max_distance_from_linear``. .. literalinclude:: ../../../tests/src/tests/ccd/test_nonlinear_ccd.cpp :language: c++ - :lines: 136-147 + :start-after: // BEGIN_RIGID_2D_MAX_DISTANCE_FROM_LINEAR + :end-before: // END_RIGID_2D_MAX_DISTANCE_FROM_LINEAR :dedent: 4 .. md-tab-item:: Python .. literalinclude:: ../../../python/tests/test_ccd.py :language: python - :lines: 96-102 + :start-after: # BEGIN_RIGID_2D_MAX_DISTANCE_FROM_LINEAR + :end-before: # END_RIGID_2D_MAX_DISTANCE_FROM_LINEAR :dedent: 8 This function computes the maximum distance over a time interval :math:`[t_0, t_1]` between the nonlinear trajectory and a line segment from :math:`x(t_0)` to :math:`x(t_1)`. Mathematically this function computes diff --git a/notebooks/find_ipctk.py b/notebooks/find_ipctk.py index 36c5e0196..d774ff803 100644 --- a/notebooks/find_ipctk.py +++ b/notebooks/find_ipctk.py @@ -1,20 +1,4 @@ -try: - import ipctk # Try to import the built module -except ImportError: - import sys - import pathlib - repo_root = pathlib.Path(__file__).parents[1] - possible_paths = [ - pathlib.Path("python").resolve(), - repo_root / "build" / "python", - repo_root / "build" / "release" / "python", - repo_root / "build" / "debug" / "python", - ] - for path in possible_paths: - if path.exists() and len(list(path.glob("ipctk.*"))) > 0: - sys.path.append(str(path)) - break - else: - raise ImportError("Could not find the ipctk module") - print(f"Using found ipctk module at {path}") - import ipctk # Try again +import sys +import pathlib +sys.path.append(str(pathlib.Path(__file__).parents[1] / "python")) +from _find_ipctk import ipctk # noqa diff --git a/python/_find_ipctk.py b/python/_find_ipctk.py new file mode 100644 index 000000000..36c5e0196 --- /dev/null +++ b/python/_find_ipctk.py @@ -0,0 +1,20 @@ +try: + import ipctk # Try to import the built module +except ImportError: + import sys + import pathlib + repo_root = pathlib.Path(__file__).parents[1] + possible_paths = [ + pathlib.Path("python").resolve(), + repo_root / "build" / "python", + repo_root / "build" / "release" / "python", + repo_root / "build" / "debug" / "python", + ] + for path in possible_paths: + if path.exists() and len(list(path.glob("ipctk.*"))) > 0: + sys.path.append(str(path)) + break + else: + raise ImportError("Could not find the ipctk module") + print(f"Using found ipctk module at {path}") + import ipctk # Try again diff --git a/python/src/adhesion/adhesion.cpp b/python/src/adhesion/adhesion.cpp index a3a4eebb1..cf6152f19 100644 --- a/python/src/adhesion/adhesion.cpp +++ b/python/src/adhesion/adhesion.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_adhesion(py::module_& m) @@ -21,7 +20,7 @@ void define_adhesion(py::module_& m) Returns: The normal adhesion potential. )ipc_Qu8mg5v7", - py::arg("d"), py::arg("dhat_p"), py::arg("dhat_a"), py::arg("a2")); + "d"_a, "dhat_p"_a, "dhat_a"_a, "a2"_a); m.def( "normal_adhesion_potential_first_derivative", @@ -38,7 +37,7 @@ void define_adhesion(py::module_& m) Returns: The first derivative of the normal adhesion potential wrt d. )ipc_Qu8mg5v7", - py::arg("d"), py::arg("dhat_p"), py::arg("dhat_a"), py::arg("a2")); + "d"_a, "dhat_p"_a, "dhat_a"_a, "a2"_a); m.def( "normal_adhesion_potential_second_derivative", @@ -55,7 +54,7 @@ void define_adhesion(py::module_& m) Returns: The second derivative of the normal adhesion potential wrt d. )ipc_Qu8mg5v7", - py::arg("d"), py::arg("dhat_p"), py::arg("dhat_a"), py::arg("a2")); + "d"_a, "dhat_p"_a, "dhat_a"_a, "a2"_a); m.def( "max_normal_adhesion_force_magnitude", @@ -71,7 +70,7 @@ void define_adhesion(py::module_& m) Returns: The maximum normal adhesion force magnitude. )ipc_Qu8mg5v7", - py::arg("dhat_p"), py::arg("dhat_a"), py::arg("a2")); + "dhat_p"_a, "dhat_a"_a, "a2"_a); m.def( "tangential_adhesion_f0", &tangential_adhesion_f0, @@ -85,7 +84,7 @@ void define_adhesion(py::module_& m) Returns: The tangential adhesion mollifier function at y. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_a")); + "y"_a, "eps_a"_a); m.def( "tangential_adhesion_f1", &tangential_adhesion_f1, @@ -99,7 +98,7 @@ void define_adhesion(py::module_& m) Returns: The first derivative of the tangential adhesion mollifier function at y. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_a")); + "y"_a, "eps_a"_a); m.def( "tangential_adhesion_f2", &tangential_adhesion_f2, @@ -113,7 +112,7 @@ void define_adhesion(py::module_& m) Returns: The second derivative of the tangential adhesion mollifier function at y. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_a")); + "y"_a, "eps_a"_a); m.def( "tangential_adhesion_f1_over_x", &tangential_adhesion_f1_over_x, @@ -127,7 +126,7 @@ void define_adhesion(py::module_& m) Returns: The first derivative of the tangential adhesion mollifier function divided by y. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_a")); + "y"_a, "eps_a"_a); m.def( "tangential_adhesion_f2_x_minus_f1_over_x3", @@ -142,5 +141,5 @@ void define_adhesion(py::module_& m) Returns: The second derivative of the tangential adhesion mollifier function times y minus the first derivative all divided by y cubed. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_a")); + "y"_a, "eps_a"_a); } diff --git a/python/src/adhesion/bindings.hpp b/python/src/adhesion/bindings.hpp index 5260974cc..b357b74e7 100644 --- a/python/src/adhesion/bindings.hpp +++ b/python/src/adhesion/bindings.hpp @@ -2,6 +2,4 @@ #include -namespace py = pybind11; - void define_adhesion(py::module_& m); \ No newline at end of file diff --git a/python/src/barrier/adaptive_stiffness.cpp b/python/src/barrier/adaptive_stiffness.cpp index 3057e927c..93e8b4cfa 100644 --- a/python/src/barrier/adaptive_stiffness.cpp +++ b/python/src/barrier/adaptive_stiffness.cpp @@ -4,7 +4,6 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_adaptive_stiffness(py::module_& m) @@ -42,10 +41,9 @@ void define_adaptive_stiffness(py::module_& m) The initial barrier stiffness. Maximum stiffness of the barrier. )ipc_Qu8mg5v7", - py::arg("bbox_diagonal"), py::arg("barrier"), py::arg("dhat"), - py::arg("average_mass"), py::arg("grad_energy"), - py::arg("grad_barrier"), py::arg("min_barrier_stiffness_scale") = 1e11, - py::arg("dmin") = 0); + "bbox_diagonal"_a, "barrier"_a, "dhat"_a, "average_mass"_a, + "grad_energy"_a, "grad_barrier"_a, + "min_barrier_stiffness_scale"_a = 1e11, "dmin"_a = 0); m.def( "update_barrier_stiffness", &update_barrier_stiffness, @@ -64,15 +62,14 @@ void define_adaptive_stiffness(py::module_& m) Returns: The updated barrier stiffness. )ipc_Qu8mg5v7", - py::arg("prev_min_distance"), py::arg("min_distance"), - py::arg("max_barrier_stiffness"), py::arg("barrier_stiffness"), - py::arg("bbox_diagonal"), py::arg("dhat_epsilon_scale") = 1e-9, - py::arg("dmin") = 0); + "prev_min_distance"_a, "min_distance"_a, "max_barrier_stiffness"_a, + "barrier_stiffness"_a, "bbox_diagonal"_a, "dhat_epsilon_scale"_a = 1e-9, + "dmin"_a = 0); m.def( "semi_implicit_stiffness", static_cast&, Eigen::ConstRef, + const CollisionStencil&, Eigen::ConstRef, Eigen::ConstRef, Eigen::ConstRef, const double)>(&semi_implicit_stiffness), R"ipc_Qu8mg5v7( @@ -91,8 +88,7 @@ void define_adaptive_stiffness(py::module_& m) Returns: The semi-implicit stiffness. )ipc_Qu8mg5v7", - py::arg("stencil"), py::arg("vertices"), py::arg("mass"), - py::arg("local_hess"), py::arg("dmin")); + "stencil"_a, "vertices"_a, "mass"_a, "local_hess"_a, "dmin"_a); m.def( "semi_implicit_stiffness", @@ -117,8 +113,8 @@ void define_adaptive_stiffness(py::module_& m) Returns: The semi-implicit stiffness's. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices"), py::arg("collisions"), - py::arg("vertex_masses"), py::arg("hess"), py::arg("dmin")); + "mesh"_a, "vertices"_a, "collisions"_a, "vertex_masses"_a, "hess"_a, + "dmin"_a); m.def( "semi_implicit_stiffness", @@ -143,6 +139,6 @@ void define_adaptive_stiffness(py::module_& m) Returns: The semi-implicit stiffness's. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices"), py::arg("collisions"), - py::arg("vertex_masses"), py::arg("hess"), py::arg("dmin")); + "mesh"_a, "vertices"_a, "collisions"_a, "vertex_masses"_a, "hess"_a, + "dmin"_a); } diff --git a/python/src/barrier/barrier.cpp b/python/src/barrier/barrier.cpp index 6f34817f8..d0c930a27 100644 --- a/python/src/barrier/barrier.cpp +++ b/python/src/barrier/barrier.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; class PyBarrier : public Barrier { @@ -21,7 +20,7 @@ void define_barrier(py::module_& m) py::class_>(m, "Barrier") .def(py::init<>()) .def( - "__call__", &Barrier::operator(), py::arg("d"), py::arg("dhat"), + "__call__", &Barrier::operator(), "d"_a, "dhat"_a, R"ipc_Qu8mg5v7( Evaluate the barrier function. @@ -33,8 +32,7 @@ void define_barrier(py::module_& m) The value of the barrier function at d. )ipc_Qu8mg5v7") .def( - "first_derivative", &Barrier::first_derivative, py::arg("d"), - py::arg("dhat"), + "first_derivative", &Barrier::first_derivative, "d"_a, "dhat"_a, R"ipc_Qu8mg5v7( Evaluate the first derivative of the barrier function wrt d. @@ -46,8 +44,7 @@ void define_barrier(py::module_& m) The value of the first derivative of the barrier function at d. )ipc_Qu8mg5v7") .def( - "second_derivative", &Barrier::second_derivative, py::arg("d"), - py::arg("dhat"), + "second_derivative", &Barrier::second_derivative, "d"_a, "dhat"_a, R"ipc_Qu8mg5v7( Evaluate the second derivative of the barrier function wrt d. @@ -59,7 +56,7 @@ void define_barrier(py::module_& m) The value of the second derivative of the barrier function at d. )ipc_Qu8mg5v7") .def( - "units", &Barrier::units, py::arg("dhat"), + "units", &Barrier::units, "dhat"_a, R"ipc_Qu8mg5v7( Get the units of the barrier function. @@ -121,7 +118,7 @@ void define_barrier(py::module_& m) .def(py::init()); m.def( - "barrier", &barrier, + "barrier", &barrier, "d"_a, "dhat"_a, R"ipc_Qu8mg5v7( Function that grows to infinity as d approaches 0 from the right. @@ -135,11 +132,10 @@ void define_barrier(py::module_& m) Returns: The value of the barrier function at d. - )ipc_Qu8mg5v7", - py::arg("d"), py::arg("dhat")); + )ipc_Qu8mg5v7"); m.def( - "barrier_first_derivative", &barrier_first_derivative, + "barrier_first_derivative", &barrier_first_derivative, "d"_a, "dhat"_a, R"ipc_Qu8mg5v7( Derivative of the barrier function. @@ -154,11 +150,11 @@ void define_barrier(py::module_& m) Returns: The derivative of the barrier wrt d. - )ipc_Qu8mg5v7", - py::arg("d"), py::arg("dhat")); + )ipc_Qu8mg5v7"); m.def( - "barrier_second_derivative", &barrier_second_derivative, + "barrier_second_derivative", &barrier_second_derivative, "d"_a, + "dhat"_a, R"ipc_Qu8mg5v7( Second derivative of the barrier function. @@ -173,6 +169,5 @@ void define_barrier(py::module_& m) Returns: The second derivative of the barrier wrt d. - )ipc_Qu8mg5v7", - py::arg("d"), py::arg("dhat")); + )ipc_Qu8mg5v7"); } diff --git a/python/src/barrier/barrier_force_magnitude.cpp b/python/src/barrier/barrier_force_magnitude.cpp index 556af8f5c..05617d712 100644 --- a/python/src/barrier/barrier_force_magnitude.cpp +++ b/python/src/barrier/barrier_force_magnitude.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_barrier_force_magnitude(py::module_& m) @@ -22,8 +21,8 @@ void define_barrier_force_magnitude(py::module_& m) Returns: The magnitude of the force. )ipc_Qu8mg5v7", - py::arg("distance_squared"), py::arg("barrier"), py::arg("dhat"), - py::arg("barrier_stiffness"), py::arg("dmin") = 0); + "distance_squared"_a, "barrier"_a, "dhat"_a, "barrier_stiffness"_a, + "dmin"_a = 0); m.def( "barrier_force_magnitude_gradient", &barrier_force_magnitude_gradient, @@ -41,7 +40,6 @@ void define_barrier_force_magnitude(py::module_& m) Returns: The gradient of the force. )ipc_Qu8mg5v7", - py::arg("distance_squared"), py::arg("distance_squared_gradient"), - py::arg("barrier"), py::arg("dhat"), py::arg("barrier_stiffness"), - py::arg("dmin") = 0); + "distance_squared"_a, "distance_squared_gradient"_a, "barrier"_a, + "dhat"_a, "barrier_stiffness"_a, "dmin"_a = 0); } diff --git a/python/src/barrier/bindings.hpp b/python/src/barrier/bindings.hpp index e3076f095..b614945f0 100644 --- a/python/src/barrier/bindings.hpp +++ b/python/src/barrier/bindings.hpp @@ -2,8 +2,6 @@ #include -namespace py = pybind11; - void define_adaptive_stiffness(py::module_& m); void define_barrier_force_magnitude(py::module_& m); void define_barrier(py::module_& m); \ No newline at end of file diff --git a/python/src/bindings.cpp b/python/src/bindings.cpp index ace6f08de..c65f0d4dd 100644 --- a/python/src/bindings.cpp +++ b/python/src/bindings.cpp @@ -1,8 +1,6 @@ #include #include -namespace py = pybind11; - PYBIND11_MODULE(ipctk, m) { // py::options options; diff --git a/python/src/bindings.hpp b/python/src/bindings.hpp index 5edc63ee9..a680b4f14 100644 --- a/python/src/bindings.hpp +++ b/python/src/bindings.hpp @@ -15,7 +15,5 @@ #include -namespace py = pybind11; - void define_collision_mesh(py::module_& m); void define_ipc(py::module_& m); \ No newline at end of file diff --git a/python/src/broad_phase/aabb.cpp b/python/src/broad_phase/aabb.cpp index f5d5b8902..b0d170468 100644 --- a/python/src/broad_phase/aabb.cpp +++ b/python/src/broad_phase/aabb.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_aabb(py::module_& m) @@ -12,13 +11,11 @@ void define_aabb(py::module_& m) .def( py::init< Eigen::ConstRef, Eigen::ConstRef>(), - py::arg("min"), py::arg("max")) + "min"_a, "max"_a) + .def(py::init(), "aabb1"_a, "aabb2"_a) .def( - py::init(), py::arg("aabb1"), - py::arg("aabb2")) - .def( - py::init(), py::arg("aabb1"), - py::arg("aabb2"), py::arg("aabb3")) + py::init(), "aabb1"_a, + "aabb2"_a, "aabb3"_a) .def_static( "from_point", py::overload_cast, const double>( @@ -33,7 +30,7 @@ void define_aabb(py::module_& m) Returns: The constructed AABB. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("inflation_radius") = 0) + "p"_a, "inflation_radius"_a = 0) .def_static( "from_point", py::overload_cast< @@ -50,7 +47,7 @@ void define_aabb(py::module_& m) Returns: The constructed AABB. )ipc_Qu8mg5v7", - py::arg("p_t0"), py::arg("p_t1"), py::arg("inflation_radius") = 0) + "p_t0"_a, "p_t1"_a, "inflation_radius"_a = 0) .def( "intersects", &AABB::intersects, R"ipc_Qu8mg5v7( @@ -62,15 +59,15 @@ void define_aabb(py::module_& m) Returns: If the two AABBs intersect. )ipc_Qu8mg5v7", - py::arg("other")) + "other"_a) .def_static( "conservative_inflation", [](ArrayMax3d min, ArrayMax3d max, const double inflation_radius) { AABB::conservative_inflation(min, max, inflation_radius); return std::make_tuple(min, max); }, - "Compute a conservative inflation of the AABB.", py::arg("min"), - py::arg("max"), py::arg("inflation_radius")) + "Compute a conservative inflation of the AABB.", "min"_a, "max"_a, + "inflation_radius"_a) .def_readwrite("min", &AABB::min, "Minimum corner of the AABB.") .def_readwrite("max", &AABB::max, "Maximum corner of the AABB.") .def_readwrite( @@ -95,7 +92,7 @@ void define_aabb(py::module_& m) Returns: Vertex AABBs. )ipc_Qu8mg5v7", - py::arg("vertices"), py::arg("inflation_radius") = 0); + "vertices"_a, "inflation_radius"_a = 0); m.def( "build_vertex_boxes", @@ -118,8 +115,7 @@ void define_aabb(py::module_& m) Returns: Vertex AABBs. )ipc_Qu8mg5v7", - py::arg("vertices_t0"), py::arg("vertices_t1"), - py::arg("inflation_radius") = 0); + "vertices_t0"_a, "vertices_t1"_a, "inflation_radius"_a = 0); m.def( "build_edge_boxes", @@ -139,7 +135,7 @@ void define_aabb(py::module_& m) Returns: edge_boxes: Edge AABBs. )ipc_Qu8mg5v7", - py::arg("vertex_boxes"), py::arg("edges")); + "vertex_boxes"_a, "edges"_a); m.def( "build_face_boxes", @@ -159,5 +155,5 @@ void define_aabb(py::module_& m) Returns: face_boxes: Face AABBs. )ipc_Qu8mg5v7", - py::arg("vertex_boxes"), py::arg("faces")); + "vertex_boxes"_a, "faces"_a); } diff --git a/python/src/broad_phase/bindings.hpp b/python/src/broad_phase/bindings.hpp index 185f98dd6..8718500d8 100644 --- a/python/src/broad_phase/bindings.hpp +++ b/python/src/broad_phase/bindings.hpp @@ -2,8 +2,6 @@ #include -namespace py = pybind11; - void define_aabb(py::module_& m); void define_broad_phase(py::module_& m); void define_brute_force(py::module_& m); diff --git a/python/src/broad_phase/broad_phase.cpp b/python/src/broad_phase/broad_phase.cpp index 8d8630dd7..8c483cf61 100644 --- a/python/src/broad_phase/broad_phase.cpp +++ b/python/src/broad_phase/broad_phase.cpp @@ -3,7 +3,6 @@ #include #include -namespace py = pybind11; using namespace ipc; class PyBroadPhase : public BroadPhase { @@ -146,8 +145,7 @@ void define_broad_phase(py::module_& m) faces: Collision mesh faces inflation_radius: Radius of inflation around all elements. )ipc_Qu8mg5v7", - py::arg("vertices"), py::arg("edges"), py::arg("faces"), - py::arg("inflation_radius") = 0) + "vertices"_a, "edges"_a, "faces"_a, "inflation_radius"_a = 0) .def( "build", py::overload_cast< @@ -166,8 +164,8 @@ void define_broad_phase(py::module_& m) faces: Collision mesh faces inflation_radius: Radius of inflation around all elements. )ipc_Qu8mg5v7", - py::arg("vertices_t0"), py::arg("vertices_t1"), py::arg("edges"), - py::arg("faces"), py::arg("inflation_radius") = 0) + "vertices_t0"_a, "vertices_t1"_a, "edges"_a, "faces"_a, + "inflation_radius"_a = 0) .def("clear", &BroadPhase::clear, "Clear any built data.") .def( "detect_vertex_vertex_candidates", @@ -261,7 +259,7 @@ void define_broad_phase(py::module_& m) dim: The dimension of the simulation (i.e., 2 or 3). candidates: The detected collision candidates. )ipc_Qu8mg5v7", - py::arg("dim")) + "dim"_a) .def_readwrite( "can_vertices_collide", &BroadPhase::can_vertices_collide, "Function for determining if two vertices can collide."); diff --git a/python/src/broad_phase/brute_force.cpp b/python/src/broad_phase/brute_force.cpp index d579eeaef..252348e36 100644 --- a/python/src/broad_phase/brute_force.cpp +++ b/python/src/broad_phase/brute_force.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_brute_force(py::module_& m) diff --git a/python/src/broad_phase/bvh.cpp b/python/src/broad_phase/bvh.cpp index c264d60ba..d2467f135 100644 --- a/python/src/broad_phase/bvh.cpp +++ b/python/src/broad_phase/bvh.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_bvh(py::module_& m) diff --git a/python/src/broad_phase/hash_grid.cpp b/python/src/broad_phase/hash_grid.cpp index 3a79457bc..e160ab0e7 100644 --- a/python/src/broad_phase/hash_grid.cpp +++ b/python/src/broad_phase/hash_grid.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_hash_grid(py::module_& m) @@ -10,11 +9,10 @@ void define_hash_grid(py::module_& m) py::class_(m, "HashItem") .def( py::init(), - "Construct a hash item as a (key, value) pair.", py::arg("key"), - py::arg("id")) + "Construct a hash item as a (key, value) pair.", "key"_a, "id"_a) .def( "__lt__", &HashItem::operator<, - "Compare HashItems by their keys for sorting.", py::arg("other")) + "Compare HashItems by their keys for sorting.", "other"_a) .def_readwrite("key", &HashItem::key, "The key of the item.") .def_readwrite("id", &HashItem::id, "The value of the item."); diff --git a/python/src/broad_phase/spatial_hash.cpp b/python/src/broad_phase/spatial_hash.cpp index ad6f31c95..b0230ea41 100644 --- a/python/src/broad_phase/spatial_hash.cpp +++ b/python/src/broad_phase/spatial_hash.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_spatial_hash(py::module_& m) @@ -15,17 +14,16 @@ void define_spatial_hash(py::module_& m) Eigen::ConstRef, Eigen::ConstRef, Eigen::ConstRef, double, double>(), - py::arg("vertices"), py::arg("edges"), py::arg("faces"), - py::arg("inflation_radius") = 0, py::arg("voxel_size") = -1) + "vertices"_a, "edges"_a, "faces"_a, "inflation_radius"_a = 0, + "voxel_size"_a = -1) .def( py::init< Eigen::ConstRef, Eigen::ConstRef, Eigen::ConstRef, Eigen::ConstRef, double, double>(), - py::arg("vertices_t0"), py::arg("vertices_t1"), py::arg("edges"), - py::arg("faces"), py::arg("inflation_radius") = 0, - py::arg("voxel_size") = -1) + "vertices_t0"_a, "vertices_t1"_a, "edges"_a, "faces"_a, + "inflation_radius"_a = 0, "voxel_size"_a = -1) .def( "build", py::overload_cast< @@ -33,8 +31,8 @@ void define_spatial_hash(py::module_& m) Eigen::ConstRef, Eigen::ConstRef, double, double>( &SpatialHash::build), - py::arg("vertices"), py::arg("edges"), py::arg("faces"), - py::arg("inflation_radius") = 0, py::arg("voxel_size") = -1) + "vertices"_a, "edges"_a, "faces"_a, "inflation_radius"_a = 0, + "voxel_size"_a = -1) .def( "build", py::overload_cast< @@ -43,25 +41,24 @@ void define_spatial_hash(py::module_& m) Eigen::ConstRef, Eigen::ConstRef, double, double>( &SpatialHash::build), - py::arg("vertices_t0"), py::arg("vertices_t1"), py::arg("edges"), - py::arg("faces"), py::arg("inflation_radius") = 0, - py::arg("voxel_size") = -1) + "vertices_t0"_a, "vertices_t1"_a, "edges"_a, "faces"_a, + "inflation_radius"_a = 0, "voxel_size"_a = -1) .def("clear", &SpatialHash::clear) .def( "is_vertex_index", &SpatialHash::is_vertex_index, - "Check if primitive index refers to a vertex.", py::arg("idx")) + "Check if primitive index refers to a vertex.", "idx"_a) .def( "is_edge_index", &SpatialHash::is_edge_index, - "Check if primitive index refers to an edge.", py::arg("idx")) + "Check if primitive index refers to an edge.", "idx"_a) .def( "is_triangle_index", &SpatialHash::is_triangle_index, - "Check if primitive index refers to a triangle.", py::arg("idx")) + "Check if primitive index refers to a triangle.", "idx"_a) .def( "to_edge_index", &SpatialHash::to_edge_index, - "Convert a primitive index to an edge index.", py::arg("idx")) + "Convert a primitive index to an edge index.", "idx"_a) .def( "to_triangle_index", &SpatialHash::to_triangle_index, - "Convert a primitive index to a triangle index.", py::arg("idx")) + "Convert a primitive index to a triangle index.", "idx"_a) .def_readwrite( "left_bottom_corner", &SpatialHash::left_bottom_corner, "The left bottom corner of the world bounding box.") diff --git a/python/src/broad_phase/sweep_and_prune.cpp b/python/src/broad_phase/sweep_and_prune.cpp index cc7c19800..8fcd83cf9 100644 --- a/python/src/broad_phase/sweep_and_prune.cpp +++ b/python/src/broad_phase/sweep_and_prune.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_sweep_and_prune(py::module_& m) diff --git a/python/src/broad_phase/sweep_and_tiniest_queue.cpp b/python/src/broad_phase/sweep_and_tiniest_queue.cpp index 338fa3d01..e480f3df6 100644 --- a/python/src/broad_phase/sweep_and_tiniest_queue.cpp +++ b/python/src/broad_phase/sweep_and_tiniest_queue.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; #ifdef IPC_TOOLKIT_WITH_CUDA using namespace ipc; // not defined if IPC_TOOLKIT_WITH_CUDA is not defined #endif diff --git a/python/src/broad_phase/voxel_size_heuristic.cpp b/python/src/broad_phase/voxel_size_heuristic.cpp index 5351a3591..b0453fb69 100644 --- a/python/src/broad_phase/voxel_size_heuristic.cpp +++ b/python/src/broad_phase/voxel_size_heuristic.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_voxel_size_heuristic(py::module_& m) @@ -12,7 +11,7 @@ void define_voxel_size_heuristic(py::module_& m) py::overload_cast< Eigen::ConstRef, Eigen::ConstRef, const double>(&suggest_good_voxel_size), - py::arg("vertices"), py::arg("edges"), py::arg("inflation_radius") = 0); + "vertices"_a, "edges"_a, "inflation_radius"_a = 0); m.def( "suggest_good_voxel_size", @@ -20,8 +19,7 @@ void define_voxel_size_heuristic(py::module_& m) Eigen::ConstRef, Eigen::ConstRef, Eigen::ConstRef, const double>( &suggest_good_voxel_size), - py::arg("vertices_t0"), py::arg("vertices_t1"), py::arg("edges"), - py::arg("inflation_radius") = 0); + "vertices_t0"_a, "vertices_t1"_a, "edges"_a, "inflation_radius"_a = 0); m.def( "mean_edge_length", @@ -33,8 +31,8 @@ void define_voxel_size_heuristic(py::module_& m) vertices_t0, vertices_t1, edges, std_deviation); return std::make_tuple(r, std_deviation); }, - "Compute the average edge length of a mesh.", py::arg("vertices_t0"), - py::arg("vertices_t1"), py::arg("edges")); + "Compute the average edge length of a mesh.", "vertices_t0"_a, + "vertices_t1"_a, "edges"_a); m.def( "mean_displacement_length", @@ -43,23 +41,23 @@ void define_voxel_size_heuristic(py::module_& m) double r = mean_displacement_length(displacements, std_deviation); return std::make_tuple(r, std_deviation); }, - "Compute the average displacement length.", py::arg("displacements")); + "Compute the average displacement length.", "displacements"_a); m.def( "median_edge_length", &median_edge_length, - "Compute the median edge length of a mesh.", py::arg("vertices_t0"), - py::arg("vertices_t1"), py::arg("edges")); + "Compute the median edge length of a mesh.", "vertices_t0"_a, + "vertices_t1"_a, "edges"_a); m.def( "median_displacement_length", &median_displacement_length, - "Compute the median displacement length.", py::arg("displacements")); + "Compute the median displacement length.", "displacements"_a); m.def( "max_edge_length", &max_edge_length, - "Compute the maximum edge length of a mesh.", py::arg("vertices_t0"), - py::arg("vertices_t1"), py::arg("edges")); + "Compute the maximum edge length of a mesh.", "vertices_t0"_a, + "vertices_t1"_a, "edges"_a); m.def( "max_displacement_length", &max_displacement_length, - "Compute the maximum displacement length.", py::arg("displacements")); + "Compute the maximum displacement length.", "displacements"_a); } diff --git a/python/src/candidates/candidates.cpp b/python/src/candidates/candidates.cpp index a51b62861..ba83bd0bc 100644 --- a/python/src/candidates/candidates.cpp +++ b/python/src/candidates/candidates.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_candidates(py::module_& m) @@ -23,9 +22,8 @@ void define_candidates(py::module_& m) inflation_radius: Amount to inflate the bounding boxes. broad_phase: Broad phase to use. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices"), - py::arg("inflation_radius") = 0, - py::arg("broad_phase") = make_default_broad_phase()) + "mesh"_a, "vertices"_a, "inflation_radius"_a = 0, + "broad_phase"_a = make_default_broad_phase()) .def( "build", py::overload_cast< @@ -45,15 +43,15 @@ void define_candidates(py::module_& m) inflation_radius: Amount to inflate the bounding boxes. broad_phase: Broad phase to use. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices_t0"), py::arg("vertices_t1"), - py::arg("inflation_radius") = 0, - py::arg("broad_phase") = make_default_broad_phase()) + "mesh"_a, "vertices_t0"_a, "vertices_t1"_a, + "inflation_radius"_a = 0, + "broad_phase"_a = make_default_broad_phase()) .def("__len__", &Candidates::size) .def("empty", &Candidates::empty) .def("clear", &Candidates::clear) .def( "__getitem__", - [](Candidates& self, size_t i) -> CollisionStencil<4>& { + [](Candidates& self, size_t i) -> CollisionStencil& { return self[i]; }, py::return_value_policy::reference) @@ -75,9 +73,8 @@ void define_candidates(py::module_& m) Returns: True if any collisions occur. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices_t0"), py::arg("vertices_t1"), - py::arg("min_distance") = 0.0, - py::arg("narrow_phase_ccd") = DEFAULT_NARROW_PHASE_CCD) + "mesh"_a, "vertices_t0"_a, "vertices_t1"_a, "min_distance"_a = 0.0, + "narrow_phase_ccd"_a = DEFAULT_NARROW_PHASE_CCD) .def( "compute_collision_free_stepsize", &Candidates::compute_collision_free_stepsize, @@ -97,9 +94,8 @@ void define_candidates(py::module_& m) Returns: A step-size :math:`\in [0, 1]` that is collision free. A value of 1.0 if a full step and 0.0 is no step. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices_t0"), py::arg("vertices_t1"), - py::arg("min_distance") = 0.0, - py::arg("narrow_phase_ccd") = DEFAULT_NARROW_PHASE_CCD) + "mesh"_a, "vertices_t0"_a, "vertices_t1"_a, "min_distance"_a = 0.0, + "narrow_phase_ccd"_a = DEFAULT_NARROW_PHASE_CCD) .def( "compute_noncandidate_conservative_stepsize", &Candidates::compute_noncandidate_conservative_stepsize, @@ -111,7 +107,7 @@ void define_candidates(py::module_& m) displacements: Surface vertex displacements (rowwise). dhat: Barrier activation distance. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("displacements"), py::arg("dhat")) + "mesh"_a, "displacements"_a, "dhat"_a) .def( "compute_cfl_stepsize", &Candidates::compute_cfl_stepsize, R"ipc_Qu8mg5v7( @@ -126,13 +122,13 @@ void define_candidates(py::module_& m) broad_phase: Broad phase algorithm to use. narrow_phase_ccd: Narrow phase CCD algorithm to use. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices_t0"), py::arg("vertices_t1"), - py::arg("dhat"), py::arg("min_distance") = 0.0, - py::arg("broad_phase") = make_default_broad_phase(), - py::arg("narrow_phase_ccd") = DEFAULT_NARROW_PHASE_CCD) + "mesh"_a, "vertices_t0"_a, "vertices_t1"_a, "dhat"_a, + "min_distance"_a = 0.0, + "broad_phase"_a = make_default_broad_phase(), + "narrow_phase_ccd"_a = DEFAULT_NARROW_PHASE_CCD) .def( - "save_obj", &Candidates::save_obj, py::arg("filename"), - py::arg("vertices"), py::arg("edges"), py::arg("faces")) + "save_obj", &Candidates::save_obj, "filename"_a, "vertices"_a, + "edges"_a, "faces"_a) .def_readwrite("vv_candidates", &Candidates::vv_candidates) .def_readwrite("ev_candidates", &Candidates::ev_candidates) .def_readwrite("ee_candidates", &Candidates::ee_candidates) diff --git a/python/src/candidates/collision_stencil.cpp b/python/src/candidates/collision_stencil.cpp index cb8d3a317..1d8a8945f 100644 --- a/python/src/candidates/collision_stencil.cpp +++ b/python/src/candidates/collision_stencil.cpp @@ -2,17 +2,16 @@ #include -namespace py = pybind11; using namespace ipc; void define_collision_stencil(py::module_& m) { - py::class_>(m, "CollisionStencil") + py::class_(m, "CollisionStencil") .def( - "num_vertices", &CollisionStencil<4>::num_vertices, + "num_vertices", &CollisionStencil::num_vertices, "Get the number of vertices in the collision stencil.") .def( - "dim", &CollisionStencil<4>::dim, + "dim", &CollisionStencil::dim, R"ipc_Qu8mg5v7( Get the dimension of the collision stencil. @@ -22,9 +21,9 @@ void define_collision_stencil(py::module_& m) Returns: The dimension of the collision stencil. )ipc_Qu8mg5v7", - py::arg("ndof")) + "ndof"_a) .def( - "vertex_ids", &CollisionStencil<4>::vertex_ids, + "vertex_ids", &CollisionStencil::vertex_ids, R"ipc_Qu8mg5v7( Get the vertex IDs of the collision stencil. @@ -35,9 +34,9 @@ void define_collision_stencil(py::module_& m) Returns: The vertex IDs of the collision stencil. Size is always 4, but elements i > num_vertices() are -1. )ipc_Qu8mg5v7", - py::arg("edges"), py::arg("faces")) + "edges"_a, "faces"_a) .def( - "vertices", &CollisionStencil<4>::vertices, + "vertices", &CollisionStencil::vertices, R"ipc_Qu8mg5v7( Get the vertex attributes of the collision stencil. @@ -51,9 +50,9 @@ void define_collision_stencil(py::module_& m) Returns: The vertex positions of the collision stencil. Size is always 4, but elements i > num_vertices() are NaN. )ipc_Qu8mg5v7", - py::arg("vertices"), py::arg("edges"), py::arg("faces")) + "vertices"_a, "edges"_a, "faces"_a) .def( - "dof", &CollisionStencil<4>::dof, + "dof", &CollisionStencil::dof, R"ipc_Qu8mg5v7( Select this stencil's DOF from the full matrix of DOF. @@ -67,14 +66,14 @@ void define_collision_stencil(py::module_& m) Returns: This stencil's DOF. )ipc_Qu8mg5v7", - py::arg("X"), py::arg("edges"), py::arg("faces")) + "X"_a, "edges"_a, "faces"_a) .def( "compute_distance", py::overload_cast< Eigen::ConstRef, Eigen::ConstRef, Eigen::ConstRef>( - &CollisionStencil<4>::compute_distance, py::const_), + &CollisionStencil::compute_distance, py::const_), R"ipc_Qu8mg5v7( Compute the distance of the stencil. @@ -86,14 +85,14 @@ void define_collision_stencil(py::module_& m) Returns: Distance of the stencil. )ipc_Qu8mg5v7", - py::arg("vertices"), py::arg("edges"), py::arg("faces")) + "vertices"_a, "edges"_a, "faces"_a) .def( "compute_distance_gradient", py::overload_cast< Eigen::ConstRef, Eigen::ConstRef, Eigen::ConstRef>( - &CollisionStencil<4>::compute_distance_gradient, py::const_), + &CollisionStencil::compute_distance_gradient, py::const_), R"ipc_Qu8mg5v7( Compute the distance gradient of the stencil w.r.t. the stencil's vertex positions. @@ -105,14 +104,14 @@ void define_collision_stencil(py::module_& m) Returns: Distance gradient of the stencil w.r.t. the stencil's vertex positions. )ipc_Qu8mg5v7", - py::arg("vertices"), py::arg("edges"), py::arg("faces")) + "vertices"_a, "edges"_a, "faces"_a) .def( "compute_distance_hessian", py::overload_cast< Eigen::ConstRef, Eigen::ConstRef, Eigen::ConstRef>( - &CollisionStencil<4>::compute_distance_hessian, py::const_), + &CollisionStencil::compute_distance_hessian, py::const_), R"ipc_Qu8mg5v7( Compute the distance Hessian of the stencil w.r.t. the stencil's vertex positions. @@ -124,11 +123,11 @@ void define_collision_stencil(py::module_& m) Returns: Distance Hessian of the stencil w.r.t. the stencil's vertex positions. )ipc_Qu8mg5v7", - py::arg("vertices"), py::arg("edges"), py::arg("faces")) + "vertices"_a, "edges"_a, "faces"_a) .def( "compute_distance", py::overload_cast>( - &CollisionStencil<4>::compute_distance, py::const_), + &CollisionStencil::compute_distance, py::const_), R"ipc_Qu8mg5v7( Compute the distance of the stencil. @@ -141,11 +140,11 @@ void define_collision_stencil(py::module_& m) Returns: Distance of the stencil. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "compute_distance_gradient", py::overload_cast>( - &CollisionStencil<4>::compute_distance_gradient, py::const_), + &CollisionStencil::compute_distance_gradient, py::const_), R"ipc_Qu8mg5v7( Compute the distance gradient of the stencil w.r.t. the stencil's vertex positions. @@ -158,11 +157,11 @@ void define_collision_stencil(py::module_& m) Returns: Distance gradient of the stencil w.r.t. the stencil's vertex positions. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "compute_distance_hessian", py::overload_cast>( - &CollisionStencil<4>::compute_distance_hessian, py::const_), + &CollisionStencil::compute_distance_hessian, py::const_), R"ipc_Qu8mg5v7( Compute the distance Hessian of the stencil w.r.t. the stencil's vertex positions. @@ -175,10 +174,10 @@ void define_collision_stencil(py::module_& m) Returns: Distance Hessian of the stencil w.r.t. the stencil's vertex positions. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "ccd", - [](const CollisionStencil<4>& self, + [](const CollisionStencil& self, Eigen::ConstRef vertices_t0, Eigen::ConstRef vertices_t1, const double min_distance, const double tmax, @@ -204,12 +203,11 @@ void define_collision_stencil(py::module_& m) If the candidate had a collision over the time interval. Computed time of impact (normalized). )ipc_Qu8mg5v7", - py::arg("vertices_t0"), py::arg("vertices_t1"), - py::arg("min_distance") = 0.0, py::arg("tmax") = 1.0, - py::arg("narrow_phase_ccd") = DEFAULT_NARROW_PHASE_CCD) + "vertices_t0"_a, "vertices_t1"_a, "min_distance"_a = 0.0, + "tmax"_a = 1.0, "narrow_phase_ccd"_a = DEFAULT_NARROW_PHASE_CCD) .def( "print_ccd_query", - [](const CollisionStencil<4>& self, + [](const CollisionStencil& self, Eigen::ConstRef vertices_t0, Eigen::ConstRef vertices_t1) -> void { self.write_ccd_query(std::cout, vertices_t0, vertices_t1); @@ -221,5 +219,5 @@ void define_collision_stencil(py::module_& m) vertices_t0: Stencil vertices at the start of the time step. vertices_t1: Stencil vertices at the end of the time step. )ipc_Qu8mg5v7", - py::arg("vertices_t0"), py::arg("vertices_t1")); + "vertices_t0"_a, "vertices_t1"_a); } diff --git a/python/src/candidates/edge_edge.cpp b/python/src/candidates/edge_edge.cpp index d4728d0d2..7b36e053b 100644 --- a/python/src/candidates/edge_edge.cpp +++ b/python/src/candidates/edge_edge.cpp @@ -2,21 +2,18 @@ #include -namespace py = pybind11; using namespace ipc; void define_edge_edge_candidate(py::module_& m) { - py::class_>(m, "EdgeEdgeCandidate") - .def( - py::init(), py::arg("edge0_id"), - py::arg("edge1_id")) + py::class_(m, "EdgeEdgeCandidate") + .def(py::init(), "edge0_id"_a, "edge1_id"_a) .def( py::init([](std::tuple edge_ids) { return std::make_unique( std::get<0>(edge_ids), std::get<1>(edge_ids)); }), - py::arg("edge_ids")) + "edge_ids"_a) .def("known_dtype", &EdgeEdgeCandidate::known_dtype) .def( "__str__", @@ -29,11 +26,11 @@ void define_edge_edge_candidate(py::module_& m) return fmt::format( "EdgeEdgeCandidate({:d}, {:d})", ee.edge0_id, ee.edge1_id); }) - .def("__eq__", &EdgeEdgeCandidate::operator==, py::arg("other")) - .def("__ne__", &EdgeEdgeCandidate::operator!=, py::arg("other")) + .def("__eq__", &EdgeEdgeCandidate::operator==, "other"_a) + .def("__ne__", &EdgeEdgeCandidate::operator!=, "other"_a) .def( "__lt__", &EdgeEdgeCandidate::operator<, - "Compare EdgeEdgeCandidates for sorting.", py::arg("other")) + "Compare EdgeEdgeCandidates for sorting.", "other"_a) .def_readwrite( "edge0_id", &EdgeEdgeCandidate::edge0_id, "ID of the first edge.") .def_readwrite( diff --git a/python/src/candidates/edge_face.cpp b/python/src/candidates/edge_face.cpp index 45c727c39..ecd62d7a0 100644 --- a/python/src/candidates/edge_face.cpp +++ b/python/src/candidates/edge_face.cpp @@ -3,22 +3,19 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_edge_face_candidate(py::module_& m) { py::class_(m, "EdgeFaceCandidate") - .def( - py::init(), py::arg("edge_id"), - py::arg("face_id")) + .def(py::init(), "edge_id"_a, "face_id"_a) .def( py::init([](std::tuple edge_and_face_id) { return std::make_unique( std::get<0>(edge_and_face_id), std::get<1>(edge_and_face_id)); }), - py::arg("edge_and_face_id")) + "edge_and_face_id"_a) .def( "__str__", [](const EdgeFaceCandidate& ev) { @@ -30,11 +27,11 @@ void define_edge_face_candidate(py::module_& m) return fmt::format( "EdgeFaceCandidate({:d}, {:d})", ev.edge_id, ev.face_id); }) - .def("__eq__", &EdgeFaceCandidate::operator==, py::arg("other")) - .def("__ne__", &EdgeFaceCandidate::operator!=, py::arg("other")) + .def("__eq__", &EdgeFaceCandidate::operator==, "other"_a) + .def("__ne__", &EdgeFaceCandidate::operator!=, "other"_a) .def( "__lt__", &EdgeFaceCandidate::operator<, - "Compare EdgeFaceCandidate for sorting.", py::arg("other")) + "Compare EdgeFaceCandidate for sorting.", "other"_a) .def_readwrite("edge_id", &EdgeFaceCandidate::edge_id, "ID of the edge") .def_readwrite( "face_id", &EdgeFaceCandidate::face_id, "ID of the face"); diff --git a/python/src/candidates/edge_vertex.cpp b/python/src/candidates/edge_vertex.cpp index 6dd53a38e..84d7dd7f5 100644 --- a/python/src/candidates/edge_vertex.cpp +++ b/python/src/candidates/edge_vertex.cpp @@ -2,22 +2,19 @@ #include -namespace py = pybind11; using namespace ipc; void define_edge_vertex_candidate(py::module_& m) { - py::class_>(m, "EdgeVertexCandidate") - .def( - py::init(), py::arg("edge_id"), - py::arg("vertex_id")) + py::class_(m, "EdgeVertexCandidate") + .def(py::init(), "edge_id"_a, "vertex_id"_a) .def( py::init([](std::tuple edge_and_vertex_id) { return std::make_unique( std::get<0>(edge_and_vertex_id), std::get<1>(edge_and_vertex_id)); }), - py::arg("edge_and_vertex_id")) + "edge_and_vertex_id"_a) .def("known_dtype", &EdgeVertexCandidate::known_dtype) .def( "__str__", @@ -31,11 +28,11 @@ void define_edge_vertex_candidate(py::module_& m) "EdgeVertexCandidate({:d}, {:d})", ev.edge_id, ev.vertex_id); }) - .def("__eq__", &EdgeVertexCandidate::operator==, py::arg("other")) - .def("__ne__", &EdgeVertexCandidate::operator!=, py::arg("other")) + .def("__eq__", &EdgeVertexCandidate::operator==, "other"_a) + .def("__ne__", &EdgeVertexCandidate::operator!=, "other"_a) .def( "__lt__", &EdgeVertexCandidate::operator<, - "Compare EdgeVertexCandidates for sorting.", py::arg("other")) + "Compare EdgeVertexCandidates for sorting.", "other"_a) .def_readwrite( "edge_id", &EdgeVertexCandidate::edge_id, "ID of the edge") .def_readwrite( diff --git a/python/src/candidates/face_face.cpp b/python/src/candidates/face_face.cpp index c2ca57306..eeeae9002 100644 --- a/python/src/candidates/face_face.cpp +++ b/python/src/candidates/face_face.cpp @@ -3,21 +3,18 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_face_face_candidate(py::module_& m) { py::class_(m, "FaceFaceCandidate") - .def( - py::init(), py::arg("face0_id"), - py::arg("face1_id")) + .def(py::init(), "face0_id"_a, "face1_id"_a) .def( py::init([](std::tuple face_ids) { return std::make_unique( std::get<0>(face_ids), std::get<1>(face_ids)); }), - py::arg("face_ids")) + "face_ids"_a) .def( "__str__", [](const FaceFaceCandidate& ff) { @@ -29,11 +26,11 @@ void define_face_face_candidate(py::module_& m) return fmt::format( "FaceFaceCandidate({:d}, {:d})", ff.face0_id, ff.face1_id); }) - .def("__eq__", &FaceFaceCandidate::operator==, py::arg("other")) - .def("__ne__", &FaceFaceCandidate::operator!=, py::arg("other")) + .def("__eq__", &FaceFaceCandidate::operator==, "other"_a) + .def("__ne__", &FaceFaceCandidate::operator!=, "other"_a) .def( "__lt__", &FaceFaceCandidate::operator<, - "Compare FaceFaceCandidate for sorting.", py::arg("other")) + "Compare FaceFaceCandidate for sorting.", "other"_a) .def_readwrite( "face0_id", &FaceFaceCandidate::face0_id, "ID of the first face.") .def_readwrite( diff --git a/python/src/candidates/face_vertex.cpp b/python/src/candidates/face_vertex.cpp index c21d38b59..06aad4a60 100644 --- a/python/src/candidates/face_vertex.cpp +++ b/python/src/candidates/face_vertex.cpp @@ -2,22 +2,19 @@ #include -namespace py = pybind11; using namespace ipc; void define_face_vertex_candidate(py::module_& m) { - py::class_>(m, "FaceVertexCandidate") - .def( - py::init(), py::arg("face_id"), - py::arg("vertex_id")) + py::class_(m, "FaceVertexCandidate") + .def(py::init(), "face_id"_a, "vertex_id"_a) .def( py::init([](std::tuple face_and_vertex_id) { return std::make_unique( std::get<0>(face_and_vertex_id), std::get<1>(face_and_vertex_id)); }), - py::arg("face_and_vertex_id")) + "face_and_vertex_id"_a) .def("known_dtype", &FaceVertexCandidate::known_dtype) .def( "__str__", @@ -31,11 +28,11 @@ void define_face_vertex_candidate(py::module_& m) "FaceVertexCandidate({:d}, {:d})", ev.face_id, ev.vertex_id); }) - .def("__eq__", &FaceVertexCandidate::operator==, py::arg("other")) - .def("__ne__", &FaceVertexCandidate::operator!=, py::arg("other")) + .def("__eq__", &FaceVertexCandidate::operator==, "other"_a) + .def("__ne__", &FaceVertexCandidate::operator!=, "other"_a) .def( "__lt__", &FaceVertexCandidate::operator<, - "Compare FaceVertexCandidate for sorting.", py::arg("other")) + "Compare FaceVertexCandidate for sorting.", "other"_a) .def_readwrite( "face_id", &FaceVertexCandidate::face_id, "ID of the face") .def_readwrite( diff --git a/python/src/candidates/vertex_vertex.cpp b/python/src/candidates/vertex_vertex.cpp index e9aa45a1f..36b1ac908 100644 --- a/python/src/candidates/vertex_vertex.cpp +++ b/python/src/candidates/vertex_vertex.cpp @@ -2,22 +2,19 @@ #include -namespace py = pybind11; using namespace ipc; void define_vertex_vertex_candidate(py::module_& m) { - py::class_>( + py::class_( m, "VertexVertexCandidate") - .def( - py::init(), py::arg("vertex0_id"), - py::arg("vertex1_id")) + .def(py::init(), "vertex0_id"_a, "vertex1_id"_a) .def( py::init([](std::tuple vertex_ids) { return std::make_unique( std::get<0>(vertex_ids), std::get<1>(vertex_ids)); }), - py::arg("vertex_ids")) + "vertex_ids"_a) .def( "__str__", [](const VertexVertexCandidate& ev) { @@ -31,11 +28,11 @@ void define_vertex_vertex_candidate(py::module_& m) "VertexVertexCandidate({:d}, {:d})", ev.vertex0_id, ev.vertex1_id); }) - .def("__eq__", &VertexVertexCandidate::operator==, py::arg("other")) - .def("__ne__", &VertexVertexCandidate::operator!=, py::arg("other")) + .def("__eq__", &VertexVertexCandidate::operator==, "other"_a) + .def("__ne__", &VertexVertexCandidate::operator!=, "other"_a) .def( "__lt__", &VertexVertexCandidate::operator<, - "Compare EdgeVertexCandidates for sorting.", py::arg("other")) + "Compare EdgeVertexCandidates for sorting.", "other"_a) .def_readwrite( "vertex0_id", &VertexVertexCandidate::vertex0_id, "ID of the first vertex") diff --git a/python/src/ccd/aabb.cpp b/python/src/ccd/aabb.cpp index 3d1306727..e7c80eaad 100644 --- a/python/src/ccd/aabb.cpp +++ b/python/src/ccd/aabb.cpp @@ -2,41 +2,37 @@ #include -namespace py = pybind11; using namespace ipc; void define_ccd_aabb(py::module_& m) { m.def( - "point_edge_aabb_cd", &point_edge_aabb_cd, py::arg("p"), py::arg("e0"), - py::arg("e1"), py::arg("dist")); + "point_edge_aabb_cd", &point_edge_aabb_cd, "p"_a, "e0"_a, "e1"_a, + "dist"_a); m.def( - "edge_edge_aabb_cd", &edge_edge_aabb_cd, py::arg("ea0"), py::arg("ea1"), - py::arg("eb0"), py::arg("eb1"), py::arg("dist")); + "edge_edge_aabb_cd", &edge_edge_aabb_cd, "ea0"_a, "ea1"_a, "eb0"_a, + "eb1"_a, "dist"_a); m.def( - "point_triangle_aabb_cd", &point_triangle_aabb_cd, py::arg("p"), - py::arg("t0"), py::arg("t1"), py::arg("t2"), py::arg("dist")); + "point_triangle_aabb_cd", &point_triangle_aabb_cd, "p"_a, "t0"_a, + "t1"_a, "t2"_a, "dist"_a); m.def( - "edge_triangle_aabb_cd", &edge_triangle_aabb_cd, py::arg("e0"), - py::arg("e1"), py::arg("t0"), py::arg("t1"), py::arg("t2"), - py::arg("dist")); + "edge_triangle_aabb_cd", &edge_triangle_aabb_cd, "e0"_a, "e1"_a, "t0"_a, + "t1"_a, "t2"_a, "dist"_a); m.def( - "point_edge_aabb_ccd", &point_edge_aabb_ccd, py::arg("p_t0"), - py::arg("e0_t0"), py::arg("e1_t0"), py::arg("p_t1"), py::arg("e0_t1"), - py::arg("e1_t1"), py::arg("dist")); + "point_edge_aabb_ccd", &point_edge_aabb_ccd, "p_t0"_a, "e0_t0"_a, + "e1_t0"_a, "p_t1"_a, "e0_t1"_a, "e1_t1"_a, "dist"_a); m.def( - "edge_edge_aabb_ccd", &edge_edge_aabb_ccd, py::arg("ea0_t0"), - py::arg("ea1_t0"), py::arg("eb0_t0"), py::arg("eb1_t0"), - py::arg("ea0_t1"), py::arg("ea1_t1"), py::arg("eb0_t1"), - py::arg("eb1_t1"), py::arg("dist")); + "edge_edge_aabb_ccd", &edge_edge_aabb_ccd, "ea0_t0"_a, "ea1_t0"_a, + "eb0_t0"_a, "eb1_t0"_a, "ea0_t1"_a, "ea1_t1"_a, "eb0_t1"_a, "eb1_t1"_a, + "dist"_a); m.def( - "point_triangle_aabb_ccd", &point_triangle_aabb_ccd, py::arg("p_t0"), - py::arg("t0_t0"), py::arg("t1_t0"), py::arg("t2_t0"), py::arg("p_t1"), - py::arg("t0_t1"), py::arg("t1_t1"), py::arg("t2_t1"), py::arg("dist")); + "point_triangle_aabb_ccd", &point_triangle_aabb_ccd, "p_t0"_a, + "t0_t0"_a, "t1_t0"_a, "t2_t0"_a, "p_t1"_a, "t0_t1"_a, "t1_t1"_a, + "t2_t1"_a, "dist"_a); } diff --git a/python/src/ccd/additive_ccd.cpp b/python/src/ccd/additive_ccd.cpp index f9498b945..e57d94904 100644 --- a/python/src/ccd/additive_ccd.cpp +++ b/python/src/ccd/additive_ccd.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_additive_ccd(py::module_& m) @@ -16,8 +15,8 @@ void define_additive_ccd(py::module_& m) Parameters: conservative_rescaling: The conservative rescaling of the time of impact. )ipc_Qu8mg5v7", - py::arg("max_iterations") = AdditiveCCD::DEFAULT_MAX_ITERATIONS, - py::arg("conservative_rescaling") = + "max_iterations"_a = AdditiveCCD::DEFAULT_MAX_ITERATIONS, + "conservative_rescaling"_a = AdditiveCCD::DEFAULT_CONSERVATIVE_RESCALING) .def_readonly_static( "DEFAULT_CONSERVATIVE_RESCALING", diff --git a/python/src/ccd/bindings.hpp b/python/src/ccd/bindings.hpp index b5a5e96ff..49bf39ceb 100644 --- a/python/src/ccd/bindings.hpp +++ b/python/src/ccd/bindings.hpp @@ -1,7 +1,6 @@ #pragma once #include -namespace py = pybind11; void define_ccd_aabb(py::module_& m); void define_additive_ccd(py::module_& m); diff --git a/python/src/ccd/check_initial_distance.cpp b/python/src/ccd/check_initial_distance.cpp index 4e0ca9406..54219e56a 100644 --- a/python/src/ccd/check_initial_distance.cpp +++ b/python/src/ccd/check_initial_distance.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_check_initial_distance(py::module_& m) @@ -15,5 +14,5 @@ void define_check_initial_distance(py::module_& m) check_initial_distance(initial_distance, min_distance, toi); return std::make_tuple(r, toi); }, - py::arg("initial_distance"), py::arg("min_distance")); + "initial_distance"_a, "min_distance"_a); } diff --git a/python/src/ccd/inexact_ccd.cpp b/python/src/ccd/inexact_ccd.cpp index 2daab8a9c..264738142 100644 --- a/python/src/ccd/inexact_ccd.cpp +++ b/python/src/ccd/inexact_ccd.cpp @@ -4,8 +4,6 @@ #include -namespace py = pybind11; - void define_inexact_ccd(py::module_& m) { #ifdef IPC_TOOLKIT_WITH_INEXACT_CCD @@ -20,7 +18,7 @@ void define_inexact_ccd(py::module_& m) Parameters: conservative_rescaling: The conservative rescaling of the time of impact. )ipc_Qu8mg5v7", - py::arg("conservative_rescaling") = + "conservative_rescaling"_a = InexactCCD::DEFAULT_CONSERVATIVE_RESCALING) .def_readonly_static( "DEFAULT_CONSERVATIVE_RESCALING", diff --git a/python/src/ccd/inexact_point_edge.cpp b/python/src/ccd/inexact_point_edge.cpp index 0ee7b5181..010c74494 100644 --- a/python/src/ccd/inexact_point_edge.cpp +++ b/python/src/ccd/inexact_point_edge.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_inexact_point_edge(py::module_& m) @@ -39,6 +38,6 @@ void define_inexact_point_edge(py::module_& m) True if a collision was detected, false otherwise. Output time of impact )ipc_Qu8mg5v7", - py::arg("p_t0"), py::arg("e0_t0"), py::arg("e1_t0"), py::arg("p_t1"), - py::arg("e0_t1"), py::arg("e1_t1"), py::arg("conservative_rescaling")); + "p_t0"_a, "e0_t0"_a, "e1_t0"_a, "p_t1"_a, "e0_t1"_a, "e1_t1"_a, + "conservative_rescaling"_a); } diff --git a/python/src/ccd/narrow_phase_ccd.cpp b/python/src/ccd/narrow_phase_ccd.cpp index 86c6017b0..1668a0c63 100644 --- a/python/src/ccd/narrow_phase_ccd.cpp +++ b/python/src/ccd/narrow_phase_ccd.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; class PyNarrowPhaseCCD : public NarrowPhaseCCD { @@ -114,9 +113,8 @@ void define_narrow_phase_ccd(py::module_& m) p0_t0, p1_t0, p0_t1, p1_t1, toi, min_distance, tmax); return std::make_tuple(r, toi); }, - py::arg("p0_t0"), py::arg("p1_t0"), py::arg("p0_t1"), - py::arg("p1_t1"), py::arg("min_distance") = 0.0, - py::arg("tmax") = 1.0) + "p0_t0"_a, "p1_t0"_a, "p0_t1"_a, "p1_t1"_a, "min_distance"_a = 0.0, + "tmax"_a = 1.0) .def( "point_edge_ccd", [](const NarrowPhaseCCD& self, Eigen::ConstRef p_t0, @@ -132,9 +130,8 @@ void define_narrow_phase_ccd(py::module_& m) tmax); return std::make_tuple(r, toi); }, - py::arg("p_t0"), py::arg("e0_t0"), py::arg("e1_t0"), - py::arg("p_t1"), py::arg("e0_t1"), py::arg("e1_t1"), - py::arg("min_distance") = 0.0, py::arg("tmax") = 1.0) + "p_t0"_a, "e0_t0"_a, "e1_t0"_a, "p_t1"_a, "e0_t1"_a, "e1_t1"_a, + "min_distance"_a = 0.0, "tmax"_a = 1.0) .def( "point_triangle_ccd", [](const NarrowPhaseCCD& self, @@ -153,10 +150,8 @@ void define_narrow_phase_ccd(py::module_& m) min_distance, tmax); return std::make_tuple(r, toi); }, - py::arg("p_t0"), py::arg("t0_t0"), py::arg("t1_t0"), - py::arg("t2_t0"), py::arg("p_t1"), py::arg("t0_t1"), - py::arg("t1_t1"), py::arg("t2_t1"), py::arg("min_distance") = 0.0, - py::arg("tmax") = 1.0) + "p_t0"_a, "t0_t0"_a, "t1_t0"_a, "t2_t0"_a, "p_t1"_a, "t0_t1"_a, + "t1_t1"_a, "t2_t1"_a, "min_distance"_a = 0.0, "tmax"_a = 1.0) .def( "edge_edge_ccd", [](const NarrowPhaseCCD& self, @@ -175,8 +170,7 @@ void define_narrow_phase_ccd(py::module_& m) eb1_t1, toi, min_distance, tmax); return std::make_tuple(r, toi); }, - py::arg("ea0_t0"), py::arg("ea1_t0"), py::arg("eb0_t0"), - py::arg("eb1_t0"), py::arg("ea0_t1"), py::arg("ea1_t1"), - py::arg("eb0_t1"), py::arg("eb1_t1"), py::arg("min_distance") = 0.0, - py::arg("tmax") = 1.0); + "ea0_t0"_a, "ea1_t0"_a, "eb0_t0"_a, "eb1_t0"_a, "ea0_t1"_a, + "ea1_t1"_a, "eb0_t1"_a, "eb1_t1"_a, "min_distance"_a = 0.0, + "tmax"_a = 1.0); } diff --git a/python/src/ccd/nonlinear_ccd.cpp b/python/src/ccd/nonlinear_ccd.cpp index 868e21cfd..2f836da10 100644 --- a/python/src/ccd/nonlinear_ccd.cpp +++ b/python/src/ccd/nonlinear_ccd.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; class PyNonlinearTrajectory : public NonlinearTrajectory { @@ -33,7 +32,7 @@ void define_nonlinear_ccd(py::module_& m) .def(py::init<>()) .def( "__call__", &NonlinearTrajectory::operator(), - "Compute the point's position at time t", py::arg("t")) + "Compute the point's position at time t", "t"_a) .def( "max_distance_from_linear", &NonlinearTrajectory::max_distance_from_linear, @@ -44,7 +43,7 @@ void define_nonlinear_ccd(py::module_& m) t0: Start time of the trajectory t1: End time of the trajectory )ipc_Qu8mg5v7", - py::arg("t0"), py::arg("t1")); + "t0"_a, "t1"_a); #ifdef IPC_TOOLKIT_WITH_FILIB py::class_< @@ -56,12 +55,12 @@ void define_nonlinear_ccd(py::module_& m) [](const IntervalNonlinearTrajectory& self, const double t) { return self(t); }, - "Compute the point's position at time t", py::arg("t")) + "Compute the point's position at time t", "t"_a) .def( "__call__", py::overload_cast( &IntervalNonlinearTrajectory::operator(), py::const_), - "Compute the point's position over a time interval t", py::arg("t")) + "Compute the point's position over a time interval t", "t"_a) .def( "max_distance_from_linear", &IntervalNonlinearTrajectory::max_distance_from_linear, @@ -75,7 +74,7 @@ void define_nonlinear_ccd(py::module_& m) t0: Start time of the trajectory t1: End time of the trajectory )ipc_Qu8mg5v7", - py::arg("t0"), py::arg("t1")); + "t0"_a, "t1"_a); #endif m.def( @@ -106,11 +105,10 @@ void define_nonlinear_ccd(py::module_& m) True if the two points collide, false otherwise. Output time of impact )ipc_Qu8mg5v7", - py::arg("p0"), py::arg("p1"), py::arg("tmax") = 1.0, - py::arg("min_distance") = 0, - py::arg("tolerance") = TightInclusionCCD::DEFAULT_TOLERANCE, - py::arg("max_iterations") = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, - py::arg("conservative_rescaling") = + "p0"_a, "p1"_a, "tmax"_a = 1.0, "min_distance"_a = 0, + "tolerance"_a = TightInclusionCCD::DEFAULT_TOLERANCE, + "max_iterations"_a = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, + "conservative_rescaling"_a = TightInclusionCCD::DEFAULT_CONSERVATIVE_RESCALING); m.def( @@ -143,11 +141,10 @@ void define_nonlinear_ccd(py::module_& m) True if the point and edge collide, false otherwise. Output time of impact )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1"), py::arg("tmax") = 1.0, - py::arg("min_distance") = 0, - py::arg("tolerance") = TightInclusionCCD::DEFAULT_TOLERANCE, - py::arg("max_iterations") = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, - py::arg("conservative_rescaling") = + "p"_a, "e0"_a, "e1"_a, "tmax"_a = 1.0, "min_distance"_a = 0, + "tolerance"_a = TightInclusionCCD::DEFAULT_TOLERANCE, + "max_iterations"_a = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, + "conservative_rescaling"_a = TightInclusionCCD::DEFAULT_CONSERVATIVE_RESCALING); m.def( @@ -181,11 +178,11 @@ void define_nonlinear_ccd(py::module_& m) True if the two edges collide, false otherwise. Output time of impact )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1"), - py::arg("tmax") = 1.0, py::arg("min_distance") = 0, - py::arg("tolerance") = TightInclusionCCD::DEFAULT_TOLERANCE, - py::arg("max_iterations") = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, - py::arg("conservative_rescaling") = + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a, "tmax"_a = 1.0, + "min_distance"_a = 0, + "tolerance"_a = TightInclusionCCD::DEFAULT_TOLERANCE, + "max_iterations"_a = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, + "conservative_rescaling"_a = TightInclusionCCD::DEFAULT_CONSERVATIVE_RESCALING); m.def( @@ -219,11 +216,10 @@ void define_nonlinear_ccd(py::module_& m) True if the point and triangle collide, false otherwise. Output time of impact )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2"), - py::arg("tmax") = 1.0, py::arg("min_distance") = 0, - py::arg("tolerance") = TightInclusionCCD::DEFAULT_TOLERANCE, - py::arg("max_iterations") = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, - py::arg("conservative_rescaling") = + "p"_a, "t0"_a, "t1"_a, "t2"_a, "tmax"_a = 1.0, "min_distance"_a = 0, + "tolerance"_a = TightInclusionCCD::DEFAULT_TOLERANCE, + "max_iterations"_a = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, + "conservative_rescaling"_a = TightInclusionCCD::DEFAULT_CONSERVATIVE_RESCALING); m.def( @@ -258,9 +254,8 @@ void define_nonlinear_ccd(py::module_& m) Output time of impact. )ipc_Qu8mg5v7", - py::arg("distance"), py::arg("max_distance_from_linear"), - py::arg("linear_ccd"), py::arg("tmax") = 1.0, - py::arg("min_distance") = 0, - py::arg("conservative_rescaling") = + "distance"_a, "max_distance_from_linear"_a, "linear_ccd"_a, + "tmax"_a = 1.0, "min_distance"_a = 0, + "conservative_rescaling"_a = TightInclusionCCD::DEFAULT_CONSERVATIVE_RESCALING); } diff --git a/python/src/ccd/point_static_plane.cpp b/python/src/ccd/point_static_plane.cpp index b9764a73b..20ca41d0c 100644 --- a/python/src/ccd/point_static_plane.cpp +++ b/python/src/ccd/point_static_plane.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_point_static_plane(py::module_& m) @@ -34,8 +33,7 @@ void define_point_static_plane(py::module_& m) True if a collision was detected, false otherwise. Output time of impact )ipc_Qu8mg5v7", - py::arg("p_t0"), py::arg("p_t1"), py::arg("plane_origin"), - py::arg("plane_normal"), - py::arg("conservative_rescaling") = + "p_t0"_a, "p_t1"_a, "plane_origin"_a, "plane_normal"_a, + "conservative_rescaling"_a = TightInclusionCCD::DEFAULT_CONSERVATIVE_RESCALING); } diff --git a/python/src/ccd/tight_inclusion_ccd.cpp b/python/src/ccd/tight_inclusion_ccd.cpp index 64737567e..dc23f3f4d 100644 --- a/python/src/ccd/tight_inclusion_ccd.cpp +++ b/python/src/ccd/tight_inclusion_ccd.cpp @@ -5,7 +5,6 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_tight_inclusion_ccd(py::module_& m) @@ -70,16 +69,13 @@ void define_tight_inclusion_ccd(py::module_& m) the earliest time of collision if collision happens (infinity if no collision occurs), and if max_iterations < 0, the solver precision otherwise the input tolerance. )ipc_Qu8mg5v7", - py::arg("ea0_t0"), py::arg("ea1_t0"), py::arg("eb0_t0"), - py::arg("eb1_t0"), py::arg("ea0_t1"), py::arg("ea1_t1"), - py::arg("eb0_t1"), py::arg("eb1_t1"), py::arg("min_distance") = 0, - py::arg("tmax") = 1, - py::arg("tolerance") = TightInclusionCCD::DEFAULT_TOLERANCE, - py::arg("max_iterations") = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, - py::arg("filter") = ticcd::Array3::Constant(-1), - py::arg("no_zero_toi") = ticcd::DEFAULT_NO_ZERO_TOI, - py::arg("ccd_method") = - ticcd::CCDRootFindingMethod::BREADTH_FIRST_SEARCH); + "ea0_t0"_a, "ea1_t0"_a, "eb0_t0"_a, "eb1_t0"_a, "ea0_t1"_a, "ea1_t1"_a, + "eb0_t1"_a, "eb1_t1"_a, "min_distance"_a = 0, "tmax"_a = 1, + "tolerance"_a = TightInclusionCCD::DEFAULT_TOLERANCE, + "max_iterations"_a = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, + "filter"_a = ticcd::Array3::Constant(-1), + "no_zero_toi"_a = ticcd::DEFAULT_NO_ZERO_TOI, + "ccd_method"_a = ticcd::CCDRootFindingMethod::BREADTH_FIRST_SEARCH); m_ti.def( "point_triangle_ccd", @@ -125,15 +121,13 @@ void define_tight_inclusion_ccd(py::module_& m) the earliest time of collision if collision happens (infinity if no collision occurs), and if max_iterations < 0, the solver precision otherwise the input tolerance. )ipc_Qu8mg5v7", - py::arg("v_t0"), py::arg("f0_t0"), py::arg("f1_t0"), py::arg("f2_t0"), - py::arg("v_t1"), py::arg("f0_t1"), py::arg("f1_t1"), py::arg("f2_t1"), - py::arg("min_distance") = 0, py::arg("tmax") = 1, - py::arg("tolerance") = TightInclusionCCD::DEFAULT_TOLERANCE, - py::arg("max_iterations") = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, - py::arg("filter") = ticcd::Array3::Constant(-1), - py::arg("no_zero_toi") = ticcd::DEFAULT_NO_ZERO_TOI, - py::arg("ccd_method") = - ticcd::CCDRootFindingMethod::BREADTH_FIRST_SEARCH); + "v_t0"_a, "f0_t0"_a, "f1_t0"_a, "f2_t0"_a, "v_t1"_a, "f0_t1"_a, + "f1_t1"_a, "f2_t1"_a, "min_distance"_a = 0, "tmax"_a = 1, + "tolerance"_a = TightInclusionCCD::DEFAULT_TOLERANCE, + "max_iterations"_a = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, + "filter"_a = ticcd::Array3::Constant(-1), + "no_zero_toi"_a = ticcd::DEFAULT_NO_ZERO_TOI, + "ccd_method"_a = ticcd::CCDRootFindingMethod::BREADTH_FIRST_SEARCH); m_ti.def( "compute_ccd_filters", @@ -161,8 +155,8 @@ void define_tight_inclusion_ccd(py::module_& m) Returns: The numerical error filters for the input parameters. )ipc_Qu8mg5v7", - py::arg("min_corner"), py::arg("max_corner"), py::arg("is_vertex_face"), - py::arg("using_minimum_separation")); + "min_corner"_a, "max_corner"_a, "is_vertex_face"_a, + "using_minimum_separation"_a); py::class_(m, "TightInclusionCCD") .def( @@ -173,10 +167,9 @@ void define_tight_inclusion_ccd(py::module_& m) Parameters: conservative_rescaling: The conservative rescaling of the time of impact. )ipc_Qu8mg5v7", - py::arg("tolerance") = TightInclusionCCD::DEFAULT_TOLERANCE, - py::arg("max_iterations") = - TightInclusionCCD::DEFAULT_MAX_ITERATIONS, - py::arg("conservative_rescaling") = + "tolerance"_a = TightInclusionCCD::DEFAULT_TOLERANCE, + "max_iterations"_a = TightInclusionCCD::DEFAULT_MAX_ITERATIONS, + "conservative_rescaling"_a = TightInclusionCCD::DEFAULT_CONSERVATIVE_RESCALING) .def_readonly_static( "DEFAULT_TOLERANCE", &TightInclusionCCD::DEFAULT_TOLERANCE, diff --git a/python/src/collision_mesh.cpp b/python/src/collision_mesh.cpp index f88a46cbe..680dbee65 100644 --- a/python/src/collision_mesh.cpp +++ b/python/src/collision_mesh.cpp @@ -3,7 +3,6 @@ #include #include -namespace py = pybind11; using namespace ipc; #ifdef IPC_TOOLKIT_WITH_ABSEIL @@ -93,7 +92,7 @@ void define_collision_mesh(py::module_& m) explicit_values: A map from vertex pairs to whether they can collide. Only the upper triangle is used. The map is assumed to be symmetric. default_value: The default value to return if the pair is not in the map. )ipc_Qu8mg5v7", - py::arg("explicit_values"), py::arg("default_value")) + "explicit_values"_a, "default_value"_a) .def( "__call__", &SparseCanCollide::operator(), R"ipc_Qu8mg5v7( Can two vertices collide? @@ -105,14 +104,13 @@ void define_collision_mesh(py::module_& m) Returns: The value of the pair if it is in the map, otherwise the default value. )ipc_Qu8mg5v7", - py::arg("i"), py::arg("j")); + "i"_a, "j"_a); py::class_( m, "VertexPatchesCanCollide", "A functor which returns true if the vertices are in different patches.") .def( - py::init>(), - py::arg("vertex_patches"), + py::init>(), "vertex_patches"_a, R"ipc_Qu8mg5v7( Construct a new Vertex Patches Can Collide object. @@ -130,7 +128,7 @@ void define_collision_mesh(py::module_& m) Returns: True if the vertices are in different patches. )ipc_Qu8mg5v7", - py::arg("i"), py::arg("j")); + "i"_a, "j"_a); py::class_(m, "CollisionMesh") .def( @@ -148,12 +146,13 @@ void define_collision_mesh(py::module_& m) faces: The faces of the collision mesh (#F × 3). displacement_map: The displacement mapping from displacements on the full mesh to the collision mesh. )ipc_Qu8mg5v7", - py::arg("rest_positions"), py::arg("edges") = Eigen::MatrixXi(), - py::arg("faces") = Eigen::MatrixXi(), - py::arg("displacement_map") = Eigen::SparseMatrix()) + "rest_positions"_a, "edges"_a = Eigen::MatrixXi(), + "faces"_a = Eigen::MatrixXi(), + "displacement_map"_a = Eigen::SparseMatrix()) .def( py::init< - const std::vector&, const std::vector&, Eigen::ConstRef, + const std::vector&, const std::vector&, + Eigen::ConstRef, Eigen::ConstRef, Eigen::ConstRef, const Eigen::SparseMatrix&>(), @@ -168,10 +167,9 @@ void define_collision_mesh(py::module_& m) faces: The faces of the collision mesh indexed into the full mesh vertices (#F × 3). displacement_map: The displacement mapping from displacements on the full mesh to the collision mesh. )ipc_Qu8mg5v7", - py::arg("include_vertex"), py::arg("orient_vertex"), py::arg("full_rest_positions"), - py::arg("edges") = Eigen::MatrixXi(), - py::arg("faces") = Eigen::MatrixXi(), - py::arg("displacement_map") = Eigen::SparseMatrix()) + "include_vertex"_a, "orient_vertex"_a, "full_rest_positions"_a, + "edges"_a = Eigen::MatrixXi(), "faces"_a = Eigen::MatrixXi(), + "displacement_map"_a = Eigen::SparseMatrix()) .def_static( "build_from_full_mesh", &CollisionMesh::build_from_full_mesh, R"ipc_Qu8mg5v7( @@ -185,8 +183,7 @@ void define_collision_mesh(py::module_& m) Returns: Constructed CollisionMesh. )ipc_Qu8mg5v7", - py::arg("full_rest_positions"), py::arg("edges"), - py::arg("faces") = Eigen::MatrixXi()) + "full_rest_positions"_a, "edges"_a, "faces"_a = Eigen::MatrixXi()) .def( "init_adjacencies", &CollisionMesh::init_adjacencies, "Initialize vertex-vertex and edge-vertex adjacencies.") @@ -248,7 +245,7 @@ void define_collision_mesh(py::module_& m) Returns: The vertex positions of the collision mesh (#V × dim). )ipc_Qu8mg5v7", - py::arg("full_positions")) + "full_positions"_a) .def( "displace_vertices", &CollisionMesh::displace_vertices, R"ipc_Qu8mg5v7( @@ -260,7 +257,7 @@ void define_collision_mesh(py::module_& m) Returns: The vertex positions of the collision mesh (#V × dim). )ipc_Qu8mg5v7", - py::arg("full_displacements")) + "full_displacements"_a) .def( "map_displacements", &CollisionMesh::map_displacements, R"ipc_Qu8mg5v7( @@ -272,7 +269,7 @@ void define_collision_mesh(py::module_& m) Returns: The vertex displacements on the collision mesh (#V × dim). )ipc_Qu8mg5v7", - py::arg("full_displacements")) + "full_displacements"_a) .def( "to_full_vertex_id", &CollisionMesh::to_full_vertex_id, R"ipc_Qu8mg5v7( @@ -284,7 +281,7 @@ void define_collision_mesh(py::module_& m) Returns: Vertex ID in the full mesh. )ipc_Qu8mg5v7", - py::arg("id")) + "id"_a) .def( "to_full_dof", py::overload_cast>( @@ -300,7 +297,7 @@ void define_collision_mesh(py::module_& m) Returns: Vector quantity on the full mesh with size equal to full_ndof(). )ipc_Qu8mg5v7", - py::arg("x")) + "x"_a) .def( "to_full_dof", py::overload_cast&>( @@ -316,7 +313,7 @@ void define_collision_mesh(py::module_& m) Returns: Matrix quantity on the full mesh with size equal to full_ndof() × full_ndof(). )ipc_Qu8mg5v7", - py::arg("X")) + "X"_a) .def_property_readonly( "vertex_vertex_adjacencies", &CollisionMesh::vertex_vertex_adjacencies, @@ -342,7 +339,7 @@ void define_collision_mesh(py::module_& m) Returns: True if the vertex is on the boundary of the collision mesh. )ipc_Qu8mg5v7", - py::arg("vi")) + "vi"_a) .def( "vertex_area", &CollisionMesh::vertex_area, R"ipc_Qu8mg5v7( @@ -354,7 +351,7 @@ void define_collision_mesh(py::module_& m) Returns: Barycentric area of vertex vi. )ipc_Qu8mg5v7", - py::arg("vi")) + "vi"_a) .def_property_readonly( "vertex_areas", &CollisionMesh::vertex_areas, "Get the barycentric area of the vertices.") @@ -373,7 +370,7 @@ void define_collision_mesh(py::module_& m) Returns: Gradient of the barycentric area of vertex vi wrt the rest positions of all points. )ipc_Qu8mg5v7", - py::arg("vi")) + "vi"_a) .def( "edge_area", &CollisionMesh::edge_area, R"ipc_Qu8mg5v7( @@ -385,7 +382,7 @@ void define_collision_mesh(py::module_& m) Returns: Barycentric area of edge ei. )ipc_Qu8mg5v7", - py::arg("ei")) + "ei"_a) .def( "edge_areas", &CollisionMesh::edge_areas, "Get the barycentric area of the edges.") @@ -404,7 +401,7 @@ void define_collision_mesh(py::module_& m) Returns: Gradient of the barycentric area of edge ei wrt the rest positions of all points. )ipc_Qu8mg5v7", - py::arg("ei")) + "ei"_a) .def( "are_area_jacobians_initialized", &CollisionMesh::are_area_jacobians_initialized, @@ -422,8 +419,7 @@ void define_collision_mesh(py::module_& m) Returns: A vector of bools indicating whether each vertex is on the surface. )ipc_Qu8mg5v7", - py::arg("num_vertices"), py::arg("edges"), - py::arg("codim_vertices") = Eigen::VectorXi()) + "num_vertices"_a, "edges"_a, "codim_vertices"_a = Eigen::VectorXi()) .def_static( "construct_faces_to_edges", &CollisionMesh::construct_faces_to_edges, @@ -437,7 +433,7 @@ void define_collision_mesh(py::module_& m) Returns: Matrix that maps from the faces' edges to rows in the edges matrix. )ipc_Qu8mg5v7", - py::arg("faces"), py::arg("edges")) + "faces"_a, "edges"_a) .def_property( "can_collide", [](CollisionMesh& self) { return self.can_collide; }, [](CollisionMesh& self, const py::object& can_collide) { diff --git a/python/src/collisions/normal/bindings.hpp b/python/src/collisions/normal/bindings.hpp index 424547b60..2894ce62c 100644 --- a/python/src/collisions/normal/bindings.hpp +++ b/python/src/collisions/normal/bindings.hpp @@ -1,7 +1,6 @@ #pragma once #include -namespace py = pybind11; void define_normal_collision(py::module_& m); void define_normal_collisions(py::module_& m); diff --git a/python/src/collisions/normal/edge_edge.cpp b/python/src/collisions/normal/edge_edge.cpp index 66d889993..3a77f345e 100644 --- a/python/src/collisions/normal/edge_edge.cpp +++ b/python/src/collisions/normal/edge_edge.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_edge_edge_normal_collision(py::module_& m) @@ -13,25 +12,24 @@ void define_edge_edge_normal_collision(py::module_& m) py::init< const index_t, const index_t, const double, const EdgeEdgeDistanceType>(), - py::arg("edge0_id"), py::arg("edge1_id"), py::arg("eps_x"), - py::arg("dtype") = EdgeEdgeDistanceType::AUTO) + "edge0_id"_a, "edge1_id"_a, "eps_x"_a, + "dtype"_a = EdgeEdgeDistanceType::AUTO) .def( py::init< const EdgeEdgeCandidate&, const double, const EdgeEdgeDistanceType>(), - py::arg("candidate"), py::arg("eps_x"), - py::arg("dtype") = EdgeEdgeDistanceType::AUTO) + "candidate"_a, "eps_x"_a, "dtype"_a = EdgeEdgeDistanceType::AUTO) // .def( // py::init< // const index_t, const index_t, const double, const double, // const Eigen::SparseVector&, // const EdgeEdgeDistanceType>(), - // py::arg("edge0_id"), py::arg("edge1_id"), py::arg("eps_x"), - // py::arg("weight"), py::arg("weight_gradient"), - // py::arg("dtype") = EdgeEdgeDistanceType::AUTO) - .def("__eq__", &EdgeEdgeNormalCollision::operator==, py::arg("other")) - .def("__ne__", &EdgeEdgeNormalCollision::operator!=, py::arg("other")) - .def("__lt__", &EdgeEdgeNormalCollision::operator<, py::arg("other")) + // "edge0_id"_a, "edge1_id"_a, "eps_x"_a, + // "weight"_a, "weight_gradient"_a, + // "dtype"_a = EdgeEdgeDistanceType::AUTO) + .def("__eq__", &EdgeEdgeNormalCollision::operator==, "other"_a) + .def("__ne__", &EdgeEdgeNormalCollision::operator!=, "other"_a) + .def("__lt__", &EdgeEdgeNormalCollision::operator<, "other"_a) .def_readwrite( "eps_x", &EdgeEdgeNormalCollision::eps_x, "Mollifier activation threshold.") diff --git a/python/src/collisions/normal/edge_vertex.cpp b/python/src/collisions/normal/edge_vertex.cpp index c9617f3b8..96e941460 100644 --- a/python/src/collisions/normal/edge_vertex.cpp +++ b/python/src/collisions/normal/edge_vertex.cpp @@ -2,21 +2,18 @@ #include -namespace py = pybind11; using namespace ipc; void define_edge_vertex_normal_collision(py::module_& m) { py::class_( m, "EdgeVertexNormalCollision") - .def( - py::init(), py::arg("edge_id"), - py::arg("vertex_id")) - .def(py::init(), py::arg("candidate")); + .def(py::init(), "edge_id"_a, "vertex_id"_a) + .def(py::init(), "candidate"_a); // .def( // py::init< // const index_t, const index_t, const double, // const Eigen::SparseVector&>(), - // py::arg("edge_id"), py::arg("vertex_id"), py::arg("weight"), - // py::arg("weight_gradient")); + // "edge_id"_a, "vertex_id"_a, "weight"_a, + // "weight_gradient"_a); } diff --git a/python/src/collisions/normal/face_vertex.cpp b/python/src/collisions/normal/face_vertex.cpp index d85de27ad..3bc4e83e8 100644 --- a/python/src/collisions/normal/face_vertex.cpp +++ b/python/src/collisions/normal/face_vertex.cpp @@ -2,21 +2,18 @@ #include -namespace py = pybind11; using namespace ipc; void define_face_vertex_normal_collision(py::module_& m) { py::class_( m, "FaceVertexNormalCollision") - .def( - py::init(), "", py::arg("face_id"), - py::arg("vertex_id")) - .def(py::init(), py::arg("candidate")); + .def(py::init(), "", "face_id"_a, "vertex_id"_a) + .def(py::init(), "candidate"_a); // .def( // py::init< // const index_t, const index_t, const double, // const Eigen::SparseVector&>(), - // py::arg("face_id"), py::arg("vertex_id"), py::arg("weight"), - // py::arg("weight_gradient")); + // "face_id"_a, "vertex_id"_a, "weight"_a, + // "weight_gradient"_a); } diff --git a/python/src/collisions/normal/normal_collision.cpp b/python/src/collisions/normal/normal_collision.cpp index 503095589..c2a4497d0 100644 --- a/python/src/collisions/normal/normal_collision.cpp +++ b/python/src/collisions/normal/normal_collision.cpp @@ -2,12 +2,11 @@ #include -namespace py = pybind11; using namespace ipc; void define_normal_collision(py::module_& m) { - py::class_>(m, "NormalCollision") + py::class_(m, "NormalCollision") .def( "is_mollified", &NormalCollision::is_mollified, "Does the distance potentially have to be mollified?") @@ -22,7 +21,7 @@ void define_normal_collision(py::module_& m) Returns: The mollifier threshold. )ipc_Qu8mg5v7", - py::arg("rest_positions")) + "rest_positions"_a) .def( "mollifier", py::overload_cast>( @@ -36,7 +35,7 @@ void define_normal_collision(py::module_& m) Returns: The mollifier value. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "mollifier", py::overload_cast, double>( @@ -51,7 +50,7 @@ void define_normal_collision(py::module_& m) Returns: The mollifier value. )ipc_Qu8mg5v7", - py::arg("positions"), py::arg("eps_x")) + "positions"_a, "eps_x"_a) .def( "mollifier_gradient", py::overload_cast>( @@ -65,7 +64,7 @@ void define_normal_collision(py::module_& m) Returns: The mollifier gradient. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "mollifier_gradient", py::overload_cast, double>( @@ -80,7 +79,7 @@ void define_normal_collision(py::module_& m) Returns: The mollifier gradient. )ipc_Qu8mg5v7", - py::arg("positions"), py::arg("eps_x")) + "positions"_a, "eps_x"_a) .def( "mollifier_hessian", py::overload_cast>( @@ -94,7 +93,7 @@ void define_normal_collision(py::module_& m) Returns: The mollifier Hessian. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "mollifier_hessian", py::overload_cast, double>( @@ -109,7 +108,7 @@ void define_normal_collision(py::module_& m) Returns: The mollifier Hessian. )ipc_Qu8mg5v7", - py::arg("positions"), py::arg("eps_x")) + "positions"_a, "eps_x"_a) .def( "mollifier_gradient_wrt_x", &NormalCollision::mollifier_gradient_wrt_x, @@ -123,7 +122,7 @@ void define_normal_collision(py::module_& m) Returns: The mollifier gradient w.r.t. rest positions. )ipc_Qu8mg5v7", - py::arg("rest_positions"), py::arg("positions")) + "rest_positions"_a, "positions"_a) .def( "mollifier_gradient_jacobian_wrt_x", &NormalCollision::mollifier_gradient_jacobian_wrt_x, @@ -137,7 +136,7 @@ void define_normal_collision(py::module_& m) Returns: The jacobian of the mollifier's gradient w.r.t. rest positions. )ipc_Qu8mg5v7", - py::arg("rest_positions"), py::arg("positions")) + "rest_positions"_a, "positions"_a) .def_readwrite( "dmin", &NormalCollision::dmin, "The minimum separation distance.") .def_readwrite( diff --git a/python/src/collisions/normal/normal_collisions.cpp b/python/src/collisions/normal/normal_collisions.cpp index 21c31fea1..2e68d79a7 100644 --- a/python/src/collisions/normal/normal_collisions.cpp +++ b/python/src/collisions/normal/normal_collisions.cpp @@ -3,26 +3,28 @@ #include #include -namespace py = pybind11; using namespace ipc; template void define_SmoothCollisionTemplate(py::module_& m, std::string name) { py::class_(m, name.c_str()) - .def("name", &collision_type::name, "Get the type name of collision") - .def("num_vertices", &collision_type::num_vertices, "Get the number of vertices"); + .def("name", &collision_type::name, "Get the type name of collision") + .def( + "num_vertices", &collision_type::num_vertices, + "Get the number of vertices"); } -template void define_SmoothCollisions(py::module_& m, std::string name) { - py::class_>(m, name.c_str()) + py::class_(m, name.c_str()) .def(py::init()) .def( "build", py::overload_cast< - const CollisionMesh&, Eigen::ConstRef, const ParameterType, const bool, std::shared_ptr>(&SmoothCollisions::build), + const CollisionMesh&, Eigen::ConstRef, + const ParameterType, const bool, std::shared_ptr>( + &SmoothCollisions::build), R"ipc_Qu8mg5v7( Initialize the set of collisions used to compute the barrier potential. @@ -34,9 +36,11 @@ void define_SmoothCollisions(py::module_& m, std::string name) broad_phase: Broad phase method. )ipc_Qu8mg5v7", py::arg("mesh"), py::arg("vertices"), py::arg("param"), - py::arg("use_adaptive_dhat") = false, py::arg("broad_phase") = make_default_broad_phase()) + py::arg("use_adaptive_dhat") = false, + py::arg("broad_phase") = make_default_broad_phase()) .def( - "compute_minimum_distance", &SmoothCollisions::compute_minimum_distance, + "compute_minimum_distance", + &SmoothCollisions::compute_minimum_distance, R"ipc_Qu8mg5v7( Computes the minimum distance between any non-adjacent elements. @@ -48,12 +52,16 @@ void define_SmoothCollisions(py::module_& m, std::string name) The minimum distance between any non-adjacent elements. )ipc_Qu8mg5v7", py::arg("mesh"), py::arg("vertices")) - .def("__len__", &SmoothCollisions::size, "Get the number of collisions.") - .def("empty", &SmoothCollisions::empty, "Get if the collision set is empty.") - .def("clear", &SmoothCollisions::clear, "Clear the collision set.") + .def( + "__len__", &SmoothCollisions::size, "Get the number of collisions.") + .def( + "empty", &SmoothCollisions::empty, + "Get if the collision set is empty.") + .def("clear", &SmoothCollisions::clear, "Clear the collision set.") .def( "__getitem__", - [](SmoothCollisions& self, size_t i) -> typename SmoothCollisions::value_type& { return self[i]; }, + [](SmoothCollisions& self, size_t i) -> + typename SmoothCollisions::value_type& { return self[i]; }, py::return_value_policy::reference, R"ipc_Qu8mg5v7( Get a reference to collision at index i. @@ -66,9 +74,11 @@ void define_SmoothCollisions(py::module_& m, std::string name) )ipc_Qu8mg5v7", py::arg("i")) .def( - "to_string", &SmoothCollisions::to_string, py::arg("mesh"), + "to_string", &SmoothCollisions::to_string, py::arg("mesh"), py::arg("vertices"), py::arg("param")) - .def("n_candidates", &SmoothCollisions::n_candidates, "Get the number of candidates."); + .def( + "n_candidates", &SmoothCollisions::n_candidates, + "Get the number of candidates."); } void define_normal_collisions(py::module_& m) @@ -91,9 +101,8 @@ void define_normal_collisions(py::module_& m) dmin: Minimum distance. broad_phase: Broad-phase to use. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices"), py::arg("dhat"), - py::arg("dmin") = 0, - py::arg("broad_phase") = make_default_broad_phase()) + "mesh"_a, "vertices"_a, "dhat"_a, "dmin"_a = 0, + "broad_phase"_a = make_default_broad_phase()) .def( "build", py::overload_cast< @@ -110,8 +119,7 @@ void define_normal_collisions(py::module_& m) dhat: The activation distance of the barrier. dmin: Minimum distance. )ipc_Qu8mg5v7", - py::arg("candidates"), py::arg("mesh"), py::arg("vertices"), - py::arg("dhat"), py::arg("dmin") = 0) + "candidates"_a, "mesh"_a, "vertices"_a, "dhat"_a, "dmin"_a = 0) .def( "compute_minimum_distance", &NormalCollisions::compute_minimum_distance, @@ -125,7 +133,7 @@ void define_normal_collisions(py::module_& m) Returns: The minimum distance between any non-adjacent elements. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices")) + "mesh"_a, "vertices"_a) .def( "__len__", &NormalCollisions::size, "Get the number of collisions.") .def( @@ -147,7 +155,7 @@ void define_normal_collisions(py::module_& m) Returns: A reference to the collision. )ipc_Qu8mg5v7", - py::arg("i")) + "i"_a) .def( "is_vertex_vertex", &NormalCollisions::is_vertex_vertex, R"ipc_Qu8mg5v7( @@ -159,7 +167,7 @@ void define_normal_collisions(py::module_& m) Returns: If the collision at i is a vertex-vertex collision. )ipc_Qu8mg5v7", - py::arg("i")) + "i"_a) .def( "is_edge_vertex", &NormalCollisions::is_edge_vertex, R"ipc_Qu8mg5v7( @@ -171,7 +179,7 @@ void define_normal_collisions(py::module_& m) Returns: If the collision at i is an edge-vertex collision. )ipc_Qu8mg5v7", - py::arg("i")) + "i"_a) .def( "is_edge_edge", &NormalCollisions::is_edge_edge, R"ipc_Qu8mg5v7( @@ -183,7 +191,7 @@ void define_normal_collisions(py::module_& m) Returns: If the collision at i is an edge-edge collision. )ipc_Qu8mg5v7", - py::arg("i")) + "i"_a) .def( "is_face_vertex", &NormalCollisions::is_face_vertex, R"ipc_Qu8mg5v7( @@ -195,7 +203,7 @@ void define_normal_collisions(py::module_& m) Returns: If the collision at i is an face-vertex collision. )ipc_Qu8mg5v7", - py::arg("i")) + "i"_a) .def( "is_plane_vertex", &NormalCollisions::is_plane_vertex, R"ipc_Qu8mg5v7( @@ -207,10 +215,8 @@ void define_normal_collisions(py::module_& m) Returns: If the collision at i is an plane-vertex collision. )ipc_Qu8mg5v7", - py::arg("i")) - .def( - "__str__", &NormalCollisions::to_string, py::arg("mesh"), - py::arg("vertices")) + "i"_a) + .def("__str__", &NormalCollisions::to_string, "mesh"_a, "vertices"_a) .def_property( "use_area_weighting", &NormalCollisions::use_area_weighting, &NormalCollisions::set_use_area_weighting, @@ -231,11 +237,10 @@ void define_normal_collisions(py::module_& m) .def_readwrite("fv_collisions", &NormalCollisions::fv_collisions) .def_readwrite("pv_collisions", &NormalCollisions::pv_collisions); - py::class_>(m, "SmoothCollision2") - .def("n_dofs", &SmoothCollision<6>::n_dofs, "Get the degree of freedom") + py::class_(m, "SmoothCollision2") + .def("n_dofs", &SmoothCollision::n_dofs, "Get the degree of freedom") .def( - "__call__", - &SmoothCollision<6>::operator(), + "__call__", &SmoothCollision::operator(), R"ipc_Qu8mg5v7( Compute the potential. @@ -249,7 +254,7 @@ void define_normal_collisions(py::module_& m) py::arg("positions"), py::arg("params")) .def( "__getitem__", - [](SmoothCollision<6>& self, size_t i) -> long { return self[i]; }, + [](SmoothCollision& self, size_t i) -> long { return self[i]; }, R"ipc_Qu8mg5v7( Get primitive id. @@ -261,9 +266,12 @@ void define_normal_collisions(py::module_& m) )ipc_Qu8mg5v7", py::arg("i")); - define_SmoothCollisionTemplate, SmoothCollision<6>>(m, "Edge2Point2Collision"); - define_SmoothCollisionTemplate, SmoothCollision<6>>(m, "Point2Point2Collision"); + define_SmoothCollisionTemplate< + SmoothCollisionTemplate, SmoothCollision>( + m, "Edge2Point2Collision"); + define_SmoothCollisionTemplate< + SmoothCollisionTemplate, SmoothCollision>( + m, "Point2Point2Collision"); - define_SmoothCollisions<2>(m, "SmoothCollisions2"); - define_SmoothCollisions<3>(m, "SmoothCollisions3"); + define_SmoothCollisions(m, "SmoothCollisions"); } diff --git a/python/src/collisions/normal/plane_vertex.cpp b/python/src/collisions/normal/plane_vertex.cpp index a476a4635..07f727c32 100644 --- a/python/src/collisions/normal/plane_vertex.cpp +++ b/python/src/collisions/normal/plane_vertex.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_plane_vertex_normal_collision(py::module_& m) @@ -13,8 +12,7 @@ void define_plane_vertex_normal_collision(py::module_& m) py::init< Eigen::ConstRef, Eigen::ConstRef, const index_t>(), - py::arg("plane_origin"), py::arg("plane_normal"), - py::arg("vertex_id")) + "plane_origin"_a, "plane_normal"_a, "vertex_id"_a) .def_readwrite( "plane_origin", &PlaneVertexNormalCollision::plane_origin, "The plane's origin.") diff --git a/python/src/collisions/normal/vertex_vertex.cpp b/python/src/collisions/normal/vertex_vertex.cpp index e2293138d..c33261b39 100644 --- a/python/src/collisions/normal/vertex_vertex.cpp +++ b/python/src/collisions/normal/vertex_vertex.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_vertex_vertex_normal_collision(py::module_& m) @@ -10,14 +9,12 @@ void define_vertex_vertex_normal_collision(py::module_& m) py::class_< VertexVertexNormalCollision, VertexVertexCandidate, NormalCollision>( m, "VertexVertexNormalCollision") - .def( - py::init(), "", py::arg("vertex0_id"), - py::arg("vertex1_id")) - .def(py::init(), py::arg("vv_candidate")); + .def(py::init(), "", "vertex0_id"_a, "vertex1_id"_a) + .def(py::init(), "vv_candidate"_a); // .def( // py::init< // const index_t, const index_t, const double, // const Eigen::SparseVector&>(), - // py::arg("vertex0_id"), py::arg("vertex1_id"), py::arg("weight"), - // py::arg("weight_gradient")); + // "vertex0_id"_a, "vertex1_id"_a, "weight"_a, + // "weight_gradient"_a); } diff --git a/python/src/collisions/tangential/bindings.hpp b/python/src/collisions/tangential/bindings.hpp index 1deecfc31..491d4966f 100644 --- a/python/src/collisions/tangential/bindings.hpp +++ b/python/src/collisions/tangential/bindings.hpp @@ -1,7 +1,6 @@ #pragma once #include -namespace py = pybind11; void define_tangential_collision(py::module_& m); void define_tangential_collisions(py::module_& m); diff --git a/python/src/collisions/tangential/edge_edge.cpp b/python/src/collisions/tangential/edge_edge.cpp index eb80b1ea9..e91a57402 100644 --- a/python/src/collisions/tangential/edge_edge.cpp +++ b/python/src/collisions/tangential/edge_edge.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_edge_edge_tangential_collision(py::module_& m) @@ -10,11 +9,11 @@ void define_edge_edge_tangential_collision(py::module_& m) py::class_< EdgeEdgeTangentialCollision, EdgeEdgeCandidate, TangentialCollision>( m, "EdgeEdgeTangentialCollision") - .def(py::init(), py::arg("collision")) + .def(py::init(), "collision"_a) .def( py::init< const EdgeEdgeNormalCollision&, Eigen::ConstRef, const NormalPotential&, const double>(), - py::arg("collision"), py::arg("positions"), - py::arg("normal_potential"), py::arg("normal_stiffness")); + "collision"_a, "positions"_a, "normal_potential"_a, + "normal_stiffness"_a); } diff --git a/python/src/collisions/tangential/edge_vertex.cpp b/python/src/collisions/tangential/edge_vertex.cpp index 108ca9ced..d36cfbcd5 100644 --- a/python/src/collisions/tangential/edge_vertex.cpp +++ b/python/src/collisions/tangential/edge_vertex.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_edge_vertex_tangential_collision(py::module_& m) @@ -10,11 +9,11 @@ void define_edge_vertex_tangential_collision(py::module_& m) py::class_< EdgeVertexTangentialCollision, EdgeVertexCandidate, TangentialCollision>(m, "EdgeVertexTangentialCollision") - .def(py::init(), py::arg("collision")) + .def(py::init(), "collision"_a) .def( py::init< const EdgeVertexNormalCollision&, Eigen::ConstRef, const NormalPotential&, const double>(), - py::arg("collision"), py::arg("positions"), - py::arg("normal_potential"), py::arg("normal_stiffness")); + "collision"_a, "positions"_a, "normal_potential"_a, + "normal_stiffness"_a); } diff --git a/python/src/collisions/tangential/face_vertex.cpp b/python/src/collisions/tangential/face_vertex.cpp index df5a99ca0..9df8b4206 100644 --- a/python/src/collisions/tangential/face_vertex.cpp +++ b/python/src/collisions/tangential/face_vertex.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_face_vertex_tangential_collision(py::module_& m) @@ -10,11 +9,11 @@ void define_face_vertex_tangential_collision(py::module_& m) py::class_< FaceVertexTangentialCollision, FaceVertexCandidate, TangentialCollision>(m, "FaceVertexTangentialCollision") - .def(py::init(), py::arg("collision")) + .def(py::init(), "collision"_a) .def( py::init< const FaceVertexNormalCollision&, Eigen::ConstRef, const NormalPotential&, const double>(), - py::arg("collision"), py::arg("positions"), - py::arg("normal_potential"), py::arg("normal_stiffness")); + "collision"_a, "positions"_a, "normal_potential"_a, + "normal_stiffness"_a); } diff --git a/python/src/collisions/tangential/tangential_collision.cpp b/python/src/collisions/tangential/tangential_collision.cpp index 89167173e..9e1a24076 100644 --- a/python/src/collisions/tangential/tangential_collision.cpp +++ b/python/src/collisions/tangential/tangential_collision.cpp @@ -2,12 +2,11 @@ #include -namespace py = pybind11; using namespace ipc; void define_tangential_collision(py::module_& m) { - py::class_>(m, "TangentialCollision") + py::class_(m, "TangentialCollision") .def_property_readonly( "dim", &TangentialCollision::dim, "Get the dimension of the collision.") @@ -26,7 +25,7 @@ void define_tangential_collision(py::module_& m) Returns: Tangent basis of the collision. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "compute_tangent_basis_jacobian", &TangentialCollision::compute_tangent_basis_jacobian, @@ -39,7 +38,7 @@ void define_tangential_collision(py::module_& m) Returns: Jacobian of the tangent basis of the collision. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "compute_closest_point", &TangentialCollision::compute_closest_point, @@ -52,7 +51,7 @@ void define_tangential_collision(py::module_& m) Returns: Barycentric coordinates of the closest point. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "compute_closest_point_jacobian", &TangentialCollision::compute_closest_point_jacobian, @@ -65,7 +64,7 @@ void define_tangential_collision(py::module_& m) Returns: Jacobian of the barycentric coordinates of the closest point. )ipc_Qu8mg5v7", - py::arg("positions")) + "positions"_a) .def( "relative_velocity", &TangentialCollision::relative_velocity, R"ipc_Qu8mg5v7( @@ -77,7 +76,7 @@ void define_tangential_collision(py::module_& m) Returns: Relative velocity of the collision. )ipc_Qu8mg5v7", - py::arg("velocities")) + "velocities"_a) .def( "relative_velocity_matrix", py::overload_cast<>( @@ -104,7 +103,7 @@ void define_tangential_collision(py::module_& m) Returns: A matrix M such that `relative_velocity = M * velocities`. )ipc_Qu8mg5v7", - py::arg("closest_point")) + "closest_point"_a) .def( "relative_velocity_matrix_jacobian", &TangentialCollision::relative_velocity_matrix_jacobian, @@ -117,7 +116,7 @@ void define_tangential_collision(py::module_& m) Returns: Jacobian of the relative velocity premultiplier wrt the closest points. )ipc_Qu8mg5v7", - py::arg("closest_point")) + "closest_point"_a) .def_readwrite( "normal_force_magnitude", &TangentialCollision::normal_force_magnitude, diff --git a/python/src/collisions/tangential/tangential_collisions.cpp b/python/src/collisions/tangential/tangential_collisions.cpp index 8a9c697e5..e30c33f1f 100644 --- a/python/src/collisions/tangential/tangential_collisions.cpp +++ b/python/src/collisions/tangential/tangential_collisions.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_tangential_collisions(py::module_& m) @@ -15,9 +14,8 @@ void define_tangential_collisions(py::module_& m) const CollisionMesh&, Eigen::ConstRef, const NormalCollisions&, const NormalPotential&, double, double>(&TangentialCollisions::build), - py::arg("mesh"), py::arg("vertices"), py::arg("collisions"), - py::arg("normal_potential"), py::arg("normal_stiffness"), - py::arg("mu")) + "mesh"_a, "vertices"_a, "collisions"_a, "normal_potential"_a, + "normal_stiffness"_a, "mu"_a) .def( "build", [](TangentialCollisions& self, const CollisionMesh& mesh, @@ -30,9 +28,8 @@ void define_tangential_collisions(py::module_& m) mesh, vertices, collisions, normal_potential, normal_stiffness, mus); }, - py::arg("mesh"), py::arg("vertices"), py::arg("collisions"), - py::arg("normal_potential"), py::arg("normal_stiffness"), - py::arg("mus")) + "mesh"_a, "vertices"_a, "collisions"_a, "normal_potential"_a, + "normal_stiffness"_a, "mus"_a) .def( "build", py::overload_cast< @@ -41,9 +38,8 @@ void define_tangential_collisions(py::module_& m) Eigen::ConstRef, const std::function&>( &TangentialCollisions::build), - py::arg("mesh"), py::arg("vertices"), py::arg("collisions"), - py::arg("normal_potential"), py::arg("normal_stiffness"), - py::arg("mus"), py::arg("blend_mu")) + "mesh"_a, "vertices"_a, "collisions"_a, "normal_potential"_a, + "normal_stiffness"_a, "mus"_a, "blend_mu"_a) .def( "__len__", &TangentialCollisions::size, "Get the number of friction collisions.") @@ -68,10 +64,10 @@ void define_tangential_collisions(py::module_& m) Returns: A reference to the collision. )ipc_Qu8mg5v7", - py::arg("i")) + "i"_a) .def_static( "default_blend_mu", &TangentialCollisions::default_blend_mu, - py::arg("mu0"), py::arg("mu1")) + "mu0"_a, "mu1"_a) .def_readwrite("vv_collisions", &TangentialCollisions::vv_collisions) .def_readwrite("ev_collisions", &TangentialCollisions::ev_collisions) .def_readwrite("ee_collisions", &TangentialCollisions::ee_collisions) diff --git a/python/src/collisions/tangential/vertex_vertex.cpp b/python/src/collisions/tangential/vertex_vertex.cpp index e9e4e7749..468977e95 100644 --- a/python/src/collisions/tangential/vertex_vertex.cpp +++ b/python/src/collisions/tangential/vertex_vertex.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_vertex_vertex_tangential_collision(py::module_& m) @@ -10,14 +9,12 @@ void define_vertex_vertex_tangential_collision(py::module_& m) py::class_< VertexVertexTangentialCollision, VertexVertexCandidate, TangentialCollision>(m, "VertexVertexTangentialCollision") - .def( - py::init(), - py::arg("collision")) + .def(py::init(), "collision"_a) .def( py::init< const VertexVertexNormalCollision&, Eigen::ConstRef, const NormalPotential&, const double>(), - py::arg("collision"), py::arg("positions"), - py::arg("normal_potential"), py::arg("normal_stiffness")); + "collision"_a, "positions"_a, "normal_potential"_a, + "normal_stiffness"_a); } diff --git a/python/src/common.hpp b/python/src/common.hpp index 96ce9fc1c..2fc728f4c 100644 --- a/python/src/common.hpp +++ b/python/src/common.hpp @@ -9,6 +9,9 @@ #include #include +namespace py = pybind11; +using namespace py::literals; + #include #include @@ -17,7 +20,7 @@ void assert_2D_or_3D_vector( const Eigen::MatrixBase& v, const std::string& name) { if ((v.size() != 2 && v.size() != 3) || (v.rows() != 1 && v.cols() != 1)) { - throw pybind11::value_error( + throw py::value_error( "Parameter " + name + " has invalid size: expected " + name + " to be a 2D or 3D vector but got " + name + ".shape = [" + std::to_string(v.rows()) + ", " + std::to_string(v.cols()) + "]"); @@ -29,7 +32,7 @@ void assert_3D_vector( const Eigen::MatrixBase& v, const std::string& name) { if (v.size() != 3 || (v.rows() != 1 && v.cols() != 1)) { - throw pybind11::value_error( + throw py::value_error( "Parameter " + name + " has invalid size: expected " + name + " to be a 3D vector but got " + name + ".shape = [" + std::to_string(v.rows()) + ", " + std::to_string(v.cols()) + "]"); @@ -41,7 +44,7 @@ inline void assert_is_sparse_vector( const Eigen::SparseMatrix& M, const std::string& name) { if (M.cols() != 1) { - throw pybind11::value_error( + throw py::value_error( "Parameter " + name + " has invalid size: expected " + name + " to be a sparse vector but got " + name + ".shape = [" + std::to_string(M.rows()) + ", " + std::to_string(M.cols()) + "]"); diff --git a/python/src/distance/bindings.hpp b/python/src/distance/bindings.hpp index 4665ca399..1388f8384 100644 --- a/python/src/distance/bindings.hpp +++ b/python/src/distance/bindings.hpp @@ -1,7 +1,6 @@ #pragma once #include -namespace py = pybind11; void define_distance_type(py::module_& m); void define_edge_edge_mollifier(py::module_& m); diff --git a/python/src/distance/distance_type.cpp b/python/src/distance/distance_type.cpp index ebd099870..2a1259ff6 100644 --- a/python/src/distance/distance_type.cpp +++ b/python/src/distance/distance_type.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_distance_type(py::module_& m) @@ -99,7 +98,7 @@ void define_distance_type(py::module_& m) Returns: The distance type of the point-edge pair. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1")); + "p"_a, "e0"_a, "e1"_a); m.def( "point_triangle_distance_type", &point_triangle_distance_type, @@ -115,7 +114,7 @@ void define_distance_type(py::module_& m) Returns: The distance type of the point-triangle pair. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2")); + "p"_a, "t0"_a, "t1"_a, "t2"_a); m.def( "edge_edge_distance_type", &edge_edge_distance_type, @@ -131,7 +130,7 @@ void define_distance_type(py::module_& m) Returns: The distance type of the edge-edge pair. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "edge_edge_parallel_distance_type", &edge_edge_parallel_distance_type, @@ -147,5 +146,5 @@ void define_distance_type(py::module_& m) Returns: The distance type of the edge-edge pair. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); } diff --git a/python/src/distance/edge_edge.cpp b/python/src/distance/edge_edge.cpp index f7bc1c620..8db1ef867 100644 --- a/python/src/distance/edge_edge.cpp +++ b/python/src/distance/edge_edge.cpp @@ -3,7 +3,6 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_edge_edge_distance(py::module_& m) @@ -26,8 +25,8 @@ void define_edge_edge_distance(py::module_& m) Returns: The distance between the two edges. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1"), - py::arg("dtype") = EdgeEdgeDistanceType::AUTO); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a, + "dtype"_a = EdgeEdgeDistanceType::AUTO); m.def( "edge_edge_distance_gradient", &edge_edge_distance_gradient, @@ -47,8 +46,8 @@ void define_edge_edge_distance(py::module_& m) Returns: The gradient of the distance wrt ea0, ea1, eb0, and eb1. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1"), - py::arg("dtype") = EdgeEdgeDistanceType::AUTO); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a, + "dtype"_a = EdgeEdgeDistanceType::AUTO); m.def( "edge_edge_distance_hessian", &edge_edge_distance_hessian, @@ -68,6 +67,6 @@ void define_edge_edge_distance(py::module_& m) Returns: The hessian of the distance wrt ea0, ea1, eb0, and eb1. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1"), - py::arg("dtype") = EdgeEdgeDistanceType::AUTO); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a, + "dtype"_a = EdgeEdgeDistanceType::AUTO); } diff --git a/python/src/distance/edge_edge_mollifier.cpp b/python/src/distance/edge_edge_mollifier.cpp index 9dce8789f..a8efddba6 100644 --- a/python/src/distance/edge_edge_mollifier.cpp +++ b/python/src/distance/edge_edge_mollifier.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_edge_edge_mollifier(py::module_& m) @@ -21,7 +20,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The squared norm of the edge-edge cross product. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "edge_edge_cross_squarednorm_gradient", @@ -43,7 +42,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The gradient of the squared norm of the edge cross product wrt ea0, ea1, eb0, and eb1. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "edge_edge_cross_squarednorm_hessian", @@ -65,7 +64,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The hessian of the squared norm of the edge cross product wrt ea0, ea1, eb0, and eb1. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "edge_edge_mollifier", @@ -80,7 +79,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The mollifier coefficient to premultiply the edge-edge distance. )ipc_Qu8mg5v7", - py::arg("x"), py::arg("eps_x")); + "x"_a, "eps_x"_a); m.def( "edge_edge_mollifier_gradient", @@ -96,7 +95,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The gradient of the mollifier function for edge-edge distance wrt x. )ipc_Qu8mg5v7", - py::arg("x"), py::arg("eps_x")); + "x"_a, "eps_x"_a); m.def( "edge_edge_mollifier_derivative_wrt_eps_x", @@ -111,7 +110,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The derivative of the mollifier function for edge-edge distance wrt eps_x. )ipc_Qu8mg5v7", - py::arg("x"), py::arg("eps_x")); + "x"_a, "eps_x"_a); m.def( "edge_edge_mollifier_hessian", @@ -127,7 +126,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The hessian of the mollifier function for edge-edge distance wrt x. )ipc_Qu8mg5v7", - py::arg("x"), py::arg("eps_x")); + "x"_a, "eps_x"_a); m.def( "edge_edge_mollifier_gradient_derivative_wrt_eps_x", @@ -142,7 +141,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The derivative of the gradient of the mollifier function for edge-edge distance wrt eps_x. )ipc_Qu8mg5v7", - py::arg("x"), py::arg("eps_x")); + "x"_a, "eps_x"_a); m.def( "edge_edge_mollifier", @@ -167,8 +166,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The mollifier coefficient to premultiply the edge-edge distance. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1"), - py::arg("eps_x")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a, "eps_x"_a); m.def( "edge_edge_mollifier_gradient", @@ -191,8 +189,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The gradient of the mollifier. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1"), - py::arg("eps_x")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a, "eps_x"_a); m.def( "edge_edge_mollifier_hessian", @@ -215,8 +212,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The hessian of the mollifier. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1"), - py::arg("eps_x")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a, "eps_x"_a); m.def( "edge_edge_mollifier_gradient_wrt_x", @@ -237,9 +233,8 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The derivative of the mollifier wrt rest positions. )ipc_Qu8mg5v7", - py::arg("ea0_rest"), py::arg("ea1_rest"), py::arg("eb0_rest"), - py::arg("eb1_rest"), py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), - py::arg("eb1")); + "ea0_rest"_a, "ea1_rest"_a, "eb0_rest"_a, "eb1_rest"_a, "ea0"_a, + "ea1"_a, "eb0"_a, "eb1"_a); m.def( "edge_edge_mollifier_gradient_jacobian_wrt_x", @@ -263,9 +258,8 @@ void define_edge_edge_mollifier(py::module_& m) Returns: The jacobian of the mollifier's gradient wrt rest positions. )ipc_Qu8mg5v7", - py::arg("ea0_rest"), py::arg("ea1_rest"), py::arg("eb0_rest"), - py::arg("eb1_rest"), py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), - py::arg("eb1")); + "ea0_rest"_a, "ea1_rest"_a, "eb0_rest"_a, "eb1_rest"_a, "ea0"_a, + "ea1"_a, "eb0"_a, "eb1"_a); m.def( "edge_edge_mollifier_threshold", &edge_edge_mollifier_threshold, @@ -283,8 +277,7 @@ void define_edge_edge_mollifier(py::module_& m) Returns: Threshold for edge-edge mollification. )ipc_Qu8mg5v7", - py::arg("ea0_rest"), py::arg("ea1_rest"), py::arg("eb0_rest"), - py::arg("eb1_rest")); + "ea0_rest"_a, "ea1_rest"_a, "eb0_rest"_a, "eb1_rest"_a); m.def( "edge_edge_mollifier_threshold_gradient", @@ -303,6 +296,5 @@ void define_edge_edge_mollifier(py::module_& m) Returns: Gradient of the threshold for edge-edge mollification. )ipc_Qu8mg5v7", - py::arg("ea0_rest"), py::arg("ea1_rest"), py::arg("eb0_rest"), - py::arg("eb1_rest")); + "ea0_rest"_a, "ea1_rest"_a, "eb0_rest"_a, "eb1_rest"_a); } diff --git a/python/src/distance/line_line.cpp b/python/src/distance/line_line.cpp index 7dfbca8fb..42400816f 100644 --- a/python/src/distance/line_line.cpp +++ b/python/src/distance/line_line.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_line_line_distance(py::module_& m) @@ -27,7 +26,7 @@ void define_line_line_distance(py::module_& m) Returns: The distance between the two lines. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "line_line_distance_gradient", &line_line_distance_gradient, @@ -49,7 +48,7 @@ void define_line_line_distance(py::module_& m) Returns: The gradient of the distance wrt ea0, ea1, eb0, and eb1. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "line_line_distance_hessian", &line_line_distance_hessian, @@ -71,5 +70,5 @@ void define_line_line_distance(py::module_& m) Returns: The hessian of the distance wrt ea0, ea1, eb0, and eb1. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); } diff --git a/python/src/distance/point_edge.cpp b/python/src/distance/point_edge.cpp index 79b655eca..4b0a0fa8f 100644 --- a/python/src/distance/point_edge.cpp +++ b/python/src/distance/point_edge.cpp @@ -3,7 +3,6 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_point_edge_distance(py::module_& m) @@ -25,8 +24,7 @@ void define_point_edge_distance(py::module_& m) Returns: The distance between the point and edge. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1"), - py::arg("dtype") = PointEdgeDistanceType::AUTO); + "p"_a, "e0"_a, "e1"_a, "dtype"_a = PointEdgeDistanceType::AUTO); m.def( "point_edge_distance_gradient", &point_edge_distance_gradient, @@ -45,8 +43,7 @@ void define_point_edge_distance(py::module_& m) Returns: grad The gradient of the distance wrt p, e0, and e1. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1"), - py::arg("dtype") = PointEdgeDistanceType::AUTO); + "p"_a, "e0"_a, "e1"_a, "dtype"_a = PointEdgeDistanceType::AUTO); m.def( "point_edge_distance_hessian", &point_edge_distance_hessian, @@ -65,6 +62,5 @@ void define_point_edge_distance(py::module_& m) Returns: hess The hessian of the distance wrt p, e0, and e1. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1"), - py::arg("dtype") = PointEdgeDistanceType::AUTO); + "p"_a, "e0"_a, "e1"_a, "dtype"_a = PointEdgeDistanceType::AUTO); } diff --git a/python/src/distance/point_line.cpp b/python/src/distance/point_line.cpp index bb7b23973..c500f3661 100644 --- a/python/src/distance/point_line.cpp +++ b/python/src/distance/point_line.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_point_line_distance(py::module_& m) @@ -23,7 +22,7 @@ void define_point_line_distance(py::module_& m) Returns: The distance between the point and line. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1")); + "p"_a, "e0"_a, "e1"_a); m.def( "point_line_distance_gradient", &point_line_distance_gradient, @@ -41,7 +40,7 @@ void define_point_line_distance(py::module_& m) Returns: The gradient of the distance wrt p, e0, and e1. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1")); + "p"_a, "e0"_a, "e1"_a); m.def( "point_line_distance_hessian", &point_line_distance_hessian, @@ -59,5 +58,5 @@ void define_point_line_distance(py::module_& m) Returns: The hessian of the distance wrt p, e0, and e1. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1")); + "p"_a, "e0"_a, "e1"_a); } diff --git a/python/src/distance/point_plane.cpp b/python/src/distance/point_plane.cpp index b5a2b1bb3..48073a1ce 100644 --- a/python/src/distance/point_plane.cpp +++ b/python/src/distance/point_plane.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_point_plane_distance(py::module_& m) @@ -27,7 +26,7 @@ void define_point_plane_distance(py::module_& m) Returns: The distance between the point and plane. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("origin"), py::arg("normal")); + "p"_a, "origin"_a, "normal"_a); m.def( "point_plane_distance", @@ -51,7 +50,7 @@ void define_point_plane_distance(py::module_& m) Returns: The distance between the point and plane. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2")); + "p"_a, "t0"_a, "t1"_a, "t2"_a); m.def( "point_plane_distance_gradient", @@ -74,7 +73,7 @@ void define_point_plane_distance(py::module_& m) Returns: The gradient of the distance wrt p. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("origin"), py::arg("normal")); + "p"_a, "origin"_a, "normal"_a); m.def( "point_plane_distance_gradient", @@ -99,7 +98,7 @@ void define_point_plane_distance(py::module_& m) Returns: The gradient of the distance wrt p, t0, t1, and t2. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2")); + "p"_a, "t0"_a, "t1"_a, "t2"_a); m.def( "point_plane_distance_hessian", @@ -122,7 +121,7 @@ void define_point_plane_distance(py::module_& m) Returns: The hessian of the distance wrt p. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("origin"), py::arg("normal")); + "p"_a, "origin"_a, "normal"_a); m.def( "point_plane_distance_hessian", @@ -147,5 +146,5 @@ void define_point_plane_distance(py::module_& m) Returns: The hessian of the distance wrt p, t0, t1, and t2. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2")); + "p"_a, "t0"_a, "t1"_a, "t2"_a); } diff --git a/python/src/distance/point_point.cpp b/python/src/distance/point_point.cpp index 61e242312..401d161f8 100644 --- a/python/src/distance/point_point.cpp +++ b/python/src/distance/point_point.cpp @@ -3,7 +3,6 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_point_point_distance(py::module_& m) @@ -23,7 +22,7 @@ void define_point_point_distance(py::module_& m) Returns: The distance between p0 and p1. )ipc_Qu8mg5v7", - py::arg("p0"), py::arg("p1")); + "p0"_a, "p1"_a); m.def( "point_point_distance_gradient", &point_point_distance_gradient, @@ -40,7 +39,7 @@ void define_point_point_distance(py::module_& m) Returns: The computed gradient. )ipc_Qu8mg5v7", - py::arg("p0"), py::arg("p1")); + "p0"_a, "p1"_a); m.def( "point_point_distance_hessian", &point_point_distance_hessian, @@ -57,5 +56,5 @@ void define_point_point_distance(py::module_& m) Returns: The computed hessian. )ipc_Qu8mg5v7", - py::arg("p0"), py::arg("p1")); + "p0"_a, "p1"_a); } diff --git a/python/src/distance/point_triangle.cpp b/python/src/distance/point_triangle.cpp index 2ac91f825..eb3419a3b 100644 --- a/python/src/distance/point_triangle.cpp +++ b/python/src/distance/point_triangle.cpp @@ -3,7 +3,6 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_point_triangle_distance(py::module_& m) @@ -26,8 +25,8 @@ void define_point_triangle_distance(py::module_& m) Returns: The distance between the point and triangle. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2"), - py::arg("dtype") = PointTriangleDistanceType::AUTO); + "p"_a, "t0"_a, "t1"_a, "t2"_a, + "dtype"_a = PointTriangleDistanceType::AUTO); m.def( "point_triangle_distance_gradient", &point_triangle_distance_gradient, @@ -47,8 +46,8 @@ void define_point_triangle_distance(py::module_& m) Returns: The gradient of the distance wrt p, t0, t1, and t2. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2"), - py::arg("dtype") = PointTriangleDistanceType::AUTO); + "p"_a, "t0"_a, "t1"_a, "t2"_a, + "dtype"_a = PointTriangleDistanceType::AUTO); m.def( "point_triangle_distance_hessian", &point_triangle_distance_hessian, @@ -68,6 +67,6 @@ void define_point_triangle_distance(py::module_& m) Returns: The hessian of the distance wrt p, t0, t1, and t2. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2"), - py::arg("dtype") = PointTriangleDistanceType::AUTO); + "p"_a, "t0"_a, "t1"_a, "t2"_a, + "dtype"_a = PointTriangleDistanceType::AUTO); } diff --git a/python/src/friction/bindings.hpp b/python/src/friction/bindings.hpp index 4c939300d..82ee13fa8 100644 --- a/python/src/friction/bindings.hpp +++ b/python/src/friction/bindings.hpp @@ -1,6 +1,5 @@ #pragma once #include -namespace py = pybind11; void define_smooth_friction_mollifier(py::module_& m); \ No newline at end of file diff --git a/python/src/friction/smooth_friction_mollifier.cpp b/python/src/friction/smooth_friction_mollifier.cpp index c9029d3d6..ba9fe0d99 100644 --- a/python/src/friction/smooth_friction_mollifier.cpp +++ b/python/src/friction/smooth_friction_mollifier.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_smooth_friction_mollifier(py::module_& m) @@ -28,7 +27,7 @@ void define_smooth_friction_mollifier(py::module_& m) Returns: The value of the mollifier function at y. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_v")); + "y"_a, "eps_v"_a); m.def( "smooth_friction_f1", &smooth_friction_f1, @@ -49,7 +48,7 @@ void define_smooth_friction_mollifier(py::module_& m) Returns: The value of the derivative of the smooth friction mollifier at y. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_v")); + "y"_a, "eps_v"_a); m.def( "smooth_friction_f2", &smooth_friction_f2, @@ -70,7 +69,7 @@ void define_smooth_friction_mollifier(py::module_& m) Returns: The value of the second derivative of the smooth friction mollifier at y. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_v")); + "y"_a, "eps_v"_a); m.def( "smooth_friction_f1_over_x", &smooth_friction_f1_over_x, @@ -91,7 +90,7 @@ void define_smooth_friction_mollifier(py::module_& m) Returns: The value of the derivative of smooth_friction_f0 divided by y. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_v")); + "y"_a, "eps_v"_a); m.def( "smooth_friction_f2_x_minus_f1_over_x3", @@ -113,5 +112,5 @@ void define_smooth_friction_mollifier(py::module_& m) Returns: The derivative of f1 times y minus f1 all divided by y cubed. )ipc_Qu8mg5v7", - py::arg("y"), py::arg("eps_v")); + "y"_a, "eps_v"_a); } diff --git a/python/src/implicits/bindings.hpp b/python/src/implicits/bindings.hpp index cc185ff78..df6ab2e47 100644 --- a/python/src/implicits/bindings.hpp +++ b/python/src/implicits/bindings.hpp @@ -1,6 +1,5 @@ #pragma once #include -namespace py = pybind11; void define_plane_implicit(py::module_& m); \ No newline at end of file diff --git a/python/src/implicits/plane.cpp b/python/src/implicits/plane.cpp index d8d36de8b..ef3c02839 100644 --- a/python/src/implicits/plane.cpp +++ b/python/src/implicits/plane.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_plane_implicit(py::module_& m) @@ -37,8 +36,8 @@ void define_plane_implicit(py::module_& m) Returns: The constructed set of collisions. )ipc_Qu8mg5v7", - py::arg("points"), py::arg("plane_origins"), py::arg("plane_normals"), - py::arg("dhat"), py::arg("dmin") = 0); + "points"_a, "plane_origins"_a, "plane_normals"_a, "dhat"_a, + "dmin"_a = 0); m.def( "construct_point_plane_collisions", @@ -72,8 +71,8 @@ void define_plane_implicit(py::module_& m) Returns: The constructed set of collisions. )ipc_Qu8mg5v7", - py::arg("points"), py::arg("plane_origins"), py::arg("plane_normals"), - py::arg("dhat"), py::arg("dmin"), py::arg("can_collide")); + "points"_a, "plane_origins"_a, "plane_normals"_a, "dhat"_a, "dmin"_a, + "can_collide"_a); m.def( "is_step_point_plane_collision_free", @@ -99,8 +98,7 @@ void define_plane_implicit(py::module_& m) Returns: True if any collisions occur. )ipc_Qu8mg5v7", - py::arg("points_t0"), py::arg("points_t1"), py::arg("plane_origins"), - py::arg("plane_normals")); + "points_t0"_a, "points_t1"_a, "plane_origins"_a, "plane_normals"_a); m.def( "is_step_point_plane_collision_free", @@ -129,8 +127,8 @@ void define_plane_implicit(py::module_& m) Returns: True if any collisions occur. )ipc_Qu8mg5v7", - py::arg("points_t0"), py::arg("points_t1"), py::arg("plane_origins"), - py::arg("plane_normals"), py::arg("can_collide")); + "points_t0"_a, "points_t1"_a, "plane_origins"_a, "plane_normals"_a, + "can_collide"_a); m.def( "compute_point_plane_collision_free_stepsize", @@ -159,8 +157,7 @@ void define_plane_implicit(py::module_& m) Returns: A step-size $\in [0, 1]$ that is collision free. )ipc_Qu8mg5v7", - py::arg("points_t0"), py::arg("points_t1"), py::arg("plane_origins"), - py::arg("plane_normals")); + "points_t0"_a, "points_t1"_a, "plane_origins"_a, "plane_normals"_a); m.def( "compute_point_plane_collision_free_stepsize", @@ -191,6 +188,6 @@ void define_plane_implicit(py::module_& m) Returns: A step-size $\in [0, 1]$ that is collision free. )ipc_Qu8mg5v7", - py::arg("points_t0"), py::arg("points_t1"), py::arg("plane_origins"), - py::arg("plane_normals"), py::arg("can_collide")); + "points_t0"_a, "points_t1"_a, "plane_origins"_a, "plane_normals"_a, + "can_collide"_a); } diff --git a/python/src/ipc.cpp b/python/src/ipc.cpp index f4e84942d..eb81bcb3f 100644 --- a/python/src/ipc.cpp +++ b/python/src/ipc.cpp @@ -5,7 +5,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_ipc(py::module_& m) @@ -31,10 +30,9 @@ void define_ipc(py::module_& m) Returns: True if any collisions occur. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices_t0"), py::arg("vertices_t1"), - py::arg("min_distance") = 0.0, - py::arg("broad_phase") = make_default_broad_phase(), - py::arg("narrow_phase_ccd") = DEFAULT_NARROW_PHASE_CCD); + "mesh"_a, "vertices_t0"_a, "vertices_t1"_a, "min_distance"_a = 0.0, + "broad_phase"_a = make_default_broad_phase(), + "narrow_phase_ccd"_a = DEFAULT_NARROW_PHASE_CCD); m.def( "compute_collision_free_stepsize", &compute_collision_free_stepsize, @@ -55,10 +53,9 @@ void define_ipc(py::module_& m) Returns: A step-size :math:`\in [0, 1]` that is collision free. A value of 1.0 if a full step and 0.0 is no step. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices_t0"), py::arg("vertices_t1"), - py::arg("min_distance") = 0.0, - py::arg("broad_phase") = make_default_broad_phase(), - py::arg("narrow_phase_ccd") = DEFAULT_NARROW_PHASE_CCD); + "mesh"_a, "vertices_t0"_a, "vertices_t1"_a, "min_distance"_a = 0.0, + "broad_phase"_a = make_default_broad_phase(), + "narrow_phase_ccd"_a = DEFAULT_NARROW_PHASE_CCD); m.def( "has_intersections", &has_intersections, @@ -73,8 +70,7 @@ void define_ipc(py::module_& m) Returns: A boolean for if the mesh has intersections. )ipc_Qu8mg5v7", - py::arg("mesh"), py::arg("vertices"), - py::arg("broad_phase") = make_default_broad_phase()); + "mesh"_a, "vertices"_a, "broad_phase"_a = make_default_broad_phase()); m.def( "edges", @@ -92,5 +88,5 @@ void define_ipc(py::module_& m) Returns: #E by 2 list of edges in no particular order )ipc_Qu8mg5v7", - py::arg("F")); + "F"_a); } diff --git a/python/src/potentials/barrier_potential.cpp b/python/src/potentials/barrier_potential.cpp index b0b8eeef8..f5ec5200e 100644 --- a/python/src/potentials/barrier_potential.cpp +++ b/python/src/potentials/barrier_potential.cpp @@ -3,7 +3,6 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_barrier_potential(py::module_& m) @@ -17,7 +16,7 @@ void define_barrier_potential(py::module_& m) Parameters: dhat: The activation distance of the barrier. )ipc_Qu8mg5v7", - py::arg("dhat"), py::arg("use_physical_barrier") = false) + "dhat"_a, "use_physical_barrier"_a = false) .def( py::init< const std::shared_ptr, const double, const bool>(), @@ -28,8 +27,7 @@ void define_barrier_potential(py::module_& m) barrier: The barrier function. dhat: The activation distance of the barrier. )ipc_Qu8mg5v7", - py::arg("barrier"), py::arg("dhat"), - py::arg("use_physical_barrier") = false) + "barrier"_a, "dhat"_a, "use_physical_barrier"_a = false) .def_property( "dhat", &BarrierPotential::dhat, &BarrierPotential::set_dhat, "Barrier activation distance.") @@ -73,8 +71,7 @@ void define_smooth_potential(py::module_& m) .def_readonly("beta_n", &ParameterType::beta_n) .def_readonly("r", &ParameterType::r); - py::class_>>( - m, "SmoothPotential") + py::class_(m, "SmoothPotential") .def( py::init(), R"ipc_Qu8mg5v7( @@ -87,11 +84,9 @@ void define_smooth_potential(py::module_& m) .def( "__call__", py::overload_cast< - const SmoothCollisions<2>&, const CollisionMesh&, + const SmoothCollisions&, const CollisionMesh&, Eigen::ConstRef>( - &SmoothContactPotential< - SmoothCollisions<2>>::Potential::operator(), - py::const_), + &ipc::SmoothContactPotential::operator(), py::const_), R"ipc_Qu8mg5v7( Compute the barrier potential for a set of collisions. @@ -107,11 +102,9 @@ void define_smooth_potential(py::module_& m) .def( "gradient", py::overload_cast< - const SmoothCollisions<2>&, const CollisionMesh&, + const SmoothCollisions&, const CollisionMesh&, Eigen::ConstRef>( - &SmoothContactPotential< - SmoothCollisions<2>>::Potential::gradient, - py::const_), + &ipc::SmoothContactPotential::gradient, py::const_), R"ipc_Qu8mg5v7( Compute the gradient of the barrier potential. @@ -127,11 +120,9 @@ void define_smooth_potential(py::module_& m) .def( "hessian", py::overload_cast< - const SmoothCollisions<2>&, const CollisionMesh&, + const SmoothCollisions&, const CollisionMesh&, Eigen::ConstRef, const PSDProjectionMethod>( - &SmoothContactPotential< - SmoothCollisions<2>>::Potential::hessian, - py::const_), + &ipc::SmoothContactPotential::hessian, py::const_), R"ipc_Qu8mg5v7( Compute the hessian of the barrier potential. @@ -149,9 +140,8 @@ void define_smooth_potential(py::module_& m) .def( "__call__", py::overload_cast< - const SmoothCollision<6>&, Eigen::ConstRef>>( - &SmoothContactPotential>::operator(), - py::const_), + const SmoothCollision&, Eigen::ConstRef>( + &ipc::SmoothContactPotential::operator(), py::const_), R"ipc_Qu8mg5v7( Compute the potential for a single collision. @@ -166,9 +156,8 @@ void define_smooth_potential(py::module_& m) .def( "gradient", py::overload_cast< - const SmoothCollision<6>&, Eigen::ConstRef>>( - &SmoothContactPotential>::gradient, - py::const_), + const SmoothCollision&, Eigen::ConstRef>( + &SmoothContactPotential::gradient, py::const_), R"ipc_Qu8mg5v7( Compute the gradient of the potential for a single collision. @@ -183,10 +172,9 @@ void define_smooth_potential(py::module_& m) .def( "hessian", py::overload_cast< - const SmoothCollision<6>&, Eigen::ConstRef>, + const SmoothCollision&, Eigen::ConstRef, const PSDProjectionMethod>( - &SmoothContactPotential>::hessian, - py::const_), + &SmoothContactPotential::hessian, py::const_), R"ipc_Qu8mg5v7( Compute the hessian of the potential for a single collision. diff --git a/python/src/potentials/bindings.hpp b/python/src/potentials/bindings.hpp index 04b58cf5c..00d61f6d3 100644 --- a/python/src/potentials/bindings.hpp +++ b/python/src/potentials/bindings.hpp @@ -1,7 +1,6 @@ #pragma once #include -namespace py = pybind11; void define_barrier_potential(py::module_& m); void define_smooth_potential(py::module_& m); diff --git a/python/src/potentials/friction_potential.cpp b/python/src/potentials/friction_potential.cpp index 58cd9db1d..0150ce32d 100644 --- a/python/src/potentials/friction_potential.cpp +++ b/python/src/potentials/friction_potential.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_friction_potential(py::module_& m) @@ -16,7 +15,7 @@ void define_friction_potential(py::module_& m) Parameters: eps_v: The smooth friction mollifier parameter :math:`\\epsilon_{v}`. )ipc_Qu8mg5v7", - py::arg("eps_v")) + "eps_v"_a) .def_property( "eps_v", &FrictionPotential::eps_v, &FrictionPotential::set_eps_v, "The smooth friction mollifier parameter :math:`\\epsilon_{v}`."); diff --git a/python/src/potentials/normal_adhesion_potential.cpp b/python/src/potentials/normal_adhesion_potential.cpp index c886cbfc5..13f76d988 100644 --- a/python/src/potentials/normal_adhesion_potential.cpp +++ b/python/src/potentials/normal_adhesion_potential.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_normal_adhesion_potential(py::module_& m) @@ -11,8 +10,7 @@ void define_normal_adhesion_potential(py::module_& m) m, "NormalAdhesionPotential") .def( py::init(), - py::arg("dhat_p"), py::arg("dhat_a"), py::arg("Y"), - py::arg("eps_c")) + "dhat_p"_a, "dhat_a"_a, "Y"_a, "eps_c"_a) .def_readwrite( "dhat_p", &NormalAdhesionPotential::dhat_p, "The distance of largest adhesion force (:math:`\\hat{d}_{p}`) (:math:`0 < \\hat{d}_{p} < \\hat{d}_{a}`).") diff --git a/python/src/potentials/normal_potential.cpp b/python/src/potentials/normal_potential.cpp index b36239738..46bbdd6cc 100644 --- a/python/src/potentials/normal_potential.cpp +++ b/python/src/potentials/normal_potential.cpp @@ -3,7 +3,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_normal_potential(py::module_& m) @@ -32,7 +31,7 @@ void define_normal_potential(py::module_& m) Returns: The derivative of the force with respect to X, the rest vertices. )ipc_Qu8mg5v7", - py::arg("collisions"), py::arg("mesh"), py::arg("vertices")) + "collisions"_a, "mesh"_a, "vertices"_a) .def( "shape_derivative", [](const NormalPotential& self, const NormalCollision& collision, @@ -54,8 +53,7 @@ void define_normal_potential(py::module_& m) positions: The collision stencil's positions. ,out]: out Store the triplets of the shape derivative here. )ipc_Qu8mg5v7", - py::arg("collision"), py::arg("vertex_ids"), - py::arg("rest_positions"), py::arg("positions")) + "collision"_a, "vertex_ids"_a, "rest_positions"_a, "positions"_a) .def( "force_magnitude", &NormalPotential::force_magnitude, R"ipc_Qu8mg5v7( @@ -69,8 +67,7 @@ void define_normal_potential(py::module_& m) Returns: The force magnitude. )ipc_Qu8mg5v7", - py::arg("distance_squared"), py::arg("dmin"), - py::arg("barrier_stiffness")) + "distance_squared"_a, "dmin"_a, "barrier_stiffness"_a) .def( "force_magnitude_gradient", &NormalPotential::force_magnitude_gradient, @@ -86,6 +83,6 @@ void define_normal_potential(py::module_& m) Returns: The gradient of the force. )ipc_Qu8mg5v7", - py::arg("distance_squared"), py::arg("distance_squared_gradient"), - py::arg("dmin"), py::arg("barrier_stiffness")); + "distance_squared"_a, "distance_squared_gradient"_a, "dmin"_a, + "barrier_stiffness"_a); } diff --git a/python/src/potentials/potential.hpp b/python/src/potentials/potential.hpp index bdff0ad7e..0a58b833a 100644 --- a/python/src/potentials/potential.hpp +++ b/python/src/potentials/potential.hpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; /// @brief Define the methods of the templated generic Potential class. @@ -32,7 +31,7 @@ void define_potential_methods(PyClass& potential) Returns: The potential for a set of collisions. )ipc_Qu8mg5v7", - py::arg("collisions"), py::arg("mesh"), py::arg("X")) + "collisions"_a, "mesh"_a, "X"_a) .def( "gradient", py::overload_cast< @@ -50,7 +49,7 @@ void define_potential_methods(PyClass& potential) Returns: The gradient of the potential w.r.t. X. This will have a size of |X|. )ipc_Qu8mg5v7", - py::arg("collisions"), py::arg("mesh"), py::arg("X")) + "collisions"_a, "mesh"_a, "X"_a) .def( "hessian", py::overload_cast< @@ -69,8 +68,8 @@ void define_potential_methods(PyClass& potential) Returns: The Hessian of the potential w.r.t. X. This will have a size of |X|×|X|. )ipc_Qu8mg5v7", - py::arg("collisions"), py::arg("mesh"), py::arg("X"), - py::arg("project_hessian_to_psd") = PSDProjectionMethod::NONE) + "collisions"_a, "mesh"_a, "X"_a, + "project_hessian_to_psd"_a = PSDProjectionMethod::NONE) .def( "__call__", py::overload_cast>( @@ -85,7 +84,7 @@ void define_potential_methods(PyClass& potential) Returns: The potential. )ipc_Qu8mg5v7", - py::arg("collision"), py::arg("x")) + "collision"_a, "x"_a) .def( "gradient", py::overload_cast>( @@ -100,7 +99,7 @@ void define_potential_methods(PyClass& potential) Returns: The gradient of the potential. )ipc_Qu8mg5v7", - py::arg("collision"), py::arg("x")) + "collision"_a, "x"_a) .def( "hessian", py::overload_cast< @@ -117,6 +116,6 @@ void define_potential_methods(PyClass& potential) Returns: The hessian of the potential. )ipc_Qu8mg5v7", - py::arg("collision"), py::arg("x"), - py::arg("project_hessian_to_psd") = PSDProjectionMethod::NONE); + "collision"_a, "x"_a, + "project_hessian_to_psd"_a = PSDProjectionMethod::NONE); } diff --git a/python/src/potentials/tangential_adhesion_potential.cpp b/python/src/potentials/tangential_adhesion_potential.cpp index 08b411a13..87113610d 100644 --- a/python/src/potentials/tangential_adhesion_potential.cpp +++ b/python/src/potentials/tangential_adhesion_potential.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_tangential_adhesion_potential(py::module_& m) @@ -17,7 +16,7 @@ void define_tangential_adhesion_potential(py::module_& m) Parameters: eps_a: The tangential adhesion mollifier parameter :math:`\epsilon_a`. )ipc_Qu8mg5v7", - py::arg("eps_a")) + "eps_a"_a) .def_property( "eps_a", &TangentialAdhesionPotential::eps_a, &TangentialAdhesionPotential::set_eps_a, diff --git a/python/src/potentials/tangential_potential.cpp b/python/src/potentials/tangential_potential.cpp index fa6eab7e4..8e53c3dae 100644 --- a/python/src/potentials/tangential_potential.cpp +++ b/python/src/potentials/tangential_potential.cpp @@ -3,7 +3,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_tangential_potential(py::module_& m) @@ -53,10 +52,9 @@ void define_tangential_potential(py::module_& m) Returns: The friction force. )ipc_Qu8mg5v7", - py::arg("collisions"), py::arg("mesh"), py::arg("rest_positions"), - py::arg("lagged_displacements"), py::arg("velocities"), - py::arg("normal_potential"), py::arg("normal_stiffness"), - py::arg("dmin") = 0, py::arg("no_mu") = false) + "collisions"_a, "mesh"_a, "rest_positions"_a, + "lagged_displacements"_a, "velocities"_a, "normal_potential"_a, + "normal_stiffness"_a, "dmin"_a = 0, "no_mu"_a = false) .def( "force_jacobian", py::overload_cast< @@ -83,10 +81,9 @@ void define_tangential_potential(py::module_& m) Returns: The Jacobian of the friction force wrt the velocities. )ipc_Qu8mg5v7", - py::arg("collisions"), py::arg("mesh"), py::arg("rest_positions"), - py::arg("lagged_displacements"), py::arg("velocities"), - py::arg("normal_potential"), py::arg("normal_stiffness"), - py::arg("wrt"), py::arg("dmin") = 0) + "collisions"_a, "mesh"_a, "rest_positions"_a, + "lagged_displacements"_a, "velocities"_a, "normal_potential"_a, + "normal_stiffness"_a, "wrt"_a, "dmin"_a = 0) .def( "force", py::overload_cast< @@ -110,10 +107,9 @@ void define_tangential_potential(py::module_& m) Returns: Friction force )ipc_Qu8mg5v7", - py::arg("collision"), py::arg("rest_positions"), - py::arg("lagged_displacements"), py::arg("velocities"), - py::arg("normal_potential"), py::arg("normal_stiffness"), - py::arg("dmin") = 0, py::arg("no_mu") = false) + "collision"_a, "rest_positions"_a, "lagged_displacements"_a, + "velocities"_a, "normal_potential"_a, "normal_stiffness"_a, + "dmin"_a = 0, "no_mu"_a = false) .def( "force_jacobian", py::overload_cast< @@ -138,8 +134,7 @@ void define_tangential_potential(py::module_& m) Returns: Friction force Jacobian )ipc_Qu8mg5v7", - py::arg("collision"), py::arg("rest_positions"), - py::arg("lagged_displacements"), py::arg("velocities"), - py::arg("normal_potential"), py::arg("normal_stiffness"), - py::arg("wrt"), py::arg("dmin") = 0); + "collision"_a, "rest_positions"_a, "lagged_displacements"_a, + "velocities"_a, "normal_potential"_a, "normal_stiffness"_a, "wrt"_a, + "dmin"_a = 0); } diff --git a/python/src/tangent/bindings.hpp b/python/src/tangent/bindings.hpp index 92fd8fc9f..5e74c5ec0 100644 --- a/python/src/tangent/bindings.hpp +++ b/python/src/tangent/bindings.hpp @@ -1,7 +1,6 @@ #pragma once #include -namespace py = pybind11; void define_closest_point(py::module_& m); void define_relative_velocity(py::module_& m); diff --git a/python/src/tangent/closest_point.cpp b/python/src/tangent/closest_point.cpp index c2cae085a..7c033e94b 100644 --- a/python/src/tangent/closest_point.cpp +++ b/python/src/tangent/closest_point.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_closest_point(py::module_& m) @@ -17,7 +16,7 @@ void define_closest_point(py::module_& m) return point_edge_closest_point(p, e0, e1); }, R"ipc_Qu8mg5v7( - Compute the baricentric coordinate of the closest point on the edge. + Compute the barycentric coordinate of the closest point on the edge. Parameters: p: Point @@ -27,7 +26,7 @@ void define_closest_point(py::module_& m) Returns: barycentric coordinates of the closest point )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1")); + "p"_a, "e0"_a, "e1"_a); m.def( "point_edge_closest_point_jacobian", @@ -49,7 +48,7 @@ void define_closest_point(py::module_& m) Returns: Jacobian of the closest point )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1")); + "p"_a, "e0"_a, "e1"_a); m.def( "edge_edge_closest_point", @@ -71,7 +70,7 @@ void define_closest_point(py::module_& m) Returns: Barycentric coordinates of the closest points )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "edge_edge_closest_point_jacobian", @@ -93,7 +92,7 @@ void define_closest_point(py::module_& m) Returns: Jacobian of the closest points )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "point_triangle_closest_point", @@ -115,7 +114,7 @@ void define_closest_point(py::module_& m) Returns: Barycentric coordinates of the closest point )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2")); + "p"_a, "t0"_a, "t1"_a, "t2"_a); m.def( "point_triangle_closest_point_jacobian", @@ -137,5 +136,5 @@ void define_closest_point(py::module_& m) Returns: Jacobian of the closest point )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2")); + "p"_a, "t0"_a, "t1"_a, "t2"_a); } diff --git a/python/src/tangent/relative_velocity.cpp b/python/src/tangent/relative_velocity.cpp index 6b2396498..591b23a18 100644 --- a/python/src/tangent/relative_velocity.cpp +++ b/python/src/tangent/relative_velocity.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_relative_velocity(py::module_& m) @@ -19,7 +18,7 @@ void define_relative_velocity(py::module_& m) Returns: The relative velocity of the two points )ipc_Qu8mg5v7", - py::arg("dp0"), py::arg("dp1")); + "dp0"_a, "dp1"_a); m.def( "point_point_relative_velocity_matrix", @@ -33,7 +32,7 @@ void define_relative_velocity(py::module_& m) Returns: The relative velocity premultiplier matrix )ipc_Qu8mg5v7", - py::arg("dim")); + "dim"_a); m.def( "point_point_relative_velocity_matrix_jacobian", @@ -47,7 +46,7 @@ void define_relative_velocity(py::module_& m) Returns: The Jacobian of the relative velocity premultiplier matrix )ipc_Qu8mg5v7", - py::arg("dim")); + "dim"_a); m.def( "point_edge_relative_velocity", &point_edge_relative_velocity, @@ -63,7 +62,7 @@ void define_relative_velocity(py::module_& m) Returns: The relative velocity of the point and the edge )ipc_Qu8mg5v7", - py::arg("dp"), py::arg("de0"), py::arg("de1"), py::arg("alpha")); + "dp"_a, "de0"_a, "de1"_a, "alpha"_a); m.def( "point_edge_relative_velocity_matrix", @@ -78,7 +77,7 @@ void define_relative_velocity(py::module_& m) Returns: The relative velocity premultiplier matrix )ipc_Qu8mg5v7", - py::arg("dim"), py::arg("alpha")); + "dim"_a, "alpha"_a); m.def( "point_edge_relative_velocity_matrix_jacobian", @@ -93,7 +92,7 @@ void define_relative_velocity(py::module_& m) Returns: The Jacobian of the relative velocity premultiplier matrix )ipc_Qu8mg5v7", - py::arg("dim"), py::arg("alpha")); + "dim"_a, "alpha"_a); m.def( "edge_edge_relative_velocity", &edge_edge_relative_velocity, @@ -110,8 +109,7 @@ void define_relative_velocity(py::module_& m) Returns: The relative velocity of the edges )ipc_Qu8mg5v7", - py::arg("dea0"), py::arg("dea1"), py::arg("deb0"), py::arg("deb1"), - py::arg("coords")); + "dea0"_a, "dea1"_a, "deb0"_a, "deb1"_a, "coords"_a); m.def( "edge_edge_relative_velocity_matrix", @@ -126,7 +124,7 @@ void define_relative_velocity(py::module_& m) Returns: The relative velocity matrix )ipc_Qu8mg5v7", - py::arg("dim"), py::arg("coords")); + "dim"_a, "coords"_a); m.def( "edge_edge_relative_velocity_matrix_jacobian", @@ -141,7 +139,7 @@ void define_relative_velocity(py::module_& m) Returns: The Jacobian of the relative velocity matrix )ipc_Qu8mg5v7", - py::arg("dim"), py::arg("coords")); + "dim"_a, "coords"_a); m.def( "point_triangle_relative_velocity", &point_triangle_relative_velocity, @@ -153,13 +151,12 @@ void define_relative_velocity(py::module_& m) dt0: Velocity of the first vertex of the triangle dt1: Velocity of the second vertex of the triangle dt2: Velocity of the third vertex of the triangle - coords: Baricentric coordinates of the closest point on the triangle + coords: Barycentric coordinates of the closest point on the triangle Returns: The relative velocity of the point to the triangle )ipc_Qu8mg5v7", - py::arg("dp"), py::arg("dt0"), py::arg("dt1"), py::arg("dt2"), - py::arg("coords")); + "dp"_a, "dt0"_a, "dt1"_a, "dt2"_a, "coords"_a); m.def( "point_triangle_relative_velocity_matrix", @@ -169,12 +166,12 @@ void define_relative_velocity(py::module_& m) Parameters: dim: Dimension (2 or 3) - coords: Baricentric coordinates of the closest point on the triangle + coords: Barycentric coordinates of the closest point on the triangle Returns: The relative velocity matrix )ipc_Qu8mg5v7", - py::arg("dim"), py::arg("coords")); + "dim"_a, "coords"_a); m.def( "point_triangle_relative_velocity_matrix_jacobian", @@ -184,10 +181,10 @@ void define_relative_velocity(py::module_& m) Parameters: dim: Dimension (2 or 3) - coords: Baricentric coordinates of the closest point on the triangle + coords: Barycentric coordinates of the closest point on the triangle Returns: The Jacobian of the relative velocity matrix )ipc_Qu8mg5v7", - py::arg("dim"), py::arg("coords")); + "dim"_a, "coords"_a); } diff --git a/python/src/tangent/tangent_basis.cpp b/python/src/tangent/tangent_basis.cpp index 4539d8b94..a25112d69 100644 --- a/python/src/tangent/tangent_basis.cpp +++ b/python/src/tangent/tangent_basis.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_tangent_basis(py::module_& m) @@ -24,7 +23,7 @@ void define_tangent_basis(py::module_& m) Returns: A 3x2 matrix whose columns are the basis vectors. )ipc_Qu8mg5v7", - py::arg("p0"), py::arg("p1")); + "p0"_a, "p1"_a); m.def( "point_point_tangent_basis_jacobian", @@ -43,7 +42,7 @@ void define_tangent_basis(py::module_& m) Returns: A 6*3x2 matrix whose columns are the basis vectors. )ipc_Qu8mg5v7", - py::arg("p0"), py::arg("p1")); + "p0"_a, "p1"_a); m.def( "point_edge_tangent_basis", @@ -65,7 +64,7 @@ void define_tangent_basis(py::module_& m) Returns: A 3x2 matrix whose columns are the basis vectors. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1")); + "p"_a, "e0"_a, "e1"_a); m.def( "point_edge_tangent_basis_jacobian", @@ -87,7 +86,7 @@ void define_tangent_basis(py::module_& m) Returns: A 9*3x2 matrix whose columns are the basis vectors. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("e0"), py::arg("e1")); + "p"_a, "e0"_a, "e1"_a); m.def( "edge_edge_tangent_basis", @@ -109,7 +108,7 @@ void define_tangent_basis(py::module_& m) Returns: A 3x2 matrix whose columns are the basis vectors. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "edge_edge_tangent_basis_jacobian", @@ -131,7 +130,7 @@ void define_tangent_basis(py::module_& m) Returns: A 12*3x2 matrix whose columns are the basis vectors. )ipc_Qu8mg5v7", - py::arg("ea0"), py::arg("ea1"), py::arg("eb0"), py::arg("eb1")); + "ea0"_a, "ea1"_a, "eb0"_a, "eb1"_a); m.def( "point_triangle_tangent_basis", @@ -160,7 +159,7 @@ void define_tangent_basis(py::module_& m) Returns: A 3x2 matrix whose columns are the basis vectors. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2")); + "p"_a, "t0"_a, "t1"_a, "t2"_a); m.def( "point_triangle_tangent_basis_jacobian", @@ -182,5 +181,5 @@ void define_tangent_basis(py::module_& m) Returns: A 12*3x2 matrix whose columns are the basis vectors. )ipc_Qu8mg5v7", - py::arg("p"), py::arg("t0"), py::arg("t1"), py::arg("t2")); + "p"_a, "t0"_a, "t1"_a, "t2"_a); } diff --git a/python/src/utils/area_gradient.cpp b/python/src/utils/area_gradient.cpp index 3f9fb6f3d..df6152676 100644 --- a/python/src/utils/area_gradient.cpp +++ b/python/src/utils/area_gradient.cpp @@ -3,7 +3,6 @@ #include #include -namespace py = pybind11; using namespace ipc; void define_area_gradient(py::module_& m) @@ -20,7 +19,7 @@ void define_area_gradient(py::module_& m) Returns: The gradient of the edge's length wrt e0, and e1. )ipc_Qu8mg5v7", - py::arg("e0"), py::arg("e1")); + "e0"_a, "e1"_a); m.def( "triangle_area_gradient", &triangle_area_gradient, @@ -35,5 +34,5 @@ void define_area_gradient(py::module_& m) Returns: The gradient of the triangle's area t0, t1, and t2. )ipc_Qu8mg5v7", - py::arg("t0"), py::arg("t1"), py::arg("t2")); + "t0"_a, "t1"_a, "t2"_a); } diff --git a/python/src/utils/bindings.hpp b/python/src/utils/bindings.hpp index 648fbdb46..93794ebc4 100644 --- a/python/src/utils/bindings.hpp +++ b/python/src/utils/bindings.hpp @@ -1,7 +1,6 @@ #pragma once #include -namespace py = pybind11; void define_area_gradient(py::module_& m); void define_eigen_ext(py::module_& m); diff --git a/python/src/utils/eigen_ext.cpp b/python/src/utils/eigen_ext.cpp index 029d23732..0f8afef12 100644 --- a/python/src/utils/eigen_ext.cpp +++ b/python/src/utils/eigen_ext.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_eigen_ext(py::module_& m) @@ -23,7 +22,7 @@ void define_eigen_ext(py::module_& m) Returns: Projected matrix )ipc_Qu8mg5v7", - py::arg("A"), py::arg("eps") = 1e-8); + "A"_a, "eps"_a = 1e-8); py::enum_( m, "PSDProjectionMethod", @@ -52,5 +51,5 @@ void define_eigen_ext(py::module_& m) Returns: Projected matrix )ipc_Qu8mg5v7", - py::arg("A"), py::arg("method") = PSDProjectionMethod::CLAMP); + "A"_a, "method"_a = PSDProjectionMethod::CLAMP); } diff --git a/python/src/utils/intersection.cpp b/python/src/utils/intersection.cpp index 6e7430ee5..c30d25286 100644 --- a/python/src/utils/intersection.cpp +++ b/python/src/utils/intersection.cpp @@ -4,15 +4,13 @@ #include -namespace py = pybind11; using namespace ipc; void define_intersection(py::module_& m) { m.def( - "is_edge_intersecting_triangle", &is_edge_intersecting_triangle, - py::arg("e0"), py::arg("e1"), py::arg("t0"), py::arg("t1"), - py::arg("t2")); + "is_edge_intersecting_triangle", &is_edge_intersecting_triangle, "e0"_a, + "e1"_a, "t0"_a, "t1"_a, "t2"_a); m.def( "segment_segment_intersect", @@ -35,5 +33,5 @@ void define_intersection(py::module_& m) Returns: true if they intersect )ipc_Qu8mg5v7", - py::arg("A"), py::arg("B"), py::arg("C"), py::arg("D")); + "A"_a, "B"_a, "C"_a, "D"_a); } diff --git a/python/src/utils/interval.cpp b/python/src/utils/interval.cpp index 9301cd9d0..c65f47476 100644 --- a/python/src/utils/interval.cpp +++ b/python/src/utils/interval.cpp @@ -3,7 +3,6 @@ #include -namespace py = pybind11; #ifdef IPC_TOOLKIT_WITH_FILIB using namespace filib; #endif @@ -44,8 +43,8 @@ void define_interval(py::module_& m) py::class_(m_filib, "Interval") .def(py::init()) - .def(py::init(), py::arg("x")) - .def(py::init(), py::arg("x"), py::arg("y")) + .def(py::init(), "x"_a) + .def(py::init(), "x"_a, "y"_a) .def( "__str__", [](const Interval& self) { diff --git a/python/src/utils/logger.cpp b/python/src/utils/logger.cpp index ae08b21fe..6cc699931 100644 --- a/python/src/utils/logger.cpp +++ b/python/src/utils/logger.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_logger(py::module_& m) @@ -24,5 +23,5 @@ void define_logger(py::module_& m) [](const spdlog::level::level_enum& level) { logger().set_level(level); }, - "Set log level", py::arg("level")); + "Set log level", "level"_a); } diff --git a/python/src/utils/thread_limiter.cpp b/python/src/utils/thread_limiter.cpp index f142087e5..859b353f8 100644 --- a/python/src/utils/thread_limiter.cpp +++ b/python/src/utils/thread_limiter.cpp @@ -8,7 +8,6 @@ #include -namespace py = pybind11; using namespace ipc; static std::shared_ptr thread_limiter; @@ -40,7 +39,7 @@ void define_thread_limiter(py::module_& m) "get maximum number of threads to use"); m.def( "set_num_threads", &set_num_threads, - "set maximum number of threads to use", py::arg("nthreads")); + "set maximum number of threads to use", "nthreads"_a); std::atexit([]() { thread_limiter.reset(); }); } diff --git a/python/src/utils/vertex_to_min_edge.cpp b/python/src/utils/vertex_to_min_edge.cpp index df4e121ec..a6211d434 100644 --- a/python/src/utils/vertex_to_min_edge.cpp +++ b/python/src/utils/vertex_to_min_edge.cpp @@ -2,12 +2,10 @@ #include -namespace py = pybind11; using namespace ipc; void define_vertex_to_min_edge(py::module_& m) { m.def( - "vertex_to_min_edge", &vertex_to_min_edge, py::arg("num_vertices"), - py::arg("edges")); + "vertex_to_min_edge", &vertex_to_min_edge, "num_vertices"_a, "edges"_a); } diff --git a/python/src/utils/world_bbox_diagonal_length.cpp b/python/src/utils/world_bbox_diagonal_length.cpp index 5e19888d2..c4a54a60a 100644 --- a/python/src/utils/world_bbox_diagonal_length.cpp +++ b/python/src/utils/world_bbox_diagonal_length.cpp @@ -2,7 +2,6 @@ #include -namespace py = pybind11; using namespace ipc; void define_world_bbox_diagonal_length(py::module_& m) @@ -18,5 +17,5 @@ void define_world_bbox_diagonal_length(py::module_& m) Returns: The diagonal length of the world bounding box. )ipc_Qu8mg5v7", - py::arg("vertices")); + "vertices"_a); } diff --git a/python/tests/find_ipctk.py b/python/tests/find_ipctk.py index b3197cc04..8572b99da 100644 --- a/python/tests/find_ipctk.py +++ b/python/tests/find_ipctk.py @@ -1,20 +1,4 @@ -try: - import ipctk # Try to import the built module -except ImportError: - import sys - import pathlib - repo_root = pathlib.Path(__file__).parents[2] - possible_paths = [ - pathlib.Path("python").resolve(), - repo_root / "build" / "python", - repo_root / "build" / "release" / "python", - repo_root / "build" / "debug" / "python", - ] - for path in possible_paths: - if path.exists() and len(list(path.glob("ipctk.*"))) > 0: - sys.path.append(str(path)) - break - else: - raise ImportError("Could not find the ipctk module") - print(f"Using found ipctk module at {path}") - import ipctk # Try again +import sys +import pathlib +sys.path.append(str(pathlib.Path(__file__).parents[1])) +from _find_ipctk import ipctk # noqa diff --git a/python/tests/test_ccd.py b/python/tests/test_ccd.py index aa0b0d2cb..a09eee98b 100644 --- a/python/tests/test_ccd.py +++ b/python/tests/test_ccd.py @@ -161,12 +161,15 @@ def __init__(self, position, translation, delta_translation, rotation, delta_rot self.rotation = rotation self.delta_rotation = delta_rotation + # BEGIN_RIGID_2D_CALL def __call__(self, t): theta = self.rotation + t * self.delta_rotation R = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]]) return R @ self.position + self.translation + t * self.delta_translation + # END_RIGID_2D_CALL + # BEGIN_RIGID_2D_MAX_DISTANCE_FROM_LINEAR def max_distance_from_linear(self, t0, t1): if self.delta_rotation * (t1 - t0) >= 2 * np.pi: # This is the most conservative estimate @@ -174,6 +177,7 @@ def max_distance_from_linear(self, t0, t1): p_t0 = self(t0) p_t1 = self(t1) return np.linalg.norm(self((t0 + t1) / 2) - ((p_t1 - p_t0) * 0.5 + p_t0)) + # END_RIGID_2D_MAX_DISTANCE_FROM_LINEAR # END_RIGID_2D_TRAJECTORY # BEGIN_TEST_RIGID_2D_TRAJECTORY diff --git a/src/ipc/barrier/adaptive_stiffness.cpp b/src/ipc/barrier/adaptive_stiffness.cpp index 49079ff02..f766d2786 100644 --- a/src/ipc/barrier/adaptive_stiffness.cpp +++ b/src/ipc/barrier/adaptive_stiffness.cpp @@ -103,7 +103,7 @@ double update_barrier_stiffness( // double semi_implicit_stiffness( - const CollisionStencil<4>& stencil, + const CollisionStencil& stencil, Eigen::ConstRef vertices, Eigen::ConstRef mass, Eigen::ConstRef local_hess, @@ -158,7 +158,7 @@ Eigen::VectorXd semi_implicit_stiffness( Eigen::VectorXd stiffnesses(collisions.size()); for (size_t ci = 0; ci < collisions.size(); ci++) { - const CollisionStencil<4>& collision = collisions[ci]; + const CollisionStencil& collision = collisions[ci]; const unsigned N = collision.num_vertices(); const VectorMax12d positions = diff --git a/src/ipc/barrier/adaptive_stiffness.hpp b/src/ipc/barrier/adaptive_stiffness.hpp index 64a4affb6..167864552 100644 --- a/src/ipc/barrier/adaptive_stiffness.hpp +++ b/src/ipc/barrier/adaptive_stiffness.hpp @@ -65,7 +65,7 @@ double update_barrier_stiffness( /// @param dmin Minimum distance between elements. /// @return The semi-implicit stiffness. double semi_implicit_stiffness( - const CollisionStencil<4>& stencil, + const CollisionStencil& stencil, Eigen::ConstRef vertices, Eigen::ConstRef mass, Eigen::ConstRef local_hess, diff --git a/src/ipc/broad_phase/broad_phase.cpp b/src/ipc/broad_phase/broad_phase.cpp index 17df5e9e1..f0cf6d90a 100644 --- a/src/ipc/broad_phase/broad_phase.cpp +++ b/src/ipc/broad_phase/broad_phase.cpp @@ -11,10 +11,10 @@ namespace ipc { -std::shared_ptr build_broad_phase(const BroadPhaseMethod& broad_phase_method) +std::shared_ptr +build_broad_phase(const BroadPhaseMethod& broad_phase_method) { - switch(broad_phase_method) - { + switch (broad_phase_method) { case BroadPhaseMethod::HASH_GRID: return std::make_shared(); case BroadPhaseMethod::BRUTE_FORCE: diff --git a/src/ipc/broad_phase/broad_phase.hpp b/src/ipc/broad_phase/broad_phase.hpp index 65ee2b9d6..21082a40b 100644 --- a/src/ipc/broad_phase/broad_phase.hpp +++ b/src/ipc/broad_phase/broad_phase.hpp @@ -15,7 +15,13 @@ namespace ipc { class Candidates; // Forward declaration -enum class BroadPhaseMethod { HASH_GRID, BRUTE_FORCE, SPATIAL_HASH, BVH, SWEEP_AND_TINIEST_QUEUE }; +enum class BroadPhaseMethod { + HASH_GRID, + BRUTE_FORCE, + SPATIAL_HASH, + BVH, + SWEEP_AND_TINIEST_QUEUE +}; class BroadPhase { public: @@ -106,5 +112,6 @@ class BroadPhase { std::vector face_boxes; }; -std::shared_ptr build_broad_phase(const BroadPhaseMethod& broad_phase_method); +std::shared_ptr +build_broad_phase(const BroadPhaseMethod& broad_phase_method); } // namespace ipc diff --git a/src/ipc/candidates/candidates.cpp b/src/ipc/candidates/candidates.cpp index 6789313ac..e3799c8f0 100644 --- a/src/ipc/candidates/candidates.cpp +++ b/src/ipc/candidates/candidates.cpp @@ -195,7 +195,7 @@ bool Candidates::is_step_collision_free( // Narrow phase for (size_t i = 0; i < size(); i++) { - const CollisionStencil<4>& candidate = (*this)[i]; + const CollisionStencil& candidate = (*this)[i]; double toi; bool is_collision = candidate.ccd( @@ -240,7 +240,7 @@ double Candidates::compute_collision_free_stepsize( tmax = earliest_toi; } - const CollisionStencil<4>& candidate = (*this)[i]; + const CollisionStencil& candidate = (*this)[i]; double toi = std::numeric_limits::infinity(); // output const bool are_colliding = candidate.ccd( @@ -344,7 +344,7 @@ void Candidates::clear() fv_candidates.clear(); } -CollisionStencil<4>& Candidates::operator[](size_t i) +CollisionStencil& Candidates::operator[](size_t i) { if (i < vv_candidates.size()) { return vv_candidates[i]; @@ -364,7 +364,7 @@ CollisionStencil<4>& Candidates::operator[](size_t i) throw std::out_of_range("Candidate index is out of range!"); } -const CollisionStencil<4>& Candidates::operator[](size_t i) const +const CollisionStencil& Candidates::operator[](size_t i) const { if (i < vv_candidates.size()) { return vv_candidates[i]; diff --git a/src/ipc/candidates/candidates.hpp b/src/ipc/candidates/candidates.hpp index 9e1ccf75e..17f7c69fa 100644 --- a/src/ipc/candidates/candidates.hpp +++ b/src/ipc/candidates/candidates.hpp @@ -49,8 +49,8 @@ class Candidates { void clear(); - CollisionStencil<4>& operator[](size_t i); - const CollisionStencil<4>& operator[](size_t i) const; + CollisionStencil& operator[](size_t i); + const CollisionStencil& operator[](size_t i) const; /// @brief Determine if the step is collision free from the set of candidates. /// @note Assumes the trajectory is linear. diff --git a/src/ipc/candidates/collision_stencil.cpp b/src/ipc/candidates/collision_stencil.cpp index 7afcc2810..dd0e54a92 100644 --- a/src/ipc/candidates/collision_stencil.cpp +++ b/src/ipc/candidates/collision_stencil.cpp @@ -2,11 +2,10 @@ namespace ipc { -template -std::ostream& CollisionStencil::write_ccd_query( +std::ostream& CollisionStencil::write_ccd_query( std::ostream& out, - Eigen::ConstRef> vertices_t0, - Eigen::ConstRef> vertices_t1) const + Eigen::ConstRef> vertices_t0, + Eigen::ConstRef> vertices_t1) const { assert(vertices_t0.size() == vertices_t1.size()); diff --git a/src/ipc/candidates/collision_stencil.hpp b/src/ipc/candidates/collision_stencil.hpp index 075b64f1f..bc7739463 100644 --- a/src/ipc/candidates/collision_stencil.hpp +++ b/src/ipc/candidates/collision_stencil.hpp @@ -11,9 +11,9 @@ namespace ipc { /// @brief A stencil representing a collision between at most four vertices. -template class CollisionStencil { +class CollisionStencil { public: - constexpr static int element_size = max_vert; + constexpr static int element_size = 4; CollisionStencil() = default; virtual ~CollisionStencil() = default; @@ -33,17 +33,16 @@ template class CollisionStencil { /// @param edges Collision mesh edges /// @param faces Collision mesh faces /// @return The vertex IDs of the collision stencil. Size is always 4, but elements i > num_vertices() are -1. - virtual std::array vertex_ids( + virtual std::array vertex_ids( Eigen::ConstRef edges, Eigen::ConstRef faces) const = 0; /// @brief Get the vertex attributes of the collision stencil. - /// @tparam T Type of the attributes /// @param vertices Vertex attributes /// @param edges Collision mesh edges /// @param faces Collision mesh faces /// @return The vertex positions of the collision stencil. Size is always 4, but elements i > num_vertices() are NaN. - std::array vertices( + std::array vertices( Eigen::ConstRef vertices, Eigen::ConstRef edges, Eigen::ConstRef faces) const @@ -52,8 +51,8 @@ template class CollisionStencil { const auto vertex_ids = this->vertex_ids(edges, faces); - std::array stencil_vertices; - for (int i = 0; i < max_vert; i++) { + std::array stencil_vertices; + for (int i = 0; i < 4; i++) { if (vertex_ids[i] >= 0) { stencil_vertices[i] = vertices.row(vertex_ids[i]); } else { @@ -65,18 +64,17 @@ template class CollisionStencil { } /// @brief Select this stencil's DOF from the full matrix of DOF. - /// @tparam T Type of the DOF /// @param X Full matrix of DOF (rowwise). /// @param edges Collision mesh edges /// @param faces Collision mesh faces /// @return This stencil's DOF. - Vector + Vector dof(Eigen::ConstRef X, Eigen::ConstRef edges, Eigen::ConstRef faces) const { const int dim = X.cols(); - Vector x(num_vertices() * dim); + Vector x(num_vertices() * dim); const auto idx = vertex_ids(edges, faces); for (int i = 0; i < num_vertices(); i++) { x.segment(i * dim, dim) = X.row(idx[i]); @@ -102,7 +100,7 @@ template class CollisionStencil { /// @param edges Collision mesh edges /// @param faces Collision mesh faces /// @return Distance gradient of the stencil w.r.t. the stencil's vertex positions. - Vector compute_distance_gradient( + Vector compute_distance_gradient( Eigen::ConstRef vertices, Eigen::ConstRef edges, Eigen::ConstRef faces) const @@ -115,7 +113,7 @@ template class CollisionStencil { /// @param edges Collision mesh edges /// @param faces Collision mesh faces /// @return Distance Hessian of the stencil w.r.t. the stencil's vertex positions. - MatrixMax compute_distance_hessian( + MatrixMax compute_distance_hessian( Eigen::ConstRef vertices, Eigen::ConstRef edges, Eigen::ConstRef faces) const @@ -145,27 +143,27 @@ template class CollisionStencil { /// @note positions can be computed as stencil.dof(vertices, edges, faces) /// @return Distance of the stencil. virtual double compute_distance( - Eigen::ConstRef>& positions) const = 0; + Eigen::ConstRef>& positions) const = 0; /// @brief Compute the distance gradient of the stencil w.r.t. the stencil's vertex positions. /// @param positions Stencil's vertex positions. /// @note positions can be computed as stencil.dof(vertices, edges, faces) /// @return Distance gradient of the stencil w.r.t. the stencil's vertex positions. - virtual Vector compute_distance_gradient( - Eigen::ConstRef> positions) const = 0; + virtual Vector compute_distance_gradient( + Eigen::ConstRef> positions) const = 0; /// @brief Compute the distance Hessian of the stencil w.r.t. the stencil's vertex positions. /// @param positions Stencil's vertex positions. /// @note positions can be computed as stencil.dof(vertices, edges, faces) /// @return Distance Hessian of the stencil w.r.t. the stencil's vertex positions. - virtual MatrixMax - compute_distance_hessian(Eigen::ConstRef> positions) const = 0; + virtual MatrixMax compute_distance_hessian( + Eigen::ConstRef> positions) const = 0; /// @brief Compute the coefficients of the stencil s.t. d(x) = ‖∑ cᵢ xᵢ‖². /// @param positions Stencil's vertex positions. /// @return Coefficients of the stencil. - virtual VectorMax4d - compute_coefficients(Eigen::ConstRef> positions) const = 0; + virtual VectorMax4d compute_coefficients( + Eigen::ConstRef> positions) const = 0; /// @brief Perform narrow-phase CCD on the candidate. /// @param[in] vertices_t0 Stencil vertices at the start of the time step. @@ -176,8 +174,8 @@ template class CollisionStencil { /// @param[in] narrow_phase_ccd The narrow phase CCD algorithm to use. /// @return If the candidate had a collision over the time interval. virtual bool - ccd(Eigen::ConstRef> vertices_t0, - Eigen::ConstRef> vertices_t1, + ccd(Eigen::ConstRef> vertices_t0, + Eigen::ConstRef> vertices_t1, double& toi, const double min_distance = 0.0, const double tmax = 1.0, @@ -191,8 +189,8 @@ template class CollisionStencil { /// @return The stream. std::ostream& write_ccd_query( std::ostream& out, - Eigen::ConstRef> vertices_t0, - Eigen::ConstRef> vertices_t1) const; + Eigen::ConstRef> vertices_t0, + Eigen::ConstRef> vertices_t1) const; }; } // namespace ipc \ No newline at end of file diff --git a/src/ipc/candidates/edge_edge.hpp b/src/ipc/candidates/edge_edge.hpp index 4df3616db..61c843379 100644 --- a/src/ipc/candidates/edge_edge.hpp +++ b/src/ipc/candidates/edge_edge.hpp @@ -9,7 +9,7 @@ namespace ipc { -class EdgeEdgeCandidate : virtual public CollisionStencil<4> { +class EdgeEdgeCandidate : virtual public CollisionStencil { public: EdgeEdgeCandidate(index_t edge0_id, index_t edge1_id); @@ -18,6 +18,10 @@ class EdgeEdgeCandidate : virtual public CollisionStencil<4> { int num_vertices() const override { return 4; }; + /// @brief Get the vertex IDs for the edge-edge pair + /// @param edges The edge connectivity matrix + /// @param faces The face connectivity matrix + /// @return An array of vertex IDs in the order: [ea0i, ea1i, eb0i, eb1i] std::array vertex_ids( Eigen::ConstRef edges, Eigen::ConstRef faces) const override @@ -26,10 +30,10 @@ class EdgeEdgeCandidate : virtual public CollisionStencil<4> { edges(edge1_id, 0), edges(edge1_id, 1) } }; } - using CollisionStencil<4>::compute_coefficients; - using CollisionStencil<4>::compute_distance; - using CollisionStencil<4>::compute_distance_gradient; - using CollisionStencil<4>::compute_distance_hessian; + using CollisionStencil::compute_coefficients; + using CollisionStencil::compute_distance; + using CollisionStencil::compute_distance_gradient; + using CollisionStencil::compute_distance_hessian; double compute_distance(Eigen::ConstRef positions) const override; diff --git a/src/ipc/candidates/edge_vertex.hpp b/src/ipc/candidates/edge_vertex.hpp index 07a424ec4..2be02a3ba 100644 --- a/src/ipc/candidates/edge_vertex.hpp +++ b/src/ipc/candidates/edge_vertex.hpp @@ -9,7 +9,7 @@ namespace ipc { -class EdgeVertexCandidate : virtual public CollisionStencil<4> { +class EdgeVertexCandidate : virtual public CollisionStencil { public: EdgeVertexCandidate(index_t edge_id, index_t vertex_id); @@ -18,6 +18,10 @@ class EdgeVertexCandidate : virtual public CollisionStencil<4> { int num_vertices() const override { return 3; }; + /// @brief Get the vertex IDs for the edge-vertex pair + /// @param edges The edge connectivity matrix + /// @param faces The face connectivity matrix + /// @return An array of vertex IDs in the order: [vi, e0i, e1i, -1] std::array vertex_ids( Eigen::ConstRef edges, Eigen::ConstRef faces) const override @@ -25,10 +29,10 @@ class EdgeVertexCandidate : virtual public CollisionStencil<4> { return { { vertex_id, edges(edge_id, 0), edges(edge_id, 1), -1 } }; } - using CollisionStencil<4>::compute_coefficients; - using CollisionStencil<4>::compute_distance; - using CollisionStencil<4>::compute_distance_gradient; - using CollisionStencil<4>::compute_distance_hessian; + using CollisionStencil::compute_coefficients; + using CollisionStencil::compute_distance; + using CollisionStencil::compute_distance_gradient; + using CollisionStencil::compute_distance_hessian; double compute_distance(Eigen::ConstRef positions) const override; diff --git a/src/ipc/candidates/face_vertex.hpp b/src/ipc/candidates/face_vertex.hpp index e328bdb21..b391823b4 100644 --- a/src/ipc/candidates/face_vertex.hpp +++ b/src/ipc/candidates/face_vertex.hpp @@ -9,7 +9,7 @@ namespace ipc { -class FaceVertexCandidate : virtual public CollisionStencil<4> { +class FaceVertexCandidate : virtual public CollisionStencil { public: FaceVertexCandidate(index_t face_id, index_t vertex_id); @@ -18,6 +18,10 @@ class FaceVertexCandidate : virtual public CollisionStencil<4> { int num_vertices() const override { return 4; }; + /// @brief Get the vertex IDs for the face-vertex pair + /// @param edges The edge connectivity matrix + /// @param faces The face connectivity matrix + /// @return An array of vertex IDs in the order: [vi, f0i, f1i, f2i] std::array vertex_ids( Eigen::ConstRef edges, Eigen::ConstRef faces) const override @@ -26,10 +30,10 @@ class FaceVertexCandidate : virtual public CollisionStencil<4> { faces(face_id, 2) } }; } - using CollisionStencil<4>::compute_coefficients; - using CollisionStencil<4>::compute_distance; - using CollisionStencil<4>::compute_distance_gradient; - using CollisionStencil<4>::compute_distance_hessian; + using CollisionStencil::compute_coefficients; + using CollisionStencil::compute_distance; + using CollisionStencil::compute_distance_gradient; + using CollisionStencil::compute_distance_hessian; double compute_distance(Eigen::ConstRef positions) const override; diff --git a/src/ipc/candidates/vertex_vertex.hpp b/src/ipc/candidates/vertex_vertex.hpp index b99f10774..dff19d973 100644 --- a/src/ipc/candidates/vertex_vertex.hpp +++ b/src/ipc/candidates/vertex_vertex.hpp @@ -9,7 +9,7 @@ namespace ipc { -class VertexVertexCandidate : virtual public CollisionStencil<4> { +class VertexVertexCandidate : virtual public CollisionStencil { public: VertexVertexCandidate(index_t vertex0_id, index_t vertex1_id); @@ -29,10 +29,10 @@ class VertexVertexCandidate : virtual public CollisionStencil<4> { return { { vertex0_id, vertex1_id, -1, -1 } }; } - using CollisionStencil<4>::compute_coefficients; - using CollisionStencil<4>::compute_distance; - using CollisionStencil<4>::compute_distance_gradient; - using CollisionStencil<4>::compute_distance_hessian; + using CollisionStencil::compute_coefficients; + using CollisionStencil::compute_distance; + using CollisionStencil::compute_distance_gradient; + using CollisionStencil::compute_distance_hessian; double compute_distance(Eigen::ConstRef positions) const override; diff --git a/src/ipc/collision_mesh.cpp b/src/ipc/collision_mesh.cpp index 380dd9875..3d286edd0 100644 --- a/src/ipc/collision_mesh.cpp +++ b/src/ipc/collision_mesh.cpp @@ -1,16 +1,15 @@ #include "collision_mesh.hpp" #include - #include #include -#include #include #include +#include #include -#include #include +#include namespace ipc { @@ -134,13 +133,11 @@ void CollisionMesh::construct_edges_to_faces() { if (dim() == 2) return; - + m_edges_to_faces.setOnes(num_edges(), 2); m_edges_to_faces *= -1; - for (int f = 0; f < m_faces_to_edges.rows(); f++) - { - for (int le = 0; le < 3; le++) - { + for (int f = 0; f < m_faces_to_edges.rows(); f++) { + for (int le = 0; le < 3; le++) { if (m_edges_to_faces(m_faces_to_edges(f, le), 0) < 0) m_edges_to_faces(m_faces_to_edges(f, le), 0) = f; else if (m_edges_to_faces(m_faces_to_edges(f, le), 1) < 0) @@ -278,7 +275,7 @@ void CollisionMesh::init_areas() m_vertices_to_edges[m_edges(i, j)].push_back(i); } } - + m_vertices_to_faces.resize(num_vertices()); for (int i = 0; i < m_faces.rows(); i++) { for (int j = 0; j < m_faces.cols(); j++) { @@ -513,9 +510,11 @@ Eigen::MatrixXi CollisionMesh::construct_faces_to_edges( return faces_to_edges; } -double CollisionMesh::edge_length(const int &edge_id) const +double CollisionMesh::edge_length(const int& edge_id) const { - return (m_rest_positions.row(m_edges(edge_id, 0)) - m_rest_positions.row(m_edges(edge_id, 1))).norm(); + return (m_rest_positions.row(m_edges(edge_id, 0)) + - m_rest_positions.row(m_edges(edge_id, 1))) + .norm(); } double CollisionMesh::max_edge_length() const @@ -526,14 +525,13 @@ double CollisionMesh::max_edge_length() const return val; } -std::vector CollisionMesh::find_vertex_adjacent_vertices(const long &v) const +std::vector +CollisionMesh::find_vertex_adjacent_vertices(const long& v) const { std::vector neighbors; - if (dim() == 2) - { + if (dim() == 2) { neighbors.assign(2, -1); - for (long i : vertex_edge_adjacencies()[v]) - { + for (long i : vertex_edge_adjacencies()[v]) { if (edges()(i, 0) == v) neighbors[0] = edges()(i, 1); else if (edges()(i, 1) == v) @@ -541,44 +539,40 @@ std::vector CollisionMesh::find_vertex_adjacent_vertices(const long &v) co else throw std::runtime_error("Invalid edge-vertex adjacency!"); } - } - else - { - if (vertices_to_faces()[v].size() > 0) - { - // construct a map of neighboring vertices, it maps every neighbor to the next counter-clockwise neighbor + } else { + if (vertices_to_faces()[v].size() > 0) { + // construct a map of neighboring vertices, it maps every neighbor + // to the next counter-clockwise neighbor std::unordered_map map; - for (auto f : vertices_to_faces()[v]) - { - for (int lv = 0; lv < 3; lv++) - { - if (faces()(f, lv) == v) - { - map[faces()(f, (lv+1)%3)] = faces()(f, (lv+2)%3); + for (auto f : vertices_to_faces()[v]) { + for (int lv = 0; lv < 3; lv++) { + if (faces()(f, lv) == v) { + map[faces()(f, (lv + 1) % 3)] = + faces()(f, (lv + 2) % 3); break; } } } if (vertices_to_faces()[v].size() != map.size()) - throw std::runtime_error("Non-manifold vertex! Map size smaller than neighbor!"); - + throw std::runtime_error( + "Non-manifold vertex! Map size smaller than neighbor!"); + // verify that the neighboring vertices form a loop auto iter = map.find(map.begin()->first); - while (neighbors.empty() || iter->first != neighbors.front()) - { + while (neighbors.empty() || iter->first != neighbors.front()) { neighbors.push_back(iter->first); iter = map.find(iter->second); - if (iter == map.end()) - { - logger().error("neighbor faces {}, map {}", vertices_to_faces()[v].size(), map); - throw std::runtime_error("Non-manifold vertex! Cannot find next neighbor!"); + if (iter == map.end()) { + logger().error( + "neighbor faces {}, map {}", + vertices_to_faces()[v].size(), map); + throw std::runtime_error( + "Non-manifold vertex! Cannot find next neighbor!"); } } if (neighbors.size() != map.size()) throw std::runtime_error("Non-manifold vertex!"); - } - else - { + } else { for (int eid : vertices_to_edges()[v]) neighbors.push_back( edges()(eid, 0) == v ? edges()(eid, 1) : edges()(eid, 0)); diff --git a/src/ipc/collision_mesh.hpp b/src/ipc/collision_mesh.hpp index 7bea88521..a682dd7c5 100644 --- a/src/ipc/collision_mesh.hpp +++ b/src/ipc/collision_mesh.hpp @@ -51,7 +51,8 @@ class CollisionMesh { Eigen::ConstRef faces = Eigen::MatrixXi()) { return CollisionMesh( - construct_is_on_surface(full_rest_positions.rows(), edges), std::vector(full_rest_positions.rows(), false), + construct_is_on_surface(full_rest_positions.rows(), edges), + std::vector(full_rest_positions.rows(), false), full_rest_positions, edges, faces); } diff --git a/src/ipc/collisions/normal/normal_collision.hpp b/src/ipc/collisions/normal/normal_collision.hpp index 10d5ed2d6..2c5d4f182 100644 --- a/src/ipc/collisions/normal/normal_collision.hpp +++ b/src/ipc/collisions/normal/normal_collision.hpp @@ -4,13 +4,14 @@ #include #include #include + #include #include namespace ipc { -class NormalCollision : virtual public CollisionStencil<4> { +class NormalCollision : virtual public CollisionStencil { public: NormalCollision() = default; diff --git a/src/ipc/collisions/normal/normal_collisions.cpp b/src/ipc/collisions/normal/normal_collisions.cpp index 646a7590c..cb4774466 100644 --- a/src/ipc/collisions/normal/normal_collisions.cpp +++ b/src/ipc/collisions/normal/normal_collisions.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -16,8 +17,6 @@ #include // std::out_of_range -#include - namespace ipc { namespace { diff --git a/src/ipc/collisions/normal/plane_vertex.hpp b/src/ipc/collisions/normal/plane_vertex.hpp index 0d9b10d4f..2df51fc88 100644 --- a/src/ipc/collisions/normal/plane_vertex.hpp +++ b/src/ipc/collisions/normal/plane_vertex.hpp @@ -21,10 +21,10 @@ class PlaneVertexNormalCollision : public NormalCollision { return { { vertex_id, -1, -1, -1 } }; } - using CollisionStencil<4>::compute_coefficients; - using CollisionStencil<4>::compute_distance; - using CollisionStencil<4>::compute_distance_gradient; - using CollisionStencil<4>::compute_distance_hessian; + using CollisionStencil::compute_coefficients; + using CollisionStencil::compute_distance; + using CollisionStencil::compute_distance_gradient; + using CollisionStencil::compute_distance_hessian; /// @brief Compute the distance between the point and plane. /// @param point Point's position. diff --git a/src/ipc/collisions/tangential/edge_edge.cpp b/src/ipc/collisions/tangential/edge_edge.cpp index f0f3cd969..56dfc9dd6 100644 --- a/src/ipc/collisions/tangential/edge_edge.cpp +++ b/src/ipc/collisions/tangential/edge_edge.cpp @@ -21,8 +21,7 @@ EdgeEdgeTangentialCollision::EdgeEdgeTangentialCollision( const double normal_force) : EdgeEdgeTangentialCollision(collision) { - TangentialCollision::init( - collision, positions, normal_force); + TangentialCollision::init(collision, positions, normal_force); } EdgeEdgeTangentialCollision::EdgeEdgeTangentialCollision( diff --git a/src/ipc/collisions/tangential/edge_vertex.cpp b/src/ipc/collisions/tangential/edge_vertex.cpp index b054bcc54..97e520abf 100644 --- a/src/ipc/collisions/tangential/edge_vertex.cpp +++ b/src/ipc/collisions/tangential/edge_vertex.cpp @@ -21,8 +21,7 @@ EdgeVertexTangentialCollision::EdgeVertexTangentialCollision( const double normal_force) : EdgeVertexTangentialCollision(collision) { - TangentialCollision::init( - collision, positions, normal_force); + TangentialCollision::init(collision, positions, normal_force); } EdgeVertexTangentialCollision::EdgeVertexTangentialCollision( diff --git a/src/ipc/collisions/tangential/face_vertex.cpp b/src/ipc/collisions/tangential/face_vertex.cpp index 7f77e853f..0f0c01cb3 100644 --- a/src/ipc/collisions/tangential/face_vertex.cpp +++ b/src/ipc/collisions/tangential/face_vertex.cpp @@ -21,8 +21,7 @@ FaceVertexTangentialCollision::FaceVertexTangentialCollision( const double normal_force) : FaceVertexTangentialCollision(collision) { - TangentialCollision::init( - collision, positions, normal_force); + TangentialCollision::init(collision, positions, normal_force); } FaceVertexTangentialCollision::FaceVertexTangentialCollision( diff --git a/src/ipc/collisions/tangential/face_vertex.hpp b/src/ipc/collisions/tangential/face_vertex.hpp index 81387e9f6..f2dd9d469 100644 --- a/src/ipc/collisions/tangential/face_vertex.hpp +++ b/src/ipc/collisions/tangential/face_vertex.hpp @@ -12,10 +12,10 @@ class FaceVertexTangentialCollision : public FaceVertexCandidate, using FaceVertexCandidate::FaceVertexCandidate; FaceVertexTangentialCollision(const FaceVertexNormalCollision& collision); - + FaceVertexTangentialCollision( const FaceVertexNormalCollision& collision, - Eigen::ConstRef positions, + Eigen::ConstRef positions, const double normal_force); FaceVertexTangentialCollision( diff --git a/src/ipc/collisions/tangential/tangential_collision.hpp b/src/ipc/collisions/tangential/tangential_collision.hpp index 865159508..a9146282a 100644 --- a/src/ipc/collisions/tangential/tangential_collision.hpp +++ b/src/ipc/collisions/tangential/tangential_collision.hpp @@ -2,13 +2,13 @@ #include #include -#include #include +#include #include namespace ipc { -class TangentialCollision : virtual public CollisionStencil<4> { +class TangentialCollision : virtual public CollisionStencil { protected: /// @brief Initialize the collision. /// @param collision NormalCollision stencil. @@ -90,8 +90,7 @@ class TangentialCollision : virtual public CollisionStencil<4> { public: /// @brief Normal force magnitude double normal_force_magnitude; - std::shared_ptr> smooth_collision_2d; - std::shared_ptr> smooth_collision_3d; + std::shared_ptr smooth_collision; /// @brief Ratio between normal and tangential forces (e.g., friction coefficient) double mu; diff --git a/src/ipc/collisions/tangential/tangential_collisions.cpp b/src/ipc/collisions/tangential/tangential_collisions.cpp index c38a37899..5d26acdc7 100644 --- a/src/ipc/collisions/tangential/tangential_collisions.cpp +++ b/src/ipc/collisions/tangential/tangential_collisions.cpp @@ -11,11 +11,10 @@ namespace ipc { -template void TangentialCollisions::build_for_smooth_contact( const CollisionMesh& mesh, const Eigen::MatrixXd& vertices, - const SmoothCollisions& collisions, + const SmoothCollisions& collisions, const ParameterType& params, const double barrier_stiffness, const Eigen::VectorXd& mus, @@ -35,16 +34,15 @@ void TangentialCollisions::build_for_smooth_contact( for (size_t i = 0; i < collisions.size(); i++) { const auto& cc = collisions[i]; Eigen::VectorXd contact_potential_grad = - cc.gradient(cc.dof(vertices, edges, faces), params); + cc.gradient(cc.dof(vertices), params); const double contact_force = barrier_stiffness * contact_potential_grad.norm(); - if constexpr (dim == 3) { + if (mesh.dim() == 3) { TangentialCollision* ptr = nullptr; - if (const auto cvv = dynamic_cast*>(&cc)) { - Eigen::VectorXd collision_points = - cvv->core_dof(vertices, edges, faces); + if (const auto cvv = dynamic_cast< + const SmoothCollisionTemplate*>(&cc)) { + Eigen::VectorXd collision_points = cvv->core_dof(vertices); FC_vv.emplace_back( VertexVertexNormalCollision( cc[0], cc[1], 1., Eigen::SparseVector()), @@ -55,11 +53,10 @@ void TangentialCollisions::build_for_smooth_contact( FC_vv.back().mu = blend_mu(mus(v0i), mus(v1i)); ptr = &(FC_vv.back()); } else if ( - const auto cev = dynamic_cast< - const SmoothCollisionTemplate*>( - &cc)) { - Eigen::VectorXd collision_points = - cev->core_dof(vertices, edges, faces); + const auto cev = + dynamic_cast*>( + &cc)) { + Eigen::VectorXd collision_points = cev->core_dof(vertices); collision_points = collision_points({ 6, 7, 8, 0, 1, 2, 3, 4, 5 }) .eval(); // {edge, point} -> {point, edge} @@ -76,12 +73,11 @@ void TangentialCollisions::build_for_smooth_contact( FC_ev.back().mu = blend_mu(edge_mu, mus(vi)); ptr = &(FC_ev.back()); } else if ( - const auto cee = dynamic_cast< - const SmoothCollisionTemplate*>( - &cc)) { - Eigen::VectorXd collision_points = - cee->core_dof(vertices, edges, faces); - const auto vert_ids = cee->core_vertex_ids(edges, faces); + const auto cee = + dynamic_cast*>( + &cc)) { + Eigen::VectorXd collision_points = cee->core_dof(vertices); + const auto vert_ids = cee->core_vertex_ids(); const Eigen::Vector3d ea0 = vertices.row(vert_ids[0]); const Eigen::Vector3d ea1 = vertices.row(vert_ids[1]); const Eigen::Vector3d eb0 = vertices.row(vert_ids[2]); @@ -107,11 +103,10 @@ void TangentialCollisions::build_for_smooth_contact( FC_ee.back().mu = blend_mu(ea_mu, eb_mu); ptr = &(FC_ee.back()); } else if ( - const auto cfv = dynamic_cast< - const SmoothCollisionTemplate*>( - &cc)) { - Eigen::VectorXd collision_points = - cfv->core_dof(vertices, edges, faces); + const auto cfv = + dynamic_cast*>( + &cc)) { + Eigen::VectorXd collision_points = cfv->core_dof(vertices); collision_points = collision_points({ 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8 }) .eval(); // {face, point} -> {point, face} @@ -129,13 +124,12 @@ void TangentialCollisions::build_for_smooth_contact( ptr = &(FC_fv.back()); } if (ptr) - ptr->smooth_collision_3d = collisions.collisions[i]; + ptr->smooth_collision = collisions.collisions[i]; } else { TangentialCollision* ptr = nullptr; - if (const auto cvv = dynamic_cast*>(&cc)) { - Eigen::VectorXd collision_points = - cvv->core_dof(vertices, edges, faces); + if (const auto cvv = dynamic_cast< + const SmoothCollisionTemplate*>(&cc)) { + Eigen::VectorXd collision_points = cvv->core_dof(vertices); FC_vv.emplace_back( VertexVertexNormalCollision( cc[0], cc[1], 1., Eigen::SparseVector()), @@ -146,11 +140,10 @@ void TangentialCollisions::build_for_smooth_contact( FC_vv.back().mu = blend_mu(mus(v0i), mus(v1i)); ptr = &(FC_vv.back()); } else if ( - const auto cev = dynamic_cast< - const SmoothCollisionTemplate*>( - &cc)) { - Eigen::VectorXd collision_points = - cev->core_dof(vertices, edges, faces); + const auto cev = + dynamic_cast*>( + &cc)) { + Eigen::VectorXd collision_points = cev->core_dof(vertices); collision_points = collision_points({ 4, 5, 0, 1, 2, 3 }) .eval(); // {edge, point} -> {point, edge} @@ -168,29 +161,11 @@ void TangentialCollisions::build_for_smooth_contact( ptr = &(FC_ev.back()); } if (ptr) - ptr->smooth_collision_2d = collisions.collisions[i]; + ptr->smooth_collision = collisions.collisions[i]; } } } -template void TangentialCollisions::build_for_smooth_contact<2>( - const CollisionMesh& mesh, - const Eigen::MatrixXd& vertices, - const SmoothCollisions<2>& collisions, - const ParameterType& params, - const double barrier_stiffness, - const Eigen::VectorXd& mus, - const std::function& blend_mu); - -template void TangentialCollisions::build_for_smooth_contact<3>( - const CollisionMesh& mesh, - const Eigen::MatrixXd& vertices, - const SmoothCollisions<3>& collisions, - const ParameterType& params, - const double barrier_stiffness, - const Eigen::VectorXd& mus, - const std::function& blend_mu); - void TangentialCollisions::build( const CollisionMesh& mesh, Eigen::ConstRef vertices, diff --git a/src/ipc/collisions/tangential/tangential_collisions.hpp b/src/ipc/collisions/tangential/tangential_collisions.hpp index 1b57d54c6..6b902f84f 100644 --- a/src/ipc/collisions/tangential/tangential_collisions.hpp +++ b/src/ipc/collisions/tangential/tangential_collisions.hpp @@ -46,11 +46,10 @@ class TangentialCollisions { const std::function& blend_mu = default_blend_mu); - template void build_for_smooth_contact( const CollisionMesh& mesh, const Eigen::MatrixXd& vertices, - const SmoothCollisions& collisions, + const SmoothCollisions& collisions, const ParameterType& params, const double barrier_stiffness, const Eigen::VectorXd& mus, diff --git a/src/ipc/collisions/tangential/vertex_vertex.cpp b/src/ipc/collisions/tangential/vertex_vertex.cpp index 9da2932b0..2075627e7 100644 --- a/src/ipc/collisions/tangential/vertex_vertex.cpp +++ b/src/ipc/collisions/tangential/vertex_vertex.cpp @@ -21,8 +21,7 @@ VertexVertexTangentialCollision::VertexVertexTangentialCollision( const double normal_force) : VertexVertexTangentialCollision(collision) { - TangentialCollision::init( - collision, positions, normal_force); + TangentialCollision::init(collision, positions, normal_force); } VertexVertexTangentialCollision::VertexVertexTangentialCollision( diff --git a/src/ipc/distance/edge_edge.cpp b/src/ipc/distance/edge_edge.cpp index d64955486..49f32e787 100644 --- a/src/ipc/distance/edge_edge.cpp +++ b/src/ipc/distance/edge_edge.cpp @@ -1,6 +1,7 @@ #include "edge_edge.hpp" + #include #include #include diff --git a/src/ipc/potentials/potential.hpp b/src/ipc/potentials/potential.hpp index 2cecbae65..c3bc708cb 100644 --- a/src/ipc/potentials/potential.hpp +++ b/src/ipc/potentials/potential.hpp @@ -59,14 +59,16 @@ template class Potential { /// @param x The collision stencil's degrees of freedom. /// @return The potential. virtual double operator()( - const TCollision& collision, Eigen::ConstRef> x) const = 0; + const TCollision& collision, + Eigen::ConstRef> x) const = 0; /// @brief Compute the gradient of the potential for a single collision. /// @param collision The collision. /// @param x The collision stencil's degrees of freedom. /// @return The gradient of the potential. virtual Vector gradient( - const TCollision& collision, Eigen::ConstRef> x) const = 0; + const TCollision& collision, + Eigen::ConstRef> x) const = 0; /// @brief Compute the hessian of the potential for a single collision. /// @param collision The collision. diff --git a/src/ipc/potentials/potential.tpp b/src/ipc/potentials/potential.tpp index 6049e352c..a31024971 100644 --- a/src/ipc/potentials/potential.tpp +++ b/src/ipc/potentials/potential.tpp @@ -3,11 +3,11 @@ #include "potential.hpp" #include +#include #include #include #include -#include namespace ipc { @@ -54,9 +54,12 @@ Eigen::VectorXd Potential::gradient( const int dim = X.cols(); - auto storage = ipc::utils::create_thread_storage(Eigen::VectorXd::Zero(X.size())); - ipc::utils::maybe_parallel_for(collisions.size(), [&](int start, int end, int thread_id) { - auto& global_grad = ipc::utils::get_local_thread_storage(storage, thread_id); + auto storage = ipc::utils::create_thread_storage( + Eigen::VectorXd::Zero(X.size())); + ipc::utils::maybe_parallel_for( + collisions.size(), [&](int start, int end, int thread_id) { + auto& global_grad = + ipc::utils::get_local_thread_storage(storage, thread_id); for (size_t i = start; i < end; i++) { const TCollision& collision = collisions[i]; @@ -76,7 +79,7 @@ Eigen::VectorXd Potential::gradient( Eigen::VectorXd grad; grad.setZero(X.size()); - for (const auto &local_storage : storage) + for (const auto& local_storage : storage) grad += local_storage; return grad; } @@ -102,9 +105,12 @@ Eigen::SparseMatrix Potential::hessian( const int max_triplets_size = int(1e7); const int buffer_size = std::min(max_triplets_size, ndof); - auto storage = ipc::utils::create_thread_storage(LocalThreadMatStorage(buffer_size, ndof, ndof)); - ipc::utils::maybe_parallel_for(collisions.size(), [&](int start, int end, int thread_id) { - auto& hess_triplets = ipc::utils::get_local_thread_storage(storage, thread_id); + auto storage = ipc::utils::create_thread_storage( + LocalThreadMatStorage(buffer_size, ndof, ndof)); + ipc::utils::maybe_parallel_for( + collisions.size(), [&](int start, int end, int thread_id) { + auto& hess_triplets = + ipc::utils::get_local_thread_storage(storage, thread_id); for (size_t i = start; i < end; i++) { const TCollision& collision = collisions[i]; @@ -126,22 +132,20 @@ Eigen::SparseMatrix Potential::hessian( Eigen::SparseMatrix hess(ndof, ndof); - // Assemble the stiffness matrix by concatenating the tuples in each local storage + // Assemble the stiffness matrix by concatenating the tuples in each local + // storage // Collect thread storages - std::vector storages(storage.size()); + std::vector storages(storage.size()); int index = 0; - for (auto &local_storage : storage) - { + for (auto& local_storage : storage) { storages[index++] = &local_storage; } - utils::maybe_parallel_for(storages.size(), [&](int i) { - storages[i]->cache->prune(); - }); + utils::maybe_parallel_for( + storages.size(), [&](int i) { storages[i]->cache->prune(); }); - if (storage.size() == 0) - { + if (storage.size() == 0) { return Eigen::SparseMatrix(); } @@ -150,8 +154,7 @@ Eigen::SparseMatrix Potential::hessian( index = 0; int triplet_count = 0; - for (auto &local_storage : storage) - { + for (auto& local_storage : storage) { offsets[index++] = triplet_count; triplet_count += local_storage.cache->triplet_count(); } @@ -159,47 +162,48 @@ Eigen::SparseMatrix Potential::hessian( std::vector> triplets; assert(storages.size() >= 1); - if (storages[0]->cache->is_dense()) - { + if (storages[0]->cache->is_dense()) { // Serially merge local storages Eigen::MatrixXd tmp(hess); - for (const auto &local_storage : storage) - tmp += dynamic_cast(*local_storage.cache).mat(); + for (const auto& local_storage : storage) + tmp += dynamic_cast(*local_storage.cache) + .mat(); hess = tmp.sparseView(); hess.makeCompressed(); - } - else if (triplet_count >= triplets.max_size()) - { - // Serial fallback version in case the vector of triplets cannot be allocated + } else if (triplet_count >= triplets.max_size()) { + // Serial fallback version in case the vector of triplets cannot be + // allocated - logger().warn("Cannot allocate space for triplets, switching to serial assembly."); + logger().warn( + "Cannot allocate space for triplets, switching to serial assembly."); // Serially merge local storages - for (LocalThreadMatStorage &local_storage : storage) + for (LocalThreadMatStorage& local_storage : storage) hess += local_storage.cache->get_matrix(false); // will also prune hess.makeCompressed(); - } - else - { + } else { triplets.resize(triplet_count); // Parallel copy into triplets utils::maybe_parallel_for(storages.size(), [&](int i) { - const SparseMatrixCache &cache = dynamic_cast(*storages[i]->cache); + const SparseMatrixCache& cache = + dynamic_cast(*storages[i]->cache); int offset = offsets[i]; - std::copy(cache.entries().begin(), cache.entries().end(), triplets.begin() + offset); + std::copy( + cache.entries().begin(), cache.entries().end(), + triplets.begin() + offset); offset += cache.entries().size(); - if (cache.mat().nonZeros() > 0) - { + if (cache.mat().nonZeros() > 0) { int count = 0; - for (int k = 0; k < cache.mat().outerSize(); ++k) - { - for (Eigen::SparseMatrix::InnerIterator it(cache.mat(), k); it; ++it) - { + for (int k = 0; k < cache.mat().outerSize(); ++k) { + for (Eigen::SparseMatrix::InnerIterator it( + cache.mat(), k); + it; ++it) { assert(count < cache.mat().nonZeros()); - triplets[offset + count++] = Eigen::Triplet(it.row(), it.col(), it.value()); + triplets[offset + count++] = Eigen::Triplet( + it.row(), it.col(), it.value()); } } } diff --git a/src/ipc/potentials/tangential_potential.cpp b/src/ipc/potentials/tangential_potential.cpp index 34aa11cf5..212aa31cb 100644 --- a/src/ipc/potentials/tangential_potential.cpp +++ b/src/ipc/potentials/tangential_potential.cpp @@ -498,8 +498,7 @@ Eigen::VectorXd TangentialPotential::smooth_contact_force( local_force = smooth_contact_force( collision, collision.dof(rest_positions, edges, faces), collision.dof(lagged_displacements, edges, faces), - collision.dof(velocities, edges, faces), - no_mu); + collision.dof(velocities, edges, faces), no_mu); const auto vis = collision.vertex_ids(mesh.edges(), mesh.faces()); @@ -535,7 +534,8 @@ Eigen::SparseMatrix TangentialPotential::smooth_contact_force_jacobian( tbb::enumerable_thread_specific>> storage; - const Eigen::MatrixXd lagged_positions = rest_positions + lagged_displacements; + const Eigen::MatrixXd lagged_positions = + rest_positions + lagged_displacements; tbb::parallel_for( tbb::blocked_range(size_t(0), collisions.size()), @@ -547,9 +547,7 @@ Eigen::SparseMatrix TangentialPotential::smooth_contact_force_jacobian( // This jacobian doesn't include the derivatives of normal // contact force - const MatrixMax< - double, element_size, - element_size> + const MatrixMax local_force_jacobian = collision.normal_force_magnitude * force_jacobian_unit( @@ -576,38 +574,20 @@ Eigen::SparseMatrix TangentialPotential::smooth_contact_force_jacobian( local_force = smooth_contact_force( collision, collision.dof(rest_positions, edges, faces), collision.dof(lagged_displacements, edges, faces), - collision.dof(velocities, edges, faces), - false, true); + collision.dof(velocities, edges, faces), false, true); // normal_force_grad is the gradient of contact force norm Eigen::VectorXd normal_force_grad; std::vector cc_vert_ids; - { - Eigen::MatrixXd Xt = rest_positions + lagged_displacements; - if (dim == 2) { - auto cc = collision.smooth_collision_2d; - const Eigen::VectorXd contact_grad = - cc->gradient(cc->dof(Xt, edges, faces), params); - const Eigen::MatrixXd contact_hess = - cc->hessian(cc->dof(Xt, edges, faces), params); - normal_force_grad = (1 / contact_grad.norm()) - * (contact_hess * contact_grad); - auto tmp_ids = cc->vertex_ids(edges, faces); - cc_vert_ids = - std::vector(tmp_ids.begin(), tmp_ids.end()); - } else if (dim == 3) { - auto cc = collision.smooth_collision_3d; - const Eigen::VectorXd contact_grad = - cc->gradient(cc->dof(Xt, edges, faces), params); - const Eigen::MatrixXd contact_hess = - cc->hessian(cc->dof(Xt, edges, faces), params); - normal_force_grad = (1 / contact_grad.norm()) - * (contact_hess * contact_grad); - auto tmp_ids = cc->vertex_ids(edges, faces); - cc_vert_ids = - std::vector(tmp_ids.begin(), tmp_ids.end()); - } - } + Eigen::MatrixXd Xt = rest_positions + lagged_displacements; + auto cc = collision.smooth_collision; + const Eigen::VectorXd contact_grad = + cc->gradient(cc->dof(Xt), params); + const Eigen::MatrixXd contact_hess = + cc->hessian(cc->dof(Xt), params); + normal_force_grad = + (1 / contact_grad.norm()) * (contact_hess * contact_grad); + cc_vert_ids = cc->vertex_ids(); local_jacobian_to_global_triplets( local_force * normal_force_grad.transpose(), vis, @@ -637,7 +617,8 @@ Eigen::SparseMatrix TangentialPotential::smooth_contact_force_jacobian( // collision!"); // } - // Vector local_force = + // Vector local_force + // = // smooth_contact_force( // collision, collision.dof(rest_positions, edges, faces), // collision.dof(lagged_displacements, edges, faces), @@ -684,8 +665,8 @@ TangentialPotential::smooth_contact_force( // TangentialPotential::element_size> u = dof(lagged_displacements, edges, // faces); const Vector v = // dof(velocities, edges, faces); - const Vector lagged_positions = - rest_positions + lagged_displacements; // = x + const Vector + lagged_positions = rest_positions + lagged_displacements; // = x // Compute N(x + u) // const double N = collision.compute_normal_force_magnitude( @@ -750,12 +731,12 @@ Eigen::MatrixXd TangentialPotential::smooth_contact_force_jacobian( // Compute ∇N -- commented, compute it outside // Vector grad_N; // if (need_jac_N_or_T) { - // // ∇ₓN = ∇ᵤN - // grad_N = normal_potential.force_magnitude_gradient( - // collision.compute_distance(lagged_positions), - // collision.compute_distance_gradient(lagged_positions), dmin, - // normal_stiffness); - // assert(grad_N.array().isFinite().all()); + // // ∇ₓN = ∇ᵤN + // grad_N = normal_potential.force_magnitude_gradient( + // collision.compute_distance(lagged_positions), + // collision.compute_distance_gradient(lagged_positions), dmin, + // normal_stiffness); + // assert(grad_N.array().isFinite().all()); // } // Compute P @@ -770,14 +751,10 @@ Eigen::MatrixXd TangentialPotential::smooth_contact_force_jacobian( collision.relative_velocity_matrix(beta); // Compute T = ΓᵀP - const MatrixMax T = - Gamma.transpose() * P; + const MatrixMax T = Gamma.transpose() * P; // Compute ∇T - MatrixMax< - double, - element_size * element_size, 2> - jac_T; + MatrixMax jac_T; if (need_jac_N_or_T) { jac_T.resize(n * n, dim - 1); // ∇T = ∇(ΓᵀP) = ∇ΓᵀP + Γᵀ∇P @@ -792,12 +769,10 @@ Eigen::MatrixXd TangentialPotential::smooth_contact_force_jacobian( // Vertex-vertex does not have a closest point if (beta.size()) { // ∇Γ(β) = ∇ᵦΓ∇β ∈ ℝ^{d×n×n} ≡ ℝ^{nd×n} - const MatrixMax - jac_beta = - collision.compute_closest_point_jacobian(lagged_positions); - const MatrixMax - jac_Gamma_wrt_beta = - collision.relative_velocity_matrix_jacobian(beta); + const MatrixMax jac_beta = + collision.compute_closest_point_jacobian(lagged_positions); + const MatrixMax jac_Gamma_wrt_beta = + collision.relative_velocity_matrix_jacobian(beta); for (int k = 0; k < n; k++) { for (int b = 0; b < beta.size(); b++) { @@ -842,17 +817,12 @@ Eigen::MatrixXd TangentialPotential::smooth_contact_force_jacobian( } // Premultiplied values - const Vector T_times_tau = - T * tau; + const Vector T_times_tau = T * tau; // ------------------------------------------------------------------------ // Compute J = ∇F = ∇(-μ N f₁(‖τ‖)/‖τ‖ T τ) - MatrixMax< - double, element_size, - element_size> - J = MatrixMax< - double, element_size, - element_size>::Zero(n, n); + MatrixMax J = + MatrixMax::Zero(n, n); // = -μ f₁(‖τ‖)/‖τ‖ (T τ) [∇N]ᵀ // if (need_jac_N_or_T) { @@ -923,14 +893,10 @@ TangentialPotential::force_jacobian_unit( collision.relative_velocity_matrix(beta); // Compute T = ΓᵀP - const MatrixMax T = - Gamma.transpose() * P; + const MatrixMax T = Gamma.transpose() * P; // Compute ∇T - MatrixMax< - double, - element_size * element_size, 2> - jac_T; + MatrixMax jac_T; if (need_jac_N_or_T) { jac_T.resize(n * n, dim - 1); // ∇T = ∇(ΓᵀP) = ∇ΓᵀP + Γᵀ∇P @@ -945,12 +911,10 @@ TangentialPotential::force_jacobian_unit( // Vertex-vertex does not have a closest point if (beta.size()) { // ∇Γ(β) = ∇ᵦΓ∇β ∈ ℝ^{d×n×n} ≡ ℝ^{nd×n} - const MatrixMax - jac_beta = - collision.compute_closest_point_jacobian(lagged_positions); - const MatrixMax - jac_Gamma_wrt_beta = - collision.relative_velocity_matrix_jacobian(beta); + const MatrixMax jac_beta = + collision.compute_closest_point_jacobian(lagged_positions); + const MatrixMax jac_Gamma_wrt_beta = + collision.relative_velocity_matrix_jacobian(beta); for (int k = 0; k < n; k++) { for (int b = 0; b < beta.size(); b++) { @@ -995,17 +959,12 @@ TangentialPotential::force_jacobian_unit( } // Premultiplied values - const Vector T_times_tau = - T * tau; + const Vector T_times_tau = T * tau; // ------------------------------------------------------------------------ // Compute J = ∇F = ∇(-μ N f₁(‖τ‖)/‖τ‖ T τ) - MatrixMax< - double, element_size, - element_size> - J = MatrixMax< - double, element_size, - element_size>::Zero(n, n); + MatrixMax J = + MatrixMax::Zero(n, n); // + -μ N T τ [∇(f₁(‖τ‖)/‖τ‖)] J += T_times_tau * grad_f1_over_norm_tau.transpose(); diff --git a/src/ipc/potentials/tangential_potential.hpp b/src/ipc/potentials/tangential_potential.hpp index 7e5aa2ef8..f311e8c5a 100644 --- a/src/ipc/potentials/tangential_potential.hpp +++ b/src/ipc/potentials/tangential_potential.hpp @@ -87,30 +87,23 @@ class TangentialPotential : public Potential { Eigen::ConstRef rest_positions, Eigen::ConstRef lagged_displacements, Eigen::ConstRef velocities, - const ParameterType ¶ms, + const ParameterType& params, const DiffWRT wrt, const double dmin = 0) const; - Vector - smooth_contact_force( + Vector smooth_contact_force( const TangentialCollision& collision, - const Vector& - rest_positions, // = x - const Vector& - lagged_displacements, // = u - const Vector& - velocities, // = v + const Vector& rest_positions, // = x + const Vector& lagged_displacements, // = u + const Vector& velocities, // = v const bool no_mu = false, const bool no_contact_force_multiplier = false) const; Eigen::MatrixXd smooth_contact_force_jacobian( const TangentialCollision& collision, - const Vector& - rest_positions, // = x - const Vector& - lagged_displacements, // = u - const Vector& - velocities, // = v + const Vector& rest_positions, // = x + const Vector& lagged_displacements, // = u + const Vector& velocities, // = v const DiffWRT wrt) const; /// @brief Compute the friction force Jacobian assuming the contact force magnitude being 1. diff --git a/src/ipc/smooth_contact/CMakeLists.txt b/src/ipc/smooth_contact/CMakeLists.txt index dd5313508..93ad869af 100644 --- a/src/ipc/smooth_contact/CMakeLists.txt +++ b/src/ipc/smooth_contact/CMakeLists.txt @@ -1,5 +1,6 @@ set(SOURCES common.hpp + smooth_contact_potential.cpp smooth_contact_potential.hpp smooth_collisions.cpp smooth_collisions.hpp diff --git a/src/ipc/smooth_contact/collisions/smooth_collision.cpp b/src/ipc/smooth_contact/collisions/smooth_collision.cpp index 7be10aa03..b88c0738a 100644 --- a/src/ipc/smooth_contact/collisions/smooth_collision.cpp +++ b/src/ipc/smooth_contact/collisions/smooth_collision.cpp @@ -2,9 +2,8 @@ namespace ipc { -template -CollisionType -SmoothCollisionTemplate::type() const +template +CollisionType SmoothCollisionTemplate::type() const { if constexpr ( std::is_same_v && std::is_same_v) @@ -31,9 +30,25 @@ SmoothCollisionTemplate::type() const return CollisionType::VertexVertex; } -template -std::string -SmoothCollisionTemplate::name() const +Eigen::VectorXd SmoothCollision::dof(Eigen::ConstRef X) const +{ + const int dim = X.cols(); + Eigen::VectorXd x(num_vertices() * dim); + if (dim == 2) { + for (int i = 0; i < num_vertices(); i++) { + x.segment<2>(i * 2) = X.row(vertex_ids_[i]); + } + } else if (dim == 3) { + for (int i = 0; i < num_vertices(); i++) { + x.segment<3>(i * 3) = X.row(vertex_ids_[i]); + } + } else + throw std::runtime_error("Invalid dimension!"); + return x; +} + +template +std::string SmoothCollisionTemplate::name() const { if constexpr ( std::is_same_v && std::is_same_v) @@ -60,9 +75,9 @@ SmoothCollisionTemplate::name() const return "vert-vert"; } -template -auto SmoothCollisionTemplate:: - get_core_indices() const -> Vector +template +auto SmoothCollisionTemplate::get_core_indices() const + -> Vector { Vector core_indices; core_indices << Eigen::VectorXi::LinSpaced( @@ -72,17 +87,16 @@ auto SmoothCollisionTemplate:: return core_indices; } -template -SmoothCollisionTemplate:: - SmoothCollisionTemplate( - index_t primitive0_, - index_t primitive1_, - SmoothCollisionTemplate::DTYPE dtype, - const CollisionMesh& mesh, - const ParameterType& param, - const double& dhat, - const Eigen::MatrixXd& V) - : SmoothCollision(primitive0_, primitive1_, dhat, mesh) +template +SmoothCollisionTemplate::SmoothCollisionTemplate( + index_t primitive0_, + index_t primitive1_, + SmoothCollisionTemplate::DTYPE dtype, + const CollisionMesh& mesh, + const ParameterType& param, + const double& dhat, + const Eigen::MatrixXd& V) + : SmoothCollision(primitive0_, primitive1_, dhat, mesh) { VectorMax3d d = PrimitiveDistance::compute_closest_direction( @@ -90,30 +104,35 @@ SmoothCollisionTemplate:: pA = std::make_unique(primitive0_, mesh, V, d, param); pB = std::make_unique(primitive1_, mesh, V, -d, param); - if (pA->n_vertices() + pB->n_vertices() > max_vert) + if ((pA->n_vertices() + pB->n_vertices()) * dim > element_size) logger().error( "Too many neighbors for collision pair! {} > {}! Increase max_vert_3d in common.hpp", - pA->n_vertices() + pB->n_vertices(), max_vert); + pA->n_vertices() + pB->n_vertices(), max_vert_3d); int i = 0; + Super::vertex_ids_.assign( + pA->vertex_ids().size() + pB->vertex_ids().size(), -1); for (auto& v : pA->vertex_ids()) - Super::vertices[i++] = v; + Super::vertex_ids_[i++] = v; for (auto& v : pB->vertex_ids()) - Super::vertices[i++] = v; + Super::vertex_ids_[i++] = v; assert(i == pA->n_vertices() + pB->n_vertices()); Super::is_active_ = - (d.norm() < Super::get_dhat()) && pA->is_active() && pB->is_active(); + (d.norm() < Super::dhat()) && pA->is_active() && pB->is_active(); - if (d.norm() < 1e-12) + if (d.norm() < 1e-12) { logger().warn( "pair distance {}, id {} and {}, dtype {}, active {}", d.norm(), primitive0_, primitive1_, PrimitiveDistType::name, Super::is_active_); + + logger().warn("value {}", (*this)(this->dof(V), param)); + } } -template -double SmoothCollisionTemplate::operator()( - Eigen::ConstRef> positions, +template +double SmoothCollisionTemplate::operator()( + Eigen::ConstRef> positions, const ParameterType& params) const { Vector x; @@ -129,23 +148,26 @@ double SmoothCollisionTemplate::operator()( assert(positions.size() == pA->n_dofs() + pB->n_dofs()); double a1 = pA->potential(closest_direction, positions.head(pA->n_dofs())); double a2 = pB->potential(-closest_direction, positions.tail(pB->n_dofs())); - double a3 = Math::inv_barrier(dist / Super::get_dhat(), params.r); + double a3 = Math::inv_barrier(dist / Super::dhat(), params.r); double a4 = PrimitiveDistanceTemplate::mollifier( x, dist * dist); + if (params.r == 0) + logger().error("Invalid param!"); + if (dist < 1e-12) logger().warn( - "pair distance {:.3e}, barrier {:.3e}, mollifier {:.3e}, orient {:.3e} {:.3e}", - dist, a3, a4, a1, a2); + "pair distance {:.3e}, dhat {:.3e}, r {}, barrier {:.3e}, mollifier {:.3e}, orient {:.3e} {:.3e}", + dist, Super::dhat(), params.r, a3, a4, a1, a2); return a1 * a2 * a3 * a4; } -template -auto SmoothCollisionTemplate::gradient( - Eigen::ConstRef> positions, - const ParameterType& params) const -> Vector +template +auto SmoothCollisionTemplate::gradient( + Eigen::ConstRef> positions, + const ParameterType& params) const -> Vector { const auto core_indices = get_core_indices(); @@ -172,13 +194,13 @@ auto SmoothCollisionTemplate::gradient( double barrier = 0; Vector gBarrier = Vector::Zero(); { - barrier = Math::inv_barrier(dist / Super::get_dhat(), params.r); + barrier = Math::inv_barrier(dist / Super::dhat(), params.r); const Vector closest_direction_normalized = closest_direction / dist; const double barrier_1st_deriv = - Math::inv_barrier_grad(dist / Super::get_dhat(), params.r) - / Super::get_dhat(); + Math::inv_barrier_grad(dist / Super::dhat(), params.r) + / Super::dhat(); const Vector gBarrier_wrt_d = barrier_1st_deriv * closest_direction_normalized; gBarrier = closest_direction_grad.transpose() * gBarrier_wrt_d; @@ -219,12 +241,11 @@ auto SmoothCollisionTemplate::gradient( // grad of tangent/normal terms double orient = 0; - Vector gOrient; + Vector gOrient; { - Vector gA = Vector::Zero( - n_dofs()), - gB = Vector::Zero( - n_dofs()); + Vector + gA = Vector::Zero(n_dofs()), + gB = Vector::Zero(n_dofs()); { gA(core_indices) = closest_direction_grad.transpose() * gA_reduced.head(dim); @@ -251,10 +272,11 @@ auto SmoothCollisionTemplate::gradient( return gOrient; } -template -auto SmoothCollisionTemplate::hessian( - Eigen::ConstRef> positions, - const ParameterType& params) const -> Eigen::MatrixXd +template +auto SmoothCollisionTemplate::hessian( + Eigen::ConstRef> positions, + const ParameterType& params) const + -> MatrixMax { const auto core_indices = get_core_indices(); @@ -290,20 +312,20 @@ auto SmoothCollisionTemplate::hessian( Eigen::Matrix hBarrier = Eigen::Matrix::Zero(); { - barrier = Math::inv_barrier(dist / Super::get_dhat(), params.r); + barrier = Math::inv_barrier(dist / Super::dhat(), params.r); const Vector closest_direction_normalized = closest_direction / dist; const double barrier_1st_deriv = - Math::inv_barrier_grad(dist / Super::get_dhat(), params.r) - / Super::get_dhat(); + Math::inv_barrier_grad(dist / Super::dhat(), params.r) + / Super::dhat(); const Vector gBarrier_wrt_d = barrier_1st_deriv * closest_direction_normalized; gBarrier = closest_direction_grad.transpose() * gBarrier_wrt_d; const double barrier_2nd_deriv = - Math::inv_barrier_hess(dist / Super::get_dhat(), params.r) - / Super::get_dhat() / Super::get_dhat(); + Math::inv_barrier_hess(dist / Super::dhat(), params.r) + / Super::dhat() / Super::dhat(); const Eigen::Matrix hBarrier_wrt_d = (barrier_1st_deriv / dist) * Eigen::Matrix::Identity() @@ -374,15 +396,17 @@ auto SmoothCollisionTemplate::hessian( // grad of tangent/normal terms double orient = 0; - Vector gOrient; - Eigen::MatrixXd hOrient; + Vector gOrient; + MatrixMax hOrient; { - Vector gA = Vector::Zero( - n_dofs()), - gB = Vector::Zero( - n_dofs()); - Eigen::MatrixXd hA = Eigen::MatrixXd::Zero(n_dofs(), n_dofs()), - hB = Eigen::MatrixXd::Zero(n_dofs(), n_dofs()); + Vector + gA = Vector::Zero(n_dofs()), + gB = Vector::Zero(n_dofs()); + MatrixMax + hA = MatrixMax::Zero( + n_dofs(), n_dofs()), + hB = MatrixMax::Zero( + n_dofs(), n_dofs()); { gA(core_indices) = closest_direction_grad.transpose() * gA_reduced.head(dim); @@ -448,11 +472,12 @@ auto SmoothCollisionTemplate::hessian( // ---- distance ---- -template -double -SmoothCollisionTemplate::compute_distance( - Eigen::ConstRef> positions) const +template +double SmoothCollisionTemplate::compute_distance( + Eigen::ConstRef vertices) const { + Vector positions = dof(vertices); + Vector x; x << positions.head(PrimitiveA::n_core_points * dim), positions.segment(pA->n_dofs(), PrimitiveB::n_core_points * dim); @@ -465,70 +490,23 @@ SmoothCollisionTemplate::compute_distance( return closest_direction.squaredNorm(); } -template -auto SmoothCollisionTemplate:: - compute_distance_gradient( - Eigen::ConstRef> positions) const - -> Vector -{ - Vector x; - x << positions.head(PrimitiveA::n_core_points * dim), - positions.segment(pA->n_dofs(), PrimitiveB::n_core_points * dim); - - Vector closest_direction; - Eigen::Matrix closest_direction_grad; - std::tie(closest_direction, closest_direction_grad) = - PrimitiveDistance:: - compute_closest_direction_gradient(x, DTYPE::AUTO); - - return 2 * closest_direction_grad.transpose() * closest_direction; -} - -template -auto SmoothCollisionTemplate:: - compute_distance_hessian( - Eigen::ConstRef> positions) const - -> MatrixMax -{ - Vector x; - x << positions.head(PrimitiveA::n_core_points * dim), - positions.segment(pA->n_dofs(), PrimitiveB::n_core_points * dim); - - Vector closest_direction; - Eigen::Matrix closest_direction_grad; - std::array, dim> - closest_direction_hess; - std::tie( - closest_direction, closest_direction_grad, closest_direction_hess) = - PrimitiveDistance:: - compute_closest_direction_hessian(x, DTYPE::AUTO); - - Eigen::Matrix dist_sqr_hess = - 2 * closest_direction_grad.transpose() * closest_direction_grad; - for (int d = 0; d < dim; d++) - dist_sqr_hess += 2 * closest_direction(d) * closest_direction_hess[d]; - - return dist_sqr_hess; -} - -template -auto SmoothCollisionTemplate::core_vertex_ids( - const Eigen::MatrixXi& edges, const Eigen::MatrixXi& faces) const +template +auto SmoothCollisionTemplate::core_vertex_ids() const -> std::array { std::array vids; auto ids = get_core_indices(); for (int i = 0; i < n_core_dofs; i++) - vids[i] = Super::vertices[ids[i]]; + vids[i] = Super::vertex_ids_[ids[i]]; return vids; } // Note: Primitive pair order cannot change -template class SmoothCollisionTemplate; -template class SmoothCollisionTemplate; +template class SmoothCollisionTemplate; +template class SmoothCollisionTemplate; -template class SmoothCollisionTemplate; -template class SmoothCollisionTemplate; -template class SmoothCollisionTemplate; -template class SmoothCollisionTemplate; +template class SmoothCollisionTemplate; +template class SmoothCollisionTemplate; +template class SmoothCollisionTemplate; +template class SmoothCollisionTemplate; } // namespace ipc \ No newline at end of file diff --git a/src/ipc/smooth_contact/collisions/smooth_collision.hpp b/src/ipc/smooth_contact/collisions/smooth_collision.hpp index 3b806e183..3e9820c3e 100644 --- a/src/ipc/smooth_contact/collisions/smooth_collision.hpp +++ b/src/ipc/smooth_contact/collisions/smooth_collision.hpp @@ -13,9 +13,10 @@ enum class CollisionType { EdgeEdge, }; -template -class SmoothCollision : public CollisionStencil { -protected: +class SmoothCollision { +public: + constexpr static int element_size = 3 * max_vert_3d; + SmoothCollision( long primitive0_, long primitive1_, @@ -25,76 +26,66 @@ class SmoothCollision : public CollisionStencil { , primitive1(primitive1_) , dhat_(dhat) { - vertices.fill(-1); } -public: - constexpr static int max_size = max_vert * 3; virtual ~SmoothCollision() = default; bool is_active() const { return is_active_; } + double dhat() const { return dhat_; } + + virtual std::string name() const = 0; + virtual int n_dofs() const = 0; + virtual CollisionType type() const = 0; - std::array vertex_ids( - Eigen::ConstRef edges, - Eigen::ConstRef faces) const override + /// @brief Get the number of vertices in the collision stencil. + virtual int num_vertices() const = 0; + + /// @brief Get the vertex IDs of the collision stencil. + /// @return The vertex IDs of the collision stencil. Size is always 4, but elements i > num_vertices() are -1. + std::vector vertex_ids() const { return vertex_ids_; } + + /// @brief Get the vertex attributes of the collision stencil. + /// @tparam T Type of the attributes + /// @param vertices Vertex attributes + /// @return The vertex positions of the collision stencil. Size is always 4, but elements i > num_vertices() are NaN. + Eigen::MatrixXd vertices(Eigen::ConstRef vertices) const { - return vertices; + const int dim = vertices.cols(); + Eigen::MatrixXd stencil_vertices(vertex_ids_.size(), dim); + for (int i = 0; i < vertex_ids_.size(); i++) { + stencil_vertices.row(i) = vertices.row(vertex_ids_[i]); + } + + return stencil_vertices; } - // ---- non distance type potential ---- + /// @brief Select this stencil's DOF from the full matrix of DOF. + /// @tparam T Type of the DOF + /// @param X Full matrix of DOF (rowwise). + /// @return This stencil's DOF. + Eigen::VectorXd dof(Eigen::ConstRef X) const; + + /// @brief Compute the distance of the stencil. + /// @param vertices Collision mesh vertices + /// @return Distance of the stencil. + virtual double + compute_distance(Eigen::ConstRef vertices) const = 0; virtual double operator()( - Eigen::ConstRef> positions, + Eigen::ConstRef> positions, const ParameterType& params) const = 0; - virtual Vector gradient( - Eigen::ConstRef> positions, + virtual Vector gradient( + Eigen::ConstRef> positions, const ParameterType& params) const = 0; - virtual Eigen::MatrixXd hessian( - Eigen::ConstRef> positions, + virtual MatrixMax hessian( + Eigen::ConstRef> positions, const ParameterType& params) const = 0; - // ---- distance ---- - - Vector compute_distance_gradient( - Eigen::ConstRef> positions) - const override - { - return Vector::Zero(max_size); - } - - MatrixMax compute_distance_hessian( - Eigen::ConstRef> positions) - const override - { - return MatrixMax::Zero(max_size, max_size); - } - - VectorMax4d compute_coefficients( - Eigen::ConstRef> positions) - const override - { - VectorMax4d coeffs(4); - coeffs << 0, 0, 0, 0; - return coeffs; - } - - bool - ccd(Eigen::ConstRef> vertices_t0, - Eigen::ConstRef> vertices_t1, - double& toi, - const double min_distance = 0.0, - const double tmax = 1.0, - const NarrowPhaseCCD& narrow_phase_ccd = - DEFAULT_NARROW_PHASE_CCD) const override - { - return false; - } - bool operator==(const SmoothCollision& other) const { return ( @@ -119,23 +110,19 @@ class SmoothCollision : public CollisionStencil { return std::make_pair(primitive0, primitive1); } - double get_dhat() const { return dhat_; } - - virtual std::string name() const { return ""; } - double weight = 1; protected: bool is_active_ = true; index_t primitive0, primitive1; double dhat_; - std::array vertices; + std::vector vertex_ids_; }; -template -class SmoothCollisionTemplate : public SmoothCollision { +template +class SmoothCollisionTemplate : public SmoothCollision { public: - using Super = SmoothCollision; + using Super = SmoothCollision; using DTYPE = typename PrimitiveDistType::type; constexpr static int n_core_points = PrimitiveA::n_core_points + PrimitiveB::n_core_points; @@ -143,7 +130,7 @@ class SmoothCollisionTemplate : public SmoothCollision { constexpr static int n_core_dofs_A = PrimitiveA::n_core_points * dim; constexpr static int n_core_dofs_B = PrimitiveB::n_core_points * dim; constexpr static int n_core_dofs = n_core_points * dim; - constexpr static int max_size = SmoothCollision::max_size; + constexpr static int element_size = Super::element_size; SmoothCollisionTemplate( index_t primitive0_, @@ -161,8 +148,7 @@ class SmoothCollisionTemplate : public SmoothCollision { CollisionType type() const override; Vector get_core_indices() const; - std::array core_vertex_ids( - const Eigen::MatrixXi& edges, const Eigen::MatrixXi& faces) const; + std::array core_vertex_ids() const; inline int num_vertices() const override { @@ -170,41 +156,29 @@ class SmoothCollisionTemplate : public SmoothCollision { } template - Vector core_dof( - const MatrixX& X, - const Eigen::MatrixXi& edges, - const Eigen::MatrixXi& faces) const + Vector core_dof(const MatrixX& X) const { - return this->dof(X, edges, faces)(get_core_indices()); + return this->dof(X)(get_core_indices()); } // ---- non distance type potential ---- double operator()( - Eigen::ConstRef> positions, + Eigen::ConstRef> positions, const ParameterType& params) const override; - Vector gradient( - Eigen::ConstRef> positions, + Vector gradient( + Eigen::ConstRef> positions, const ParameterType& params) const override; - Eigen::MatrixXd hessian( - Eigen::ConstRef> positions, + MatrixMax hessian( + Eigen::ConstRef> positions, const ParameterType& params) const override; // ---- distance ---- - double compute_distance( - Eigen::ConstRef> positions) - const override; - - Vector compute_distance_gradient( - Eigen::ConstRef> positions) - const override; - - MatrixMax compute_distance_hessian( - Eigen::ConstRef> positions) - const override; + double + compute_distance(Eigen::ConstRef vertices) const override; private: std::unique_ptr pA; diff --git a/src/ipc/smooth_contact/distance/edge_edge.cpp b/src/ipc/smooth_contact/distance/edge_edge.cpp index b22fb0e6c..a4ce5f314 100644 --- a/src/ipc/smooth_contact/distance/edge_edge.cpp +++ b/src/ipc/smooth_contact/distance/edge_edge.cpp @@ -1,9 +1,11 @@ #include "edge_edge.hpp" -#include -#include #include "autogen.hpp" +#include + +#include + namespace ipc { std::tuple> @@ -16,7 +18,8 @@ line_line_closest_point_direction_gradient( const Vector3d ea = ea1 - ea0; const Vector3d eb = eb1 - eb0; const Vector3d normal = ea.cross(eb); - const Eigen::Matrix cross_grad = cross_product_gradient(ea, eb); + const Eigen::Matrix cross_grad = + cross_product_gradient(ea, eb); const double normal_sqr_norm = normal.squaredNorm(); const Vector3d t = eb0 - ea0; @@ -24,13 +27,19 @@ line_line_closest_point_direction_gradient( Eigen::Matrix grad = Eigen::Matrix::Zero(); // derivative wrt. normal, tempararily store here - grad(Eigen::all, {3,4,5}) = (normal * t.transpose() + t.transpose() * normal * Eigen::Matrix3d::Identity() - 2 * vec * normal.transpose()) / normal_sqr_norm; + grad(Eigen::all, { 3, 4, 5 }) = + (normal * t.transpose() + + t.transpose() * normal * Eigen::Matrix3d::Identity() + - 2 * vec * normal.transpose()) + / normal_sqr_norm; // derivative wrt. t grad.middleCols<3>(6) = normal * normal.transpose() / normal_sqr_norm; grad.leftCols<3>() = -grad.middleCols<3>(6); // contributions from n - grad(Eigen::all, {3,4,5, 9,10,11}) = grad(Eigen::all, {3,4,5}) * cross_grad; - grad(Eigen::all, {0,1,2, 6,7,8}) -= grad(Eigen::all, {3,4,5, 9,10,11}); + grad(Eigen::all, { 3, 4, 5, 9, 10, 11 }) = + grad(Eigen::all, { 3, 4, 5 }) * cross_grad; + grad(Eigen::all, { 0, 1, 2, 6, 7, 8 }) -= + grad(Eigen::all, { 3, 4, 5, 9, 10, 11 }); return std::make_tuple(vec, grad); } @@ -45,7 +54,8 @@ line_line_closest_point_direction_hessian( const Vector3d ea = ea1 - ea0; const Vector3d eb = eb1 - eb0; const Vector3d normal = ea.cross(eb); - const Eigen::Matrix cross_grad = cross_product_gradient(ea, eb); + const Eigen::Matrix cross_grad = + cross_product_gradient(ea, eb); const std::array cross_hess = cross_product_hessian(ea, eb); const double normal_sqr_norm = normal.squaredNorm(); @@ -54,22 +64,27 @@ line_line_closest_point_direction_hessian( Eigen::Matrix grad = Eigen::Matrix::Zero(); // derivative wrt. normal and t - Eigen::Matrix3d grad_normal = (normal * t.transpose() - 2 * vec * normal.transpose()) / normal_sqr_norm; - grad_normal.diagonal().array() += (t.transpose() * normal)(0) / normal_sqr_norm; + Eigen::Matrix3d grad_normal = + (normal * t.transpose() - 2 * vec * normal.transpose()) + / normal_sqr_norm; + grad_normal.diagonal().array() += + (t.transpose() * normal)(0) / normal_sqr_norm; Eigen::Matrix3d grad_t = normal * normal.transpose() / normal_sqr_norm; grad.middleCols<3>(6) = grad_t; grad.leftCols<3>() = -grad_t; // contributions from n to ea, eb - grad(Eigen::all, {3,4,5, 9,10,11}) = grad_normal * cross_grad; - grad(Eigen::all, {0,1,2, 6,7,8}) -= grad(Eigen::all, {3,4,5, 9,10,11}); + grad(Eigen::all, { 3, 4, 5, 9, 10, 11 }) = grad_normal * cross_grad; + grad(Eigen::all, { 0, 1, 2, 6, 7, 8 }) -= + grad(Eigen::all, { 3, 4, 5, 9, 10, 11 }); // hessian of output wrt. normal std::array hess_wrt_normal; // hessian of output wrt. normal (row) and t (col) std::array mixed_hess; - for (int d = 0; d < 3; d++) - { - hess_wrt_normal[d] = -2 * (normal * grad_normal.row(d) + grad_normal.row(d).transpose() * normal.transpose()); + for (int d = 0; d < 3; d++) { + hess_wrt_normal[d] = -2 + * (normal * grad_normal.row(d) + + grad_normal.row(d).transpose() * normal.transpose()); hess_wrt_normal[d].col(d) += t; hess_wrt_normal[d].row(d) += t.transpose(); hess_wrt_normal[d].diagonal().array() -= 2 * vec(d); @@ -83,23 +98,29 @@ line_line_closest_point_direction_hessian( // grad and hessian of [normal, t] wrt. [ea0, ea1, eb0, eb1] Eigen::Matrix inner_grad; - inner_grad << -cross_grad.leftCols<3>(), cross_grad.leftCols<3>(), -cross_grad.rightCols<3>(), cross_grad.rightCols<3>(); - + inner_grad << -cross_grad.leftCols<3>(), cross_grad.leftCols<3>(), + -cross_grad.rightCols<3>(), cross_grad.rightCols<3>(); + std::array inner_hess; { Eigen::Matrix2d tmp; tmp << 1, -1, -1, 1; for (int d = 0; d < 3; d++) - inner_hess[d] << Eigen::KroneckerProduct(tmp, cross_hess[d].block<3, 3>(0, 0)), - Eigen::KroneckerProduct(tmp, cross_hess[d].block<3, 3>(0, 3)), - Eigen::KroneckerProduct(tmp, cross_hess[d].block<3, 3>(3, 0)), - Eigen::KroneckerProduct(tmp, cross_hess[d].block<3, 3>(3, 3)); + inner_hess[d] + << Eigen::KroneckerProduct( + tmp, cross_hess[d].block<3, 3>(0, 0)), + Eigen::KroneckerProduct( + tmp, cross_hess[d].block<3, 3>(0, 3)), + Eigen::KroneckerProduct( + tmp, cross_hess[d].block<3, 3>(3, 0)), + Eigen::KroneckerProduct( + tmp, cross_hess[d].block<3, 3>(3, 3)); } - + std::array hess; - for (int d = 0; d < 3; d++) - { - Eigen::Matrix tmp = inner_grad.transpose() * mixed_hess[d]; + for (int d = 0; d < 3; d++) { + Eigen::Matrix tmp = + inner_grad.transpose() * mixed_hess[d]; hess[d] = inner_grad.transpose() * hess_wrt_normal[d] * inner_grad; hess[d].middleCols<3>(6) += tmp; hess[d].middleCols<3>(0) -= tmp; @@ -112,7 +133,6 @@ line_line_closest_point_direction_hessian( return std::make_tuple(vec, grad, hess); } - std::tuple> line_line_closest_point_pairs_gradient( const Eigen::Ref& ea0, @@ -133,7 +153,7 @@ line_line_closest_point_pairs_gradient( grad.block<3, 3>(3, 9).diagonal().array() += uv(1); grad.block<3, 3>(3, 6).diagonal().array() += (1 - uv(1)); - return {out, grad}; + return { out, grad }; } std::tuple, std::array> @@ -158,47 +178,40 @@ line_line_closest_point_pairs_hessian( grad.block<3, 3>(3, 6).diagonal().array() += (1 - uv(1)); std::array hess; - for (auto &h : hess) + for (auto& h : hess) h.setZero(); { Eigen::Matrix Ha, Hb; autogen::edge_edge_closest_point_hessian_a( - ea0.x(), ea0.y(), ea0.z(), - ea1.x(), ea1.y(), ea1.z(), - eb0.x(), eb0.y(), eb0.z(), - eb1.x(), eb1.y(), eb1.z(), - Ha.data()); + ea0.x(), ea0.y(), ea0.z(), ea1.x(), ea1.y(), ea1.z(), eb0.x(), + eb0.y(), eb0.z(), eb1.x(), eb1.y(), eb1.z(), Ha.data()); autogen::edge_edge_closest_point_hessian_b( - ea0.x(), ea0.y(), ea0.z(), - ea1.x(), ea1.y(), ea1.z(), - eb0.x(), eb0.y(), eb0.z(), - eb1.x(), eb1.y(), eb1.z(), - Hb.data()); - - for (int d = 0; d < 3; d++) - { + ea0.x(), ea0.y(), ea0.z(), ea1.x(), ea1.y(), ea1.z(), eb0.x(), + eb0.y(), eb0.z(), eb1.x(), eb1.y(), eb1.z(), Hb.data()); + + for (int d = 0; d < 3; d++) { // wrt. uv hess[d] += (ea1(d) - ea0(d)) * Ha; - hess[d+3] += (eb1(d) - eb0(d)) * Hb; + hess[d + 3] += (eb1(d) - eb0(d)) * Hb; // wrt. ea0 & uv(0) hess[d].row(d) -= J.row(0); hess[d].col(d) -= J.row(0).transpose(); // wrt. ea1 & uv(0) - hess[d].row(d+3) += J.row(0); - hess[d].col(d+3) += J.row(0).transpose(); + hess[d].row(d + 3) += J.row(0); + hess[d].col(d + 3) += J.row(0).transpose(); // wrt. eb0 & uv(1) - hess[d+3].row(d+6) -= J.row(1); - hess[d+3].col(d+6) -= J.row(1).transpose(); + hess[d + 3].row(d + 6) -= J.row(1); + hess[d + 3].col(d + 6) -= J.row(1).transpose(); // wrt. eb1 & uv(1) - hess[d+3].row(d+9) += J.row(1); - hess[d+3].col(d+9) += J.row(1).transpose(); + hess[d + 3].row(d + 9) += J.row(1); + hess[d + 3].col(d + 9) += J.row(1).transpose(); } } - return {out, grad, hess}; -} + return { out, grad, hess }; } +} // namespace ipc diff --git a/src/ipc/smooth_contact/distance/edge_edge.tpp b/src/ipc/smooth_contact/distance/edge_edge.tpp index 1cfce6a42..37072dcb0 100644 --- a/src/ipc/smooth_contact/distance/edge_edge.tpp +++ b/src/ipc/smooth_contact/distance/edge_edge.tpp @@ -183,23 +183,31 @@ Eigen::Matrix edge_edge_closest_point_pairs( break; case EdgeEdgeDistanceType::EA_EB0: - out << eb0 - PointEdgeDistance::point_line_closest_point_direction( - eb0, ea0, ea1), eb0; + out << eb0 + - PointEdgeDistance:: + point_line_closest_point_direction(eb0, ea0, ea1), + eb0; break; case EdgeEdgeDistanceType::EA_EB1: - out << eb1 - PointEdgeDistance::point_line_closest_point_direction( - eb1, ea0, ea1), eb1; + out << eb1 + - PointEdgeDistance:: + point_line_closest_point_direction(eb1, ea0, ea1), + eb1; break; case EdgeEdgeDistanceType::EA0_EB: - out << ea0, ea0 - PointEdgeDistance< - scalar, 3>::point_line_closest_point_direction(ea0, eb0, eb1); + out << ea0, + ea0 + - PointEdgeDistance::point_line_closest_point_direction( + ea0, eb0, eb1); break; case EdgeEdgeDistanceType::EA1_EB: - out << ea1, ea1 - PointEdgeDistance< - scalar, 3>::point_line_closest_point_direction(ea1, eb0, eb1); + out << ea1, + ea1 + - PointEdgeDistance::point_line_closest_point_direction( + ea1, eb0, eb1); break; case EdgeEdgeDistanceType::EA_EB: diff --git a/src/ipc/smooth_contact/distance/mollifier.cpp b/src/ipc/smooth_contact/distance/mollifier.cpp index d0a949e62..9448b6b78 100644 --- a/src/ipc/smooth_contact/distance/mollifier.cpp +++ b/src/ipc/smooth_contact/distance/mollifier.cpp @@ -1,14 +1,17 @@ #ifndef DERIVATIVES_WITH_AUTODIFF #include "mollifier.hpp" -#include + +#include "point_edge.hpp" + #include #include -#include "point_edge.hpp" +#include namespace ipc { namespace { - // double func_aux(const double& a, const double& b, const double& c, const double& eps) + // double func_aux(const double& a, const double& b, const double& c, const + // double& eps) // { // return Math::mollifier((a - c) / c / eps); // } @@ -21,22 +24,22 @@ namespace { return out; } - GradType<3> - func_aux_grad(const double& a, const double& b, const double& c, const double& eps) + GradType<3> func_aux_grad( + const double& a, const double& b, const double& c, const double& eps) { const double val = (a - c) / c / eps; - return std::make_tuple(Math::mollifier(val), - Eigen::Vector3d(1. / c, 0., -a / c / c) * Math::mollifier_grad(val) / eps); + return std::make_tuple( + Math::mollifier(val), + Eigen::Vector3d(1. / c, 0., -a / c / c) + * Math::mollifier_grad(val) / eps); } - HessianType<3> - func_aux_hess(const double& a, const double& b, const double& c, const double& eps) + HessianType<3> func_aux_hess( + const double& a, const double& b, const double& c, const double& eps) { const double c2 = 1. / c / c; Eigen::Matrix3d h1; - h1 << 0., 0., -c2, - 0., 0., 0., - -c2, 0., 2 * a * c2 / c; + h1 << 0., 0., -c2, 0., 0., 0., -c2, 0., 2 * a * c2 / c; Eigen::Vector3d g1; g1 << 1. / c, 0., -a * c2; @@ -44,9 +47,9 @@ namespace { const double g2 = Math::mollifier_grad(val / eps) / eps; const double h2 = Math::mollifier_hess(val / eps) / eps / eps; - return std::make_tuple(Math::mollifier(val / eps), - g1 * g2, - h1 * g2 + g1 * h2 * g1.transpose()); + return std::make_tuple( + Math::mollifier(val / eps), g1 * g2, + h1 * g2 + g1 * h2 * g1.transpose()); } } // namespace @@ -76,16 +79,16 @@ GradType<13> edge_edge_mollifier_gradient( Eigen::Vector4d point_edge_dists; Eigen::Matrix point_edge_dists_grad; point_edge_dists_grad.setZero(); - for (int i = 0; i < 4; i++) - { - point_edge_dists(i) = - point_edge_distance(input.segment<3>(3 * vert_indices(i, 0)), - input.segment<3>(3 * vert_indices(i, 1)), - input.segment<3>(3 * vert_indices(i, 2))); - point_edge_dists_grad(i, dof_indices.row(i)) = - point_edge_distance_gradient(input.segment<3>(3 * vert_indices(i, 0)), + for (int i = 0; i < 4; i++) { + point_edge_dists(i) = point_edge_distance( + input.segment<3>(3 * vert_indices(i, 0)), input.segment<3>(3 * vert_indices(i, 1)), input.segment<3>(3 * vert_indices(i, 2))); + point_edge_dists_grad(i, dof_indices.row(i)) = + point_edge_distance_gradient( + input.segment<3>(3 * vert_indices(i, 0)), + input.segment<3>(3 * vert_indices(i, 1)), + input.segment<3>(3 * vert_indices(i, 2))); } // derivatives of edge lengths @@ -99,14 +102,15 @@ GradType<13> edge_edge_mollifier_gradient( edge_lengths_grad.block<1, 3>(i, 3 + 6 * i) = -2 * edge; } - // derivatives of mollifier and ratios, input order : [dist_sqr, edge_lengths - // (1 x 2), point_edge_dists (1 x 4)] + // derivatives of mollifier and ratios, input order : [dist_sqr, + // edge_lengths (1 x 2), point_edge_dists (1 x 4)] Eigen::Vector4d mollifier; Eigen::Matrix mollifier_grad; mollifier_grad.setZero(); for (int i = 0; i < 4; i++) { const double len = edge_lengths(1 - i / 2); - const auto [val2, g2] = func_aux_grad(point_edge_dists(i), len, input(12), mollifier_threshold_eps); + const auto [val2, g2] = func_aux_grad( + point_edge_dists(i), len, input(12), mollifier_threshold_eps); Eigen::Vector3i ind; ind << 3 + i, 2 - i / 2, 0; @@ -126,19 +130,20 @@ GradType<13> edge_edge_mollifier_gradient( // derivatives of mollifier products, input order : [dist_sqr, edge_lengths // (1 x 2), point_edge_dists (1 x 4)] - Vector product_grad = mollifier_grad.transpose() * partial_products_1; - + Vector product_grad = + mollifier_grad.transpose() * partial_products_1; + // derivatives wrt. input : [ea0, ea1, eb0, eb1, dist_sqr] Vector grad; - grad << edge_lengths_grad.transpose() * product_grad.segment<2>(1) + - point_edge_dists_grad.transpose() * product_grad.segment<4>(3), product_grad(0); - + grad << edge_lengths_grad.transpose() * product_grad.segment<2>(1) + + point_edge_dists_grad.transpose() * product_grad.segment<4>(3), + product_grad(0); + return std::make_tuple(mollifier.prod(), grad); } /// @brief Compute the hessian of the mollifier function wrt. 4 edge points and the distance squared -HessianType<13> -edge_edge_mollifier_hessian( +HessianType<13> edge_edge_mollifier_hessian( const Eigen::Ref>& ea0, const Eigen::Ref>& ea1, const Eigen::Ref>& eb0, @@ -166,20 +171,21 @@ edge_edge_mollifier_hessian( std::array, 4> point_edge_dists_hess; for (auto& mat : point_edge_dists_hess) mat.setZero(); - for (int i = 0; i < 4; i++) - { - point_edge_dists(i) = - point_edge_distance(input.segment<3>(3 * vert_indices(i, 0)), - input.segment<3>(3 * vert_indices(i, 1)), - input.segment<3>(3 * vert_indices(i, 2))); - point_edge_dists_grad(i, dof_indices.row(i)) = - point_edge_distance_gradient(input.segment<3>(3 * vert_indices(i, 0)), + for (int i = 0; i < 4; i++) { + point_edge_dists(i) = point_edge_distance( + input.segment<3>(3 * vert_indices(i, 0)), input.segment<3>(3 * vert_indices(i, 1)), input.segment<3>(3 * vert_indices(i, 2))); + point_edge_dists_grad(i, dof_indices.row(i)) = + point_edge_distance_gradient( + input.segment<3>(3 * vert_indices(i, 0)), + input.segment<3>(3 * vert_indices(i, 1)), + input.segment<3>(3 * vert_indices(i, 2))); point_edge_dists_hess[i](dof_indices.row(i), dof_indices.row(i)) = - point_edge_distance_hessian(input.segment<3>(3 * vert_indices(i, 0)), - input.segment<3>(3 * vert_indices(i, 1)), - input.segment<3>(3 * vert_indices(i, 2))); + point_edge_distance_hessian( + input.segment<3>(3 * vert_indices(i, 0)), + input.segment<3>(3 * vert_indices(i, 1)), + input.segment<3>(3 * vert_indices(i, 2))); } // derivatives of edge lengths @@ -187,14 +193,15 @@ edge_edge_mollifier_hessian( Eigen::Matrix edge_lengths_grad; edge_lengths_grad.setZero(); for (int i = 0; i < 2; i++) { - const Vector3d edge = input.segment<3>(i * 6) - input.segment<3>(i * 6 + 3); + const Vector3d edge = + input.segment<3>(i * 6) - input.segment<3>(i * 6 + 3); edge_lengths(i) = edge.squaredNorm(); edge_lengths_grad.block<1, 3>(i, 0 + 6 * i) = 2 * edge; edge_lengths_grad.block<1, 3>(i, 3 + 6 * i) = -2 * edge; } - // derivatives of mollifier and ratios, input order : [dist_sqr, edge_lengths - // (1 x 2), point_edge_dists (1 x 4)] + // derivatives of mollifier and ratios, input order : [dist_sqr, + // edge_lengths (1 x 2), point_edge_dists (1 x 4)] Eigen::Vector4d mollifier; Eigen::Matrix mollifier_grad; mollifier_grad.setZero(); @@ -203,7 +210,8 @@ edge_edge_mollifier_hessian( mat.setZero(); for (int i = 0; i < 4; i++) { const double len = edge_lengths(1 - i / 2); - const auto [val, g, h] = func_aux_hess(point_edge_dists(i), len, input(12), mollifier_threshold_eps); + const auto [val, g, h] = func_aux_hess( + point_edge_dists(i), len, input(12), mollifier_threshold_eps); Eigen::Vector3i ind; ind << 3 + i, 2 - i / 2, 0; @@ -232,11 +240,13 @@ edge_edge_mollifier_hessian( // derivatives of mollifier products, input order : [dist_sqr, edge_lengths // (1 x 2), point_edge_dists (1 x 4)] - Vector product_grad = mollifier_grad.transpose() * partial_products_1; - Eigen::Matrix product_hess = mollifier_grad.transpose() * partial_products_2 * mollifier_grad; + Vector product_grad = + mollifier_grad.transpose() * partial_products_1; + Eigen::Matrix product_hess = + mollifier_grad.transpose() * partial_products_2 * mollifier_grad; for (int i = 0; i < 4; i++) product_hess += mollifier_hess[i] * partial_products_1(i); - + // derivatives wrt. input : [ea0, ea1, eb0, eb1, dist_sqr] Vector grad = Vector::Zero(); Eigen::Matrix hess = Eigen::Matrix::Zero(); @@ -249,19 +259,21 @@ edge_edge_mollifier_hessian( hess(12, 12) = product_hess(0, 0); hess.block<1, 12>(12, 0) += product_hess.block<1, 6>(0, 1) * grads; - hess.block<12, 1>(0, 12) += grads.transpose() * product_hess.block<6, 1>(1, 0); + hess.block<12, 1>(0, 12) += + grads.transpose() * product_hess.block<6, 1>(1, 0); - for (int j = 0; j < 2; j++) - { + for (int j = 0; j < 2; j++) { const double val = 2 * product_grad(1 + j); hess.block<6, 6>(j * 6, j * 6).diagonal().array() += val; hess.block<3, 3>(j * 6, j * 6 + 3).diagonal().array() -= val; hess.block<3, 3>(j * 6 + 3, j * 6).diagonal().array() -= val; } for (int i = 0; i < 4; i++) - hess.topLeftCorner<12, 12>() += product_grad(3 + i) * point_edge_dists_hess[i]; + hess.topLeftCorner<12, 12>() += + product_grad(3 + i) * point_edge_dists_hess[i]; - hess.topLeftCorner<12, 12>() += grads.transpose() * product_hess.block<6, 6>(1, 1) * grads; + hess.topLeftCorner<12, 12>() += + grads.transpose() * product_hess.block<6, 6>(1, 1) * grads; } return std::make_tuple(mollifier.prod(), grad, hess); } @@ -294,8 +306,7 @@ std::array edge_edge_mollifier_type( } /// @brief Compute the gradient of the mollifier function wrt. 4 edge points and the distance squared -GradType<13> -point_face_mollifier_gradient( +GradType<13> point_face_mollifier_gradient( const Eigen::Ref& p, const Eigen::Ref& e0, const Eigen::Ref& e1, @@ -307,39 +318,45 @@ point_face_mollifier_gradient( Vector3d vals; Eigen::Matrix grads; - for (int i = 0; i < 3; i++) - { + for (int i = 0; i < 3; i++) { const int ei = i * 3 + 3; const int ej = ((i + 1) % 3) * 3 + 3; const int ek = ((i + 2) % 3) * 3 + 3; Vector ind; - Eigen::Matrix dist_grad = Eigen::Matrix::Zero(); + Eigen::Matrix dist_grad = + Eigen::Matrix::Zero(); - const double point_edge_dist = point_line_distance(p, x.segment<3>(ei), x.segment<3>(ej)); - ind << 0,1,2 , ei,ei+1,ei+2, ej,ej+1,ej+2; - dist_grad(0, ind) = point_line_distance_gradient(p, x.segment<3>(ei), x.segment<3>(ej)); + const double point_edge_dist = + point_line_distance(p, x.segment<3>(ei), x.segment<3>(ej)); + ind << 0, 1, 2, ei, ei + 1, ei + 2, ej, ej + 1, ej + 2; + dist_grad(0, ind) = + point_line_distance_gradient(p, x.segment<3>(ei), x.segment<3>(ej)); + + const double vert_edge_dist = point_line_distance( + x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); + ind << ek, ek + 1, ek + 2, ei, ei + 1, ei + 2, ej, ej + 1, ej + 2; + dist_grad(1, ind) = point_line_distance_gradient( + x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); - const double vert_edge_dist = point_line_distance(x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); - ind << ek,ek+1,ek+2, ei,ei+1,ei+2, ej,ej+1,ej+2; - dist_grad(1, ind) = point_line_distance_gradient(x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); - Vector3d tmp_grad; - std::tie(vals(i), tmp_grad) = func_aux_grad(point_edge_dist, vert_edge_dist, dist_sqr, mollifier_threshold_eps); + std::tie(vals(i), tmp_grad) = func_aux_grad( + point_edge_dist, vert_edge_dist, dist_sqr, mollifier_threshold_eps); grads.row(i) = tmp_grad.head<2>().transpose() * dist_grad; grads(i, 12) += tmp_grad(2); } - Vector grad = (vals(0) * vals(1)) * grads.row(2) + (vals(0) * vals(2)) * grads.row(1) + (vals(1) * vals(2)) * grads.row(0); + Vector grad = (vals(0) * vals(1)) * grads.row(2) + + (vals(0) * vals(2)) * grads.row(1) + + (vals(1) * vals(2)) * grads.row(0); return std::make_tuple(vals.prod(), grad); } /// @brief Compute the hessian of the mollifier function wrt. 4 edge points and the distance squared -HessianType<13> -point_face_mollifier_hessian( +HessianType<13> point_face_mollifier_hessian( const Eigen::Ref& p, const Eigen::Ref& e0, const Eigen::Ref& e1, @@ -352,49 +369,64 @@ point_face_mollifier_hessian( Vector3d vals; Eigen::Matrix grads; std::array, 3> hesses; - for (int i = 0; i < 3; i++) - { + for (int i = 0; i < 3; i++) { const int ei = i * 3 + 3; const int ej = ((i + 1) % 3) * 3 + 3; const int ek = ((i + 2) % 3) * 3 + 3; Vector ind; - Eigen::Matrix dist_grad = Eigen::Matrix::Zero(); - Eigen::Matrix point_edge_dist_hess = Eigen::Matrix::Zero(), vert_edge_dist_hess = Eigen::Matrix::Zero(); - - const double point_edge_dist = point_line_distance(p, x.segment<3>(ei), x.segment<3>(ej)); - ind << 0,1,2 , ei,ei+1,ei+2, ej,ej+1,ej+2; - dist_grad(0, ind) = point_line_distance_gradient(p, x.segment<3>(ei), x.segment<3>(ej)); - point_edge_dist_hess(ind, ind) = point_line_distance_hessian(p, x.segment<3>(ei), x.segment<3>(ej)); + Eigen::Matrix dist_grad = + Eigen::Matrix::Zero(); + Eigen::Matrix point_edge_dist_hess = + Eigen::Matrix::Zero(), + vert_edge_dist_hess = + Eigen::Matrix::Zero(); + + const double point_edge_dist = + point_line_distance(p, x.segment<3>(ei), x.segment<3>(ej)); + ind << 0, 1, 2, ei, ei + 1, ei + 2, ej, ej + 1, ej + 2; + dist_grad(0, ind) = + point_line_distance_gradient(p, x.segment<3>(ei), x.segment<3>(ej)); + point_edge_dist_hess(ind, ind) = + point_line_distance_hessian(p, x.segment<3>(ei), x.segment<3>(ej)); + + const double vert_edge_dist = point_line_distance( + x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); + ind << ek, ek + 1, ek + 2, ei, ei + 1, ei + 2, ej, ej + 1, ej + 2; + dist_grad(1, ind) = point_line_distance_gradient( + x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); + vert_edge_dist_hess(ind, ind) = point_line_distance_hessian( + x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); - const double vert_edge_dist = point_line_distance(x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); - ind << ek,ek+1,ek+2, ei,ei+1,ei+2, ej,ej+1,ej+2; - dist_grad(1, ind) = point_line_distance_gradient(x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); - vert_edge_dist_hess(ind, ind) = point_line_distance_hessian(x.segment<3>(ek), x.segment<3>(ei), x.segment<3>(ej)); - Vector3d tmp_grad; Matrix3d tmp_hess; - std::tie(vals(i), tmp_grad, tmp_hess) = func_aux_hess(point_edge_dist, vert_edge_dist, dist_sqr, mollifier_threshold_eps); + std::tie(vals(i), tmp_grad, tmp_hess) = func_aux_hess( + point_edge_dist, vert_edge_dist, dist_sqr, mollifier_threshold_eps); grads.row(i) = tmp_grad.head<2>().transpose() * dist_grad; grads(i, 12) += tmp_grad(2); - hesses[i] = tmp_grad(0) * point_edge_dist_hess + tmp_grad(1) * vert_edge_dist_hess; - hesses[i] += dist_grad.transpose() * tmp_hess.topLeftCorner<2, 2>() * dist_grad; + hesses[i] = tmp_grad(0) * point_edge_dist_hess + + tmp_grad(1) * vert_edge_dist_hess; + hesses[i] += + dist_grad.transpose() * tmp_hess.topLeftCorner<2, 2>() * dist_grad; hesses[i](12, 12) += tmp_hess(2, 2); hesses[i].col(12) += dist_grad.transpose() * tmp_hess.block<2, 1>(0, 2); hesses[i].row(12) += tmp_hess.block<1, 2>(2, 0) * dist_grad; } - Vector grad = (vals(0) * vals(1)) * grads.row(2) + (vals(0) * vals(2)) * grads.row(1) + (vals(1) * vals(2)) * grads.row(0); - Eigen::Matrix hess = (vals(0) * vals(1)) * hesses[2] + (vals(0) * vals(2)) * hesses[1] + (vals(1) * vals(2)) * hesses[0] + - grads.row(0).transpose() * vals(2) * grads.row(1) + - grads.row(1).transpose() * vals(2) * grads.row(0) + - grads.row(0).transpose() * vals(1) * grads.row(2) + - grads.row(2).transpose() * vals(1) * grads.row(0) + - grads.row(1).transpose() * vals(0) * grads.row(2) + - grads.row(2).transpose() * vals(0) * grads.row(1); + Vector grad = (vals(0) * vals(1)) * grads.row(2) + + (vals(0) * vals(2)) * grads.row(1) + + (vals(1) * vals(2)) * grads.row(0); + Eigen::Matrix hess = (vals(0) * vals(1)) * hesses[2] + + (vals(0) * vals(2)) * hesses[1] + (vals(1) * vals(2)) * hesses[0] + + grads.row(0).transpose() * vals(2) * grads.row(1) + + grads.row(1).transpose() * vals(2) * grads.row(0) + + grads.row(0).transpose() * vals(1) * grads.row(2) + + grads.row(2).transpose() * vals(1) * grads.row(0) + + grads.row(1).transpose() * vals(0) * grads.row(2) + + grads.row(2).transpose() * vals(0) * grads.row(1); return std::make_tuple(vals.prod(), grad, hess); } diff --git a/src/ipc/smooth_contact/distance/mollifier.hpp b/src/ipc/smooth_contact/distance/mollifier.hpp index ffdbaa1d3..0f673281d 100644 --- a/src/ipc/smooth_contact/distance/mollifier.hpp +++ b/src/ipc/smooth_contact/distance/mollifier.hpp @@ -1,7 +1,7 @@ #pragma once -#include "point_face.hpp" -#include "point_edge.hpp" #include "edge_edge.hpp" +#include "point_edge.hpp" +#include "point_face.hpp" namespace ipc { template @@ -37,8 +37,7 @@ GradType<13> edge_edge_mollifier_gradient( const double& dist_sqr); /// @brief Compute the hessian of the mollifier function wrt. 4 edge points and the distance squared -HessianType<13> -edge_edge_mollifier_hessian( +HessianType<13> edge_edge_mollifier_hessian( const Eigen::Ref& ea0, const Eigen::Ref& ea1, const Eigen::Ref& eb0, @@ -55,8 +54,7 @@ scalar point_face_mollifier( const scalar& dist_sqr); /// @brief Compute the gradient of the mollifier function wrt. 4 edge points and the distance squared -GradType<13> -point_face_mollifier_gradient( +GradType<13> point_face_mollifier_gradient( const Eigen::Ref& p, const Eigen::Ref& e0, const Eigen::Ref& e1, @@ -64,8 +62,7 @@ point_face_mollifier_gradient( const double& dist_sqr); /// @brief Compute the hessian of the mollifier function wrt. 4 edge points and the distance squared -HessianType<13> -point_face_mollifier_hessian( +HessianType<13> point_face_mollifier_hessian( const Eigen::Ref& p, const Eigen::Ref& e0, const Eigen::Ref& e1, diff --git a/src/ipc/smooth_contact/distance/mollifier.tpp b/src/ipc/smooth_contact/distance/mollifier.tpp index 0cb25a7cf..d8e9d5b48 100644 --- a/src/ipc/smooth_contact/distance/mollifier.tpp +++ b/src/ipc/smooth_contact/distance/mollifier.tpp @@ -10,8 +10,7 @@ scalar point_edge_mollifier( const Eigen::Ref>& e1, const scalar& dist_sqr) { - const scalar denominator = - dist_sqr * mollifier_threshold_eps; + const scalar denominator = dist_sqr * mollifier_threshold_eps; return Math::mollifier( ((p - e0).squaredNorm() - dist_sqr) / denominator) * Math::mollifier( @@ -29,30 +28,34 @@ scalar edge_edge_mollifier( { const scalar da = dist_sqr * mollifier_threshold_eps; const scalar db = dist_sqr * mollifier_threshold_eps; - scalar a = (mtypes[0] == HEAVISIDE_TYPE::VARIANT) ? Math::mollifier( - (PointEdgeDistance::point_edge_sqr_distance( - ea0, eb0, eb1) - - dist_sqr) - / db) - : scalar(1.); - scalar b = (mtypes[1] == HEAVISIDE_TYPE::VARIANT) ? Math::mollifier( - (PointEdgeDistance::point_edge_sqr_distance( - ea1, eb0, eb1) - - dist_sqr) - / db) - : scalar(1.); - scalar c = (mtypes[2] == HEAVISIDE_TYPE::VARIANT) ? Math::mollifier( - (PointEdgeDistance::point_edge_sqr_distance( - eb0, ea0, ea1) - - dist_sqr) - / da) - : scalar(1.); - scalar d = (mtypes[3] == HEAVISIDE_TYPE::VARIANT) ? Math::mollifier( - (PointEdgeDistance::point_edge_sqr_distance( - eb1, ea0, ea1) - - dist_sqr) - / da) - : scalar(1.); + scalar a = (mtypes[0] == HEAVISIDE_TYPE::VARIANT) + ? Math::mollifier( + (PointEdgeDistance::point_edge_sqr_distance( + ea0, eb0, eb1) + - dist_sqr) + / db) + : scalar(1.); + scalar b = (mtypes[1] == HEAVISIDE_TYPE::VARIANT) + ? Math::mollifier( + (PointEdgeDistance::point_edge_sqr_distance( + ea1, eb0, eb1) + - dist_sqr) + / db) + : scalar(1.); + scalar c = (mtypes[2] == HEAVISIDE_TYPE::VARIANT) + ? Math::mollifier( + (PointEdgeDistance::point_edge_sqr_distance( + eb0, ea0, ea1) + - dist_sqr) + / da) + : scalar(1.); + scalar d = (mtypes[3] == HEAVISIDE_TYPE::VARIANT) + ? Math::mollifier( + (PointEdgeDistance::point_edge_sqr_distance( + eb1, ea0, ea1) + - dist_sqr) + / da) + : scalar(1.); return a * b * c * d; } @@ -67,19 +70,19 @@ scalar point_face_mollifier( { // use point-line distance instead of point-edge distance because // this function vanishes if the point is outside the triangle, so - // whenever this function is nonzero the point-edge distance equals + // whenever this function is nonzero the point-edge distance equals // the point-line distance return Math::mollifier( (PointEdgeDistance::point_line_sqr_distance(p, e0, e1) - - dist_sqr) / mollifier_threshold_eps - / dist_sqr) + - dist_sqr) + / mollifier_threshold_eps / dist_sqr) * Math::mollifier( (PointEdgeDistance::point_line_sqr_distance(p, e2, e1) - - dist_sqr) / mollifier_threshold_eps - / dist_sqr) + - dist_sqr) + / mollifier_threshold_eps / dist_sqr) * Math::mollifier( (PointEdgeDistance::point_line_sqr_distance(p, e0, e2) - - dist_sqr) / mollifier_threshold_eps - / dist_sqr); + - dist_sqr) + / mollifier_threshold_eps / dist_sqr); } } // namespace ipc \ No newline at end of file diff --git a/src/ipc/smooth_contact/distance/point_edge.cpp b/src/ipc/smooth_contact/distance/point_edge.cpp index 650c3ee47..1953087a7 100644 --- a/src/ipc/smooth_contact/distance/point_edge.cpp +++ b/src/ipc/smooth_contact/distance/point_edge.cpp @@ -1,4 +1,5 @@ #include "point_edge.hpp" + #include namespace ipc { @@ -249,7 +250,7 @@ PointEdgeDistanceDerivatives::point_edge_closest_point_direction_hessian( Eigen::Matrix grad = Eigen::Matrix::Zero(); std::array, dim> hess; - for (auto &hi : hess) + for (auto& hi : hess) hi.setZero(); #ifdef DERIVATIVES_WITH_AUTODIFF using T = ADHessian; diff --git a/src/ipc/smooth_contact/distance/point_edge.hpp b/src/ipc/smooth_contact/distance/point_edge.hpp index ad8ad7485..1d2c03a3a 100644 --- a/src/ipc/smooth_contact/distance/point_edge.hpp +++ b/src/ipc/smooth_contact/distance/point_edge.hpp @@ -1,10 +1,11 @@ #pragma once #include -#include -#include #include +#include #include +#include + #include namespace ipc { diff --git a/src/ipc/smooth_contact/distance/point_face.cpp b/src/ipc/smooth_contact/distance/point_face.cpp index 666cf8ca5..44b778597 100644 --- a/src/ipc/smooth_contact/distance/point_face.cpp +++ b/src/ipc/smooth_contact/distance/point_face.cpp @@ -1,6 +1,8 @@ #include "point_face.hpp" -#include "point_edge.hpp" + #include "autogen.hpp" +#include "point_edge.hpp" + #include namespace ipc { @@ -13,15 +15,18 @@ point_plane_closest_point_direction_grad( const Eigen::Ref& t2) { const Eigen::Vector2d uv = point_triangle_closest_point(p, t0, t1, t2); - const Eigen::Matrix jac = point_triangle_closest_point_jacobian(p, t0, t1, t2); - const Vector3d direc = p - (t0 * (1 - uv(0) - uv(1)) + t1 * uv(0) + t2 * uv(1)); - Eigen::Matrix grad = - (t1 - t0) * jac.row(0) - (t2 - t0) * jac.row(1); + const Eigen::Matrix jac = + point_triangle_closest_point_jacobian(p, t0, t1, t2); + const Vector3d direc = + p - (t0 * (1 - uv(0) - uv(1)) + t1 * uv(0) + t2 * uv(1)); + Eigen::Matrix grad = + -(t1 - t0) * jac.row(0) - (t2 - t0) * jac.row(1); grad.middleCols<3>(3).diagonal().array() -= 1. - uv(0) - uv(1); grad.middleCols<3>(6).diagonal().array() -= uv(0); grad.middleCols<3>(9).diagonal().array() -= uv(1); grad.leftCols<3>().diagonal().array() += 1.; - return {direc, grad}; + return { direc, grad }; } std::tuple, std::array> @@ -33,50 +38,48 @@ point_plane_closest_point_direction_hessian( { // compute derivatives of uv const Eigen::Vector2d uv = point_triangle_closest_point(p, t0, t1, t2); - const Eigen::Matrix jac = point_triangle_closest_point_jacobian(p, t0, t1, t2); + const Eigen::Matrix jac = + point_triangle_closest_point_jacobian(p, t0, t1, t2); std::array H; autogen::triangle_closest_point_hessian_0( - p(0), p(1), p(2), - t0(0), t0(1), t0(2), - t1(0), t1(1), t1(2), - t2(0), t2(1), t2(2), H[0].data()); + p(0), p(1), p(2), t0(0), t0(1), t0(2), t1(0), t1(1), t1(2), t2(0), + t2(1), t2(2), H[0].data()); autogen::triangle_closest_point_hessian_1( - p(0), p(1), p(2), - t0(0), t0(1), t0(2), - t1(0), t1(1), t1(2), - t2(0), t2(1), t2(2), H[1].data()); - + p(0), p(1), p(2), t0(0), t0(1), t0(2), t1(0), t1(1), t1(2), t2(0), + t2(1), t2(2), H[1].data()); + // compute derivatives of the closest point - const Vector3d direc = p - (t0 * (1 - uv(0) - uv(1)) + t1 * uv(0) + t2 * uv(1)); + const Vector3d direc = + p - (t0 * (1 - uv(0) - uv(1)) + t1 * uv(0) + t2 * uv(1)); - Eigen::Matrix grad = - (t1 - t0) * jac.row(0) - (t2 - t0) * jac.row(1); + Eigen::Matrix grad = + -(t1 - t0) * jac.row(0) - (t2 - t0) * jac.row(1); grad.middleCols<3>(3).diagonal().array() -= 1. - uv(0) - uv(1); grad.middleCols<3>(6).diagonal().array() -= uv(0); grad.middleCols<3>(9).diagonal().array() -= uv(1); grad.leftCols<3>().diagonal().array() += 1.; - + std::array hess; for (auto& h : hess) h.setZero(); - for (int d = 0; d < 3; d++) - { + for (int d = 0; d < 3; d++) { // wrt. uv hess[d] -= (t1(d) - t0(d)) * H[0] + (t2(d) - t0(d)) * H[1]; - + // wrt. uv & t0 - hess[d].row(3+d) += jac.row(0) + jac.row(1); - hess[d].col(3+d) += (jac.row(0) + jac.row(1)).transpose(); + hess[d].row(3 + d) += jac.row(0) + jac.row(1); + hess[d].col(3 + d) += (jac.row(0) + jac.row(1)).transpose(); // wrt. uv & t1 - hess[d].row(6+d) -= jac.row(0); - hess[d].col(6+d) -= jac.row(0).transpose(); + hess[d].row(6 + d) -= jac.row(0); + hess[d].col(6 + d) -= jac.row(0).transpose(); // wrt. uv & t2 - hess[d].row(9+d) -= jac.row(1); - hess[d].col(9+d) -= jac.row(1).transpose(); + hess[d].row(9 + d) -= jac.row(1); + hess[d].col(9 + d) -= jac.row(1).transpose(); } - return {direc, grad, hess}; + return { direc, grad, hess }; } std::tuple> @@ -108,32 +111,33 @@ point_triangle_closest_point_direction_grad( grad.middleCols<3>(9) = -Eigen::Matrix::Identity(); break; - case PointTriangleDistanceType::P_E0: - { - const auto [pts_, d_grad] = PointEdgeDistanceDerivatives<3>::point_line_closest_point_direction_grad(p, t0, t1); + case PointTriangleDistanceType::P_E0: { + const auto [pts_, d_grad] = PointEdgeDistanceDerivatives< + 3>::point_line_closest_point_direction_grad(p, t0, t1); pts = pts_; - grad(Eigen::all, {0,1,2,3,4,5,6,7,8}) = d_grad; + grad(Eigen::all, { 0, 1, 2, 3, 4, 5, 6, 7, 8 }) = d_grad; break; } - case PointTriangleDistanceType::P_E1: - { - const auto [pts_, d_grad] = PointEdgeDistanceDerivatives<3>::point_line_closest_point_direction_grad(p, t1, t2); + case PointTriangleDistanceType::P_E1: { + const auto [pts_, d_grad] = PointEdgeDistanceDerivatives< + 3>::point_line_closest_point_direction_grad(p, t1, t2); pts = pts_; - grad(Eigen::all, {0,1,2,6,7,8,9,10,11}) = d_grad; + grad(Eigen::all, { 0, 1, 2, 6, 7, 8, 9, 10, 11 }) = d_grad; break; } - case PointTriangleDistanceType::P_E2: - { - const auto [pts_, d_grad] = PointEdgeDistanceDerivatives<3>::point_line_closest_point_direction_grad(p, t2, t0); + case PointTriangleDistanceType::P_E2: { + const auto [pts_, d_grad] = PointEdgeDistanceDerivatives< + 3>::point_line_closest_point_direction_grad(p, t2, t0); pts = pts_; - grad(Eigen::all, {0,1,2,9,10,11,3,4,5}) = d_grad; + grad(Eigen::all, { 0, 1, 2, 9, 10, 11, 3, 4, 5 }) = d_grad; break; } case PointTriangleDistanceType::P_T: - std::tie(pts, grad) = point_plane_closest_point_direction_grad(p, t0, t1, t2); + std::tie(pts, grad) = + point_plane_closest_point_direction_grad(p, t0, t1, t2); break; default: @@ -141,7 +145,7 @@ point_triangle_closest_point_direction_grad( "Invalid distance type for point-triangle distance!"); } - return {pts, grad}; + return { pts, grad }; } std::tuple, std::array> @@ -176,11 +180,11 @@ point_triangle_closest_point_direction_hessian( grad.middleCols<3>(9) = -Eigen::Matrix::Identity(); break; - case PointTriangleDistanceType::P_E0: - { - const auto [d, d_grad, d_hess] = PointEdgeDistanceDerivatives<3>::point_line_closest_point_direction_hessian(p, t0, t1); + case PointTriangleDistanceType::P_E0: { + const auto [d, d_grad, d_hess] = PointEdgeDistanceDerivatives< + 3>::point_line_closest_point_direction_hessian(p, t0, t1); pts = d; - std::vector ind{0,1,2,3,4,5,6,7,8}; + std::vector ind { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; grad(Eigen::all, ind) = d_grad; for (int i = 0; i < 3; i++) hess[i](ind, ind) = d_hess[i]; @@ -188,32 +192,33 @@ point_triangle_closest_point_direction_hessian( break; } - case PointTriangleDistanceType::P_E1: - { - const auto [d, d_grad, d_hess] = PointEdgeDistanceDerivatives<3>::point_line_closest_point_direction_hessian(p, t1, t2); + case PointTriangleDistanceType::P_E1: { + const auto [d, d_grad, d_hess] = PointEdgeDistanceDerivatives< + 3>::point_line_closest_point_direction_hessian(p, t1, t2); pts = d; - std::vector ind{0,1,2,6,7,8,9,10,11}; + std::vector ind { 0, 1, 2, 6, 7, 8, 9, 10, 11 }; grad(Eigen::all, ind) = d_grad; for (int i = 0; i < 3; i++) hess[i](ind, ind) = d_hess[i]; - + break; } - case PointTriangleDistanceType::P_E2: - { - const auto [d, d_grad, d_hess] = PointEdgeDistanceDerivatives<3>::point_line_closest_point_direction_hessian(p, t2, t0); + case PointTriangleDistanceType::P_E2: { + const auto [d, d_grad, d_hess] = PointEdgeDistanceDerivatives< + 3>::point_line_closest_point_direction_hessian(p, t2, t0); pts = d; - std::vector ind{0,1,2,9,10,11,3,4,5}; + std::vector ind { 0, 1, 2, 9, 10, 11, 3, 4, 5 }; grad(Eigen::all, ind) = d_grad; for (int i = 0; i < 3; i++) hess[i](ind, ind) = d_hess[i]; - + break; } case PointTriangleDistanceType::P_T: - std::tie(pts, grad, hess) = point_plane_closest_point_direction_hessian(p, t0, t1, t2); + std::tie(pts, grad, hess) = + point_plane_closest_point_direction_hessian(p, t0, t1, t2); break; default: @@ -221,7 +226,7 @@ point_triangle_closest_point_direction_hessian( "Invalid distance type for point-triangle distance!"); } - return {pts, grad, hess}; + return { pts, grad, hess }; } -} \ No newline at end of file +} // namespace ipc \ No newline at end of file diff --git a/src/ipc/smooth_contact/distance/primitive_distance.cpp b/src/ipc/smooth_contact/distance/primitive_distance.cpp index 0c85f2421..19fb7a342 100644 --- a/src/ipc/smooth_contact/distance/primitive_distance.cpp +++ b/src/ipc/smooth_contact/distance/primitive_distance.cpp @@ -1,10 +1,9 @@ #include "primitive_distance.hpp" #include -#include #include +#include #include - #include #include #include @@ -79,35 +78,36 @@ double PrimitiveDistance::compute_distance( } template <> -GradType::n_core_dofs> +GradType::n_core_dofs> PrimitiveDistance::compute_distance_gradient( const Vector::n_core_dofs>& x, typename PrimitiveDistType::type dtype) { const double dist = point_triangle_distance( - x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dtype); + x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dtype); Vector dist_grad = point_triangle_distance_gradient( - x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dtype); - dist_grad = dist_grad({3,4,5,6,7,8,9,10,11,0,1,2}).eval(); - return {dist, dist_grad}; + x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dtype); + dist_grad = dist_grad({ 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2 }).eval(); + return { dist, dist_grad }; } template <> -HessianType::n_core_dofs> +HessianType::n_core_dofs> PrimitiveDistance::compute_distance_hessian( const Vector::n_core_dofs>& x, typename PrimitiveDistType::type dtype) { const double dist = point_triangle_distance( - x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dtype); + x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dtype); Vector dist_grad = point_triangle_distance_gradient( + x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dtype); + Eigen::Matrix dist_hess = + point_triangle_distance_hessian( x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dtype); - Eigen::Matrix dist_hess = point_triangle_distance_hessian( - x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dtype); - const std::vector ind{3,4,5,6,7,8,9,10,11,0,1,2}; + const std::vector ind { 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2 }; dist_grad = dist_grad(ind).eval(); dist_hess = dist_hess(ind, ind).eval(); - return {dist, dist_grad, dist_hess}; + return { dist, dist_grad, dist_hess }; } template <> @@ -124,7 +124,7 @@ double PrimitiveDistance::compute_distance( } template <> -GradType::n_core_dofs> +GradType::n_core_dofs> PrimitiveDistance::compute_distance_gradient( const Vector::n_core_dofs>& x, typename PrimitiveDistType::type dtype) @@ -133,11 +133,12 @@ PrimitiveDistance::compute_distance_gradient( edge_edge_distance( x.head<3>(), x.segment<3>(3), x.segment<3>(6), x.tail<3>(), dtype), edge_edge_distance_gradient( - x.head<3>(), x.segment<3>(3), x.segment<3>(6), x.tail<3>(), dtype)}; + x.head<3>(), x.segment<3>(3), x.segment<3>(6), x.tail<3>(), dtype) + }; } template <> -HessianType::n_core_dofs> +HessianType::n_core_dofs> PrimitiveDistance::compute_distance_hessian( const Vector::n_core_dofs>& x, typename PrimitiveDistType::type dtype) @@ -148,7 +149,8 @@ PrimitiveDistance::compute_distance_hessian( edge_edge_distance_gradient( x.head<3>(), x.segment<3>(3), x.segment<3>(6), x.tail<3>(), dtype), edge_edge_distance_hessian( - x.head<3>(), x.segment<3>(3), x.segment<3>(6), x.tail<3>(), dtype)}; + x.head<3>(), x.segment<3>(3), x.segment<3>(6), x.tail<3>(), dtype) + }; } template <> @@ -164,47 +166,49 @@ double PrimitiveDistance::compute_distance( } template <> -GradType::n_core_dofs> +GradType::n_core_dofs> PrimitiveDistance::compute_distance_gradient( const Vector::n_core_dofs>& x, typename PrimitiveDistType::type dtype) { - const double dist = point_edge_distance( - x.tail<3>(), x.head<3>(), x.segment<3>(3), dtype); + const double dist = + point_edge_distance(x.tail<3>(), x.head<3>(), x.segment<3>(3), dtype); Vector dist_grad = point_edge_distance_gradient( - x.tail<3>(), x.head<3>(), x.segment<3>(3), dtype); - dist_grad = dist_grad({3,4,5,6,7,8,0,1,2}).eval(); - return {dist, dist_grad}; + x.tail<3>(), x.head<3>(), x.segment<3>(3), dtype); + dist_grad = dist_grad({ 3, 4, 5, 6, 7, 8, 0, 1, 2 }).eval(); + return { dist, dist_grad }; } template <> -HessianType::n_core_dofs> +HessianType::n_core_dofs> PrimitiveDistance::compute_distance_hessian( const Vector::n_core_dofs>& x, typename PrimitiveDistType::type dtype) { - const double dist = point_edge_distance( - x.tail<3>(), x.head<3>(), x.segment<3>(3), dtype); + const double dist = + point_edge_distance(x.tail<3>(), x.head<3>(), x.segment<3>(3), dtype); Vector dist_grad = point_edge_distance_gradient( + x.tail<3>(), x.head<3>(), x.segment<3>(3), dtype); + Eigen::Matrix dist_hess = + point_edge_distance_hessian( x.tail<3>(), x.head<3>(), x.segment<3>(3), dtype); - Eigen::Matrix dist_hess = point_edge_distance_hessian( - x.tail<3>(), x.head<3>(), x.segment<3>(3), dtype); - const std::vector ind{3,4,5,6,7,8,0,1,2}; + const std::vector ind { 3, 4, 5, 6, 7, 8, 0, 1, 2 }; dist_grad = dist_grad(ind).eval(); dist_hess = dist_hess(ind, ind).eval(); - return {dist, dist_grad, dist_hess}; + return { dist, dist_grad, dist_hess }; } template <> -GradType::n_core_dofs> +GradType::n_core_dofs> PrimitiveDistance::compute_distance_gradient( const Vector::n_core_dofs>& x, typename PrimitiveDistType::type dtype) { const double dist = (x.head<3>() - x.tail<3>()).squaredNorm(); Vector dist_grad; - dist_grad << 2 * (x.head<3>() - x.tail<3>()), -2 * (x.head<3>() - x.tail<3>()); - return {dist, dist_grad}; + dist_grad << 2 * (x.head<3>() - x.tail<3>()), + -2 * (x.head<3>() - x.tail<3>()); + return { dist, dist_grad }; } template <> @@ -322,8 +326,18 @@ PrimitiveDistance::compute_closest_direction( #ifndef DERIVATIVES_WITH_AUTODIFF template <> -std::tuple::dim>, Eigen::Matrix::dim, PrimitiveDistance::n_core_dofs>, - std::array::n_core_dofs, PrimitiveDistance::n_core_dofs>, PrimitiveDistance::dim>> +std::tuple< + Vector::dim>, + Eigen::Matrix< + double, + PrimitiveDistance::dim, + PrimitiveDistance::n_core_dofs>, + std::array< + Eigen::Matrix< + double, + PrimitiveDistance::n_core_dofs, + PrimitiveDistance::n_core_dofs>, + PrimitiveDistance::dim>> PrimitiveDistance::compute_closest_direction_hessian( const Vector& x, typename PrimitiveDistType::type dtype) @@ -335,8 +349,18 @@ PrimitiveDistance::compute_closest_direction_hessian( } template <> -std::tuple::dim>, Eigen::Matrix::dim, PrimitiveDistance::n_core_dofs>, - std::array::n_core_dofs, PrimitiveDistance::n_core_dofs>, PrimitiveDistance::dim>> +std::tuple< + Vector::dim>, + Eigen::Matrix< + double, + PrimitiveDistance::dim, + PrimitiveDistance::n_core_dofs>, + std::array< + Eigen::Matrix< + double, + PrimitiveDistance::n_core_dofs, + PrimitiveDistance::n_core_dofs>, + PrimitiveDistance::dim>> PrimitiveDistance::compute_closest_direction_hessian( const Vector& x, typename PrimitiveDistType::type dtype) @@ -346,14 +370,24 @@ PrimitiveDistance::compute_closest_direction_hessian( J.leftCols<2>().diagonal().array() = -1; J.rightCols<2>().diagonal().array() = 1; std::array, 2> H; - for (auto &h : H) + for (auto& h : H) h.setZero(); return std::make_tuple(out, J, H); } template <> -std::tuple::dim>, Eigen::Matrix::dim, PrimitiveDistance::n_core_dofs>, - std::array::n_core_dofs, PrimitiveDistance::n_core_dofs>, PrimitiveDistance::dim>> +std::tuple< + Vector::dim>, + Eigen::Matrix< + double, + PrimitiveDistance::dim, + PrimitiveDistance::n_core_dofs>, + std::array< + Eigen::Matrix< + double, + PrimitiveDistance::n_core_dofs, + PrimitiveDistance::n_core_dofs>, + PrimitiveDistance::dim>> PrimitiveDistance::compute_closest_direction_hessian( const Vector& x, typename PrimitiveDistType::type dtype) @@ -363,7 +397,7 @@ PrimitiveDistance::compute_closest_direction_hessian( J.leftCols<3>().diagonal().array() = -1; J.rightCols<3>().diagonal().array() = 1; std::array, 3> H; - for (auto &h : H) + for (auto& h : H) h.setZero(); return std::make_tuple(out, J, H); } @@ -374,12 +408,11 @@ PrimitiveDistance::compute_mollifier_gradient( const Vector& x, const double dist_sqr) { const auto otypes = edge_edge_mollifier_type( - x.head(3), x.segment(3, 3), x.segment(6, 3), - x.tail(3), dist_sqr); + x.head(3), x.segment(3, 3), x.segment(6, 3), x.tail(3), dist_sqr); return edge_edge_mollifier_gradient( - x.head(3), x.segment(3, 3), x.segment(6, 3), - x.tail(3), otypes, dist_sqr); + x.head(3), x.segment(3, 3), x.segment(6, 3), x.tail(3), otypes, + dist_sqr); } template <> @@ -388,12 +421,11 @@ PrimitiveDistance::compute_mollifier_hessian( const Vector& x, const double dist_sqr) { const auto otypes = edge_edge_mollifier_type( - x.head<3>(), x.segment<3>(3), x.segment<3>(6), - x.tail<3>(), dist_sqr); + x.head<3>(), x.segment<3>(3), x.segment<3>(6), x.tail<3>(), dist_sqr); return edge_edge_mollifier_hessian( - x.head<3>(), x.segment<3>(3), x.segment<3>(6), - x.tail<3>(), otypes, dist_sqr); + x.head<3>(), x.segment<3>(3), x.segment<3>(6), x.tail<3>(), otypes, + dist_sqr); } template <> @@ -404,7 +436,7 @@ PrimitiveDistance::compute_mollifier_gradient( const auto [val, grad] = point_face_mollifier_gradient( x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dist_sqr); Vector indices; - indices << 3,4,5,6,7,8,9,10,11,0,1,2,12; + indices << 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 12; return std::make_tuple(val, grad(indices)); } @@ -416,7 +448,7 @@ PrimitiveDistance::compute_mollifier_hessian( const auto [val, grad, hess] = point_face_mollifier_hessian( x.tail<3>(), x.head<3>(), x.segment<3>(3), x.segment<3>(6), dist_sqr); Vector indices; - indices << 3,4,5,6,7,8,9,10,11,0,1,2,12; + indices << 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 12; return std::make_tuple(val, grad(indices), hess(indices, indices)); } diff --git a/src/ipc/smooth_contact/distance/primitive_distance.hpp b/src/ipc/smooth_contact/distance/primitive_distance.hpp index e45350b4a..f27461280 100644 --- a/src/ipc/smooth_contact/distance/primitive_distance.hpp +++ b/src/ipc/smooth_contact/distance/primitive_distance.hpp @@ -1,15 +1,13 @@ #pragma once -#include #include #include - +#include +#include +#include #include #include -#include -#include -#include - #include +#include namespace ipc { template @@ -72,12 +70,13 @@ template class PrimitiveDistance { static_assert( PrimitiveA::dim == PrimitiveB::dim, "Primitives must have the same dimension"); + public: constexpr static int dim = PrimitiveA::dim; constexpr static int n_core_dofs = PrimitiveA::n_core_points * PrimitiveA::dim + PrimitiveB::n_core_points * PrimitiveB::dim; - + static typename PrimitiveDistType::type compute_distance_type(const Vector& x); @@ -95,9 +94,10 @@ template class PrimitiveDistance { DiffScalarBase::setVariableCount(n_core_dofs); using T = ADGrad; const Vector X = slice_positions(x); - const T d = PrimitiveDistanceTemplate::compute_distance(X, dtype); + const T d = PrimitiveDistanceTemplate< + PrimitiveA, PrimitiveB, T>::compute_distance(X, dtype); - return {d.getValue(), d.getGradient()}; + return { d.getValue(), d.getGradient() }; } static HessianType compute_distance_hessian( @@ -107,9 +107,10 @@ template class PrimitiveDistance { DiffScalarBase::setVariableCount(n_core_dofs); using T = ADHessian; const Vector X = slice_positions(x); - const T d = PrimitiveDistanceTemplate::compute_distance(X, dtype); + const T d = PrimitiveDistanceTemplate< + PrimitiveA, PrimitiveB, T>::compute_distance(X, dtype); - return {d.getValue(), d.getGradient(), d.getHessian()}; + return { d.getValue(), d.getGradient(), d.getHessian() }; } // points from primitiveA to primitiveB @@ -120,27 +121,31 @@ template class PrimitiveDistance { const long& b, typename PrimitiveDistType::type dtype); - static std::tuple, Eigen::Matrix> - compute_closest_direction_gradient( - const Vector& x, - typename PrimitiveDistType::type dtype) + static std:: + tuple, Eigen::Matrix> + compute_closest_direction_gradient( + const Vector& x, + typename PrimitiveDistType::type dtype) { DiffScalarBase::setVariableCount(n_core_dofs); using T = ADGrad; const Vector X = slice_positions(x); - const Vector d = PrimitiveDistanceTemplate::compute_closest_direction(X, dtype); + const Vector d = PrimitiveDistanceTemplate< + PrimitiveA, PrimitiveB, T>::compute_closest_direction(X, dtype); Vector out; - Eigen::Matrix J = Eigen::Matrix::Zero(); - for (int i = 0; i < dim; i++) - { + Eigen::Matrix J = + Eigen::Matrix::Zero(); + for (int i = 0; i < dim; i++) { out(i) = d(i).getValue(); J.row(i) = d(i).getGradient(); } return std::make_tuple(out, J); } - static std::tuple, Eigen::Matrix, + static std::tuple< + Vector, + Eigen::Matrix, std::array, dim>> compute_closest_direction_hessian( const Vector& x, @@ -149,13 +154,14 @@ template class PrimitiveDistance { DiffScalarBase::setVariableCount(n_core_dofs); using T = ADHessian; const Vector X = slice_positions(x); - const Vector d = PrimitiveDistanceTemplate::compute_closest_direction(X, dtype); + const Vector d = PrimitiveDistanceTemplate< + PrimitiveA, PrimitiveB, T>::compute_closest_direction(X, dtype); Vector out; - Eigen::Matrix J = Eigen::Matrix::Zero(); + Eigen::Matrix J = + Eigen::Matrix::Zero(); std::array, dim> H; - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { out(i) = d(i).getValue(); J.row(i) = d(i).getGradient(); H[i] = d(i).getHessian(); @@ -163,28 +169,35 @@ template class PrimitiveDistance { return std::make_tuple(out, J, H); } - static GradType - compute_mollifier_gradient( + static GradType compute_mollifier_gradient( const Vector& x, const double dist_sqr) { DiffScalarBase::setVariableCount(n_core_dofs + 1); using T = ADGrad; - const Vector X = slice_positions((Vector() << x, dist_sqr).finished()); - const T out = PrimitiveDistanceTemplate::mollifier(X.head(n_core_dofs), X(n_core_dofs)); + const Vector X = + slice_positions( + (Vector() << x, dist_sqr).finished()); + const T out = + PrimitiveDistanceTemplate::mollifier( + X.head(n_core_dofs), X(n_core_dofs)); return std::make_tuple(out.getValue(), out.getGradient()); } - static HessianType - compute_mollifier_hessian( + static HessianType compute_mollifier_hessian( const Vector& x, const double dist_sqr) { DiffScalarBase::setVariableCount(n_core_dofs + 1); using T = ADHessian; - const Vector X = slice_positions((Vector() << x, dist_sqr).finished()); - const T out = PrimitiveDistanceTemplate::mollifier(X.head(n_core_dofs), X(n_core_dofs)); - - return std::make_tuple(out.getValue(), out.getGradient(), out.getHessian()); + const Vector X = + slice_positions( + (Vector() << x, dist_sqr).finished()); + const T out = + PrimitiveDistanceTemplate::mollifier( + X.head(n_core_dofs), X(n_core_dofs)); + + return std::make_tuple( + out.getValue(), out.getGradient(), out.getHessian()); } }; diff --git a/src/ipc/smooth_contact/distance/primitive_distance.tpp b/src/ipc/smooth_contact/distance/primitive_distance.tpp index 42334be95..f8ff32a67 100644 --- a/src/ipc/smooth_contact/distance/primitive_distance.tpp +++ b/src/ipc/smooth_contact/distance/primitive_distance.tpp @@ -17,8 +17,9 @@ public: typename PrimitiveDistType::type dtype) { return point_triangle_sqr_distance( - x.template tail<3>() /* point */, x.template head<3>(), x.template segment<3>(3), - x.template segment<3>(6) /* face */, dtype); + x.template tail<3>() /* point */, x.template head<3>(), + x.template segment<3>(3), x.template segment<3>(6) /* face */, + dtype); } static Vector compute_closest_direction( @@ -26,15 +27,17 @@ public: typename PrimitiveDistType::type dtype) { return point_triangle_closest_point_direction( - x.template tail<3>() /* point */, x.template head<3>(), x.template segment<3>(3), - x.template segment<3>(6) /* face */, dtype); + x.template tail<3>() /* point */, x.template head<3>(), + x.template segment<3>(3), x.template segment<3>(6) /* face */, + dtype); } static T mollifier(const Vector& x, const T& dist_sqr) { return point_face_mollifier( - x.template tail<3>() /* point */, x.template head<3>(), x.template segment<3>(3), - x.template segment<3>(6) /* face */, dist_sqr); + x.template tail<3>() /* point */, x.template head<3>(), + x.template segment<3>(3), x.template segment<3>(6) /* face */, + dist_sqr); } }; @@ -51,8 +54,10 @@ public: typename PrimitiveDistType::type dtype) { return edge_edge_sqr_distance( - x.template head<3>() /* edge 0 */, x.template segment<3>(3) /* edge 0 */, - x.template segment<3>(6) /* edge 1 */, x.template tail<3>() /* edge 1 */, dtype); + x.template head<3>() /* edge 0 */, + x.template segment<3>(3) /* edge 0 */, + x.template segment<3>(6) /* edge 1 */, + x.template tail<3>() /* edge 1 */, dtype); } static Vector compute_closest_direction( @@ -60,8 +65,10 @@ public: typename PrimitiveDistType::type dtype) { return edge_edge_closest_point_direction( - x.template head<3>() /* edge 0 */, x.template segment<3>(3) /* edge 0 */, - x.template segment<3>(6) /* edge 1 */, x.template tail<3>() /* edge 1 */, dtype); + x.template head<3>() /* edge 0 */, + x.template segment<3>(3) /* edge 0 */, + x.template segment<3>(6) /* edge 1 */, + x.template tail<3>() /* edge 1 */, dtype); } static T mollifier(const Vector& x, const T& dist_sqr) @@ -69,9 +76,10 @@ public: std::array types; types.fill(HEAVISIDE_TYPE::VARIANT); return edge_edge_mollifier( - x.template head<3>() /* edge 0 */, x.template segment<3>(3) /* edge 0 */, - x.template segment<3>(6) /* edge 1 */, x.template tail<3>() /* edge 1 */, types, - dist_sqr); + x.template head<3>() /* edge 0 */, + x.template segment<3>(3) /* edge 0 */, + x.template segment<3>(6) /* edge 1 */, + x.template tail<3>() /* edge 1 */, types, dist_sqr); } }; @@ -79,8 +87,8 @@ template class PrimitiveDistanceTemplate { static_assert( Edge2::dim == Point2::dim, "Primitives must have the same dimension"); constexpr static int dim = Point2::dim; - constexpr static int n_core_dofs = Edge2::n_core_points * Edge2::dim - + Point2::n_core_points * Point2::dim; + constexpr static int n_core_dofs = + Edge2::n_core_points * Edge2::dim + Point2::n_core_points * Point2::dim; public: static T compute_distance( @@ -104,7 +112,8 @@ public: static T mollifier(const Vector& x, const T& dist_sqr) { return point_edge_mollifier( - x.template tail<2>() /* point */, x.template segment<2>(2) /* edge */, + x.template tail<2>() /* point */, + x.template segment<2>(2) /* edge */, x.template head<2>() /* edge */, dist_sqr); } }; @@ -138,7 +147,8 @@ public: static T mollifier(const Vector& x, const T& dist_sqr) { return point_edge_mollifier( - x.template tail<3>() /* point */, x.template segment<3>(3) /* edge */, + x.template tail<3>() /* point */, + x.template segment<3>(3) /* edge */, x.template head<3>() /* edge */, dist_sqr); } }; @@ -199,4 +209,4 @@ public: } }; -} +} // namespace ipc diff --git a/src/ipc/smooth_contact/primitives/edge2.cpp b/src/ipc/smooth_contact/primitives/edge2.cpp index 91d3ce6fe..3e0380809 100644 --- a/src/ipc/smooth_contact/primitives/edge2.cpp +++ b/src/ipc/smooth_contact/primitives/edge2.cpp @@ -11,7 +11,8 @@ Edge2::Edge2( { _vert_ids = { { mesh.edges()(id, 0), mesh.edges()(id, 1) } }; - is_active_ = (mesh.is_orient_vertex(_vert_ids[0]) && mesh.is_orient_vertex(_vert_ids[1])) + is_active_ = (mesh.is_orient_vertex(_vert_ids[0]) + && mesh.is_orient_vertex(_vert_ids[1])) || Math::cross2( d, vertices.row(_vert_ids[1]) - vertices.row(_vert_ids[0])) > 0; diff --git a/src/ipc/smooth_contact/primitives/edge3.cpp b/src/ipc/smooth_contact/primitives/edge3.cpp index d9cf2ecb5..0a1b293c2 100644 --- a/src/ipc/smooth_contact/primitives/edge3.cpp +++ b/src/ipc/smooth_contact/primitives/edge3.cpp @@ -375,7 +375,9 @@ Edge3::Edge3( const ParameterType& param) : Primitive(id, param) { - orientable = (mesh.is_orient_vertex(mesh.edges()(id, 0)) && mesh.is_orient_vertex(mesh.edges()(id, 0))); + orientable = + (mesh.is_orient_vertex(mesh.edges()(id, 0)) + && mesh.is_orient_vertex(mesh.edges()(id, 0))); std::array neighbors { { -1, -1, -1, -1 } }; { diff --git a/src/ipc/smooth_contact/primitives/point2.cpp b/src/ipc/smooth_contact/primitives/point2.cpp index dc7f6e71c..6155fc903 100644 --- a/src/ipc/smooth_contact/primitives/point2.cpp +++ b/src/ipc/smooth_contact/primitives/point2.cpp @@ -108,7 +108,8 @@ Point2::Point2( is_active_ = dn.dot(t0) > -param.alpha_t; } else { - _vert_ids = { { id } }; + _vert_ids.resize(1); + _vert_ids[0] = id; is_active_ = true; } } diff --git a/src/ipc/smooth_contact/smooth_collisions.cpp b/src/ipc/smooth_contact/smooth_collisions.cpp index e50c1f4ca..64f0a6087 100644 --- a/src/ipc/smooth_contact/smooth_collisions.cpp +++ b/src/ipc/smooth_contact/smooth_collisions.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -19,8 +18,7 @@ namespace ipc { -template -void SmoothCollisions::compute_adaptive_dhat( +void SmoothCollisions::compute_adaptive_dhat( const CollisionMesh& mesh, Eigen::ConstRef vertices, // set to zero for rest pose const ParameterType param, @@ -39,8 +37,10 @@ void SmoothCollisions::compute_adaptive_dhat( vert_adaptive_dhat.setConstant(mesh.num_vertices(), dhat); edge_adaptive_dhat.setConstant(mesh.num_edges(), dhat); - if constexpr (dim == 3) + if (mesh.dim() == 3) face_adaptive_dhat.setConstant(mesh.num_faces(), dhat); + else + face_adaptive_dhat.resize(0); auto assign_min = [](double& a, const double& b) -> void { a = std::min(a, b); @@ -48,8 +48,7 @@ void SmoothCollisions::compute_adaptive_dhat( for (const auto& cc : collisions) { const double dist = param.get_adaptive_dhat_ratio() - * sqrt(cc->compute_distance( - cc->dof(vertices, mesh.edges(), mesh.faces()))); + * sqrt(cc->compute_distance(vertices)); switch (cc->type()) { case CollisionType::EdgeEdge: assign_min(edge_adaptive_dhat((*cc)[0]), dist); @@ -74,7 +73,7 @@ void SmoothCollisions::compute_adaptive_dhat( // face adaptive dhat should be minimum of all its adjacent vertices and // edges - if constexpr (dim == 3) + if (mesh.dim() == 3) for (int f = 0; f < mesh.num_faces(); f++) { for (int lv = 0; lv < 3; lv++) { face_adaptive_dhat(f) = std::min( @@ -100,14 +99,13 @@ void SmoothCollisions::compute_adaptive_dhat( logger().debug( "Adaptive dhat: edge dhat min {:.2e}, max {:.2e}", edge_adaptive_dhat.minCoeff(), edge_adaptive_dhat.maxCoeff()); - if constexpr (dim == 3) + if (mesh.dim() == 3) logger().debug( "Adaptive dhat: face dhat min {:.2e}, max {:.2e}", face_adaptive_dhat.minCoeff(), face_adaptive_dhat.maxCoeff()); } -template -void SmoothCollisions::build( +void SmoothCollisions::build( const CollisionMesh& mesh, Eigen::ConstRef vertices, const ParameterType param, @@ -125,8 +123,7 @@ void SmoothCollisions::build( this->build(candidates, mesh, vertices, param, use_adaptive_dhat); } -template -void SmoothCollisions::build( +void SmoothCollisions::build( const Candidates& candidates_, const CollisionMesh& mesh, Eigen::ConstRef vertices, @@ -143,8 +140,11 @@ void SmoothCollisions::build( vert_adaptive_dhat(0) = dhat; edge_adaptive_dhat.resize(1); edge_adaptive_dhat(0) = dhat; - face_adaptive_dhat.resize(1); - face_adaptive_dhat(0) = dhat; + if (mesh.dim() == 3) { + face_adaptive_dhat.resize(1); + face_adaptive_dhat(0) = dhat; + } else + face_adaptive_dhat.resize(0); } auto vert_dhat = [&](const long& v_id) { @@ -157,25 +157,28 @@ void SmoothCollisions::build( return this->get_face_dhat(f_id); }; - // tbb::enumerable_thread_specific> storage; - auto storage = - ipc::utils::create_thread_storage>( - SmoothCollisionsBuilder()); - if constexpr (dim == 2) { + if (mesh.dim() == 2) { + auto storage = + ipc::utils::create_thread_storage>( + SmoothCollisionsBuilder<2>()); ipc::utils::maybe_parallel_for( candidates_.ev_candidates.size(), [&](int start, int end, int thread_id) { - SmoothCollisionsBuilder& local_storage = + SmoothCollisionsBuilder<2>& local_storage = ipc::utils::get_local_thread_storage(storage, thread_id); local_storage.add_edge_vertex_collisions( mesh, vertices, candidates_.ev_candidates, param, vert_dhat, edge_dhat, start, end); }); + SmoothCollisionsBuilder<2>::merge(storage, *this); } else { + auto storage = + ipc::utils::create_thread_storage>( + SmoothCollisionsBuilder<3>()); ipc::utils::maybe_parallel_for( candidates_.ee_candidates.size(), [&](int start, int end, int thread_id) { - SmoothCollisionsBuilder& local_storage = + SmoothCollisionsBuilder<3>& local_storage = ipc::utils::get_local_thread_storage(storage, thread_id); local_storage.add_edge_edge_collisions( mesh, vertices, candidates_.ee_candidates, param, vert_dhat, @@ -185,36 +188,23 @@ void SmoothCollisions::build( ipc::utils::maybe_parallel_for( candidates_.fv_candidates.size(), [&](int start, int end, int thread_id) { - SmoothCollisionsBuilder& local_storage = + SmoothCollisionsBuilder<3>& local_storage = ipc::utils::get_local_thread_storage(storage, thread_id); local_storage.add_face_vertex_collisions( mesh, vertices, candidates_.fv_candidates, param, vert_dhat, edge_dhat, face_dhat, start, end); }); + SmoothCollisionsBuilder<3>::merge(storage, *this); } - SmoothCollisionsBuilder::merge(storage, *this); candidates = candidates_; - - // logger().debug(to_string(mesh, vertices, param)); } // ============================================================================ +size_t SmoothCollisions::size() const { return collisions.size(); } +bool SmoothCollisions::empty() const { return collisions.empty(); } +void SmoothCollisions::clear() { collisions.clear(); } -template size_t SmoothCollisions::size() const -{ - return collisions.size(); -} - -template bool SmoothCollisions::empty() const -{ - return collisions.empty(); -} - -template void SmoothCollisions::clear() { collisions.clear(); } - -template -typename SmoothCollisions::value_type& -SmoothCollisions::operator[](size_t i) +typename SmoothCollisions::value_type& SmoothCollisions::operator[](size_t i) { if (i < collisions.size()) { return *collisions[i]; @@ -222,9 +212,8 @@ SmoothCollisions::operator[](size_t i) throw std::out_of_range("Collision index is out of range!"); } -template -const typename SmoothCollisions::value_type& -SmoothCollisions::operator[](size_t i) const +const typename SmoothCollisions::value_type& +SmoothCollisions::operator[](size_t i) const { if (i < collisions.size()) { return *collisions[i]; @@ -232,8 +221,7 @@ SmoothCollisions::operator[](size_t i) const throw std::out_of_range("Collision index is out of range!"); } -template -std::string SmoothCollisions::to_string( +std::string SmoothCollisions::to_string( const CollisionMesh& mesh, Eigen::ConstRef vertices, const ParameterType& params) const @@ -244,22 +232,16 @@ std::string SmoothCollisions::to_string( { ss << fmt::format( "[{}]: ({} {}) dist {} potential {} grad {}", cc->name(), - (*cc)[0], (*cc)[1], - cc->compute_distance( - cc->dof(vertices, mesh.edges(), mesh.faces())), - (*cc)(cc->dof(vertices, mesh.edges(), mesh.faces()), params), - (*cc) - .gradient( - cc->dof(vertices, mesh.edges(), mesh.faces()), params) - .norm()); + (*cc)[0], (*cc)[1], cc->compute_distance(vertices), + (*cc)(cc->dof(vertices), params), + (*cc).gradient(cc->dof(vertices), params).norm()); } } return ss.str(); } // NOTE: Actually distance squared -template -double SmoothCollisions::compute_minimum_distance( +double SmoothCollisions::compute_minimum_distance( const CollisionMesh& mesh, Eigen::ConstRef vertices) const { assert(vertices.rows() == mesh.num_vertices()); @@ -292,8 +274,7 @@ double SmoothCollisions::compute_minimum_distance( return storage.combine([](double a, double b) { return std::min(a, b); }); } -template -double SmoothCollisions::compute_active_minimum_distance( +double SmoothCollisions::compute_active_minimum_distance( const CollisionMesh& mesh, Eigen::ConstRef vertices) const { assert(vertices.rows() == mesh.num_vertices()); @@ -302,9 +283,6 @@ double SmoothCollisions::compute_active_minimum_distance( return std::numeric_limits::infinity(); } - const Eigen::MatrixXi& edges = mesh.edges(); - const Eigen::MatrixXi& faces = mesh.faces(); - tbb::enumerable_thread_specific storage( std::numeric_limits::infinity()); @@ -314,8 +292,7 @@ double SmoothCollisions::compute_active_minimum_distance( double& local_min_dist = storage.local(); for (size_t i = r.begin(); i < r.end(); i++) { - const double dist = collisions[i]->compute_distance( - collisions[i]->dof(vertices, edges, faces)); + const double dist = collisions[i]->compute_distance(vertices); if (collisions[i]->is_active() && dist < local_min_dist) { local_min_dist = dist; @@ -326,6 +303,4 @@ double SmoothCollisions::compute_active_minimum_distance( return storage.combine([](double a, double b) { return std::min(a, b); }); } -template class SmoothCollisions<2>; -template class SmoothCollisions<3>; } // namespace ipc diff --git a/src/ipc/smooth_contact/smooth_collisions.hpp b/src/ipc/smooth_contact/smooth_collisions.hpp index 9e21d32eb..00bc976ad 100644 --- a/src/ipc/smooth_contact/smooth_collisions.hpp +++ b/src/ipc/smooth_contact/smooth_collisions.hpp @@ -1,7 +1,5 @@ #pragma once -#include - #include #include #include @@ -10,19 +8,21 @@ #include #include #include +#include #include #include namespace ipc { -template class SmoothCollisions { +class SmoothCollisions { public: /// @brief The type of the collisions. - using value_type = SmoothCollision::value>; + using value_type = SmoothCollision; public: SmoothCollisions() = default; + virtual ~SmoothCollisions() = default; void compute_adaptive_dhat( const CollisionMesh& mesh, @@ -113,7 +113,7 @@ template class SmoothCollisions { { double out = std::max( vert_adaptive_dhat.maxCoeff(), edge_adaptive_dhat.maxCoeff()); - if constexpr (dim == 3) + if (face_adaptive_dhat.size() > 0) return std::max(out, face_adaptive_dhat.maxCoeff()); return out; } diff --git a/src/ipc/smooth_contact/smooth_collisions_builder.cpp b/src/ipc/smooth_contact/smooth_collisions_builder.cpp index 25ceca74c..f7e2cdd2f 100644 --- a/src/ipc/smooth_contact/smooth_collisions_builder.cpp +++ b/src/ipc/smooth_contact/smooth_collisions_builder.cpp @@ -18,8 +18,7 @@ namespace { const std::shared_ptr& pair, unordered_map, std::shared_ptr>& cc_to_id_, - std::vector< - std::shared_ptr::value_type>>& + std::vector>& collisions_) { if (pair->is_active() @@ -33,8 +32,7 @@ namespace { template void add_collision( const std::shared_ptr& pair, - std::vector< - std::shared_ptr::value_type>>& + std::vector>& collisions_) { if (pair->is_active()) @@ -55,9 +53,8 @@ void SmoothCollisionsBuilder<2>::add_edge_vertex_collisions( for (size_t i = start_i; i < end_i; i++) { const auto& [ei, vi] = candidates[i]; - add_collision<2, SmoothCollisionTemplate>( - std::make_shared< - SmoothCollisionTemplate>( + add_collision<2, SmoothCollisionTemplate>( + std::make_shared>( ei, vi, PointEdgeDistanceType::AUTO, mesh, param, std::min(edge_dhat(ei), vert_dhat(vi)), vertices), vert_edge_2_to_id, collisions); @@ -67,10 +64,8 @@ void SmoothCollisionsBuilder<2>::add_edge_vertex_collisions( const double dhat = std::min(vert_dhat(vi), vert_dhat(vj)); if ((vertices.row(vi) - vertices.row(vj)).norm() >= dhat) continue; - add_collision< - 2, SmoothCollisionTemplate>( - std::make_shared< - SmoothCollisionTemplate>( + add_collision<2, SmoothCollisionTemplate>( + std::make_shared>( std::min(vi, vj), std::max(vi, vj), PointPointDistanceType::AUTO, mesh, param, dhat, vertices), vert_vert_2_to_id, collisions); @@ -106,9 +101,8 @@ void SmoothCollisionsBuilder<3>::add_edge_edge_collisions( || distance >= param.dhat) continue; - add_collision<3, SmoothCollisionTemplate>( - std::make_shared< - SmoothCollisionTemplate>( + add_collision<3, SmoothCollisionTemplate>( + std::make_shared>( std::min(eai, ebi), std::max(eai, ebi), actual_dtype, mesh, param, std::min(edge_dhat(eai), edge_dhat(ebi)), vertices), collisions); @@ -142,10 +136,8 @@ void SmoothCollisionsBuilder<3>::add_face_vertex_collisions( continue; if (pt_dtype == PointTriangleDistanceType::P_T) - add_collision< - 3, SmoothCollisionTemplate>( - std::make_shared< - SmoothCollisionTemplate>( + add_collision<3, SmoothCollisionTemplate>( + std::make_shared>( fi, vi, pt_dtype, mesh, param, std::min(face_dhat(fi), vert_dhat(vi)), vertices), collisions); @@ -155,10 +147,8 @@ void SmoothCollisionsBuilder<3>::add_face_vertex_collisions( const double dhat = std::min(vert_dhat(vi), vert_dhat(vj)); if ((vertices.row(vi) - vertices.row(vj)).norm() >= dhat) continue; - add_collision< - 3, SmoothCollisionTemplate>( - std::make_shared< - SmoothCollisionTemplate>( + add_collision<3, SmoothCollisionTemplate>( + std::make_shared>( std::min(vi, vj), std::max(vi, vj), PointPointDistanceType::AUTO, mesh, param, dhat, vertices), vert_vert_3_to_id, collisions); @@ -179,10 +169,8 @@ void SmoothCollisionsBuilder<3>::add_face_vertex_collisions( || sqrt(distance_sqr) >= dhat) continue; - add_collision< - 3, SmoothCollisionTemplate>( - std::make_shared< - SmoothCollisionTemplate>( + add_collision<3, SmoothCollisionTemplate>( + std::make_shared>( eid, vi, pe_dtype, mesh, param, dhat, vertices), edge_vert_3_to_id, collisions); } @@ -191,15 +179,15 @@ void SmoothCollisionsBuilder<3>::add_face_vertex_collisions( void SmoothCollisionsBuilder<3>::merge( const utils::ParallelCacheType>& local_storage, - SmoothCollisions<3>& merged_collisions) + SmoothCollisions& merged_collisions) { unordered_map< std::pair, - std::shared_ptr>> + std::shared_ptr>> vert_vert_3_to_id; unordered_map< std::pair, - std::shared_ptr>> + std::shared_ptr>> edge_vert_3_to_id; // size up the hash items @@ -248,15 +236,15 @@ void SmoothCollisionsBuilder<3>::merge( void SmoothCollisionsBuilder<2>::merge( const utils::ParallelCacheType>& local_storage, - SmoothCollisions<2>& merged_collisions) + SmoothCollisions& merged_collisions) { unordered_map< std::pair, - std::shared_ptr>> + std::shared_ptr>> vert_vert_2_to_id; unordered_map< std::pair, - std::shared_ptr>> + std::shared_ptr>> vert_edge_2_to_id; // size up the hash items diff --git a/src/ipc/smooth_contact/smooth_collisions_builder.hpp b/src/ipc/smooth_contact/smooth_collisions_builder.hpp index bbb48ef48..2807f5192 100644 --- a/src/ipc/smooth_contact/smooth_collisions_builder.hpp +++ b/src/ipc/smooth_contact/smooth_collisions_builder.hpp @@ -30,10 +30,10 @@ template <> class SmoothCollisionsBuilder<2> { static void merge( const utils::ParallelCacheType>& local_storage, - SmoothCollisions<2>& merged_collisions); + SmoothCollisions& merged_collisions); // Constructed collisions - std::vector::value_type>> + std::vector> collisions; // ------------------------------------------------------------------------- @@ -41,11 +41,11 @@ template <> class SmoothCollisionsBuilder<2> { // Store the indices to pairs to avoid duplicates. unordered_map< std::pair, - std::shared_ptr>> + std::shared_ptr>> vert_vert_2_to_id; unordered_map< std::pair, - std::shared_ptr>> + std::shared_ptr>> vert_edge_2_to_id; }; @@ -79,10 +79,10 @@ template <> class SmoothCollisionsBuilder<3> { static void merge( const utils::ParallelCacheType>& local_storage, - SmoothCollisions<3>& merged_collisions); + SmoothCollisions& merged_collisions); // Constructed collisions - std::vector::value_type>> + std::vector> collisions; // ------------------------------------------------------------------------- @@ -91,11 +91,11 @@ template <> class SmoothCollisionsBuilder<3> { // and Edge-Edge unordered_map< std::pair, - std::shared_ptr>> + std::shared_ptr>> vert_vert_3_to_id; unordered_map< std::pair, - std::shared_ptr>> + std::shared_ptr>> edge_vert_3_to_id; }; diff --git a/src/ipc/smooth_contact/smooth_contact_potential.cpp b/src/ipc/smooth_contact/smooth_contact_potential.cpp new file mode 100644 index 000000000..de796fa3f --- /dev/null +++ b/src/ipc/smooth_contact/smooth_contact_potential.cpp @@ -0,0 +1,224 @@ +#include "smooth_contact_potential.hpp" + +#include +#include + +#include +#include +#include + +namespace ipc { + +double SmoothContactPotential::operator()( + const SmoothCollisions& collisions, + const CollisionMesh& mesh, + Eigen::ConstRef X) const +{ + assert(X.rows() == mesh.num_vertices()); + + if (collisions.empty()) { + return 0; + } + + tbb::enumerable_thread_specific storage(0); + + tbb::parallel_for( + tbb::blocked_range(size_t(0), collisions.size()), + [&](const tbb::blocked_range& r) { + auto& local_potential = storage.local(); + for (size_t i = r.begin(); i < r.end(); i++) { + // Quadrature weight is premultiplied by local potential + local_potential += (*this)(collisions[i], collisions[i].dof(X)); + } + }); + + return storage.combine([](double a, double b) { return a + b; }); +} + +Eigen::VectorXd SmoothContactPotential::gradient( + const SmoothCollisions& collisions, + const CollisionMesh& mesh, + Eigen::ConstRef X) const +{ + assert(X.rows() == mesh.num_vertices()); + + if (collisions.empty()) { + return Eigen::VectorXd::Zero(X.size()); + } + + const int dim = X.cols(); + + auto storage = ipc::utils::create_thread_storage( + Eigen::VectorXd::Zero(X.size())); + ipc::utils::maybe_parallel_for( + collisions.size(), [&](int start, int end, int thread_id) { + auto& global_grad = + ipc::utils::get_local_thread_storage(storage, thread_id); + + for (size_t i = start; i < end; i++) { + const SmoothCollision& collision = collisions[i]; + + const Eigen::VectorXd local_grad = + this->gradient(collision, collision.dof(X)); + + const std::vector vids = collision.vertex_ids(); + + local_gradient_to_global_gradient( + local_grad, vids, dim, global_grad); + } + }); + + Eigen::VectorXd grad; + grad.setZero(X.size()); + for (const auto& local_storage : storage) + grad += local_storage; + return grad; +} + +Eigen::SparseMatrix SmoothContactPotential::hessian( + const SmoothCollisions& collisions, + const CollisionMesh& mesh, + Eigen::ConstRef X, + const PSDProjectionMethod project_hessian_to_psd) const +{ + assert(X.rows() == mesh.num_vertices()); + + if (collisions.empty()) { + return Eigen::SparseMatrix(X.size(), X.size()); + } + + const int dim = X.cols(); + const int ndof = X.size(); + + const int max_triplets_size = int(1e7); + const int buffer_size = std::min(max_triplets_size, ndof); + auto storage = ipc::utils::create_thread_storage( + LocalThreadMatStorage(buffer_size, ndof, ndof)); + ipc::utils::maybe_parallel_for( + collisions.size(), [&](int start, int end, int thread_id) { + auto& hess_triplets = + ipc::utils::get_local_thread_storage(storage, thread_id); + + for (size_t i = start; i < end; i++) { + const SmoothCollision& collision = collisions[i]; + + const Eigen::MatrixXd local_hess = this->hessian( + collisions[i], collisions[i].dof(X), + project_hessian_to_psd); + + local_hessian_to_global_triplets( + local_hess, collision.vertex_ids(), dim, + *(hess_triplets.cache)); + } + }); + + Eigen::SparseMatrix hess(ndof, ndof); + + // Assemble the stiffness matrix by concatenating the tuples in each local + // storage + + // Collect thread storages + std::vector storages(storage.size()); + int index = 0; + for (auto& local_storage : storage) { + storages[index++] = &local_storage; + } + + utils::maybe_parallel_for( + storages.size(), [&](int i) { storages[i]->cache->prune(); }); + + if (storage.size() == 0) { + return Eigen::SparseMatrix(); + } + + // Prepares for parallel concatenation + std::vector offsets(storage.size()); + + index = 0; + int triplet_count = 0; + for (auto& local_storage : storage) { + offsets[index++] = triplet_count; + triplet_count += local_storage.cache->triplet_count(); + } + + std::vector> triplets; + + assert(storages.size() >= 1); + if (storages[0]->cache->is_dense()) { + // Serially merge local storages + Eigen::MatrixXd tmp(hess); + for (const auto& local_storage : storage) + tmp += dynamic_cast(*local_storage.cache) + .mat(); + hess = tmp.sparseView(); + hess.makeCompressed(); + } else if (triplet_count >= triplets.max_size()) { + // Serial fallback version in case the vector of triplets cannot be + // allocated + + logger().warn( + "Cannot allocate space for triplets, switching to serial assembly."); + + // Serially merge local storages + for (LocalThreadMatStorage& local_storage : storage) + hess += local_storage.cache->get_matrix(false); // will also prune + hess.makeCompressed(); + } else { + triplets.resize(triplet_count); + + // Parallel copy into triplets + utils::maybe_parallel_for(storages.size(), [&](int i) { + const SparseMatrixCache& cache = + dynamic_cast(*storages[i]->cache); + int offset = offsets[i]; + + std::copy( + cache.entries().begin(), cache.entries().end(), + triplets.begin() + offset); + offset += cache.entries().size(); + + if (cache.mat().nonZeros() > 0) { + int count = 0; + for (int k = 0; k < cache.mat().outerSize(); ++k) { + for (Eigen::SparseMatrix::InnerIterator it( + cache.mat(), k); + it; ++it) { + assert(count < cache.mat().nonZeros()); + triplets[offset + count++] = Eigen::Triplet( + it.row(), it.col(), it.value()); + } + } + } + }); + + // Sort and assemble + hess.setFromTriplets(triplets.begin(), triplets.end()); + } + + return hess; +} + +double SmoothContactPotential::operator()( + const SmoothCollision& collision, + Eigen::ConstRef positions) const +{ + return collision.weight * collision(positions, params); +} + +Eigen::VectorXd SmoothContactPotential::gradient( + const SmoothCollision& collision, + Eigen::ConstRef positions) const +{ + return collision.weight * collision.gradient(positions, params); +} + +Eigen::MatrixXd SmoothContactPotential::hessian( + const SmoothCollision& collision, + Eigen::ConstRef positions, + const PSDProjectionMethod project_hessian_to_psd) const +{ + Eigen::MatrixXd hess = + collision.weight * collision.hessian(positions, params); + return project_to_psd(hess, project_hessian_to_psd); +} +} // namespace ipc \ No newline at end of file diff --git a/src/ipc/smooth_contact/smooth_contact_potential.hpp b/src/ipc/smooth_contact/smooth_contact_potential.hpp index bd5d95936..18015132d 100644 --- a/src/ipc/smooth_contact/smooth_contact_potential.hpp +++ b/src/ipc/smooth_contact/smooth_contact_potential.hpp @@ -1,22 +1,50 @@ #pragma once -#include +#include #include +#include namespace ipc { -template -class SmoothContactPotential : public Potential { - using Super = Potential; - using TCollision = typename TCollisions::value_type; - +class SmoothContactPotential { public: SmoothContactPotential(const ParameterType& _params) : params(_params) { } + virtual ~SmoothContactPotential() = default; + + // -- Cumulative methods --------------------------------------------------- + + /// @brief Compute the potential for a set of collisions. + /// @param collisions The set of collisions. + /// @param mesh The collision mesh. + /// @param X Degrees of freedom of the collision mesh (e.g., vertices or velocities). + /// @returns The potential for a set of collisions. + double operator()( + const SmoothCollisions& collisions, + const CollisionMesh& mesh, + Eigen::ConstRef X) const; + + /// @brief Compute the gradient of the potential. + /// @param collisions The set of collisions. + /// @param mesh The collision mesh. + /// @param X Degrees of freedom of the collision mesh (e.g., vertices or velocities). + /// @returns The gradient of the potential w.r.t. X. This will have a size of |X|. + Eigen::VectorXd gradient( + const SmoothCollisions& collisions, + const CollisionMesh& mesh, + Eigen::ConstRef X) const; - using Super::element_size; - using Super::operator(); - using Super::gradient; - using Super::hessian; + /// @brief Compute the hessian of the potential. + /// @param collisions The set of collisions. + /// @param mesh The collision mesh. + /// @param X Degrees of freedom of the collision mesh (e.g., vertices or velocities). + /// @param project_hessian_to_psd Make sure the hessian is positive semi-definite. + /// @returns The Hessian of the potential w.r.t. X. This will have a size of |X|×|X|. + virtual Eigen::SparseMatrix hessian( + const SmoothCollisions& collisions, + const CollisionMesh& mesh, + Eigen::ConstRef X, + const PSDProjectionMethod project_hessian_to_psd = + PSDProjectionMethod::NONE) const; // -- Single collision methods --------------------------------------------- @@ -25,39 +53,26 @@ class SmoothContactPotential : public Potential { /// @param positions The collision stencil's positions. /// @return The potential. double operator()( - const TCollision& collision, - Eigen::ConstRef> positions) - const override - { - return collision.weight * collision(positions, params); - } + const SmoothCollision& collision, + Eigen::ConstRef positions) const; /// @brief Compute the gradient of the potential for a single collision. /// @param collision The collision. /// @param positions The collision stencil's positions. /// @return The gradient of the potential. - Vector gradient( - const TCollision& collision, - Eigen::ConstRef> positions) - const override - { - return collision.weight * collision.gradient(positions, params); - } + Eigen::VectorXd gradient( + const SmoothCollision& collision, + Eigen::ConstRef positions) const; /// @brief Compute the hessian of the potential for a single collision. /// @param collision The collision. /// @param positions The collision stencil's positions. /// @return The hessian of the potential. - MatrixMax hessian( - const TCollision& collision, - Eigen::ConstRef> positions, + Eigen::MatrixXd hessian( + const SmoothCollision& collision, + Eigen::ConstRef positions, const PSDProjectionMethod project_hessian_to_psd = - PSDProjectionMethod::NONE) const override - { - MatrixMax hess = - collision.weight * collision.hessian(positions, params); - return project_to_psd(hess, project_hessian_to_psd); - } + PSDProjectionMethod::NONE) const; protected: ParameterType params; diff --git a/src/ipc/tangent/closest_point.cpp b/src/ipc/tangent/closest_point.cpp index 4ac44cc2f..c6a5634dd 100644 --- a/src/ipc/tangent/closest_point.cpp +++ b/src/ipc/tangent/closest_point.cpp @@ -1,9 +1,9 @@ #include "closest_point.hpp" +#include + #include #include - -#include namespace ipc { // ============================================================================ @@ -49,10 +49,9 @@ MatrixMax9d point_edge_closest_point_hessian( Matrix9d H; autogen::point_edge_closest_point_3D_hessian( - p(0), p(1), dim == 2 ? 0 : p(2), - e0(0), e0(1), dim == 2 ? 0 : e0(2), + p(0), p(1), dim == 2 ? 0 : p(2), e0(0), e0(1), dim == 2 ? 0 : e0(2), e1(0), e1(1), dim == 2 ? 0 : e1(2), H.data()); - + return H; } diff --git a/src/ipc/tangent/relative_velocity.hpp b/src/ipc/tangent/relative_velocity.hpp index 34a891ad4..0c1eafe2b 100644 --- a/src/ipc/tangent/relative_velocity.hpp +++ b/src/ipc/tangent/relative_velocity.hpp @@ -104,7 +104,7 @@ Eigen::Vector3d point_triangle_relative_velocity( /// @brief Compute the point-triangle relative velocity matrix. /// @param dim Dimension (2 or 3) -/// @param coords Baricentric coordinates of the closest point on the triangle +/// @param coords Barycentric coordinates of the closest point on the triangle /// @return The relative velocity matrix MatrixMax point_triangle_relative_velocity_matrix( const int dim, Eigen::ConstRef coords); diff --git a/src/ipc/utils/AutodiffTypes.hpp b/src/ipc/utils/AutodiffTypes.hpp index 3fb3c484d..ca733ced9 100644 --- a/src/ipc/utils/AutodiffTypes.hpp +++ b/src/ipc/utils/AutodiffTypes.hpp @@ -1,7 +1,7 @@ #pragma once -#include "eigen_ext.hpp" #include "autodiff.h" +#include "eigen_ext.hpp" namespace ipc { template diff --git a/src/ipc/utils/CMakeLists.txt b/src/ipc/utils/CMakeLists.txt index 812543184..0858e9431 100644 --- a/src/ipc/utils/CMakeLists.txt +++ b/src/ipc/utils/CMakeLists.txt @@ -22,8 +22,6 @@ set(SOURCES quadrature.hpp tangents.cpp tangents.hpp - getRSS.h - getRSS.c math.cpp math.hpp math.tpp diff --git a/src/ipc/utils/MatrixCache.cpp b/src/ipc/utils/MatrixCache.cpp index d589ff070..e02ba757c 100644 --- a/src/ipc/utils/MatrixCache.cpp +++ b/src/ipc/utils/MatrixCache.cpp @@ -1,406 +1,396 @@ #include "MatrixCache.hpp" -#include "MaybeParallelFor.hpp" #include "logger.hpp" +#include "MaybeParallelFor.hpp" + +namespace ipc { +SparseMatrixCache::SparseMatrixCache(const size_t size) { init(size); } + +SparseMatrixCache::SparseMatrixCache(const size_t rows, const size_t cols) +{ + init(rows, cols); +} + +SparseMatrixCache::SparseMatrixCache(const MatrixCache& other) { init(other); } + +SparseMatrixCache::SparseMatrixCache( + const SparseMatrixCache& other, const bool copy_main_cache_ptr) +{ + init(other, copy_main_cache_ptr); +} + +void SparseMatrixCache::init(const size_t size) +{ + assert(mapping().empty() || size_ == size); + + size_ = size; + tmp_.resize(size_, size_); + mat_.resize(size_, size_); + mat_.setZero(); +} + +void SparseMatrixCache::init(const size_t rows, const size_t cols) +{ + assert(mapping().empty()); + + size_ = rows == cols ? rows : 0; + tmp_.resize(rows, cols); + mat_.resize(rows, cols); + mat_.setZero(); +} + +void SparseMatrixCache::init(const MatrixCache& other) +{ + assert(this != &other); + assert(&other == &dynamic_cast(other)); + init(dynamic_cast(other)); +} + +void SparseMatrixCache::init( + const SparseMatrixCache& other, const bool copy_main_cache_ptr) +{ + assert(this != &other); + if (copy_main_cache_ptr) { + main_cache_ = other.main_cache_; + } else if (main_cache_ == nullptr) { + main_cache_ = other.main_cache(); + // Only one level of cache + assert( + main_cache_ != this && main_cache_ != nullptr + && main_cache_->main_cache_ == nullptr); + } + size_ = other.size_; + + values_.resize(other.values_.size()); + + tmp_.resize(other.mat_.rows(), other.mat_.cols()); + mat_.resize(other.mat_.rows(), other.mat_.cols()); + mat_.setZero(); + std::fill(values_.begin(), values_.end(), 0); +} + +void SparseMatrixCache::set_zero() +{ + tmp_.setZero(); + mat_.setZero(); + + std::fill(values_.begin(), values_.end(), 0); +} + +void SparseMatrixCache::add_value( + const int e, const int i, const int j, const double value) +{ + // caches have yet to be constructed (likely because the matrix has yet to + // be fully assembled) + if (mapping().empty()) { + // save entry so it can be added to the matrix later + entries_.emplace_back(i, j, value); + + // save the index information so the cache can be built later + if (second_cache_entries_.size() <= e) + second_cache_entries_.resize(e + 1); + second_cache_entries_[e].emplace_back(i, j); + } else { + if (e != current_e_) { + current_e_ = e; + current_e_index_ = 0; + } + + // save entry directly to value buffer at the proper index + values_[second_cache()[e][current_e_index_]] += value; + current_e_index_++; + } +} + +void SparseMatrixCache::prune() +{ + // caches have yet to be constructed (likely because the matrix has yet to + // be fully assembled) + if (mapping().empty()) { + tmp_.setFromTriplets(entries_.begin(), entries_.end()); + tmp_.makeCompressed(); + mat_ += tmp_; -namespace ipc + tmp_.setZero(); + tmp_.data().squeeze(); + mat_.makeCompressed(); + + entries_.clear(); + + mat_.makeCompressed(); + } +} + +Eigen::SparseMatrix +SparseMatrixCache::get_matrix(const bool compute_mapping) +{ + prune(); + + // caches have yet to be constructed (likely because the matrix has yet to + // be fully assembled) + if (mapping().empty()) { + if (compute_mapping && size_ > 0) { + assert(main_cache_ == nullptr); + + values_.resize(mat_.nonZeros()); + inner_index_.resize(mat_.nonZeros()); + outer_index_.resize(mat_.rows() + 1); + mapping_.resize(mat_.rows()); + + // note: mat_ is column major + const auto inn_ptr = mat_.innerIndexPtr(); + const auto out_ptr = mat_.outerIndexPtr(); + inner_index_.assign(inn_ptr, inn_ptr + inner_index_.size()); + outer_index_.assign(out_ptr, out_ptr + outer_index_.size()); + + size_t index = 0; + // loop over columns of the matrix + for (size_t i = 0; i < mat_.cols(); ++i) { + const auto start = outer_index_[i]; + const auto end = outer_index_[i + 1]; + + // loop over the nonzero elements of the given column + for (size_t ii = start; ii < end; ++ii) { + // pick out current row + const auto j = inner_index_[ii]; + auto& map = mapping_[j]; + map.emplace_back(i, index); + ++index; + } + } + + logger().trace("Cache computed"); + + second_cache_.clear(); + second_cache_.resize(second_cache_entries_.size()); + // loop over each element + for (int e = 0; e < second_cache_entries_.size(); ++e) { + // loop over each global index affected by the given element + for (const auto& p : second_cache_entries_[e]) { + const int i = p.first; + const int j = p.second; + + // pick out column/sparse matrix index pairs for the given + // column + const auto& map = mapping()[i]; + int index = -1; + + // loop over column/sparse matrix index pairs + for (const auto& p : map) { + // match columns + if (p.first == j) { + assert(p.second < values_.size()); + index = p.second; + break; + } + } + assert(index >= 0); + + // save the sparse matrix index used by this element + second_cache_[e].emplace_back(index); + } + } + + second_cache_entries_.resize(0); + + logger().trace("Second cache computed"); + } + } else { + assert(size_ > 0); + const auto& outer_index = main_cache()->outer_index_; + const auto& inner_index = main_cache()->inner_index_; + // directly write the values to the matrix + mat_ = Eigen::Map>( + size_, size_, values_.size(), &outer_index[0], &inner_index[0], + &values_[0]); + + current_e_ = -1; + current_e_index_ = -1; + } + std::fill(values_.begin(), values_.end(), 0); + return mat_; +} + +std::shared_ptr +SparseMatrixCache::operator+(const MatrixCache& a) const +{ + assert(&a == &dynamic_cast(a)); + return *this + dynamic_cast(a); +} + +std::shared_ptr +SparseMatrixCache::operator+(const SparseMatrixCache& a) const +{ + std::shared_ptr out = + std::make_shared(a); + + if (a.mapping().empty() || mapping().empty()) { + out->mat_ = a.mat_ + mat_; + const size_t this_e_size = second_cache_entries_.size(); + const size_t a_e_size = a.second_cache_entries_.size(); + + out->second_cache_entries_.resize(std::max(this_e_size, a_e_size)); + for (int e = 0; e < std::min(this_e_size, a_e_size); ++e) { + assert( + second_cache_entries_[e].size() == 0 + || a.second_cache_entries_[e].size() == 0); + out->second_cache_entries_[e].insert( + out->second_cache_entries_[e].end(), + second_cache_entries_[e].begin(), + second_cache_entries_[e].end()); + out->second_cache_entries_[e].insert( + out->second_cache_entries_[e].end(), + a.second_cache_entries_[e].begin(), + a.second_cache_entries_[e].end()); + } + + for (int e = std::min(this_e_size, a_e_size); + e < std::max(this_e_size, a_e_size); ++e) { + if (second_cache_entries_.size() < e) + out->second_cache_entries_[e].insert( + out->second_cache_entries_[e].end(), + second_cache_entries_[e].begin(), + second_cache_entries_[e].end()); + else + out->second_cache_entries_[e].insert( + out->second_cache_entries_[e].end(), + a.second_cache_entries_[e].begin(), + a.second_cache_entries_[e].end()); + } + } else { + const auto& outer_index = main_cache()->outer_index_; + const auto& inner_index = main_cache()->inner_index_; + const auto& aouter_index = a.main_cache()->outer_index_; + const auto& ainner_index = a.main_cache()->inner_index_; + assert(ainner_index.size() == inner_index.size()); + assert(aouter_index.size() == outer_index.size()); + assert(a.values_.size() == values_.size()); + + ipc::utils::maybe_parallel_for( + a.values_.size(), [&](int start, int end, int thread_id) { + for (int i = start; i < end; ++i) { + out->values_[i] = a.values_[i] + values_[i]; + } + }); + } + + return out; +} + +void SparseMatrixCache::operator+=(const MatrixCache& o) { - SparseMatrixCache::SparseMatrixCache(const size_t size) - { - init(size); - } - - SparseMatrixCache::SparseMatrixCache(const size_t rows, const size_t cols) - { - init(rows, cols); - } - - SparseMatrixCache::SparseMatrixCache(const MatrixCache &other) - { - init(other); - } - - SparseMatrixCache::SparseMatrixCache( - const SparseMatrixCache &other, const bool copy_main_cache_ptr) - { - init(other, copy_main_cache_ptr); - } - - void SparseMatrixCache::init(const size_t size) - { - assert(mapping().empty() || size_ == size); - - size_ = size; - tmp_.resize(size_, size_); - mat_.resize(size_, size_); - mat_.setZero(); - } - - void SparseMatrixCache::init(const size_t rows, const size_t cols) - { - assert(mapping().empty()); - - size_ = rows == cols ? rows : 0; - tmp_.resize(rows, cols); - mat_.resize(rows, cols); - mat_.setZero(); - } - - void SparseMatrixCache::init(const MatrixCache &other) - { - assert(this != &other); - assert(&other == &dynamic_cast(other)); - init(dynamic_cast(other)); - } - - void SparseMatrixCache::init( - const SparseMatrixCache &other, const bool copy_main_cache_ptr) - { - assert(this != &other); - if (copy_main_cache_ptr) - { - main_cache_ = other.main_cache_; - } - else if (main_cache_ == nullptr) - { - main_cache_ = other.main_cache(); - // Only one level of cache - assert(main_cache_ != this && main_cache_ != nullptr && main_cache_->main_cache_ == nullptr); - } - size_ = other.size_; - - values_.resize(other.values_.size()); - - tmp_.resize(other.mat_.rows(), other.mat_.cols()); - mat_.resize(other.mat_.rows(), other.mat_.cols()); - mat_.setZero(); - std::fill(values_.begin(), values_.end(), 0); - } - - void SparseMatrixCache::set_zero() - { - tmp_.setZero(); - mat_.setZero(); - - std::fill(values_.begin(), values_.end(), 0); - } - - void SparseMatrixCache::add_value(const int e, const int i, const int j, const double value) - { - // caches have yet to be constructed (likely because the matrix has yet to be fully assembled) - if (mapping().empty()) - { - // save entry so it can be added to the matrix later - entries_.emplace_back(i, j, value); - - // save the index information so the cache can be built later - if (second_cache_entries_.size() <= e) - second_cache_entries_.resize(e + 1); - second_cache_entries_[e].emplace_back(i, j); - } - else - { - if (e != current_e_) - { - current_e_ = e; - current_e_index_ = 0; - } - - // save entry directly to value buffer at the proper index - values_[second_cache()[e][current_e_index_]] += value; - current_e_index_++; - } - } - - void SparseMatrixCache::prune() - { - // caches have yet to be constructed (likely because the matrix has yet to be fully assembled) - if (mapping().empty()) - { - tmp_.setFromTriplets(entries_.begin(), entries_.end()); - tmp_.makeCompressed(); - mat_ += tmp_; - - tmp_.setZero(); - tmp_.data().squeeze(); - mat_.makeCompressed(); - - entries_.clear(); - - mat_.makeCompressed(); - } - } - - Eigen::SparseMatrix SparseMatrixCache::get_matrix(const bool compute_mapping) - { - prune(); - - // caches have yet to be constructed (likely because the matrix has yet to be fully assembled) - if (mapping().empty()) - { - if (compute_mapping && size_ > 0) - { - assert(main_cache_ == nullptr); - - values_.resize(mat_.nonZeros()); - inner_index_.resize(mat_.nonZeros()); - outer_index_.resize(mat_.rows() + 1); - mapping_.resize(mat_.rows()); - - // note: mat_ is column major - const auto inn_ptr = mat_.innerIndexPtr(); - const auto out_ptr = mat_.outerIndexPtr(); - inner_index_.assign(inn_ptr, inn_ptr + inner_index_.size()); - outer_index_.assign(out_ptr, out_ptr + outer_index_.size()); - - size_t index = 0; - // loop over columns of the matrix - for (size_t i = 0; i < mat_.cols(); ++i) - { - const auto start = outer_index_[i]; - const auto end = outer_index_[i + 1]; - - // loop over the nonzero elements of the given column - for (size_t ii = start; ii < end; ++ii) - { - // pick out current row - const auto j = inner_index_[ii]; - auto &map = mapping_[j]; - map.emplace_back(i, index); - ++index; - } - } - - logger().trace("Cache computed"); - - second_cache_.clear(); - second_cache_.resize(second_cache_entries_.size()); - // loop over each element - for (int e = 0; e < second_cache_entries_.size(); ++e) - { - // loop over each global index affected by the given element - for (const auto &p : second_cache_entries_[e]) - { - const int i = p.first; - const int j = p.second; - - // pick out column/sparse matrix index pairs for the given column - const auto &map = mapping()[i]; - int index = -1; - - // loop over column/sparse matrix index pairs - for (const auto &p : map) - { - // match columns - if (p.first == j) - { - assert(p.second < values_.size()); - index = p.second; - break; - } - } - assert(index >= 0); - - // save the sparse matrix index used by this element - second_cache_[e].emplace_back(index); - } - } - - second_cache_entries_.resize(0); - - logger().trace("Second cache computed"); - } - } - else - { - assert(size_ > 0); - const auto &outer_index = main_cache()->outer_index_; - const auto &inner_index = main_cache()->inner_index_; - // directly write the values to the matrix - mat_ = Eigen::Map>( - size_, size_, values_.size(), &outer_index[0], &inner_index[0], &values_[0]); - - current_e_ = -1; - current_e_index_ = -1; - - } - std::fill(values_.begin(), values_.end(), 0); - return mat_; - } - - std::shared_ptr SparseMatrixCache::operator+(const MatrixCache &a) const - { - assert(&a == &dynamic_cast(a)); - return *this + dynamic_cast(a); - } - - std::shared_ptr SparseMatrixCache::operator+(const SparseMatrixCache &a) const - { - std::shared_ptr out = std::make_shared(a); - - if (a.mapping().empty() || mapping().empty()) - { - out->mat_ = a.mat_ + mat_; - const size_t this_e_size = second_cache_entries_.size(); - const size_t a_e_size = a.second_cache_entries_.size(); - - out->second_cache_entries_.resize(std::max(this_e_size, a_e_size)); - for (int e = 0; e < std::min(this_e_size, a_e_size); ++e) - { - assert(second_cache_entries_[e].size() == 0 || a.second_cache_entries_[e].size() == 0); - out->second_cache_entries_[e].insert(out->second_cache_entries_[e].end(), second_cache_entries_[e].begin(), second_cache_entries_[e].end()); - out->second_cache_entries_[e].insert(out->second_cache_entries_[e].end(), a.second_cache_entries_[e].begin(), a.second_cache_entries_[e].end()); - } - - for (int e = std::min(this_e_size, a_e_size); e < std::max(this_e_size, a_e_size); ++e) - { - if (second_cache_entries_.size() < e) - out->second_cache_entries_[e].insert(out->second_cache_entries_[e].end(), second_cache_entries_[e].begin(), second_cache_entries_[e].end()); - else - out->second_cache_entries_[e].insert(out->second_cache_entries_[e].end(), a.second_cache_entries_[e].begin(), a.second_cache_entries_[e].end()); - } - } - else - { - const auto &outer_index = main_cache()->outer_index_; - const auto &inner_index = main_cache()->inner_index_; - const auto &aouter_index = a.main_cache()->outer_index_; - const auto &ainner_index = a.main_cache()->inner_index_; - assert(ainner_index.size() == inner_index.size()); - assert(aouter_index.size() == outer_index.size()); - assert(a.values_.size() == values_.size()); - - ipc::utils::maybe_parallel_for(a.values_.size(), [&](int start, int end, int thread_id) { - for (int i = start; i < end; ++i) - { - out->values_[i] = a.values_[i] + values_[i]; - } - }); - } - - return out; - } - - void SparseMatrixCache::operator+=(const MatrixCache &o) - { - assert(&o == &dynamic_cast(o)); - *this += dynamic_cast(o); - } - - void SparseMatrixCache::operator+=(const SparseMatrixCache &o) - { - if (mapping().empty() || o.mapping().empty()) - { - mat_ += o.mat_; - - const size_t this_e_size = second_cache_entries_.size(); - const size_t o_e_size = o.second_cache_entries_.size(); - - second_cache_entries_.resize(std::max(this_e_size, o_e_size)); - for (int e = 0; e < o_e_size; ++e) - { - assert(second_cache_entries_[e].size() == 0 || o.second_cache_entries_[e].size() == 0); - second_cache_entries_[e].insert(second_cache_entries_[e].end(), o.second_cache_entries_[e].begin(), o.second_cache_entries_[e].end()); - } - } - else - { - const auto &outer_index = main_cache()->outer_index_; - const auto &inner_index = main_cache()->inner_index_; - const auto &oouter_index = o.main_cache()->outer_index_; - const auto &oinner_index = o.main_cache()->inner_index_; - assert(inner_index.size() == oinner_index.size()); - assert(outer_index.size() == oouter_index.size()); - assert(values_.size() == o.values_.size()); - - ipc::utils::maybe_parallel_for(o.values_.size(), [&](int start, int end, int thread_id) { - for (int i = start; i < end; ++i) - { - values_[i] += o.values_[i]; - } - }); - } - } - - // ======================================================================== - - DenseMatrixCache::DenseMatrixCache(const size_t size) - { - mat_.setZero(size, size); - } - - DenseMatrixCache::DenseMatrixCache(const size_t rows, const size_t cols) - { - mat_.setZero(rows, cols); - } - - DenseMatrixCache::DenseMatrixCache(const MatrixCache &other) - { - init(other); - } - - DenseMatrixCache::DenseMatrixCache(const DenseMatrixCache &other) - { - init(other); - } - - void DenseMatrixCache::init(const size_t size) - { - mat_.setZero(size, size); - } - - void DenseMatrixCache::init(const size_t rows, const size_t cols) - { - mat_.setZero(rows, cols); - } - - void DenseMatrixCache::init(const MatrixCache &other) - { - init(dynamic_cast(other)); - } - - void DenseMatrixCache::init(const DenseMatrixCache &other) - { - mat_.setZero(other.mat_.rows(), other.mat_.cols()); - } - - void DenseMatrixCache::set_zero() - { - mat_.setZero(); - } - - void DenseMatrixCache::add_value(const int e, const int i, const int j, const double value) - { - mat_(i, j) += value; - } - - void DenseMatrixCache::prune() {} - - Eigen::SparseMatrix DenseMatrixCache::get_matrix(const bool compute_mapping) - { - return mat_.sparseView(); - } - - std::shared_ptr DenseMatrixCache::operator+(const MatrixCache &a) const - { - return *this + dynamic_cast(a); - } - - std::shared_ptr DenseMatrixCache::operator+(const DenseMatrixCache &a) const - { - std::shared_ptr out = std::make_shared(a); - out->mat_ += mat_; - return out; - } - - void DenseMatrixCache::operator+=(const MatrixCache &o) - { - *this += dynamic_cast(o); - } - - void DenseMatrixCache::operator+=(const DenseMatrixCache &o) - { - mat_ += o.mat_; - } - -} // namespace utils \ No newline at end of file + assert(&o == &dynamic_cast(o)); + *this += dynamic_cast(o); +} + +void SparseMatrixCache::operator+=(const SparseMatrixCache& o) +{ + if (mapping().empty() || o.mapping().empty()) { + mat_ += o.mat_; + + const size_t this_e_size = second_cache_entries_.size(); + const size_t o_e_size = o.second_cache_entries_.size(); + + second_cache_entries_.resize(std::max(this_e_size, o_e_size)); + for (int e = 0; e < o_e_size; ++e) { + assert( + second_cache_entries_[e].size() == 0 + || o.second_cache_entries_[e].size() == 0); + second_cache_entries_[e].insert( + second_cache_entries_[e].end(), + o.second_cache_entries_[e].begin(), + o.second_cache_entries_[e].end()); + } + } else { + const auto& outer_index = main_cache()->outer_index_; + const auto& inner_index = main_cache()->inner_index_; + const auto& oouter_index = o.main_cache()->outer_index_; + const auto& oinner_index = o.main_cache()->inner_index_; + assert(inner_index.size() == oinner_index.size()); + assert(outer_index.size() == oouter_index.size()); + assert(values_.size() == o.values_.size()); + + ipc::utils::maybe_parallel_for( + o.values_.size(), [&](int start, int end, int thread_id) { + for (int i = start; i < end; ++i) { + values_[i] += o.values_[i]; + } + }); + } +} + +// ======================================================================== + +DenseMatrixCache::DenseMatrixCache(const size_t size) +{ + mat_.setZero(size, size); +} + +DenseMatrixCache::DenseMatrixCache(const size_t rows, const size_t cols) +{ + mat_.setZero(rows, cols); +} + +DenseMatrixCache::DenseMatrixCache(const MatrixCache& other) { init(other); } + +DenseMatrixCache::DenseMatrixCache(const DenseMatrixCache& other) +{ + init(other); +} + +void DenseMatrixCache::init(const size_t size) { mat_.setZero(size, size); } + +void DenseMatrixCache::init(const size_t rows, const size_t cols) +{ + mat_.setZero(rows, cols); +} + +void DenseMatrixCache::init(const MatrixCache& other) +{ + init(dynamic_cast(other)); +} + +void DenseMatrixCache::init(const DenseMatrixCache& other) +{ + mat_.setZero(other.mat_.rows(), other.mat_.cols()); +} + +void DenseMatrixCache::set_zero() { mat_.setZero(); } + +void DenseMatrixCache::add_value( + const int e, const int i, const int j, const double value) +{ + mat_(i, j) += value; +} + +void DenseMatrixCache::prune() { } + +Eigen::SparseMatrix +DenseMatrixCache::get_matrix(const bool compute_mapping) +{ + return mat_.sparseView(); +} + +std::shared_ptr +DenseMatrixCache::operator+(const MatrixCache& a) const +{ + return *this + dynamic_cast(a); +} + +std::shared_ptr +DenseMatrixCache::operator+(const DenseMatrixCache& a) const +{ + std::shared_ptr out = + std::make_shared(a); + out->mat_ += mat_; + return out; +} + +void DenseMatrixCache::operator+=(const MatrixCache& o) +{ + *this += dynamic_cast(o); +} + +void DenseMatrixCache::operator+=(const DenseMatrixCache& o) { mat_ += o.mat_; } + +} // namespace ipc \ No newline at end of file diff --git a/src/ipc/utils/MatrixCache.hpp b/src/ipc/utils/MatrixCache.hpp index 3c4c89ca0..32a34e6a6 100644 --- a/src/ipc/utils/MatrixCache.hpp +++ b/src/ipc/utils/MatrixCache.hpp @@ -4,172 +4,202 @@ #include -namespace ipc -{ - /// abstract class used for caching - class MatrixCache - { - public: - MatrixCache() {} - virtual ~MatrixCache() = default; - - virtual std::unique_ptr copy() const = 0; - - virtual void init(const size_t size) = 0; - virtual void init(const size_t rows, const size_t cols) = 0; - virtual void init(const MatrixCache &other) = 0; - - virtual void set_zero() = 0; - - virtual void reserve(const size_t size) = 0; - virtual size_t entries_size() const = 0; - virtual size_t capacity() const = 0; - virtual size_t non_zeros() const = 0; - virtual size_t triplet_count() const = 0; - virtual bool is_sparse() const = 0; - bool is_dense() const { return !is_sparse(); } - - virtual void add_value(const int e, const int i, const int j, const double value) = 0; - virtual Eigen::SparseMatrix get_matrix(const bool compute_mapping = true) = 0; - virtual void prune() = 0; - - virtual std::shared_ptr operator+(const MatrixCache &a) const = 0; - virtual void operator+=(const MatrixCache &o) = 0; - }; - - class SparseMatrixCache : public MatrixCache - { - public: - // constructors (call init functions below) - SparseMatrixCache() {} - SparseMatrixCache(const size_t size); - SparseMatrixCache(const size_t rows, const size_t cols); - SparseMatrixCache(const MatrixCache &other); - SparseMatrixCache(const SparseMatrixCache &other, const bool copy_main_cache_ptr = false); - - inline std::unique_ptr copy() const override - { - // just copy main cache pointer - return std::make_unique(*this, true); - } - - /// set matrix to be size x size - void init(const size_t size) override; - /// set matrix to be rows x cols - void init(const size_t rows, const size_t cols) override; - /// set matrix to be a matrix of all zeros with same size as other - void init(const MatrixCache &other) override; - /// set matrix to be a matrix of all zeros with same size as other (potentially with the same main cache) - void init(const SparseMatrixCache &other, const bool copy_main_cache_ptr = false); - - /// set matrix values to zero - /// modifies tmp_, mat_, and values (setting all to zero) - void set_zero() override; - - inline void reserve(const size_t size) override { entries_.reserve(size); } - inline size_t entries_size() const override { return entries_.size(); } - inline size_t capacity() const override { return entries_.capacity(); } - inline size_t non_zeros() const override { return mapping_.empty() ? mat_.nonZeros() : values_.size(); } - inline size_t triplet_count() const override { return entries_.size() + mat_.nonZeros(); } - inline bool is_sparse() const override { return true; } - inline size_t mapping_size() const { return mapping_.size(); } - - /// e = element_index, i = global row_index, j = global column_index, value = value to add to matrix - /// if the cache is yet to be constructed, save the row, column, and value to be added to the second cache - /// in this case, modifies_ entries_ and second_cache_entries_ - /// otherwise, save the value directly in the second cache - /// in this case, modfies values_ - void add_value(const int e, const int i, const int j, const double value) override; - /// if the cache is yet to be constructed, save the - /// cached (ordered) indices in inner_index_ and outer_index_ - /// then fill in map and second_cache_ - /// in this case, modifies inner_index_, outer_index_, map, and second_cache_ to reflect the matrix structure - /// also empties second_cache_entries and sets values_ to zero - /// otherwise, update mat_ directly using the cached indices and values_ - /// in this case, modifies mat_ and sets values_ to zero - Eigen::SparseMatrix get_matrix(const bool compute_mapping = true) override; - /// if caches have yet to be constructed, add the saved triplets to mat_ - /// modifies tmp_ and mat_, also sets entries_ to be empty after writing its values to mat_ - void prune() override; ///< add saved entries to stored matrix - - std::shared_ptr operator+(const MatrixCache &a) const override; - std::shared_ptr operator+(const SparseMatrixCache &a) const; - void operator+=(const MatrixCache &o) override; - void operator+=(const SparseMatrixCache &o); - - const Eigen::SparseMatrix &mat() const { return mat_; } - const std::vector> &entries() const { return entries_; } - - private: - size_t size_; - Eigen::SparseMatrix tmp_, mat_; - std::vector> entries_; ///< contains global matrix indices and corresponding value - std::vector>> mapping_; ///< maps row indices to column index/local index pairs - std::vector inner_index_, outer_index_; ///< saves inner/outer indices for sparse matrix - std::vector values_; ///< buffer for values (corresponds to inner/outer_index_ structure for sparse matrix) - const SparseMatrixCache *main_cache_ = nullptr; - - std::vector> second_cache_; ///< maps element index to local index - std::vector>> second_cache_entries_; ///< maps element indices to global matrix indices - int current_e_ = -1; - int current_e_index_ = -1; - - inline const SparseMatrixCache *main_cache() const - { - return main_cache_ == nullptr ? this : main_cache_; - } - - inline const std::vector>> &mapping() const - { - return main_cache()->mapping_; - } - - inline const std::vector> &second_cache() const - { - return main_cache()->second_cache_; - } - }; - - class DenseMatrixCache : public MatrixCache - { - public: - DenseMatrixCache() {} - DenseMatrixCache(const size_t size); - DenseMatrixCache(const size_t rows, const size_t cols); - DenseMatrixCache(const MatrixCache &other); - DenseMatrixCache(const DenseMatrixCache &other); - - inline std::unique_ptr copy() const override - { - return std::make_unique(*this); - } - - void init(const size_t size) override; - void init(const size_t rows, const size_t cols) override; - void init(const MatrixCache &other) override; - void init(const DenseMatrixCache &other); - - void set_zero() override; - - inline void reserve(const size_t size) override {} - inline size_t entries_size() const override { return 0; } - inline size_t capacity() const override { return mat_.size(); } - inline size_t non_zeros() const override { return mat_.size(); } - inline size_t triplet_count() const override { return non_zeros(); } - inline bool is_sparse() const override { return false; } - - void add_value(const int e, const int i, const int j, const double value) override; - Eigen::SparseMatrix get_matrix(const bool compute_mapping = true) override; - void prune() override; - - std::shared_ptr operator+(const MatrixCache &a) const override; - std::shared_ptr operator+(const DenseMatrixCache &a) const; - void operator+=(const MatrixCache &o) override; - void operator+=(const DenseMatrixCache &o); - - const Eigen::MatrixXd &mat() const { return mat_; } - - private: - Eigen::MatrixXd mat_; - }; -} // namespace utils +namespace ipc { +/// abstract class used for caching +class MatrixCache { +public: + MatrixCache() { } + virtual ~MatrixCache() = default; + + virtual std::unique_ptr copy() const = 0; + + virtual void init(const size_t size) = 0; + virtual void init(const size_t rows, const size_t cols) = 0; + virtual void init(const MatrixCache& other) = 0; + + virtual void set_zero() = 0; + + virtual void reserve(const size_t size) = 0; + virtual size_t entries_size() const = 0; + virtual size_t capacity() const = 0; + virtual size_t non_zeros() const = 0; + virtual size_t triplet_count() const = 0; + virtual bool is_sparse() const = 0; + bool is_dense() const { return !is_sparse(); } + + virtual void + add_value(const int e, const int i, const int j, const double value) = 0; + virtual Eigen::SparseMatrix + get_matrix(const bool compute_mapping = true) = 0; + virtual void prune() = 0; + + virtual std::shared_ptr + operator+(const MatrixCache& a) const = 0; + virtual void operator+=(const MatrixCache& o) = 0; +}; + +class SparseMatrixCache : public MatrixCache { +public: + // constructors (call init functions below) + SparseMatrixCache() { } + SparseMatrixCache(const size_t size); + SparseMatrixCache(const size_t rows, const size_t cols); + SparseMatrixCache(const MatrixCache& other); + SparseMatrixCache( + const SparseMatrixCache& other, const bool copy_main_cache_ptr = false); + + inline std::unique_ptr copy() const override + { + // just copy main cache pointer + return std::make_unique(*this, true); + } + + /// set matrix to be size x size + void init(const size_t size) override; + /// set matrix to be rows x cols + void init(const size_t rows, const size_t cols) override; + /// set matrix to be a matrix of all zeros with same size as other + void init(const MatrixCache& other) override; + /// set matrix to be a matrix of all zeros with same size as other + /// (potentially with the same main cache) + void init( + const SparseMatrixCache& other, const bool copy_main_cache_ptr = false); + + /// set matrix values to zero + /// modifies tmp_, mat_, and values (setting all to zero) + void set_zero() override; + + inline void reserve(const size_t size) override { entries_.reserve(size); } + inline size_t entries_size() const override { return entries_.size(); } + inline size_t capacity() const override { return entries_.capacity(); } + inline size_t non_zeros() const override + { + return mapping_.empty() ? mat_.nonZeros() : values_.size(); + } + inline size_t triplet_count() const override + { + return entries_.size() + mat_.nonZeros(); + } + inline bool is_sparse() const override { return true; } + inline size_t mapping_size() const { return mapping_.size(); } + + /// e = element_index, i = global row_index, j = global column_index, value + /// = value to add to matrix if the cache is yet to be constructed, save the + /// row, column, and value to be added to the second cache + /// in this case, modifies_ entries_ and second_cache_entries_ + /// otherwise, save the value directly in the second cache + /// in this case, modfies values_ + void add_value( + const int e, const int i, const int j, const double value) override; + /// if the cache is yet to be constructed, save the + /// cached (ordered) indices in inner_index_ and outer_index_ + /// then fill in map and second_cache_ + /// in this case, modifies inner_index_, outer_index_, map, and + /// second_cache_ to reflect the matrix structure also empties + /// second_cache_entries and sets values_ to zero + /// otherwise, update mat_ directly using the cached indices and values_ + /// in this case, modifies mat_ and sets values_ to zero + Eigen::SparseMatrix + get_matrix(const bool compute_mapping = true) override; + /// if caches have yet to be constructed, add the saved triplets to mat_ + /// modifies tmp_ and mat_, also sets entries_ to be empty after writing its + /// values to mat_ + void prune() override; ///< add saved entries to stored matrix + + std::shared_ptr operator+(const MatrixCache& a) const override; + std::shared_ptr operator+(const SparseMatrixCache& a) const; + void operator+=(const MatrixCache& o) override; + void operator+=(const SparseMatrixCache& o); + + const Eigen::SparseMatrix& mat() const + { + return mat_; + } + const std::vector>& entries() const + { + return entries_; + } + +private: + size_t size_; + Eigen::SparseMatrix tmp_, mat_; + std::vector> + entries_; ///< contains global matrix indices and corresponding value + std::vector>> + mapping_; ///< maps row indices to column index/local index pairs + std::vector inner_index_, + outer_index_; ///< saves inner/outer indices for sparse matrix + std::vector + values_; ///< buffer for values (corresponds to inner/outer_index_ + ///< structure for sparse matrix) + const SparseMatrixCache* main_cache_ = nullptr; + + std::vector> + second_cache_; ///< maps element index to local index + std::vector>> + second_cache_entries_; ///< maps element indices to global matrix + ///< indices + int current_e_ = -1; + int current_e_index_ = -1; + + inline const SparseMatrixCache* main_cache() const + { + return main_cache_ == nullptr ? this : main_cache_; + } + + inline const std::vector>>& + mapping() const + { + return main_cache()->mapping_; + } + + inline const std::vector>& second_cache() const + { + return main_cache()->second_cache_; + } +}; + +class DenseMatrixCache : public MatrixCache { +public: + DenseMatrixCache() { } + DenseMatrixCache(const size_t size); + DenseMatrixCache(const size_t rows, const size_t cols); + DenseMatrixCache(const MatrixCache& other); + DenseMatrixCache(const DenseMatrixCache& other); + + inline std::unique_ptr copy() const override + { + return std::make_unique(*this); + } + + void init(const size_t size) override; + void init(const size_t rows, const size_t cols) override; + void init(const MatrixCache& other) override; + void init(const DenseMatrixCache& other); + + void set_zero() override; + + inline void reserve(const size_t size) override { } + inline size_t entries_size() const override { return 0; } + inline size_t capacity() const override { return mat_.size(); } + inline size_t non_zeros() const override { return mat_.size(); } + inline size_t triplet_count() const override { return non_zeros(); } + inline bool is_sparse() const override { return false; } + + void add_value( + const int e, const int i, const int j, const double value) override; + Eigen::SparseMatrix + get_matrix(const bool compute_mapping = true) override; + void prune() override; + + std::shared_ptr operator+(const MatrixCache& a) const override; + std::shared_ptr operator+(const DenseMatrixCache& a) const; + void operator+=(const MatrixCache& o) override; + void operator+=(const DenseMatrixCache& o); + + const Eigen::MatrixXd& mat() const { return mat_; } + +private: + Eigen::MatrixXd mat_; +}; +} // namespace ipc diff --git a/src/ipc/utils/MaybeParallelFor.hpp b/src/ipc/utils/MaybeParallelFor.hpp index 30f1b75f1..9fc99c675 100644 --- a/src/ipc/utils/MaybeParallelFor.hpp +++ b/src/ipc/utils/MaybeParallelFor.hpp @@ -1,48 +1,51 @@ #pragma once #if defined(IPC_TOOLKIT_WITH_TBB) +#include #include #include -#include #elif defined(IPC_TOOLKIT_WITH_CPP_THREADS) #include "par_for.hpp" + #include #else #include // Not using parallel for #endif -namespace ipc -{ - namespace utils - { - - template +namespace ipc { +namespace utils { + + template #if defined(IPC_TOOLKIT_WITH_TBB) - using ParallelCacheType = tbb::enumerable_thread_specific; + using ParallelCacheType = tbb::enumerable_thread_specific; #elif defined(IPC_TOOLKIT_WITH_CPP_THREADS) - using ParallelCacheType = std::vector; + using ParallelCacheType = std::vector; #else - using ParallelCacheType = std::array; + using ParallelCacheType = std::array; #endif - // Perform a parallel (maybe) for loop. - // The parallel for used depends on the compile definitions. - // The overall for loop is from 0 up to `size` with an increment of 1. - inline void maybe_parallel_for(int size, const std::function &partial_for); - inline void maybe_parallel_for(int size, const std::function &body); - - // Returns thread specific storage for further use in `maybe_parallel_for()`. - // The return type depends on the threading library used. - // TBB ⟹ `std::vector` - // C++ Threads ⟹ `tbb::enumerable_thread_specific` - // none ⟹ `std::array` - template - inline auto create_thread_storage(const LocalStorage &initial_local_storage); - - template - inline auto &get_local_thread_storage(Storages &storage, int thread_id); - } // namespace utils -} + // Perform a parallel (maybe) for loop. + // The parallel for used depends on the compile definitions. + // The overall for loop is from 0 up to `size` with an increment of 1. + inline void maybe_parallel_for( + int size, const std::function& partial_for); + inline void + maybe_parallel_for(int size, const std::function& body); + + // Returns thread specific storage for further use in + // `maybe_parallel_for()`. The return type depends on the threading library + // used. + // TBB ⟹ `std::vector` + // C++ Threads ⟹ `tbb::enumerable_thread_specific` + // none ⟹ `std::array` + template + inline auto + create_thread_storage(const LocalStorage& initial_local_storage); + + template + inline auto& get_local_thread_storage(Storages& storage, int thread_id); +} // namespace utils +} // namespace ipc #include "MaybeParallelFor.tpp" diff --git a/src/ipc/utils/MaybeParallelFor.tpp b/src/ipc/utils/MaybeParallelFor.tpp index 9b3b6540a..fb820cab3 100644 --- a/src/ipc/utils/MaybeParallelFor.tpp +++ b/src/ipc/utils/MaybeParallelFor.tpp @@ -1,70 +1,77 @@ #include "MaybeParallelFor.hpp" #if defined(IPC_TOOLKIT_WITH_TBB) +#include #include #include -#include #elif defined(IPC_TOOLKIT_WITH_CPP_THREADS) #include "par_for.hpp" + #include #else // Not using parallel for #endif -namespace ipc -{ - namespace utils - { - inline void maybe_parallel_for(int size, const std::function &partial_for) - { +namespace ipc { +namespace utils { + inline void maybe_parallel_for( + int size, const std::function& partial_for) + { #if defined(IPC_TOOLKIT_WITH_CPP_THREADS) - par_for(size, partial_for); + par_for(size, partial_for); #elif defined(IPC_TOOLKIT_WITH_TBB) - tbb::parallel_for(tbb::blocked_range(0, size), [&](const tbb::blocked_range &r) { - partial_for(r.begin(), r.end(), tbb::this_task_arena::current_thread_index()); - }); + tbb::parallel_for( + tbb::blocked_range(0, size), + [&](const tbb::blocked_range& r) { + partial_for( + r.begin(), r.end(), + tbb::this_task_arena::current_thread_index()); + }); #else - partial_for(0, size, /*thread_id=*/0); // actually the full for loop + partial_for(0, size, /*thread_id=*/0); // actually the full for loop #endif - } + } - inline void maybe_parallel_for(int size, const std::function &body) - { + inline void + maybe_parallel_for(int size, const std::function& body) + { #if defined(IPC_TOOLKIT_WITH_CPP_THREADS) - for (int i = 0; i < size; ++i) - body(i); + for (int i = 0; i < size; ++i) + body(i); #elif defined(IPC_TOOLKIT_WITH_TBB) - tbb::parallel_for(0, size, body); + tbb::parallel_for(0, size, body); #else - for (int i = 0; i < size; ++i) - body(i); + for (int i = 0; i < size; ++i) + body(i); #endif - } + } - template - inline auto create_thread_storage(const LocalStorage &initial_local_storage) - { + template + inline auto create_thread_storage(const LocalStorage& initial_local_storage) + { #if defined(IPC_TOOLKIT_WITH_CPP_THREADS) - return std::vector(get_n_threads(), initial_local_storage); + return std::vector( + get_n_threads(), initial_local_storage); #elif defined(IPC_TOOLKIT_WITH_TBB) - return tbb::enumerable_thread_specific(initial_local_storage); + return tbb::enumerable_thread_specific( + initial_local_storage); #else - return std::array{{initial_local_storage}}; + return std::array { { initial_local_storage } }; #endif - } + } - template - inline auto &get_local_thread_storage(Storages &storage, int thread_id) - { + template + inline auto& get_local_thread_storage(Storages& storage, int thread_id) + { #if defined(IPC_TOOLKIT_WITH_CPP_THREADS) - return storage[thread_id]; + return storage[thread_id]; #elif defined(IPC_TOOLKIT_WITH_TBB) - return storage.local(); + return storage.local(); #else - assert(thread_id == 0); - assert(storage.size() == 1); - return storage[0]; + assert(thread_id == 0); + assert(storage.size() == 1); + return storage[0]; #endif - } - } // namespace utils -} + } +} // namespace utils +} // namespace ipc diff --git a/src/ipc/utils/autodiff.h b/src/ipc/utils/autodiff.h index 952bb4ef9..34e6ea2a9 100644 --- a/src/ipc/utils/autodiff.h +++ b/src/ipc/utils/autodiff.h @@ -29,6 +29,7 @@ #endif #include + #include #include diff --git a/src/ipc/utils/eigen_ext.hpp b/src/ipc/utils/eigen_ext.hpp index 588420120..3485934c4 100644 --- a/src/ipc/utils/eigen_ext.hpp +++ b/src/ipc/utils/eigen_ext.hpp @@ -168,10 +168,10 @@ using ArrayMax4d = ArrayMax4; /// @brief A dynamic size array with a fixed maximum size of 4×1 using ArrayMax4i = ArrayMax4; +template using GradType = std::tuple>; template -using GradType = std::tuple>; -template -using HessianType = std::tuple, Eigen::Matrix>; +using HessianType = + std::tuple, Eigen::Matrix>; /// @brief Matrix projection onto positive definite cone /// @param A Symmetric matrix to project diff --git a/src/ipc/utils/finitediff.hpp b/src/ipc/utils/finitediff.hpp index d15e207ce..4972bfab0 100644 --- a/src/ipc/utils/finitediff.hpp +++ b/src/ipc/utils/finitediff.hpp @@ -1,7 +1,6 @@ #pragma once #include - #include namespace ipc { diff --git a/src/ipc/utils/getRSS.c b/src/ipc/utils/getRSS.c deleted file mode 100644 index 6e442dd50..000000000 --- a/src/ipc/utils/getRSS.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Author: David Robert Nadeau - * Site: http://NadeauSoftware.com/ - * License: Creative Commons Attribution 3.0 Unported License - * http://creativecommons.org/licenses/by/3.0/deed.en_US - */ - -#if defined(_WIN32) -#include -#include - -#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) -#include -#include - -#if defined(__APPLE__) && defined(__MACH__) -#include - -#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) -#include -#include - -#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) -#include - -#endif - -#else -#error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS." -#endif - -/** - * Returns the peak (maximum so far) resident set size (physical - * memory use) measured in bytes, or zero if the value cannot be - * determined on this OS. - */ -size_t getPeakRSS(void) -{ -#if defined(_WIN32) - /* Windows -------------------------------------------------- */ - PROCESS_MEMORY_COUNTERS info; - GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); - return (size_t)info.PeakWorkingSetSize; - -#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) - /* AIX and Solaris ------------------------------------------ */ - struct psinfo psinfo; - int fd = -1; - if ((fd = open("/proc/self/psinfo", O_RDONLY)) == -1) - return (size_t)0L; /* Can't open? */ - if (read(fd, &psinfo, sizeof(psinfo)) != sizeof(psinfo)) - { - close(fd); - return (size_t)0L; /* Can't read? */ - } - close(fd); - return (size_t)(psinfo.pr_rssize * 1024L); - -#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) - /* BSD, Linux, and OSX -------------------------------------- */ - struct rusage rusage; - getrusage(RUSAGE_SELF, &rusage); -#if defined(__APPLE__) && defined(__MACH__) - return (size_t)rusage.ru_maxrss; -#else - return (size_t)(rusage.ru_maxrss * 1024L); -#endif - -#else - /* Unknown OS ----------------------------------------------- */ - return (size_t)0L; /* Unsupported. */ -#endif -} - -/** - * Returns the current resident set size (physical memory use) measured - * in bytes, or zero if the value cannot be determined on this OS. - */ -size_t getCurrentRSS(void) -{ -#if defined(_WIN32) - /* Windows -------------------------------------------------- */ - PROCESS_MEMORY_COUNTERS info; - GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); - return (size_t)info.WorkingSetSize; - -#elif defined(__APPLE__) && defined(__MACH__) - /* OSX ------------------------------------------------------ */ - struct mach_task_basic_info info; - mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; - if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, - (task_info_t)&info, &infoCount) - != KERN_SUCCESS) - return (size_t)0L; /* Can't access? */ - return (size_t)info.resident_size; - -#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) - /* Linux ---------------------------------------------------- */ - long rss = 0L; - FILE *fp = NULL; - if ((fp = fopen("/proc/self/statm", "r")) == NULL) - return (size_t)0L; /* Can't open? */ - if (fscanf(fp, "%*s%ld", &rss) != 1) - { - fclose(fp); - return (size_t)0L; /* Can't read? */ - } - fclose(fp); - return (size_t)rss * (size_t)sysconf(_SC_PAGESIZE); - -#else - /* AIX, BSD, Solaris, and Unknown OS ------------------------ */ - return (size_t)0L; /* Unsupported. */ -#endif -} diff --git a/src/ipc/utils/getRSS.h b/src/ipc/utils/getRSS.h deleted file mode 100644 index 1d74579d8..000000000 --- a/src/ipc/utils/getRSS.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#ifdef __cplusplus -extern "C" -{ -#endif - - size_t getPeakRSS(); - size_t getCurrentRSS(); - -#ifdef __cplusplus -} -#endif diff --git a/src/ipc/utils/local_to_global.hpp b/src/ipc/utils/local_to_global.hpp index 72181c68b..6a964d71c 100644 --- a/src/ipc/utils/local_to_global.hpp +++ b/src/ipc/utils/local_to_global.hpp @@ -1,10 +1,11 @@ #pragma once +#include "MatrixCache.hpp" + #include #include #include -#include "MatrixCache.hpp" namespace ipc { @@ -92,8 +93,7 @@ void local_jacobian_to_global_triplets( } } -class LocalThreadMatStorage -{ +class LocalThreadMatStorage { public: std::unique_ptr cache = nullptr; @@ -104,17 +104,17 @@ class LocalThreadMatStorage init(buffer_size, rows, cols); } - LocalThreadMatStorage(const int buffer_size, const MatrixCache &c) + LocalThreadMatStorage(const int buffer_size, const MatrixCache& c) { init(buffer_size, c); } - LocalThreadMatStorage(const LocalThreadMatStorage &other) + LocalThreadMatStorage(const LocalThreadMatStorage& other) : cache(other.cache->copy()) { } - LocalThreadMatStorage &operator=(const LocalThreadMatStorage &other) + LocalThreadMatStorage& operator=(const LocalThreadMatStorage& other) { assert(other.cache != nullptr); cache = other.cache->copy(); @@ -130,7 +130,7 @@ class LocalThreadMatStorage cache->init(rows, cols); } - void init(const int buffer_size, const MatrixCache &c) + void init(const int buffer_size, const MatrixCache& c) { if (cache == nullptr) cache = c.copy(); @@ -154,9 +154,10 @@ void local_hessian_to_global_triplets( for (int j = 0; j < n_verts; j++) { for (int k = 0; k < dim; k++) { for (int l = 0; l < dim; l++) { - const auto &val = local_hessian(dim * i + k, dim * j + l); + const auto& val = local_hessian(dim * i + k, dim * j + l); if (val != 0) - triplets.add_value(0, dim * ids[i] + k, dim * ids[j] + l, val); + triplets.add_value( + 0, dim * ids[i] + k, dim * ids[j] + l, val); } } } diff --git a/src/ipc/utils/math.cpp b/src/ipc/utils/math.cpp index 589d62857..df171830d 100644 --- a/src/ipc/utils/math.cpp +++ b/src/ipc/utils/math.cpp @@ -1,7 +1,9 @@ #include "math.hpp" -#include + #include "AutodiffTypes.hpp" +#include + DECLARE_DIFFSCALAR_BASE(); namespace ipc { @@ -186,7 +188,8 @@ HessianType<9> negative_orientation_penalty_hess( const double& beta) { const Vector3d n = t1.cross(t2); - const Eigen::Matrix cross_grad = cross_product_gradient(t1, t2); + const Eigen::Matrix cross_grad = + cross_product_gradient(t1, t2); const std::array cross_hess = cross_product_hessian(t1, t2); auto [y, dy, ddy] = opposite_direction_penalty_hess(n, d, alpha, beta); diff --git a/src/ipc/utils/math.hpp b/src/ipc/utils/math.hpp index 95444b228..63804e8c2 100644 --- a/src/ipc/utils/math.hpp +++ b/src/ipc/utils/math.hpp @@ -1,8 +1,9 @@ #pragma once -#include #include "eigen_ext.hpp" +#include + namespace ipc { enum class HEAVISIDE_TYPE { ZERO = 0, ONE = 1, VARIANT = 2 }; diff --git a/src/ipc/utils/math.tpp b/src/ipc/utils/math.tpp index fce7192bd..b2439b77b 100644 --- a/src/ipc/utils/math.tpp +++ b/src/ipc/utils/math.tpp @@ -1,6 +1,6 @@ #pragma once -#include "math.hpp" #include "AutodiffTypes.hpp" +#include "math.hpp" namespace ipc { @@ -59,7 +59,7 @@ namespace { return x; } -} +} // namespace template double Math::sign(const double& x) { diff --git a/src/ipc/utils/par_for.cpp b/src/ipc/utils/par_for.cpp index 5c6cbddea..95e1f54a9 100644 --- a/src/ipc/utils/par_for.cpp +++ b/src/ipc/utils/par_for.cpp @@ -1,33 +1,32 @@ #include "par_for.hpp" -#include #include +#include -namespace ipc -{ - namespace utils - { - void par_for(const int size, const std::function &func) - { +namespace ipc { +namespace utils { + void par_for(const int size, const std::function& func) + { #ifdef IPC_TOOLKIT_WITH_CPP_THREADS - const size_t n_threads = get_n_threads(); - if (n_threads == 1) - func(0, size, /*thread_id=*/0); // actually the full for loop - else - { - std::vector threads(n_threads); + const size_t n_threads = get_n_threads(); + if (n_threads == 1) + func(0, size, /*thread_id=*/0); // actually the full for loop + else { + std::vector threads(n_threads); - for (int t = 0; t < n_threads; t++) - { - threads[t] = std::thread(std::bind( - func, - t * size / n_threads, - (t + 1) == n_threads ? size : (t + 1) * size / n_threads, - t)); - } - std::for_each(threads.begin(), threads.end(), [](std::thread &x) { x.join(); }); - } + for (int t = 0; t < n_threads; t++) { + threads[t] = std::thread( + std::bind( + func, t * size / n_threads, + (t + 1) == n_threads ? size + : (t + 1) * size / n_threads, + t)); + } + std::for_each(threads.begin(), threads.end(), [](std::thread& x) { + x.join(); + }); + } #endif - } - } // namespace utils -} + } +} // namespace utils +} // namespace ipc diff --git a/src/ipc/utils/par_for.hpp b/src/ipc/utils/par_for.hpp index 9212bc984..4682912d1 100644 --- a/src/ipc/utils/par_for.hpp +++ b/src/ipc/utils/par_for.hpp @@ -1,53 +1,55 @@ #pragma once +#include "eigen_ext.hpp" + #include #include -#include "eigen_ext.hpp" - #ifdef IPC_TOOLKIT_WITH_TBB #include #endif -namespace ipc -{ - namespace utils - { - class NThread - { - public: - static NThread &get() - { - static NThread instance; - return instance; - } - - inline size_t num_threads() const { return num_threads_; } - - void set_num_threads(const int max_threads) - { - const unsigned int tmp = max_threads <= 0 ? std::numeric_limits::max() : max_threads; - const unsigned int num_threads = std::min(tmp, std::thread::hardware_concurrency()); - - num_threads_ = num_threads; +namespace ipc { +namespace utils { + class NThread { + public: + static NThread& get() + { + static NThread instance; + return instance; + } + + inline size_t num_threads() const { return num_threads_; } + + void set_num_threads(const int max_threads) + { + const unsigned int tmp = max_threads <= 0 + ? std::numeric_limits::max() + : max_threads; + const unsigned int num_threads = + std::min(tmp, std::thread::hardware_concurrency()); + + num_threads_ = num_threads; #ifdef IPC_TOOLKIT_WITH_TBB - thread_limiter = std::make_shared(tbb::global_control::max_allowed_parallelism, num_threads); + thread_limiter = std::make_shared( + tbb::global_control::max_allowed_parallelism, num_threads); #endif - Eigen::setNbThreads(num_threads); - } + Eigen::setNbThreads(num_threads); + } - private: - NThread() {} + private: + NThread() { } - size_t num_threads_; + size_t num_threads_; #ifdef IPC_TOOLKIT_WITH_TBB - /// limits the number of used threads - std::shared_ptr thread_limiter; + /// limits the number of used threads + std::shared_ptr thread_limiter; #endif - }; + }; - void par_for(const int size, const std::function &func); - inline size_t get_n_threads() { return NThread::get().num_threads(); } - } // namespace utils -} + void + par_for(const int size, const std::function& func); + inline size_t get_n_threads() { return NThread::get().num_threads(); } +} // namespace utils +} // namespace ipc diff --git a/src/ipc/utils/quadrature.hpp b/src/ipc/utils/quadrature.hpp index 793ff9ab1..84be363fb 100644 --- a/src/ipc/utils/quadrature.hpp +++ b/src/ipc/utils/quadrature.hpp @@ -1,7 +1,6 @@ #pragma once #include - #include namespace ipc { diff --git a/src/ipc/utils/tangents.hpp b/src/ipc/utils/tangents.hpp index dceec304f..c3f45fa9a 100644 --- a/src/ipc/utils/tangents.hpp +++ b/src/ipc/utils/tangents.hpp @@ -1,7 +1,6 @@ #pragma once #include - #include namespace ipc { diff --git a/tests/src/tests/barrier/test_eigen.cpp b/tests/src/tests/barrier/test_eigen.cpp index a72d2520c..45c14f55b 100644 --- a/tests/src/tests/barrier/test_eigen.cpp +++ b/tests/src/tests/barrier/test_eigen.cpp @@ -8,19 +8,17 @@ #include #include -Eigen::Matrix3i fun1() { +Eigen::Matrix3i fun1() +{ Eigen::Matrix3i A; - A << 1, 2, 3, - 4, 5, 6, - 7, 8, 9; + A << 1, 2, 3, 4, 5, 6, 7, 8, 9; return A; } -std::tuple func2() { +std::tuple func2() +{ Eigen::Matrix3i A; - A << 1, 2, 3, - 4, 5, 6, - 7, 8, 9; + A << 1, 2, 3, 4, 5, 6, 7, 8, 9; return std::make_tuple(0., A); } @@ -32,7 +30,7 @@ TEST_CASE("assign sub matrix", "[eigen_unit]") for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) - CHECK(B(i+1, j+1) == 3 * i + j + 1); + CHECK(B(i + 1, j + 1) == 3 * i + j + 1); } TEST_CASE("assign sub matrix in tuple", "[eigen_unit]") @@ -46,14 +44,15 @@ TEST_CASE("assign sub matrix in tuple", "[eigen_unit]") CHECK(b == 0); for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) - CHECK(B(i+1, j+1) == 3 * i + j + 1); + CHECK(B(i + 1, j + 1) == 3 * i + j + 1); } TEST_CASE("eigen map and ref", "[eigen_unit]") { Eigen::Matrix4i B; B.setZero(); - Eigen::Ref> ref = Eigen::Map>(B.data() + 4, 12); + Eigen::Ref> ref = + Eigen::Map>(B.data() + 4, 12); ref(5) = 1; std::cout << "B:\n" << B << "\n"; @@ -64,7 +63,7 @@ TEST_CASE("eigen ref and seqN", "[eigen_unit]") { Eigen::Matrix4i B; B.setZero(); - B({1,2,3},{1,2,3}) = fun1(); + B({ 1, 2, 3 }, { 1, 2, 3 }) = fun1(); std::cout << "B:\n" << B << "\n"; } diff --git a/tests/src/tests/benchmark_eigen.cpp b/tests/src/tests/benchmark_eigen.cpp index 407f73849..cb335f438 100644 --- a/tests/src/tests/benchmark_eigen.cpp +++ b/tests/src/tests/benchmark_eigen.cpp @@ -210,33 +210,22 @@ TEST_CASE("eigen vec dynamic vs static", "[!benchmark][eigen]") TEST_CASE("eigen mat dynamic vs static", "[!benchmark][eigen]") { - const Eigen::Matrix V = Eigen::MatrixXd::Random(100, 3); + const Eigen::Matrix V = + Eigen::MatrixXd::Random(100, 3); const Eigen::Matrix3d X = Eigen::Matrix3d::Random(); int i = 55; - BENCHMARK("Static") - { - return X * V.middleRows(i, 3); - }; + BENCHMARK("Static") { return X * V.middleRows(i, 3); }; - BENCHMARK("Dynamic") - { - return X * V.block<3, 3>(i, 0); - }; + BENCHMARK("Dynamic") { return X * V.block<3, 3>(i, 0); }; } TEST_CASE("trace vs sqr norm", "[!benchmark][eigen]") { const Eigen::Matrix3d V = Eigen::MatrixXd::Random(3, 3); - BENCHMARK("trace") - { - return (V.transpose() * V).trace(); - }; + BENCHMARK("trace") { return (V.transpose() * V).trace(); }; - BENCHMARK("sqr_norm") - { - return V.squaredNorm(); - }; + BENCHMARK("sqr_norm") { return V.squaredNorm(); }; } \ No newline at end of file diff --git a/tests/src/tests/ccd/test_nonlinear_ccd.cpp b/tests/src/tests/ccd/test_nonlinear_ccd.cpp index 4d6bccf30..cc4cb284a 100644 --- a/tests/src/tests/ccd/test_nonlinear_ccd.cpp +++ b/tests/src/tests/ccd/test_nonlinear_ccd.cpp @@ -126,6 +126,7 @@ class Rigid2DTrajectory : virtual public ipc::NonlinearTrajectory { { } + // BEGIN_RIGID_2D_CALL VectorMax3d operator()(const double t) const override { const Eigen::Matrix2d R = @@ -134,7 +135,9 @@ class Rigid2DTrajectory : virtual public ipc::NonlinearTrajectory { return R * position + translation + t * delta_translation; } + // END_RIGID_2D_CALL + // BEGIN_RIGID_2D_MAX_DISTANCE_FROM_LINEAR double max_distance_from_linear(const double t0, const double t1) const override { @@ -147,6 +150,7 @@ class Rigid2DTrajectory : virtual public ipc::NonlinearTrajectory { const VectorMax3d p_t1 = (*this)(t1); return ((*this)((t0 + t1) / 2) - ((p_t1 - p_t0) * 0.5 + p_t0)).norm(); } + // END_RIGID_2D_MAX_DISTANCE_FROM_LINEAR protected: Eigen::Vector2d position; diff --git a/tests/src/tests/config.hpp.in b/tests/src/tests/config.hpp.in index 8a0e42e67..846030758 100644 --- a/tests/src/tests/config.hpp.in +++ b/tests/src/tests/config.hpp.in @@ -18,6 +18,7 @@ static const std::filesystem::path #endif static const std::filesystem::path DATA_DIR("@IPC_TOOLKIT_TESTS_DATA_DIR@"); -static const std::filesystem::path GCP_DATA_DIR("@IPC_TOOLKIT_TESTS_GCP_DATA_DIR@"); +static const std::filesystem::path + GCP_DATA_DIR("@IPC_TOOLKIT_TESTS_GCP_DATA_DIR@"); } // namespace ipc::tests \ No newline at end of file diff --git a/tests/src/tests/distance/test_edge_edge.cpp b/tests/src/tests/distance/test_edge_edge.cpp index be3a26e12..99693f773 100644 --- a/tests/src/tests/distance/test_edge_edge.cpp +++ b/tests/src/tests/distance/test_edge_edge.cpp @@ -309,15 +309,13 @@ TEST_CASE( // CHECK(distance.getHessian().squaredNorm() != Catch::Approx(0.0)); } - -TEST_CASE( - "Edge normal term", "[distance][edge-edge][gradient]") +TEST_CASE("Edge normal term", "[distance][edge-edge][gradient]") { ORIENTATION_TYPES otypes; otypes.set_size(2); const double alpha = 0.85; const double beta = 0.2; - ParameterType param{1e-3, 1, 0, alpha, beta, 2}; + ParameterType param { 1e-3, 1, 0, alpha, beta, 2 }; ipc::Vector3d dn, e0, e1, f0, f1; e0 << 0, 0, 0; @@ -328,20 +326,31 @@ TEST_CASE( ipc::Vector15d x; x << dn, e0, e1, f0, f1; - - const auto [val, grad, hess] = smooth_edge3_normal_term_hessian(dn, e0, e1, f0, f1, alpha, beta, otypes); + + const auto [val, grad, hess] = smooth_edge3_normal_term_hessian( + dn, e0, e1, f0, f1, alpha, beta, otypes); Eigen::VectorXd fgrad; - fd::finite_gradient(x, [&](const Eigen::VectorXd &y) { - return smooth_edge3_normal_term(y.head(3), y.segment(3, 3), y.segment(6, 3), y.segment(9, 3), y.segment(12, 3), alpha, beta, otypes); - }, fgrad, fd::AccuracyOrder::FOURTH, 1e-5); + fd::finite_gradient( + x, + [&](const Eigen::VectorXd& y) { + return smooth_edge3_normal_term( + y.head(3), y.segment(3, 3), y.segment(6, 3), y.segment(9, 3), + y.segment(12, 3), alpha, beta, otypes); + }, + fgrad, fd::AccuracyOrder::FOURTH, 1e-5); CHECK((fgrad - grad).norm() / 1e-8 <= grad.norm()); Eigen::MatrixXd fhess; - fd::finite_jacobian(x, [&](const Eigen::VectorXd &y) { - return std::get<1>(smooth_edge3_normal_term_gradient(y.head(3), y.segment(3, 3), y.segment(6, 3), y.segment(9, 3), y.segment(12, 3), alpha, beta, otypes)); - }, fhess, fd::AccuracyOrder::SECOND, 1e-7); + fd::finite_jacobian( + x, + [&](const Eigen::VectorXd& y) { + return std::get<1>(smooth_edge3_normal_term_gradient( + y.head(3), y.segment(3, 3), y.segment(6, 3), y.segment(9, 3), + y.segment(12, 3), alpha, beta, otypes)); + }, + fhess, fd::AccuracyOrder::SECOND, 1e-7); CHECK((fhess - hess).norm() / 1e-6 <= hess.norm()); } diff --git a/tests/src/tests/distance/test_line_line.cpp b/tests/src/tests/distance/test_line_line.cpp index 5f79d34bb..e1b4c7421 100644 --- a/tests/src/tests/distance/test_line_line.cpp +++ b/tests/src/tests/distance/test_line_line.cpp @@ -29,14 +29,15 @@ TEST_CASE("Line-line closest point pair", "[distance][line-line]") double yb = GENERATE(take(5, random(-100.0, 100.0))); double zb = GENERATE(take(5, random(-0.5, 0.5))); - Eigen::Vector3d eb0(0, yb, - 1 - zb), eb1(0, yb, 1); + Eigen::Vector3d eb0(0, yb, -1 - zb), eb1(0, yb, 1); double expected_distance = line_line_distance(ea0, ea1, eb0, eb1); - Eigen::Matrix closest_points - = line_line_closest_point_pairs(ea0, ea1, eb0, eb1); - double distance = (closest_points.col(0) - closest_points.col(1)).squaredNorm(); - + Eigen::Matrix closest_points = + line_line_closest_point_pairs(ea0, ea1, eb0, eb1); + double distance = + (closest_points.col(0) - closest_points.col(1)).squaredNorm(); + CHECK(distance == Catch::Approx(expected_distance)); } @@ -94,7 +95,8 @@ TEST_CASE("Line-line distance hessian", "[distance][line-line][hessian]") CHECK(fd::compare_hessian(hess, expected_hess, 1e-2)); } -TEST_CASE("Line-line closest direction hessian", "[distance][line-line][hessian]") +TEST_CASE( + "Line-line closest direction hessian", "[distance][line-line][hessian]") { double ya = GENERATE(take(2, random(-10.0, 10.0))); Eigen::Vector3d ea0(-1, ya, 0), ea1(1, ya, 0); @@ -104,16 +106,21 @@ TEST_CASE("Line-line closest direction hessian", "[distance][line-line][hessian] using T = ADHessian<12>; DiffScalarBase::setVariableCount(12); - const auto x = slice_positions((Vector12d() << ea0, ea1, eb0, eb1).finished()); - BENCHMARK("AutoDiff Hessian") { - line_line_closest_point_direction(x.row(0), x.row(1), x.row(2), x.row(3)); + const auto x = slice_positions( + (Vector12d() << ea0, ea1, eb0, eb1).finished()); + BENCHMARK("AutoDiff Hessian") + { + line_line_closest_point_direction( + x.row(0), x.row(1), x.row(2), x.row(3)); }; - BENCHMARK("Hessian") { + BENCHMARK("Hessian") + { line_line_closest_point_direction_hessian(ea0, ea1, eb0, eb1); }; } -TEST_CASE("Line-line closest point pairs gradient", "[distance][line-line][gradient]") +TEST_CASE( + "Line-line closest point pairs gradient", "[distance][line-line][gradient]") { double ya = GENERATE(take(10, random(-10.0, 10.0))); Eigen::Vector3d ea0(-1, ya, 0), ea1(1, ya, 0); @@ -123,24 +130,29 @@ TEST_CASE("Line-line closest point pairs gradient", "[distance][line-line][gradi using T = ADGrad<12>; DiffScalarBase::setVariableCount(12); - const auto x = slice_positions((Vector12d() << ea0, ea1, eb0, eb1).finished()); - auto yAD = line_line_closest_point_pairs(x.row(0), x.row(1), x.row(2), x.row(3)); + const auto x = slice_positions( + (Vector12d() << ea0, ea1, eb0, eb1).finished()); + auto yAD = line_line_closest_point_pairs( + x.row(0), x.row(1), x.row(2), x.row(3)); auto [y, grad] = line_line_closest_point_pairs_gradient(ea0, ea1, eb0, eb1); - for (int i = 0; i < yAD.size(); i++) - { + for (int i = 0; i < yAD.size(); i++) { REQUIRE((yAD(i).getValue() - y(i)) < 1e-8); - REQUIRE((yAD(i).getGradient() - grad.row(i).transpose()).norm() < 1e-6 * grad.row(i).norm()); + REQUIRE( + (yAD(i).getGradient() - grad.row(i).transpose()).norm() + < 1e-6 * grad.row(i).norm()); } // BENCHMARK("AutoDiff Gradient") { - // line_line_closest_point_pairs(x.row(0), x.row(1), x.row(2), x.row(3)); + // line_line_closest_point_pairs(x.row(0), x.row(1), x.row(2), + // x.row(3)); // }; // BENCHMARK("Gradient") { // line_line_closest_point_pairs_gradient(ea0, ea1, eb0, eb1); // }; } -TEST_CASE("Line-line closest point pairs hessian", "[distance][line-line][hessian]") +TEST_CASE( + "Line-line closest point pairs hessian", "[distance][line-line][hessian]") { double ya = GENERATE(take(10, random(-10.0, 10.0))); Eigen::Vector3d ea0(-1, ya, 0.05), ea1(1, ya, 0); @@ -150,18 +162,23 @@ TEST_CASE("Line-line closest point pairs hessian", "[distance][line-line][hessia using T = ADHessian<12>; DiffScalarBase::setVariableCount(12); - const auto x = slice_positions((Vector12d() << ea0, ea1, eb0, eb1).finished()); - auto yAD = line_line_closest_point_pairs(x.row(0), x.row(1), x.row(2), x.row(3)); - auto [y, grad, hess] = line_line_closest_point_pairs_hessian(ea0, ea1, eb0, eb1); - for (int i = 0; i < yAD.size(); i++) - { + const auto x = slice_positions( + (Vector12d() << ea0, ea1, eb0, eb1).finished()); + auto yAD = line_line_closest_point_pairs( + x.row(0), x.row(1), x.row(2), x.row(3)); + auto [y, grad, hess] = + line_line_closest_point_pairs_hessian(ea0, ea1, eb0, eb1); + for (int i = 0; i < yAD.size(); i++) { REQUIRE((yAD(i).getValue() - y(i)) < 1e-8); - REQUIRE((yAD(i).getGradient() - grad.row(i).transpose()).norm() < 1e-8 * grad.row(i).norm()); + REQUIRE( + (yAD(i).getGradient() - grad.row(i).transpose()).norm() + < 1e-8 * grad.row(i).norm()); REQUIRE((yAD(i).getHessian() - hess[i]).norm() < 1e-8 * hess[i].norm()); } // BENCHMARK("AutoDiff Hessian") { - // line_line_closest_point_pairs(x.row(0), x.row(1), x.row(2), x.row(3)); + // line_line_closest_point_pairs(x.row(0), x.row(1), x.row(2), + // x.row(3)); // }; // BENCHMARK("Hessian") { // line_line_closest_point_pairs_hessian(ea0, ea1, eb0, eb1); diff --git a/tests/src/tests/distance/test_point_line.cpp b/tests/src/tests/distance/test_point_line.cpp index 6684235d7..2ce27e28b 100644 --- a/tests/src/tests/distance/test_point_line.cpp +++ b/tests/src/tests/distance/test_point_line.cpp @@ -158,7 +158,8 @@ TEST_CASE( CHECK(fd::compare_hessian(hess, fhess, 1e-2)); } -TEST_CASE("Point-line closest point pairs hessian", "[distance][point-line][hessian]") +TEST_CASE( + "Point-line closest point pairs hessian", "[distance][point-line][hessian]") { double ya = GENERATE(take(2, random(-10.0, 10.0))); Eigen::Vector3d p(1, ya, 0); @@ -168,20 +169,28 @@ TEST_CASE("Point-line closest point pairs hessian", "[distance][point-line][hess using T = ADHessian<9>; DiffScalarBase::setVariableCount(9); - const auto x = slice_positions((Vector9d() << p, eb0, eb1).finished()); - auto yAD = PointEdgeDistance::point_line_closest_point_direction(x.row(0), x.row(1), x.row(2)); - auto [y, grad, hess] = PointEdgeDistanceDerivatives<3>::point_line_closest_point_direction_hessian(p, eb0, eb1); - for (int i = 0; i < yAD.size(); i++) - { + const auto x = + slice_positions((Vector9d() << p, eb0, eb1).finished()); + auto yAD = PointEdgeDistance::point_line_closest_point_direction( + x.row(0), x.row(1), x.row(2)); + auto [y, grad, hess] = PointEdgeDistanceDerivatives< + 3>::point_line_closest_point_direction_hessian(p, eb0, eb1); + for (int i = 0; i < yAD.size(); i++) { REQUIRE((yAD(i).getValue() - y(i)) < 1e-8); - REQUIRE((yAD(i).getGradient() - grad.row(i).transpose()).norm() < 1e-8 * grad.row(i).norm()); + REQUIRE( + (yAD(i).getGradient() - grad.row(i).transpose()).norm() + < 1e-8 * grad.row(i).norm()); REQUIRE((yAD(i).getHessian() - hess[i]).norm() < 1e-8 * hess[i].norm()); } - BENCHMARK("AutoDiff Hessian") { - PointEdgeDistance::point_line_closest_point_direction(x.row(0), x.row(1), x.row(2)); + BENCHMARK("AutoDiff Hessian") + { + PointEdgeDistance::point_line_closest_point_direction( + x.row(0), x.row(1), x.row(2)); }; - BENCHMARK("Hessian") { - PointEdgeDistanceDerivatives<3>::point_line_closest_point_direction_hessian(p, eb0, eb1); + BENCHMARK("Hessian") + { + PointEdgeDistanceDerivatives< + 3>::point_line_closest_point_direction_hessian(p, eb0, eb1); }; } diff --git a/tests/src/tests/distance/test_point_triangle.cpp b/tests/src/tests/distance/test_point_triangle.cpp index 51731827b..65c9a9c65 100644 --- a/tests/src/tests/distance/test_point_triangle.cpp +++ b/tests/src/tests/distance/test_point_triangle.cpp @@ -268,7 +268,9 @@ TEST_CASE("Point-triangle distance hessian", "[distance][point-triangle][hess]") CHECK(fd::compare_hessian(hess, fhess, 1e-2)); } -TEST_CASE("Point-triangle closest direction gradient", "[distance][point-triangle][grad]") +TEST_CASE( + "Point-triangle closest direction gradient", + "[distance][point-triangle][grad]") { double py = GENERATE(-10, -1, -1e-5, 0, 1e-5, 1, 10); Eigen::Vector3d p(0, py, 0); @@ -338,7 +340,8 @@ TEST_CASE("Point-triangle closest direction gradient", "[distance][point-triangl Vector12d x; x << p, t0, t1, t2; - const auto [vec, grad, hess] = point_triangle_closest_point_direction_hessian(p, t0, t1, t2, dtype); + const auto [vec, grad, hess] = + point_triangle_closest_point_direction_hessian(p, t0, t1, t2, dtype); // Compute the gradient using finite differences Eigen::MatrixXd fjac; @@ -346,21 +349,22 @@ TEST_CASE("Point-triangle closest direction gradient", "[distance][point-triangl x, [dtype](const Eigen::VectorXd& _x) { return point_triangle_closest_point_direction( - _x.segment<3>(0), _x.segment<3>(3), _x.segment<3>(6), _x.segment<3>(9), dtype); + _x.segment<3>(0), _x.segment<3>(3), _x.segment<3>(6), + _x.segment<3>(9), dtype); }, fjac); - + std::array grad_fjac; - for (int i = 0; i < 3; i++) - { + for (int i = 0; i < 3; i++) { fd::finite_hessian( x, [dtype, i](const Eigen::VectorXd& _x) { return point_triangle_closest_point_direction( - _x.segment<3>(0), _x.segment<3>(3), _x.segment<3>(6), _x.segment<3>(9), dtype)(i); + _x.segment<3>(0), _x.segment<3>(3), _x.segment<3>(6), + _x.segment<3>(9), dtype)(i); }, grad_fjac[i]); - + CHECK(fd::compare_jacobian(grad_fjac[i], hess[i], 1e-5)); } diff --git a/tests/src/tests/friction/friction_data_generator.cpp b/tests/src/tests/friction/friction_data_generator.cpp index 6d5cd3c41..41dd0812e 100644 --- a/tests/src/tests/friction/friction_data_generator.cpp +++ b/tests/src/tests/friction/friction_data_generator.cpp @@ -149,9 +149,9 @@ FrictionData friction_data_generator() using namespace ipc; -SmoothFrictionData<3> smooth_friction_data_generator_3d() +SmoothFrictionData smooth_friction_data_generator_3d() { - SmoothFrictionData<3> data; + SmoothFrictionData data; auto& [V0, V1, E, F, collisions, mu, epsv_times_h, param, barrier_stiffness] = data; @@ -165,7 +165,7 @@ SmoothFrictionData<3> smooth_friction_data_generator_3d() barrier_stiffness = 1.; #else epsv_times_h = 1.; // pow(10, GENERATE(range(-6, 0, 2))); - dhat = 1e-1; // pow(10, GENERATE(range(-4, 0, 2))); + dhat = 1e-2; // pow(10, GENERATE(range(-4, 0, 2))); barrier_stiffness = 1.; // 100; #endif @@ -197,8 +197,7 @@ SmoothFrictionData<3> smooth_friction_data_generator_3d() CollisionMesh mesh(V0, E, F); collisions.collisions.push_back( - std::make_shared< - SmoothCollisionTemplate>( + std::make_shared>( 0, 0, PointTriangleDistanceType::P_T, mesh, param, dhat, V0)); } SECTION("edge-edge") @@ -245,8 +244,7 @@ SmoothFrictionData<3> smooth_friction_data_generator_3d() CollisionMesh mesh(V0, E, F); collisions.collisions.push_back( - std::make_shared< - SmoothCollisionTemplate>( + std::make_shared>( e0, e1, EdgeEdgeDistanceType::EA_EB, mesh, param, dhat, V0)); } SECTION("point-edge") @@ -282,8 +280,7 @@ SmoothFrictionData<3> smooth_friction_data_generator_3d() CollisionMesh mesh(V0, E, F); collisions.collisions.push_back( - std::make_shared< - SmoothCollisionTemplate>( + std::make_shared>( e, 0, PointEdgeDistanceType::AUTO, mesh, param, dhat, V0)); } SECTION("point-point") @@ -308,17 +305,16 @@ SmoothFrictionData<3> smooth_friction_data_generator_3d() CollisionMesh mesh(V0, E, F); collisions.collisions.push_back( - std::make_shared< - SmoothCollisionTemplate>( + std::make_shared>( 0, 1, PointPointDistanceType::AUTO, mesh, param, dhat, V0)); } return data; } -SmoothFrictionData<2> smooth_friction_data_generator_2d() +SmoothFrictionData smooth_friction_data_generator_2d() { - SmoothFrictionData<2> data; + SmoothFrictionData data; auto& [V0, V1, E, F, collisions, mu, epsv_times_h, param, barrier_stiffness] = data; @@ -366,8 +362,7 @@ SmoothFrictionData<2> smooth_friction_data_generator_2d() CollisionMesh mesh(V0, E, F); collisions.collisions.push_back( - std::make_shared< - SmoothCollisionTemplate>( + std::make_shared>( e, 0, PointEdgeDistanceType::AUTO, mesh, param, dhat, V0)); } SECTION("point-point 2D") @@ -390,8 +385,7 @@ SmoothFrictionData<2> smooth_friction_data_generator_2d() CollisionMesh mesh(V0, E, F); collisions.collisions.push_back( - std::make_shared< - SmoothCollisionTemplate>( + std::make_shared>( 0, 1, PointPointDistanceType::AUTO, mesh, param, dhat, V0)); } diff --git a/tests/src/tests/friction/friction_data_generator.hpp b/tests/src/tests/friction/friction_data_generator.hpp index dfd367920..7a1b7a37c 100644 --- a/tests/src/tests/friction/friction_data_generator.hpp +++ b/tests/src/tests/friction/friction_data_generator.hpp @@ -22,17 +22,17 @@ Eigen::VectorXd GeomSpaced(int num, double start, double stop); FrictionData friction_data_generator(); -template struct SmoothFrictionData { +struct SmoothFrictionData { Eigen::MatrixXd V0; Eigen::MatrixXd V1; Eigen::MatrixXi E; Eigen::MatrixXi F; - ipc::SmoothCollisions collisions; + ipc::SmoothCollisions collisions; double mu; double epsv_times_h; ipc::ParameterType p; double barrier_stiffness; }; -SmoothFrictionData<2> smooth_friction_data_generator_2d(); -SmoothFrictionData<3> smooth_friction_data_generator_3d(); +SmoothFrictionData smooth_friction_data_generator_2d(); +SmoothFrictionData smooth_friction_data_generator_3d(); diff --git a/tests/src/tests/friction/test_force_jacobian.cpp b/tests/src/tests/friction/test_force_jacobian.cpp index 101844e1c..906f13527 100644 --- a/tests/src/tests/friction/test_force_jacobian.cpp +++ b/tests/src/tests/friction/test_force_jacobian.cpp @@ -318,7 +318,8 @@ TEST_CASE( std::vector is_on_surface = CollisionMesh::construct_is_on_surface(X.rows(), E); - CollisionMesh mesh(is_on_surface, std::vector(X.rows(), false), X, E, F); + CollisionMesh mesh( + is_on_surface, std::vector(X.rows(), false), X, E, F); mesh.init_area_jacobians(); X = mesh.vertices(X); @@ -344,18 +345,18 @@ TEST_CASE( mesh, Ut, U, collisions, mu, epsv_dt, dhat, kappa, true); } -template void check_smooth_friction_force_jacobian( const CollisionMesh& mesh, const Eigen::MatrixXd& Ut, const Eigen::MatrixXd& U, - const SmoothCollisions& collisions, + const SmoothCollisions& collisions, const double mu, const double epsv_times_h, const ParameterType& params, const double barrier_stiffness, const bool recompute_collisions) { + const int dim = mesh.dim(); const double dhat = params.dhat; const Eigen::MatrixXd& X = mesh.rest_positions(); double distance_t0 = collisions.compute_minimum_distance(mesh, X + Ut); @@ -370,7 +371,7 @@ void check_smooth_friction_force_jacobian( CAPTURE(mu, epsv_times_h, dhat, barrier_stiffness, collisions.size()); TangentialCollisions friction_collisions; - friction_collisions.build_for_smooth_contact( + friction_collisions.build_for_smooth_contact( mesh, X + Ut, collisions, params, barrier_stiffness, Eigen::VectorXd::Ones(mesh.num_vertices()) * mu); CHECK(friction_collisions.size()); @@ -415,64 +416,58 @@ void check_smooth_friction_force_jacobian( /////////////////////////////////////////////////////////////////////////// - auto create_smooth_collision = - [&](const CollisionMesh& fd_mesh, - const Eigen::MatrixXd& fd_lagged_positions) { - SmoothCollisions fd_collisions; - assert(friction_collisions.size() == 1); - - if constexpr (dim == 3) { - auto cc = friction_collisions[0].smooth_collision_3d; - - std::shared_ptr> fd_cc; - if (cc->type() == CollisionType::EdgeEdge) - fd_cc = std::make_shared< - SmoothCollisionTemplate>( - (*cc)[0], (*cc)[1], - PrimitiveDistType::type::AUTO, fd_mesh, - params, dhat, fd_lagged_positions); - else if (cc->type() == CollisionType::EdgeVertex) - fd_cc = std::make_shared< - SmoothCollisionTemplate>( + auto create_smooth_collision = [&](const CollisionMesh& fd_mesh, + const Eigen::MatrixXd& + fd_lagged_positions) { + SmoothCollisions fd_collisions; + assert(friction_collisions.size() == 1); + + auto cc = friction_collisions[0].smooth_collision; + std::shared_ptr fd_cc; + if (dim == 3) { + if (cc->type() == CollisionType::EdgeEdge) + fd_cc = std::make_shared>( + (*cc)[0], (*cc)[1], + PrimitiveDistType::type::AUTO, fd_mesh, + params, dhat, fd_lagged_positions); + else if (cc->type() == CollisionType::EdgeVertex) + fd_cc = + std::make_shared>( (*cc)[0], (*cc)[1], PrimitiveDistType::type::AUTO, fd_mesh, params, dhat, fd_lagged_positions); - else if (cc->type() == CollisionType::VertexVertex) - fd_cc = std::make_shared< - SmoothCollisionTemplate>( + else if (cc->type() == CollisionType::VertexVertex) + fd_cc = + std::make_shared>( (*cc)[0], (*cc)[1], PrimitiveDistType::type::AUTO, fd_mesh, params, dhat, fd_lagged_positions); - else if (cc->type() == CollisionType::FaceVertex) - fd_cc = std::make_shared< - SmoothCollisionTemplate>( - (*cc)[0], (*cc)[1], - PrimitiveDistType::type::AUTO, fd_mesh, - params, dhat, fd_lagged_positions); + else if (cc->type() == CollisionType::FaceVertex) + fd_cc = std::make_shared>( + (*cc)[0], (*cc)[1], + PrimitiveDistType::type::AUTO, fd_mesh, + params, dhat, fd_lagged_positions); - fd_collisions.collisions.push_back(fd_cc); - } else { - auto cc = friction_collisions[0].smooth_collision_2d; - - std::shared_ptr> fd_cc; - if (cc->type() == CollisionType::EdgeVertex) - fd_cc = std::make_shared< - SmoothCollisionTemplate>( + fd_collisions.collisions.push_back(fd_cc); + } else { + if (cc->type() == CollisionType::EdgeVertex) + fd_cc = + std::make_shared>( (*cc)[0], (*cc)[1], PrimitiveDistType::type::AUTO, fd_mesh, params, dhat, fd_lagged_positions); - else if (cc->type() == CollisionType::VertexVertex) - fd_cc = std::make_shared< - SmoothCollisionTemplate>( + else if (cc->type() == CollisionType::VertexVertex) + fd_cc = + std::make_shared>( (*cc)[0], (*cc)[1], PrimitiveDistType::type::AUTO, fd_mesh, params, dhat, fd_lagged_positions); - fd_collisions.collisions.push_back(fd_cc); - } + fd_collisions.collisions.push_back(fd_cc); + } - return fd_collisions; - }; + return fd_collisions; + }; /////////////////////////////////////////////////////////////////////////// @@ -483,7 +478,7 @@ void check_smooth_friction_force_jacobian( // Eigen::VectorXd::Zero(X.size()); // { // auto cc = create_smooth_collision(mesh, lagged_positions); - // SmoothContactPotential> potential(params); + // SmoothContactPotential potential(params); // Eigen::VectorXd g = potential.gradient(cc, mesh, // lagged_positions); Eigen::SparseMatrix h = // potential.hessian(cc, mesh, lagged_positions); @@ -499,7 +494,7 @@ void check_smooth_friction_force_jacobian( // auto fd_cc = create_smooth_collision(fd_mesh, // fd_lagged_positions); - // SmoothContactPotential> potential(params); + // SmoothContactPotential potential(params); // return potential.gradient(fd_cc, fd_mesh, // fd_lagged_positions).norm(); // }; @@ -522,11 +517,11 @@ void check_smooth_friction_force_jacobian( CollisionMesh fd_mesh(fd_X, mesh.edges(), mesh.faces()); - SmoothCollisions fd_collisions = + auto fd_collisions = create_smooth_collision(fd_mesh, fd_lagged_positions); TangentialCollisions fd_friction_collisions; - fd_friction_collisions.build_for_smooth_contact( + fd_friction_collisions.build_for_smooth_contact( fd_mesh, fd_lagged_positions, fd_collisions, params, barrier_stiffness, Eigen::VectorXd::Ones(mesh.num_vertices()) * mu); @@ -555,11 +550,10 @@ void check_smooth_friction_force_jacobian( Eigen::MatrixXd fd_Ut = fd::unflatten(ut, Ut.cols()); Eigen::MatrixXd fd_lagged_positions = X + fd_Ut; - SmoothCollisions fd_collisions = - create_smooth_collision(mesh, fd_lagged_positions); + auto fd_collisions = create_smooth_collision(mesh, fd_lagged_positions); TangentialCollisions fd_friction_collisions; - fd_friction_collisions.build_for_smooth_contact( + fd_friction_collisions.build_for_smooth_contact( mesh, fd_lagged_positions, fd_collisions, params, barrier_stiffness, Eigen::VectorXd::Ones(mesh.num_vertices()) * mu); @@ -601,7 +595,7 @@ void check_smooth_friction_force_jacobian( TEST_CASE( "Smooth friction force jacobian 2D", "[friction-smooth][force-jacobian]") { - SmoothFrictionData<2> data = smooth_friction_data_generator_2d(); + SmoothFrictionData data = smooth_friction_data_generator_2d(); const auto& [V0, V1, E, F, collisions, mu, epsv_times_h, param, barrier_stiffness] = data; @@ -612,7 +606,7 @@ TEST_CASE( CollisionMesh mesh(X, E, F); - check_smooth_friction_force_jacobian<2>( + check_smooth_friction_force_jacobian( mesh, Ut, U, collisions, mu, epsv_times_h, param, barrier_stiffness, false); } @@ -620,7 +614,11 @@ TEST_CASE( TEST_CASE( "Smooth friction force jacobian 3D", "[friction-smooth][force-jacobian]") { - SmoothFrictionData<3> data = smooth_friction_data_generator_3d(); +#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && !defined(NDEBUG) + SKIP("'Smooth friction force jacobian 3D' test is skipped in debug mode"); +#endif + + SmoothFrictionData data = smooth_friction_data_generator_3d(); const auto& [V0, V1, E, F, collisions, mu, epsv_times_h, param, barrier_stiffness] = data; @@ -631,7 +629,7 @@ TEST_CASE( CollisionMesh mesh(X, E, F); - check_smooth_friction_force_jacobian<3>( + check_smooth_friction_force_jacobian( mesh, Ut, U, collisions, mu, epsv_times_h, param, barrier_stiffness, false); } \ No newline at end of file diff --git a/tests/src/tests/potential/test_new.cpp b/tests/src/tests/potential/test_new.cpp index 78f7423ed..2e797cd94 100644 --- a/tests/src/tests/potential/test_new.cpp +++ b/tests/src/tests/potential/test_new.cpp @@ -18,8 +18,6 @@ #include #include -#include - using namespace ipc; // TEST_CASE( diff --git a/tests/src/tests/potential/test_smooth_potential.cpp b/tests/src/tests/potential/test_smooth_potential.cpp index fc68e8719..5b9b542f7 100644 --- a/tests/src/tests/potential/test_smooth_potential.cpp +++ b/tests/src/tests/potential/test_smooth_potential.cpp @@ -72,7 +72,7 @@ std::string tagsopt = "[.][smooth_potential]"; // } // { -// SmoothCollisions<3> collisions; +// SmoothCollisions collisions; // ParameterType param(dhat, 0.8, 0, 1, 0, 2); // collisions.build(mesh, vertices, param, false, method); @@ -82,7 +82,7 @@ std::string tagsopt = "[.][smooth_potential]"; // } // { -// SmoothCollisions<3> collisions; +// SmoothCollisions collisions; // ParameterType param(dhat, 1, 0, 0, 0.1, 2); // collisions.build(mesh, vertices, param, false, method); @@ -92,7 +92,7 @@ std::string tagsopt = "[.][smooth_potential]"; // } // { -// SmoothCollisions<3> collisions; +// SmoothCollisions collisions; // ParameterType param(dhat, 0.8, 0, 0, 0.1, 2); // collisions.build(mesh, vertices, param, false, method); @@ -165,7 +165,7 @@ TEST_CASE("Smooth barrier potential full gradient and hessian 3D", tagsopt) CollisionMesh mesh; - SmoothCollisions<3> collisions; + SmoothCollisions collisions; if (all_vertices_on_surface) { mesh = CollisionMesh(vertices, edges, faces); } else { @@ -181,7 +181,7 @@ TEST_CASE("Smooth barrier potential full gradient and hessian 3D", tagsopt) CHECK(collisions.size() > 0); CHECK(!has_intersections(mesh, vertices)); - SmoothContactPotential> potential(param); + SmoothContactPotential potential(param); std::cout << "energy: " << potential(collisions, mesh, vertices) << "\n"; // ------------------------------------------------------------------------- @@ -259,7 +259,7 @@ TEST_CASE("Smooth barrier potential real sim 2D C^2", "[smooth_potential]") CollisionMesh mesh; ParameterType param(dhat, 0.9, -0.05, 0.95, 0.05, 1); param.set_adaptive_dhat_ratio(min_dist_ratio); - SmoothCollisions<2> collisions; + SmoothCollisions collisions; mesh = CollisionMesh(vertices, edges, faces); collisions.compute_adaptive_dhat(mesh, vertices, param, method); collisions.build(mesh, vertices, param, adaptive_dhat, method); @@ -270,7 +270,7 @@ TEST_CASE("Smooth barrier potential real sim 2D C^2", "[smooth_potential]") CHECK(!has_intersections(mesh, vertices)); - SmoothContactPotential> potential(param); + SmoothContactPotential potential(param); std::cout << "energy: " << potential(collisions, mesh, vertices) << "\n"; // ------------------------------------------------------------------------- @@ -347,7 +347,7 @@ TEST_CASE("Smooth barrier potential real sim 2D C^1", "[smooth_potential]") CollisionMesh mesh; ParameterType param(dhat, 0.9, -0.05, 0.95, 0.05, 1); param.set_adaptive_dhat_ratio(min_dist_ratio); - SmoothCollisions<2> collisions; + SmoothCollisions collisions; mesh = CollisionMesh(vertices, edges, faces); collisions.compute_adaptive_dhat(mesh, vertices, param, method); collisions.build(mesh, vertices, param, adaptive_dhat, method); @@ -358,7 +358,7 @@ TEST_CASE("Smooth barrier potential real sim 2D C^1", "[smooth_potential]") CHECK(!has_intersections(mesh, vertices)); - SmoothContactPotential> potential(param); + SmoothContactPotential potential(param); std::cout << "energy: " << potential(collisions, mesh, vertices) << "\n"; // ------------------------------------------------------------------------- @@ -449,7 +449,7 @@ TEST_CASE("Smooth barrier potential real sim 2D C^1", "[smooth_potential]") // { // igl::Timer timer; // timer.start(); -// SmoothCollisions<3> collisions; +// SmoothCollisions collisions; // ParameterType param(dhat, 0.8, 0, 0, 0.1, 2); // collisions.build(mesh, vertices, param, false, method); @@ -461,7 +461,7 @@ TEST_CASE("Smooth barrier potential real sim 2D C^1", "[smooth_potential]") // std::cout << "OIPC build time " << timer.getElapsedTime() << " s\n"; // timer.start(); -// SmoothContactPotential> potential(param); +// SmoothContactPotential potential(param); // const Eigen::VectorXd grad_b = // potential.gradient(collisions, mesh, vertices); diff --git a/tests/src/tests/utils/test_quadrature.cpp b/tests/src/tests/utils/test_quadrature.cpp index 04e3dbc5b..baa029e8e 100644 --- a/tests/src/tests/utils/test_quadrature.cpp +++ b/tests/src/tests/utils/test_quadrature.cpp @@ -12,11 +12,11 @@ TEST_CASE("Line Quadrature", "[quadrature]") { Eigen::VectorXd pts, weights; line_quadrature(N, pts, weights); - + const double a = 10.2, b = 3.4; Eigen::VectorXd ys = pts.array() * a + b; CHECK(ys.size() == N); - + const double quadrature = weights.dot(ys); const double analytic = 0.5 * a + b; CHECK(quadrature == Catch::Approx(analytic).margin(1e-12)); @@ -27,11 +27,11 @@ TEST_CASE("Triangle Quadrature", "[quadrature]") Eigen::Matrix pts; Eigen::VectorXd weights; triangle_quadrature(N, pts, weights); - + const double a = 10.2, b = 3.4, c = 1.2; Eigen::VectorXd ys = pts.col(0).array() * a + pts.col(1).array() * b + c; CHECK(ys.size() == (N * (N + 1) / 2)); - + const double quadrature = weights.dot(ys); const double analytic = a / 6.0 + b / 6.0 + c / 2.0; CHECK(quadrature == Catch::Approx(analytic).margin(1e-12));