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,261 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 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
+ ###########################################################################
17
+ # Example Burgers
18
+ #
19
+ # This example simulates an inviscid non-conservative Burgers PDE using
20
+ # Discontinuous Galerkin with minmod slope limiter
21
+ #
22
+ # d u /dt + (u . grad) u = 0
23
+ #
24
+ ###########################################################################
25
+
26
+ import warp as wp
27
+ import warp.examples.fem.utils as fem_example_utils
28
+ import warp.fem as fem
29
+
30
+
31
+ @fem.integrand
32
+ def vel_mass_form(
33
+ s: fem.Sample,
34
+ u: fem.Field,
35
+ v: fem.Field,
36
+ ):
37
+ return wp.dot(v(s), u(s))
38
+
39
+
40
+ @fem.integrand
41
+ def upwind_transport_form(s: fem.Sample, domain: fem.Domain, u: fem.Field, v: fem.Field, w: fem.Field):
42
+ # Upwinding transport with discontinuous convection velocity,
43
+ # using jump(w v) = jump(w) avg(v) + avg(w) jump(w)
44
+
45
+ nor = fem.normal(domain, s)
46
+ w_avg_n = wp.dot(fem.average(w, s), nor)
47
+ w_jump_n = wp.dot(fem.jump(w, s), nor)
48
+
49
+ x = domain(s)
50
+ v_avg = fem.average(v, s)
51
+ if x[0] <= 0.0 or x[0] >= 1.0: # out
52
+ # if x[0] >= 1.0: # out
53
+ v_jump = v(s)
54
+ else:
55
+ v_jump = fem.jump(v, s)
56
+
57
+ u_avg = fem.average(u, s)
58
+ u_jump = fem.jump(u, s)
59
+
60
+ return wp.dot(u_avg, v_jump * w_avg_n + v_avg * w_jump_n) + 0.5 * wp.dot(v_jump, u_jump) * (
61
+ wp.abs(w_avg_n) + 0.5 * wp.abs(w_jump_n)
62
+ )
63
+
64
+
65
+ @fem.integrand
66
+ def cell_transport_form(s: fem.Sample, domain: fem.Domain, u: fem.Field, v: fem.Field, w: fem.Field):
67
+ # ((w . grad) u) . v = v^T (grad u) w = grad(u) : (v w^T)
68
+ # with integration by parts
69
+ # u . Div (w v^T) = u^T grad(v) w + u^T v div (w)
70
+
71
+ return -wp.dot(fem.div(w, s) * v(s) + fem.grad(v, s) * w(s), u(s))
72
+
73
+
74
+ @fem.integrand
75
+ def initial_condition(s: fem.Sample, domain: fem.Domain):
76
+ x = domain(s)[0] * 2.0
77
+ wave = wp.sin(x * wp.pi)
78
+ return wp.vec2(wp.where(x <= 1.0, wave, 0.0), 0.0)
79
+
80
+
81
+ @fem.integrand
82
+ def velocity_norm(s: fem.Sample, u: fem.Field):
83
+ return wp.length(u(s))
84
+
85
+
86
+ @wp.func
87
+ def minmod(a: float, b: float):
88
+ sa = wp.sign(a)
89
+ sb = wp.sign(b)
90
+ return wp.where(sa == sb, sa * wp.min(wp.abs(a), wp.abs(b)), 0.0)
91
+
92
+
93
+ @fem.integrand
94
+ def slope_limiter(domain: fem.Domain, s: fem.Sample, u: fem.Field, dx: wp.vec2):
95
+ # Minmod slope limiter against P0 discretization (evaluation at cell centers)
96
+ # Assumes regular grid topology
97
+
98
+ center_coords = fem.Coords(0.5, 0.5, 0.0)
99
+ cell_center = fem.make_free_sample(s.element_index, center_coords)
100
+ center_pos = domain(cell_center)
101
+
102
+ u_center = u(cell_center)
103
+
104
+ delta_coords = s.element_coords - center_coords
105
+
106
+ neighbour_xp = fem.lookup(domain, center_pos + wp.vec2(dx[0], 0.0))
107
+ neighbour_yp = fem.lookup(domain, center_pos + wp.vec2(0.0, dx[1]))
108
+ neighbour_xm = fem.lookup(domain, center_pos - wp.vec2(dx[0], 0.0))
109
+ neighbour_ym = fem.lookup(domain, center_pos - wp.vec2(0.0, dx[1]))
110
+
111
+ u_nxp = u(neighbour_xp)
112
+ u_nyp = u(neighbour_yp)
113
+ u_nxm = u(neighbour_xm)
114
+ u_nym = u(neighbour_ym)
115
+
116
+ gx = minmod(u_nxp[0] - u_center[0], u_center[0] - u_nxm[0]) * delta_coords[0]
117
+ gy = minmod(u_nyp[1] - u_center[1], u_center[1] - u_nym[1]) * delta_coords[1]
118
+
119
+ delta_u = u(s) - u_center
120
+ return u_center + wp.vec2(minmod(gx, delta_u[0]), minmod(gy, delta_u[1]))
121
+
122
+
123
+ class Example:
124
+ def __init__(self, quiet=False, resolution=50, degree=1):
125
+ self._quiet = quiet
126
+
127
+ res = resolution
128
+ self.sim_dt = 1.0 / res
129
+ self.current_frame = 0
130
+
131
+ geo = fem.Grid2D(res=wp.vec2i(resolution))
132
+
133
+ domain = fem.Cells(geometry=geo)
134
+ sides = fem.Sides(geo)
135
+
136
+ basis_space = fem.make_polynomial_basis_space(geo, degree=degree, discontinuous=True)
137
+ vector_space = fem.make_collocated_function_space(basis_space, dtype=wp.vec2)
138
+ scalar_space = fem.make_collocated_function_space(basis_space, dtype=float)
139
+
140
+ # Test function for ou vector space
141
+ self._test = fem.make_test(space=vector_space, domain=domain)
142
+ # Test function for integration on sides
143
+ self._side_test = fem.make_test(space=vector_space, domain=sides)
144
+
145
+ # Inertia matrix
146
+ # For simplicity, use nodal integration so that inertia matrix is diagonal
147
+ trial = fem.make_trial(space=vector_space, domain=domain)
148
+ matrix_inertia = fem.integrate(
149
+ vel_mass_form, fields={"u": trial, "v": self._test}, output_dtype=wp.float32, assembly="nodal"
150
+ )
151
+ self._inv_mass_matrix = wp.sparse.bsr_copy(matrix_inertia)
152
+ fem_example_utils.invert_diagonal_bsr_matrix(self._inv_mass_matrix)
153
+
154
+ # Initial condition
155
+ self.velocity_field = vector_space.make_field()
156
+ fem.interpolate(initial_condition, dest=self.velocity_field)
157
+
158
+ # Velocity norm field -- for visualization purposes
159
+ self.velocity_norm_field = scalar_space.make_field()
160
+ fem.interpolate(velocity_norm, dest=self.velocity_norm_field, fields={"u": self.velocity_field})
161
+
162
+ self.renderer = fem_example_utils.Plot()
163
+ self.renderer.add_field("u_norm", self.velocity_norm_field)
164
+
165
+ def _velocity_delta(self, trial_velocity):
166
+ # Integration on sides
167
+ rhs = fem.integrate(
168
+ upwind_transport_form,
169
+ fields={"u": trial_velocity.trace(), "v": self._side_test, "w": trial_velocity.trace()},
170
+ output_dtype=wp.vec2,
171
+ )
172
+
173
+ if self.velocity_field.space.degree > 0:
174
+ # Integration on cells (if not piecewise-constant)
175
+ fem.linalg.array_axpy(
176
+ x=fem.integrate(
177
+ cell_transport_form,
178
+ fields={"u": trial_velocity, "v": self._test, "w": trial_velocity},
179
+ output_dtype=wp.vec2,
180
+ quadrature=fem.RegularQuadrature(
181
+ order=3, domain=self._test.domain, family=fem.Polynomial.LOBATTO_GAUSS_LEGENDRE
182
+ ),
183
+ ),
184
+ y=rhs,
185
+ alpha=1.0,
186
+ beta=1.0,
187
+ )
188
+ return self._inv_mass_matrix @ rhs
189
+
190
+ def step(self):
191
+ self.current_frame += 1
192
+
193
+ # Third-order Strong Stability Preserving Runge-Kutta (SSPRK3)
194
+
195
+ k1 = self._velocity_delta(self.velocity_field)
196
+
197
+ # tmp = v0 - dt * k1
198
+ tmp = self.velocity_field.space.make_field()
199
+ fem.linalg.array_axpy(y=tmp.dof_values, x=self.velocity_field.dof_values, alpha=1.0, beta=0.0)
200
+ fem.linalg.array_axpy(y=tmp.dof_values, x=k1, alpha=-self.sim_dt, beta=1.0)
201
+ k2 = self._velocity_delta(tmp)
202
+
203
+ # tmp = v0 - dt * (0.25 * k1 + 0.25 * k2)
204
+ fem.linalg.array_axpy(y=tmp.dof_values, x=k1, alpha=0.75 * self.sim_dt, beta=1.0)
205
+ fem.linalg.array_axpy(y=tmp.dof_values, x=k2, alpha=-0.25 * self.sim_dt, beta=1.0)
206
+ k3 = self._velocity_delta(tmp)
207
+
208
+ # v = v0 - dt * (1/6 * k1 + 1/6 * k2 + 2/3 * k3)
209
+ fem.linalg.array_axpy(y=self.velocity_field.dof_values, x=k1, alpha=-1.0 / 6.0 * self.sim_dt, beta=1.0)
210
+ fem.linalg.array_axpy(y=self.velocity_field.dof_values, x=k2, alpha=-1.0 / 6.0 * self.sim_dt, beta=1.0)
211
+ fem.linalg.array_axpy(y=self.velocity_field.dof_values, x=k3, alpha=-2.0 / 3.0 * self.sim_dt, beta=1.0)
212
+
213
+ # Apply slope limiter
214
+ if self.velocity_field.space.degree > 0:
215
+ res = self.velocity_field.space.geometry.res
216
+ dx = wp.vec2(1.0 / res[0], 1.0 / res[1])
217
+ fem.interpolate(slope_limiter, dest=tmp, fields={"u": self.velocity_field}, values={"dx": dx})
218
+ wp.copy(src=tmp.dof_values, dest=self.velocity_field.dof_values)
219
+
220
+ # Update velocity norm (for visualization)
221
+ fem.interpolate(velocity_norm, dest=self.velocity_norm_field, fields={"u": self.velocity_field})
222
+
223
+ def render(self):
224
+ self.renderer.begin_frame(time=self.current_frame * self.sim_dt)
225
+ self.renderer.add_field("u_norm", self.velocity_norm_field)
226
+ self.renderer.end_frame()
227
+
228
+
229
+ if __name__ == "__main__":
230
+ import argparse
231
+
232
+ wp.set_module_options({"enable_backward": False})
233
+
234
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
235
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
236
+ parser.add_argument("--resolution", type=int, default=50, help="Grid resolution.")
237
+ parser.add_argument("--num_frames", type=int, default=250, help="Total number of frames.")
238
+ parser.add_argument("--degree", choices=(0, 1), type=int, default=1, help="Discretization order.")
239
+ parser.add_argument(
240
+ "--headless",
241
+ action="store_true",
242
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
243
+ )
244
+ parser.add_argument("--quiet", action="store_true")
245
+
246
+ args = parser.parse_known_args()[0]
247
+
248
+ with wp.ScopedDevice(args.device):
249
+ example = Example(
250
+ quiet=args.quiet,
251
+ resolution=args.resolution,
252
+ degree=args.degree,
253
+ )
254
+
255
+ for k in range(args.num_frames):
256
+ print(f"Frame {k}:")
257
+ example.step()
258
+ example.render()
259
+
260
+ if not args.headless:
261
+ example.renderer.plot()
@@ -0,0 +1,181 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 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
+ ###########################################################################
17
+ # Example Convection Diffusion
18
+ #
19
+ # This example simulates a convection-diffusion PDE using
20
+ # semi-Lagrangian advection
21
+ #
22
+ # D phi / dt - nu d2 phi / dx^2 = 0
23
+ ###########################################################################
24
+
25
+ import warp as wp
26
+ import warp.examples.fem.utils as fem_example_utils
27
+ import warp.fem as fem
28
+
29
+
30
+ @fem.integrand
31
+ def initial_condition(domain: fem.Domain, s: fem.Sample):
32
+ """Initial condition: 1.0 in ]0.6, 0.4[ x ]0.2, 0.8[, 0.0 elsewhere"""
33
+ pos = domain(s)
34
+ if pos[0] > 0.4 and pos[0] < 0.6 and pos[1] > 0.2 and pos[1] < 0.8:
35
+ return 1.0
36
+ return 0.0
37
+
38
+
39
+ @wp.func
40
+ def velocity(pos: wp.vec2, ang_vel: float):
41
+ center = wp.vec2(0.5, 0.5)
42
+ offset = pos - center
43
+ return wp.vec2(offset[1], -offset[0]) * ang_vel
44
+
45
+
46
+ @fem.integrand
47
+ def inertia_form(s: fem.Sample, phi: fem.Field, psi: fem.Field, dt: float):
48
+ return phi(s) * psi(s) / dt
49
+
50
+
51
+ @fem.integrand
52
+ def transported_inertia_form(
53
+ s: fem.Sample, domain: fem.Domain, phi: fem.Field, psi: fem.Field, ang_vel: float, dt: float
54
+ ):
55
+ pos = domain(s)
56
+ vel = velocity(pos, ang_vel)
57
+
58
+ # semi-Lagrangian advection; evaluate phi upstream
59
+ conv_pos = pos - vel * dt
60
+ # lookup operator constructs a Sample from a world position.
61
+ # the optional last argument provides a initial guess for the lookup
62
+ conv_phi = phi(fem.lookup(domain, conv_pos, s))
63
+
64
+ return conv_phi * psi(s) / dt
65
+
66
+
67
+ @fem.integrand
68
+ def diffusion_form(
69
+ s: fem.Sample,
70
+ u: fem.Field,
71
+ v: fem.Field,
72
+ ):
73
+ return wp.dot(
74
+ fem.grad(u, s),
75
+ fem.grad(v, s),
76
+ )
77
+
78
+
79
+ @fem.integrand
80
+ def diffusion_and_inertia_form(s: fem.Sample, phi: fem.Field, psi: fem.Field, dt: float, nu: float):
81
+ return inertia_form(s, phi, psi, dt) + nu * diffusion_form(s, phi, psi)
82
+
83
+
84
+ class Example:
85
+ def __init__(self, quiet=False, degree=2, resolution=50, mesh: str = "grid", viscosity=0.001, ang_vel=1.0):
86
+ self._quiet = quiet
87
+
88
+ self._ang_vel = ang_vel
89
+
90
+ res = resolution
91
+ self.sim_dt = 1.0 / (ang_vel * res)
92
+ self.current_frame = 0
93
+
94
+ if mesh == "tri":
95
+ positions, tri_vidx = fem_example_utils.gen_trimesh(res=wp.vec2i(resolution))
96
+ geo = fem.Trimesh2D(tri_vertex_indices=tri_vidx, positions=positions, build_bvh=True)
97
+ elif mesh == "quad":
98
+ positions, quad_vidx = fem_example_utils.gen_quadmesh(res=wp.vec2i(resolution))
99
+ geo = fem.Quadmesh2D(quad_vertex_indices=quad_vidx, positions=positions, build_bvh=True)
100
+ else:
101
+ geo = fem.Grid2D(res=wp.vec2i(resolution))
102
+
103
+ domain = fem.Cells(geometry=geo)
104
+ scalar_space = fem.make_polynomial_space(geo, degree=degree)
105
+
106
+ # Initial condition
107
+ self._phi_field = scalar_space.make_field()
108
+ fem.interpolate(initial_condition, dest=self._phi_field)
109
+
110
+ # Assemble diffusion and inertia matrix
111
+ self._test = fem.make_test(space=scalar_space, domain=domain)
112
+ self._trial = fem.make_trial(space=scalar_space, domain=domain)
113
+ self._matrix = fem.integrate(
114
+ diffusion_and_inertia_form,
115
+ fields={"phi": self._trial, "psi": self._test},
116
+ values={"nu": viscosity, "dt": self.sim_dt},
117
+ output_dtype=float,
118
+ )
119
+
120
+ self.renderer = fem_example_utils.Plot()
121
+ self.renderer.add_field("phi", self._phi_field)
122
+
123
+ def step(self):
124
+ self.current_frame += 1
125
+
126
+ # right-hand-side -- advected inertia
127
+ rhs = fem.integrate(
128
+ transported_inertia_form,
129
+ fields={"phi": self._phi_field, "psi": self._test},
130
+ values={"ang_vel": self._ang_vel, "dt": self.sim_dt},
131
+ output_dtype=float,
132
+ )
133
+
134
+ # Solve linear system
135
+ fem_example_utils.bsr_cg(self._matrix, x=self._phi_field.dof_values, b=rhs, quiet=self._quiet, tol=1.0e-12)
136
+
137
+ def render(self):
138
+ self.renderer.begin_frame(time=self.current_frame * self.sim_dt)
139
+ self.renderer.add_field("phi", self._phi_field)
140
+ self.renderer.end_frame()
141
+
142
+
143
+ if __name__ == "__main__":
144
+ import argparse
145
+
146
+ wp.set_module_options({"enable_backward": False})
147
+
148
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
149
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
150
+ parser.add_argument("--resolution", type=int, default=50, help="Grid resolution.")
151
+ parser.add_argument("--degree", type=int, default=2, help="Polynomial degree of shape functions.")
152
+ parser.add_argument("--num_frames", type=int, default=250, help="Total number of frames.")
153
+ parser.add_argument("--viscosity", type=float, default=0.001, help="Fluid viscosity parameter.")
154
+ parser.add_argument("--ang_vel", type=float, default=1.0, help="Angular velocity.")
155
+ parser.add_argument("--mesh", choices=("grid", "tri", "quad"), default="grid", help="Mesh type.")
156
+ parser.add_argument(
157
+ "--headless",
158
+ action="store_true",
159
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
160
+ )
161
+ parser.add_argument("--quiet", action="store_true", help="Suppresses the printing out of iteration residuals.")
162
+
163
+ args = parser.parse_known_args()[0]
164
+
165
+ with wp.ScopedDevice(args.device):
166
+ example = Example(
167
+ quiet=args.quiet,
168
+ degree=args.degree,
169
+ resolution=args.resolution,
170
+ mesh=args.mesh,
171
+ viscosity=args.viscosity,
172
+ ang_vel=args.ang_vel,
173
+ )
174
+
175
+ for k in range(args.num_frames):
176
+ print(f"Frame {k}:")
177
+ example.step()
178
+ example.render()
179
+
180
+ if not args.headless:
181
+ example.renderer.plot()
@@ -0,0 +1,225 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 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
+ ###########################################################################
17
+ # Example Convection Diffusion DG
18
+ #
19
+ # This example simulates a convection-diffusion PDE using Discontinuous
20
+ # Galerkin with upwind transport and Symmetric Interior Penalty
21
+ #
22
+ # D phi / dt - nu d2 phi / dx^2 = 0
23
+ ###########################################################################
24
+
25
+ import warp as wp
26
+ import warp.examples.fem.utils as fem_example_utils
27
+ import warp.fem as fem
28
+ from warp.examples.fem.example_convection_diffusion import (
29
+ diffusion_form,
30
+ inertia_form,
31
+ initial_condition,
32
+ velocity,
33
+ )
34
+
35
+
36
+ # Standard transport term, on cells' interior
37
+ @fem.integrand
38
+ def transport_form(s: fem.Sample, domain: fem.Domain, phi: fem.Field, psi: fem.Field, ang_vel: float):
39
+ pos = domain(s)
40
+ vel = velocity(pos, ang_vel)
41
+
42
+ return psi(s) * wp.dot(fem.grad(phi, s), vel)
43
+
44
+
45
+ # Upwind flux, on cell sides
46
+ @fem.integrand
47
+ def upwind_transport_form(s: fem.Sample, domain: fem.Domain, phi: fem.Field, psi: fem.Field, ang_vel: float):
48
+ pos = domain(s)
49
+ vel = velocity(pos, ang_vel)
50
+ vel_n = wp.dot(vel, fem.normal(domain, s))
51
+
52
+ if wp.min(pos) <= 0.0 or wp.max(pos) >= 1.0: # boundary side
53
+ return phi(s) * (-psi(s) * vel_n + 0.5 * psi(s) * wp.abs(vel_n))
54
+
55
+ # interior side
56
+ return fem.jump(phi, s) * (-fem.average(psi, s) * vel_n + 0.5 * fem.jump(psi, s) * wp.abs(vel_n))
57
+
58
+
59
+ # Symmetric-Interior-Penalty diffusion term (See Pietro Ern 2012)
60
+ @fem.integrand
61
+ def sip_diffusion_form(
62
+ s: fem.Sample,
63
+ domain: fem.Domain,
64
+ psi: fem.Field,
65
+ phi: fem.Field,
66
+ ):
67
+ nor = fem.normal(domain, s)
68
+ penalty = fem.measure_ratio(domain, s) * float(fem.degree(psi) * fem.degree(phi))
69
+
70
+ return penalty * fem.jump(phi, s) * fem.jump(psi, s) - (
71
+ wp.dot(fem.grad_average(phi, s), nor) * fem.jump(psi, s)
72
+ + wp.dot(fem.grad_average(psi, s), nor) * fem.jump(phi, s)
73
+ )
74
+
75
+
76
+ class Example:
77
+ def __init__(self, quiet=False, degree=2, resolution=50, mesh="grid", viscosity=0.0001, ang_vel=1.0):
78
+ self._quiet = quiet
79
+
80
+ res = resolution
81
+ self.sim_dt = 1.0 / (ang_vel * res)
82
+ self.current_frame = 0
83
+
84
+ if mesh == "tri":
85
+ positions, tri_vidx = fem_example_utils.gen_trimesh(res=wp.vec2i(resolution))
86
+ geo = fem.Trimesh2D(tri_vertex_indices=tri_vidx, positions=positions)
87
+ elif mesh == "quad":
88
+ positions, quad_vidx = fem_example_utils.gen_quadmesh(res=wp.vec2i(resolution))
89
+ geo = fem.Quadmesh2D(quad_vertex_indices=quad_vidx, positions=positions)
90
+ else:
91
+ geo = fem.Grid2D(res=wp.vec2i(resolution))
92
+
93
+ domain = fem.Cells(geometry=geo)
94
+ sides = fem.Sides(geo)
95
+ scalar_space = fem.make_polynomial_space(
96
+ geo,
97
+ discontinuous=True,
98
+ degree=degree,
99
+ family=fem.Polynomial.LOBATTO_GAUSS_LEGENDRE,
100
+ )
101
+
102
+ # Assemble transport, diffusion and inertia matrices
103
+
104
+ self._test = fem.make_test(space=scalar_space, domain=domain)
105
+ trial = fem.make_trial(space=scalar_space, domain=domain)
106
+
107
+ matrix_inertia = fem.integrate(
108
+ inertia_form,
109
+ fields={"phi": trial, "psi": self._test},
110
+ values={"dt": self.sim_dt},
111
+ )
112
+
113
+ matrix_transport = fem.integrate(
114
+ transport_form,
115
+ fields={"phi": trial, "psi": self._test},
116
+ values={"ang_vel": ang_vel},
117
+ )
118
+
119
+ self._side_test = fem.make_test(space=scalar_space, domain=sides)
120
+ side_trial = fem.make_trial(space=scalar_space, domain=sides)
121
+ fem.integrate(
122
+ upwind_transport_form,
123
+ fields={"phi": side_trial, "psi": self._side_test},
124
+ values={"ang_vel": ang_vel},
125
+ output=matrix_transport,
126
+ add=True,
127
+ )
128
+
129
+ matrix_diffusion = fem.integrate(
130
+ diffusion_form,
131
+ fields={"u": trial, "v": self._test},
132
+ )
133
+ matrix_diffusion += fem.integrate(
134
+ sip_diffusion_form,
135
+ fields={"phi": side_trial, "psi": self._side_test},
136
+ )
137
+ self._matrix = matrix_inertia + matrix_transport + viscosity * matrix_diffusion
138
+
139
+ # Initial condition
140
+ self._phi_field = scalar_space.make_field()
141
+ fem.interpolate(initial_condition, dest=self._phi_field)
142
+
143
+ self._phi_curvature_field = scalar_space.make_field()
144
+ self._compute_phi_curvature()
145
+
146
+ self.renderer = fem_example_utils.Plot()
147
+ self.renderer.add_field("phi", self._phi_field)
148
+ self.renderer.add_field("phi_curvature", self._phi_curvature_field)
149
+
150
+ def step(self):
151
+ self.current_frame += 1
152
+
153
+ rhs = fem.integrate(
154
+ inertia_form,
155
+ fields={"phi": self._phi_field, "psi": self._test},
156
+ values={"dt": self.sim_dt},
157
+ )
158
+
159
+ phi = wp.zeros_like(rhs)
160
+ fem_example_utils.bsr_cg(self._matrix, b=rhs, x=phi, method="bicgstab", quiet=self._quiet)
161
+ wp.utils.array_cast(in_array=phi, out_array=self._phi_field.dof_values)
162
+
163
+ # for visualization purposes only
164
+ self._compute_phi_curvature()
165
+
166
+ def _compute_phi_curvature(self):
167
+ fem.integrate(
168
+ diffusion_form,
169
+ fields={"u": self._phi_field, "v": self._test},
170
+ output=self._phi_curvature_field.dof_values,
171
+ )
172
+ fem.integrate(
173
+ sip_diffusion_form,
174
+ fields={"phi": self._phi_field.trace(), "psi": self._side_test},
175
+ output=self._phi_curvature_field.dof_values,
176
+ add=True,
177
+ )
178
+
179
+ def render(self):
180
+ self.renderer.begin_frame(time=self.current_frame * self.sim_dt)
181
+ self.renderer.add_field("phi", self._phi_field)
182
+ self.renderer.add_field("phi_curvature", self._phi_curvature_field)
183
+
184
+ self.renderer.end_frame()
185
+
186
+
187
+ if __name__ == "__main__":
188
+ import argparse
189
+
190
+ wp.set_module_options({"enable_backward": False})
191
+
192
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
193
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
194
+ parser.add_argument("--resolution", type=int, default=50, help="Grid resolution.")
195
+ parser.add_argument("--degree", type=int, default=2, help="Polynomial degree of shape functions.")
196
+ parser.add_argument("--num_frames", type=int, default=100, help="Total number of frames.")
197
+ parser.add_argument("--viscosity", type=float, default=0.001, help="Fluid viscosity parameter.")
198
+ parser.add_argument("--ang_vel", type=float, default=1.0, help="Angular velocity.")
199
+ parser.add_argument("--mesh", choices=("grid", "tri", "quad"), default="grid", help="Mesh type.")
200
+ parser.add_argument(
201
+ "--headless",
202
+ action="store_true",
203
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
204
+ )
205
+ parser.add_argument("--quiet", action="store_true")
206
+
207
+ args = parser.parse_known_args()[0]
208
+
209
+ with wp.ScopedDevice(args.device):
210
+ example = Example(
211
+ quiet=args.quiet,
212
+ degree=args.degree,
213
+ resolution=args.resolution,
214
+ mesh=args.mesh,
215
+ viscosity=args.viscosity,
216
+ ang_vel=args.ang_vel,
217
+ )
218
+
219
+ for k in range(args.num_frames):
220
+ print(f"Frame {k}:")
221
+ example.step()
222
+ example.render()
223
+
224
+ if not args.headless:
225
+ example.renderer.plot()