warp-lang 1.2.2__py3-none-macosx_10_13_universal2.whl → 1.3.0__py3-none-macosx_10_13_universal2.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 +8 -6
- warp/autograd.py +823 -0
- warp/bin/libwarp.dylib +0 -0
- warp/build.py +6 -2
- warp/builtins.py +1410 -886
- warp/codegen.py +503 -166
- warp/config.py +48 -18
- warp/context.py +400 -198
- warp/dlpack.py +8 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/benchmarks/benchmark_cloth_warp.py +1 -1
- warp/examples/benchmarks/benchmark_interop_torch.py +158 -0
- warp/examples/benchmarks/benchmark_launches.py +1 -1
- warp/examples/core/example_cupy.py +78 -0
- warp/examples/fem/example_apic_fluid.py +17 -36
- warp/examples/fem/example_burgers.py +9 -18
- warp/examples/fem/example_convection_diffusion.py +7 -17
- warp/examples/fem/example_convection_diffusion_dg.py +27 -47
- warp/examples/fem/example_deformed_geometry.py +11 -22
- warp/examples/fem/example_diffusion.py +7 -18
- warp/examples/fem/example_diffusion_3d.py +24 -28
- warp/examples/fem/example_diffusion_mgpu.py +7 -14
- warp/examples/fem/example_magnetostatics.py +190 -0
- warp/examples/fem/example_mixed_elasticity.py +111 -80
- warp/examples/fem/example_navier_stokes.py +30 -34
- warp/examples/fem/example_nonconforming_contact.py +290 -0
- warp/examples/fem/example_stokes.py +17 -32
- warp/examples/fem/example_stokes_transfer.py +12 -21
- warp/examples/fem/example_streamlines.py +350 -0
- warp/examples/fem/utils.py +936 -0
- warp/fabric.py +5 -2
- warp/fem/__init__.py +13 -3
- warp/fem/cache.py +161 -11
- warp/fem/dirichlet.py +37 -28
- warp/fem/domain.py +105 -14
- warp/fem/field/__init__.py +14 -3
- warp/fem/field/field.py +454 -11
- warp/fem/field/nodal_field.py +33 -18
- warp/fem/geometry/deformed_geometry.py +50 -15
- warp/fem/geometry/hexmesh.py +12 -24
- warp/fem/geometry/nanogrid.py +106 -31
- warp/fem/geometry/quadmesh_2d.py +6 -11
- warp/fem/geometry/tetmesh.py +103 -61
- warp/fem/geometry/trimesh_2d.py +98 -47
- warp/fem/integrate.py +231 -186
- warp/fem/operator.py +14 -9
- warp/fem/quadrature/pic_quadrature.py +35 -9
- warp/fem/quadrature/quadrature.py +119 -32
- warp/fem/space/basis_space.py +98 -22
- warp/fem/space/collocated_function_space.py +3 -1
- warp/fem/space/function_space.py +7 -2
- warp/fem/space/grid_2d_function_space.py +3 -3
- warp/fem/space/grid_3d_function_space.py +4 -4
- warp/fem/space/hexmesh_function_space.py +3 -2
- warp/fem/space/nanogrid_function_space.py +12 -14
- warp/fem/space/partition.py +45 -47
- warp/fem/space/restriction.py +19 -16
- warp/fem/space/shape/cube_shape_function.py +91 -3
- warp/fem/space/shape/shape_function.py +7 -0
- warp/fem/space/shape/square_shape_function.py +32 -0
- warp/fem/space/shape/tet_shape_function.py +11 -7
- warp/fem/space/shape/triangle_shape_function.py +10 -1
- warp/fem/space/topology.py +116 -42
- warp/fem/types.py +8 -1
- warp/fem/utils.py +301 -83
- warp/native/array.h +16 -0
- warp/native/builtin.h +0 -15
- warp/native/cuda_util.cpp +14 -6
- warp/native/exports.h +1348 -1308
- warp/native/quat.h +79 -0
- warp/native/rand.h +27 -4
- warp/native/sparse.cpp +83 -81
- warp/native/sparse.cu +381 -453
- warp/native/vec.h +64 -0
- warp/native/volume.cpp +40 -49
- warp/native/volume_builder.cu +2 -3
- warp/native/volume_builder.h +12 -17
- warp/native/warp.cu +3 -3
- warp/native/warp.h +69 -59
- warp/render/render_opengl.py +17 -9
- warp/sim/articulation.py +117 -17
- warp/sim/collide.py +35 -29
- warp/sim/model.py +123 -18
- warp/sim/render.py +3 -1
- warp/sparse.py +867 -203
- warp/stubs.py +312 -541
- warp/tape.py +29 -1
- warp/tests/disabled_kinematics.py +1 -1
- warp/tests/test_adam.py +1 -1
- warp/tests/test_arithmetic.py +1 -1
- warp/tests/test_array.py +58 -1
- warp/tests/test_array_reduce.py +1 -1
- warp/tests/test_async.py +1 -1
- warp/tests/test_atomic.py +1 -1
- warp/tests/test_bool.py +1 -1
- warp/tests/test_builtins_resolution.py +1 -1
- warp/tests/test_bvh.py +6 -1
- warp/tests/test_closest_point_edge_edge.py +1 -1
- warp/tests/test_codegen.py +66 -1
- warp/tests/test_compile_consts.py +1 -1
- warp/tests/test_conditional.py +1 -1
- warp/tests/test_copy.py +1 -1
- warp/tests/test_ctypes.py +1 -1
- warp/tests/test_dense.py +1 -1
- warp/tests/test_devices.py +1 -1
- warp/tests/test_dlpack.py +1 -1
- warp/tests/test_examples.py +33 -4
- warp/tests/test_fabricarray.py +5 -2
- warp/tests/test_fast_math.py +1 -1
- warp/tests/test_fem.py +213 -6
- warp/tests/test_fp16.py +1 -1
- warp/tests/test_func.py +1 -1
- warp/tests/test_future_annotations.py +90 -0
- warp/tests/test_generics.py +1 -1
- warp/tests/test_grad.py +1 -1
- warp/tests/test_grad_customs.py +1 -1
- warp/tests/test_grad_debug.py +247 -0
- warp/tests/test_hash_grid.py +6 -1
- warp/tests/test_implicit_init.py +354 -0
- warp/tests/test_import.py +1 -1
- warp/tests/test_indexedarray.py +1 -1
- warp/tests/test_intersect.py +1 -1
- warp/tests/test_jax.py +1 -1
- warp/tests/test_large.py +1 -1
- warp/tests/test_launch.py +1 -1
- warp/tests/test_lerp.py +1 -1
- warp/tests/test_linear_solvers.py +1 -1
- warp/tests/test_lvalue.py +1 -1
- warp/tests/test_marching_cubes.py +5 -2
- warp/tests/test_mat.py +34 -35
- warp/tests/test_mat_lite.py +2 -1
- warp/tests/test_mat_scalar_ops.py +1 -1
- warp/tests/test_math.py +1 -1
- warp/tests/test_matmul.py +20 -16
- warp/tests/test_matmul_lite.py +1 -1
- warp/tests/test_mempool.py +1 -1
- warp/tests/test_mesh.py +5 -2
- warp/tests/test_mesh_query_aabb.py +1 -1
- warp/tests/test_mesh_query_point.py +1 -1
- warp/tests/test_mesh_query_ray.py +1 -1
- warp/tests/test_mlp.py +1 -1
- warp/tests/test_model.py +1 -1
- warp/tests/test_module_hashing.py +77 -1
- warp/tests/test_modules_lite.py +1 -1
- warp/tests/test_multigpu.py +1 -1
- warp/tests/test_noise.py +1 -1
- warp/tests/test_operators.py +1 -1
- warp/tests/test_options.py +1 -1
- warp/tests/test_overwrite.py +542 -0
- warp/tests/test_peer.py +1 -1
- warp/tests/test_pinned.py +1 -1
- warp/tests/test_print.py +1 -1
- warp/tests/test_quat.py +15 -1
- warp/tests/test_rand.py +1 -1
- warp/tests/test_reload.py +1 -1
- warp/tests/test_rounding.py +1 -1
- warp/tests/test_runlength_encode.py +1 -1
- warp/tests/test_scalar_ops.py +95 -0
- warp/tests/test_sim_grad.py +1 -1
- warp/tests/test_sim_kinematics.py +1 -1
- warp/tests/test_smoothstep.py +1 -1
- warp/tests/test_sparse.py +82 -15
- warp/tests/test_spatial.py +1 -1
- warp/tests/test_special_values.py +2 -11
- warp/tests/test_streams.py +11 -1
- warp/tests/test_struct.py +1 -1
- warp/tests/test_tape.py +1 -1
- warp/tests/test_torch.py +194 -1
- warp/tests/test_transient_module.py +1 -1
- warp/tests/test_types.py +1 -1
- warp/tests/test_utils.py +1 -1
- warp/tests/test_vec.py +15 -63
- warp/tests/test_vec_lite.py +2 -1
- warp/tests/test_vec_scalar_ops.py +65 -1
- warp/tests/test_verify_fp.py +1 -1
- warp/tests/test_volume.py +28 -2
- warp/tests/test_volume_write.py +1 -1
- warp/tests/unittest_serial.py +1 -1
- warp/tests/unittest_suites.py +9 -1
- warp/tests/walkthrough_debug.py +1 -1
- warp/thirdparty/unittest_parallel.py +2 -5
- warp/torch.py +103 -41
- warp/types.py +341 -224
- warp/utils.py +11 -2
- {warp_lang-1.2.2.dist-info → warp_lang-1.3.0.dist-info}/METADATA +99 -46
- warp_lang-1.3.0.dist-info/RECORD +368 -0
- warp/examples/fem/bsr_utils.py +0 -378
- warp/examples/fem/mesh_utils.py +0 -133
- warp/examples/fem/plot_utils.py +0 -292
- warp_lang-1.2.2.dist-info/RECORD +0 -359
- {warp_lang-1.2.2.dist-info → warp_lang-1.3.0.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.2.2.dist-info → warp_lang-1.3.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.2.2.dist-info → warp_lang-1.3.0.dist-info}/top_level.txt +0 -0
warp/fem/space/restriction.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import warp as wp
|
|
2
2
|
from warp.fem.cache import TemporaryStore, borrow_temporary, borrow_temporary_like, cached_arg_value
|
|
3
3
|
from warp.fem.domain import GeometryDomain
|
|
4
|
-
from warp.fem.types import NodeElementIndex
|
|
4
|
+
from warp.fem.types import NULL_NODE_INDEX, NodeElementIndex
|
|
5
5
|
from warp.fem.utils import compress_node_indices
|
|
6
6
|
|
|
7
7
|
from .partition import SpacePartition
|
|
@@ -36,7 +36,7 @@ class SpaceRestriction:
|
|
|
36
36
|
def _compute_node_element_indices(self, device, temporary_store: TemporaryStore):
|
|
37
37
|
from warp.fem import cache
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
MAX_NODES_PER_ELEMENT = self.space_topology.MAX_NODES_PER_ELEMENT
|
|
40
40
|
|
|
41
41
|
@cache.dynamic_kernel(
|
|
42
42
|
suffix=f"{self.domain.name}_{self.space_topology.name}_{self.space_partition.name}",
|
|
@@ -51,14 +51,17 @@ class SpaceRestriction:
|
|
|
51
51
|
):
|
|
52
52
|
domain_element_index = wp.tid()
|
|
53
53
|
element_index = self.domain.element_index(domain_index_arg, domain_element_index)
|
|
54
|
-
|
|
54
|
+
element_node_count = self.space_topology.element_node_count(element_arg, topo_arg, element_index)
|
|
55
|
+
for n in range(element_node_count):
|
|
55
56
|
space_nidx = self.space_topology.element_node_index(element_arg, topo_arg, element_index, n)
|
|
56
57
|
partition_nidx = self.space_partition.partition_node_index(partition_arg, space_nidx)
|
|
57
58
|
element_node_indices[domain_element_index, n] = partition_nidx
|
|
59
|
+
for n in range(element_node_count, MAX_NODES_PER_ELEMENT):
|
|
60
|
+
element_node_indices[domain_element_index, n] = NULL_NODE_INDEX
|
|
58
61
|
|
|
59
62
|
element_node_indices = borrow_temporary(
|
|
60
63
|
temporary_store,
|
|
61
|
-
shape=(self.domain.element_count(),
|
|
64
|
+
shape=(self.domain.element_count(), MAX_NODES_PER_ELEMENT),
|
|
62
65
|
dtype=int,
|
|
63
66
|
device=device,
|
|
64
67
|
)
|
|
@@ -83,7 +86,10 @@ class SpaceRestriction:
|
|
|
83
86
|
self._node_count,
|
|
84
87
|
self._dof_partition_indices,
|
|
85
88
|
) = compress_node_indices(
|
|
86
|
-
self.space_partition.node_count(),
|
|
89
|
+
self.space_partition.node_count(),
|
|
90
|
+
flattened_node_indices,
|
|
91
|
+
return_unique_nodes=True,
|
|
92
|
+
temporary_store=temporary_store,
|
|
87
93
|
)
|
|
88
94
|
|
|
89
95
|
# Extract element index and index in element
|
|
@@ -93,7 +99,7 @@ class SpaceRestriction:
|
|
|
93
99
|
kernel=SpaceRestriction._split_vertex_element_index,
|
|
94
100
|
dim=flattened_node_indices.shape,
|
|
95
101
|
inputs=[
|
|
96
|
-
|
|
102
|
+
MAX_NODES_PER_ELEMENT,
|
|
97
103
|
node_array_indices.array,
|
|
98
104
|
self._dof_element_indices.array,
|
|
99
105
|
self._dof_indices_in_element.array,
|
|
@@ -132,20 +138,17 @@ class SpaceRestriction:
|
|
|
132
138
|
return arg
|
|
133
139
|
|
|
134
140
|
@wp.func
|
|
135
|
-
def node_partition_index(args: NodeArg,
|
|
136
|
-
return args.dof_partition_indices[
|
|
141
|
+
def node_partition_index(args: NodeArg, restriction_node_index: int):
|
|
142
|
+
return args.dof_partition_indices[restriction_node_index]
|
|
137
143
|
|
|
138
144
|
@wp.func
|
|
139
|
-
def
|
|
140
|
-
|
|
141
|
-
return args.dof_element_offsets[partition_node_index + 1] - args.dof_element_offsets[partition_node_index]
|
|
145
|
+
def node_element_range(args: NodeArg, partition_node_index: int):
|
|
146
|
+
return args.dof_element_offsets[partition_node_index], args.dof_element_offsets[partition_node_index + 1]
|
|
142
147
|
|
|
143
148
|
@wp.func
|
|
144
|
-
def node_element_index(args: NodeArg,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
domain_element_index = args.dof_element_indices[offset]
|
|
148
|
-
index_in_element = args.dof_indices_in_element[offset]
|
|
149
|
+
def node_element_index(args: NodeArg, node_element_offset: int):
|
|
150
|
+
domain_element_index = args.dof_element_indices[node_element_offset]
|
|
151
|
+
index_in_element = args.dof_indices_in_element[node_element_offset]
|
|
149
152
|
return NodeElementIndex(domain_element_index, index_in_element)
|
|
150
153
|
|
|
151
154
|
@wp.kernel
|
|
@@ -98,7 +98,7 @@ class CubeTripolynomialShapeFunctions:
|
|
|
98
98
|
|
|
99
99
|
# x face
|
|
100
100
|
type_instance = mi
|
|
101
|
-
type_index =
|
|
101
|
+
type_index = (j - 1) * (ORDER - 1) + k - 1
|
|
102
102
|
return CubeTripolynomialShapeFunctions.FACE, type_instance, type_index
|
|
103
103
|
|
|
104
104
|
if zj + mj == 1:
|
|
@@ -110,13 +110,13 @@ class CubeTripolynomialShapeFunctions:
|
|
|
110
110
|
|
|
111
111
|
# y face
|
|
112
112
|
type_instance = 2 + mj
|
|
113
|
-
type_index =
|
|
113
|
+
type_index = (k - 1) * (ORDER - 1) + i - 1
|
|
114
114
|
return CubeTripolynomialShapeFunctions.FACE, type_instance, type_index
|
|
115
115
|
|
|
116
116
|
if zk + mk == 1:
|
|
117
117
|
# z face
|
|
118
118
|
type_instance = 4 + mk
|
|
119
|
-
type_index =
|
|
119
|
+
type_index = (i - 1) * (ORDER - 1) + j - 1
|
|
120
120
|
return CubeTripolynomialShapeFunctions.FACE, type_instance, type_index
|
|
121
121
|
|
|
122
122
|
type_index = ((i - 1) * (ORDER - 1) + (j - 1)) * (ORDER - 1) + k - 1
|
|
@@ -322,6 +322,87 @@ class CubeTripolynomialShapeFunctions:
|
|
|
322
322
|
|
|
323
323
|
return grid_to_tets(self.ORDER, self.ORDER, self.ORDER)
|
|
324
324
|
|
|
325
|
+
def element_vtk_cells(self):
|
|
326
|
+
n = self.ORDER + 1
|
|
327
|
+
|
|
328
|
+
# vertices
|
|
329
|
+
cells = [
|
|
330
|
+
[
|
|
331
|
+
[0, 0, 0],
|
|
332
|
+
[n - 1, 0, 0],
|
|
333
|
+
[n - 1, n - 1, 0],
|
|
334
|
+
[0, n - 1, 0],
|
|
335
|
+
[0, 0, n - 1],
|
|
336
|
+
[n - 1, 0, n - 1],
|
|
337
|
+
[n - 1, n - 1, n - 1],
|
|
338
|
+
[0, n - 1, n - 1],
|
|
339
|
+
]
|
|
340
|
+
]
|
|
341
|
+
|
|
342
|
+
if self.ORDER == 1:
|
|
343
|
+
cell_type = 12 # vtk_hexahedron
|
|
344
|
+
else:
|
|
345
|
+
middle = np.arange(1, n - 1)
|
|
346
|
+
front = np.zeros(n - 2, dtype=int)
|
|
347
|
+
back = np.full(n - 2, n - 1)
|
|
348
|
+
|
|
349
|
+
# edges
|
|
350
|
+
cells.append(np.column_stack((middle, front, front)))
|
|
351
|
+
cells.append(np.column_stack((back, middle, front)))
|
|
352
|
+
cells.append(np.column_stack((middle, back, front)))
|
|
353
|
+
cells.append(np.column_stack((front, middle, front)))
|
|
354
|
+
|
|
355
|
+
cells.append(np.column_stack((middle, front, back)))
|
|
356
|
+
cells.append(np.column_stack((back, middle, back)))
|
|
357
|
+
cells.append(np.column_stack((middle, back, back)))
|
|
358
|
+
cells.append(np.column_stack((front, middle, back)))
|
|
359
|
+
|
|
360
|
+
cells.append(np.column_stack((front, front, middle)))
|
|
361
|
+
cells.append(np.column_stack((back, front, middle)))
|
|
362
|
+
cells.append(np.column_stack((back, back, middle)))
|
|
363
|
+
cells.append(np.column_stack((front, back, middle)))
|
|
364
|
+
|
|
365
|
+
# faces
|
|
366
|
+
|
|
367
|
+
face = np.meshgrid(middle, middle)
|
|
368
|
+
front = np.zeros((n - 2) ** 2, dtype=int)
|
|
369
|
+
back = np.full((n - 2) ** 2, n - 1)
|
|
370
|
+
|
|
371
|
+
# YZ
|
|
372
|
+
cells.append(
|
|
373
|
+
np.column_stack((front, face[0].flatten(), face[1].flatten())),
|
|
374
|
+
)
|
|
375
|
+
cells.append(
|
|
376
|
+
np.column_stack((back, face[0].flatten(), face[1].flatten())),
|
|
377
|
+
)
|
|
378
|
+
# XZ
|
|
379
|
+
cells.append(
|
|
380
|
+
np.column_stack((face[0].flatten(), front, face[1].flatten())),
|
|
381
|
+
)
|
|
382
|
+
cells.append(
|
|
383
|
+
np.column_stack((face[0].flatten(), back, face[1].flatten())),
|
|
384
|
+
)
|
|
385
|
+
# XY
|
|
386
|
+
cells.append(
|
|
387
|
+
np.column_stack((face[0].flatten(), face[1].flatten(), front)),
|
|
388
|
+
)
|
|
389
|
+
cells.append(
|
|
390
|
+
np.column_stack((face[0].flatten(), face[1].flatten(), back)),
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
# interior
|
|
394
|
+
interior = np.meshgrid(middle, middle, middle)
|
|
395
|
+
cells.append(
|
|
396
|
+
np.column_stack((interior[0].flatten(), interior[1].flatten(), interior[2].flatten())),
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
cell_type = 72 # vtk_lagrange_hexahedron
|
|
400
|
+
|
|
401
|
+
cells = np.concatenate(cells)
|
|
402
|
+
cell_indices = cells[:, 0] * n * n + cells[:, 1] * n + cells[:, 2]
|
|
403
|
+
|
|
404
|
+
return cell_indices[np.newaxis, :], np.array([cell_type], dtype=np.int8)
|
|
405
|
+
|
|
325
406
|
|
|
326
407
|
class CubeSerendipityShapeFunctions:
|
|
327
408
|
"""
|
|
@@ -632,6 +713,12 @@ class CubeSerendipityShapeFunctions:
|
|
|
632
713
|
|
|
633
714
|
raise NotImplementedError()
|
|
634
715
|
|
|
716
|
+
def element_vtk_cells(self):
|
|
717
|
+
tets = np.array(self.element_node_tets())
|
|
718
|
+
cell_type = 10 # VTK_TETRA
|
|
719
|
+
|
|
720
|
+
return tets, np.full(tets.shape[0], cell_type, dtype=np.int8)
|
|
721
|
+
|
|
635
722
|
|
|
636
723
|
class CubeNonConformingPolynomialShapeFunctions:
|
|
637
724
|
# embeds the largest regular tet centered at (0.5, 0.5, 0.5) into the reference cube
|
|
@@ -656,6 +743,7 @@ class CubeNonConformingPolynomialShapeFunctions:
|
|
|
656
743
|
self.NODES_PER_ELEMENT = self._tet_shape.NODES_PER_ELEMENT
|
|
657
744
|
|
|
658
745
|
self.element_node_tets = self._tet_shape.element_node_tets
|
|
746
|
+
self.element_vtk_cells = self._tet_shape.element_vtk_cells
|
|
659
747
|
|
|
660
748
|
@property
|
|
661
749
|
def name(self) -> str:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
1
3
|
import warp as wp
|
|
2
4
|
from warp.fem import cache
|
|
3
5
|
from warp.fem.geometry import Element
|
|
@@ -100,3 +102,8 @@ class ConstantShapeFunction:
|
|
|
100
102
|
return grad_type(0.0)
|
|
101
103
|
|
|
102
104
|
return element_inner_weight_gradient
|
|
105
|
+
|
|
106
|
+
def element_vtk_cells(self):
|
|
107
|
+
cell_type = 1 # VTK_VERTEX
|
|
108
|
+
|
|
109
|
+
return np.zeros((1, 1), dtype=int), np.full(1, cell_type, dtype=np.int8)
|
|
@@ -206,6 +206,31 @@ class SquareBipolynomialShapeFunctions:
|
|
|
206
206
|
|
|
207
207
|
return grid_to_tris(self.ORDER, self.ORDER)
|
|
208
208
|
|
|
209
|
+
def element_vtk_cells(self):
|
|
210
|
+
n = self.ORDER + 1
|
|
211
|
+
|
|
212
|
+
# vertices
|
|
213
|
+
cells = [[0, (n - 1) * n, n * n - 1, n - 1]]
|
|
214
|
+
|
|
215
|
+
if self.ORDER == 1:
|
|
216
|
+
cell_type = 9 # VTK_QUAD
|
|
217
|
+
else:
|
|
218
|
+
middle = np.arange(1, n - 1)
|
|
219
|
+
|
|
220
|
+
# edges
|
|
221
|
+
cells.append(middle * n)
|
|
222
|
+
cells.append(middle + (n - 1) * n)
|
|
223
|
+
cells.append(middle * n + n - 1)
|
|
224
|
+
cells.append(middle)
|
|
225
|
+
|
|
226
|
+
# faces
|
|
227
|
+
interior = np.broadcast_to(middle, (n - 2, n - 2))
|
|
228
|
+
cells.append((interior * n + interior.transpose()).flatten())
|
|
229
|
+
|
|
230
|
+
cell_type = 70 # VTK_LAGRANGE_QUADRILATERAL
|
|
231
|
+
|
|
232
|
+
return np.concatenate(cells)[np.newaxis, :], np.array([cell_type], dtype=np.int8)
|
|
233
|
+
|
|
209
234
|
|
|
210
235
|
class SquareSerendipityShapeFunctions:
|
|
211
236
|
"""
|
|
@@ -501,6 +526,12 @@ class SquareSerendipityShapeFunctions:
|
|
|
501
526
|
|
|
502
527
|
return element_triangles
|
|
503
528
|
|
|
529
|
+
def element_vtk_cells(self):
|
|
530
|
+
tris = np.array(self.element_node_triangulation())
|
|
531
|
+
cell_type = 5 # VTK_TRIANGLE
|
|
532
|
+
|
|
533
|
+
return tris, np.full(tris.shape[0], cell_type, dtype=np.int8)
|
|
534
|
+
|
|
504
535
|
|
|
505
536
|
class SquareNonConformingPolynomialShapeFunctions:
|
|
506
537
|
# embeds the largest equilateral triangle centered at (0.5, 0.5) into the reference square
|
|
@@ -516,6 +547,7 @@ class SquareNonConformingPolynomialShapeFunctions:
|
|
|
516
547
|
self.NODES_PER_ELEMENT = self._tri_shape.NODES_PER_ELEMENT
|
|
517
548
|
|
|
518
549
|
self.element_node_triangulation = self._tri_shape.element_node_triangulation
|
|
550
|
+
self.element_vtk_cells = self._tri_shape.element_vtk_cells
|
|
519
551
|
|
|
520
552
|
@property
|
|
521
553
|
def name(self) -> str:
|
|
@@ -92,7 +92,6 @@ def _tet_node_index(tx: int, ty: int, tz: int, degree: int):
|
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
class TetrahedronPolynomialShapeFunctions:
|
|
95
|
-
INVALID = wp.constant(-1)
|
|
96
95
|
VERTEX = wp.constant(0)
|
|
97
96
|
EDGE = wp.constant(1)
|
|
98
97
|
FACE = wp.constant(2)
|
|
@@ -138,14 +137,10 @@ class TetrahedronPolynomialShapeFunctions:
|
|
|
138
137
|
|
|
139
138
|
def _get_node_type_and_type_index(self):
|
|
140
139
|
ORDER = self.ORDER
|
|
141
|
-
NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
|
|
142
140
|
|
|
143
141
|
def node_type_and_index(
|
|
144
142
|
node_index_in_elt: int,
|
|
145
143
|
):
|
|
146
|
-
if node_index_in_elt < 0 or node_index_in_elt >= NODES_PER_ELEMENT:
|
|
147
|
-
return TetrahedronPolynomialShapeFunctions.INVALID, TetrahedronPolynomialShapeFunctions.INVALID
|
|
148
|
-
|
|
149
144
|
if node_index_in_elt < 4:
|
|
150
145
|
return TetrahedronPolynomialShapeFunctions.VERTEX, node_index_in_elt
|
|
151
146
|
|
|
@@ -208,7 +203,7 @@ class TetrahedronPolynomialShapeFunctions:
|
|
|
208
203
|
|
|
209
204
|
def make_trace_node_quadrature_weight(self):
|
|
210
205
|
if self.ORDER == 3:
|
|
211
|
-
# P3
|
|
206
|
+
# P3 intrinsic quadrature
|
|
212
207
|
vertex_weight = 1.0 / 30
|
|
213
208
|
edge_weight = 0.075
|
|
214
209
|
interior_weight = 0.45
|
|
@@ -447,6 +442,14 @@ class TetrahedronPolynomialShapeFunctions:
|
|
|
447
442
|
|
|
448
443
|
return np.array(element_tets)
|
|
449
444
|
|
|
445
|
+
def element_vtk_cells(self):
|
|
446
|
+
cells = np.arange(self.NODES_PER_ELEMENT)
|
|
447
|
+
if self.ORDER == 1:
|
|
448
|
+
cell_type = 10 # VTK_TETRA
|
|
449
|
+
else:
|
|
450
|
+
cell_type = 71 # VTK_LAGRANGE_TETRAHEDRON
|
|
451
|
+
return cells[np.newaxis, :], np.array([cell_type], dtype=np.int8)
|
|
452
|
+
|
|
450
453
|
|
|
451
454
|
class TetrahedronNonConformingPolynomialShapeFunctions:
|
|
452
455
|
def __init__(self, degree: int):
|
|
@@ -455,6 +458,7 @@ class TetrahedronNonConformingPolynomialShapeFunctions:
|
|
|
455
458
|
self.NODES_PER_ELEMENT = self._tet_shape.NODES_PER_ELEMENT
|
|
456
459
|
|
|
457
460
|
self.element_node_tets = self._tet_shape.element_node_tets
|
|
461
|
+
self.element_vtk_cells = self._tet_shape.element_vtk_cells
|
|
458
462
|
|
|
459
463
|
if self.ORDER == 1:
|
|
460
464
|
self._TET_SCALE = 0.4472135955 # so v at 0.5854101966249680 (order 2)
|
|
@@ -489,7 +493,7 @@ class TetrahedronNonConformingPolynomialShapeFunctions:
|
|
|
489
493
|
|
|
490
494
|
def make_node_quadrature_weight(self):
|
|
491
495
|
# Intrinsic quadrature -- precomputed integral of node shape functions
|
|
492
|
-
# over element. Order
|
|
496
|
+
# over element. Order equal to self.ORDER
|
|
493
497
|
|
|
494
498
|
if self.ORDER == 2:
|
|
495
499
|
vertex_weight = 0.07499641
|
|
@@ -103,7 +103,7 @@ class Triangle2DPolynomialShapeFunctions:
|
|
|
103
103
|
|
|
104
104
|
def make_node_quadrature_weight(self):
|
|
105
105
|
if self.ORDER == 3:
|
|
106
|
-
# P3
|
|
106
|
+
# P3 intrinsic quadrature
|
|
107
107
|
vertex_weight = 1.0 / 30
|
|
108
108
|
edge_weight = 0.075
|
|
109
109
|
interior_weight = 0.45
|
|
@@ -309,6 +309,14 @@ class Triangle2DPolynomialShapeFunctions:
|
|
|
309
309
|
|
|
310
310
|
return np.array(element_triangles)
|
|
311
311
|
|
|
312
|
+
def element_vtk_cells(self):
|
|
313
|
+
cells = np.arange(self.NODES_PER_ELEMENT)
|
|
314
|
+
if self.ORDER == 1:
|
|
315
|
+
cell_type = 5 # VTK_TRIANGLE
|
|
316
|
+
else:
|
|
317
|
+
cell_type = 69 # VTK_LAGRANGE_TRIANGLE
|
|
318
|
+
return cells[np.newaxis, :], np.array([cell_type], dtype=np.int8)
|
|
319
|
+
|
|
312
320
|
|
|
313
321
|
class Triangle2DNonConformingPolynomialShapeFunctions:
|
|
314
322
|
def __init__(self, degree: int):
|
|
@@ -317,6 +325,7 @@ class Triangle2DNonConformingPolynomialShapeFunctions:
|
|
|
317
325
|
self.NODES_PER_ELEMENT = self._tri_shape.NODES_PER_ELEMENT
|
|
318
326
|
|
|
319
327
|
self.element_node_triangulation = self._tri_shape.element_node_triangulation
|
|
328
|
+
self.element_vtk_cells = self._tri_shape.element_vtk_cells
|
|
320
329
|
|
|
321
330
|
# Coordinates (a, b, b) of embedded triangle
|
|
322
331
|
if self.ORDER == 1:
|