warp-lang 1.4.2__py3-none-macosx_10_13_universal2.whl → 1.5.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/__init__.py +4 -0
- warp/autograd.py +43 -8
- warp/bin/libwarp.dylib +0 -0
- warp/build.py +21 -2
- warp/build_dll.py +23 -6
- warp/builtins.py +1819 -7
- warp/codegen.py +197 -61
- warp/config.py +2 -2
- warp/context.py +379 -107
- warp/examples/assets/pixel.jpg +0 -0
- warp/examples/benchmarks/benchmark_cloth_paddle.py +86 -0
- warp/examples/benchmarks/benchmark_gemm.py +121 -0
- warp/examples/benchmarks/benchmark_interop_paddle.py +158 -0
- warp/examples/benchmarks/benchmark_tile.py +179 -0
- warp/examples/fem/example_adaptive_grid.py +37 -10
- warp/examples/fem/example_apic_fluid.py +3 -2
- warp/examples/fem/example_convection_diffusion_dg.py +4 -5
- warp/examples/fem/example_deformed_geometry.py +1 -1
- warp/examples/fem/example_diffusion_3d.py +47 -4
- warp/examples/fem/example_distortion_energy.py +220 -0
- warp/examples/fem/example_magnetostatics.py +127 -85
- warp/examples/fem/example_nonconforming_contact.py +5 -5
- warp/examples/fem/example_stokes.py +3 -1
- warp/examples/fem/example_streamlines.py +12 -19
- warp/examples/fem/utils.py +38 -15
- warp/examples/sim/example_cloth.py +4 -25
- warp/examples/sim/example_quadruped.py +2 -1
- warp/examples/tile/example_tile_convolution.py +58 -0
- warp/examples/tile/example_tile_fft.py +47 -0
- warp/examples/tile/example_tile_filtering.py +105 -0
- warp/examples/tile/example_tile_matmul.py +79 -0
- warp/examples/tile/example_tile_mlp.py +375 -0
- warp/fem/__init__.py +8 -0
- warp/fem/cache.py +16 -12
- warp/fem/dirichlet.py +1 -1
- warp/fem/domain.py +44 -1
- warp/fem/field/__init__.py +1 -2
- warp/fem/field/field.py +31 -19
- warp/fem/field/nodal_field.py +101 -49
- warp/fem/field/virtual.py +794 -0
- warp/fem/geometry/__init__.py +2 -2
- warp/fem/geometry/deformed_geometry.py +3 -105
- warp/fem/geometry/element.py +13 -0
- warp/fem/geometry/geometry.py +165 -7
- warp/fem/geometry/grid_2d.py +3 -6
- warp/fem/geometry/grid_3d.py +31 -28
- warp/fem/geometry/hexmesh.py +3 -46
- warp/fem/geometry/nanogrid.py +3 -2
- warp/fem/geometry/{quadmesh_2d.py → quadmesh.py} +280 -159
- warp/fem/geometry/tetmesh.py +2 -43
- warp/fem/geometry/{trimesh_2d.py → trimesh.py} +354 -186
- warp/fem/integrate.py +683 -261
- warp/fem/linalg.py +404 -0
- warp/fem/operator.py +101 -18
- warp/fem/polynomial.py +5 -5
- warp/fem/quadrature/quadrature.py +45 -21
- warp/fem/space/__init__.py +45 -11
- warp/fem/space/basis_function_space.py +451 -0
- warp/fem/space/basis_space.py +58 -11
- warp/fem/space/function_space.py +146 -5
- warp/fem/space/grid_2d_function_space.py +80 -66
- warp/fem/space/grid_3d_function_space.py +113 -68
- warp/fem/space/hexmesh_function_space.py +96 -108
- warp/fem/space/nanogrid_function_space.py +62 -110
- warp/fem/space/quadmesh_function_space.py +208 -0
- warp/fem/space/shape/__init__.py +45 -7
- warp/fem/space/shape/cube_shape_function.py +328 -54
- warp/fem/space/shape/shape_function.py +10 -1
- warp/fem/space/shape/square_shape_function.py +328 -60
- warp/fem/space/shape/tet_shape_function.py +269 -19
- warp/fem/space/shape/triangle_shape_function.py +238 -19
- warp/fem/space/tetmesh_function_space.py +69 -37
- warp/fem/space/topology.py +38 -0
- warp/fem/space/trimesh_function_space.py +179 -0
- warp/fem/utils.py +6 -331
- warp/jax_experimental.py +3 -1
- warp/native/array.h +15 -0
- warp/native/builtin.h +66 -26
- warp/native/bvh.h +4 -0
- warp/native/coloring.cpp +604 -0
- warp/native/cuda_util.cpp +68 -51
- warp/native/cuda_util.h +2 -1
- warp/native/fabric.h +8 -0
- warp/native/hashgrid.h +4 -0
- warp/native/marching.cu +8 -0
- warp/native/mat.h +14 -3
- warp/native/mathdx.cpp +59 -0
- warp/native/mesh.h +4 -0
- warp/native/range.h +13 -1
- warp/native/reduce.cpp +9 -1
- warp/native/reduce.cu +7 -0
- warp/native/runlength_encode.cpp +9 -1
- warp/native/runlength_encode.cu +7 -1
- warp/native/scan.cpp +8 -0
- warp/native/scan.cu +8 -0
- warp/native/scan.h +8 -1
- warp/native/sparse.cpp +8 -0
- warp/native/sparse.cu +8 -0
- warp/native/temp_buffer.h +7 -0
- warp/native/tile.h +1854 -0
- warp/native/tile_gemm.h +341 -0
- warp/native/tile_reduce.h +210 -0
- warp/native/volume_builder.cu +8 -0
- warp/native/volume_builder.h +8 -0
- warp/native/warp.cpp +10 -2
- warp/native/warp.cu +369 -15
- warp/native/warp.h +12 -2
- warp/optim/adam.py +39 -4
- warp/paddle.py +29 -12
- warp/render/render_opengl.py +140 -67
- warp/sim/graph_coloring.py +292 -0
- warp/sim/import_urdf.py +8 -8
- warp/sim/integrator_euler.py +4 -2
- warp/sim/integrator_featherstone.py +115 -44
- warp/sim/integrator_vbd.py +6 -0
- warp/sim/model.py +109 -32
- warp/sparse.py +1 -1
- warp/stubs.py +569 -4
- warp/tape.py +12 -7
- warp/tests/assets/pixel.npy +0 -0
- warp/tests/aux_test_instancing_gc.py +18 -0
- warp/tests/test_array.py +39 -0
- warp/tests/test_codegen.py +81 -1
- warp/tests/test_codegen_instancing.py +30 -0
- warp/tests/test_collision.py +110 -0
- warp/tests/test_coloring.py +251 -0
- warp/tests/test_context.py +34 -0
- warp/tests/test_examples.py +21 -5
- warp/tests/test_fem.py +453 -113
- warp/tests/test_func.py +34 -4
- warp/tests/test_generics.py +52 -0
- warp/tests/test_iter.py +68 -0
- warp/tests/test_lerp.py +13 -87
- warp/tests/test_mat_scalar_ops.py +1 -1
- warp/tests/test_matmul.py +6 -9
- warp/tests/test_matmul_lite.py +6 -11
- warp/tests/test_mesh_query_point.py +1 -1
- warp/tests/test_module_hashing.py +23 -0
- warp/tests/test_overwrite.py +45 -0
- warp/tests/test_paddle.py +27 -87
- warp/tests/test_print.py +56 -1
- warp/tests/test_smoothstep.py +17 -83
- warp/tests/test_spatial.py +1 -1
- warp/tests/test_static.py +3 -3
- warp/tests/test_tile.py +744 -0
- warp/tests/test_tile_mathdx.py +144 -0
- warp/tests/test_tile_mlp.py +383 -0
- warp/tests/test_tile_reduce.py +374 -0
- warp/tests/test_tile_shared_memory.py +190 -0
- warp/tests/test_vbd.py +12 -20
- warp/tests/test_volume.py +43 -0
- warp/tests/unittest_suites.py +19 -2
- warp/tests/unittest_utils.py +4 -2
- warp/types.py +340 -74
- warp/utils.py +23 -3
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.1.dist-info}/METADATA +32 -7
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.1.dist-info}/RECORD +160 -133
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.1.dist-info}/WHEEL +1 -1
- warp/fem/field/test.py +0 -180
- warp/fem/field/trial.py +0 -183
- warp/fem/space/collocated_function_space.py +0 -102
- warp/fem/space/quadmesh_2d_function_space.py +0 -261
- warp/fem/space/trimesh_2d_function_space.py +0 -153
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.1.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.4.2.dist-info → warp_lang-1.5.1.dist-info}/top_level.txt +0 -0
warp/fem/field/test.py
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import warp as wp
|
|
2
|
-
from warp.fem import cache, utils
|
|
3
|
-
from warp.fem.space import FunctionSpace, SpaceRestriction
|
|
4
|
-
from warp.fem.types import Sample, get_node_index_in_element
|
|
5
|
-
|
|
6
|
-
from .field import SpaceField
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TestField(SpaceField):
|
|
10
|
-
"""Field defined over a space restriction that can be used as a test function.
|
|
11
|
-
|
|
12
|
-
In order to reuse computations, it is possible to define the test field using a SpaceRestriction
|
|
13
|
-
defined for a different value type than the test function value type, as long as the node topology is similar.
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
def __init__(self, space_restriction: SpaceRestriction, space: FunctionSpace):
|
|
17
|
-
if space_restriction.domain.dimension == space.dimension - 1:
|
|
18
|
-
space = space.trace()
|
|
19
|
-
|
|
20
|
-
if space_restriction.domain.dimension != space.dimension:
|
|
21
|
-
raise ValueError("Incompatible space and domain dimensions")
|
|
22
|
-
|
|
23
|
-
if space.topology != space_restriction.space_topology:
|
|
24
|
-
raise ValueError("Incompatible space and space partition topologies")
|
|
25
|
-
|
|
26
|
-
super().__init__(space, space_restriction.space_partition)
|
|
27
|
-
|
|
28
|
-
self.space_restriction = space_restriction
|
|
29
|
-
self.domain = self.space_restriction.domain
|
|
30
|
-
|
|
31
|
-
self.EvalArg = self.space.SpaceArg
|
|
32
|
-
self.ElementEvalArg = self._make_element_eval_arg()
|
|
33
|
-
|
|
34
|
-
self.eval_degree = self._make_eval_degree()
|
|
35
|
-
self.eval_inner = self._make_eval_inner()
|
|
36
|
-
self.eval_grad_inner = self._make_eval_grad_inner()
|
|
37
|
-
self.eval_div_inner = self._make_eval_div_inner()
|
|
38
|
-
self.eval_outer = self._make_eval_outer()
|
|
39
|
-
self.eval_grad_outer = self._make_eval_grad_outer()
|
|
40
|
-
self.eval_div_outer = self._make_eval_div_outer()
|
|
41
|
-
self.at_node = self._make_at_node()
|
|
42
|
-
|
|
43
|
-
@property
|
|
44
|
-
def name(self) -> str:
|
|
45
|
-
return self.space.name + "Test"
|
|
46
|
-
|
|
47
|
-
def eval_arg_value(self, device) -> wp.codegen.StructInstance:
|
|
48
|
-
return self.space.space_arg_value(device)
|
|
49
|
-
|
|
50
|
-
def _make_element_eval_arg(self):
|
|
51
|
-
from warp.fem import cache
|
|
52
|
-
|
|
53
|
-
@cache.dynamic_struct(suffix=self.name)
|
|
54
|
-
class ElementEvalArg:
|
|
55
|
-
elt_arg: self.domain.ElementArg
|
|
56
|
-
eval_arg: self.EvalArg
|
|
57
|
-
|
|
58
|
-
return ElementEvalArg
|
|
59
|
-
|
|
60
|
-
def _make_eval_inner(self):
|
|
61
|
-
@cache.dynamic_func(suffix=self.name)
|
|
62
|
-
def eval_test_inner(args: self.ElementEvalArg, s: Sample):
|
|
63
|
-
weight = self.space.element_inner_weight(
|
|
64
|
-
args.elt_arg,
|
|
65
|
-
args.eval_arg,
|
|
66
|
-
s.element_index,
|
|
67
|
-
s.element_coords,
|
|
68
|
-
get_node_index_in_element(s.test_dof),
|
|
69
|
-
)
|
|
70
|
-
return weight * self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.test_dof)
|
|
71
|
-
|
|
72
|
-
return eval_test_inner
|
|
73
|
-
|
|
74
|
-
def _make_eval_grad_inner(self):
|
|
75
|
-
if not self.gradient_valid():
|
|
76
|
-
return None
|
|
77
|
-
|
|
78
|
-
@cache.dynamic_func(suffix=self.name)
|
|
79
|
-
def eval_nabla_test_inner(args: self.ElementEvalArg, s: Sample):
|
|
80
|
-
nabla_weight = self.space.element_inner_weight_gradient(
|
|
81
|
-
args.elt_arg,
|
|
82
|
-
args.eval_arg,
|
|
83
|
-
s.element_index,
|
|
84
|
-
s.element_coords,
|
|
85
|
-
get_node_index_in_element(s.test_dof),
|
|
86
|
-
)
|
|
87
|
-
grad_transform = self.space.element_inner_reference_gradient_transform(args.elt_arg, s)
|
|
88
|
-
return utils.generalized_outer(
|
|
89
|
-
self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.test_dof),
|
|
90
|
-
nabla_weight * grad_transform,
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
return eval_nabla_test_inner
|
|
94
|
-
|
|
95
|
-
def _make_eval_div_inner(self):
|
|
96
|
-
if not self.divergence_valid():
|
|
97
|
-
return None
|
|
98
|
-
|
|
99
|
-
@cache.dynamic_func(suffix=self.name)
|
|
100
|
-
def eval_div_test_inner(args: self.ElementEvalArg, s: Sample):
|
|
101
|
-
nabla_weight = self.space.element_inner_weight_gradient(
|
|
102
|
-
args.elt_arg,
|
|
103
|
-
args.eval_arg,
|
|
104
|
-
s.element_index,
|
|
105
|
-
s.element_coords,
|
|
106
|
-
get_node_index_in_element(s.test_dof),
|
|
107
|
-
)
|
|
108
|
-
grad_transform = self.space.element_inner_reference_gradient_transform(args.elt_arg, s)
|
|
109
|
-
return utils.generalized_inner(
|
|
110
|
-
self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.test_dof),
|
|
111
|
-
nabla_weight * grad_transform,
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
return eval_div_test_inner
|
|
115
|
-
|
|
116
|
-
def _make_eval_outer(self):
|
|
117
|
-
@cache.dynamic_func(suffix=self.name)
|
|
118
|
-
def eval_test_outer(args: self.ElementEvalArg, s: Sample):
|
|
119
|
-
weight = self.space.element_outer_weight(
|
|
120
|
-
args.elt_arg,
|
|
121
|
-
args.eval_arg,
|
|
122
|
-
s.element_index,
|
|
123
|
-
s.element_coords,
|
|
124
|
-
get_node_index_in_element(s.test_dof),
|
|
125
|
-
)
|
|
126
|
-
return weight * self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.test_dof)
|
|
127
|
-
|
|
128
|
-
return eval_test_outer
|
|
129
|
-
|
|
130
|
-
def _make_eval_grad_outer(self):
|
|
131
|
-
if not self.gradient_valid():
|
|
132
|
-
return None
|
|
133
|
-
|
|
134
|
-
@cache.dynamic_func(suffix=self.name)
|
|
135
|
-
def eval_nabla_test_outer(args: self.ElementEvalArg, s: Sample):
|
|
136
|
-
nabla_weight = self.space.element_outer_weight_gradient(
|
|
137
|
-
args.elt_arg,
|
|
138
|
-
args.eval_arg,
|
|
139
|
-
s.element_index,
|
|
140
|
-
s.element_coords,
|
|
141
|
-
get_node_index_in_element(s.test_dof),
|
|
142
|
-
)
|
|
143
|
-
grad_transform = self.space.element_outer_reference_gradient_transform(args.elt_arg, s)
|
|
144
|
-
return utils.generalized_outer(
|
|
145
|
-
self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.test_dof),
|
|
146
|
-
nabla_weight * grad_transform,
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
return eval_nabla_test_outer
|
|
150
|
-
|
|
151
|
-
def _make_eval_div_outer(self):
|
|
152
|
-
if not self.divergence_valid():
|
|
153
|
-
return None
|
|
154
|
-
|
|
155
|
-
@cache.dynamic_func(suffix=self.name)
|
|
156
|
-
def eval_div_test_outer(args: self.ElementEvalArg, s: Sample):
|
|
157
|
-
nabla_weight = self.space.element_outer_weight_gradient(
|
|
158
|
-
args.elt_arg,
|
|
159
|
-
args.eval_arg,
|
|
160
|
-
s.element_index,
|
|
161
|
-
s.element_coords,
|
|
162
|
-
get_node_index_in_element(s.test_dof),
|
|
163
|
-
)
|
|
164
|
-
grad_transform = self.space.element_outer_reference_gradient_transform(args.elt_arg, s)
|
|
165
|
-
return utils.generalized_inner(
|
|
166
|
-
self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.test_dof),
|
|
167
|
-
nabla_weight * grad_transform,
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
return eval_div_test_outer
|
|
171
|
-
|
|
172
|
-
def _make_at_node(self):
|
|
173
|
-
@cache.dynamic_func(suffix=self.name)
|
|
174
|
-
def at_node(args: self.ElementEvalArg, s: Sample):
|
|
175
|
-
node_coords = self.space.node_coords_in_element(
|
|
176
|
-
args.elt_arg, args.eval_arg, s.element_index, get_node_index_in_element(s.test_dof)
|
|
177
|
-
)
|
|
178
|
-
return Sample(s.element_index, node_coords, s.qp_index, s.qp_weight, s.test_dof, s.trial_dof)
|
|
179
|
-
|
|
180
|
-
return at_node
|
warp/fem/field/trial.py
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import warp as wp
|
|
2
|
-
from warp.fem import cache, utils
|
|
3
|
-
from warp.fem.domain import GeometryDomain
|
|
4
|
-
from warp.fem.space import FunctionSpace, SpacePartition
|
|
5
|
-
from warp.fem.types import Sample, get_node_index_in_element
|
|
6
|
-
|
|
7
|
-
from .field import SpaceField
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class TrialField(SpaceField):
|
|
11
|
-
"""Field defined over a domain that can be used as a trial function"""
|
|
12
|
-
|
|
13
|
-
def __init__(
|
|
14
|
-
self,
|
|
15
|
-
space: FunctionSpace,
|
|
16
|
-
space_partition: SpacePartition,
|
|
17
|
-
domain: GeometryDomain,
|
|
18
|
-
):
|
|
19
|
-
if domain.dimension == space.dimension - 1:
|
|
20
|
-
space = space.trace()
|
|
21
|
-
|
|
22
|
-
if domain.dimension != space.dimension:
|
|
23
|
-
raise ValueError("Incompatible space and domain dimensions")
|
|
24
|
-
|
|
25
|
-
if not space.topology.is_derived_from(space_partition.space_topology):
|
|
26
|
-
raise ValueError("Incompatible space and space partition topologies")
|
|
27
|
-
|
|
28
|
-
super().__init__(space, space_partition)
|
|
29
|
-
|
|
30
|
-
self.domain = domain
|
|
31
|
-
|
|
32
|
-
self.EvalArg = self.space.SpaceArg
|
|
33
|
-
self.ElementEvalArg = self._make_element_eval_arg()
|
|
34
|
-
|
|
35
|
-
self.eval_degree = self._make_eval_degree()
|
|
36
|
-
self.eval_inner = self._make_eval_inner()
|
|
37
|
-
self.eval_grad_inner = self._make_eval_grad_inner()
|
|
38
|
-
self.eval_div_inner = self._make_eval_div_inner()
|
|
39
|
-
self.eval_outer = self._make_eval_outer()
|
|
40
|
-
self.eval_grad_outer = self._make_eval_grad_outer()
|
|
41
|
-
self.eval_div_outer = self._make_eval_div_outer()
|
|
42
|
-
self.at_node = self._make_at_node()
|
|
43
|
-
|
|
44
|
-
def partition_node_count(self) -> int:
|
|
45
|
-
"""Returns the number of nodes in the associated space topology partition"""
|
|
46
|
-
return self.space_partition.node_count()
|
|
47
|
-
|
|
48
|
-
@property
|
|
49
|
-
def name(self) -> str:
|
|
50
|
-
return self.space.name + "Trial"
|
|
51
|
-
|
|
52
|
-
def eval_arg_value(self, device) -> wp.codegen.StructInstance:
|
|
53
|
-
return self.space.space_arg_value(device)
|
|
54
|
-
|
|
55
|
-
def _make_element_eval_arg(self):
|
|
56
|
-
@cache.dynamic_struct(suffix=self.name)
|
|
57
|
-
class ElementEvalArg:
|
|
58
|
-
elt_arg: self.domain.ElementArg
|
|
59
|
-
eval_arg: self.EvalArg
|
|
60
|
-
|
|
61
|
-
return ElementEvalArg
|
|
62
|
-
|
|
63
|
-
def _make_eval_inner(self):
|
|
64
|
-
@cache.dynamic_func(suffix=self.name)
|
|
65
|
-
def eval_trial_inner(args: self.ElementEvalArg, s: Sample):
|
|
66
|
-
weight = self.space.element_inner_weight(
|
|
67
|
-
args.elt_arg,
|
|
68
|
-
args.eval_arg,
|
|
69
|
-
s.element_index,
|
|
70
|
-
s.element_coords,
|
|
71
|
-
get_node_index_in_element(s.trial_dof),
|
|
72
|
-
)
|
|
73
|
-
return weight * self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.trial_dof)
|
|
74
|
-
|
|
75
|
-
return eval_trial_inner
|
|
76
|
-
|
|
77
|
-
def _make_eval_grad_inner(self):
|
|
78
|
-
if not self.gradient_valid():
|
|
79
|
-
return None
|
|
80
|
-
|
|
81
|
-
@cache.dynamic_func(suffix=self.name)
|
|
82
|
-
def eval_nabla_trial_inner(args: self.ElementEvalArg, s: Sample):
|
|
83
|
-
nabla_weight = self.space.element_inner_weight_gradient(
|
|
84
|
-
args.elt_arg,
|
|
85
|
-
args.eval_arg,
|
|
86
|
-
s.element_index,
|
|
87
|
-
s.element_coords,
|
|
88
|
-
get_node_index_in_element(s.trial_dof),
|
|
89
|
-
)
|
|
90
|
-
grad_transform = self.space.element_inner_reference_gradient_transform(args.elt_arg, s)
|
|
91
|
-
return utils.generalized_outer(
|
|
92
|
-
self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.trial_dof),
|
|
93
|
-
nabla_weight * grad_transform,
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
return eval_nabla_trial_inner
|
|
97
|
-
|
|
98
|
-
def _make_eval_div_inner(self):
|
|
99
|
-
if not self.divergence_valid():
|
|
100
|
-
return None
|
|
101
|
-
|
|
102
|
-
@cache.dynamic_func(suffix=self.name)
|
|
103
|
-
def eval_div_trial_inner(args: self.ElementEvalArg, s: Sample):
|
|
104
|
-
nabla_weight = self.space.element_inner_weight_gradient(
|
|
105
|
-
args.elt_arg,
|
|
106
|
-
args.eval_arg,
|
|
107
|
-
s.element_index,
|
|
108
|
-
s.element_coords,
|
|
109
|
-
get_node_index_in_element(s.trial_dof),
|
|
110
|
-
)
|
|
111
|
-
grad_transform = self.space.element_inner_reference_gradient_transform(args.elt_arg, s)
|
|
112
|
-
return utils.generalized_inner(
|
|
113
|
-
self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.trial_dof),
|
|
114
|
-
nabla_weight * grad_transform,
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
return eval_div_trial_inner
|
|
118
|
-
|
|
119
|
-
def _make_eval_outer(self):
|
|
120
|
-
@cache.dynamic_func(suffix=self.name)
|
|
121
|
-
def eval_trial_outer(args: self.ElementEvalArg, s: Sample):
|
|
122
|
-
weight = self.space.element_outer_weight(
|
|
123
|
-
args.elt_arg,
|
|
124
|
-
args.eval_arg,
|
|
125
|
-
s.element_index,
|
|
126
|
-
s.element_coords,
|
|
127
|
-
get_node_index_in_element(s.trial_dof),
|
|
128
|
-
)
|
|
129
|
-
return weight * self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.trial_dof)
|
|
130
|
-
|
|
131
|
-
return eval_trial_outer
|
|
132
|
-
|
|
133
|
-
def _make_eval_grad_outer(self):
|
|
134
|
-
if not self.gradient_valid():
|
|
135
|
-
return None
|
|
136
|
-
|
|
137
|
-
@cache.dynamic_func(suffix=self.name)
|
|
138
|
-
def eval_nabla_trial_outer(args: self.ElementEvalArg, s: Sample):
|
|
139
|
-
nabla_weight = self.space.element_outer_weight_gradient(
|
|
140
|
-
args.elt_arg,
|
|
141
|
-
args.eval_arg,
|
|
142
|
-
s.element_index,
|
|
143
|
-
s.element_coords,
|
|
144
|
-
get_node_index_in_element(s.trial_dof),
|
|
145
|
-
)
|
|
146
|
-
grad_transform = self.space.element_outer_reference_gradient_transform(args.elt_arg, s)
|
|
147
|
-
return utils.generalized_outer(
|
|
148
|
-
self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.trial_dof),
|
|
149
|
-
nabla_weight * grad_transform,
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
return eval_nabla_trial_outer
|
|
153
|
-
|
|
154
|
-
def _make_eval_div_outer(self):
|
|
155
|
-
if not self.divergence_valid():
|
|
156
|
-
return None
|
|
157
|
-
|
|
158
|
-
@cache.dynamic_func(suffix=self.name)
|
|
159
|
-
def eval_div_trial_outer(args: self.ElementEvalArg, s: Sample):
|
|
160
|
-
nabla_weight = self.space.element_outer_weight_gradient(
|
|
161
|
-
args.elt_arg,
|
|
162
|
-
args.eval_arg,
|
|
163
|
-
s.element_index,
|
|
164
|
-
s.element_coords,
|
|
165
|
-
get_node_index_in_element(s.trial_dof),
|
|
166
|
-
)
|
|
167
|
-
grad_transform = self.space.element_outer_reference_gradient_transform(args.elt_arg, s)
|
|
168
|
-
return utils.generalized_inner(
|
|
169
|
-
self.space.unit_dof_value(args.elt_arg, args.eval_arg, s.trial_dof),
|
|
170
|
-
nabla_weight * grad_transform,
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
return eval_div_trial_outer
|
|
174
|
-
|
|
175
|
-
def _make_at_node(self):
|
|
176
|
-
@cache.dynamic_func(suffix=self.name)
|
|
177
|
-
def at_node(args: self.ElementEvalArg, s: Sample):
|
|
178
|
-
node_coords = self.space.node_coords_in_element(
|
|
179
|
-
args.elt_arg, args.eval_arg, s.element_index, get_node_index_in_element(s.trial_dof)
|
|
180
|
-
)
|
|
181
|
-
return Sample(s.element_index, node_coords, s.qp_index, s.qp_weight, s.test_dof, s.trial_dof)
|
|
182
|
-
|
|
183
|
-
return at_node
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
|
-
import warp as wp
|
|
4
|
-
from warp.fem import cache, utils
|
|
5
|
-
from warp.fem.types import DofIndex, get_node_coord
|
|
6
|
-
|
|
7
|
-
from .basis_space import BasisSpace
|
|
8
|
-
from .dof_mapper import DofMapper, IdentityMapper
|
|
9
|
-
from .function_space import FunctionSpace
|
|
10
|
-
from .partition import SpacePartition, make_space_partition
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class CollocatedFunctionSpace(FunctionSpace):
|
|
14
|
-
"""Function space where values are collocated at nodes"""
|
|
15
|
-
|
|
16
|
-
def __init__(self, basis: BasisSpace, dtype: type = float, dof_mapper: DofMapper = None):
|
|
17
|
-
super().__init__(topology=basis.topology)
|
|
18
|
-
|
|
19
|
-
self.dof_mapper = IdentityMapper(dtype) if dof_mapper is None else dof_mapper
|
|
20
|
-
self.dtype = self.dof_mapper.value_dtype
|
|
21
|
-
self.dof_dtype = self.dof_mapper.dof_dtype
|
|
22
|
-
self.VALUE_DOF_COUNT = self.dof_mapper.DOF_SIZE
|
|
23
|
-
|
|
24
|
-
self._basis = basis
|
|
25
|
-
self.SpaceArg = self._basis.BasisArg
|
|
26
|
-
|
|
27
|
-
self.ORDER = self._basis.ORDER
|
|
28
|
-
|
|
29
|
-
self.unit_dof_value = self._make_unit_dof_value(self.dof_mapper)
|
|
30
|
-
|
|
31
|
-
self.node_coords_in_element = self._basis.make_node_coords_in_element()
|
|
32
|
-
self.node_quadrature_weight = self._basis.make_node_quadrature_weight()
|
|
33
|
-
self.element_inner_weight = self._basis.make_element_inner_weight()
|
|
34
|
-
self.element_inner_weight_gradient = self._basis.make_element_inner_weight_gradient()
|
|
35
|
-
self.element_outer_weight = self._basis.make_element_outer_weight()
|
|
36
|
-
self.element_outer_weight_gradient = self._basis.make_element_outer_weight_gradient()
|
|
37
|
-
|
|
38
|
-
# For backward compatibility
|
|
39
|
-
if hasattr(basis, "node_grid"):
|
|
40
|
-
self.node_grid = basis.node_grid
|
|
41
|
-
if hasattr(basis, "node_triangulation"):
|
|
42
|
-
self.node_triangulation = basis.node_triangulation
|
|
43
|
-
if hasattr(basis, "node_tets"):
|
|
44
|
-
self.node_tets = basis.node_tets
|
|
45
|
-
if hasattr(basis, "node_hexes"):
|
|
46
|
-
self.node_hexes = basis.node_hexes
|
|
47
|
-
if hasattr(basis, "vtk_cells"):
|
|
48
|
-
self.vtk_cells = basis.vtk_cells
|
|
49
|
-
|
|
50
|
-
def space_arg_value(self, device):
|
|
51
|
-
return self._basis.basis_arg_value(device)
|
|
52
|
-
|
|
53
|
-
@property
|
|
54
|
-
def name(self):
|
|
55
|
-
return f"{self._basis.name}_{self.dof_mapper}".replace(".", "_")
|
|
56
|
-
|
|
57
|
-
@property
|
|
58
|
-
def degree(self):
|
|
59
|
-
"""Maximum polynomial degree of the underlying basis"""
|
|
60
|
-
return self.ORDER
|
|
61
|
-
|
|
62
|
-
def make_field(
|
|
63
|
-
self,
|
|
64
|
-
space_partition: Optional[SpacePartition] = None,
|
|
65
|
-
) -> "wp.fem.field.NodalField":
|
|
66
|
-
from warp.fem.field import NodalField
|
|
67
|
-
|
|
68
|
-
if space_partition is None:
|
|
69
|
-
space_partition = make_space_partition(space_topology=self.topology)
|
|
70
|
-
|
|
71
|
-
return NodalField(space=self, space_partition=space_partition)
|
|
72
|
-
|
|
73
|
-
def _make_unit_dof_value(self, dof_mapper: DofMapper):
|
|
74
|
-
@cache.dynamic_func(suffix=self.name)
|
|
75
|
-
def unit_dof_value(geo_arg: self.topology.ElementArg, space_arg: self.SpaceArg, dof: DofIndex):
|
|
76
|
-
return dof_mapper.dof_to_value(utils.unit_element(dof_mapper.dof_dtype(0.0), get_node_coord(dof)))
|
|
77
|
-
|
|
78
|
-
return unit_dof_value
|
|
79
|
-
|
|
80
|
-
def node_count(self):
|
|
81
|
-
return self.topology.node_count()
|
|
82
|
-
|
|
83
|
-
def node_positions(self, out: Optional[wp.array] = None) -> wp.array:
|
|
84
|
-
return self._basis.node_positions(out=out)
|
|
85
|
-
|
|
86
|
-
def trace(self) -> "CollocatedFunctionSpace":
|
|
87
|
-
return CollocatedFunctionSpaceTrace(self)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class CollocatedFunctionSpaceTrace(CollocatedFunctionSpace):
|
|
91
|
-
"""Trace of a :class:`CollocatedFunctionSpace`"""
|
|
92
|
-
|
|
93
|
-
def __init__(self, space: CollocatedFunctionSpace):
|
|
94
|
-
self._space = space
|
|
95
|
-
super().__init__(space._basis.trace(), space.dtype, space.dof_mapper)
|
|
96
|
-
|
|
97
|
-
@property
|
|
98
|
-
def name(self):
|
|
99
|
-
return f"{self._space.name}_Trace"
|
|
100
|
-
|
|
101
|
-
def __eq__(self, other: "CollocatedFunctionSpaceTrace") -> bool:
|
|
102
|
-
return self._space == other._space
|