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
warp/fem/space/shape/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c)
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -13,133 +13,56 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
from enum import Enum
|
|
18
|
-
from typing import Optional
|
|
16
|
+
# isort: skip_file
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
# Keeping those imports non-deprecated for now,
|
|
19
|
+
# Will be deprecated after unification of the shape functions API (1.11+)
|
|
22
20
|
|
|
23
|
-
from .
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
CubeSerendipityShapeFunctions,
|
|
28
|
-
CubeShapeFunction,
|
|
29
|
-
CubeTripolynomialShapeFunctions,
|
|
21
|
+
from warp._src.fem.space.shape import CubeShapeFunction as CubeShapeFunction
|
|
22
|
+
from warp._src.fem.space.shape import CubeNedelecFirstKindShapeFunctions as CubeNedelecFirstKindShapeFunctions
|
|
23
|
+
from warp._src.fem.space.shape import (
|
|
24
|
+
CubeNonConformingPolynomialShapeFunctions as CubeNonConformingPolynomialShapeFunctions,
|
|
30
25
|
)
|
|
31
|
-
from .
|
|
32
|
-
from .
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
from warp._src.fem.space.shape import CubeRaviartThomasShapeFunctions as CubeRaviartThomasShapeFunctions
|
|
27
|
+
from warp._src.fem.space.shape import CubeSerendipityShapeFunctions as CubeSerendipityShapeFunctions
|
|
28
|
+
from warp._src.fem.space.shape import CubeTripolynomialShapeFunctions as CubeTripolynomialShapeFunctions
|
|
29
|
+
|
|
30
|
+
from warp._src.fem.space.shape import SquareShapeFunction as SquareShapeFunction
|
|
31
|
+
from warp._src.fem.space.shape import SquareBipolynomialShapeFunctions as SquareBipolynomialShapeFunctions
|
|
32
|
+
from warp._src.fem.space.shape import SquareNedelecFirstKindShapeFunctions as SquareNedelecFirstKindShapeFunctions
|
|
33
|
+
from warp._src.fem.space.shape import (
|
|
34
|
+
SquareNonConformingPolynomialShapeFunctions as SquareNonConformingPolynomialShapeFunctions,
|
|
39
35
|
)
|
|
40
|
-
from .
|
|
41
|
-
|
|
42
|
-
TetrahedronNonConformingPolynomialShapeFunctions,
|
|
43
|
-
TetrahedronPolynomialShapeFunctions,
|
|
44
|
-
TetrahedronRaviartThomasShapeFunctions,
|
|
45
|
-
TetrahedronShapeFunction,
|
|
46
|
-
)
|
|
47
|
-
from .triangle_shape_function import (
|
|
48
|
-
TriangleNedelecFirstKindShapeFunctions,
|
|
49
|
-
TriangleNonConformingPolynomialShapeFunctions,
|
|
50
|
-
TrianglePolynomialShapeFunctions,
|
|
51
|
-
TriangleRaviartThomasShapeFunctions,
|
|
52
|
-
TriangleShapeFunction,
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class ElementBasis(Enum):
|
|
57
|
-
"""Choice of basis function to equip individual elements"""
|
|
58
|
-
|
|
59
|
-
LAGRANGE = "P"
|
|
60
|
-
"""Lagrange basis functions :math:`P_k` for simplices, tensor products :math:`Q_k` for squares and cubes"""
|
|
61
|
-
SERENDIPITY = "S"
|
|
62
|
-
"""Serendipity elements :math:`S_k`, corresponding to Lagrange nodes with interior points removed (for degree <= 3)"""
|
|
63
|
-
NONCONFORMING_POLYNOMIAL = "dP"
|
|
64
|
-
"""Simplex Lagrange basis functions :math:`P_{kd}` embedded into non conforming reference elements (e.g. squares or cubes). Discontinuous only."""
|
|
65
|
-
NEDELEC_FIRST_KIND = "N1"
|
|
66
|
-
"""Nédélec (first kind) H(curl) shape functions. Should be used with covariant function space."""
|
|
67
|
-
RAVIART_THOMAS = "RT"
|
|
68
|
-
"""Raviart-Thomas H(div) shape functions. Should be used with contravariant function space."""
|
|
69
|
-
|
|
36
|
+
from warp._src.fem.space.shape import SquareRaviartThomasShapeFunctions as SquareRaviartThomasShapeFunctions
|
|
37
|
+
from warp._src.fem.space.shape import SquareSerendipityShapeFunctions as SquareSerendipityShapeFunctions
|
|
70
38
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
):
|
|
79
|
-
"""
|
|
80
|
-
Equips a reference element with a shape function basis.
|
|
81
|
-
|
|
82
|
-
Args:
|
|
83
|
-
element_class: the type of reference element on which to build the shape function
|
|
84
|
-
space_dimension: the dimension of the embedding space
|
|
85
|
-
degree: polynomial degree of the per-element shape functions
|
|
86
|
-
element_basis: type of basis function for the individual elements
|
|
87
|
-
family: Polynomial family used to generate the shape function basis. If not provided, a reasonable basis is chosen.
|
|
88
|
-
|
|
89
|
-
Returns:
|
|
90
|
-
the corresponding shape function
|
|
91
|
-
"""
|
|
92
|
-
|
|
93
|
-
if degree == 0:
|
|
94
|
-
return ConstantShapeFunction(element_class(), space_dimension)
|
|
39
|
+
from warp._src.fem.space.shape import TriangleShapeFunction as TriangleShapeFunction
|
|
40
|
+
from warp._src.fem.space.shape import TriangleNedelecFirstKindShapeFunctions as TriangleNedelecFirstKindShapeFunctions
|
|
41
|
+
from warp._src.fem.space.shape import (
|
|
42
|
+
TriangleNonConformingPolynomialShapeFunctions as TriangleNonConformingPolynomialShapeFunctions,
|
|
43
|
+
)
|
|
44
|
+
from warp._src.fem.space.shape import TrianglePolynomialShapeFunctions as TrianglePolynomialShapeFunctions
|
|
45
|
+
from warp._src.fem.space.shape import TriangleRaviartThomasShapeFunctions as TriangleRaviartThomasShapeFunctions
|
|
95
46
|
|
|
96
|
-
|
|
97
|
-
|
|
47
|
+
from warp._src.fem.space.shape import TetrahedronShapeFunction as TetrahedronShapeFunction
|
|
48
|
+
from warp._src.fem.space.shape import (
|
|
49
|
+
TetrahedronNedelecFirstKindShapeFunctions as TetrahedronNedelecFirstKindShapeFunctions,
|
|
50
|
+
)
|
|
51
|
+
from warp._src.fem.space.shape import (
|
|
52
|
+
TetrahedronNonConformingPolynomialShapeFunctions as TetrahedronNonConformingPolynomialShapeFunctions,
|
|
53
|
+
)
|
|
54
|
+
from warp._src.fem.space.shape import TetrahedronPolynomialShapeFunctions as TetrahedronPolynomialShapeFunctions
|
|
55
|
+
from warp._src.fem.space.shape import TetrahedronRaviartThomasShapeFunctions as TetrahedronRaviartThomasShapeFunctions
|
|
98
56
|
|
|
99
|
-
|
|
100
|
-
if element_basis == ElementBasis.NEDELEC_FIRST_KIND:
|
|
101
|
-
return SquareNedelecFirstKindShapeFunctions(degree=degree)
|
|
102
|
-
if element_basis == ElementBasis.RAVIART_THOMAS:
|
|
103
|
-
return SquareRaviartThomasShapeFunctions(degree=degree)
|
|
104
|
-
if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
105
|
-
return SquareNonConformingPolynomialShapeFunctions(degree=degree)
|
|
106
|
-
if element_basis == ElementBasis.SERENDIPITY and degree > 1:
|
|
107
|
-
return SquareSerendipityShapeFunctions(degree=degree, family=family)
|
|
57
|
+
from warp._src.fem.space.shape import ConstantShapeFunction as ConstantShapeFunction
|
|
108
58
|
|
|
109
|
-
return SquareBipolynomialShapeFunctions(degree=degree, family=family)
|
|
110
|
-
if issubclass(element_class, _element.Triangle):
|
|
111
|
-
if element_basis == ElementBasis.NEDELEC_FIRST_KIND:
|
|
112
|
-
return TriangleNedelecFirstKindShapeFunctions(degree=degree)
|
|
113
|
-
if element_basis == ElementBasis.RAVIART_THOMAS:
|
|
114
|
-
return TriangleRaviartThomasShapeFunctions(degree=degree)
|
|
115
|
-
if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
116
|
-
return TriangleNonConformingPolynomialShapeFunctions(degree=degree)
|
|
117
|
-
if element_basis == ElementBasis.SERENDIPITY and degree > 2:
|
|
118
|
-
raise NotImplementedError("Serendipity variant not implemented yet for Triangle elements")
|
|
119
59
|
|
|
120
|
-
|
|
60
|
+
# TODO: Remove after cleaning up the public API.
|
|
121
61
|
|
|
122
|
-
|
|
123
|
-
if element_basis == ElementBasis.NEDELEC_FIRST_KIND:
|
|
124
|
-
return CubeNedelecFirstKindShapeFunctions(degree=degree)
|
|
125
|
-
if element_basis == ElementBasis.RAVIART_THOMAS:
|
|
126
|
-
return CubeRaviartThomasShapeFunctions(degree=degree)
|
|
127
|
-
if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
128
|
-
return CubeNonConformingPolynomialShapeFunctions(degree=degree)
|
|
129
|
-
if element_basis == ElementBasis.SERENDIPITY and degree > 1:
|
|
130
|
-
return CubeSerendipityShapeFunctions(degree=degree, family=family)
|
|
62
|
+
from warp._src.fem.space import shape as _shape
|
|
131
63
|
|
|
132
|
-
return CubeTripolynomialShapeFunctions(degree=degree, family=family)
|
|
133
|
-
if issubclass(element_class, _element.Tetrahedron):
|
|
134
|
-
if element_basis == ElementBasis.NEDELEC_FIRST_KIND:
|
|
135
|
-
return TetrahedronNedelecFirstKindShapeFunctions(degree=degree)
|
|
136
|
-
if element_basis == ElementBasis.RAVIART_THOMAS:
|
|
137
|
-
return TetrahedronRaviartThomasShapeFunctions(degree=degree)
|
|
138
|
-
if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
139
|
-
return TetrahedronNonConformingPolynomialShapeFunctions(degree=degree)
|
|
140
|
-
if element_basis == ElementBasis.SERENDIPITY and degree > 2:
|
|
141
|
-
raise NotImplementedError("Serendipity variant not implemented yet for Tet elements")
|
|
142
64
|
|
|
143
|
-
|
|
65
|
+
def __getattr__(name):
|
|
66
|
+
from warp._src.utils import get_deprecated_api
|
|
144
67
|
|
|
145
|
-
|
|
68
|
+
return get_deprecated_api(_shape, "wp.fem.space", name)
|
warp/fem/space/topology.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c)
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -13,443 +13,12 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
# TODO: Remove after cleaning up the public API.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
from warp.fem import cache
|
|
20
|
-
from warp.fem.geometry import DeformedGeometry, Geometry
|
|
21
|
-
from warp.fem.types import NULL_ELEMENT_INDEX, NULL_NODE_INDEX, ElementIndex
|
|
18
|
+
from warp._src.fem.space import topology as _topology
|
|
22
19
|
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Interface class for defining the topology of a function space.
|
|
21
|
+
def __getattr__(name):
|
|
22
|
+
from warp._src.utils import get_deprecated_api
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
the connectivity pattern of the function space.
|
|
30
|
-
It does not specify the actual location of the nodes within the elements, or the valuation function.
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
dimension: int
|
|
34
|
-
"""Embedding dimension of the function space"""
|
|
35
|
-
|
|
36
|
-
MAX_NODES_PER_ELEMENT: int
|
|
37
|
-
"""maximum number of interpolation nodes per element of the geometry.
|
|
38
|
-
|
|
39
|
-
.. note:: This will change to be defined per-element in future versions
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
_dynamic_attribute_constructors: ClassVar = {
|
|
43
|
-
"element_node_count": lambda obj: obj._make_constant_element_node_count(),
|
|
44
|
-
"element_node_sign": lambda obj: obj._make_constant_element_node_sign(),
|
|
45
|
-
"side_neighbor_node_counts": lambda obj: obj._make_constant_side_neighbor_node_counts(),
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@wp.struct
|
|
49
|
-
class TopologyArg:
|
|
50
|
-
"""Structure containing arguments to be passed to device functions"""
|
|
51
|
-
|
|
52
|
-
pass
|
|
53
|
-
|
|
54
|
-
def __init__(self, geometry: Geometry, max_nodes_per_element: int):
|
|
55
|
-
self._geometry = geometry
|
|
56
|
-
self.dimension = geometry.dimension
|
|
57
|
-
self.MAX_NODES_PER_ELEMENT = wp.constant(max_nodes_per_element)
|
|
58
|
-
self.ElementArg = geometry.CellArg
|
|
59
|
-
|
|
60
|
-
cache.setup_dynamic_attributes(self, cls=__class__)
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def geometry(self) -> Geometry:
|
|
64
|
-
"""Underlying geometry"""
|
|
65
|
-
return self._geometry
|
|
66
|
-
|
|
67
|
-
def node_count(self) -> int:
|
|
68
|
-
"""Number of nodes in the interpolation basis"""
|
|
69
|
-
raise NotImplementedError
|
|
70
|
-
|
|
71
|
-
def topo_arg_value(self, device) -> "TopologyArg":
|
|
72
|
-
"""Value of the topology argument structure to be passed to device functions"""
|
|
73
|
-
return SpaceTopology.TopologyArg()
|
|
74
|
-
|
|
75
|
-
def fill_topo_arg(self, arg, device):
|
|
76
|
-
pass
|
|
77
|
-
|
|
78
|
-
@property
|
|
79
|
-
def name(self):
|
|
80
|
-
return f"{self.__class__.__name__}_{self.MAX_NODES_PER_ELEMENT}"
|
|
81
|
-
|
|
82
|
-
def __str__(self):
|
|
83
|
-
return self.name
|
|
84
|
-
|
|
85
|
-
@staticmethod
|
|
86
|
-
def element_node_count(
|
|
87
|
-
geo_arg: "ElementArg", # noqa: F821
|
|
88
|
-
topo_arg: "TopologyArg",
|
|
89
|
-
element_index: ElementIndex,
|
|
90
|
-
) -> int:
|
|
91
|
-
"""Returns the actual number of nodes in a given element"""
|
|
92
|
-
raise NotImplementedError
|
|
93
|
-
|
|
94
|
-
@staticmethod
|
|
95
|
-
def element_node_index(
|
|
96
|
-
geo_arg: "ElementArg", # noqa: F821
|
|
97
|
-
topo_arg: "TopologyArg",
|
|
98
|
-
element_index: ElementIndex,
|
|
99
|
-
node_index_in_elt: int,
|
|
100
|
-
) -> int:
|
|
101
|
-
"""Global node index for a given node in a given element"""
|
|
102
|
-
raise NotImplementedError
|
|
103
|
-
|
|
104
|
-
@staticmethod
|
|
105
|
-
def side_neighbor_node_counts(
|
|
106
|
-
side_arg: "ElementArg", # noqa: F821
|
|
107
|
-
side_index: ElementIndex,
|
|
108
|
-
) -> Tuple[int, int]:
|
|
109
|
-
"""Returns the number of nodes for both the inner and outer cells of a given sides"""
|
|
110
|
-
raise NotImplementedError
|
|
111
|
-
|
|
112
|
-
def element_node_indices(self, out: Optional[wp.array] = None) -> wp.array:
|
|
113
|
-
"""Returns a temporary array containing the global index for each node of each element"""
|
|
114
|
-
|
|
115
|
-
MAX_NODES_PER_ELEMENT = self.MAX_NODES_PER_ELEMENT
|
|
116
|
-
|
|
117
|
-
@cache.dynamic_kernel(suffix=self.name)
|
|
118
|
-
def fill_element_node_indices(
|
|
119
|
-
geo_cell_arg: self.geometry.CellArg,
|
|
120
|
-
topo_arg: self.TopologyArg,
|
|
121
|
-
element_node_indices: wp.array2d(dtype=int),
|
|
122
|
-
):
|
|
123
|
-
element_index = wp.tid()
|
|
124
|
-
element_node_count = self.element_node_count(geo_cell_arg, topo_arg, element_index)
|
|
125
|
-
for n in range(element_node_count):
|
|
126
|
-
element_node_indices[element_index, n] = self.element_node_index(
|
|
127
|
-
geo_cell_arg, topo_arg, element_index, n
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
shape = (self.geometry.cell_count(), MAX_NODES_PER_ELEMENT)
|
|
131
|
-
if out is None:
|
|
132
|
-
element_node_indices = wp.empty(
|
|
133
|
-
shape=shape,
|
|
134
|
-
dtype=int,
|
|
135
|
-
)
|
|
136
|
-
else:
|
|
137
|
-
if out.shape != shape or out.dtype != wp.int32:
|
|
138
|
-
raise ValueError(f"Out element node indices array must have shape {shape} and data type 'int32'")
|
|
139
|
-
element_node_indices = out
|
|
140
|
-
|
|
141
|
-
wp.launch(
|
|
142
|
-
dim=element_node_indices.shape[0],
|
|
143
|
-
kernel=fill_element_node_indices,
|
|
144
|
-
inputs=[
|
|
145
|
-
self.geometry.cell_arg_value(device=element_node_indices.device),
|
|
146
|
-
self.topo_arg_value(device=element_node_indices.device),
|
|
147
|
-
element_node_indices,
|
|
148
|
-
],
|
|
149
|
-
device=element_node_indices.device,
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
return element_node_indices
|
|
153
|
-
|
|
154
|
-
# Interface generating trace space topology
|
|
155
|
-
|
|
156
|
-
def trace(self) -> "TraceSpaceTopology":
|
|
157
|
-
"""Trace of the function space over lower-dimensional elements of the geometry"""
|
|
158
|
-
|
|
159
|
-
return TraceSpaceTopology(self)
|
|
160
|
-
|
|
161
|
-
@property
|
|
162
|
-
def is_trace(self) -> bool:
|
|
163
|
-
"""Whether this topology is defined on the trace of the geometry"""
|
|
164
|
-
return self.dimension == self.geometry.dimension - 1
|
|
165
|
-
|
|
166
|
-
def full_space_topology(self) -> "SpaceTopology":
|
|
167
|
-
"""Returns the full space topology from which this topology is derived"""
|
|
168
|
-
return self
|
|
169
|
-
|
|
170
|
-
def __eq__(self, other: "SpaceTopology") -> bool:
|
|
171
|
-
"""Checks whether two topologies are compatible"""
|
|
172
|
-
return self.geometry == other.geometry and self.name == other.name
|
|
173
|
-
|
|
174
|
-
def is_derived_from(self, other: "SpaceTopology") -> bool:
|
|
175
|
-
"""Checks whether two topologies are equal, or `self` is the trace of `other`"""
|
|
176
|
-
if self.dimension == other.dimension:
|
|
177
|
-
return self == other
|
|
178
|
-
if self.dimension + 1 == other.dimension:
|
|
179
|
-
return self.full_space_topology() == other
|
|
180
|
-
return False
|
|
181
|
-
|
|
182
|
-
def _make_constant_element_node_count(self):
|
|
183
|
-
NODES_PER_ELEMENT = wp.constant(self.MAX_NODES_PER_ELEMENT)
|
|
184
|
-
|
|
185
|
-
@cache.dynamic_func(suffix=self.name)
|
|
186
|
-
def constant_element_node_count(
|
|
187
|
-
geo_arg: self.geometry.CellArg,
|
|
188
|
-
topo_arg: self.TopologyArg,
|
|
189
|
-
element_index: ElementIndex,
|
|
190
|
-
):
|
|
191
|
-
return NODES_PER_ELEMENT
|
|
192
|
-
|
|
193
|
-
return constant_element_node_count
|
|
194
|
-
|
|
195
|
-
def _make_constant_side_neighbor_node_counts(self):
|
|
196
|
-
NODES_PER_ELEMENT = wp.constant(self.MAX_NODES_PER_ELEMENT)
|
|
197
|
-
|
|
198
|
-
@cache.dynamic_func(suffix=self.name)
|
|
199
|
-
def constant_side_neighbor_node_counts(
|
|
200
|
-
side_arg: self.geometry.SideArg,
|
|
201
|
-
element_index: ElementIndex,
|
|
202
|
-
):
|
|
203
|
-
return NODES_PER_ELEMENT, NODES_PER_ELEMENT
|
|
204
|
-
|
|
205
|
-
return constant_side_neighbor_node_counts
|
|
206
|
-
|
|
207
|
-
def _make_constant_element_node_sign(self):
|
|
208
|
-
@cache.dynamic_func(suffix=self.name)
|
|
209
|
-
def constant_element_node_sign(
|
|
210
|
-
geo_arg: self.geometry.CellArg,
|
|
211
|
-
topo_arg: self.TopologyArg,
|
|
212
|
-
element_index: ElementIndex,
|
|
213
|
-
node_index_in_element: int,
|
|
214
|
-
):
|
|
215
|
-
return 1.0
|
|
216
|
-
|
|
217
|
-
return constant_element_node_sign
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
class TraceSpaceTopology(SpaceTopology):
|
|
221
|
-
"""Auto-generated trace topology defining the node indices associated to the geometry sides"""
|
|
222
|
-
|
|
223
|
-
_dynamic_attribute_constructors: ClassVar = {
|
|
224
|
-
"inner_cell_index": lambda obj: obj._make_inner_cell_index(),
|
|
225
|
-
"outer_cell_index": lambda obj: obj._make_outer_cell_index(),
|
|
226
|
-
"neighbor_cell_index": lambda obj: obj._make_neighbor_cell_index(),
|
|
227
|
-
"element_node_index": lambda obj: obj._make_element_node_index(),
|
|
228
|
-
"element_node_count": lambda obj: obj._make_element_node_count(),
|
|
229
|
-
"element_node_sign": lambda obj: obj._make_element_node_sign(),
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
def __init__(self, topo: SpaceTopology):
|
|
233
|
-
self._topo = topo
|
|
234
|
-
|
|
235
|
-
super().__init__(topo.geometry, 2 * topo.MAX_NODES_PER_ELEMENT)
|
|
236
|
-
|
|
237
|
-
self.dimension = topo.dimension - 1
|
|
238
|
-
self.ElementArg = topo.geometry.SideArg
|
|
239
|
-
|
|
240
|
-
self.TopologyArg = topo.TopologyArg
|
|
241
|
-
self.topo_arg_value = topo.topo_arg_value
|
|
242
|
-
self.fill_topo_arg = topo.fill_topo_arg
|
|
243
|
-
|
|
244
|
-
self.side_neighbor_node_counts = None
|
|
245
|
-
cache.setup_dynamic_attributes(self, cls=__class__)
|
|
246
|
-
|
|
247
|
-
def node_count(self) -> int:
|
|
248
|
-
return self._topo.node_count()
|
|
249
|
-
|
|
250
|
-
@property
|
|
251
|
-
def name(self):
|
|
252
|
-
return f"{self._topo.name}_Trace"
|
|
253
|
-
|
|
254
|
-
def _make_inner_cell_index(self):
|
|
255
|
-
@cache.dynamic_func(suffix=self.name)
|
|
256
|
-
def inner_cell_index(side_arg: self.geometry.SideArg, element_index: ElementIndex, node_index_in_elt: int):
|
|
257
|
-
inner_count, outer_count = self._topo.side_neighbor_node_counts(side_arg, element_index)
|
|
258
|
-
if node_index_in_elt >= inner_count:
|
|
259
|
-
return NULL_ELEMENT_INDEX, NULL_NODE_INDEX
|
|
260
|
-
return self.geometry.side_inner_cell_index(side_arg, element_index), node_index_in_elt
|
|
261
|
-
|
|
262
|
-
return inner_cell_index
|
|
263
|
-
|
|
264
|
-
def _make_outer_cell_index(self):
|
|
265
|
-
@cache.dynamic_func(suffix=self.name)
|
|
266
|
-
def outer_cell_index(side_arg: self.geometry.SideArg, element_index: ElementIndex, node_index_in_elt: int):
|
|
267
|
-
inner_count, outer_count = self._topo.side_neighbor_node_counts(side_arg, element_index)
|
|
268
|
-
if node_index_in_elt < inner_count:
|
|
269
|
-
return NULL_ELEMENT_INDEX, NULL_NODE_INDEX
|
|
270
|
-
return self.geometry.side_outer_cell_index(side_arg, element_index), node_index_in_elt - inner_count
|
|
271
|
-
|
|
272
|
-
return outer_cell_index
|
|
273
|
-
|
|
274
|
-
def _make_neighbor_cell_index(self):
|
|
275
|
-
@cache.dynamic_func(suffix=self.name)
|
|
276
|
-
def neighbor_cell_index(side_arg: self.geometry.SideArg, element_index: ElementIndex, node_index_in_elt: int):
|
|
277
|
-
inner_count, outer_count = self._topo.side_neighbor_node_counts(side_arg, element_index)
|
|
278
|
-
if node_index_in_elt < inner_count:
|
|
279
|
-
return self.geometry.side_inner_cell_index(side_arg, element_index), node_index_in_elt
|
|
280
|
-
|
|
281
|
-
return (
|
|
282
|
-
self.geometry.side_outer_cell_index(side_arg, element_index),
|
|
283
|
-
node_index_in_elt - inner_count,
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
return neighbor_cell_index
|
|
287
|
-
|
|
288
|
-
def _make_element_node_count(self):
|
|
289
|
-
@cache.dynamic_func(suffix=self.name)
|
|
290
|
-
def trace_element_node_count(
|
|
291
|
-
geo_side_arg: self.geometry.SideArg,
|
|
292
|
-
topo_arg: self._topo.TopologyArg,
|
|
293
|
-
element_index: ElementIndex,
|
|
294
|
-
):
|
|
295
|
-
inner_count, outer_count = self._topo.side_neighbor_node_counts(geo_side_arg, element_index)
|
|
296
|
-
return inner_count + outer_count
|
|
297
|
-
|
|
298
|
-
return trace_element_node_count
|
|
299
|
-
|
|
300
|
-
def _make_element_node_index(self):
|
|
301
|
-
@cache.dynamic_func(suffix=self.name)
|
|
302
|
-
def trace_element_node_index(
|
|
303
|
-
geo_side_arg: self.geometry.SideArg,
|
|
304
|
-
topo_arg: self._topo.TopologyArg,
|
|
305
|
-
element_index: ElementIndex,
|
|
306
|
-
node_index_in_elt: int,
|
|
307
|
-
):
|
|
308
|
-
cell_index, index_in_cell = self.neighbor_cell_index(geo_side_arg, element_index, node_index_in_elt)
|
|
309
|
-
|
|
310
|
-
geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
|
|
311
|
-
return self._topo.element_node_index(geo_cell_arg, topo_arg, cell_index, index_in_cell)
|
|
312
|
-
|
|
313
|
-
return trace_element_node_index
|
|
314
|
-
|
|
315
|
-
def _make_element_node_sign(self):
|
|
316
|
-
@cache.dynamic_func(suffix=self.name)
|
|
317
|
-
def trace_element_node_sign(
|
|
318
|
-
geo_side_arg: self.geometry.SideArg,
|
|
319
|
-
topo_arg: self._topo.TopologyArg,
|
|
320
|
-
element_index: ElementIndex,
|
|
321
|
-
node_index_in_elt: int,
|
|
322
|
-
):
|
|
323
|
-
cell_index, index_in_cell = self.neighbor_cell_index(geo_side_arg, element_index, node_index_in_elt)
|
|
324
|
-
|
|
325
|
-
geo_cell_arg = self.geometry.side_to_cell_arg(geo_side_arg)
|
|
326
|
-
return self._topo.element_node_sign(geo_cell_arg, topo_arg, cell_index, index_in_cell)
|
|
327
|
-
|
|
328
|
-
return trace_element_node_sign
|
|
329
|
-
|
|
330
|
-
def full_space_topology(self) -> SpaceTopology:
|
|
331
|
-
"""Returns the full space topology from which this topology is derived"""
|
|
332
|
-
return self._topo
|
|
333
|
-
|
|
334
|
-
def __eq__(self, other: "TraceSpaceTopology") -> bool:
|
|
335
|
-
return self._topo == other._topo
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
class RegularDiscontinuousSpaceTopologyMixin:
|
|
339
|
-
"""Helper for defining discontinuous topologies (per-element nodes)"""
|
|
340
|
-
|
|
341
|
-
def __init__(self, *args, **kwargs):
|
|
342
|
-
super().__init__(*args, **kwargs)
|
|
343
|
-
self.element_node_index = self._make_element_node_index()
|
|
344
|
-
|
|
345
|
-
def node_count(self):
|
|
346
|
-
return self.geometry.cell_count() * self.MAX_NODES_PER_ELEMENT
|
|
347
|
-
|
|
348
|
-
@property
|
|
349
|
-
def name(self):
|
|
350
|
-
return f"{self.geometry.name}_D{self.MAX_NODES_PER_ELEMENT}"
|
|
351
|
-
|
|
352
|
-
def _make_element_node_index(self):
|
|
353
|
-
NODES_PER_ELEMENT = self.MAX_NODES_PER_ELEMENT
|
|
354
|
-
|
|
355
|
-
@cache.dynamic_func(suffix=self.name)
|
|
356
|
-
def element_node_index(
|
|
357
|
-
elt_arg: self.geometry.CellArg,
|
|
358
|
-
topo_arg: self.TopologyArg,
|
|
359
|
-
element_index: ElementIndex,
|
|
360
|
-
node_index_in_elt: int,
|
|
361
|
-
):
|
|
362
|
-
return NODES_PER_ELEMENT * element_index + node_index_in_elt
|
|
363
|
-
|
|
364
|
-
return element_node_index
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
class RegularDiscontinuousSpaceTopology(RegularDiscontinuousSpaceTopologyMixin, SpaceTopology):
|
|
368
|
-
"""Topology for generic discontinuous spaces"""
|
|
369
|
-
|
|
370
|
-
pass
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
class DeformedGeometrySpaceTopology(SpaceTopology):
|
|
374
|
-
_dynamic_attribute_constructors: ClassVar = {
|
|
375
|
-
"element_node_index": lambda obj: obj._make_element_node_index(),
|
|
376
|
-
"element_node_count": lambda obj: obj._make_element_node_count(),
|
|
377
|
-
"element_node_sign": lambda obj: obj._make_element_node_sign(),
|
|
378
|
-
"side_neighbor_node_counts": lambda obj: obj._make_side_neighbor_node_counts(),
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
def __init__(self, geometry: DeformedGeometry, base_topology: SpaceTopology):
|
|
382
|
-
self.base = base_topology
|
|
383
|
-
super().__init__(geometry, base_topology.MAX_NODES_PER_ELEMENT)
|
|
384
|
-
|
|
385
|
-
self.node_count = self.base.node_count
|
|
386
|
-
self.topo_arg_value = self.base.topo_arg_value
|
|
387
|
-
self.fill_topo_arg = self.base.fill_topo_arg
|
|
388
|
-
self.TopologyArg = self.base.TopologyArg
|
|
389
|
-
|
|
390
|
-
cache.setup_dynamic_attributes(self, cls=__class__)
|
|
391
|
-
|
|
392
|
-
@property
|
|
393
|
-
def name(self):
|
|
394
|
-
return f"{self.base.name}_{self.geometry.field.name}"
|
|
395
|
-
|
|
396
|
-
def _make_element_node_index(self):
|
|
397
|
-
@cache.dynamic_func(suffix=self.name)
|
|
398
|
-
def element_node_index(
|
|
399
|
-
elt_arg: self.geometry.CellArg,
|
|
400
|
-
topo_arg: self.TopologyArg,
|
|
401
|
-
element_index: ElementIndex,
|
|
402
|
-
node_index_in_elt: int,
|
|
403
|
-
):
|
|
404
|
-
return self.base.element_node_index(elt_arg.base_arg, topo_arg, element_index, node_index_in_elt)
|
|
405
|
-
|
|
406
|
-
return element_node_index
|
|
407
|
-
|
|
408
|
-
def _make_element_node_count(self):
|
|
409
|
-
@cache.dynamic_func(suffix=self.name)
|
|
410
|
-
def element_node_count(
|
|
411
|
-
elt_arg: self.geometry.CellArg,
|
|
412
|
-
topo_arg: self.TopologyArg,
|
|
413
|
-
element_count: ElementIndex,
|
|
414
|
-
):
|
|
415
|
-
return self.base.element_node_count(elt_arg.base_arg, topo_arg, element_count)
|
|
416
|
-
|
|
417
|
-
return element_node_count
|
|
418
|
-
|
|
419
|
-
def _make_side_neighbor_node_counts(self):
|
|
420
|
-
@cache.dynamic_func(suffix=self.name)
|
|
421
|
-
def side_neighbor_node_counts(
|
|
422
|
-
side_arg: self.geometry.SideArg,
|
|
423
|
-
element_index: ElementIndex,
|
|
424
|
-
):
|
|
425
|
-
inner_count, outer_count = self.base.side_neighbor_node_counts(side_arg.base_arg, element_index)
|
|
426
|
-
return inner_count, outer_count
|
|
427
|
-
|
|
428
|
-
return side_neighbor_node_counts
|
|
429
|
-
|
|
430
|
-
def _make_element_node_sign(self):
|
|
431
|
-
@cache.dynamic_func(suffix=self.name)
|
|
432
|
-
def element_node_sign(
|
|
433
|
-
elt_arg: self.geometry.CellArg,
|
|
434
|
-
topo_arg: self.TopologyArg,
|
|
435
|
-
element_index: ElementIndex,
|
|
436
|
-
node_index_in_elt: int,
|
|
437
|
-
):
|
|
438
|
-
return self.base.element_node_sign(elt_arg.base_arg, topo_arg, element_index, node_index_in_elt)
|
|
439
|
-
|
|
440
|
-
return element_node_sign
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
def forward_base_topology(topology_class: Type[SpaceTopology], geometry: Geometry, *args, **kwargs) -> SpaceTopology:
|
|
444
|
-
"""
|
|
445
|
-
If `geometry` is *not* a :class:`DeformedGeometry`, constructs a normal instance of `topology_class` over `geometry`, forwarding additional arguments.
|
|
446
|
-
|
|
447
|
-
If `geometry` *is* a :class:`DeformedGeometry`, constructs an instance of `topology_class` over the base (undeformed) geometry of `geometry`, then warp it
|
|
448
|
-
in a :class:`DeformedGeometrySpaceTopology` forwarding the calls to the underlying topology.
|
|
449
|
-
"""
|
|
450
|
-
|
|
451
|
-
if isinstance(geometry, DeformedGeometry):
|
|
452
|
-
base_topo = topology_class(geometry.base, *args, **kwargs)
|
|
453
|
-
return DeformedGeometrySpaceTopology(geometry, base_topo)
|
|
454
|
-
|
|
455
|
-
return topology_class(geometry, *args, **kwargs)
|
|
24
|
+
return get_deprecated_api(_topology, "wp.fem.space", name)
|