warp-lang 0.10.1__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 (300) hide show
  1. warp/__init__.py +10 -4
  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 +5 -3
  6. warp/build_dll.py +29 -9
  7. warp/builtins.py +868 -507
  8. warp/codegen.py +1074 -638
  9. warp/config.py +3 -3
  10. warp/constants.py +6 -0
  11. warp/context.py +715 -222
  12. warp/fabric.py +326 -0
  13. warp/fem/__init__.py +27 -0
  14. warp/fem/cache.py +389 -0
  15. warp/fem/dirichlet.py +181 -0
  16. warp/fem/domain.py +263 -0
  17. warp/fem/field/__init__.py +101 -0
  18. warp/fem/field/field.py +149 -0
  19. warp/fem/field/nodal_field.py +299 -0
  20. warp/fem/field/restriction.py +21 -0
  21. warp/fem/field/test.py +181 -0
  22. warp/fem/field/trial.py +183 -0
  23. warp/fem/geometry/__init__.py +19 -0
  24. warp/fem/geometry/closest_point.py +70 -0
  25. warp/fem/geometry/deformed_geometry.py +271 -0
  26. warp/fem/geometry/element.py +744 -0
  27. warp/fem/geometry/geometry.py +186 -0
  28. warp/fem/geometry/grid_2d.py +373 -0
  29. warp/fem/geometry/grid_3d.py +435 -0
  30. warp/fem/geometry/hexmesh.py +953 -0
  31. warp/fem/geometry/partition.py +376 -0
  32. warp/fem/geometry/quadmesh_2d.py +532 -0
  33. warp/fem/geometry/tetmesh.py +840 -0
  34. warp/fem/geometry/trimesh_2d.py +577 -0
  35. warp/fem/integrate.py +1616 -0
  36. warp/fem/operator.py +191 -0
  37. warp/fem/polynomial.py +213 -0
  38. warp/fem/quadrature/__init__.py +2 -0
  39. warp/fem/quadrature/pic_quadrature.py +245 -0
  40. warp/fem/quadrature/quadrature.py +294 -0
  41. warp/fem/space/__init__.py +292 -0
  42. warp/fem/space/basis_space.py +489 -0
  43. warp/fem/space/collocated_function_space.py +105 -0
  44. warp/fem/space/dof_mapper.py +236 -0
  45. warp/fem/space/function_space.py +145 -0
  46. warp/fem/space/grid_2d_function_space.py +267 -0
  47. warp/fem/space/grid_3d_function_space.py +306 -0
  48. warp/fem/space/hexmesh_function_space.py +352 -0
  49. warp/fem/space/partition.py +350 -0
  50. warp/fem/space/quadmesh_2d_function_space.py +369 -0
  51. warp/fem/space/restriction.py +160 -0
  52. warp/fem/space/shape/__init__.py +15 -0
  53. warp/fem/space/shape/cube_shape_function.py +738 -0
  54. warp/fem/space/shape/shape_function.py +103 -0
  55. warp/fem/space/shape/square_shape_function.py +611 -0
  56. warp/fem/space/shape/tet_shape_function.py +567 -0
  57. warp/fem/space/shape/triangle_shape_function.py +429 -0
  58. warp/fem/space/tetmesh_function_space.py +292 -0
  59. warp/fem/space/topology.py +295 -0
  60. warp/fem/space/trimesh_2d_function_space.py +221 -0
  61. warp/fem/types.py +77 -0
  62. warp/fem/utils.py +495 -0
  63. warp/native/array.h +147 -44
  64. warp/native/builtin.h +122 -149
  65. warp/native/bvh.cpp +73 -325
  66. warp/native/bvh.cu +406 -23
  67. warp/native/bvh.h +34 -43
  68. warp/native/clang/clang.cpp +13 -8
  69. warp/native/crt.h +2 -0
  70. warp/native/cuda_crt.h +5 -0
  71. warp/native/cuda_util.cpp +15 -3
  72. warp/native/cuda_util.h +3 -1
  73. warp/native/cutlass/tools/library/scripts/conv2d_operation.py +463 -0
  74. warp/native/cutlass/tools/library/scripts/conv3d_operation.py +321 -0
  75. warp/native/cutlass/tools/library/scripts/gemm_operation.py +988 -0
  76. warp/native/cutlass/tools/library/scripts/generator.py +4625 -0
  77. warp/native/cutlass/tools/library/scripts/library.py +799 -0
  78. warp/native/cutlass/tools/library/scripts/manifest.py +402 -0
  79. warp/native/cutlass/tools/library/scripts/pycutlass/docs/source/conf.py +96 -0
  80. warp/native/cutlass/tools/library/scripts/pycutlass/profile/conv/conv2d_f16_sm80.py +106 -0
  81. warp/native/cutlass/tools/library/scripts/pycutlass/profile/gemm/gemm_f32_sm80.py +91 -0
  82. warp/native/cutlass/tools/library/scripts/pycutlass/setup.py +80 -0
  83. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/__init__.py +48 -0
  84. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/arguments.py +118 -0
  85. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/c_types.py +241 -0
  86. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/compiler.py +432 -0
  87. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/conv2d_operation.py +631 -0
  88. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/epilogue.py +1026 -0
  89. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/frontend.py +104 -0
  90. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/gemm_operation.py +1276 -0
  91. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/library.py +744 -0
  92. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/memory_manager.py +74 -0
  93. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/operation.py +110 -0
  94. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/parser.py +619 -0
  95. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/reduction_operation.py +398 -0
  96. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/tensor_ref.py +70 -0
  97. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/__init__.py +4 -0
  98. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/conv2d_testbed.py +646 -0
  99. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_grouped_testbed.py +235 -0
  100. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_testbed.py +557 -0
  101. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/profiler.py +70 -0
  102. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/type_hint.py +39 -0
  103. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/__init__.py +1 -0
  104. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/device.py +76 -0
  105. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/reference_model.py +255 -0
  106. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/__init__.py +0 -0
  107. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +201 -0
  108. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +177 -0
  109. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +98 -0
  110. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +95 -0
  111. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +163 -0
  112. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +187 -0
  113. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +309 -0
  114. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +54 -0
  115. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  116. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  117. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +253 -0
  118. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +97 -0
  119. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +242 -0
  120. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  121. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  122. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/run_all_tests.py +10 -0
  123. warp/native/cutlass/tools/library/scripts/pycutlass/test/frontend/test_frontend.py +146 -0
  124. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/__init__.py +0 -0
  125. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_bf16_sm80.py +96 -0
  126. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f16_sm80.py +447 -0
  127. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f32_sm80.py +146 -0
  128. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f64_sm80.py +102 -0
  129. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_grouped_sm80.py +203 -0
  130. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_s8_sm80.py +229 -0
  131. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/run_all_tests.py +9 -0
  132. warp/native/cutlass/tools/library/scripts/pycutlass/test/unit/test_sm80.py +453 -0
  133. warp/native/cutlass/tools/library/scripts/rank_2k_operation.py +398 -0
  134. warp/native/cutlass/tools/library/scripts/rank_k_operation.py +387 -0
  135. warp/native/cutlass/tools/library/scripts/rt.py +796 -0
  136. warp/native/cutlass/tools/library/scripts/symm_operation.py +400 -0
  137. warp/native/cutlass/tools/library/scripts/trmm_operation.py +407 -0
  138. warp/native/cutlass_gemm.cu +5 -3
  139. warp/native/exports.h +1240 -952
  140. warp/native/fabric.h +228 -0
  141. warp/native/hashgrid.cpp +4 -4
  142. warp/native/hashgrid.h +22 -2
  143. warp/native/intersect.h +22 -7
  144. warp/native/intersect_adj.h +8 -8
  145. warp/native/intersect_tri.h +1 -1
  146. warp/native/marching.cu +157 -161
  147. warp/native/mat.h +80 -19
  148. warp/native/matnn.h +2 -2
  149. warp/native/mesh.cpp +33 -108
  150. warp/native/mesh.cu +114 -23
  151. warp/native/mesh.h +446 -46
  152. warp/native/noise.h +272 -329
  153. warp/native/quat.h +51 -8
  154. warp/native/rand.h +45 -35
  155. warp/native/range.h +6 -2
  156. warp/native/reduce.cpp +1 -1
  157. warp/native/reduce.cu +10 -12
  158. warp/native/runlength_encode.cu +6 -10
  159. warp/native/scan.cu +8 -11
  160. warp/native/sparse.cpp +4 -4
  161. warp/native/sparse.cu +164 -154
  162. warp/native/spatial.h +2 -2
  163. warp/native/temp_buffer.h +14 -30
  164. warp/native/vec.h +107 -23
  165. warp/native/volume.h +120 -0
  166. warp/native/warp.cpp +560 -30
  167. warp/native/warp.cu +431 -44
  168. warp/native/warp.h +13 -4
  169. warp/optim/__init__.py +1 -0
  170. warp/optim/linear.py +922 -0
  171. warp/optim/sgd.py +92 -0
  172. warp/render/render_opengl.py +335 -119
  173. warp/render/render_usd.py +11 -11
  174. warp/sim/__init__.py +2 -2
  175. warp/sim/articulation.py +385 -185
  176. warp/sim/collide.py +8 -0
  177. warp/sim/import_mjcf.py +297 -106
  178. warp/sim/import_urdf.py +389 -210
  179. warp/sim/import_usd.py +198 -97
  180. warp/sim/inertia.py +17 -18
  181. warp/sim/integrator_euler.py +14 -8
  182. warp/sim/integrator_xpbd.py +158 -16
  183. warp/sim/model.py +795 -291
  184. warp/sim/render.py +3 -3
  185. warp/sim/utils.py +3 -0
  186. warp/sparse.py +640 -150
  187. warp/stubs.py +606 -267
  188. warp/tape.py +61 -10
  189. warp/tests/__main__.py +3 -6
  190. warp/tests/assets/curlnoise_golden.npy +0 -0
  191. warp/tests/assets/pnoise_golden.npy +0 -0
  192. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  193. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  194. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  195. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  196. warp/tests/aux_test_unresolved_func.py +14 -0
  197. warp/tests/aux_test_unresolved_symbol.py +14 -0
  198. warp/tests/disabled_kinematics.py +239 -0
  199. warp/tests/run_coverage_serial.py +31 -0
  200. warp/tests/test_adam.py +103 -106
  201. warp/tests/test_arithmetic.py +128 -74
  202. warp/tests/test_array.py +212 -97
  203. warp/tests/test_array_reduce.py +57 -23
  204. warp/tests/test_atomic.py +64 -28
  205. warp/tests/test_bool.py +99 -0
  206. warp/tests/test_builtins_resolution.py +1292 -0
  207. warp/tests/test_bvh.py +42 -18
  208. warp/tests/test_closest_point_edge_edge.py +54 -57
  209. warp/tests/test_codegen.py +208 -130
  210. warp/tests/test_compile_consts.py +28 -20
  211. warp/tests/test_conditional.py +108 -24
  212. warp/tests/test_copy.py +10 -12
  213. warp/tests/test_ctypes.py +112 -88
  214. warp/tests/test_dense.py +21 -14
  215. warp/tests/test_devices.py +98 -0
  216. warp/tests/test_dlpack.py +75 -75
  217. warp/tests/test_examples.py +277 -0
  218. warp/tests/test_fabricarray.py +955 -0
  219. warp/tests/test_fast_math.py +15 -11
  220. warp/tests/test_fem.py +1271 -0
  221. warp/tests/test_fp16.py +53 -19
  222. warp/tests/test_func.py +187 -86
  223. warp/tests/test_generics.py +194 -49
  224. warp/tests/test_grad.py +178 -109
  225. warp/tests/test_grad_customs.py +176 -0
  226. warp/tests/test_hash_grid.py +52 -37
  227. warp/tests/test_import.py +10 -23
  228. warp/tests/test_indexedarray.py +32 -31
  229. warp/tests/test_intersect.py +18 -9
  230. warp/tests/test_large.py +141 -0
  231. warp/tests/test_launch.py +14 -41
  232. warp/tests/test_lerp.py +64 -65
  233. warp/tests/test_linear_solvers.py +154 -0
  234. warp/tests/test_lvalue.py +493 -0
  235. warp/tests/test_marching_cubes.py +12 -13
  236. warp/tests/test_mat.py +517 -2898
  237. warp/tests/test_mat_lite.py +115 -0
  238. warp/tests/test_mat_scalar_ops.py +2889 -0
  239. warp/tests/test_math.py +103 -9
  240. warp/tests/test_matmul.py +305 -69
  241. warp/tests/test_matmul_lite.py +410 -0
  242. warp/tests/test_mesh.py +71 -14
  243. warp/tests/test_mesh_query_aabb.py +41 -25
  244. warp/tests/test_mesh_query_point.py +140 -22
  245. warp/tests/test_mesh_query_ray.py +39 -22
  246. warp/tests/test_mlp.py +30 -22
  247. warp/tests/test_model.py +92 -89
  248. warp/tests/test_modules_lite.py +39 -0
  249. warp/tests/test_multigpu.py +88 -114
  250. warp/tests/test_noise.py +12 -11
  251. warp/tests/test_operators.py +16 -20
  252. warp/tests/test_options.py +11 -11
  253. warp/tests/test_pinned.py +17 -18
  254. warp/tests/test_print.py +32 -11
  255. warp/tests/test_quat.py +275 -129
  256. warp/tests/test_rand.py +18 -16
  257. warp/tests/test_reload.py +38 -34
  258. warp/tests/test_rounding.py +50 -43
  259. warp/tests/test_runlength_encode.py +168 -20
  260. warp/tests/test_smoothstep.py +9 -11
  261. warp/tests/test_snippet.py +143 -0
  262. warp/tests/test_sparse.py +261 -63
  263. warp/tests/test_spatial.py +276 -243
  264. warp/tests/test_streams.py +110 -85
  265. warp/tests/test_struct.py +268 -63
  266. warp/tests/test_tape.py +39 -21
  267. warp/tests/test_torch.py +118 -89
  268. warp/tests/test_transient_module.py +12 -13
  269. warp/tests/test_types.py +614 -0
  270. warp/tests/test_utils.py +494 -0
  271. warp/tests/test_vec.py +354 -2050
  272. warp/tests/test_vec_lite.py +73 -0
  273. warp/tests/test_vec_scalar_ops.py +2099 -0
  274. warp/tests/test_volume.py +457 -293
  275. warp/tests/test_volume_write.py +124 -134
  276. warp/tests/unittest_serial.py +35 -0
  277. warp/tests/unittest_suites.py +341 -0
  278. warp/tests/unittest_utils.py +568 -0
  279. warp/tests/unused_test_misc.py +71 -0
  280. warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
  281. warp/thirdparty/appdirs.py +36 -45
  282. warp/thirdparty/unittest_parallel.py +549 -0
  283. warp/torch.py +9 -6
  284. warp/types.py +1089 -366
  285. warp/utils.py +93 -387
  286. warp_lang-0.11.0.dist-info/METADATA +238 -0
  287. warp_lang-0.11.0.dist-info/RECORD +332 -0
  288. {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/WHEEL +1 -1
  289. warp/tests/test_all.py +0 -219
  290. warp/tests/test_array_scan.py +0 -60
  291. warp/tests/test_base.py +0 -208
  292. warp/tests/test_unresolved_func.py +0 -7
  293. warp/tests/test_unresolved_symbol.py +0 -7
  294. warp_lang-0.10.1.dist-info/METADATA +0 -21
  295. warp_lang-0.10.1.dist-info/RECORD +0 -188
  296. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  297. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  298. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  299. {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/LICENSE.md +0 -0
  300. {warp_lang-0.10.1.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
@@ -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)
431
+
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))
332
433
 
333
- multiplier = c / (denom) # + alpha)
434
+ dlambda = -1.0 * (c + alpha * lambdas[tid] + gamma * grad_dot_v) / ((1.0 + gamma) * denominator + alpha)
334
435
 
335
- xd = dir * multiplier
436
+ delta0 = w1 * dlambda * grad_x1
437
+ delta1 = w2 * dlambda * grad_x2
438
+ delta2 = w3 * dlambda * grad_x3
439
+ delta3 = w4 * dlambda * grad_x4
336
440
 
337
- wp.atomic_sub(delta, i, xd * wi)
338
- wp.atomic_add(delta, j, xd * wj)
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
 
@@ -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,