warp-lang 1.10.0__py3-none-macosx_11_0_arm64.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 (468) hide show
  1. warp/__init__.py +334 -0
  2. warp/__init__.pyi +5856 -0
  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/_src/builtins.py +10555 -0
  8. warp/_src/codegen.py +4361 -0
  9. warp/_src/config.py +178 -0
  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/_src/fem/domain.py +553 -0
  19. warp/_src/fem/field/__init__.py +131 -0
  20. warp/_src/fem/field/field.py +703 -0
  21. warp/_src/fem/field/nodal_field.py +403 -0
  22. warp/_src/fem/field/restriction.py +39 -0
  23. warp/_src/fem/field/virtual.py +1021 -0
  24. warp/_src/fem/geometry/__init__.py +32 -0
  25. warp/_src/fem/geometry/adaptive_nanogrid.py +782 -0
  26. warp/_src/fem/geometry/closest_point.py +99 -0
  27. warp/_src/fem/geometry/deformed_geometry.py +277 -0
  28. warp/_src/fem/geometry/element.py +854 -0
  29. warp/_src/fem/geometry/geometry.py +693 -0
  30. warp/_src/fem/geometry/grid_2d.py +478 -0
  31. warp/_src/fem/geometry/grid_3d.py +539 -0
  32. warp/_src/fem/geometry/hexmesh.py +956 -0
  33. warp/_src/fem/geometry/nanogrid.py +660 -0
  34. warp/_src/fem/geometry/partition.py +483 -0
  35. warp/_src/fem/geometry/quadmesh.py +597 -0
  36. warp/_src/fem/geometry/tetmesh.py +762 -0
  37. warp/_src/fem/geometry/trimesh.py +588 -0
  38. warp/_src/fem/integrate.py +2507 -0
  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/_src/fem/quadrature/__init__.py +17 -0
  43. warp/_src/fem/quadrature/pic_quadrature.py +318 -0
  44. warp/_src/fem/quadrature/quadrature.py +665 -0
  45. warp/_src/fem/space/__init__.py +248 -0
  46. warp/_src/fem/space/basis_function_space.py +499 -0
  47. warp/_src/fem/space/basis_space.py +681 -0
  48. warp/_src/fem/space/dof_mapper.py +253 -0
  49. warp/_src/fem/space/function_space.py +312 -0
  50. warp/_src/fem/space/grid_2d_function_space.py +179 -0
  51. warp/_src/fem/space/grid_3d_function_space.py +229 -0
  52. warp/_src/fem/space/hexmesh_function_space.py +255 -0
  53. warp/_src/fem/space/nanogrid_function_space.py +199 -0
  54. warp/_src/fem/space/partition.py +435 -0
  55. warp/_src/fem/space/quadmesh_function_space.py +222 -0
  56. warp/_src/fem/space/restriction.py +221 -0
  57. warp/_src/fem/space/shape/__init__.py +152 -0
  58. warp/_src/fem/space/shape/cube_shape_function.py +1107 -0
  59. warp/_src/fem/space/shape/shape_function.py +134 -0
  60. warp/_src/fem/space/shape/square_shape_function.py +928 -0
  61. warp/_src/fem/space/shape/tet_shape_function.py +829 -0
  62. warp/_src/fem/space/shape/triangle_shape_function.py +674 -0
  63. warp/_src/fem/space/tetmesh_function_space.py +270 -0
  64. warp/_src/fem/space/topology.py +461 -0
  65. warp/_src/fem/space/trimesh_function_space.py +193 -0
  66. warp/_src/fem/types.py +114 -0
  67. warp/_src/fem/utils.py +488 -0
  68. warp/_src/jax.py +188 -0
  69. warp/_src/jax_experimental/__init__.py +14 -0
  70. warp/_src/jax_experimental/custom_call.py +389 -0
  71. warp/_src/jax_experimental/ffi.py +1286 -0
  72. warp/_src/jax_experimental/xla_ffi.py +658 -0
  73. warp/_src/marching_cubes.py +710 -0
  74. warp/_src/math.py +416 -0
  75. warp/_src/optim/__init__.py +14 -0
  76. warp/_src/optim/adam.py +165 -0
  77. warp/_src/optim/linear.py +1608 -0
  78. warp/_src/optim/sgd.py +114 -0
  79. warp/_src/paddle.py +408 -0
  80. warp/_src/render/__init__.py +14 -0
  81. warp/_src/render/imgui_manager.py +291 -0
  82. warp/_src/render/render_opengl.py +3638 -0
  83. warp/_src/render/render_usd.py +939 -0
  84. warp/_src/render/utils.py +162 -0
  85. warp/_src/sparse.py +2718 -0
  86. warp/_src/tape.py +1208 -0
  87. warp/_src/thirdparty/__init__.py +0 -0
  88. warp/_src/thirdparty/appdirs.py +598 -0
  89. warp/_src/thirdparty/dlpack.py +145 -0
  90. warp/_src/thirdparty/unittest_parallel.py +676 -0
  91. warp/_src/torch.py +393 -0
  92. warp/_src/types.py +5888 -0
  93. warp/_src/utils.py +1695 -0
  94. warp/autograd.py +33 -0
  95. warp/bin/libwarp-clang.dylib +0 -0
  96. warp/bin/libwarp.dylib +0 -0
  97. warp/build.py +29 -0
  98. warp/build_dll.py +24 -0
  99. warp/codegen.py +24 -0
  100. warp/constants.py +24 -0
  101. warp/context.py +33 -0
  102. warp/dlpack.py +24 -0
  103. warp/examples/__init__.py +24 -0
  104. warp/examples/assets/bear.usd +0 -0
  105. warp/examples/assets/bunny.usd +0 -0
  106. warp/examples/assets/cube.usd +0 -0
  107. warp/examples/assets/nonuniform.usd +0 -0
  108. warp/examples/assets/nvidia_logo.png +0 -0
  109. warp/examples/assets/pixel.jpg +0 -0
  110. warp/examples/assets/rocks.nvdb +0 -0
  111. warp/examples/assets/rocks.usd +0 -0
  112. warp/examples/assets/sphere.usd +0 -0
  113. warp/examples/assets/square_cloth.usd +0 -0
  114. warp/examples/benchmarks/benchmark_api.py +389 -0
  115. warp/examples/benchmarks/benchmark_cloth.py +296 -0
  116. warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
  117. warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
  118. warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
  119. warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
  120. warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
  121. warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
  122. warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
  123. warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
  124. warp/examples/benchmarks/benchmark_gemm.py +164 -0
  125. warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
  126. warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
  127. warp/examples/benchmarks/benchmark_launches.py +301 -0
  128. warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
  129. warp/examples/benchmarks/benchmark_tile_sort.py +155 -0
  130. warp/examples/browse.py +37 -0
  131. warp/examples/core/example_cupy.py +86 -0
  132. warp/examples/core/example_dem.py +241 -0
  133. warp/examples/core/example_fluid.py +299 -0
  134. warp/examples/core/example_graph_capture.py +150 -0
  135. warp/examples/core/example_marching_cubes.py +195 -0
  136. warp/examples/core/example_mesh.py +180 -0
  137. warp/examples/core/example_mesh_intersect.py +211 -0
  138. warp/examples/core/example_nvdb.py +182 -0
  139. warp/examples/core/example_raycast.py +111 -0
  140. warp/examples/core/example_raymarch.py +205 -0
  141. warp/examples/core/example_render_opengl.py +290 -0
  142. warp/examples/core/example_sample_mesh.py +300 -0
  143. warp/examples/core/example_sph.py +411 -0
  144. warp/examples/core/example_spin_lock.py +93 -0
  145. warp/examples/core/example_torch.py +211 -0
  146. warp/examples/core/example_wave.py +269 -0
  147. warp/examples/core/example_work_queue.py +118 -0
  148. warp/examples/distributed/example_jacobi_mpi.py +506 -0
  149. warp/examples/fem/example_adaptive_grid.py +286 -0
  150. warp/examples/fem/example_apic_fluid.py +469 -0
  151. warp/examples/fem/example_burgers.py +261 -0
  152. warp/examples/fem/example_convection_diffusion.py +181 -0
  153. warp/examples/fem/example_convection_diffusion_dg.py +225 -0
  154. warp/examples/fem/example_darcy_ls_optimization.py +489 -0
  155. warp/examples/fem/example_deformed_geometry.py +172 -0
  156. warp/examples/fem/example_diffusion.py +196 -0
  157. warp/examples/fem/example_diffusion_3d.py +225 -0
  158. warp/examples/fem/example_diffusion_mgpu.py +225 -0
  159. warp/examples/fem/example_distortion_energy.py +228 -0
  160. warp/examples/fem/example_elastic_shape_optimization.py +387 -0
  161. warp/examples/fem/example_magnetostatics.py +242 -0
  162. warp/examples/fem/example_mixed_elasticity.py +293 -0
  163. warp/examples/fem/example_navier_stokes.py +263 -0
  164. warp/examples/fem/example_nonconforming_contact.py +300 -0
  165. warp/examples/fem/example_stokes.py +213 -0
  166. warp/examples/fem/example_stokes_transfer.py +262 -0
  167. warp/examples/fem/example_streamlines.py +357 -0
  168. warp/examples/fem/utils.py +1047 -0
  169. warp/examples/interop/example_jax_callable.py +146 -0
  170. warp/examples/interop/example_jax_ffi_callback.py +132 -0
  171. warp/examples/interop/example_jax_kernel.py +232 -0
  172. warp/examples/optim/example_diffray.py +561 -0
  173. warp/examples/optim/example_fluid_checkpoint.py +497 -0
  174. warp/examples/tile/example_tile_block_cholesky.py +502 -0
  175. warp/examples/tile/example_tile_cholesky.py +88 -0
  176. warp/examples/tile/example_tile_convolution.py +66 -0
  177. warp/examples/tile/example_tile_fft.py +55 -0
  178. warp/examples/tile/example_tile_filtering.py +113 -0
  179. warp/examples/tile/example_tile_matmul.py +85 -0
  180. warp/examples/tile/example_tile_mcgp.py +191 -0
  181. warp/examples/tile/example_tile_mlp.py +385 -0
  182. warp/examples/tile/example_tile_nbody.py +199 -0
  183. warp/fabric.py +24 -0
  184. warp/fem/__init__.py +173 -0
  185. warp/fem/adaptivity.py +26 -0
  186. warp/fem/cache.py +30 -0
  187. warp/fem/dirichlet.py +24 -0
  188. warp/fem/field/__init__.py +24 -0
  189. warp/fem/field/field.py +26 -0
  190. warp/fem/geometry/__init__.py +21 -0
  191. warp/fem/geometry/closest_point.py +31 -0
  192. warp/fem/linalg.py +38 -0
  193. warp/fem/operator.py +32 -0
  194. warp/fem/polynomial.py +29 -0
  195. warp/fem/space/__init__.py +22 -0
  196. warp/fem/space/basis_space.py +24 -0
  197. warp/fem/space/shape/__init__.py +68 -0
  198. warp/fem/space/topology.py +24 -0
  199. warp/fem/types.py +24 -0
  200. warp/fem/utils.py +32 -0
  201. warp/jax.py +29 -0
  202. warp/jax_experimental/__init__.py +29 -0
  203. warp/jax_experimental/custom_call.py +29 -0
  204. warp/jax_experimental/ffi.py +39 -0
  205. warp/jax_experimental/xla_ffi.py +24 -0
  206. warp/marching_cubes.py +24 -0
  207. warp/math.py +37 -0
  208. warp/native/array.h +1687 -0
  209. warp/native/builtin.h +2327 -0
  210. warp/native/bvh.cpp +562 -0
  211. warp/native/bvh.cu +826 -0
  212. warp/native/bvh.h +555 -0
  213. warp/native/clang/clang.cpp +541 -0
  214. warp/native/coloring.cpp +622 -0
  215. warp/native/crt.cpp +51 -0
  216. warp/native/crt.h +568 -0
  217. warp/native/cuda_crt.h +1058 -0
  218. warp/native/cuda_util.cpp +677 -0
  219. warp/native/cuda_util.h +313 -0
  220. warp/native/error.cpp +77 -0
  221. warp/native/error.h +36 -0
  222. warp/native/exports.h +2023 -0
  223. warp/native/fabric.h +246 -0
  224. warp/native/hashgrid.cpp +311 -0
  225. warp/native/hashgrid.cu +89 -0
  226. warp/native/hashgrid.h +240 -0
  227. warp/native/initializer_array.h +41 -0
  228. warp/native/intersect.h +1253 -0
  229. warp/native/intersect_adj.h +375 -0
  230. warp/native/intersect_tri.h +348 -0
  231. warp/native/mat.h +5189 -0
  232. warp/native/mathdx.cpp +93 -0
  233. warp/native/matnn.h +221 -0
  234. warp/native/mesh.cpp +266 -0
  235. warp/native/mesh.cu +406 -0
  236. warp/native/mesh.h +2097 -0
  237. warp/native/nanovdb/GridHandle.h +533 -0
  238. warp/native/nanovdb/HostBuffer.h +591 -0
  239. warp/native/nanovdb/NanoVDB.h +6246 -0
  240. warp/native/nanovdb/NodeManager.h +323 -0
  241. warp/native/nanovdb/PNanoVDB.h +3390 -0
  242. warp/native/noise.h +859 -0
  243. warp/native/quat.h +1664 -0
  244. warp/native/rand.h +342 -0
  245. warp/native/range.h +145 -0
  246. warp/native/reduce.cpp +174 -0
  247. warp/native/reduce.cu +363 -0
  248. warp/native/runlength_encode.cpp +79 -0
  249. warp/native/runlength_encode.cu +61 -0
  250. warp/native/scan.cpp +47 -0
  251. warp/native/scan.cu +55 -0
  252. warp/native/scan.h +23 -0
  253. warp/native/solid_angle.h +466 -0
  254. warp/native/sort.cpp +251 -0
  255. warp/native/sort.cu +286 -0
  256. warp/native/sort.h +35 -0
  257. warp/native/sparse.cpp +241 -0
  258. warp/native/sparse.cu +435 -0
  259. warp/native/spatial.h +1306 -0
  260. warp/native/svd.h +727 -0
  261. warp/native/temp_buffer.h +46 -0
  262. warp/native/tile.h +4124 -0
  263. warp/native/tile_radix_sort.h +1112 -0
  264. warp/native/tile_reduce.h +838 -0
  265. warp/native/tile_scan.h +240 -0
  266. warp/native/tuple.h +189 -0
  267. warp/native/vec.h +2199 -0
  268. warp/native/version.h +23 -0
  269. warp/native/volume.cpp +501 -0
  270. warp/native/volume.cu +68 -0
  271. warp/native/volume.h +970 -0
  272. warp/native/volume_builder.cu +483 -0
  273. warp/native/volume_builder.h +52 -0
  274. warp/native/volume_impl.h +70 -0
  275. warp/native/warp.cpp +1143 -0
  276. warp/native/warp.cu +4604 -0
  277. warp/native/warp.h +358 -0
  278. warp/optim/__init__.py +20 -0
  279. warp/optim/adam.py +24 -0
  280. warp/optim/linear.py +35 -0
  281. warp/optim/sgd.py +24 -0
  282. warp/paddle.py +24 -0
  283. warp/py.typed +0 -0
  284. warp/render/__init__.py +22 -0
  285. warp/render/imgui_manager.py +29 -0
  286. warp/render/render_opengl.py +24 -0
  287. warp/render/render_usd.py +24 -0
  288. warp/render/utils.py +24 -0
  289. warp/sparse.py +51 -0
  290. warp/tape.py +24 -0
  291. warp/tests/__init__.py +1 -0
  292. warp/tests/__main__.py +4 -0
  293. warp/tests/assets/curlnoise_golden.npy +0 -0
  294. warp/tests/assets/mlp_golden.npy +0 -0
  295. warp/tests/assets/pixel.npy +0 -0
  296. warp/tests/assets/pnoise_golden.npy +0 -0
  297. warp/tests/assets/spiky.usd +0 -0
  298. warp/tests/assets/test_grid.nvdb +0 -0
  299. warp/tests/assets/test_index_grid.nvdb +0 -0
  300. warp/tests/assets/test_int32_grid.nvdb +0 -0
  301. warp/tests/assets/test_vec_grid.nvdb +0 -0
  302. warp/tests/assets/torus.nvdb +0 -0
  303. warp/tests/assets/torus.usda +105 -0
  304. warp/tests/aux_test_class_kernel.py +34 -0
  305. warp/tests/aux_test_compile_consts_dummy.py +18 -0
  306. warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
  307. warp/tests/aux_test_dependent.py +29 -0
  308. warp/tests/aux_test_grad_customs.py +29 -0
  309. warp/tests/aux_test_instancing_gc.py +26 -0
  310. warp/tests/aux_test_module_aot.py +7 -0
  311. warp/tests/aux_test_module_unload.py +23 -0
  312. warp/tests/aux_test_name_clash1.py +40 -0
  313. warp/tests/aux_test_name_clash2.py +40 -0
  314. warp/tests/aux_test_reference.py +9 -0
  315. warp/tests/aux_test_reference_reference.py +8 -0
  316. warp/tests/aux_test_square.py +16 -0
  317. warp/tests/aux_test_unresolved_func.py +22 -0
  318. warp/tests/aux_test_unresolved_symbol.py +22 -0
  319. warp/tests/cuda/__init__.py +0 -0
  320. warp/tests/cuda/test_async.py +676 -0
  321. warp/tests/cuda/test_conditional_captures.py +1147 -0
  322. warp/tests/cuda/test_ipc.py +124 -0
  323. warp/tests/cuda/test_mempool.py +233 -0
  324. warp/tests/cuda/test_multigpu.py +169 -0
  325. warp/tests/cuda/test_peer.py +139 -0
  326. warp/tests/cuda/test_pinned.py +84 -0
  327. warp/tests/cuda/test_streams.py +691 -0
  328. warp/tests/geometry/__init__.py +0 -0
  329. warp/tests/geometry/test_bvh.py +335 -0
  330. warp/tests/geometry/test_hash_grid.py +259 -0
  331. warp/tests/geometry/test_marching_cubes.py +294 -0
  332. warp/tests/geometry/test_mesh.py +318 -0
  333. warp/tests/geometry/test_mesh_query_aabb.py +392 -0
  334. warp/tests/geometry/test_mesh_query_point.py +935 -0
  335. warp/tests/geometry/test_mesh_query_ray.py +323 -0
  336. warp/tests/geometry/test_volume.py +1103 -0
  337. warp/tests/geometry/test_volume_write.py +346 -0
  338. warp/tests/interop/__init__.py +0 -0
  339. warp/tests/interop/test_dlpack.py +730 -0
  340. warp/tests/interop/test_jax.py +1673 -0
  341. warp/tests/interop/test_paddle.py +800 -0
  342. warp/tests/interop/test_torch.py +1001 -0
  343. warp/tests/run_coverage_serial.py +39 -0
  344. warp/tests/test_adam.py +162 -0
  345. warp/tests/test_arithmetic.py +1096 -0
  346. warp/tests/test_array.py +3756 -0
  347. warp/tests/test_array_reduce.py +156 -0
  348. warp/tests/test_assert.py +303 -0
  349. warp/tests/test_atomic.py +336 -0
  350. warp/tests/test_atomic_bitwise.py +209 -0
  351. warp/tests/test_atomic_cas.py +312 -0
  352. warp/tests/test_bool.py +220 -0
  353. warp/tests/test_builtins_resolution.py +732 -0
  354. warp/tests/test_closest_point_edge_edge.py +327 -0
  355. warp/tests/test_codegen.py +974 -0
  356. warp/tests/test_codegen_instancing.py +1495 -0
  357. warp/tests/test_compile_consts.py +215 -0
  358. warp/tests/test_conditional.py +298 -0
  359. warp/tests/test_context.py +35 -0
  360. warp/tests/test_copy.py +319 -0
  361. warp/tests/test_ctypes.py +618 -0
  362. warp/tests/test_dense.py +73 -0
  363. warp/tests/test_devices.py +127 -0
  364. warp/tests/test_enum.py +136 -0
  365. warp/tests/test_examples.py +424 -0
  366. warp/tests/test_fabricarray.py +998 -0
  367. warp/tests/test_fast_math.py +72 -0
  368. warp/tests/test_fem.py +2204 -0
  369. warp/tests/test_fixedarray.py +229 -0
  370. warp/tests/test_fp16.py +136 -0
  371. warp/tests/test_func.py +501 -0
  372. warp/tests/test_future_annotations.py +100 -0
  373. warp/tests/test_generics.py +656 -0
  374. warp/tests/test_grad.py +893 -0
  375. warp/tests/test_grad_customs.py +339 -0
  376. warp/tests/test_grad_debug.py +341 -0
  377. warp/tests/test_implicit_init.py +411 -0
  378. warp/tests/test_import.py +45 -0
  379. warp/tests/test_indexedarray.py +1140 -0
  380. warp/tests/test_intersect.py +103 -0
  381. warp/tests/test_iter.py +76 -0
  382. warp/tests/test_large.py +177 -0
  383. warp/tests/test_launch.py +411 -0
  384. warp/tests/test_lerp.py +151 -0
  385. warp/tests/test_linear_solvers.py +223 -0
  386. warp/tests/test_lvalue.py +427 -0
  387. warp/tests/test_map.py +526 -0
  388. warp/tests/test_mat.py +3515 -0
  389. warp/tests/test_mat_assign_copy.py +178 -0
  390. warp/tests/test_mat_constructors.py +573 -0
  391. warp/tests/test_mat_lite.py +122 -0
  392. warp/tests/test_mat_scalar_ops.py +2913 -0
  393. warp/tests/test_math.py +212 -0
  394. warp/tests/test_module_aot.py +287 -0
  395. warp/tests/test_module_hashing.py +258 -0
  396. warp/tests/test_modules_lite.py +70 -0
  397. warp/tests/test_noise.py +252 -0
  398. warp/tests/test_operators.py +299 -0
  399. warp/tests/test_options.py +129 -0
  400. warp/tests/test_overwrite.py +551 -0
  401. warp/tests/test_print.py +408 -0
  402. warp/tests/test_quat.py +2653 -0
  403. warp/tests/test_quat_assign_copy.py +145 -0
  404. warp/tests/test_rand.py +339 -0
  405. warp/tests/test_reload.py +303 -0
  406. warp/tests/test_rounding.py +157 -0
  407. warp/tests/test_runlength_encode.py +196 -0
  408. warp/tests/test_scalar_ops.py +133 -0
  409. warp/tests/test_smoothstep.py +108 -0
  410. warp/tests/test_snippet.py +318 -0
  411. warp/tests/test_sparse.py +845 -0
  412. warp/tests/test_spatial.py +2859 -0
  413. warp/tests/test_spatial_assign_copy.py +160 -0
  414. warp/tests/test_special_values.py +361 -0
  415. warp/tests/test_static.py +640 -0
  416. warp/tests/test_struct.py +901 -0
  417. warp/tests/test_tape.py +242 -0
  418. warp/tests/test_transient_module.py +93 -0
  419. warp/tests/test_triangle_closest_point.py +192 -0
  420. warp/tests/test_tuple.py +361 -0
  421. warp/tests/test_types.py +615 -0
  422. warp/tests/test_utils.py +594 -0
  423. warp/tests/test_vec.py +1408 -0
  424. warp/tests/test_vec_assign_copy.py +143 -0
  425. warp/tests/test_vec_constructors.py +325 -0
  426. warp/tests/test_vec_lite.py +80 -0
  427. warp/tests/test_vec_scalar_ops.py +2327 -0
  428. warp/tests/test_verify_fp.py +100 -0
  429. warp/tests/test_version.py +75 -0
  430. warp/tests/tile/__init__.py +0 -0
  431. warp/tests/tile/test_tile.py +1519 -0
  432. warp/tests/tile/test_tile_atomic_bitwise.py +403 -0
  433. warp/tests/tile/test_tile_cholesky.py +608 -0
  434. warp/tests/tile/test_tile_load.py +724 -0
  435. warp/tests/tile/test_tile_mathdx.py +156 -0
  436. warp/tests/tile/test_tile_matmul.py +179 -0
  437. warp/tests/tile/test_tile_mlp.py +400 -0
  438. warp/tests/tile/test_tile_reduce.py +950 -0
  439. warp/tests/tile/test_tile_shared_memory.py +376 -0
  440. warp/tests/tile/test_tile_sort.py +121 -0
  441. warp/tests/tile/test_tile_view.py +173 -0
  442. warp/tests/unittest_serial.py +47 -0
  443. warp/tests/unittest_suites.py +430 -0
  444. warp/tests/unittest_utils.py +469 -0
  445. warp/tests/walkthrough_debug.py +95 -0
  446. warp/torch.py +24 -0
  447. warp/types.py +51 -0
  448. warp/utils.py +31 -0
  449. warp_lang-1.10.0.dist-info/METADATA +459 -0
  450. warp_lang-1.10.0.dist-info/RECORD +468 -0
  451. warp_lang-1.10.0.dist-info/WHEEL +5 -0
  452. warp_lang-1.10.0.dist-info/licenses/LICENSE.md +176 -0
  453. warp_lang-1.10.0.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
  454. warp_lang-1.10.0.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
  455. warp_lang-1.10.0.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
  456. warp_lang-1.10.0.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
  457. warp_lang-1.10.0.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
  458. warp_lang-1.10.0.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
  459. warp_lang-1.10.0.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
  460. warp_lang-1.10.0.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
  461. warp_lang-1.10.0.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
  462. warp_lang-1.10.0.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
  463. warp_lang-1.10.0.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
  464. warp_lang-1.10.0.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
  465. warp_lang-1.10.0.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
  466. warp_lang-1.10.0.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
  467. warp_lang-1.10.0.dist-info/licenses/licenses/windingnumber-LICENSE.txt +21 -0
  468. warp_lang-1.10.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,829 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import numpy as np
17
+
18
+ import warp as wp
19
+ from warp._src.fem import cache
20
+ from warp._src.fem.types import Coords
21
+
22
+ from .shape_function import ShapeFunction
23
+
24
+ _wp_module_name_ = "warp.fem.space.shape.tet_shape_function"
25
+
26
+
27
+ def _tet_node_index(tx: int, ty: int, tz: int, degree: int):
28
+ from .triangle_shape_function import _triangle_node_index
29
+
30
+ VERTEX_NODE_COUNT = 4
31
+ EDGE_INTERIOR_NODE_COUNT = degree - 1
32
+ VERTEX_EDGE_NODE_COUNT = VERTEX_NODE_COUNT + 6 * EDGE_INTERIOR_NODE_COUNT
33
+ FACE_INTERIOR_NODE_COUNT = (degree - 1) * (degree - 2) // 2
34
+ VERTEX_EDGE_FACE_NODE_COUNT = VERTEX_EDGE_NODE_COUNT + 4 * FACE_INTERIOR_NODE_COUNT
35
+
36
+ # Index in similar order to e.g. VTK
37
+ # First vertices, then edges (counterclockwise), then faces, then interior points (recursively)
38
+
39
+ if tx == 0:
40
+ if ty == 0:
41
+ if tz == 0:
42
+ return 0
43
+ elif tz == degree:
44
+ return 3
45
+ else:
46
+ # 0-3 edge
47
+ edge_index = 3
48
+ return VERTEX_NODE_COUNT + EDGE_INTERIOR_NODE_COUNT * edge_index + (tz - 1)
49
+ elif tz == 0:
50
+ if ty == degree:
51
+ return 2
52
+ else:
53
+ # 2-0 edge
54
+ edge_index = 2
55
+ return VERTEX_NODE_COUNT + EDGE_INTERIOR_NODE_COUNT * edge_index + (EDGE_INTERIOR_NODE_COUNT - ty)
56
+ elif tz + ty == degree:
57
+ # 2-3 edge
58
+ edge_index = 5
59
+ return VERTEX_NODE_COUNT + EDGE_INTERIOR_NODE_COUNT * edge_index + (tz - 1)
60
+ else:
61
+ # 2-3-0 face
62
+ face_index = 2
63
+ return (
64
+ VERTEX_EDGE_NODE_COUNT
65
+ + FACE_INTERIOR_NODE_COUNT * face_index
66
+ + _triangle_node_index(degree - 1 - ty - tz, tz - 1, degree - 3)
67
+ )
68
+ elif ty == 0:
69
+ if tz == 0:
70
+ if tx == degree:
71
+ return 1
72
+ else:
73
+ # 0-1 edge
74
+ edge_index = 0
75
+ return VERTEX_NODE_COUNT + EDGE_INTERIOR_NODE_COUNT * edge_index + (tx - 1)
76
+ elif tz + tx == degree:
77
+ # 1-3 edge
78
+ edge_index = 4
79
+ return VERTEX_NODE_COUNT + EDGE_INTERIOR_NODE_COUNT * edge_index + (tz - 1)
80
+ else:
81
+ # 3-0-1 face
82
+ face_index = 3
83
+ return (
84
+ VERTEX_EDGE_NODE_COUNT
85
+ + FACE_INTERIOR_NODE_COUNT * face_index
86
+ + _triangle_node_index(tx - 1, tz - 1, degree - 3)
87
+ )
88
+ elif tz == 0:
89
+ if tx + ty == degree:
90
+ # 1-2 edge
91
+ edge_index = 1
92
+ return VERTEX_NODE_COUNT + EDGE_INTERIOR_NODE_COUNT * edge_index + (ty - 1)
93
+ else:
94
+ # 0-1-2 face
95
+ face_index = 0
96
+ return (
97
+ VERTEX_EDGE_NODE_COUNT
98
+ + FACE_INTERIOR_NODE_COUNT * face_index
99
+ + _triangle_node_index(tx - 1, ty - 1, degree - 3)
100
+ )
101
+ elif tx + ty + tz == degree:
102
+ # 1-2-3 face
103
+ face_index = 1
104
+ return (
105
+ VERTEX_EDGE_NODE_COUNT
106
+ + FACE_INTERIOR_NODE_COUNT * face_index
107
+ + _triangle_node_index(tx - 1, tz - 1, degree - 3)
108
+ )
109
+
110
+ return VERTEX_EDGE_FACE_NODE_COUNT + _tet_node_index(tx - 1, ty - 1, tz - 1, degree - 4)
111
+
112
+
113
+ class TetrahedronShapeFunction(ShapeFunction):
114
+ VERTEX = wp.constant(0)
115
+ EDGE = wp.constant(1)
116
+ FACE = wp.constant(2)
117
+ INTERIOR = wp.constant(3)
118
+
119
+ VERTEX_NODE_COUNT: int
120
+ """Number of shape function nodes per vertex"""
121
+
122
+ EDGE_NODE_COUNT: int
123
+ """Number of shape function nodes per tet edge (excluding vertex nodes)"""
124
+
125
+ FACE_NODE_COUNT: int
126
+ """Number of shape function nodes per tet face (excluding edge and vertex nodes)"""
127
+
128
+ INTERIOR_NODE_COUNT: int
129
+ """Number of shape function nodes per tet (excluding face, edge and vertex nodes)"""
130
+
131
+ @staticmethod
132
+ def node_type_and_index(node_index_in_elt: int):
133
+ pass
134
+
135
+ @wp.func
136
+ def edge_vidx(edge: int):
137
+ if edge < 3:
138
+ c1 = edge
139
+ c2 = (edge + 1) % 3
140
+ else:
141
+ c1 = edge - 3
142
+ c2 = 3
143
+ return c1, c2
144
+
145
+ @wp.func
146
+ def opposite_edge_vidx(edge: int):
147
+ if edge < 3:
148
+ e1 = (edge + 2) % 3
149
+ e2 = 3
150
+ else:
151
+ e1 = (edge - 2) % 3
152
+ e2 = (edge - 1) % 3
153
+ return e1, e2
154
+
155
+ @wp.func
156
+ def _vertex_coords(vidx: int):
157
+ return wp.vec3(
158
+ float(vidx == 1),
159
+ float(vidx == 2),
160
+ float(vidx == 3),
161
+ )
162
+
163
+
164
+ class TetrahedronPolynomialShapeFunctions(TetrahedronShapeFunction):
165
+ def __init__(self, degree: int):
166
+ self.ORDER = wp.constant(degree)
167
+
168
+ self.NODES_PER_ELEMENT = wp.constant((degree + 1) * (degree + 2) * (degree + 3) // 6)
169
+ self.NODES_PER_SIDE = wp.constant((degree + 1) * (degree + 2) // 2)
170
+
171
+ self.VERTEX_NODE_COUNT = wp.constant(1)
172
+ self.EDGE_NODE_COUNT = wp.constant(degree - 1)
173
+ self.FACE_NODE_COUNT = wp.constant(max(0, degree - 2) * max(0, degree - 1) // 2)
174
+ self.INTERIOR_NODE_COUNT = wp.constant(max(0, degree - 1) * max(0, degree - 2) * max(0, degree - 3) // 6)
175
+
176
+ self.NODES_PER_ELEMENT = wp.constant((degree + 1) * (degree + 2) * (degree + 3) // 6)
177
+ self.NODES_PER_SIDE = wp.constant((degree + 1) * (degree + 2) // 2)
178
+
179
+ tet_coords = np.empty((self.NODES_PER_ELEMENT, 3), dtype=int)
180
+
181
+ for tx in range(degree + 1):
182
+ for ty in range(degree + 1 - tx):
183
+ for tz in range(degree + 1 - tx - ty):
184
+ index = _tet_node_index(tx, ty, tz, degree)
185
+ tet_coords[index] = [tx, ty, tz]
186
+
187
+ CoordTypeVec = cache.cached_mat_type(dtype=int, shape=(self.NODES_PER_ELEMENT, 3))
188
+ self.NODE_TET_COORDS = wp.constant(CoordTypeVec(tet_coords))
189
+
190
+ self.node_type_and_type_index = self._get_node_type_and_type_index()
191
+ self._node_tet_coordinates = self._get_node_tet_coordinates()
192
+
193
+ @property
194
+ def name(self) -> str:
195
+ return f"Tet_P{self.ORDER}"
196
+
197
+ def _get_node_tet_coordinates(self):
198
+ NODE_TET_COORDS = self.NODE_TET_COORDS
199
+
200
+ def node_tet_coordinates(
201
+ node_index_in_elt: int,
202
+ ):
203
+ return NODE_TET_COORDS[node_index_in_elt]
204
+
205
+ return cache.get_func(node_tet_coordinates, self.name)
206
+
207
+ def _get_node_type_and_type_index(self):
208
+ ORDER = self.ORDER
209
+
210
+ def node_type_and_index(
211
+ node_index_in_elt: int,
212
+ ):
213
+ if node_index_in_elt < 4:
214
+ return TetrahedronPolynomialShapeFunctions.VERTEX, node_index_in_elt
215
+
216
+ if node_index_in_elt < (6 * ORDER - 2):
217
+ return TetrahedronPolynomialShapeFunctions.EDGE, (node_index_in_elt - 4)
218
+
219
+ if node_index_in_elt < (2 * ORDER * ORDER + 2):
220
+ return TetrahedronPolynomialShapeFunctions.FACE, (node_index_in_elt - (6 * ORDER - 2))
221
+
222
+ return TetrahedronPolynomialShapeFunctions.INTERIOR, (node_index_in_elt - (2 * ORDER * ORDER + 2))
223
+
224
+ return cache.get_func(node_type_and_index, self.name)
225
+
226
+ def make_node_coords_in_element(self):
227
+ ORDER = self.ORDER
228
+
229
+ def node_coords_in_element(
230
+ node_index_in_elt: int,
231
+ ):
232
+ tet_coords = self._node_tet_coordinates(node_index_in_elt)
233
+ cx = float(tet_coords[0]) / float(ORDER)
234
+ cy = float(tet_coords[1]) / float(ORDER)
235
+ cz = float(tet_coords[2]) / float(ORDER)
236
+ return Coords(cx, cy, cz)
237
+
238
+ return cache.get_func(node_coords_in_element, self.name)
239
+
240
+ def make_node_quadrature_weight(self):
241
+ if self.ORDER == 3:
242
+ # Order 1, but optimized quadrature weights for monomials of order <= 6
243
+ vertex_weight = 0.007348845656
244
+ edge_weight = 0.020688129855
245
+ face_weight = 0.180586764778
246
+ interior_weight = 0.0
247
+ else:
248
+ vertex_weight = 1.0 / self.NODES_PER_ELEMENT
249
+ edge_weight = 1.0 / self.NODES_PER_ELEMENT
250
+ face_weight = 1.0 / self.NODES_PER_ELEMENT
251
+ interior_weight = 1.0 / self.NODES_PER_ELEMENT
252
+
253
+ VERTEX_WEIGHT = wp.constant(vertex_weight)
254
+ EDGE_WEIGHT = wp.constant(edge_weight)
255
+ FACE_WEIGHT = wp.constant(face_weight)
256
+ INTERIOR_WEIGHT = wp.constant(interior_weight)
257
+
258
+ @cache.dynamic_func(suffix=self.name)
259
+ def node_quadrature_weight(node_index_in_element: int):
260
+ node_type, type_index = self.node_type_and_type_index(node_index_in_element)
261
+
262
+ if node_type == TetrahedronPolynomialShapeFunctions.VERTEX:
263
+ return VERTEX_WEIGHT
264
+ elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
265
+ return EDGE_WEIGHT
266
+ elif node_type == TetrahedronPolynomialShapeFunctions.FACE:
267
+ return FACE_WEIGHT
268
+
269
+ return INTERIOR_WEIGHT
270
+
271
+ return node_quadrature_weight
272
+
273
+ def make_trace_node_quadrature_weight(self):
274
+ if self.ORDER == 3:
275
+ # P3 intrinsic quadrature
276
+ vertex_weight = 1.0 / 30
277
+ edge_weight = 0.075
278
+ interior_weight = 0.45
279
+ elif self.ORDER == 2:
280
+ # Order 1, but optimized quadrature weights for monomials of order <= 4
281
+ vertex_weight = 0.022335964126
282
+ edge_weight = 0.310997369207
283
+ interior_weight = 0.0
284
+ else:
285
+ vertex_weight = 1.0 / self.NODES_PER_SIDE
286
+ edge_weight = 1.0 / self.NODES_PER_SIDE
287
+ interior_weight = 1.0 / self.NODES_PER_SIDE
288
+
289
+ VERTEX_WEIGHT = wp.constant(vertex_weight)
290
+ EDGE_WEIGHT = wp.constant(edge_weight)
291
+ FACE_INTERIOR_WEIGHT = wp.constant(interior_weight)
292
+
293
+ @cache.dynamic_func(suffix=self.name)
294
+ def trace_node_quadrature_weight(node_index_in_element: int):
295
+ node_type, type_index = self.node_type_and_type_index(node_index_in_element)
296
+
297
+ if node_type == TetrahedronPolynomialShapeFunctions.VERTEX:
298
+ return VERTEX_WEIGHT
299
+ elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
300
+ return EDGE_WEIGHT
301
+
302
+ return FACE_INTERIOR_WEIGHT
303
+
304
+ return trace_node_quadrature_weight
305
+
306
+ def make_element_inner_weight(self):
307
+ ORDER = self.ORDER
308
+
309
+ def element_inner_weight_linear(
310
+ coords: Coords,
311
+ node_index_in_elt: int,
312
+ ):
313
+ if node_index_in_elt < 0 or node_index_in_elt >= 4:
314
+ return 0.0
315
+
316
+ tet_coords = wp.vec4(1.0 - coords[0] - coords[1] - coords[2], coords[0], coords[1], coords[2])
317
+ return tet_coords[node_index_in_elt]
318
+
319
+ def element_inner_weight_quadratic(
320
+ coords: Coords,
321
+ node_index_in_elt: int,
322
+ ):
323
+ node_type, type_index = self.node_type_and_type_index(node_index_in_elt)
324
+
325
+ tet_coords = wp.vec4(1.0 - coords[0] - coords[1] - coords[2], coords[0], coords[1], coords[2])
326
+
327
+ if node_type == TetrahedronPolynomialShapeFunctions.VERTEX:
328
+ # Vertex
329
+ return tet_coords[type_index] * (2.0 * tet_coords[type_index] - 1.0)
330
+
331
+ elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
332
+ # Edge
333
+ c1, c2 = TetrahedronShapeFunction.edge_vidx(type_index)
334
+ return 4.0 * tet_coords[c1] * tet_coords[c2]
335
+
336
+ return 0.0
337
+
338
+ def element_inner_weight_cubic(
339
+ coords: Coords,
340
+ node_index_in_elt: int,
341
+ ):
342
+ node_type, type_index = self.node_type_and_type_index(node_index_in_elt)
343
+
344
+ tet_coords = wp.vec4(1.0 - coords[0] - coords[1] - coords[2], coords[0], coords[1], coords[2])
345
+
346
+ if node_type == TetrahedronPolynomialShapeFunctions.VERTEX:
347
+ # Vertex
348
+ return (
349
+ 0.5
350
+ * tet_coords[type_index]
351
+ * (3.0 * tet_coords[type_index] - 1.0)
352
+ * (3.0 * tet_coords[type_index] - 2.0)
353
+ )
354
+
355
+ elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
356
+ # Edge
357
+ edge = type_index // 2
358
+ edge_node = type_index - 2 * edge
359
+
360
+ if edge < 3:
361
+ c1 = (edge + edge_node) % 3
362
+ c2 = (edge + 1 - edge_node) % 3
363
+ elif edge_node == 0:
364
+ c1 = edge - 3
365
+ c2 = 3
366
+ else:
367
+ c1 = 3
368
+ c2 = edge - 3
369
+
370
+ return 4.5 * tet_coords[c1] * tet_coords[c2] * (3.0 * tet_coords[c1] - 1.0)
371
+
372
+ elif node_type == TetrahedronPolynomialShapeFunctions.FACE:
373
+ # Interior
374
+ c1 = type_index
375
+ c2 = (c1 + 1) % 4
376
+ c3 = (c1 + 2) % 4
377
+ return 27.0 * tet_coords[c1] * tet_coords[c2] * tet_coords[c3]
378
+
379
+ return 0.0
380
+
381
+ if ORDER == 1:
382
+ return cache.get_func(element_inner_weight_linear, self.name)
383
+ elif ORDER == 2:
384
+ return cache.get_func(element_inner_weight_quadratic, self.name)
385
+ elif ORDER == 3:
386
+ return cache.get_func(element_inner_weight_cubic, self.name)
387
+
388
+ return None
389
+
390
+ def make_element_inner_weight_gradient(self):
391
+ ORDER = self.ORDER
392
+
393
+ def element_inner_weight_gradient_linear(
394
+ coords: Coords,
395
+ node_index_in_elt: int,
396
+ ):
397
+ if node_index_in_elt < 0 or node_index_in_elt >= 4:
398
+ return wp.vec3(0.0)
399
+
400
+ dw_dc = wp.vec4(0.0)
401
+ dw_dc[node_index_in_elt] = 1.0
402
+
403
+ dw_du = wp.vec3(dw_dc[1] - dw_dc[0], dw_dc[2] - dw_dc[0], dw_dc[3] - dw_dc[0])
404
+
405
+ return dw_du
406
+
407
+ def element_inner_weight_gradient_quadratic(
408
+ coords: Coords,
409
+ node_index_in_elt: int,
410
+ ):
411
+ node_type, type_index = self.node_type_and_type_index(node_index_in_elt)
412
+
413
+ tet_coords = wp.vec4(1.0 - coords[0] - coords[1] - coords[2], coords[0], coords[1], coords[2])
414
+ dw_dc = wp.vec4(0.0)
415
+
416
+ if node_type == TetrahedronPolynomialShapeFunctions.VERTEX:
417
+ # Vertex
418
+ dw_dc[type_index] = 4.0 * tet_coords[type_index] - 1.0
419
+
420
+ elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
421
+ # Edge
422
+ c1, c2 = TetrahedronShapeFunction.edge_vidx(type_index)
423
+ dw_dc[c1] = 4.0 * tet_coords[c2]
424
+ dw_dc[c2] = 4.0 * tet_coords[c1]
425
+
426
+ dw_du = wp.vec3(dw_dc[1] - dw_dc[0], dw_dc[2] - dw_dc[0], dw_dc[3] - dw_dc[0])
427
+ return dw_du
428
+
429
+ def element_inner_weight_gradient_cubic(
430
+ coords: Coords,
431
+ node_index_in_elt: int,
432
+ ):
433
+ node_type, type_index = self.node_type_and_type_index(node_index_in_elt)
434
+
435
+ tet_coords = wp.vec4(1.0 - coords[0] - coords[1] - coords[2], coords[0], coords[1], coords[2])
436
+
437
+ dw_dc = wp.vec4(0.0)
438
+
439
+ if node_type == TetrahedronPolynomialShapeFunctions.VERTEX:
440
+ # Vertex
441
+ dw_dc[type_index] = (
442
+ 0.5 * 27.0 * tet_coords[type_index] * tet_coords[type_index] - 9.0 * tet_coords[type_index] + 1.0
443
+ )
444
+
445
+ elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
446
+ # Edge
447
+ edge = type_index // 2
448
+ edge_node = type_index - 2 * edge
449
+
450
+ if edge < 3:
451
+ c1 = (edge + edge_node) % 3
452
+ c2 = (edge + 1 - edge_node) % 3
453
+ elif edge_node == 0:
454
+ c1 = edge - 3
455
+ c2 = 3
456
+ else:
457
+ c1 = 3
458
+ c2 = edge - 3
459
+
460
+ dw_dc[c1] = 4.5 * tet_coords[c2] * (6.0 * tet_coords[c1] - 1.0)
461
+ dw_dc[c2] = 4.5 * tet_coords[c1] * (3.0 * tet_coords[c1] - 1.0)
462
+
463
+ elif node_type == TetrahedronPolynomialShapeFunctions.FACE:
464
+ # Interior
465
+ c1 = type_index
466
+ c2 = (c1 + 1) % 4
467
+ c3 = (c1 + 2) % 4
468
+
469
+ dw_dc[c1] = 27.0 * tet_coords[c2] * tet_coords[c3]
470
+ dw_dc[c2] = 27.0 * tet_coords[c3] * tet_coords[c1]
471
+ dw_dc[c3] = 27.0 * tet_coords[c1] * tet_coords[c2]
472
+
473
+ dw_du = wp.vec3(dw_dc[1] - dw_dc[0], dw_dc[2] - dw_dc[0], dw_dc[3] - dw_dc[0])
474
+ return dw_du
475
+
476
+ if ORDER == 1:
477
+ return cache.get_func(element_inner_weight_gradient_linear, self.name)
478
+ elif ORDER == 2:
479
+ return cache.get_func(element_inner_weight_gradient_quadratic, self.name)
480
+ elif ORDER == 3:
481
+ return cache.get_func(element_inner_weight_gradient_cubic, self.name)
482
+
483
+ return None
484
+
485
+ def element_node_tets(self):
486
+ if self.ORDER == 1:
487
+ element_tets = [[0, 1, 2, 3]]
488
+ if self.ORDER == 2:
489
+ element_tets = [
490
+ [0, 4, 6, 7],
491
+ [1, 5, 4, 8],
492
+ [2, 6, 5, 9],
493
+ [3, 7, 8, 9],
494
+ [4, 5, 6, 8],
495
+ [8, 7, 9, 6],
496
+ [6, 5, 9, 8],
497
+ [6, 8, 7, 4],
498
+ ]
499
+ elif self.ORDER == 3:
500
+ raise NotImplementedError()
501
+
502
+ return np.array(element_tets)
503
+
504
+ def element_vtk_cells(self):
505
+ cells = np.arange(self.NODES_PER_ELEMENT)
506
+ if self.ORDER == 1:
507
+ cell_type = 10 # VTK_TETRA
508
+ else:
509
+ cell_type = 71 # VTK_LAGRANGE_TETRAHEDRON
510
+ return cells[np.newaxis, :], np.array([cell_type], dtype=np.int8)
511
+
512
+
513
+ class TetrahedronNonConformingPolynomialShapeFunctions(ShapeFunction):
514
+ def __init__(self, degree: int):
515
+ self._tet_shape = TetrahedronPolynomialShapeFunctions(degree=degree)
516
+ self.ORDER = self._tet_shape.ORDER
517
+ self.NODES_PER_ELEMENT = self._tet_shape.NODES_PER_ELEMENT
518
+
519
+ self.element_node_tets = self._tet_shape.element_node_tets
520
+ self.element_vtk_cells = self._tet_shape.element_vtk_cells
521
+
522
+ if self.ORDER == 1:
523
+ self._TET_SCALE = 0.4472135955 # so v at 0.5854101966249680 (order 2)
524
+ elif self.ORDER == 2:
525
+ self._TET_SCALE = 0.6123779296874996 # optimized for low intrinsic quadrature error of deg 4
526
+ elif self.ORDER == 3:
527
+ self._TET_SCALE = 0.7153564453124999 # optimized for low intrinsic quadrature error of deg 6
528
+ else:
529
+ self._TET_SCALE = 1.0
530
+
531
+ self._TET_SCALE = wp.constant(self._TET_SCALE)
532
+ self._TET_OFFSET = wp.constant((1.0 - self._TET_SCALE) * wp.vec3(0.25, 0.25, 0.25))
533
+
534
+ @property
535
+ def name(self) -> str:
536
+ return f"Tet_P{self.ORDER}d"
537
+
538
+ def make_node_coords_in_element(self):
539
+ node_coords_in_tet = self._tet_shape.make_node_coords_in_element()
540
+
541
+ TET_SCALE = self._TET_SCALE
542
+ TET_OFFSET = self._TET_OFFSET
543
+
544
+ @cache.dynamic_func(suffix=self.name)
545
+ def node_coords_in_element(
546
+ node_index_in_elt: int,
547
+ ):
548
+ tet_coords = node_coords_in_tet(node_index_in_elt)
549
+ return TET_SCALE * tet_coords + TET_OFFSET
550
+
551
+ return node_coords_in_element
552
+
553
+ def make_node_quadrature_weight(self):
554
+ # Intrinsic quadrature -- precomputed integral of node shape functions
555
+ # over element. Order equal to self.ORDER
556
+
557
+ if self.ORDER == 2:
558
+ vertex_weight = 0.07499641
559
+ edge_weight = 0.11666908
560
+ face_interior_weight = 0.0
561
+ elif self.ORDER == 3:
562
+ vertex_weight = 0.03345134
563
+ edge_weight = 0.04521887
564
+ face_interior_weight = 0.08089206
565
+ else:
566
+ vertex_weight = 1.0 / self.NODES_PER_ELEMENT
567
+ edge_weight = 1.0 / self.NODES_PER_ELEMENT
568
+ face_interior_weight = 1.0 / self.NODES_PER_ELEMENT
569
+
570
+ VERTEX_WEIGHT = wp.constant(vertex_weight)
571
+ EDGE_WEIGHT = wp.constant(edge_weight)
572
+ FACE_INTERIOR_WEIGHT = wp.constant(face_interior_weight)
573
+
574
+ @cache.dynamic_func(suffix=self.name)
575
+ def node_quadrature_weight(node_index_in_element: int):
576
+ node_type, type_index = self._tet_shape.node_type_and_type_index(node_index_in_element)
577
+
578
+ if node_type == TetrahedronPolynomialShapeFunctions.VERTEX:
579
+ return VERTEX_WEIGHT
580
+ elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
581
+ return EDGE_WEIGHT
582
+
583
+ return FACE_INTERIOR_WEIGHT
584
+
585
+ return node_quadrature_weight
586
+
587
+ def make_trace_node_quadrature_weight(self):
588
+ # Non-conforming, zero measure on sides
589
+
590
+ @wp.func
591
+ def zero(node_index_in_elt: int):
592
+ return 0.0
593
+
594
+ return zero
595
+
596
+ def make_element_inner_weight(self):
597
+ tet_inner_weight = self._tet_shape.make_element_inner_weight()
598
+
599
+ TET_SCALE = self._TET_SCALE
600
+ TET_OFFSET = self._TET_OFFSET
601
+
602
+ @cache.dynamic_func(suffix=self.name)
603
+ def element_inner_weight(
604
+ coords: Coords,
605
+ node_index_in_elt: int,
606
+ ):
607
+ tet_coords = (coords - TET_OFFSET) / TET_SCALE
608
+
609
+ return tet_inner_weight(tet_coords, node_index_in_elt)
610
+
611
+ return element_inner_weight
612
+
613
+ def make_element_inner_weight_gradient(self):
614
+ tet_inner_weight_gradient = self._tet_shape.make_element_inner_weight_gradient()
615
+
616
+ TET_SCALE = self._TET_SCALE
617
+ TET_OFFSET = self._TET_OFFSET
618
+
619
+ @cache.dynamic_func(suffix=self.name)
620
+ def element_inner_weight_gradient(
621
+ coords: Coords,
622
+ node_index_in_elt: int,
623
+ ):
624
+ tet_coords = (coords - TET_OFFSET) / TET_SCALE
625
+ grad = tet_inner_weight_gradient(tet_coords, node_index_in_elt)
626
+ return grad / TET_SCALE
627
+
628
+ return element_inner_weight_gradient
629
+
630
+
631
+ class TetrahedronNedelecFirstKindShapeFunctions(TetrahedronShapeFunction):
632
+ value = ShapeFunction.Value.CovariantVector
633
+
634
+ def __init__(self, degree: int):
635
+ if degree != 1:
636
+ raise NotImplementedError("Only linear Nédélec implemented right now")
637
+
638
+ self.ORDER = wp.constant(degree)
639
+
640
+ self.NODES_PER_ELEMENT = wp.constant(6)
641
+ self.NODES_PER_SIDE = wp.constant(3)
642
+
643
+ self.VERTEX_NODE_COUNT = wp.constant(0)
644
+ self.EDGE_NODE_COUNT = wp.constant(1)
645
+ self.FACE_NODE_COUNT = wp.constant(0)
646
+ self.INTERIOR_NODE_COUNT = wp.constant(0)
647
+
648
+ self.node_type_and_type_index = self._get_node_type_and_type_index()
649
+
650
+ @property
651
+ def name(self) -> str:
652
+ return f"TetN1_{self.ORDER}"
653
+
654
+ def _get_node_type_and_type_index(self):
655
+ @cache.dynamic_func(suffix=self.name)
656
+ def node_type_and_index(
657
+ node_index_in_elt: int,
658
+ ):
659
+ return TetrahedronShapeFunction.EDGE, node_index_in_elt
660
+
661
+ return node_type_and_index
662
+
663
+ def make_node_coords_in_element(self):
664
+ @cache.dynamic_func(suffix=self.name)
665
+ def node_coords_in_element(
666
+ node_index_in_elt: int,
667
+ ):
668
+ c1, c2 = TetrahedronShapeFunction.edge_vidx(node_index_in_elt)
669
+
670
+ coords = wp.vec4(0.0)
671
+ coords[c1] = 0.5
672
+ coords[c2] = 0.5
673
+
674
+ return Coords(coords[1], coords[2], coords[3])
675
+
676
+ return node_coords_in_element
677
+
678
+ def make_node_quadrature_weight(self):
679
+ NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
680
+
681
+ @cache.dynamic_func(suffix=self.name)
682
+ def node_quadrature_weight(node_index_in_element: int):
683
+ return 1.0 / float(NODES_PER_ELEMENT)
684
+
685
+ return node_quadrature_weight
686
+
687
+ def make_trace_node_quadrature_weight(self):
688
+ NODES_PER_SIDE = self.NODES_PER_SIDE
689
+
690
+ @cache.dynamic_func(suffix=self.name)
691
+ def trace_node_quadrature_weight(node_index_in_element: int):
692
+ return 1.0 / float(NODES_PER_SIDE)
693
+
694
+ return trace_node_quadrature_weight
695
+
696
+ def make_element_inner_weight(self):
697
+ ORDER = self.ORDER
698
+
699
+ def element_inner_weight_linear(
700
+ coords: Coords,
701
+ node_index_in_elt: int,
702
+ ):
703
+ e1, e2 = TetrahedronShapeFunction.opposite_edge_vidx(node_index_in_elt)
704
+
705
+ v1 = self._vertex_coords(e1)
706
+ v2 = self._vertex_coords(e2)
707
+
708
+ nor = v2 - v1
709
+ return wp.cross(nor, coords - v1)
710
+
711
+ if ORDER == 1:
712
+ return cache.get_func(element_inner_weight_linear, self.name)
713
+
714
+ return None
715
+
716
+ def make_element_inner_weight_gradient(self):
717
+ ORDER = self.ORDER
718
+
719
+ def element_inner_weight_gradient_linear(
720
+ coords: Coords,
721
+ node_index_in_elt: int,
722
+ ):
723
+ e1, e2 = TetrahedronShapeFunction.opposite_edge_vidx(node_index_in_elt)
724
+
725
+ v1 = self._vertex_coords(e1)
726
+ v2 = self._vertex_coords(e2)
727
+
728
+ nor = v2 - v1
729
+ return wp.skew(nor)
730
+
731
+ if ORDER == 1:
732
+ return cache.get_func(element_inner_weight_gradient_linear, self.name)
733
+
734
+ return None
735
+
736
+
737
+ class TetrahedronRaviartThomasShapeFunctions(TetrahedronShapeFunction):
738
+ value = ShapeFunction.Value.ContravariantVector
739
+
740
+ def __init__(self, degree: int):
741
+ if degree != 1:
742
+ raise NotImplementedError("Only linear Raviart-Thomas implemented right now")
743
+
744
+ self.ORDER = wp.constant(degree)
745
+
746
+ self.NODES_PER_ELEMENT = wp.constant(4)
747
+ self.NODES_PER_SIDE = wp.constant(1)
748
+
749
+ self.VERTEX_NODE_COUNT = wp.constant(0)
750
+ self.EDGE_NODE_COUNT = wp.constant(0)
751
+ self.FACE_NODE_COUNT = wp.constant(1)
752
+ self.INTERIOR_NODE_COUNT = wp.constant(0)
753
+
754
+ self.node_type_and_type_index = self._get_node_type_and_type_index()
755
+
756
+ @property
757
+ def name(self) -> str:
758
+ return f"TetRT_{self.ORDER}"
759
+
760
+ def _get_node_type_and_type_index(self):
761
+ @cache.dynamic_func(suffix=self.name)
762
+ def node_type_and_index(
763
+ node_index_in_elt: int,
764
+ ):
765
+ return TetrahedronShapeFunction.FACE, node_index_in_elt
766
+
767
+ return node_type_and_index
768
+
769
+ def make_node_coords_in_element(self):
770
+ @cache.dynamic_func(suffix=self.name)
771
+ def node_coords_in_element(
772
+ node_index_in_elt: int,
773
+ ):
774
+ v = (node_index_in_elt + 3) % 4
775
+
776
+ coords = wp.vec4(1.0 / 3.0)
777
+ coords[v] = 0.0
778
+
779
+ return Coords(coords[1], coords[2], coords[3])
780
+
781
+ return node_coords_in_element
782
+
783
+ def make_node_quadrature_weight(self):
784
+ NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
785
+
786
+ @cache.dynamic_func(suffix=self.name)
787
+ def node_quadrature_weight(node_index_in_element: int):
788
+ return 1.0 / float(NODES_PER_ELEMENT)
789
+
790
+ return node_quadrature_weight
791
+
792
+ def make_trace_node_quadrature_weight(self):
793
+ NODES_PER_SIDE = self.NODES_PER_SIDE
794
+
795
+ @cache.dynamic_func(suffix=self.name)
796
+ def trace_node_quadrature_weight(node_index_in_element: int):
797
+ return 1.0 / float(NODES_PER_SIDE)
798
+
799
+ return trace_node_quadrature_weight
800
+
801
+ def make_element_inner_weight(self):
802
+ ORDER = self.ORDER
803
+
804
+ def element_inner_weight_linear(
805
+ coords: Coords,
806
+ node_index_in_elt: int,
807
+ ):
808
+ v = (node_index_in_elt + 3) % 4
809
+
810
+ return 2.0 * (coords - self._vertex_coords(v))
811
+
812
+ if ORDER == 1:
813
+ return cache.get_func(element_inner_weight_linear, self.name)
814
+
815
+ return None
816
+
817
+ def make_element_inner_weight_gradient(self):
818
+ ORDER = self.ORDER
819
+
820
+ def element_inner_weight_gradient_linear(
821
+ coords: Coords,
822
+ node_index_in_elt: int,
823
+ ):
824
+ return 2.0 * wp.identity(n=3, dtype=float)
825
+
826
+ if ORDER == 1:
827
+ return cache.get_func(element_inner_weight_gradient_linear, self.name)
828
+
829
+ return None