warp-lang 1.4.2__py3-none-win_amd64.whl → 1.5.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +4 -0
- warp/autograd.py +43 -8
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +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
|
@@ -4,6 +4,8 @@ import warp as wp
|
|
|
4
4
|
from warp.fem import cache
|
|
5
5
|
from warp.fem.types import Coords
|
|
6
6
|
|
|
7
|
+
from .shape_function import ShapeFunction
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
def _tet_node_index(tx: int, ty: int, tz: int, degree: int):
|
|
9
11
|
from .triangle_shape_function import _triangle_node_index
|
|
@@ -91,18 +93,79 @@ def _tet_node_index(tx: int, ty: int, tz: int, degree: int):
|
|
|
91
93
|
return VERTEX_EDGE_FACE_NODE_COUNT + _tet_node_index(tx - 1, ty - 1, tz - 1, degree - 4)
|
|
92
94
|
|
|
93
95
|
|
|
94
|
-
class
|
|
96
|
+
class TetrahedronShapeFunction(ShapeFunction):
|
|
95
97
|
VERTEX = wp.constant(0)
|
|
96
98
|
EDGE = wp.constant(1)
|
|
97
99
|
FACE = wp.constant(2)
|
|
98
100
|
INTERIOR = wp.constant(3)
|
|
99
101
|
|
|
102
|
+
VERTEX_NODE_COUNT: int
|
|
103
|
+
"""Number of shape function nodes per vertex"""
|
|
104
|
+
|
|
105
|
+
EDGE_NODE_COUNT: int
|
|
106
|
+
"""Number of shape function nodes per tet edge (excluding vertex nodes)"""
|
|
107
|
+
|
|
108
|
+
FACE_NODE_COUNT: int
|
|
109
|
+
"""Number of shape function nodes per tet face (excluding edge and vertex nodes)"""
|
|
110
|
+
|
|
111
|
+
INTERIOR_NODE_COUNT: int
|
|
112
|
+
"""Number of shape function nodes per tet (excluding face, edge and vertex nodes)"""
|
|
113
|
+
|
|
114
|
+
@staticmethod
|
|
115
|
+
def node_type_and_index(node_index_in_elt: int):
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
@wp.func
|
|
119
|
+
def edge_vidx(edge: int):
|
|
120
|
+
if edge < 3:
|
|
121
|
+
c1 = edge
|
|
122
|
+
c2 = (edge + 1) % 3
|
|
123
|
+
else:
|
|
124
|
+
c1 = edge - 3
|
|
125
|
+
c2 = 3
|
|
126
|
+
return c1, c2
|
|
127
|
+
|
|
128
|
+
@wp.func
|
|
129
|
+
def opposite_edge_vidx(edge: int):
|
|
130
|
+
if edge < 3:
|
|
131
|
+
e1 = (edge + 2) % 3
|
|
132
|
+
e2 = 3
|
|
133
|
+
else:
|
|
134
|
+
e1 = (edge - 2) % 3
|
|
135
|
+
e2 = (edge - 1) % 3
|
|
136
|
+
return e1, e2
|
|
137
|
+
|
|
138
|
+
@wp.func
|
|
139
|
+
def _vertex_coords(vidx: int):
|
|
140
|
+
return wp.vec3(
|
|
141
|
+
float(vidx == 1),
|
|
142
|
+
float(vidx == 2),
|
|
143
|
+
float(vidx == 3),
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class TetrahedronPolynomialShapeFunctions(TetrahedronShapeFunction):
|
|
100
148
|
def __init__(self, degree: int):
|
|
101
149
|
self.ORDER = wp.constant(degree)
|
|
102
150
|
|
|
103
151
|
self.NODES_PER_ELEMENT = wp.constant((degree + 1) * (degree + 2) * (degree + 3) // 6)
|
|
104
152
|
self.NODES_PER_SIDE = wp.constant((degree + 1) * (degree + 2) // 2)
|
|
105
153
|
|
|
154
|
+
self.VERTEX_NODE_COUNT = wp.constant(1)
|
|
155
|
+
self.EDGE_NODE_COUNT = wp.constant(degree - 1)
|
|
156
|
+
self.NODES_PER_ELEMENT = wp.constant((degree + 1) * (degree + 2) * (degree + 3) // 6)
|
|
157
|
+
self.NODES_PER_SIDE = wp.constant((degree + 1) * (degree + 2) // 2)
|
|
158
|
+
|
|
159
|
+
self.SIDE_NODE_COUNT = wp.constant(self.NODES_PER_ELEMENT - 3 * (self.VERTEX_NODE_COUNT + self.EDGE_NODE_COUNT))
|
|
160
|
+
self.INTERIOR_NODE_COUNT = wp.constant(
|
|
161
|
+
self.NODES_PER_ELEMENT - 3 * (self.VERTEX_NODE_COUNT + self.EDGE_NODE_COUNT)
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
self.VERTEX_NODE_COUNT = wp.constant(1)
|
|
165
|
+
self.EDGE_NODE_COUNT = wp.constant(degree - 1)
|
|
166
|
+
self.FACE_NODE_COUNT = wp.constant(max(0, degree - 2) * max(0, degree - 1) // 2)
|
|
167
|
+
self.INERIOR_NODE_COUNT = wp.constant(max(0, degree - 1) * max(0, degree - 2) * max(0, degree - 3) // 6)
|
|
168
|
+
|
|
106
169
|
tet_coords = np.empty((self.NODES_PER_ELEMENT, 3), dtype=int)
|
|
107
170
|
|
|
108
171
|
for tx in range(degree + 1):
|
|
@@ -127,11 +190,7 @@ class TetrahedronPolynomialShapeFunctions:
|
|
|
127
190
|
def node_tet_coordinates(
|
|
128
191
|
node_index_in_elt: int,
|
|
129
192
|
):
|
|
130
|
-
return
|
|
131
|
-
NODE_TET_COORDS[node_index_in_elt, 0],
|
|
132
|
-
NODE_TET_COORDS[node_index_in_elt, 1],
|
|
133
|
-
NODE_TET_COORDS[node_index_in_elt, 2],
|
|
134
|
-
)
|
|
193
|
+
return NODE_TET_COORDS[node_index_in_elt]
|
|
135
194
|
|
|
136
195
|
return cache.get_func(node_tet_coordinates, self.name)
|
|
137
196
|
|
|
@@ -261,12 +320,7 @@ class TetrahedronPolynomialShapeFunctions:
|
|
|
261
320
|
|
|
262
321
|
elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
|
|
263
322
|
# Edge
|
|
264
|
-
|
|
265
|
-
c1 = type_index
|
|
266
|
-
c2 = (type_index + 1) % 3
|
|
267
|
-
else:
|
|
268
|
-
c1 = type_index - 3
|
|
269
|
-
c2 = 3
|
|
323
|
+
c1, c2 = TetrahedronShapeFunction.edge_vidx(type_index)
|
|
270
324
|
return 4.0 * tet_coords[c1] * tet_coords[c2]
|
|
271
325
|
|
|
272
326
|
return 0.0
|
|
@@ -355,12 +409,7 @@ class TetrahedronPolynomialShapeFunctions:
|
|
|
355
409
|
|
|
356
410
|
elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
|
|
357
411
|
# Edge
|
|
358
|
-
|
|
359
|
-
c1 = type_index
|
|
360
|
-
c2 = (type_index + 1) % 3
|
|
361
|
-
else:
|
|
362
|
-
c1 = type_index - 3
|
|
363
|
-
c2 = 3
|
|
412
|
+
c1, c2 = TetrahedronShapeFunction.edge_vidx(type_index)
|
|
364
413
|
dw_dc[c1] = 4.0 * tet_coords[c2]
|
|
365
414
|
dw_dc[c2] = 4.0 * tet_coords[c1]
|
|
366
415
|
|
|
@@ -451,7 +500,7 @@ class TetrahedronPolynomialShapeFunctions:
|
|
|
451
500
|
return cells[np.newaxis, :], np.array([cell_type], dtype=np.int8)
|
|
452
501
|
|
|
453
502
|
|
|
454
|
-
class TetrahedronNonConformingPolynomialShapeFunctions:
|
|
503
|
+
class TetrahedronNonConformingPolynomialShapeFunctions(ShapeFunction):
|
|
455
504
|
def __init__(self, degree: int):
|
|
456
505
|
self._tet_shape = TetrahedronPolynomialShapeFunctions(degree=degree)
|
|
457
506
|
self.ORDER = self._tet_shape.ORDER
|
|
@@ -567,3 +616,204 @@ class TetrahedronNonConformingPolynomialShapeFunctions:
|
|
|
567
616
|
return grad / TET_SCALE
|
|
568
617
|
|
|
569
618
|
return element_inner_weight_gradient
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
class TetrahedronNedelecFirstKindShapeFunctions(TetrahedronShapeFunction):
|
|
622
|
+
value = ShapeFunction.Value.CovariantVector
|
|
623
|
+
|
|
624
|
+
def __init__(self, degree: int):
|
|
625
|
+
if degree != 1:
|
|
626
|
+
raise NotImplementedError("Only linear Nédélec implemented right now")
|
|
627
|
+
|
|
628
|
+
self.ORDER = wp.constant(degree)
|
|
629
|
+
|
|
630
|
+
self.NODES_PER_ELEMENT = wp.constant(6)
|
|
631
|
+
self.NODES_PER_SIDE = wp.constant(3)
|
|
632
|
+
|
|
633
|
+
self.VERTEX_NODE_COUNT = wp.constant(0)
|
|
634
|
+
self.EDGE_NODE_COUNT = wp.constant(1)
|
|
635
|
+
self.FACE_NODE_COUNT = wp.constant(0)
|
|
636
|
+
self.INTERIOR_NODE_COUNT = wp.constant(0)
|
|
637
|
+
|
|
638
|
+
self.node_type_and_type_index = self._get_node_type_and_type_index()
|
|
639
|
+
|
|
640
|
+
@property
|
|
641
|
+
def name(self) -> str:
|
|
642
|
+
return f"TetN1_{self.ORDER}"
|
|
643
|
+
|
|
644
|
+
def _get_node_type_and_type_index(self):
|
|
645
|
+
@cache.dynamic_func(suffix=self.name)
|
|
646
|
+
def node_type_and_index(
|
|
647
|
+
node_index_in_elt: int,
|
|
648
|
+
):
|
|
649
|
+
return TetrahedronShapeFunction.EDGE, node_index_in_elt
|
|
650
|
+
|
|
651
|
+
return node_type_and_index
|
|
652
|
+
|
|
653
|
+
def make_node_coords_in_element(self):
|
|
654
|
+
@cache.dynamic_func(suffix=self.name)
|
|
655
|
+
def node_coords_in_element(
|
|
656
|
+
node_index_in_elt: int,
|
|
657
|
+
):
|
|
658
|
+
c1, c2 = TetrahedronShapeFunction.edge_vidx(node_index_in_elt)
|
|
659
|
+
|
|
660
|
+
coords = wp.vec4(0.0)
|
|
661
|
+
coords[c1] = 0.5
|
|
662
|
+
coords[c2] = 0.5
|
|
663
|
+
|
|
664
|
+
return Coords(coords[1], coords[2], coords[3])
|
|
665
|
+
|
|
666
|
+
return node_coords_in_element
|
|
667
|
+
|
|
668
|
+
def make_node_quadrature_weight(self):
|
|
669
|
+
NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
|
|
670
|
+
|
|
671
|
+
@cache.dynamic_func(suffix=self.name)
|
|
672
|
+
def node_quadrature_weight(node_index_in_element: int):
|
|
673
|
+
return 1.0 / float(NODES_PER_ELEMENT)
|
|
674
|
+
|
|
675
|
+
return node_quadrature_weight
|
|
676
|
+
|
|
677
|
+
def make_trace_node_quadrature_weight(self):
|
|
678
|
+
NODES_PER_SIDE = self.NODES_PER_SIDE
|
|
679
|
+
|
|
680
|
+
@cache.dynamic_func(suffix=self.name)
|
|
681
|
+
def trace_node_quadrature_weight(node_index_in_element: int):
|
|
682
|
+
return 1.0 / float(NODES_PER_SIDE)
|
|
683
|
+
|
|
684
|
+
return trace_node_quadrature_weight
|
|
685
|
+
|
|
686
|
+
def make_element_inner_weight(self):
|
|
687
|
+
ORDER = self.ORDER
|
|
688
|
+
|
|
689
|
+
def element_inner_weight_linear(
|
|
690
|
+
coords: Coords,
|
|
691
|
+
node_index_in_elt: int,
|
|
692
|
+
):
|
|
693
|
+
e1, e2 = TetrahedronShapeFunction.opposite_edge_vidx(node_index_in_elt)
|
|
694
|
+
|
|
695
|
+
v1 = self._vertex_coords(e1)
|
|
696
|
+
v2 = self._vertex_coords(e2)
|
|
697
|
+
|
|
698
|
+
nor = v2 - v1
|
|
699
|
+
return wp.cross(nor, coords - v1)
|
|
700
|
+
|
|
701
|
+
if ORDER == 1:
|
|
702
|
+
return cache.get_func(element_inner_weight_linear, self.name)
|
|
703
|
+
|
|
704
|
+
return None
|
|
705
|
+
|
|
706
|
+
def make_element_inner_weight_gradient(self):
|
|
707
|
+
ORDER = self.ORDER
|
|
708
|
+
|
|
709
|
+
def element_inner_weight_gradient_linear(
|
|
710
|
+
coords: Coords,
|
|
711
|
+
node_index_in_elt: int,
|
|
712
|
+
):
|
|
713
|
+
e1, e2 = TetrahedronShapeFunction.opposite_edge_vidx(node_index_in_elt)
|
|
714
|
+
|
|
715
|
+
v1 = self._vertex_coords(e1)
|
|
716
|
+
v2 = self._vertex_coords(e2)
|
|
717
|
+
|
|
718
|
+
nor = v2 - v1
|
|
719
|
+
return wp.skew(nor)
|
|
720
|
+
|
|
721
|
+
if ORDER == 1:
|
|
722
|
+
return cache.get_func(element_inner_weight_gradient_linear, self.name)
|
|
723
|
+
|
|
724
|
+
return None
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
class TetrahedronRaviartThomasShapeFunctions(TetrahedronShapeFunction):
|
|
728
|
+
value = ShapeFunction.Value.ContravariantVector
|
|
729
|
+
|
|
730
|
+
def __init__(self, degree: int):
|
|
731
|
+
if degree != 1:
|
|
732
|
+
raise NotImplementedError("Only linear Raviart-Thomas implemented right now")
|
|
733
|
+
|
|
734
|
+
self.ORDER = wp.constant(degree)
|
|
735
|
+
|
|
736
|
+
self.NODES_PER_ELEMENT = wp.constant(4)
|
|
737
|
+
self.NODES_PER_SIDE = wp.constant(1)
|
|
738
|
+
|
|
739
|
+
self.VERTEX_NODE_COUNT = wp.constant(0)
|
|
740
|
+
self.EDGE_NODE_COUNT = wp.constant(0)
|
|
741
|
+
self.FACE_NODE_COUNT = wp.constant(1)
|
|
742
|
+
self.INTERIOR_NODE_COUNT = wp.constant(0)
|
|
743
|
+
|
|
744
|
+
self.node_type_and_type_index = self._get_node_type_and_type_index()
|
|
745
|
+
|
|
746
|
+
@property
|
|
747
|
+
def name(self) -> str:
|
|
748
|
+
return f"TetRT_{self.ORDER}"
|
|
749
|
+
|
|
750
|
+
def _get_node_type_and_type_index(self):
|
|
751
|
+
@cache.dynamic_func(suffix=self.name)
|
|
752
|
+
def node_type_and_index(
|
|
753
|
+
node_index_in_elt: int,
|
|
754
|
+
):
|
|
755
|
+
return TetrahedronShapeFunction.FACE, node_index_in_elt
|
|
756
|
+
|
|
757
|
+
return node_type_and_index
|
|
758
|
+
|
|
759
|
+
def make_node_coords_in_element(self):
|
|
760
|
+
@cache.dynamic_func(suffix=self.name)
|
|
761
|
+
def node_coords_in_element(
|
|
762
|
+
node_index_in_elt: int,
|
|
763
|
+
):
|
|
764
|
+
v = (node_index_in_elt + 3) % 4
|
|
765
|
+
|
|
766
|
+
coords = wp.vec4(1.0 / 3.0)
|
|
767
|
+
coords[v] = 0.0
|
|
768
|
+
|
|
769
|
+
return Coords(coords[1], coords[2], coords[3])
|
|
770
|
+
|
|
771
|
+
return node_coords_in_element
|
|
772
|
+
|
|
773
|
+
def make_node_quadrature_weight(self):
|
|
774
|
+
NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
|
|
775
|
+
|
|
776
|
+
@cache.dynamic_func(suffix=self.name)
|
|
777
|
+
def node_quadrature_weight(node_index_in_element: int):
|
|
778
|
+
return 1.0 / float(NODES_PER_ELEMENT)
|
|
779
|
+
|
|
780
|
+
return node_quadrature_weight
|
|
781
|
+
|
|
782
|
+
def make_trace_node_quadrature_weight(self):
|
|
783
|
+
NODES_PER_SIDE = self.NODES_PER_SIDE
|
|
784
|
+
|
|
785
|
+
@cache.dynamic_func(suffix=self.name)
|
|
786
|
+
def trace_node_quadrature_weight(node_index_in_element: int):
|
|
787
|
+
return 1.0 / float(NODES_PER_SIDE)
|
|
788
|
+
|
|
789
|
+
return trace_node_quadrature_weight
|
|
790
|
+
|
|
791
|
+
def make_element_inner_weight(self):
|
|
792
|
+
ORDER = self.ORDER
|
|
793
|
+
|
|
794
|
+
def element_inner_weight_linear(
|
|
795
|
+
coords: Coords,
|
|
796
|
+
node_index_in_elt: int,
|
|
797
|
+
):
|
|
798
|
+
v = (node_index_in_elt + 3) % 4
|
|
799
|
+
|
|
800
|
+
return 2.0 * (coords - self._vertex_coords(v))
|
|
801
|
+
|
|
802
|
+
if ORDER == 1:
|
|
803
|
+
return cache.get_func(element_inner_weight_linear, self.name)
|
|
804
|
+
|
|
805
|
+
return None
|
|
806
|
+
|
|
807
|
+
def make_element_inner_weight_gradient(self):
|
|
808
|
+
ORDER = self.ORDER
|
|
809
|
+
|
|
810
|
+
def element_inner_weight_gradient_linear(
|
|
811
|
+
coords: Coords,
|
|
812
|
+
node_index_in_elt: int,
|
|
813
|
+
):
|
|
814
|
+
return 2.0 * wp.identity(n=3, dtype=float)
|
|
815
|
+
|
|
816
|
+
if ORDER == 1:
|
|
817
|
+
return cache.get_func(element_inner_weight_gradient_linear, self.name)
|
|
818
|
+
|
|
819
|
+
return None
|