warp-lang 1.9.0__py3-none-win_amd64.whl → 1.10.0rc2__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 (350) hide show
  1. warp/__init__.py +301 -287
  2. warp/__init__.pyi +2220 -313
  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} +1497 -226
  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.dll +0 -0
  92. warp/bin/warp.dll +0 -0
  93. warp/build.py +8 -588
  94. warp/build_dll.py +6 -471
  95. warp/codegen.py +6 -4246
  96. warp/constants.py +6 -39
  97. warp/context.py +12 -7851
  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 +3 -2
  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 -342
  136. warp/jax_experimental/ffi.py +17 -853
  137. warp/jax_experimental/xla_ffi.py +5 -596
  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 +316 -39
  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/sort.cu +22 -13
  159. warp/native/sort.h +2 -0
  160. warp/native/sparse.cu +7 -3
  161. warp/native/spatial.h +12 -0
  162. warp/native/tile.h +837 -70
  163. warp/native/tile_radix_sort.h +1 -1
  164. warp/native/tile_reduce.h +394 -46
  165. warp/native/tile_scan.h +4 -4
  166. warp/native/vec.h +469 -53
  167. warp/native/version.h +23 -0
  168. warp/native/volume.cpp +1 -1
  169. warp/native/volume.cu +1 -0
  170. warp/native/volume.h +1 -1
  171. warp/native/volume_builder.cu +2 -0
  172. warp/native/warp.cpp +60 -32
  173. warp/native/warp.cu +313 -201
  174. warp/native/warp.h +14 -11
  175. warp/optim/__init__.py +6 -3
  176. warp/optim/adam.py +6 -145
  177. warp/optim/linear.py +14 -1585
  178. warp/optim/sgd.py +6 -94
  179. warp/paddle.py +6 -388
  180. warp/render/__init__.py +8 -4
  181. warp/render/imgui_manager.py +7 -267
  182. warp/render/render_opengl.py +6 -3616
  183. warp/render/render_usd.py +6 -918
  184. warp/render/utils.py +6 -142
  185. warp/sparse.py +37 -2563
  186. warp/tape.py +6 -1188
  187. warp/tests/__main__.py +1 -1
  188. warp/tests/cuda/test_async.py +4 -4
  189. warp/tests/cuda/test_conditional_captures.py +1 -1
  190. warp/tests/cuda/test_multigpu.py +1 -1
  191. warp/tests/cuda/test_streams.py +58 -1
  192. warp/tests/geometry/test_bvh.py +157 -22
  193. warp/tests/geometry/test_hash_grid.py +38 -0
  194. warp/tests/geometry/test_marching_cubes.py +0 -1
  195. warp/tests/geometry/test_mesh.py +5 -3
  196. warp/tests/geometry/test_mesh_query_aabb.py +5 -12
  197. warp/tests/geometry/test_mesh_query_point.py +5 -2
  198. warp/tests/geometry/test_mesh_query_ray.py +15 -3
  199. warp/tests/geometry/test_volume_write.py +5 -5
  200. warp/tests/interop/test_dlpack.py +14 -14
  201. warp/tests/interop/test_jax.py +1382 -79
  202. warp/tests/interop/test_paddle.py +1 -1
  203. warp/tests/test_adam.py +0 -1
  204. warp/tests/test_arithmetic.py +9 -9
  205. warp/tests/test_array.py +529 -100
  206. warp/tests/test_array_reduce.py +3 -3
  207. warp/tests/test_atomic.py +12 -8
  208. warp/tests/test_atomic_bitwise.py +209 -0
  209. warp/tests/test_atomic_cas.py +4 -4
  210. warp/tests/test_bool.py +2 -2
  211. warp/tests/test_builtins_resolution.py +5 -571
  212. warp/tests/test_codegen.py +34 -15
  213. warp/tests/test_conditional.py +1 -1
  214. warp/tests/test_context.py +6 -6
  215. warp/tests/test_copy.py +242 -161
  216. warp/tests/test_ctypes.py +3 -3
  217. warp/tests/test_devices.py +24 -2
  218. warp/tests/test_examples.py +16 -84
  219. warp/tests/test_fabricarray.py +35 -35
  220. warp/tests/test_fast_math.py +0 -2
  221. warp/tests/test_fem.py +60 -14
  222. warp/tests/test_fixedarray.py +3 -3
  223. warp/tests/test_func.py +8 -5
  224. warp/tests/test_generics.py +1 -1
  225. warp/tests/test_indexedarray.py +24 -24
  226. warp/tests/test_intersect.py +39 -9
  227. warp/tests/test_large.py +1 -1
  228. warp/tests/test_lerp.py +3 -1
  229. warp/tests/test_linear_solvers.py +1 -1
  230. warp/tests/test_map.py +49 -4
  231. warp/tests/test_mat.py +52 -62
  232. warp/tests/test_mat_constructors.py +4 -5
  233. warp/tests/test_mat_lite.py +1 -1
  234. warp/tests/test_mat_scalar_ops.py +121 -121
  235. warp/tests/test_math.py +34 -0
  236. warp/tests/test_module_aot.py +4 -4
  237. warp/tests/test_modules_lite.py +28 -2
  238. warp/tests/test_print.py +11 -11
  239. warp/tests/test_quat.py +93 -58
  240. warp/tests/test_runlength_encode.py +1 -1
  241. warp/tests/test_scalar_ops.py +38 -10
  242. warp/tests/test_smoothstep.py +1 -1
  243. warp/tests/test_sparse.py +126 -15
  244. warp/tests/test_spatial.py +105 -87
  245. warp/tests/test_special_values.py +6 -6
  246. warp/tests/test_static.py +7 -7
  247. warp/tests/test_struct.py +13 -2
  248. warp/tests/test_triangle_closest_point.py +48 -1
  249. warp/tests/test_tuple.py +96 -0
  250. warp/tests/test_types.py +82 -9
  251. warp/tests/test_utils.py +52 -52
  252. warp/tests/test_vec.py +29 -29
  253. warp/tests/test_vec_constructors.py +5 -5
  254. warp/tests/test_vec_scalar_ops.py +97 -97
  255. warp/tests/test_version.py +75 -0
  256. warp/tests/tile/test_tile.py +239 -0
  257. warp/tests/tile/test_tile_atomic_bitwise.py +403 -0
  258. warp/tests/tile/test_tile_cholesky.py +7 -4
  259. warp/tests/tile/test_tile_load.py +26 -2
  260. warp/tests/tile/test_tile_mathdx.py +3 -3
  261. warp/tests/tile/test_tile_matmul.py +1 -1
  262. warp/tests/tile/test_tile_mlp.py +2 -4
  263. warp/tests/tile/test_tile_reduce.py +214 -13
  264. warp/tests/unittest_suites.py +6 -14
  265. warp/tests/unittest_utils.py +10 -9
  266. warp/tests/walkthrough_debug.py +3 -1
  267. warp/torch.py +6 -373
  268. warp/types.py +29 -5750
  269. warp/utils.py +10 -1659
  270. {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/METADATA +47 -103
  271. warp_lang-1.10.0rc2.dist-info/RECORD +468 -0
  272. warp_lang-1.10.0rc2.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
  273. warp_lang-1.10.0rc2.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
  274. warp_lang-1.10.0rc2.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
  275. warp_lang-1.10.0rc2.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
  276. warp_lang-1.10.0rc2.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
  277. warp_lang-1.10.0rc2.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
  278. warp_lang-1.10.0rc2.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
  279. warp_lang-1.10.0rc2.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
  280. warp_lang-1.10.0rc2.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
  281. warp_lang-1.10.0rc2.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
  282. warp_lang-1.10.0rc2.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
  283. warp_lang-1.10.0rc2.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
  284. warp_lang-1.10.0rc2.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
  285. warp_lang-1.10.0rc2.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
  286. warp_lang-1.10.0rc2.dist-info/licenses/licenses/windingnumber-LICENSE.txt +21 -0
  287. warp/examples/assets/cartpole.urdf +0 -110
  288. warp/examples/assets/crazyflie.usd +0 -0
  289. warp/examples/assets/nv_ant.xml +0 -92
  290. warp/examples/assets/nv_humanoid.xml +0 -183
  291. warp/examples/assets/quadruped.urdf +0 -268
  292. warp/examples/optim/example_bounce.py +0 -266
  293. warp/examples/optim/example_cloth_throw.py +0 -228
  294. warp/examples/optim/example_drone.py +0 -870
  295. warp/examples/optim/example_inverse_kinematics.py +0 -182
  296. warp/examples/optim/example_inverse_kinematics_torch.py +0 -191
  297. warp/examples/optim/example_softbody_properties.py +0 -400
  298. warp/examples/optim/example_spring_cage.py +0 -245
  299. warp/examples/optim/example_trajectory.py +0 -227
  300. warp/examples/sim/example_cartpole.py +0 -143
  301. warp/examples/sim/example_cloth.py +0 -225
  302. warp/examples/sim/example_cloth_self_contact.py +0 -316
  303. warp/examples/sim/example_granular.py +0 -130
  304. warp/examples/sim/example_granular_collision_sdf.py +0 -202
  305. warp/examples/sim/example_jacobian_ik.py +0 -244
  306. warp/examples/sim/example_particle_chain.py +0 -124
  307. warp/examples/sim/example_quadruped.py +0 -203
  308. warp/examples/sim/example_rigid_chain.py +0 -203
  309. warp/examples/sim/example_rigid_contact.py +0 -195
  310. warp/examples/sim/example_rigid_force.py +0 -133
  311. warp/examples/sim/example_rigid_gyroscopic.py +0 -115
  312. warp/examples/sim/example_rigid_soft_contact.py +0 -140
  313. warp/examples/sim/example_soft_body.py +0 -196
  314. warp/examples/tile/example_tile_walker.py +0 -327
  315. warp/sim/__init__.py +0 -74
  316. warp/sim/articulation.py +0 -793
  317. warp/sim/collide.py +0 -2570
  318. warp/sim/graph_coloring.py +0 -307
  319. warp/sim/import_mjcf.py +0 -791
  320. warp/sim/import_snu.py +0 -227
  321. warp/sim/import_urdf.py +0 -579
  322. warp/sim/import_usd.py +0 -898
  323. warp/sim/inertia.py +0 -357
  324. warp/sim/integrator.py +0 -245
  325. warp/sim/integrator_euler.py +0 -2000
  326. warp/sim/integrator_featherstone.py +0 -2101
  327. warp/sim/integrator_vbd.py +0 -2487
  328. warp/sim/integrator_xpbd.py +0 -3295
  329. warp/sim/model.py +0 -4821
  330. warp/sim/particles.py +0 -121
  331. warp/sim/render.py +0 -431
  332. warp/sim/utils.py +0 -431
  333. warp/tests/sim/disabled_kinematics.py +0 -244
  334. warp/tests/sim/test_cloth.py +0 -863
  335. warp/tests/sim/test_collision.py +0 -743
  336. warp/tests/sim/test_coloring.py +0 -347
  337. warp/tests/sim/test_inertia.py +0 -161
  338. warp/tests/sim/test_model.py +0 -226
  339. warp/tests/sim/test_sim_grad.py +0 -287
  340. warp/tests/sim/test_sim_grad_bounce_linear.py +0 -212
  341. warp/tests/sim/test_sim_kinematics.py +0 -98
  342. warp/thirdparty/__init__.py +0 -0
  343. warp_lang-1.9.0.dist-info/RECORD +0 -456
  344. /warp/{fem → _src/fem}/quadrature/__init__.py +0 -0
  345. /warp/{tests/sim → _src/thirdparty}/__init__.py +0 -0
  346. /warp/{thirdparty → _src/thirdparty}/appdirs.py +0 -0
  347. /warp/{thirdparty → _src/thirdparty}/dlpack.py +0 -0
  348. {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/WHEEL +0 -0
  349. {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/licenses/LICENSE.md +0 -0
  350. {warp_lang-1.9.0.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)