warp-lang 1.9.1__py3-none-manylinux_2_34_aarch64.whl → 1.10.0rc2__py3-none-manylinux_2_34_aarch64.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 +301 -287
- warp/__init__.pyi +794 -305
- warp/_src/__init__.py +14 -0
- warp/_src/autograd.py +1075 -0
- warp/_src/build.py +618 -0
- warp/_src/build_dll.py +640 -0
- warp/{builtins.py → _src/builtins.py} +1382 -377
- warp/_src/codegen.py +4359 -0
- warp/{config.py → _src/config.py} +178 -169
- warp/_src/constants.py +57 -0
- warp/_src/context.py +8294 -0
- warp/_src/dlpack.py +462 -0
- warp/_src/fabric.py +355 -0
- warp/_src/fem/__init__.py +14 -0
- warp/_src/fem/adaptivity.py +508 -0
- warp/_src/fem/cache.py +687 -0
- warp/_src/fem/dirichlet.py +188 -0
- warp/{fem → _src/fem}/domain.py +40 -30
- warp/_src/fem/field/__init__.py +131 -0
- warp/_src/fem/field/field.py +701 -0
- warp/{fem → _src/fem}/field/nodal_field.py +30 -15
- warp/{fem → _src/fem}/field/restriction.py +1 -1
- warp/{fem → _src/fem}/field/virtual.py +53 -27
- warp/_src/fem/geometry/__init__.py +32 -0
- warp/{fem → _src/fem}/geometry/adaptive_nanogrid.py +77 -163
- warp/_src/fem/geometry/closest_point.py +97 -0
- warp/{fem → _src/fem}/geometry/deformed_geometry.py +14 -22
- warp/{fem → _src/fem}/geometry/element.py +32 -10
- warp/{fem → _src/fem}/geometry/geometry.py +48 -20
- warp/{fem → _src/fem}/geometry/grid_2d.py +12 -23
- warp/{fem → _src/fem}/geometry/grid_3d.py +12 -23
- warp/{fem → _src/fem}/geometry/hexmesh.py +40 -63
- warp/{fem → _src/fem}/geometry/nanogrid.py +255 -248
- warp/{fem → _src/fem}/geometry/partition.py +121 -63
- warp/{fem → _src/fem}/geometry/quadmesh.py +26 -45
- warp/{fem → _src/fem}/geometry/tetmesh.py +40 -63
- warp/{fem → _src/fem}/geometry/trimesh.py +26 -45
- warp/{fem → _src/fem}/integrate.py +164 -158
- warp/_src/fem/linalg.py +383 -0
- warp/_src/fem/operator.py +396 -0
- warp/_src/fem/polynomial.py +229 -0
- warp/{fem → _src/fem}/quadrature/pic_quadrature.py +15 -20
- warp/{fem → _src/fem}/quadrature/quadrature.py +95 -47
- warp/_src/fem/space/__init__.py +248 -0
- warp/{fem → _src/fem}/space/basis_function_space.py +20 -11
- warp/_src/fem/space/basis_space.py +679 -0
- warp/{fem → _src/fem}/space/dof_mapper.py +3 -3
- warp/{fem → _src/fem}/space/function_space.py +14 -13
- warp/{fem → _src/fem}/space/grid_2d_function_space.py +4 -7
- warp/{fem → _src/fem}/space/grid_3d_function_space.py +4 -4
- warp/{fem → _src/fem}/space/hexmesh_function_space.py +4 -10
- warp/{fem → _src/fem}/space/nanogrid_function_space.py +3 -9
- warp/{fem → _src/fem}/space/partition.py +117 -60
- warp/{fem → _src/fem}/space/quadmesh_function_space.py +4 -10
- warp/{fem → _src/fem}/space/restriction.py +66 -33
- warp/_src/fem/space/shape/__init__.py +152 -0
- warp/{fem → _src/fem}/space/shape/cube_shape_function.py +9 -9
- warp/{fem → _src/fem}/space/shape/shape_function.py +8 -9
- warp/{fem → _src/fem}/space/shape/square_shape_function.py +6 -6
- warp/{fem → _src/fem}/space/shape/tet_shape_function.py +3 -3
- warp/{fem → _src/fem}/space/shape/triangle_shape_function.py +3 -3
- warp/{fem → _src/fem}/space/tetmesh_function_space.py +3 -9
- warp/_src/fem/space/topology.py +459 -0
- warp/{fem → _src/fem}/space/trimesh_function_space.py +3 -9
- warp/_src/fem/types.py +112 -0
- warp/_src/fem/utils.py +486 -0
- warp/_src/jax.py +186 -0
- warp/_src/jax_experimental/__init__.py +14 -0
- warp/_src/jax_experimental/custom_call.py +387 -0
- warp/_src/jax_experimental/ffi.py +1284 -0
- warp/_src/jax_experimental/xla_ffi.py +656 -0
- warp/_src/marching_cubes.py +708 -0
- warp/_src/math.py +414 -0
- warp/_src/optim/__init__.py +14 -0
- warp/_src/optim/adam.py +163 -0
- warp/_src/optim/linear.py +1606 -0
- warp/_src/optim/sgd.py +112 -0
- warp/_src/paddle.py +406 -0
- warp/_src/render/__init__.py +14 -0
- warp/_src/render/imgui_manager.py +289 -0
- warp/_src/render/render_opengl.py +3636 -0
- warp/_src/render/render_usd.py +937 -0
- warp/_src/render/utils.py +160 -0
- warp/_src/sparse.py +2716 -0
- warp/_src/tape.py +1206 -0
- warp/{thirdparty → _src/thirdparty}/unittest_parallel.py +9 -2
- warp/_src/torch.py +391 -0
- warp/_src/types.py +5870 -0
- warp/_src/utils.py +1693 -0
- warp/autograd.py +12 -1054
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +8 -588
- warp/build_dll.py +6 -721
- warp/codegen.py +6 -4251
- warp/constants.py +6 -39
- warp/context.py +12 -8062
- warp/dlpack.py +6 -444
- warp/examples/distributed/example_jacobi_mpi.py +4 -5
- warp/examples/fem/example_adaptive_grid.py +1 -1
- warp/examples/fem/example_apic_fluid.py +1 -1
- warp/examples/fem/example_burgers.py +8 -8
- warp/examples/fem/example_diffusion.py +1 -1
- warp/examples/fem/example_distortion_energy.py +1 -1
- warp/examples/fem/example_mixed_elasticity.py +2 -2
- warp/examples/fem/example_navier_stokes.py +1 -1
- warp/examples/fem/example_nonconforming_contact.py +7 -7
- warp/examples/fem/example_stokes.py +1 -1
- warp/examples/fem/example_stokes_transfer.py +1 -1
- warp/examples/fem/utils.py +2 -2
- warp/examples/interop/example_jax_callable.py +1 -1
- warp/examples/interop/example_jax_ffi_callback.py +1 -1
- warp/examples/interop/example_jax_kernel.py +1 -1
- warp/examples/tile/example_tile_mcgp.py +191 -0
- warp/fabric.py +6 -337
- warp/fem/__init__.py +159 -97
- warp/fem/adaptivity.py +7 -489
- warp/fem/cache.py +9 -648
- warp/fem/dirichlet.py +6 -184
- warp/fem/field/__init__.py +8 -109
- warp/fem/field/field.py +7 -652
- warp/fem/geometry/__init__.py +7 -18
- warp/fem/geometry/closest_point.py +11 -77
- warp/fem/linalg.py +18 -366
- warp/fem/operator.py +11 -369
- warp/fem/polynomial.py +9 -209
- warp/fem/space/__init__.py +5 -211
- warp/fem/space/basis_space.py +6 -662
- warp/fem/space/shape/__init__.py +41 -118
- warp/fem/space/topology.py +6 -437
- warp/fem/types.py +6 -81
- warp/fem/utils.py +11 -444
- warp/jax.py +8 -165
- warp/jax_experimental/__init__.py +14 -1
- warp/jax_experimental/custom_call.py +8 -365
- warp/jax_experimental/ffi.py +17 -873
- warp/jax_experimental/xla_ffi.py +5 -605
- warp/marching_cubes.py +5 -689
- warp/math.py +16 -393
- warp/native/array.h +385 -37
- warp/native/builtin.h +314 -37
- warp/native/bvh.cpp +43 -9
- warp/native/bvh.cu +62 -27
- warp/native/bvh.h +310 -309
- warp/native/clang/clang.cpp +102 -97
- warp/native/coloring.cpp +0 -1
- warp/native/crt.h +208 -0
- warp/native/exports.h +156 -0
- warp/native/hashgrid.cu +2 -0
- warp/native/intersect.h +24 -1
- warp/native/intersect_tri.h +44 -35
- warp/native/mat.h +1456 -276
- warp/native/mesh.cpp +4 -4
- warp/native/mesh.cu +4 -2
- warp/native/mesh.h +176 -61
- warp/native/quat.h +0 -52
- warp/native/scan.cu +2 -0
- warp/native/sparse.cu +7 -3
- warp/native/spatial.h +12 -0
- warp/native/tile.h +681 -89
- warp/native/tile_radix_sort.h +1 -1
- warp/native/tile_reduce.h +394 -46
- warp/native/tile_scan.h +4 -4
- warp/native/vec.h +469 -0
- warp/native/version.h +23 -0
- warp/native/volume.cpp +1 -1
- warp/native/volume.cu +1 -0
- warp/native/volume.h +1 -1
- warp/native/volume_builder.cu +2 -0
- warp/native/warp.cpp +57 -29
- warp/native/warp.cu +253 -171
- warp/native/warp.h +11 -8
- warp/optim/__init__.py +6 -3
- warp/optim/adam.py +6 -145
- warp/optim/linear.py +14 -1585
- warp/optim/sgd.py +6 -94
- warp/paddle.py +6 -388
- warp/render/__init__.py +8 -4
- warp/render/imgui_manager.py +7 -267
- warp/render/render_opengl.py +6 -3618
- warp/render/render_usd.py +6 -919
- warp/render/utils.py +6 -142
- warp/sparse.py +37 -2563
- warp/tape.py +6 -1188
- warp/tests/__main__.py +1 -1
- warp/tests/cuda/test_async.py +4 -4
- warp/tests/cuda/test_conditional_captures.py +1 -1
- warp/tests/cuda/test_multigpu.py +1 -1
- warp/tests/cuda/test_streams.py +58 -1
- warp/tests/geometry/test_bvh.py +157 -22
- warp/tests/geometry/test_marching_cubes.py +0 -1
- warp/tests/geometry/test_mesh.py +5 -3
- warp/tests/geometry/test_mesh_query_aabb.py +5 -12
- warp/tests/geometry/test_mesh_query_point.py +5 -2
- warp/tests/geometry/test_mesh_query_ray.py +15 -3
- warp/tests/geometry/test_volume_write.py +5 -5
- warp/tests/interop/test_dlpack.py +14 -14
- warp/tests/interop/test_jax.py +772 -49
- warp/tests/interop/test_paddle.py +1 -1
- warp/tests/test_adam.py +0 -1
- warp/tests/test_arithmetic.py +9 -9
- warp/tests/test_array.py +527 -100
- warp/tests/test_array_reduce.py +3 -3
- warp/tests/test_atomic.py +12 -8
- warp/tests/test_atomic_bitwise.py +209 -0
- warp/tests/test_atomic_cas.py +4 -4
- warp/tests/test_bool.py +2 -2
- warp/tests/test_builtins_resolution.py +5 -571
- warp/tests/test_codegen.py +33 -14
- warp/tests/test_conditional.py +1 -1
- warp/tests/test_context.py +6 -6
- warp/tests/test_copy.py +242 -161
- warp/tests/test_ctypes.py +3 -3
- warp/tests/test_devices.py +24 -2
- warp/tests/test_examples.py +16 -84
- warp/tests/test_fabricarray.py +35 -35
- warp/tests/test_fast_math.py +0 -2
- warp/tests/test_fem.py +56 -10
- warp/tests/test_fixedarray.py +3 -3
- warp/tests/test_func.py +8 -5
- warp/tests/test_generics.py +1 -1
- warp/tests/test_indexedarray.py +24 -24
- warp/tests/test_intersect.py +39 -9
- warp/tests/test_large.py +1 -1
- warp/tests/test_lerp.py +3 -1
- warp/tests/test_linear_solvers.py +1 -1
- warp/tests/test_map.py +35 -4
- warp/tests/test_mat.py +52 -62
- warp/tests/test_mat_constructors.py +4 -5
- warp/tests/test_mat_lite.py +1 -1
- warp/tests/test_mat_scalar_ops.py +121 -121
- warp/tests/test_math.py +34 -0
- warp/tests/test_module_aot.py +4 -4
- warp/tests/test_modules_lite.py +28 -2
- warp/tests/test_print.py +11 -11
- warp/tests/test_quat.py +93 -58
- warp/tests/test_runlength_encode.py +1 -1
- warp/tests/test_scalar_ops.py +38 -10
- warp/tests/test_smoothstep.py +1 -1
- warp/tests/test_sparse.py +126 -15
- warp/tests/test_spatial.py +105 -87
- warp/tests/test_special_values.py +6 -6
- warp/tests/test_static.py +7 -7
- warp/tests/test_struct.py +13 -2
- warp/tests/test_triangle_closest_point.py +48 -1
- warp/tests/test_types.py +27 -15
- warp/tests/test_utils.py +52 -52
- warp/tests/test_vec.py +29 -29
- warp/tests/test_vec_constructors.py +5 -5
- warp/tests/test_vec_scalar_ops.py +97 -97
- warp/tests/test_version.py +75 -0
- warp/tests/tile/test_tile.py +178 -0
- warp/tests/tile/test_tile_atomic_bitwise.py +403 -0
- warp/tests/tile/test_tile_cholesky.py +7 -4
- warp/tests/tile/test_tile_load.py +26 -2
- warp/tests/tile/test_tile_mathdx.py +3 -3
- warp/tests/tile/test_tile_matmul.py +1 -1
- warp/tests/tile/test_tile_mlp.py +2 -4
- warp/tests/tile/test_tile_reduce.py +214 -13
- warp/tests/unittest_suites.py +6 -14
- warp/tests/unittest_utils.py +10 -9
- warp/tests/walkthrough_debug.py +3 -1
- warp/torch.py +6 -373
- warp/types.py +29 -5764
- warp/utils.py +10 -1659
- {warp_lang-1.9.1.dist-info → warp_lang-1.10.0rc2.dist-info}/METADATA +46 -99
- warp_lang-1.10.0rc2.dist-info/RECORD +468 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
- warp_lang-1.10.0rc2.dist-info/licenses/licenses/windingnumber-LICENSE.txt +21 -0
- warp/examples/assets/cartpole.urdf +0 -110
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/nv_ant.xml +0 -92
- warp/examples/assets/nv_humanoid.xml +0 -183
- warp/examples/assets/quadruped.urdf +0 -268
- warp/examples/optim/example_bounce.py +0 -266
- warp/examples/optim/example_cloth_throw.py +0 -228
- warp/examples/optim/example_drone.py +0 -870
- warp/examples/optim/example_inverse_kinematics.py +0 -182
- warp/examples/optim/example_inverse_kinematics_torch.py +0 -191
- warp/examples/optim/example_softbody_properties.py +0 -400
- warp/examples/optim/example_spring_cage.py +0 -245
- warp/examples/optim/example_trajectory.py +0 -227
- warp/examples/sim/example_cartpole.py +0 -143
- warp/examples/sim/example_cloth.py +0 -225
- warp/examples/sim/example_cloth_self_contact.py +0 -316
- warp/examples/sim/example_granular.py +0 -130
- warp/examples/sim/example_granular_collision_sdf.py +0 -202
- warp/examples/sim/example_jacobian_ik.py +0 -244
- warp/examples/sim/example_particle_chain.py +0 -124
- warp/examples/sim/example_quadruped.py +0 -203
- warp/examples/sim/example_rigid_chain.py +0 -203
- warp/examples/sim/example_rigid_contact.py +0 -195
- warp/examples/sim/example_rigid_force.py +0 -133
- warp/examples/sim/example_rigid_gyroscopic.py +0 -115
- warp/examples/sim/example_rigid_soft_contact.py +0 -140
- warp/examples/sim/example_soft_body.py +0 -196
- warp/examples/tile/example_tile_walker.py +0 -327
- warp/sim/__init__.py +0 -74
- warp/sim/articulation.py +0 -793
- warp/sim/collide.py +0 -2570
- warp/sim/graph_coloring.py +0 -307
- warp/sim/import_mjcf.py +0 -791
- warp/sim/import_snu.py +0 -227
- warp/sim/import_urdf.py +0 -579
- warp/sim/import_usd.py +0 -898
- warp/sim/inertia.py +0 -357
- warp/sim/integrator.py +0 -245
- warp/sim/integrator_euler.py +0 -2000
- warp/sim/integrator_featherstone.py +0 -2101
- warp/sim/integrator_vbd.py +0 -2487
- warp/sim/integrator_xpbd.py +0 -3295
- warp/sim/model.py +0 -4821
- warp/sim/particles.py +0 -121
- warp/sim/render.py +0 -431
- warp/sim/utils.py +0 -431
- warp/tests/sim/disabled_kinematics.py +0 -244
- warp/tests/sim/test_cloth.py +0 -863
- warp/tests/sim/test_collision.py +0 -743
- warp/tests/sim/test_coloring.py +0 -347
- warp/tests/sim/test_inertia.py +0 -161
- warp/tests/sim/test_model.py +0 -226
- warp/tests/sim/test_sim_grad.py +0 -287
- warp/tests/sim/test_sim_grad_bounce_linear.py +0 -212
- warp/tests/sim/test_sim_kinematics.py +0 -98
- warp/thirdparty/__init__.py +0 -0
- warp_lang-1.9.1.dist-info/RECORD +0 -456
- /warp/{fem → _src/fem}/quadrature/__init__.py +0 -0
- /warp/{tests/sim → _src/thirdparty}/__init__.py +0 -0
- /warp/{thirdparty → _src/thirdparty}/appdirs.py +0 -0
- /warp/{thirdparty → _src/thirdparty}/dlpack.py +0 -0
- {warp_lang-1.9.1.dist-info → warp_lang-1.10.0rc2.dist-info}/WHEEL +0 -0
- {warp_lang-1.9.1.dist-info → warp_lang-1.10.0rc2.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.9.1.dist-info → warp_lang-1.10.0rc2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2023 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
|
+
from typing import Any, Optional
|
|
17
|
+
|
|
18
|
+
import warp as wp
|
|
19
|
+
from warp._src.fem.linalg import array_axpy, symmetric_eigenvalues_qr
|
|
20
|
+
from warp._src.types import type_is_matrix, type_size
|
|
21
|
+
from warp.sparse import BsrMatrix, bsr_assign, bsr_axpy, bsr_block_index, bsr_copy, bsr_mm, bsr_mv
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def normalize_dirichlet_projector(projector_matrix: BsrMatrix, fixed_value: Optional[wp.array] = None):
|
|
25
|
+
"""
|
|
26
|
+
Scale projector so that it becomes idempotent, and apply the same scaling to fixed_value if provided
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
if projector_matrix.ncol != projector_matrix.nrow:
|
|
30
|
+
raise ValueError("Projector must be a square block-diagonal matrix")
|
|
31
|
+
|
|
32
|
+
# Cast blocks to matrix type if necessary
|
|
33
|
+
projector_values = projector_matrix.values
|
|
34
|
+
if not type_is_matrix(projector_values.dtype):
|
|
35
|
+
projector_values = wp.array(
|
|
36
|
+
data=None,
|
|
37
|
+
ptr=projector_values.ptr,
|
|
38
|
+
capacity=projector_values.capacity,
|
|
39
|
+
device=projector_values.device,
|
|
40
|
+
dtype=wp.mat(shape=projector_matrix.block_shape, dtype=projector_matrix.scalar_type),
|
|
41
|
+
shape=projector_values.shape[0],
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
if fixed_value is None:
|
|
45
|
+
wp.launch(
|
|
46
|
+
kernel=_normalize_dirichlet_projector_kernel,
|
|
47
|
+
dim=projector_matrix.nrow,
|
|
48
|
+
device=projector_values.device,
|
|
49
|
+
inputs=[projector_matrix.offsets, projector_matrix.columns, projector_values],
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
else:
|
|
53
|
+
if fixed_value.shape[0] != projector_matrix.nrow:
|
|
54
|
+
raise ValueError("Fixed value array must be of length equal to the number of rows of blocks")
|
|
55
|
+
|
|
56
|
+
if type_size(fixed_value.dtype) == 1:
|
|
57
|
+
# array of scalars, convert to 1d array of vectors
|
|
58
|
+
fixed_value = wp.array(
|
|
59
|
+
data=None,
|
|
60
|
+
ptr=fixed_value.ptr,
|
|
61
|
+
capacity=fixed_value.capacity,
|
|
62
|
+
device=fixed_value.device,
|
|
63
|
+
dtype=wp.vec(length=projector_matrix.block_shape[0], dtype=projector_matrix.scalar_type),
|
|
64
|
+
shape=fixed_value.shape[0],
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
wp.launch(
|
|
68
|
+
kernel=_normalize_dirichlet_projector_and_values_kernel,
|
|
69
|
+
dim=projector_matrix.nrow,
|
|
70
|
+
device=projector_values.device,
|
|
71
|
+
inputs=[projector_matrix.offsets, projector_matrix.columns, projector_values, fixed_value],
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def project_system_rhs(
|
|
76
|
+
system_matrix: BsrMatrix, system_rhs: wp.array, projector_matrix: BsrMatrix, fixed_value: Optional[wp.array] = None
|
|
77
|
+
):
|
|
78
|
+
"""Projects the right-hand-side of a linear system to enforce Dirichlet boundary conditions
|
|
79
|
+
|
|
80
|
+
``rhs = (I - projector) * ( rhs - system * projector * fixed_value) + projector * fixed_value``
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
rhs_tmp = wp.empty_like(system_rhs)
|
|
84
|
+
rhs_tmp.assign(system_rhs)
|
|
85
|
+
|
|
86
|
+
if fixed_value is None:
|
|
87
|
+
system_rhs.zero_()
|
|
88
|
+
else:
|
|
89
|
+
bsr_mv(A=projector_matrix, x=fixed_value, y=system_rhs, alpha=1.0, beta=0.0)
|
|
90
|
+
|
|
91
|
+
bsr_mv(A=system_matrix, x=system_rhs, y=rhs_tmp, alpha=-1.0, beta=1.0)
|
|
92
|
+
|
|
93
|
+
# here rhs_tmp = system_rhs - system_matrix * projector * fixed_value
|
|
94
|
+
# system_rhs = projector * fixed_value
|
|
95
|
+
array_axpy(x=rhs_tmp, y=system_rhs, alpha=1.0, beta=1.0)
|
|
96
|
+
bsr_mv(A=projector_matrix, x=rhs_tmp, y=system_rhs, alpha=-1.0, beta=1.0)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def project_system_matrix(system_matrix: BsrMatrix, projector_matrix: BsrMatrix):
|
|
100
|
+
"""Projects the right-hand-side of a linear system to enforce Dirichlet boundary conditions
|
|
101
|
+
|
|
102
|
+
``system = (I - projector) * system * (I - projector) + projector``
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
complement_system = bsr_copy(system_matrix)
|
|
106
|
+
bsr_mm(x=projector_matrix, y=system_matrix, z=complement_system, alpha=-1.0, beta=1.0)
|
|
107
|
+
|
|
108
|
+
bsr_assign(dest=system_matrix, src=complement_system)
|
|
109
|
+
bsr_axpy(x=projector_matrix, y=system_matrix)
|
|
110
|
+
bsr_mm(x=complement_system, y=projector_matrix, z=system_matrix, alpha=-1.0, beta=1.0)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def project_linear_system(
|
|
114
|
+
system_matrix: BsrMatrix,
|
|
115
|
+
system_rhs: wp.array,
|
|
116
|
+
projector_matrix: BsrMatrix,
|
|
117
|
+
fixed_value: Optional[wp.array] = None,
|
|
118
|
+
normalize_projector=True,
|
|
119
|
+
):
|
|
120
|
+
"""
|
|
121
|
+
Projects both the left-hand-side and right-hand-side of a linear system to enforce Dirichlet boundary conditions
|
|
122
|
+
|
|
123
|
+
If normalize_projector is True, first apply scaling so that the projector_matrix is idempotent
|
|
124
|
+
"""
|
|
125
|
+
if normalize_projector:
|
|
126
|
+
normalize_dirichlet_projector(projector_matrix, fixed_value)
|
|
127
|
+
|
|
128
|
+
project_system_rhs(system_matrix, system_rhs, projector_matrix, fixed_value)
|
|
129
|
+
project_system_matrix(system_matrix, projector_matrix)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@wp.func
|
|
133
|
+
def _normalize_projector_and_value(A: Any, b: Any):
|
|
134
|
+
# Do a modal decomposition of the left and right hand side,
|
|
135
|
+
# Make lhs an orthogonal projection and apply corresponding scaling to right-hand side
|
|
136
|
+
|
|
137
|
+
eps = wp.trace(A) * A.dtype(1.0e-6)
|
|
138
|
+
|
|
139
|
+
diag, ev = symmetric_eigenvalues_qr(A, eps * eps)
|
|
140
|
+
|
|
141
|
+
zero = A.dtype(0)
|
|
142
|
+
A_unitary = type(A)(zero)
|
|
143
|
+
b_normalized = type(b)(zero)
|
|
144
|
+
|
|
145
|
+
for k in range(b.length):
|
|
146
|
+
if diag[k] > eps: # ignore small eigenmodes
|
|
147
|
+
v = ev[k]
|
|
148
|
+
A_unitary += wp.outer(v, v)
|
|
149
|
+
b_normalized += wp.dot(v, b) / diag[k] * v
|
|
150
|
+
|
|
151
|
+
return A_unitary, b_normalized
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@wp.kernel
|
|
155
|
+
def _normalize_dirichlet_projector_and_values_kernel(
|
|
156
|
+
offsets: wp.array(dtype=int),
|
|
157
|
+
columns: wp.array(dtype=int),
|
|
158
|
+
block_values: wp.array(dtype=Any),
|
|
159
|
+
fixed_values: wp.array(dtype=Any),
|
|
160
|
+
):
|
|
161
|
+
row = wp.tid()
|
|
162
|
+
|
|
163
|
+
diag = bsr_block_index(row, row, offsets, columns)
|
|
164
|
+
|
|
165
|
+
if diag != -1:
|
|
166
|
+
P = block_values[diag]
|
|
167
|
+
|
|
168
|
+
P_norm, v_norm = _normalize_projector_and_value(P, fixed_values[row])
|
|
169
|
+
|
|
170
|
+
block_values[diag] = P_norm
|
|
171
|
+
fixed_values[row] = v_norm
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@wp.kernel
|
|
175
|
+
def _normalize_dirichlet_projector_kernel(
|
|
176
|
+
offsets: wp.array(dtype=int),
|
|
177
|
+
columns: wp.array(dtype=int),
|
|
178
|
+
block_values: wp.array(dtype=Any),
|
|
179
|
+
):
|
|
180
|
+
row = wp.tid()
|
|
181
|
+
|
|
182
|
+
diag = bsr_block_index(row, row, offsets, columns)
|
|
183
|
+
|
|
184
|
+
if diag != -1:
|
|
185
|
+
P = block_values[diag]
|
|
186
|
+
|
|
187
|
+
P_norm, v_norm = _normalize_projector_and_value(P, type(P[0])())
|
|
188
|
+
block_values[diag] = P_norm
|
warp/{fem → _src/fem}/domain.py
RENAMED
|
@@ -17,18 +17,18 @@ from functools import cached_property
|
|
|
17
17
|
from typing import Any, Optional, Set, Union
|
|
18
18
|
|
|
19
19
|
import warp as wp
|
|
20
|
-
import warp.
|
|
21
|
-
import warp.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
from warp.fem.geometry import (
|
|
20
|
+
import warp._src.fem.cache as cache
|
|
21
|
+
import warp._src.fem.utils as utils
|
|
22
|
+
from warp._src.codegen import Struct, StructInstance
|
|
23
|
+
from warp._src.context import Devicelike
|
|
24
|
+
from warp._src.fem.geometry import (
|
|
25
25
|
Element,
|
|
26
26
|
Geometry,
|
|
27
27
|
GeometryPartition,
|
|
28
28
|
WholeGeometryPartition,
|
|
29
29
|
)
|
|
30
|
-
from warp.fem.operator import Operator
|
|
31
|
-
from warp.fem.types import NULL_ELEMENT_INDEX, ElementKind
|
|
30
|
+
from warp._src.fem.operator import Operator
|
|
31
|
+
from warp._src.fem.types import NULL_ELEMENT_INDEX, ElementKind
|
|
32
32
|
|
|
33
33
|
GeometryOrPartition = Union[Geometry, GeometryPartition]
|
|
34
34
|
|
|
@@ -44,7 +44,7 @@ class GeometryDomain:
|
|
|
44
44
|
|
|
45
45
|
self.geometry = self.geometry_partition.geometry
|
|
46
46
|
|
|
47
|
-
@
|
|
47
|
+
@cached_property
|
|
48
48
|
def name(self) -> str:
|
|
49
49
|
return f"{self.geometry_partition.name}_{self.__class__.__name__}"
|
|
50
50
|
|
|
@@ -73,18 +73,28 @@ class GeometryDomain:
|
|
|
73
73
|
return self.geometry.cell_count()
|
|
74
74
|
|
|
75
75
|
def reference_element(self) -> Element:
|
|
76
|
-
"""
|
|
76
|
+
"""Type of reference element"""
|
|
77
77
|
raise NotImplementedError
|
|
78
78
|
|
|
79
|
-
def element_index_arg_value(self, device:
|
|
79
|
+
def element_index_arg_value(self, device: Devicelike) -> StructInstance:
|
|
80
80
|
"""Value of the argument to be passed to device functions"""
|
|
81
|
-
|
|
81
|
+
args = self.ElementIndexArg()
|
|
82
|
+
self.fill_element_index_arg(args, device)
|
|
83
|
+
return args
|
|
84
|
+
|
|
85
|
+
def fill_element_index_arg(self, arg: "GeometryDomain.ElementIndexArg", device: Devicelike):
|
|
86
|
+
arg.assign(self.element_index_arg_value(device))
|
|
82
87
|
|
|
83
|
-
def element_arg_value(self, device:
|
|
88
|
+
def element_arg_value(self, device: Devicelike) -> StructInstance:
|
|
84
89
|
"""Value of the argument to be passed to device functions"""
|
|
85
|
-
|
|
90
|
+
args = self.ElementArg()
|
|
91
|
+
self.fill_element_arg(args, device)
|
|
92
|
+
return args
|
|
93
|
+
|
|
94
|
+
def fill_element_arg(self, arg: "GeometryDomain.ElementArg", device: Devicelike):
|
|
95
|
+
arg.assign(self.element_arg_value(device))
|
|
86
96
|
|
|
87
|
-
ElementIndexArg:
|
|
97
|
+
ElementIndexArg: Struct
|
|
88
98
|
"""Structure containing arguments to be passed to device functions computing element indices"""
|
|
89
99
|
|
|
90
100
|
element_index: wp.Function
|
|
@@ -93,7 +103,7 @@ class GeometryDomain:
|
|
|
93
103
|
element_partition_index: wp.Function
|
|
94
104
|
"""Device function for retrieving linearized index in the domain's partition from an ElementIndex"""
|
|
95
105
|
|
|
96
|
-
ElementArg:
|
|
106
|
+
ElementArg: Struct
|
|
97
107
|
"""Structure containing arguments to be passed to device functions computing element geometry"""
|
|
98
108
|
|
|
99
109
|
element_measure: wp.Function
|
|
@@ -164,13 +174,13 @@ class Cells(GeometryDomain):
|
|
|
164
174
|
return self.geometry.cell_count()
|
|
165
175
|
|
|
166
176
|
@property
|
|
167
|
-
def ElementIndexArg(self) ->
|
|
177
|
+
def ElementIndexArg(self) -> Struct:
|
|
168
178
|
return self.geometry_partition.CellArg
|
|
169
179
|
|
|
170
|
-
def element_index_arg_value(self, device:
|
|
180
|
+
def element_index_arg_value(self, device: Devicelike) -> StructInstance:
|
|
171
181
|
return self.geometry_partition.cell_arg_value(device)
|
|
172
182
|
|
|
173
|
-
def fill_element_index_arg(self, arg: ElementIndexArg, device:
|
|
183
|
+
def fill_element_index_arg(self, arg: ElementIndexArg, device: Devicelike):
|
|
174
184
|
self.geometry_partition.fill_cell_arg(arg, device)
|
|
175
185
|
|
|
176
186
|
@property
|
|
@@ -181,14 +191,14 @@ class Cells(GeometryDomain):
|
|
|
181
191
|
def element_partition_index(self) -> wp.Function:
|
|
182
192
|
return self.geometry_partition.partition_cell_index
|
|
183
193
|
|
|
184
|
-
def element_arg_value(self, device:
|
|
194
|
+
def element_arg_value(self, device: Devicelike) -> StructInstance:
|
|
185
195
|
return self.geometry.cell_arg_value(device)
|
|
186
196
|
|
|
187
|
-
def fill_element_arg(self, arg: "ElementArg", device:
|
|
197
|
+
def fill_element_arg(self, arg: "ElementArg", device: Devicelike):
|
|
188
198
|
self.geometry.fill_cell_arg(arg, device)
|
|
189
199
|
|
|
190
200
|
@property
|
|
191
|
-
def ElementArg(self) ->
|
|
201
|
+
def ElementArg(self) -> Struct:
|
|
192
202
|
return self.geometry.CellArg
|
|
193
203
|
|
|
194
204
|
@property
|
|
@@ -223,7 +233,7 @@ class Cells(GeometryDomain):
|
|
|
223
233
|
def element_lookup(self) -> wp.Function:
|
|
224
234
|
return self.geometry.cell_lookup
|
|
225
235
|
|
|
226
|
-
@
|
|
236
|
+
@cached_property
|
|
227
237
|
def element_partition_lookup(self) -> wp.Function:
|
|
228
238
|
pos_type = cache.cached_vec_type(self.geometry.dimension, dtype=float)
|
|
229
239
|
|
|
@@ -295,13 +305,13 @@ class Sides(GeometryDomain):
|
|
|
295
305
|
return self.geometry.side_count()
|
|
296
306
|
|
|
297
307
|
@property
|
|
298
|
-
def ElementIndexArg(self) ->
|
|
308
|
+
def ElementIndexArg(self) -> Struct:
|
|
299
309
|
return self.geometry_partition.SideArg
|
|
300
310
|
|
|
301
|
-
def element_index_arg_value(self, device:
|
|
311
|
+
def element_index_arg_value(self, device: Devicelike) -> StructInstance:
|
|
302
312
|
return self.geometry_partition.side_arg_value(device)
|
|
303
313
|
|
|
304
|
-
def fill_element_index_arg(self, arg: "ElementIndexArg", device:
|
|
314
|
+
def fill_element_index_arg(self, arg: "ElementIndexArg", device: Devicelike):
|
|
305
315
|
self.geometry_partition.fill_side_arg(arg, device)
|
|
306
316
|
|
|
307
317
|
@property
|
|
@@ -309,13 +319,13 @@ class Sides(GeometryDomain):
|
|
|
309
319
|
return self.geometry_partition.side_index
|
|
310
320
|
|
|
311
321
|
@property
|
|
312
|
-
def ElementArg(self) ->
|
|
322
|
+
def ElementArg(self) -> Struct:
|
|
313
323
|
return self.geometry.SideArg
|
|
314
324
|
|
|
315
|
-
def element_arg_value(self, device:
|
|
325
|
+
def element_arg_value(self, device: Devicelike) -> StructInstance:
|
|
316
326
|
return self.geometry.side_arg_value(device)
|
|
317
327
|
|
|
318
|
-
def fill_element_arg(self, arg: "ElementArg", device:
|
|
328
|
+
def fill_element_arg(self, arg: "ElementArg", device: Devicelike):
|
|
319
329
|
self.geometry.fill_side_arg(arg, device)
|
|
320
330
|
|
|
321
331
|
@property
|
|
@@ -498,12 +508,12 @@ class Subdomain(GeometryDomain):
|
|
|
498
508
|
return ElementIndexArg
|
|
499
509
|
|
|
500
510
|
@cache.cached_arg_value
|
|
501
|
-
def element_index_arg_value(self, device:
|
|
511
|
+
def element_index_arg_value(self, device: Devicelike):
|
|
502
512
|
arg = self.ElementIndexArg()
|
|
503
513
|
self.fill_element_index_arg(arg, device)
|
|
504
514
|
return arg
|
|
505
515
|
|
|
506
|
-
def fill_element_index_arg(self, arg: "GeometryDomain.ElementIndexArg", device:
|
|
516
|
+
def fill_element_index_arg(self, arg: "GeometryDomain.ElementIndexArg", device: Devicelike):
|
|
507
517
|
self._domain.fill_element_index_arg(arg.domain_arg, device)
|
|
508
518
|
arg.element_indices = self._element_indices.to(device)
|
|
509
519
|
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2023 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
|
+
from typing import Optional, Union
|
|
17
|
+
|
|
18
|
+
from warp._src.fem.domain import Cells, GeometryDomain
|
|
19
|
+
from warp._src.fem.space import (
|
|
20
|
+
FunctionSpace,
|
|
21
|
+
SpacePartition,
|
|
22
|
+
SpaceRestriction,
|
|
23
|
+
make_space_partition,
|
|
24
|
+
make_space_restriction,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
from .field import DiscreteField, FieldLike, GeometryField, ImplicitField, NonconformingField, SpaceField, UniformField
|
|
28
|
+
from .nodal_field import NodalField
|
|
29
|
+
from .restriction import FieldRestriction
|
|
30
|
+
from .virtual import LocalTestField, LocalTrialField, TestField, TrialField
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def make_restriction(
|
|
34
|
+
field: DiscreteField,
|
|
35
|
+
space_restriction: Optional[SpaceRestriction] = None,
|
|
36
|
+
domain: Optional[GeometryDomain] = None,
|
|
37
|
+
device=None,
|
|
38
|
+
) -> FieldRestriction:
|
|
39
|
+
"""
|
|
40
|
+
Restricts a discrete field to a subset of elements.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
field: the discrete field to restrict
|
|
44
|
+
space_restriction: the function space restriction defining the subset of elements to consider
|
|
45
|
+
domain: if ``space_restriction`` is not provided, the :py:class:`Domain` defining the subset of elements to consider
|
|
46
|
+
device: Warp device on which to perform and store computations
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
the field restriction
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
if space_restriction is None:
|
|
53
|
+
space_restriction = make_space_restriction(space_partition=field.space_partition, domain=domain, device=device)
|
|
54
|
+
|
|
55
|
+
return FieldRestriction(field=field, space_restriction=space_restriction)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def make_test(
|
|
59
|
+
space: FunctionSpace,
|
|
60
|
+
space_restriction: Optional[SpaceRestriction] = None,
|
|
61
|
+
space_partition: Optional[SpacePartition] = None,
|
|
62
|
+
domain: Optional[GeometryDomain] = None,
|
|
63
|
+
device=None,
|
|
64
|
+
) -> TestField:
|
|
65
|
+
"""
|
|
66
|
+
Constructs a test field over a function space or its restriction
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
space: the function space
|
|
70
|
+
space_restriction: restriction of the space topology to a domain
|
|
71
|
+
space_partition: if `space_restriction` is ``None``, the optional subset of node indices to consider
|
|
72
|
+
domain: if `space_restriction` is ``None``, optional subset of elements to consider
|
|
73
|
+
device: Warp device on which to perform and store computations
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
the test field
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
if space_restriction is None:
|
|
80
|
+
space_restriction = make_space_restriction(
|
|
81
|
+
space_topology=space.topology, space_partition=space_partition, domain=domain, device=device
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
return TestField(space_restriction=space_restriction, space=space)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def make_trial(
|
|
88
|
+
space: FunctionSpace,
|
|
89
|
+
space_restriction: Optional[SpaceRestriction] = None,
|
|
90
|
+
space_partition: Optional[SpacePartition] = None,
|
|
91
|
+
domain: Optional[GeometryDomain] = None,
|
|
92
|
+
) -> TrialField:
|
|
93
|
+
"""
|
|
94
|
+
Constructs a trial field over a function space or partition
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
space: the function space or function space restriction
|
|
98
|
+
space_restriction: restriction of the space topology to a domain
|
|
99
|
+
space_partition: if `space_restriction` is ``None``, the optional subset of node indices to consider
|
|
100
|
+
domain: if `space_restriction` is ``None``, optional subset of elements to consider
|
|
101
|
+
device: Warp device on which to perform and store computations
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
the trial field
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
if space_restriction is not None:
|
|
108
|
+
domain = space_restriction.domain
|
|
109
|
+
space_partition = space_restriction.space_partition
|
|
110
|
+
|
|
111
|
+
if space_partition is None:
|
|
112
|
+
if domain is None:
|
|
113
|
+
domain = Cells(geometry=space.geometry)
|
|
114
|
+
space_partition = make_space_partition(
|
|
115
|
+
space_topology=space.topology, geometry_partition=domain.geometry_partition
|
|
116
|
+
)
|
|
117
|
+
elif domain is None:
|
|
118
|
+
domain = Cells(geometry=space_partition.geo_partition)
|
|
119
|
+
|
|
120
|
+
return TrialField(space, space_partition, domain)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def make_discrete_field(
|
|
124
|
+
space: FunctionSpace,
|
|
125
|
+
space_partition: Optional[SpacePartition] = None,
|
|
126
|
+
) -> DiscreteField:
|
|
127
|
+
"""Constructs a zero-initialized discrete field over a function space or partition
|
|
128
|
+
|
|
129
|
+
See also: :meth:`warp.fem.FunctionSpace.make_field`
|
|
130
|
+
"""
|
|
131
|
+
return space.make_field(space_partition=space_partition)
|