warp-lang 1.4.2__py3-none-manylinux2014_x86_64.whl → 1.5.0__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.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +4 -0
- warp/autograd.py +43 -8
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +21 -2
- warp/build_dll.py +23 -6
- warp/builtins.py +1783 -2
- warp/codegen.py +177 -45
- warp/config.py +2 -2
- warp/context.py +321 -73
- warp/examples/assets/pixel.jpg +0 -0
- warp/examples/benchmarks/benchmark_cloth_paddle.py +86 -0
- warp/examples/benchmarks/benchmark_gemm.py +121 -0
- warp/examples/benchmarks/benchmark_interop_paddle.py +158 -0
- warp/examples/benchmarks/benchmark_tile.py +179 -0
- warp/examples/fem/example_adaptive_grid.py +37 -10
- warp/examples/fem/example_apic_fluid.py +3 -2
- warp/examples/fem/example_convection_diffusion_dg.py +4 -5
- warp/examples/fem/example_deformed_geometry.py +1 -1
- warp/examples/fem/example_diffusion_3d.py +47 -4
- warp/examples/fem/example_distortion_energy.py +220 -0
- warp/examples/fem/example_magnetostatics.py +127 -85
- warp/examples/fem/example_nonconforming_contact.py +5 -5
- warp/examples/fem/example_stokes.py +3 -1
- warp/examples/fem/example_streamlines.py +12 -19
- warp/examples/fem/utils.py +38 -15
- warp/examples/sim/example_cloth.py +2 -25
- warp/examples/sim/example_quadruped.py +2 -1
- warp/examples/tile/example_tile_convolution.py +58 -0
- warp/examples/tile/example_tile_fft.py +47 -0
- warp/examples/tile/example_tile_filtering.py +105 -0
- warp/examples/tile/example_tile_matmul.py +79 -0
- warp/examples/tile/example_tile_mlp.py +375 -0
- warp/fem/__init__.py +8 -0
- warp/fem/cache.py +16 -12
- warp/fem/dirichlet.py +1 -1
- warp/fem/domain.py +44 -1
- warp/fem/field/__init__.py +1 -2
- warp/fem/field/field.py +31 -19
- warp/fem/field/nodal_field.py +101 -49
- warp/fem/field/virtual.py +794 -0
- warp/fem/geometry/__init__.py +2 -2
- warp/fem/geometry/deformed_geometry.py +3 -105
- warp/fem/geometry/element.py +13 -0
- warp/fem/geometry/geometry.py +165 -5
- warp/fem/geometry/grid_2d.py +3 -6
- warp/fem/geometry/grid_3d.py +31 -28
- warp/fem/geometry/hexmesh.py +3 -46
- warp/fem/geometry/nanogrid.py +3 -2
- warp/fem/geometry/{quadmesh_2d.py → quadmesh.py} +280 -159
- warp/fem/geometry/tetmesh.py +2 -43
- warp/fem/geometry/{trimesh_2d.py → trimesh.py} +354 -186
- warp/fem/integrate.py +683 -261
- warp/fem/linalg.py +404 -0
- warp/fem/operator.py +101 -18
- warp/fem/polynomial.py +5 -5
- warp/fem/quadrature/quadrature.py +45 -21
- warp/fem/space/__init__.py +45 -11
- warp/fem/space/basis_function_space.py +451 -0
- warp/fem/space/basis_space.py +58 -11
- warp/fem/space/function_space.py +146 -5
- warp/fem/space/grid_2d_function_space.py +80 -66
- warp/fem/space/grid_3d_function_space.py +113 -68
- warp/fem/space/hexmesh_function_space.py +96 -108
- warp/fem/space/nanogrid_function_space.py +62 -110
- warp/fem/space/quadmesh_function_space.py +208 -0
- warp/fem/space/shape/__init__.py +45 -7
- warp/fem/space/shape/cube_shape_function.py +328 -54
- warp/fem/space/shape/shape_function.py +10 -1
- warp/fem/space/shape/square_shape_function.py +328 -60
- warp/fem/space/shape/tet_shape_function.py +269 -19
- warp/fem/space/shape/triangle_shape_function.py +238 -19
- warp/fem/space/tetmesh_function_space.py +69 -37
- warp/fem/space/topology.py +38 -0
- warp/fem/space/trimesh_function_space.py +179 -0
- warp/fem/utils.py +6 -331
- warp/jax_experimental.py +3 -1
- warp/native/array.h +15 -0
- warp/native/builtin.h +66 -26
- warp/native/bvh.h +4 -0
- warp/native/coloring.cpp +600 -0
- warp/native/cuda_util.cpp +14 -0
- warp/native/cuda_util.h +2 -1
- warp/native/fabric.h +8 -0
- warp/native/hashgrid.h +4 -0
- warp/native/marching.cu +8 -0
- warp/native/mat.h +14 -3
- warp/native/mathdx.cpp +59 -0
- warp/native/mesh.h +4 -0
- warp/native/range.h +13 -1
- warp/native/reduce.cpp +9 -1
- warp/native/reduce.cu +7 -0
- warp/native/runlength_encode.cpp +9 -1
- warp/native/runlength_encode.cu +7 -1
- warp/native/scan.cpp +8 -0
- warp/native/scan.cu +8 -0
- warp/native/scan.h +8 -1
- warp/native/sparse.cpp +8 -0
- warp/native/sparse.cu +8 -0
- warp/native/temp_buffer.h +7 -0
- warp/native/tile.h +1857 -0
- warp/native/tile_gemm.h +341 -0
- warp/native/tile_reduce.h +210 -0
- warp/native/volume_builder.cu +8 -0
- warp/native/volume_builder.h +8 -0
- warp/native/warp.cpp +10 -2
- warp/native/warp.cu +369 -15
- warp/native/warp.h +12 -2
- warp/optim/adam.py +39 -4
- warp/paddle.py +29 -12
- warp/render/render_opengl.py +137 -65
- warp/sim/graph_coloring.py +292 -0
- warp/sim/integrator_euler.py +4 -2
- warp/sim/integrator_featherstone.py +115 -44
- warp/sim/integrator_vbd.py +6 -0
- warp/sim/model.py +88 -15
- warp/stubs.py +569 -4
- warp/tape.py +12 -7
- warp/tests/assets/pixel.npy +0 -0
- warp/tests/aux_test_instancing_gc.py +18 -0
- warp/tests/test_array.py +39 -0
- warp/tests/test_codegen.py +81 -1
- warp/tests/test_codegen_instancing.py +30 -0
- warp/tests/test_collision.py +110 -0
- warp/tests/test_coloring.py +241 -0
- warp/tests/test_context.py +34 -0
- warp/tests/test_examples.py +18 -4
- warp/tests/test_fem.py +453 -113
- warp/tests/test_func.py +13 -0
- warp/tests/test_generics.py +52 -0
- warp/tests/test_iter.py +68 -0
- warp/tests/test_mat_scalar_ops.py +1 -1
- warp/tests/test_mesh_query_point.py +1 -1
- warp/tests/test_module_hashing.py +23 -0
- warp/tests/test_paddle.py +27 -87
- warp/tests/test_print.py +56 -1
- warp/tests/test_spatial.py +1 -1
- warp/tests/test_tile.py +700 -0
- warp/tests/test_tile_mathdx.py +144 -0
- warp/tests/test_tile_mlp.py +383 -0
- warp/tests/test_tile_reduce.py +374 -0
- warp/tests/test_tile_shared_memory.py +190 -0
- warp/tests/test_vbd.py +12 -20
- warp/tests/test_volume.py +43 -0
- warp/tests/unittest_suites.py +19 -2
- warp/tests/unittest_utils.py +4 -0
- warp/types.py +338 -72
- warp/utils.py +22 -1
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/METADATA +33 -7
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/RECORD +153 -126
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/WHEEL +1 -1
- warp/fem/field/test.py +0 -180
- warp/fem/field/trial.py +0 -183
- warp/fem/space/collocated_function_space.py +0 -102
- warp/fem/space/quadmesh_2d_function_space.py +0 -261
- warp/fem/space/trimesh_2d_function_space.py +0 -153
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/top_level.txt +0 -0
warp/fem/geometry/__init__.py
CHANGED
|
@@ -12,6 +12,6 @@ from .partition import (
|
|
|
12
12
|
LinearGeometryPartition,
|
|
13
13
|
WholeGeometryPartition,
|
|
14
14
|
)
|
|
15
|
-
from .
|
|
15
|
+
from .quadmesh import Quadmesh, Quadmesh2D, Quadmesh3D
|
|
16
16
|
from .tetmesh import Tetmesh
|
|
17
|
-
from .
|
|
17
|
+
from .trimesh import Trimesh, Trimesh2D, Trimesh3D
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
|
|
3
1
|
import warp as wp
|
|
4
2
|
from warp.fem import cache
|
|
5
|
-
from warp.fem.types import Coords, ElementIndex, Sample
|
|
3
|
+
from warp.fem.types import Coords, ElementIndex, Sample
|
|
6
4
|
|
|
7
5
|
from .geometry import Geometry
|
|
8
6
|
|
|
@@ -53,8 +51,6 @@ class DeformedGeometry(Geometry):
|
|
|
53
51
|
|
|
54
52
|
self.cell_position = self._make_cell_position()
|
|
55
53
|
self.cell_deformation_gradient = self._make_cell_deformation_gradient()
|
|
56
|
-
self.cell_inverse_deformation_gradient = self._make_cell_inverse_deformation_gradient()
|
|
57
|
-
self.cell_measure = self._make_cell_measure()
|
|
58
54
|
|
|
59
55
|
self.boundary_side_index = self.base.boundary_side_index
|
|
60
56
|
|
|
@@ -66,11 +62,8 @@ class DeformedGeometry(Geometry):
|
|
|
66
62
|
self.side_inner_cell_coords = self._make_side_inner_cell_coords()
|
|
67
63
|
self.side_outer_cell_coords = self._make_side_outer_cell_coords()
|
|
68
64
|
self.side_from_cell_coords = self._make_side_from_cell_coords()
|
|
69
|
-
|
|
70
|
-
self.
|
|
71
|
-
self.side_measure = self._make_side_measure()
|
|
72
|
-
self.side_measure_ratio = self._make_side_measure_ratio()
|
|
73
|
-
self.side_normal = self._make_side_normal()
|
|
65
|
+
|
|
66
|
+
self._make_default_dependent_implementations()
|
|
74
67
|
|
|
75
68
|
@property
|
|
76
69
|
def name(self):
|
|
@@ -111,26 +104,6 @@ class DeformedGeometry(Geometry):
|
|
|
111
104
|
|
|
112
105
|
return cell_deformation_gradient if self._relative else cell_deformation_gradient_absolute
|
|
113
106
|
|
|
114
|
-
def _make_cell_inverse_deformation_gradient(self):
|
|
115
|
-
@cache.dynamic_func(suffix=self.name)
|
|
116
|
-
def cell_inverse_deformation_gradient(cell_arg: self.CellArg, s: Sample):
|
|
117
|
-
return wp.inverse(self.cell_deformation_gradient(cell_arg, s))
|
|
118
|
-
|
|
119
|
-
return cell_inverse_deformation_gradient
|
|
120
|
-
|
|
121
|
-
def _make_cell_measure(self):
|
|
122
|
-
REF_MEASURE = wp.constant(self.reference_cell().measure())
|
|
123
|
-
|
|
124
|
-
@cache.dynamic_func(suffix=self.name)
|
|
125
|
-
def cell_measure(args: self.CellArg, s: Sample):
|
|
126
|
-
return wp.abs(wp.determinant(self.cell_deformation_gradient(args, s))) * REF_MEASURE
|
|
127
|
-
|
|
128
|
-
return cell_measure
|
|
129
|
-
|
|
130
|
-
@wp.func
|
|
131
|
-
def cell_normal(args: Any, s: Sample):
|
|
132
|
-
return wp.vec2(0.0)
|
|
133
|
-
|
|
134
107
|
def _make_side_arg(self):
|
|
135
108
|
@cache.dynamic_struct(suffix=self.name)
|
|
136
109
|
class SideArg:
|
|
@@ -182,81 +155,6 @@ class DeformedGeometry(Geometry):
|
|
|
182
155
|
|
|
183
156
|
return side_deformation_gradient if self._relative else side_deformation_gradient_absolute
|
|
184
157
|
|
|
185
|
-
def _make_side_inner_inverse_deformation_gradient(self):
|
|
186
|
-
@cache.dynamic_func(suffix=self.name)
|
|
187
|
-
def side_inner_inverse_deformation_gradient(args: self.SideArg, s: Sample):
|
|
188
|
-
cell_index = self.side_inner_cell_index(args, s.element_index)
|
|
189
|
-
cell_coords = self.side_inner_cell_coords(args, s.element_index, s.element_coords)
|
|
190
|
-
cell_arg = self.side_to_cell_arg(args)
|
|
191
|
-
return self.cell_inverse_deformation_gradient(cell_arg, make_free_sample(cell_index, cell_coords))
|
|
192
|
-
|
|
193
|
-
def _make_side_outer_inverse_deformation_gradient(self):
|
|
194
|
-
@cache.dynamic_func(suffix=self.name)
|
|
195
|
-
def side_outer_inverse_deformation_gradient(args: self.SideArg, s: Sample):
|
|
196
|
-
cell_index = self.side_outer_cell_index(args, s.element_index)
|
|
197
|
-
cell_coords = self.side_outer_cell_coords(args, s.element_index, s.element_coords)
|
|
198
|
-
cell_arg = self.side_to_cell_arg(args)
|
|
199
|
-
return self.cell_inverse_deformation_gradient(cell_arg, make_free_sample(cell_index, cell_coords))
|
|
200
|
-
|
|
201
|
-
@wp.func
|
|
202
|
-
def _side_measure(F: wp.vec2):
|
|
203
|
-
return wp.length(F)
|
|
204
|
-
|
|
205
|
-
@wp.func
|
|
206
|
-
def _side_measure(F: _mat32):
|
|
207
|
-
Fcross = wp.vec3(
|
|
208
|
-
F[1, 0] * F[2, 1] - F[2, 0] * F[1, 1],
|
|
209
|
-
F[2, 0] * F[0, 1] - F[0, 0] * F[2, 1],
|
|
210
|
-
F[0, 0] * F[1, 1] - F[1, 0] * F[0, 1],
|
|
211
|
-
)
|
|
212
|
-
return wp.length(Fcross)
|
|
213
|
-
|
|
214
|
-
@wp.func
|
|
215
|
-
def _side_normal(F: wp.vec2):
|
|
216
|
-
return wp.normalize(wp.vec2(-F[1], F[0]))
|
|
217
|
-
|
|
218
|
-
@wp.func
|
|
219
|
-
def _side_normal(F: _mat32):
|
|
220
|
-
Fcross = wp.vec3(
|
|
221
|
-
F[1, 0] * F[2, 1] - F[2, 0] * F[1, 1],
|
|
222
|
-
F[2, 0] * F[0, 1] - F[0, 0] * F[2, 1],
|
|
223
|
-
F[0, 0] * F[1, 1] - F[1, 0] * F[0, 1],
|
|
224
|
-
)
|
|
225
|
-
return wp.normalize(Fcross)
|
|
226
|
-
|
|
227
|
-
def _make_side_measure(self):
|
|
228
|
-
REF_MEASURE = wp.constant(self.reference_side().measure())
|
|
229
|
-
|
|
230
|
-
@cache.dynamic_func(suffix=self.name)
|
|
231
|
-
def side_measure(args: self.SideArg, s: Sample):
|
|
232
|
-
F = self.side_deformation_gradient(args, s)
|
|
233
|
-
return DeformedGeometry._side_measure(F) * REF_MEASURE
|
|
234
|
-
|
|
235
|
-
return side_measure
|
|
236
|
-
|
|
237
|
-
def _make_side_measure_ratio(self):
|
|
238
|
-
@cache.dynamic_func(suffix=self.name)
|
|
239
|
-
def side_measure_ratio(args: self.SideArg, s: Sample):
|
|
240
|
-
inner = self.side_inner_cell_index(args, s.element_index)
|
|
241
|
-
outer = self.side_outer_cell_index(args, s.element_index)
|
|
242
|
-
inner_coords = self.side_inner_cell_coords(args, s.element_index, s.element_coords)
|
|
243
|
-
outer_coords = self.side_outer_cell_coords(args, s.element_index, s.element_coords)
|
|
244
|
-
cell_arg = self.side_to_cell_arg(args)
|
|
245
|
-
return self.side_measure(args, s) / wp.min(
|
|
246
|
-
self.cell_measure(cell_arg, make_free_sample(inner, inner_coords)),
|
|
247
|
-
self.cell_measure(cell_arg, make_free_sample(outer, outer_coords)),
|
|
248
|
-
)
|
|
249
|
-
|
|
250
|
-
return side_measure_ratio
|
|
251
|
-
|
|
252
|
-
def _make_side_normal(self):
|
|
253
|
-
@cache.dynamic_func(suffix=self.name)
|
|
254
|
-
def side_normal(args: self.SideArg, s: Sample):
|
|
255
|
-
F = self.side_deformation_gradient(args, s)
|
|
256
|
-
return DeformedGeometry._side_normal(F)
|
|
257
|
-
|
|
258
|
-
return side_normal
|
|
259
|
-
|
|
260
158
|
def _make_side_inner_cell_index(self):
|
|
261
159
|
@cache.dynamic_func(suffix=self.name)
|
|
262
160
|
def side_inner_cell_index(args: self.SideArg, side_index: ElementIndex):
|
warp/fem/geometry/element.py
CHANGED
|
@@ -5,6 +5,9 @@ from warp.fem.types import Coords
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class Element:
|
|
8
|
+
dimension = 0
|
|
9
|
+
"""Intrinsic dimension of the element"""
|
|
10
|
+
|
|
8
11
|
def measure() -> float:
|
|
9
12
|
"""Measure (area, volume, ...) of the reference element"""
|
|
10
13
|
raise NotImplementedError
|
|
@@ -33,6 +36,8 @@ def _point_count_from_order(order: int, family: Polynomial):
|
|
|
33
36
|
|
|
34
37
|
|
|
35
38
|
class Cube(Element):
|
|
39
|
+
dimension = 3
|
|
40
|
+
|
|
36
41
|
@staticmethod
|
|
37
42
|
def measure() -> float:
|
|
38
43
|
return 1.0
|
|
@@ -52,6 +57,8 @@ class Cube(Element):
|
|
|
52
57
|
|
|
53
58
|
|
|
54
59
|
class Square(Element):
|
|
60
|
+
dimension = 2
|
|
61
|
+
|
|
55
62
|
@staticmethod
|
|
56
63
|
def measure() -> float:
|
|
57
64
|
return 1.0
|
|
@@ -71,6 +78,8 @@ class Square(Element):
|
|
|
71
78
|
|
|
72
79
|
|
|
73
80
|
class LinearEdge(Element):
|
|
81
|
+
dimension = 1
|
|
82
|
+
|
|
74
83
|
@staticmethod
|
|
75
84
|
def measure() -> float:
|
|
76
85
|
return 1.0
|
|
@@ -88,6 +97,8 @@ class LinearEdge(Element):
|
|
|
88
97
|
|
|
89
98
|
|
|
90
99
|
class Triangle(Element):
|
|
100
|
+
dimension = 2
|
|
101
|
+
|
|
91
102
|
@staticmethod
|
|
92
103
|
def measure() -> float:
|
|
93
104
|
return 0.5
|
|
@@ -430,6 +441,8 @@ class Triangle(Element):
|
|
|
430
441
|
|
|
431
442
|
|
|
432
443
|
class Tetrahedron(Element):
|
|
444
|
+
dimension = 3
|
|
445
|
+
|
|
433
446
|
@staticmethod
|
|
434
447
|
def measure() -> float:
|
|
435
448
|
return 1.0 / 6.0
|
warp/fem/geometry/geometry.py
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
from typing import Any
|
|
2
2
|
|
|
3
3
|
import warp as wp
|
|
4
|
-
from warp.fem
|
|
4
|
+
from warp.fem import cache
|
|
5
|
+
from warp.fem.types import Coords, ElementIndex, Sample, make_free_sample
|
|
5
6
|
|
|
6
7
|
from .element import Element
|
|
7
8
|
|
|
9
|
+
_mat32 = wp.mat(shape=(3, 2), dtype=float)
|
|
10
|
+
|
|
8
11
|
|
|
9
12
|
class Geometry:
|
|
10
13
|
"""
|
|
@@ -35,6 +38,11 @@ class Geometry:
|
|
|
35
38
|
"""Prototypical element for a side"""
|
|
36
39
|
raise NotImplementedError
|
|
37
40
|
|
|
41
|
+
@property
|
|
42
|
+
def cell_dimension(self) -> int:
|
|
43
|
+
"""Manifold dimension of the geometry cells"""
|
|
44
|
+
return self.reference_cell().dimension
|
|
45
|
+
|
|
38
46
|
@property
|
|
39
47
|
def name(self) -> str:
|
|
40
48
|
return self.__class__.__name__
|
|
@@ -67,7 +75,7 @@ class Geometry:
|
|
|
67
75
|
raise NotImplementedError
|
|
68
76
|
|
|
69
77
|
@staticmethod
|
|
70
|
-
def cell_inverse_deformation_gradient(args: "Geometry.CellArg",
|
|
78
|
+
def cell_inverse_deformation_gradient(args: "Geometry.CellArg", s: "Sample"):
|
|
71
79
|
"""Device function returning the matrix right-transforming a gradient w.r.t. cell space to a gradient w.r.t. world space
|
|
72
80
|
(i.e. the inverse deformation gradient)
|
|
73
81
|
"""
|
|
@@ -115,12 +123,12 @@ class Geometry:
|
|
|
115
123
|
raise NotImplementedError
|
|
116
124
|
|
|
117
125
|
@staticmethod
|
|
118
|
-
def side_deformation_gradient(args: "Geometry.
|
|
119
|
-
"""Device function returning the gradient of world position with respect to reference
|
|
126
|
+
def side_deformation_gradient(args: "Geometry.SideArg", s: "Sample"):
|
|
127
|
+
"""Device function returning the gradient of world position with respect to reference side"""
|
|
120
128
|
raise NotImplementedError
|
|
121
129
|
|
|
122
130
|
@staticmethod
|
|
123
|
-
def side_inner_inverse_deformation_gradient(args: "Geometry.
|
|
131
|
+
def side_inner_inverse_deformation_gradient(args: "Geometry.Siderg", side_index: ElementIndex, coords: Coords):
|
|
124
132
|
"""Device function returning the matrix right-transforming a gradient w.r.t. inner cell space to a gradient w.r.t. world space
|
|
125
133
|
(i.e. the inverse deformation gradient)
|
|
126
134
|
"""
|
|
@@ -182,3 +190,155 @@ class Geometry:
|
|
|
182
190
|
def side_to_cell_arg(side_arg: "Geometry.SideArg"):
|
|
183
191
|
"""Device function converting a side-related argument value to a cell-related argument value, for promoting trace samples to the full space"""
|
|
184
192
|
raise NotImplementedError
|
|
193
|
+
|
|
194
|
+
# Default implementations for dependent quantities
|
|
195
|
+
# Can be overridden in derived classes if more efficient implementations exist
|
|
196
|
+
|
|
197
|
+
def _make_default_dependent_implementations(self):
|
|
198
|
+
self.cell_inverse_deformation_gradient = self._make_cell_inverse_deformation_gradient()
|
|
199
|
+
self.cell_measure = self._make_cell_measure()
|
|
200
|
+
self.cell_normal = self._make_cell_normal()
|
|
201
|
+
|
|
202
|
+
self.side_inner_inverse_deformation_gradient = self._make_side_inner_inverse_deformation_gradient()
|
|
203
|
+
self.side_outer_inverse_deformation_gradient = self._make_side_outer_inverse_deformation_gradient()
|
|
204
|
+
self.side_measure = self._make_side_measure()
|
|
205
|
+
self.side_measure_ratio = self._make_side_measure_ratio()
|
|
206
|
+
self.side_normal = self._make_side_normal()
|
|
207
|
+
|
|
208
|
+
@wp.func
|
|
209
|
+
def _element_measure(F: wp.vec2):
|
|
210
|
+
return wp.length(F)
|
|
211
|
+
|
|
212
|
+
@wp.func
|
|
213
|
+
def _element_measure(F: wp.vec3):
|
|
214
|
+
return wp.length(F)
|
|
215
|
+
|
|
216
|
+
@wp.func
|
|
217
|
+
def _element_measure(F: _mat32):
|
|
218
|
+
Ft = wp.transpose(F)
|
|
219
|
+
Fcross = wp.cross(Ft[0], Ft[1])
|
|
220
|
+
return wp.length(Fcross)
|
|
221
|
+
|
|
222
|
+
@wp.func
|
|
223
|
+
def _element_measure(F: wp.mat33):
|
|
224
|
+
return wp.abs(wp.determinant(F))
|
|
225
|
+
|
|
226
|
+
@wp.func
|
|
227
|
+
def _element_measure(F: wp.mat22):
|
|
228
|
+
return wp.abs(wp.determinant(F))
|
|
229
|
+
|
|
230
|
+
@wp.func
|
|
231
|
+
def _element_normal(F: wp.vec2):
|
|
232
|
+
return wp.normalize(wp.vec2(-F[1], F[0]))
|
|
233
|
+
|
|
234
|
+
@wp.func
|
|
235
|
+
def _element_normal(F: _mat32):
|
|
236
|
+
Ft = wp.transpose(F)
|
|
237
|
+
Fcross = wp.cross(Ft[0], Ft[1])
|
|
238
|
+
return wp.normalize(Fcross)
|
|
239
|
+
|
|
240
|
+
def _make_cell_measure(self):
|
|
241
|
+
REF_MEASURE = wp.constant(self.reference_cell().measure())
|
|
242
|
+
|
|
243
|
+
@cache.dynamic_func(suffix=self.name)
|
|
244
|
+
def cell_measure(args: self.CellArg, s: Sample):
|
|
245
|
+
F = self.cell_deformation_gradient(args, s)
|
|
246
|
+
return Geometry._element_measure(F) * REF_MEASURE
|
|
247
|
+
|
|
248
|
+
return cell_measure
|
|
249
|
+
|
|
250
|
+
def _make_cell_normal(self):
|
|
251
|
+
cell_dim = self.reference_cell().dimension
|
|
252
|
+
geo_dim = self.dimension
|
|
253
|
+
normal_vec = wp.vec(length=geo_dim, dtype=float)
|
|
254
|
+
|
|
255
|
+
@cache.dynamic_func(suffix=self.name)
|
|
256
|
+
def zero_normal(args: self.CellArg, s: Sample):
|
|
257
|
+
return normal_vec(0.0)
|
|
258
|
+
|
|
259
|
+
@cache.dynamic_func(suffix=self.name)
|
|
260
|
+
def cell_hyperplane_normal(args: self.CellArg, s: Sample):
|
|
261
|
+
F = self.cell_deformation_gradient(args, s)
|
|
262
|
+
return Geometry._element_normal(F)
|
|
263
|
+
|
|
264
|
+
if cell_dim == geo_dim:
|
|
265
|
+
return zero_normal
|
|
266
|
+
if cell_dim == geo_dim - 1:
|
|
267
|
+
return cell_hyperplane_normal
|
|
268
|
+
|
|
269
|
+
return None
|
|
270
|
+
|
|
271
|
+
def _make_cell_inverse_deformation_gradient(self):
|
|
272
|
+
cell_dim = self.reference_cell().dimension
|
|
273
|
+
geo_dim = self.dimension
|
|
274
|
+
|
|
275
|
+
@cache.dynamic_func(suffix=self.name)
|
|
276
|
+
def cell_inverse_deformation_gradient(cell_arg: self.CellArg, s: Sample):
|
|
277
|
+
return wp.inverse(self.cell_deformation_gradient(cell_arg, s))
|
|
278
|
+
|
|
279
|
+
@cache.dynamic_func(suffix=self.name)
|
|
280
|
+
def cell_pseudoinverse_deformation_gradient(cell_arg: self.CellArg, s: Sample):
|
|
281
|
+
F = self.cell_deformation_gradient(cell_arg, s)
|
|
282
|
+
Ft = wp.transpose(F)
|
|
283
|
+
return wp.inverse(Ft * F) * Ft
|
|
284
|
+
|
|
285
|
+
return cell_inverse_deformation_gradient if cell_dim == geo_dim else cell_pseudoinverse_deformation_gradient
|
|
286
|
+
|
|
287
|
+
def _make_side_measure(self):
|
|
288
|
+
REF_MEASURE = wp.constant(self.reference_side().measure())
|
|
289
|
+
|
|
290
|
+
@cache.dynamic_func(suffix=self.name)
|
|
291
|
+
def side_measure(args: self.SideArg, s: Sample):
|
|
292
|
+
F = self.side_deformation_gradient(args, s)
|
|
293
|
+
return Geometry._element_measure(F) * REF_MEASURE
|
|
294
|
+
|
|
295
|
+
return side_measure
|
|
296
|
+
|
|
297
|
+
def _make_side_measure_ratio(self):
|
|
298
|
+
@cache.dynamic_func(suffix=self.name)
|
|
299
|
+
def side_measure_ratio(args: self.SideArg, s: Sample):
|
|
300
|
+
inner = self.side_inner_cell_index(args, s.element_index)
|
|
301
|
+
outer = self.side_outer_cell_index(args, s.element_index)
|
|
302
|
+
inner_coords = self.side_inner_cell_coords(args, s.element_index, s.element_coords)
|
|
303
|
+
outer_coords = self.side_outer_cell_coords(args, s.element_index, s.element_coords)
|
|
304
|
+
cell_arg = self.side_to_cell_arg(args)
|
|
305
|
+
return self.side_measure(args, s) / wp.min(
|
|
306
|
+
self.cell_measure(cell_arg, make_free_sample(inner, inner_coords)),
|
|
307
|
+
self.cell_measure(cell_arg, make_free_sample(outer, outer_coords)),
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
return side_measure_ratio
|
|
311
|
+
|
|
312
|
+
def _make_side_normal(self):
|
|
313
|
+
side_dim = self.reference_side().dimension
|
|
314
|
+
geo_dim = self.dimension
|
|
315
|
+
|
|
316
|
+
@cache.dynamic_func(suffix=self.name)
|
|
317
|
+
def hyperplane_normal(args: self.SideArg, s: Sample):
|
|
318
|
+
F = self.side_deformation_gradient(args, s)
|
|
319
|
+
return Geometry._element_normal(F)
|
|
320
|
+
|
|
321
|
+
if side_dim == geo_dim - 1:
|
|
322
|
+
return hyperplane_normal
|
|
323
|
+
|
|
324
|
+
return None
|
|
325
|
+
|
|
326
|
+
def _make_side_inner_inverse_deformation_gradient(self):
|
|
327
|
+
@cache.dynamic_func(suffix=self.name)
|
|
328
|
+
def side_inner_inverse_deformation_gradient(args: self.SideArg, s: Sample):
|
|
329
|
+
cell_index = self.side_inner_cell_index(args, s.element_index)
|
|
330
|
+
cell_coords = self.side_inner_cell_coords(args, s.element_index, s.element_coords)
|
|
331
|
+
cell_arg = self.side_to_cell_arg(args)
|
|
332
|
+
return self.cell_inverse_deformation_gradient(cell_arg, make_free_sample(cell_index, cell_coords))
|
|
333
|
+
|
|
334
|
+
return side_inner_inverse_deformation_gradient
|
|
335
|
+
|
|
336
|
+
def _make_side_outer_inverse_deformation_gradient(self):
|
|
337
|
+
@cache.dynamic_func(suffix=self.name)
|
|
338
|
+
def side_outer_inverse_deformation_gradient(args: self.SideArg, s: Sample):
|
|
339
|
+
cell_index = self.side_outer_cell_index(args, s.element_index)
|
|
340
|
+
cell_coords = self.side_outer_cell_coords(args, s.element_index, s.element_coords)
|
|
341
|
+
cell_arg = self.side_to_cell_arg(args)
|
|
342
|
+
return self.cell_inverse_deformation_gradient(cell_arg, make_free_sample(cell_index, cell_coords))
|
|
343
|
+
|
|
344
|
+
return side_outer_inverse_deformation_gradient
|
warp/fem/geometry/grid_2d.py
CHANGED
|
@@ -29,7 +29,7 @@ class Grid2D(Geometry):
|
|
|
29
29
|
Args:
|
|
30
30
|
res: Resolution of the grid along each dimension
|
|
31
31
|
bounds_lo: Position of the lower bound of the axis-aligned grid
|
|
32
|
-
|
|
32
|
+
bounds_hi: Position of the upper bound of the axis-aligned grid
|
|
33
33
|
"""
|
|
34
34
|
|
|
35
35
|
if bounds_lo is None:
|
|
@@ -158,10 +158,7 @@ class Grid2D(Geometry):
|
|
|
158
158
|
return Grid2D.Side(axis, origin)
|
|
159
159
|
|
|
160
160
|
axis_side_index = side_index - 2 * arg.cell_count
|
|
161
|
-
|
|
162
|
-
axis = 0
|
|
163
|
-
else:
|
|
164
|
-
axis = 1
|
|
161
|
+
axis = wp.select(axis_side_index < arg.axis_offsets[1], 1, 0)
|
|
165
162
|
|
|
166
163
|
altitude = arg.cell_arg.res[Grid2D.ROTATION[axis, 0]]
|
|
167
164
|
longitude = axis_side_index - arg.axis_offsets[axis]
|
|
@@ -230,7 +227,7 @@ class Grid2D(Geometry):
|
|
|
230
227
|
|
|
231
228
|
args.axis_offsets = wp.vec2i(
|
|
232
229
|
0,
|
|
233
|
-
self.res[
|
|
230
|
+
self.res[1],
|
|
234
231
|
)
|
|
235
232
|
args.cell_count = self.cell_count()
|
|
236
233
|
args.cell_arg = self.cell_arg_value(device)
|
warp/fem/geometry/grid_3d.py
CHANGED
|
@@ -23,17 +23,13 @@ class Grid3D(Geometry):
|
|
|
23
23
|
|
|
24
24
|
dimension = 3
|
|
25
25
|
|
|
26
|
-
Permutation = wp.types.matrix(shape=(3, 3), dtype=int)
|
|
27
|
-
LOC_TO_WORLD = wp.constant(Permutation(0, 1, 2, 1, 2, 0, 2, 0, 1))
|
|
28
|
-
WORLD_TO_LOC = wp.constant(Permutation(0, 1, 2, 2, 0, 1, 1, 2, 0))
|
|
29
|
-
|
|
30
26
|
def __init__(self, res: wp.vec3i, bounds_lo: Optional[wp.vec3] = None, bounds_hi: Optional[wp.vec3] = None):
|
|
31
27
|
"""Constructs a dense 3D grid
|
|
32
28
|
|
|
33
29
|
Args:
|
|
34
30
|
res: Resolution of the grid along each dimension
|
|
35
31
|
bounds_lo: Position of the lower bound of the axis-aligned grid
|
|
36
|
-
|
|
32
|
+
bounds_hi: Position of the upper bound of the axis-aligned grid
|
|
37
33
|
"""
|
|
38
34
|
|
|
39
35
|
if bounds_lo is None:
|
|
@@ -148,28 +144,32 @@ class Grid3D(Geometry):
|
|
|
148
144
|
@wp.func
|
|
149
145
|
def _world_to_local(axis: int, vec: Any):
|
|
150
146
|
return type(vec)(
|
|
151
|
-
vec[
|
|
152
|
-
vec[
|
|
153
|
-
vec[
|
|
147
|
+
vec[axis],
|
|
148
|
+
vec[(axis + 1) % 3],
|
|
149
|
+
vec[(axis + 2) % 3],
|
|
154
150
|
)
|
|
155
151
|
|
|
156
152
|
@wp.func
|
|
157
153
|
def _local_to_world(axis: int, vec: Any):
|
|
158
154
|
return type(vec)(
|
|
159
|
-
vec[
|
|
160
|
-
vec[
|
|
161
|
-
vec[
|
|
155
|
+
vec[(2 * axis) % 3],
|
|
156
|
+
vec[(2 * axis + 1) % 3],
|
|
157
|
+
vec[(2 * axis + 2) % 3],
|
|
162
158
|
)
|
|
163
159
|
|
|
160
|
+
@wp.func
|
|
161
|
+
def _local_to_world_axis(axis: int, loc_index: Any):
|
|
162
|
+
return (axis + loc_index) % 3
|
|
163
|
+
|
|
164
164
|
@wp.func
|
|
165
165
|
def side_index(arg: SideArg, side: Side):
|
|
166
|
-
alt_axis = Grid3D.
|
|
166
|
+
alt_axis = Grid3D._local_to_world_axis(side.axis, 0)
|
|
167
167
|
if side.origin[0] == arg.cell_arg.res[alt_axis]:
|
|
168
168
|
# Upper-boundary side
|
|
169
169
|
longitude = side.origin[1]
|
|
170
170
|
latitude = side.origin[2]
|
|
171
171
|
|
|
172
|
-
latitude_res = arg.cell_arg.res[Grid3D.
|
|
172
|
+
latitude_res = arg.cell_arg.res[Grid3D._local_to_world_axis(side.axis, 2)]
|
|
173
173
|
lat_long = latitude_res * longitude + latitude
|
|
174
174
|
|
|
175
175
|
return 3 * arg.cell_count + arg.axis_offsets[side.axis] + lat_long
|
|
@@ -179,24 +179,27 @@ class Grid3D(Geometry):
|
|
|
179
179
|
|
|
180
180
|
@wp.func
|
|
181
181
|
def get_side(arg: SideArg, side_index: ElementIndex):
|
|
182
|
+
res = arg.cell_arg.res
|
|
183
|
+
|
|
182
184
|
if side_index < 3 * arg.cell_count:
|
|
183
185
|
axis = side_index // arg.cell_count
|
|
184
186
|
cell_index = side_index - axis * arg.cell_count
|
|
185
|
-
|
|
186
|
-
return Grid3D.Side(axis,
|
|
187
|
+
origin_loc = Grid3D._world_to_local(axis, Grid3D.get_cell(res, cell_index))
|
|
188
|
+
return Grid3D.Side(axis, origin_loc)
|
|
187
189
|
|
|
190
|
+
axis_offsets = arg.axis_offsets
|
|
188
191
|
axis_side_index = side_index - 3 * arg.cell_count
|
|
189
|
-
if axis_side_index <
|
|
192
|
+
if axis_side_index < axis_offsets[1]:
|
|
190
193
|
axis = 0
|
|
191
|
-
elif axis_side_index <
|
|
194
|
+
elif axis_side_index < axis_offsets[2]:
|
|
192
195
|
axis = 1
|
|
193
196
|
else:
|
|
194
197
|
axis = 2
|
|
195
198
|
|
|
196
|
-
altitude =
|
|
199
|
+
altitude = res[Grid3D._local_to_world_axis(axis, 0)]
|
|
197
200
|
|
|
198
|
-
lat_long = axis_side_index -
|
|
199
|
-
latitude_res =
|
|
201
|
+
lat_long = axis_side_index - axis_offsets[axis]
|
|
202
|
+
latitude_res = res[Grid3D._local_to_world_axis(axis, 2)]
|
|
200
203
|
|
|
201
204
|
longitude = lat_long // latitude_res
|
|
202
205
|
latitude = lat_long - longitude * latitude_res
|
|
@@ -299,7 +302,7 @@ class Grid3D(Geometry):
|
|
|
299
302
|
axis = 2
|
|
300
303
|
|
|
301
304
|
lat_long = axis_side_index - args.axis_offsets[axis]
|
|
302
|
-
latitude_res = args.cell_arg.res[Grid3D.
|
|
305
|
+
latitude_res = args.cell_arg.res[Grid3D._local_to_world_axis(axis, 2)]
|
|
303
306
|
|
|
304
307
|
longitude = lat_long // latitude_res
|
|
305
308
|
latitude = lat_long - longitude * latitude_res
|
|
@@ -347,14 +350,14 @@ class Grid3D(Geometry):
|
|
|
347
350
|
@wp.func
|
|
348
351
|
def side_measure(args: SideArg, s: Sample):
|
|
349
352
|
side = Grid3D.get_side(args, s.element_index)
|
|
350
|
-
long_axis = Grid3D.
|
|
351
|
-
lat_axis = Grid3D.
|
|
353
|
+
long_axis = Grid3D._local_to_world_axis(side.axis, 1)
|
|
354
|
+
lat_axis = Grid3D._local_to_world_axis(side.axis, 2)
|
|
352
355
|
return args.cell_arg.cell_size[long_axis] * args.cell_arg.cell_size[lat_axis]
|
|
353
356
|
|
|
354
357
|
@wp.func
|
|
355
358
|
def side_measure_ratio(args: SideArg, s: Sample):
|
|
356
359
|
side = Grid3D.get_side(args, s.element_index)
|
|
357
|
-
alt_axis = Grid3D.
|
|
360
|
+
alt_axis = Grid3D._local_to_world_axis(side.axis, 0)
|
|
358
361
|
return 1.0 / args.cell_arg.cell_size[alt_axis]
|
|
359
362
|
|
|
360
363
|
@wp.func
|
|
@@ -381,7 +384,7 @@ class Grid3D(Geometry):
|
|
|
381
384
|
def side_outer_cell_index(arg: SideArg, side_index: ElementIndex):
|
|
382
385
|
side = Grid3D.get_side(arg, side_index)
|
|
383
386
|
|
|
384
|
-
alt_axis = Grid3D.
|
|
387
|
+
alt_axis = Grid3D._local_to_world_axis(side.axis, 0)
|
|
385
388
|
|
|
386
389
|
outer_alt = wp.select(
|
|
387
390
|
side.origin[0] == arg.cell_arg.res[alt_axis], side.origin[0], arg.cell_arg.res[alt_axis] - 1
|
|
@@ -406,7 +409,7 @@ class Grid3D(Geometry):
|
|
|
406
409
|
def side_outer_cell_coords(args: SideArg, side_index: ElementIndex, side_coords: Coords):
|
|
407
410
|
side = Grid3D.get_side(args, side_index)
|
|
408
411
|
|
|
409
|
-
alt_axis = Grid3D.
|
|
412
|
+
alt_axis = Grid3D._local_to_world_axis(side.axis, 0)
|
|
410
413
|
outer_alt = wp.select(side.origin[0] == args.cell_arg.res[alt_axis], 0.0, 1.0)
|
|
411
414
|
|
|
412
415
|
side_coord0 = wp.select(side.origin[0] == 0, side_coords[0], 1.0 - side_coords[0])
|
|
@@ -424,8 +427,8 @@ class Grid3D(Geometry):
|
|
|
424
427
|
cell = Grid3D.get_cell(args.cell_arg.res, element_index)
|
|
425
428
|
|
|
426
429
|
if float(side.origin[0] - cell[side.axis]) == element_coords[side.axis]:
|
|
427
|
-
long_axis = Grid3D.
|
|
428
|
-
lat_axis = Grid3D.
|
|
430
|
+
long_axis = Grid3D._local_to_world_axis(side.axis, 1)
|
|
431
|
+
lat_axis = Grid3D._local_to_world_axis(side.axis, 2)
|
|
429
432
|
long_coord = element_coords[long_axis]
|
|
430
433
|
long_coord = wp.select(side.origin[0] == 0, long_coord, 1.0 - long_coord)
|
|
431
434
|
return Coords(long_coord, element_coords[lat_axis], 0.0)
|
warp/fem/geometry/hexmesh.py
CHANGED
|
@@ -7,7 +7,7 @@ from warp.fem.cache import (
|
|
|
7
7
|
borrow_temporary_like,
|
|
8
8
|
cached_arg_value,
|
|
9
9
|
)
|
|
10
|
-
from warp.fem.types import OUTSIDE, Coords, ElementIndex, Sample
|
|
10
|
+
from warp.fem.types import OUTSIDE, Coords, ElementIndex, Sample
|
|
11
11
|
|
|
12
12
|
from .element import Cube, Square
|
|
13
13
|
from .geometry import Geometry
|
|
@@ -142,6 +142,8 @@ class Hexmesh(Geometry):
|
|
|
142
142
|
self._edge_count = 0
|
|
143
143
|
self._build_topology(temporary_store)
|
|
144
144
|
|
|
145
|
+
self._make_default_dependent_implementations()
|
|
146
|
+
|
|
145
147
|
def cell_count(self):
|
|
146
148
|
return self.hex_vertex_indices.shape[0]
|
|
147
149
|
|
|
@@ -246,18 +248,6 @@ class Hexmesh(Geometry):
|
|
|
246
248
|
+ wp.outer(cell_arg.positions[hex_idx[7]], wp.vec3(-w_p[1] * w_p[2], w_m[0] * w_p[2], w_m[0] * w_p[1]))
|
|
247
249
|
)
|
|
248
250
|
|
|
249
|
-
@wp.func
|
|
250
|
-
def cell_inverse_deformation_gradient(cell_arg: CellArg, s: Sample):
|
|
251
|
-
return wp.inverse(Hexmesh.cell_deformation_gradient(cell_arg, s))
|
|
252
|
-
|
|
253
|
-
@wp.func
|
|
254
|
-
def cell_measure(args: CellArg, s: Sample):
|
|
255
|
-
return wp.abs(wp.determinant(Hexmesh.cell_deformation_gradient(args, s)))
|
|
256
|
-
|
|
257
|
-
@wp.func
|
|
258
|
-
def cell_normal(args: CellArg, s: Sample):
|
|
259
|
-
return wp.vec3(0.0)
|
|
260
|
-
|
|
261
251
|
@cached_arg_value
|
|
262
252
|
def side_index_arg_value(self, device) -> SideIndexArg:
|
|
263
253
|
args = self.SideIndexArg()
|
|
@@ -319,39 +309,6 @@ class Hexmesh(Geometry):
|
|
|
319
309
|
v1, v2 = Hexmesh._side_deformation_vecs(args, s.element_index, s.element_coords)
|
|
320
310
|
return _mat32(v1, v2)
|
|
321
311
|
|
|
322
|
-
@wp.func
|
|
323
|
-
def side_inner_inverse_deformation_gradient(args: SideArg, s: Sample):
|
|
324
|
-
cell_index = Hexmesh.side_inner_cell_index(args, s.element_index)
|
|
325
|
-
cell_coords = Hexmesh.side_inner_cell_coords(args, s.element_index, s.element_coords)
|
|
326
|
-
return Hexmesh.cell_inverse_deformation_gradient(args.cell_arg, make_free_sample(cell_index, cell_coords))
|
|
327
|
-
|
|
328
|
-
@wp.func
|
|
329
|
-
def side_outer_inverse_deformation_gradient(args: SideArg, s: Sample):
|
|
330
|
-
cell_index = Hexmesh.side_outer_cell_index(args, s.element_index)
|
|
331
|
-
cell_coords = Hexmesh.side_outer_cell_coords(args, s.element_index, s.element_coords)
|
|
332
|
-
return Hexmesh.cell_inverse_deformation_gradient(args.cell_arg, make_free_sample(cell_index, cell_coords))
|
|
333
|
-
|
|
334
|
-
@wp.func
|
|
335
|
-
def side_measure(args: SideArg, s: Sample):
|
|
336
|
-
v1, v2 = Hexmesh._side_deformation_vecs(args, s.element_index, s.element_coords)
|
|
337
|
-
return wp.length(wp.cross(v1, v2))
|
|
338
|
-
|
|
339
|
-
@wp.func
|
|
340
|
-
def side_measure_ratio(args: SideArg, s: Sample):
|
|
341
|
-
inner = Hexmesh.side_inner_cell_index(args, s.element_index)
|
|
342
|
-
outer = Hexmesh.side_outer_cell_index(args, s.element_index)
|
|
343
|
-
inner_coords = Hexmesh.side_inner_cell_coords(args, s.element_index, s.element_coords)
|
|
344
|
-
outer_coords = Hexmesh.side_outer_cell_coords(args, s.element_index, s.element_coords)
|
|
345
|
-
return Hexmesh.side_measure(args, s) / wp.min(
|
|
346
|
-
Hexmesh.cell_measure(args.cell_arg, make_free_sample(inner, inner_coords)),
|
|
347
|
-
Hexmesh.cell_measure(args.cell_arg, make_free_sample(outer, outer_coords)),
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
@wp.func
|
|
351
|
-
def side_normal(args: SideArg, s: Sample):
|
|
352
|
-
v1, v2 = Hexmesh._side_deformation_vecs(args, s.element_index, s.element_coords)
|
|
353
|
-
return wp.normalize(wp.cross(v1, v2))
|
|
354
|
-
|
|
355
312
|
@wp.func
|
|
356
313
|
def side_inner_cell_index(arg: SideArg, side_index: ElementIndex):
|
|
357
314
|
return arg.face_hex_indices[side_index][0]
|
warp/fem/geometry/nanogrid.py
CHANGED
|
@@ -4,6 +4,7 @@ import numpy as np
|
|
|
4
4
|
|
|
5
5
|
import warp as wp
|
|
6
6
|
from warp.fem import cache, utils
|
|
7
|
+
from warp.fem.linalg import basis_element
|
|
7
8
|
from warp.fem.types import NULL_ELEMENT_INDEX, OUTSIDE, Coords, ElementIndex, Sample, make_free_sample
|
|
8
9
|
|
|
9
10
|
from .element import Cube, Square
|
|
@@ -300,8 +301,8 @@ class Nanogrid(Geometry):
|
|
|
300
301
|
|
|
301
302
|
@wp.func
|
|
302
303
|
def _face_tangent_vecs(cell_grid: wp.uint64, axis: int, flip: int):
|
|
303
|
-
u_axis =
|
|
304
|
-
v_axis =
|
|
304
|
+
u_axis = basis_element(wp.vec3(), (axis + 1 + flip) % 3)
|
|
305
|
+
v_axis = basis_element(wp.vec3(), (axis + 2 - flip) % 3)
|
|
305
306
|
|
|
306
307
|
return wp.volume_index_to_world_dir(cell_grid, u_axis), wp.volume_index_to_world_dir(cell_grid, v_axis)
|
|
307
308
|
|