warp-lang 1.9.0__py3-none-win_amd64.whl → 1.10.0rc2__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 +2220 -313
- 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} +1497 -226
- 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.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +8 -588
- warp/build_dll.py +6 -471
- warp/codegen.py +6 -4246
- warp/constants.py +6 -39
- warp/context.py +12 -7851
- 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 +3 -2
- 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 -342
- warp/jax_experimental/ffi.py +17 -853
- warp/jax_experimental/xla_ffi.py +5 -596
- warp/marching_cubes.py +5 -689
- warp/math.py +16 -393
- warp/native/array.h +385 -37
- warp/native/builtin.h +316 -39
- 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/sort.cu +22 -13
- warp/native/sort.h +2 -0
- warp/native/sparse.cu +7 -3
- warp/native/spatial.h +12 -0
- warp/native/tile.h +837 -70
- 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 -53
- 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 +60 -32
- warp/native/warp.cu +313 -201
- warp/native/warp.h +14 -11
- 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 -3616
- warp/render/render_usd.py +6 -918
- 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_hash_grid.py +38 -0
- 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 +1382 -79
- 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 +529 -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 +34 -15
- 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 +60 -14
- 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 +49 -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_tuple.py +96 -0
- warp/tests/test_types.py +82 -9
- 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 +239 -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 -5750
- warp/utils.py +10 -1659
- {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/METADATA +47 -103
- 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.0.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.0.dist-info → warp_lang-1.10.0rc2.dist-info}/WHEEL +0 -0
- {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.9.0.dist-info → warp_lang-1.10.0rc2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,459 @@
|
|
|
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 functools import cached_property
|
|
17
|
+
from typing import ClassVar, Optional, Tuple, Type
|
|
18
|
+
|
|
19
|
+
import warp as wp
|
|
20
|
+
from warp._src.fem import cache
|
|
21
|
+
from warp._src.fem.geometry import DeformedGeometry, Geometry
|
|
22
|
+
from warp._src.fem.types import NULL_ELEMENT_INDEX, NULL_NODE_INDEX, ElementIndex
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SpaceTopology:
|
|
26
|
+
"""
|
|
27
|
+
Interface class for defining the topology of a function space.
|
|
28
|
+
|
|
29
|
+
The topology only considers the indices of the nodes in each element, and as such,
|
|
30
|
+
the connectivity pattern of the function space.
|
|
31
|
+
It does not specify the actual location of the nodes within the elements, or the valuation function.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
dimension: int
|
|
35
|
+
"""Embedding dimension of the function space"""
|
|
36
|
+
|
|
37
|
+
MAX_NODES_PER_ELEMENT: int
|
|
38
|
+
"""maximum number of interpolation nodes per element of the geometry.
|
|
39
|
+
|
|
40
|
+
.. note:: This will change to be defined per-element in future versions
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
_dynamic_attribute_constructors: ClassVar = {
|
|
44
|
+
"element_node_count": lambda obj: obj._make_constant_element_node_count(),
|
|
45
|
+
"element_node_sign": lambda obj: obj._make_constant_element_node_sign(),
|
|
46
|
+
"side_neighbor_node_counts": lambda obj: obj._make_constant_side_neighbor_node_counts(),
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@wp.struct
|
|
50
|
+
class TopologyArg:
|
|
51
|
+
"""Structure containing arguments to be passed to device functions"""
|
|
52
|
+
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
def __init__(self, geometry: Geometry, max_nodes_per_element: int):
|
|
56
|
+
self._geometry = geometry
|
|
57
|
+
self.dimension = geometry.dimension
|
|
58
|
+
self.MAX_NODES_PER_ELEMENT = wp.constant(max_nodes_per_element)
|
|
59
|
+
self.ElementArg = geometry.CellArg
|
|
60
|
+
|
|
61
|
+
cache.setup_dynamic_attributes(self, cls=__class__)
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def geometry(self) -> Geometry:
|
|
65
|
+
"""Underlying geometry"""
|
|
66
|
+
return self._geometry
|
|
67
|
+
|
|
68
|
+
def node_count(self) -> int:
|
|
69
|
+
"""Number of nodes in the interpolation basis"""
|
|
70
|
+
raise NotImplementedError
|
|
71
|
+
|
|
72
|
+
@cache.cached_arg_value
|
|
73
|
+
def topo_arg_value(self, device) -> "TopologyArg":
|
|
74
|
+
"""Value of the topology argument structure to be passed to device functions"""
|
|
75
|
+
arg = self.TopologyArg()
|
|
76
|
+
self.fill_topo_arg(arg, device)
|
|
77
|
+
return arg
|
|
78
|
+
|
|
79
|
+
def fill_topo_arg(self, arg, device):
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
@cached_property
|
|
83
|
+
def name(self):
|
|
84
|
+
return f"{self.__class__.__name__}_{self.MAX_NODES_PER_ELEMENT}"
|
|
85
|
+
|
|
86
|
+
def __str__(self):
|
|
87
|
+
return self.name
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
def element_node_count(
|
|
91
|
+
geo_arg: "ElementArg", # noqa: F821
|
|
92
|
+
topo_arg: "TopologyArg",
|
|
93
|
+
element_index: ElementIndex,
|
|
94
|
+
) -> int:
|
|
95
|
+
"""Returns the actual number of nodes in a given element"""
|
|
96
|
+
raise NotImplementedError
|
|
97
|
+
|
|
98
|
+
@staticmethod
|
|
99
|
+
def element_node_index(
|
|
100
|
+
geo_arg: "ElementArg", # noqa: F821
|
|
101
|
+
topo_arg: "TopologyArg",
|
|
102
|
+
element_index: ElementIndex,
|
|
103
|
+
node_index_in_elt: int,
|
|
104
|
+
) -> int:
|
|
105
|
+
"""Global node index for a given node in a given element"""
|
|
106
|
+
raise NotImplementedError
|
|
107
|
+
|
|
108
|
+
@staticmethod
|
|
109
|
+
def side_neighbor_node_counts(
|
|
110
|
+
side_arg: "ElementArg", # noqa: F821
|
|
111
|
+
side_index: ElementIndex,
|
|
112
|
+
) -> Tuple[int, int]:
|
|
113
|
+
"""Returns the number of nodes for both the inner and outer cells of a given sides"""
|
|
114
|
+
raise NotImplementedError
|
|
115
|
+
|
|
116
|
+
def element_node_indices(self, out: Optional[wp.array] = None) -> wp.array:
|
|
117
|
+
"""Returns a temporary array containing the global index for each node of each element"""
|
|
118
|
+
|
|
119
|
+
MAX_NODES_PER_ELEMENT = self.MAX_NODES_PER_ELEMENT
|
|
120
|
+
|
|
121
|
+
@cache.dynamic_kernel(suffix=self.name)
|
|
122
|
+
def fill_element_node_indices(
|
|
123
|
+
geo_cell_arg: self.geometry.CellArg,
|
|
124
|
+
topo_arg: self.TopologyArg,
|
|
125
|
+
element_node_indices: wp.array2d(dtype=int),
|
|
126
|
+
):
|
|
127
|
+
element_index = wp.tid()
|
|
128
|
+
element_node_count = self.element_node_count(geo_cell_arg, topo_arg, element_index)
|
|
129
|
+
for n in range(element_node_count):
|
|
130
|
+
element_node_indices[element_index, n] = self.element_node_index(
|
|
131
|
+
geo_cell_arg, topo_arg, element_index, n
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
shape = (self.geometry.cell_count(), MAX_NODES_PER_ELEMENT)
|
|
135
|
+
if out is None:
|
|
136
|
+
element_node_indices = wp.empty(
|
|
137
|
+
shape=shape,
|
|
138
|
+
dtype=int,
|
|
139
|
+
)
|
|
140
|
+
else:
|
|
141
|
+
if out.shape != shape or out.dtype != wp.int32:
|
|
142
|
+
raise ValueError(f"Out element node indices array must have shape {shape} and data type 'int32'")
|
|
143
|
+
element_node_indices = out
|
|
144
|
+
|
|
145
|
+
wp.launch(
|
|
146
|
+
dim=element_node_indices.shape[0],
|
|
147
|
+
kernel=fill_element_node_indices,
|
|
148
|
+
inputs=[
|
|
149
|
+
self.geometry.cell_arg_value(device=element_node_indices.device),
|
|
150
|
+
self.topo_arg_value(device=element_node_indices.device),
|
|
151
|
+
element_node_indices,
|
|
152
|
+
],
|
|
153
|
+
device=element_node_indices.device,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
return element_node_indices
|
|
157
|
+
|
|
158
|
+
# Interface generating trace space topology
|
|
159
|
+
|
|
160
|
+
def trace(self) -> "TraceSpaceTopology":
|
|
161
|
+
"""Trace of the function space over lower-dimensional elements of the geometry"""
|
|
162
|
+
|
|
163
|
+
return TraceSpaceTopology(self)
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def is_trace(self) -> bool:
|
|
167
|
+
"""Whether this topology is defined on the trace of the geometry"""
|
|
168
|
+
return self.dimension == self.geometry.dimension - 1
|
|
169
|
+
|
|
170
|
+
def full_space_topology(self) -> "SpaceTopology":
|
|
171
|
+
"""Returns the full space topology from which this topology is derived"""
|
|
172
|
+
return self
|
|
173
|
+
|
|
174
|
+
def __eq__(self, other: "SpaceTopology") -> bool:
|
|
175
|
+
"""Checks whether two topologies are compatible"""
|
|
176
|
+
return self.geometry == other.geometry and self.name == other.name
|
|
177
|
+
|
|
178
|
+
def is_derived_from(self, other: "SpaceTopology") -> bool:
|
|
179
|
+
"""Checks whether two topologies are equal, or `self` is the trace of `other`"""
|
|
180
|
+
if self.dimension == other.dimension:
|
|
181
|
+
return self == other
|
|
182
|
+
if self.dimension + 1 == other.dimension:
|
|
183
|
+
return self.full_space_topology() == other
|
|
184
|
+
return False
|
|
185
|
+
|
|
186
|
+
def _make_constant_element_node_count(self):
|
|
187
|
+
NODES_PER_ELEMENT = wp.constant(self.MAX_NODES_PER_ELEMENT)
|
|
188
|
+
|
|
189
|
+
@cache.dynamic_func(suffix=self.name)
|
|
190
|
+
def constant_element_node_count(
|
|
191
|
+
geo_arg: self.geometry.CellArg,
|
|
192
|
+
topo_arg: self.TopologyArg,
|
|
193
|
+
element_index: ElementIndex,
|
|
194
|
+
):
|
|
195
|
+
return NODES_PER_ELEMENT
|
|
196
|
+
|
|
197
|
+
return constant_element_node_count
|
|
198
|
+
|
|
199
|
+
def _make_constant_side_neighbor_node_counts(self):
|
|
200
|
+
NODES_PER_ELEMENT = wp.constant(self.MAX_NODES_PER_ELEMENT)
|
|
201
|
+
|
|
202
|
+
@cache.dynamic_func(suffix=self.name)
|
|
203
|
+
def constant_side_neighbor_node_counts(
|
|
204
|
+
side_arg: self.geometry.SideArg,
|
|
205
|
+
element_index: ElementIndex,
|
|
206
|
+
):
|
|
207
|
+
return NODES_PER_ELEMENT, NODES_PER_ELEMENT
|
|
208
|
+
|
|
209
|
+
return constant_side_neighbor_node_counts
|
|
210
|
+
|
|
211
|
+
def _make_constant_element_node_sign(self):
|
|
212
|
+
@cache.dynamic_func(suffix=self.name)
|
|
213
|
+
def constant_element_node_sign(
|
|
214
|
+
geo_arg: self.geometry.CellArg,
|
|
215
|
+
topo_arg: self.TopologyArg,
|
|
216
|
+
element_index: ElementIndex,
|
|
217
|
+
node_index_in_element: int,
|
|
218
|
+
):
|
|
219
|
+
return 1.0
|
|
220
|
+
|
|
221
|
+
return constant_element_node_sign
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class TraceSpaceTopology(SpaceTopology):
|
|
225
|
+
"""Auto-generated trace topology defining the node indices associated to the geometry sides"""
|
|
226
|
+
|
|
227
|
+
_dynamic_attribute_constructors: ClassVar = {
|
|
228
|
+
"inner_cell_index": lambda obj: obj._make_inner_cell_index(),
|
|
229
|
+
"outer_cell_index": lambda obj: obj._make_outer_cell_index(),
|
|
230
|
+
"neighbor_cell_index": lambda obj: obj._make_neighbor_cell_index(),
|
|
231
|
+
"element_node_index": lambda obj: obj._make_element_node_index(),
|
|
232
|
+
"element_node_count": lambda obj: obj._make_element_node_count(),
|
|
233
|
+
"element_node_sign": lambda obj: obj._make_element_node_sign(),
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
def __init__(self, topo: SpaceTopology):
|
|
237
|
+
self._topo = topo
|
|
238
|
+
|
|
239
|
+
super().__init__(topo.geometry, 2 * topo.MAX_NODES_PER_ELEMENT)
|
|
240
|
+
|
|
241
|
+
self.dimension = topo.dimension - 1
|
|
242
|
+
self.ElementArg = topo.geometry.SideArg
|
|
243
|
+
|
|
244
|
+
self.TopologyArg = topo.TopologyArg
|
|
245
|
+
self.topo_arg_value = topo.topo_arg_value
|
|
246
|
+
self.fill_topo_arg = topo.fill_topo_arg
|
|
247
|
+
|
|
248
|
+
self.side_neighbor_node_counts = None
|
|
249
|
+
cache.setup_dynamic_attributes(self, cls=__class__)
|
|
250
|
+
|
|
251
|
+
def node_count(self) -> int:
|
|
252
|
+
return self._topo.node_count()
|
|
253
|
+
|
|
254
|
+
@cached_property
|
|
255
|
+
def name(self):
|
|
256
|
+
return f"{self._topo.name}_Trace"
|
|
257
|
+
|
|
258
|
+
def _make_inner_cell_index(self):
|
|
259
|
+
@cache.dynamic_func(suffix=self.name)
|
|
260
|
+
def inner_cell_index(side_arg: self.geometry.SideArg, element_index: ElementIndex, node_index_in_elt: int):
|
|
261
|
+
inner_count, outer_count = self._topo.side_neighbor_node_counts(side_arg, element_index)
|
|
262
|
+
if node_index_in_elt >= inner_count:
|
|
263
|
+
return NULL_ELEMENT_INDEX, NULL_NODE_INDEX
|
|
264
|
+
return self.geometry.side_inner_cell_index(side_arg, element_index), node_index_in_elt
|
|
265
|
+
|
|
266
|
+
return inner_cell_index
|
|
267
|
+
|
|
268
|
+
def _make_outer_cell_index(self):
|
|
269
|
+
@cache.dynamic_func(suffix=self.name)
|
|
270
|
+
def outer_cell_index(side_arg: self.geometry.SideArg, element_index: ElementIndex, node_index_in_elt: int):
|
|
271
|
+
inner_count, outer_count = self._topo.side_neighbor_node_counts(side_arg, element_index)
|
|
272
|
+
if node_index_in_elt < inner_count:
|
|
273
|
+
return NULL_ELEMENT_INDEX, NULL_NODE_INDEX
|
|
274
|
+
return self.geometry.side_outer_cell_index(side_arg, element_index), node_index_in_elt - inner_count
|
|
275
|
+
|
|
276
|
+
return outer_cell_index
|
|
277
|
+
|
|
278
|
+
def _make_neighbor_cell_index(self):
|
|
279
|
+
@cache.dynamic_func(suffix=self.name)
|
|
280
|
+
def neighbor_cell_index(side_arg: self.geometry.SideArg, element_index: ElementIndex, node_index_in_elt: int):
|
|
281
|
+
inner_count, outer_count = self._topo.side_neighbor_node_counts(side_arg, element_index)
|
|
282
|
+
if node_index_in_elt < inner_count:
|
|
283
|
+
return self.geometry.side_inner_cell_index(side_arg, element_index), node_index_in_elt
|
|
284
|
+
|
|
285
|
+
return (
|
|
286
|
+
self.geometry.side_outer_cell_index(side_arg, element_index),
|
|
287
|
+
node_index_in_elt - inner_count,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
return neighbor_cell_index
|
|
291
|
+
|
|
292
|
+
def _make_element_node_count(self):
|
|
293
|
+
@cache.dynamic_func(suffix=self.name)
|
|
294
|
+
def trace_element_node_count(
|
|
295
|
+
geo_side_arg: self.geometry.SideArg,
|
|
296
|
+
topo_arg: self._topo.TopologyArg,
|
|
297
|
+
element_index: ElementIndex,
|
|
298
|
+
):
|
|
299
|
+
inner_count, outer_count = self._topo.side_neighbor_node_counts(geo_side_arg, element_index)
|
|
300
|
+
return inner_count + outer_count
|
|
301
|
+
|
|
302
|
+
return trace_element_node_count
|
|
303
|
+
|
|
304
|
+
def _make_element_node_index(self):
|
|
305
|
+
@cache.dynamic_func(suffix=self.name)
|
|
306
|
+
def trace_element_node_index(
|
|
307
|
+
geo_side_arg: self.geometry.SideArg,
|
|
308
|
+
topo_arg: self._topo.TopologyArg,
|
|
309
|
+
element_index: ElementIndex,
|
|
310
|
+
node_index_in_elt: int,
|
|
311
|
+
):
|
|
312
|
+
cell_index, index_in_cell = self.neighbor_cell_index(geo_side_arg, element_index, node_index_in_elt)
|
|
313
|
+
|
|
314
|
+
geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
|
|
315
|
+
return self._topo.element_node_index(geo_cell_arg, topo_arg, cell_index, index_in_cell)
|
|
316
|
+
|
|
317
|
+
return trace_element_node_index
|
|
318
|
+
|
|
319
|
+
def _make_element_node_sign(self):
|
|
320
|
+
@cache.dynamic_func(suffix=self.name)
|
|
321
|
+
def trace_element_node_sign(
|
|
322
|
+
geo_side_arg: self.geometry.SideArg,
|
|
323
|
+
topo_arg: self._topo.TopologyArg,
|
|
324
|
+
element_index: ElementIndex,
|
|
325
|
+
node_index_in_elt: int,
|
|
326
|
+
):
|
|
327
|
+
cell_index, index_in_cell = self.neighbor_cell_index(geo_side_arg, element_index, node_index_in_elt)
|
|
328
|
+
|
|
329
|
+
geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
|
|
330
|
+
return self._topo.element_node_sign(geo_cell_arg, topo_arg, cell_index, index_in_cell)
|
|
331
|
+
|
|
332
|
+
return trace_element_node_sign
|
|
333
|
+
|
|
334
|
+
def full_space_topology(self) -> SpaceTopology:
|
|
335
|
+
"""Returns the full space topology from which this topology is derived"""
|
|
336
|
+
return self._topo
|
|
337
|
+
|
|
338
|
+
def __eq__(self, other: "TraceSpaceTopology") -> bool:
|
|
339
|
+
return self._topo == other._topo
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
class RegularDiscontinuousSpaceTopologyMixin:
|
|
343
|
+
"""Helper for defining discontinuous topologies (per-element nodes)"""
|
|
344
|
+
|
|
345
|
+
def __init__(self, *args, **kwargs):
|
|
346
|
+
super().__init__(*args, **kwargs)
|
|
347
|
+
self.element_node_index = self._make_element_node_index()
|
|
348
|
+
|
|
349
|
+
def node_count(self):
|
|
350
|
+
return self.geometry.cell_count() * self.MAX_NODES_PER_ELEMENT
|
|
351
|
+
|
|
352
|
+
@cached_property
|
|
353
|
+
def name(self):
|
|
354
|
+
return f"{self.geometry.name}_D{self.MAX_NODES_PER_ELEMENT}"
|
|
355
|
+
|
|
356
|
+
def _make_element_node_index(self):
|
|
357
|
+
NODES_PER_ELEMENT = self.MAX_NODES_PER_ELEMENT
|
|
358
|
+
|
|
359
|
+
@cache.dynamic_func(suffix=self.name)
|
|
360
|
+
def element_node_index(
|
|
361
|
+
elt_arg: self.geometry.CellArg,
|
|
362
|
+
topo_arg: self.TopologyArg,
|
|
363
|
+
element_index: ElementIndex,
|
|
364
|
+
node_index_in_elt: int,
|
|
365
|
+
):
|
|
366
|
+
return NODES_PER_ELEMENT * element_index + node_index_in_elt
|
|
367
|
+
|
|
368
|
+
return element_node_index
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
class RegularDiscontinuousSpaceTopology(RegularDiscontinuousSpaceTopologyMixin, SpaceTopology):
|
|
372
|
+
"""Topology for generic discontinuous spaces"""
|
|
373
|
+
|
|
374
|
+
pass
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
class DeformedGeometrySpaceTopology(SpaceTopology):
|
|
378
|
+
_dynamic_attribute_constructors: ClassVar = {
|
|
379
|
+
"element_node_index": lambda obj: obj._make_element_node_index(),
|
|
380
|
+
"element_node_count": lambda obj: obj._make_element_node_count(),
|
|
381
|
+
"element_node_sign": lambda obj: obj._make_element_node_sign(),
|
|
382
|
+
"side_neighbor_node_counts": lambda obj: obj._make_side_neighbor_node_counts(),
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
def __init__(self, geometry: DeformedGeometry, base_topology: SpaceTopology):
|
|
386
|
+
self.base = base_topology
|
|
387
|
+
super().__init__(geometry, base_topology.MAX_NODES_PER_ELEMENT)
|
|
388
|
+
|
|
389
|
+
self.node_count = self.base.node_count
|
|
390
|
+
self.topo_arg_value = self.base.topo_arg_value
|
|
391
|
+
self.fill_topo_arg = self.base.fill_topo_arg
|
|
392
|
+
self.TopologyArg = self.base.TopologyArg
|
|
393
|
+
|
|
394
|
+
cache.setup_dynamic_attributes(self, cls=__class__)
|
|
395
|
+
|
|
396
|
+
@cached_property
|
|
397
|
+
def name(self):
|
|
398
|
+
return f"{self.base.name}_{self.geometry.field.name}"
|
|
399
|
+
|
|
400
|
+
def _make_element_node_index(self):
|
|
401
|
+
@cache.dynamic_func(suffix=self.name)
|
|
402
|
+
def element_node_index(
|
|
403
|
+
elt_arg: self.geometry.CellArg,
|
|
404
|
+
topo_arg: self.TopologyArg,
|
|
405
|
+
element_index: ElementIndex,
|
|
406
|
+
node_index_in_elt: int,
|
|
407
|
+
):
|
|
408
|
+
return self.base.element_node_index(elt_arg.base_arg, topo_arg, element_index, node_index_in_elt)
|
|
409
|
+
|
|
410
|
+
return element_node_index
|
|
411
|
+
|
|
412
|
+
def _make_element_node_count(self):
|
|
413
|
+
@cache.dynamic_func(suffix=self.name)
|
|
414
|
+
def element_node_count(
|
|
415
|
+
elt_arg: self.geometry.CellArg,
|
|
416
|
+
topo_arg: self.TopologyArg,
|
|
417
|
+
element_count: ElementIndex,
|
|
418
|
+
):
|
|
419
|
+
return self.base.element_node_count(elt_arg.base_arg, topo_arg, element_count)
|
|
420
|
+
|
|
421
|
+
return element_node_count
|
|
422
|
+
|
|
423
|
+
def _make_side_neighbor_node_counts(self):
|
|
424
|
+
@cache.dynamic_func(suffix=self.name)
|
|
425
|
+
def side_neighbor_node_counts(
|
|
426
|
+
side_arg: self.geometry.SideArg,
|
|
427
|
+
element_index: ElementIndex,
|
|
428
|
+
):
|
|
429
|
+
inner_count, outer_count = self.base.side_neighbor_node_counts(side_arg.base_arg, element_index)
|
|
430
|
+
return inner_count, outer_count
|
|
431
|
+
|
|
432
|
+
return side_neighbor_node_counts
|
|
433
|
+
|
|
434
|
+
def _make_element_node_sign(self):
|
|
435
|
+
@cache.dynamic_func(suffix=self.name)
|
|
436
|
+
def element_node_sign(
|
|
437
|
+
elt_arg: self.geometry.CellArg,
|
|
438
|
+
topo_arg: self.TopologyArg,
|
|
439
|
+
element_index: ElementIndex,
|
|
440
|
+
node_index_in_elt: int,
|
|
441
|
+
):
|
|
442
|
+
return self.base.element_node_sign(elt_arg.base_arg, topo_arg, element_index, node_index_in_elt)
|
|
443
|
+
|
|
444
|
+
return element_node_sign
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def forward_base_topology(topology_class: Type[SpaceTopology], geometry: Geometry, *args, **kwargs) -> SpaceTopology:
|
|
448
|
+
"""
|
|
449
|
+
If `geometry` is *not* a :class:`DeformedGeometry`, constructs a normal instance of `topology_class` over `geometry`, forwarding additional arguments.
|
|
450
|
+
|
|
451
|
+
If `geometry` *is* a :class:`DeformedGeometry`, constructs an instance of `topology_class` over the base (undeformed) geometry of `geometry`, then warp it
|
|
452
|
+
in a :class:`DeformedGeometrySpaceTopology` forwarding the calls to the underlying topology.
|
|
453
|
+
"""
|
|
454
|
+
|
|
455
|
+
if isinstance(geometry, DeformedGeometry):
|
|
456
|
+
base_topo = topology_class(geometry.base, *args, **kwargs)
|
|
457
|
+
return DeformedGeometrySpaceTopology(geometry, base_topo)
|
|
458
|
+
|
|
459
|
+
return topology_class(geometry, *args, **kwargs)
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
16
|
import warp as wp
|
|
17
|
-
from warp.fem import cache
|
|
18
|
-
from warp.fem.geometry import Trimesh
|
|
19
|
-
from warp.fem.types import ElementIndex
|
|
17
|
+
from warp._src.fem import cache
|
|
18
|
+
from warp._src.fem.geometry import Trimesh
|
|
19
|
+
from warp._src.fem.types import ElementIndex
|
|
20
20
|
|
|
21
21
|
from .shape import TriangleShapeFunction
|
|
22
22
|
from .topology import SpaceTopology, forward_base_topology
|
|
@@ -47,12 +47,6 @@ class TrimeshSpaceTopology(SpaceTopology):
|
|
|
47
47
|
def name(self):
|
|
48
48
|
return f"{self.geometry.name}_{self._shape.name}"
|
|
49
49
|
|
|
50
|
-
@cache.cached_arg_value
|
|
51
|
-
def topo_arg_value(self, device):
|
|
52
|
-
arg = TrimeshTopologyArg()
|
|
53
|
-
self.fill_topo_arg(arg, device)
|
|
54
|
-
return arg
|
|
55
|
-
|
|
56
50
|
def fill_topo_arg(self, arg: TrimeshTopologyArg, device):
|
|
57
51
|
arg.tri_edge_indices = self._tri_edge_indices.to(device)
|
|
58
52
|
arg.edge_vertex_indices = self._mesh.edge_vertex_indices.to(device)
|
warp/_src/fem/types.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
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 enum import IntEnum
|
|
17
|
+
|
|
18
|
+
import warp as wp
|
|
19
|
+
|
|
20
|
+
# kept to avoid breaking existing example code, no longer used internally
|
|
21
|
+
vec2i = wp.vec2i
|
|
22
|
+
vec3i = wp.vec3i
|
|
23
|
+
vec4i = wp.vec4i
|
|
24
|
+
|
|
25
|
+
Coords = wp.vec3
|
|
26
|
+
"""Type representing coordinates within elements"""
|
|
27
|
+
OUTSIDE = -1.0e8
|
|
28
|
+
"""Constant indicating an invalid element coordinate"""
|
|
29
|
+
|
|
30
|
+
ElementIndex = int
|
|
31
|
+
"""Type representing the index of an element in the geometry"""
|
|
32
|
+
QuadraturePointIndex = int
|
|
33
|
+
"""Type representing the index of a quadrature point"""
|
|
34
|
+
NodeIndex = int
|
|
35
|
+
"""Type representing the index of a node in a function space"""
|
|
36
|
+
|
|
37
|
+
NULL_ELEMENT_INDEX: ElementIndex = wp.constant(-1)
|
|
38
|
+
"""Constant indicating an invalid element index"""
|
|
39
|
+
NULL_QP_INDEX: QuadraturePointIndex = wp.constant(-1)
|
|
40
|
+
"""Constant indicating an invalid quadrature point index"""
|
|
41
|
+
NULL_NODE_INDEX: NodeIndex = wp.constant((1 << 31) - 1) # this should be larger than normal nodes when sorting
|
|
42
|
+
"""Constant indicating an invalid node index"""
|
|
43
|
+
|
|
44
|
+
DofIndex = wp.vec2i
|
|
45
|
+
"""Opaque descriptor for indexing degrees of freedom within elements"""
|
|
46
|
+
NULL_DOF_INDEX: DofIndex = wp.constant(DofIndex(-1, -1))
|
|
47
|
+
"""Constant indicating an invalid degree of freedom index"""
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@wp.func
|
|
51
|
+
def get_node_index_in_element(dof_idx: DofIndex):
|
|
52
|
+
return dof_idx[0]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@wp.func
|
|
56
|
+
def get_node_coord(dof_idx: DofIndex):
|
|
57
|
+
return dof_idx[1]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ElementKind(IntEnum):
|
|
61
|
+
"""Type of geometry elements"""
|
|
62
|
+
|
|
63
|
+
CELL = 0
|
|
64
|
+
"""Cells: elements that have the same dimension as the geometry"""
|
|
65
|
+
SIDE = 1
|
|
66
|
+
"""Sides: elements that have one dimension less than the geometry"""
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@wp.struct
|
|
70
|
+
class NodeElementIndex:
|
|
71
|
+
domain_element_index: ElementIndex
|
|
72
|
+
node_index_in_element: int
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@wp.struct
|
|
76
|
+
class Sample:
|
|
77
|
+
"""Per-sample point context for evaluating fields and related operators in integrands"""
|
|
78
|
+
|
|
79
|
+
element_index: ElementIndex
|
|
80
|
+
"""Index of the geometry element the sample point is in"""
|
|
81
|
+
element_coords: Coords
|
|
82
|
+
"""Coordinates of the sample point inside the element"""
|
|
83
|
+
qp_index: QuadraturePointIndex = NULL_QP_INDEX
|
|
84
|
+
"""If the sample corresponds to a quadrature point, its global index"""
|
|
85
|
+
qp_weight: float = 0.0
|
|
86
|
+
"""If the sample corresponds to a quadrature point, its weight"""
|
|
87
|
+
test_dof: DofIndex = NULL_DOF_INDEX
|
|
88
|
+
"""For linear of bilinear form assembly, index of the test degree-of-freedom currently being considered"""
|
|
89
|
+
trial_dof: DofIndex = NULL_DOF_INDEX
|
|
90
|
+
"""For bilinear form assembly, index of the trial degree-of-freedom currently being considered"""
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@wp.func
|
|
94
|
+
def make_free_sample(element_index: ElementIndex, element_coords: Coords):
|
|
95
|
+
"""Returns a :class:`Sample` that is not associated to any quadrature point or dof"""
|
|
96
|
+
return Sample(element_index, element_coords, NULL_QP_INDEX, 0.0, NULL_DOF_INDEX, NULL_DOF_INDEX)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class Field:
|
|
100
|
+
"""
|
|
101
|
+
Tag for field-like integrand arguments
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
call_operator: "warp.fem.operator.Operator" = None # noqa: F821 Set in operator.py
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class Domain:
|
|
108
|
+
"""
|
|
109
|
+
Tag for domain-like integrand arguments
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
call_operator: "warp.fem.operator.Operator" = None # noqa: F821 Set in operator.py
|