warp-lang 1.9.0__py3-none-win_amd64.whl → 1.10.0rc2__py3-none-win_amd64.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 (350) hide show
  1. warp/__init__.py +301 -287
  2. warp/__init__.pyi +2220 -313
  3. warp/_src/__init__.py +14 -0
  4. warp/_src/autograd.py +1075 -0
  5. warp/_src/build.py +618 -0
  6. warp/_src/build_dll.py +640 -0
  7. warp/{builtins.py → _src/builtins.py} +1497 -226
  8. warp/_src/codegen.py +4359 -0
  9. warp/{config.py → _src/config.py} +178 -169
  10. warp/_src/constants.py +57 -0
  11. warp/_src/context.py +8294 -0
  12. warp/_src/dlpack.py +462 -0
  13. warp/_src/fabric.py +355 -0
  14. warp/_src/fem/__init__.py +14 -0
  15. warp/_src/fem/adaptivity.py +508 -0
  16. warp/_src/fem/cache.py +687 -0
  17. warp/_src/fem/dirichlet.py +188 -0
  18. warp/{fem → _src/fem}/domain.py +40 -30
  19. warp/_src/fem/field/__init__.py +131 -0
  20. warp/_src/fem/field/field.py +701 -0
  21. warp/{fem → _src/fem}/field/nodal_field.py +30 -15
  22. warp/{fem → _src/fem}/field/restriction.py +1 -1
  23. warp/{fem → _src/fem}/field/virtual.py +53 -27
  24. warp/_src/fem/geometry/__init__.py +32 -0
  25. warp/{fem → _src/fem}/geometry/adaptive_nanogrid.py +77 -163
  26. warp/_src/fem/geometry/closest_point.py +97 -0
  27. warp/{fem → _src/fem}/geometry/deformed_geometry.py +14 -22
  28. warp/{fem → _src/fem}/geometry/element.py +32 -10
  29. warp/{fem → _src/fem}/geometry/geometry.py +48 -20
  30. warp/{fem → _src/fem}/geometry/grid_2d.py +12 -23
  31. warp/{fem → _src/fem}/geometry/grid_3d.py +12 -23
  32. warp/{fem → _src/fem}/geometry/hexmesh.py +40 -63
  33. warp/{fem → _src/fem}/geometry/nanogrid.py +255 -248
  34. warp/{fem → _src/fem}/geometry/partition.py +121 -63
  35. warp/{fem → _src/fem}/geometry/quadmesh.py +26 -45
  36. warp/{fem → _src/fem}/geometry/tetmesh.py +40 -63
  37. warp/{fem → _src/fem}/geometry/trimesh.py +26 -45
  38. warp/{fem → _src/fem}/integrate.py +164 -158
  39. warp/_src/fem/linalg.py +383 -0
  40. warp/_src/fem/operator.py +396 -0
  41. warp/_src/fem/polynomial.py +229 -0
  42. warp/{fem → _src/fem}/quadrature/pic_quadrature.py +15 -20
  43. warp/{fem → _src/fem}/quadrature/quadrature.py +95 -47
  44. warp/_src/fem/space/__init__.py +248 -0
  45. warp/{fem → _src/fem}/space/basis_function_space.py +20 -11
  46. warp/_src/fem/space/basis_space.py +679 -0
  47. warp/{fem → _src/fem}/space/dof_mapper.py +3 -3
  48. warp/{fem → _src/fem}/space/function_space.py +14 -13
  49. warp/{fem → _src/fem}/space/grid_2d_function_space.py +4 -7
  50. warp/{fem → _src/fem}/space/grid_3d_function_space.py +4 -4
  51. warp/{fem → _src/fem}/space/hexmesh_function_space.py +4 -10
  52. warp/{fem → _src/fem}/space/nanogrid_function_space.py +3 -9
  53. warp/{fem → _src/fem}/space/partition.py +117 -60
  54. warp/{fem → _src/fem}/space/quadmesh_function_space.py +4 -10
  55. warp/{fem → _src/fem}/space/restriction.py +66 -33
  56. warp/_src/fem/space/shape/__init__.py +152 -0
  57. warp/{fem → _src/fem}/space/shape/cube_shape_function.py +9 -9
  58. warp/{fem → _src/fem}/space/shape/shape_function.py +8 -9
  59. warp/{fem → _src/fem}/space/shape/square_shape_function.py +6 -6
  60. warp/{fem → _src/fem}/space/shape/tet_shape_function.py +3 -3
  61. warp/{fem → _src/fem}/space/shape/triangle_shape_function.py +3 -3
  62. warp/{fem → _src/fem}/space/tetmesh_function_space.py +3 -9
  63. warp/_src/fem/space/topology.py +459 -0
  64. warp/{fem → _src/fem}/space/trimesh_function_space.py +3 -9
  65. warp/_src/fem/types.py +112 -0
  66. warp/_src/fem/utils.py +486 -0
  67. warp/_src/jax.py +186 -0
  68. warp/_src/jax_experimental/__init__.py +14 -0
  69. warp/_src/jax_experimental/custom_call.py +387 -0
  70. warp/_src/jax_experimental/ffi.py +1284 -0
  71. warp/_src/jax_experimental/xla_ffi.py +656 -0
  72. warp/_src/marching_cubes.py +708 -0
  73. warp/_src/math.py +414 -0
  74. warp/_src/optim/__init__.py +14 -0
  75. warp/_src/optim/adam.py +163 -0
  76. warp/_src/optim/linear.py +1606 -0
  77. warp/_src/optim/sgd.py +112 -0
  78. warp/_src/paddle.py +406 -0
  79. warp/_src/render/__init__.py +14 -0
  80. warp/_src/render/imgui_manager.py +289 -0
  81. warp/_src/render/render_opengl.py +3636 -0
  82. warp/_src/render/render_usd.py +937 -0
  83. warp/_src/render/utils.py +160 -0
  84. warp/_src/sparse.py +2716 -0
  85. warp/_src/tape.py +1206 -0
  86. warp/{thirdparty → _src/thirdparty}/unittest_parallel.py +9 -2
  87. warp/_src/torch.py +391 -0
  88. warp/_src/types.py +5870 -0
  89. warp/_src/utils.py +1693 -0
  90. warp/autograd.py +12 -1054
  91. warp/bin/warp-clang.dll +0 -0
  92. warp/bin/warp.dll +0 -0
  93. warp/build.py +8 -588
  94. warp/build_dll.py +6 -471
  95. warp/codegen.py +6 -4246
  96. warp/constants.py +6 -39
  97. warp/context.py +12 -7851
  98. warp/dlpack.py +6 -444
  99. warp/examples/distributed/example_jacobi_mpi.py +4 -5
  100. warp/examples/fem/example_adaptive_grid.py +1 -1
  101. warp/examples/fem/example_apic_fluid.py +1 -1
  102. warp/examples/fem/example_burgers.py +8 -8
  103. warp/examples/fem/example_diffusion.py +1 -1
  104. warp/examples/fem/example_distortion_energy.py +1 -1
  105. warp/examples/fem/example_mixed_elasticity.py +2 -2
  106. warp/examples/fem/example_navier_stokes.py +1 -1
  107. warp/examples/fem/example_nonconforming_contact.py +7 -7
  108. warp/examples/fem/example_stokes.py +1 -1
  109. warp/examples/fem/example_stokes_transfer.py +1 -1
  110. warp/examples/fem/utils.py +2 -2
  111. warp/examples/interop/example_jax_callable.py +1 -1
  112. warp/examples/interop/example_jax_ffi_callback.py +1 -1
  113. warp/examples/interop/example_jax_kernel.py +3 -2
  114. warp/examples/tile/example_tile_mcgp.py +191 -0
  115. warp/fabric.py +6 -337
  116. warp/fem/__init__.py +159 -97
  117. warp/fem/adaptivity.py +7 -489
  118. warp/fem/cache.py +9 -648
  119. warp/fem/dirichlet.py +6 -184
  120. warp/fem/field/__init__.py +8 -109
  121. warp/fem/field/field.py +7 -652
  122. warp/fem/geometry/__init__.py +7 -18
  123. warp/fem/geometry/closest_point.py +11 -77
  124. warp/fem/linalg.py +18 -366
  125. warp/fem/operator.py +11 -369
  126. warp/fem/polynomial.py +9 -209
  127. warp/fem/space/__init__.py +5 -211
  128. warp/fem/space/basis_space.py +6 -662
  129. warp/fem/space/shape/__init__.py +41 -118
  130. warp/fem/space/topology.py +6 -437
  131. warp/fem/types.py +6 -81
  132. warp/fem/utils.py +11 -444
  133. warp/jax.py +8 -165
  134. warp/jax_experimental/__init__.py +14 -1
  135. warp/jax_experimental/custom_call.py +8 -342
  136. warp/jax_experimental/ffi.py +17 -853
  137. warp/jax_experimental/xla_ffi.py +5 -596
  138. warp/marching_cubes.py +5 -689
  139. warp/math.py +16 -393
  140. warp/native/array.h +385 -37
  141. warp/native/builtin.h +316 -39
  142. warp/native/bvh.cpp +43 -9
  143. warp/native/bvh.cu +62 -27
  144. warp/native/bvh.h +310 -309
  145. warp/native/clang/clang.cpp +102 -97
  146. warp/native/coloring.cpp +0 -1
  147. warp/native/crt.h +208 -0
  148. warp/native/exports.h +156 -0
  149. warp/native/hashgrid.cu +2 -0
  150. warp/native/intersect.h +24 -1
  151. warp/native/intersect_tri.h +44 -35
  152. warp/native/mat.h +1456 -276
  153. warp/native/mesh.cpp +4 -4
  154. warp/native/mesh.cu +4 -2
  155. warp/native/mesh.h +176 -61
  156. warp/native/quat.h +0 -52
  157. warp/native/scan.cu +2 -0
  158. warp/native/sort.cu +22 -13
  159. warp/native/sort.h +2 -0
  160. warp/native/sparse.cu +7 -3
  161. warp/native/spatial.h +12 -0
  162. warp/native/tile.h +837 -70
  163. warp/native/tile_radix_sort.h +1 -1
  164. warp/native/tile_reduce.h +394 -46
  165. warp/native/tile_scan.h +4 -4
  166. warp/native/vec.h +469 -53
  167. warp/native/version.h +23 -0
  168. warp/native/volume.cpp +1 -1
  169. warp/native/volume.cu +1 -0
  170. warp/native/volume.h +1 -1
  171. warp/native/volume_builder.cu +2 -0
  172. warp/native/warp.cpp +60 -32
  173. warp/native/warp.cu +313 -201
  174. warp/native/warp.h +14 -11
  175. warp/optim/__init__.py +6 -3
  176. warp/optim/adam.py +6 -145
  177. warp/optim/linear.py +14 -1585
  178. warp/optim/sgd.py +6 -94
  179. warp/paddle.py +6 -388
  180. warp/render/__init__.py +8 -4
  181. warp/render/imgui_manager.py +7 -267
  182. warp/render/render_opengl.py +6 -3616
  183. warp/render/render_usd.py +6 -918
  184. warp/render/utils.py +6 -142
  185. warp/sparse.py +37 -2563
  186. warp/tape.py +6 -1188
  187. warp/tests/__main__.py +1 -1
  188. warp/tests/cuda/test_async.py +4 -4
  189. warp/tests/cuda/test_conditional_captures.py +1 -1
  190. warp/tests/cuda/test_multigpu.py +1 -1
  191. warp/tests/cuda/test_streams.py +58 -1
  192. warp/tests/geometry/test_bvh.py +157 -22
  193. warp/tests/geometry/test_hash_grid.py +38 -0
  194. warp/tests/geometry/test_marching_cubes.py +0 -1
  195. warp/tests/geometry/test_mesh.py +5 -3
  196. warp/tests/geometry/test_mesh_query_aabb.py +5 -12
  197. warp/tests/geometry/test_mesh_query_point.py +5 -2
  198. warp/tests/geometry/test_mesh_query_ray.py +15 -3
  199. warp/tests/geometry/test_volume_write.py +5 -5
  200. warp/tests/interop/test_dlpack.py +14 -14
  201. warp/tests/interop/test_jax.py +1382 -79
  202. warp/tests/interop/test_paddle.py +1 -1
  203. warp/tests/test_adam.py +0 -1
  204. warp/tests/test_arithmetic.py +9 -9
  205. warp/tests/test_array.py +529 -100
  206. warp/tests/test_array_reduce.py +3 -3
  207. warp/tests/test_atomic.py +12 -8
  208. warp/tests/test_atomic_bitwise.py +209 -0
  209. warp/tests/test_atomic_cas.py +4 -4
  210. warp/tests/test_bool.py +2 -2
  211. warp/tests/test_builtins_resolution.py +5 -571
  212. warp/tests/test_codegen.py +34 -15
  213. warp/tests/test_conditional.py +1 -1
  214. warp/tests/test_context.py +6 -6
  215. warp/tests/test_copy.py +242 -161
  216. warp/tests/test_ctypes.py +3 -3
  217. warp/tests/test_devices.py +24 -2
  218. warp/tests/test_examples.py +16 -84
  219. warp/tests/test_fabricarray.py +35 -35
  220. warp/tests/test_fast_math.py +0 -2
  221. warp/tests/test_fem.py +60 -14
  222. warp/tests/test_fixedarray.py +3 -3
  223. warp/tests/test_func.py +8 -5
  224. warp/tests/test_generics.py +1 -1
  225. warp/tests/test_indexedarray.py +24 -24
  226. warp/tests/test_intersect.py +39 -9
  227. warp/tests/test_large.py +1 -1
  228. warp/tests/test_lerp.py +3 -1
  229. warp/tests/test_linear_solvers.py +1 -1
  230. warp/tests/test_map.py +49 -4
  231. warp/tests/test_mat.py +52 -62
  232. warp/tests/test_mat_constructors.py +4 -5
  233. warp/tests/test_mat_lite.py +1 -1
  234. warp/tests/test_mat_scalar_ops.py +121 -121
  235. warp/tests/test_math.py +34 -0
  236. warp/tests/test_module_aot.py +4 -4
  237. warp/tests/test_modules_lite.py +28 -2
  238. warp/tests/test_print.py +11 -11
  239. warp/tests/test_quat.py +93 -58
  240. warp/tests/test_runlength_encode.py +1 -1
  241. warp/tests/test_scalar_ops.py +38 -10
  242. warp/tests/test_smoothstep.py +1 -1
  243. warp/tests/test_sparse.py +126 -15
  244. warp/tests/test_spatial.py +105 -87
  245. warp/tests/test_special_values.py +6 -6
  246. warp/tests/test_static.py +7 -7
  247. warp/tests/test_struct.py +13 -2
  248. warp/tests/test_triangle_closest_point.py +48 -1
  249. warp/tests/test_tuple.py +96 -0
  250. warp/tests/test_types.py +82 -9
  251. warp/tests/test_utils.py +52 -52
  252. warp/tests/test_vec.py +29 -29
  253. warp/tests/test_vec_constructors.py +5 -5
  254. warp/tests/test_vec_scalar_ops.py +97 -97
  255. warp/tests/test_version.py +75 -0
  256. warp/tests/tile/test_tile.py +239 -0
  257. warp/tests/tile/test_tile_atomic_bitwise.py +403 -0
  258. warp/tests/tile/test_tile_cholesky.py +7 -4
  259. warp/tests/tile/test_tile_load.py +26 -2
  260. warp/tests/tile/test_tile_mathdx.py +3 -3
  261. warp/tests/tile/test_tile_matmul.py +1 -1
  262. warp/tests/tile/test_tile_mlp.py +2 -4
  263. warp/tests/tile/test_tile_reduce.py +214 -13
  264. warp/tests/unittest_suites.py +6 -14
  265. warp/tests/unittest_utils.py +10 -9
  266. warp/tests/walkthrough_debug.py +3 -1
  267. warp/torch.py +6 -373
  268. warp/types.py +29 -5750
  269. warp/utils.py +10 -1659
  270. {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/METADATA +47 -103
  271. warp_lang-1.10.0rc2.dist-info/RECORD +468 -0
  272. warp_lang-1.10.0rc2.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
  273. warp_lang-1.10.0rc2.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
  274. warp_lang-1.10.0rc2.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
  275. warp_lang-1.10.0rc2.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
  276. warp_lang-1.10.0rc2.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
  277. warp_lang-1.10.0rc2.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
  278. warp_lang-1.10.0rc2.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
  279. warp_lang-1.10.0rc2.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
  280. warp_lang-1.10.0rc2.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
  281. warp_lang-1.10.0rc2.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
  282. warp_lang-1.10.0rc2.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
  283. warp_lang-1.10.0rc2.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
  284. warp_lang-1.10.0rc2.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
  285. warp_lang-1.10.0rc2.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
  286. warp_lang-1.10.0rc2.dist-info/licenses/licenses/windingnumber-LICENSE.txt +21 -0
  287. warp/examples/assets/cartpole.urdf +0 -110
  288. warp/examples/assets/crazyflie.usd +0 -0
  289. warp/examples/assets/nv_ant.xml +0 -92
  290. warp/examples/assets/nv_humanoid.xml +0 -183
  291. warp/examples/assets/quadruped.urdf +0 -268
  292. warp/examples/optim/example_bounce.py +0 -266
  293. warp/examples/optim/example_cloth_throw.py +0 -228
  294. warp/examples/optim/example_drone.py +0 -870
  295. warp/examples/optim/example_inverse_kinematics.py +0 -182
  296. warp/examples/optim/example_inverse_kinematics_torch.py +0 -191
  297. warp/examples/optim/example_softbody_properties.py +0 -400
  298. warp/examples/optim/example_spring_cage.py +0 -245
  299. warp/examples/optim/example_trajectory.py +0 -227
  300. warp/examples/sim/example_cartpole.py +0 -143
  301. warp/examples/sim/example_cloth.py +0 -225
  302. warp/examples/sim/example_cloth_self_contact.py +0 -316
  303. warp/examples/sim/example_granular.py +0 -130
  304. warp/examples/sim/example_granular_collision_sdf.py +0 -202
  305. warp/examples/sim/example_jacobian_ik.py +0 -244
  306. warp/examples/sim/example_particle_chain.py +0 -124
  307. warp/examples/sim/example_quadruped.py +0 -203
  308. warp/examples/sim/example_rigid_chain.py +0 -203
  309. warp/examples/sim/example_rigid_contact.py +0 -195
  310. warp/examples/sim/example_rigid_force.py +0 -133
  311. warp/examples/sim/example_rigid_gyroscopic.py +0 -115
  312. warp/examples/sim/example_rigid_soft_contact.py +0 -140
  313. warp/examples/sim/example_soft_body.py +0 -196
  314. warp/examples/tile/example_tile_walker.py +0 -327
  315. warp/sim/__init__.py +0 -74
  316. warp/sim/articulation.py +0 -793
  317. warp/sim/collide.py +0 -2570
  318. warp/sim/graph_coloring.py +0 -307
  319. warp/sim/import_mjcf.py +0 -791
  320. warp/sim/import_snu.py +0 -227
  321. warp/sim/import_urdf.py +0 -579
  322. warp/sim/import_usd.py +0 -898
  323. warp/sim/inertia.py +0 -357
  324. warp/sim/integrator.py +0 -245
  325. warp/sim/integrator_euler.py +0 -2000
  326. warp/sim/integrator_featherstone.py +0 -2101
  327. warp/sim/integrator_vbd.py +0 -2487
  328. warp/sim/integrator_xpbd.py +0 -3295
  329. warp/sim/model.py +0 -4821
  330. warp/sim/particles.py +0 -121
  331. warp/sim/render.py +0 -431
  332. warp/sim/utils.py +0 -431
  333. warp/tests/sim/disabled_kinematics.py +0 -244
  334. warp/tests/sim/test_cloth.py +0 -863
  335. warp/tests/sim/test_collision.py +0 -743
  336. warp/tests/sim/test_coloring.py +0 -347
  337. warp/tests/sim/test_inertia.py +0 -161
  338. warp/tests/sim/test_model.py +0 -226
  339. warp/tests/sim/test_sim_grad.py +0 -287
  340. warp/tests/sim/test_sim_grad_bounce_linear.py +0 -212
  341. warp/tests/sim/test_sim_kinematics.py +0 -98
  342. warp/thirdparty/__init__.py +0 -0
  343. warp_lang-1.9.0.dist-info/RECORD +0 -456
  344. /warp/{fem → _src/fem}/quadrature/__init__.py +0 -0
  345. /warp/{tests/sim → _src/thirdparty}/__init__.py +0 -0
  346. /warp/{thirdparty → _src/thirdparty}/appdirs.py +0 -0
  347. /warp/{thirdparty → _src/thirdparty}/dlpack.py +0 -0
  348. {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/WHEEL +0 -0
  349. {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/licenses/LICENSE.md +0 -0
  350. {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,668 +13,12 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- from typing import ClassVar, Optional
16
+ # TODO: Remove after cleaning up the public API.
17
17
 
18
- import numpy as np
18
+ from warp._src.fem.space import basis_space as _basis_space
19
19
 
20
- import warp as wp
21
- from warp.fem import cache
22
- from warp.fem.geometry import Geometry
23
- from warp.fem.quadrature import Quadrature
24
- from warp.fem.types import (
25
- NULL_ELEMENT_INDEX,
26
- NULL_QP_INDEX,
27
- Coords,
28
- ElementIndex,
29
- QuadraturePointIndex,
30
- make_free_sample,
31
- )
32
20
 
33
- from .shape import ShapeFunction
34
- from .topology import RegularDiscontinuousSpaceTopology, SpaceTopology
21
+ def __getattr__(name):
22
+ from warp._src.utils import get_deprecated_api
35
23
 
36
-
37
- class BasisSpace:
38
- """Interface class for defining a shape function space over a geometry.
39
-
40
- A basis space makes it easy to define multiple function spaces sharing the same basis (and thus nodes) but with different valuation functions;
41
- however, it is not a required component of a function space.
42
-
43
- See also: :func:`make_polynomial_basis_space`, :func:`make_collocated_function_space`
44
- """
45
-
46
- @wp.struct
47
- class BasisArg:
48
- """Argument structure to be passed to device functions"""
49
-
50
- pass
51
-
52
- def __init__(self, topology: SpaceTopology):
53
- self._topology = topology
54
-
55
- @property
56
- def topology(self) -> SpaceTopology:
57
- """Underlying topology of the basis space"""
58
- return self._topology
59
-
60
- @property
61
- def geometry(self) -> Geometry:
62
- """Underlying geometry of the basis space"""
63
- return self._topology.geometry
64
-
65
- @property
66
- def value(self) -> ShapeFunction.Value:
67
- """Value type for the underlying shape functions"""
68
- raise NotImplementedError()
69
-
70
- def basis_arg_value(self, device) -> "BasisArg":
71
- """Value for the argument structure to be passed to device functions"""
72
- return BasisSpace.BasisArg()
73
-
74
- def fill_basis_arg(self, arg, device):
75
- pass
76
-
77
- # Helpers for generating node positions
78
-
79
- def node_positions(self, out: Optional[wp.array] = None) -> wp.array:
80
- """Returns a temporary array containing the world position for each node"""
81
-
82
- pos_type = cache.cached_vec_type(length=self.geometry.dimension, dtype=float)
83
-
84
- node_coords_in_element = self.make_node_coords_in_element()
85
-
86
- @cache.dynamic_kernel(suffix=self.name, kernel_options={"max_unroll": 4, "enable_backward": False})
87
- def fill_node_positions(
88
- geo_cell_arg: self.geometry.CellArg,
89
- basis_arg: self.BasisArg,
90
- topo_arg: self.topology.TopologyArg,
91
- node_positions: wp.array(dtype=pos_type),
92
- ):
93
- element_index = wp.tid()
94
-
95
- element_node_count = self.topology.element_node_count(geo_cell_arg, topo_arg, element_index)
96
- for n in range(element_node_count):
97
- node_index = self.topology.element_node_index(geo_cell_arg, topo_arg, element_index, n)
98
- coords = node_coords_in_element(geo_cell_arg, basis_arg, element_index, n)
99
-
100
- sample = make_free_sample(element_index, coords)
101
- pos = self.geometry.cell_position(geo_cell_arg, sample)
102
-
103
- node_positions[node_index] = pos
104
-
105
- shape = (self.topology.node_count(),)
106
- if out is None:
107
- node_positions = wp.empty(
108
- shape=shape,
109
- dtype=pos_type,
110
- )
111
- else:
112
- if out.shape != shape or not wp.types.types_equal(pos_type, out.dtype):
113
- raise ValueError(
114
- f"Out node positions array must have shape {shape} and data type {wp.types.type_repr(pos_type)}"
115
- )
116
- node_positions = out
117
-
118
- wp.launch(
119
- dim=self.geometry.cell_count(),
120
- kernel=fill_node_positions,
121
- inputs=[
122
- self.geometry.cell_arg_value(device=node_positions.device),
123
- self.basis_arg_value(device=node_positions.device),
124
- self.topology.topo_arg_value(device=node_positions.device),
125
- node_positions,
126
- ],
127
- )
128
-
129
- return node_positions
130
-
131
- def make_node_coords_in_element(self):
132
- raise NotImplementedError()
133
-
134
- def make_node_quadrature_weight(self):
135
- raise NotImplementedError()
136
-
137
- def make_element_inner_weight(self):
138
- raise NotImplementedError()
139
-
140
- def make_element_outer_weight(self):
141
- return self.make_element_inner_weight()
142
-
143
- def make_element_inner_weight_gradient(self):
144
- raise NotImplementedError()
145
-
146
- def make_element_outer_weight_gradient(self):
147
- return self.make_element_inner_weight_gradient()
148
-
149
- def make_trace_node_quadrature_weight(self):
150
- raise NotImplementedError()
151
-
152
- def trace(self) -> "TraceBasisSpace":
153
- return TraceBasisSpace(self)
154
-
155
- @property
156
- def weight_type(self):
157
- if self.value is ShapeFunction.Value.Scalar:
158
- return float
159
-
160
- return cache.cached_vec_type(length=self.geometry.cell_dimension, dtype=float)
161
-
162
- @property
163
- def weight_gradient_type(self):
164
- if self.value is ShapeFunction.Value.Scalar:
165
- return wp.vec(length=self.geometry.cell_dimension, dtype=float)
166
-
167
- return cache.cached_mat_type(shape=(self.geometry.cell_dimension, self.geometry.cell_dimension), dtype=float)
168
-
169
-
170
- class ShapeBasisSpace(BasisSpace):
171
- """Base class for defining shape-function-based basis spaces."""
172
-
173
- def __init__(self, topology: SpaceTopology, shape: ShapeFunction):
174
- super().__init__(topology)
175
- self._shape = shape
176
-
177
- if self.value is not ShapeFunction.Value.Scalar:
178
- self.BasisArg = self.topology.TopologyArg
179
- self.basis_arg_value = self.topology.topo_arg_value
180
- self.fill_basis_arg = self.topology.fill_topo_arg
181
-
182
- self.ORDER = self._shape.ORDER
183
-
184
- if hasattr(shape, "element_node_triangulation"):
185
- self.node_triangulation = self._node_triangulation
186
- if hasattr(shape, "element_node_tets"):
187
- self.node_tets = self._node_tets
188
- if hasattr(shape, "element_node_hexes"):
189
- self.node_hexes = self._node_hexes
190
- if hasattr(shape, "element_vtk_cells"):
191
- self.vtk_cells = self._vtk_cells
192
- if hasattr(topology, "node_grid"):
193
- self.node_grid = topology.node_grid
194
-
195
- @property
196
- def shape(self) -> ShapeFunction:
197
- """Shape functions used for defining individual element basis"""
198
- return self._shape
199
-
200
- @property
201
- def value(self) -> ShapeFunction.Value:
202
- return self.shape.value
203
-
204
- @property
205
- def name(self):
206
- return f"{self.topology.name}_{self._shape.name}"
207
-
208
- def make_node_coords_in_element(self):
209
- shape_node_coords_in_element = self._shape.make_node_coords_in_element()
210
-
211
- @cache.dynamic_func(suffix=self.name)
212
- def node_coords_in_element(
213
- elt_arg: self.geometry.CellArg,
214
- basis_arg: self.BasisArg,
215
- element_index: ElementIndex,
216
- node_index_in_elt: int,
217
- ):
218
- return shape_node_coords_in_element(node_index_in_elt)
219
-
220
- return node_coords_in_element
221
-
222
- def make_node_quadrature_weight(self):
223
- shape_node_quadrature_weight = self._shape.make_node_quadrature_weight()
224
-
225
- if shape_node_quadrature_weight is None:
226
- return None
227
-
228
- @cache.dynamic_func(suffix=self.name)
229
- def node_quadrature_weight(
230
- elt_arg: self.geometry.CellArg,
231
- basis_arg: self.BasisArg,
232
- element_index: ElementIndex,
233
- node_index_in_elt: int,
234
- ):
235
- return shape_node_quadrature_weight(node_index_in_elt)
236
-
237
- return node_quadrature_weight
238
-
239
- def make_element_inner_weight(self):
240
- shape_element_inner_weight = self._shape.make_element_inner_weight()
241
-
242
- @cache.dynamic_func(suffix=self.name)
243
- def element_inner_weight(
244
- elt_arg: self.geometry.CellArg,
245
- basis_arg: self.BasisArg,
246
- element_index: ElementIndex,
247
- coords: Coords,
248
- node_index_in_elt: int,
249
- qp_index: QuadraturePointIndex,
250
- ):
251
- if wp.static(self.value == ShapeFunction.Value.Scalar):
252
- return shape_element_inner_weight(coords, node_index_in_elt)
253
- else:
254
- sign = self.topology.element_node_sign(elt_arg, basis_arg, element_index, node_index_in_elt)
255
- return sign * shape_element_inner_weight(coords, node_index_in_elt)
256
-
257
- return element_inner_weight
258
-
259
- def make_element_inner_weight_gradient(self):
260
- shape_element_inner_weight_gradient = self._shape.make_element_inner_weight_gradient()
261
-
262
- @cache.dynamic_func(suffix=self.name)
263
- def element_inner_weight_gradient(
264
- elt_arg: self.geometry.CellArg,
265
- basis_arg: self.BasisArg,
266
- element_index: ElementIndex,
267
- coords: Coords,
268
- node_index_in_elt: int,
269
- qp_index: QuadraturePointIndex,
270
- ):
271
- if wp.static(self.value == ShapeFunction.Value.Scalar):
272
- return shape_element_inner_weight_gradient(coords, node_index_in_elt)
273
- else:
274
- sign = self.topology.element_node_sign(elt_arg, basis_arg, element_index, node_index_in_elt)
275
- return sign * shape_element_inner_weight_gradient(coords, node_index_in_elt)
276
-
277
- return element_inner_weight_gradient
278
-
279
- def make_trace_node_quadrature_weight(self, trace_basis):
280
- shape_trace_node_quadrature_weight = self._shape.make_trace_node_quadrature_weight()
281
-
282
- if shape_trace_node_quadrature_weight is None:
283
- return None
284
-
285
- @cache.dynamic_func(suffix=self.name)
286
- def trace_node_quadrature_weight(
287
- geo_side_arg: trace_basis.geometry.SideArg,
288
- basis_arg: trace_basis.BasisArg,
289
- element_index: ElementIndex,
290
- node_index_in_elt: int,
291
- ):
292
- neighbour_elem, index_in_neighbour = trace_basis.topology.neighbor_cell_index(
293
- geo_side_arg, element_index, node_index_in_elt
294
- )
295
- return shape_trace_node_quadrature_weight(index_in_neighbour)
296
-
297
- return trace_node_quadrature_weight
298
-
299
- def _node_triangulation(self):
300
- element_node_indices = self._topology.element_node_indices().numpy()
301
- element_triangles = self._shape.element_node_triangulation()
302
-
303
- tri_indices = element_node_indices[:, element_triangles].reshape(-1, 3)
304
- return tri_indices
305
-
306
- def _node_tets(self):
307
- element_node_indices = self._topology.element_node_indices().numpy()
308
- element_tets = self._shape.element_node_tets()
309
-
310
- tet_indices = element_node_indices[:, element_tets].reshape(-1, 4)
311
- return tet_indices
312
-
313
- def _node_hexes(self):
314
- element_node_indices = self._topology.element_node_indices().numpy()
315
- element_hexes = self._shape.element_node_hexes()
316
-
317
- hex_indices = element_node_indices[:, element_hexes].reshape(-1, 8)
318
- return hex_indices
319
-
320
- def _vtk_cells(self):
321
- element_node_indices = self._topology.element_node_indices().numpy()
322
- element_vtk_cells, element_vtk_cell_types = self._shape.element_vtk_cells()
323
-
324
- idx_per_cell = element_vtk_cells.shape[1]
325
- cell_indices = element_node_indices[:, element_vtk_cells].reshape(-1, idx_per_cell)
326
- cells = np.hstack((np.full((cell_indices.shape[0], 1), idx_per_cell), cell_indices))
327
-
328
- return cells.flatten(), np.tile(element_vtk_cell_types, element_node_indices.shape[0])
329
-
330
-
331
- class TraceBasisSpace(BasisSpace):
332
- """Auto-generated trace space evaluating the cell-defined basis on the geometry sides"""
333
-
334
- def __init__(self, basis: BasisSpace):
335
- super().__init__(basis.topology.trace())
336
-
337
- self.ORDER = basis.ORDER
338
-
339
- self._basis = basis
340
- self.BasisArg = self._basis.BasisArg
341
- self.basis_arg_value = self._basis.basis_arg_value
342
- self.fill_basis_arg = self._basis.fill_basis_arg
343
-
344
- @property
345
- def name(self):
346
- return f"{self._basis.name}_Trace"
347
-
348
- @property
349
- def value(self) -> ShapeFunction.Value:
350
- return self._basis.value
351
-
352
- def make_node_coords_in_element(self):
353
- node_coords_in_cell = self._basis.make_node_coords_in_element()
354
-
355
- @cache.dynamic_func(suffix=self._basis.name)
356
- def trace_node_coords_in_element(
357
- geo_side_arg: self.geometry.SideArg,
358
- basis_arg: self.BasisArg,
359
- element_index: ElementIndex,
360
- node_index_in_elt: int,
361
- ):
362
- neighbour_elem, index_in_neighbour = self.topology.neighbor_cell_index(
363
- geo_side_arg, element_index, node_index_in_elt
364
- )
365
- geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
366
- neighbour_coords = node_coords_in_cell(
367
- geo_cell_arg,
368
- basis_arg,
369
- neighbour_elem,
370
- index_in_neighbour,
371
- )
372
-
373
- return self.geometry.side_from_cell_coords(geo_side_arg, element_index, neighbour_elem, neighbour_coords)
374
-
375
- return trace_node_coords_in_element
376
-
377
- def make_node_quadrature_weight(self):
378
- return self._basis.make_trace_node_quadrature_weight(self)
379
-
380
- def make_element_inner_weight(self):
381
- cell_inner_weight = self._basis.make_element_inner_weight()
382
-
383
- @cache.dynamic_func(suffix=self._basis.name)
384
- def trace_element_inner_weight(
385
- geo_side_arg: self.geometry.SideArg,
386
- basis_arg: self.BasisArg,
387
- element_index: ElementIndex,
388
- coords: Coords,
389
- node_index_in_elt: int,
390
- qp_index: QuadraturePointIndex,
391
- ):
392
- cell_index, index_in_cell = self.topology.inner_cell_index(geo_side_arg, element_index, node_index_in_elt)
393
- if cell_index == NULL_ELEMENT_INDEX:
394
- return self.weight_type(0.0)
395
-
396
- cell_coords = self.geometry.side_inner_cell_coords(geo_side_arg, element_index, coords)
397
-
398
- geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
399
- return cell_inner_weight(geo_cell_arg, basis_arg, cell_index, cell_coords, index_in_cell, NULL_QP_INDEX)
400
-
401
- return trace_element_inner_weight
402
-
403
- def make_element_outer_weight(self):
404
- cell_outer_weight = self._basis.make_element_outer_weight()
405
-
406
- @cache.dynamic_func(suffix=self._basis.name)
407
- def trace_element_outer_weight(
408
- geo_side_arg: self.geometry.SideArg,
409
- basis_arg: self.BasisArg,
410
- element_index: ElementIndex,
411
- coords: Coords,
412
- node_index_in_elt: int,
413
- qp_index: QuadraturePointIndex,
414
- ):
415
- cell_index, index_in_cell = self.topology.outer_cell_index(geo_side_arg, element_index, node_index_in_elt)
416
- if cell_index == NULL_ELEMENT_INDEX:
417
- return self.weight_type(0.0)
418
-
419
- cell_coords = self.geometry.side_outer_cell_coords(geo_side_arg, element_index, coords)
420
-
421
- geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
422
- return cell_outer_weight(geo_cell_arg, basis_arg, cell_index, cell_coords, index_in_cell, NULL_QP_INDEX)
423
-
424
- return trace_element_outer_weight
425
-
426
- def make_element_inner_weight_gradient(self):
427
- cell_inner_weight_gradient = self._basis.make_element_inner_weight_gradient()
428
-
429
- @cache.dynamic_func(suffix=self._basis.name)
430
- def trace_element_inner_weight_gradient(
431
- geo_side_arg: self.geometry.SideArg,
432
- basis_arg: self.BasisArg,
433
- element_index: ElementIndex,
434
- coords: Coords,
435
- node_index_in_elt: int,
436
- qp_index: QuadraturePointIndex,
437
- ):
438
- cell_index, index_in_cell = self.topology.inner_cell_index(geo_side_arg, element_index, node_index_in_elt)
439
- if cell_index == NULL_ELEMENT_INDEX:
440
- return self.weight_gradient_type(0.0)
441
-
442
- cell_coords = self.geometry.side_inner_cell_coords(geo_side_arg, element_index, coords)
443
- geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
444
- return cell_inner_weight_gradient(
445
- geo_cell_arg, basis_arg, cell_index, cell_coords, index_in_cell, NULL_QP_INDEX
446
- )
447
-
448
- return trace_element_inner_weight_gradient
449
-
450
- def make_element_outer_weight_gradient(self):
451
- cell_outer_weight_gradient = self._basis.make_element_outer_weight_gradient()
452
-
453
- @cache.dynamic_func(suffix=self._basis.name)
454
- def trace_element_outer_weight_gradient(
455
- geo_side_arg: self.geometry.SideArg,
456
- basis_arg: self.BasisArg,
457
- element_index: ElementIndex,
458
- coords: Coords,
459
- node_index_in_elt: int,
460
- qp_index: QuadraturePointIndex,
461
- ):
462
- cell_index, index_in_cell = self.topology.outer_cell_index(geo_side_arg, element_index, node_index_in_elt)
463
- if cell_index == NULL_ELEMENT_INDEX:
464
- return self.weight_gradient_type(0.0)
465
-
466
- cell_coords = self.geometry.side_outer_cell_coords(geo_side_arg, element_index, coords)
467
- geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
468
- return cell_outer_weight_gradient(
469
- geo_cell_arg, basis_arg, cell_index, cell_coords, index_in_cell, NULL_QP_INDEX
470
- )
471
-
472
- return trace_element_outer_weight_gradient
473
-
474
- def __eq__(self, other: "TraceBasisSpace") -> bool:
475
- return self._topo == other._topo
476
-
477
-
478
- class PiecewiseConstantBasisSpace(ShapeBasisSpace):
479
- class Trace(TraceBasisSpace):
480
- def make_node_coords_in_element(self):
481
- # Makes the single node visible to all sides; useful for interpolating on boundaries
482
- # For higher-order non-conforming elements direct interpolation on boundary is not possible,
483
- # need to do proper integration then solve with mass matrix
484
-
485
- CENTER_COORDS = Coords(self.geometry.reference_side().center())
486
-
487
- @cache.dynamic_func(suffix=self._basis.name)
488
- def trace_node_coords_in_element(
489
- geo_side_arg: self.geometry.SideArg,
490
- basis_arg: self.BasisArg,
491
- element_index: ElementIndex,
492
- node_index_in_elt: int,
493
- ):
494
- return CENTER_COORDS
495
-
496
- return trace_node_coords_in_element
497
-
498
- def trace(self):
499
- return PiecewiseConstantBasisSpace.Trace(self)
500
-
501
-
502
- def make_discontinuous_basis_space(geometry: Geometry, shape: ShapeFunction):
503
- topology = RegularDiscontinuousSpaceTopology(geometry, shape.NODES_PER_ELEMENT)
504
-
505
- if shape.NODES_PER_ELEMENT == 1:
506
- # piecewise-constant space
507
- return PiecewiseConstantBasisSpace(topology=topology, shape=shape)
508
-
509
- return ShapeBasisSpace(topology=topology, shape=shape)
510
-
511
-
512
- class UnstructuredPointTopology(SpaceTopology):
513
- """Topology for unstructured points defined from quadrature formula. See :class:`PointBasisSpace`"""
514
-
515
- _dynamic_attribute_constructors: ClassVar = {
516
- "element_node_index": lambda obj: obj._make_element_node_index(),
517
- "element_node_count": lambda obj: obj._make_element_node_count(),
518
- "side_neighbor_node_counts": lambda obj: obj._make_side_neighbor_node_counts(),
519
- }
520
-
521
- def __init__(self, quadrature: Quadrature):
522
- if quadrature.max_points_per_element() is None:
523
- raise ValueError("Quadrature must define a maximum number of points per element")
524
-
525
- if quadrature.domain.element_count() != quadrature.domain.geometry_element_count():
526
- raise ValueError("Point topology may only be defined on quadrature domains than span the whole geometry")
527
-
528
- self._quadrature = quadrature
529
- self.TopologyArg = quadrature.Arg
530
- self.topo_arg_value = quadrature.arg_value
531
- self.fill_topo_arg = quadrature.fill_arg
532
-
533
- super().__init__(quadrature.domain.geometry, max_nodes_per_element=quadrature.max_points_per_element())
534
-
535
- cache.setup_dynamic_attributes(self, cls=__class__)
536
-
537
- def node_count(self):
538
- return self._quadrature.total_point_count()
539
-
540
- @property
541
- def name(self):
542
- return f"PointTopology_{self._quadrature}"
543
-
544
- def topo_arg_value(self, device) -> SpaceTopology.TopologyArg:
545
- """Value of the topology argument structure to be passed to device functions"""
546
- return self._quadrature.arg_value(device)
547
-
548
- def _make_element_node_index(self):
549
- @cache.dynamic_func(suffix=self.name)
550
- def element_node_index(
551
- elt_arg: self.geometry.CellArg,
552
- topo_arg: self.TopologyArg,
553
- element_index: ElementIndex,
554
- node_index_in_elt: int,
555
- ):
556
- return self._quadrature.point_index(elt_arg, topo_arg, element_index, element_index, node_index_in_elt)
557
-
558
- return element_node_index
559
-
560
- def _make_element_node_count(self):
561
- @cache.dynamic_func(suffix=self.name)
562
- def element_node_count(
563
- elt_arg: self.geometry.CellArg,
564
- topo_arg: self.TopologyArg,
565
- element_index: ElementIndex,
566
- ):
567
- return self._quadrature.point_count(elt_arg, topo_arg, element_index, element_index)
568
-
569
- return element_node_count
570
-
571
- def _make_side_neighbor_node_counts(self):
572
- @cache.dynamic_func(suffix=self.name)
573
- def side_neighbor_node_counts(
574
- side_arg: self.geometry.SideArg,
575
- element_index: ElementIndex,
576
- ):
577
- return 0, 0
578
-
579
- return side_neighbor_node_counts
580
-
581
-
582
- class PointBasisSpace(BasisSpace):
583
- """An unstructured :class:`BasisSpace` that is non-zero at a finite set of points only.
584
-
585
- The node locations and nodal quadrature weights are defined by a :class:`Quadrature` formula.
586
- """
587
-
588
- def __init__(self, quadrature: Quadrature):
589
- self._quadrature = quadrature
590
-
591
- topology = UnstructuredPointTopology(quadrature)
592
- super().__init__(topology)
593
-
594
- self.BasisArg = quadrature.Arg
595
- self.basis_arg_value = quadrature.arg_value
596
- self.fill_basis_arg = quadrature.fill_arg
597
-
598
- self.ORDER = 0
599
-
600
- self.make_element_outer_weight = self.make_element_inner_weight
601
- self.make_element_outer_weight_gradient = self.make_element_outer_weight_gradient
602
-
603
- @property
604
- def name(self):
605
- return f"{self._quadrature.name}_Point"
606
-
607
- @property
608
- def value(self) -> ShapeFunction.Value:
609
- return ShapeFunction.Value.Scalar
610
-
611
- def make_node_coords_in_element(self):
612
- @cache.dynamic_func(suffix=self.name)
613
- def node_coords_in_element(
614
- elt_arg: self._quadrature.domain.ElementArg,
615
- basis_arg: self.BasisArg,
616
- element_index: ElementIndex,
617
- node_index_in_elt: int,
618
- ):
619
- return self._quadrature.point_coords(elt_arg, basis_arg, element_index, element_index, node_index_in_elt)
620
-
621
- return node_coords_in_element
622
-
623
- def make_node_quadrature_weight(self):
624
- @cache.dynamic_func(suffix=self.name)
625
- def node_quadrature_weight(
626
- elt_arg: self._quadrature.domain.ElementArg,
627
- basis_arg: self.BasisArg,
628
- element_index: ElementIndex,
629
- node_index_in_elt: int,
630
- ):
631
- return self._quadrature.point_weight(elt_arg, basis_arg, element_index, element_index, node_index_in_elt)
632
-
633
- return node_quadrature_weight
634
-
635
- def make_element_inner_weight(self):
636
- _DIRAC_INTEGRATION_RADIUS = wp.constant(1.0e-6)
637
-
638
- @cache.dynamic_func(suffix=self.name)
639
- def element_inner_weight(
640
- elt_arg: self._quadrature.domain.ElementArg,
641
- basis_arg: self.BasisArg,
642
- element_index: ElementIndex,
643
- coords: Coords,
644
- node_index_in_elt: int,
645
- qp_index: QuadraturePointIndex,
646
- ):
647
- qp_coord = self._quadrature.point_coords(
648
- elt_arg, basis_arg, element_index, element_index, node_index_in_elt
649
- )
650
- return wp.where(wp.length_sq(coords - qp_coord) < _DIRAC_INTEGRATION_RADIUS, 1.0, 0.0)
651
-
652
- return element_inner_weight
653
-
654
- def make_element_inner_weight_gradient(self):
655
- gradient_vec = cache.cached_vec_type(length=self.geometry.cell_dimension, dtype=float)
656
-
657
- @cache.dynamic_func(suffix=self.name)
658
- def element_inner_weight_gradient(
659
- elt_arg: self._quadrature.domain.ElementArg,
660
- basis_arg: self.BasisArg,
661
- element_index: ElementIndex,
662
- coords: Coords,
663
- node_index_in_elt: int,
664
- qp_index: QuadraturePointIndex,
665
- ):
666
- return gradient_vec(0.0)
667
-
668
- return element_inner_weight_gradient
669
-
670
- def make_trace_node_quadrature_weight(self, trace_basis):
671
- @cache.dynamic_func(suffix=self.name)
672
- def trace_node_quadrature_weight(
673
- elt_arg: trace_basis.geometry.SideArg,
674
- basis_arg: trace_basis.BasisArg,
675
- element_index: ElementIndex,
676
- node_index_in_elt: int,
677
- ):
678
- return 0.0
679
-
680
- return trace_node_quadrature_weight
24
+ return get_deprecated_api(_basis_space, "wp.fem.space", name)