warp-lang 0.10.1__py3-none-win_amd64.whl → 0.11.0__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 (300) hide show
  1. warp/__init__.py +10 -4
  2. warp/__init__.pyi +1 -0
  3. warp/bin/warp-clang.dll +0 -0
  4. warp/bin/warp.dll +0 -0
  5. warp/build.py +5 -3
  6. warp/build_dll.py +29 -9
  7. warp/builtins.py +868 -507
  8. warp/codegen.py +1074 -638
  9. warp/config.py +3 -3
  10. warp/constants.py +6 -0
  11. warp/context.py +715 -222
  12. warp/fabric.py +326 -0
  13. warp/fem/__init__.py +27 -0
  14. warp/fem/cache.py +389 -0
  15. warp/fem/dirichlet.py +181 -0
  16. warp/fem/domain.py +263 -0
  17. warp/fem/field/__init__.py +101 -0
  18. warp/fem/field/field.py +149 -0
  19. warp/fem/field/nodal_field.py +299 -0
  20. warp/fem/field/restriction.py +21 -0
  21. warp/fem/field/test.py +181 -0
  22. warp/fem/field/trial.py +183 -0
  23. warp/fem/geometry/__init__.py +19 -0
  24. warp/fem/geometry/closest_point.py +70 -0
  25. warp/fem/geometry/deformed_geometry.py +271 -0
  26. warp/fem/geometry/element.py +744 -0
  27. warp/fem/geometry/geometry.py +186 -0
  28. warp/fem/geometry/grid_2d.py +373 -0
  29. warp/fem/geometry/grid_3d.py +435 -0
  30. warp/fem/geometry/hexmesh.py +953 -0
  31. warp/fem/geometry/partition.py +376 -0
  32. warp/fem/geometry/quadmesh_2d.py +532 -0
  33. warp/fem/geometry/tetmesh.py +840 -0
  34. warp/fem/geometry/trimesh_2d.py +577 -0
  35. warp/fem/integrate.py +1616 -0
  36. warp/fem/operator.py +191 -0
  37. warp/fem/polynomial.py +213 -0
  38. warp/fem/quadrature/__init__.py +2 -0
  39. warp/fem/quadrature/pic_quadrature.py +245 -0
  40. warp/fem/quadrature/quadrature.py +294 -0
  41. warp/fem/space/__init__.py +292 -0
  42. warp/fem/space/basis_space.py +489 -0
  43. warp/fem/space/collocated_function_space.py +105 -0
  44. warp/fem/space/dof_mapper.py +236 -0
  45. warp/fem/space/function_space.py +145 -0
  46. warp/fem/space/grid_2d_function_space.py +267 -0
  47. warp/fem/space/grid_3d_function_space.py +306 -0
  48. warp/fem/space/hexmesh_function_space.py +352 -0
  49. warp/fem/space/partition.py +350 -0
  50. warp/fem/space/quadmesh_2d_function_space.py +369 -0
  51. warp/fem/space/restriction.py +160 -0
  52. warp/fem/space/shape/__init__.py +15 -0
  53. warp/fem/space/shape/cube_shape_function.py +738 -0
  54. warp/fem/space/shape/shape_function.py +103 -0
  55. warp/fem/space/shape/square_shape_function.py +611 -0
  56. warp/fem/space/shape/tet_shape_function.py +567 -0
  57. warp/fem/space/shape/triangle_shape_function.py +429 -0
  58. warp/fem/space/tetmesh_function_space.py +292 -0
  59. warp/fem/space/topology.py +295 -0
  60. warp/fem/space/trimesh_2d_function_space.py +221 -0
  61. warp/fem/types.py +77 -0
  62. warp/fem/utils.py +495 -0
  63. warp/native/array.h +147 -44
  64. warp/native/builtin.h +122 -149
  65. warp/native/bvh.cpp +73 -325
  66. warp/native/bvh.cu +406 -23
  67. warp/native/bvh.h +34 -43
  68. warp/native/clang/clang.cpp +13 -8
  69. warp/native/crt.h +2 -0
  70. warp/native/cuda_crt.h +5 -0
  71. warp/native/cuda_util.cpp +15 -3
  72. warp/native/cuda_util.h +3 -1
  73. warp/native/cutlass/tools/library/scripts/conv2d_operation.py +463 -0
  74. warp/native/cutlass/tools/library/scripts/conv3d_operation.py +321 -0
  75. warp/native/cutlass/tools/library/scripts/gemm_operation.py +988 -0
  76. warp/native/cutlass/tools/library/scripts/generator.py +4625 -0
  77. warp/native/cutlass/tools/library/scripts/library.py +799 -0
  78. warp/native/cutlass/tools/library/scripts/manifest.py +402 -0
  79. warp/native/cutlass/tools/library/scripts/pycutlass/docs/source/conf.py +96 -0
  80. warp/native/cutlass/tools/library/scripts/pycutlass/profile/conv/conv2d_f16_sm80.py +106 -0
  81. warp/native/cutlass/tools/library/scripts/pycutlass/profile/gemm/gemm_f32_sm80.py +91 -0
  82. warp/native/cutlass/tools/library/scripts/pycutlass/setup.py +80 -0
  83. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/__init__.py +48 -0
  84. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/arguments.py +118 -0
  85. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/c_types.py +241 -0
  86. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/compiler.py +432 -0
  87. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/conv2d_operation.py +631 -0
  88. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/epilogue.py +1026 -0
  89. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/frontend.py +104 -0
  90. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/gemm_operation.py +1276 -0
  91. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/library.py +744 -0
  92. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/memory_manager.py +74 -0
  93. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/operation.py +110 -0
  94. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/parser.py +619 -0
  95. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/reduction_operation.py +398 -0
  96. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/tensor_ref.py +70 -0
  97. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/__init__.py +4 -0
  98. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/conv2d_testbed.py +646 -0
  99. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_grouped_testbed.py +235 -0
  100. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_testbed.py +557 -0
  101. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/profiler.py +70 -0
  102. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/type_hint.py +39 -0
  103. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/__init__.py +1 -0
  104. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/device.py +76 -0
  105. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/reference_model.py +255 -0
  106. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/__init__.py +0 -0
  107. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +201 -0
  108. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +177 -0
  109. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +98 -0
  110. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +95 -0
  111. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +163 -0
  112. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +187 -0
  113. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +309 -0
  114. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +54 -0
  115. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  116. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  117. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +253 -0
  118. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +97 -0
  119. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +242 -0
  120. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  121. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  122. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/run_all_tests.py +10 -0
  123. warp/native/cutlass/tools/library/scripts/pycutlass/test/frontend/test_frontend.py +146 -0
  124. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/__init__.py +0 -0
  125. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_bf16_sm80.py +96 -0
  126. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f16_sm80.py +447 -0
  127. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f32_sm80.py +146 -0
  128. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f64_sm80.py +102 -0
  129. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_grouped_sm80.py +203 -0
  130. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_s8_sm80.py +229 -0
  131. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/run_all_tests.py +9 -0
  132. warp/native/cutlass/tools/library/scripts/pycutlass/test/unit/test_sm80.py +453 -0
  133. warp/native/cutlass/tools/library/scripts/rank_2k_operation.py +398 -0
  134. warp/native/cutlass/tools/library/scripts/rank_k_operation.py +387 -0
  135. warp/native/cutlass/tools/library/scripts/rt.py +796 -0
  136. warp/native/cutlass/tools/library/scripts/symm_operation.py +400 -0
  137. warp/native/cutlass/tools/library/scripts/trmm_operation.py +407 -0
  138. warp/native/cutlass_gemm.cu +5 -3
  139. warp/native/exports.h +1240 -952
  140. warp/native/fabric.h +228 -0
  141. warp/native/hashgrid.cpp +4 -4
  142. warp/native/hashgrid.h +22 -2
  143. warp/native/intersect.h +22 -7
  144. warp/native/intersect_adj.h +8 -8
  145. warp/native/intersect_tri.h +1 -1
  146. warp/native/marching.cu +157 -161
  147. warp/native/mat.h +80 -19
  148. warp/native/matnn.h +2 -2
  149. warp/native/mesh.cpp +33 -108
  150. warp/native/mesh.cu +114 -23
  151. warp/native/mesh.h +446 -46
  152. warp/native/noise.h +272 -329
  153. warp/native/quat.h +51 -8
  154. warp/native/rand.h +45 -35
  155. warp/native/range.h +6 -2
  156. warp/native/reduce.cpp +1 -1
  157. warp/native/reduce.cu +10 -12
  158. warp/native/runlength_encode.cu +6 -10
  159. warp/native/scan.cu +8 -11
  160. warp/native/sparse.cpp +4 -4
  161. warp/native/sparse.cu +164 -154
  162. warp/native/spatial.h +2 -2
  163. warp/native/temp_buffer.h +14 -30
  164. warp/native/vec.h +107 -23
  165. warp/native/volume.h +120 -0
  166. warp/native/warp.cpp +560 -30
  167. warp/native/warp.cu +431 -44
  168. warp/native/warp.h +13 -4
  169. warp/optim/__init__.py +1 -0
  170. warp/optim/linear.py +922 -0
  171. warp/optim/sgd.py +92 -0
  172. warp/render/render_opengl.py +335 -119
  173. warp/render/render_usd.py +11 -11
  174. warp/sim/__init__.py +2 -2
  175. warp/sim/articulation.py +385 -185
  176. warp/sim/collide.py +8 -0
  177. warp/sim/import_mjcf.py +297 -106
  178. warp/sim/import_urdf.py +389 -210
  179. warp/sim/import_usd.py +198 -97
  180. warp/sim/inertia.py +17 -18
  181. warp/sim/integrator_euler.py +14 -8
  182. warp/sim/integrator_xpbd.py +158 -16
  183. warp/sim/model.py +795 -291
  184. warp/sim/render.py +3 -3
  185. warp/sim/utils.py +3 -0
  186. warp/sparse.py +640 -150
  187. warp/stubs.py +606 -267
  188. warp/tape.py +61 -10
  189. warp/tests/__main__.py +3 -6
  190. warp/tests/assets/curlnoise_golden.npy +0 -0
  191. warp/tests/assets/pnoise_golden.npy +0 -0
  192. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  193. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  194. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  195. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  196. warp/tests/aux_test_unresolved_func.py +14 -0
  197. warp/tests/aux_test_unresolved_symbol.py +14 -0
  198. warp/tests/disabled_kinematics.py +239 -0
  199. warp/tests/run_coverage_serial.py +31 -0
  200. warp/tests/test_adam.py +103 -106
  201. warp/tests/test_arithmetic.py +128 -74
  202. warp/tests/test_array.py +212 -97
  203. warp/tests/test_array_reduce.py +57 -23
  204. warp/tests/test_atomic.py +64 -28
  205. warp/tests/test_bool.py +99 -0
  206. warp/tests/test_builtins_resolution.py +1292 -0
  207. warp/tests/test_bvh.py +42 -18
  208. warp/tests/test_closest_point_edge_edge.py +54 -57
  209. warp/tests/test_codegen.py +208 -130
  210. warp/tests/test_compile_consts.py +28 -20
  211. warp/tests/test_conditional.py +108 -24
  212. warp/tests/test_copy.py +10 -12
  213. warp/tests/test_ctypes.py +112 -88
  214. warp/tests/test_dense.py +21 -14
  215. warp/tests/test_devices.py +98 -0
  216. warp/tests/test_dlpack.py +75 -75
  217. warp/tests/test_examples.py +277 -0
  218. warp/tests/test_fabricarray.py +955 -0
  219. warp/tests/test_fast_math.py +15 -11
  220. warp/tests/test_fem.py +1271 -0
  221. warp/tests/test_fp16.py +53 -19
  222. warp/tests/test_func.py +187 -86
  223. warp/tests/test_generics.py +194 -49
  224. warp/tests/test_grad.py +178 -109
  225. warp/tests/test_grad_customs.py +176 -0
  226. warp/tests/test_hash_grid.py +52 -37
  227. warp/tests/test_import.py +10 -23
  228. warp/tests/test_indexedarray.py +32 -31
  229. warp/tests/test_intersect.py +18 -9
  230. warp/tests/test_large.py +141 -0
  231. warp/tests/test_launch.py +14 -41
  232. warp/tests/test_lerp.py +64 -65
  233. warp/tests/test_linear_solvers.py +154 -0
  234. warp/tests/test_lvalue.py +493 -0
  235. warp/tests/test_marching_cubes.py +12 -13
  236. warp/tests/test_mat.py +517 -2898
  237. warp/tests/test_mat_lite.py +115 -0
  238. warp/tests/test_mat_scalar_ops.py +2889 -0
  239. warp/tests/test_math.py +103 -9
  240. warp/tests/test_matmul.py +305 -69
  241. warp/tests/test_matmul_lite.py +410 -0
  242. warp/tests/test_mesh.py +71 -14
  243. warp/tests/test_mesh_query_aabb.py +41 -25
  244. warp/tests/test_mesh_query_point.py +140 -22
  245. warp/tests/test_mesh_query_ray.py +39 -22
  246. warp/tests/test_mlp.py +30 -22
  247. warp/tests/test_model.py +92 -89
  248. warp/tests/test_modules_lite.py +39 -0
  249. warp/tests/test_multigpu.py +88 -114
  250. warp/tests/test_noise.py +12 -11
  251. warp/tests/test_operators.py +16 -20
  252. warp/tests/test_options.py +11 -11
  253. warp/tests/test_pinned.py +17 -18
  254. warp/tests/test_print.py +32 -11
  255. warp/tests/test_quat.py +275 -129
  256. warp/tests/test_rand.py +18 -16
  257. warp/tests/test_reload.py +38 -34
  258. warp/tests/test_rounding.py +50 -43
  259. warp/tests/test_runlength_encode.py +168 -20
  260. warp/tests/test_smoothstep.py +9 -11
  261. warp/tests/test_snippet.py +143 -0
  262. warp/tests/test_sparse.py +261 -63
  263. warp/tests/test_spatial.py +276 -243
  264. warp/tests/test_streams.py +110 -85
  265. warp/tests/test_struct.py +268 -63
  266. warp/tests/test_tape.py +39 -21
  267. warp/tests/test_torch.py +118 -89
  268. warp/tests/test_transient_module.py +12 -13
  269. warp/tests/test_types.py +614 -0
  270. warp/tests/test_utils.py +494 -0
  271. warp/tests/test_vec.py +354 -2050
  272. warp/tests/test_vec_lite.py +73 -0
  273. warp/tests/test_vec_scalar_ops.py +2099 -0
  274. warp/tests/test_volume.py +457 -293
  275. warp/tests/test_volume_write.py +124 -134
  276. warp/tests/unittest_serial.py +35 -0
  277. warp/tests/unittest_suites.py +341 -0
  278. warp/tests/unittest_utils.py +568 -0
  279. warp/tests/unused_test_misc.py +71 -0
  280. warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
  281. warp/thirdparty/appdirs.py +36 -45
  282. warp/thirdparty/unittest_parallel.py +549 -0
  283. warp/torch.py +9 -6
  284. warp/types.py +1089 -366
  285. warp/utils.py +93 -387
  286. warp_lang-0.11.0.dist-info/METADATA +238 -0
  287. warp_lang-0.11.0.dist-info/RECORD +332 -0
  288. {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/WHEEL +1 -1
  289. warp/tests/test_all.py +0 -219
  290. warp/tests/test_array_scan.py +0 -60
  291. warp/tests/test_base.py +0 -208
  292. warp/tests/test_unresolved_func.py +0 -7
  293. warp/tests/test_unresolved_symbol.py +0 -7
  294. warp_lang-0.10.1.dist-info/METADATA +0 -21
  295. warp_lang-0.10.1.dist-info/RECORD +0 -188
  296. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  297. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  298. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  299. {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/LICENSE.md +0 -0
  300. {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,236 @@
1
+ from typing import Any
2
+ from enum import Enum
3
+ import math
4
+
5
+ import warp as wp
6
+ import warp.types
7
+
8
+ vec6 = wp.types.vector(length=6, dtype=wp.float32)
9
+
10
+ _SQRT_2 = wp.constant(math.sqrt(2.0))
11
+ _SQRT_3 = wp.constant(math.sqrt(3.0))
12
+ _SQRT_1_2 = wp.constant(math.sqrt(1.0 / 2.0))
13
+ _SQRT_1_3 = wp.constant(math.sqrt(1.0 / 3.0))
14
+
15
+
16
+ class DofMapper:
17
+ """Base class from mapping node degrees of freedom to function values"""
18
+
19
+ value_dtype: type
20
+ dof_dtype: type
21
+ DOF_SIZE: int
22
+
23
+ @wp.func
24
+ def dof_to_value(dof: Any):
25
+ raise NotImplementedError
26
+
27
+ @wp.func
28
+ def value_to_dof(val: Any):
29
+ raise NotImplementedError
30
+
31
+ def __str__(self):
32
+ return f"{self.value_dtype.__name__}_{self.DOF_SIZE}"
33
+
34
+
35
+ class IdentityMapper(DofMapper):
36
+ """Identity mapper"""
37
+
38
+ def __init__(self, dtype: type):
39
+ if dtype == float:
40
+ dtype = wp.float32
41
+
42
+ self.value_dtype = dtype
43
+ self.dof_dtype = dtype
44
+
45
+ size = warp.types.type_length(dtype)
46
+ self.DOF_SIZE = wp.constant(size)
47
+
48
+ @wp.func
49
+ def dof_to_value(dof: Any):
50
+ return dof
51
+
52
+ @wp.func
53
+ def value_to_dof(val: Any):
54
+ return val
55
+
56
+
57
+ class SymmetricTensorMapper(DofMapper):
58
+ """Orthonormal isomorphism from R^{n (n+1)} to nxn symmetric tensors,
59
+ using usual L2 norm for vectors and half Frobenius norm, (tau : tau)/2 for tensors.
60
+ """
61
+
62
+ class Mapping(Enum):
63
+ VOIGT = 0
64
+ """Voigt ordering of vector coefficients:
65
+ first the three diagonal terms, then off-diagonal coefficients"""
66
+ DB16 = 1
67
+ """Ordering that also separates normal from tangential coefficients:
68
+ first trace, then other diagonal terms, then off-diagonal coefficients.
69
+ See [Daviet and Bertails-Descoubes 2016]"""
70
+
71
+ def __init__(self, dtype: type, mapping: Mapping = Mapping.VOIGT):
72
+ self.value_dtype = dtype
73
+ self.mapping = mapping
74
+
75
+ if dtype == wp.mat22:
76
+ self.dof_dtype = wp.vec3
77
+ self.DOF_SIZE = wp.constant(3)
78
+ if mapping == SymmetricTensorMapper.Mapping.VOIGT:
79
+ self.dof_to_value = SymmetricTensorMapper.dof_to_value_2d_voigt
80
+ self.value_to_dof = SymmetricTensorMapper.value_to_dof_2d_voigt
81
+ else:
82
+ self.dof_to_value = SymmetricTensorMapper.dof_to_value_2d
83
+ self.value_to_dof = SymmetricTensorMapper.value_to_dof_2d
84
+ elif dtype == wp.mat33:
85
+ self.dof_dtype = vec6
86
+ self.DOF_SIZE = wp.constant(6)
87
+ if mapping == SymmetricTensorMapper.Mapping.VOIGT:
88
+ self.dof_to_value = SymmetricTensorMapper.dof_to_value_3d_voigt
89
+ self.value_to_dof = SymmetricTensorMapper.value_to_dof_3d_voigt
90
+ else:
91
+ self.dof_to_value = SymmetricTensorMapper.dof_to_value_3d
92
+ self.value_to_dof = SymmetricTensorMapper.value_to_dof_3d
93
+ else:
94
+ raise ValueError("Unsupported value dtype: ", dtype)
95
+
96
+ def __str__(self):
97
+ return f"{self.mapping}_{self.DOF_SIZE}"
98
+
99
+ @wp.func
100
+ def dof_to_value_2d(dof: wp.vec3):
101
+ a = dof[0]
102
+ b = dof[1]
103
+ c = dof[2]
104
+ return wp.mat22(a + b, c, c, a - b)
105
+
106
+ @wp.func
107
+ def value_to_dof_2d(val: wp.mat22):
108
+ a = 0.5 * (val[0, 0] + val[1, 1])
109
+ b = 0.5 * (val[0, 0] - val[1, 1])
110
+ c = 0.5 * (val[0, 1] + val[1, 0])
111
+ return wp.vec3(a, b, c)
112
+
113
+ @wp.func
114
+ def dof_to_value_2d_voigt(dof: wp.vec3):
115
+ a = _SQRT_2 * dof[0]
116
+ b = _SQRT_2 * dof[1]
117
+ c = dof[2]
118
+ return wp.mat22(a, c, c, b)
119
+
120
+ @wp.func
121
+ def value_to_dof_2d_voigt(val: wp.mat22):
122
+ a = _SQRT_1_2 * val[0, 0]
123
+ b = _SQRT_1_2 * val[1, 1]
124
+ c = 0.5 * (val[0, 1] + val[1, 0])
125
+ return wp.vec3(a, b, c)
126
+
127
+ @wp.func
128
+ def dof_to_value_3d(dof: vec6):
129
+ a = dof[0] * _SQRT_2 * _SQRT_1_3
130
+ b = dof[1]
131
+ c = dof[2] * _SQRT_1_3
132
+ d = dof[3]
133
+ e = dof[4]
134
+ f = dof[5]
135
+ return wp.mat33(
136
+ a + b - c,
137
+ f,
138
+ e,
139
+ f,
140
+ a - b - c,
141
+ d,
142
+ e,
143
+ d,
144
+ a + 2.0 * c,
145
+ )
146
+
147
+ @wp.func
148
+ def value_to_dof_3d(val: wp.mat33):
149
+ a = (val[0, 0] + val[1, 1] + val[2, 2]) * _SQRT_1_3 * _SQRT_1_2
150
+ b = 0.5 * (val[0, 0] - val[1, 1])
151
+ c = 0.5 * (val[2, 2] - (val[0, 0] + val[1, 1] + val[2, 2]) / 3.0) * _SQRT_3
152
+
153
+ d = 0.5 * (val[2, 1] + val[1, 2])
154
+ e = 0.5 * (val[0, 2] + val[2, 0])
155
+ f = 0.5 * (val[1, 0] + val[0, 1])
156
+
157
+ return vec6(a, b, c, d, e, f)
158
+
159
+ @wp.func
160
+ def dof_to_value_3d_voigt(dof: vec6):
161
+ a = _SQRT_2 * dof[0]
162
+ b = _SQRT_2 * dof[1]
163
+ c = _SQRT_2 * dof[2]
164
+ d = dof[3]
165
+ e = dof[4]
166
+ f = dof[5]
167
+ return wp.mat33(
168
+ a,
169
+ f,
170
+ e,
171
+ f,
172
+ b,
173
+ d,
174
+ e,
175
+ d,
176
+ c,
177
+ )
178
+
179
+ @wp.func
180
+ def value_to_dof_3d_voigt(val: wp.mat33):
181
+ a = _SQRT_1_2 * val[0, 0]
182
+ b = _SQRT_1_2 * val[1, 1]
183
+ c = _SQRT_1_2 * val[2, 2]
184
+
185
+ d = 0.5 * (val[2, 1] + val[1, 2])
186
+ e = 0.5 * (val[0, 2] + val[2, 0])
187
+ f = 0.5 * (val[1, 0] + val[0, 1])
188
+
189
+ return vec6(a, b, c, d, e, f)
190
+
191
+
192
+ class SkewSymmetricTensorMapper(DofMapper):
193
+ """Orthonormal isomorphism from R^{n (n-1)} to nxn skew-symmetric tensors,
194
+ using usual L2 norm for vectors and half Frobenius norm, (tau : tau)/2 for tensors.
195
+ """
196
+
197
+ def __init__(self, dtype: type):
198
+ self.value_dtype = dtype
199
+
200
+ if dtype == wp.mat22:
201
+ self.dof_dtype = float
202
+ self.DOF_SIZE = wp.constant(1)
203
+ self.dof_to_value = SkewSymmetricTensorMapper.dof_to_value_2d
204
+ self.value_to_dof = SkewSymmetricTensorMapper.value_to_dof_2d
205
+ elif dtype == wp.mat33:
206
+ self.dof_dtype = wp.vec3
207
+ self.DOF_SIZE = wp.constant(3)
208
+ self.dof_to_value = SkewSymmetricTensorMapper.dof_to_value_3d
209
+ self.value_to_dof = SkewSymmetricTensorMapper.value_to_dof_3d
210
+ else:
211
+ raise ValueError("Unsupported value dtype: ", dtype)
212
+
213
+ def __str__(self):
214
+ return f"{self.__class__.__name__}_{self.DOF_SIZE}"
215
+
216
+ @wp.func
217
+ def dof_to_value_2d(dof: float):
218
+ return wp.mat22(0.0, -dof, dof, 0.0)
219
+
220
+ @wp.func
221
+ def value_to_dof_2d(val: wp.mat22):
222
+ return 0.5 * (val[1, 0] - val[0, 1])
223
+
224
+ @wp.func
225
+ def dof_to_value_3d(dof: wp.vec3):
226
+ a = dof[0]
227
+ b = dof[1]
228
+ c = dof[2]
229
+ return wp.mat33(0.0, -c, b, c, 0.0, -a, -b, a, 0.0)
230
+
231
+ @wp.func
232
+ def value_to_dof_3d(val: wp.mat33):
233
+ a = 0.5 * (val[2, 1] - val[1, 2])
234
+ b = 0.5 * (val[0, 2] - val[2, 0])
235
+ c = 0.5 * (val[1, 0] - val[0, 1])
236
+ return wp.vec3(a, b, c)
@@ -0,0 +1,145 @@
1
+ from typing import Any
2
+
3
+ import warp as wp
4
+
5
+ from warp.fem.types import DofIndex, ElementIndex, Coords
6
+ from warp.fem.geometry import Geometry
7
+
8
+ from .topology import SpaceTopology
9
+
10
+
11
+ class FunctionSpace:
12
+ """
13
+ Interface class for function spaces, i.e. geometry + interpolation basis
14
+ """
15
+
16
+ dtype: type
17
+ """Value type of the interpolation functions"""
18
+
19
+ SpaceArg: wp.codegen.Struct
20
+ """Structure containing arguments to be passed to device function"""
21
+
22
+ VALUE_DOF_COUNT: int
23
+ """Number of degrees of freedom per node, as a Warp constant"""
24
+
25
+ def __init__(self, topology: SpaceTopology):
26
+ self._topology = topology
27
+
28
+ if self._topology.is_trace:
29
+ self.element_inner_reference_gradient_transform = self.geometry.side_inner_inverse_deformation_gradient
30
+ self.element_outer_reference_gradient_transform = self.geometry.side_outer_inverse_deformation_gradient
31
+ else:
32
+ self.element_inner_reference_gradient_transform = self.geometry.cell_inverse_deformation_gradient
33
+ self.element_outer_reference_gradient_transform = self.geometry.cell_inverse_deformation_gradient
34
+
35
+ def node_count(self) -> int:
36
+ """Number of nodes in the interpolation basis"""
37
+ raise NotImplementedError
38
+
39
+ def space_arg_value(self, device) -> wp.codegen.StructInstance:
40
+ """Value of the arguments to be passed to device functions"""
41
+ raise NotImplementedError
42
+
43
+ @property
44
+ def topology(self) -> SpaceTopology:
45
+ """Underlying geometry"""
46
+ return self._topology
47
+
48
+ @property
49
+ def geometry(self) -> Geometry:
50
+ """Underlying geometry"""
51
+ return self.topology.geometry
52
+
53
+ @property
54
+ def dimension(self) -> int:
55
+ """Function space embedding dimension"""
56
+ return self.topology.dimension
57
+
58
+ @property
59
+ def degree(self) -> int:
60
+ """Maximum polynomial degree of the underlying basis"""
61
+ raise NotImplementedError
62
+
63
+ @property
64
+ def name(self):
65
+ raise NotImplementedError
66
+
67
+ def __str__(self):
68
+ return self.name
69
+
70
+ def trace(self) -> "FunctionSpace":
71
+ """Trace of the function space over lower-dimensional elements of the geometry"""
72
+ raise NotImplementedError
73
+
74
+ def make_field(self, space_partition=None):
75
+ """Creates a zero-initialized discrete field over the function space holding values for all degrees of freedom of nodes in a space partition
76
+
77
+ space_arg:
78
+ space_partition: If provided, the subset of nodes to consider
79
+
80
+ See also: :func:`make_space_partition`
81
+ """
82
+ raise NotImplementedError
83
+
84
+ @staticmethod
85
+ def unit_dof_value(elt_arg: "SpaceTopology.ElementArg", space_arg: "SpaceArg", dof: DofIndex):
86
+ """Unit value for a given degree of freedom. Typically a rank-1 tensor"""
87
+ raise NotImplementedError
88
+
89
+ @staticmethod
90
+ def node_coords_in_element(
91
+ elt_arg: "SpaceTopology.ElementArg", space_arg: "SpaceArg", element_index: ElementIndex, node_index_in_elt: int
92
+ ):
93
+ """Coordinates inside element of a given node"""
94
+ raise NotImplementedError
95
+
96
+ @staticmethod
97
+ def node_quadrature_weight(
98
+ elt_arg: "SpaceTopology.ElementArg", space_arg: "SpaceArg", element_index: ElementIndex, node_index_in_elt: int
99
+ ):
100
+ """Weight of a given node when used as a quadrature point"""
101
+ raise NotImplementedError
102
+
103
+ @staticmethod
104
+ def element_inner_weight(
105
+ elt_arg: "SpaceTopology.ElementArg",
106
+ space_arg: "SpaceArg",
107
+ element_index: ElementIndex,
108
+ coords: Coords,
109
+ node_index_in_elt: int,
110
+ ):
111
+ """Inner weight for a node at given coordinates"""
112
+ raise NotImplementedError
113
+
114
+ @staticmethod
115
+ def element_inner_weight_gradient(
116
+ elt_arg: "SpaceTopology.ElementArg",
117
+ space_arg: "SpaceArg",
118
+ element_index: ElementIndex,
119
+ coords: Coords,
120
+ node_index_in_elt: int,
121
+ ):
122
+ """Inner weight gradient w.r.t. reference space for a node at given coordinates"""
123
+ raise NotImplementedError
124
+
125
+ @staticmethod
126
+ def element_outer_weight(
127
+ elt_arg: "SpaceTopology.ElementArg",
128
+ space_arg: "SpaceArg",
129
+ element_index: ElementIndex,
130
+ coords: Coords,
131
+ node_index_in_elt: int,
132
+ ):
133
+ """Outer weight for a node at given coordinates"""
134
+ raise NotImplementedError
135
+
136
+ @staticmethod
137
+ def element_outer_weight_gradient(
138
+ elt_arg: "SpaceTopology.ElementArg",
139
+ space_arg: "SpaceArg",
140
+ element_index: ElementIndex,
141
+ coords: Coords,
142
+ node_index_in_elt: int,
143
+ ):
144
+ """Outer weight gradient w.r.t reference space for a node at given coordinates"""
145
+ raise NotImplementedError
@@ -0,0 +1,267 @@
1
+ import warp as wp
2
+ import numpy as np
3
+
4
+ from warp.fem.types import ElementIndex, Coords
5
+ from warp.fem.polynomial import Polynomial, is_closed
6
+ from warp.fem.geometry import Grid2D
7
+ from warp.fem import cache
8
+
9
+ from .topology import SpaceTopology, DiscontinuousSpaceTopologyMixin, forward_base_topology
10
+ from .basis_space import ShapeBasisSpace, TraceBasisSpace
11
+
12
+ from .shape import ShapeFunction, ConstantShapeFunction
13
+ from .shape import (
14
+ SquareBipolynomialShapeFunctions,
15
+ SquareSerendipityShapeFunctions,
16
+ SquareNonConformingPolynomialShapeFunctions,
17
+ )
18
+
19
+
20
+ class Grid2DSpaceTopology(SpaceTopology):
21
+ def __init__(self, grid: Grid2D, shape: ShapeFunction):
22
+ super().__init__(grid, shape.NODES_PER_ELEMENT)
23
+ self._shape = shape
24
+
25
+ @wp.func
26
+ def _vertex_coords(vidx_in_cell: int):
27
+ x = vidx_in_cell // 2
28
+ y = vidx_in_cell - 2 * x
29
+ return wp.vec2i(x, y)
30
+
31
+ @wp.func
32
+ def _vertex_index(cell_arg: Grid2D.CellArg, cell_index: ElementIndex, vidx_in_cell: int):
33
+ res = cell_arg.res
34
+ x_stride = res[1] + 1
35
+
36
+ corner = Grid2D.get_cell(res, cell_index) + Grid2DSpaceTopology._vertex_coords(vidx_in_cell)
37
+ return Grid2D._from_2d_index(x_stride, corner)
38
+
39
+
40
+ class Grid2DDiscontinuousSpaceTopology(
41
+ DiscontinuousSpaceTopologyMixin,
42
+ Grid2DSpaceTopology,
43
+ ):
44
+ pass
45
+
46
+
47
+ class Grid2DBasisSpace(ShapeBasisSpace):
48
+ def __init__(self, topology: Grid2DSpaceTopology, shape: ShapeFunction):
49
+ super().__init__(topology, shape)
50
+
51
+ self._grid: Grid2D = topology.geometry
52
+
53
+
54
+ class GridPiecewiseConstantBasis(Grid2DBasisSpace):
55
+ def __init__(self, grid: Grid2D):
56
+ shape = ConstantShapeFunction(grid.reference_cell(), space_dimension=2)
57
+ topology = Grid2DDiscontinuousSpaceTopology(grid, shape)
58
+ super().__init__(shape=shape, topology=topology)
59
+
60
+ if isinstance(grid, Grid2D):
61
+ self.node_grid = self._node_grid
62
+
63
+ def _node_grid(self):
64
+ res = self._grid.res
65
+
66
+ X = (np.arange(0, res[0], dtype=float) + 0.5) * self._grid.cell_size[0] + self._grid.origin[0]
67
+ Y = (np.arange(0, res[1], dtype=float) + 0.5) * self._grid.cell_size[1] + self._grid.origin[1]
68
+ return np.meshgrid(X, Y, indexing="ij")
69
+
70
+ class Trace(TraceBasisSpace):
71
+ @wp.func
72
+ def _node_coords_in_element(
73
+ side_arg: Grid2D.SideArg,
74
+ basis_arg: Grid2DBasisSpace.BasisArg,
75
+ element_index: ElementIndex,
76
+ node_index_in_element: int,
77
+ ):
78
+ return Coords(0.5, 0.0, 0.0)
79
+
80
+ def make_node_coords_in_element(self):
81
+ return self._node_coords_in_element
82
+
83
+ def trace(self):
84
+ return GridPiecewiseConstantBasis.Trace(self)
85
+
86
+
87
+ class GridBipolynomialSpaceTopology(Grid2DSpaceTopology):
88
+ def __init__(self, grid: Grid2D, shape: SquareBipolynomialShapeFunctions):
89
+ super().__init__(grid, shape)
90
+
91
+ self.element_node_index = self._make_element_node_index()
92
+
93
+ def node_count(self) -> int:
94
+ return (self.geometry.res[0] * self._shape.ORDER + 1) * (self.geometry.res[1] * self._shape.ORDER + 1)
95
+
96
+ def _make_element_node_index(self):
97
+ ORDER = self._shape.ORDER
98
+
99
+ @cache.dynamic_func(suffix=self.name)
100
+ def element_node_index(
101
+ cell_arg: Grid2D.CellArg,
102
+ topo_arg: Grid2DSpaceTopology.TopologyArg,
103
+ element_index: ElementIndex,
104
+ node_index_in_elt: int,
105
+ ):
106
+ res = cell_arg.res
107
+ cell = Grid2D.get_cell(res, element_index)
108
+
109
+ node_i = node_index_in_elt // (ORDER + 1)
110
+ node_j = node_index_in_elt - (ORDER + 1) * node_i
111
+
112
+ node_x = ORDER * cell[0] + node_i
113
+ node_y = ORDER * cell[1] + node_j
114
+
115
+ node_pitch = (res[1] * ORDER) + 1
116
+ node_index = node_pitch * node_x + node_y
117
+
118
+ return node_index
119
+
120
+ return element_node_index
121
+
122
+
123
+ class GridBipolynomialBasisSpace(Grid2DBasisSpace):
124
+ def __init__(
125
+ self,
126
+ grid: Grid2D,
127
+ degree: int,
128
+ family: Polynomial,
129
+ ):
130
+ if family is None:
131
+ family = Polynomial.LOBATTO_GAUSS_LEGENDRE
132
+
133
+ if not is_closed(family):
134
+ raise ValueError("A closed polynomial family is required to define a continuous function space")
135
+
136
+ shape = SquareBipolynomialShapeFunctions(degree, family=family)
137
+ topology = forward_base_topology(GridBipolynomialSpaceTopology, grid, shape)
138
+
139
+ super().__init__(topology, shape)
140
+
141
+ if isinstance(grid, Grid2D):
142
+ self.node_grid = self._node_grid
143
+
144
+ def _node_grid(self):
145
+ res = self._grid.res
146
+
147
+ cell_coords = np.array(self._shape.LOBATTO_COORDS)[:-1]
148
+
149
+ grid_coords_x = np.repeat(np.arange(0, res[0], dtype=float), len(cell_coords)) + np.tile(
150
+ cell_coords, reps=res[0]
151
+ )
152
+ grid_coords_x = np.append(grid_coords_x, res[0])
153
+ X = grid_coords_x * self._grid.cell_size[0] + self._grid.origin[0]
154
+
155
+ grid_coords_y = np.repeat(np.arange(0, res[1], dtype=float), len(cell_coords)) + np.tile(
156
+ cell_coords, reps=res[1]
157
+ )
158
+ grid_coords_y = np.append(grid_coords_y, res[1])
159
+ Y = grid_coords_y * self._grid.cell_size[1] + self._grid.origin[1]
160
+
161
+ return np.meshgrid(X, Y, indexing="ij")
162
+
163
+
164
+ class GridDGBipolynomialBasisSpace(Grid2DBasisSpace):
165
+ def __init__(
166
+ self,
167
+ grid: Grid2D,
168
+ degree: int,
169
+ family: Polynomial,
170
+ ):
171
+ if family is None:
172
+ family = Polynomial.LOBATTO_GAUSS_LEGENDRE
173
+
174
+ shape = SquareBipolynomialShapeFunctions(degree, family=family)
175
+ topology = Grid2DDiscontinuousSpaceTopology(grid, shape)
176
+
177
+ super().__init__(shape=shape, topology=topology)
178
+
179
+
180
+ class GridSerendipitySpaceTopology(Grid2DSpaceTopology):
181
+ def __init__(self, grid: Grid2D, shape: SquareSerendipityShapeFunctions):
182
+ super().__init__(grid, shape)
183
+
184
+ self.element_node_index = self._make_element_node_index()
185
+
186
+ TopologyArg = Grid2D.SideArg
187
+
188
+ def topo_arg_value(self, device):
189
+ return self.geometry.side_arg_value(device)
190
+
191
+ def node_count(self) -> int:
192
+ return self.geometry.vertex_count() + (self._shape.ORDER - 1) * self.geometry.side_count()
193
+
194
+ def _make_element_node_index(self):
195
+ ORDER = self._shape.ORDER
196
+
197
+ @cache.dynamic_func(suffix=self.name)
198
+ def element_node_index(
199
+ cell_arg: Grid2D.CellArg,
200
+ topo_arg: Grid2D.SideArg,
201
+ element_index: ElementIndex,
202
+ node_index_in_elt: int,
203
+ ):
204
+ node_type, type_index = self._shape.node_type_and_type_index(node_index_in_elt)
205
+
206
+ if node_type == SquareSerendipityShapeFunctions.VERTEX:
207
+ return Grid2DSpaceTopology._vertex_index(cell_arg, element_index, type_index)
208
+
209
+ side_offset, index_in_side = SquareSerendipityShapeFunctions.side_offset_and_index(type_index)
210
+ axis = 1 - (node_type - SquareSerendipityShapeFunctions.EDGE_X)
211
+
212
+ cell = Grid2D.get_cell(cell_arg.res, element_index)
213
+ origin = wp.vec2i(cell[Grid2D.ROTATION[axis, 0]] + side_offset, cell[Grid2D.ROTATION[axis, 1]])
214
+
215
+ side = Grid2D.Side(axis, origin)
216
+ side_index = Grid2D.side_index(topo_arg, side)
217
+
218
+ res = cell_arg.res
219
+ vertex_count = (res[0] + 1) * (res[1] + 1)
220
+
221
+ return vertex_count + (ORDER - 1) * side_index + index_in_side
222
+
223
+ return element_node_index
224
+
225
+
226
+ class GridSerendipityBasisSpace(Grid2DBasisSpace):
227
+ def __init__(
228
+ self,
229
+ grid: Grid2D,
230
+ degree: int,
231
+ family: Polynomial,
232
+ ):
233
+ if family is None:
234
+ family = Polynomial.LOBATTO_GAUSS_LEGENDRE
235
+
236
+ shape = SquareSerendipityShapeFunctions(degree, family=family)
237
+ topology = forward_base_topology(GridSerendipitySpaceTopology, grid, shape=shape)
238
+
239
+ super().__init__(topology=topology, shape=shape)
240
+
241
+
242
+ class GridDGSerendipityBasisSpace(Grid2DBasisSpace):
243
+ def __init__(
244
+ self,
245
+ grid: Grid2D,
246
+ degree: int,
247
+ family: Polynomial,
248
+ ):
249
+ if family is None:
250
+ family = Polynomial.LOBATTO_GAUSS_LEGENDRE
251
+
252
+ shape = SquareSerendipityShapeFunctions(degree, family=family)
253
+ topology = Grid2DDiscontinuousSpaceTopology(grid, shape=shape)
254
+
255
+ super().__init__(topology=topology, shape=shape)
256
+
257
+
258
+ class GridDGPolynomialBasisSpace(Grid2DBasisSpace):
259
+ def __init__(
260
+ self,
261
+ grid: Grid2D,
262
+ degree: int,
263
+ ):
264
+ shape = SquareNonConformingPolynomialShapeFunctions(degree)
265
+ topology = Grid2DDiscontinuousSpaceTopology(grid, shape=shape)
266
+
267
+ super().__init__(topology=topology, shape=shape)