warp-lang 1.0.0b2__py3-none-win_amd64.whl → 1.0.0b6__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 (271) 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.dll +0 -0
  57. warp/bin/warp.dll +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/bin/warp-clang.so +0 -0
  257. warp/bin/warp.so +0 -0
  258. warp/fem/field/discrete_field.py +0 -80
  259. warp/fem/space/nodal_function_space.py +0 -233
  260. warp/tests/test_all.py +0 -223
  261. warp/tests/test_array_scan.py +0 -60
  262. warp/tests/test_base.py +0 -208
  263. warp/tests/test_unresolved_func.py +0 -7
  264. warp/tests/test_unresolved_symbol.py +0 -7
  265. warp_lang-1.0.0b2.dist-info/METADATA +0 -26
  266. warp_lang-1.0.0b2.dist-info/RECORD +0 -380
  267. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  268. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  269. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  270. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
  271. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  import warp as wp
2
2
 
3
- from warp.fem.types import ElementIndex, Coords, vec2i, Sample, NULL_QP_INDEX, NULL_DOF_INDEX
3
+ from warp.fem.types import ElementIndex, Coords, Sample, make_free_sample, OUTSIDE
4
+ from warp.fem.cache import cached_arg_value
4
5
 
5
6
  from .geometry import Geometry
6
7
  from .element import Square, LinearEdge
@@ -8,7 +9,7 @@ from .element import Square, LinearEdge
8
9
 
9
10
  @wp.struct
10
11
  class Grid2DCellArg:
11
- res: vec2i
12
+ res: wp.vec2i
12
13
  cell_size: wp.vec2
13
14
  origin: wp.vec2
14
15
 
@@ -16,10 +17,12 @@ class Grid2DCellArg:
16
17
  class Grid2D(Geometry):
17
18
  """Two-dimensional regular grid geometry"""
18
19
 
20
+ dimension = 2
21
+
19
22
  Permutation = wp.types.matrix(shape=(2, 2), dtype=int)
20
23
  ROTATION = wp.constant(Permutation(0, 1, 1, 0))
21
24
 
22
- def __init__(self, res: vec2i, bounds_lo: wp.vec2 = wp.vec2(0.0), bounds_hi: wp.vec2 = wp.vec2(1.0)):
25
+ def __init__(self, res: wp.vec2i, bounds_lo: wp.vec2 = wp.vec2(0.0), bounds_hi: wp.vec2 = wp.vec2(1.0)):
23
26
  """Constructs a dense 2D grid
24
27
 
25
28
  Args:
@@ -28,15 +31,18 @@ class Grid2D(Geometry):
28
31
  bounds_up: Position of the upper bound of the axis-aligned grid
29
32
  """
30
33
 
31
- self.dimension = 2
32
34
  self.bounds_lo = bounds_lo
33
35
  self.bounds_hi = bounds_hi
34
36
 
35
37
  self._res = res
36
38
 
37
39
  @property
38
- def extents(self) -> wp.vec2:
39
- return self.bounds_hi - self.bounds_lo
40
+ def extents(self) -> wp.vec3:
41
+ # Avoid using native sub due to higher over of calling builtins from Python
42
+ return wp.vec2(
43
+ self.bounds_hi[0] - self.bounds_lo[0],
44
+ self.bounds_hi[1] - self.bounds_lo[1],
45
+ )
40
46
 
41
47
  @property
42
48
  def cell_size(self) -> wp.vec2:
@@ -74,46 +80,46 @@ class Grid2D(Geometry):
74
80
 
75
81
  @property
76
82
  def strides(self):
77
- return vec2i(self.res[1], 1)
83
+ return wp.vec2i(self.res[1], 1)
78
84
 
79
85
  # Utility device functions
80
86
  CellArg = Grid2DCellArg
81
- Cell = vec2i
87
+ Cell = wp.vec2i
82
88
 
83
89
  @wp.func
84
90
  def _to_2d_index(x_stride: int, index: int):
85
91
  x = index // x_stride
86
92
  y = index - x_stride * x
87
- return vec2i(x, y)
93
+ return wp.vec2i(x, y)
88
94
 
89
95
  @wp.func
90
- def _from_2d_index(x_stride: int, index: vec2i):
96
+ def _from_2d_index(x_stride: int, index: wp.vec2i):
91
97
  return x_stride * index[0] + index[1]
92
98
 
93
99
  @wp.func
94
- def cell_index(res: vec2i, cell: Cell):
100
+ def cell_index(res: wp.vec2i, cell: Cell):
95
101
  return Grid2D._from_2d_index(res[1], cell)
96
102
 
97
103
  @wp.func
98
- def get_cell(res: vec2i, cell_index: ElementIndex):
104
+ def get_cell(res: wp.vec2i, cell_index: ElementIndex):
99
105
  return Grid2D._to_2d_index(res[1], cell_index)
100
106
 
101
107
  @wp.struct
102
108
  class Side:
103
109
  axis: int # normal; 0: horizontal, 1: vertical
104
- origin: vec2i # index of vertex at corner (0,0)
110
+ origin: wp.vec2i # index of vertex at corner (0,0)
105
111
 
106
112
  @wp.struct
107
113
  class SideArg:
108
114
  cell_count: int
109
- axis_offsets: vec2i
115
+ axis_offsets: wp.vec2i
110
116
  cell_arg: Grid2DCellArg
111
117
 
112
118
  SideIndexArg = SideArg
113
119
 
114
120
  @wp.func
115
- def _rotate(axis: int, vec: vec2i):
116
- return vec2i(
121
+ def _rotate(axis: int, vec: wp.vec2i):
122
+ return wp.vec2i(
117
123
  vec[Grid2D.ROTATION[axis, 0]],
118
124
  vec[Grid2D.ROTATION[axis, 1]],
119
125
  )
@@ -125,7 +131,6 @@ class Grid2D(Geometry):
125
131
  vec[Grid2D.ROTATION[axis, 1]],
126
132
  )
127
133
 
128
-
129
134
  @wp.func
130
135
  def side_index(arg: SideArg, side: Side):
131
136
  alt_axis = Grid2D.ROTATION[side.axis, 0]
@@ -154,11 +159,12 @@ class Grid2D(Geometry):
154
159
  altitude = arg.cell_arg.res[Grid2D.ROTATION[axis, 0]]
155
160
  longitude = axis_side_index - arg.axis_offsets[axis]
156
161
 
157
- origin_loc = vec2i(altitude, longitude)
162
+ origin_loc = wp.vec2i(altitude, longitude)
158
163
  return Grid2D.Side(axis, origin_loc)
159
164
 
160
165
  # Geometry device interface
161
166
 
167
+ @cached_arg_value
162
168
  def cell_arg_value(self, device) -> CellArg:
163
169
  args = self.CellArg()
164
170
  args.res = self.res
@@ -177,6 +183,14 @@ class Grid2D(Geometry):
177
183
  + args.origin
178
184
  )
179
185
 
186
+ @wp.func
187
+ def cell_deformation_gradient(args: CellArg, s: Sample):
188
+ return wp.diag(args.cell_size)
189
+
190
+ @wp.func
191
+ def cell_inverse_deformation_gradient(args: CellArg, s: Sample):
192
+ return wp.diag(wp.cw_div(wp.vec2(1.0), args.cell_size))
193
+
180
194
  @wp.func
181
195
  def cell_lookup(args: CellArg, pos: wp.vec2):
182
196
  loc_pos = wp.cw_div(pos - args.origin, args.cell_size)
@@ -189,46 +203,39 @@ class Grid2D(Geometry):
189
203
  coords = Coords(x - x_cell, y - y_cell, 0.0)
190
204
  cell_index = Grid2D.cell_index(args.res, Grid2D.Cell(int(x_cell), int(y_cell)))
191
205
 
192
- return Sample(cell_index, coords, NULL_QP_INDEX, 0.0, NULL_DOF_INDEX, NULL_DOF_INDEX)
206
+ return make_free_sample(cell_index, coords)
193
207
 
194
208
  @wp.func
195
209
  def cell_lookup(args: CellArg, pos: wp.vec2, guess: Sample):
196
210
  return Grid2D.cell_lookup(args, pos)
197
211
 
198
- @wp.func
199
- def cell_measure(args: CellArg, cell_index: ElementIndex, coords: Coords):
200
- return args.cell_size[0] * args.cell_size[1]
201
-
202
212
  @wp.func
203
213
  def cell_measure(args: CellArg, s: Sample):
204
- return Grid2D.cell_measure(args, s.element_index, s.element_coords)
205
-
206
- @wp.func
207
- def cell_measure_ratio(args: CellArg, s: Sample):
208
- return 1.0
214
+ return args.cell_size[0] * args.cell_size[1]
209
215
 
210
216
  @wp.func
211
217
  def cell_normal(args: CellArg, s: Sample):
212
218
  return wp.vec2(0.0)
213
219
 
220
+ @cached_arg_value
214
221
  def side_arg_value(self, device) -> SideArg:
215
222
  args = self.SideArg()
216
-
217
- args.axis_offsets = vec2i(
223
+
224
+ args.axis_offsets = wp.vec2i(
218
225
  0,
219
226
  self.res[0],
220
227
  )
221
228
  args.cell_count = self.cell_count()
222
229
  args.cell_arg = self.cell_arg_value(device)
223
230
  return args
224
-
231
+
225
232
  def side_index_arg_value(self, device) -> SideIndexArg:
226
233
  return self.side_arg_value(device)
227
234
 
228
235
  @wp.func
229
236
  def boundary_side_index(args: SideArg, boundary_side_index: int):
230
237
  """Boundary side to side index"""
231
-
238
+
232
239
  axis_side_index = boundary_side_index // 2
233
240
  border = boundary_side_index - 2 * axis_side_index
234
241
 
@@ -240,16 +247,18 @@ class Grid2D(Geometry):
240
247
  longitude = axis_side_index - args.axis_offsets[axis]
241
248
  altitude = border * args.cell_arg.res[axis]
242
249
 
243
- side = Grid2D.Side(axis, vec2i(altitude, longitude))
250
+ side = Grid2D.Side(axis, wp.vec2i(altitude, longitude))
244
251
  return Grid2D.side_index(args, side)
245
252
 
246
253
  @wp.func
247
254
  def side_position(args: SideArg, s: Sample):
248
255
  side = Grid2D.get_side(args, s.element_index)
249
256
 
257
+ coord = wp.select((side.origin[0] == 0) == (side.axis == 0), 1.0 - s.element_coords[0], s.element_coords[0])
258
+
250
259
  local_pos = wp.vec2(
251
260
  float(side.origin[0]),
252
- float(side.origin[1]) + s.element_coords[0],
261
+ float(side.origin[1]) + coord,
253
262
  )
254
263
 
255
264
  pos = args.cell_arg.origin + wp.cw_mul(Grid2D._rotate(side.axis, local_pos), args.cell_arg.cell_size)
@@ -257,14 +266,26 @@ class Grid2D(Geometry):
257
266
  return pos
258
267
 
259
268
  @wp.func
260
- def side_measure(args: SideArg, side_index: ElementIndex, coords: Coords):
261
- side = Grid2D.get_side(args, side_index)
262
- long_axis = Grid2D.ROTATION[side.axis, 1]
263
- return args.cell_arg.cell_size[long_axis]
269
+ def side_deformation_gradient(args: SideArg, s: Sample):
270
+ side = Grid2D.get_side(args, s.element_index)
271
+
272
+ sign = wp.select((side.origin[0] == 0) == (side.axis == 0), -1.0, 1.0)
273
+
274
+ return wp.cw_mul(Grid2D._rotate(side.axis, wp.vec2(0.0, sign)), args.cell_arg.cell_size)
275
+
276
+ @wp.func
277
+ def side_inner_inverse_deformation_gradient(args: SideArg, s: Sample):
278
+ return Grid2D.cell_inverse_deformation_gradient(args.cell_arg, s)
279
+
280
+ @wp.func
281
+ def side_outer_inverse_deformation_gradient(args: SideArg, s: Sample):
282
+ return Grid2D.cell_inverse_deformation_gradient(args.cell_arg, s)
264
283
 
265
284
  @wp.func
266
285
  def side_measure(args: SideArg, s: Sample):
267
- return args.cell_arg.cell_size
286
+ side = Grid2D.get_side(args, s.element_index)
287
+ long_axis = Grid2D.ROTATION[side.axis, 1]
288
+ return args.cell_arg.cell_size[long_axis]
268
289
 
269
290
  @wp.func
270
291
  def side_measure_ratio(args: SideArg, s: Sample):
@@ -276,10 +297,7 @@ class Grid2D(Geometry):
276
297
  def side_normal(args: SideArg, s: Sample):
277
298
  side = Grid2D.get_side(args, s.element_index)
278
299
 
279
- if side.origin[0] == 0:
280
- sign = -1.0
281
- else:
282
- sign = 1.0
300
+ sign = wp.select(side.origin[0] == 0, 1.0, -1.0)
283
301
 
284
302
  local_n = wp.vec2(sign, 0.0)
285
303
  return Grid2D._rotate(side.axis, local_n)
@@ -288,12 +306,9 @@ class Grid2D(Geometry):
288
306
  def side_inner_cell_index(arg: SideArg, side_index: ElementIndex):
289
307
  side = Grid2D.get_side(arg, side_index)
290
308
 
291
- if side.origin[0] == 0:
292
- inner_alt = 0
293
- else:
294
- inner_alt = side.origin[0] - 1
309
+ inner_alt = wp.select(side.origin[0] == 0, side.origin[0] - 1, 0)
295
310
 
296
- inner_origin = vec2i(inner_alt, side.origin[1])
311
+ inner_origin = wp.vec2i(inner_alt, side.origin[1])
297
312
 
298
313
  cell = Grid2D._rotate(side.axis, inner_origin)
299
314
  return Grid2D.cell_index(arg.cell_arg.res, cell)
@@ -303,13 +318,56 @@ class Grid2D(Geometry):
303
318
  side = Grid2D.get_side(arg, side_index)
304
319
 
305
320
  alt_axis = Grid2D.ROTATION[side.axis, 0]
321
+ outer_alt = wp.select(
322
+ side.origin[0] == arg.cell_arg.res[alt_axis], side.origin[0], arg.cell_arg.res[alt_axis] - 1
323
+ )
306
324
 
307
- if side.origin[0] == arg.cell_arg.res[alt_axis]:
308
- outer_alt = arg.cell_arg.res[alt_axis] - 1
309
- else:
310
- outer_alt = side.origin[0]
311
-
312
- outer_origin = vec2i(outer_alt, side.origin[1])
325
+ outer_origin = wp.vec2i(outer_alt, side.origin[1])
313
326
 
314
327
  cell = Grid2D._rotate(side.axis, outer_origin)
315
328
  return Grid2D.cell_index(arg.cell_arg.res, cell)
329
+
330
+ @wp.func
331
+ def side_inner_cell_coords(args: SideArg, side_index: ElementIndex, side_coords: Coords):
332
+ side = Grid2D.get_side(args, side_index)
333
+
334
+ inner_alt = wp.select(side.origin[0] == 0, 1.0, 0.0)
335
+
336
+ side_coord = wp.select((side.origin[0] == 0) == (side.axis == 0), 1.0 - side_coords[0], side_coords[0])
337
+
338
+ coords = Grid2D._rotate(side.axis, wp.vec2(inner_alt, side_coord))
339
+ return Coords(coords[0], coords[1], 0.0)
340
+
341
+ @wp.func
342
+ def side_outer_cell_coords(args: SideArg, side_index: ElementIndex, side_coords: Coords):
343
+ side = Grid2D.get_side(args, side_index)
344
+
345
+ alt_axis = Grid2D.ROTATION[side.axis, 0]
346
+ outer_alt = wp.select(side.origin[0] == args.cell_arg.res[alt_axis], 0.0, 1.0)
347
+
348
+ side_coord = wp.select((side.origin[0] == 0) == (side.axis == 0), 1.0 - side_coords[0], side_coords[0])
349
+
350
+ coords = Grid2D._rotate(side.axis, wp.vec2(outer_alt, side_coord))
351
+ return Coords(coords[0], coords[1], 0.0)
352
+
353
+ @wp.func
354
+ def side_from_cell_coords(
355
+ args: SideArg,
356
+ side_index: ElementIndex,
357
+ element_index: ElementIndex,
358
+ element_coords: Coords,
359
+ ):
360
+ side = Grid2D.get_side(args, side_index)
361
+ cell = Grid2D.get_cell(args.cell_arg.res, element_index)
362
+
363
+ if float(side.origin[0] - cell[side.axis]) == element_coords[side.axis]:
364
+ long_axis = Grid2D.ROTATION[side.axis, 1]
365
+ axis_coord = element_coords[long_axis]
366
+ side_coord = wp.select((side.origin[0] == 0) == (side.axis == 0), 1.0 - axis_coord, axis_coord)
367
+ return Coords(side_coord, 0.0, 0.0)
368
+
369
+ return Coords(OUTSIDE)
370
+
371
+ @wp.func
372
+ def side_to_cell_arg(side_arg: SideArg):
373
+ return side_arg.cell_arg