warp-lang 1.9.1__py3-none-manylinux_2_34_aarch64.whl → 1.10.0rc2__py3-none-manylinux_2_34_aarch64.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 (346) hide show
  1. warp/__init__.py +301 -287
  2. warp/__init__.pyi +794 -305
  3. warp/_src/__init__.py +14 -0
  4. warp/_src/autograd.py +1075 -0
  5. warp/_src/build.py +618 -0
  6. warp/_src/build_dll.py +640 -0
  7. warp/{builtins.py → _src/builtins.py} +1382 -377
  8. warp/_src/codegen.py +4359 -0
  9. warp/{config.py → _src/config.py} +178 -169
  10. warp/_src/constants.py +57 -0
  11. warp/_src/context.py +8294 -0
  12. warp/_src/dlpack.py +462 -0
  13. warp/_src/fabric.py +355 -0
  14. warp/_src/fem/__init__.py +14 -0
  15. warp/_src/fem/adaptivity.py +508 -0
  16. warp/_src/fem/cache.py +687 -0
  17. warp/_src/fem/dirichlet.py +188 -0
  18. warp/{fem → _src/fem}/domain.py +40 -30
  19. warp/_src/fem/field/__init__.py +131 -0
  20. warp/_src/fem/field/field.py +701 -0
  21. warp/{fem → _src/fem}/field/nodal_field.py +30 -15
  22. warp/{fem → _src/fem}/field/restriction.py +1 -1
  23. warp/{fem → _src/fem}/field/virtual.py +53 -27
  24. warp/_src/fem/geometry/__init__.py +32 -0
  25. warp/{fem → _src/fem}/geometry/adaptive_nanogrid.py +77 -163
  26. warp/_src/fem/geometry/closest_point.py +97 -0
  27. warp/{fem → _src/fem}/geometry/deformed_geometry.py +14 -22
  28. warp/{fem → _src/fem}/geometry/element.py +32 -10
  29. warp/{fem → _src/fem}/geometry/geometry.py +48 -20
  30. warp/{fem → _src/fem}/geometry/grid_2d.py +12 -23
  31. warp/{fem → _src/fem}/geometry/grid_3d.py +12 -23
  32. warp/{fem → _src/fem}/geometry/hexmesh.py +40 -63
  33. warp/{fem → _src/fem}/geometry/nanogrid.py +255 -248
  34. warp/{fem → _src/fem}/geometry/partition.py +121 -63
  35. warp/{fem → _src/fem}/geometry/quadmesh.py +26 -45
  36. warp/{fem → _src/fem}/geometry/tetmesh.py +40 -63
  37. warp/{fem → _src/fem}/geometry/trimesh.py +26 -45
  38. warp/{fem → _src/fem}/integrate.py +164 -158
  39. warp/_src/fem/linalg.py +383 -0
  40. warp/_src/fem/operator.py +396 -0
  41. warp/_src/fem/polynomial.py +229 -0
  42. warp/{fem → _src/fem}/quadrature/pic_quadrature.py +15 -20
  43. warp/{fem → _src/fem}/quadrature/quadrature.py +95 -47
  44. warp/_src/fem/space/__init__.py +248 -0
  45. warp/{fem → _src/fem}/space/basis_function_space.py +20 -11
  46. warp/_src/fem/space/basis_space.py +679 -0
  47. warp/{fem → _src/fem}/space/dof_mapper.py +3 -3
  48. warp/{fem → _src/fem}/space/function_space.py +14 -13
  49. warp/{fem → _src/fem}/space/grid_2d_function_space.py +4 -7
  50. warp/{fem → _src/fem}/space/grid_3d_function_space.py +4 -4
  51. warp/{fem → _src/fem}/space/hexmesh_function_space.py +4 -10
  52. warp/{fem → _src/fem}/space/nanogrid_function_space.py +3 -9
  53. warp/{fem → _src/fem}/space/partition.py +117 -60
  54. warp/{fem → _src/fem}/space/quadmesh_function_space.py +4 -10
  55. warp/{fem → _src/fem}/space/restriction.py +66 -33
  56. warp/_src/fem/space/shape/__init__.py +152 -0
  57. warp/{fem → _src/fem}/space/shape/cube_shape_function.py +9 -9
  58. warp/{fem → _src/fem}/space/shape/shape_function.py +8 -9
  59. warp/{fem → _src/fem}/space/shape/square_shape_function.py +6 -6
  60. warp/{fem → _src/fem}/space/shape/tet_shape_function.py +3 -3
  61. warp/{fem → _src/fem}/space/shape/triangle_shape_function.py +3 -3
  62. warp/{fem → _src/fem}/space/tetmesh_function_space.py +3 -9
  63. warp/_src/fem/space/topology.py +459 -0
  64. warp/{fem → _src/fem}/space/trimesh_function_space.py +3 -9
  65. warp/_src/fem/types.py +112 -0
  66. warp/_src/fem/utils.py +486 -0
  67. warp/_src/jax.py +186 -0
  68. warp/_src/jax_experimental/__init__.py +14 -0
  69. warp/_src/jax_experimental/custom_call.py +387 -0
  70. warp/_src/jax_experimental/ffi.py +1284 -0
  71. warp/_src/jax_experimental/xla_ffi.py +656 -0
  72. warp/_src/marching_cubes.py +708 -0
  73. warp/_src/math.py +414 -0
  74. warp/_src/optim/__init__.py +14 -0
  75. warp/_src/optim/adam.py +163 -0
  76. warp/_src/optim/linear.py +1606 -0
  77. warp/_src/optim/sgd.py +112 -0
  78. warp/_src/paddle.py +406 -0
  79. warp/_src/render/__init__.py +14 -0
  80. warp/_src/render/imgui_manager.py +289 -0
  81. warp/_src/render/render_opengl.py +3636 -0
  82. warp/_src/render/render_usd.py +937 -0
  83. warp/_src/render/utils.py +160 -0
  84. warp/_src/sparse.py +2716 -0
  85. warp/_src/tape.py +1206 -0
  86. warp/{thirdparty → _src/thirdparty}/unittest_parallel.py +9 -2
  87. warp/_src/torch.py +391 -0
  88. warp/_src/types.py +5870 -0
  89. warp/_src/utils.py +1693 -0
  90. warp/autograd.py +12 -1054
  91. warp/bin/warp-clang.so +0 -0
  92. warp/bin/warp.so +0 -0
  93. warp/build.py +8 -588
  94. warp/build_dll.py +6 -721
  95. warp/codegen.py +6 -4251
  96. warp/constants.py +6 -39
  97. warp/context.py +12 -8062
  98. warp/dlpack.py +6 -444
  99. warp/examples/distributed/example_jacobi_mpi.py +4 -5
  100. warp/examples/fem/example_adaptive_grid.py +1 -1
  101. warp/examples/fem/example_apic_fluid.py +1 -1
  102. warp/examples/fem/example_burgers.py +8 -8
  103. warp/examples/fem/example_diffusion.py +1 -1
  104. warp/examples/fem/example_distortion_energy.py +1 -1
  105. warp/examples/fem/example_mixed_elasticity.py +2 -2
  106. warp/examples/fem/example_navier_stokes.py +1 -1
  107. warp/examples/fem/example_nonconforming_contact.py +7 -7
  108. warp/examples/fem/example_stokes.py +1 -1
  109. warp/examples/fem/example_stokes_transfer.py +1 -1
  110. warp/examples/fem/utils.py +2 -2
  111. warp/examples/interop/example_jax_callable.py +1 -1
  112. warp/examples/interop/example_jax_ffi_callback.py +1 -1
  113. warp/examples/interop/example_jax_kernel.py +1 -1
  114. warp/examples/tile/example_tile_mcgp.py +191 -0
  115. warp/fabric.py +6 -337
  116. warp/fem/__init__.py +159 -97
  117. warp/fem/adaptivity.py +7 -489
  118. warp/fem/cache.py +9 -648
  119. warp/fem/dirichlet.py +6 -184
  120. warp/fem/field/__init__.py +8 -109
  121. warp/fem/field/field.py +7 -652
  122. warp/fem/geometry/__init__.py +7 -18
  123. warp/fem/geometry/closest_point.py +11 -77
  124. warp/fem/linalg.py +18 -366
  125. warp/fem/operator.py +11 -369
  126. warp/fem/polynomial.py +9 -209
  127. warp/fem/space/__init__.py +5 -211
  128. warp/fem/space/basis_space.py +6 -662
  129. warp/fem/space/shape/__init__.py +41 -118
  130. warp/fem/space/topology.py +6 -437
  131. warp/fem/types.py +6 -81
  132. warp/fem/utils.py +11 -444
  133. warp/jax.py +8 -165
  134. warp/jax_experimental/__init__.py +14 -1
  135. warp/jax_experimental/custom_call.py +8 -365
  136. warp/jax_experimental/ffi.py +17 -873
  137. warp/jax_experimental/xla_ffi.py +5 -605
  138. warp/marching_cubes.py +5 -689
  139. warp/math.py +16 -393
  140. warp/native/array.h +385 -37
  141. warp/native/builtin.h +314 -37
  142. warp/native/bvh.cpp +43 -9
  143. warp/native/bvh.cu +62 -27
  144. warp/native/bvh.h +310 -309
  145. warp/native/clang/clang.cpp +102 -97
  146. warp/native/coloring.cpp +0 -1
  147. warp/native/crt.h +208 -0
  148. warp/native/exports.h +156 -0
  149. warp/native/hashgrid.cu +2 -0
  150. warp/native/intersect.h +24 -1
  151. warp/native/intersect_tri.h +44 -35
  152. warp/native/mat.h +1456 -276
  153. warp/native/mesh.cpp +4 -4
  154. warp/native/mesh.cu +4 -2
  155. warp/native/mesh.h +176 -61
  156. warp/native/quat.h +0 -52
  157. warp/native/scan.cu +2 -0
  158. warp/native/sparse.cu +7 -3
  159. warp/native/spatial.h +12 -0
  160. warp/native/tile.h +681 -89
  161. warp/native/tile_radix_sort.h +1 -1
  162. warp/native/tile_reduce.h +394 -46
  163. warp/native/tile_scan.h +4 -4
  164. warp/native/vec.h +469 -0
  165. warp/native/version.h +23 -0
  166. warp/native/volume.cpp +1 -1
  167. warp/native/volume.cu +1 -0
  168. warp/native/volume.h +1 -1
  169. warp/native/volume_builder.cu +2 -0
  170. warp/native/warp.cpp +57 -29
  171. warp/native/warp.cu +253 -171
  172. warp/native/warp.h +11 -8
  173. warp/optim/__init__.py +6 -3
  174. warp/optim/adam.py +6 -145
  175. warp/optim/linear.py +14 -1585
  176. warp/optim/sgd.py +6 -94
  177. warp/paddle.py +6 -388
  178. warp/render/__init__.py +8 -4
  179. warp/render/imgui_manager.py +7 -267
  180. warp/render/render_opengl.py +6 -3618
  181. warp/render/render_usd.py +6 -919
  182. warp/render/utils.py +6 -142
  183. warp/sparse.py +37 -2563
  184. warp/tape.py +6 -1188
  185. warp/tests/__main__.py +1 -1
  186. warp/tests/cuda/test_async.py +4 -4
  187. warp/tests/cuda/test_conditional_captures.py +1 -1
  188. warp/tests/cuda/test_multigpu.py +1 -1
  189. warp/tests/cuda/test_streams.py +58 -1
  190. warp/tests/geometry/test_bvh.py +157 -22
  191. warp/tests/geometry/test_marching_cubes.py +0 -1
  192. warp/tests/geometry/test_mesh.py +5 -3
  193. warp/tests/geometry/test_mesh_query_aabb.py +5 -12
  194. warp/tests/geometry/test_mesh_query_point.py +5 -2
  195. warp/tests/geometry/test_mesh_query_ray.py +15 -3
  196. warp/tests/geometry/test_volume_write.py +5 -5
  197. warp/tests/interop/test_dlpack.py +14 -14
  198. warp/tests/interop/test_jax.py +772 -49
  199. warp/tests/interop/test_paddle.py +1 -1
  200. warp/tests/test_adam.py +0 -1
  201. warp/tests/test_arithmetic.py +9 -9
  202. warp/tests/test_array.py +527 -100
  203. warp/tests/test_array_reduce.py +3 -3
  204. warp/tests/test_atomic.py +12 -8
  205. warp/tests/test_atomic_bitwise.py +209 -0
  206. warp/tests/test_atomic_cas.py +4 -4
  207. warp/tests/test_bool.py +2 -2
  208. warp/tests/test_builtins_resolution.py +5 -571
  209. warp/tests/test_codegen.py +33 -14
  210. warp/tests/test_conditional.py +1 -1
  211. warp/tests/test_context.py +6 -6
  212. warp/tests/test_copy.py +242 -161
  213. warp/tests/test_ctypes.py +3 -3
  214. warp/tests/test_devices.py +24 -2
  215. warp/tests/test_examples.py +16 -84
  216. warp/tests/test_fabricarray.py +35 -35
  217. warp/tests/test_fast_math.py +0 -2
  218. warp/tests/test_fem.py +56 -10
  219. warp/tests/test_fixedarray.py +3 -3
  220. warp/tests/test_func.py +8 -5
  221. warp/tests/test_generics.py +1 -1
  222. warp/tests/test_indexedarray.py +24 -24
  223. warp/tests/test_intersect.py +39 -9
  224. warp/tests/test_large.py +1 -1
  225. warp/tests/test_lerp.py +3 -1
  226. warp/tests/test_linear_solvers.py +1 -1
  227. warp/tests/test_map.py +35 -4
  228. warp/tests/test_mat.py +52 -62
  229. warp/tests/test_mat_constructors.py +4 -5
  230. warp/tests/test_mat_lite.py +1 -1
  231. warp/tests/test_mat_scalar_ops.py +121 -121
  232. warp/tests/test_math.py +34 -0
  233. warp/tests/test_module_aot.py +4 -4
  234. warp/tests/test_modules_lite.py +28 -2
  235. warp/tests/test_print.py +11 -11
  236. warp/tests/test_quat.py +93 -58
  237. warp/tests/test_runlength_encode.py +1 -1
  238. warp/tests/test_scalar_ops.py +38 -10
  239. warp/tests/test_smoothstep.py +1 -1
  240. warp/tests/test_sparse.py +126 -15
  241. warp/tests/test_spatial.py +105 -87
  242. warp/tests/test_special_values.py +6 -6
  243. warp/tests/test_static.py +7 -7
  244. warp/tests/test_struct.py +13 -2
  245. warp/tests/test_triangle_closest_point.py +48 -1
  246. warp/tests/test_types.py +27 -15
  247. warp/tests/test_utils.py +52 -52
  248. warp/tests/test_vec.py +29 -29
  249. warp/tests/test_vec_constructors.py +5 -5
  250. warp/tests/test_vec_scalar_ops.py +97 -97
  251. warp/tests/test_version.py +75 -0
  252. warp/tests/tile/test_tile.py +178 -0
  253. warp/tests/tile/test_tile_atomic_bitwise.py +403 -0
  254. warp/tests/tile/test_tile_cholesky.py +7 -4
  255. warp/tests/tile/test_tile_load.py +26 -2
  256. warp/tests/tile/test_tile_mathdx.py +3 -3
  257. warp/tests/tile/test_tile_matmul.py +1 -1
  258. warp/tests/tile/test_tile_mlp.py +2 -4
  259. warp/tests/tile/test_tile_reduce.py +214 -13
  260. warp/tests/unittest_suites.py +6 -14
  261. warp/tests/unittest_utils.py +10 -9
  262. warp/tests/walkthrough_debug.py +3 -1
  263. warp/torch.py +6 -373
  264. warp/types.py +29 -5764
  265. warp/utils.py +10 -1659
  266. {warp_lang-1.9.1.dist-info → warp_lang-1.10.0rc2.dist-info}/METADATA +46 -99
  267. warp_lang-1.10.0rc2.dist-info/RECORD +468 -0
  268. warp_lang-1.10.0rc2.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
  269. warp_lang-1.10.0rc2.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
  270. warp_lang-1.10.0rc2.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
  271. warp_lang-1.10.0rc2.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
  272. warp_lang-1.10.0rc2.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
  273. warp_lang-1.10.0rc2.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
  274. warp_lang-1.10.0rc2.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
  275. warp_lang-1.10.0rc2.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
  276. warp_lang-1.10.0rc2.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
  277. warp_lang-1.10.0rc2.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
  278. warp_lang-1.10.0rc2.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
  279. warp_lang-1.10.0rc2.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
  280. warp_lang-1.10.0rc2.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
  281. warp_lang-1.10.0rc2.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
  282. warp_lang-1.10.0rc2.dist-info/licenses/licenses/windingnumber-LICENSE.txt +21 -0
  283. warp/examples/assets/cartpole.urdf +0 -110
  284. warp/examples/assets/crazyflie.usd +0 -0
  285. warp/examples/assets/nv_ant.xml +0 -92
  286. warp/examples/assets/nv_humanoid.xml +0 -183
  287. warp/examples/assets/quadruped.urdf +0 -268
  288. warp/examples/optim/example_bounce.py +0 -266
  289. warp/examples/optim/example_cloth_throw.py +0 -228
  290. warp/examples/optim/example_drone.py +0 -870
  291. warp/examples/optim/example_inverse_kinematics.py +0 -182
  292. warp/examples/optim/example_inverse_kinematics_torch.py +0 -191
  293. warp/examples/optim/example_softbody_properties.py +0 -400
  294. warp/examples/optim/example_spring_cage.py +0 -245
  295. warp/examples/optim/example_trajectory.py +0 -227
  296. warp/examples/sim/example_cartpole.py +0 -143
  297. warp/examples/sim/example_cloth.py +0 -225
  298. warp/examples/sim/example_cloth_self_contact.py +0 -316
  299. warp/examples/sim/example_granular.py +0 -130
  300. warp/examples/sim/example_granular_collision_sdf.py +0 -202
  301. warp/examples/sim/example_jacobian_ik.py +0 -244
  302. warp/examples/sim/example_particle_chain.py +0 -124
  303. warp/examples/sim/example_quadruped.py +0 -203
  304. warp/examples/sim/example_rigid_chain.py +0 -203
  305. warp/examples/sim/example_rigid_contact.py +0 -195
  306. warp/examples/sim/example_rigid_force.py +0 -133
  307. warp/examples/sim/example_rigid_gyroscopic.py +0 -115
  308. warp/examples/sim/example_rigid_soft_contact.py +0 -140
  309. warp/examples/sim/example_soft_body.py +0 -196
  310. warp/examples/tile/example_tile_walker.py +0 -327
  311. warp/sim/__init__.py +0 -74
  312. warp/sim/articulation.py +0 -793
  313. warp/sim/collide.py +0 -2570
  314. warp/sim/graph_coloring.py +0 -307
  315. warp/sim/import_mjcf.py +0 -791
  316. warp/sim/import_snu.py +0 -227
  317. warp/sim/import_urdf.py +0 -579
  318. warp/sim/import_usd.py +0 -898
  319. warp/sim/inertia.py +0 -357
  320. warp/sim/integrator.py +0 -245
  321. warp/sim/integrator_euler.py +0 -2000
  322. warp/sim/integrator_featherstone.py +0 -2101
  323. warp/sim/integrator_vbd.py +0 -2487
  324. warp/sim/integrator_xpbd.py +0 -3295
  325. warp/sim/model.py +0 -4821
  326. warp/sim/particles.py +0 -121
  327. warp/sim/render.py +0 -431
  328. warp/sim/utils.py +0 -431
  329. warp/tests/sim/disabled_kinematics.py +0 -244
  330. warp/tests/sim/test_cloth.py +0 -863
  331. warp/tests/sim/test_collision.py +0 -743
  332. warp/tests/sim/test_coloring.py +0 -347
  333. warp/tests/sim/test_inertia.py +0 -161
  334. warp/tests/sim/test_model.py +0 -226
  335. warp/tests/sim/test_sim_grad.py +0 -287
  336. warp/tests/sim/test_sim_grad_bounce_linear.py +0 -212
  337. warp/tests/sim/test_sim_kinematics.py +0 -98
  338. warp/thirdparty/__init__.py +0 -0
  339. warp_lang-1.9.1.dist-info/RECORD +0 -456
  340. /warp/{fem → _src/fem}/quadrature/__init__.py +0 -0
  341. /warp/{tests/sim → _src/thirdparty}/__init__.py +0 -0
  342. /warp/{thirdparty → _src/thirdparty}/appdirs.py +0 -0
  343. /warp/{thirdparty → _src/thirdparty}/dlpack.py +0 -0
  344. {warp_lang-1.9.1.dist-info → warp_lang-1.10.0rc2.dist-info}/WHEEL +0 -0
  345. {warp_lang-1.9.1.dist-info → warp_lang-1.10.0rc2.dist-info}/licenses/LICENSE.md +0 -0
  346. {warp_lang-1.9.1.dist-info → warp_lang-1.10.0rc2.dist-info}/top_level.txt +0 -0
warp/fem/types.py CHANGED
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,87 +13,12 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- from enum import Enum
16
+ # TODO: Remove after cleaning up the public API.
17
17
 
18
- import warp as wp
18
+ from warp._src.fem import types as _types
19
19
 
20
- # kept to avoid breaking existing example code, no longer used internally
21
- vec2i = wp.vec2i
22
- vec3i = wp.vec3i
23
- vec4i = wp.vec4i
24
20
 
25
- Coords = wp.vec3
26
- OUTSIDE = wp.constant(-1.0e8)
21
+ def __getattr__(name):
22
+ from warp._src.utils import get_deprecated_api
27
23
 
28
- ElementIndex = int
29
- QuadraturePointIndex = int
30
- NodeIndex = int
31
-
32
- NULL_ELEMENT_INDEX = wp.constant(-1)
33
- NULL_QP_INDEX = wp.constant(-1)
34
- NULL_NODE_INDEX = wp.constant((1 << 31) - 1) # this should be larger than normal nodes when sorting
35
-
36
- DofIndex = wp.vec2i
37
- """Opaque descriptor for indexing degrees of freedom within elements"""
38
- NULL_DOF_INDEX = wp.constant(DofIndex(-1, -1))
39
-
40
-
41
- @wp.func
42
- def get_node_index_in_element(dof_idx: DofIndex):
43
- return dof_idx[0]
44
-
45
-
46
- @wp.func
47
- def get_node_coord(dof_idx: DofIndex):
48
- return dof_idx[1]
49
-
50
-
51
- class ElementKind(Enum):
52
- CELL = 0
53
- SIDE = 1
54
-
55
-
56
- @wp.struct
57
- class NodeElementIndex:
58
- domain_element_index: ElementIndex
59
- node_index_in_element: int
60
-
61
-
62
- @wp.struct
63
- class Sample:
64
- """Per-sample point context for evaluating fields and related operators in integrands"""
65
-
66
- element_index: ElementIndex
67
- """Index of the geometry element the sample point is in"""
68
- element_coords: Coords
69
- """Coordinates of the sample point inside the element"""
70
- qp_index: QuadraturePointIndex = NULL_QP_INDEX
71
- """If the sample corresponds to a quadrature point, its global index"""
72
- qp_weight: float = 0.0
73
- """If the sample corresponds to a quadrature point, its weight"""
74
- test_dof: DofIndex = NULL_DOF_INDEX
75
- """For linear of bilinear form assembly, index of the test degree-of-freedom currently being considered"""
76
- trial_dof: DofIndex = NULL_DOF_INDEX
77
- """For bilinear form assembly, index of the trial degree-of-freedom currently being considered"""
78
-
79
-
80
- @wp.func
81
- def make_free_sample(element_index: ElementIndex, element_coords: Coords):
82
- """Returns a :class:`Sample` that is not associated to any quadrature point or dof"""
83
- return Sample(element_index, element_coords, NULL_QP_INDEX, 0.0, NULL_DOF_INDEX, NULL_DOF_INDEX)
84
-
85
-
86
- class Field:
87
- """
88
- Tag for field-like integrand arguments
89
- """
90
-
91
- call_operator: "warp.fem.operator.Operator" = None # noqa: F821 Set in operator.py
92
-
93
-
94
- class Domain:
95
- """
96
- Tag for domain-like integrand arguments
97
- """
98
-
99
- call_operator: "warp.fem.operator.Operator" = None # noqa: F821 Set in operator.py
24
+ return get_deprecated_api(_types, "wp.fem", name)
warp/fem/utils.py CHANGED
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,453 +13,20 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- from typing import Tuple, Union
16
+ # isort: skip_file
17
17
 
18
- import numpy as np
18
+ from warp._src.fem.utils import grid_to_quads as grid_to_quads
19
+ from warp._src.fem.utils import grid_to_tris as grid_to_tris
20
+ from warp._src.fem.utils import grid_to_tets as grid_to_tets
21
+ from warp._src.fem.utils import grid_to_hexes as grid_to_hexes
19
22
 
20
- import warp as wp
21
- import warp.fem.cache as cache
22
- import warp.types
23
- from warp.fem.linalg import ( # noqa: F401 (for backward compatibility, not part of public API but used in examples)
24
- array_axpy,
25
- inverse_qr,
26
- symmetric_eigenvalues_qr,
27
- )
28
- from warp.fem.types import NULL_NODE_INDEX
29
- from warp.utils import array_scan, radix_sort_pairs, runlength_encode
30
23
 
24
+ # TODO: Remove after cleaning up the public API.
31
25
 
32
- def type_zero_element(dtype):
33
- suffix = warp.types.get_type_code(dtype)
26
+ from warp._src.fem import utils as _utils
34
27
 
35
- if dtype in warp.types.scalar_types:
36
28
 
37
- @cache.dynamic_func(suffix=suffix)
38
- def zero_element():
39
- return dtype(0.0)
29
+ def __getattr__(name):
30
+ from warp._src.utils import get_deprecated_api
40
31
 
41
- return zero_element
42
-
43
- @cache.dynamic_func(suffix=suffix)
44
- def zero_element():
45
- return dtype()
46
-
47
- return zero_element
48
-
49
-
50
- def type_basis_element(dtype):
51
- suffix = warp.types.get_type_code(dtype)
52
-
53
- if dtype in warp.types.scalar_types:
54
-
55
- @cache.dynamic_func(suffix=suffix)
56
- def basis_element(coord: int):
57
- return dtype(1.0)
58
-
59
- return basis_element
60
-
61
- if warp.types.type_is_matrix(dtype):
62
- cols = dtype._shape_[1]
63
-
64
- @cache.dynamic_func(suffix=suffix)
65
- def basis_element(coord: int):
66
- v = dtype()
67
- i = coord // cols
68
- j = coord - i * cols
69
- v[i, j] = v.dtype(1.0)
70
- return v
71
-
72
- return basis_element
73
-
74
- @cache.dynamic_func(suffix=suffix)
75
- def basis_element(coord: int):
76
- v = dtype()
77
- v[coord] = v.dtype(1.0)
78
- return v
79
-
80
- return basis_element
81
-
82
-
83
- def compress_node_indices(
84
- node_count: int,
85
- node_indices: wp.array(dtype=int),
86
- return_unique_nodes=False,
87
- temporary_store: cache.TemporaryStore = None,
88
- ) -> Union[Tuple[cache.Temporary, cache.Temporary], Tuple[cache.Temporary, cache.Temporary, int, cache.Temporary]]:
89
- """
90
- Compress an unsorted list of node indices into:
91
- - a node_offsets array, giving for each node the start offset of corresponding indices in sorted_array_indices
92
- - a sorted_array_indices array, listing the indices in the input array corresponding to each node
93
-
94
- Plus if `return_unique_nodes` is ``True``,
95
- - the number of unique node indices
96
- - a unique_node_indices array containing the sorted list of unique node indices (i.e. the list of indices i for which node_offsets[i] < node_offsets[i+1])
97
-
98
- Node indices equal to NULL_NODE_INDEX will be ignored
99
- """
100
-
101
- index_count = node_indices.size
102
- device = node_indices.device
103
-
104
- with wp.ScopedDevice(device):
105
- sorted_node_indices_temp = cache.borrow_temporary(temporary_store, shape=2 * index_count, dtype=int)
106
- sorted_array_indices_temp = cache.borrow_temporary_like(sorted_node_indices_temp, temporary_store)
107
-
108
- sorted_node_indices = sorted_node_indices_temp.array
109
- sorted_array_indices = sorted_array_indices_temp.array
110
-
111
- indices_per_element = 1 if node_indices.ndim == 1 else node_indices.shape[-1]
112
- wp.launch(
113
- kernel=_prepare_node_sort_kernel,
114
- dim=index_count,
115
- inputs=[node_indices.flatten(), sorted_node_indices, sorted_array_indices, indices_per_element],
116
- )
117
-
118
- # Sort indices
119
- radix_sort_pairs(sorted_node_indices, sorted_array_indices, count=index_count)
120
-
121
- # Build prefix sum of number of elements per node
122
- unique_node_indices_temp = cache.borrow_temporary(temporary_store, shape=index_count, dtype=int)
123
- node_element_counts_temp = cache.borrow_temporary(temporary_store, shape=index_count, dtype=int)
124
-
125
- unique_node_indices = unique_node_indices_temp.array
126
- node_element_counts = node_element_counts_temp.array
127
-
128
- unique_node_count_dev = cache.borrow_temporary(temporary_store, shape=(1,), dtype=int)
129
-
130
- runlength_encode(
131
- sorted_node_indices,
132
- unique_node_indices,
133
- node_element_counts,
134
- value_count=index_count,
135
- run_count=unique_node_count_dev.array,
136
- )
137
-
138
- # Scatter seen run counts to global array of element count per node
139
- node_offsets_temp = cache.borrow_temporary(temporary_store, shape=(node_count + 1), dtype=int)
140
- node_offsets = node_offsets_temp.array
141
-
142
- node_offsets.zero_()
143
- wp.launch(
144
- kernel=_scatter_node_counts,
145
- dim=node_count + 1, # +1 to accommodate possible NULL node,
146
- inputs=[node_element_counts, unique_node_indices, node_offsets, unique_node_count_dev.array],
147
- )
148
-
149
- if device.is_cuda and return_unique_nodes:
150
- unique_node_count_host = cache.borrow_temporary(
151
- temporary_store, shape=(1,), dtype=int, pinned=True, device="cpu"
152
- )
153
- wp.copy(src=unique_node_count_dev.array, dest=unique_node_count_host.array, count=1)
154
- copy_event = cache.capture_event(device)
155
-
156
- # Prefix sum of number of elements per node
157
- array_scan(node_offsets, node_offsets, inclusive=True)
158
-
159
- sorted_node_indices_temp.release()
160
- node_element_counts_temp.release()
161
-
162
- if not return_unique_nodes:
163
- unique_node_count_dev.release()
164
- return node_offsets_temp, sorted_array_indices_temp
165
-
166
- if device.is_cuda:
167
- cache.synchronize_event(copy_event)
168
- unique_node_count_dev.release()
169
- else:
170
- unique_node_count_host = unique_node_count_dev
171
- unique_node_count = int(unique_node_count_host.array.numpy()[0])
172
- unique_node_count_host.release()
173
- return node_offsets_temp, sorted_array_indices_temp, unique_node_count, unique_node_indices_temp
174
-
175
-
176
- def host_read_at_index(array: wp.array, index: int = -1, temporary_store: cache.TemporaryStore = None) -> int:
177
- """Returns the value of the array element at the given index on host"""
178
-
179
- if index < 0:
180
- index += array.shape[0]
181
- return array[index : index + 1].numpy()[0]
182
-
183
-
184
- def masked_indices(
185
- mask: wp.array, missing_index=-1, temporary_store: cache.TemporaryStore = None
186
- ) -> Tuple[cache.Temporary, cache.Temporary]:
187
- """
188
- From an array of boolean masks (must be either 0 or 1), returns:
189
- - The list of indices for which the mask is 1
190
- - A map associating to each element of the input mask array its local index if non-zero, or missing_index if zero.
191
- """
192
-
193
- offsets_temp = cache.borrow_temporary_like(mask, temporary_store)
194
- offsets = offsets_temp.array
195
-
196
- wp.utils.array_scan(mask, offsets, inclusive=True)
197
-
198
- # Get back total counts on host
199
- masked_count = int(host_read_at_index(offsets, temporary_store=temporary_store))
200
-
201
- # Convert counts to indices
202
- indices_temp = cache.borrow_temporary(temporary_store, shape=masked_count, device=mask.device, dtype=int)
203
-
204
- wp.launch(
205
- kernel=_masked_indices_kernel,
206
- dim=offsets.shape,
207
- inputs=[missing_index, mask, offsets, indices_temp.array, offsets],
208
- device=mask.device,
209
- )
210
-
211
- return indices_temp, offsets_temp
212
-
213
-
214
- @wp.kernel
215
- def _prepare_node_sort_kernel(
216
- node_indices: wp.array(dtype=int),
217
- sort_keys: wp.array(dtype=int),
218
- sort_values: wp.array(dtype=int),
219
- divisor: int,
220
- ):
221
- i = wp.tid()
222
- node = node_indices[i]
223
- sort_keys[i] = wp.where(node >= 0, node, NULL_NODE_INDEX)
224
- sort_values[i] = i // divisor
225
-
226
-
227
- @wp.kernel
228
- def _scatter_node_counts(
229
- unique_counts: wp.array(dtype=int),
230
- unique_node_indices: wp.array(dtype=int),
231
- node_counts: wp.array(dtype=int),
232
- unique_node_count: wp.array(dtype=int),
233
- ):
234
- i = wp.tid()
235
-
236
- if i >= unique_node_count[0]:
237
- return
238
-
239
- node_index = unique_node_indices[i]
240
- if node_index == NULL_NODE_INDEX:
241
- wp.atomic_sub(unique_node_count, 0, 1)
242
- return
243
-
244
- node_counts[1 + node_index] = unique_counts[i]
245
-
246
-
247
- @wp.kernel
248
- def _masked_indices_kernel(
249
- missing_index: int,
250
- mask: wp.array(dtype=int),
251
- offsets: wp.array(dtype=int),
252
- masked_to_global: wp.array(dtype=int),
253
- global_to_masked: wp.array(dtype=int),
254
- ):
255
- i = wp.tid()
256
-
257
- if mask[i] == 0:
258
- global_to_masked[i] = missing_index
259
- else:
260
- masked_idx = offsets[i] - 1
261
- global_to_masked[i] = masked_idx
262
- masked_to_global[masked_idx] = i
263
-
264
-
265
- def grid_to_tris(Nx: int, Ny: int):
266
- """Constructs a triangular mesh topology by dividing each cell of a dense 2D grid into two triangles.
267
-
268
- The resulting triangles will be oriented counter-clockwise assuming that `y` is the fastest moving index direction
269
-
270
- Args:
271
- Nx: Resolution of the grid along `x` dimension
272
- Ny: Resolution of the grid along `y` dimension
273
-
274
- Returns:
275
- Array of shape (2 * Nx * Ny, 3) containing vertex indices for each triangle
276
- """
277
-
278
- cx, cy = np.meshgrid(np.arange(Nx, dtype=int), np.arange(Ny, dtype=int), indexing="ij")
279
-
280
- vidx = np.transpose(
281
- np.array(
282
- [
283
- (Ny + 1) * cx + cy,
284
- (Ny + 1) * (cx + 1) + cy,
285
- (Ny + 1) * (cx + 1) + (cy + 1),
286
- (Ny + 1) * cx + cy,
287
- (Ny + 1) * (cx + 1) + (cy + 1),
288
- (Ny + 1) * (cx) + (cy + 1),
289
- ]
290
- )
291
- ).reshape((-1, 3))
292
-
293
- return vidx
294
-
295
-
296
- def grid_to_tets(Nx: int, Ny: int, Nz: int):
297
- """Constructs a tetrahedral mesh topology by diving each cell of a dense 3D grid into five tetrahedrons
298
-
299
- The resulting tets have positive volume assuming that `z` is the fastest moving index direction
300
-
301
- Args:
302
- Nx: Resolution of the grid along `x` dimension
303
- Ny: Resolution of the grid along `y` dimension
304
- Nz: Resolution of the grid along `z` dimension
305
-
306
- Returns:
307
- Array of shape (5 * Nx * Ny * Nz, 4) containing vertex indices for each tet
308
- """
309
-
310
- # Global node indices for each cell
311
- cx, cy, cz = np.meshgrid(
312
- np.arange(Nx, dtype=int), np.arange(Ny, dtype=int), np.arange(Nz, dtype=int), indexing="ij"
313
- )
314
-
315
- grid_vidx = np.array(
316
- [
317
- (Ny + 1) * (Nz + 1) * cx + (Nz + 1) * cy + cz,
318
- (Ny + 1) * (Nz + 1) * cx + (Nz + 1) * cy + cz + 1,
319
- (Ny + 1) * (Nz + 1) * cx + (Nz + 1) * (cy + 1) + cz,
320
- (Ny + 1) * (Nz + 1) * cx + (Nz + 1) * (cy + 1) + cz + 1,
321
- (Ny + 1) * (Nz + 1) * (cx + 1) + (Nz + 1) * cy + cz,
322
- (Ny + 1) * (Nz + 1) * (cx + 1) + (Nz + 1) * cy + cz + 1,
323
- (Ny + 1) * (Nz + 1) * (cx + 1) + (Nz + 1) * (cy + 1) + cz,
324
- (Ny + 1) * (Nz + 1) * (cx + 1) + (Nz + 1) * (cy + 1) + cz + 1,
325
- ]
326
- )
327
-
328
- # decompose grid cells into 5 tets
329
- tet_vidx = np.array(
330
- [
331
- [0, 1, 2, 4],
332
- [3, 2, 1, 7],
333
- [5, 1, 7, 4],
334
- [6, 7, 4, 2],
335
- [4, 1, 2, 7],
336
- ]
337
- )
338
-
339
- # Convert to 3d index coordinates
340
- vidx_coords = np.array(
341
- [
342
- [0, 0, 0],
343
- [0, 0, 1],
344
- [0, 1, 0],
345
- [0, 1, 1],
346
- [1, 0, 0],
347
- [1, 0, 1],
348
- [1, 1, 0],
349
- [1, 1, 1],
350
- ]
351
- )
352
- tet_coords = vidx_coords[tet_vidx]
353
-
354
- # Symmetry bits for each cell
355
- ox, oy, oz = np.meshgrid(
356
- np.arange(Nx, dtype=int) % 2, np.arange(Ny, dtype=int) % 2, np.arange(Nz, dtype=int) % 2, indexing="ij"
357
- )
358
- tet_coords = np.broadcast_to(tet_coords, shape=(*ox.shape, *tet_coords.shape))
359
-
360
- # Flip coordinates according to symmetry
361
- ox_bk = np.broadcast_to(ox.reshape(*ox.shape, 1, 1), tet_coords.shape[:-1])
362
- oy_bk = np.broadcast_to(oy.reshape(*oy.shape, 1, 1), tet_coords.shape[:-1])
363
- oz_bk = np.broadcast_to(oz.reshape(*oz.shape, 1, 1), tet_coords.shape[:-1])
364
-
365
- tet_coords_x = tet_coords[..., 0] ^ ox_bk
366
- tet_coords_y = tet_coords[..., 1] ^ oy_bk
367
- tet_coords_z = tet_coords[..., 2] ^ oz_bk
368
-
369
- # Back to local vertex indices
370
- corner_indices = 4 * tet_coords_x + 2 * tet_coords_y + tet_coords_z
371
-
372
- # Now go from cell-local to global node indices
373
- # There must be a nicer way than this, but for small grids this works
374
-
375
- corner_indices = corner_indices.reshape(-1, 4)
376
-
377
- grid_vidx = grid_vidx.reshape((8, -1, 1))
378
- grid_vidx = np.broadcast_to(grid_vidx, shape=(8, grid_vidx.shape[1], 5))
379
- grid_vidx = grid_vidx.reshape((8, -1))
380
-
381
- node_indices = np.arange(corner_indices.shape[0])
382
- tet_grid_vidx = np.transpose(
383
- [
384
- grid_vidx[corner_indices[:, 0], node_indices],
385
- grid_vidx[corner_indices[:, 1], node_indices],
386
- grid_vidx[corner_indices[:, 2], node_indices],
387
- grid_vidx[corner_indices[:, 3], node_indices],
388
- ]
389
- )
390
-
391
- return tet_grid_vidx
392
-
393
-
394
- def grid_to_quads(Nx: int, Ny: int):
395
- """Constructs a quadrilateral mesh topology from a dense 2D grid
396
-
397
- The resulting quads will be indexed counter-clockwise
398
-
399
- Args:
400
- Nx: Resolution of the grid along `x` dimension
401
- Ny: Resolution of the grid along `y` dimension
402
-
403
- Returns:
404
- Array of shape (Nx * Ny, 4) containing vertex indices for each quadrilateral
405
- """
406
-
407
- quad_vtx = np.array(
408
- [
409
- [0, 0],
410
- [1, 0],
411
- [1, 1],
412
- [0, 1],
413
- ]
414
- ).T
415
-
416
- quads = np.stack(np.meshgrid(np.arange(0, Nx), np.arange(0, Ny), indexing="ij"))
417
-
418
- quads_vtx_shape = (*quads.shape, quad_vtx.shape[1])
419
- quads_vtx = np.broadcast_to(quads.reshape(*quads.shape, 1), quads_vtx_shape) + np.broadcast_to(
420
- quad_vtx.reshape(2, 1, 1, quad_vtx.shape[1]), quads_vtx_shape
421
- )
422
-
423
- quad_vtx_indices = quads_vtx[0] * (Ny + 1) + quads_vtx[1]
424
-
425
- return quad_vtx_indices.reshape(-1, 4)
426
-
427
-
428
- def grid_to_hexes(Nx: int, Ny: int, Nz: int):
429
- """Constructs a hexahedral mesh topology from a dense 3D grid
430
-
431
- The resulting hexes will be indexed following usual convention assuming that `z` is the fastest moving index direction
432
- (counter-clockwise bottom vertices, then counter-clockwise top vertices)
433
-
434
- Args:
435
- Nx: Resolution of the grid along `x` dimension
436
- Ny: Resolution of the grid along `y` dimension
437
- Nz: Resolution of the grid along `z` dimension
438
-
439
- Returns:
440
- Array of shape (Nx * Ny * Nz, 8) containing vertex indices for each hexahedron
441
- """
442
-
443
- hex_vtx = np.array(
444
- [
445
- [0, 0, 0],
446
- [1, 0, 0],
447
- [1, 1, 0],
448
- [0, 1, 0],
449
- [0, 0, 1],
450
- [1, 0, 1],
451
- [1, 1, 1],
452
- [0, 1, 1],
453
- ]
454
- ).T
455
-
456
- hexes = np.stack(np.meshgrid(np.arange(0, Nx), np.arange(0, Ny), np.arange(0, Nz), indexing="ij"))
457
-
458
- hexes_vtx_shape = (*hexes.shape, hex_vtx.shape[1])
459
- hexes_vtx = np.broadcast_to(hexes.reshape(*hexes.shape, 1), hexes_vtx_shape) + np.broadcast_to(
460
- hex_vtx.reshape(3, 1, 1, 1, hex_vtx.shape[1]), hexes_vtx_shape
461
- )
462
-
463
- hexes_vtx_indices = hexes_vtx[0] * (Nz + 1) * (Ny + 1) + hexes_vtx[1] * (Nz + 1) + hexes_vtx[2]
464
-
465
- return hexes_vtx_indices.reshape(-1, 8)
32
+ return get_deprecated_api(_utils, "wp.fem", name)