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,928 @@
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 math
17
+
18
+ import numpy as np
19
+
20
+ import warp as wp
21
+ from warp._src.fem import cache
22
+ from warp._src.fem.polynomial import Polynomial, is_closed, lagrange_scales, quadrature_1d
23
+ from warp._src.fem.types import Coords
24
+
25
+ from .shape_function import ShapeFunction
26
+ from .triangle_shape_function import TrianglePolynomialShapeFunctions
27
+
28
+ _wp_module_name_ = "warp.fem.space.shape.square_shape_function"
29
+
30
+
31
+ class SquareShapeFunction(ShapeFunction):
32
+ VERTEX = 0
33
+ EDGE_X = 1
34
+ EDGE_Y = 2
35
+ INTERIOR = 3
36
+
37
+ VERTEX_NODE_COUNT: int
38
+ """Number of shape function nodes per vertex"""
39
+
40
+ EDGE_NODE_COUNT: int
41
+ """Number of shape function nodes per triangle edge (excluding vertex nodes)"""
42
+
43
+ INTERIOR_NODE_COUNT: int
44
+ """Number of shape function nodes per triangle (excluding edge and vertex nodes)"""
45
+
46
+ @wp.func
47
+ def _vertex_coords_f(vidx_in_cell: int):
48
+ x = vidx_in_cell // 2
49
+ y = vidx_in_cell - 2 * x
50
+ return wp.vec2(float(x), float(y))
51
+
52
+
53
+ class SquareBipolynomialShapeFunctions(SquareShapeFunction):
54
+ def __init__(self, degree: int, family: Polynomial):
55
+ self.family = family
56
+
57
+ self.ORDER = wp.constant(degree)
58
+ self.NODES_PER_ELEMENT = wp.constant((degree + 1) * (degree + 1))
59
+ self.NODES_PER_SIDE = wp.constant(degree + 1)
60
+
61
+ if is_closed(self.family):
62
+ self.VERTEX_NODE_COUNT = wp.constant(1)
63
+ self.EDGE_NODE_COUNT = wp.constant(max(0, degree - 1))
64
+ self.INTERIOR_NODE_COUNT = wp.constant(max(0, degree - 1) ** 2)
65
+ else:
66
+ self.VERTEX_NODE_COUNT = wp.constant(0)
67
+ self.EDGE_NODE_COUNT = wp.constant(0)
68
+ self.INTERIOR_NODE_COUNT = self.NODES_PER_ELEMENT
69
+
70
+ lobatto_coords, lobatto_weight = quadrature_1d(point_count=degree + 1, family=family)
71
+ lagrange_scale = lagrange_scales(lobatto_coords)
72
+
73
+ NodeVec = cache.cached_vec_type(length=degree + 1, dtype=wp.float32)
74
+ self.LOBATTO_COORDS = wp.constant(NodeVec(lobatto_coords))
75
+ self.LOBATTO_WEIGHT = wp.constant(NodeVec(lobatto_weight))
76
+ self.LAGRANGE_SCALE = wp.constant(NodeVec(lagrange_scale))
77
+ self.ORDER_PLUS_ONE = wp.constant(self.ORDER + 1)
78
+
79
+ self._node_ij = self._make_node_ij()
80
+ self.node_type_and_type_index = self._make_node_type_and_type_index()
81
+
82
+ @property
83
+ def name(self) -> str:
84
+ return f"Square_Q{self.ORDER}_{self.family}"
85
+
86
+ def _make_node_ij(self):
87
+ ORDER_PLUS_ONE = self.ORDER_PLUS_ONE
88
+
89
+ def node_ij(node_index_in_elt: int):
90
+ node_i = node_index_in_elt // ORDER_PLUS_ONE
91
+ node_j = node_index_in_elt - ORDER_PLUS_ONE * node_i
92
+ return node_i, node_j
93
+
94
+ return cache.get_func(node_ij, self.name)
95
+
96
+ def _make_node_type_and_type_index(self):
97
+ ORDER = self.ORDER
98
+
99
+ @cache.dynamic_func(suffix=self.name)
100
+ def node_type_and_type_index_open(
101
+ node_index_in_elt: int,
102
+ ):
103
+ return SquareShapeFunction.INTERIOR, 0, node_index_in_elt
104
+
105
+ @cache.dynamic_func(suffix=self.name)
106
+ def node_type_and_type_index(
107
+ node_index_in_elt: int,
108
+ ):
109
+ i, j = self._node_ij(node_index_in_elt)
110
+
111
+ zi = int(i == 0)
112
+ zj = int(j == 0)
113
+
114
+ mi = int(i == ORDER)
115
+ mj = int(j == ORDER)
116
+
117
+ if zi + mi == 1:
118
+ if zj + mj == 1:
119
+ # vertex
120
+ type_instance = mi * 2 + mj
121
+ return SquareShapeFunction.VERTEX, type_instance, 0
122
+ # y edge
123
+ type_index = j - 1
124
+ type_instance = mi
125
+ return SquareShapeFunction.EDGE_Y, type_instance, type_index
126
+ elif zj + mj == 1:
127
+ # x edge
128
+ type_index = i - 1
129
+ type_instance = mj
130
+ return SquareShapeFunction.EDGE_X, type_instance, type_index
131
+
132
+ type_index = (i - 1) * (ORDER - 1) + (j - 1)
133
+ return SquareShapeFunction.INTERIOR, 0, type_index
134
+
135
+ return node_type_and_type_index if is_closed(self.family) else node_type_and_type_index_open
136
+
137
+ def make_node_coords_in_element(self):
138
+ LOBATTO_COORDS = self.LOBATTO_COORDS
139
+
140
+ @cache.dynamic_func(suffix=self.name)
141
+ def node_coords_in_element(
142
+ node_index_in_elt: int,
143
+ ):
144
+ node_i, node_j = self._node_ij(node_index_in_elt)
145
+ return Coords(LOBATTO_COORDS[node_i], LOBATTO_COORDS[node_j], 0.0)
146
+
147
+ return node_coords_in_element
148
+
149
+ def make_node_quadrature_weight(self):
150
+ ORDER = self.ORDER
151
+ LOBATTO_WEIGHT = self.LOBATTO_WEIGHT
152
+
153
+ def node_quadrature_weight(
154
+ node_index_in_elt: int,
155
+ ):
156
+ node_i, node_j = self._node_ij(node_index_in_elt)
157
+ return LOBATTO_WEIGHT[node_i] * LOBATTO_WEIGHT[node_j]
158
+
159
+ def node_quadrature_weight_linear(
160
+ node_index_in_elt: int,
161
+ ):
162
+ return 0.25
163
+
164
+ if ORDER == 1:
165
+ return cache.get_func(node_quadrature_weight_linear, self.name)
166
+
167
+ return cache.get_func(node_quadrature_weight, self.name)
168
+
169
+ def make_trace_node_quadrature_weight(self):
170
+ ORDER = self.ORDER
171
+ LOBATTO_WEIGHT = self.LOBATTO_WEIGHT
172
+
173
+ def trace_node_quadrature_weight(
174
+ node_index_in_elt: int,
175
+ ):
176
+ # We're either on a side interior or at a vertex
177
+ # I.e., either both indices are at extrema, or only one is
178
+ # Pick the interior one if possible, if both are at extrema pick any one
179
+ node_i, node_j = self._node_ij(node_index_in_elt)
180
+ if node_i > 0 and node_i < ORDER:
181
+ return LOBATTO_WEIGHT[node_i]
182
+
183
+ return LOBATTO_WEIGHT[node_j]
184
+
185
+ def trace_node_quadrature_weight_linear(
186
+ node_index_in_elt: int,
187
+ ):
188
+ return 0.5
189
+
190
+ def trace_node_quadrature_weight_open(
191
+ node_index_in_elt: int,
192
+ ):
193
+ return 0.0
194
+
195
+ if not is_closed(self.family):
196
+ return cache.get_func(trace_node_quadrature_weight_open, self.name)
197
+
198
+ if ORDER == 1:
199
+ return cache.get_func(trace_node_quadrature_weight_linear, self.name)
200
+
201
+ return cache.get_func(trace_node_quadrature_weight, self.name)
202
+
203
+ def make_element_inner_weight(self):
204
+ ORDER_PLUS_ONE = self.ORDER_PLUS_ONE
205
+ LOBATTO_COORDS = self.LOBATTO_COORDS
206
+ LAGRANGE_SCALE = self.LAGRANGE_SCALE
207
+
208
+ def element_inner_weight(
209
+ coords: Coords,
210
+ node_index_in_elt: int,
211
+ ):
212
+ node_i, node_j = self._node_ij(node_index_in_elt)
213
+
214
+ w = float(1.0)
215
+ for k in range(ORDER_PLUS_ONE):
216
+ if k != node_i:
217
+ w *= coords[0] - LOBATTO_COORDS[k]
218
+ if k != node_j:
219
+ w *= coords[1] - LOBATTO_COORDS[k]
220
+
221
+ w *= LAGRANGE_SCALE[node_i] * LAGRANGE_SCALE[node_j]
222
+
223
+ return w
224
+
225
+ def element_inner_weight_linear(
226
+ coords: Coords,
227
+ node_index_in_elt: int,
228
+ ):
229
+ v = SquareBipolynomialShapeFunctions._vertex_coords_f(node_index_in_elt)
230
+
231
+ wx = (1.0 - coords[0]) * (1.0 - v[0]) + v[0] * coords[0]
232
+ wy = (1.0 - coords[1]) * (1.0 - v[1]) + v[1] * coords[1]
233
+ return wx * wy
234
+
235
+ if self.ORDER == 1 and is_closed(self.family):
236
+ return cache.get_func(element_inner_weight_linear, self.name)
237
+
238
+ return cache.get_func(element_inner_weight, self.name)
239
+
240
+ def make_element_inner_weight_gradient(self):
241
+ ORDER_PLUS_ONE = self.ORDER_PLUS_ONE
242
+ LOBATTO_COORDS = self.LOBATTO_COORDS
243
+ LAGRANGE_SCALE = self.LAGRANGE_SCALE
244
+
245
+ def element_inner_weight_gradient(
246
+ coords: Coords,
247
+ node_index_in_elt: int,
248
+ ):
249
+ node_i, node_j = self._node_ij(node_index_in_elt)
250
+
251
+ prefix_x = float(1.0)
252
+ prefix_y = float(1.0)
253
+ for k in range(ORDER_PLUS_ONE):
254
+ if k != node_i:
255
+ prefix_y *= coords[0] - LOBATTO_COORDS[k]
256
+ if k != node_j:
257
+ prefix_x *= coords[1] - LOBATTO_COORDS[k]
258
+
259
+ grad_x = float(0.0)
260
+ grad_y = float(0.0)
261
+
262
+ for k in range(ORDER_PLUS_ONE):
263
+ if k != node_i:
264
+ delta_x = coords[0] - LOBATTO_COORDS[k]
265
+ grad_x = grad_x * delta_x + prefix_x
266
+ prefix_x *= delta_x
267
+ if k != node_j:
268
+ delta_y = coords[1] - LOBATTO_COORDS[k]
269
+ grad_y = grad_y * delta_y + prefix_y
270
+ prefix_y *= delta_y
271
+
272
+ grad = LAGRANGE_SCALE[node_i] * LAGRANGE_SCALE[node_j] * wp.vec2(grad_x, grad_y)
273
+
274
+ return grad
275
+
276
+ def element_inner_weight_gradient_linear(
277
+ coords: Coords,
278
+ node_index_in_elt: int,
279
+ ):
280
+ v = SquareBipolynomialShapeFunctions._vertex_coords_f(node_index_in_elt)
281
+
282
+ wx = (1.0 - coords[0]) * (1.0 - v[0]) + v[0] * coords[0]
283
+ wy = (1.0 - coords[1]) * (1.0 - v[1]) + v[1] * coords[1]
284
+
285
+ dx = 2.0 * v[0] - 1.0
286
+ dy = 2.0 * v[1] - 1.0
287
+
288
+ return wp.vec2(dx * wy, dy * wx)
289
+
290
+ if self.ORDER == 1 and is_closed(self.family):
291
+ return cache.get_func(element_inner_weight_gradient_linear, self.name)
292
+
293
+ return cache.get_func(element_inner_weight_gradient, self.name)
294
+
295
+ def element_node_triangulation(self):
296
+ from warp._src.fem.utils import grid_to_tris
297
+
298
+ return grid_to_tris(self.ORDER, self.ORDER)
299
+
300
+ def element_vtk_cells(self):
301
+ n = self.ORDER + 1
302
+
303
+ # vertices
304
+ cells = [[0, (n - 1) * n, n * n - 1, n - 1]]
305
+
306
+ if self.ORDER == 1:
307
+ cell_type = 9 # VTK_QUAD
308
+ else:
309
+ middle = np.arange(1, n - 1)
310
+
311
+ # edges
312
+ cells.append(middle * n)
313
+ cells.append(middle + (n - 1) * n)
314
+ cells.append(middle * n + n - 1)
315
+ cells.append(middle)
316
+
317
+ # faces
318
+ interior = np.broadcast_to(middle, (n - 2, n - 2))
319
+ cells.append((interior * n + interior.transpose()).flatten())
320
+
321
+ cell_type = 70 # VTK_LAGRANGE_QUADRILATERAL
322
+
323
+ return np.concatenate(cells)[np.newaxis, :], np.array([cell_type], dtype=np.int8)
324
+
325
+
326
+ class SquareSerendipityShapeFunctions(SquareShapeFunction):
327
+ """
328
+ Serendipity element ~ tensor product space without interior nodes
329
+ Side shape functions are usual Lagrange shape functions times a linear function in the normal direction
330
+ Corner shape functions are bilinear shape functions times a function of (x^{d-1} + y^{d-1})
331
+ """
332
+
333
+ def __init__(self, degree: int, family: Polynomial):
334
+ if not is_closed(family):
335
+ raise ValueError("A closed polynomial family is required to define serendipity elements")
336
+
337
+ if degree not in [2, 3]:
338
+ raise NotImplementedError("Serendipity element only implemented for order 2 or 3")
339
+
340
+ self.family = family
341
+
342
+ self.ORDER = wp.constant(degree)
343
+ self.NODES_PER_ELEMENT = wp.constant(4 * degree)
344
+ self.NODES_PER_SIDE = wp.constant(degree + 1)
345
+
346
+ self.VERTEX_NODE_COUNT = wp.constant(1)
347
+ self.EDGE_NODE_COUNT = wp.constant(degree - 1)
348
+ self.INTERIOR_NODE_COUNT = wp.constant(0)
349
+
350
+ lobatto_coords, lobatto_weight = quadrature_1d(point_count=degree + 1, family=family)
351
+ lagrange_scale = lagrange_scales(lobatto_coords)
352
+
353
+ NodeVec = cache.cached_vec_type(length=degree + 1, dtype=wp.float32)
354
+ self.LOBATTO_COORDS = wp.constant(NodeVec(lobatto_coords))
355
+ self.LOBATTO_WEIGHT = wp.constant(NodeVec(lobatto_weight))
356
+ self.LAGRANGE_SCALE = wp.constant(NodeVec(lagrange_scale))
357
+ self.ORDER_PLUS_ONE = wp.constant(self.ORDER + 1)
358
+
359
+ self.node_type_and_type_index = self._get_node_type_and_type_index()
360
+ self._node_lobatto_indices = self._get_node_lobatto_indices()
361
+
362
+ @property
363
+ def name(self) -> str:
364
+ return f"Square_S{self.ORDER}_{self.family}"
365
+
366
+ def _get_node_type_and_type_index(self):
367
+ @cache.dynamic_func(suffix=self.name)
368
+ def node_type_and_index(
369
+ node_index_in_elt: int,
370
+ ):
371
+ if node_index_in_elt < 4:
372
+ return SquareSerendipityShapeFunctions.VERTEX, node_index_in_elt, 0
373
+
374
+ edge_index = (node_index_in_elt - 4) // 2
375
+ edge_axis = node_index_in_elt - 4 - 2 * edge_index
376
+
377
+ index_in_side = edge_index // 2
378
+ side_offset = edge_index - 2 * index_in_side
379
+ return SquareSerendipityShapeFunctions.EDGE_X + edge_axis, side_offset, index_in_side
380
+
381
+ return node_type_and_index
382
+
383
+ def _get_node_lobatto_indices(self):
384
+ ORDER = self.ORDER
385
+
386
+ @cache.dynamic_func(suffix=self.name)
387
+ def node_lobatto_indices(node_type: int, type_instance: int, type_index: int):
388
+ if node_type == SquareSerendipityShapeFunctions.VERTEX:
389
+ node_i = type_instance // 2
390
+ node_j = type_instance - 2 * node_i
391
+ return node_i * ORDER, node_j * ORDER
392
+
393
+ if node_type == SquareSerendipityShapeFunctions.EDGE_X:
394
+ node_i = 1 + type_index
395
+ node_j = type_instance * ORDER
396
+ else:
397
+ node_j = 1 + type_index
398
+ node_i = type_instance * ORDER
399
+
400
+ return node_i, node_j
401
+
402
+ return node_lobatto_indices
403
+
404
+ def make_node_coords_in_element(self):
405
+ LOBATTO_COORDS = self.LOBATTO_COORDS
406
+
407
+ @cache.dynamic_func(suffix=self.name)
408
+ def node_coords_in_element(
409
+ node_index_in_elt: int,
410
+ ):
411
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
412
+ node_i, node_j = self._node_lobatto_indices(node_type, type_instance, type_index)
413
+ return Coords(LOBATTO_COORDS[node_i], LOBATTO_COORDS[node_j], 0.0)
414
+
415
+ return node_coords_in_element
416
+
417
+ def make_node_quadrature_weight(self):
418
+ ORDER = self.ORDER
419
+
420
+ @cache.dynamic_func(suffix=self.name)
421
+ def node_quadrature_weight(
422
+ node_index_in_elt: int,
423
+ ):
424
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
425
+ if node_type == SquareSerendipityShapeFunctions.VERTEX:
426
+ return 0.25 / float(ORDER * ORDER)
427
+
428
+ return (0.25 - 0.25 / float(ORDER * ORDER)) / float(ORDER - 1)
429
+
430
+ return node_quadrature_weight
431
+
432
+ def make_trace_node_quadrature_weight(self):
433
+ LOBATTO_WEIGHT = self.LOBATTO_WEIGHT
434
+
435
+ @cache.dynamic_func(suffix=self.name)
436
+ def trace_node_quadrature_weight(
437
+ node_index_in_elt: int,
438
+ ):
439
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
440
+ if node_type == SquareSerendipityShapeFunctions.VERTEX:
441
+ return LOBATTO_WEIGHT[0]
442
+
443
+ return LOBATTO_WEIGHT[1 + type_index]
444
+
445
+ return trace_node_quadrature_weight
446
+
447
+ def make_element_inner_weight(self):
448
+ ORDER = self.ORDER
449
+ ORDER_PLUS_ONE = self.ORDER_PLUS_ONE
450
+
451
+ LOBATTO_COORDS = self.LOBATTO_COORDS
452
+ LAGRANGE_SCALE = self.LAGRANGE_SCALE
453
+
454
+ DEGREE_3_CIRCLE_RAD = wp.constant(0.5**2 + (0.5 - LOBATTO_COORDS[1]) ** 2)
455
+ DEGREE_3_CIRCLE_SCALE = 1.0 / (0.5 - DEGREE_3_CIRCLE_RAD)
456
+
457
+ @cache.dynamic_func(suffix=self.name)
458
+ def element_inner_weight(
459
+ coords: Coords,
460
+ node_index_in_elt: int,
461
+ ):
462
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
463
+ node_i, node_j = self._node_lobatto_indices(node_type, type_instance, type_index)
464
+
465
+ if node_type == SquareSerendipityShapeFunctions.VERTEX:
466
+ cx = wp.where(node_i == 0, 1.0 - coords[0], coords[0])
467
+ cy = wp.where(node_j == 0, 1.0 - coords[1], coords[1])
468
+
469
+ w = cx * cy
470
+
471
+ if ORDER == 2:
472
+ w *= cx + cy - 2.0 + LOBATTO_COORDS[1]
473
+ return w * LAGRANGE_SCALE[0]
474
+ if ORDER == 3:
475
+ w *= (cx - 0.5) * (cx - 0.5) + (cy - 0.5) * (cy - 0.5) - DEGREE_3_CIRCLE_RAD
476
+ return w * DEGREE_3_CIRCLE_SCALE
477
+
478
+ w = float(1.0)
479
+ if node_type == SquareSerendipityShapeFunctions.EDGE_Y:
480
+ w *= wp.where(node_i == 0, 1.0 - coords[0], coords[0])
481
+ else:
482
+ for k in range(ORDER_PLUS_ONE):
483
+ if k != node_i:
484
+ w *= coords[0] - LOBATTO_COORDS[k]
485
+
486
+ w *= LAGRANGE_SCALE[node_i]
487
+
488
+ if node_type == SquareSerendipityShapeFunctions.EDGE_X:
489
+ w *= wp.where(node_j == 0, 1.0 - coords[1], coords[1])
490
+ else:
491
+ for k in range(ORDER_PLUS_ONE):
492
+ if k != node_j:
493
+ w *= coords[1] - LOBATTO_COORDS[k]
494
+ w *= LAGRANGE_SCALE[node_j]
495
+
496
+ return w
497
+
498
+ return element_inner_weight
499
+
500
+ def make_element_inner_weight_gradient(self):
501
+ ORDER = self.ORDER
502
+ ORDER_PLUS_ONE = self.ORDER_PLUS_ONE
503
+ LOBATTO_COORDS = self.LOBATTO_COORDS
504
+ LAGRANGE_SCALE = self.LAGRANGE_SCALE
505
+
506
+ DEGREE_3_CIRCLE_RAD = wp.constant(0.5**2 + (0.5 - LOBATTO_COORDS[1]) ** 2)
507
+ DEGREE_3_CIRCLE_SCALE = 1.0 / (0.5 - DEGREE_3_CIRCLE_RAD)
508
+
509
+ @cache.dynamic_func(suffix=self.name)
510
+ def element_inner_weight_gradient(
511
+ coords: Coords,
512
+ node_index_in_elt: int,
513
+ ):
514
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
515
+ node_i, node_j = self._node_lobatto_indices(node_type, type_instance, type_index)
516
+
517
+ if node_type == SquareSerendipityShapeFunctions.VERTEX:
518
+ cx = wp.where(node_i == 0, 1.0 - coords[0], coords[0])
519
+ cy = wp.where(node_j == 0, 1.0 - coords[1], coords[1])
520
+
521
+ gx = wp.where(node_i == 0, -1.0, 1.0)
522
+ gy = wp.where(node_j == 0, -1.0, 1.0)
523
+
524
+ if ORDER == 2:
525
+ w = cx + cy - 2.0 + LOBATTO_COORDS[1]
526
+ grad_x = cy * gx * (w + cx)
527
+ grad_y = cx * gy * (w + cy)
528
+
529
+ return wp.vec2(grad_x, grad_y) * LAGRANGE_SCALE[0]
530
+
531
+ if ORDER == 3:
532
+ w = (cx - 0.5) * (cx - 0.5) + (cy - 0.5) * (cy - 0.5) - DEGREE_3_CIRCLE_RAD
533
+
534
+ dw_dcx = 2.0 * cx - 1.0
535
+ dw_dcy = 2.0 * cy - 1.0
536
+ grad_x = cy * gx * (w + cx * dw_dcx)
537
+ grad_y = cx * gy * (w + cy * dw_dcy)
538
+
539
+ return wp.vec2(grad_x, grad_y) * DEGREE_3_CIRCLE_SCALE
540
+
541
+ if node_type == SquareSerendipityShapeFunctions.EDGE_X:
542
+ prefix_x = wp.where(node_j == 0, 1.0 - coords[1], coords[1])
543
+ else:
544
+ prefix_x = LAGRANGE_SCALE[node_j]
545
+ for k in range(ORDER_PLUS_ONE):
546
+ if k != node_j:
547
+ prefix_x *= coords[1] - LOBATTO_COORDS[k]
548
+
549
+ if node_type == SquareSerendipityShapeFunctions.EDGE_Y:
550
+ prefix_y = wp.where(node_i == 0, 1.0 - coords[0], coords[0])
551
+ else:
552
+ prefix_y = LAGRANGE_SCALE[node_i]
553
+ for k in range(ORDER_PLUS_ONE):
554
+ if k != node_i:
555
+ prefix_y *= coords[0] - LOBATTO_COORDS[k]
556
+
557
+ if node_type == SquareSerendipityShapeFunctions.EDGE_X:
558
+ grad_y = wp.where(node_j == 0, -1.0, 1.0) * prefix_y
559
+ else:
560
+ prefix_y *= LAGRANGE_SCALE[node_j]
561
+ grad_y = float(0.0)
562
+ for k in range(ORDER_PLUS_ONE):
563
+ if k != node_j:
564
+ delta_y = coords[1] - LOBATTO_COORDS[k]
565
+ grad_y = grad_y * delta_y + prefix_y
566
+ prefix_y *= delta_y
567
+
568
+ if node_type == SquareSerendipityShapeFunctions.EDGE_Y:
569
+ grad_x = wp.where(node_i == 0, -1.0, 1.0) * prefix_x
570
+ else:
571
+ prefix_x *= LAGRANGE_SCALE[node_i]
572
+ grad_x = float(0.0)
573
+ for k in range(ORDER_PLUS_ONE):
574
+ if k != node_i:
575
+ delta_x = coords[0] - LOBATTO_COORDS[k]
576
+ grad_x = grad_x * delta_x + prefix_x
577
+ prefix_x *= delta_x
578
+
579
+ grad = wp.vec2(grad_x, grad_y)
580
+ return grad
581
+
582
+ return element_inner_weight_gradient
583
+
584
+ def element_node_triangulation(self):
585
+ if self.ORDER == 2:
586
+ element_triangles = [
587
+ [0, 4, 5],
588
+ [5, 4, 6],
589
+ [5, 6, 1],
590
+ [4, 2, 7],
591
+ [4, 7, 6],
592
+ [6, 7, 3],
593
+ ]
594
+ else:
595
+ element_triangles = [
596
+ [0, 4, 5],
597
+ [2, 7, 8],
598
+ [3, 10, 11],
599
+ [1, 9, 6],
600
+ [5, 6, 9],
601
+ [5, 4, 6],
602
+ [8, 11, 10],
603
+ [8, 7, 11],
604
+ [4, 8, 10],
605
+ [4, 10, 6],
606
+ ]
607
+
608
+ return element_triangles
609
+
610
+ def element_vtk_cells(self):
611
+ tris = np.array(self.element_node_triangulation())
612
+ cell_type = 5 # VTK_TRIANGLE
613
+
614
+ return tris, np.full(tris.shape[0], cell_type, dtype=np.int8)
615
+
616
+
617
+ class SquareNonConformingPolynomialShapeFunctions(ShapeFunction):
618
+ # embeds the largest equilateral triangle centered at (0.5, 0.5) into the reference square
619
+ _tri_height = 0.75
620
+ _tri_side = 2.0 / math.sqrt(3.0) * _tri_height
621
+ _tri_to_square = np.array([[_tri_side, _tri_side / 2.0], [0.0, _tri_height]])
622
+
623
+ _TRI_OFFSET = wp.constant(wp.vec2(0.5 - 0.5 * _tri_side, 0.5 - _tri_height / 3.0))
624
+
625
+ def __init__(self, degree: int):
626
+ self._tri_shape = TrianglePolynomialShapeFunctions(degree=degree)
627
+ self.ORDER = self._tri_shape.ORDER
628
+ self.NODES_PER_ELEMENT = self._tri_shape.NODES_PER_ELEMENT
629
+
630
+ self.element_node_triangulation = self._tri_shape.element_node_triangulation
631
+ self.element_vtk_cells = self._tri_shape.element_vtk_cells
632
+
633
+ @property
634
+ def name(self) -> str:
635
+ return f"Square_P{self.ORDER}d"
636
+
637
+ def make_node_coords_in_element(self):
638
+ node_coords_in_tet = self._tri_shape.make_node_coords_in_element()
639
+
640
+ TRI_TO_SQUARE = wp.constant(wp.mat22(self._tri_to_square))
641
+
642
+ @cache.dynamic_func(suffix=self.name)
643
+ def node_coords_in_element(
644
+ node_index_in_elt: int,
645
+ ):
646
+ tri_coords = node_coords_in_tet(node_index_in_elt)
647
+ coords = (
648
+ TRI_TO_SQUARE * wp.vec2(tri_coords[1], tri_coords[2])
649
+ ) + SquareNonConformingPolynomialShapeFunctions._TRI_OFFSET
650
+ return Coords(coords[0], coords[1], 0.0)
651
+
652
+ return node_coords_in_element
653
+
654
+ def make_node_quadrature_weight(self):
655
+ NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
656
+
657
+ if self.ORDER == 2:
658
+ # Intrinsic quadrature (order 2)
659
+ @cache.dynamic_func(suffix=self.name)
660
+ def node_quadrature_weight_quadratic(
661
+ node_index_in_elt: int,
662
+ ):
663
+ node_type, type_index = self._tri_shape.node_type_and_type_index(node_index_in_elt)
664
+ if node_type == TrianglePolynomialShapeFunctions.VERTEX:
665
+ return 0.18518521
666
+ return 0.14814811
667
+
668
+ return node_quadrature_weight_quadratic
669
+
670
+ @cache.dynamic_func(suffix=self.name)
671
+ def node_uniform_quadrature_weight(
672
+ node_index_in_elt: int,
673
+ ):
674
+ return 1.0 / float(NODES_PER_ELEMENT)
675
+
676
+ return node_uniform_quadrature_weight
677
+
678
+ def make_trace_node_quadrature_weight(self):
679
+ # Non-conforming, zero measure on sides
680
+
681
+ @wp.func
682
+ def zero(node_index_in_elt: int):
683
+ return 0.0
684
+
685
+ return zero
686
+
687
+ def make_element_inner_weight(self):
688
+ tri_inner_weight = self._tri_shape.make_element_inner_weight()
689
+
690
+ SQUARE_TO_TRI = wp.constant(wp.mat22(np.linalg.inv(self._tri_to_square)))
691
+
692
+ @cache.dynamic_func(suffix=self.name)
693
+ def element_inner_weight(
694
+ coords: Coords,
695
+ node_index_in_elt: int,
696
+ ):
697
+ tri_param = SQUARE_TO_TRI * (
698
+ wp.vec2(coords[0], coords[1]) - SquareNonConformingPolynomialShapeFunctions._TRI_OFFSET
699
+ )
700
+ tri_coords = Coords(1.0 - tri_param[0] - tri_param[1], tri_param[0], tri_param[1])
701
+
702
+ return tri_inner_weight(tri_coords, node_index_in_elt)
703
+
704
+ return element_inner_weight
705
+
706
+ def make_element_inner_weight_gradient(self):
707
+ tri_inner_weight_gradient = self._tri_shape.make_element_inner_weight_gradient()
708
+
709
+ SQUARE_TO_TRI = wp.constant(wp.mat22(np.linalg.inv(self._tri_to_square)))
710
+
711
+ @cache.dynamic_func(suffix=self.name)
712
+ def element_inner_weight_gradient(
713
+ coords: Coords,
714
+ node_index_in_elt: int,
715
+ ):
716
+ tri_param = SQUARE_TO_TRI * (
717
+ wp.vec2(coords[0], coords[1]) - SquareNonConformingPolynomialShapeFunctions._TRI_OFFSET
718
+ )
719
+ tri_coords = Coords(1.0 - tri_param[0] - tri_param[1], tri_param[0], tri_param[1])
720
+
721
+ grad = tri_inner_weight_gradient(tri_coords, node_index_in_elt)
722
+ return wp.transpose(SQUARE_TO_TRI) * grad
723
+
724
+ return element_inner_weight_gradient
725
+
726
+
727
+ class SquareNedelecFirstKindShapeFunctions(SquareShapeFunction):
728
+ value = ShapeFunction.Value.CovariantVector
729
+
730
+ def __init__(self, degree: int):
731
+ if degree != 1:
732
+ raise NotImplementedError("Only linear Nédélec implemented right now")
733
+
734
+ self.ORDER = wp.constant(degree)
735
+ self.NODES_PER_ELEMENT = wp.constant(4)
736
+ self.NODES_PER_SIDE = wp.constant(1)
737
+
738
+ self.VERTEX_NODE_COUNT = wp.constant(0)
739
+ self.EDGE_NODE_COUNT = wp.constant(1)
740
+ self.INTERIOR_NODE_COUNT = wp.constant(0)
741
+
742
+ self.node_type_and_type_index = self._get_node_type_and_type_index()
743
+
744
+ @property
745
+ def name(self) -> str:
746
+ return f"SquareN1_{self.ORDER}"
747
+
748
+ def _get_node_type_and_type_index(self):
749
+ @cache.dynamic_func(suffix=self.name)
750
+ def node_type_and_index(
751
+ node_index_in_elt: int,
752
+ ):
753
+ axis = node_index_in_elt // 2
754
+ offset = node_index_in_elt - 2 * axis
755
+ return SquareShapeFunction.EDGE_X + axis, offset, 0
756
+
757
+ return node_type_and_index
758
+
759
+ def make_node_coords_in_element(self):
760
+ @cache.dynamic_func(suffix=self.name)
761
+ def node_coords_in_element(
762
+ node_index_in_elt: int,
763
+ ):
764
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
765
+ axis = node_type - SquareShapeFunction.EDGE_X
766
+
767
+ coords = Coords()
768
+ coords[axis] = 0.5
769
+ coords[1 - axis] = float(type_instance)
770
+
771
+ return node_coords_in_element
772
+
773
+ def make_node_quadrature_weight(self):
774
+ NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
775
+
776
+ @cache.dynamic_func(suffix=self.name)
777
+ def node_quadrature_weight(node_index_in_element: int):
778
+ return 1.0 / float(NODES_PER_ELEMENT)
779
+
780
+ return node_quadrature_weight
781
+
782
+ def make_trace_node_quadrature_weight(self):
783
+ NODES_PER_SIDE = self.NODES_PER_SIDE
784
+
785
+ @cache.dynamic_func(suffix=self.name)
786
+ def trace_node_quadrature_weight(node_index_in_element: int):
787
+ return 1.0 / float(NODES_PER_SIDE)
788
+
789
+ return trace_node_quadrature_weight
790
+
791
+ def make_element_inner_weight(self):
792
+ @cache.dynamic_func(suffix=self.name)
793
+ def element_inner_weight(
794
+ coords: Coords,
795
+ node_index_in_elt: int,
796
+ ):
797
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
798
+
799
+ axis = node_type - SquareShapeFunction.EDGE_X
800
+ a = float(2 * type_instance - 1)
801
+ b = float(1 - type_instance)
802
+
803
+ w = wp.vec2(0.0)
804
+ w[axis] = b + a * coords[1 - axis]
805
+
806
+ return w
807
+
808
+ return element_inner_weight
809
+
810
+ def make_element_inner_weight_gradient(self):
811
+ @cache.dynamic_func(suffix=self.name)
812
+ def element_inner_weight_gradient(
813
+ coords: Coords,
814
+ node_index_in_elt: int,
815
+ ):
816
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
817
+
818
+ axis = node_type - SquareShapeFunction.EDGE_X
819
+ a = float(2 * type_instance - 1)
820
+
821
+ grad = wp.mat22(0.0)
822
+ grad[axis, 1 - axis] = a
823
+
824
+ return grad
825
+
826
+ return element_inner_weight_gradient
827
+
828
+
829
+ class SquareRaviartThomasShapeFunctions(SquareShapeFunction):
830
+ value = ShapeFunction.Value.ContravariantVector
831
+
832
+ def __init__(self, degree: int):
833
+ if degree != 1:
834
+ raise NotImplementedError("Only linear Nédélec implemented right now")
835
+
836
+ self.ORDER = wp.constant(degree)
837
+ self.NODES_PER_ELEMENT = wp.constant(4)
838
+ self.NODES_PER_SIDE = wp.constant(1)
839
+
840
+ self.VERTEX_NODE_COUNT = wp.constant(0)
841
+ self.EDGE_NODE_COUNT = wp.constant(1)
842
+ self.INTERIOR_NODE_COUNT = wp.constant(0)
843
+
844
+ self.node_type_and_type_index = self._get_node_type_and_type_index()
845
+
846
+ @property
847
+ def name(self) -> str:
848
+ return f"SquareRT_{self.ORDER}"
849
+
850
+ def _get_node_type_and_type_index(self):
851
+ @cache.dynamic_func(suffix=self.name)
852
+ def node_type_and_index(
853
+ node_index_in_elt: int,
854
+ ):
855
+ axis = node_index_in_elt // 2
856
+ offset = node_index_in_elt - 2 * axis
857
+ return SquareShapeFunction.EDGE_X + axis, offset, 0
858
+
859
+ return node_type_and_index
860
+
861
+ def make_node_coords_in_element(self):
862
+ @cache.dynamic_func(suffix=self.name)
863
+ def node_coords_in_element(
864
+ node_index_in_elt: int,
865
+ ):
866
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
867
+ axis = node_type - SquareShapeFunction.EDGE_X
868
+
869
+ coords = Coords()
870
+ coords[axis] = 0.5
871
+ coords[1 - axis] = float(type_instance)
872
+
873
+ return node_coords_in_element
874
+
875
+ def make_node_quadrature_weight(self):
876
+ NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
877
+
878
+ @cache.dynamic_func(suffix=self.name)
879
+ def node_quadrature_weight(node_index_in_element: int):
880
+ return 1.0 / float(NODES_PER_ELEMENT)
881
+
882
+ return node_quadrature_weight
883
+
884
+ def make_trace_node_quadrature_weight(self):
885
+ NODES_PER_SIDE = self.NODES_PER_SIDE
886
+
887
+ @cache.dynamic_func(suffix=self.name)
888
+ def trace_node_quadrature_weight(node_index_in_element: int):
889
+ return 1.0 / float(NODES_PER_SIDE)
890
+
891
+ return trace_node_quadrature_weight
892
+
893
+ def make_element_inner_weight(self):
894
+ @cache.dynamic_func(suffix=self.name)
895
+ def element_inner_weight(
896
+ coords: Coords,
897
+ node_index_in_elt: int,
898
+ ):
899
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
900
+
901
+ axis = node_type - SquareShapeFunction.EDGE_X
902
+ a = float(2 * type_instance - 1)
903
+ b = float(1 - type_instance)
904
+
905
+ w = wp.vec2(0.0)
906
+ w[1 - axis] = b + a * coords[1 - axis]
907
+
908
+ return w
909
+
910
+ return element_inner_weight
911
+
912
+ def make_element_inner_weight_gradient(self):
913
+ @cache.dynamic_func(suffix=self.name)
914
+ def element_inner_weight_gradient(
915
+ coords: Coords,
916
+ node_index_in_elt: int,
917
+ ):
918
+ node_type, type_instance, type_index = self.node_type_and_type_index(node_index_in_elt)
919
+
920
+ axis = node_type - SquareShapeFunction.EDGE_X
921
+ a = float(2 * type_instance - 1)
922
+
923
+ grad = wp.mat22(0.0)
924
+ grad[1 - axis, 1 - axis] = a
925
+
926
+ return grad
927
+
928
+ return element_inner_weight_gradient