warp-lang 1.9.1__py3-none-win_amd64.whl → 1.10.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +301 -287
- warp/__init__.pyi +882 -305
- warp/_src/__init__.py +14 -0
- warp/_src/autograd.py +1077 -0
- warp/_src/build.py +620 -0
- warp/_src/build_dll.py +642 -0
- warp/{builtins.py → _src/builtins.py} +1435 -379
- warp/_src/codegen.py +4361 -0
- warp/{config.py → _src/config.py} +178 -169
- warp/_src/constants.py +59 -0
- warp/_src/context.py +8352 -0
- warp/_src/dlpack.py +464 -0
- warp/_src/fabric.py +362 -0
- warp/_src/fem/__init__.py +14 -0
- warp/_src/fem/adaptivity.py +510 -0
- warp/_src/fem/cache.py +689 -0
- warp/_src/fem/dirichlet.py +190 -0
- warp/{fem → _src/fem}/domain.py +42 -30
- warp/_src/fem/field/__init__.py +131 -0
- warp/_src/fem/field/field.py +703 -0
- warp/{fem → _src/fem}/field/nodal_field.py +32 -15
- warp/{fem → _src/fem}/field/restriction.py +3 -1
- warp/{fem → _src/fem}/field/virtual.py +55 -27
- warp/_src/fem/geometry/__init__.py +32 -0
- warp/{fem → _src/fem}/geometry/adaptive_nanogrid.py +79 -163
- warp/_src/fem/geometry/closest_point.py +99 -0
- warp/{fem → _src/fem}/geometry/deformed_geometry.py +16 -22
- warp/{fem → _src/fem}/geometry/element.py +34 -10
- warp/{fem → _src/fem}/geometry/geometry.py +50 -20
- warp/{fem → _src/fem}/geometry/grid_2d.py +14 -23
- warp/{fem → _src/fem}/geometry/grid_3d.py +14 -23
- warp/{fem → _src/fem}/geometry/hexmesh.py +42 -63
- warp/{fem → _src/fem}/geometry/nanogrid.py +256 -247
- warp/{fem → _src/fem}/geometry/partition.py +123 -63
- warp/{fem → _src/fem}/geometry/quadmesh.py +28 -45
- warp/{fem → _src/fem}/geometry/tetmesh.py +42 -63
- warp/{fem → _src/fem}/geometry/trimesh.py +28 -45
- warp/{fem → _src/fem}/integrate.py +166 -158
- warp/_src/fem/linalg.py +385 -0
- warp/_src/fem/operator.py +398 -0
- warp/_src/fem/polynomial.py +231 -0
- warp/{fem → _src/fem}/quadrature/pic_quadrature.py +17 -20
- warp/{fem → _src/fem}/quadrature/quadrature.py +97 -47
- warp/_src/fem/space/__init__.py +248 -0
- warp/{fem → _src/fem}/space/basis_function_space.py +22 -11
- warp/_src/fem/space/basis_space.py +681 -0
- warp/{fem → _src/fem}/space/dof_mapper.py +5 -3
- warp/{fem → _src/fem}/space/function_space.py +16 -13
- warp/{fem → _src/fem}/space/grid_2d_function_space.py +6 -7
- warp/{fem → _src/fem}/space/grid_3d_function_space.py +6 -4
- warp/{fem → _src/fem}/space/hexmesh_function_space.py +6 -10
- warp/{fem → _src/fem}/space/nanogrid_function_space.py +5 -9
- warp/{fem → _src/fem}/space/partition.py +119 -60
- warp/{fem → _src/fem}/space/quadmesh_function_space.py +6 -10
- warp/{fem → _src/fem}/space/restriction.py +68 -33
- warp/_src/fem/space/shape/__init__.py +152 -0
- warp/{fem → _src/fem}/space/shape/cube_shape_function.py +11 -9
- warp/{fem → _src/fem}/space/shape/shape_function.py +10 -9
- warp/{fem → _src/fem}/space/shape/square_shape_function.py +8 -6
- warp/{fem → _src/fem}/space/shape/tet_shape_function.py +5 -3
- warp/{fem → _src/fem}/space/shape/triangle_shape_function.py +5 -3
- warp/{fem → _src/fem}/space/tetmesh_function_space.py +5 -9
- warp/_src/fem/space/topology.py +461 -0
- warp/{fem → _src/fem}/space/trimesh_function_space.py +5 -9
- warp/_src/fem/types.py +114 -0
- warp/_src/fem/utils.py +488 -0
- warp/_src/jax.py +188 -0
- warp/_src/jax_experimental/__init__.py +14 -0
- warp/_src/jax_experimental/custom_call.py +389 -0
- warp/_src/jax_experimental/ffi.py +1286 -0
- warp/_src/jax_experimental/xla_ffi.py +658 -0
- warp/_src/marching_cubes.py +710 -0
- warp/_src/math.py +416 -0
- warp/_src/optim/__init__.py +14 -0
- warp/_src/optim/adam.py +165 -0
- warp/_src/optim/linear.py +1608 -0
- warp/_src/optim/sgd.py +114 -0
- warp/_src/paddle.py +408 -0
- warp/_src/render/__init__.py +14 -0
- warp/_src/render/imgui_manager.py +291 -0
- warp/_src/render/render_opengl.py +3638 -0
- warp/_src/render/render_usd.py +939 -0
- warp/_src/render/utils.py +162 -0
- warp/_src/sparse.py +2718 -0
- warp/_src/tape.py +1208 -0
- warp/{thirdparty → _src/thirdparty}/unittest_parallel.py +9 -2
- warp/_src/torch.py +393 -0
- warp/_src/types.py +5888 -0
- warp/_src/utils.py +1695 -0
- warp/autograd.py +12 -1054
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +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 +3 -3
- 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 +521 -250
- 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 +18 -17
- 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 +578 -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.0.dist-info}/METADATA +46 -99
- warp_lang-1.10.0.dist-info/RECORD +468 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
- warp_lang-1.10.0.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.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.9.1.dist-info → warp_lang-1.10.0.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.9.1.dist-info → warp_lang-1.10.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,190 @@
|
|
|
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
|
+
_wp_module_name_ = "warp.fem.dirichlet"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def normalize_dirichlet_projector(projector_matrix: BsrMatrix, fixed_value: Optional[wp.array] = None):
|
|
27
|
+
"""
|
|
28
|
+
Scale projector so that it becomes idempotent, and apply the same scaling to fixed_value if provided
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
if projector_matrix.ncol != projector_matrix.nrow:
|
|
32
|
+
raise ValueError("Projector must be a square block-diagonal matrix")
|
|
33
|
+
|
|
34
|
+
# Cast blocks to matrix type if necessary
|
|
35
|
+
projector_values = projector_matrix.values
|
|
36
|
+
if not type_is_matrix(projector_values.dtype):
|
|
37
|
+
projector_values = wp.array(
|
|
38
|
+
data=None,
|
|
39
|
+
ptr=projector_values.ptr,
|
|
40
|
+
capacity=projector_values.capacity,
|
|
41
|
+
device=projector_values.device,
|
|
42
|
+
dtype=wp.mat(shape=projector_matrix.block_shape, dtype=projector_matrix.scalar_type),
|
|
43
|
+
shape=projector_values.shape[0],
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
if fixed_value is None:
|
|
47
|
+
wp.launch(
|
|
48
|
+
kernel=_normalize_dirichlet_projector_kernel,
|
|
49
|
+
dim=projector_matrix.nrow,
|
|
50
|
+
device=projector_values.device,
|
|
51
|
+
inputs=[projector_matrix.offsets, projector_matrix.columns, projector_values],
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
else:
|
|
55
|
+
if fixed_value.shape[0] != projector_matrix.nrow:
|
|
56
|
+
raise ValueError("Fixed value array must be of length equal to the number of rows of blocks")
|
|
57
|
+
|
|
58
|
+
if type_size(fixed_value.dtype) == 1:
|
|
59
|
+
# array of scalars, convert to 1d array of vectors
|
|
60
|
+
fixed_value = wp.array(
|
|
61
|
+
data=None,
|
|
62
|
+
ptr=fixed_value.ptr,
|
|
63
|
+
capacity=fixed_value.capacity,
|
|
64
|
+
device=fixed_value.device,
|
|
65
|
+
dtype=wp.vec(length=projector_matrix.block_shape[0], dtype=projector_matrix.scalar_type),
|
|
66
|
+
shape=fixed_value.shape[0],
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
wp.launch(
|
|
70
|
+
kernel=_normalize_dirichlet_projector_and_values_kernel,
|
|
71
|
+
dim=projector_matrix.nrow,
|
|
72
|
+
device=projector_values.device,
|
|
73
|
+
inputs=[projector_matrix.offsets, projector_matrix.columns, projector_values, fixed_value],
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def project_system_rhs(
|
|
78
|
+
system_matrix: BsrMatrix, system_rhs: wp.array, projector_matrix: BsrMatrix, fixed_value: Optional[wp.array] = None
|
|
79
|
+
):
|
|
80
|
+
"""Projects the right-hand-side of a linear system to enforce Dirichlet boundary conditions
|
|
81
|
+
|
|
82
|
+
``rhs = (I - projector) * ( rhs - system * projector * fixed_value) + projector * fixed_value``
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
rhs_tmp = wp.empty_like(system_rhs)
|
|
86
|
+
rhs_tmp.assign(system_rhs)
|
|
87
|
+
|
|
88
|
+
if fixed_value is None:
|
|
89
|
+
system_rhs.zero_()
|
|
90
|
+
else:
|
|
91
|
+
bsr_mv(A=projector_matrix, x=fixed_value, y=system_rhs, alpha=1.0, beta=0.0)
|
|
92
|
+
|
|
93
|
+
bsr_mv(A=system_matrix, x=system_rhs, y=rhs_tmp, alpha=-1.0, beta=1.0)
|
|
94
|
+
|
|
95
|
+
# here rhs_tmp = system_rhs - system_matrix * projector * fixed_value
|
|
96
|
+
# system_rhs = projector * fixed_value
|
|
97
|
+
array_axpy(x=rhs_tmp, y=system_rhs, alpha=1.0, beta=1.0)
|
|
98
|
+
bsr_mv(A=projector_matrix, x=rhs_tmp, y=system_rhs, alpha=-1.0, beta=1.0)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def project_system_matrix(system_matrix: BsrMatrix, projector_matrix: BsrMatrix):
|
|
102
|
+
"""Projects the right-hand-side of a linear system to enforce Dirichlet boundary conditions
|
|
103
|
+
|
|
104
|
+
``system = (I - projector) * system * (I - projector) + projector``
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
complement_system = bsr_copy(system_matrix)
|
|
108
|
+
bsr_mm(x=projector_matrix, y=system_matrix, z=complement_system, alpha=-1.0, beta=1.0)
|
|
109
|
+
|
|
110
|
+
bsr_assign(dest=system_matrix, src=complement_system)
|
|
111
|
+
bsr_axpy(x=projector_matrix, y=system_matrix)
|
|
112
|
+
bsr_mm(x=complement_system, y=projector_matrix, z=system_matrix, alpha=-1.0, beta=1.0)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def project_linear_system(
|
|
116
|
+
system_matrix: BsrMatrix,
|
|
117
|
+
system_rhs: wp.array,
|
|
118
|
+
projector_matrix: BsrMatrix,
|
|
119
|
+
fixed_value: Optional[wp.array] = None,
|
|
120
|
+
normalize_projector=True,
|
|
121
|
+
):
|
|
122
|
+
"""
|
|
123
|
+
Projects both the left-hand-side and right-hand-side of a linear system to enforce Dirichlet boundary conditions
|
|
124
|
+
|
|
125
|
+
If normalize_projector is True, first apply scaling so that the projector_matrix is idempotent
|
|
126
|
+
"""
|
|
127
|
+
if normalize_projector:
|
|
128
|
+
normalize_dirichlet_projector(projector_matrix, fixed_value)
|
|
129
|
+
|
|
130
|
+
project_system_rhs(system_matrix, system_rhs, projector_matrix, fixed_value)
|
|
131
|
+
project_system_matrix(system_matrix, projector_matrix)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@wp.func
|
|
135
|
+
def _normalize_projector_and_value(A: Any, b: Any):
|
|
136
|
+
# Do a modal decomposition of the left and right hand side,
|
|
137
|
+
# Make lhs an orthogonal projection and apply corresponding scaling to right-hand side
|
|
138
|
+
|
|
139
|
+
eps = wp.trace(A) * A.dtype(1.0e-6)
|
|
140
|
+
|
|
141
|
+
diag, ev = symmetric_eigenvalues_qr(A, eps * eps)
|
|
142
|
+
|
|
143
|
+
zero = A.dtype(0)
|
|
144
|
+
A_unitary = type(A)(zero)
|
|
145
|
+
b_normalized = type(b)(zero)
|
|
146
|
+
|
|
147
|
+
for k in range(b.length):
|
|
148
|
+
if diag[k] > eps: # ignore small eigenmodes
|
|
149
|
+
v = ev[k]
|
|
150
|
+
A_unitary += wp.outer(v, v)
|
|
151
|
+
b_normalized += wp.dot(v, b) / diag[k] * v
|
|
152
|
+
|
|
153
|
+
return A_unitary, b_normalized
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@wp.kernel
|
|
157
|
+
def _normalize_dirichlet_projector_and_values_kernel(
|
|
158
|
+
offsets: wp.array(dtype=int),
|
|
159
|
+
columns: wp.array(dtype=int),
|
|
160
|
+
block_values: wp.array(dtype=Any),
|
|
161
|
+
fixed_values: wp.array(dtype=Any),
|
|
162
|
+
):
|
|
163
|
+
row = wp.tid()
|
|
164
|
+
|
|
165
|
+
diag = bsr_block_index(row, row, offsets, columns)
|
|
166
|
+
|
|
167
|
+
if diag != -1:
|
|
168
|
+
P = block_values[diag]
|
|
169
|
+
|
|
170
|
+
P_norm, v_norm = _normalize_projector_and_value(P, fixed_values[row])
|
|
171
|
+
|
|
172
|
+
block_values[diag] = P_norm
|
|
173
|
+
fixed_values[row] = v_norm
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@wp.kernel
|
|
177
|
+
def _normalize_dirichlet_projector_kernel(
|
|
178
|
+
offsets: wp.array(dtype=int),
|
|
179
|
+
columns: wp.array(dtype=int),
|
|
180
|
+
block_values: wp.array(dtype=Any),
|
|
181
|
+
):
|
|
182
|
+
row = wp.tid()
|
|
183
|
+
|
|
184
|
+
diag = bsr_block_index(row, row, offsets, columns)
|
|
185
|
+
|
|
186
|
+
if diag != -1:
|
|
187
|
+
P = block_values[diag]
|
|
188
|
+
|
|
189
|
+
P_norm, v_norm = _normalize_projector_and_value(P, type(P[0])())
|
|
190
|
+
block_values[diag] = P_norm
|
warp/{fem → _src/fem}/domain.py
RENAMED
|
@@ -17,18 +17,20 @@ 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
|
+
|
|
33
|
+
_wp_module_name_ = "warp.fem.domain"
|
|
32
34
|
|
|
33
35
|
GeometryOrPartition = Union[Geometry, GeometryPartition]
|
|
34
36
|
|
|
@@ -44,7 +46,7 @@ class GeometryDomain:
|
|
|
44
46
|
|
|
45
47
|
self.geometry = self.geometry_partition.geometry
|
|
46
48
|
|
|
47
|
-
@
|
|
49
|
+
@cached_property
|
|
48
50
|
def name(self) -> str:
|
|
49
51
|
return f"{self.geometry_partition.name}_{self.__class__.__name__}"
|
|
50
52
|
|
|
@@ -73,18 +75,28 @@ class GeometryDomain:
|
|
|
73
75
|
return self.geometry.cell_count()
|
|
74
76
|
|
|
75
77
|
def reference_element(self) -> Element:
|
|
76
|
-
"""
|
|
78
|
+
"""Type of reference element"""
|
|
77
79
|
raise NotImplementedError
|
|
78
80
|
|
|
79
|
-
def element_index_arg_value(self, device:
|
|
81
|
+
def element_index_arg_value(self, device: Devicelike) -> StructInstance:
|
|
80
82
|
"""Value of the argument to be passed to device functions"""
|
|
81
|
-
|
|
83
|
+
args = self.ElementIndexArg()
|
|
84
|
+
self.fill_element_index_arg(args, device)
|
|
85
|
+
return args
|
|
86
|
+
|
|
87
|
+
def fill_element_index_arg(self, arg: "GeometryDomain.ElementIndexArg", device: Devicelike):
|
|
88
|
+
arg.assign(self.element_index_arg_value(device))
|
|
82
89
|
|
|
83
|
-
def element_arg_value(self, device:
|
|
90
|
+
def element_arg_value(self, device: Devicelike) -> StructInstance:
|
|
84
91
|
"""Value of the argument to be passed to device functions"""
|
|
85
|
-
|
|
92
|
+
args = self.ElementArg()
|
|
93
|
+
self.fill_element_arg(args, device)
|
|
94
|
+
return args
|
|
95
|
+
|
|
96
|
+
def fill_element_arg(self, arg: "GeometryDomain.ElementArg", device: Devicelike):
|
|
97
|
+
arg.assign(self.element_arg_value(device))
|
|
86
98
|
|
|
87
|
-
ElementIndexArg:
|
|
99
|
+
ElementIndexArg: Struct
|
|
88
100
|
"""Structure containing arguments to be passed to device functions computing element indices"""
|
|
89
101
|
|
|
90
102
|
element_index: wp.Function
|
|
@@ -93,7 +105,7 @@ class GeometryDomain:
|
|
|
93
105
|
element_partition_index: wp.Function
|
|
94
106
|
"""Device function for retrieving linearized index in the domain's partition from an ElementIndex"""
|
|
95
107
|
|
|
96
|
-
ElementArg:
|
|
108
|
+
ElementArg: Struct
|
|
97
109
|
"""Structure containing arguments to be passed to device functions computing element geometry"""
|
|
98
110
|
|
|
99
111
|
element_measure: wp.Function
|
|
@@ -164,13 +176,13 @@ class Cells(GeometryDomain):
|
|
|
164
176
|
return self.geometry.cell_count()
|
|
165
177
|
|
|
166
178
|
@property
|
|
167
|
-
def ElementIndexArg(self) ->
|
|
179
|
+
def ElementIndexArg(self) -> Struct:
|
|
168
180
|
return self.geometry_partition.CellArg
|
|
169
181
|
|
|
170
|
-
def element_index_arg_value(self, device:
|
|
182
|
+
def element_index_arg_value(self, device: Devicelike) -> StructInstance:
|
|
171
183
|
return self.geometry_partition.cell_arg_value(device)
|
|
172
184
|
|
|
173
|
-
def fill_element_index_arg(self, arg: ElementIndexArg, device:
|
|
185
|
+
def fill_element_index_arg(self, arg: ElementIndexArg, device: Devicelike):
|
|
174
186
|
self.geometry_partition.fill_cell_arg(arg, device)
|
|
175
187
|
|
|
176
188
|
@property
|
|
@@ -181,14 +193,14 @@ class Cells(GeometryDomain):
|
|
|
181
193
|
def element_partition_index(self) -> wp.Function:
|
|
182
194
|
return self.geometry_partition.partition_cell_index
|
|
183
195
|
|
|
184
|
-
def element_arg_value(self, device:
|
|
196
|
+
def element_arg_value(self, device: Devicelike) -> StructInstance:
|
|
185
197
|
return self.geometry.cell_arg_value(device)
|
|
186
198
|
|
|
187
|
-
def fill_element_arg(self, arg: "ElementArg", device:
|
|
199
|
+
def fill_element_arg(self, arg: "ElementArg", device: Devicelike):
|
|
188
200
|
self.geometry.fill_cell_arg(arg, device)
|
|
189
201
|
|
|
190
202
|
@property
|
|
191
|
-
def ElementArg(self) ->
|
|
203
|
+
def ElementArg(self) -> Struct:
|
|
192
204
|
return self.geometry.CellArg
|
|
193
205
|
|
|
194
206
|
@property
|
|
@@ -223,7 +235,7 @@ class Cells(GeometryDomain):
|
|
|
223
235
|
def element_lookup(self) -> wp.Function:
|
|
224
236
|
return self.geometry.cell_lookup
|
|
225
237
|
|
|
226
|
-
@
|
|
238
|
+
@cached_property
|
|
227
239
|
def element_partition_lookup(self) -> wp.Function:
|
|
228
240
|
pos_type = cache.cached_vec_type(self.geometry.dimension, dtype=float)
|
|
229
241
|
|
|
@@ -295,13 +307,13 @@ class Sides(GeometryDomain):
|
|
|
295
307
|
return self.geometry.side_count()
|
|
296
308
|
|
|
297
309
|
@property
|
|
298
|
-
def ElementIndexArg(self) ->
|
|
310
|
+
def ElementIndexArg(self) -> Struct:
|
|
299
311
|
return self.geometry_partition.SideArg
|
|
300
312
|
|
|
301
|
-
def element_index_arg_value(self, device:
|
|
313
|
+
def element_index_arg_value(self, device: Devicelike) -> StructInstance:
|
|
302
314
|
return self.geometry_partition.side_arg_value(device)
|
|
303
315
|
|
|
304
|
-
def fill_element_index_arg(self, arg: "ElementIndexArg", device:
|
|
316
|
+
def fill_element_index_arg(self, arg: "ElementIndexArg", device: Devicelike):
|
|
305
317
|
self.geometry_partition.fill_side_arg(arg, device)
|
|
306
318
|
|
|
307
319
|
@property
|
|
@@ -309,13 +321,13 @@ class Sides(GeometryDomain):
|
|
|
309
321
|
return self.geometry_partition.side_index
|
|
310
322
|
|
|
311
323
|
@property
|
|
312
|
-
def ElementArg(self) ->
|
|
324
|
+
def ElementArg(self) -> Struct:
|
|
313
325
|
return self.geometry.SideArg
|
|
314
326
|
|
|
315
|
-
def element_arg_value(self, device:
|
|
327
|
+
def element_arg_value(self, device: Devicelike) -> StructInstance:
|
|
316
328
|
return self.geometry.side_arg_value(device)
|
|
317
329
|
|
|
318
|
-
def fill_element_arg(self, arg: "ElementArg", device:
|
|
330
|
+
def fill_element_arg(self, arg: "ElementArg", device: Devicelike):
|
|
319
331
|
self.geometry.fill_side_arg(arg, device)
|
|
320
332
|
|
|
321
333
|
@property
|
|
@@ -498,12 +510,12 @@ class Subdomain(GeometryDomain):
|
|
|
498
510
|
return ElementIndexArg
|
|
499
511
|
|
|
500
512
|
@cache.cached_arg_value
|
|
501
|
-
def element_index_arg_value(self, device:
|
|
513
|
+
def element_index_arg_value(self, device: Devicelike):
|
|
502
514
|
arg = self.ElementIndexArg()
|
|
503
515
|
self.fill_element_index_arg(arg, device)
|
|
504
516
|
return arg
|
|
505
517
|
|
|
506
|
-
def fill_element_index_arg(self, arg: "GeometryDomain.ElementIndexArg", device:
|
|
518
|
+
def fill_element_index_arg(self, arg: "GeometryDomain.ElementIndexArg", device: Devicelike):
|
|
507
519
|
self._domain.fill_element_index_arg(arg.domain_arg, device)
|
|
508
520
|
arg.element_indices = self._element_indices.to(device)
|
|
509
521
|
|
|
@@ -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)
|