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,133 +13,56 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- import functools
17
- from enum import Enum
18
- from typing import Optional
16
+ # isort: skip_file
19
17
 
20
- from warp.fem.geometry import element as _element
21
- from warp.fem.polynomial import Polynomial
18
+ # Keeping those imports non-deprecated for now,
19
+ # Will be deprecated after unification of the shape functions API (1.11+)
22
20
 
23
- from .cube_shape_function import (
24
- CubeNedelecFirstKindShapeFunctions,
25
- CubeNonConformingPolynomialShapeFunctions,
26
- CubeRaviartThomasShapeFunctions,
27
- CubeSerendipityShapeFunctions,
28
- CubeShapeFunction,
29
- CubeTripolynomialShapeFunctions,
21
+ from warp._src.fem.space.shape import CubeShapeFunction as CubeShapeFunction
22
+ from warp._src.fem.space.shape import CubeNedelecFirstKindShapeFunctions as CubeNedelecFirstKindShapeFunctions
23
+ from warp._src.fem.space.shape import (
24
+ CubeNonConformingPolynomialShapeFunctions as CubeNonConformingPolynomialShapeFunctions,
30
25
  )
31
- from .shape_function import ConstantShapeFunction, ShapeFunction
32
- from .square_shape_function import (
33
- SquareBipolynomialShapeFunctions,
34
- SquareNedelecFirstKindShapeFunctions,
35
- SquareNonConformingPolynomialShapeFunctions,
36
- SquareRaviartThomasShapeFunctions,
37
- SquareSerendipityShapeFunctions,
38
- SquareShapeFunction,
26
+ from warp._src.fem.space.shape import CubeRaviartThomasShapeFunctions as CubeRaviartThomasShapeFunctions
27
+ from warp._src.fem.space.shape import CubeSerendipityShapeFunctions as CubeSerendipityShapeFunctions
28
+ from warp._src.fem.space.shape import CubeTripolynomialShapeFunctions as CubeTripolynomialShapeFunctions
29
+
30
+ from warp._src.fem.space.shape import SquareShapeFunction as SquareShapeFunction
31
+ from warp._src.fem.space.shape import SquareBipolynomialShapeFunctions as SquareBipolynomialShapeFunctions
32
+ from warp._src.fem.space.shape import SquareNedelecFirstKindShapeFunctions as SquareNedelecFirstKindShapeFunctions
33
+ from warp._src.fem.space.shape import (
34
+ SquareNonConformingPolynomialShapeFunctions as SquareNonConformingPolynomialShapeFunctions,
39
35
  )
40
- from .tet_shape_function import (
41
- TetrahedronNedelecFirstKindShapeFunctions,
42
- TetrahedronNonConformingPolynomialShapeFunctions,
43
- TetrahedronPolynomialShapeFunctions,
44
- TetrahedronRaviartThomasShapeFunctions,
45
- TetrahedronShapeFunction,
46
- )
47
- from .triangle_shape_function import (
48
- TriangleNedelecFirstKindShapeFunctions,
49
- TriangleNonConformingPolynomialShapeFunctions,
50
- TrianglePolynomialShapeFunctions,
51
- TriangleRaviartThomasShapeFunctions,
52
- TriangleShapeFunction,
53
- )
54
-
55
-
56
- class ElementBasis(Enum):
57
- """Choice of basis function to equip individual elements"""
58
-
59
- LAGRANGE = "P"
60
- """Lagrange basis functions :math:`P_k` for simplices, tensor products :math:`Q_k` for squares and cubes"""
61
- SERENDIPITY = "S"
62
- """Serendipity elements :math:`S_k`, corresponding to Lagrange nodes with interior points removed (for degree <= 3)"""
63
- NONCONFORMING_POLYNOMIAL = "dP"
64
- """Simplex Lagrange basis functions :math:`P_{kd}` embedded into non conforming reference elements (e.g. squares or cubes). Discontinuous only."""
65
- NEDELEC_FIRST_KIND = "N1"
66
- """Nédélec (first kind) H(curl) shape functions. Should be used with covariant function space."""
67
- RAVIART_THOMAS = "RT"
68
- """Raviart-Thomas H(div) shape functions. Should be used with contravariant function space."""
69
-
36
+ from warp._src.fem.space.shape import SquareRaviartThomasShapeFunctions as SquareRaviartThomasShapeFunctions
37
+ from warp._src.fem.space.shape import SquareSerendipityShapeFunctions as SquareSerendipityShapeFunctions
70
38
 
71
- @functools.lru_cache(maxsize=None)
72
- def get_shape_function(
73
- element_class: type,
74
- space_dimension: int,
75
- degree: int,
76
- element_basis: ElementBasis,
77
- family: Optional[Polynomial] = None,
78
- ):
79
- """
80
- Equips a reference element with a shape function basis.
81
-
82
- Args:
83
- element_class: the type of reference element on which to build the shape function
84
- space_dimension: the dimension of the embedding space
85
- degree: polynomial degree of the per-element shape functions
86
- element_basis: type of basis function for the individual elements
87
- family: Polynomial family used to generate the shape function basis. If not provided, a reasonable basis is chosen.
88
-
89
- Returns:
90
- the corresponding shape function
91
- """
92
-
93
- if degree == 0:
94
- return ConstantShapeFunction(element_class(), space_dimension)
39
+ from warp._src.fem.space.shape import TriangleShapeFunction as TriangleShapeFunction
40
+ from warp._src.fem.space.shape import TriangleNedelecFirstKindShapeFunctions as TriangleNedelecFirstKindShapeFunctions
41
+ from warp._src.fem.space.shape import (
42
+ TriangleNonConformingPolynomialShapeFunctions as TriangleNonConformingPolynomialShapeFunctions,
43
+ )
44
+ from warp._src.fem.space.shape import TrianglePolynomialShapeFunctions as TrianglePolynomialShapeFunctions
45
+ from warp._src.fem.space.shape import TriangleRaviartThomasShapeFunctions as TriangleRaviartThomasShapeFunctions
95
46
 
96
- if family is None:
97
- family = Polynomial.LOBATTO_GAUSS_LEGENDRE
47
+ from warp._src.fem.space.shape import TetrahedronShapeFunction as TetrahedronShapeFunction
48
+ from warp._src.fem.space.shape import (
49
+ TetrahedronNedelecFirstKindShapeFunctions as TetrahedronNedelecFirstKindShapeFunctions,
50
+ )
51
+ from warp._src.fem.space.shape import (
52
+ TetrahedronNonConformingPolynomialShapeFunctions as TetrahedronNonConformingPolynomialShapeFunctions,
53
+ )
54
+ from warp._src.fem.space.shape import TetrahedronPolynomialShapeFunctions as TetrahedronPolynomialShapeFunctions
55
+ from warp._src.fem.space.shape import TetrahedronRaviartThomasShapeFunctions as TetrahedronRaviartThomasShapeFunctions
98
56
 
99
- if issubclass(element_class, _element.Square):
100
- if element_basis == ElementBasis.NEDELEC_FIRST_KIND:
101
- return SquareNedelecFirstKindShapeFunctions(degree=degree)
102
- if element_basis == ElementBasis.RAVIART_THOMAS:
103
- return SquareRaviartThomasShapeFunctions(degree=degree)
104
- if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
105
- return SquareNonConformingPolynomialShapeFunctions(degree=degree)
106
- if element_basis == ElementBasis.SERENDIPITY and degree > 1:
107
- return SquareSerendipityShapeFunctions(degree=degree, family=family)
57
+ from warp._src.fem.space.shape import ConstantShapeFunction as ConstantShapeFunction
108
58
 
109
- return SquareBipolynomialShapeFunctions(degree=degree, family=family)
110
- if issubclass(element_class, _element.Triangle):
111
- if element_basis == ElementBasis.NEDELEC_FIRST_KIND:
112
- return TriangleNedelecFirstKindShapeFunctions(degree=degree)
113
- if element_basis == ElementBasis.RAVIART_THOMAS:
114
- return TriangleRaviartThomasShapeFunctions(degree=degree)
115
- if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
116
- return TriangleNonConformingPolynomialShapeFunctions(degree=degree)
117
- if element_basis == ElementBasis.SERENDIPITY and degree > 2:
118
- raise NotImplementedError("Serendipity variant not implemented yet for Triangle elements")
119
59
 
120
- return TrianglePolynomialShapeFunctions(degree=degree)
60
+ # TODO: Remove after cleaning up the public API.
121
61
 
122
- if issubclass(element_class, _element.Cube):
123
- if element_basis == ElementBasis.NEDELEC_FIRST_KIND:
124
- return CubeNedelecFirstKindShapeFunctions(degree=degree)
125
- if element_basis == ElementBasis.RAVIART_THOMAS:
126
- return CubeRaviartThomasShapeFunctions(degree=degree)
127
- if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
128
- return CubeNonConformingPolynomialShapeFunctions(degree=degree)
129
- if element_basis == ElementBasis.SERENDIPITY and degree > 1:
130
- return CubeSerendipityShapeFunctions(degree=degree, family=family)
62
+ from warp._src.fem.space import shape as _shape
131
63
 
132
- return CubeTripolynomialShapeFunctions(degree=degree, family=family)
133
- if issubclass(element_class, _element.Tetrahedron):
134
- if element_basis == ElementBasis.NEDELEC_FIRST_KIND:
135
- return TetrahedronNedelecFirstKindShapeFunctions(degree=degree)
136
- if element_basis == ElementBasis.RAVIART_THOMAS:
137
- return TetrahedronRaviartThomasShapeFunctions(degree=degree)
138
- if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
139
- return TetrahedronNonConformingPolynomialShapeFunctions(degree=degree)
140
- if element_basis == ElementBasis.SERENDIPITY and degree > 2:
141
- raise NotImplementedError("Serendipity variant not implemented yet for Tet elements")
142
64
 
143
- return TetrahedronPolynomialShapeFunctions(degree=degree)
65
+ def __getattr__(name):
66
+ from warp._src.utils import get_deprecated_api
144
67
 
145
- raise NotImplementedError(f"Unrecognized element type {element_class.__name__}")
68
+ return get_deprecated_api(_shape, "wp.fem.space", name)
@@ -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,443 +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, Tuple, Type
16
+ # TODO: Remove after cleaning up the public API.
17
17
 
18
- import warp as wp
19
- from warp.fem import cache
20
- from warp.fem.geometry import DeformedGeometry, Geometry
21
- from warp.fem.types import NULL_ELEMENT_INDEX, NULL_NODE_INDEX, ElementIndex
18
+ from warp._src.fem.space import topology as _topology
22
19
 
23
20
 
24
- class SpaceTopology:
25
- """
26
- Interface class for defining the topology of a function space.
21
+ def __getattr__(name):
22
+ from warp._src.utils import get_deprecated_api
27
23
 
28
- The topology only considers the indices of the nodes in each element, and as such,
29
- the connectivity pattern of the function space.
30
- It does not specify the actual location of the nodes within the elements, or the valuation function.
31
- """
32
-
33
- dimension: int
34
- """Embedding dimension of the function space"""
35
-
36
- MAX_NODES_PER_ELEMENT: int
37
- """maximum number of interpolation nodes per element of the geometry.
38
-
39
- .. note:: This will change to be defined per-element in future versions
40
- """
41
-
42
- _dynamic_attribute_constructors: ClassVar = {
43
- "element_node_count": lambda obj: obj._make_constant_element_node_count(),
44
- "element_node_sign": lambda obj: obj._make_constant_element_node_sign(),
45
- "side_neighbor_node_counts": lambda obj: obj._make_constant_side_neighbor_node_counts(),
46
- }
47
-
48
- @wp.struct
49
- class TopologyArg:
50
- """Structure containing arguments to be passed to device functions"""
51
-
52
- pass
53
-
54
- def __init__(self, geometry: Geometry, max_nodes_per_element: int):
55
- self._geometry = geometry
56
- self.dimension = geometry.dimension
57
- self.MAX_NODES_PER_ELEMENT = wp.constant(max_nodes_per_element)
58
- self.ElementArg = geometry.CellArg
59
-
60
- cache.setup_dynamic_attributes(self, cls=__class__)
61
-
62
- @property
63
- def geometry(self) -> Geometry:
64
- """Underlying geometry"""
65
- return self._geometry
66
-
67
- def node_count(self) -> int:
68
- """Number of nodes in the interpolation basis"""
69
- raise NotImplementedError
70
-
71
- def topo_arg_value(self, device) -> "TopologyArg":
72
- """Value of the topology argument structure to be passed to device functions"""
73
- return SpaceTopology.TopologyArg()
74
-
75
- def fill_topo_arg(self, arg, device):
76
- pass
77
-
78
- @property
79
- def name(self):
80
- return f"{self.__class__.__name__}_{self.MAX_NODES_PER_ELEMENT}"
81
-
82
- def __str__(self):
83
- return self.name
84
-
85
- @staticmethod
86
- def element_node_count(
87
- geo_arg: "ElementArg", # noqa: F821
88
- topo_arg: "TopologyArg",
89
- element_index: ElementIndex,
90
- ) -> int:
91
- """Returns the actual number of nodes in a given element"""
92
- raise NotImplementedError
93
-
94
- @staticmethod
95
- def element_node_index(
96
- geo_arg: "ElementArg", # noqa: F821
97
- topo_arg: "TopologyArg",
98
- element_index: ElementIndex,
99
- node_index_in_elt: int,
100
- ) -> int:
101
- """Global node index for a given node in a given element"""
102
- raise NotImplementedError
103
-
104
- @staticmethod
105
- def side_neighbor_node_counts(
106
- side_arg: "ElementArg", # noqa: F821
107
- side_index: ElementIndex,
108
- ) -> Tuple[int, int]:
109
- """Returns the number of nodes for both the inner and outer cells of a given sides"""
110
- raise NotImplementedError
111
-
112
- def element_node_indices(self, out: Optional[wp.array] = None) -> wp.array:
113
- """Returns a temporary array containing the global index for each node of each element"""
114
-
115
- MAX_NODES_PER_ELEMENT = self.MAX_NODES_PER_ELEMENT
116
-
117
- @cache.dynamic_kernel(suffix=self.name)
118
- def fill_element_node_indices(
119
- geo_cell_arg: self.geometry.CellArg,
120
- topo_arg: self.TopologyArg,
121
- element_node_indices: wp.array2d(dtype=int),
122
- ):
123
- element_index = wp.tid()
124
- element_node_count = self.element_node_count(geo_cell_arg, topo_arg, element_index)
125
- for n in range(element_node_count):
126
- element_node_indices[element_index, n] = self.element_node_index(
127
- geo_cell_arg, topo_arg, element_index, n
128
- )
129
-
130
- shape = (self.geometry.cell_count(), MAX_NODES_PER_ELEMENT)
131
- if out is None:
132
- element_node_indices = wp.empty(
133
- shape=shape,
134
- dtype=int,
135
- )
136
- else:
137
- if out.shape != shape or out.dtype != wp.int32:
138
- raise ValueError(f"Out element node indices array must have shape {shape} and data type 'int32'")
139
- element_node_indices = out
140
-
141
- wp.launch(
142
- dim=element_node_indices.shape[0],
143
- kernel=fill_element_node_indices,
144
- inputs=[
145
- self.geometry.cell_arg_value(device=element_node_indices.device),
146
- self.topo_arg_value(device=element_node_indices.device),
147
- element_node_indices,
148
- ],
149
- device=element_node_indices.device,
150
- )
151
-
152
- return element_node_indices
153
-
154
- # Interface generating trace space topology
155
-
156
- def trace(self) -> "TraceSpaceTopology":
157
- """Trace of the function space over lower-dimensional elements of the geometry"""
158
-
159
- return TraceSpaceTopology(self)
160
-
161
- @property
162
- def is_trace(self) -> bool:
163
- """Whether this topology is defined on the trace of the geometry"""
164
- return self.dimension == self.geometry.dimension - 1
165
-
166
- def full_space_topology(self) -> "SpaceTopology":
167
- """Returns the full space topology from which this topology is derived"""
168
- return self
169
-
170
- def __eq__(self, other: "SpaceTopology") -> bool:
171
- """Checks whether two topologies are compatible"""
172
- return self.geometry == other.geometry and self.name == other.name
173
-
174
- def is_derived_from(self, other: "SpaceTopology") -> bool:
175
- """Checks whether two topologies are equal, or `self` is the trace of `other`"""
176
- if self.dimension == other.dimension:
177
- return self == other
178
- if self.dimension + 1 == other.dimension:
179
- return self.full_space_topology() == other
180
- return False
181
-
182
- def _make_constant_element_node_count(self):
183
- NODES_PER_ELEMENT = wp.constant(self.MAX_NODES_PER_ELEMENT)
184
-
185
- @cache.dynamic_func(suffix=self.name)
186
- def constant_element_node_count(
187
- geo_arg: self.geometry.CellArg,
188
- topo_arg: self.TopologyArg,
189
- element_index: ElementIndex,
190
- ):
191
- return NODES_PER_ELEMENT
192
-
193
- return constant_element_node_count
194
-
195
- def _make_constant_side_neighbor_node_counts(self):
196
- NODES_PER_ELEMENT = wp.constant(self.MAX_NODES_PER_ELEMENT)
197
-
198
- @cache.dynamic_func(suffix=self.name)
199
- def constant_side_neighbor_node_counts(
200
- side_arg: self.geometry.SideArg,
201
- element_index: ElementIndex,
202
- ):
203
- return NODES_PER_ELEMENT, NODES_PER_ELEMENT
204
-
205
- return constant_side_neighbor_node_counts
206
-
207
- def _make_constant_element_node_sign(self):
208
- @cache.dynamic_func(suffix=self.name)
209
- def constant_element_node_sign(
210
- geo_arg: self.geometry.CellArg,
211
- topo_arg: self.TopologyArg,
212
- element_index: ElementIndex,
213
- node_index_in_element: int,
214
- ):
215
- return 1.0
216
-
217
- return constant_element_node_sign
218
-
219
-
220
- class TraceSpaceTopology(SpaceTopology):
221
- """Auto-generated trace topology defining the node indices associated to the geometry sides"""
222
-
223
- _dynamic_attribute_constructors: ClassVar = {
224
- "inner_cell_index": lambda obj: obj._make_inner_cell_index(),
225
- "outer_cell_index": lambda obj: obj._make_outer_cell_index(),
226
- "neighbor_cell_index": lambda obj: obj._make_neighbor_cell_index(),
227
- "element_node_index": lambda obj: obj._make_element_node_index(),
228
- "element_node_count": lambda obj: obj._make_element_node_count(),
229
- "element_node_sign": lambda obj: obj._make_element_node_sign(),
230
- }
231
-
232
- def __init__(self, topo: SpaceTopology):
233
- self._topo = topo
234
-
235
- super().__init__(topo.geometry, 2 * topo.MAX_NODES_PER_ELEMENT)
236
-
237
- self.dimension = topo.dimension - 1
238
- self.ElementArg = topo.geometry.SideArg
239
-
240
- self.TopologyArg = topo.TopologyArg
241
- self.topo_arg_value = topo.topo_arg_value
242
- self.fill_topo_arg = topo.fill_topo_arg
243
-
244
- self.side_neighbor_node_counts = None
245
- cache.setup_dynamic_attributes(self, cls=__class__)
246
-
247
- def node_count(self) -> int:
248
- return self._topo.node_count()
249
-
250
- @property
251
- def name(self):
252
- return f"{self._topo.name}_Trace"
253
-
254
- def _make_inner_cell_index(self):
255
- @cache.dynamic_func(suffix=self.name)
256
- def inner_cell_index(side_arg: self.geometry.SideArg, element_index: ElementIndex, node_index_in_elt: int):
257
- inner_count, outer_count = self._topo.side_neighbor_node_counts(side_arg, element_index)
258
- if node_index_in_elt >= inner_count:
259
- return NULL_ELEMENT_INDEX, NULL_NODE_INDEX
260
- return self.geometry.side_inner_cell_index(side_arg, element_index), node_index_in_elt
261
-
262
- return inner_cell_index
263
-
264
- def _make_outer_cell_index(self):
265
- @cache.dynamic_func(suffix=self.name)
266
- def outer_cell_index(side_arg: self.geometry.SideArg, element_index: ElementIndex, node_index_in_elt: int):
267
- inner_count, outer_count = self._topo.side_neighbor_node_counts(side_arg, element_index)
268
- if node_index_in_elt < inner_count:
269
- return NULL_ELEMENT_INDEX, NULL_NODE_INDEX
270
- return self.geometry.side_outer_cell_index(side_arg, element_index), node_index_in_elt - inner_count
271
-
272
- return outer_cell_index
273
-
274
- def _make_neighbor_cell_index(self):
275
- @cache.dynamic_func(suffix=self.name)
276
- def neighbor_cell_index(side_arg: self.geometry.SideArg, element_index: ElementIndex, node_index_in_elt: int):
277
- inner_count, outer_count = self._topo.side_neighbor_node_counts(side_arg, element_index)
278
- if node_index_in_elt < inner_count:
279
- return self.geometry.side_inner_cell_index(side_arg, element_index), node_index_in_elt
280
-
281
- return (
282
- self.geometry.side_outer_cell_index(side_arg, element_index),
283
- node_index_in_elt - inner_count,
284
- )
285
-
286
- return neighbor_cell_index
287
-
288
- def _make_element_node_count(self):
289
- @cache.dynamic_func(suffix=self.name)
290
- def trace_element_node_count(
291
- geo_side_arg: self.geometry.SideArg,
292
- topo_arg: self._topo.TopologyArg,
293
- element_index: ElementIndex,
294
- ):
295
- inner_count, outer_count = self._topo.side_neighbor_node_counts(geo_side_arg, element_index)
296
- return inner_count + outer_count
297
-
298
- return trace_element_node_count
299
-
300
- def _make_element_node_index(self):
301
- @cache.dynamic_func(suffix=self.name)
302
- def trace_element_node_index(
303
- geo_side_arg: self.geometry.SideArg,
304
- topo_arg: self._topo.TopologyArg,
305
- element_index: ElementIndex,
306
- node_index_in_elt: int,
307
- ):
308
- cell_index, index_in_cell = self.neighbor_cell_index(geo_side_arg, element_index, node_index_in_elt)
309
-
310
- geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
311
- return self._topo.element_node_index(geo_cell_arg, topo_arg, cell_index, index_in_cell)
312
-
313
- return trace_element_node_index
314
-
315
- def _make_element_node_sign(self):
316
- @cache.dynamic_func(suffix=self.name)
317
- def trace_element_node_sign(
318
- geo_side_arg: self.geometry.SideArg,
319
- topo_arg: self._topo.TopologyArg,
320
- element_index: ElementIndex,
321
- node_index_in_elt: int,
322
- ):
323
- cell_index, index_in_cell = self.neighbor_cell_index(geo_side_arg, element_index, node_index_in_elt)
324
-
325
- geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
326
- return self._topo.element_node_sign(geo_cell_arg, topo_arg, cell_index, index_in_cell)
327
-
328
- return trace_element_node_sign
329
-
330
- def full_space_topology(self) -> SpaceTopology:
331
- """Returns the full space topology from which this topology is derived"""
332
- return self._topo
333
-
334
- def __eq__(self, other: "TraceSpaceTopology") -> bool:
335
- return self._topo == other._topo
336
-
337
-
338
- class RegularDiscontinuousSpaceTopologyMixin:
339
- """Helper for defining discontinuous topologies (per-element nodes)"""
340
-
341
- def __init__(self, *args, **kwargs):
342
- super().__init__(*args, **kwargs)
343
- self.element_node_index = self._make_element_node_index()
344
-
345
- def node_count(self):
346
- return self.geometry.cell_count() * self.MAX_NODES_PER_ELEMENT
347
-
348
- @property
349
- def name(self):
350
- return f"{self.geometry.name}_D{self.MAX_NODES_PER_ELEMENT}"
351
-
352
- def _make_element_node_index(self):
353
- NODES_PER_ELEMENT = self.MAX_NODES_PER_ELEMENT
354
-
355
- @cache.dynamic_func(suffix=self.name)
356
- def element_node_index(
357
- elt_arg: self.geometry.CellArg,
358
- topo_arg: self.TopologyArg,
359
- element_index: ElementIndex,
360
- node_index_in_elt: int,
361
- ):
362
- return NODES_PER_ELEMENT * element_index + node_index_in_elt
363
-
364
- return element_node_index
365
-
366
-
367
- class RegularDiscontinuousSpaceTopology(RegularDiscontinuousSpaceTopologyMixin, SpaceTopology):
368
- """Topology for generic discontinuous spaces"""
369
-
370
- pass
371
-
372
-
373
- class DeformedGeometrySpaceTopology(SpaceTopology):
374
- _dynamic_attribute_constructors: ClassVar = {
375
- "element_node_index": lambda obj: obj._make_element_node_index(),
376
- "element_node_count": lambda obj: obj._make_element_node_count(),
377
- "element_node_sign": lambda obj: obj._make_element_node_sign(),
378
- "side_neighbor_node_counts": lambda obj: obj._make_side_neighbor_node_counts(),
379
- }
380
-
381
- def __init__(self, geometry: DeformedGeometry, base_topology: SpaceTopology):
382
- self.base = base_topology
383
- super().__init__(geometry, base_topology.MAX_NODES_PER_ELEMENT)
384
-
385
- self.node_count = self.base.node_count
386
- self.topo_arg_value = self.base.topo_arg_value
387
- self.fill_topo_arg = self.base.fill_topo_arg
388
- self.TopologyArg = self.base.TopologyArg
389
-
390
- cache.setup_dynamic_attributes(self, cls=__class__)
391
-
392
- @property
393
- def name(self):
394
- return f"{self.base.name}_{self.geometry.field.name}"
395
-
396
- def _make_element_node_index(self):
397
- @cache.dynamic_func(suffix=self.name)
398
- def element_node_index(
399
- elt_arg: self.geometry.CellArg,
400
- topo_arg: self.TopologyArg,
401
- element_index: ElementIndex,
402
- node_index_in_elt: int,
403
- ):
404
- return self.base.element_node_index(elt_arg.base_arg, topo_arg, element_index, node_index_in_elt)
405
-
406
- return element_node_index
407
-
408
- def _make_element_node_count(self):
409
- @cache.dynamic_func(suffix=self.name)
410
- def element_node_count(
411
- elt_arg: self.geometry.CellArg,
412
- topo_arg: self.TopologyArg,
413
- element_count: ElementIndex,
414
- ):
415
- return self.base.element_node_count(elt_arg.base_arg, topo_arg, element_count)
416
-
417
- return element_node_count
418
-
419
- def _make_side_neighbor_node_counts(self):
420
- @cache.dynamic_func(suffix=self.name)
421
- def side_neighbor_node_counts(
422
- side_arg: self.geometry.SideArg,
423
- element_index: ElementIndex,
424
- ):
425
- inner_count, outer_count = self.base.side_neighbor_node_counts(side_arg.base_arg, element_index)
426
- return inner_count, outer_count
427
-
428
- return side_neighbor_node_counts
429
-
430
- def _make_element_node_sign(self):
431
- @cache.dynamic_func(suffix=self.name)
432
- def element_node_sign(
433
- elt_arg: self.geometry.CellArg,
434
- topo_arg: self.TopologyArg,
435
- element_index: ElementIndex,
436
- node_index_in_elt: int,
437
- ):
438
- return self.base.element_node_sign(elt_arg.base_arg, topo_arg, element_index, node_index_in_elt)
439
-
440
- return element_node_sign
441
-
442
-
443
- def forward_base_topology(topology_class: Type[SpaceTopology], geometry: Geometry, *args, **kwargs) -> SpaceTopology:
444
- """
445
- If `geometry` is *not* a :class:`DeformedGeometry`, constructs a normal instance of `topology_class` over `geometry`, forwarding additional arguments.
446
-
447
- If `geometry` *is* a :class:`DeformedGeometry`, constructs an instance of `topology_class` over the base (undeformed) geometry of `geometry`, then warp it
448
- in a :class:`DeformedGeometrySpaceTopology` forwarding the calls to the underlying topology.
449
- """
450
-
451
- if isinstance(geometry, DeformedGeometry):
452
- base_topo = topology_class(geometry.base, *args, **kwargs)
453
- return DeformedGeometrySpaceTopology(geometry, base_topo)
454
-
455
- return topology_class(geometry, *args, **kwargs)
24
+ return get_deprecated_api(_topology, "wp.fem.space", name)