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,429 @@
1
+ import warp as wp
2
+ import numpy as np
3
+
4
+ from warp.fem.types import Coords
5
+ from warp.fem import cache
6
+
7
+
8
+ def _triangle_node_index(tx: int, ty: int, degree: int):
9
+ VERTEX_NODE_COUNT = 3
10
+ SIDE_INTERIOR_NODE_COUNT = degree - 1
11
+
12
+ # Index in similar order to e.g. VTK
13
+ # First vertices, then edge (counterclokwise) then interior points (recursively)
14
+
15
+ if tx == 0:
16
+ if ty == 0:
17
+ return 0
18
+ elif ty == degree:
19
+ return 2
20
+ else:
21
+ edge_index = 2
22
+ return VERTEX_NODE_COUNT + SIDE_INTERIOR_NODE_COUNT * edge_index + (SIDE_INTERIOR_NODE_COUNT - ty)
23
+ elif ty == 0:
24
+ if tx == degree:
25
+ return 1
26
+ else:
27
+ edge_index = 0
28
+ return VERTEX_NODE_COUNT + SIDE_INTERIOR_NODE_COUNT * edge_index + tx - 1
29
+ elif tx + ty == degree:
30
+ edge_index = 1
31
+ return VERTEX_NODE_COUNT + SIDE_INTERIOR_NODE_COUNT * edge_index + ty - 1
32
+
33
+ vertex_edge_node_count = 3 * degree
34
+ return vertex_edge_node_count + _triangle_node_index(tx - 1, ty - 1, degree - 3)
35
+
36
+
37
+ class Triangle2DPolynomialShapeFunctions:
38
+ VERTEX = wp.constant(0)
39
+ EDGE = wp.constant(1)
40
+ INTERIOR = wp.constant(2)
41
+
42
+ def __init__(self, degree: int):
43
+ self.ORDER = wp.constant(degree)
44
+
45
+ self.NODES_PER_ELEMENT = wp.constant((degree + 1) * (degree + 2) // 2)
46
+ self.NODES_PER_SIDE = wp.constant(degree + 1)
47
+
48
+ triangle_coords = np.empty((self.NODES_PER_ELEMENT, 2), dtype=int)
49
+
50
+ for tx in range(degree + 1):
51
+ for ty in range(degree + 1 - tx):
52
+ index = _triangle_node_index(tx, ty, degree)
53
+ triangle_coords[index] = [tx, ty]
54
+
55
+ CoordTypeVec = wp.mat(dtype=int, shape=(self.NODES_PER_ELEMENT, 2))
56
+ self.NODE_TRIANGLE_COORDS = wp.constant(CoordTypeVec(triangle_coords))
57
+
58
+ self.node_type_and_type_index = self._get_node_type_and_type_index()
59
+ self._node_triangle_coordinates = self._get_node_triangle_coordinates()
60
+
61
+ @property
62
+ def name(self) -> str:
63
+ return f"Tri_P{self.ORDER}"
64
+
65
+ def _get_node_triangle_coordinates(self):
66
+ NODE_TRIANGLE_COORDS = self.NODE_TRIANGLE_COORDS
67
+
68
+ def node_triangle_coordinates(
69
+ node_index_in_elt: int,
70
+ ):
71
+ return wp.vec2i(NODE_TRIANGLE_COORDS[node_index_in_elt, 0], NODE_TRIANGLE_COORDS[node_index_in_elt, 1])
72
+
73
+ return cache.get_func(node_triangle_coordinates, self.name)
74
+
75
+ def _get_node_type_and_type_index(self):
76
+ ORDER = self.ORDER
77
+
78
+ def node_type_and_index(
79
+ node_index_in_elt: int,
80
+ ):
81
+ if node_index_in_elt < 3:
82
+ return Triangle2DPolynomialShapeFunctions.VERTEX, node_index_in_elt
83
+
84
+ if node_index_in_elt < 3 * ORDER:
85
+ return Triangle2DPolynomialShapeFunctions.EDGE, (node_index_in_elt - 3)
86
+
87
+ return Triangle2DPolynomialShapeFunctions.INTERIOR, (node_index_in_elt - 3 * ORDER)
88
+
89
+ return cache.get_func(node_type_and_index, self.name)
90
+
91
+ def make_node_coords_in_element(self):
92
+ ORDER = self.ORDER
93
+
94
+ def node_coords_in_element(
95
+ node_index_in_elt: int,
96
+ ):
97
+ tri_coords = self._node_triangle_coordinates(node_index_in_elt)
98
+ cx = float(tri_coords[0]) / float(ORDER)
99
+ cy = float(tri_coords[1]) / float(ORDER)
100
+ return Coords(1.0 - cx - cy, cx, cy)
101
+
102
+ return cache.get_func(node_coords_in_element, self.name)
103
+
104
+ def make_node_quadrature_weight(self):
105
+ if self.ORDER == 3:
106
+ # P3 intrisic quadrature
107
+ vertex_weight = 1.0 / 30
108
+ edge_weight = 0.075
109
+ interior_weight = 0.45
110
+ elif self.ORDER == 2:
111
+ # Order 1, but optimized quadrature weights for monomials of order <= 4
112
+ vertex_weight = 0.022335964126
113
+ edge_weight = 0.310997369207
114
+ interior_weight = 0.0
115
+ else:
116
+ vertex_weight = 1.0 / self.NODES_PER_ELEMENT
117
+ edge_weight = 1.0 / self.NODES_PER_ELEMENT
118
+ interior_weight = 1.0 / self.NODES_PER_ELEMENT
119
+
120
+ VERTEX_WEIGHT = wp.constant(vertex_weight)
121
+ EDGE_WEIGHT = wp.constant(edge_weight)
122
+ INTERIOR_WEIGHT = wp.constant(interior_weight)
123
+
124
+ @cache.dynamic_func(suffix=self.name)
125
+ def node_quadrature_weight(node_index_in_element: int):
126
+ node_type, type_index = self.node_type_and_type_index(node_index_in_element)
127
+
128
+ if node_type == Triangle2DPolynomialShapeFunctions.VERTEX:
129
+ return VERTEX_WEIGHT
130
+ elif node_type == Triangle2DPolynomialShapeFunctions.EDGE:
131
+ return EDGE_WEIGHT
132
+
133
+ return INTERIOR_WEIGHT
134
+
135
+ return node_quadrature_weight
136
+
137
+ def make_trace_node_quadrature_weight(self):
138
+ # Closed Newton-Cotes
139
+ if self.ORDER == 3:
140
+ vertex_weight = 1.0 / 8.0
141
+ edge_weight = 3.0 / 8.0
142
+ elif self.ORDER == 2:
143
+ vertex_weight = 1.0 / 6.0
144
+ edge_weight = 2.0 / 3.0
145
+ else:
146
+ vertex_weight = 1.0 / self.NODES_PER_SIDE
147
+ edge_weight = 1.0 / self.NODES_PER_SIDE
148
+
149
+ VERTEX_WEIGHT = wp.constant(vertex_weight)
150
+ EDGE_WEIGHT = wp.constant(edge_weight)
151
+
152
+ @cache.dynamic_func(suffix=self.name)
153
+ def trace_node_quadrature_weight(node_index_in_element: int):
154
+ node_type, type_index = self.node_type_and_type_index(node_index_in_element)
155
+
156
+ return wp.select(node_type == Triangle2DPolynomialShapeFunctions.VERTEX, EDGE_WEIGHT, VERTEX_WEIGHT)
157
+
158
+ return trace_node_quadrature_weight
159
+
160
+ def make_element_inner_weight(self):
161
+ ORDER = self.ORDER
162
+
163
+ def element_inner_weight_linear(
164
+ coords: Coords,
165
+ node_index_in_elt: int,
166
+ ):
167
+ return coords[node_index_in_elt]
168
+
169
+ def element_inner_weight_quadratic(
170
+ coords: Coords,
171
+ node_index_in_elt: int,
172
+ ):
173
+ node_type, type_index = self.node_type_and_type_index(node_index_in_elt)
174
+
175
+ if node_type == Triangle2DPolynomialShapeFunctions.VERTEX:
176
+ # Vertex
177
+ return coords[type_index] * (2.0 * coords[type_index] - 1.0)
178
+
179
+ # Edge
180
+ c1 = type_index
181
+ c2 = (type_index + 1) % 3
182
+ return 4.0 * coords[c1] * coords[c2]
183
+
184
+ def element_inner_weight_cubic(
185
+ coords: Coords,
186
+ node_index_in_elt: int,
187
+ ):
188
+ node_type, type_index = self.node_type_and_type_index(node_index_in_elt)
189
+
190
+ if node_type == Triangle2DPolynomialShapeFunctions.VERTEX:
191
+ # Vertex
192
+ return 0.5 * coords[type_index] * (3.0 * coords[type_index] - 1.0) * (3.0 * coords[type_index] - 2.0)
193
+
194
+ elif node_type == Triangle2DPolynomialShapeFunctions.EDGE:
195
+ # Edge
196
+ edge = type_index // 2
197
+ k = type_index - 2 * edge
198
+ c1 = (edge + k) % 3
199
+ c2 = (edge + 1 - k) % 3
200
+
201
+ return 4.5 * coords[c1] * coords[c2] * (3.0 * coords[c1] - 1.0)
202
+
203
+ # Interior
204
+ return 27.0 * coords[0] * coords[1] * coords[2]
205
+
206
+ if ORDER == 1:
207
+ return cache.get_func(element_inner_weight_linear, self.name)
208
+ elif ORDER == 2:
209
+ return cache.get_func(element_inner_weight_quadratic, self.name)
210
+ elif ORDER == 3:
211
+ return cache.get_func(element_inner_weight_cubic, self.name)
212
+
213
+ return None
214
+
215
+ def make_element_inner_weight_gradient(self):
216
+ ORDER = self.ORDER
217
+
218
+ def element_inner_weight_gradient_linear(
219
+ coords: Coords,
220
+ node_index_in_elt: int,
221
+ ):
222
+ dw_dc = wp.vec3(0.0)
223
+ dw_dc[node_index_in_elt] = 1.0
224
+
225
+ dw_du = wp.vec2(dw_dc[1] - dw_dc[0], dw_dc[2] - dw_dc[0])
226
+ return dw_du
227
+
228
+ def element_inner_weight_gradient_quadratic(
229
+ coords: Coords,
230
+ node_index_in_elt: int,
231
+ ):
232
+ node_type, type_index = self.node_type_and_type_index(node_index_in_elt)
233
+
234
+ dw_dc = wp.vec3(0.0)
235
+
236
+ if node_type == Triangle2DPolynomialShapeFunctions.VERTEX:
237
+ # Vertex
238
+ dw_dc[type_index] = 4.0 * coords[type_index] - 1.0
239
+
240
+ else:
241
+ # Edge
242
+ c1 = type_index
243
+ c2 = (type_index + 1) % 3
244
+ dw_dc[c1] = 4.0 * coords[c2]
245
+ dw_dc[c2] = 4.0 * coords[c1]
246
+
247
+ dw_du = wp.vec2(dw_dc[1] - dw_dc[0], dw_dc[2] - dw_dc[0])
248
+ return dw_du
249
+
250
+ def element_inner_weight_gradient_cubic(
251
+ coords: Coords,
252
+ node_index_in_elt: int,
253
+ ):
254
+ node_type, type_index = self.node_type_and_type_index(node_index_in_elt)
255
+
256
+ dw_dc = wp.vec3(0.0)
257
+
258
+ if node_type == Triangle2DPolynomialShapeFunctions.VERTEX:
259
+ # Vertex
260
+ dw_dc[type_index] = (
261
+ 0.5 * 27.0 * coords[type_index] * coords[type_index] - 9.0 * coords[type_index] + 1.0
262
+ )
263
+
264
+ elif node_type == Triangle2DPolynomialShapeFunctions.EDGE:
265
+ # Edge
266
+ edge = type_index // 2
267
+ k = type_index - 2 * edge
268
+ c1 = (edge + k) % 3
269
+ c2 = (edge + 1 - k) % 3
270
+
271
+ dw_dc[c1] = 4.5 * coords[c2] * (6.0 * coords[c1] - 1.0)
272
+ dw_dc[c2] = 4.5 * coords[c1] * (3.0 * coords[c1] - 1.0)
273
+
274
+ else:
275
+ # Interior
276
+ dw_dc = wp.vec3(
277
+ 27.0 * coords[1] * coords[2], 27.0 * coords[2] * coords[0], 27.0 * coords[0] * coords[1]
278
+ )
279
+
280
+ dw_du = wp.vec2(dw_dc[1] - dw_dc[0], dw_dc[2] - dw_dc[0])
281
+ return dw_du
282
+
283
+ if ORDER == 1:
284
+ return cache.get_func(element_inner_weight_gradient_linear, self.name)
285
+ elif ORDER == 2:
286
+ return cache.get_func(element_inner_weight_gradient_quadratic, self.name)
287
+ elif ORDER == 3:
288
+ return cache.get_func(element_inner_weight_gradient_cubic, self.name)
289
+
290
+ return None
291
+
292
+ def element_node_triangulation(self):
293
+ if self.ORDER == 1:
294
+ element_triangles = [[0, 1, 2]]
295
+ if self.ORDER == 2:
296
+ element_triangles = [[0, 3, 5], [3, 1, 4], [2, 5, 4], [3, 4, 5]]
297
+ elif self.ORDER == 3:
298
+ element_triangles = [
299
+ [0, 3, 8],
300
+ [3, 4, 9],
301
+ [4, 1, 5],
302
+ [8, 3, 9],
303
+ [4, 5, 9],
304
+ [8, 9, 7],
305
+ [9, 5, 6],
306
+ [6, 7, 9],
307
+ [7, 6, 2],
308
+ ]
309
+
310
+ return np.array(element_triangles)
311
+
312
+
313
+ class Triangle2DNonConformingPolynomialShapeFunctions:
314
+ def __init__(self, degree: int):
315
+ self._tri_shape = Triangle2DPolynomialShapeFunctions(degree=degree)
316
+ self.ORDER = self._tri_shape.ORDER
317
+ self.NODES_PER_ELEMENT = self._tri_shape.NODES_PER_ELEMENT
318
+
319
+ self.element_node_triangulation = self._tri_shape.element_node_triangulation
320
+
321
+ # Coordinates (a, b, b) of embedded triangle
322
+ if self.ORDER == 1:
323
+ # Order 2
324
+ a = 2.0 / 3.0
325
+ elif self.ORDER == 2:
326
+ # Order 2, optimized for small intrinsic quadrature error up to degree 4
327
+ a = 0.7790771484375001
328
+ elif self.ORDER == 3:
329
+ # Order 3, optimized for small intrinsic quadrature error up to degree 6
330
+ a = 0.8429443359375002
331
+ else:
332
+ a = 1.0
333
+
334
+ b = 0.5 * (1.0 - a)
335
+ self._small_to_big = np.full((3, 3), b) + (a - b) * np.eye(3)
336
+ self._tri_scale = a - b
337
+
338
+ @property
339
+ def name(self) -> str:
340
+ return f"Tri_P{self.ORDER}d"
341
+
342
+ def make_node_quadrature_weight(self):
343
+ # Intrinsic quadrature -- precomputed integral of node shape functions
344
+ # over element. Order equal to self.ORDER
345
+
346
+ if self.ORDER == 2:
347
+ vertex_weight = 0.13743348
348
+ edge_weight = 0.19589985
349
+ interior_weight = 0.0
350
+ elif self.ORDER == 3:
351
+ vertex_weight = 0.07462578
352
+ edge_weight = 0.1019807
353
+ interior_weight = 0.16423881
354
+ else:
355
+ vertex_weight = 1.0 / self.NODES_PER_ELEMENT
356
+ edge_weight = 1.0 / self.NODES_PER_ELEMENT
357
+ interior_weight = 1.0 / self.NODES_PER_ELEMENT
358
+
359
+ VERTEX_WEIGHT = wp.constant(vertex_weight)
360
+ EDGE_WEIGHT = wp.constant(edge_weight)
361
+ INTERIOR_WEIGHT = wp.constant(interior_weight)
362
+
363
+ @cache.dynamic_func(suffix=self.name)
364
+ def node_quadrature_weight(node_index_in_element: int):
365
+ node_type, type_index = self._tri_shape.node_type_and_type_index(node_index_in_element)
366
+
367
+ if node_type == Triangle2DPolynomialShapeFunctions.VERTEX:
368
+ return VERTEX_WEIGHT
369
+ elif node_type == Triangle2DPolynomialShapeFunctions.EDGE:
370
+ return EDGE_WEIGHT
371
+
372
+ return INTERIOR_WEIGHT
373
+
374
+ return node_quadrature_weight
375
+
376
+ def make_trace_node_quadrature_weight(self):
377
+ # Non-conforming, zero measure on sides
378
+
379
+ @wp.func
380
+ def zero(node_index_in_elt: int):
381
+ return 0.0
382
+
383
+ return zero
384
+
385
+ def make_node_coords_in_element(self):
386
+ node_coords_in_tet = self._tri_shape.make_node_coords_in_element()
387
+
388
+ SMALL_TO_BIG = wp.constant(wp.mat33(self._small_to_big))
389
+
390
+ @cache.dynamic_func(suffix=self.name)
391
+ def node_coords_in_element(
392
+ node_index_in_elt: int,
393
+ ):
394
+ tri_coords = node_coords_in_tet(node_index_in_elt)
395
+ return SMALL_TO_BIG * tri_coords
396
+
397
+ return node_coords_in_element
398
+
399
+ def make_element_inner_weight(self):
400
+ tri_inner_weight = self._tri_shape.make_element_inner_weight()
401
+
402
+ BIG_TO_SMALL = wp.constant(wp.mat33(np.linalg.inv(self._small_to_big)))
403
+
404
+ @cache.dynamic_func(suffix=self.name)
405
+ def element_inner_weight(
406
+ coords: Coords,
407
+ node_index_in_elt: int,
408
+ ):
409
+ tri_coords = BIG_TO_SMALL * coords
410
+ return tri_inner_weight(tri_coords, node_index_in_elt)
411
+
412
+ return element_inner_weight
413
+
414
+ def make_element_inner_weight_gradient(self):
415
+ tri_inner_weight_gradient = self._tri_shape.make_element_inner_weight_gradient()
416
+
417
+ BIG_TO_SMALL = wp.constant(wp.mat33(np.linalg.inv(self._small_to_big)))
418
+ INV_TRI_SCALE = wp.constant(1.0 / self._tri_scale)
419
+
420
+ @cache.dynamic_func(suffix=self.name)
421
+ def element_inner_weight_gradient(
422
+ coords: Coords,
423
+ node_index_in_elt: int,
424
+ ):
425
+ tri_coords = BIG_TO_SMALL * coords
426
+ grad = tri_inner_weight_gradient(tri_coords, node_index_in_elt)
427
+ return INV_TRI_SCALE * grad
428
+
429
+ return element_inner_weight_gradient