warp-lang 1.7.0__py3-none-manylinux_2_28_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 +139 -0
- warp/__init__.pyi +1 -0
- warp/autograd.py +1142 -0
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +557 -0
- warp/build_dll.py +405 -0
- warp/builtins.py +6855 -0
- warp/codegen.py +3969 -0
- warp/config.py +158 -0
- warp/constants.py +57 -0
- warp/context.py +6812 -0
- warp/dlpack.py +462 -0
- warp/examples/__init__.py +24 -0
- warp/examples/assets/bear.usd +0 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cartpole.urdf +110 -0
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/cube.usd +0 -0
- warp/examples/assets/nonuniform.usd +0 -0
- warp/examples/assets/nv_ant.xml +92 -0
- warp/examples/assets/nv_humanoid.xml +183 -0
- warp/examples/assets/nvidia_logo.png +0 -0
- warp/examples/assets/pixel.jpg +0 -0
- warp/examples/assets/quadruped.urdf +268 -0
- warp/examples/assets/rocks.nvdb +0 -0
- warp/examples/assets/rocks.usd +0 -0
- warp/examples/assets/sphere.usd +0 -0
- warp/examples/assets/square_cloth.usd +0 -0
- warp/examples/benchmarks/benchmark_api.py +389 -0
- warp/examples/benchmarks/benchmark_cloth.py +296 -0
- warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
- warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
- warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
- warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
- warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
- warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
- warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
- warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
- warp/examples/benchmarks/benchmark_gemm.py +164 -0
- warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
- warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
- warp/examples/benchmarks/benchmark_launches.py +301 -0
- warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
- warp/examples/browse.py +37 -0
- warp/examples/core/example_cupy.py +86 -0
- warp/examples/core/example_dem.py +241 -0
- warp/examples/core/example_fluid.py +299 -0
- warp/examples/core/example_graph_capture.py +150 -0
- warp/examples/core/example_marching_cubes.py +194 -0
- warp/examples/core/example_mesh.py +180 -0
- warp/examples/core/example_mesh_intersect.py +211 -0
- warp/examples/core/example_nvdb.py +182 -0
- warp/examples/core/example_raycast.py +111 -0
- warp/examples/core/example_raymarch.py +205 -0
- warp/examples/core/example_render_opengl.py +193 -0
- warp/examples/core/example_sample_mesh.py +300 -0
- warp/examples/core/example_sph.py +411 -0
- warp/examples/core/example_torch.py +211 -0
- warp/examples/core/example_wave.py +269 -0
- warp/examples/fem/example_adaptive_grid.py +286 -0
- warp/examples/fem/example_apic_fluid.py +423 -0
- warp/examples/fem/example_burgers.py +261 -0
- warp/examples/fem/example_convection_diffusion.py +178 -0
- warp/examples/fem/example_convection_diffusion_dg.py +204 -0
- warp/examples/fem/example_deformed_geometry.py +172 -0
- warp/examples/fem/example_diffusion.py +196 -0
- warp/examples/fem/example_diffusion_3d.py +225 -0
- warp/examples/fem/example_diffusion_mgpu.py +220 -0
- warp/examples/fem/example_distortion_energy.py +228 -0
- warp/examples/fem/example_magnetostatics.py +240 -0
- warp/examples/fem/example_mixed_elasticity.py +291 -0
- warp/examples/fem/example_navier_stokes.py +261 -0
- warp/examples/fem/example_nonconforming_contact.py +298 -0
- warp/examples/fem/example_stokes.py +213 -0
- warp/examples/fem/example_stokes_transfer.py +262 -0
- warp/examples/fem/example_streamlines.py +352 -0
- warp/examples/fem/utils.py +1000 -0
- warp/examples/interop/example_jax_callable.py +116 -0
- warp/examples/interop/example_jax_ffi_callback.py +132 -0
- warp/examples/interop/example_jax_kernel.py +205 -0
- warp/examples/optim/example_bounce.py +266 -0
- warp/examples/optim/example_cloth_throw.py +228 -0
- warp/examples/optim/example_diffray.py +561 -0
- warp/examples/optim/example_drone.py +870 -0
- warp/examples/optim/example_fluid_checkpoint.py +497 -0
- warp/examples/optim/example_inverse_kinematics.py +182 -0
- warp/examples/optim/example_inverse_kinematics_torch.py +191 -0
- warp/examples/optim/example_softbody_properties.py +400 -0
- warp/examples/optim/example_spring_cage.py +245 -0
- warp/examples/optim/example_trajectory.py +227 -0
- warp/examples/sim/example_cartpole.py +143 -0
- warp/examples/sim/example_cloth.py +225 -0
- warp/examples/sim/example_cloth_self_contact.py +322 -0
- warp/examples/sim/example_granular.py +130 -0
- warp/examples/sim/example_granular_collision_sdf.py +202 -0
- warp/examples/sim/example_jacobian_ik.py +244 -0
- warp/examples/sim/example_particle_chain.py +124 -0
- warp/examples/sim/example_quadruped.py +203 -0
- warp/examples/sim/example_rigid_chain.py +203 -0
- warp/examples/sim/example_rigid_contact.py +195 -0
- warp/examples/sim/example_rigid_force.py +133 -0
- warp/examples/sim/example_rigid_gyroscopic.py +115 -0
- warp/examples/sim/example_rigid_soft_contact.py +140 -0
- warp/examples/sim/example_soft_body.py +196 -0
- warp/examples/tile/example_tile_cholesky.py +87 -0
- warp/examples/tile/example_tile_convolution.py +66 -0
- warp/examples/tile/example_tile_fft.py +55 -0
- warp/examples/tile/example_tile_filtering.py +113 -0
- warp/examples/tile/example_tile_matmul.py +85 -0
- warp/examples/tile/example_tile_mlp.py +383 -0
- warp/examples/tile/example_tile_nbody.py +199 -0
- warp/examples/tile/example_tile_walker.py +327 -0
- warp/fabric.py +355 -0
- warp/fem/__init__.py +106 -0
- warp/fem/adaptivity.py +508 -0
- warp/fem/cache.py +572 -0
- warp/fem/dirichlet.py +202 -0
- warp/fem/domain.py +411 -0
- warp/fem/field/__init__.py +125 -0
- warp/fem/field/field.py +619 -0
- warp/fem/field/nodal_field.py +326 -0
- warp/fem/field/restriction.py +37 -0
- warp/fem/field/virtual.py +848 -0
- warp/fem/geometry/__init__.py +32 -0
- warp/fem/geometry/adaptive_nanogrid.py +857 -0
- warp/fem/geometry/closest_point.py +84 -0
- warp/fem/geometry/deformed_geometry.py +221 -0
- warp/fem/geometry/element.py +776 -0
- warp/fem/geometry/geometry.py +362 -0
- warp/fem/geometry/grid_2d.py +392 -0
- warp/fem/geometry/grid_3d.py +452 -0
- warp/fem/geometry/hexmesh.py +911 -0
- warp/fem/geometry/nanogrid.py +571 -0
- warp/fem/geometry/partition.py +389 -0
- warp/fem/geometry/quadmesh.py +663 -0
- warp/fem/geometry/tetmesh.py +855 -0
- warp/fem/geometry/trimesh.py +806 -0
- warp/fem/integrate.py +2335 -0
- warp/fem/linalg.py +419 -0
- warp/fem/operator.py +293 -0
- warp/fem/polynomial.py +229 -0
- warp/fem/quadrature/__init__.py +17 -0
- warp/fem/quadrature/pic_quadrature.py +299 -0
- warp/fem/quadrature/quadrature.py +591 -0
- warp/fem/space/__init__.py +228 -0
- warp/fem/space/basis_function_space.py +468 -0
- warp/fem/space/basis_space.py +667 -0
- warp/fem/space/dof_mapper.py +251 -0
- warp/fem/space/function_space.py +309 -0
- warp/fem/space/grid_2d_function_space.py +177 -0
- warp/fem/space/grid_3d_function_space.py +227 -0
- warp/fem/space/hexmesh_function_space.py +257 -0
- warp/fem/space/nanogrid_function_space.py +201 -0
- warp/fem/space/partition.py +367 -0
- warp/fem/space/quadmesh_function_space.py +223 -0
- warp/fem/space/restriction.py +179 -0
- warp/fem/space/shape/__init__.py +143 -0
- warp/fem/space/shape/cube_shape_function.py +1105 -0
- warp/fem/space/shape/shape_function.py +133 -0
- warp/fem/space/shape/square_shape_function.py +926 -0
- warp/fem/space/shape/tet_shape_function.py +834 -0
- warp/fem/space/shape/triangle_shape_function.py +672 -0
- warp/fem/space/tetmesh_function_space.py +271 -0
- warp/fem/space/topology.py +424 -0
- warp/fem/space/trimesh_function_space.py +194 -0
- warp/fem/types.py +99 -0
- warp/fem/utils.py +420 -0
- warp/jax.py +187 -0
- warp/jax_experimental/__init__.py +16 -0
- warp/jax_experimental/custom_call.py +351 -0
- warp/jax_experimental/ffi.py +698 -0
- warp/jax_experimental/xla_ffi.py +602 -0
- warp/math.py +244 -0
- warp/native/array.h +1145 -0
- warp/native/builtin.h +1800 -0
- warp/native/bvh.cpp +492 -0
- warp/native/bvh.cu +791 -0
- warp/native/bvh.h +554 -0
- warp/native/clang/clang.cpp +536 -0
- warp/native/coloring.cpp +613 -0
- warp/native/crt.cpp +51 -0
- warp/native/crt.h +362 -0
- warp/native/cuda_crt.h +1058 -0
- warp/native/cuda_util.cpp +646 -0
- warp/native/cuda_util.h +307 -0
- warp/native/error.cpp +77 -0
- warp/native/error.h +36 -0
- warp/native/exports.h +1878 -0
- warp/native/fabric.h +245 -0
- warp/native/hashgrid.cpp +311 -0
- warp/native/hashgrid.cu +87 -0
- warp/native/hashgrid.h +240 -0
- warp/native/initializer_array.h +41 -0
- warp/native/intersect.h +1230 -0
- warp/native/intersect_adj.h +375 -0
- warp/native/intersect_tri.h +339 -0
- warp/native/marching.cpp +19 -0
- warp/native/marching.cu +514 -0
- warp/native/marching.h +19 -0
- warp/native/mat.h +2220 -0
- warp/native/mathdx.cpp +87 -0
- warp/native/matnn.h +343 -0
- warp/native/mesh.cpp +266 -0
- warp/native/mesh.cu +404 -0
- warp/native/mesh.h +1980 -0
- warp/native/nanovdb/GridHandle.h +366 -0
- warp/native/nanovdb/HostBuffer.h +590 -0
- warp/native/nanovdb/NanoVDB.h +6624 -0
- warp/native/nanovdb/PNanoVDB.h +3390 -0
- warp/native/noise.h +859 -0
- warp/native/quat.h +1371 -0
- warp/native/rand.h +342 -0
- warp/native/range.h +139 -0
- warp/native/reduce.cpp +174 -0
- warp/native/reduce.cu +364 -0
- warp/native/runlength_encode.cpp +79 -0
- warp/native/runlength_encode.cu +61 -0
- warp/native/scan.cpp +47 -0
- warp/native/scan.cu +53 -0
- warp/native/scan.h +23 -0
- warp/native/solid_angle.h +466 -0
- warp/native/sort.cpp +251 -0
- warp/native/sort.cu +277 -0
- warp/native/sort.h +33 -0
- warp/native/sparse.cpp +378 -0
- warp/native/sparse.cu +524 -0
- warp/native/spatial.h +657 -0
- warp/native/svd.h +702 -0
- warp/native/temp_buffer.h +46 -0
- warp/native/tile.h +2584 -0
- warp/native/tile_reduce.h +264 -0
- warp/native/vec.h +1426 -0
- warp/native/volume.cpp +501 -0
- warp/native/volume.cu +67 -0
- warp/native/volume.h +969 -0
- warp/native/volume_builder.cu +477 -0
- warp/native/volume_builder.h +52 -0
- warp/native/volume_impl.h +70 -0
- warp/native/warp.cpp +1082 -0
- warp/native/warp.cu +3636 -0
- warp/native/warp.h +381 -0
- warp/optim/__init__.py +17 -0
- warp/optim/adam.py +163 -0
- warp/optim/linear.py +1137 -0
- warp/optim/sgd.py +112 -0
- warp/paddle.py +407 -0
- warp/render/__init__.py +18 -0
- warp/render/render_opengl.py +3518 -0
- warp/render/render_usd.py +784 -0
- warp/render/utils.py +160 -0
- warp/sim/__init__.py +65 -0
- warp/sim/articulation.py +793 -0
- warp/sim/collide.py +2395 -0
- warp/sim/graph_coloring.py +300 -0
- warp/sim/import_mjcf.py +790 -0
- warp/sim/import_snu.py +227 -0
- warp/sim/import_urdf.py +579 -0
- warp/sim/import_usd.py +894 -0
- warp/sim/inertia.py +324 -0
- warp/sim/integrator.py +242 -0
- warp/sim/integrator_euler.py +1997 -0
- warp/sim/integrator_featherstone.py +2101 -0
- warp/sim/integrator_vbd.py +2048 -0
- warp/sim/integrator_xpbd.py +3292 -0
- warp/sim/model.py +4791 -0
- warp/sim/particles.py +121 -0
- warp/sim/render.py +427 -0
- warp/sim/utils.py +428 -0
- warp/sparse.py +2057 -0
- warp/stubs.py +3333 -0
- warp/tape.py +1203 -0
- warp/tests/__init__.py +1 -0
- warp/tests/__main__.py +4 -0
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/mlp_golden.npy +0 -0
- warp/tests/assets/pixel.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/assets/spiky.usd +0 -0
- warp/tests/assets/test_grid.nvdb +0 -0
- warp/tests/assets/test_index_grid.nvdb +0 -0
- warp/tests/assets/test_int32_grid.nvdb +0 -0
- warp/tests/assets/test_vec_grid.nvdb +0 -0
- warp/tests/assets/torus.nvdb +0 -0
- warp/tests/assets/torus.usda +105 -0
- warp/tests/aux_test_class_kernel.py +34 -0
- warp/tests/aux_test_compile_consts_dummy.py +18 -0
- warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
- warp/tests/aux_test_dependent.py +29 -0
- warp/tests/aux_test_grad_customs.py +29 -0
- warp/tests/aux_test_instancing_gc.py +26 -0
- warp/tests/aux_test_module_unload.py +23 -0
- warp/tests/aux_test_name_clash1.py +40 -0
- warp/tests/aux_test_name_clash2.py +40 -0
- warp/tests/aux_test_reference.py +9 -0
- warp/tests/aux_test_reference_reference.py +8 -0
- warp/tests/aux_test_square.py +16 -0
- warp/tests/aux_test_unresolved_func.py +22 -0
- warp/tests/aux_test_unresolved_symbol.py +22 -0
- warp/tests/cuda/__init__.py +0 -0
- warp/tests/cuda/test_async.py +676 -0
- warp/tests/cuda/test_ipc.py +124 -0
- warp/tests/cuda/test_mempool.py +233 -0
- warp/tests/cuda/test_multigpu.py +169 -0
- warp/tests/cuda/test_peer.py +139 -0
- warp/tests/cuda/test_pinned.py +84 -0
- warp/tests/cuda/test_streams.py +634 -0
- warp/tests/geometry/__init__.py +0 -0
- warp/tests/geometry/test_bvh.py +200 -0
- warp/tests/geometry/test_hash_grid.py +221 -0
- warp/tests/geometry/test_marching_cubes.py +74 -0
- warp/tests/geometry/test_mesh.py +316 -0
- warp/tests/geometry/test_mesh_query_aabb.py +399 -0
- warp/tests/geometry/test_mesh_query_point.py +932 -0
- warp/tests/geometry/test_mesh_query_ray.py +311 -0
- warp/tests/geometry/test_volume.py +1103 -0
- warp/tests/geometry/test_volume_write.py +346 -0
- warp/tests/interop/__init__.py +0 -0
- warp/tests/interop/test_dlpack.py +729 -0
- warp/tests/interop/test_jax.py +371 -0
- warp/tests/interop/test_paddle.py +800 -0
- warp/tests/interop/test_torch.py +1001 -0
- warp/tests/run_coverage_serial.py +39 -0
- warp/tests/sim/__init__.py +0 -0
- warp/tests/sim/disabled_kinematics.py +244 -0
- warp/tests/sim/flaky_test_sim_grad.py +290 -0
- warp/tests/sim/test_collision.py +604 -0
- warp/tests/sim/test_coloring.py +258 -0
- warp/tests/sim/test_model.py +224 -0
- warp/tests/sim/test_sim_grad_bounce_linear.py +212 -0
- warp/tests/sim/test_sim_kinematics.py +98 -0
- warp/tests/sim/test_vbd.py +597 -0
- warp/tests/test_adam.py +163 -0
- warp/tests/test_arithmetic.py +1096 -0
- warp/tests/test_array.py +2972 -0
- warp/tests/test_array_reduce.py +156 -0
- warp/tests/test_assert.py +250 -0
- warp/tests/test_atomic.py +153 -0
- warp/tests/test_bool.py +220 -0
- warp/tests/test_builtins_resolution.py +1298 -0
- warp/tests/test_closest_point_edge_edge.py +327 -0
- warp/tests/test_codegen.py +810 -0
- warp/tests/test_codegen_instancing.py +1495 -0
- warp/tests/test_compile_consts.py +215 -0
- warp/tests/test_conditional.py +252 -0
- warp/tests/test_context.py +42 -0
- warp/tests/test_copy.py +238 -0
- warp/tests/test_ctypes.py +638 -0
- warp/tests/test_dense.py +73 -0
- warp/tests/test_devices.py +97 -0
- warp/tests/test_examples.py +482 -0
- warp/tests/test_fabricarray.py +996 -0
- warp/tests/test_fast_math.py +74 -0
- warp/tests/test_fem.py +2003 -0
- warp/tests/test_fp16.py +136 -0
- warp/tests/test_func.py +454 -0
- warp/tests/test_future_annotations.py +98 -0
- warp/tests/test_generics.py +656 -0
- warp/tests/test_grad.py +893 -0
- warp/tests/test_grad_customs.py +339 -0
- warp/tests/test_grad_debug.py +341 -0
- warp/tests/test_implicit_init.py +411 -0
- warp/tests/test_import.py +45 -0
- warp/tests/test_indexedarray.py +1140 -0
- warp/tests/test_intersect.py +73 -0
- warp/tests/test_iter.py +76 -0
- warp/tests/test_large.py +177 -0
- warp/tests/test_launch.py +411 -0
- warp/tests/test_lerp.py +151 -0
- warp/tests/test_linear_solvers.py +193 -0
- warp/tests/test_lvalue.py +427 -0
- warp/tests/test_mat.py +2089 -0
- warp/tests/test_mat_lite.py +122 -0
- warp/tests/test_mat_scalar_ops.py +2913 -0
- warp/tests/test_math.py +178 -0
- warp/tests/test_mlp.py +282 -0
- warp/tests/test_module_hashing.py +258 -0
- warp/tests/test_modules_lite.py +44 -0
- warp/tests/test_noise.py +252 -0
- warp/tests/test_operators.py +299 -0
- warp/tests/test_options.py +129 -0
- warp/tests/test_overwrite.py +551 -0
- warp/tests/test_print.py +339 -0
- warp/tests/test_quat.py +2315 -0
- warp/tests/test_rand.py +339 -0
- warp/tests/test_reload.py +302 -0
- warp/tests/test_rounding.py +185 -0
- warp/tests/test_runlength_encode.py +196 -0
- warp/tests/test_scalar_ops.py +105 -0
- warp/tests/test_smoothstep.py +108 -0
- warp/tests/test_snippet.py +318 -0
- warp/tests/test_sparse.py +582 -0
- warp/tests/test_spatial.py +2229 -0
- warp/tests/test_special_values.py +361 -0
- warp/tests/test_static.py +592 -0
- warp/tests/test_struct.py +734 -0
- warp/tests/test_tape.py +204 -0
- warp/tests/test_transient_module.py +93 -0
- warp/tests/test_triangle_closest_point.py +145 -0
- warp/tests/test_types.py +562 -0
- warp/tests/test_utils.py +588 -0
- warp/tests/test_vec.py +1487 -0
- warp/tests/test_vec_lite.py +80 -0
- warp/tests/test_vec_scalar_ops.py +2327 -0
- warp/tests/test_verify_fp.py +100 -0
- warp/tests/tile/__init__.py +0 -0
- warp/tests/tile/test_tile.py +780 -0
- warp/tests/tile/test_tile_load.py +407 -0
- warp/tests/tile/test_tile_mathdx.py +208 -0
- warp/tests/tile/test_tile_mlp.py +402 -0
- warp/tests/tile/test_tile_reduce.py +447 -0
- warp/tests/tile/test_tile_shared_memory.py +247 -0
- warp/tests/tile/test_tile_view.py +173 -0
- warp/tests/unittest_serial.py +47 -0
- warp/tests/unittest_suites.py +427 -0
- warp/tests/unittest_utils.py +468 -0
- warp/tests/walkthrough_debug.py +93 -0
- warp/thirdparty/__init__.py +0 -0
- warp/thirdparty/appdirs.py +598 -0
- warp/thirdparty/dlpack.py +145 -0
- warp/thirdparty/unittest_parallel.py +570 -0
- warp/torch.py +391 -0
- warp/types.py +5230 -0
- warp/utils.py +1137 -0
- warp_lang-1.7.0.dist-info/METADATA +516 -0
- warp_lang-1.7.0.dist-info/RECORD +429 -0
- warp_lang-1.7.0.dist-info/WHEEL +5 -0
- warp_lang-1.7.0.dist-info/licenses/LICENSE.md +202 -0
- warp_lang-1.7.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
###########################################################################
|
|
17
|
+
# Example Nonconforming Contact
|
|
18
|
+
#
|
|
19
|
+
# This example demonstrates using nonconforming fields (warp.fem.NonconformingField)
|
|
20
|
+
# to solve a no-slip contact problem between two elastic bodies discretized separately.
|
|
21
|
+
#
|
|
22
|
+
# Div[ E: D(u) ] = g over each body
|
|
23
|
+
# u_top = u_bottom along the contact surface (top body bottom boundary)
|
|
24
|
+
# u_bottom = 0 along the bottom boundary of the bottom body
|
|
25
|
+
#
|
|
26
|
+
# with E the rank-4 elasticity tensor
|
|
27
|
+
#
|
|
28
|
+
# Below we use a simple staggered scheme for solving bodies iteratively,
|
|
29
|
+
# but more robust methods could be considered (e.g. Augmented Lagrangian)
|
|
30
|
+
###########################################################################
|
|
31
|
+
|
|
32
|
+
import numpy as np
|
|
33
|
+
|
|
34
|
+
import warp as wp
|
|
35
|
+
import warp.examples.fem.utils as fem_example_utils
|
|
36
|
+
import warp.fem as fem
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@wp.func
|
|
40
|
+
def compute_stress(tau: wp.mat22, E: wp.mat33):
|
|
41
|
+
"""Strain to stress computation (using Voigt notation to drop tensor order)"""
|
|
42
|
+
tau_sym = wp.vec3(tau[0, 0], tau[1, 1], tau[0, 1] + tau[1, 0])
|
|
43
|
+
sig_sym = E * tau_sym
|
|
44
|
+
return wp.mat22(sig_sym[0], 0.5 * sig_sym[2], 0.5 * sig_sym[2], sig_sym[1])
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@fem.integrand
|
|
48
|
+
def stress_form(s: fem.Sample, u: fem.Field, tau: fem.Field, E: wp.mat33):
|
|
49
|
+
"""Stress inside body: (E : D(u)) : tau"""
|
|
50
|
+
return wp.ddot(tau(s), compute_stress(fem.D(u, s), E))
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@fem.integrand
|
|
54
|
+
def boundary_stress_form(
|
|
55
|
+
s: fem.Sample,
|
|
56
|
+
domain: fem.Domain,
|
|
57
|
+
u: fem.Field,
|
|
58
|
+
tau: fem.Field,
|
|
59
|
+
):
|
|
60
|
+
"""Stress on boundary: u' tau n"""
|
|
61
|
+
return wp.dot(tau(s) * fem.normal(domain, s), u(s))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@fem.integrand
|
|
65
|
+
def symmetric_grad_form(
|
|
66
|
+
s: fem.Sample,
|
|
67
|
+
u: fem.Field,
|
|
68
|
+
tau: fem.Field,
|
|
69
|
+
):
|
|
70
|
+
"""Symmetric part of gradient of displacement: D(u) : tau"""
|
|
71
|
+
return wp.ddot(tau(s), fem.D(u, s))
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@fem.integrand
|
|
75
|
+
def gravity_form(
|
|
76
|
+
s: fem.Sample,
|
|
77
|
+
v: fem.Field,
|
|
78
|
+
gravity: float,
|
|
79
|
+
):
|
|
80
|
+
return -gravity * v(s)[1]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@fem.integrand
|
|
84
|
+
def bottom_boundary_projector_form(
|
|
85
|
+
s: fem.Sample,
|
|
86
|
+
domain: fem.Domain,
|
|
87
|
+
u: fem.Field,
|
|
88
|
+
v: fem.Field,
|
|
89
|
+
):
|
|
90
|
+
# non zero on bottom boundary only
|
|
91
|
+
nor = fem.normal(domain, s)
|
|
92
|
+
return wp.dot(u(s), v(s)) * wp.max(0.0, -nor[1])
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@fem.integrand
|
|
96
|
+
def tensor_mass_form(
|
|
97
|
+
s: fem.Sample,
|
|
98
|
+
sig: fem.Field,
|
|
99
|
+
tau: fem.Field,
|
|
100
|
+
):
|
|
101
|
+
return wp.ddot(tau(s), sig(s))
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class Example:
|
|
105
|
+
def __init__(
|
|
106
|
+
self,
|
|
107
|
+
degree=2,
|
|
108
|
+
resolution=16,
|
|
109
|
+
young_modulus=1.0,
|
|
110
|
+
poisson_ratio=0.5,
|
|
111
|
+
nonconforming_stresses=False,
|
|
112
|
+
):
|
|
113
|
+
self._geo1 = fem.Grid2D(bounds_hi=wp.vec2(1.0, 0.5), res=wp.vec2i(resolution))
|
|
114
|
+
self._geo2 = fem.Grid2D(bounds_lo=(0.33, 0.5), bounds_hi=(0.67, 0.5 + 0.33), res=wp.vec2i(resolution))
|
|
115
|
+
|
|
116
|
+
# Strain-stress matrix
|
|
117
|
+
young = young_modulus
|
|
118
|
+
poisson = poisson_ratio
|
|
119
|
+
self._elasticity_mat = wp.mat33(
|
|
120
|
+
young
|
|
121
|
+
/ (1.0 - poisson * poisson)
|
|
122
|
+
* np.array(
|
|
123
|
+
[
|
|
124
|
+
[1.0, poisson, 0.0],
|
|
125
|
+
[poisson, 1.0, 0.0],
|
|
126
|
+
[0.0, 0.0, (2.0 * (1.0 + poisson)) * (1.0 - poisson * poisson)],
|
|
127
|
+
]
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# Displacement spaces and fields -- S_k
|
|
132
|
+
self._u1_space = fem.make_polynomial_space(
|
|
133
|
+
self._geo1, degree=degree, dtype=wp.vec2, element_basis=fem.ElementBasis.SERENDIPITY
|
|
134
|
+
)
|
|
135
|
+
self._u2_space = fem.make_polynomial_space(
|
|
136
|
+
self._geo2, degree=degree, dtype=wp.vec2, element_basis=fem.ElementBasis.SERENDIPITY
|
|
137
|
+
)
|
|
138
|
+
self._u1_field = self._u1_space.make_field()
|
|
139
|
+
self._u2_field = self._u2_space.make_field()
|
|
140
|
+
|
|
141
|
+
# Stress spaces and fields -- Q_{k-1}d
|
|
142
|
+
# Store stress degrees of freedom as symmetric tensors (3 dof) rather than full 2x2 matrices
|
|
143
|
+
self._tau1_space = fem.make_polynomial_space(
|
|
144
|
+
self._geo1,
|
|
145
|
+
degree=degree - 1,
|
|
146
|
+
discontinuous=True,
|
|
147
|
+
element_basis=fem.ElementBasis.LAGRANGE,
|
|
148
|
+
dof_mapper=fem.SymmetricTensorMapper(wp.mat22),
|
|
149
|
+
)
|
|
150
|
+
self._tau2_space = fem.make_polynomial_space(
|
|
151
|
+
self._geo2,
|
|
152
|
+
degree=degree - 1,
|
|
153
|
+
discontinuous=True,
|
|
154
|
+
element_basis=fem.ElementBasis.LAGRANGE,
|
|
155
|
+
dof_mapper=fem.SymmetricTensorMapper(wp.mat22),
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
self._sig1_field = self._tau1_space.make_field()
|
|
159
|
+
self._sig2_field = self._tau2_space.make_field()
|
|
160
|
+
self._sig2_field_new = self._tau2_space.make_field()
|
|
161
|
+
|
|
162
|
+
self.renderer = fem_example_utils.Plot()
|
|
163
|
+
|
|
164
|
+
def step(self):
|
|
165
|
+
# Solve for the two bodies separately
|
|
166
|
+
# Body (top) is 25x more dense and 5x stiffer than top body
|
|
167
|
+
# Body 1 affects body 2 through bottom displacement dirichlet BC
|
|
168
|
+
# Body 2 affects body 1 through applied strain on top
|
|
169
|
+
self.solve_solid(self._u1_field, self._sig1_field, self._u2_field, self._sig2_field, gravity=1.0, stiffness=1.0)
|
|
170
|
+
self.solve_solid(
|
|
171
|
+
self._u2_field, self._sig2_field_new, self._u1_field, self._sig1_field, gravity=25.0, stiffness=5.0
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Damped update of coupling stress (for stability)
|
|
175
|
+
alpha = 0.1
|
|
176
|
+
fem.utils.array_axpy(
|
|
177
|
+
x=self._sig2_field_new.dof_values, y=self._sig2_field.dof_values, alpha=alpha, beta=1.0 - alpha
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
def solve_solid(
|
|
181
|
+
self,
|
|
182
|
+
u_field,
|
|
183
|
+
stress_field,
|
|
184
|
+
other_u_field,
|
|
185
|
+
other_stress_field,
|
|
186
|
+
gravity: float,
|
|
187
|
+
stiffness: float,
|
|
188
|
+
):
|
|
189
|
+
u_space = u_field.space
|
|
190
|
+
stress_space = stress_field.space
|
|
191
|
+
geo = u_field.space.geometry
|
|
192
|
+
|
|
193
|
+
domain = fem.Cells(geometry=geo)
|
|
194
|
+
boundary = fem.BoundarySides(geometry=geo)
|
|
195
|
+
|
|
196
|
+
u_test = fem.make_test(space=u_space, domain=domain)
|
|
197
|
+
u_trial = fem.make_trial(space=u_space, domain=domain)
|
|
198
|
+
tau_test = fem.make_test(space=stress_space, domain=domain)
|
|
199
|
+
tau_trial = fem.make_trial(space=stress_space, domain=domain)
|
|
200
|
+
|
|
201
|
+
u_bd_test = fem.make_test(space=u_space, domain=boundary)
|
|
202
|
+
u_bd_trial = fem.make_trial(space=u_space, domain=boundary)
|
|
203
|
+
|
|
204
|
+
# Assemble stiffness matrix
|
|
205
|
+
# (Note: this is constant per body, this could be precomputed)
|
|
206
|
+
sym_grad_matrix = fem.integrate(symmetric_grad_form, fields={"u": u_trial, "tau": tau_test})
|
|
207
|
+
|
|
208
|
+
tau_inv_mass_matrix = fem.integrate(tensor_mass_form, fields={"sig": tau_trial, "tau": tau_test}, nodal=True)
|
|
209
|
+
fem_example_utils.invert_diagonal_bsr_matrix(tau_inv_mass_matrix)
|
|
210
|
+
|
|
211
|
+
stress_matrix = tau_inv_mass_matrix @ fem.integrate(
|
|
212
|
+
stress_form, fields={"u": u_trial, "tau": tau_test}, values={"E": self._elasticity_mat * stiffness}
|
|
213
|
+
)
|
|
214
|
+
stiffness_matrix = sym_grad_matrix.transpose() @ stress_matrix
|
|
215
|
+
|
|
216
|
+
# Right-hand-side
|
|
217
|
+
u_rhs = fem.integrate(gravity_form, fields={"v": u_test}, values={"gravity": gravity}, output_dtype=wp.vec2d)
|
|
218
|
+
|
|
219
|
+
# Add boundary stress from other solid field
|
|
220
|
+
other_stress_field = fem.field.field.NonconformingField(boundary, other_stress_field)
|
|
221
|
+
fem.integrate(
|
|
222
|
+
boundary_stress_form,
|
|
223
|
+
fields={"u": u_bd_test, "tau": other_stress_field},
|
|
224
|
+
output=u_rhs,
|
|
225
|
+
add=True,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
# Enforce boundary conditions
|
|
229
|
+
u_bd_matrix = fem.integrate(
|
|
230
|
+
bottom_boundary_projector_form, fields={"u": u_bd_trial, "v": u_bd_test}, nodal=True
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# read displacement from other body set create bottom boundary Dirichlet BC
|
|
234
|
+
other_u_field = fem.field.field.NonconformingField(boundary, other_u_field)
|
|
235
|
+
u_bd_rhs = fem.integrate(
|
|
236
|
+
bottom_boundary_projector_form, fields={"u": other_u_field, "v": u_bd_test}, nodal=True
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
fem.project_linear_system(stiffness_matrix, u_rhs, u_bd_matrix, u_bd_rhs)
|
|
240
|
+
|
|
241
|
+
# solve
|
|
242
|
+
x = wp.zeros_like(u_rhs)
|
|
243
|
+
wp.utils.array_cast(in_array=u_field.dof_values, out_array=x)
|
|
244
|
+
fem_example_utils.bsr_cg(stiffness_matrix, b=u_rhs, x=x, tol=1.0e-6, quiet=True)
|
|
245
|
+
|
|
246
|
+
# Extract result
|
|
247
|
+
stress = stress_matrix @ x
|
|
248
|
+
wp.utils.array_cast(in_array=x, out_array=u_field.dof_values)
|
|
249
|
+
wp.utils.array_cast(in_array=stress, out_array=stress_field.dof_values)
|
|
250
|
+
|
|
251
|
+
def render(self):
|
|
252
|
+
self.renderer.add_field("u1", self._u1_field)
|
|
253
|
+
self.renderer.add_field("u2", self._u2_field)
|
|
254
|
+
self.renderer.add_field("sig1", self._sig1_field)
|
|
255
|
+
self.renderer.add_field("sig2", self._sig2_field)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
if __name__ == "__main__":
|
|
259
|
+
import argparse
|
|
260
|
+
|
|
261
|
+
wp.set_module_options({"enable_backward": False})
|
|
262
|
+
|
|
263
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
264
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
265
|
+
parser.add_argument("--resolution", type=int, default=32, help="Grid resolution.")
|
|
266
|
+
parser.add_argument("--degree", type=int, default=2, help="Polynomial degree of shape functions.")
|
|
267
|
+
parser.add_argument("--young_modulus", type=float, default=10.0)
|
|
268
|
+
parser.add_argument("--poisson_ratio", type=float, default=0.9)
|
|
269
|
+
parser.add_argument("--num_steps", type=int, default=50)
|
|
270
|
+
parser.add_argument(
|
|
271
|
+
"--headless",
|
|
272
|
+
action="store_true",
|
|
273
|
+
help="Run in headless mode, suppressing the opening of any graphical windows.",
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
args = parser.parse_known_args()[0]
|
|
277
|
+
|
|
278
|
+
with wp.ScopedDevice(args.device):
|
|
279
|
+
example = Example(
|
|
280
|
+
degree=args.degree,
|
|
281
|
+
resolution=args.resolution,
|
|
282
|
+
young_modulus=args.young_modulus,
|
|
283
|
+
poisson_ratio=args.poisson_ratio,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
for i in range(args.num_steps):
|
|
287
|
+
print("Step", i)
|
|
288
|
+
example.step()
|
|
289
|
+
example.render()
|
|
290
|
+
|
|
291
|
+
if not args.headless:
|
|
292
|
+
example.renderer.plot(
|
|
293
|
+
{
|
|
294
|
+
"rows": 2,
|
|
295
|
+
"u1": {"displacement": {}},
|
|
296
|
+
"u2": {"displacement": {}},
|
|
297
|
+
},
|
|
298
|
+
)
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
###########################################################################
|
|
17
|
+
# Example Stokes
|
|
18
|
+
#
|
|
19
|
+
# This example solves a 2D Stokes flow problem
|
|
20
|
+
#
|
|
21
|
+
# -nu D(u) + grad p = 0
|
|
22
|
+
# Div u = 0
|
|
23
|
+
#
|
|
24
|
+
# with (soft) velocity-Dirichlet boundary conditions
|
|
25
|
+
###########################################################################
|
|
26
|
+
|
|
27
|
+
import warp as wp
|
|
28
|
+
import warp.examples.fem.utils as fem_example_utils
|
|
29
|
+
import warp.fem as fem
|
|
30
|
+
from warp.fem.utils import array_axpy
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@fem.integrand
|
|
34
|
+
def viscosity_form(s: fem.Sample, u: fem.Field, v: fem.Field, nu: float):
|
|
35
|
+
return nu * wp.ddot(fem.D(u, s), fem.D(v, s))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@fem.integrand
|
|
39
|
+
def top_mass_form(
|
|
40
|
+
s: fem.Sample,
|
|
41
|
+
domain: fem.Domain,
|
|
42
|
+
u: fem.Field,
|
|
43
|
+
v: fem.Field,
|
|
44
|
+
):
|
|
45
|
+
# non zero on top boundary of domain only
|
|
46
|
+
nor = fem.normal(domain, s)
|
|
47
|
+
return wp.dot(u(s), v(s)) * wp.max(0.0, nor[1])
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@fem.integrand
|
|
51
|
+
def mass_form(
|
|
52
|
+
s: fem.Sample,
|
|
53
|
+
u: fem.Field,
|
|
54
|
+
v: fem.Field,
|
|
55
|
+
):
|
|
56
|
+
return wp.dot(u(s), v(s))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@fem.integrand
|
|
60
|
+
def div_form(
|
|
61
|
+
s: fem.Sample,
|
|
62
|
+
u: fem.Field,
|
|
63
|
+
q: fem.Field,
|
|
64
|
+
):
|
|
65
|
+
return q(s) * fem.div(u, s)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class Example:
|
|
69
|
+
def __init__(
|
|
70
|
+
self,
|
|
71
|
+
quiet=False,
|
|
72
|
+
mesh="grid",
|
|
73
|
+
degree=2,
|
|
74
|
+
resolution=50,
|
|
75
|
+
viscosity=1.0,
|
|
76
|
+
top_velocity=1.0,
|
|
77
|
+
boundary_strength=100.0,
|
|
78
|
+
nonconforming_pressures=False,
|
|
79
|
+
):
|
|
80
|
+
self._quiet = quiet
|
|
81
|
+
|
|
82
|
+
self.viscosity = viscosity
|
|
83
|
+
self.boundary_strength = boundary_strength
|
|
84
|
+
|
|
85
|
+
# Grid or triangle mesh geometry
|
|
86
|
+
if mesh == "tri":
|
|
87
|
+
positions, tri_vidx = fem_example_utils.gen_trimesh(res=wp.vec2i(resolution))
|
|
88
|
+
geo = fem.Trimesh2D(tri_vertex_indices=tri_vidx, positions=positions)
|
|
89
|
+
elif mesh == "quad":
|
|
90
|
+
positions, quad_vidx = fem_example_utils.gen_quadmesh(res=wp.vec2i(resolution))
|
|
91
|
+
geo = fem.Quadmesh2D(quad_vertex_indices=quad_vidx, positions=positions)
|
|
92
|
+
else:
|
|
93
|
+
geo = fem.Grid2D(res=wp.vec2i(resolution))
|
|
94
|
+
|
|
95
|
+
# Function spaces -- Q_d for vel, P_{d-1} for pressure
|
|
96
|
+
u_space = fem.make_polynomial_space(geo, degree=degree, dtype=wp.vec2)
|
|
97
|
+
if mesh != "tri" and nonconforming_pressures:
|
|
98
|
+
p_space = fem.make_polynomial_space(
|
|
99
|
+
geo, degree=degree - 1, element_basis=fem.ElementBasis.NONCONFORMING_POLYNOMIAL
|
|
100
|
+
)
|
|
101
|
+
else:
|
|
102
|
+
p_space = fem.make_polynomial_space(geo, degree=degree - 1)
|
|
103
|
+
|
|
104
|
+
# Vector and scalar fields
|
|
105
|
+
self._u_field = u_space.make_field()
|
|
106
|
+
self._p_field = p_space.make_field()
|
|
107
|
+
|
|
108
|
+
self._bd_field = fem.UniformField(domain=fem.BoundarySides(geo), value=wp.vec2(top_velocity, 0.0))
|
|
109
|
+
|
|
110
|
+
self.renderer = fem_example_utils.Plot()
|
|
111
|
+
|
|
112
|
+
def step(self):
|
|
113
|
+
u_space = self._u_field.space
|
|
114
|
+
p_space = self._p_field.space
|
|
115
|
+
geo = u_space.geometry
|
|
116
|
+
|
|
117
|
+
domain = fem.Cells(geometry=geo)
|
|
118
|
+
boundary = fem.BoundarySides(geo)
|
|
119
|
+
|
|
120
|
+
# Viscosity
|
|
121
|
+
u_test = fem.make_test(space=u_space, domain=domain)
|
|
122
|
+
u_trial = fem.make_trial(space=u_space, domain=domain)
|
|
123
|
+
|
|
124
|
+
u_visc_matrix = fem.integrate(
|
|
125
|
+
viscosity_form,
|
|
126
|
+
fields={"u": u_trial, "v": u_test},
|
|
127
|
+
values={"nu": self.viscosity},
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Weak velocity boundary conditions
|
|
131
|
+
u_bd_test = fem.make_test(space=u_space, domain=boundary)
|
|
132
|
+
u_bd_trial = fem.make_trial(space=u_space, domain=boundary)
|
|
133
|
+
u_rhs = fem.integrate(top_mass_form, fields={"u": self._bd_field, "v": u_bd_test}, output_dtype=wp.vec2d)
|
|
134
|
+
u_bd_matrix = fem.integrate(mass_form, fields={"u": u_bd_trial, "v": u_bd_test})
|
|
135
|
+
|
|
136
|
+
# Pressure-velocity coupling
|
|
137
|
+
p_test = fem.make_test(space=p_space, domain=domain)
|
|
138
|
+
div_matrix = fem.integrate(div_form, fields={"u": u_trial, "q": p_test})
|
|
139
|
+
|
|
140
|
+
# Define and solve the saddle-point system
|
|
141
|
+
u_matrix = u_visc_matrix
|
|
142
|
+
u_matrix += self.boundary_strength * u_bd_matrix
|
|
143
|
+
array_axpy(x=u_rhs, y=u_rhs, alpha=0.0, beta=self.boundary_strength)
|
|
144
|
+
|
|
145
|
+
p_rhs = wp.zeros(p_space.node_count(), dtype=wp.float64)
|
|
146
|
+
x_u = wp.zeros_like(u_rhs)
|
|
147
|
+
x_p = wp.zeros_like(p_rhs)
|
|
148
|
+
|
|
149
|
+
fem_example_utils.bsr_solve_saddle(
|
|
150
|
+
fem_example_utils.SaddleSystem(A=u_matrix, B=div_matrix),
|
|
151
|
+
x_u=x_u,
|
|
152
|
+
x_p=x_p,
|
|
153
|
+
b_u=u_rhs,
|
|
154
|
+
b_p=p_rhs,
|
|
155
|
+
quiet=self._quiet,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
wp.utils.array_cast(in_array=x_u, out_array=self._u_field.dof_values)
|
|
159
|
+
wp.utils.array_cast(in_array=x_p, out_array=self._p_field.dof_values)
|
|
160
|
+
|
|
161
|
+
def render(self):
|
|
162
|
+
self.renderer.add_field("pressure", self._p_field)
|
|
163
|
+
self.renderer.add_field("velocity", self._u_field)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
if __name__ == "__main__":
|
|
167
|
+
import argparse
|
|
168
|
+
|
|
169
|
+
wp.set_module_options({"enable_backward": False})
|
|
170
|
+
|
|
171
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
172
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
173
|
+
parser.add_argument("--resolution", type=int, default=50, help="Grid resolution.")
|
|
174
|
+
parser.add_argument("--degree", type=int, default=2, help="Polynomial degree of shape functions.")
|
|
175
|
+
parser.add_argument(
|
|
176
|
+
"--top_velocity",
|
|
177
|
+
type=float,
|
|
178
|
+
default=1.0,
|
|
179
|
+
help="Horizontal velocity initial condition at the top of the domain.",
|
|
180
|
+
)
|
|
181
|
+
parser.add_argument("--viscosity", type=float, default=1.0, help="Fluid viscosity parameter.")
|
|
182
|
+
parser.add_argument("--boundary_strength", type=float, default=100.0, help="Soft boundary condition strength.")
|
|
183
|
+
parser.add_argument("--mesh", choices=("grid", "tri", "quad"), default="grid", help="Mesh type.")
|
|
184
|
+
parser.add_argument(
|
|
185
|
+
"--nonconforming_pressures", action="store_true", help="For grid, use non-conforming pressure (Q_d/P_{d-1})."
|
|
186
|
+
)
|
|
187
|
+
parser.add_argument(
|
|
188
|
+
"--headless",
|
|
189
|
+
action="store_true",
|
|
190
|
+
help="Run in headless mode, suppressing the opening of any graphical windows.",
|
|
191
|
+
)
|
|
192
|
+
parser.add_argument("--quiet", action="store_true", help="Suppresses the printing out of iteration residuals.")
|
|
193
|
+
|
|
194
|
+
args = parser.parse_known_args()[0]
|
|
195
|
+
|
|
196
|
+
with wp.ScopedDevice(args.device):
|
|
197
|
+
example = Example(
|
|
198
|
+
quiet=args.quiet,
|
|
199
|
+
mesh=args.mesh,
|
|
200
|
+
degree=args.degree,
|
|
201
|
+
resolution=args.resolution,
|
|
202
|
+
viscosity=args.viscosity,
|
|
203
|
+
top_velocity=args.top_velocity,
|
|
204
|
+
boundary_strength=args.boundary_strength,
|
|
205
|
+
nonconforming_pressures=args.nonconforming_pressures,
|
|
206
|
+
)
|
|
207
|
+
example.step()
|
|
208
|
+
example.render()
|
|
209
|
+
|
|
210
|
+
if not args.headless:
|
|
211
|
+
example.renderer.plot(
|
|
212
|
+
options={"velocity": {"streamlines": {}}, "pressure": {"contours": {}}}, backend="matplotlib"
|
|
213
|
+
)
|