warp-lang 1.0.2__py3-none-win_amd64.whl → 1.2.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 +108 -97
- warp/__init__.pyi +1 -1
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +88 -113
- warp/build_dll.py +383 -375
- warp/builtins.py +3693 -3354
- warp/codegen.py +2925 -2792
- warp/config.py +40 -36
- warp/constants.py +49 -45
- warp/context.py +5409 -5102
- warp/dlpack.py +442 -442
- warp/examples/__init__.py +16 -16
- warp/examples/assets/bear.usd +0 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cartpole.urdf +110 -110
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/cube.usd +0 -0
- warp/examples/assets/nv_ant.xml +92 -92
- warp/examples/assets/nv_humanoid.xml +183 -183
- warp/examples/assets/quadruped.urdf +267 -267
- warp/examples/assets/rocks.nvdb +0 -0
- warp/examples/assets/rocks.usd +0 -0
- warp/examples/assets/sphere.usd +0 -0
- warp/examples/benchmarks/benchmark_api.py +381 -383
- warp/examples/benchmarks/benchmark_cloth.py +278 -277
- warp/examples/benchmarks/benchmark_cloth_cupy.py +88 -88
- warp/examples/benchmarks/benchmark_cloth_jax.py +97 -100
- warp/examples/benchmarks/benchmark_cloth_numba.py +146 -142
- warp/examples/benchmarks/benchmark_cloth_numpy.py +77 -77
- warp/examples/benchmarks/benchmark_cloth_pytorch.py +86 -86
- warp/examples/benchmarks/benchmark_cloth_taichi.py +112 -112
- warp/examples/benchmarks/benchmark_cloth_warp.py +145 -146
- warp/examples/benchmarks/benchmark_launches.py +293 -295
- warp/examples/browse.py +29 -29
- warp/examples/core/example_dem.py +232 -219
- warp/examples/core/example_fluid.py +291 -267
- warp/examples/core/example_graph_capture.py +142 -126
- warp/examples/core/example_marching_cubes.py +186 -174
- warp/examples/core/example_mesh.py +172 -155
- warp/examples/core/example_mesh_intersect.py +203 -193
- warp/examples/core/example_nvdb.py +174 -170
- warp/examples/core/example_raycast.py +103 -90
- warp/examples/core/example_raymarch.py +197 -178
- warp/examples/core/example_render_opengl.py +183 -141
- warp/examples/core/example_sph.py +403 -387
- warp/examples/core/example_torch.py +219 -181
- warp/examples/core/example_wave.py +261 -248
- warp/examples/fem/bsr_utils.py +378 -380
- warp/examples/fem/example_apic_fluid.py +432 -389
- warp/examples/fem/example_burgers.py +262 -0
- warp/examples/fem/example_convection_diffusion.py +180 -168
- warp/examples/fem/example_convection_diffusion_dg.py +217 -209
- warp/examples/fem/example_deformed_geometry.py +175 -159
- warp/examples/fem/example_diffusion.py +199 -173
- warp/examples/fem/example_diffusion_3d.py +178 -152
- warp/examples/fem/example_diffusion_mgpu.py +219 -214
- warp/examples/fem/example_mixed_elasticity.py +242 -222
- warp/examples/fem/example_navier_stokes.py +257 -243
- warp/examples/fem/example_stokes.py +218 -192
- warp/examples/fem/example_stokes_transfer.py +263 -249
- warp/examples/fem/mesh_utils.py +133 -109
- warp/examples/fem/plot_utils.py +292 -287
- warp/examples/optim/example_bounce.py +258 -246
- warp/examples/optim/example_cloth_throw.py +220 -209
- warp/examples/optim/example_diffray.py +564 -536
- warp/examples/optim/example_drone.py +862 -835
- warp/examples/optim/example_inverse_kinematics.py +174 -168
- warp/examples/optim/example_inverse_kinematics_torch.py +183 -169
- warp/examples/optim/example_spring_cage.py +237 -231
- warp/examples/optim/example_trajectory.py +221 -199
- warp/examples/optim/example_walker.py +304 -293
- warp/examples/sim/example_cartpole.py +137 -129
- warp/examples/sim/example_cloth.py +194 -186
- warp/examples/sim/example_granular.py +122 -111
- warp/examples/sim/example_granular_collision_sdf.py +195 -186
- warp/examples/sim/example_jacobian_ik.py +234 -214
- warp/examples/sim/example_particle_chain.py +116 -105
- warp/examples/sim/example_quadruped.py +191 -180
- warp/examples/sim/example_rigid_chain.py +195 -187
- warp/examples/sim/example_rigid_contact.py +187 -177
- warp/examples/sim/example_rigid_force.py +125 -125
- warp/examples/sim/example_rigid_gyroscopic.py +107 -95
- warp/examples/sim/example_rigid_soft_contact.py +132 -122
- warp/examples/sim/example_soft_body.py +188 -177
- warp/fabric.py +337 -335
- warp/fem/__init__.py +61 -27
- warp/fem/cache.py +403 -388
- warp/fem/dirichlet.py +178 -179
- warp/fem/domain.py +262 -263
- warp/fem/field/__init__.py +100 -101
- warp/fem/field/field.py +148 -149
- warp/fem/field/nodal_field.py +298 -299
- warp/fem/field/restriction.py +22 -21
- warp/fem/field/test.py +180 -181
- warp/fem/field/trial.py +183 -183
- warp/fem/geometry/__init__.py +16 -19
- warp/fem/geometry/closest_point.py +69 -70
- warp/fem/geometry/deformed_geometry.py +270 -271
- warp/fem/geometry/element.py +748 -744
- warp/fem/geometry/geometry.py +184 -186
- warp/fem/geometry/grid_2d.py +380 -373
- warp/fem/geometry/grid_3d.py +437 -435
- warp/fem/geometry/hexmesh.py +953 -953
- warp/fem/geometry/nanogrid.py +455 -0
- warp/fem/geometry/partition.py +374 -376
- warp/fem/geometry/quadmesh_2d.py +532 -532
- warp/fem/geometry/tetmesh.py +840 -840
- warp/fem/geometry/trimesh_2d.py +577 -577
- warp/fem/integrate.py +1684 -1615
- warp/fem/operator.py +190 -191
- warp/fem/polynomial.py +214 -213
- warp/fem/quadrature/__init__.py +2 -2
- warp/fem/quadrature/pic_quadrature.py +243 -245
- warp/fem/quadrature/quadrature.py +295 -294
- warp/fem/space/__init__.py +179 -292
- warp/fem/space/basis_space.py +522 -489
- warp/fem/space/collocated_function_space.py +100 -105
- warp/fem/space/dof_mapper.py +236 -236
- warp/fem/space/function_space.py +148 -145
- warp/fem/space/grid_2d_function_space.py +148 -267
- warp/fem/space/grid_3d_function_space.py +167 -306
- warp/fem/space/hexmesh_function_space.py +253 -352
- warp/fem/space/nanogrid_function_space.py +202 -0
- warp/fem/space/partition.py +350 -350
- warp/fem/space/quadmesh_2d_function_space.py +261 -369
- warp/fem/space/restriction.py +161 -160
- warp/fem/space/shape/__init__.py +90 -15
- warp/fem/space/shape/cube_shape_function.py +728 -738
- warp/fem/space/shape/shape_function.py +102 -103
- warp/fem/space/shape/square_shape_function.py +611 -611
- warp/fem/space/shape/tet_shape_function.py +565 -567
- warp/fem/space/shape/triangle_shape_function.py +429 -429
- warp/fem/space/tetmesh_function_space.py +224 -292
- warp/fem/space/topology.py +297 -295
- warp/fem/space/trimesh_2d_function_space.py +153 -221
- warp/fem/types.py +77 -77
- warp/fem/utils.py +495 -495
- warp/jax.py +166 -141
- warp/jax_experimental.py +341 -339
- warp/native/array.h +1081 -1025
- warp/native/builtin.h +1603 -1560
- warp/native/bvh.cpp +402 -398
- warp/native/bvh.cu +533 -525
- warp/native/bvh.h +430 -429
- warp/native/clang/clang.cpp +496 -464
- warp/native/crt.cpp +42 -32
- warp/native/crt.h +352 -335
- warp/native/cuda_crt.h +1049 -1049
- warp/native/cuda_util.cpp +549 -540
- warp/native/cuda_util.h +288 -203
- warp/native/cutlass_gemm.cpp +34 -34
- warp/native/cutlass_gemm.cu +372 -372
- warp/native/error.cpp +66 -66
- warp/native/error.h +27 -27
- warp/native/exports.h +187 -0
- warp/native/fabric.h +228 -228
- warp/native/hashgrid.cpp +301 -278
- warp/native/hashgrid.cu +78 -77
- warp/native/hashgrid.h +227 -227
- warp/native/initializer_array.h +32 -32
- warp/native/intersect.h +1204 -1204
- warp/native/intersect_adj.h +365 -365
- warp/native/intersect_tri.h +322 -322
- warp/native/marching.cpp +2 -2
- warp/native/marching.cu +497 -497
- warp/native/marching.h +2 -2
- warp/native/mat.h +1545 -1498
- warp/native/matnn.h +333 -333
- warp/native/mesh.cpp +203 -203
- warp/native/mesh.cu +292 -293
- warp/native/mesh.h +1887 -1887
- warp/native/nanovdb/GridHandle.h +366 -0
- warp/native/nanovdb/HostBuffer.h +590 -0
- warp/native/nanovdb/NanoVDB.h +6624 -4782
- warp/native/nanovdb/PNanoVDB.h +3390 -2553
- warp/native/noise.h +850 -850
- warp/native/quat.h +1112 -1085
- warp/native/rand.h +303 -299
- warp/native/range.h +108 -108
- warp/native/reduce.cpp +156 -156
- warp/native/reduce.cu +348 -348
- warp/native/runlength_encode.cpp +61 -61
- warp/native/runlength_encode.cu +46 -46
- warp/native/scan.cpp +30 -30
- warp/native/scan.cu +36 -36
- warp/native/scan.h +7 -7
- warp/native/solid_angle.h +442 -442
- warp/native/sort.cpp +94 -94
- warp/native/sort.cu +97 -97
- warp/native/sort.h +14 -14
- warp/native/sparse.cpp +337 -337
- warp/native/sparse.cu +544 -544
- warp/native/spatial.h +630 -630
- warp/native/svd.h +562 -562
- warp/native/temp_buffer.h +30 -30
- warp/native/vec.h +1177 -1133
- warp/native/volume.cpp +529 -297
- warp/native/volume.cu +58 -32
- warp/native/volume.h +960 -538
- warp/native/volume_builder.cu +446 -425
- warp/native/volume_builder.h +34 -19
- warp/native/volume_impl.h +61 -0
- warp/native/warp.cpp +1057 -1052
- warp/native/warp.cu +2949 -2828
- warp/native/warp.h +321 -305
- warp/optim/__init__.py +9 -9
- warp/optim/adam.py +120 -120
- warp/optim/linear.py +1104 -939
- warp/optim/sgd.py +104 -92
- warp/render/__init__.py +10 -10
- warp/render/render_opengl.py +3356 -3204
- warp/render/render_usd.py +768 -749
- warp/render/utils.py +152 -150
- warp/sim/__init__.py +52 -59
- warp/sim/articulation.py +685 -685
- warp/sim/collide.py +1594 -1590
- warp/sim/import_mjcf.py +489 -481
- warp/sim/import_snu.py +220 -221
- warp/sim/import_urdf.py +536 -516
- warp/sim/import_usd.py +887 -881
- warp/sim/inertia.py +316 -317
- warp/sim/integrator.py +234 -233
- warp/sim/integrator_euler.py +1956 -1956
- warp/sim/integrator_featherstone.py +1917 -1991
- warp/sim/integrator_xpbd.py +3288 -3312
- warp/sim/model.py +4473 -4314
- warp/sim/particles.py +113 -112
- warp/sim/render.py +417 -403
- warp/sim/utils.py +413 -410
- warp/sparse.py +1289 -1227
- warp/stubs.py +2192 -2469
- warp/tape.py +1162 -225
- warp/tests/__init__.py +1 -1
- warp/tests/__main__.py +4 -4
- warp/tests/assets/test_index_grid.nvdb +0 -0
- warp/tests/assets/torus.usda +105 -105
- warp/tests/aux_test_class_kernel.py +26 -26
- warp/tests/aux_test_compile_consts_dummy.py +10 -10
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -21
- warp/tests/aux_test_dependent.py +20 -22
- warp/tests/aux_test_grad_customs.py +21 -23
- warp/tests/aux_test_reference.py +9 -11
- warp/tests/aux_test_reference_reference.py +8 -10
- warp/tests/aux_test_square.py +15 -17
- warp/tests/aux_test_unresolved_func.py +14 -14
- warp/tests/aux_test_unresolved_symbol.py +14 -14
- warp/tests/disabled_kinematics.py +237 -239
- warp/tests/run_coverage_serial.py +31 -31
- warp/tests/test_adam.py +155 -157
- warp/tests/test_arithmetic.py +1088 -1124
- warp/tests/test_array.py +2415 -2326
- warp/tests/test_array_reduce.py +148 -150
- warp/tests/test_async.py +666 -656
- warp/tests/test_atomic.py +139 -141
- warp/tests/test_bool.py +212 -149
- warp/tests/test_builtins_resolution.py +1290 -1292
- warp/tests/test_bvh.py +162 -171
- warp/tests/test_closest_point_edge_edge.py +227 -228
- warp/tests/test_codegen.py +562 -553
- warp/tests/test_compile_consts.py +217 -101
- warp/tests/test_conditional.py +244 -246
- warp/tests/test_copy.py +230 -215
- warp/tests/test_ctypes.py +630 -632
- warp/tests/test_dense.py +65 -67
- warp/tests/test_devices.py +89 -98
- warp/tests/test_dlpack.py +528 -529
- warp/tests/test_examples.py +403 -378
- warp/tests/test_fabricarray.py +952 -955
- warp/tests/test_fast_math.py +60 -54
- warp/tests/test_fem.py +1298 -1278
- warp/tests/test_fp16.py +128 -130
- warp/tests/test_func.py +336 -337
- warp/tests/test_generics.py +596 -571
- warp/tests/test_grad.py +885 -640
- warp/tests/test_grad_customs.py +331 -336
- warp/tests/test_hash_grid.py +208 -164
- warp/tests/test_import.py +37 -39
- warp/tests/test_indexedarray.py +1132 -1134
- warp/tests/test_intersect.py +65 -67
- warp/tests/test_jax.py +305 -307
- warp/tests/test_large.py +169 -164
- warp/tests/test_launch.py +352 -354
- warp/tests/test_lerp.py +217 -261
- warp/tests/test_linear_solvers.py +189 -171
- warp/tests/test_lvalue.py +419 -493
- warp/tests/test_marching_cubes.py +63 -65
- warp/tests/test_mat.py +1799 -1827
- warp/tests/test_mat_lite.py +113 -115
- warp/tests/test_mat_scalar_ops.py +2905 -2889
- warp/tests/test_math.py +124 -193
- warp/tests/test_matmul.py +498 -499
- warp/tests/test_matmul_lite.py +408 -410
- warp/tests/test_mempool.py +186 -190
- warp/tests/test_mesh.py +281 -324
- warp/tests/test_mesh_query_aabb.py +226 -241
- warp/tests/test_mesh_query_point.py +690 -702
- warp/tests/test_mesh_query_ray.py +290 -303
- warp/tests/test_mlp.py +274 -276
- warp/tests/test_model.py +108 -110
- warp/tests/test_module_hashing.py +111 -0
- warp/tests/test_modules_lite.py +36 -39
- warp/tests/test_multigpu.py +161 -163
- warp/tests/test_noise.py +244 -248
- warp/tests/test_operators.py +248 -250
- warp/tests/test_options.py +121 -125
- warp/tests/test_peer.py +131 -137
- warp/tests/test_pinned.py +76 -78
- warp/tests/test_print.py +52 -54
- warp/tests/test_quat.py +2084 -2086
- warp/tests/test_rand.py +324 -288
- warp/tests/test_reload.py +207 -217
- warp/tests/test_rounding.py +177 -179
- warp/tests/test_runlength_encode.py +188 -190
- warp/tests/test_sim_grad.py +241 -0
- warp/tests/test_sim_kinematics.py +89 -97
- warp/tests/test_smoothstep.py +166 -168
- warp/tests/test_snippet.py +303 -266
- warp/tests/test_sparse.py +466 -460
- warp/tests/test_spatial.py +2146 -2148
- warp/tests/test_special_values.py +362 -0
- warp/tests/test_streams.py +484 -473
- warp/tests/test_struct.py +708 -675
- warp/tests/test_tape.py +171 -148
- warp/tests/test_torch.py +741 -743
- warp/tests/test_transient_module.py +85 -87
- warp/tests/test_types.py +554 -659
- warp/tests/test_utils.py +488 -499
- warp/tests/test_vec.py +1262 -1268
- warp/tests/test_vec_lite.py +71 -73
- warp/tests/test_vec_scalar_ops.py +2097 -2099
- warp/tests/test_verify_fp.py +92 -94
- warp/tests/test_volume.py +961 -736
- warp/tests/test_volume_write.py +338 -265
- warp/tests/unittest_serial.py +38 -37
- warp/tests/unittest_suites.py +367 -359
- warp/tests/unittest_utils.py +434 -578
- warp/tests/unused_test_misc.py +69 -71
- warp/tests/walkthrough_debug.py +85 -85
- warp/thirdparty/appdirs.py +598 -598
- warp/thirdparty/dlpack.py +143 -143
- warp/thirdparty/unittest_parallel.py +563 -561
- warp/torch.py +321 -295
- warp/types.py +4941 -4450
- warp/utils.py +1008 -821
- {warp_lang-1.0.2.dist-info → warp_lang-1.2.0.dist-info}/LICENSE.md +126 -126
- {warp_lang-1.0.2.dist-info → warp_lang-1.2.0.dist-info}/METADATA +365 -400
- warp_lang-1.2.0.dist-info/RECORD +359 -0
- warp/examples/assets/cube.usda +0 -42
- warp/examples/assets/sphere.usda +0 -56
- warp/examples/assets/torus.usda +0 -105
- warp/examples/fem/example_convection_diffusion_dg0.py +0 -194
- warp/native/nanovdb/PNanoVDBWrite.h +0 -295
- warp_lang-1.0.2.dist-info/RECORD +0 -352
- {warp_lang-1.0.2.dist-info → warp_lang-1.2.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.0.2.dist-info → warp_lang-1.2.0.dist-info}/top_level.txt +0 -0
warp/examples/fem/plot_utils.py
CHANGED
|
@@ -1,287 +1,292 @@
|
|
|
1
|
-
from typing import Set
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
|
|
5
|
-
from warp.fem import DiscreteField
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def plot_grid_surface(field, axes=None):
|
|
9
|
-
import matplotlib.pyplot as plt
|
|
10
|
-
from matplotlib import cm
|
|
11
|
-
|
|
12
|
-
if axes is None:
|
|
13
|
-
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
14
|
-
|
|
15
|
-
node_positions = field.space.node_grid()
|
|
16
|
-
|
|
17
|
-
# Make data.
|
|
18
|
-
X = node_positions[0]
|
|
19
|
-
Y = node_positions[1]
|
|
20
|
-
Z = field.dof_values.numpy().reshape(X.shape)
|
|
21
|
-
|
|
22
|
-
# Plot the surface.
|
|
23
|
-
return axes.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def plot_tri_surface(field, axes=None):
|
|
27
|
-
import matplotlib.pyplot as plt
|
|
28
|
-
from matplotlib import cm
|
|
29
|
-
from matplotlib.tri.triangulation import Triangulation
|
|
30
|
-
|
|
31
|
-
if axes is None:
|
|
32
|
-
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
33
|
-
|
|
34
|
-
node_positions = field.space.node_positions().numpy()
|
|
35
|
-
|
|
36
|
-
triangulation = Triangulation(
|
|
37
|
-
x=node_positions[:, 0], y=node_positions[:, 1], triangles=field.space.node_triangulation()
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
Z = field.dof_values.numpy()
|
|
41
|
-
|
|
42
|
-
# Plot the surface.
|
|
43
|
-
return axes.plot_trisurf(triangulation, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def plot_scatter_surface(field, axes=None):
|
|
47
|
-
import matplotlib.pyplot as plt
|
|
48
|
-
from matplotlib import cm
|
|
49
|
-
|
|
50
|
-
if axes is None:
|
|
51
|
-
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
52
|
-
|
|
53
|
-
X, Y = field.space.node_positions().numpy().T
|
|
54
|
-
|
|
55
|
-
# Make data.
|
|
56
|
-
Z = field.dof_values.numpy().reshape(X.shape)
|
|
57
|
-
|
|
58
|
-
# Plot the surface.
|
|
59
|
-
return axes.scatter(X, Y, Z, c=Z, cmap=cm.coolwarm)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def plot_surface(field, axes=None):
|
|
63
|
-
if hasattr(field.space, "node_grid"):
|
|
64
|
-
return plot_grid_surface(field, axes)
|
|
65
|
-
elif hasattr(field.space, "node_triangulation"):
|
|
66
|
-
return plot_tri_surface(field, axes)
|
|
67
|
-
else:
|
|
68
|
-
return plot_scatter_surface(field, axes)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def plot_grid_color(field, axes=None):
|
|
72
|
-
import matplotlib.pyplot as plt
|
|
73
|
-
from matplotlib import cm
|
|
74
|
-
|
|
75
|
-
if axes is None:
|
|
76
|
-
fig, axes = plt.subplots()
|
|
77
|
-
|
|
78
|
-
node_positions = field.space.node_grid()
|
|
79
|
-
|
|
80
|
-
# Make data.
|
|
81
|
-
X = node_positions[0]
|
|
82
|
-
Y = node_positions[1]
|
|
83
|
-
Z = field.dof_values.numpy().reshape(X.shape)
|
|
84
|
-
|
|
85
|
-
# Plot the surface.
|
|
86
|
-
return axes.pcolormesh(X, Y, Z, cmap=cm.coolwarm)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def plot_velocities(field, axes=None):
|
|
90
|
-
import matplotlib.pyplot as plt
|
|
91
|
-
|
|
92
|
-
if axes is None:
|
|
93
|
-
fig, axes = plt.subplots()
|
|
94
|
-
|
|
95
|
-
node_positions = field.space.node_positions().numpy()
|
|
96
|
-
|
|
97
|
-
# Make data.
|
|
98
|
-
X = node_positions[:, 0]
|
|
99
|
-
Y = node_positions[:, 1]
|
|
100
|
-
|
|
101
|
-
vel = field.dof_values.numpy()
|
|
102
|
-
u = np.ascontiguousarray(vel[:, 0])
|
|
103
|
-
v = np.ascontiguousarray(vel[:, 1])
|
|
104
|
-
|
|
105
|
-
u = u.reshape(X.shape)
|
|
106
|
-
v = v.reshape(X.shape)
|
|
107
|
-
|
|
108
|
-
return axes.quiver(X, Y, u, v)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def plot_grid_streamlines(field, axes=None):
|
|
112
|
-
import matplotlib.pyplot as plt
|
|
113
|
-
|
|
114
|
-
if axes is None:
|
|
115
|
-
fig, axes = plt.subplots()
|
|
116
|
-
|
|
117
|
-
node_positions = field.space.node_grid()
|
|
118
|
-
|
|
119
|
-
# Make data.
|
|
120
|
-
X = node_positions[0][:, 0]
|
|
121
|
-
Y = node_positions[1][0, :]
|
|
122
|
-
|
|
123
|
-
vel = field.dof_values.numpy()
|
|
124
|
-
u = np.ascontiguousarray(vel[:, 0])
|
|
125
|
-
v = np.ascontiguousarray(vel[:, 1])
|
|
126
|
-
|
|
127
|
-
u = np.transpose(u.reshape(node_positions[0].shape))
|
|
128
|
-
v = np.transpose(v.reshape(node_positions[0].shape))
|
|
129
|
-
|
|
130
|
-
splot = axes.streamplot(X, Y, u, v, density=2)
|
|
131
|
-
splot.axes = axes
|
|
132
|
-
return splot
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def plot_3d_scatter(field, axes=None):
|
|
136
|
-
import matplotlib.pyplot as plt
|
|
137
|
-
from matplotlib import cm
|
|
138
|
-
|
|
139
|
-
if axes is None:
|
|
140
|
-
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
141
|
-
|
|
142
|
-
X, Y, Z = field.space.node_positions().numpy().T
|
|
143
|
-
|
|
144
|
-
# Make data.
|
|
145
|
-
f = field.dof_values.numpy().reshape(X.shape)
|
|
146
|
-
|
|
147
|
-
# Plot the surface.
|
|
148
|
-
return axes.scatter(X, Y, Z, c=f, cmap=cm.coolwarm)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def plot_3d_velocities(field, axes=None):
|
|
152
|
-
import matplotlib.pyplot as plt
|
|
153
|
-
|
|
154
|
-
if axes is None:
|
|
155
|
-
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
156
|
-
|
|
157
|
-
X, Y, Z = field.space.node_positions().numpy().T
|
|
158
|
-
|
|
159
|
-
vel = field.dof_values.numpy()
|
|
160
|
-
u = np.ascontiguousarray(vel[:, 0])
|
|
161
|
-
v = np.ascontiguousarray(vel[:, 1])
|
|
162
|
-
w = np.ascontiguousarray(vel[:, 2])
|
|
163
|
-
|
|
164
|
-
u = u.reshape(X.shape)
|
|
165
|
-
v = v.reshape(X.shape)
|
|
166
|
-
w = w.reshape(X.shape)
|
|
167
|
-
|
|
168
|
-
return axes.quiver(X, Y, Z, u, v, w, length=1.0 / X.shape[0], normalize=False)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
class Plot:
|
|
172
|
-
def __init__(self, stage=None, default_point_radius=0.01):
|
|
173
|
-
self.default_point_radius = default_point_radius
|
|
174
|
-
|
|
175
|
-
self._surfaces = {}
|
|
176
|
-
self._surface_vectors = {}
|
|
177
|
-
self._volumes = {}
|
|
178
|
-
|
|
179
|
-
self._usd_renderer = None
|
|
180
|
-
if stage is not None:
|
|
181
|
-
try:
|
|
182
|
-
from warp.render import UsdRenderer
|
|
183
|
-
|
|
184
|
-
self._usd_renderer = UsdRenderer(stage)
|
|
185
|
-
except Exception as err:
|
|
186
|
-
print(f"Could not initialize UsdRenderer for stage '{stage}': {err}.")
|
|
187
|
-
|
|
188
|
-
def begin_frame(self, time):
|
|
189
|
-
if self._usd_renderer is not None:
|
|
190
|
-
self._usd_renderer.begin_frame(time=time)
|
|
191
|
-
|
|
192
|
-
def end_frame(self):
|
|
193
|
-
if self._usd_renderer is not None:
|
|
194
|
-
self._usd_renderer.end_frame()
|
|
195
|
-
|
|
196
|
-
def add_surface(self, name: str, field: DiscreteField):
|
|
197
|
-
if self._usd_renderer is not None:
|
|
198
|
-
points_2d = field.space.node_positions().numpy()
|
|
199
|
-
values = field.dof_values.numpy()
|
|
200
|
-
points_3d = np.hstack((points_2d, values.reshape(-1, 1)))
|
|
201
|
-
|
|
202
|
-
if hasattr(field.space, "node_triangulation"):
|
|
203
|
-
indices = field.space.node_triangulation()
|
|
204
|
-
self._usd_renderer.render_mesh(name, points=points_3d, indices=indices)
|
|
205
|
-
else:
|
|
206
|
-
self._usd_renderer.render_points(name, points=points_3d, radius=self.default_point_radius)
|
|
207
|
-
|
|
208
|
-
if name not in self._surfaces:
|
|
209
|
-
field_clone = field.space.make_field(space_partition=field.space_partition)
|
|
210
|
-
self._surfaces[name] = (field_clone, [])
|
|
211
|
-
|
|
212
|
-
self._surfaces[name][1].append(field.dof_values.numpy())
|
|
213
|
-
|
|
214
|
-
def add_surface_vector(self, name: str, field: DiscreteField):
|
|
215
|
-
if self._usd_renderer is not None:
|
|
216
|
-
points_2d = field.space.node_positions().numpy()
|
|
217
|
-
values = field.dof_values.numpy()
|
|
218
|
-
points_3d = np.hstack((points_2d + values, np.zeros_like(points_2d[:, 0]).reshape(-1, 1)))
|
|
219
|
-
|
|
220
|
-
if hasattr(field.space, "node_triangulation"):
|
|
221
|
-
indices = field.space.node_triangulation()
|
|
222
|
-
self._usd_renderer.render_mesh(name, points=points_3d, indices=indices)
|
|
223
|
-
else:
|
|
224
|
-
self._usd_renderer.render_points(name, points=points_3d, radius=self.default_point_radius)
|
|
225
|
-
|
|
226
|
-
if name not in self._surface_vectors:
|
|
227
|
-
field_clone = field.space.make_field(space_partition=field.space_partition)
|
|
228
|
-
self._surface_vectors[name] = (field_clone, [])
|
|
229
|
-
|
|
230
|
-
self._surface_vectors[name][1].append(field.dof_values.numpy())
|
|
231
|
-
|
|
232
|
-
def add_volume(self, name: str, field: DiscreteField):
|
|
233
|
-
if self._usd_renderer is not None:
|
|
234
|
-
points_3d = field.space.node_positions().numpy()
|
|
235
|
-
values = field.dof_values.numpy()
|
|
236
|
-
|
|
237
|
-
self._usd_renderer.render_points(name, points_3d, radius=values)
|
|
238
|
-
|
|
239
|
-
if name not in self._volumes:
|
|
240
|
-
field_clone = field.space.make_field(space_partition=field.space_partition)
|
|
241
|
-
self._volumes[name] = (field_clone, [])
|
|
242
|
-
|
|
243
|
-
self._volumes[name][1].append(field.dof_values.numpy())
|
|
244
|
-
|
|
245
|
-
def plot(self, streamlines: Set[str] =
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
ax.
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if
|
|
276
|
-
ax =
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
1
|
+
from typing import Set
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from warp.fem import DiscreteField
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def plot_grid_surface(field, axes=None):
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
from matplotlib import cm
|
|
11
|
+
|
|
12
|
+
if axes is None:
|
|
13
|
+
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
14
|
+
|
|
15
|
+
node_positions = field.space.node_grid()
|
|
16
|
+
|
|
17
|
+
# Make data.
|
|
18
|
+
X = node_positions[0]
|
|
19
|
+
Y = node_positions[1]
|
|
20
|
+
Z = field.dof_values.numpy().reshape(X.shape)
|
|
21
|
+
|
|
22
|
+
# Plot the surface.
|
|
23
|
+
return axes.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def plot_tri_surface(field, axes=None):
|
|
27
|
+
import matplotlib.pyplot as plt
|
|
28
|
+
from matplotlib import cm
|
|
29
|
+
from matplotlib.tri.triangulation import Triangulation
|
|
30
|
+
|
|
31
|
+
if axes is None:
|
|
32
|
+
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
33
|
+
|
|
34
|
+
node_positions = field.space.node_positions().numpy()
|
|
35
|
+
|
|
36
|
+
triangulation = Triangulation(
|
|
37
|
+
x=node_positions[:, 0], y=node_positions[:, 1], triangles=field.space.node_triangulation()
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
Z = field.dof_values.numpy()
|
|
41
|
+
|
|
42
|
+
# Plot the surface.
|
|
43
|
+
return axes.plot_trisurf(triangulation, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def plot_scatter_surface(field, axes=None):
|
|
47
|
+
import matplotlib.pyplot as plt
|
|
48
|
+
from matplotlib import cm
|
|
49
|
+
|
|
50
|
+
if axes is None:
|
|
51
|
+
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
52
|
+
|
|
53
|
+
X, Y = field.space.node_positions().numpy().T
|
|
54
|
+
|
|
55
|
+
# Make data.
|
|
56
|
+
Z = field.dof_values.numpy().reshape(X.shape)
|
|
57
|
+
|
|
58
|
+
# Plot the surface.
|
|
59
|
+
return axes.scatter(X, Y, Z, c=Z, cmap=cm.coolwarm)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def plot_surface(field, axes=None):
|
|
63
|
+
if hasattr(field.space, "node_grid"):
|
|
64
|
+
return plot_grid_surface(field, axes)
|
|
65
|
+
elif hasattr(field.space, "node_triangulation"):
|
|
66
|
+
return plot_tri_surface(field, axes)
|
|
67
|
+
else:
|
|
68
|
+
return plot_scatter_surface(field, axes)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def plot_grid_color(field, axes=None):
|
|
72
|
+
import matplotlib.pyplot as plt
|
|
73
|
+
from matplotlib import cm
|
|
74
|
+
|
|
75
|
+
if axes is None:
|
|
76
|
+
fig, axes = plt.subplots()
|
|
77
|
+
|
|
78
|
+
node_positions = field.space.node_grid()
|
|
79
|
+
|
|
80
|
+
# Make data.
|
|
81
|
+
X = node_positions[0]
|
|
82
|
+
Y = node_positions[1]
|
|
83
|
+
Z = field.dof_values.numpy().reshape(X.shape)
|
|
84
|
+
|
|
85
|
+
# Plot the surface.
|
|
86
|
+
return axes.pcolormesh(X, Y, Z, cmap=cm.coolwarm)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def plot_velocities(field, axes=None):
|
|
90
|
+
import matplotlib.pyplot as plt
|
|
91
|
+
|
|
92
|
+
if axes is None:
|
|
93
|
+
fig, axes = plt.subplots()
|
|
94
|
+
|
|
95
|
+
node_positions = field.space.node_positions().numpy()
|
|
96
|
+
|
|
97
|
+
# Make data.
|
|
98
|
+
X = node_positions[:, 0]
|
|
99
|
+
Y = node_positions[:, 1]
|
|
100
|
+
|
|
101
|
+
vel = field.dof_values.numpy()
|
|
102
|
+
u = np.ascontiguousarray(vel[:, 0])
|
|
103
|
+
v = np.ascontiguousarray(vel[:, 1])
|
|
104
|
+
|
|
105
|
+
u = u.reshape(X.shape)
|
|
106
|
+
v = v.reshape(X.shape)
|
|
107
|
+
|
|
108
|
+
return axes.quiver(X, Y, u, v)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def plot_grid_streamlines(field, axes=None):
|
|
112
|
+
import matplotlib.pyplot as plt
|
|
113
|
+
|
|
114
|
+
if axes is None:
|
|
115
|
+
fig, axes = plt.subplots()
|
|
116
|
+
|
|
117
|
+
node_positions = field.space.node_grid()
|
|
118
|
+
|
|
119
|
+
# Make data.
|
|
120
|
+
X = node_positions[0][:, 0]
|
|
121
|
+
Y = node_positions[1][0, :]
|
|
122
|
+
|
|
123
|
+
vel = field.dof_values.numpy()
|
|
124
|
+
u = np.ascontiguousarray(vel[:, 0])
|
|
125
|
+
v = np.ascontiguousarray(vel[:, 1])
|
|
126
|
+
|
|
127
|
+
u = np.transpose(u.reshape(node_positions[0].shape))
|
|
128
|
+
v = np.transpose(v.reshape(node_positions[0].shape))
|
|
129
|
+
|
|
130
|
+
splot = axes.streamplot(X, Y, u, v, density=2)
|
|
131
|
+
splot.axes = axes
|
|
132
|
+
return splot
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def plot_3d_scatter(field, axes=None):
|
|
136
|
+
import matplotlib.pyplot as plt
|
|
137
|
+
from matplotlib import cm
|
|
138
|
+
|
|
139
|
+
if axes is None:
|
|
140
|
+
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
141
|
+
|
|
142
|
+
X, Y, Z = field.space.node_positions().numpy().T
|
|
143
|
+
|
|
144
|
+
# Make data.
|
|
145
|
+
f = field.dof_values.numpy().reshape(X.shape)
|
|
146
|
+
|
|
147
|
+
# Plot the surface.
|
|
148
|
+
return axes.scatter(X, Y, Z, c=f, cmap=cm.coolwarm)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def plot_3d_velocities(field, axes=None):
|
|
152
|
+
import matplotlib.pyplot as plt
|
|
153
|
+
|
|
154
|
+
if axes is None:
|
|
155
|
+
fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
|
|
156
|
+
|
|
157
|
+
X, Y, Z = field.space.node_positions().numpy().T
|
|
158
|
+
|
|
159
|
+
vel = field.dof_values.numpy()
|
|
160
|
+
u = np.ascontiguousarray(vel[:, 0])
|
|
161
|
+
v = np.ascontiguousarray(vel[:, 1])
|
|
162
|
+
w = np.ascontiguousarray(vel[:, 2])
|
|
163
|
+
|
|
164
|
+
u = u.reshape(X.shape)
|
|
165
|
+
v = v.reshape(X.shape)
|
|
166
|
+
w = w.reshape(X.shape)
|
|
167
|
+
|
|
168
|
+
return axes.quiver(X, Y, Z, u, v, w, length=1.0 / X.shape[0], normalize=False)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class Plot:
|
|
172
|
+
def __init__(self, stage=None, default_point_radius=0.01):
|
|
173
|
+
self.default_point_radius = default_point_radius
|
|
174
|
+
|
|
175
|
+
self._surfaces = {}
|
|
176
|
+
self._surface_vectors = {}
|
|
177
|
+
self._volumes = {}
|
|
178
|
+
|
|
179
|
+
self._usd_renderer = None
|
|
180
|
+
if stage is not None:
|
|
181
|
+
try:
|
|
182
|
+
from warp.render import UsdRenderer
|
|
183
|
+
|
|
184
|
+
self._usd_renderer = UsdRenderer(stage)
|
|
185
|
+
except Exception as err:
|
|
186
|
+
print(f"Could not initialize UsdRenderer for stage '{stage}': {err}.")
|
|
187
|
+
|
|
188
|
+
def begin_frame(self, time):
|
|
189
|
+
if self._usd_renderer is not None:
|
|
190
|
+
self._usd_renderer.begin_frame(time=time)
|
|
191
|
+
|
|
192
|
+
def end_frame(self):
|
|
193
|
+
if self._usd_renderer is not None:
|
|
194
|
+
self._usd_renderer.end_frame()
|
|
195
|
+
|
|
196
|
+
def add_surface(self, name: str, field: DiscreteField):
|
|
197
|
+
if self._usd_renderer is not None:
|
|
198
|
+
points_2d = field.space.node_positions().numpy()
|
|
199
|
+
values = field.dof_values.numpy()
|
|
200
|
+
points_3d = np.hstack((points_2d, values.reshape(-1, 1)))
|
|
201
|
+
|
|
202
|
+
if hasattr(field.space, "node_triangulation"):
|
|
203
|
+
indices = field.space.node_triangulation()
|
|
204
|
+
self._usd_renderer.render_mesh(name, points=points_3d, indices=indices)
|
|
205
|
+
else:
|
|
206
|
+
self._usd_renderer.render_points(name, points=points_3d, radius=self.default_point_radius)
|
|
207
|
+
|
|
208
|
+
if name not in self._surfaces:
|
|
209
|
+
field_clone = field.space.make_field(space_partition=field.space_partition)
|
|
210
|
+
self._surfaces[name] = (field_clone, [])
|
|
211
|
+
|
|
212
|
+
self._surfaces[name][1].append(field.dof_values.numpy())
|
|
213
|
+
|
|
214
|
+
def add_surface_vector(self, name: str, field: DiscreteField):
|
|
215
|
+
if self._usd_renderer is not None:
|
|
216
|
+
points_2d = field.space.node_positions().numpy()
|
|
217
|
+
values = field.dof_values.numpy()
|
|
218
|
+
points_3d = np.hstack((points_2d + values, np.zeros_like(points_2d[:, 0]).reshape(-1, 1)))
|
|
219
|
+
|
|
220
|
+
if hasattr(field.space, "node_triangulation"):
|
|
221
|
+
indices = field.space.node_triangulation()
|
|
222
|
+
self._usd_renderer.render_mesh(name, points=points_3d, indices=indices)
|
|
223
|
+
else:
|
|
224
|
+
self._usd_renderer.render_points(name, points=points_3d, radius=self.default_point_radius)
|
|
225
|
+
|
|
226
|
+
if name not in self._surface_vectors:
|
|
227
|
+
field_clone = field.space.make_field(space_partition=field.space_partition)
|
|
228
|
+
self._surface_vectors[name] = (field_clone, [])
|
|
229
|
+
|
|
230
|
+
self._surface_vectors[name][1].append(field.dof_values.numpy())
|
|
231
|
+
|
|
232
|
+
def add_volume(self, name: str, field: DiscreteField):
|
|
233
|
+
if self._usd_renderer is not None:
|
|
234
|
+
points_3d = field.space.node_positions().numpy()
|
|
235
|
+
values = field.dof_values.numpy()
|
|
236
|
+
|
|
237
|
+
self._usd_renderer.render_points(name, points_3d, radius=values)
|
|
238
|
+
|
|
239
|
+
if name not in self._volumes:
|
|
240
|
+
field_clone = field.space.make_field(space_partition=field.space_partition)
|
|
241
|
+
self._volumes[name] = (field_clone, [])
|
|
242
|
+
|
|
243
|
+
self._volumes[name][1].append(field.dof_values.numpy())
|
|
244
|
+
|
|
245
|
+
def plot(self, streamlines: Set[str] = None):
|
|
246
|
+
if streamlines is None:
|
|
247
|
+
streamlines = []
|
|
248
|
+
return self._plot_matplotlib(streamlines)
|
|
249
|
+
|
|
250
|
+
def _plot_matplotlib(self, streamlines: Set[str] = None):
|
|
251
|
+
import matplotlib.animation as animation
|
|
252
|
+
import matplotlib.pyplot as plt
|
|
253
|
+
|
|
254
|
+
if streamlines is None:
|
|
255
|
+
streamlines = []
|
|
256
|
+
|
|
257
|
+
def make_animation(ax, field, values, plot_func, num_frames: int):
|
|
258
|
+
def animate(i):
|
|
259
|
+
ax.clear()
|
|
260
|
+
field.dof_values = values[i]
|
|
261
|
+
return plot_func(field, axes=ax)
|
|
262
|
+
|
|
263
|
+
return animation.FuncAnimation(
|
|
264
|
+
ax.figure,
|
|
265
|
+
animate,
|
|
266
|
+
interval=30,
|
|
267
|
+
blit=False,
|
|
268
|
+
frames=len(values),
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
for _name, (field, values) in self._surfaces.items():
|
|
272
|
+
field.dof_values = values[0]
|
|
273
|
+
ax = plot_surface(field).axes
|
|
274
|
+
|
|
275
|
+
if len(values) > 1:
|
|
276
|
+
_anim = make_animation(ax, field, values, plot_func=plot_surface, num_frames=len(values))
|
|
277
|
+
|
|
278
|
+
for name, (field, values) in self._surface_vectors.items():
|
|
279
|
+
field.dof_values = values[0]
|
|
280
|
+
if name in streamlines and hasattr(field.space, "node_grid"):
|
|
281
|
+
ax = plot_grid_streamlines(field).axes
|
|
282
|
+
else:
|
|
283
|
+
ax = plot_velocities(field).axes
|
|
284
|
+
|
|
285
|
+
if len(values) > 1:
|
|
286
|
+
_anim = make_animation(ax, field, values, plot_func=plot_velocities, num_frames=len(values))
|
|
287
|
+
|
|
288
|
+
for _name, (field, values) in self._volumes.items():
|
|
289
|
+
field.dof_values = values[0]
|
|
290
|
+
ax = plot_3d_scatter(field).axes
|
|
291
|
+
|
|
292
|
+
plt.show()
|