warp-lang 0.9.0__py3-none-win_amd64.whl → 0.11.0__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of warp-lang might be problematic. Click here for more details.

Files changed (315) hide show
  1. warp/__init__.py +15 -7
  2. warp/__init__.pyi +1 -0
  3. warp/bin/warp-clang.dll +0 -0
  4. warp/bin/warp.dll +0 -0
  5. warp/build.py +22 -443
  6. warp/build_dll.py +384 -0
  7. warp/builtins.py +998 -488
  8. warp/codegen.py +1307 -739
  9. warp/config.py +5 -3
  10. warp/constants.py +6 -0
  11. warp/context.py +1291 -548
  12. warp/dlpack.py +31 -31
  13. warp/fabric.py +326 -0
  14. warp/fem/__init__.py +27 -0
  15. warp/fem/cache.py +389 -0
  16. warp/fem/dirichlet.py +181 -0
  17. warp/fem/domain.py +263 -0
  18. warp/fem/field/__init__.py +101 -0
  19. warp/fem/field/field.py +149 -0
  20. warp/fem/field/nodal_field.py +299 -0
  21. warp/fem/field/restriction.py +21 -0
  22. warp/fem/field/test.py +181 -0
  23. warp/fem/field/trial.py +183 -0
  24. warp/fem/geometry/__init__.py +19 -0
  25. warp/fem/geometry/closest_point.py +70 -0
  26. warp/fem/geometry/deformed_geometry.py +271 -0
  27. warp/fem/geometry/element.py +744 -0
  28. warp/fem/geometry/geometry.py +186 -0
  29. warp/fem/geometry/grid_2d.py +373 -0
  30. warp/fem/geometry/grid_3d.py +435 -0
  31. warp/fem/geometry/hexmesh.py +953 -0
  32. warp/fem/geometry/partition.py +376 -0
  33. warp/fem/geometry/quadmesh_2d.py +532 -0
  34. warp/fem/geometry/tetmesh.py +840 -0
  35. warp/fem/geometry/trimesh_2d.py +577 -0
  36. warp/fem/integrate.py +1616 -0
  37. warp/fem/operator.py +191 -0
  38. warp/fem/polynomial.py +213 -0
  39. warp/fem/quadrature/__init__.py +2 -0
  40. warp/fem/quadrature/pic_quadrature.py +245 -0
  41. warp/fem/quadrature/quadrature.py +294 -0
  42. warp/fem/space/__init__.py +292 -0
  43. warp/fem/space/basis_space.py +489 -0
  44. warp/fem/space/collocated_function_space.py +105 -0
  45. warp/fem/space/dof_mapper.py +236 -0
  46. warp/fem/space/function_space.py +145 -0
  47. warp/fem/space/grid_2d_function_space.py +267 -0
  48. warp/fem/space/grid_3d_function_space.py +306 -0
  49. warp/fem/space/hexmesh_function_space.py +352 -0
  50. warp/fem/space/partition.py +350 -0
  51. warp/fem/space/quadmesh_2d_function_space.py +369 -0
  52. warp/fem/space/restriction.py +160 -0
  53. warp/fem/space/shape/__init__.py +15 -0
  54. warp/fem/space/shape/cube_shape_function.py +738 -0
  55. warp/fem/space/shape/shape_function.py +103 -0
  56. warp/fem/space/shape/square_shape_function.py +611 -0
  57. warp/fem/space/shape/tet_shape_function.py +567 -0
  58. warp/fem/space/shape/triangle_shape_function.py +429 -0
  59. warp/fem/space/tetmesh_function_space.py +292 -0
  60. warp/fem/space/topology.py +295 -0
  61. warp/fem/space/trimesh_2d_function_space.py +221 -0
  62. warp/fem/types.py +77 -0
  63. warp/fem/utils.py +495 -0
  64. warp/native/array.h +164 -55
  65. warp/native/builtin.h +150 -174
  66. warp/native/bvh.cpp +75 -328
  67. warp/native/bvh.cu +406 -23
  68. warp/native/bvh.h +37 -45
  69. warp/native/clang/clang.cpp +136 -24
  70. warp/native/crt.cpp +1 -76
  71. warp/native/crt.h +111 -104
  72. warp/native/cuda_crt.h +1049 -0
  73. warp/native/cuda_util.cpp +15 -3
  74. warp/native/cuda_util.h +3 -1
  75. warp/native/cutlass/tools/library/scripts/conv2d_operation.py +463 -0
  76. warp/native/cutlass/tools/library/scripts/conv3d_operation.py +321 -0
  77. warp/native/cutlass/tools/library/scripts/gemm_operation.py +988 -0
  78. warp/native/cutlass/tools/library/scripts/generator.py +4625 -0
  79. warp/native/cutlass/tools/library/scripts/library.py +799 -0
  80. warp/native/cutlass/tools/library/scripts/manifest.py +402 -0
  81. warp/native/cutlass/tools/library/scripts/pycutlass/docs/source/conf.py +96 -0
  82. warp/native/cutlass/tools/library/scripts/pycutlass/profile/conv/conv2d_f16_sm80.py +106 -0
  83. warp/native/cutlass/tools/library/scripts/pycutlass/profile/gemm/gemm_f32_sm80.py +91 -0
  84. warp/native/cutlass/tools/library/scripts/pycutlass/setup.py +80 -0
  85. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/__init__.py +48 -0
  86. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/arguments.py +118 -0
  87. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/c_types.py +241 -0
  88. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/compiler.py +432 -0
  89. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/conv2d_operation.py +631 -0
  90. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/epilogue.py +1026 -0
  91. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/frontend.py +104 -0
  92. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/gemm_operation.py +1276 -0
  93. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/library.py +744 -0
  94. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/memory_manager.py +74 -0
  95. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/operation.py +110 -0
  96. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/parser.py +619 -0
  97. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/reduction_operation.py +398 -0
  98. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/tensor_ref.py +70 -0
  99. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/__init__.py +4 -0
  100. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/conv2d_testbed.py +646 -0
  101. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_grouped_testbed.py +235 -0
  102. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_testbed.py +557 -0
  103. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/profiler.py +70 -0
  104. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/type_hint.py +39 -0
  105. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/__init__.py +1 -0
  106. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/device.py +76 -0
  107. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/reference_model.py +255 -0
  108. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/__init__.py +0 -0
  109. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +201 -0
  110. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +177 -0
  111. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +98 -0
  112. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +95 -0
  113. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +163 -0
  114. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +187 -0
  115. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +309 -0
  116. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +54 -0
  117. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  118. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  119. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +253 -0
  120. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +97 -0
  121. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +242 -0
  122. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  123. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  124. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/run_all_tests.py +10 -0
  125. warp/native/cutlass/tools/library/scripts/pycutlass/test/frontend/test_frontend.py +146 -0
  126. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/__init__.py +0 -0
  127. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_bf16_sm80.py +96 -0
  128. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f16_sm80.py +447 -0
  129. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f32_sm80.py +146 -0
  130. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f64_sm80.py +102 -0
  131. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_grouped_sm80.py +203 -0
  132. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_s8_sm80.py +229 -0
  133. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/run_all_tests.py +9 -0
  134. warp/native/cutlass/tools/library/scripts/pycutlass/test/unit/test_sm80.py +453 -0
  135. warp/native/cutlass/tools/library/scripts/rank_2k_operation.py +398 -0
  136. warp/native/cutlass/tools/library/scripts/rank_k_operation.py +387 -0
  137. warp/native/cutlass/tools/library/scripts/rt.py +796 -0
  138. warp/native/cutlass/tools/library/scripts/symm_operation.py +400 -0
  139. warp/native/cutlass/tools/library/scripts/trmm_operation.py +407 -0
  140. warp/native/cutlass_gemm.cu +5 -3
  141. warp/native/exports.h +1240 -949
  142. warp/native/fabric.h +228 -0
  143. warp/native/hashgrid.cpp +4 -4
  144. warp/native/hashgrid.h +22 -2
  145. warp/native/initializer_array.h +2 -2
  146. warp/native/intersect.h +22 -7
  147. warp/native/intersect_adj.h +8 -8
  148. warp/native/intersect_tri.h +13 -16
  149. warp/native/marching.cu +157 -161
  150. warp/native/mat.h +119 -19
  151. warp/native/matnn.h +2 -2
  152. warp/native/mesh.cpp +108 -83
  153. warp/native/mesh.cu +243 -6
  154. warp/native/mesh.h +1547 -458
  155. warp/native/nanovdb/NanoVDB.h +1 -1
  156. warp/native/noise.h +272 -329
  157. warp/native/quat.h +51 -8
  158. warp/native/rand.h +45 -35
  159. warp/native/range.h +6 -2
  160. warp/native/reduce.cpp +157 -0
  161. warp/native/reduce.cu +348 -0
  162. warp/native/runlength_encode.cpp +62 -0
  163. warp/native/runlength_encode.cu +46 -0
  164. warp/native/scan.cu +11 -13
  165. warp/native/scan.h +1 -0
  166. warp/native/solid_angle.h +442 -0
  167. warp/native/sort.cpp +13 -0
  168. warp/native/sort.cu +9 -1
  169. warp/native/sparse.cpp +338 -0
  170. warp/native/sparse.cu +545 -0
  171. warp/native/spatial.h +2 -2
  172. warp/native/temp_buffer.h +30 -0
  173. warp/native/vec.h +126 -24
  174. warp/native/volume.h +120 -0
  175. warp/native/warp.cpp +658 -53
  176. warp/native/warp.cu +660 -68
  177. warp/native/warp.h +112 -12
  178. warp/optim/__init__.py +1 -0
  179. warp/optim/linear.py +922 -0
  180. warp/optim/sgd.py +92 -0
  181. warp/render/render_opengl.py +392 -152
  182. warp/render/render_usd.py +11 -11
  183. warp/sim/__init__.py +2 -2
  184. warp/sim/articulation.py +385 -185
  185. warp/sim/collide.py +21 -8
  186. warp/sim/import_mjcf.py +297 -106
  187. warp/sim/import_urdf.py +389 -210
  188. warp/sim/import_usd.py +198 -97
  189. warp/sim/inertia.py +17 -18
  190. warp/sim/integrator_euler.py +14 -8
  191. warp/sim/integrator_xpbd.py +161 -19
  192. warp/sim/model.py +795 -291
  193. warp/sim/optimizer.py +2 -6
  194. warp/sim/render.py +65 -3
  195. warp/sim/utils.py +3 -0
  196. warp/sparse.py +1227 -0
  197. warp/stubs.py +665 -223
  198. warp/tape.py +66 -15
  199. warp/tests/__main__.py +3 -6
  200. warp/tests/assets/curlnoise_golden.npy +0 -0
  201. warp/tests/assets/pnoise_golden.npy +0 -0
  202. warp/tests/assets/torus.usda +105 -105
  203. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  204. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  205. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  206. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  207. warp/tests/aux_test_unresolved_func.py +14 -0
  208. warp/tests/aux_test_unresolved_symbol.py +14 -0
  209. warp/tests/disabled_kinematics.py +239 -0
  210. warp/tests/run_coverage_serial.py +31 -0
  211. warp/tests/test_adam.py +103 -106
  212. warp/tests/test_arithmetic.py +128 -74
  213. warp/tests/test_array.py +1497 -211
  214. warp/tests/test_array_reduce.py +150 -0
  215. warp/tests/test_atomic.py +64 -28
  216. warp/tests/test_bool.py +99 -0
  217. warp/tests/test_builtins_resolution.py +1292 -0
  218. warp/tests/test_bvh.py +75 -43
  219. warp/tests/test_closest_point_edge_edge.py +54 -57
  220. warp/tests/test_codegen.py +233 -128
  221. warp/tests/test_compile_consts.py +28 -20
  222. warp/tests/test_conditional.py +108 -24
  223. warp/tests/test_copy.py +10 -12
  224. warp/tests/test_ctypes.py +112 -88
  225. warp/tests/test_dense.py +21 -14
  226. warp/tests/test_devices.py +98 -0
  227. warp/tests/test_dlpack.py +136 -108
  228. warp/tests/test_examples.py +277 -0
  229. warp/tests/test_fabricarray.py +955 -0
  230. warp/tests/test_fast_math.py +15 -11
  231. warp/tests/test_fem.py +1271 -0
  232. warp/tests/test_fp16.py +53 -19
  233. warp/tests/test_func.py +187 -74
  234. warp/tests/test_generics.py +194 -49
  235. warp/tests/test_grad.py +180 -116
  236. warp/tests/test_grad_customs.py +176 -0
  237. warp/tests/test_hash_grid.py +52 -37
  238. warp/tests/test_import.py +10 -23
  239. warp/tests/test_indexedarray.py +577 -24
  240. warp/tests/test_intersect.py +18 -9
  241. warp/tests/test_large.py +141 -0
  242. warp/tests/test_launch.py +251 -15
  243. warp/tests/test_lerp.py +64 -65
  244. warp/tests/test_linear_solvers.py +154 -0
  245. warp/tests/test_lvalue.py +493 -0
  246. warp/tests/test_marching_cubes.py +12 -13
  247. warp/tests/test_mat.py +508 -2778
  248. warp/tests/test_mat_lite.py +115 -0
  249. warp/tests/test_mat_scalar_ops.py +2889 -0
  250. warp/tests/test_math.py +103 -9
  251. warp/tests/test_matmul.py +305 -69
  252. warp/tests/test_matmul_lite.py +410 -0
  253. warp/tests/test_mesh.py +71 -14
  254. warp/tests/test_mesh_query_aabb.py +41 -25
  255. warp/tests/test_mesh_query_point.py +325 -34
  256. warp/tests/test_mesh_query_ray.py +39 -22
  257. warp/tests/test_mlp.py +30 -22
  258. warp/tests/test_model.py +92 -89
  259. warp/tests/test_modules_lite.py +39 -0
  260. warp/tests/test_multigpu.py +88 -114
  261. warp/tests/test_noise.py +12 -11
  262. warp/tests/test_operators.py +16 -20
  263. warp/tests/test_options.py +11 -11
  264. warp/tests/test_pinned.py +17 -18
  265. warp/tests/test_print.py +32 -11
  266. warp/tests/test_quat.py +275 -129
  267. warp/tests/test_rand.py +18 -16
  268. warp/tests/test_reload.py +38 -34
  269. warp/tests/test_rounding.py +50 -43
  270. warp/tests/test_runlength_encode.py +190 -0
  271. warp/tests/test_smoothstep.py +9 -11
  272. warp/tests/test_snippet.py +143 -0
  273. warp/tests/test_sparse.py +460 -0
  274. warp/tests/test_spatial.py +276 -243
  275. warp/tests/test_streams.py +110 -85
  276. warp/tests/test_struct.py +331 -85
  277. warp/tests/test_tape.py +39 -21
  278. warp/tests/test_torch.py +118 -89
  279. warp/tests/test_transient_module.py +12 -13
  280. warp/tests/test_types.py +614 -0
  281. warp/tests/test_utils.py +494 -0
  282. warp/tests/test_vec.py +354 -1987
  283. warp/tests/test_vec_lite.py +73 -0
  284. warp/tests/test_vec_scalar_ops.py +2099 -0
  285. warp/tests/test_volume.py +457 -293
  286. warp/tests/test_volume_write.py +124 -134
  287. warp/tests/unittest_serial.py +35 -0
  288. warp/tests/unittest_suites.py +341 -0
  289. warp/tests/unittest_utils.py +568 -0
  290. warp/tests/unused_test_misc.py +71 -0
  291. warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
  292. warp/thirdparty/appdirs.py +36 -45
  293. warp/thirdparty/unittest_parallel.py +549 -0
  294. warp/torch.py +72 -30
  295. warp/types.py +1744 -713
  296. warp/utils.py +360 -350
  297. warp_lang-0.11.0.dist-info/LICENSE.md +36 -0
  298. warp_lang-0.11.0.dist-info/METADATA +238 -0
  299. warp_lang-0.11.0.dist-info/RECORD +332 -0
  300. {warp_lang-0.9.0.dist-info → warp_lang-0.11.0.dist-info}/WHEEL +1 -1
  301. warp/bin/warp-clang.exp +0 -0
  302. warp/bin/warp-clang.lib +0 -0
  303. warp/bin/warp.exp +0 -0
  304. warp/bin/warp.lib +0 -0
  305. warp/tests/test_all.py +0 -215
  306. warp/tests/test_array_scan.py +0 -60
  307. warp/tests/test_base.py +0 -208
  308. warp/tests/test_unresolved_func.py +0 -7
  309. warp/tests/test_unresolved_symbol.py +0 -7
  310. warp_lang-0.9.0.dist-info/METADATA +0 -20
  311. warp_lang-0.9.0.dist-info/RECORD +0 -177
  312. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  313. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  314. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  315. {warp_lang-0.9.0.dist-info → warp_lang-0.11.0.dist-info}/top_level.txt +0 -0
@@ -135,8 +135,6 @@ def solve_particle_shape_contacts(
135
135
  body_delta: wp.array(dtype=wp.spatial_vector),
136
136
  ):
137
137
  tid = wp.tid()
138
- if (particle_flags[tid] & PARTICLE_FLAG_ACTIVE) == 0:
139
- return
140
138
 
141
139
  count = min(contact_max, contact_count[0])
142
140
  if tid >= count:
@@ -146,6 +144,9 @@ def solve_particle_shape_contacts(
146
144
  body_index = shape_body[shape_index]
147
145
  particle_index = contact_particle[tid]
148
146
 
147
+ if (particle_flags[particle_index] & PARTICLE_FLAG_ACTIVE) == 0:
148
+ return
149
+
149
150
  px = particle_x[particle_index]
150
151
  pv = particle_v[particle_index]
151
152
 
@@ -161,7 +162,7 @@ def solve_particle_shape_contacts(
161
162
  r = bx - wp.transform_point(X_wb, X_com)
162
163
 
163
164
  n = contact_normal[tid]
164
- c = wp.dot(n, px - bx) - particle_radius[tid]
165
+ c = wp.dot(n, px - bx) - particle_radius[particle_index]
165
166
 
166
167
  if c > particle_ka:
167
168
  return
@@ -249,7 +250,7 @@ def solve_particle_particle_contacts(
249
250
  # particle contact
250
251
  query = wp.hash_grid_query(grid, x, radius + max_radius + k_cohesion)
251
252
  index = int(0)
252
-
253
+
253
254
  delta = wp.vec3(0.0)
254
255
 
255
256
  while wp.hash_grid_query_next(query, index):
@@ -258,7 +259,7 @@ def solve_particle_particle_contacts(
258
259
  n = x - particle_x[index]
259
260
  d = wp.length(n)
260
261
  err = d - radius - particle_radius[index]
261
-
262
+
262
263
  # compute inverse masses
263
264
  w2 = particle_invmass[index]
264
265
  denom = w1 + w2
@@ -292,6 +293,7 @@ def solve_springs(
292
293
  spring_stiffness: wp.array(dtype=float),
293
294
  spring_damping: wp.array(dtype=float),
294
295
  dt: float,
296
+ lambdas: wp.array(dtype=float),
295
297
  delta: wp.array(dtype=wp.vec3),
296
298
  ):
297
299
  tid = wp.tid()
@@ -313,29 +315,135 @@ def solve_springs(
313
315
  vij = vi - vj
314
316
 
315
317
  l = wp.length(xij)
316
- l_inv = 1.0 / l
317
318
 
318
- # normalized spring direction
319
- dir = xij * l_inv
319
+ if l == 0.0:
320
+ return
320
321
 
321
- c = l - rest
322
- dcdt = wp.dot(dir, vij)
322
+ n = xij / l
323
323
 
324
- # damping based on relative velocity.
325
- # fs = dir * (ke * c + kd * dcdt)
324
+ c = l - rest
325
+ grad_c_xi = n
326
+ grad_c_xj = -1.0 * n
326
327
 
327
328
  wi = invmass[i]
328
329
  wj = invmass[j]
329
330
 
330
331
  denom = wi + wj
332
+
333
+ # Note strict inequality for damping -- 0 damping is ok
334
+ if denom <= 0.0 or ke <= 0.0 or kd < 0.0:
335
+ return
336
+
337
+ alpha= 1.0 / (ke * dt * dt)
338
+ gamma = kd / (ke * dt)
339
+
340
+ grad_c_dot_v = dt * wp.dot(grad_c_xi, vij) # Note: dt because from the paper we want x_i - x^n, not v...
341
+ dlambda = -1.0 * (c + alpha* lambdas[tid] + gamma * grad_c_dot_v) / ((1.0 + gamma) * denom + alpha)
342
+
343
+ dxi = wi * dlambda * grad_c_xi
344
+ dxj = wj * dlambda * grad_c_xj
345
+
346
+ lambdas[tid] = lambdas[tid] + dlambda
347
+
348
+ wp.atomic_add(delta, i, dxi)
349
+ wp.atomic_add(delta, j, dxj)
350
+
351
+
352
+ @wp.kernel
353
+ def bending_constraint(
354
+ x: wp.array(dtype=wp.vec3),
355
+ v: wp.array(dtype=wp.vec3),
356
+ invmass: wp.array(dtype=float),
357
+ indices: wp.array2d(dtype=int),
358
+ rest: wp.array(dtype=float),
359
+ bending_properties: wp.array2d(dtype=float),
360
+ dt: float,
361
+ lambdas: wp.array(dtype=float),
362
+ delta: wp.array(dtype=wp.vec3),
363
+ ):
364
+
365
+ tid = wp.tid()
366
+ eps = 1.0e-6
367
+
368
+ ke = bending_properties[tid, 0]
369
+ kd = bending_properties[tid, 1]
370
+
371
+ i = indices[tid, 0]
372
+ j = indices[tid, 1]
373
+ k = indices[tid, 2]
374
+ l = indices[tid, 3]
375
+
376
+ if i == -1 or j == -1 or k == -1 or l == -1:
377
+ return
378
+
379
+ rest_angle = rest[tid]
380
+
381
+ x1 = x[i]
382
+ x2 = x[j]
383
+ x3 = x[k]
384
+ x4 = x[l]
385
+
386
+ v1 = v[i]
387
+ v2 = v[j]
388
+ v3 = v[k]
389
+ v4 = v[l]
390
+
391
+ w1 = invmass[i]
392
+ w2 = invmass[j]
393
+ w3 = invmass[k]
394
+ w4 = invmass[l]
395
+
396
+ n1 = wp.cross(x3 - x1, x4 - x1) # normal to face 1
397
+ n2 = wp.cross(x4 - x2, x3 - x2) # normal to face 2
398
+
399
+ n1_length = wp.length(n1)
400
+ n2_length = wp.length(n2)
401
+
402
+ if n1_length < eps or n2_length < eps:
403
+ return
404
+
405
+ n1 /= n1_length
406
+ n2 /= n2_length
407
+
408
+ cos_theta = wp.dot(n1, n2)
409
+
410
+ e = x4 - x3
411
+ e_hat = wp.normalize(e)
412
+ e_length = wp.length(e)
413
+
414
+ derivative_flip = wp.sign(wp.dot(wp.cross(n1, n2), e))
415
+ derivative_flip *= -1.0
416
+ angle = wp.acos(cos_theta)
417
+
418
+ grad_x1 = n1 * e_length * derivative_flip
419
+ grad_x2 = n2 * e_length * derivative_flip
420
+ grad_x3 = (n1 * wp.dot(x1 - x4, e_hat) + n2 * wp.dot(x2 - x4, e_hat)) * derivative_flip
421
+ grad_x4 = (n1 * wp.dot(x3 - x1, e_hat) + n2 * wp.dot(x3 - x2, e_hat)) * derivative_flip
422
+ c = angle - rest_angle
423
+ denominator = (w1 * wp.length_sq(grad_x1) + w2 * wp.length_sq(grad_x2) + w3 * wp.length_sq(grad_x3) + w4 * wp.length_sq(grad_x4))
424
+
425
+ # Note strict inequality for damping -- 0 damping is ok
426
+ if denominator <= 0.0 or ke <= 0.0 or kd < 0.0:
427
+ return
428
+
331
429
  alpha = 1.0 / (ke * dt * dt)
430
+ gamma = kd / (ke * dt)
332
431
 
333
- multiplier = c / (denom) # + alpha)
432
+ grad_dot_v = dt * (wp.dot(grad_x1, v1) + wp.dot(grad_x2, v2) + wp.dot(grad_x3, v3) + wp.dot(grad_x4, v4))
334
433
 
335
- xd = dir * multiplier
434
+ dlambda = -1.0 * (c + alpha * lambdas[tid] + gamma * grad_dot_v) / ((1.0 + gamma) * denominator + alpha)
336
435
 
337
- wp.atomic_sub(delta, i, xd * wi)
338
- wp.atomic_add(delta, j, xd * wj)
436
+ delta0 = w1 * dlambda * grad_x1
437
+ delta1 = w2 * dlambda * grad_x2
438
+ delta2 = w3 * dlambda * grad_x3
439
+ delta3 = w4 * dlambda * grad_x4
440
+
441
+ lambdas[tid] = lambdas[tid] + dlambda
442
+
443
+ wp.atomic_add(delta, i, delta0)
444
+ wp.atomic_add(delta, j, delta1)
445
+ wp.atomic_add(delta, k, delta2)
446
+ wp.atomic_add(delta, l, delta3)
339
447
 
340
448
 
341
449
  @wp.kernel
@@ -495,6 +603,7 @@ def apply_particle_deltas(
495
603
  particle_flags: wp.array(dtype=wp.uint32),
496
604
  delta: wp.array(dtype=wp.vec3),
497
605
  dt: float,
606
+ v_max: float,
498
607
  x_out: wp.array(dtype=wp.vec3),
499
608
  v_out: wp.array(dtype=wp.vec3),
500
609
  ):
@@ -511,6 +620,11 @@ def apply_particle_deltas(
511
620
  x_new = xp + d
512
621
  v_new = (x_new - x0) / dt
513
622
 
623
+ # enforce velocity limit to prevent instability
624
+ v_new_mag = wp.length(v_new)
625
+ if v_new_mag > v_max:
626
+ v_new *= v_max / v_new_mag
627
+
514
628
  x_out[tid] = x_new
515
629
  v_out[tid] = v_new
516
630
 
@@ -1873,11 +1987,12 @@ class XPBDIntegrator:
1873
1987
  inputs=[
1874
1988
  state_in.particle_q,
1875
1989
  state_in.particle_qd,
1876
- state_out.particle_f,
1990
+ state_in.particle_f,
1877
1991
  model.particle_inv_mass,
1878
1992
  model.particle_flags,
1879
1993
  model.gravity,
1880
1994
  dt,
1995
+ model.particle_max_velocity,
1881
1996
  ],
1882
1997
  outputs=[particle_q, particle_qd],
1883
1998
  device=model.device,
@@ -1927,6 +2042,12 @@ class XPBDIntegrator:
1927
2042
  device=model.device,
1928
2043
  )
1929
2044
 
2045
+ if model.spring_count:
2046
+ model.spring_constraint_lambdas.zero_()
2047
+
2048
+ if model.edge_count:
2049
+ model.edge_constraint_lambdas.zero_()
2050
+
1930
2051
  for i in range(self.iterations):
1931
2052
  # print(f"### iteration {i} / {self.iterations-1}")
1932
2053
 
@@ -2009,7 +2130,7 @@ class XPBDIntegrator:
2009
2130
  outputs=[deltas, state_out.body_deltas],
2010
2131
  device=model.device,
2011
2132
  )
2012
-
2133
+
2013
2134
  if model.particle_max_radius > 0.0:
2014
2135
  wp.launch(
2015
2136
  kernel=solve_particle_particle_contacts,
@@ -2031,7 +2152,7 @@ class XPBDIntegrator:
2031
2152
  device=model.device,
2032
2153
  )
2033
2154
 
2034
- # damped springs
2155
+ # distance constraints
2035
2156
  if model.spring_count:
2036
2157
  wp.launch(
2037
2158
  kernel=solve_springs,
@@ -2045,6 +2166,26 @@ class XPBDIntegrator:
2045
2166
  model.spring_stiffness,
2046
2167
  model.spring_damping,
2047
2168
  dt,
2169
+ model.spring_constraint_lambdas,
2170
+ ],
2171
+ outputs=[deltas],
2172
+ device=model.device,
2173
+ )
2174
+
2175
+ # bending constraints
2176
+ if model.edge_count:
2177
+ wp.launch(
2178
+ kernel=bending_constraint,
2179
+ dim=model.edge_count,
2180
+ inputs=[
2181
+ particle_q,
2182
+ particle_qd,
2183
+ model.particle_inv_mass,
2184
+ model.edge_indices,
2185
+ model.edge_rest_angle,
2186
+ model.edge_bending_properties,
2187
+ dt,
2188
+ model.edge_constraint_lambdas,
2048
2189
  ],
2049
2190
  outputs=[deltas],
2050
2191
  device=model.device,
@@ -2087,6 +2228,7 @@ class XPBDIntegrator:
2087
2228
  model.particle_flags,
2088
2229
  deltas,
2089
2230
  dt,
2231
+ model.particle_max_velocity,
2090
2232
  ],
2091
2233
  outputs=[new_particle_q, new_particle_qd],
2092
2234
  device=model.device,