warp-lang 1.0.0b2__py3-none-manylinux2014_x86_64.whl → 1.0.0b6__py3-none-manylinux2014_x86_64.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.
Files changed (269) hide show
  1. docs/conf.py +17 -5
  2. examples/env/env_ant.py +1 -1
  3. examples/env/env_cartpole.py +1 -1
  4. examples/env/env_humanoid.py +1 -1
  5. examples/env/env_usd.py +4 -1
  6. examples/env/environment.py +8 -9
  7. examples/example_dem.py +34 -33
  8. examples/example_diffray.py +364 -337
  9. examples/example_fluid.py +32 -23
  10. examples/example_jacobian_ik.py +97 -93
  11. examples/example_marching_cubes.py +6 -16
  12. examples/example_mesh.py +6 -16
  13. examples/example_mesh_intersect.py +16 -14
  14. examples/example_nvdb.py +14 -16
  15. examples/example_raycast.py +14 -13
  16. examples/example_raymarch.py +16 -23
  17. examples/example_render_opengl.py +19 -10
  18. examples/example_sim_cartpole.py +82 -78
  19. examples/example_sim_cloth.py +45 -48
  20. examples/example_sim_fk_grad.py +51 -44
  21. examples/example_sim_fk_grad_torch.py +47 -40
  22. examples/example_sim_grad_bounce.py +108 -133
  23. examples/example_sim_grad_cloth.py +99 -113
  24. examples/example_sim_granular.py +5 -6
  25. examples/{example_sim_sdf_shape.py → example_sim_granular_collision_sdf.py} +37 -26
  26. examples/example_sim_neo_hookean.py +51 -55
  27. examples/example_sim_particle_chain.py +4 -4
  28. examples/example_sim_quadruped.py +126 -81
  29. examples/example_sim_rigid_chain.py +54 -61
  30. examples/example_sim_rigid_contact.py +66 -70
  31. examples/example_sim_rigid_fem.py +3 -3
  32. examples/example_sim_rigid_force.py +1 -1
  33. examples/example_sim_rigid_gyroscopic.py +3 -4
  34. examples/example_sim_rigid_kinematics.py +28 -39
  35. examples/example_sim_trajopt.py +112 -110
  36. examples/example_sph.py +9 -8
  37. examples/example_wave.py +7 -7
  38. examples/fem/bsr_utils.py +30 -17
  39. examples/fem/example_apic_fluid.py +85 -69
  40. examples/fem/example_convection_diffusion.py +97 -93
  41. examples/fem/example_convection_diffusion_dg.py +142 -149
  42. examples/fem/example_convection_diffusion_dg0.py +141 -136
  43. examples/fem/example_deformed_geometry.py +146 -0
  44. examples/fem/example_diffusion.py +115 -84
  45. examples/fem/example_diffusion_3d.py +116 -86
  46. examples/fem/example_diffusion_mgpu.py +102 -79
  47. examples/fem/example_mixed_elasticity.py +139 -100
  48. examples/fem/example_navier_stokes.py +175 -162
  49. examples/fem/example_stokes.py +143 -111
  50. examples/fem/example_stokes_transfer.py +186 -157
  51. examples/fem/mesh_utils.py +59 -97
  52. examples/fem/plot_utils.py +138 -17
  53. tools/ci/publishing/build_nodes_info.py +54 -0
  54. warp/__init__.py +4 -3
  55. warp/__init__.pyi +1 -0
  56. warp/bin/warp-clang.so +0 -0
  57. warp/bin/warp.so +0 -0
  58. warp/build.py +5 -3
  59. warp/build_dll.py +29 -9
  60. warp/builtins.py +836 -492
  61. warp/codegen.py +864 -553
  62. warp/config.py +3 -1
  63. warp/context.py +389 -172
  64. warp/fem/__init__.py +24 -6
  65. warp/fem/cache.py +318 -25
  66. warp/fem/dirichlet.py +7 -3
  67. warp/fem/domain.py +14 -0
  68. warp/fem/field/__init__.py +30 -38
  69. warp/fem/field/field.py +149 -0
  70. warp/fem/field/nodal_field.py +244 -138
  71. warp/fem/field/restriction.py +8 -6
  72. warp/fem/field/test.py +127 -59
  73. warp/fem/field/trial.py +117 -60
  74. warp/fem/geometry/__init__.py +5 -1
  75. warp/fem/geometry/deformed_geometry.py +271 -0
  76. warp/fem/geometry/element.py +24 -1
  77. warp/fem/geometry/geometry.py +86 -14
  78. warp/fem/geometry/grid_2d.py +112 -54
  79. warp/fem/geometry/grid_3d.py +134 -65
  80. warp/fem/geometry/hexmesh.py +953 -0
  81. warp/fem/geometry/partition.py +85 -33
  82. warp/fem/geometry/quadmesh_2d.py +532 -0
  83. warp/fem/geometry/tetmesh.py +451 -115
  84. warp/fem/geometry/trimesh_2d.py +197 -92
  85. warp/fem/integrate.py +534 -268
  86. warp/fem/operator.py +58 -31
  87. warp/fem/polynomial.py +11 -0
  88. warp/fem/quadrature/__init__.py +1 -1
  89. warp/fem/quadrature/pic_quadrature.py +150 -58
  90. warp/fem/quadrature/quadrature.py +209 -57
  91. warp/fem/space/__init__.py +230 -53
  92. warp/fem/space/basis_space.py +489 -0
  93. warp/fem/space/collocated_function_space.py +105 -0
  94. warp/fem/space/dof_mapper.py +49 -2
  95. warp/fem/space/function_space.py +90 -39
  96. warp/fem/space/grid_2d_function_space.py +149 -496
  97. warp/fem/space/grid_3d_function_space.py +173 -538
  98. warp/fem/space/hexmesh_function_space.py +352 -0
  99. warp/fem/space/partition.py +129 -76
  100. warp/fem/space/quadmesh_2d_function_space.py +369 -0
  101. warp/fem/space/restriction.py +46 -34
  102. warp/fem/space/shape/__init__.py +15 -0
  103. warp/fem/space/shape/cube_shape_function.py +738 -0
  104. warp/fem/space/shape/shape_function.py +103 -0
  105. warp/fem/space/shape/square_shape_function.py +611 -0
  106. warp/fem/space/shape/tet_shape_function.py +567 -0
  107. warp/fem/space/shape/triangle_shape_function.py +429 -0
  108. warp/fem/space/tetmesh_function_space.py +132 -1039
  109. warp/fem/space/topology.py +295 -0
  110. warp/fem/space/trimesh_2d_function_space.py +104 -742
  111. warp/fem/types.py +13 -11
  112. warp/fem/utils.py +335 -60
  113. warp/native/array.h +120 -34
  114. warp/native/builtin.h +101 -72
  115. warp/native/bvh.cpp +73 -325
  116. warp/native/bvh.cu +406 -23
  117. warp/native/bvh.h +22 -40
  118. warp/native/clang/clang.cpp +1 -0
  119. warp/native/crt.h +2 -0
  120. warp/native/cuda_util.cpp +8 -3
  121. warp/native/cuda_util.h +1 -0
  122. warp/native/exports.h +1522 -1243
  123. warp/native/intersect.h +19 -4
  124. warp/native/intersect_adj.h +8 -8
  125. warp/native/mat.h +76 -17
  126. warp/native/mesh.cpp +33 -108
  127. warp/native/mesh.cu +114 -18
  128. warp/native/mesh.h +395 -40
  129. warp/native/noise.h +272 -329
  130. warp/native/quat.h +51 -8
  131. warp/native/rand.h +44 -34
  132. warp/native/reduce.cpp +1 -1
  133. warp/native/sparse.cpp +4 -4
  134. warp/native/sparse.cu +163 -155
  135. warp/native/spatial.h +2 -2
  136. warp/native/temp_buffer.h +18 -14
  137. warp/native/vec.h +103 -21
  138. warp/native/warp.cpp +2 -1
  139. warp/native/warp.cu +28 -3
  140. warp/native/warp.h +4 -3
  141. warp/render/render_opengl.py +261 -109
  142. warp/sim/__init__.py +1 -2
  143. warp/sim/articulation.py +385 -185
  144. warp/sim/import_mjcf.py +59 -48
  145. warp/sim/import_urdf.py +15 -15
  146. warp/sim/import_usd.py +174 -102
  147. warp/sim/inertia.py +17 -18
  148. warp/sim/integrator_xpbd.py +4 -3
  149. warp/sim/model.py +330 -250
  150. warp/sim/render.py +1 -1
  151. warp/sparse.py +625 -152
  152. warp/stubs.py +341 -309
  153. warp/tape.py +9 -6
  154. warp/tests/__main__.py +3 -6
  155. warp/tests/assets/curlnoise_golden.npy +0 -0
  156. warp/tests/assets/pnoise_golden.npy +0 -0
  157. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  158. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  159. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  160. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  161. warp/tests/aux_test_unresolved_func.py +14 -0
  162. warp/tests/aux_test_unresolved_symbol.py +14 -0
  163. warp/tests/disabled_kinematics.py +239 -0
  164. warp/tests/run_coverage_serial.py +31 -0
  165. warp/tests/test_adam.py +103 -106
  166. warp/tests/test_arithmetic.py +94 -74
  167. warp/tests/test_array.py +82 -101
  168. warp/tests/test_array_reduce.py +57 -23
  169. warp/tests/test_atomic.py +64 -28
  170. warp/tests/test_bool.py +22 -12
  171. warp/tests/test_builtins_resolution.py +1292 -0
  172. warp/tests/test_bvh.py +18 -18
  173. warp/tests/test_closest_point_edge_edge.py +54 -57
  174. warp/tests/test_codegen.py +165 -134
  175. warp/tests/test_compile_consts.py +28 -20
  176. warp/tests/test_conditional.py +108 -24
  177. warp/tests/test_copy.py +10 -12
  178. warp/tests/test_ctypes.py +112 -88
  179. warp/tests/test_dense.py +21 -14
  180. warp/tests/test_devices.py +98 -0
  181. warp/tests/test_dlpack.py +75 -75
  182. warp/tests/test_examples.py +237 -0
  183. warp/tests/test_fabricarray.py +22 -24
  184. warp/tests/test_fast_math.py +15 -11
  185. warp/tests/test_fem.py +1034 -124
  186. warp/tests/test_fp16.py +23 -16
  187. warp/tests/test_func.py +187 -86
  188. warp/tests/test_generics.py +194 -49
  189. warp/tests/test_grad.py +123 -181
  190. warp/tests/test_grad_customs.py +176 -0
  191. warp/tests/test_hash_grid.py +35 -34
  192. warp/tests/test_import.py +10 -23
  193. warp/tests/test_indexedarray.py +24 -25
  194. warp/tests/test_intersect.py +18 -9
  195. warp/tests/test_large.py +141 -0
  196. warp/tests/test_launch.py +14 -41
  197. warp/tests/test_lerp.py +64 -65
  198. warp/tests/test_lvalue.py +493 -0
  199. warp/tests/test_marching_cubes.py +12 -13
  200. warp/tests/test_mat.py +517 -2898
  201. warp/tests/test_mat_lite.py +115 -0
  202. warp/tests/test_mat_scalar_ops.py +2889 -0
  203. warp/tests/test_math.py +103 -9
  204. warp/tests/test_matmul.py +304 -69
  205. warp/tests/test_matmul_lite.py +410 -0
  206. warp/tests/test_mesh.py +60 -22
  207. warp/tests/test_mesh_query_aabb.py +21 -25
  208. warp/tests/test_mesh_query_point.py +111 -22
  209. warp/tests/test_mesh_query_ray.py +12 -24
  210. warp/tests/test_mlp.py +30 -22
  211. warp/tests/test_model.py +92 -89
  212. warp/tests/test_modules_lite.py +39 -0
  213. warp/tests/test_multigpu.py +88 -114
  214. warp/tests/test_noise.py +12 -11
  215. warp/tests/test_operators.py +16 -20
  216. warp/tests/test_options.py +11 -11
  217. warp/tests/test_pinned.py +17 -18
  218. warp/tests/test_print.py +32 -11
  219. warp/tests/test_quat.py +275 -129
  220. warp/tests/test_rand.py +18 -16
  221. warp/tests/test_reload.py +38 -34
  222. warp/tests/test_rounding.py +50 -43
  223. warp/tests/test_runlength_encode.py +168 -20
  224. warp/tests/test_smoothstep.py +9 -11
  225. warp/tests/test_snippet.py +143 -0
  226. warp/tests/test_sparse.py +261 -63
  227. warp/tests/test_spatial.py +276 -243
  228. warp/tests/test_streams.py +110 -85
  229. warp/tests/test_struct.py +268 -63
  230. warp/tests/test_tape.py +39 -21
  231. warp/tests/test_torch.py +90 -86
  232. warp/tests/test_transient_module.py +10 -12
  233. warp/tests/test_types.py +363 -0
  234. warp/tests/test_utils.py +451 -0
  235. warp/tests/test_vec.py +354 -2050
  236. warp/tests/test_vec_lite.py +73 -0
  237. warp/tests/test_vec_scalar_ops.py +2099 -0
  238. warp/tests/test_volume.py +418 -376
  239. warp/tests/test_volume_write.py +124 -134
  240. warp/tests/unittest_serial.py +35 -0
  241. warp/tests/unittest_suites.py +291 -0
  242. warp/tests/unittest_utils.py +342 -0
  243. warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
  244. warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
  245. warp/thirdparty/appdirs.py +36 -45
  246. warp/thirdparty/unittest_parallel.py +589 -0
  247. warp/types.py +622 -211
  248. warp/utils.py +54 -393
  249. warp_lang-1.0.0b6.dist-info/METADATA +238 -0
  250. warp_lang-1.0.0b6.dist-info/RECORD +409 -0
  251. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
  252. examples/example_cache_management.py +0 -40
  253. examples/example_multigpu.py +0 -54
  254. examples/example_struct.py +0 -65
  255. examples/fem/example_stokes_transfer_3d.py +0 -210
  256. warp/fem/field/discrete_field.py +0 -80
  257. warp/fem/space/nodal_function_space.py +0 -233
  258. warp/tests/test_all.py +0 -223
  259. warp/tests/test_array_scan.py +0 -60
  260. warp/tests/test_base.py +0 -208
  261. warp/tests/test_unresolved_func.py +0 -7
  262. warp/tests/test_unresolved_symbol.py +0 -7
  263. warp_lang-1.0.0b2.dist-info/METADATA +0 -26
  264. warp_lang-1.0.0b2.dist-info/RECORD +0 -378
  265. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  266. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  267. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  268. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
  269. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
@@ -1,210 +0,0 @@
1
- """
2
- This example computes a 3D weakly-compressible Stokes flow around a moving object, including:
3
- - defining active cells from a mask, and restricting the computation domain to those
4
- - utilizing the PicQuadrature to integrate over unstructured particles
5
- """
6
-
7
- import warp as wp
8
- import numpy as np
9
-
10
- from warp.fem.types import *
11
- from warp.fem.geometry import Grid3D, ExplicitGeometryPartition
12
- from warp.fem.field import make_test, make_trial
13
- from warp.fem.space import make_polynomial_space, make_space_partition
14
- from warp.fem.domain import Cells
15
- from warp.fem.integrate import integrate, interpolate
16
- from warp.fem.operator import integrand, D, div
17
- from warp.fem.quadrature import PicQuadrature
18
- from warp.fem.utils import array_axpy
19
-
20
- from warp.sparse import bsr_mv
21
-
22
- from plot_utils import plot_3d_scatter, plot_3d_velocities
23
- from bsr_utils import bsr_cg
24
- from example_stokes_transfer import inverse_array_kernel
25
-
26
- from warp.utils import array_cast
27
- from warp.sparse import bsr_transposed, bsr_mm, bsr_axpy
28
-
29
- import matplotlib.pyplot as plt
30
-
31
-
32
- @integrand
33
- def vel_from_particles_form(s: Sample, particle_vel: wp.array(dtype=wp.vec3), v: Field):
34
- vel = particle_vel[s.qp_index]
35
- return wp.dot(vel, v(s))
36
-
37
-
38
- @integrand
39
- def viscosity_form(s: Sample, u: Field, v: Field, nu: float):
40
- return nu * wp.ddot(D(u, s), D(v, s))
41
-
42
-
43
- @integrand
44
- def mass_form(
45
- s: Sample,
46
- u: Field,
47
- v: Field,
48
- ):
49
- return wp.dot(u(s), v(s))
50
-
51
-
52
- @integrand
53
- def scalar_mass_form(
54
- s: Sample,
55
- p: Field,
56
- q: Field,
57
- ):
58
- return p(s) * q(s)
59
-
60
-
61
- @integrand
62
- def div_form(
63
- s: Sample,
64
- u: Field,
65
- q: Field,
66
- ):
67
- return q(s) * div(u, s)
68
-
69
-
70
- @integrand
71
- def cell_activity(s: Sample, domain: Domain, c1: wp.vec3, c2: wp.vec3, radius: float):
72
- pos = domain(s)
73
- if wp.length(pos - c1) < radius:
74
- return 0.0
75
- if wp.length(pos - c2) < radius:
76
- return 0.0
77
- return 1.0
78
-
79
-
80
- if __name__ == "__main__":
81
- wp.init()
82
- wp.set_module_options({"enable_backward": False})
83
-
84
- res = 20
85
- geo = Grid3D(
86
- res=vec3i(res, res, res),
87
- bounds_lo=wp.vec3(0.0, 0.0, 0.0),
88
- bounds_hi=wp.vec3(1.0, 1.0, 1.0),
89
- )
90
-
91
- vel = 1.0
92
- viscosity = 100.0
93
- compliance = 0.01
94
- bd_strength = 100000.0
95
-
96
- # Generate particles defining the transfer displacement
97
- circle_radius = 0.15
98
- c1_center = np.array([0.25, 0.5, 0.5])
99
- c2_center = np.array([0.75, 0.5, 0.5])
100
-
101
- particles_per_side = int(4 * circle_radius * res)
102
-
103
- particles_x = np.linspace(-circle_radius, circle_radius, particles_per_side)
104
- cube_particles = np.array([[px, py, pz] for px in particles_x for py in particles_x for pz in particles_x])
105
-
106
- particles_per_circle = particles_per_side**3
107
- n_particles = 2 * particles_per_circle
108
- particles = np.empty((n_particles, 3), dtype=float)
109
-
110
- particles[:particles_per_circle, :] = cube_particles + c1_center
111
- particles[particles_per_circle:, :] = cube_particles + c2_center
112
-
113
- particle_areas = np.ones(n_particles) * circle_radius * circle_radius / (res * res)
114
- particle_velocities = np.zeros_like(particles)
115
- particle_velocities[:particles_per_circle, 0] = vel
116
- particle_velocities[particles_per_circle:, 0] = -vel
117
-
118
- particles = wp.array(particles, dtype=wp.vec3)
119
- particle_areas = wp.array(particle_areas, dtype=float)
120
- particle_velocities = wp.array(particle_velocities, dtype=wp.vec3)
121
-
122
- # Disable cells that are interior to the circles
123
- cell_space = make_polynomial_space(geo, degree=0)
124
- activity = cell_space.make_field()
125
- interpolate(
126
- cell_activity,
127
- dest=activity,
128
- values={"c1": c1_center, "c2": c2_center, "radius": circle_radius - 1.0 / res},
129
- )
130
-
131
- active_partition = ExplicitGeometryPartition(geo, wp.array(activity.dof_values.numpy(), dtype=int))
132
- print("Active cells:", active_partition.cell_count())
133
-
134
- # Function spaces -- Q1 for vel, Q0 for pressure
135
- u_space = make_polynomial_space(geo, degree=1, dtype=wp.vec3)
136
- p_space = make_polynomial_space(geo, degree=0)
137
- active_space_partition = make_space_partition(space=u_space, geometry_partition=active_partition)
138
- active_p_space_partition = make_space_partition(space=p_space, geometry_partition=active_partition)
139
-
140
- domain = Cells(geometry=active_partition)
141
- pic_quadrature = PicQuadrature(domain, particles, particle_areas)
142
-
143
- # Boundary condition on particles
144
- u_test = make_test(space=u_space, space_partition=active_space_partition, domain=domain)
145
- u_trial = make_trial(space=u_space, space_partition=active_space_partition, domain=domain)
146
-
147
- u_rhs = integrate(
148
- vel_from_particles_form,
149
- quadrature=pic_quadrature,
150
- fields={"v": u_test},
151
- values={"particle_vel": particle_velocities},
152
- output_dtype=wp.vec3d
153
- )
154
-
155
- u_bd_matrix = integrate(mass_form, quadrature=pic_quadrature, fields={"u": u_trial, "v": u_test})
156
-
157
- # Viscosity
158
- u_visc_matrix = integrate(
159
- viscosity_form,
160
- fields={"u": u_trial, "v": u_test},
161
- values={"nu": viscosity}
162
- )
163
-
164
- # Pressure-velocity coupling
165
- p_test = make_test(space=p_space, space_partition=active_p_space_partition, domain=domain)
166
- p_trial = make_trial(space=p_space, space_partition=active_p_space_partition, domain=domain)
167
-
168
- div_matrix = integrate(div_form, fields={"u": u_trial, "q": p_test})
169
- inv_p_mass_matrix = integrate(scalar_mass_form, fields={"p": p_trial, "q": p_test})
170
- wp.launch(
171
- kernel=inverse_array_kernel,
172
- dim=inv_p_mass_matrix.values.shape,
173
- device=inv_p_mass_matrix.values.device,
174
- inputs=[inv_p_mass_matrix.values],
175
- )
176
-
177
- # Assemble linear system
178
- u_matrix = u_visc_matrix
179
- bsr_axpy(u_bd_matrix, u_matrix, alpha=bd_strength)
180
-
181
- div_matrix_t = bsr_transposed(div_matrix)
182
- gradient_matrix = bsr_mm(div_matrix_t, inv_p_mass_matrix)
183
- bsr_mm(gradient_matrix, div_matrix, u_matrix, alpha=1.0 / compliance, beta=1.0)
184
-
185
- array_axpy(u_rhs, u_rhs, alpha=0.0, beta=bd_strength)
186
-
187
- # Solve for displacement
188
- u_res = wp.zeros_like(u_rhs)
189
- bsr_cg(u_matrix, x=u_res, b=u_rhs)
190
-
191
- # Recompute pressure
192
- p_res = wp.zeros(n=active_p_space_partition.node_count(), dtype=wp.float64)
193
- p_tmp = wp.empty_like(p_res)
194
- bsr_mv(A=div_matrix, x=u_res, y=p_tmp)
195
- bsr_mv(A=inv_p_mass_matrix, x=p_tmp, y=p_res, alpha=-1)
196
-
197
- # Display result
198
- u_field = u_space.make_field()
199
- p_field = p_space.make_field()
200
-
201
- u_nodes = wp.indexedarray(u_field.dof_values, indices=active_space_partition.space_node_indices())
202
- p_nodes = wp.indexedarray(p_field.dof_values, indices=active_p_space_partition.space_node_indices())
203
-
204
- array_cast(in_array=u_res, out_array=u_nodes)
205
- array_cast(in_array=p_res, out_array=p_nodes)
206
-
207
- plot_3d_scatter(p_field)
208
- plot_3d_velocities(u_field)
209
-
210
- plt.show()
@@ -1,80 +0,0 @@
1
- from typing import Any
2
-
3
- import warp as wp
4
-
5
- from warp.fem.types import Sample
6
- from warp.fem.space import FunctionSpace, SpacePartition
7
-
8
-
9
- class DiscreteField:
10
- """Field defined over a partition of a discrete function space"""
11
-
12
- EvalArg: wp.codegen.Struct
13
- """Structure containing arguments passed to device functions for field evaluation"""
14
-
15
- def __init__(self, space: FunctionSpace, space_partition: SpacePartition):
16
- self.space = space
17
- self.space_partition = space_partition
18
-
19
- self.dtype = self.space.dtype
20
- self.dof_dtype = self.space.dof_dtype
21
-
22
- def eval_arg_value(self, device) -> wp.codegen.StructInstance:
23
- raise NotImplementedError
24
-
25
- @property
26
- def dof_values(self) -> wp.array:
27
- """Array of degrees of freedom values"""
28
- raise NotImplementedError
29
-
30
- @dof_values.setter
31
- def dof_values(self, values: wp.array):
32
- """Sets degrees of freedom values from an array"""
33
- raise NotImplementedError
34
-
35
- @property
36
- def name(self) -> str:
37
- return f"{self.__class__.__qualname__}_{self.space.name}_{self.space_partition.name}"
38
-
39
- @property
40
- def __str__(self) -> str:
41
- return self.name
42
-
43
- def trace(self) -> FunctionSpace:
44
- """Trace of this field over a lower-dimensional function space"""
45
- raise NotImplementedError
46
-
47
- def eval_arg_value(self, device):
48
- """Value of arguments to be passed to device functions"""
49
- raise NotImplementedError
50
-
51
- def set_node_value(args: Any, node_index: int, value: Any):
52
- """Device function setting the value at given node"""
53
- raise NotImplementedError
54
-
55
- def eval_inner(args: Any, s: "Sample"):
56
- """Device function evaluating the inner field value at a sample point"""
57
- raise NotImplementedError
58
-
59
- def eval_grad_inner(args: Any, s: "Sample"):
60
- """Device function evaluating the inner field gradient at a sample point"""
61
- raise NotImplementedError
62
-
63
- def eval_outer(args: Any, s: "Sample"):
64
- """Device function evaluating the outer field value at a sample point"""
65
- raise NotImplementedError
66
-
67
- def eval_grad_outer(args: Any, s: "Sample"):
68
- """Device function evaluating the outer field gradient at a sample point"""
69
- raise NotImplementedError
70
-
71
- @staticmethod
72
- def _make_eval_degree(EvalArg, space: FunctionSpace):
73
- ORDER = space.ORDER
74
-
75
- def degree(args: EvalArg):
76
- return ORDER
77
-
78
- from warp.fem import cache
79
-
80
- return cache.get_func(degree, space)
@@ -1,233 +0,0 @@
1
- from typing import Any
2
-
3
- import warp as wp
4
-
5
- from warp.fem.types import DofIndex, ElementIndex, Coords, get_node_coord
6
- from warp.fem.geometry import GeometryPartition
7
- from warp.fem import utils
8
-
9
-
10
- from .function_space import FunctionSpace
11
- from .dof_mapper import DofMapper, IdentityMapper
12
- from .partition import make_space_partition, SpacePartition
13
-
14
-
15
- class NodalFunctionSpace(FunctionSpace):
16
- """Function space where values are collocated at nodes"""
17
-
18
- def __init__(self, dtype: type = float, dof_mapper: DofMapper = None):
19
- self.dof_mapper = IdentityMapper(dtype) if dof_mapper is None else dof_mapper
20
- self.dtype = self.dof_mapper.value_dtype
21
- self.dof_dtype = self.dof_mapper.dof_dtype
22
-
23
- if self.dtype == wp.float32:
24
- self.gradient_dtype = wp.vec2
25
- elif self.dtype == wp.vec2:
26
- self.gradient_dtype = wp.mat22
27
- elif self.dtype == wp.vec3:
28
- self.gradient_dtype = wp.mat33
29
- else:
30
- self.gradient_dtype = None
31
-
32
- self.VALUE_DOF_COUNT = self.dof_mapper.DOF_SIZE
33
- self.unit_dof_value = self._make_unit_dof_value(self.dof_mapper)
34
-
35
- @property
36
- def name(self):
37
- return f"{self.__class__.__qualname__}_{self.ORDER}_{self.dof_mapper}".replace(".", "_")
38
-
39
- def make_field(
40
- self,
41
- space_partition: SpacePartition = None,
42
- geometry_partition: GeometryPartition = None,
43
- ) -> "wp.fem.field.NodalField":
44
- from warp.fem.field import NodalField
45
-
46
- if space_partition is None:
47
- space_partition = make_space_partition(self, geometry_partition)
48
-
49
- return NodalField(space=self, space_partition=space_partition)
50
-
51
- @staticmethod
52
- def _make_unit_dof_value(dof_mapper: DofMapper):
53
- from warp.fem import cache
54
-
55
- def unit_dof_value(args: Any, dof: DofIndex):
56
- return dof_mapper.dof_to_value(utils.unit_element(dof_mapper.dof_dtype(0.0), get_node_coord(dof)))
57
-
58
- return cache.get_func(unit_dof_value, str(dof_mapper))
59
-
60
- # Interface for generating Trace space
61
-
62
- def _inner_cell_index(args: Any, side_index: ElementIndex):
63
- """Given a side, returns the index of the inner cell"""
64
- raise NotImplementedError
65
-
66
- def _outer_cell_index(args: Any, side_index: ElementIndex):
67
- """Given a side, returns the index of the outer cell"""
68
- raise NotImplementedError
69
-
70
- def _inner_cell_coords(args: Any, side_index: ElementIndex, side_coords: Coords):
71
- """Given coordinates within a side, returns coordinates within the inner cell"""
72
- raise NotImplementedError
73
-
74
- def _outer_cell_coords(args: Any, side_index: ElementIndex, side_coords: Coords):
75
- """Given coordinates within a side, returns coordinates within the outer cell"""
76
- raise NotImplementedError
77
-
78
- def _cell_to_side_coords(
79
- args: Any,
80
- side_index: ElementIndex,
81
- element_index: ElementIndex,
82
- element_coords: Coords,
83
- ):
84
- """Given coordinates within a cell, returns coordinates within a side, or OUTSIDE"""
85
- raise NotImplementedError
86
-
87
-
88
- class NodalFunctionSpaceTrace(NodalFunctionSpace):
89
- """Trace of a NodalFunctionSpace"""
90
-
91
- def __init__(self, space: NodalFunctionSpace):
92
- self._space = space
93
-
94
- super().__init__(space.dtype, space.dof_mapper)
95
- self.geometry = space.geometry
96
-
97
- self.NODES_PER_ELEMENT = wp.constant(2 * space.NODES_PER_ELEMENT)
98
- self.DIMENSION = space.DIMENSION - 1
99
-
100
- self.SpaceArg = space.SpaceArg
101
- self.space_arg_value = space.space_arg_value
102
-
103
- def node_count(self) -> int:
104
- return self._space.node_count()
105
-
106
- @property
107
- def name(self):
108
- return f"{self._space.name}_Trace"
109
-
110
- @staticmethod
111
- def _make_element_node_index(space: NodalFunctionSpace):
112
- from warp.fem import cache
113
-
114
- NODES_PER_ELEMENT = space.NODES_PER_ELEMENT
115
-
116
- def trace_element_node_index(args: space.SpaceArg, element_index: ElementIndex, node_index_in_elt: int):
117
- if node_index_in_elt < NODES_PER_ELEMENT:
118
- inner_element = space._inner_cell_index(args, element_index)
119
- return space.element_node_index(args, inner_element, node_index_in_elt)
120
-
121
- outer_element = space._outer_cell_index(args, element_index)
122
- return space.element_node_index(args, outer_element, node_index_in_elt - NODES_PER_ELEMENT)
123
-
124
- return cache.get_func(trace_element_node_index, space.name)
125
-
126
- @staticmethod
127
- def _make_node_coords_in_element(space: NodalFunctionSpace):
128
- from warp.fem import cache
129
-
130
- NODES_PER_ELEMENT = space.NODES_PER_ELEMENT
131
-
132
- def trace_node_coords_in_element(
133
- args: space.SpaceArg,
134
- element_index: ElementIndex,
135
- node_index_in_elt: int,
136
- ):
137
- if node_index_in_elt < NODES_PER_ELEMENT:
138
- neighbour_elem = space._inner_cell_index(args, element_index)
139
- neighbour_coords = space.node_coords_in_element(args, neighbour_elem, node_index_in_elt)
140
- else:
141
- neighbour_elem = space._outer_cell_index(args, element_index)
142
- neighbour_coords = space.node_coords_in_element(
143
- args,
144
- neighbour_elem,
145
- node_index_in_elt - NODES_PER_ELEMENT,
146
- )
147
-
148
- return space._cell_to_side_coords(args, element_index, neighbour_elem, neighbour_coords)
149
-
150
- return cache.get_func(trace_node_coords_in_element, space.name)
151
-
152
- @staticmethod
153
- def _make_element_inner_weight(space: NodalFunctionSpace):
154
- from warp.fem import cache
155
-
156
- def trace_element_inner_weight(
157
- args: space.SpaceArg,
158
- element_index: ElementIndex,
159
- coords: Coords,
160
- node_index_in_elt: int,
161
- ):
162
- return space.element_inner_weight(
163
- args,
164
- space._inner_cell_index(args, element_index),
165
- space._inner_cell_coords(args, element_index, coords),
166
- node_index_in_elt,
167
- )
168
-
169
- return cache.get_func(trace_element_inner_weight, space.name)
170
-
171
- @staticmethod
172
- def _make_element_outer_weight(space: NodalFunctionSpace):
173
- from warp.fem import cache
174
-
175
- NODES_PER_ELEMENT = space.NODES_PER_ELEMENT
176
-
177
- def trace_element_outer_weight(
178
- args: space.SpaceArg,
179
- element_index: ElementIndex,
180
- coords: Coords,
181
- node_index_in_elt: int,
182
- ):
183
- return space.element_outer_weight(
184
- args,
185
- space._outer_cell_index(args, element_index),
186
- space._outer_cell_coords(args, element_index, coords),
187
- node_index_in_elt - NODES_PER_ELEMENT,
188
- )
189
-
190
- return cache.get_func(trace_element_outer_weight, space.name)
191
-
192
- @staticmethod
193
- def _make_element_inner_weight_gradient(space: NodalFunctionSpace):
194
- from warp.fem import cache
195
-
196
- def trace_element_inner_weight_gradient(
197
- args: space.SpaceArg,
198
- element_index: ElementIndex,
199
- coords: Coords,
200
- node_index_in_elt: int,
201
- ):
202
- return space.element_inner_weight_gradient(
203
- args,
204
- space._inner_cell_index(args, element_index),
205
- space._inner_cell_coords(args, element_index, coords),
206
- node_index_in_elt,
207
- )
208
-
209
- return cache.get_func(trace_element_inner_weight_gradient, space.name)
210
-
211
- @staticmethod
212
- def _make_element_outer_weight_gradient(space: NodalFunctionSpace):
213
- from warp.fem import cache
214
-
215
- NODES_PER_ELEMENT = space.NODES_PER_ELEMENT
216
-
217
- def trace_element_outer_weight_gradient(
218
- args: space.SpaceArg,
219
- element_index: ElementIndex,
220
- coords: Coords,
221
- node_index_in_elt: int,
222
- ):
223
- return space.element_outer_weight_gradient(
224
- args,
225
- space._outer_cell_index(args, element_index),
226
- space._outer_cell_coords(args, element_index, coords),
227
- node_index_in_elt - NODES_PER_ELEMENT,
228
- )
229
-
230
- return cache.get_func(trace_element_outer_weight_gradient, space.name)
231
-
232
- def __eq__(self, other: "NodalFunctionSpaceTrace") -> bool:
233
- return self._space == other._space