warp-lang 1.9.1__py3-none-win_amd64.whl → 1.10.0__py3-none-win_amd64.whl

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

Potentially problematic release.


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

Files changed (346) hide show
  1. warp/__init__.py +301 -287
  2. warp/__init__.pyi +882 -305
  3. warp/_src/__init__.py +14 -0
  4. warp/_src/autograd.py +1077 -0
  5. warp/_src/build.py +620 -0
  6. warp/_src/build_dll.py +642 -0
  7. warp/{builtins.py → _src/builtins.py} +1435 -379
  8. warp/_src/codegen.py +4361 -0
  9. warp/{config.py → _src/config.py} +178 -169
  10. warp/_src/constants.py +59 -0
  11. warp/_src/context.py +8352 -0
  12. warp/_src/dlpack.py +464 -0
  13. warp/_src/fabric.py +362 -0
  14. warp/_src/fem/__init__.py +14 -0
  15. warp/_src/fem/adaptivity.py +510 -0
  16. warp/_src/fem/cache.py +689 -0
  17. warp/_src/fem/dirichlet.py +190 -0
  18. warp/{fem → _src/fem}/domain.py +42 -30
  19. warp/_src/fem/field/__init__.py +131 -0
  20. warp/_src/fem/field/field.py +703 -0
  21. warp/{fem → _src/fem}/field/nodal_field.py +32 -15
  22. warp/{fem → _src/fem}/field/restriction.py +3 -1
  23. warp/{fem → _src/fem}/field/virtual.py +55 -27
  24. warp/_src/fem/geometry/__init__.py +32 -0
  25. warp/{fem → _src/fem}/geometry/adaptive_nanogrid.py +79 -163
  26. warp/_src/fem/geometry/closest_point.py +99 -0
  27. warp/{fem → _src/fem}/geometry/deformed_geometry.py +16 -22
  28. warp/{fem → _src/fem}/geometry/element.py +34 -10
  29. warp/{fem → _src/fem}/geometry/geometry.py +50 -20
  30. warp/{fem → _src/fem}/geometry/grid_2d.py +14 -23
  31. warp/{fem → _src/fem}/geometry/grid_3d.py +14 -23
  32. warp/{fem → _src/fem}/geometry/hexmesh.py +42 -63
  33. warp/{fem → _src/fem}/geometry/nanogrid.py +256 -247
  34. warp/{fem → _src/fem}/geometry/partition.py +123 -63
  35. warp/{fem → _src/fem}/geometry/quadmesh.py +28 -45
  36. warp/{fem → _src/fem}/geometry/tetmesh.py +42 -63
  37. warp/{fem → _src/fem}/geometry/trimesh.py +28 -45
  38. warp/{fem → _src/fem}/integrate.py +166 -158
  39. warp/_src/fem/linalg.py +385 -0
  40. warp/_src/fem/operator.py +398 -0
  41. warp/_src/fem/polynomial.py +231 -0
  42. warp/{fem → _src/fem}/quadrature/pic_quadrature.py +17 -20
  43. warp/{fem → _src/fem}/quadrature/quadrature.py +97 -47
  44. warp/_src/fem/space/__init__.py +248 -0
  45. warp/{fem → _src/fem}/space/basis_function_space.py +22 -11
  46. warp/_src/fem/space/basis_space.py +681 -0
  47. warp/{fem → _src/fem}/space/dof_mapper.py +5 -3
  48. warp/{fem → _src/fem}/space/function_space.py +16 -13
  49. warp/{fem → _src/fem}/space/grid_2d_function_space.py +6 -7
  50. warp/{fem → _src/fem}/space/grid_3d_function_space.py +6 -4
  51. warp/{fem → _src/fem}/space/hexmesh_function_space.py +6 -10
  52. warp/{fem → _src/fem}/space/nanogrid_function_space.py +5 -9
  53. warp/{fem → _src/fem}/space/partition.py +119 -60
  54. warp/{fem → _src/fem}/space/quadmesh_function_space.py +6 -10
  55. warp/{fem → _src/fem}/space/restriction.py +68 -33
  56. warp/_src/fem/space/shape/__init__.py +152 -0
  57. warp/{fem → _src/fem}/space/shape/cube_shape_function.py +11 -9
  58. warp/{fem → _src/fem}/space/shape/shape_function.py +10 -9
  59. warp/{fem → _src/fem}/space/shape/square_shape_function.py +8 -6
  60. warp/{fem → _src/fem}/space/shape/tet_shape_function.py +5 -3
  61. warp/{fem → _src/fem}/space/shape/triangle_shape_function.py +5 -3
  62. warp/{fem → _src/fem}/space/tetmesh_function_space.py +5 -9
  63. warp/_src/fem/space/topology.py +461 -0
  64. warp/{fem → _src/fem}/space/trimesh_function_space.py +5 -9
  65. warp/_src/fem/types.py +114 -0
  66. warp/_src/fem/utils.py +488 -0
  67. warp/_src/jax.py +188 -0
  68. warp/_src/jax_experimental/__init__.py +14 -0
  69. warp/_src/jax_experimental/custom_call.py +389 -0
  70. warp/_src/jax_experimental/ffi.py +1286 -0
  71. warp/_src/jax_experimental/xla_ffi.py +658 -0
  72. warp/_src/marching_cubes.py +710 -0
  73. warp/_src/math.py +416 -0
  74. warp/_src/optim/__init__.py +14 -0
  75. warp/_src/optim/adam.py +165 -0
  76. warp/_src/optim/linear.py +1608 -0
  77. warp/_src/optim/sgd.py +114 -0
  78. warp/_src/paddle.py +408 -0
  79. warp/_src/render/__init__.py +14 -0
  80. warp/_src/render/imgui_manager.py +291 -0
  81. warp/_src/render/render_opengl.py +3638 -0
  82. warp/_src/render/render_usd.py +939 -0
  83. warp/_src/render/utils.py +162 -0
  84. warp/_src/sparse.py +2718 -0
  85. warp/_src/tape.py +1208 -0
  86. warp/{thirdparty → _src/thirdparty}/unittest_parallel.py +9 -2
  87. warp/_src/torch.py +393 -0
  88. warp/_src/types.py +5888 -0
  89. warp/_src/utils.py +1695 -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 +3 -3
  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 +521 -250
  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 +18 -17
  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 +578 -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.0.dist-info}/METADATA +46 -99
  267. warp_lang-1.10.0.dist-info/RECORD +468 -0
  268. warp_lang-1.10.0.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
  269. warp_lang-1.10.0.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
  270. warp_lang-1.10.0.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
  271. warp_lang-1.10.0.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
  272. warp_lang-1.10.0.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
  273. warp_lang-1.10.0.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
  274. warp_lang-1.10.0.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
  275. warp_lang-1.10.0.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
  276. warp_lang-1.10.0.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
  277. warp_lang-1.10.0.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
  278. warp_lang-1.10.0.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
  279. warp_lang-1.10.0.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
  280. warp_lang-1.10.0.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
  281. warp_lang-1.10.0.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
  282. warp_lang-1.10.0.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.0.dist-info}/WHEEL +0 -0
  345. {warp_lang-1.9.1.dist-info → warp_lang-1.10.0.dist-info}/licenses/LICENSE.md +0 -0
  346. {warp_lang-1.9.1.dist-info → warp_lang-1.10.0.dist-info}/top_level.txt +0 -0
@@ -18,104 +18,74 @@ 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))
27
+ _wp_module_name_ = "warp.fem.geometry.nanogrid"
30
28
 
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
29
 
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"""
30
+ class NanogridBase(Geometry):
31
+ """Base class for regular and adaptive Nanogrid"""
79
32
 
80
33
  dimension = 3
81
34
 
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.
35
+ # Flag used for building edge/face grids to disambiguiate axis within the grid
36
+ # Morton indexing allows for
37
+ GRID_AXIS_FLAG = wp.constant(wp.int32(1 << 20))
85
38
 
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
- """
39
+ FACE_AXIS_MASK = wp.constant(wp.uint8((1 << 2) - 1))
40
+ FACE_INNER_OFFSET_BIT = wp.constant(wp.uint8(2))
41
+ FACE_OUTER_OFFSET_BIT = wp.constant(wp.uint8(3))
92
42
 
93
- self._cell_grid = grid
94
- self._cell_grid_info = grid.get_grid_info()
43
+ def __init__(
44
+ self,
45
+ cell_grid: wp.Volume,
46
+ cell_ijk: wp.array(dtype=wp.vec3i),
47
+ node_grid: wp.Volume,
48
+ node_ijk: wp.array(dtype=wp.vec3i),
49
+ ):
50
+ self._cell_grid = cell_grid
51
+ self._cell_ijk = cell_ijk
52
+ self._node_grid = node_grid
53
+ self._node_ijk = node_ijk
95
54
 
96
- device = grid.device
55
+ self._face_grid = None
56
+ self._face_ijk = None
57
+ self._boundary_face_indices = None
97
58
 
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)
59
+ self._cell_grid_info = cell_grid.get_grid_info()
60
+ self._init_transform()
101
61
 
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)
62
+ def reference_cell(self) -> Element:
63
+ return Element.CUBE
106
64
 
107
- self._face_grid = None
108
- self._face_ijk = None
65
+ def reference_side(self) -> Element:
66
+ return Element.SQUARE
109
67
 
110
- self._edge_grid = None
111
- self._edge_count = 0
68
+ def _init_transform(self):
69
+ transform = np.array(self.transform).reshape(3, 3)
112
70
 
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
- )
71
+ diag = np.diag(transform)
72
+ if np.max(np.abs(transform - np.diag(diag))) < 1.0e-6 * np.max(diag):
73
+ # Rectangular voxels
74
+ self._inverse_transform = wp.mat33f(
75
+ 1.0 / diag[0], 0.0, 0.0, 0.0, 1.0 / diag[1], 0.0, 0.0, 0.0, 1.0 / diag[2]
76
+ )
77
+ self._cell_volume = wp.float32(diag[0] * diag[1] * diag[2])
78
+ self._face_areas = wp.vec3(diag[1] * diag[2], diag[2] * diag[0], diag[0] * diag[1])
79
+ else:
80
+ self._inverse_transform = wp.mat33f(np.linalg.inv(transform))
81
+ self._cell_volume = wp.float32(abs(np.linalg.det(transform)))
82
+ self._face_areas = wp.vec3(
83
+ tuple(np.linalg.norm(np.cross(transform[:, k - 2], transform[:, k - 1])) for k in range(3))
84
+ )
85
+
86
+ @property
87
+ def transform(self):
88
+ return self._cell_grid_info.transform_matrix
119
89
 
120
90
  @property
121
91
  def cell_grid(self) -> wp.Volume:
@@ -130,11 +100,6 @@ class Nanogrid(Geometry):
130
100
  self._ensure_face_grid()
131
101
  return self._face_grid
132
102
 
133
- @property
134
- def edge_grid(self) -> wp.Volume:
135
- self._ensure_edge_grid()
136
- return self._edge_grid
137
-
138
103
  def cell_count(self):
139
104
  return self._cell_ijk.shape[0]
140
105
 
@@ -149,77 +114,19 @@ class Nanogrid(Geometry):
149
114
  self._ensure_face_grid()
150
115
  return self._boundary_face_indices.shape[0]
151
116
 
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
117
+ @wp.struct
118
+ class SideIndexArg:
119
+ boundary_face_indices: wp.array(dtype=int)
209
120
 
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)
121
+ def fill_side_index_arg(self, arg: SideIndexArg, device):
122
+ self._ensure_face_grid()
123
+ arg.boundary_face_indices = self._boundary_face_indices.to(device)
214
124
 
215
125
  @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
126
+ def boundary_side_index(args: SideIndexArg, boundary_side_index: int):
127
+ return args.boundary_face_indices[boundary_side_index]
220
128
 
221
- @staticmethod
222
- def _make_filtered_cell_lookup(grid_geo, filter_func: wp.Function = None):
129
+ def make_filtered_cell_lookup(grid_geo, filter_func: wp.Function = None):
223
130
  suffix = f"{grid_geo.name}{filter_func.key if filter_func is not None else ''}"
224
131
 
225
132
  @cache.dynamic_func(suffix=suffix)
@@ -285,49 +192,53 @@ class Nanogrid(Geometry):
285
192
 
286
193
  return cell_lookup
287
194
 
288
- def make_filtered_cell_lookup(self, filter_func):
289
- return Nanogrid._make_filtered_cell_lookup(self, filter_func)
195
+ def _ensure_face_grid(self):
196
+ if self._face_ijk is None:
197
+ self._build_face_grid()
290
198
 
291
199
  @wp.func
292
- def cell_measure(args: CellArg, s: Sample):
293
- return args.cell_volume
200
+ def _add_axis_flag(ijk: wp.vec3i, axis: int):
201
+ coord = ijk[axis]
202
+ ijk[axis] = wp.where(coord < 0, coord & (~NanogridBase.GRID_AXIS_FLAG), coord | NanogridBase.GRID_AXIS_FLAG)
203
+ return ijk
294
204
 
295
205
  @wp.func
296
- def cell_normal(args: CellArg, s: Sample):
297
- return wp.vec3(0.0)
206
+ def _extract_axis_flag(ijk: wp.vec3i):
207
+ for ax in range(3):
208
+ coord = ijk[ax]
209
+ if coord < 0:
210
+ if (ijk[ax] & NanogridBase.GRID_AXIS_FLAG) == 0:
211
+ ijk[ax] = ijk[ax] | NanogridBase.GRID_AXIS_FLAG
212
+ return ax, ijk
213
+ else:
214
+ if (ijk[ax] & NanogridBase.GRID_AXIS_FLAG) != 0:
215
+ ijk[ax] = ijk[ax] & (~NanogridBase.GRID_AXIS_FLAG)
216
+ return ax, ijk
298
217
 
299
- SideArg = NanogridSideArg
218
+ return -1, ijk
300
219
 
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
220
+ @wp.func
221
+ def _make_face_flags(axis: int, plus_cell_index: int, minus_cell_index: int):
222
+ plus_boundary = wp.uint8(wp.where(plus_cell_index == -1, 1, 0)) << NanogridBase.FACE_OUTER_OFFSET_BIT
223
+ minus_boundary = wp.uint8(wp.where(minus_cell_index == -1, 1, 0)) << NanogridBase.FACE_INNER_OFFSET_BIT
306
224
 
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
225
+ return wp.uint8(axis) | plus_boundary | minus_boundary
313
226
 
314
- @wp.struct
315
- class SideIndexArg:
316
- boundary_face_indices: wp.array(dtype=int)
227
+ @wp.func
228
+ def _get_boundary_mask(flags: wp.uint8):
229
+ return int((flags >> NanogridBase.FACE_OUTER_OFFSET_BIT) | (flags >> NanogridBase.FACE_INNER_OFFSET_BIT)) & 1
317
230
 
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
231
+ @wp.func
232
+ def _get_face_axis(flags: wp.uint8):
233
+ return wp.int32(flags & NanogridBase.FACE_AXIS_MASK)
323
234
 
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)
235
+ @wp.func
236
+ def _get_face_inner_offset(flags: wp.uint8):
237
+ return wp.int32(flags >> NanogridBase.FACE_INNER_OFFSET_BIT) & 1
327
238
 
328
239
  @wp.func
329
- def boundary_side_index(args: SideIndexArg, boundary_side_index: int):
330
- return args.boundary_face_indices[boundary_side_index]
240
+ def _get_face_outer_offset(flags: wp.uint8):
241
+ return wp.int32(flags >> NanogridBase.FACE_OUTER_OFFSET_BIT) & 1
331
242
 
332
243
  @wp.func
333
244
  def _side_to_cell_coords(axis: int, flip: int, inner: float, side_coords: Coords):
@@ -342,16 +253,141 @@ class Nanogrid(Geometry):
342
253
  return Coords(cell_coords[(axis + 1 + flip) % 3], cell_coords[(axis + 2 - flip) % 3], 0.0)
343
254
 
344
255
  @wp.func
345
- def _get_face_axis(flags: wp.uint8):
346
- return wp.int32(flags & FACE_AXIS_MASK)
256
+ def _face_tangent_vecs(cell_grid: wp.uint64, axis: int, flip: int):
257
+ u_axis = wp.vec3()
258
+ v_axis = wp.vec3()
259
+ u_axis[(axis + 1 + flip) % 3] = 1.0
260
+ v_axis[(axis + 2 - flip) % 3] = 1.0
261
+ return wp.volume_index_to_world_dir(cell_grid, u_axis), wp.volume_index_to_world_dir(cell_grid, v_axis)
262
+
263
+
264
+ @wp.struct
265
+ class NanogridCellArg:
266
+ # Utility device functions
267
+ cell_grid: wp.uint64
268
+ cell_ijk: wp.array(dtype=wp.vec3i)
269
+ inverse_transform: wp.mat33
270
+ cell_volume: float
271
+
272
+
273
+ @wp.struct
274
+ class NanogridSideArg:
275
+ # Utility device functions
276
+ cell_arg: NanogridCellArg
277
+ face_ijk: wp.array(dtype=wp.vec3i)
278
+ face_flags: wp.array(dtype=wp.uint8)
279
+ face_areas: wp.vec3
280
+
281
+
282
+ class Nanogrid(NanogridBase):
283
+ """Sparse grid geometry"""
284
+
285
+ def __init__(self, grid: wp.Volume, temporary_store: Optional[cache.TemporaryStore] = None):
286
+ """
287
+ Constructs a sparse grid geometry from an in-memory NanoVDB volume.
288
+
289
+ Args:
290
+ grid: The NanoVDB volume. Any type is accepted, but for indexing efficiency an index grid is recommended.
291
+ If `grid` is an 'on' index grid, cells will be created for active voxels only, otherwise cells will
292
+ be created for all leaf voxels.
293
+ temporary_store: shared pool from which to allocate temporary arrays
294
+ """
295
+
296
+ self._cell_grid = grid
297
+ self._cell_grid_info = grid.get_grid_info()
298
+
299
+ device = self._cell_grid.device
300
+ cell_ijk = wp.array(dtype=wp.vec3i, shape=(grid.get_voxel_count(),), device=device)
301
+ grid.get_voxels(out=cell_ijk)
302
+
303
+ node_grid = _build_node_grid(cell_ijk, grid, temporary_store)
304
+ node_count = node_grid.get_voxel_count()
305
+ node_ijk = wp.array(shape=(node_count,), dtype=wp.vec3i, device=device)
306
+ node_grid.get_voxels(out=node_ijk)
307
+
308
+ super().__init__(grid, cell_ijk, node_grid, node_ijk)
309
+
310
+ self._edge_count = 0
311
+ self._edge_grid = None
312
+
313
+ @property
314
+ def edge_grid(self) -> wp.Volume:
315
+ self._ensure_edge_grid()
316
+ return self._edge_grid
317
+
318
+ def edge_count(self):
319
+ self._ensure_edge_grid()
320
+ return self._edge_count
321
+
322
+ CellArg = NanogridCellArg
323
+
324
+ def fill_cell_arg(self, arg, device):
325
+ arg.cell_grid = self._cell_grid.id
326
+ arg.cell_ijk = self._cell_ijk
327
+
328
+ arg.inverse_transform = self._inverse_transform
329
+ arg.cell_volume = self._cell_volume
347
330
 
348
331
  @wp.func
349
- def _get_face_inner_offset(flags: wp.uint8):
350
- return wp.int32(flags >> FACE_INNER_OFFSET_BIT) & 1
332
+ def cell_position(args: CellArg, s: Sample):
333
+ uvw = wp.vec3(args.cell_ijk[s.element_index]) + s.element_coords
334
+ return wp.volume_index_to_world(args.cell_grid, uvw - wp.vec3(0.5))
351
335
 
352
336
  @wp.func
353
- def _get_face_outer_offset(flags: wp.uint8):
354
- return wp.int32(flags >> FACE_OUTER_OFFSET_BIT) & 1
337
+ def cell_deformation_gradient(args: CellArg, s: Sample):
338
+ return wp.inverse(args.inverse_transform)
339
+
340
+ @wp.func
341
+ def cell_inverse_deformation_gradient(args: CellArg, s: Sample):
342
+ return args.inverse_transform
343
+
344
+ def supports_cell_lookup(self, device):
345
+ return True
346
+
347
+ @wp.func
348
+ def _lookup_cell_index(args: NanogridCellArg, i: int, j: int, k: int):
349
+ return wp.volume_lookup_index(args.cell_grid, i, j, k)
350
+
351
+ @wp.func
352
+ def _cell_coordinates_local(args: NanogridCellArg, cell_index: int, uvw: wp.vec3):
353
+ ijk = wp.vec3(args.cell_ijk[cell_index])
354
+ rel_pos = uvw - ijk
355
+ return rel_pos
356
+
357
+ @wp.func
358
+ def _cell_closest_point_local(args: NanogridCellArg, cell_index: int, uvw: wp.vec3):
359
+ ijk = wp.vec3(args.cell_ijk[cell_index])
360
+ rel_pos = uvw - ijk
361
+ coords = wp.min(wp.max(rel_pos, wp.vec3(0.0)), wp.vec3(1.0))
362
+ return wp.length_sq(wp.volume_index_to_world_dir(args.cell_grid, coords - rel_pos)), coords
363
+
364
+ @wp.func
365
+ def cell_coordinates(args: NanogridCellArg, cell_index: int, pos: wp.vec3):
366
+ uvw = wp.volume_world_to_index(args.cell_grid, pos) + wp.vec3(0.5)
367
+ return Nanogrid._cell_coordinates_local(args, cell_index, uvw)
368
+
369
+ @wp.func
370
+ def cell_closest_point(args: NanogridCellArg, cell_index: int, pos: wp.vec3):
371
+ uvw = wp.volume_world_to_index(args.cell_grid, pos) + wp.vec3(0.5)
372
+ dist, coords = Nanogrid._cell_closest_point_local(args, cell_index, uvw)
373
+ return coords, dist
374
+
375
+ @wp.func
376
+ def cell_measure(args: CellArg, s: Sample):
377
+ return args.cell_volume
378
+
379
+ @wp.func
380
+ def cell_normal(args: CellArg, s: Sample):
381
+ return wp.vec3(0.0)
382
+
383
+ SideArg = NanogridSideArg
384
+
385
+ def fill_side_arg(self, arg: SideArg, device):
386
+ self._ensure_face_grid()
387
+ self.fill_cell_arg(arg.cell_arg, device)
388
+ arg.face_ijk = self._face_ijk.to(device)
389
+ arg.face_flags = self._face_flags.to(device)
390
+ arg.face_areas = self._face_areas
355
391
 
356
392
  @wp.func
357
393
  def side_position(args: SideArg, s: Sample):
@@ -365,14 +401,6 @@ class Nanogrid(Geometry):
365
401
  cell_grid = args.cell_arg.cell_grid
366
402
  return wp.volume_index_to_world(cell_grid, uvw - wp.vec3(0.5))
367
403
 
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
404
  @wp.func
377
405
  def side_deformation_gradient(args: SideArg, s: Sample):
378
406
  flags = args.face_flags[s.element_index]
@@ -509,19 +537,15 @@ class Nanogrid(Geometry):
509
537
  _build_face_flags,
510
538
  dim=face_count,
511
539
  device=device,
512
- inputs=[self._cell_grid.id, self._face_ijk, self._face_flags, boundary_face_mask.array],
540
+ inputs=[self._cell_grid.id, self._face_ijk, self._face_flags, boundary_face_mask],
513
541
  )
514
- boundary_face_indices, _ = utils.masked_indices(boundary_face_mask.array)
542
+ boundary_face_indices, _ = utils.masked_indices(boundary_face_mask)
515
543
  self._boundary_face_indices = boundary_face_indices.detach()
516
544
 
517
545
  def _build_edge_grid(self, temporary_store: Optional[cache.TemporaryStore] = None):
518
546
  self._edge_grid = _build_edge_grid(self._cell_ijk, self._cell_grid, temporary_store)
519
547
  self._edge_count = self._edge_grid.get_voxel_count()
520
548
 
521
- def _ensure_face_grid(self):
522
- if self._face_ijk is None:
523
- self._build_face_grid()
524
-
525
549
  def _ensure_edge_grid(self):
526
550
  if self._edge_grid is None:
527
551
  self._build_edge_grid()
@@ -543,13 +567,13 @@ def _cell_face_indices(
543
567
  ):
544
568
  cell = wp.tid()
545
569
  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)
570
+ node_ijk[cell, 0] = NanogridBase._add_axis_flag(ijk, 0)
571
+ node_ijk[cell, 1] = NanogridBase._add_axis_flag(ijk, 1)
572
+ node_ijk[cell, 2] = NanogridBase._add_axis_flag(ijk, 2)
549
573
 
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)
574
+ node_ijk[cell, 3] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 0, 0), 0)
575
+ node_ijk[cell, 4] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 1, 0), 1)
576
+ node_ijk[cell, 5] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 0, 1), 2)
553
577
 
554
578
 
555
579
  @wp.kernel
@@ -559,32 +583,30 @@ def _cell_edge_indices(
559
583
  ):
560
584
  cell = wp.tid()
561
585
  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)
586
+ edge_ijk[cell, 0] = NanogridBase._add_axis_flag(ijk, 0)
587
+ edge_ijk[cell, 1] = NanogridBase._add_axis_flag(ijk, 1)
588
+ edge_ijk[cell, 2] = NanogridBase._add_axis_flag(ijk, 2)
565
589
 
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)
590
+ edge_ijk[cell, 3] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 1, 0), 0)
591
+ edge_ijk[cell, 4] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 0, 1), 1)
592
+ edge_ijk[cell, 5] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 0, 0), 2)
569
593
 
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)
594
+ edge_ijk[cell, 6] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 1, 1), 0)
595
+ edge_ijk[cell, 7] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 0, 1), 1)
596
+ edge_ijk[cell, 8] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 1, 0), 2)
573
597
 
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)
598
+ edge_ijk[cell, 9] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 0, 1), 0)
599
+ edge_ijk[cell, 10] = NanogridBase._add_axis_flag(ijk + wp.vec3i(1, 0, 0), 1)
600
+ edge_ijk[cell, 11] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 1, 0), 2)
577
601
 
578
602
 
579
603
  def _build_node_grid(cell_ijk, grid: wp.Volume, temporary_store: cache.TemporaryStore):
580
604
  cell_count = cell_ijk.shape[0]
581
605
 
582
606
  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
- )
607
+ wp.launch(_cell_node_indices, dim=cell_nodes.shape, inputs=[cell_ijk, cell_nodes], device=cell_ijk.device)
586
608
  node_grid = wp.Volume.allocate_by_voxels(
587
- cell_nodes.array.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
609
+ cell_nodes.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
588
610
  )
589
611
 
590
612
  return node_grid
@@ -594,9 +616,9 @@ def _build_face_grid(cell_ijk, grid: wp.Volume, temporary_store: cache.Temporary
594
616
  cell_count = cell_ijk.shape[0]
595
617
 
596
618
  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)
619
+ wp.launch(_cell_face_indices, dim=cell_count, inputs=[cell_ijk, cell_faces], device=cell_ijk.device)
598
620
  face_grid = wp.Volume.allocate_by_voxels(
599
- cell_faces.array.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
621
+ cell_faces.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
600
622
  )
601
623
 
602
624
  return face_grid
@@ -606,27 +628,14 @@ def _build_edge_grid(cell_ijk, grid: wp.Volume, temporary_store: cache.Temporary
606
628
  cell_count = cell_ijk.shape[0]
607
629
 
608
630
  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)
631
+ wp.launch(_cell_edge_indices, dim=cell_count, inputs=[cell_ijk, cell_edges], device=cell_ijk.device)
610
632
  edge_grid = wp.Volume.allocate_by_voxels(
611
- cell_edges.array.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
633
+ cell_edges.flatten(), voxel_size=grid.get_voxel_size(), device=cell_ijk.device
612
634
  )
613
635
 
614
636
  return edge_grid
615
637
 
616
638
 
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
639
  @wp.kernel
631
640
  def _build_face_flags(
632
641
  cell_grid: wp.uint64,
@@ -636,7 +645,7 @@ def _build_face_flags(
636
645
  ):
637
646
  face = wp.tid()
638
647
 
639
- axis, ijk = _extract_axis_flag(face_ijk[face])
648
+ axis, ijk = NanogridBase._extract_axis_flag(face_ijk[face])
640
649
 
641
650
  ijk_minus = ijk
642
651
  ijk_minus[axis] -= 1
@@ -646,6 +655,6 @@ def _build_face_flags(
646
655
 
647
656
  face_ijk[face] = ijk
648
657
 
649
- flags = _make_face_flags(axis, plus_cell_index, minus_cell_index)
658
+ flags = NanogridBase._make_face_flags(axis, plus_cell_index, minus_cell_index)
650
659
  face_flags[face] = flags
651
- boundary_face_mask[face] = _get_boundary_mask(flags)
660
+ boundary_face_mask[face] = NanogridBase._get_boundary_mask(flags)