warp-lang 1.0.2__py3-none-manylinux2014_x86_64.whl → 1.2.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 +108 -97
- warp/__init__.pyi +1 -1
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +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
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
|
|
2
|
+
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
|
3
|
+
# and proprietary rights in and to this software, related documentation
|
|
4
|
+
# and any modifications thereto. Any use, reproduction, disclosure or
|
|
5
|
+
# distribution of this software and related documentation without an express
|
|
6
|
+
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
|
+
|
|
8
|
+
###########################################################################
|
|
9
|
+
# Example Burgers
|
|
10
|
+
#
|
|
11
|
+
# This example simulates an inviscid non-conservative Burgers PDE using
|
|
12
|
+
# Discontinuous Galerkin with minmod slope limiter
|
|
13
|
+
#
|
|
14
|
+
# d u /dt + (u . grad) u = 0
|
|
15
|
+
#
|
|
16
|
+
###########################################################################
|
|
17
|
+
|
|
18
|
+
import warp as wp
|
|
19
|
+
import warp.fem as fem
|
|
20
|
+
import warp.sparse as sp
|
|
21
|
+
|
|
22
|
+
# Import example utilities
|
|
23
|
+
# Make sure that works both when imported as module and run as standalone file
|
|
24
|
+
try:
|
|
25
|
+
from .bsr_utils import invert_diagonal_bsr_mass_matrix
|
|
26
|
+
from .plot_utils import Plot
|
|
27
|
+
except ImportError:
|
|
28
|
+
from bsr_utils import invert_diagonal_bsr_mass_matrix
|
|
29
|
+
from plot_utils import Plot
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@fem.integrand
|
|
33
|
+
def vel_mass_form(
|
|
34
|
+
s: fem.Sample,
|
|
35
|
+
u: fem.Field,
|
|
36
|
+
v: fem.Field,
|
|
37
|
+
):
|
|
38
|
+
return wp.dot(v(s), u(s))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@fem.integrand
|
|
42
|
+
def upwind_transport_form(s: fem.Sample, domain: fem.Domain, u: fem.Field, v: fem.Field, w: fem.Field):
|
|
43
|
+
# Upwinding transport with discontinuous convection velocity,
|
|
44
|
+
# using jump(w v) = jump(w) avg(v) + avg(w) jump(w)
|
|
45
|
+
|
|
46
|
+
nor = fem.normal(domain, s)
|
|
47
|
+
w_avg_n = wp.dot(fem.average(w, s), nor)
|
|
48
|
+
w_jump_n = wp.dot(fem.jump(w, s), nor)
|
|
49
|
+
|
|
50
|
+
x = domain(s)
|
|
51
|
+
v_avg = fem.average(v, s)
|
|
52
|
+
if x[0] <= 0.0 or x[0] >= 1.0: # out
|
|
53
|
+
# if x[0] >= 1.0: # out
|
|
54
|
+
v_jump = v(s)
|
|
55
|
+
else:
|
|
56
|
+
v_jump = fem.jump(v, s)
|
|
57
|
+
|
|
58
|
+
u_avg = fem.average(u, s)
|
|
59
|
+
u_jump = fem.jump(u, s)
|
|
60
|
+
|
|
61
|
+
return wp.dot(u_avg, v_jump * w_avg_n + v_avg * w_jump_n) + 0.5 * wp.dot(v_jump, u_jump) * (
|
|
62
|
+
wp.abs(w_avg_n) + 0.5 * wp.abs(w_jump_n)
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@fem.integrand
|
|
67
|
+
def cell_transport_form(s: fem.Sample, domain: fem.Domain, u: fem.Field, v: fem.Field, w: fem.Field):
|
|
68
|
+
# ((w . grad) u) . v = v^T (grad u) w = grad(u) : (v w^T)
|
|
69
|
+
# with integration by parts
|
|
70
|
+
# u . Div (w v^T) = u^T grad(v) w + u^T v div (w)
|
|
71
|
+
|
|
72
|
+
return -wp.dot(fem.div(w, s) * v(s) + fem.grad(v, s) * w(s), u(s))
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@fem.integrand
|
|
76
|
+
def initial_condition(s: fem.Sample, domain: fem.Domain):
|
|
77
|
+
x = domain(s)[0] * 2.0
|
|
78
|
+
wave = wp.sin(x * wp.pi)
|
|
79
|
+
return wp.vec2(wp.select(x <= 1.0, 0.0, wave), 0.0)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@fem.integrand
|
|
83
|
+
def velocity_norm(s: fem.Sample, u: fem.Field):
|
|
84
|
+
return wp.length(u(s))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@wp.func
|
|
88
|
+
def minmod(a: float, b: float):
|
|
89
|
+
sa = wp.sign(a)
|
|
90
|
+
sb = wp.sign(b)
|
|
91
|
+
return wp.select(sa == sb, 0.0, sa * wp.min(wp.abs(a), wp.abs(b)))
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@fem.integrand
|
|
95
|
+
def slope_limiter(domain: fem.Domain, s: fem.Sample, u: fem.Field, dx: wp.vec2):
|
|
96
|
+
# Minmod slope limiter against P0 discretization (evaluation at cell centers)
|
|
97
|
+
# Assumes regular grid topology
|
|
98
|
+
|
|
99
|
+
center_coords = fem.Coords(0.5, 0.5, 0.0)
|
|
100
|
+
cell_center = fem.types.make_free_sample(s.element_index, center_coords)
|
|
101
|
+
center_pos = domain(cell_center)
|
|
102
|
+
|
|
103
|
+
u_center = u(cell_center)
|
|
104
|
+
|
|
105
|
+
delta_coords = s.element_coords - center_coords
|
|
106
|
+
|
|
107
|
+
neighbour_xp = fem.lookup(domain, center_pos + wp.vec2(dx[0], 0.0))
|
|
108
|
+
neighbour_yp = fem.lookup(domain, center_pos + wp.vec2(0.0, dx[1]))
|
|
109
|
+
neighbour_xm = fem.lookup(domain, center_pos - wp.vec2(dx[0], 0.0))
|
|
110
|
+
neighbour_ym = fem.lookup(domain, center_pos - wp.vec2(0.0, dx[1]))
|
|
111
|
+
|
|
112
|
+
u_nxp = u(neighbour_xp)
|
|
113
|
+
u_nyp = u(neighbour_yp)
|
|
114
|
+
u_nxm = u(neighbour_xm)
|
|
115
|
+
u_nym = u(neighbour_ym)
|
|
116
|
+
|
|
117
|
+
gx = minmod(u_nxp[0] - u_center[0], u_center[0] - u_nxm[0]) * delta_coords[0]
|
|
118
|
+
gy = minmod(u_nyp[1] - u_center[1], u_center[1] - u_nym[1]) * delta_coords[1]
|
|
119
|
+
|
|
120
|
+
delta_u = u(s) - u_center
|
|
121
|
+
return u_center + wp.vec2(minmod(gx, delta_u[0]), minmod(gy, delta_u[1]))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class Example:
|
|
125
|
+
def __init__(self, quiet=False, resolution=50, degree=1):
|
|
126
|
+
self._quiet = quiet
|
|
127
|
+
|
|
128
|
+
res = resolution
|
|
129
|
+
self.sim_dt = 1.0 / res
|
|
130
|
+
self.current_frame = 0
|
|
131
|
+
|
|
132
|
+
geo = fem.Grid2D(res=wp.vec2i(resolution))
|
|
133
|
+
|
|
134
|
+
domain = fem.Cells(geometry=geo)
|
|
135
|
+
sides = fem.Sides(geo)
|
|
136
|
+
|
|
137
|
+
basis_space = fem.make_polynomial_basis_space(geo, degree=degree, discontinuous=True)
|
|
138
|
+
vector_space = fem.make_collocated_function_space(basis_space, dtype=wp.vec2)
|
|
139
|
+
scalar_space = fem.make_collocated_function_space(basis_space, dtype=float)
|
|
140
|
+
|
|
141
|
+
# Test function for ou vector space
|
|
142
|
+
self._test = fem.make_test(space=vector_space, domain=domain)
|
|
143
|
+
# Test function for integration on sides
|
|
144
|
+
self._side_test = fem.make_test(space=vector_space, domain=sides)
|
|
145
|
+
|
|
146
|
+
# Inertia matrix
|
|
147
|
+
# For simplicity, use nodal integration so that inertia matrix is diagonal
|
|
148
|
+
trial = fem.make_trial(space=vector_space, domain=domain)
|
|
149
|
+
matrix_inertia = fem.integrate(
|
|
150
|
+
vel_mass_form, fields={"u": trial, "v": self._test}, output_dtype=wp.float32, nodal=True
|
|
151
|
+
)
|
|
152
|
+
self._inv_mass_matrix = sp.bsr_copy(matrix_inertia)
|
|
153
|
+
invert_diagonal_bsr_mass_matrix(self._inv_mass_matrix)
|
|
154
|
+
|
|
155
|
+
# Initial condition
|
|
156
|
+
self.velocity_field = vector_space.make_field()
|
|
157
|
+
fem.interpolate(initial_condition, dest=self.velocity_field)
|
|
158
|
+
|
|
159
|
+
# Velocity nor field -- for visualization purposes
|
|
160
|
+
self.velocity_norm_field = scalar_space.make_field()
|
|
161
|
+
fem.interpolate(velocity_norm, dest=self.velocity_norm_field, fields={"u": self.velocity_field})
|
|
162
|
+
|
|
163
|
+
self.renderer = Plot()
|
|
164
|
+
self.renderer.add_surface("u_norm", self.velocity_norm_field)
|
|
165
|
+
|
|
166
|
+
def _velocity_delta(self, trial_velocity):
|
|
167
|
+
# Integration on sides
|
|
168
|
+
rhs = fem.integrate(
|
|
169
|
+
upwind_transport_form,
|
|
170
|
+
fields={"u": trial_velocity.trace(), "v": self._side_test, "w": trial_velocity.trace()},
|
|
171
|
+
output_dtype=wp.vec2,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
if self.velocity_field.space.degree > 0:
|
|
175
|
+
# Integration on cells (if not piecewise-constant)
|
|
176
|
+
fem.utils.array_axpy(
|
|
177
|
+
x=fem.integrate(
|
|
178
|
+
cell_transport_form,
|
|
179
|
+
fields={"u": trial_velocity, "v": self._test, "w": trial_velocity},
|
|
180
|
+
output_dtype=wp.vec2,
|
|
181
|
+
quadrature=fem.RegularQuadrature(
|
|
182
|
+
order=3, domain=self._test.domain, family=fem.Polynomial.LOBATTO_GAUSS_LEGENDRE
|
|
183
|
+
),
|
|
184
|
+
),
|
|
185
|
+
y=rhs,
|
|
186
|
+
alpha=1.0,
|
|
187
|
+
beta=1.0,
|
|
188
|
+
)
|
|
189
|
+
return sp.bsr_mv(self._inv_mass_matrix, rhs)
|
|
190
|
+
|
|
191
|
+
def step(self):
|
|
192
|
+
self.current_frame += 1
|
|
193
|
+
|
|
194
|
+
# Third-order Strong Stability Preserving Runge-Kutta (SSPRK3)
|
|
195
|
+
|
|
196
|
+
k1 = self._velocity_delta(self.velocity_field)
|
|
197
|
+
|
|
198
|
+
# tmp = v0 - dt * k1
|
|
199
|
+
tmp = self.velocity_field.space.make_field()
|
|
200
|
+
fem.utils.array_axpy(y=tmp.dof_values, x=self.velocity_field.dof_values, alpha=1.0, beta=0.0)
|
|
201
|
+
fem.utils.array_axpy(y=tmp.dof_values, x=k1, alpha=-self.sim_dt, beta=1.0)
|
|
202
|
+
k2 = self._velocity_delta(tmp)
|
|
203
|
+
|
|
204
|
+
# tmp = v0 - dt * (0.25 * k1 + 0.25 * k2)
|
|
205
|
+
fem.utils.array_axpy(y=tmp.dof_values, x=k1, alpha=0.75 * self.sim_dt, beta=1.0)
|
|
206
|
+
fem.utils.array_axpy(y=tmp.dof_values, x=k2, alpha=-0.25 * self.sim_dt, beta=1.0)
|
|
207
|
+
k3 = self._velocity_delta(tmp)
|
|
208
|
+
|
|
209
|
+
# v = v0 - dt * (1/6 * k1 + 1/6 * k2 + 2/3 * k3)
|
|
210
|
+
fem.utils.array_axpy(y=self.velocity_field.dof_values, x=k1, alpha=-1.0 / 6.0 * self.sim_dt, beta=1.0)
|
|
211
|
+
fem.utils.array_axpy(y=self.velocity_field.dof_values, x=k2, alpha=-1.0 / 6.0 * self.sim_dt, beta=1.0)
|
|
212
|
+
fem.utils.array_axpy(y=self.velocity_field.dof_values, x=k3, alpha=-2.0 / 3.0 * self.sim_dt, beta=1.0)
|
|
213
|
+
|
|
214
|
+
# Apply slope limiter
|
|
215
|
+
if self.velocity_field.space.degree > 0:
|
|
216
|
+
res = self.velocity_field.space.geometry.res
|
|
217
|
+
dx = wp.vec2(1.0 / res[0], 1.0 / res[1])
|
|
218
|
+
fem.interpolate(slope_limiter, dest=tmp, fields={"u": self.velocity_field}, values={"dx": dx})
|
|
219
|
+
wp.copy(src=tmp.dof_values, dest=self.velocity_field.dof_values)
|
|
220
|
+
|
|
221
|
+
# Update velocity norm (for visualization)
|
|
222
|
+
fem.interpolate(velocity_norm, dest=self.velocity_norm_field, fields={"u": self.velocity_field})
|
|
223
|
+
|
|
224
|
+
def render(self):
|
|
225
|
+
self.renderer.begin_frame(time=self.current_frame * self.sim_dt)
|
|
226
|
+
self.renderer.add_surface("u_norm", self.velocity_norm_field)
|
|
227
|
+
self.renderer.end_frame()
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
if __name__ == "__main__":
|
|
231
|
+
import argparse
|
|
232
|
+
|
|
233
|
+
wp.set_module_options({"enable_backward": False})
|
|
234
|
+
|
|
235
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
236
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
237
|
+
parser.add_argument("--resolution", type=int, default=50, help="Grid resolution.")
|
|
238
|
+
parser.add_argument("--num_frames", type=int, default=250, help="Total number of frames.")
|
|
239
|
+
parser.add_argument("--degree", choices=(0, 1), type=int, default=1, help="Discretization order.")
|
|
240
|
+
parser.add_argument(
|
|
241
|
+
"--headless",
|
|
242
|
+
action="store_true",
|
|
243
|
+
help="Run in headless mode, suppressing the opening of any graphical windows.",
|
|
244
|
+
)
|
|
245
|
+
parser.add_argument("--quiet", action="store_true")
|
|
246
|
+
|
|
247
|
+
args = parser.parse_known_args()[0]
|
|
248
|
+
|
|
249
|
+
with wp.ScopedDevice(args.device):
|
|
250
|
+
example = Example(
|
|
251
|
+
quiet=args.quiet,
|
|
252
|
+
resolution=args.resolution,
|
|
253
|
+
degree=args.degree,
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
for k in range(args.num_frames):
|
|
257
|
+
print(f"Frame {k}:")
|
|
258
|
+
example.step()
|
|
259
|
+
example.render()
|
|
260
|
+
|
|
261
|
+
if not args.headless:
|
|
262
|
+
example.renderer.plot()
|
|
@@ -1,168 +1,180 @@
|
|
|
1
|
-
# Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
|
|
2
|
-
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
|
3
|
-
# and proprietary rights in and to this software, related documentation
|
|
4
|
-
# and any modifications thereto. Any use, reproduction, disclosure or
|
|
5
|
-
# distribution of this software and related documentation without an express
|
|
6
|
-
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
|
-
|
|
8
|
-
###########################################################################
|
|
9
|
-
# Example Convection Diffusion
|
|
10
|
-
#
|
|
11
|
-
# This example simulates a convection-diffusion PDE using
|
|
12
|
-
# semi-Lagrangian advection
|
|
13
|
-
#
|
|
14
|
-
# D phi / dt - nu d2 phi / dx^2 = 0
|
|
15
|
-
###########################################################################
|
|
16
|
-
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
from .
|
|
26
|
-
|
|
27
|
-
from
|
|
28
|
-
|
|
29
|
-
from
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
self.
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
self.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
example
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
1
|
+
# Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
|
|
2
|
+
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
|
3
|
+
# and proprietary rights in and to this software, related documentation
|
|
4
|
+
# and any modifications thereto. Any use, reproduction, disclosure or
|
|
5
|
+
# distribution of this software and related documentation without an express
|
|
6
|
+
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
|
+
|
|
8
|
+
###########################################################################
|
|
9
|
+
# Example Convection Diffusion
|
|
10
|
+
#
|
|
11
|
+
# This example simulates a convection-diffusion PDE using
|
|
12
|
+
# semi-Lagrangian advection
|
|
13
|
+
#
|
|
14
|
+
# D phi / dt - nu d2 phi / dx^2 = 0
|
|
15
|
+
###########################################################################
|
|
16
|
+
|
|
17
|
+
import warp as wp
|
|
18
|
+
import warp.fem as fem
|
|
19
|
+
|
|
20
|
+
# Import example utilities
|
|
21
|
+
# Make sure that works both when imported as module and run as standalone file
|
|
22
|
+
try:
|
|
23
|
+
from .bsr_utils import bsr_cg
|
|
24
|
+
from .mesh_utils import gen_trimesh
|
|
25
|
+
from .plot_utils import Plot
|
|
26
|
+
except ImportError:
|
|
27
|
+
from bsr_utils import bsr_cg
|
|
28
|
+
from mesh_utils import gen_trimesh
|
|
29
|
+
from plot_utils import Plot
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@fem.integrand
|
|
33
|
+
def initial_condition(domain: fem.Domain, s: fem.Sample):
|
|
34
|
+
"""Initial condition: 1.0 in ]0.6, 0.4[ x ]0.2, 0.8[, 0.0 elsewhere"""
|
|
35
|
+
pos = domain(s)
|
|
36
|
+
if pos[0] > 0.4 and pos[0] < 0.6 and pos[1] > 0.2 and pos[1] < 0.8:
|
|
37
|
+
return 1.0
|
|
38
|
+
return 0.0
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@wp.func
|
|
42
|
+
def velocity(pos: wp.vec2, ang_vel: float):
|
|
43
|
+
center = wp.vec2(0.5, 0.5)
|
|
44
|
+
offset = pos - center
|
|
45
|
+
return wp.vec2(offset[1], -offset[0]) * ang_vel
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@fem.integrand
|
|
49
|
+
def inertia_form(s: fem.Sample, phi: fem.Field, psi: fem.Field, dt: float):
|
|
50
|
+
return phi(s) * psi(s) / dt
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@fem.integrand
|
|
54
|
+
def transported_inertia_form(
|
|
55
|
+
s: fem.Sample, domain: fem.Domain, phi: fem.Field, psi: fem.Field, ang_vel: float, dt: float
|
|
56
|
+
):
|
|
57
|
+
pos = domain(s)
|
|
58
|
+
vel = velocity(pos, ang_vel)
|
|
59
|
+
|
|
60
|
+
# semi-Lagrangian advection; evaluate phi upstream
|
|
61
|
+
conv_pos = pos - vel * dt
|
|
62
|
+
# lookup operator constructs a Sample from a world position.
|
|
63
|
+
# the optional last argument provides a initial guess for the lookup
|
|
64
|
+
conv_phi = phi(fem.lookup(domain, conv_pos, s))
|
|
65
|
+
|
|
66
|
+
return conv_phi * psi(s) / dt
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@fem.integrand
|
|
70
|
+
def diffusion_form(
|
|
71
|
+
s: fem.Sample,
|
|
72
|
+
u: fem.Field,
|
|
73
|
+
v: fem.Field,
|
|
74
|
+
):
|
|
75
|
+
return wp.dot(
|
|
76
|
+
fem.grad(u, s),
|
|
77
|
+
fem.grad(v, s),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@fem.integrand
|
|
82
|
+
def diffusion_and_inertia_form(s: fem.Sample, phi: fem.Field, psi: fem.Field, dt: float, nu: float):
|
|
83
|
+
return inertia_form(s, phi, psi, dt) + nu * diffusion_form(s, phi, psi)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class Example:
|
|
87
|
+
def __init__(self, quiet=False, degree=2, resolution=50, tri_mesh=False, viscosity=0.001, ang_vel=1.0):
|
|
88
|
+
self._quiet = quiet
|
|
89
|
+
|
|
90
|
+
self._ang_vel = ang_vel
|
|
91
|
+
|
|
92
|
+
res = resolution
|
|
93
|
+
self.sim_dt = 1.0 / (ang_vel * res)
|
|
94
|
+
self.current_frame = 0
|
|
95
|
+
|
|
96
|
+
if tri_mesh:
|
|
97
|
+
positions, tri_vidx = gen_trimesh(res=wp.vec2i(res))
|
|
98
|
+
geo = fem.Trimesh2D(tri_vertex_indices=tri_vidx, positions=positions)
|
|
99
|
+
else:
|
|
100
|
+
geo = fem.Grid2D(res=wp.vec2i(res))
|
|
101
|
+
|
|
102
|
+
domain = fem.Cells(geometry=geo)
|
|
103
|
+
scalar_space = fem.make_polynomial_space(geo, degree=degree)
|
|
104
|
+
|
|
105
|
+
# Initial condition
|
|
106
|
+
self._phi_field = scalar_space.make_field()
|
|
107
|
+
fem.interpolate(initial_condition, dest=self._phi_field)
|
|
108
|
+
|
|
109
|
+
# Assemble diffusion and inertia matrix
|
|
110
|
+
self._test = fem.make_test(space=scalar_space, domain=domain)
|
|
111
|
+
self._trial = fem.make_trial(space=scalar_space, domain=domain)
|
|
112
|
+
self._matrix = fem.integrate(
|
|
113
|
+
diffusion_and_inertia_form,
|
|
114
|
+
fields={"phi": self._trial, "psi": self._test},
|
|
115
|
+
values={"nu": viscosity, "dt": self.sim_dt},
|
|
116
|
+
output_dtype=float,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
self.renderer = Plot()
|
|
120
|
+
self.renderer.add_surface("phi", self._phi_field)
|
|
121
|
+
|
|
122
|
+
def step(self):
|
|
123
|
+
self.current_frame += 1
|
|
124
|
+
|
|
125
|
+
# right-hand-side -- advected inertia
|
|
126
|
+
rhs = fem.integrate(
|
|
127
|
+
transported_inertia_form,
|
|
128
|
+
fields={"phi": self._phi_field, "psi": self._test},
|
|
129
|
+
values={"ang_vel": self._ang_vel, "dt": self.sim_dt},
|
|
130
|
+
output_dtype=float,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# Solve linear system
|
|
134
|
+
bsr_cg(self._matrix, x=self._phi_field.dof_values, b=rhs, quiet=self._quiet, tol=1.0e-12)
|
|
135
|
+
|
|
136
|
+
def render(self):
|
|
137
|
+
self.renderer.begin_frame(time=self.current_frame * self.sim_dt)
|
|
138
|
+
self.renderer.add_surface("phi", self._phi_field)
|
|
139
|
+
self.renderer.end_frame()
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
if __name__ == "__main__":
|
|
143
|
+
import argparse
|
|
144
|
+
|
|
145
|
+
wp.set_module_options({"enable_backward": False})
|
|
146
|
+
|
|
147
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
148
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
149
|
+
parser.add_argument("--resolution", type=int, default=50, help="Grid resolution.")
|
|
150
|
+
parser.add_argument("--degree", type=int, default=2, help="Polynomial degree of shape functions.")
|
|
151
|
+
parser.add_argument("--num_frames", type=int, default=250, help="Total number of frames.")
|
|
152
|
+
parser.add_argument("--viscosity", type=float, default=0.001, help="Fluid viscosity parameter.")
|
|
153
|
+
parser.add_argument("--ang_vel", type=float, default=1.0, help="Angular velocity.")
|
|
154
|
+
parser.add_argument("--tri_mesh", action="store_true", help="Use a triangular mesh.")
|
|
155
|
+
parser.add_argument(
|
|
156
|
+
"--headless",
|
|
157
|
+
action="store_true",
|
|
158
|
+
help="Run in headless mode, suppressing the opening of any graphical windows.",
|
|
159
|
+
)
|
|
160
|
+
parser.add_argument("--quiet", action="store_true", help="Suppresses the printing out of iteration residuals.")
|
|
161
|
+
|
|
162
|
+
args = parser.parse_known_args()[0]
|
|
163
|
+
|
|
164
|
+
with wp.ScopedDevice(args.device):
|
|
165
|
+
example = Example(
|
|
166
|
+
quiet=args.quiet,
|
|
167
|
+
degree=args.degree,
|
|
168
|
+
resolution=args.resolution,
|
|
169
|
+
tri_mesh=args.tri_mesh,
|
|
170
|
+
viscosity=args.viscosity,
|
|
171
|
+
ang_vel=args.ang_vel,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
for k in range(args.num_frames):
|
|
175
|
+
print(f"Frame {k}:")
|
|
176
|
+
example.step()
|
|
177
|
+
example.render()
|
|
178
|
+
|
|
179
|
+
if not args.headless:
|
|
180
|
+
example.renderer.plot()
|