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,220 @@
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 Diffusion MGPU
18
+ #
19
+ # This example illustrates using domain decomposition to
20
+ # solve a diffusion PDE over multiple devices
21
+ ###########################################################################
22
+
23
+ from typing import Tuple
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_diffusion import diffusion_form, linear_form
29
+ from warp.sparse import bsr_axpy, bsr_mv
30
+ from warp.utils import array_cast
31
+
32
+
33
+ @fem.integrand
34
+ def mass_form(
35
+ s: fem.Sample,
36
+ u: fem.Field,
37
+ v: fem.Field,
38
+ ):
39
+ return u(s) * v(s)
40
+
41
+
42
+ @wp.kernel
43
+ def scal_kernel(a: wp.array(dtype=wp.float64), res: wp.array(dtype=wp.float64), alpha: wp.float64):
44
+ res[wp.tid()] = a[wp.tid()] * alpha
45
+
46
+
47
+ @wp.kernel
48
+ def sum_kernel(a: wp.indexedarray(dtype=wp.float64), b: wp.array(dtype=wp.float64)):
49
+ a[wp.tid()] = a[wp.tid()] + b[wp.tid()]
50
+
51
+
52
+ def sum_vecs(vecs, indices, sum: wp.array, tmp: wp.array):
53
+ for v, idx in zip(vecs, indices):
54
+ wp.copy(dest=tmp, src=v)
55
+ idx_sum = wp.indexedarray(sum, idx)
56
+ wp.launch(kernel=sum_kernel, dim=idx.shape, device=sum.device, inputs=[idx_sum, tmp])
57
+
58
+ return sum
59
+
60
+
61
+ class DistributedSystem:
62
+ device = None
63
+ scalar_type: type
64
+ tmp_buf: wp.array
65
+
66
+ nrow: int
67
+ shape = Tuple[int, int]
68
+ rank_data = None
69
+
70
+ def mv_routine(self, x: wp.array, y: wp.array, z: wp.array, alpha=1.0, beta=0.0):
71
+ """Distributed matrix-vector multiplication routine, for example purposes"""
72
+
73
+ tmp = self.tmp_buf
74
+
75
+ wp.launch(kernel=scal_kernel, dim=y.shape, device=y.device, inputs=[y, z, wp.float64(beta)])
76
+
77
+ stream = wp.get_stream()
78
+
79
+ for mat_i, x_i, y_i, idx in zip(*self.rank_data):
80
+ # WAR copy with indexed array requiring matching shape
81
+ tmp_i = wp.array(ptr=tmp.ptr, device=tmp.device, capacity=tmp.capacity, dtype=tmp.dtype, shape=idx.shape)
82
+
83
+ # Compress rhs on rank 0
84
+ x_idx = wp.indexedarray(x, idx)
85
+ wp.copy(dest=tmp_i, src=x_idx, count=idx.size, stream=stream)
86
+
87
+ # Send to rank i
88
+ wp.copy(dest=x_i, src=tmp_i, count=idx.size, stream=stream)
89
+
90
+ with wp.ScopedDevice(x_i.device):
91
+ wp.wait_stream(stream)
92
+ bsr_mv(A=mat_i, x=x_i, y=y_i, alpha=alpha, beta=0.0)
93
+
94
+ wp.wait_stream(wp.get_stream(x_i.device))
95
+
96
+ # Back to rank 0 for sum
97
+ wp.copy(dest=tmp_i, src=y_i, count=idx.size, stream=stream)
98
+ z_idx = wp.indexedarray(z, idx)
99
+ wp.launch(kernel=sum_kernel, dim=idx.shape, device=z_idx.device, inputs=[z_idx, tmp_i], stream=stream)
100
+
101
+ wp.wait_stream(stream)
102
+
103
+
104
+ class Example:
105
+ def __init__(self, quiet=False, device=None):
106
+ self._bd_weight = 100.0
107
+ self._quiet = quiet
108
+
109
+ self._geo = fem.Grid2D(res=wp.vec2i(25))
110
+
111
+ self._main_device = wp.get_device(device)
112
+
113
+ with wp.ScopedDevice(self._main_device):
114
+ self._scalar_space = fem.make_polynomial_space(self._geo, degree=3)
115
+ self._scalar_field = self._scalar_space.make_field()
116
+
117
+ self.renderer = fem_example_utils.Plot()
118
+
119
+ def step(self):
120
+ devices = wp.get_cuda_devices()
121
+ main_device = self._main_device
122
+
123
+ rhs_vecs = []
124
+ res_vecs = []
125
+ matrices = []
126
+ indices = []
127
+
128
+ # Build local system for each device
129
+ for k, device in enumerate(devices):
130
+ with wp.ScopedDevice(device):
131
+ # Construct the partition corresponding to the k'th device
132
+ geo_partition = fem.LinearGeometryPartition(self._geo, k, len(devices))
133
+ matrix, rhs, partition_node_indices = self._assemble_local_system(geo_partition)
134
+
135
+ rhs_vecs.append(rhs)
136
+ res_vecs.append(wp.empty_like(rhs))
137
+ matrices.append(matrix)
138
+ indices.append(partition_node_indices.to(main_device))
139
+
140
+ # Global rhs as sum of all local rhs
141
+ glob_rhs = wp.zeros(n=self._scalar_space.node_count(), dtype=wp.float64, device=main_device)
142
+
143
+ # This temporary buffer will be used for peer-to-peer copying during graph capture,
144
+ # so we allocate it using the default CUDA allocator. This ensures that the copying
145
+ # will succeed without enabling mempool access between devices, which is not supported
146
+ # on all systems.
147
+ with wp.ScopedMempool(main_device, False):
148
+ tmp = wp.empty_like(glob_rhs)
149
+
150
+ sum_vecs(rhs_vecs, indices, glob_rhs, tmp)
151
+
152
+ # Distributed CG
153
+ global_res = wp.zeros_like(glob_rhs)
154
+ A = DistributedSystem()
155
+ A.device = main_device
156
+ A.dtype = glob_rhs.dtype
157
+ A.nrow = self._scalar_space.node_count()
158
+ A.shape = (A.nrow, A.nrow)
159
+ A.tmp_buf = tmp
160
+ A.rank_data = (matrices, rhs_vecs, res_vecs, indices)
161
+
162
+ with wp.ScopedDevice(main_device):
163
+ fem_example_utils.bsr_cg(
164
+ A, x=global_res, b=glob_rhs, use_diag_precond=False, quiet=self._quiet, mv_routine=A.mv_routine
165
+ )
166
+
167
+ array_cast(in_array=global_res, out_array=self._scalar_field.dof_values)
168
+
169
+ def render(self):
170
+ self.renderer.add_field("solution", self._scalar_field)
171
+
172
+ def _assemble_local_system(self, geo_partition: fem.GeometryPartition):
173
+ scalar_space = self._scalar_space
174
+ space_partition = fem.make_space_partition(scalar_space, geo_partition)
175
+
176
+ domain = fem.Cells(geometry=geo_partition)
177
+
178
+ # Right-hand-side
179
+ test = fem.make_test(space=scalar_space, space_partition=space_partition, domain=domain)
180
+ rhs = fem.integrate(linear_form, fields={"v": test})
181
+
182
+ # Weakly-imposed boundary conditions on all sides
183
+ boundary = fem.BoundarySides(geometry=geo_partition)
184
+ bd_test = fem.make_test(space=scalar_space, space_partition=space_partition, domain=boundary)
185
+ bd_trial = fem.make_trial(space=scalar_space, space_partition=space_partition, domain=boundary)
186
+ bd_matrix = fem.integrate(mass_form, fields={"u": bd_trial, "v": bd_test})
187
+
188
+ # Diffusion form
189
+ trial = fem.make_trial(space=scalar_space, space_partition=space_partition, domain=domain)
190
+ matrix = fem.integrate(diffusion_form, fields={"u": trial, "v": test}, values={"nu": 1.0})
191
+
192
+ bsr_axpy(y=matrix, x=bd_matrix, alpha=self._bd_weight)
193
+
194
+ return matrix, rhs, space_partition.space_node_indices()
195
+
196
+
197
+ if __name__ == "__main__":
198
+ import argparse
199
+
200
+ wp.set_module_options({"enable_backward": False})
201
+
202
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
203
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
204
+ parser.add_argument("--quiet", action="store_true", help="Suppresses the printing out of iteration residuals.")
205
+ parser.add_argument(
206
+ "--headless",
207
+ action="store_true",
208
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
209
+ )
210
+
211
+ args = parser.parse_known_args()[0]
212
+
213
+ with wp.ScopedTimer(__file__):
214
+ example = Example(quiet=args.quiet, device=args.device)
215
+
216
+ example.step()
217
+ example.render()
218
+
219
+ if not args.headless:
220
+ example.renderer.plot()
@@ -0,0 +1,228 @@
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 Distortion Energy
18
+ #
19
+ # This example illustrates using a Newton loop to minimize distortion of a
20
+ # 3D surface (u,v) parameterization under a Symmetric Dirichlet energy,
21
+ #
22
+ # E(F) = 1/2 |F|^2 + |F^{-1}|^2
23
+ #
24
+ # with F := dx/du
25
+ ###########################################################################
26
+
27
+ import numpy as np
28
+
29
+ import warp as wp
30
+ import warp.examples.fem.utils as fem_example_utils
31
+ import warp.fem as fem
32
+
33
+
34
+ @fem.integrand
35
+ def distortion_gradient_form(s: fem.Sample, u_cur: fem.Field, v: fem.Field):
36
+ # Symmetric Dirichlet energy gradient (linear form)
37
+ # E = 1/2 (F:F + F^-T:F^-T)
38
+
39
+ F = fem.grad(u_cur, s)
40
+
41
+ F_inv_sq = wp.inverse(F * wp.transpose(F))
42
+ F_inv = F_inv_sq * F
43
+
44
+ dE_dF = F - F_inv_sq * F_inv
45
+
46
+ return wp.ddot(fem.grad(v, s), dE_dF)
47
+
48
+
49
+ @fem.integrand
50
+ def distortion_hessian_form(s: fem.Sample, u_cur: fem.Field, u: fem.Field, v: fem.Field):
51
+ # Symmetric Dirichlet energy approximate hessian (bilinear form)
52
+
53
+ # F:F term
54
+ H = wp.ddot(fem.grad(v, s), fem.grad(u, s))
55
+
56
+ # F^-T:F^-T term
57
+ F = fem.grad(u_cur, s)
58
+ F_inv_sq = wp.inverse(F * wp.transpose(F))
59
+
60
+ # Gauss--Newton (ignore F^-2 derivative)
61
+ H += wp.ddot(F_inv_sq * fem.grad(v, s), F_inv_sq * F_inv_sq * fem.grad(u, s))
62
+
63
+ return H
64
+
65
+
66
+ @fem.integrand
67
+ def initial_guess(
68
+ s: fem.Sample,
69
+ domain: fem.Domain,
70
+ ):
71
+ # initialization for UV parameter
72
+ x = domain(s)
73
+ return wp.vec2(x[0], x[1])
74
+
75
+
76
+ @fem.integrand
77
+ def boundary_projector_form(
78
+ s: fem.Sample,
79
+ domain: fem.Domain,
80
+ u: fem.Field,
81
+ v: fem.Field,
82
+ ):
83
+ # Fix a single point
84
+ # (underconstrained, solution up to a rotation in UV space)
85
+ w = wp.where(s.qp_index == 0, 1.0, 0.0)
86
+ return w * wp.dot(u(s), v(s))
87
+
88
+
89
+ @fem.integrand
90
+ def checkerboard(s: fem.Sample, domain: fem.Domain, u: fem.Field):
91
+ # checkerboard pattern for parameter visualization
92
+ u_s = u(s)
93
+ return wp.sign(wp.cos(16.0 * u_s[0]) * wp.sin(16.0 * u_s[1]))
94
+
95
+
96
+ class Example:
97
+ def __init__(
98
+ self,
99
+ quiet=False,
100
+ degree=2,
101
+ resolution=25,
102
+ mesh="grid",
103
+ nonconforming_stresses=False,
104
+ ):
105
+ self._quiet = quiet
106
+
107
+ def deform_along_z(positions, z_scale=1.0):
108
+ pos = positions.numpy()
109
+ pos_z = z_scale * np.cos(3.0 * pos[:, 0]) * np.sin(4.0 * pos[:, 1])
110
+ pos = np.hstack((pos, np.expand_dims(pos_z, axis=1)))
111
+ return wp.array(pos, dtype=wp.vec3)
112
+
113
+ # Grid or mesh geometry
114
+ if mesh == "tri":
115
+ positions, tri_vidx = fem_example_utils.gen_trimesh(res=wp.vec2i(resolution))
116
+ self._uv_geo = fem.Trimesh2D(tri_vertex_indices=tri_vidx, positions=wp.zeros_like(positions))
117
+
118
+ positions = deform_along_z(positions)
119
+ self._geo = fem.Trimesh3D(tri_vertex_indices=tri_vidx, positions=positions)
120
+ elif mesh == "quad":
121
+ positions, quad_vidx = fem_example_utils.gen_quadmesh(res=wp.vec2i(resolution))
122
+ self._uv_geo = fem.Quadmesh2D(quad_vertex_indices=quad_vidx, positions=wp.zeros_like(positions))
123
+
124
+ positions = deform_along_z(positions)
125
+ self._geo = fem.Quadmesh3D(quad_vertex_indices=quad_vidx, positions=positions)
126
+ else:
127
+ positions, quad_vidx = fem_example_utils.gen_quadmesh(res=wp.vec2i(resolution))
128
+ self._uv_geo = fem.Quadmesh2D(quad_vertex_indices=quad_vidx, positions=wp.zeros_like(positions))
129
+
130
+ undef_positions = deform_along_z(positions, z_scale=0.0)
131
+ flat_geo = fem.Quadmesh3D(quad_vertex_indices=quad_vidx, positions=undef_positions)
132
+
133
+ deformation_field = fem.make_discrete_field(fem.make_polynomial_space(flat_geo, dtype=wp.vec3))
134
+ deformation_field.dof_values = deform_along_z(positions)
135
+
136
+ self._geo = deformation_field.make_deformed_geometry(relative=False)
137
+
138
+ # parameter space
139
+ self._u_space = fem.make_polynomial_space(self._geo, degree=degree, dtype=wp.vec2)
140
+ self._u_field = self._u_space.make_field()
141
+ self._du_field = self._u_space.make_field()
142
+ fem.interpolate(initial_guess, dest=self._u_field)
143
+
144
+ # scalar parameter visualization function
145
+ viz_space = fem.make_polynomial_space(self._geo, degree=3, dtype=float)
146
+ self.viz_field = viz_space.make_field()
147
+ # For visualization of uv in 2D space
148
+ uv_space = fem.make_polynomial_space(self._uv_geo, degree=degree, dtype=wp.vec2)
149
+ self._uv_field = uv_space.make_field()
150
+
151
+ self.renderer = fem_example_utils.Plot()
152
+
153
+ def step(self):
154
+ boundary = fem.BoundarySides(self._geo)
155
+ domain = fem.Cells(geometry=self._geo)
156
+
157
+ # Parameter boundary conditions
158
+ u_bd_test = fem.make_test(space=self._u_space, domain=boundary)
159
+ u_bd_trial = fem.make_trial(space=self._u_space, domain=boundary)
160
+ u_bd_matrix = fem.integrate(
161
+ boundary_projector_form, fields={"u": u_bd_trial, "v": u_bd_test}, nodal=True, output_dtype=float
162
+ )
163
+ fem.normalize_dirichlet_projector(u_bd_matrix)
164
+
165
+ u_test = fem.make_test(space=self._u_space, domain=domain)
166
+ u_trial = fem.make_trial(space=self._u_space, domain=domain)
167
+
168
+ # Newton iterations (without line-search for simplicity)
169
+ for _newton_iteration in range(10):
170
+ u_matrix = fem.integrate(
171
+ distortion_hessian_form, fields={"u_cur": self._u_field, "u": u_trial, "v": u_test}, output_dtype=float
172
+ )
173
+
174
+ u_rhs = fem.integrate(
175
+ distortion_gradient_form, fields={"u_cur": self._u_field, "v": u_test}, output_dtype=wp.vec2
176
+ )
177
+
178
+ fem.project_linear_system(u_matrix, u_rhs, u_bd_matrix, normalize_projector=False)
179
+
180
+ # Solve for uv increment
181
+ du = self._du_field.dof_values
182
+ du.zero_()
183
+ fem_example_utils.bsr_cg(u_matrix, b=u_rhs, x=du, quiet=self._quiet)
184
+
185
+ # Accumulate to UV field
186
+ fem.utils.array_axpy(x=du, y=self._u_field.dof_values, alpha=-1.0, beta=1.0)
187
+
188
+ def render(self):
189
+ # Visualization
190
+ fem.interpolate(checkerboard, fields={"u": self._u_field}, dest=self.viz_field)
191
+
192
+ self._uv_field.dof_values = wp.clone(self._u_field.dof_values)
193
+
194
+ self.renderer.add_field("pattern", self.viz_field)
195
+ self.renderer.add_field("uv", self._uv_field)
196
+
197
+
198
+ if __name__ == "__main__":
199
+ import argparse
200
+
201
+ wp.set_module_options({"enable_backward": False})
202
+
203
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
204
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
205
+ parser.add_argument("--resolution", type=int, default=25, help="Grid resolution.")
206
+ parser.add_argument("--degree", type=int, default=1, help="Polynomial degree of shape functions.")
207
+ parser.add_argument("--mesh", choices=("tri", "quad", "deformed"), default="tri", help="Mesh type")
208
+ parser.add_argument(
209
+ "--headless",
210
+ action="store_true",
211
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
212
+ )
213
+ parser.add_argument("--quiet", action="store_true", help="Suppresses the printing out of iteration residuals.")
214
+
215
+ args = parser.parse_known_args()[0]
216
+
217
+ with wp.ScopedDevice(args.device):
218
+ example = Example(
219
+ quiet=args.quiet,
220
+ degree=args.degree,
221
+ resolution=args.resolution,
222
+ mesh=args.mesh,
223
+ )
224
+ example.step()
225
+ example.render()
226
+
227
+ if not args.headless:
228
+ example.renderer.plot(options={"uv": {"displacement": {}}})
@@ -0,0 +1,240 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024 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 Magnetostatics
18
+ #
19
+ # This example demonstrates solving a 3d magnetostatics problem
20
+ # (a copper coil with radial current around a cylindrical iron core)
21
+ # using a curl-curl formulation and H(curl)-conforming function space
22
+ #
23
+ # 1/mu Curl B + j = 0
24
+ # Div. B = 0
25
+ #
26
+ # solved over field A such that B = Curl A,
27
+ # and Direchlet homogeneous essential boundary conditions
28
+ #
29
+ # This example also illustrates using an ImplictField to warp a grid mesh
30
+ # to a cylindrical domain
31
+ ###########################################################################
32
+
33
+ import numpy as np
34
+
35
+ import warp as wp
36
+ import warp.examples.fem.utils as fem_example_utils
37
+ import warp.fem as fem
38
+
39
+ # Physics constants
40
+ MU_0 = wp.constant(np.pi * 4.0e-7) # Vacuum magnetic permeability
41
+ MU_c = wp.constant(1.25e-6) # Copper magnetic permeability
42
+ MU_i = wp.constant(6.0e-3) # Iron magnetic permeability
43
+
44
+
45
+ @wp.func
46
+ def cube_to_cylinder(x: wp.vec3):
47
+ # mapping from unit square to unit disk
48
+ pos_xz = wp.vec3(x[0], 0.0, x[2])
49
+ return wp.max(wp.abs(pos_xz)) * wp.normalize(pos_xz) + wp.vec3(0.0, x[1], 0.0)
50
+
51
+
52
+ @wp.func
53
+ def cube_to_cylinder_grad(x: wp.vec3):
54
+ # gradient of mapping from unit square to unit disk
55
+ pos_xz = wp.vec3(x[0], 0.0, x[2])
56
+ if pos_xz == wp.vec3(0.0):
57
+ grad = wp.mat33(0.0)
58
+ else:
59
+ dir_xz = wp.normalize(pos_xz)
60
+ dir_grad = (wp.identity(n=3, dtype=float) - wp.outer(dir_xz, dir_xz)) / wp.length(pos_xz)
61
+
62
+ abs_xz = wp.abs(pos_xz)
63
+ xinf_grad = wp.where(
64
+ abs_xz[0] > abs_xz[2], wp.vec(wp.sign(pos_xz[0]), 0.0, 0.0), wp.vec3(0.0, 0.0, wp.sign(pos_xz[2]))
65
+ )
66
+ grad = dir_grad * wp.max(abs_xz) + wp.outer(dir_xz, xinf_grad)
67
+
68
+ grad[1, 1] = 1.0
69
+ return grad
70
+
71
+
72
+ @wp.func
73
+ def permeability_field(
74
+ pos: wp.vec3,
75
+ core_radius: float,
76
+ core_height: float,
77
+ coil_internal_radius: float,
78
+ coil_external_radius: float,
79
+ coil_height: float,
80
+ ):
81
+ x = wp.abs(pos[0])
82
+ y = wp.abs(pos[1])
83
+ z = wp.abs(pos[2])
84
+
85
+ r = wp.sqrt(x * x + z * z)
86
+
87
+ if r <= core_radius:
88
+ return wp.where(y < core_height, MU_i, MU_0)
89
+
90
+ if r >= coil_internal_radius and r <= coil_external_radius:
91
+ return wp.where(y < coil_height, MU_c, MU_0)
92
+
93
+ return MU_0
94
+
95
+
96
+ @wp.func
97
+ def current_field(
98
+ pos: wp.vec3,
99
+ current: float,
100
+ coil_internal_radius: float,
101
+ coil_external_radius: float,
102
+ coil_height: float,
103
+ ):
104
+ x = pos[0]
105
+ y = wp.abs(pos[1])
106
+ z = pos[2]
107
+
108
+ r = wp.sqrt(x * x + z * z)
109
+
110
+ return wp.where(
111
+ y < coil_height and r >= coil_internal_radius and r <= coil_external_radius,
112
+ wp.vec3(z, 0.0, -x) * current / r,
113
+ wp.vec3(0.0),
114
+ )
115
+
116
+
117
+ @fem.integrand
118
+ def curl_curl_form(s: fem.Sample, domain: fem.Domain, u: fem.Field, v: fem.Field, mu: fem.Field):
119
+ return wp.dot(fem.curl(u, s), fem.curl(v, s)) / mu(s)
120
+
121
+
122
+ @fem.integrand
123
+ def mass_form(s: fem.Sample, domain: fem.Domain, v: fem.Field, u: fem.Field):
124
+ return wp.dot(u(s), v(s))
125
+
126
+
127
+ @fem.integrand
128
+ def curl_expr(s: fem.Sample, u: fem.Field):
129
+ return fem.curl(u, s)
130
+
131
+
132
+ class Example:
133
+ def __init__(self, quiet=False, mesh: str = "grid", resolution=32, domain_radius=2.0, current=1.0e6):
134
+ # We mesh the unit disk by first meshing the unit square, then building a deformed geometry
135
+ # from an implicit mapping field
136
+
137
+ if mesh == "hex":
138
+ positions, hex_vidx = fem_example_utils.gen_hexmesh(
139
+ bounds_lo=wp.vec3(-domain_radius, -domain_radius, -domain_radius),
140
+ bounds_hi=wp.vec3(domain_radius, domain_radius, domain_radius),
141
+ res=wp.vec3i(resolution, resolution, resolution),
142
+ )
143
+ cube_geo = fem.Hexmesh(hex_vertex_indices=hex_vidx, positions=positions)
144
+ elif mesh == "tet":
145
+ positions, tet_vidx = fem_example_utils.gen_tetmesh(
146
+ bounds_lo=wp.vec3(-domain_radius, -domain_radius, -domain_radius),
147
+ bounds_hi=wp.vec3(domain_radius, domain_radius, domain_radius),
148
+ res=wp.vec3i(resolution, resolution, resolution),
149
+ )
150
+ cube_geo = fem.Tetmesh(tet_vertex_indices=tet_vidx, positions=positions)
151
+ elif mesh == "nano":
152
+ vol = fem_example_utils.gen_volume(
153
+ bounds_lo=wp.vec3(-domain_radius, -domain_radius, -domain_radius),
154
+ bounds_hi=wp.vec3(domain_radius, domain_radius, domain_radius),
155
+ res=wp.vec3i(resolution, resolution, resolution),
156
+ )
157
+ cube_geo = fem.Nanogrid(grid=vol)
158
+ else:
159
+ cube_geo = fem.Grid3D(
160
+ bounds_lo=wp.vec3(-domain_radius, -domain_radius, -domain_radius),
161
+ bounds_hi=wp.vec3(domain_radius, domain_radius, domain_radius),
162
+ res=wp.vec3i(resolution, resolution, resolution),
163
+ )
164
+
165
+ def_field = fem.ImplicitField(
166
+ domain=fem.Cells(cube_geo), func=cube_to_cylinder, grad_func=cube_to_cylinder_grad
167
+ )
168
+ sim_geo = def_field.make_deformed_geometry(relative=False)
169
+
170
+ coil_config = {"coil_height": 0.25, "coil_internal_radius": 0.3, "coil_external_radius": 0.4}
171
+ core_config = {"core_height": 1.0, "core_radius": 0.2}
172
+
173
+ domain = fem.Cells(sim_geo)
174
+ self._permeability_field = fem.ImplicitField(
175
+ domain, func=permeability_field, values=dict(**coil_config, **core_config)
176
+ )
177
+ self._current_field = fem.ImplicitField(domain, func=current_field, values=dict(current=current, **coil_config))
178
+
179
+ A_space = fem.make_polynomial_space(
180
+ sim_geo, degree=1, element_basis=fem.ElementBasis.NEDELEC_FIRST_KIND, dtype=wp.vec3
181
+ )
182
+ self.A_field = A_space.make_field()
183
+
184
+ B_space = fem.make_polynomial_space(sim_geo, degree=1, element_basis=fem.ElementBasis.LAGRANGE, dtype=wp.vec3)
185
+ self.B_field = B_space.make_field()
186
+
187
+ self.renderer = fem_example_utils.Plot()
188
+
189
+ def step(self):
190
+ A_space = self.A_field.space
191
+ sim_geo = A_space.geometry
192
+
193
+ u = fem.make_trial(space=A_space)
194
+ v = fem.make_test(space=A_space)
195
+ lhs = fem.integrate(curl_curl_form, fields={"u": u, "v": v, "mu": self._permeability_field}, output_dtype=float)
196
+ rhs = fem.integrate(mass_form, fields={"v": v, "u": self._current_field}, output_dtype=float)
197
+
198
+ # Dirichlet BC
199
+ boundary = fem.BoundarySides(sim_geo)
200
+ u_bd = fem.make_trial(space=A_space, domain=boundary)
201
+ v_bd = fem.make_test(space=A_space, domain=boundary)
202
+ dirichlet_bd_proj = fem.integrate(mass_form, fields={"u": u_bd, "v": v_bd}, nodal=True, output_dtype=float)
203
+ fem.project_linear_system(lhs, rhs, dirichlet_bd_proj)
204
+
205
+ # solve using Conjugate Residual (numerically rhs may not be in image of lhs)
206
+ fem_example_utils.bsr_cg(lhs, b=rhs, x=self.A_field.dof_values, method="cr", max_iters=250, quiet=False)
207
+
208
+ # compute B as curl(A)
209
+ fem.interpolate(curl_expr, dest=self.B_field, fields={"u": self.A_field})
210
+
211
+ def render(self):
212
+ self.renderer.add_field("B", self.B_field)
213
+
214
+
215
+ if __name__ == "__main__":
216
+ import argparse
217
+
218
+ wp.set_module_options({"enable_backward": False})
219
+
220
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
221
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
222
+ parser.add_argument("--resolution", type=int, default=32, help="Grid resolution.")
223
+ parser.add_argument("--mesh", type=str, default="grid", choices=["tet", "hex", "grid", "nano"], help="Mesh type.")
224
+ parser.add_argument("--radius", type=float, default=2.0, help="Radius of simulation domain.")
225
+ parser.add_argument(
226
+ "--headless",
227
+ action="store_true",
228
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
229
+ )
230
+ parser.add_argument("--quiet", action="store_true", help="Suppresses the printing out of iteration residuals.")
231
+
232
+ args = parser.parse_known_args()[0]
233
+
234
+ with wp.ScopedDevice(args.device):
235
+ example = Example(quiet=args.quiet, mesh=args.mesh, resolution=args.resolution, domain_radius=args.radius)
236
+ example.step()
237
+ example.render()
238
+
239
+ if not args.headless:
240
+ example.renderer.plot({"B": {"streamlines": {"density": 1.0}}})