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,619 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from typing import Any, Dict, Optional, Set
17
+
18
+ import warp as wp
19
+ from warp.fem import cache
20
+ from warp.fem.domain import GeometryDomain, Sides
21
+ from warp.fem.geometry import DeformedGeometry, Geometry
22
+ from warp.fem.operator import Operator, integrand
23
+ from warp.fem.space import FunctionSpace, SpacePartition
24
+ from warp.fem.types import NULL_ELEMENT_INDEX, ElementKind, Sample
25
+
26
+
27
+ class FieldLike:
28
+ """Base class for integrable fields"""
29
+
30
+ EvalArg: wp.codegen.Struct
31
+ """Structure containing field-level arguments passed to device functions for field evaluation"""
32
+
33
+ ElementEvalArg: wp.codegen.Struct
34
+ """Structure combining geometry-level and field-level arguments passed to device functions for field evaluation"""
35
+
36
+ def eval_arg_value(self, device) -> "EvalArg": # noqa: F821
37
+ """Value of the field-level arguments to be passed to device functions"""
38
+ raise NotImplementedError
39
+
40
+ @property
41
+ def degree(self) -> int:
42
+ """Polynomial degree of the field, used to estimate necessary quadrature order"""
43
+ raise NotImplementedError
44
+
45
+ @property
46
+ def name(self) -> str:
47
+ raise NotImplementedError
48
+
49
+ @property
50
+ def __str__(self) -> str:
51
+ return self.name
52
+
53
+ def eval_arg_value(self, device):
54
+ """Value of arguments to be passed to device functions"""
55
+ raise NotImplementedError
56
+
57
+ def gradient_valid(self) -> bool:
58
+ """Whether the gradient operator is implemented for this field."""
59
+ return False
60
+
61
+ def divergence_valid(self) -> bool:
62
+ """Whether the divergence operator is implemented for this field."""
63
+ return False
64
+
65
+ @staticmethod
66
+ def eval_inner(args: "ElementEvalArg", s: Sample): # noqa: F821
67
+ """Device function evaluating the inner field value at a sample point"""
68
+ raise NotImplementedError
69
+
70
+ @staticmethod
71
+ def eval_grad_inner(args: "ElementEvalArg", s: Sample): # noqa: F821
72
+ """Device function evaluating the inner field gradient at a sample point"""
73
+ raise NotImplementedError
74
+
75
+ @staticmethod
76
+ def eval_div_inner(args: "ElementEvalArg", s: Sample): # noqa: F821
77
+ """Device function evaluating the inner field divergence at a sample point"""
78
+ raise NotImplementedError
79
+
80
+ @staticmethod
81
+ def eval_outer(args: "ElementEvalArg", s: Sample): # noqa: F821
82
+ """Device function evaluating the outer field value at a sample point"""
83
+ raise NotImplementedError
84
+
85
+ @staticmethod
86
+ def eval_grad_outer(args: "ElementEvalArg", s: Sample): # noqa: F821
87
+ """Device function evaluating the outer field gradient at a sample point"""
88
+ raise NotImplementedError
89
+
90
+ @staticmethod
91
+ def eval_div_outer(args: "ElementEvalArg", s: Sample): # noqa: F821
92
+ """Device function evaluating the outer field divergence at a sample point"""
93
+ raise NotImplementedError
94
+
95
+ @staticmethod
96
+ def eval_degree(args: "ElementEvalArg"): # noqa: F821
97
+ """Polynomial degree of the field is applicable, or hint for determination of interpolation order"""
98
+ raise NotImplementedError
99
+
100
+ def notify_operator_usage(self, ops: Set[Operator]):
101
+ """Makes the Domain aware that the operators `ops` will be applied"""
102
+ pass
103
+
104
+
105
+ class GeometryField(FieldLike):
106
+ """Base class for fields defined over a geometry"""
107
+
108
+ @property
109
+ def geometry(self) -> Geometry:
110
+ """Geometry over which the field is expressed"""
111
+ raise NotImplementedError
112
+
113
+ @property
114
+ def element_kind(self) -> ElementKind:
115
+ """Kind of element over which the field is expressed"""
116
+ raise NotImplementedError
117
+
118
+ @staticmethod
119
+ def eval_reference_grad_inner(args: "ElementEvalArg", s: Sample): # noqa: F821
120
+ """Device function evaluating the inner field gradient with respect to reference element coordinates at a sample point"""
121
+ raise NotImplementedError
122
+
123
+ @staticmethod
124
+ def eval_reference_grad_outer(args: "ElementEvalArg", s: Sample): # noqa: F821
125
+ """Device function evaluating the outer field gradient with respect to reference element coordinates at a sample point"""
126
+ raise NotImplementedError
127
+
128
+ def trace(self) -> FieldLike:
129
+ """Trace of this field over lower-dimensional elements"""
130
+ raise NotImplementedError
131
+
132
+ def make_deformed_geometry(self, relative=True) -> Geometry:
133
+ """Returns a deformed version of the underlying geometry, with positions displaced according to this field's values.
134
+
135
+ Args:
136
+ relative: If ``True``, the field is interpreted as a relative displacement over the original geometry.
137
+ If ``False``, the field values are interpreted as absolute positions.
138
+
139
+ """
140
+ return DeformedGeometry(self, relative=relative)
141
+
142
+
143
+ class SpaceField(GeometryField):
144
+ """Base class for fields defined over a function space"""
145
+
146
+ def __init__(self, space: FunctionSpace, space_partition: SpacePartition):
147
+ self._space = space
148
+ self._space_partition = space_partition
149
+
150
+ self.gradient_valid = self.space.gradient_valid
151
+ self.divergence_valid = self.space.divergence_valid
152
+
153
+ @property
154
+ def geometry(self) -> Geometry:
155
+ return self._space.geometry
156
+
157
+ @property
158
+ def element_kind(self) -> ElementKind:
159
+ return self._space.element_kind
160
+
161
+ @property
162
+ def space(self) -> FunctionSpace:
163
+ return self._space
164
+
165
+ @property
166
+ def space_partition(self) -> SpacePartition:
167
+ return self._space_partition
168
+
169
+ @property
170
+ def degree(self) -> int:
171
+ return self.space.degree
172
+
173
+ @property
174
+ def dtype(self) -> type:
175
+ return self.space.dtype
176
+
177
+ @property
178
+ def dof_dtype(self) -> type:
179
+ return self.space.dof_dtype
180
+
181
+ @property
182
+ def gradient_dtype(self):
183
+ """Return type of the gradient operator. Assumes self.gradient_valid()"""
184
+ if wp.types.type_is_vector(self.dtype):
185
+ return cache.cached_mat_type(
186
+ shape=(wp.types.type_length(self.dtype), self.geometry.dimension),
187
+ dtype=wp.types.type_scalar_type(self.dtype),
188
+ )
189
+ return cache.cached_vec_type(length=self.geometry.dimension, dtype=wp.types.type_scalar_type(self.dtype))
190
+
191
+ @property
192
+ def divergence_dtype(self):
193
+ """Return type of the divergence operator. Assumes self.gradient_valid()"""
194
+ if wp.types.type_is_vector(self.dtype):
195
+ return wp.types.type_scalar_type(self.dtype)
196
+ return cache.cached_vec_type(length=self.dtype._shape_[1], dtype=wp.types.type_scalar_type(self.dtype))
197
+
198
+ def _make_eval_degree(self):
199
+ ORDER = self.space.ORDER
200
+
201
+ @cache.dynamic_func(suffix=self.name)
202
+ def degree(args: self.ElementEvalArg):
203
+ return ORDER
204
+
205
+ return degree
206
+
207
+
208
+ class DiscreteField(SpaceField):
209
+ """Explicitly-valued field defined over a partition of a discrete function space"""
210
+
211
+ @property
212
+ def dof_values(self) -> wp.array:
213
+ """Array of degrees of freedom values"""
214
+ raise NotImplementedError
215
+
216
+ @dof_values.setter
217
+ def dof_values(self, values: wp.array):
218
+ """Sets degrees of freedom values from an array"""
219
+ raise NotImplementedError
220
+
221
+ @staticmethod
222
+ def set_node_value(args: "FieldLike.EvalArg", node_index: int, value: Any):
223
+ """Device function setting the value at given node"""
224
+ raise NotImplementedError
225
+
226
+ @property
227
+ def name(self) -> str:
228
+ return f"{self.__class__.__qualname__}_{self.space.name}_{self.space_partition.name}"
229
+
230
+
231
+ class ImplicitField(GeometryField):
232
+ """Field defined from an arbitrary function over a domain.
233
+ Does not support autodiff yet, so if gradient/divergence evaluation is required corresponding functions must be provided.
234
+
235
+ Args:
236
+ domain: Domain over which the field is defined
237
+ func: Warp function evaluating the field at a given position. Must accept at least one argument, with the first argument being the evaluation position (``wp.vec2`` or ``wp.vec3``).
238
+ values: Optional dictionary of additional argument values to be passed to the evaluation function.
239
+ grad_func: Optional gradient evaluation function; must take same arguments as `func`
240
+ div_func: Optional divergence evaluation function; must take same arguments as `func`
241
+ degree: Optional hint for automatic determination of quadrature orders when integrating this field
242
+ """
243
+
244
+ def __init__(
245
+ self,
246
+ domain: GeometryDomain,
247
+ func: wp.Function,
248
+ values: Optional[Dict[str, Any]] = None,
249
+ grad_func: Optional[wp.Function] = None,
250
+ div_func: Optional[wp.Function] = None,
251
+ degree=0,
252
+ ):
253
+ self.domain = domain
254
+ self._degree = degree
255
+
256
+ if not isinstance(func, wp.Function):
257
+ raise ValueError("Implicit field function must be a warp Function (decorated with `wp.func`)")
258
+
259
+ self._func = func
260
+ self._grad_func = grad_func
261
+ self._div_func = div_func
262
+
263
+ argspec = integrand(func.func).argspec
264
+ arg_types = argspec.annotations
265
+
266
+ pos_arg_type = arg_types.pop(argspec.args[0]) if arg_types else None
267
+ if not pos_arg_type or not wp.types.types_equal(
268
+ pos_arg_type, wp.vec(length=domain.geometry.dimension, dtype=float), match_generic=True
269
+ ):
270
+ raise ValueError(
271
+ f"Implicit field function '{func.func.__name__}' must accept a position as its first argument"
272
+ )
273
+
274
+ self.EvalArg = cache.get_argument_struct(arg_types)
275
+ self.values = values
276
+
277
+ self.ElementEvalArg = self._make_element_eval_arg()
278
+ self.eval_degree = self._make_eval_degree()
279
+
280
+ self.eval_inner = self._make_eval_func(func)
281
+ self.eval_grad_inner = self._make_eval_func(grad_func)
282
+ self.eval_div_inner = self._make_eval_func(div_func)
283
+ self.eval_reference_grad_inner = self._make_eval_reference_grad()
284
+
285
+ self.eval_outer = self.eval_inner
286
+ self.eval_grad_outer = self.eval_grad_inner
287
+ self.eval_div_outer = self.eval_div_inner
288
+ self.eval_reference_grad_outer = self.eval_reference_grad_inner
289
+
290
+ @property
291
+ def values(self):
292
+ return self._func_arg
293
+
294
+ @values.setter
295
+ def values(self, v):
296
+ self._func_arg = cache.populate_argument_struct(self.EvalArg, v, self._func.func.__name__)
297
+
298
+ @property
299
+ def geometry(self) -> Geometry:
300
+ return self.domain.geometry
301
+
302
+ @property
303
+ def element_kind(self) -> ElementKind:
304
+ return self.domain.element_kind
305
+
306
+ def eval_arg_value(self, device):
307
+ return self._func_arg
308
+
309
+ @property
310
+ def degree(self) -> int:
311
+ return self._degree
312
+
313
+ @property
314
+ def name(self) -> str:
315
+ return f"Implicit_{self.domain.name}_{self.degree}_{self.EvalArg.key}"
316
+
317
+ def _make_eval_func(self, func):
318
+ if func is None:
319
+ return None
320
+
321
+ @cache.dynamic_func(
322
+ suffix=f"{self.name}_{func.key}",
323
+ code_transformers=[cache.ExpandStarredArgumentStruct({"args.eval_arg": self.EvalArg})],
324
+ )
325
+ def eval_inner(args: self.ElementEvalArg, s: Sample):
326
+ pos = self.domain.element_position(args.elt_arg, s)
327
+ return func(pos, *args.eval_arg)
328
+
329
+ return eval_inner
330
+
331
+ def _make_eval_reference_grad(self):
332
+ if self.eval_grad_inner is None:
333
+ return None
334
+
335
+ @cache.dynamic_func(suffix=f"{self.eval_grad_inner.key}")
336
+ def eval_reference_grad_inner(args: self.ElementEvalArg, s: Sample):
337
+ return self.eval_grad_inner(args, s) * self.domain.element_deformation_gradient(args.elt_arg, s)
338
+
339
+ return eval_reference_grad_inner
340
+
341
+ def _make_element_eval_arg(self):
342
+ @cache.dynamic_struct(suffix=self.name)
343
+ class ElementEvalArg:
344
+ elt_arg: self.domain.ElementArg
345
+ eval_arg: self.EvalArg
346
+
347
+ return ElementEvalArg
348
+
349
+ def _make_eval_degree(self):
350
+ ORDER = wp.constant(self._degree)
351
+
352
+ @cache.dynamic_func(suffix=self.name)
353
+ def degree(args: self.ElementEvalArg):
354
+ return ORDER
355
+
356
+ return degree
357
+
358
+ def trace(self):
359
+ if self.element_kind == ElementKind.SIDE:
360
+ raise RuntimeError("Trace only available for field defined on cell elements")
361
+
362
+ return ImplicitField(
363
+ domain=Sides(self.domain.geometry_partition),
364
+ func=self._func,
365
+ values={name: getattr(self.values, name) for name in self.EvalArg.vars},
366
+ grad_func=self._grad_func,
367
+ div_func=self._div_func,
368
+ degree=self._degree,
369
+ )
370
+
371
+
372
+ class UniformField(GeometryField):
373
+ """Field defined as a constant value over a domain.
374
+
375
+ Args:
376
+ domain: Domain over which the field is defined
377
+ value: Uniform value over the domain
378
+ """
379
+
380
+ def __init__(self, domain: GeometryDomain, value: Any):
381
+ self.domain = domain
382
+
383
+ if not wp.types.is_value(value):
384
+ raise ValueError("value must be a Warp scalar, vector or matrix")
385
+
386
+ self.dtype = wp.types.type_to_warp(type(value))
387
+ self._value = self.dtype(value)
388
+
389
+ scalar_type = wp.types.type_scalar_type(self.dtype)
390
+ if wp.types.type_is_vector(self.dtype):
391
+ grad_type = wp.mat(shape=(wp.types.type_length(self.dtype), self.geometry.dimension), dtype=scalar_type)
392
+ div_type = scalar_type
393
+ elif wp.types.type_is_matrix(self.dtype):
394
+ grad_type = None
395
+ div_type = wp.vec(length=(wp.types.type_length(self.dtype) // self.geometry.dimension), dtype=scalar_type)
396
+ else:
397
+ div_type = None
398
+ grad_type = wp.vec(length=self.geometry.dimension, dtype=scalar_type)
399
+
400
+ self.EvalArg = self._make_eval_arg()
401
+ self.ElementEvalArg = self._make_element_eval_arg()
402
+ self.eval_degree = self._make_eval_degree()
403
+
404
+ self.eval_inner = self._make_eval_inner()
405
+ self.eval_grad_inner = self._make_eval_zero(grad_type)
406
+ self.eval_div_inner = self._make_eval_zero(div_type)
407
+ self.eval_reference_grad_inner = self.eval_grad_inner
408
+
409
+ self.eval_outer = self.eval_inner
410
+ self.eval_grad_outer = self.eval_grad_inner
411
+ self.eval_div_outer = self.eval_div_inner
412
+ self.eval_reference_grad_outer = self.eval_reference_grad_inner
413
+
414
+ @property
415
+ def value(self):
416
+ return self._value
417
+
418
+ @value.setter
419
+ def value(self, v):
420
+ value_type = wp.types.type_to_warp(type(v))
421
+ assert wp.types.types_equal(value_type, self.dtype)
422
+ self._value = self.dtype(v)
423
+
424
+ @property
425
+ def geometry(self) -> Geometry:
426
+ return self.domain.geometry
427
+
428
+ @property
429
+ def element_kind(self) -> ElementKind:
430
+ return self.domain.element_kind
431
+
432
+ def eval_arg_value(self, device):
433
+ arg = self.EvalArg()
434
+ arg.value = self.value
435
+ return arg
436
+
437
+ @property
438
+ def degree(self) -> int:
439
+ return 0
440
+
441
+ @property
442
+ def name(self) -> str:
443
+ return f"Uniform{self.domain.name}_{wp.types.get_type_code(self.dtype)}"
444
+
445
+ def _make_eval_inner(self):
446
+ @cache.dynamic_func(suffix=self.name)
447
+ def eval_inner(args: self.ElementEvalArg, s: Sample):
448
+ return args.eval_arg.value
449
+
450
+ return eval_inner
451
+
452
+ def _make_eval_zero(self, dtype):
453
+ if dtype is None:
454
+ return None
455
+
456
+ scalar_type = wp.types.type_scalar_type(dtype)
457
+
458
+ @cache.dynamic_func(suffix=f"{self.name}_{wp.types.get_type_code(dtype)}")
459
+ def eval_zero(args: self.ElementEvalArg, s: Sample):
460
+ return dtype(scalar_type(0.0))
461
+
462
+ return eval_zero
463
+
464
+ def _make_eval_arg(self):
465
+ @cache.dynamic_struct(suffix=self.name)
466
+ class EvalArg:
467
+ value: self.dtype
468
+
469
+ return EvalArg
470
+
471
+ def _make_element_eval_arg(self):
472
+ @cache.dynamic_struct(suffix=self.name)
473
+ class ElementEvalArg:
474
+ elt_arg: self.domain.ElementArg
475
+ eval_arg: self.EvalArg
476
+
477
+ return ElementEvalArg
478
+
479
+ def _make_eval_degree(self):
480
+ @cache.dynamic_func(suffix=self.name)
481
+ def degree(args: self.ElementEvalArg):
482
+ return 0
483
+
484
+ return degree
485
+
486
+ def trace(self):
487
+ if self.element_kind == ElementKind.SIDE:
488
+ raise RuntimeError("Trace only available for field defined on cell elements")
489
+
490
+ return UniformField(domain=Sides(self.domain.geometry_partition), value=self.value)
491
+
492
+
493
+ class NonconformingField(GeometryField):
494
+ """Field defined as the map of a DiscreteField over a non-conforming geometry.
495
+
496
+ Args:
497
+ domain: The new domain over which the nonconforming field will be evaluated
498
+ field: Nonconforming discrete field
499
+ background: Uniform value or domain-conforming field determining the value outside of the geometry of definition of `field`
500
+ """
501
+
502
+ _LOOKUP_EPS = wp.constant(1.0e-6)
503
+
504
+ def __init__(self, domain: GeometryDomain, field: DiscreteField, background: Any = 0.0):
505
+ self.domain = domain
506
+
507
+ self.field = field
508
+ self.dtype = field.dtype
509
+
510
+ if not isinstance(background, GeometryField):
511
+ background = UniformField(domain, self.dtype(background))
512
+ elif background.geometry != domain.geometry or background.element_kind != domain.element_kind:
513
+ raise ValueError("Background field must be conforming to the domain")
514
+ self.background = background
515
+
516
+ self.EvalArg = self._make_eval_arg()
517
+ self.ElementEvalArg = self._make_element_eval_arg()
518
+ self.eval_degree = self._make_eval_degree()
519
+
520
+ self.eval_inner = self._make_nonconforming_eval("eval_inner")
521
+ self.eval_grad_inner = self._make_nonconforming_eval("eval_grad_inner")
522
+ self.eval_div_inner = self._make_nonconforming_eval("eval_div_inner")
523
+ self.eval_reference_grad_inner = self._make_eval_reference_grad()
524
+
525
+ # Nonconforming evaluation is position based, does not handle discontinuous fields
526
+ self.eval_outer = self.eval_inner
527
+ self.eval_grad_outer = self.eval_grad_inner
528
+ self.eval_div_outer = self.eval_div_inner
529
+ self.eval_reference_grad_outer = self.eval_reference_grad_inner
530
+
531
+ @property
532
+ def geometry(self) -> Geometry:
533
+ return self.domain.geometry
534
+
535
+ @property
536
+ def element_kind(self) -> ElementKind:
537
+ return self.domain.element_kind
538
+
539
+ @cache.cached_arg_value
540
+ def eval_arg_value(self, device):
541
+ arg = self.EvalArg()
542
+ arg.field_cell_eval_arg = self.field.ElementEvalArg()
543
+ arg.field_cell_eval_arg.elt_arg = self.field.geometry.cell_arg_value(device)
544
+ arg.field_cell_eval_arg.eval_arg = self.field.eval_arg_value(device)
545
+ arg.background_arg = self.background.eval_arg_value(device)
546
+ return arg
547
+
548
+ @property
549
+ def degree(self) -> int:
550
+ return self.field.degree
551
+
552
+ @property
553
+ def name(self) -> str:
554
+ return f"{self.domain.name}_{self.field.name}_{self.background.name}"
555
+
556
+ def _make_nonconforming_eval(self, eval_func_name):
557
+ field_eval = getattr(self.field, eval_func_name)
558
+ bg_eval = getattr(self.background, eval_func_name)
559
+
560
+ if field_eval is None or bg_eval is None:
561
+ return None
562
+
563
+ @cache.dynamic_func(suffix=f"{eval_func_name}_{self.name}")
564
+ def eval_nc(args: self.ElementEvalArg, s: Sample):
565
+ pos = self.domain.element_position(args.elt_arg, s)
566
+ cell_arg = args.eval_arg.field_cell_eval_arg.elt_arg
567
+ nonconforming_s = self.field.geometry.cell_lookup(cell_arg, pos)
568
+ if (
569
+ nonconforming_s.element_index == NULL_ELEMENT_INDEX
570
+ or wp.length_sq(pos - self.field.geometry.cell_position(cell_arg, nonconforming_s))
571
+ > NonconformingField._LOOKUP_EPS
572
+ ):
573
+ return bg_eval(self.background.ElementEvalArg(args.elt_arg, args.eval_arg.background_arg), s)
574
+ return field_eval(
575
+ self.field.ElementEvalArg(cell_arg, args.eval_arg.field_cell_eval_arg.eval_arg), nonconforming_s
576
+ )
577
+
578
+ return eval_nc
579
+
580
+ def _make_eval_reference_grad(self):
581
+ if self.eval_grad_inner is None:
582
+ return None
583
+
584
+ @cache.dynamic_func(suffix=f"{self.eval_grad_inner.key}")
585
+ def eval_reference_grad_inner(args: self.ElementEvalArg, s: Sample):
586
+ return self.eval_grad_inner(args, s) * self.domain.element_deformation_gradient(args.elt_arg, s)
587
+
588
+ return eval_reference_grad_inner
589
+
590
+ def _make_eval_arg(self):
591
+ @cache.dynamic_struct(suffix=self.name)
592
+ class EvalArg:
593
+ field_cell_eval_arg: self.field.ElementEvalArg
594
+ background_arg: self.background.EvalArg
595
+
596
+ return EvalArg
597
+
598
+ def _make_element_eval_arg(self):
599
+ @cache.dynamic_struct(suffix=self.name)
600
+ class ElementEvalArg:
601
+ elt_arg: self.domain.ElementArg
602
+ eval_arg: self.EvalArg
603
+
604
+ return ElementEvalArg
605
+
606
+ def _make_eval_degree(self):
607
+ @cache.dynamic_func(suffix=self.name)
608
+ def degree(args: self.ElementEvalArg):
609
+ return self.field.eval_degree(args.eval_arg.field_cell_eval_arg)
610
+
611
+ return degree
612
+
613
+ def trace(self):
614
+ if self.element_kind == ElementKind.SIDE:
615
+ raise RuntimeError("Trace only available for field defined on cell elements")
616
+
617
+ return NonconformingField(
618
+ domain=Sides(self.domain.geometry_partition), field=self.field, background=self.background.trace()
619
+ )