warp-lang 1.1.0__py3-none-macosx_10_13_universal2.whl → 1.2.1__py3-none-macosx_10_13_universal2.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/bin/libwarp-clang.dylib +0 -0
- warp/bin/libwarp.dylib +0 -0
- warp/build.py +10 -37
- warp/build_dll.py +2 -2
- warp/builtins.py +274 -6
- warp/codegen.py +51 -4
- warp/config.py +2 -2
- warp/constants.py +4 -0
- warp/context.py +422 -203
- warp/examples/benchmarks/benchmark_api.py +0 -2
- warp/examples/benchmarks/benchmark_cloth_warp.py +0 -1
- warp/examples/benchmarks/benchmark_launches.py +0 -2
- warp/examples/core/example_dem.py +0 -2
- warp/examples/core/example_fluid.py +0 -2
- warp/examples/core/example_graph_capture.py +0 -2
- warp/examples/core/example_marching_cubes.py +0 -2
- warp/examples/core/example_mesh.py +0 -2
- warp/examples/core/example_mesh_intersect.py +0 -2
- warp/examples/core/example_nvdb.py +0 -2
- warp/examples/core/example_raycast.py +0 -2
- warp/examples/core/example_raymarch.py +0 -2
- warp/examples/core/example_render_opengl.py +0 -2
- warp/examples/core/example_sph.py +0 -2
- warp/examples/core/example_torch.py +0 -3
- warp/examples/core/example_wave.py +0 -2
- warp/examples/fem/example_apic_fluid.py +140 -115
- warp/examples/fem/example_burgers.py +262 -0
- warp/examples/fem/example_convection_diffusion.py +0 -2
- warp/examples/fem/example_convection_diffusion_dg.py +0 -2
- warp/examples/fem/example_deformed_geometry.py +0 -2
- warp/examples/fem/example_diffusion.py +0 -2
- warp/examples/fem/example_diffusion_3d.py +5 -4
- warp/examples/fem/example_diffusion_mgpu.py +0 -2
- warp/examples/fem/example_mixed_elasticity.py +0 -2
- warp/examples/fem/example_navier_stokes.py +0 -2
- warp/examples/fem/example_stokes.py +0 -2
- warp/examples/fem/example_stokes_transfer.py +0 -2
- warp/examples/optim/example_bounce.py +0 -2
- warp/examples/optim/example_cloth_throw.py +0 -2
- warp/examples/optim/example_diffray.py +0 -2
- warp/examples/optim/example_drone.py +0 -2
- warp/examples/optim/example_inverse_kinematics.py +0 -2
- warp/examples/optim/example_inverse_kinematics_torch.py +0 -2
- warp/examples/optim/example_spring_cage.py +0 -2
- warp/examples/optim/example_trajectory.py +0 -2
- warp/examples/optim/example_walker.py +0 -2
- warp/examples/sim/example_cartpole.py +0 -2
- warp/examples/sim/example_cloth.py +0 -2
- warp/examples/sim/example_granular.py +0 -2
- warp/examples/sim/example_granular_collision_sdf.py +0 -2
- warp/examples/sim/example_jacobian_ik.py +0 -2
- warp/examples/sim/example_particle_chain.py +0 -2
- warp/examples/sim/example_quadruped.py +0 -2
- warp/examples/sim/example_rigid_chain.py +0 -2
- warp/examples/sim/example_rigid_contact.py +0 -2
- warp/examples/sim/example_rigid_force.py +0 -2
- warp/examples/sim/example_rigid_gyroscopic.py +0 -2
- warp/examples/sim/example_rigid_soft_contact.py +0 -2
- warp/examples/sim/example_soft_body.py +0 -2
- warp/fem/__init__.py +1 -0
- warp/fem/cache.py +3 -1
- warp/fem/geometry/__init__.py +1 -0
- warp/fem/geometry/element.py +4 -0
- warp/fem/geometry/grid_3d.py +0 -4
- warp/fem/geometry/nanogrid.py +455 -0
- warp/fem/integrate.py +63 -9
- warp/fem/space/__init__.py +43 -158
- warp/fem/space/basis_space.py +34 -0
- warp/fem/space/collocated_function_space.py +1 -1
- warp/fem/space/grid_2d_function_space.py +13 -132
- warp/fem/space/grid_3d_function_space.py +16 -154
- warp/fem/space/hexmesh_function_space.py +37 -134
- warp/fem/space/nanogrid_function_space.py +202 -0
- warp/fem/space/quadmesh_2d_function_space.py +12 -119
- warp/fem/space/restriction.py +4 -1
- warp/fem/space/shape/__init__.py +77 -0
- warp/fem/space/shape/cube_shape_function.py +5 -15
- warp/fem/space/tetmesh_function_space.py +6 -76
- warp/fem/space/trimesh_2d_function_space.py +6 -76
- warp/native/array.h +12 -3
- warp/native/builtin.h +48 -5
- warp/native/bvh.cpp +14 -10
- warp/native/bvh.cu +23 -15
- warp/native/bvh.h +1 -0
- warp/native/clang/clang.cpp +2 -1
- warp/native/crt.cpp +11 -1
- warp/native/crt.h +18 -1
- warp/native/exports.h +187 -0
- warp/native/mat.h +47 -0
- warp/native/mesh.cpp +1 -1
- warp/native/mesh.cu +1 -2
- warp/native/nanovdb/GridHandle.h +366 -0
- warp/native/nanovdb/HostBuffer.h +590 -0
- warp/native/nanovdb/NanoVDB.h +3999 -2157
- warp/native/nanovdb/PNanoVDB.h +936 -99
- warp/native/quat.h +28 -1
- warp/native/rand.h +5 -1
- warp/native/vec.h +45 -1
- warp/native/volume.cpp +335 -103
- warp/native/volume.cu +39 -13
- warp/native/volume.h +725 -303
- warp/native/volume_builder.cu +381 -360
- warp/native/volume_builder.h +16 -1
- warp/native/volume_impl.h +61 -0
- warp/native/warp.cu +8 -2
- warp/native/warp.h +15 -7
- warp/render/render_opengl.py +191 -52
- warp/sim/integrator_featherstone.py +10 -3
- warp/sim/integrator_xpbd.py +16 -22
- warp/sparse.py +89 -27
- warp/stubs.py +83 -0
- warp/tests/assets/test_index_grid.nvdb +0 -0
- warp/tests/aux_test_dependent.py +0 -2
- warp/tests/aux_test_grad_customs.py +0 -2
- warp/tests/aux_test_reference.py +0 -2
- warp/tests/aux_test_reference_reference.py +0 -2
- warp/tests/aux_test_square.py +0 -2
- warp/tests/disabled_kinematics.py +0 -2
- warp/tests/test_adam.py +0 -2
- warp/tests/test_arithmetic.py +0 -36
- warp/tests/test_array.py +9 -11
- warp/tests/test_array_reduce.py +0 -2
- warp/tests/test_async.py +0 -2
- warp/tests/test_atomic.py +0 -2
- warp/tests/test_bool.py +58 -50
- warp/tests/test_builtins_resolution.py +0 -2
- warp/tests/test_bvh.py +0 -2
- warp/tests/test_closest_point_edge_edge.py +0 -1
- warp/tests/test_codegen.py +0 -4
- warp/tests/test_compile_consts.py +130 -10
- warp/tests/test_conditional.py +0 -2
- warp/tests/test_copy.py +0 -2
- warp/tests/test_ctypes.py +6 -8
- warp/tests/test_dense.py +0 -2
- warp/tests/test_devices.py +0 -2
- warp/tests/test_dlpack.py +9 -11
- warp/tests/test_examples.py +42 -39
- warp/tests/test_fabricarray.py +0 -3
- warp/tests/test_fast_math.py +0 -2
- warp/tests/test_fem.py +75 -54
- warp/tests/test_fp16.py +0 -2
- warp/tests/test_func.py +0 -2
- warp/tests/test_generics.py +27 -2
- warp/tests/test_grad.py +147 -8
- warp/tests/test_grad_customs.py +0 -2
- warp/tests/test_hash_grid.py +1 -3
- warp/tests/test_import.py +0 -2
- warp/tests/test_indexedarray.py +0 -2
- warp/tests/test_intersect.py +0 -2
- warp/tests/test_jax.py +0 -2
- warp/tests/test_large.py +11 -9
- warp/tests/test_launch.py +0 -2
- warp/tests/test_lerp.py +10 -54
- warp/tests/test_linear_solvers.py +3 -5
- warp/tests/test_lvalue.py +0 -2
- warp/tests/test_marching_cubes.py +0 -2
- warp/tests/test_mat.py +0 -2
- warp/tests/test_mat_lite.py +0 -2
- warp/tests/test_mat_scalar_ops.py +0 -2
- warp/tests/test_math.py +0 -2
- warp/tests/test_matmul.py +35 -37
- warp/tests/test_matmul_lite.py +29 -31
- warp/tests/test_mempool.py +0 -2
- warp/tests/test_mesh.py +0 -3
- warp/tests/test_mesh_query_aabb.py +0 -2
- warp/tests/test_mesh_query_point.py +0 -2
- warp/tests/test_mesh_query_ray.py +0 -2
- warp/tests/test_mlp.py +0 -2
- warp/tests/test_model.py +0 -2
- warp/tests/test_module_hashing.py +111 -0
- warp/tests/test_modules_lite.py +0 -3
- warp/tests/test_multigpu.py +0 -2
- warp/tests/test_noise.py +0 -4
- warp/tests/test_operators.py +0 -2
- warp/tests/test_options.py +0 -2
- warp/tests/test_peer.py +0 -2
- warp/tests/test_pinned.py +0 -2
- warp/tests/test_print.py +0 -2
- warp/tests/test_quat.py +0 -2
- warp/tests/test_rand.py +41 -5
- warp/tests/test_reload.py +0 -10
- warp/tests/test_rounding.py +0 -2
- warp/tests/test_runlength_encode.py +0 -2
- warp/tests/test_sim_grad.py +0 -2
- warp/tests/test_sim_kinematics.py +0 -2
- warp/tests/test_smoothstep.py +0 -2
- warp/tests/test_snippet.py +0 -2
- warp/tests/test_sparse.py +0 -2
- warp/tests/test_spatial.py +0 -2
- warp/tests/test_special_values.py +362 -0
- warp/tests/test_streams.py +0 -2
- warp/tests/test_struct.py +0 -2
- warp/tests/test_tape.py +0 -2
- warp/tests/test_torch.py +0 -2
- warp/tests/test_transient_module.py +0 -2
- warp/tests/test_types.py +0 -2
- warp/tests/test_utils.py +0 -2
- warp/tests/test_vec.py +0 -2
- warp/tests/test_vec_lite.py +0 -2
- warp/tests/test_vec_scalar_ops.py +0 -2
- warp/tests/test_verify_fp.py +0 -2
- warp/tests/test_volume.py +237 -13
- warp/tests/test_volume_write.py +86 -3
- warp/tests/unittest_serial.py +10 -9
- warp/tests/unittest_suites.py +6 -2
- warp/tests/unittest_utils.py +2 -171
- warp/tests/unused_test_misc.py +0 -2
- warp/tests/walkthrough_debug.py +1 -1
- warp/thirdparty/unittest_parallel.py +37 -40
- warp/types.py +526 -85
- {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/METADATA +61 -31
- warp_lang-1.2.1.dist-info/RECORD +359 -0
- warp/examples/fem/example_convection_diffusion_dg0.py +0 -204
- warp/native/nanovdb/PNanoVDBWrite.h +0 -295
- warp_lang-1.1.0.dist-info/RECORD +0 -352
- {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/WHEEL +0 -0
- {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/top_level.txt +0 -0
warp/fem/space/__init__.py
CHANGED
|
@@ -9,53 +9,24 @@ import warp.fem.polynomial as _polynomial
|
|
|
9
9
|
|
|
10
10
|
from .function_space import FunctionSpace
|
|
11
11
|
from .topology import SpaceTopology
|
|
12
|
-
from .basis_space import BasisSpace, PointBasisSpace
|
|
12
|
+
from .basis_space import BasisSpace, PointBasisSpace, ShapeBasisSpace, make_discontinuous_basis_space
|
|
13
13
|
from .collocated_function_space import CollocatedFunctionSpace
|
|
14
|
+
from .shape import ElementBasis, get_shape_function
|
|
15
|
+
|
|
16
|
+
from .grid_2d_function_space import make_grid_2d_space_topology
|
|
17
|
+
|
|
18
|
+
from .grid_3d_function_space import make_grid_3d_space_topology
|
|
19
|
+
|
|
20
|
+
from .trimesh_2d_function_space import make_trimesh_2d_space_topology
|
|
21
|
+
|
|
22
|
+
from .tetmesh_function_space import make_tetmesh_space_topology
|
|
23
|
+
|
|
24
|
+
from .quadmesh_2d_function_space import make_quadmesh_2d_space_topology
|
|
25
|
+
|
|
26
|
+
from .hexmesh_function_space import make_hexmesh_space_topology
|
|
27
|
+
|
|
28
|
+
from .nanogrid_function_space import make_nanogrid_space_topology
|
|
14
29
|
|
|
15
|
-
from .grid_2d_function_space import (
|
|
16
|
-
GridPiecewiseConstantBasis,
|
|
17
|
-
GridBipolynomialBasisSpace,
|
|
18
|
-
GridDGBipolynomialBasisSpace,
|
|
19
|
-
GridSerendipityBasisSpace,
|
|
20
|
-
GridDGSerendipityBasisSpace,
|
|
21
|
-
GridDGPolynomialBasisSpace,
|
|
22
|
-
)
|
|
23
|
-
from .grid_3d_function_space import (
|
|
24
|
-
GridTripolynomialBasisSpace,
|
|
25
|
-
GridDGTripolynomialBasisSpace,
|
|
26
|
-
Grid3DPiecewiseConstantBasis,
|
|
27
|
-
Grid3DSerendipityBasisSpace,
|
|
28
|
-
Grid3DDGSerendipityBasisSpace,
|
|
29
|
-
Grid3DDGPolynomialBasisSpace,
|
|
30
|
-
)
|
|
31
|
-
from .trimesh_2d_function_space import (
|
|
32
|
-
Trimesh2DPiecewiseConstantBasis,
|
|
33
|
-
Trimesh2DPolynomialBasisSpace,
|
|
34
|
-
Trimesh2DDGPolynomialBasisSpace,
|
|
35
|
-
Trimesh2DNonConformingPolynomialBasisSpace,
|
|
36
|
-
)
|
|
37
|
-
from .tetmesh_function_space import (
|
|
38
|
-
TetmeshPiecewiseConstantBasis,
|
|
39
|
-
TetmeshPolynomialBasisSpace,
|
|
40
|
-
TetmeshDGPolynomialBasisSpace,
|
|
41
|
-
TetmeshNonConformingPolynomialBasisSpace,
|
|
42
|
-
)
|
|
43
|
-
from .quadmesh_2d_function_space import (
|
|
44
|
-
Quadmesh2DPiecewiseConstantBasis,
|
|
45
|
-
Quadmesh2DBipolynomialBasisSpace,
|
|
46
|
-
Quadmesh2DDGBipolynomialBasisSpace,
|
|
47
|
-
Quadmesh2DSerendipityBasisSpace,
|
|
48
|
-
Quadmesh2DDGSerendipityBasisSpace,
|
|
49
|
-
Quadmesh2DPolynomialBasisSpace,
|
|
50
|
-
)
|
|
51
|
-
from .hexmesh_function_space import (
|
|
52
|
-
HexmeshPiecewiseConstantBasis,
|
|
53
|
-
HexmeshTripolynomialBasisSpace,
|
|
54
|
-
HexmeshDGTripolynomialBasisSpace,
|
|
55
|
-
HexmeshSerendipityBasisSpace,
|
|
56
|
-
HexmeshDGSerendipityBasisSpace,
|
|
57
|
-
HexmeshPolynomialBasisSpace,
|
|
58
|
-
)
|
|
59
30
|
|
|
60
31
|
from .partition import SpacePartition, make_space_partition
|
|
61
32
|
from .restriction import SpaceRestriction
|
|
@@ -105,17 +76,6 @@ def make_space_restriction(
|
|
|
105
76
|
)
|
|
106
77
|
|
|
107
78
|
|
|
108
|
-
class ElementBasis(Enum):
|
|
109
|
-
"""Choice of basis function to equip individual elements"""
|
|
110
|
-
|
|
111
|
-
LAGRANGE = 0
|
|
112
|
-
"""Lagrange basis functions :math:`P_k` for simplices, tensor products :math:`Q_k` for squares and cubes"""
|
|
113
|
-
SERENDIPITY = 1
|
|
114
|
-
"""Serendipity elements :math:`S_k`, corresponding to Lagrange nodes with interior points removed (for degree <= 3)"""
|
|
115
|
-
NONCONFORMING_POLYNOMIAL = 2
|
|
116
|
-
"""Simplex Lagrange basis functions :math:`P_{kd}` embedded into non conforming reference elements (e.g. squares or cubes). Discontinuous only."""
|
|
117
|
-
|
|
118
|
-
|
|
119
79
|
def make_polynomial_basis_space(
|
|
120
80
|
geo: _geometry.Geometry,
|
|
121
81
|
degree: int = 1,
|
|
@@ -141,110 +101,35 @@ def make_polynomial_basis_space(
|
|
|
141
101
|
|
|
142
102
|
if element_basis is None:
|
|
143
103
|
element_basis = ElementBasis.LAGRANGE
|
|
104
|
+
elif element_basis == ElementBasis.SERENDIPITY and degree == 1:
|
|
105
|
+
# Degree-1 serendipity is always equivalent to Lagrange
|
|
106
|
+
element_basis = ElementBasis.LAGRANGE
|
|
107
|
+
|
|
108
|
+
shape = get_shape_function(geo.reference_cell(), geo.dimension, degree, element_basis, family)
|
|
109
|
+
|
|
110
|
+
if discontinuous or degree == 0 or element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
111
|
+
return make_discontinuous_basis_space(geo, shape)
|
|
144
112
|
|
|
113
|
+
topology = None
|
|
145
114
|
if isinstance(base_geo, _geometry.Grid2D):
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if degree == 0:
|
|
165
|
-
return Grid3DPiecewiseConstantBasis(geo)
|
|
166
|
-
|
|
167
|
-
if element_basis == ElementBasis.SERENDIPITY and degree > 1:
|
|
168
|
-
if discontinuous:
|
|
169
|
-
return Grid3DDGSerendipityBasisSpace(geo, degree=degree, family=family)
|
|
170
|
-
else:
|
|
171
|
-
return Grid3DSerendipityBasisSpace(geo, degree=degree, family=family)
|
|
172
|
-
|
|
173
|
-
if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
174
|
-
return Grid3DDGPolynomialBasisSpace(geo, degree=degree)
|
|
175
|
-
|
|
176
|
-
if discontinuous:
|
|
177
|
-
return GridDGTripolynomialBasisSpace(geo, degree=degree, family=family)
|
|
178
|
-
else:
|
|
179
|
-
return GridTripolynomialBasisSpace(geo, degree=degree, family=family)
|
|
180
|
-
|
|
181
|
-
if isinstance(base_geo, _geometry.Trimesh2D):
|
|
182
|
-
if degree == 0:
|
|
183
|
-
return Trimesh2DPiecewiseConstantBasis(geo)
|
|
184
|
-
|
|
185
|
-
if element_basis == ElementBasis.SERENDIPITY and degree > 2:
|
|
186
|
-
raise NotImplementedError("Serendipity variant not implemented yet")
|
|
187
|
-
|
|
188
|
-
if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
189
|
-
return Trimesh2DNonConformingPolynomialBasisSpace(geo, degree=degree)
|
|
190
|
-
|
|
191
|
-
if discontinuous:
|
|
192
|
-
return Trimesh2DDGPolynomialBasisSpace(geo, degree=degree)
|
|
193
|
-
else:
|
|
194
|
-
return Trimesh2DPolynomialBasisSpace(geo, degree=degree)
|
|
195
|
-
|
|
196
|
-
if isinstance(base_geo, _geometry.Tetmesh):
|
|
197
|
-
if degree == 0:
|
|
198
|
-
return TetmeshPiecewiseConstantBasis(geo)
|
|
199
|
-
|
|
200
|
-
if element_basis == ElementBasis.SERENDIPITY and degree > 2:
|
|
201
|
-
raise NotImplementedError("Serendipity variant not implemented yet")
|
|
202
|
-
|
|
203
|
-
if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
204
|
-
return TetmeshNonConformingPolynomialBasisSpace(geo, degree=degree)
|
|
205
|
-
|
|
206
|
-
if discontinuous:
|
|
207
|
-
return TetmeshDGPolynomialBasisSpace(geo, degree=degree)
|
|
208
|
-
else:
|
|
209
|
-
return TetmeshPolynomialBasisSpace(geo, degree=degree)
|
|
210
|
-
|
|
211
|
-
if isinstance(base_geo, _geometry.Quadmesh2D):
|
|
212
|
-
if degree == 0:
|
|
213
|
-
return Quadmesh2DPiecewiseConstantBasis(geo)
|
|
214
|
-
|
|
215
|
-
if element_basis == ElementBasis.SERENDIPITY and degree > 1:
|
|
216
|
-
if discontinuous:
|
|
217
|
-
return Quadmesh2DDGSerendipityBasisSpace(geo, degree=degree, family=family)
|
|
218
|
-
else:
|
|
219
|
-
return Quadmesh2DSerendipityBasisSpace(geo, degree=degree, family=family)
|
|
220
|
-
|
|
221
|
-
if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
222
|
-
return Quadmesh2DPolynomialBasisSpace(geo, degree=degree)
|
|
223
|
-
|
|
224
|
-
if discontinuous:
|
|
225
|
-
return Quadmesh2DDGBipolynomialBasisSpace(geo, degree=degree, family=family)
|
|
226
|
-
else:
|
|
227
|
-
return Quadmesh2DBipolynomialBasisSpace(geo, degree=degree, family=family)
|
|
228
|
-
|
|
229
|
-
if isinstance(base_geo, _geometry.Hexmesh):
|
|
230
|
-
if degree == 0:
|
|
231
|
-
return HexmeshPiecewiseConstantBasis(geo)
|
|
232
|
-
|
|
233
|
-
if element_basis == ElementBasis.SERENDIPITY and degree > 1:
|
|
234
|
-
if discontinuous:
|
|
235
|
-
return HexmeshDGSerendipityBasisSpace(geo, degree=degree, family=family)
|
|
236
|
-
else:
|
|
237
|
-
return HexmeshSerendipityBasisSpace(geo, degree=degree, family=family)
|
|
238
|
-
|
|
239
|
-
if element_basis == ElementBasis.NONCONFORMING_POLYNOMIAL:
|
|
240
|
-
return HexmeshPolynomialBasisSpace(geo, degree=degree)
|
|
241
|
-
|
|
242
|
-
if discontinuous:
|
|
243
|
-
return HexmeshDGTripolynomialBasisSpace(geo, degree=degree, family=family)
|
|
244
|
-
else:
|
|
245
|
-
return HexmeshTripolynomialBasisSpace(geo, degree=degree, family=family)
|
|
246
|
-
|
|
247
|
-
raise NotImplementedError()
|
|
115
|
+
topology = make_grid_2d_space_topology(geo, shape)
|
|
116
|
+
elif isinstance(base_geo, _geometry.Grid3D):
|
|
117
|
+
topology = make_grid_3d_space_topology(geo, shape)
|
|
118
|
+
elif isinstance(base_geo, _geometry.Trimesh2D):
|
|
119
|
+
topology = make_trimesh_2d_space_topology(geo, shape)
|
|
120
|
+
elif isinstance(base_geo, _geometry.Tetmesh):
|
|
121
|
+
topology = make_tetmesh_space_topology(geo, shape)
|
|
122
|
+
elif isinstance(base_geo, _geometry.Quadmesh2D):
|
|
123
|
+
topology = make_quadmesh_2d_space_topology(geo, shape)
|
|
124
|
+
elif isinstance(base_geo, _geometry.Hexmesh):
|
|
125
|
+
topology = make_hexmesh_space_topology(geo, shape)
|
|
126
|
+
elif isinstance(base_geo, _geometry.Nanogrid):
|
|
127
|
+
topology = make_nanogrid_space_topology(geo, shape)
|
|
128
|
+
|
|
129
|
+
if topology is None:
|
|
130
|
+
raise NotImplementedError(f"Unsupported geometry type {geo.name}")
|
|
131
|
+
|
|
132
|
+
return ShapeBasisSpace(topology, shape)
|
|
248
133
|
|
|
249
134
|
|
|
250
135
|
def make_collocated_function_space(
|
warp/fem/space/basis_space.py
CHANGED
|
@@ -394,6 +394,40 @@ class TraceBasisSpace(BasisSpace):
|
|
|
394
394
|
return self._topo == other._topo
|
|
395
395
|
|
|
396
396
|
|
|
397
|
+
class PiecewiseConstantBasisSpace(ShapeBasisSpace):
|
|
398
|
+
class Trace(TraceBasisSpace):
|
|
399
|
+
def make_node_coords_in_element(self):
|
|
400
|
+
# Makes the single node visible to all sides; useful for interpolating on boundaries
|
|
401
|
+
# For higher-order non-conforming elements direct interpolation on boundary is not possible,
|
|
402
|
+
# need to do proper integration then solve with mass matrix
|
|
403
|
+
|
|
404
|
+
CENTER_COORDS = Coords(self.geometry.reference_side().center())
|
|
405
|
+
|
|
406
|
+
@cache.dynamic_func(suffix=self._basis.name)
|
|
407
|
+
def trace_node_coords_in_element(
|
|
408
|
+
geo_side_arg: self.geometry.SideArg,
|
|
409
|
+
basis_arg: self.BasisArg,
|
|
410
|
+
element_index: ElementIndex,
|
|
411
|
+
node_index_in_elt: int,
|
|
412
|
+
):
|
|
413
|
+
return CENTER_COORDS
|
|
414
|
+
|
|
415
|
+
return trace_node_coords_in_element
|
|
416
|
+
|
|
417
|
+
def trace(self):
|
|
418
|
+
return PiecewiseConstantBasisSpace.Trace(self)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
def make_discontinuous_basis_space(geometry: Geometry, shape: ShapeFunction):
|
|
422
|
+
topology = DiscontinuousSpaceTopology(geometry, shape.NODES_PER_ELEMENT)
|
|
423
|
+
|
|
424
|
+
if shape.NODES_PER_ELEMENT == 1:
|
|
425
|
+
# piecewise-constant space
|
|
426
|
+
return PiecewiseConstantBasisSpace(topology=topology, shape=shape)
|
|
427
|
+
|
|
428
|
+
return ShapeBasisSpace(topology=topology, shape=shape)
|
|
429
|
+
|
|
430
|
+
|
|
397
431
|
class PointBasisSpace(BasisSpace):
|
|
398
432
|
"""An unstructured :class:`BasisSpace` that is non-zero at a finite set of points only.
|
|
399
433
|
|
|
@@ -36,7 +36,7 @@ class CollocatedFunctionSpace(FunctionSpace):
|
|
|
36
36
|
self.element_outer_weight_gradient = self._basis.make_element_outer_weight_gradient()
|
|
37
37
|
|
|
38
38
|
# For backward compatibility
|
|
39
|
-
if hasattr(basis, "node_grid"):
|
|
39
|
+
if hasattr(basis.topology, "node_grid"):
|
|
40
40
|
self.node_grid = basis.node_grid
|
|
41
41
|
if hasattr(basis, "node_triangulation"):
|
|
42
42
|
self.node_triangulation = basis.node_triangulation
|
|
@@ -3,22 +3,22 @@ import numpy as np
|
|
|
3
3
|
import warp as wp
|
|
4
4
|
from warp.fem import cache
|
|
5
5
|
from warp.fem.geometry import Grid2D
|
|
6
|
-
from warp.fem.polynomial import
|
|
7
|
-
from warp.fem.types import
|
|
6
|
+
from warp.fem.polynomial import is_closed
|
|
7
|
+
from warp.fem.types import ElementIndex
|
|
8
8
|
|
|
9
|
-
from .basis_space import ShapeBasisSpace, TraceBasisSpace
|
|
10
9
|
from .shape import (
|
|
11
|
-
ConstantShapeFunction,
|
|
12
10
|
ShapeFunction,
|
|
13
11
|
SquareBipolynomialShapeFunctions,
|
|
14
|
-
SquareNonConformingPolynomialShapeFunctions,
|
|
15
12
|
SquareSerendipityShapeFunctions,
|
|
16
13
|
)
|
|
17
|
-
from .topology import
|
|
14
|
+
from .topology import SpaceTopology, forward_base_topology
|
|
18
15
|
|
|
19
16
|
|
|
20
17
|
class Grid2DSpaceTopology(SpaceTopology):
|
|
21
18
|
def __init__(self, grid: Grid2D, shape: ShapeFunction):
|
|
19
|
+
if not is_closed(shape.family):
|
|
20
|
+
raise ValueError("A closed polynomial family is required to define a continuous function space")
|
|
21
|
+
|
|
22
22
|
super().__init__(grid, shape.NODES_PER_ELEMENT)
|
|
23
23
|
self._shape = shape
|
|
24
24
|
|
|
@@ -37,53 +37,6 @@ class Grid2DSpaceTopology(SpaceTopology):
|
|
|
37
37
|
return Grid2D._from_2d_index(x_stride, corner)
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
class Grid2DDiscontinuousSpaceTopology(
|
|
41
|
-
DiscontinuousSpaceTopologyMixin,
|
|
42
|
-
Grid2DSpaceTopology,
|
|
43
|
-
):
|
|
44
|
-
pass
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class Grid2DBasisSpace(ShapeBasisSpace):
|
|
48
|
-
def __init__(self, topology: Grid2DSpaceTopology, shape: ShapeFunction):
|
|
49
|
-
super().__init__(topology, shape)
|
|
50
|
-
|
|
51
|
-
self._grid: Grid2D = topology.geometry
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class GridPiecewiseConstantBasis(Grid2DBasisSpace):
|
|
55
|
-
def __init__(self, grid: Grid2D):
|
|
56
|
-
shape = ConstantShapeFunction(grid.reference_cell(), space_dimension=2)
|
|
57
|
-
topology = Grid2DDiscontinuousSpaceTopology(grid, shape)
|
|
58
|
-
super().__init__(shape=shape, topology=topology)
|
|
59
|
-
|
|
60
|
-
if isinstance(grid, Grid2D):
|
|
61
|
-
self.node_grid = self._node_grid
|
|
62
|
-
|
|
63
|
-
def _node_grid(self):
|
|
64
|
-
res = self._grid.res
|
|
65
|
-
|
|
66
|
-
X = (np.arange(0, res[0], dtype=float) + 0.5) * self._grid.cell_size[0] + self._grid.origin[0]
|
|
67
|
-
Y = (np.arange(0, res[1], dtype=float) + 0.5) * self._grid.cell_size[1] + self._grid.origin[1]
|
|
68
|
-
return np.meshgrid(X, Y, indexing="ij")
|
|
69
|
-
|
|
70
|
-
class Trace(TraceBasisSpace):
|
|
71
|
-
@wp.func
|
|
72
|
-
def _node_coords_in_element(
|
|
73
|
-
side_arg: Grid2D.SideArg,
|
|
74
|
-
basis_arg: Grid2DBasisSpace.BasisArg,
|
|
75
|
-
element_index: ElementIndex,
|
|
76
|
-
node_index_in_element: int,
|
|
77
|
-
):
|
|
78
|
-
return Coords(0.5, 0.0, 0.0)
|
|
79
|
-
|
|
80
|
-
def make_node_coords_in_element(self):
|
|
81
|
-
return self._node_coords_in_element
|
|
82
|
-
|
|
83
|
-
def trace(self):
|
|
84
|
-
return GridPiecewiseConstantBasis.Trace(self)
|
|
85
|
-
|
|
86
|
-
|
|
87
40
|
class GridBipolynomialSpaceTopology(Grid2DSpaceTopology):
|
|
88
41
|
def __init__(self, grid: Grid2D, shape: SquareBipolynomialShapeFunctions):
|
|
89
42
|
super().__init__(grid, shape)
|
|
@@ -119,30 +72,8 @@ class GridBipolynomialSpaceTopology(Grid2DSpaceTopology):
|
|
|
119
72
|
|
|
120
73
|
return element_node_index
|
|
121
74
|
|
|
122
|
-
|
|
123
|
-
class GridBipolynomialBasisSpace(Grid2DBasisSpace):
|
|
124
|
-
def __init__(
|
|
125
|
-
self,
|
|
126
|
-
grid: Grid2D,
|
|
127
|
-
degree: int,
|
|
128
|
-
family: Polynomial,
|
|
129
|
-
):
|
|
130
|
-
if family is None:
|
|
131
|
-
family = Polynomial.LOBATTO_GAUSS_LEGENDRE
|
|
132
|
-
|
|
133
|
-
if not is_closed(family):
|
|
134
|
-
raise ValueError("A closed polynomial family is required to define a continuous function space")
|
|
135
|
-
|
|
136
|
-
shape = SquareBipolynomialShapeFunctions(degree, family=family)
|
|
137
|
-
topology = forward_base_topology(GridBipolynomialSpaceTopology, grid, shape)
|
|
138
|
-
|
|
139
|
-
super().__init__(topology, shape)
|
|
140
|
-
|
|
141
|
-
if isinstance(grid, Grid2D):
|
|
142
|
-
self.node_grid = self._node_grid
|
|
143
|
-
|
|
144
75
|
def _node_grid(self):
|
|
145
|
-
res = self.
|
|
76
|
+
res = self.geometry.res
|
|
146
77
|
|
|
147
78
|
cell_coords = np.array(self._shape.LOBATTO_COORDS)[:-1]
|
|
148
79
|
|
|
@@ -161,22 +92,6 @@ class GridBipolynomialBasisSpace(Grid2DBasisSpace):
|
|
|
161
92
|
return np.meshgrid(X, Y, indexing="ij")
|
|
162
93
|
|
|
163
94
|
|
|
164
|
-
class GridDGBipolynomialBasisSpace(Grid2DBasisSpace):
|
|
165
|
-
def __init__(
|
|
166
|
-
self,
|
|
167
|
-
grid: Grid2D,
|
|
168
|
-
degree: int,
|
|
169
|
-
family: Polynomial,
|
|
170
|
-
):
|
|
171
|
-
if family is None:
|
|
172
|
-
family = Polynomial.LOBATTO_GAUSS_LEGENDRE
|
|
173
|
-
|
|
174
|
-
shape = SquareBipolynomialShapeFunctions(degree, family=family)
|
|
175
|
-
topology = Grid2DDiscontinuousSpaceTopology(grid, shape)
|
|
176
|
-
|
|
177
|
-
super().__init__(shape=shape, topology=topology)
|
|
178
|
-
|
|
179
|
-
|
|
180
95
|
class GridSerendipitySpaceTopology(Grid2DSpaceTopology):
|
|
181
96
|
def __init__(self, grid: Grid2D, shape: SquareSerendipityShapeFunctions):
|
|
182
97
|
super().__init__(grid, shape)
|
|
@@ -223,45 +138,11 @@ class GridSerendipitySpaceTopology(Grid2DSpaceTopology):
|
|
|
223
138
|
return element_node_index
|
|
224
139
|
|
|
225
140
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
grid: Grid2D,
|
|
230
|
-
degree: int,
|
|
231
|
-
family: Polynomial,
|
|
232
|
-
):
|
|
233
|
-
if family is None:
|
|
234
|
-
family = Polynomial.LOBATTO_GAUSS_LEGENDRE
|
|
235
|
-
|
|
236
|
-
shape = SquareSerendipityShapeFunctions(degree, family=family)
|
|
237
|
-
topology = forward_base_topology(GridSerendipitySpaceTopology, grid, shape=shape)
|
|
238
|
-
|
|
239
|
-
super().__init__(topology=topology, shape=shape)
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
class GridDGSerendipityBasisSpace(Grid2DBasisSpace):
|
|
243
|
-
def __init__(
|
|
244
|
-
self,
|
|
245
|
-
grid: Grid2D,
|
|
246
|
-
degree: int,
|
|
247
|
-
family: Polynomial,
|
|
248
|
-
):
|
|
249
|
-
if family is None:
|
|
250
|
-
family = Polynomial.LOBATTO_GAUSS_LEGENDRE
|
|
251
|
-
|
|
252
|
-
shape = SquareSerendipityShapeFunctions(degree, family=family)
|
|
253
|
-
topology = Grid2DDiscontinuousSpaceTopology(grid, shape=shape)
|
|
254
|
-
|
|
255
|
-
super().__init__(topology=topology, shape=shape)
|
|
256
|
-
|
|
141
|
+
def make_grid_2d_space_topology(grid: Grid2D, shape: ShapeFunction):
|
|
142
|
+
if isinstance(shape, SquareSerendipityShapeFunctions):
|
|
143
|
+
return forward_base_topology(GridSerendipitySpaceTopology, grid, shape)
|
|
257
144
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
self,
|
|
261
|
-
grid: Grid2D,
|
|
262
|
-
degree: int,
|
|
263
|
-
):
|
|
264
|
-
shape = SquareNonConformingPolynomialShapeFunctions(degree)
|
|
265
|
-
topology = Grid2DDiscontinuousSpaceTopology(grid, shape=shape)
|
|
145
|
+
if isinstance(shape, SquareBipolynomialShapeFunctions):
|
|
146
|
+
return forward_base_topology(GridBipolynomialSpaceTopology, grid, shape)
|
|
266
147
|
|
|
267
|
-
|
|
148
|
+
raise ValueError(f"Unsupported shape function {shape.name}")
|
|
@@ -3,23 +3,25 @@ import numpy as np
|
|
|
3
3
|
import warp as wp
|
|
4
4
|
from warp.fem import cache
|
|
5
5
|
from warp.fem.geometry import Grid3D
|
|
6
|
-
from warp.fem.polynomial import
|
|
7
|
-
from warp.fem.types import
|
|
6
|
+
from warp.fem.polynomial import is_closed
|
|
7
|
+
from warp.fem.types import ElementIndex
|
|
8
8
|
|
|
9
|
-
from .
|
|
10
|
-
from .shape import ConstantShapeFunction, ShapeFunction
|
|
11
|
-
from .shape.cube_shape_function import (
|
|
12
|
-
CubeNonConformingPolynomialShapeFunctions,
|
|
9
|
+
from .shape import (
|
|
13
10
|
CubeSerendipityShapeFunctions,
|
|
14
11
|
CubeTripolynomialShapeFunctions,
|
|
12
|
+
ShapeFunction,
|
|
15
13
|
)
|
|
16
|
-
from .topology import
|
|
14
|
+
from .topology import SpaceTopology, forward_base_topology
|
|
17
15
|
|
|
18
16
|
|
|
19
17
|
class Grid3DSpaceTopology(SpaceTopology):
|
|
20
18
|
def __init__(self, grid: Grid3D, shape: ShapeFunction):
|
|
19
|
+
if not is_closed(shape.family):
|
|
20
|
+
raise ValueError("A closed polynomial family is required to define a continuous function space")
|
|
21
|
+
|
|
21
22
|
super().__init__(grid, shape.NODES_PER_ELEMENT)
|
|
22
23
|
self._shape = shape
|
|
24
|
+
self._grid = grid
|
|
23
25
|
|
|
24
26
|
@wp.func
|
|
25
27
|
def _vertex_coords(vidx_in_cell: int):
|
|
@@ -37,52 +39,6 @@ class Grid3DSpaceTopology(SpaceTopology):
|
|
|
37
39
|
return Grid3D._from_3d_index(strides, corner)
|
|
38
40
|
|
|
39
41
|
|
|
40
|
-
class Grid3DDiscontinuousSpaceTopology(
|
|
41
|
-
DiscontinuousSpaceTopologyMixin,
|
|
42
|
-
Grid3DSpaceTopology,
|
|
43
|
-
):
|
|
44
|
-
pass
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class Grid3DBasisSpace(ShapeBasisSpace):
|
|
48
|
-
def __init__(self, topology: Grid3DSpaceTopology, shape: ShapeFunction):
|
|
49
|
-
super().__init__(topology, shape)
|
|
50
|
-
|
|
51
|
-
self._grid: Grid3D = topology.geometry
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class Grid3DPiecewiseConstantBasis(Grid3DBasisSpace):
|
|
55
|
-
def __init__(self, grid: Grid3D):
|
|
56
|
-
shape = ConstantShapeFunction(grid.reference_cell(), space_dimension=3)
|
|
57
|
-
topology = Grid3DDiscontinuousSpaceTopology(grid, shape)
|
|
58
|
-
super().__init__(shape=shape, topology=topology)
|
|
59
|
-
|
|
60
|
-
if isinstance(grid, Grid3D):
|
|
61
|
-
self.node_grid = self._node_grid
|
|
62
|
-
|
|
63
|
-
def _node_grid(self):
|
|
64
|
-
X = (np.arange(0, self.geometry.res[0], dtype=float) + 0.5) * self._grid.cell_size[0] + self._grid.bounds_lo[0]
|
|
65
|
-
Y = (np.arange(0, self.geometry.res[1], dtype=float) + 0.5) * self._grid.cell_size[1] + self._grid.bounds_lo[1]
|
|
66
|
-
Z = (np.arange(0, self.geometry.res[2], dtype=float) + 0.5) * self._grid.cell_size[2] + self._grid.bounds_lo[2]
|
|
67
|
-
return np.meshgrid(X, Y, Z, indexing="ij")
|
|
68
|
-
|
|
69
|
-
class Trace(TraceBasisSpace):
|
|
70
|
-
@wp.func
|
|
71
|
-
def _node_coords_in_element(
|
|
72
|
-
side_arg: Grid3D.SideArg,
|
|
73
|
-
basis_arg: Grid3DBasisSpace.BasisArg,
|
|
74
|
-
element_index: ElementIndex,
|
|
75
|
-
node_index_in_element: int,
|
|
76
|
-
):
|
|
77
|
-
return Coords(0.5, 0.5, 0.0)
|
|
78
|
-
|
|
79
|
-
def make_node_coords_in_element(self):
|
|
80
|
-
return self._node_coords_in_element
|
|
81
|
-
|
|
82
|
-
def trace(self):
|
|
83
|
-
return Grid3DPiecewiseConstantBasis.Trace(self)
|
|
84
|
-
|
|
85
|
-
|
|
86
42
|
class GridTripolynomialSpaceTopology(Grid3DSpaceTopology):
|
|
87
43
|
def __init__(self, grid: Grid3D, shape: CubeTripolynomialShapeFunctions):
|
|
88
44
|
super().__init__(grid, shape)
|
|
@@ -123,30 +79,8 @@ class GridTripolynomialSpaceTopology(Grid3DSpaceTopology):
|
|
|
123
79
|
|
|
124
80
|
return element_node_index
|
|
125
81
|
|
|
126
|
-
|
|
127
|
-
class GridTripolynomialBasisSpace(Grid3DBasisSpace):
|
|
128
|
-
def __init__(
|
|
129
|
-
self,
|
|
130
|
-
grid: Grid3D,
|
|
131
|
-
degree: int,
|
|
132
|
-
family: Polynomial,
|
|
133
|
-
):
|
|
134
|
-
if family is None:
|
|
135
|
-
family = Polynomial.LOBATTO_GAUSS_LEGENDRE
|
|
136
|
-
|
|
137
|
-
if not is_closed(family):
|
|
138
|
-
raise ValueError("A closed polynomial family is required to define a continuous function space")
|
|
139
|
-
|
|
140
|
-
shape = CubeTripolynomialShapeFunctions(degree, family=family)
|
|
141
|
-
topology = forward_base_topology(GridTripolynomialSpaceTopology, grid, shape)
|
|
142
|
-
|
|
143
|
-
super().__init__(topology, shape)
|
|
144
|
-
|
|
145
|
-
if isinstance(grid, Grid3D):
|
|
146
|
-
self.node_grid = self._node_grid
|
|
147
|
-
|
|
148
82
|
def _node_grid(self):
|
|
149
|
-
res = self.
|
|
83
|
+
res = self.geometry.res
|
|
150
84
|
|
|
151
85
|
cell_coords = np.array(self._shape.LOBATTO_COORDS)[:-1]
|
|
152
86
|
|
|
@@ -171,44 +105,6 @@ class GridTripolynomialBasisSpace(Grid3DBasisSpace):
|
|
|
171
105
|
return np.meshgrid(X, Y, Z, indexing="ij")
|
|
172
106
|
|
|
173
107
|
|
|
174
|
-
class GridDGTripolynomialBasisSpace(Grid3DBasisSpace):
|
|
175
|
-
def __init__(
|
|
176
|
-
self,
|
|
177
|
-
grid: Grid3D,
|
|
178
|
-
degree: int,
|
|
179
|
-
family: Polynomial,
|
|
180
|
-
):
|
|
181
|
-
if family is None:
|
|
182
|
-
family = Polynomial.LOBATTO_GAUSS_LEGENDRE
|
|
183
|
-
|
|
184
|
-
shape = CubeTripolynomialShapeFunctions(degree, family=family)
|
|
185
|
-
topology = Grid3DDiscontinuousSpaceTopology(grid, shape)
|
|
186
|
-
|
|
187
|
-
super().__init__(shape=shape, topology=topology)
|
|
188
|
-
|
|
189
|
-
def node_grid(self):
|
|
190
|
-
res = self._grid.res
|
|
191
|
-
|
|
192
|
-
cell_coords = np.array(self._shape.LOBATTO_COORDS)
|
|
193
|
-
|
|
194
|
-
grid_coords_x = np.repeat(np.arange(0, res[0], dtype=float), len(cell_coords)) + np.tile(
|
|
195
|
-
cell_coords, reps=res[0]
|
|
196
|
-
)
|
|
197
|
-
X = grid_coords_x * self._grid.cell_size[0] + self._grid.origin[0]
|
|
198
|
-
|
|
199
|
-
grid_coords_y = np.repeat(np.arange(0, res[1], dtype=float), len(cell_coords)) + np.tile(
|
|
200
|
-
cell_coords, reps=res[1]
|
|
201
|
-
)
|
|
202
|
-
Y = grid_coords_y * self._grid.cell_size[1] + self._grid.origin[1]
|
|
203
|
-
|
|
204
|
-
grid_coords_z = np.repeat(np.arange(0, res[2], dtype=float), len(cell_coords)) + np.tile(
|
|
205
|
-
cell_coords, reps=res[2]
|
|
206
|
-
)
|
|
207
|
-
Z = grid_coords_z * self._grid.cell_size[2] + self._grid.origin[2]
|
|
208
|
-
|
|
209
|
-
return np.meshgrid(X, Y, Z, indexing="ij")
|
|
210
|
-
|
|
211
|
-
|
|
212
108
|
class Grid3DSerendipitySpaceTopology(Grid3DSpaceTopology):
|
|
213
109
|
def __init__(self, grid: Grid3D, shape: CubeSerendipityShapeFunctions):
|
|
214
110
|
super().__init__(grid, shape)
|
|
@@ -261,45 +157,11 @@ class Grid3DSerendipitySpaceTopology(Grid3DSpaceTopology):
|
|
|
261
157
|
return element_node_index
|
|
262
158
|
|
|
263
159
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
grid: Grid3D,
|
|
268
|
-
degree: int,
|
|
269
|
-
family: Polynomial,
|
|
270
|
-
):
|
|
271
|
-
if family is None:
|
|
272
|
-
family = Polynomial.LOBATTO_GAUSS_LEGENDRE
|
|
273
|
-
|
|
274
|
-
shape = CubeSerendipityShapeFunctions(degree, family=family)
|
|
275
|
-
topology = forward_base_topology(Grid3DSerendipitySpaceTopology, grid, shape=shape)
|
|
276
|
-
|
|
277
|
-
super().__init__(topology=topology, shape=shape)
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
class Grid3DDGSerendipityBasisSpace(Grid3DBasisSpace):
|
|
281
|
-
def __init__(
|
|
282
|
-
self,
|
|
283
|
-
grid: Grid3D,
|
|
284
|
-
degree: int,
|
|
285
|
-
family: Polynomial,
|
|
286
|
-
):
|
|
287
|
-
if family is None:
|
|
288
|
-
family = Polynomial.LOBATTO_GAUSS_LEGENDRE
|
|
289
|
-
|
|
290
|
-
shape = CubeSerendipityShapeFunctions(degree, family=family)
|
|
291
|
-
topology = Grid3DDiscontinuousSpaceTopology(grid, shape=shape)
|
|
292
|
-
|
|
293
|
-
super().__init__(topology=topology, shape=shape)
|
|
294
|
-
|
|
160
|
+
def make_grid_3d_space_topology(grid: Grid3D, shape: ShapeFunction):
|
|
161
|
+
if isinstance(shape, CubeSerendipityShapeFunctions):
|
|
162
|
+
return forward_base_topology(Grid3DSerendipitySpaceTopology, grid, shape)
|
|
295
163
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
self,
|
|
299
|
-
grid: Grid3D,
|
|
300
|
-
degree: int,
|
|
301
|
-
):
|
|
302
|
-
shape = CubeNonConformingPolynomialShapeFunctions(degree)
|
|
303
|
-
topology = Grid3DDiscontinuousSpaceTopology(grid, shape=shape)
|
|
164
|
+
if isinstance(shape, CubeTripolynomialShapeFunctions):
|
|
165
|
+
return forward_base_topology(GridTripolynomialSpaceTopology, grid, shape)
|
|
304
166
|
|
|
305
|
-
|
|
167
|
+
raise ValueError(f"Unsupported shape function {shape.name}")
|