warp-lang 1.7.0__py3-none-manylinux_2_34_aarch64.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 (429) hide show
  1. warp/__init__.py +139 -0
  2. warp/__init__.pyi +1 -0
  3. warp/autograd.py +1142 -0
  4. warp/bin/warp-clang.so +0 -0
  5. warp/bin/warp.so +0 -0
  6. warp/build.py +557 -0
  7. warp/build_dll.py +405 -0
  8. warp/builtins.py +6855 -0
  9. warp/codegen.py +3969 -0
  10. warp/config.py +158 -0
  11. warp/constants.py +57 -0
  12. warp/context.py +6812 -0
  13. warp/dlpack.py +462 -0
  14. warp/examples/__init__.py +24 -0
  15. warp/examples/assets/bear.usd +0 -0
  16. warp/examples/assets/bunny.usd +0 -0
  17. warp/examples/assets/cartpole.urdf +110 -0
  18. warp/examples/assets/crazyflie.usd +0 -0
  19. warp/examples/assets/cube.usd +0 -0
  20. warp/examples/assets/nonuniform.usd +0 -0
  21. warp/examples/assets/nv_ant.xml +92 -0
  22. warp/examples/assets/nv_humanoid.xml +183 -0
  23. warp/examples/assets/nvidia_logo.png +0 -0
  24. warp/examples/assets/pixel.jpg +0 -0
  25. warp/examples/assets/quadruped.urdf +268 -0
  26. warp/examples/assets/rocks.nvdb +0 -0
  27. warp/examples/assets/rocks.usd +0 -0
  28. warp/examples/assets/sphere.usd +0 -0
  29. warp/examples/assets/square_cloth.usd +0 -0
  30. warp/examples/benchmarks/benchmark_api.py +389 -0
  31. warp/examples/benchmarks/benchmark_cloth.py +296 -0
  32. warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
  33. warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
  34. warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
  35. warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
  36. warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
  37. warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
  38. warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
  39. warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
  40. warp/examples/benchmarks/benchmark_gemm.py +164 -0
  41. warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
  42. warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
  43. warp/examples/benchmarks/benchmark_launches.py +301 -0
  44. warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
  45. warp/examples/browse.py +37 -0
  46. warp/examples/core/example_cupy.py +86 -0
  47. warp/examples/core/example_dem.py +241 -0
  48. warp/examples/core/example_fluid.py +299 -0
  49. warp/examples/core/example_graph_capture.py +150 -0
  50. warp/examples/core/example_marching_cubes.py +194 -0
  51. warp/examples/core/example_mesh.py +180 -0
  52. warp/examples/core/example_mesh_intersect.py +211 -0
  53. warp/examples/core/example_nvdb.py +182 -0
  54. warp/examples/core/example_raycast.py +111 -0
  55. warp/examples/core/example_raymarch.py +205 -0
  56. warp/examples/core/example_render_opengl.py +193 -0
  57. warp/examples/core/example_sample_mesh.py +300 -0
  58. warp/examples/core/example_sph.py +411 -0
  59. warp/examples/core/example_torch.py +211 -0
  60. warp/examples/core/example_wave.py +269 -0
  61. warp/examples/fem/example_adaptive_grid.py +286 -0
  62. warp/examples/fem/example_apic_fluid.py +423 -0
  63. warp/examples/fem/example_burgers.py +261 -0
  64. warp/examples/fem/example_convection_diffusion.py +178 -0
  65. warp/examples/fem/example_convection_diffusion_dg.py +204 -0
  66. warp/examples/fem/example_deformed_geometry.py +172 -0
  67. warp/examples/fem/example_diffusion.py +196 -0
  68. warp/examples/fem/example_diffusion_3d.py +225 -0
  69. warp/examples/fem/example_diffusion_mgpu.py +220 -0
  70. warp/examples/fem/example_distortion_energy.py +228 -0
  71. warp/examples/fem/example_magnetostatics.py +240 -0
  72. warp/examples/fem/example_mixed_elasticity.py +291 -0
  73. warp/examples/fem/example_navier_stokes.py +261 -0
  74. warp/examples/fem/example_nonconforming_contact.py +298 -0
  75. warp/examples/fem/example_stokes.py +213 -0
  76. warp/examples/fem/example_stokes_transfer.py +262 -0
  77. warp/examples/fem/example_streamlines.py +352 -0
  78. warp/examples/fem/utils.py +1000 -0
  79. warp/examples/interop/example_jax_callable.py +116 -0
  80. warp/examples/interop/example_jax_ffi_callback.py +132 -0
  81. warp/examples/interop/example_jax_kernel.py +205 -0
  82. warp/examples/optim/example_bounce.py +266 -0
  83. warp/examples/optim/example_cloth_throw.py +228 -0
  84. warp/examples/optim/example_diffray.py +561 -0
  85. warp/examples/optim/example_drone.py +870 -0
  86. warp/examples/optim/example_fluid_checkpoint.py +497 -0
  87. warp/examples/optim/example_inverse_kinematics.py +182 -0
  88. warp/examples/optim/example_inverse_kinematics_torch.py +191 -0
  89. warp/examples/optim/example_softbody_properties.py +400 -0
  90. warp/examples/optim/example_spring_cage.py +245 -0
  91. warp/examples/optim/example_trajectory.py +227 -0
  92. warp/examples/sim/example_cartpole.py +143 -0
  93. warp/examples/sim/example_cloth.py +225 -0
  94. warp/examples/sim/example_cloth_self_contact.py +322 -0
  95. warp/examples/sim/example_granular.py +130 -0
  96. warp/examples/sim/example_granular_collision_sdf.py +202 -0
  97. warp/examples/sim/example_jacobian_ik.py +244 -0
  98. warp/examples/sim/example_particle_chain.py +124 -0
  99. warp/examples/sim/example_quadruped.py +203 -0
  100. warp/examples/sim/example_rigid_chain.py +203 -0
  101. warp/examples/sim/example_rigid_contact.py +195 -0
  102. warp/examples/sim/example_rigid_force.py +133 -0
  103. warp/examples/sim/example_rigid_gyroscopic.py +115 -0
  104. warp/examples/sim/example_rigid_soft_contact.py +140 -0
  105. warp/examples/sim/example_soft_body.py +196 -0
  106. warp/examples/tile/example_tile_cholesky.py +87 -0
  107. warp/examples/tile/example_tile_convolution.py +66 -0
  108. warp/examples/tile/example_tile_fft.py +55 -0
  109. warp/examples/tile/example_tile_filtering.py +113 -0
  110. warp/examples/tile/example_tile_matmul.py +85 -0
  111. warp/examples/tile/example_tile_mlp.py +383 -0
  112. warp/examples/tile/example_tile_nbody.py +199 -0
  113. warp/examples/tile/example_tile_walker.py +327 -0
  114. warp/fabric.py +355 -0
  115. warp/fem/__init__.py +106 -0
  116. warp/fem/adaptivity.py +508 -0
  117. warp/fem/cache.py +572 -0
  118. warp/fem/dirichlet.py +202 -0
  119. warp/fem/domain.py +411 -0
  120. warp/fem/field/__init__.py +125 -0
  121. warp/fem/field/field.py +619 -0
  122. warp/fem/field/nodal_field.py +326 -0
  123. warp/fem/field/restriction.py +37 -0
  124. warp/fem/field/virtual.py +848 -0
  125. warp/fem/geometry/__init__.py +32 -0
  126. warp/fem/geometry/adaptive_nanogrid.py +857 -0
  127. warp/fem/geometry/closest_point.py +84 -0
  128. warp/fem/geometry/deformed_geometry.py +221 -0
  129. warp/fem/geometry/element.py +776 -0
  130. warp/fem/geometry/geometry.py +362 -0
  131. warp/fem/geometry/grid_2d.py +392 -0
  132. warp/fem/geometry/grid_3d.py +452 -0
  133. warp/fem/geometry/hexmesh.py +911 -0
  134. warp/fem/geometry/nanogrid.py +571 -0
  135. warp/fem/geometry/partition.py +389 -0
  136. warp/fem/geometry/quadmesh.py +663 -0
  137. warp/fem/geometry/tetmesh.py +855 -0
  138. warp/fem/geometry/trimesh.py +806 -0
  139. warp/fem/integrate.py +2335 -0
  140. warp/fem/linalg.py +419 -0
  141. warp/fem/operator.py +293 -0
  142. warp/fem/polynomial.py +229 -0
  143. warp/fem/quadrature/__init__.py +17 -0
  144. warp/fem/quadrature/pic_quadrature.py +299 -0
  145. warp/fem/quadrature/quadrature.py +591 -0
  146. warp/fem/space/__init__.py +228 -0
  147. warp/fem/space/basis_function_space.py +468 -0
  148. warp/fem/space/basis_space.py +667 -0
  149. warp/fem/space/dof_mapper.py +251 -0
  150. warp/fem/space/function_space.py +309 -0
  151. warp/fem/space/grid_2d_function_space.py +177 -0
  152. warp/fem/space/grid_3d_function_space.py +227 -0
  153. warp/fem/space/hexmesh_function_space.py +257 -0
  154. warp/fem/space/nanogrid_function_space.py +201 -0
  155. warp/fem/space/partition.py +367 -0
  156. warp/fem/space/quadmesh_function_space.py +223 -0
  157. warp/fem/space/restriction.py +179 -0
  158. warp/fem/space/shape/__init__.py +143 -0
  159. warp/fem/space/shape/cube_shape_function.py +1105 -0
  160. warp/fem/space/shape/shape_function.py +133 -0
  161. warp/fem/space/shape/square_shape_function.py +926 -0
  162. warp/fem/space/shape/tet_shape_function.py +834 -0
  163. warp/fem/space/shape/triangle_shape_function.py +672 -0
  164. warp/fem/space/tetmesh_function_space.py +271 -0
  165. warp/fem/space/topology.py +424 -0
  166. warp/fem/space/trimesh_function_space.py +194 -0
  167. warp/fem/types.py +99 -0
  168. warp/fem/utils.py +420 -0
  169. warp/jax.py +187 -0
  170. warp/jax_experimental/__init__.py +16 -0
  171. warp/jax_experimental/custom_call.py +351 -0
  172. warp/jax_experimental/ffi.py +698 -0
  173. warp/jax_experimental/xla_ffi.py +602 -0
  174. warp/math.py +244 -0
  175. warp/native/array.h +1145 -0
  176. warp/native/builtin.h +1800 -0
  177. warp/native/bvh.cpp +492 -0
  178. warp/native/bvh.cu +791 -0
  179. warp/native/bvh.h +554 -0
  180. warp/native/clang/clang.cpp +536 -0
  181. warp/native/coloring.cpp +613 -0
  182. warp/native/crt.cpp +51 -0
  183. warp/native/crt.h +362 -0
  184. warp/native/cuda_crt.h +1058 -0
  185. warp/native/cuda_util.cpp +646 -0
  186. warp/native/cuda_util.h +307 -0
  187. warp/native/error.cpp +77 -0
  188. warp/native/error.h +36 -0
  189. warp/native/exports.h +1878 -0
  190. warp/native/fabric.h +245 -0
  191. warp/native/hashgrid.cpp +311 -0
  192. warp/native/hashgrid.cu +87 -0
  193. warp/native/hashgrid.h +240 -0
  194. warp/native/initializer_array.h +41 -0
  195. warp/native/intersect.h +1230 -0
  196. warp/native/intersect_adj.h +375 -0
  197. warp/native/intersect_tri.h +339 -0
  198. warp/native/marching.cpp +19 -0
  199. warp/native/marching.cu +514 -0
  200. warp/native/marching.h +19 -0
  201. warp/native/mat.h +2220 -0
  202. warp/native/mathdx.cpp +87 -0
  203. warp/native/matnn.h +343 -0
  204. warp/native/mesh.cpp +266 -0
  205. warp/native/mesh.cu +404 -0
  206. warp/native/mesh.h +1980 -0
  207. warp/native/nanovdb/GridHandle.h +366 -0
  208. warp/native/nanovdb/HostBuffer.h +590 -0
  209. warp/native/nanovdb/NanoVDB.h +6624 -0
  210. warp/native/nanovdb/PNanoVDB.h +3390 -0
  211. warp/native/noise.h +859 -0
  212. warp/native/quat.h +1371 -0
  213. warp/native/rand.h +342 -0
  214. warp/native/range.h +139 -0
  215. warp/native/reduce.cpp +174 -0
  216. warp/native/reduce.cu +364 -0
  217. warp/native/runlength_encode.cpp +79 -0
  218. warp/native/runlength_encode.cu +61 -0
  219. warp/native/scan.cpp +47 -0
  220. warp/native/scan.cu +53 -0
  221. warp/native/scan.h +23 -0
  222. warp/native/solid_angle.h +466 -0
  223. warp/native/sort.cpp +251 -0
  224. warp/native/sort.cu +277 -0
  225. warp/native/sort.h +33 -0
  226. warp/native/sparse.cpp +378 -0
  227. warp/native/sparse.cu +524 -0
  228. warp/native/spatial.h +657 -0
  229. warp/native/svd.h +702 -0
  230. warp/native/temp_buffer.h +46 -0
  231. warp/native/tile.h +2584 -0
  232. warp/native/tile_reduce.h +264 -0
  233. warp/native/vec.h +1426 -0
  234. warp/native/volume.cpp +501 -0
  235. warp/native/volume.cu +67 -0
  236. warp/native/volume.h +969 -0
  237. warp/native/volume_builder.cu +477 -0
  238. warp/native/volume_builder.h +52 -0
  239. warp/native/volume_impl.h +70 -0
  240. warp/native/warp.cpp +1082 -0
  241. warp/native/warp.cu +3636 -0
  242. warp/native/warp.h +381 -0
  243. warp/optim/__init__.py +17 -0
  244. warp/optim/adam.py +163 -0
  245. warp/optim/linear.py +1137 -0
  246. warp/optim/sgd.py +112 -0
  247. warp/paddle.py +407 -0
  248. warp/render/__init__.py +18 -0
  249. warp/render/render_opengl.py +3518 -0
  250. warp/render/render_usd.py +784 -0
  251. warp/render/utils.py +160 -0
  252. warp/sim/__init__.py +65 -0
  253. warp/sim/articulation.py +793 -0
  254. warp/sim/collide.py +2395 -0
  255. warp/sim/graph_coloring.py +300 -0
  256. warp/sim/import_mjcf.py +790 -0
  257. warp/sim/import_snu.py +227 -0
  258. warp/sim/import_urdf.py +579 -0
  259. warp/sim/import_usd.py +894 -0
  260. warp/sim/inertia.py +324 -0
  261. warp/sim/integrator.py +242 -0
  262. warp/sim/integrator_euler.py +1997 -0
  263. warp/sim/integrator_featherstone.py +2101 -0
  264. warp/sim/integrator_vbd.py +2048 -0
  265. warp/sim/integrator_xpbd.py +3292 -0
  266. warp/sim/model.py +4791 -0
  267. warp/sim/particles.py +121 -0
  268. warp/sim/render.py +427 -0
  269. warp/sim/utils.py +428 -0
  270. warp/sparse.py +2057 -0
  271. warp/stubs.py +3333 -0
  272. warp/tape.py +1203 -0
  273. warp/tests/__init__.py +1 -0
  274. warp/tests/__main__.py +4 -0
  275. warp/tests/assets/curlnoise_golden.npy +0 -0
  276. warp/tests/assets/mlp_golden.npy +0 -0
  277. warp/tests/assets/pixel.npy +0 -0
  278. warp/tests/assets/pnoise_golden.npy +0 -0
  279. warp/tests/assets/spiky.usd +0 -0
  280. warp/tests/assets/test_grid.nvdb +0 -0
  281. warp/tests/assets/test_index_grid.nvdb +0 -0
  282. warp/tests/assets/test_int32_grid.nvdb +0 -0
  283. warp/tests/assets/test_vec_grid.nvdb +0 -0
  284. warp/tests/assets/torus.nvdb +0 -0
  285. warp/tests/assets/torus.usda +105 -0
  286. warp/tests/aux_test_class_kernel.py +34 -0
  287. warp/tests/aux_test_compile_consts_dummy.py +18 -0
  288. warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
  289. warp/tests/aux_test_dependent.py +29 -0
  290. warp/tests/aux_test_grad_customs.py +29 -0
  291. warp/tests/aux_test_instancing_gc.py +26 -0
  292. warp/tests/aux_test_module_unload.py +23 -0
  293. warp/tests/aux_test_name_clash1.py +40 -0
  294. warp/tests/aux_test_name_clash2.py +40 -0
  295. warp/tests/aux_test_reference.py +9 -0
  296. warp/tests/aux_test_reference_reference.py +8 -0
  297. warp/tests/aux_test_square.py +16 -0
  298. warp/tests/aux_test_unresolved_func.py +22 -0
  299. warp/tests/aux_test_unresolved_symbol.py +22 -0
  300. warp/tests/cuda/__init__.py +0 -0
  301. warp/tests/cuda/test_async.py +676 -0
  302. warp/tests/cuda/test_ipc.py +124 -0
  303. warp/tests/cuda/test_mempool.py +233 -0
  304. warp/tests/cuda/test_multigpu.py +169 -0
  305. warp/tests/cuda/test_peer.py +139 -0
  306. warp/tests/cuda/test_pinned.py +84 -0
  307. warp/tests/cuda/test_streams.py +634 -0
  308. warp/tests/geometry/__init__.py +0 -0
  309. warp/tests/geometry/test_bvh.py +200 -0
  310. warp/tests/geometry/test_hash_grid.py +221 -0
  311. warp/tests/geometry/test_marching_cubes.py +74 -0
  312. warp/tests/geometry/test_mesh.py +316 -0
  313. warp/tests/geometry/test_mesh_query_aabb.py +399 -0
  314. warp/tests/geometry/test_mesh_query_point.py +932 -0
  315. warp/tests/geometry/test_mesh_query_ray.py +311 -0
  316. warp/tests/geometry/test_volume.py +1103 -0
  317. warp/tests/geometry/test_volume_write.py +346 -0
  318. warp/tests/interop/__init__.py +0 -0
  319. warp/tests/interop/test_dlpack.py +729 -0
  320. warp/tests/interop/test_jax.py +371 -0
  321. warp/tests/interop/test_paddle.py +800 -0
  322. warp/tests/interop/test_torch.py +1001 -0
  323. warp/tests/run_coverage_serial.py +39 -0
  324. warp/tests/sim/__init__.py +0 -0
  325. warp/tests/sim/disabled_kinematics.py +244 -0
  326. warp/tests/sim/flaky_test_sim_grad.py +290 -0
  327. warp/tests/sim/test_collision.py +604 -0
  328. warp/tests/sim/test_coloring.py +258 -0
  329. warp/tests/sim/test_model.py +224 -0
  330. warp/tests/sim/test_sim_grad_bounce_linear.py +212 -0
  331. warp/tests/sim/test_sim_kinematics.py +98 -0
  332. warp/tests/sim/test_vbd.py +597 -0
  333. warp/tests/test_adam.py +163 -0
  334. warp/tests/test_arithmetic.py +1096 -0
  335. warp/tests/test_array.py +2972 -0
  336. warp/tests/test_array_reduce.py +156 -0
  337. warp/tests/test_assert.py +250 -0
  338. warp/tests/test_atomic.py +153 -0
  339. warp/tests/test_bool.py +220 -0
  340. warp/tests/test_builtins_resolution.py +1298 -0
  341. warp/tests/test_closest_point_edge_edge.py +327 -0
  342. warp/tests/test_codegen.py +810 -0
  343. warp/tests/test_codegen_instancing.py +1495 -0
  344. warp/tests/test_compile_consts.py +215 -0
  345. warp/tests/test_conditional.py +252 -0
  346. warp/tests/test_context.py +42 -0
  347. warp/tests/test_copy.py +238 -0
  348. warp/tests/test_ctypes.py +638 -0
  349. warp/tests/test_dense.py +73 -0
  350. warp/tests/test_devices.py +97 -0
  351. warp/tests/test_examples.py +482 -0
  352. warp/tests/test_fabricarray.py +996 -0
  353. warp/tests/test_fast_math.py +74 -0
  354. warp/tests/test_fem.py +2003 -0
  355. warp/tests/test_fp16.py +136 -0
  356. warp/tests/test_func.py +454 -0
  357. warp/tests/test_future_annotations.py +98 -0
  358. warp/tests/test_generics.py +656 -0
  359. warp/tests/test_grad.py +893 -0
  360. warp/tests/test_grad_customs.py +339 -0
  361. warp/tests/test_grad_debug.py +341 -0
  362. warp/tests/test_implicit_init.py +411 -0
  363. warp/tests/test_import.py +45 -0
  364. warp/tests/test_indexedarray.py +1140 -0
  365. warp/tests/test_intersect.py +73 -0
  366. warp/tests/test_iter.py +76 -0
  367. warp/tests/test_large.py +177 -0
  368. warp/tests/test_launch.py +411 -0
  369. warp/tests/test_lerp.py +151 -0
  370. warp/tests/test_linear_solvers.py +193 -0
  371. warp/tests/test_lvalue.py +427 -0
  372. warp/tests/test_mat.py +2089 -0
  373. warp/tests/test_mat_lite.py +122 -0
  374. warp/tests/test_mat_scalar_ops.py +2913 -0
  375. warp/tests/test_math.py +178 -0
  376. warp/tests/test_mlp.py +282 -0
  377. warp/tests/test_module_hashing.py +258 -0
  378. warp/tests/test_modules_lite.py +44 -0
  379. warp/tests/test_noise.py +252 -0
  380. warp/tests/test_operators.py +299 -0
  381. warp/tests/test_options.py +129 -0
  382. warp/tests/test_overwrite.py +551 -0
  383. warp/tests/test_print.py +339 -0
  384. warp/tests/test_quat.py +2315 -0
  385. warp/tests/test_rand.py +339 -0
  386. warp/tests/test_reload.py +302 -0
  387. warp/tests/test_rounding.py +185 -0
  388. warp/tests/test_runlength_encode.py +196 -0
  389. warp/tests/test_scalar_ops.py +105 -0
  390. warp/tests/test_smoothstep.py +108 -0
  391. warp/tests/test_snippet.py +318 -0
  392. warp/tests/test_sparse.py +582 -0
  393. warp/tests/test_spatial.py +2229 -0
  394. warp/tests/test_special_values.py +361 -0
  395. warp/tests/test_static.py +592 -0
  396. warp/tests/test_struct.py +734 -0
  397. warp/tests/test_tape.py +204 -0
  398. warp/tests/test_transient_module.py +93 -0
  399. warp/tests/test_triangle_closest_point.py +145 -0
  400. warp/tests/test_types.py +562 -0
  401. warp/tests/test_utils.py +588 -0
  402. warp/tests/test_vec.py +1487 -0
  403. warp/tests/test_vec_lite.py +80 -0
  404. warp/tests/test_vec_scalar_ops.py +2327 -0
  405. warp/tests/test_verify_fp.py +100 -0
  406. warp/tests/tile/__init__.py +0 -0
  407. warp/tests/tile/test_tile.py +780 -0
  408. warp/tests/tile/test_tile_load.py +407 -0
  409. warp/tests/tile/test_tile_mathdx.py +208 -0
  410. warp/tests/tile/test_tile_mlp.py +402 -0
  411. warp/tests/tile/test_tile_reduce.py +447 -0
  412. warp/tests/tile/test_tile_shared_memory.py +247 -0
  413. warp/tests/tile/test_tile_view.py +173 -0
  414. warp/tests/unittest_serial.py +47 -0
  415. warp/tests/unittest_suites.py +427 -0
  416. warp/tests/unittest_utils.py +468 -0
  417. warp/tests/walkthrough_debug.py +93 -0
  418. warp/thirdparty/__init__.py +0 -0
  419. warp/thirdparty/appdirs.py +598 -0
  420. warp/thirdparty/dlpack.py +145 -0
  421. warp/thirdparty/unittest_parallel.py +570 -0
  422. warp/torch.py +391 -0
  423. warp/types.py +5230 -0
  424. warp/utils.py +1137 -0
  425. warp_lang-1.7.0.dist-info/METADATA +516 -0
  426. warp_lang-1.7.0.dist-info/RECORD +429 -0
  427. warp_lang-1.7.0.dist-info/WHEEL +5 -0
  428. warp_lang-1.7.0.dist-info/licenses/LICENSE.md +202 -0
  429. warp_lang-1.7.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,291 @@
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 Mixed Elasticity
18
+ #
19
+ # This example illustrates using Mixed FEM to solve a nonlinear static elasticity equilibrium problem:
20
+ #
21
+ # Div[ d/dF Psi(F(u)) ] = 0
22
+ #
23
+ # with Dirichlet boundary conditions on vertical sides and Psi an elastic potential function of the deformation gradient.
24
+ # Here we choose Psi Neo-Hookean, as per Sec 3.2 of "Stable Neo-Hookean Flesh Simulation" (Smith et al. 2018),
25
+ # Psi(F) = mu ||F||^2 + lambda (det J - 1 - mu/lambda)^2
26
+ #
27
+ # which we write as a sequence of Newton iterations:
28
+ # int {sigma : grad v} = 0 for all displacement test functions v
29
+ # int {sigma : tau} = int{dPsi/dF : tau} + int{grad du : d2 Psi/dF2 : tau} for all stress test functions tau
30
+ ###########################################################################
31
+
32
+ import numpy as np
33
+
34
+ import warp as wp
35
+ import warp.examples.fem.utils as fem_example_utils
36
+ import warp.fem as fem
37
+
38
+
39
+ @fem.integrand
40
+ def displacement_gradient_form(
41
+ s: fem.Sample,
42
+ u: fem.Field,
43
+ tau: fem.Field,
44
+ ):
45
+ """grad(u) : tau"""
46
+ return wp.ddot(tau(s), fem.grad(u, s))
47
+
48
+
49
+ @wp.func
50
+ def nh_parameters_from_lame(lame: wp.vec2):
51
+ """Parameters such that for small strains model behaves according to Hooke's law"""
52
+ mu_nh = lame[1]
53
+ lambda_nh = lame[0] + lame[1]
54
+
55
+ return mu_nh, lambda_nh
56
+
57
+
58
+ @fem.integrand
59
+ def nh_stress_form(s: fem.Sample, tau: fem.Field, u_cur: fem.Field, lame: wp.vec2):
60
+ """d Psi/dF : tau"""
61
+
62
+ # Deformation gradient
63
+ F = wp.identity(n=2, dtype=float) + fem.grad(u_cur, s)
64
+
65
+ # Area term and its derivative w.r.t F
66
+ J = wp.determinant(F)
67
+ dJ_dF = wp.mat22(F[1, 1], -F[1, 0], -F[0, 1], F[0, 0])
68
+
69
+ mu_nh, lambda_nh = nh_parameters_from_lame(lame)
70
+ nh_stress = mu_nh * F + (lambda_nh * (J - 1.0) - mu_nh) * dJ_dF
71
+
72
+ return wp.ddot(tau(s), nh_stress)
73
+
74
+
75
+ @fem.integrand
76
+ def nh_stress_delta_form(s: fem.Sample, tau: fem.Field, u: fem.Field, u_cur: fem.Field, lame: wp.vec2):
77
+ """grad(u) : d2 Psi/dF2 : tau"""
78
+
79
+ tau_s = tau(s)
80
+ sigma_s = fem.grad(u, s)
81
+
82
+ F = wp.identity(n=2, dtype=float) + fem.grad(u_cur, s)
83
+ dJ_dF = wp.mat22(F[1, 1], -F[1, 0], -F[0, 1], F[0, 0])
84
+
85
+ # Gauss--Newton approximation; ignore d2J/dF2 term
86
+ mu_nh, lambda_nh = nh_parameters_from_lame(lame)
87
+ return mu_nh * wp.ddot(tau_s, sigma_s) + lambda_nh * wp.ddot(dJ_dF, tau_s) * wp.ddot(dJ_dF, sigma_s)
88
+
89
+
90
+ @fem.integrand
91
+ def vertical_boundary_projector_form(
92
+ s: fem.Sample,
93
+ domain: fem.Domain,
94
+ u: fem.Field,
95
+ v: fem.Field,
96
+ ):
97
+ # non zero on vertical boundary of domain only
98
+ nor = fem.normal(domain, s)
99
+ return wp.dot(u(s), v(s)) * wp.abs(nor[0])
100
+
101
+
102
+ @fem.integrand
103
+ def vertical_displacement_form(
104
+ s: fem.Sample,
105
+ domain: fem.Domain,
106
+ v: fem.Field,
107
+ displacement: float,
108
+ ):
109
+ # opposed to normal on vertical boundary of domain only
110
+ nor = fem.normal(domain, s)
111
+ return -wp.abs(nor[0]) * displacement * wp.dot(nor, v(s))
112
+
113
+
114
+ @fem.integrand
115
+ def tensor_mass_form(
116
+ s: fem.Sample,
117
+ sig: fem.Field,
118
+ tau: fem.Field,
119
+ ):
120
+ return wp.ddot(tau(s), sig(s))
121
+
122
+
123
+ @fem.integrand
124
+ def area_form(s: fem.Sample, u_cur: fem.Field):
125
+ F = wp.identity(n=2, dtype=float) + fem.grad(u_cur, s)
126
+ return wp.determinant(F)
127
+
128
+
129
+ class Example:
130
+ def __init__(
131
+ self,
132
+ quiet=False,
133
+ degree=2,
134
+ resolution=25,
135
+ mesh="grid",
136
+ displacement=0.1,
137
+ poisson_ratio=0.5,
138
+ nonconforming_stresses=False,
139
+ ):
140
+ self._quiet = quiet
141
+
142
+ self._displacement = displacement
143
+
144
+ # Grid or mesh geometry
145
+ if mesh == "tri":
146
+ positions, tri_vidx = fem_example_utils.gen_trimesh(res=wp.vec2i(resolution))
147
+ self._geo = fem.Trimesh2D(tri_vertex_indices=tri_vidx, positions=positions)
148
+ elif mesh == "quad":
149
+ positions, quad_vidx = fem_example_utils.gen_quadmesh(res=wp.vec2i(resolution))
150
+ self._geo = fem.Quadmesh2D(quad_vertex_indices=quad_vidx, positions=positions)
151
+ else:
152
+ self._geo = fem.Grid2D(res=wp.vec2i(resolution))
153
+
154
+ # Lame coefficients from Young modulus and Poisson ratio
155
+ self._lame = wp.vec2(1.0 / (1.0 + poisson_ratio) * np.array([poisson_ratio / (1.0 - poisson_ratio), 0.5]))
156
+
157
+ # Function spaces -- S_k for displacement, Q_k or P_{k-1}d for stress
158
+ self._u_space = fem.make_polynomial_space(
159
+ self._geo, degree=degree, dtype=wp.vec2, element_basis=fem.ElementBasis.SERENDIPITY
160
+ )
161
+
162
+ if isinstance(self._geo.reference_cell(), fem.geometry.element.Triangle):
163
+ # triangle elements
164
+ tau_basis = fem.ElementBasis.NONCONFORMING_POLYNOMIAL
165
+ tau_degree = degree - 1
166
+ else:
167
+ # square elements
168
+ tau_basis = fem.ElementBasis.LAGRANGE
169
+ tau_degree = degree
170
+
171
+ self._tau_space = fem.make_polynomial_space(
172
+ self._geo,
173
+ degree=tau_degree,
174
+ discontinuous=True,
175
+ element_basis=tau_basis,
176
+ family=fem.Polynomial.GAUSS_LEGENDRE,
177
+ dtype=wp.mat22,
178
+ )
179
+
180
+ self._u_field = self._u_space.make_field()
181
+
182
+ self.renderer = fem_example_utils.Plot()
183
+
184
+ def step(self):
185
+ boundary = fem.BoundarySides(self._geo)
186
+ domain = fem.Cells(geometry=self._geo)
187
+
188
+ # Displacement boundary conditions
189
+ u_bd_test = fem.make_test(space=self._u_space, domain=boundary)
190
+ u_bd_trial = fem.make_trial(space=self._u_space, domain=boundary)
191
+ u_bd_rhs = fem.integrate(
192
+ vertical_displacement_form,
193
+ fields={"v": u_bd_test},
194
+ values={"displacement": self._displacement},
195
+ nodal=True,
196
+ output_dtype=wp.vec2d,
197
+ )
198
+ u_bd_matrix = fem.integrate(
199
+ vertical_boundary_projector_form, fields={"u": u_bd_trial, "v": u_bd_test}, nodal=True
200
+ )
201
+
202
+ # Stress/velocity coupling
203
+ u_trial = fem.make_trial(space=self._u_space, domain=domain)
204
+ tau_test = fem.make_test(space=self._tau_space, domain=domain)
205
+ tau_trial = fem.make_trial(space=self._tau_space, domain=domain)
206
+
207
+ gradient_matrix = fem.integrate(displacement_gradient_form, fields={"u": u_trial, "tau": tau_test}).transpose()
208
+
209
+ # Compute inverse of the (block-diagonal) tau mass matrix
210
+ tau_inv_mass_matrix = fem.integrate(tensor_mass_form, fields={"sig": tau_trial, "tau": tau_test}, nodal=True)
211
+ fem_example_utils.invert_diagonal_bsr_matrix(tau_inv_mass_matrix)
212
+
213
+ # Newton iterations (without line-search for simplicity)
214
+ for newton_iteration in range(5):
215
+ stress_matrix = fem.integrate(
216
+ nh_stress_delta_form,
217
+ fields={"u_cur": self._u_field, "u": u_trial, "tau": tau_test},
218
+ values={"lame": self._lame},
219
+ )
220
+
221
+ stress_rhs = fem.integrate(
222
+ nh_stress_form,
223
+ fields={"u_cur": self._u_field, "tau": tau_test},
224
+ values={"lame": self._lame},
225
+ output_dtype=wp.vec(length=stress_matrix.block_shape[0], dtype=wp.float64),
226
+ )
227
+
228
+ # Assemble system matrix
229
+ u_matrix = gradient_matrix @ tau_inv_mass_matrix @ stress_matrix
230
+
231
+ # Enforce boundary conditions (apply displacement only at first iteration)
232
+ u_rhs = -gradient_matrix @ (tau_inv_mass_matrix @ stress_rhs)
233
+ fem.project_linear_system(u_matrix, u_rhs, u_bd_matrix, u_bd_rhs if newton_iteration == 0 else None)
234
+
235
+ x = wp.zeros_like(u_rhs)
236
+ fem_example_utils.bsr_cg(u_matrix, b=u_rhs, x=x, quiet=self._quiet)
237
+
238
+ # Extract result -- cast to float32 and accumulate to displacement field
239
+ delta_u = wp.empty_like(self._u_field.dof_values)
240
+ wp.utils.array_cast(in_array=x, out_array=delta_u)
241
+ fem.utils.array_axpy(x=delta_u, y=self._u_field.dof_values)
242
+
243
+ # Evaluate area conservation, should converge to 1.0 as Poisson ratio approaches 1.0
244
+ final_area = fem.integrate(
245
+ area_form, quadrature=fem.RegularQuadrature(domain, order=4), fields={"u_cur": self._u_field}
246
+ )
247
+ print(f"Area gain: {final_area} (using Poisson ratio={self._lame[0] / (self._lame[0] + 2.0 * self._lame[1])})")
248
+
249
+ def render(self):
250
+ self.renderer.add_field("solution", self._u_field)
251
+
252
+
253
+ if __name__ == "__main__":
254
+ import argparse
255
+
256
+ wp.set_module_options({"enable_backward": False})
257
+
258
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
259
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
260
+ parser.add_argument("--resolution", type=int, default=25, help="Grid resolution.")
261
+ parser.add_argument("--degree", type=int, default=2, help="Polynomial degree of shape functions.")
262
+ parser.add_argument("--displacement", type=float, default=-0.5)
263
+ parser.add_argument("--poisson_ratio", type=float, default=0.99)
264
+ parser.add_argument("--mesh", choices=("grid", "tri", "quad"), default="grid", help="Mesh type")
265
+ parser.add_argument(
266
+ "--nonconforming_stresses", action="store_true", help="For grid, use non-conforming stresses (Q_d/P_d)"
267
+ )
268
+ parser.add_argument(
269
+ "--headless",
270
+ action="store_true",
271
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
272
+ )
273
+ parser.add_argument("--quiet", action="store_true", help="Suppresses the printing out of iteration residuals.")
274
+
275
+ args = parser.parse_known_args()[0]
276
+
277
+ with wp.ScopedDevice(args.device):
278
+ example = Example(
279
+ quiet=args.quiet,
280
+ degree=args.degree,
281
+ resolution=args.resolution,
282
+ mesh=args.mesh,
283
+ displacement=args.displacement,
284
+ poisson_ratio=args.poisson_ratio,
285
+ nonconforming_stresses=args.nonconforming_stresses,
286
+ )
287
+ example.step()
288
+ example.render()
289
+
290
+ if not args.headless:
291
+ example.renderer.plot(options={"solution": {"displacement": {}}})
@@ -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 Navier Stokes
18
+ #
19
+ # This example solves a 2D Navier-Stokes flow problem:
20
+ #
21
+ # Du/dt -nu D(u) + grad p = 0
22
+ # Div u = 0
23
+ #
24
+ # with (hard) velocity-Dirichlet boundary conditions
25
+ # and using semi-Lagrangian advection
26
+ ###########################################################################
27
+
28
+ import warp as wp
29
+ import warp.examples.fem.utils as fem_example_utils
30
+ import warp.fem as fem
31
+ from warp.fem.utils import array_axpy
32
+
33
+
34
+ @wp.func
35
+ def u_boundary_value(x: wp.vec2, box_height: float, top_velocity: float):
36
+ # Horizontal velocity on top of domain, zero elsewhere
37
+ if x[1] >= box_height:
38
+ return wp.vec2(top_velocity, 0.0)
39
+
40
+ return wp.vec2(0.0, 0.0)
41
+
42
+
43
+ @fem.integrand
44
+ def mass_form(
45
+ s: fem.Sample,
46
+ u: fem.Field,
47
+ v: fem.Field,
48
+ ):
49
+ return wp.dot(u(s), v(s))
50
+
51
+
52
+ @fem.integrand
53
+ def inertia_form(s: fem.Sample, u: fem.Field, v: fem.Field, dt: float):
54
+ return mass_form(s, u, v) / dt
55
+
56
+
57
+ @fem.integrand
58
+ def viscosity_form(s: fem.Sample, u: fem.Field, v: fem.Field, nu: float):
59
+ return 2.0 * nu * wp.ddot(fem.D(u, s), fem.D(v, s))
60
+
61
+
62
+ @fem.integrand
63
+ def viscosity_and_inertia_form(s: fem.Sample, u: fem.Field, v: fem.Field, dt: float, nu: float):
64
+ return inertia_form(s, u, v, dt) + viscosity_form(s, u, v, nu)
65
+
66
+
67
+ @fem.integrand
68
+ def transported_inertia_form(s: fem.Sample, domain: fem.Domain, u: fem.Field, v: fem.Field, dt: float):
69
+ pos = domain(s)
70
+ vel = u(s)
71
+
72
+ conv_pos = pos - 0.5 * vel * dt
73
+ conv_s = fem.lookup(domain, conv_pos, s)
74
+ conv_vel = u(conv_s)
75
+
76
+ conv_pos = conv_pos - 0.5 * conv_vel * dt
77
+ conv_vel = u(fem.lookup(domain, conv_pos, conv_s))
78
+
79
+ return wp.dot(conv_vel, v(s)) / dt
80
+
81
+
82
+ @fem.integrand
83
+ def div_form(
84
+ s: fem.Sample,
85
+ u: fem.Field,
86
+ q: fem.Field,
87
+ ):
88
+ return -q(s) * fem.div(u, s)
89
+
90
+
91
+ class Example:
92
+ def __init__(self, quiet=False, degree=2, resolution=25, Re=1000.0, top_velocity=1.0, tri_mesh=False):
93
+ self._quiet = quiet
94
+
95
+ res = resolution
96
+ self.sim_dt = 1.0 / resolution
97
+ self.current_frame = 0
98
+
99
+ viscosity = top_velocity / Re
100
+
101
+ if tri_mesh:
102
+ positions, tri_vidx = fem_example_utils.gen_trimesh(res=wp.vec2i(res))
103
+ geo = fem.Trimesh2D(tri_vertex_indices=tri_vidx, positions=positions, build_bvh=True)
104
+ else:
105
+ geo = fem.Grid2D(res=wp.vec2i(res))
106
+
107
+ domain = fem.Cells(geometry=geo)
108
+ boundary = fem.BoundarySides(geo)
109
+
110
+ # Functions spaces: Q(d)-Q(d-1)
111
+ u_degree = degree
112
+ u_space = fem.make_polynomial_space(geo, degree=u_degree, dtype=wp.vec2)
113
+ p_space = fem.make_polynomial_space(geo, degree=u_degree - 1)
114
+
115
+ # Viscosity and inertia
116
+ u_test = fem.make_test(space=u_space, domain=domain)
117
+ u_trial = fem.make_trial(space=u_space, domain=domain)
118
+
119
+ u_matrix = fem.integrate(
120
+ viscosity_and_inertia_form,
121
+ fields={"u": u_trial, "v": u_test},
122
+ values={"nu": viscosity, "dt": self.sim_dt},
123
+ )
124
+
125
+ # Pressure-velocity coupling
126
+ p_test = fem.make_test(space=p_space, domain=domain)
127
+ div_matrix = fem.integrate(div_form, fields={"u": u_trial, "q": p_test})
128
+
129
+ # Enforcing the Dirichlet boundary condition the hard way;
130
+ # build projector for velocity left- and right-hand-sides
131
+ u_bd_test = fem.make_test(space=u_space, domain=boundary)
132
+ u_bd_trial = fem.make_trial(space=u_space, domain=boundary)
133
+ u_bd_projector = fem.integrate(mass_form, fields={"u": u_bd_trial, "v": u_bd_test}, nodal=True)
134
+
135
+ # Define an implicit field for our boundary condition value and integrate
136
+ u_bd_field = fem.ImplicitField(
137
+ domain=boundary, func=u_boundary_value, values={"top_velocity": top_velocity, "box_height": 1.0}
138
+ )
139
+ u_bd_value = fem.integrate(
140
+ mass_form,
141
+ fields={"u": u_bd_field, "v": u_bd_test},
142
+ nodal=True,
143
+ output_dtype=wp.vec2d,
144
+ )
145
+
146
+ fem.normalize_dirichlet_projector(u_bd_projector, u_bd_value)
147
+
148
+ u_bd_rhs = wp.zeros_like(u_bd_value)
149
+ fem.project_linear_system(u_matrix, u_bd_rhs, u_bd_projector, u_bd_value, normalize_projector=False)
150
+
151
+ div_bd_rhs = -div_matrix @ u_bd_value
152
+ div_matrix -= div_matrix @ u_bd_projector
153
+
154
+ # Assemble saddle system
155
+ self._saddle_system = fem_example_utils.SaddleSystem(u_matrix, div_matrix)
156
+
157
+ # Save data for computing time steps rhs
158
+ self._u_bd_projector = u_bd_projector
159
+ self._u_bd_rhs = u_bd_rhs
160
+ self._u_test = u_test
161
+ self._div_bd_rhs = div_bd_rhs
162
+
163
+ # Velocitiy and pressure fields
164
+ self._u_field = u_space.make_field()
165
+ self._p_field = p_space.make_field()
166
+
167
+ self.renderer = fem_example_utils.Plot()
168
+ self.renderer.add_field("velocity", self._u_field)
169
+
170
+ def step(self):
171
+ self.current_frame += 1
172
+
173
+ u_rhs = fem.integrate(
174
+ transported_inertia_form,
175
+ fields={"u": self._u_field, "v": self._u_test},
176
+ values={"dt": self.sim_dt},
177
+ output_dtype=wp.vec2d,
178
+ )
179
+
180
+ # Apply boundary conditions
181
+ # u_rhs = (I - P) * u_rhs + u_bd_rhs
182
+ wp.sparse.bsr_mv(self._u_bd_projector, x=u_rhs, y=u_rhs, alpha=-1.0, beta=1.0)
183
+ array_axpy(x=self._u_bd_rhs, y=u_rhs, alpha=1.0, beta=1.0)
184
+
185
+ p_rhs = self._div_bd_rhs
186
+
187
+ x_u = wp.empty_like(u_rhs)
188
+ x_p = wp.empty_like(p_rhs)
189
+ wp.utils.array_cast(out_array=x_u, in_array=self._u_field.dof_values)
190
+ wp.utils.array_cast(out_array=x_p, in_array=self._p_field.dof_values)
191
+
192
+ fem_example_utils.bsr_solve_saddle(
193
+ saddle_system=self._saddle_system,
194
+ tol=1.0e-6,
195
+ x_u=x_u,
196
+ x_p=x_p,
197
+ b_u=u_rhs,
198
+ b_p=p_rhs,
199
+ quiet=self._quiet,
200
+ )
201
+
202
+ wp.utils.array_cast(in_array=x_u, out_array=self._u_field.dof_values)
203
+ wp.utils.array_cast(in_array=x_p, out_array=self._p_field.dof_values)
204
+
205
+ def render(self):
206
+ self.renderer.begin_frame(time=self.current_frame * self.sim_dt)
207
+ self.renderer.add_field("velocity", self._u_field)
208
+ self.renderer.end_frame()
209
+
210
+
211
+ if __name__ == "__main__":
212
+ import argparse
213
+
214
+ wp.set_module_options({"enable_backward": False})
215
+
216
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
217
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
218
+ parser.add_argument("--resolution", type=int, default=25, help="Grid resolution.")
219
+ parser.add_argument("--degree", type=int, default=2, help="Polynomial degree of shape functions.")
220
+ parser.add_argument("--num_frames", type=int, default=1000, help="Total number of frames.")
221
+ parser.add_argument(
222
+ "--top_velocity",
223
+ type=float,
224
+ default=1.0,
225
+ help="Horizontal velocity boundary condition at the top of the domain.",
226
+ )
227
+ parser.add_argument("--Re", type=float, default=1000.0, help="Reynolds number.")
228
+ parser.add_argument("--tri_mesh", action="store_true", help="Use a triangular mesh.")
229
+ parser.add_argument(
230
+ "--headless",
231
+ action="store_true",
232
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
233
+ )
234
+ parser.add_argument("--quiet", action="store_true", help="Suppresses the printing out of iteration residuals.")
235
+
236
+ args = parser.parse_known_args()[0]
237
+
238
+ with wp.ScopedDevice(args.device):
239
+ example = Example(
240
+ quiet=args.quiet,
241
+ degree=args.degree,
242
+ resolution=args.resolution,
243
+ Re=args.Re,
244
+ top_velocity=args.top_velocity,
245
+ tri_mesh=args.tri_mesh,
246
+ )
247
+
248
+ for k in range(args.num_frames):
249
+ print(f"Frame {k}:")
250
+ example.step()
251
+ example.render()
252
+
253
+ example.renderer.add_field("velocity_final", example._u_field)
254
+
255
+ if not args.headless:
256
+ example.renderer.plot(
257
+ options={
258
+ "velocity": {"arrows": {"glyph_scale": 0.25}},
259
+ "velocity_final": {"streamlines": {"density": 2.0}},
260
+ }
261
+ )