warp-lang 1.9.1__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 (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.dll +0 -0
  92. warp/bin/warp.dll +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
@@ -18,104 +18,72 @@ from typing import Any, Optional
18
18
  import numpy as np
19
19
 
20
20
  import warp as wp
21
- from warp.fem import cache, utils
22
- from warp.fem.types import NULL_ELEMENT_INDEX, OUTSIDE, Coords, ElementIndex, Sample, make_free_sample
21
+ from warp._src.fem import cache, utils
22
+ from warp._src.fem.types import NULL_ELEMENT_INDEX, OUTSIDE, Coords, ElementIndex, Sample, make_free_sample
23
23
 
24
- from .element import Cube, Square
24
+ from .element import Element
25
25
  from .geometry import Geometry
26
26
 
27
- # Flag used for building edge/face grids to disambiguiate axis within the grid
28
- # Morton indexing allows for
29
- GRID_AXIS_FLAG = wp.constant(wp.int32(1 << 20))
30
27
 
31
- FACE_AXIS_MASK = wp.constant(wp.uint8((1 << 2) - 1))
32
- FACE_INNER_OFFSET_BIT = wp.constant(wp.uint8(2))
33
- FACE_OUTER_OFFSET_BIT = wp.constant(wp.uint8(3))
34
-
35
-
36
- @wp.func
37
- def _add_axis_flag(ijk: wp.vec3i, axis: int):
38
- coord = ijk[axis]
39
- ijk[axis] = wp.where(coord < 0, coord & (~GRID_AXIS_FLAG), coord | GRID_AXIS_FLAG)
40
- return ijk
41
-
42
-
43
- @wp.func
44
- def _extract_axis_flag(ijk: wp.vec3i):
45
- for ax in range(3):
46
- coord = ijk[ax]
47
- if coord < 0:
48
- if (ijk[ax] & GRID_AXIS_FLAG) == 0:
49
- ijk[ax] = ijk[ax] | GRID_AXIS_FLAG
50
- return ax, ijk
51
- else:
52
- if (ijk[ax] & GRID_AXIS_FLAG) != 0:
53
- ijk[ax] = ijk[ax] & (~GRID_AXIS_FLAG)
54
- return ax, ijk
55
-
56
- return -1, ijk
57
-
58
-
59
- @wp.struct
60
- class NanogridCellArg:
61
- # Utility device functions
62
- cell_grid: wp.uint64
63
- cell_ijk: wp.array(dtype=wp.vec3i)
64
- inverse_transform: wp.mat33
65
- cell_volume: float
66
-
67
-
68
- @wp.struct
69
- class NanogridSideArg:
70
- # Utility device functions
71
- cell_arg: NanogridCellArg
72
- face_ijk: wp.array(dtype=wp.vec3i)
73
- face_flags: wp.array(dtype=wp.uint8)
74
- face_areas: wp.vec3
75
-
76
-
77
- class Nanogrid(Geometry):
78
- """Sparse grid geometry"""
28
+ class NanogridBase(Geometry):
29
+ """Base class for regular and adaptive Nanogrid"""
79
30
 
80
31
  dimension = 3
81
32
 
82
- def __init__(self, grid: wp.Volume, temporary_store: Optional[cache.TemporaryStore] = None):
83
- """
84
- Constructs a sparse grid geometry from an in-memory NanoVDB volume.
33
+ # Flag used for building edge/face grids to disambiguiate axis within the grid
34
+ # Morton indexing allows for
35
+ GRID_AXIS_FLAG = wp.constant(wp.int32(1 << 20))
85
36
 
86
- Args:
87
- grid: The NanoVDB volume. Any type is accepted, but for indexing efficiency an index grid is recommended.
88
- If `grid` is an 'on' index grid, cells will be created for active voxels only, otherwise cells will
89
- be created for all leaf voxels.
90
- temporary_store: shared pool from which to allocate temporary arrays
91
- """
37
+ FACE_AXIS_MASK = wp.constant(wp.uint8((1 << 2) - 1))
38
+ FACE_INNER_OFFSET_BIT = wp.constant(wp.uint8(2))
39
+ FACE_OUTER_OFFSET_BIT = wp.constant(wp.uint8(3))
92
40
 
93
- self._cell_grid = grid
94
- self._cell_grid_info = grid.get_grid_info()
41
+ def __init__(
42
+ self,
43
+ cell_grid: wp.Volume,
44
+ cell_ijk: wp.array(dtype=wp.vec3i),
45
+ node_grid: wp.Volume,
46
+ node_ijk: wp.array(dtype=wp.vec3i),
47
+ ):
48
+ self._cell_grid = cell_grid
49
+ self._cell_ijk = cell_ijk
50
+ self._node_grid = node_grid
51
+ self._node_ijk = node_ijk
95
52
 
96
- device = grid.device
53
+ self._face_grid = None
54
+ self._face_ijk = None
55
+ self._boundary_face_indices = None
97
56
 
98
- cell_count = grid.get_voxel_count()
99
- self._cell_ijk = wp.array(shape=(cell_count,), dtype=wp.vec3i, device=device)
100
- grid.get_voxels(out=self._cell_ijk)
57
+ self._cell_grid_info = cell_grid.get_grid_info()
58
+ self._init_transform()
101
59
 
102
- self._node_grid = _build_node_grid(self._cell_ijk, grid, temporary_store)
103
- node_count = self._node_grid.get_voxel_count()
104
- self._node_ijk = wp.array(shape=(node_count,), dtype=wp.vec3i, device=device)
105
- self._node_grid.get_voxels(out=self._node_ijk)
60
+ def reference_cell(self) -> Element:
61
+ return Element.CUBE
106
62
 
107
- self._face_grid = None
108
- self._face_ijk = None
63
+ def reference_side(self) -> Element:
64
+ return Element.SQUARE
109
65
 
110
- self._edge_grid = None
111
- self._edge_count = 0
66
+ def _init_transform(self):
67
+ transform = np.array(self.transform).reshape(3, 3)
112
68
 
113
- transform = np.array(self._cell_grid_info.transform_matrix).reshape(3, 3)
114
- self._inverse_transform = wp.mat33f(np.linalg.inv(transform))
115
- self._cell_volume = abs(np.linalg.det(transform))
116
- self._face_areas = wp.vec3(
117
- tuple(np.linalg.norm(np.cross(transform[:, k - 2], transform[:, k - 1])) for k in range(3))
118
- )
69
+ diag = np.diag(transform)
70
+ if np.max(np.abs(transform - np.diag(diag))) < 1.0e-6 * np.max(diag):
71
+ # Rectangular voxels
72
+ self._inverse_transform = wp.mat33f(
73
+ 1.0 / diag[0], 0.0, 0.0, 0.0, 1.0 / diag[1], 0.0, 0.0, 0.0, 1.0 / diag[2]
74
+ )
75
+ self._cell_volume = wp.float32(diag[0] * diag[1] * diag[2])
76
+ self._face_areas = wp.vec3(diag[1] * diag[2], diag[2] * diag[0], diag[0] * diag[1])
77
+ else:
78
+ self._inverse_transform = wp.mat33f(np.linalg.inv(transform))
79
+ self._cell_volume = wp.float32(abs(np.linalg.det(transform)))
80
+ self._face_areas = wp.vec3(
81
+ tuple(np.linalg.norm(np.cross(transform[:, k - 2], transform[:, k - 1])) for k in range(3))
82
+ )
83
+
84
+ @property
85
+ def transform(self):
86
+ return self._cell_grid_info.transform_matrix
119
87
 
120
88
  @property
121
89
  def cell_grid(self) -> wp.Volume:
@@ -130,11 +98,6 @@ class Nanogrid(Geometry):
130
98
  self._ensure_face_grid()
131
99
  return self._face_grid
132
100
 
133
- @property
134
- def edge_grid(self) -> wp.Volume:
135
- self._ensure_edge_grid()
136
- return self._edge_grid
137
-
138
101
  def cell_count(self):
139
102
  return self._cell_ijk.shape[0]
140
103
 
@@ -149,77 +112,19 @@ class Nanogrid(Geometry):
149
112
  self._ensure_face_grid()
150
113
  return self._boundary_face_indices.shape[0]
151
114
 
152
- def edge_count(self):
153
- self._ensure_edge_grid()
154
- return self._edge_count
155
-
156
- def reference_cell(self) -> Cube:
157
- return Cube()
158
-
159
- def reference_side(self) -> Square:
160
- return Square()
161
-
162
- CellArg = NanogridCellArg
163
-
164
- @cache.cached_arg_value
165
- def cell_arg_value(self, device) -> CellArg:
166
- args = self.CellArg()
167
- self.fill_cell_arg(args, device)
168
- return args
169
-
170
- def fill_cell_arg(self, arg, device):
171
- arg.cell_grid = self._cell_grid.id
172
- arg.cell_ijk = self._cell_ijk
173
-
174
- arg.inverse_transform = self._inverse_transform
175
- arg.cell_volume = self._cell_volume
176
-
177
- @wp.func
178
- def cell_position(args: CellArg, s: Sample):
179
- uvw = wp.vec3(args.cell_ijk[s.element_index]) + s.element_coords
180
- return wp.volume_index_to_world(args.cell_grid, uvw - wp.vec3(0.5))
181
-
182
- @wp.func
183
- def cell_deformation_gradient(args: CellArg, s: Sample):
184
- return wp.inverse(args.inverse_transform)
185
-
186
- @wp.func
187
- def cell_inverse_deformation_gradient(args: CellArg, s: Sample):
188
- return args.inverse_transform
189
-
190
- def supports_cell_lookup(self, device):
191
- return True
192
-
193
- @wp.func
194
- def _lookup_cell_index(args: NanogridCellArg, i: int, j: int, k: int):
195
- return wp.volume_lookup_index(args.cell_grid, i, j, k)
196
-
197
- @wp.func
198
- def _cell_coordinates_local(args: NanogridCellArg, cell_index: int, uvw: wp.vec3):
199
- ijk = wp.vec3(args.cell_ijk[cell_index])
200
- rel_pos = uvw - ijk
201
- return rel_pos
202
-
203
- @wp.func
204
- def _cell_closest_point_local(args: NanogridCellArg, cell_index: int, uvw: wp.vec3):
205
- ijk = wp.vec3(args.cell_ijk[cell_index])
206
- rel_pos = uvw - ijk
207
- coords = wp.min(wp.max(rel_pos, wp.vec3(0.0)), wp.vec3(1.0))
208
- return wp.length_sq(wp.volume_index_to_world_dir(args.cell_grid, coords - rel_pos)), coords
115
+ @wp.struct
116
+ class SideIndexArg:
117
+ boundary_face_indices: wp.array(dtype=int)
209
118
 
210
- @wp.func
211
- def cell_coordinates(args: NanogridCellArg, cell_index: int, pos: wp.vec3):
212
- uvw = wp.volume_world_to_index(args.cell_grid, pos) + wp.vec3(0.5)
213
- return Nanogrid._cell_coordinates_local(args, cell_index, uvw)
119
+ def fill_side_index_arg(self, arg: SideIndexArg, device):
120
+ self._ensure_face_grid()
121
+ arg.boundary_face_indices = self._boundary_face_indices.to(device)
214
122
 
215
123
  @wp.func
216
- def cell_closest_point(args: NanogridCellArg, cell_index: int, pos: wp.vec3):
217
- uvw = wp.volume_world_to_index(args.cell_grid, pos) + wp.vec3(0.5)
218
- dist, coords = Nanogrid._cell_closest_point_local(args, cell_index, uvw)
219
- return coords, dist
124
+ def boundary_side_index(args: SideIndexArg, boundary_side_index: int):
125
+ return args.boundary_face_indices[boundary_side_index]
220
126
 
221
- @staticmethod
222
- def _make_filtered_cell_lookup(grid_geo, filter_func: wp.Function = None):
127
+ def make_filtered_cell_lookup(grid_geo, filter_func: wp.Function = None):
223
128
  suffix = f"{grid_geo.name}{filter_func.key if filter_func is not None else ''}"
224
129
 
225
130
  @cache.dynamic_func(suffix=suffix)
@@ -285,49 +190,53 @@ class Nanogrid(Geometry):
285
190
 
286
191
  return cell_lookup
287
192
 
288
- def make_filtered_cell_lookup(self, filter_func):
289
- return Nanogrid._make_filtered_cell_lookup(self, filter_func)
193
+ def _ensure_face_grid(self):
194
+ if self._face_ijk is None:
195
+ self._build_face_grid()
290
196
 
291
197
  @wp.func
292
- def cell_measure(args: CellArg, s: Sample):
293
- return args.cell_volume
198
+ def _add_axis_flag(ijk: wp.vec3i, axis: int):
199
+ coord = ijk[axis]
200
+ ijk[axis] = wp.where(coord < 0, coord & (~NanogridBase.GRID_AXIS_FLAG), coord | NanogridBase.GRID_AXIS_FLAG)
201
+ return ijk
294
202
 
295
203
  @wp.func
296
- def cell_normal(args: CellArg, s: Sample):
297
- return wp.vec3(0.0)
204
+ def _extract_axis_flag(ijk: wp.vec3i):
205
+ for ax in range(3):
206
+ coord = ijk[ax]
207
+ if coord < 0:
208
+ if (ijk[ax] & NanogridBase.GRID_AXIS_FLAG) == 0:
209
+ ijk[ax] = ijk[ax] | NanogridBase.GRID_AXIS_FLAG
210
+ return ax, ijk
211
+ else:
212
+ if (ijk[ax] & NanogridBase.GRID_AXIS_FLAG) != 0:
213
+ ijk[ax] = ijk[ax] & (~NanogridBase.GRID_AXIS_FLAG)
214
+ return ax, ijk
298
215
 
299
- SideArg = NanogridSideArg
216
+ return -1, ijk
300
217
 
301
- @cache.cached_arg_value
302
- def side_arg_value(self, device) -> SideArg:
303
- args = self.SideArg()
304
- self.fill_side_arg(args, device)
305
- return args
218
+ @wp.func
219
+ def _make_face_flags(axis: int, plus_cell_index: int, minus_cell_index: int):
220
+ plus_boundary = wp.uint8(wp.where(plus_cell_index == -1, 1, 0)) << NanogridBase.FACE_OUTER_OFFSET_BIT
221
+ minus_boundary = wp.uint8(wp.where(minus_cell_index == -1, 1, 0)) << NanogridBase.FACE_INNER_OFFSET_BIT
306
222
 
307
- def fill_side_arg(self, arg: SideArg, device):
308
- self._ensure_face_grid()
309
- self.fill_cell_arg(arg.cell_arg, device)
310
- arg.face_ijk = self._face_ijk.to(device)
311
- arg.face_flags = self._face_flags.to(device)
312
- arg.face_areas = self._face_areas
223
+ return wp.uint8(axis) | plus_boundary | minus_boundary
313
224
 
314
- @wp.struct
315
- class SideIndexArg:
316
- boundary_face_indices: wp.array(dtype=int)
225
+ @wp.func
226
+ def _get_boundary_mask(flags: wp.uint8):
227
+ return int((flags >> NanogridBase.FACE_OUTER_OFFSET_BIT) | (flags >> NanogridBase.FACE_INNER_OFFSET_BIT)) & 1
317
228
 
318
- @cache.cached_arg_value
319
- def side_index_arg_value(self, device) -> SideIndexArg:
320
- args = self.SideIndexArg()
321
- self.fill_side_index_arg(args, device)
322
- return args
229
+ @wp.func
230
+ def _get_face_axis(flags: wp.uint8):
231
+ return wp.int32(flags & NanogridBase.FACE_AXIS_MASK)
323
232
 
324
- def fill_side_index_arg(self, arg: SideIndexArg, device):
325
- self._ensure_face_grid()
326
- arg.boundary_face_indices = self._boundary_face_indices.to(device)
233
+ @wp.func
234
+ def _get_face_inner_offset(flags: wp.uint8):
235
+ return wp.int32(flags >> NanogridBase.FACE_INNER_OFFSET_BIT) & 1
327
236
 
328
237
  @wp.func
329
- def boundary_side_index(args: SideIndexArg, boundary_side_index: int):
330
- return args.boundary_face_indices[boundary_side_index]
238
+ def _get_face_outer_offset(flags: wp.uint8):
239
+ return wp.int32(flags >> NanogridBase.FACE_OUTER_OFFSET_BIT) & 1
331
240
 
332
241
  @wp.func
333
242
  def _side_to_cell_coords(axis: int, flip: int, inner: float, side_coords: Coords):
@@ -342,16 +251,141 @@ class Nanogrid(Geometry):
342
251
  return Coords(cell_coords[(axis + 1 + flip) % 3], cell_coords[(axis + 2 - flip) % 3], 0.0)
343
252
 
344
253
  @wp.func
345
- def _get_face_axis(flags: wp.uint8):
346
- return wp.int32(flags & FACE_AXIS_MASK)
254
+ def _face_tangent_vecs(cell_grid: wp.uint64, axis: int, flip: int):
255
+ u_axis = wp.vec3()
256
+ v_axis = wp.vec3()
257
+ u_axis[(axis + 1 + flip) % 3] = 1.0
258
+ v_axis[(axis + 2 - flip) % 3] = 1.0
259
+ return wp.volume_index_to_world_dir(cell_grid, u_axis), wp.volume_index_to_world_dir(cell_grid, v_axis)
260
+
261
+
262
+ @wp.struct
263
+ class NanogridCellArg:
264
+ # Utility device functions
265
+ cell_grid: wp.uint64
266
+ cell_ijk: wp.array(dtype=wp.vec3i)
267
+ inverse_transform: wp.mat33
268
+ cell_volume: float
269
+
270
+
271
+ @wp.struct
272
+ class NanogridSideArg:
273
+ # Utility device functions
274
+ cell_arg: NanogridCellArg
275
+ face_ijk: wp.array(dtype=wp.vec3i)
276
+ face_flags: wp.array(dtype=wp.uint8)
277
+ face_areas: wp.vec3
278
+
279
+
280
+ class Nanogrid(NanogridBase):
281
+ """Sparse grid geometry"""
282
+
283
+ def __init__(self, grid: wp.Volume, temporary_store: Optional[cache.TemporaryStore] = None):
284
+ """
285
+ Constructs a sparse grid geometry from an in-memory NanoVDB volume.
286
+
287
+ Args:
288
+ grid: The NanoVDB volume. Any type is accepted, but for indexing efficiency an index grid is recommended.
289
+ If `grid` is an 'on' index grid, cells will be created for active voxels only, otherwise cells will
290
+ be created for all leaf voxels.
291
+ temporary_store: shared pool from which to allocate temporary arrays
292
+ """
293
+
294
+ self._cell_grid = grid
295
+ self._cell_grid_info = grid.get_grid_info()
296
+
297
+ device = self._cell_grid.device
298
+ cell_ijk = wp.array(dtype=wp.vec3i, shape=(grid.get_voxel_count(),), device=device)
299
+ grid.get_voxels(out=cell_ijk)
300
+
301
+ node_grid = _build_node_grid(cell_ijk, grid, temporary_store)
302
+ node_count = node_grid.get_voxel_count()
303
+ node_ijk = wp.array(shape=(node_count,), dtype=wp.vec3i, device=device)
304
+ node_grid.get_voxels(out=node_ijk)
305
+
306
+ super().__init__(grid, cell_ijk, node_grid, node_ijk)
307
+
308
+ self._edge_count = 0
309
+ self._edge_grid = None
310
+
311
+ @property
312
+ def edge_grid(self) -> wp.Volume:
313
+ self._ensure_edge_grid()
314
+ return self._edge_grid
315
+
316
+ def edge_count(self):
317
+ self._ensure_edge_grid()
318
+ return self._edge_count
319
+
320
+ CellArg = NanogridCellArg
321
+
322
+ def fill_cell_arg(self, arg, device):
323
+ arg.cell_grid = self._cell_grid.id
324
+ arg.cell_ijk = self._cell_ijk
325
+
326
+ arg.inverse_transform = self._inverse_transform
327
+ arg.cell_volume = self._cell_volume
347
328
 
348
329
  @wp.func
349
- def _get_face_inner_offset(flags: wp.uint8):
350
- return wp.int32(flags >> FACE_INNER_OFFSET_BIT) & 1
330
+ def cell_position(args: CellArg, s: Sample):
331
+ uvw = wp.vec3(args.cell_ijk[s.element_index]) + s.element_coords
332
+ return wp.volume_index_to_world(args.cell_grid, uvw - wp.vec3(0.5))
351
333
 
352
334
  @wp.func
353
- def _get_face_outer_offset(flags: wp.uint8):
354
- return wp.int32(flags >> FACE_OUTER_OFFSET_BIT) & 1
335
+ def cell_deformation_gradient(args: CellArg, s: Sample):
336
+ return wp.inverse(args.inverse_transform)
337
+
338
+ @wp.func
339
+ def cell_inverse_deformation_gradient(args: CellArg, s: Sample):
340
+ return args.inverse_transform
341
+
342
+ def supports_cell_lookup(self, device):
343
+ return True
344
+
345
+ @wp.func
346
+ def _lookup_cell_index(args: NanogridCellArg, i: int, j: int, k: int):
347
+ return wp.volume_lookup_index(args.cell_grid, i, j, k)
348
+
349
+ @wp.func
350
+ def _cell_coordinates_local(args: NanogridCellArg, cell_index: int, uvw: wp.vec3):
351
+ ijk = wp.vec3(args.cell_ijk[cell_index])
352
+ rel_pos = uvw - ijk
353
+ return rel_pos
354
+
355
+ @wp.func
356
+ def _cell_closest_point_local(args: NanogridCellArg, cell_index: int, uvw: wp.vec3):
357
+ ijk = wp.vec3(args.cell_ijk[cell_index])
358
+ rel_pos = uvw - ijk
359
+ coords = wp.min(wp.max(rel_pos, wp.vec3(0.0)), wp.vec3(1.0))
360
+ return wp.length_sq(wp.volume_index_to_world_dir(args.cell_grid, coords - rel_pos)), coords
361
+
362
+ @wp.func
363
+ def cell_coordinates(args: NanogridCellArg, cell_index: int, pos: wp.vec3):
364
+ uvw = wp.volume_world_to_index(args.cell_grid, pos) + wp.vec3(0.5)
365
+ return Nanogrid._cell_coordinates_local(args, cell_index, uvw)
366
+
367
+ @wp.func
368
+ def cell_closest_point(args: NanogridCellArg, cell_index: int, pos: wp.vec3):
369
+ uvw = wp.volume_world_to_index(args.cell_grid, pos) + wp.vec3(0.5)
370
+ dist, coords = Nanogrid._cell_closest_point_local(args, cell_index, uvw)
371
+ return coords, dist
372
+
373
+ @wp.func
374
+ def cell_measure(args: CellArg, s: Sample):
375
+ return args.cell_volume
376
+
377
+ @wp.func
378
+ def cell_normal(args: CellArg, s: Sample):
379
+ return wp.vec3(0.0)
380
+
381
+ SideArg = NanogridSideArg
382
+
383
+ def fill_side_arg(self, arg: SideArg, device):
384
+ self._ensure_face_grid()
385
+ self.fill_cell_arg(arg.cell_arg, device)
386
+ arg.face_ijk = self._face_ijk.to(device)
387
+ arg.face_flags = self._face_flags.to(device)
388
+ arg.face_areas = self._face_areas
355
389
 
356
390
  @wp.func
357
391
  def side_position(args: SideArg, s: Sample):
@@ -365,14 +399,6 @@ class Nanogrid(Geometry):
365
399
  cell_grid = args.cell_arg.cell_grid
366
400
  return wp.volume_index_to_world(cell_grid, uvw - wp.vec3(0.5))
367
401
 
368
- @wp.func
369
- def _face_tangent_vecs(cell_grid: wp.uint64, axis: int, flip: int):
370
- u_axis = wp.vec3()
371
- v_axis = wp.vec3()
372
- u_axis[(axis + 1 + flip) % 3] = 1.0
373
- v_axis[(axis + 2 - flip) % 3] = 1.0
374
- return wp.volume_index_to_world_dir(cell_grid, u_axis), wp.volume_index_to_world_dir(cell_grid, v_axis)
375
-
376
402
  @wp.func
377
403
  def side_deformation_gradient(args: SideArg, s: Sample):
378
404
  flags = args.face_flags[s.element_index]
@@ -509,19 +535,15 @@ class Nanogrid(Geometry):
509
535
  _build_face_flags,
510
536
  dim=face_count,
511
537
  device=device,
512
- inputs=[self._cell_grid.id, self._face_ijk, self._face_flags, boundary_face_mask.array],
538
+ inputs=[self._cell_grid.id, self._face_ijk, self._face_flags, boundary_face_mask],
513
539
  )
514
- boundary_face_indices, _ = utils.masked_indices(boundary_face_mask.array)
540
+ boundary_face_indices, _ = utils.masked_indices(boundary_face_mask)
515
541
  self._boundary_face_indices = boundary_face_indices.detach()
516
542
 
517
543
  def _build_edge_grid(self, temporary_store: Optional[cache.TemporaryStore] = None):
518
544
  self._edge_grid = _build_edge_grid(self._cell_ijk, self._cell_grid, temporary_store)
519
545
  self._edge_count = self._edge_grid.get_voxel_count()
520
546
 
521
- def _ensure_face_grid(self):
522
- if self._face_ijk is None:
523
- self._build_face_grid()
524
-
525
547
  def _ensure_edge_grid(self):
526
548
  if self._edge_grid is None:
527
549
  self._build_edge_grid()
@@ -543,13 +565,13 @@ def _cell_face_indices(
543
565
  ):
544
566
  cell = wp.tid()
545
567
  ijk = cell_ijk[cell]
546
- node_ijk[cell, 0] = _add_axis_flag(ijk, 0)
547
- node_ijk[cell, 1] = _add_axis_flag(ijk, 1)
548
- node_ijk[cell, 2] = _add_axis_flag(ijk, 2)
568
+ node_ijk[cell, 0] = NanogridBase._add_axis_flag(ijk, 0)
569
+ node_ijk[cell, 1] = NanogridBase._add_axis_flag(ijk, 1)
570
+ node_ijk[cell, 2] = NanogridBase._add_axis_flag(ijk, 2)
549
571
 
550
- node_ijk[cell, 3] = _add_axis_flag(ijk + wp.vec3i(1, 0, 0), 0)
551
- node_ijk[cell, 4] = _add_axis_flag(ijk + wp.vec3i(0, 1, 0), 1)
552
- node_ijk[cell, 5] = _add_axis_flag(ijk + wp.vec3i(0, 0, 1), 2)
572
+ node_ijk[cell, 3] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 0, 0), 0)
573
+ node_ijk[cell, 4] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 1, 0), 1)
574
+ node_ijk[cell, 5] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 0, 1), 2)
553
575
 
554
576
 
555
577
  @wp.kernel
@@ -559,32 +581,30 @@ def _cell_edge_indices(
559
581
  ):
560
582
  cell = wp.tid()
561
583
  ijk = cell_ijk[cell]
562
- edge_ijk[cell, 0] = _add_axis_flag(ijk, 0)
563
- edge_ijk[cell, 1] = _add_axis_flag(ijk, 1)
564
- edge_ijk[cell, 2] = _add_axis_flag(ijk, 2)
584
+ edge_ijk[cell, 0] = NanogridBase._add_axis_flag(ijk, 0)
585
+ edge_ijk[cell, 1] = NanogridBase._add_axis_flag(ijk, 1)
586
+ edge_ijk[cell, 2] = NanogridBase._add_axis_flag(ijk, 2)
565
587
 
566
- edge_ijk[cell, 3] = _add_axis_flag(ijk + wp.vec3i(0, 1, 0), 0)
567
- edge_ijk[cell, 4] = _add_axis_flag(ijk + wp.vec3i(0, 0, 1), 1)
568
- edge_ijk[cell, 5] = _add_axis_flag(ijk + wp.vec3i(1, 0, 0), 2)
588
+ edge_ijk[cell, 3] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 1, 0), 0)
589
+ edge_ijk[cell, 4] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 0, 1), 1)
590
+ edge_ijk[cell, 5] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 0, 0), 2)
569
591
 
570
- edge_ijk[cell, 6] = _add_axis_flag(ijk + wp.vec3i(0, 1, 1), 0)
571
- edge_ijk[cell, 7] = _add_axis_flag(ijk + wp.vec3i(1, 0, 1), 1)
572
- edge_ijk[cell, 8] = _add_axis_flag(ijk + wp.vec3i(1, 1, 0), 2)
592
+ edge_ijk[cell, 6] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 1, 1), 0)
593
+ edge_ijk[cell, 7] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 0, 1), 1)
594
+ edge_ijk[cell, 8] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 1, 0), 2)
573
595
 
574
- edge_ijk[cell, 9] = _add_axis_flag(ijk + wp.vec3i(0, 0, 1), 0)
575
- edge_ijk[cell, 10] = _add_axis_flag(ijk + wp.vec3i(1, 0, 0), 1)
576
- edge_ijk[cell, 11] = _add_axis_flag(ijk + wp.vec3i(0, 1, 0), 2)
596
+ edge_ijk[cell, 9] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 0, 1), 0)
597
+ edge_ijk[cell, 10] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 0, 0), 1)
598
+ edge_ijk[cell, 11] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 1, 0), 2)
577
599
 
578
600
 
579
601
  def _build_node_grid(cell_ijk, grid: wp.Volume, temporary_store: cache.TemporaryStore):
580
602
  cell_count = cell_ijk.shape[0]
581
603
 
582
604
  cell_nodes = cache.borrow_temporary(temporary_store, shape=(cell_count, 8), dtype=wp.vec3i, device=cell_ijk.device)
583
- wp.launch(
584
- _cell_node_indices, dim=cell_nodes.array.shape, inputs=[cell_ijk, cell_nodes.array], device=cell_ijk.device
585
- )
605
+ wp.launch(_cell_node_indices, dim=cell_nodes.shape, inputs=[cell_ijk, cell_nodes], device=cell_ijk.device)
586
606
  node_grid = wp.Volume.allocate_by_voxels(
587
- cell_nodes.array.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
607
+ cell_nodes.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
588
608
  )
589
609
 
590
610
  return node_grid
@@ -594,9 +614,9 @@ def _build_face_grid(cell_ijk, grid: wp.Volume, temporary_store: cache.Temporary
594
614
  cell_count = cell_ijk.shape[0]
595
615
 
596
616
  cell_faces = cache.borrow_temporary(temporary_store, shape=(cell_count, 6), dtype=wp.vec3i, device=cell_ijk.device)
597
- wp.launch(_cell_face_indices, dim=cell_count, inputs=[cell_ijk, cell_faces.array], device=cell_ijk.device)
617
+ wp.launch(_cell_face_indices, dim=cell_count, inputs=[cell_ijk, cell_faces], device=cell_ijk.device)
598
618
  face_grid = wp.Volume.allocate_by_voxels(
599
- cell_faces.array.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
619
+ cell_faces.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
600
620
  )
601
621
 
602
622
  return face_grid
@@ -606,27 +626,14 @@ def _build_edge_grid(cell_ijk, grid: wp.Volume, temporary_store: cache.Temporary
606
626
  cell_count = cell_ijk.shape[0]
607
627
 
608
628
  cell_edges = cache.borrow_temporary(temporary_store, shape=(cell_count, 12), dtype=wp.vec3i, device=cell_ijk.device)
609
- wp.launch(_cell_edge_indices, dim=cell_count, inputs=[cell_ijk, cell_edges.array], device=cell_ijk.device)
629
+ wp.launch(_cell_edge_indices, dim=cell_count, inputs=[cell_ijk, cell_edges], device=cell_ijk.device)
610
630
  edge_grid = wp.Volume.allocate_by_voxels(
611
- cell_edges.array.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
631
+ cell_edges.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
612
632
  )
613
633
 
614
634
  return edge_grid
615
635
 
616
636
 
617
- @wp.func
618
- def _make_face_flags(axis: int, plus_cell_index: int, minus_cell_index: int):
619
- plus_boundary = wp.uint8(wp.where(plus_cell_index == -1, 1, 0)) << FACE_OUTER_OFFSET_BIT
620
- minus_boundary = wp.uint8(wp.where(minus_cell_index == -1, 1, 0)) << FACE_INNER_OFFSET_BIT
621
-
622
- return wp.uint8(axis) | plus_boundary | minus_boundary
623
-
624
-
625
- @wp.func
626
- def _get_boundary_mask(flags: wp.uint8):
627
- return int((flags >> FACE_OUTER_OFFSET_BIT) | (flags >> FACE_INNER_OFFSET_BIT)) & 1
628
-
629
-
630
637
  @wp.kernel
631
638
  def _build_face_flags(
632
639
  cell_grid: wp.uint64,
@@ -636,7 +643,7 @@ def _build_face_flags(
636
643
  ):
637
644
  face = wp.tid()
638
645
 
639
- axis, ijk = _extract_axis_flag(face_ijk[face])
646
+ axis, ijk = NanogridBase._extract_axis_flag(face_ijk[face])
640
647
 
641
648
  ijk_minus = ijk
642
649
  ijk_minus[axis] -= 1
@@ -646,6 +653,6 @@ def _build_face_flags(
646
653
 
647
654
  face_ijk[face] = ijk
648
655
 
649
- flags = _make_face_flags(axis, plus_cell_index, minus_cell_index)
656
+ flags = NanogridBase._make_face_flags(axis, plus_cell_index, minus_cell_index)
650
657
  face_flags[face] = flags
651
- boundary_face_mask[face] = _get_boundary_mask(flags)
658
+ boundary_face_mask[face] = NanogridBase._get_boundary_mask(flags)